diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2016-11-28 12:32:03 +0000 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2017-01-12 19:08:31 +0100 |
commit | b28b275c5e6c36bf7b63ed9ab7b99505de61bf98 (patch) | |
tree | ab21051d65385423e2661a04a2cf0d6f6038b5a9 | |
parent | c0fa787c2882d3db754faeecad3d4efbc6f5456d (diff) |
ifcfg-rh: write the master device name even if the master property is an UUIDnm-1-4
We used MASTER, BRIDGE and TEAM_MASTER keys for a differnet purpose than the
network.service did, confusing the legacy tooling. Let's do our best to write
compatible configuration files:
* Add *_UUID properties that won't clash with initscripts
* Ignore non-*_UUID keys on read if *_UUID is present
* If the connection.master is an UUID of a connection with a
connection.interface-name, write the uuid into the *_UUID key while setting
the non-*_UUID key to the interface name for compatibility
https://bugzilla.redhat.com/show_bug.cgi?id=1369091
(cherry picked from commit 8b7b0d3fc2604a2cdecb32d97f8cb3ff63a069f0)
-rw-r--r-- | libnm-core/nm-setting-connection.c | 14 | ||||
-rw-r--r-- | src/nm-manager.c | 24 | ||||
-rw-r--r-- | src/nm-manager.h | 3 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/reader.c | 18 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/writer.c | 39 |
5 files changed, 79 insertions, 19 deletions
diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c index f6b801c6b..a0a679e6f 100644 --- a/libnm-core/nm-setting-connection.c +++ b/libnm-core/nm-setting-connection.c @@ -1650,9 +1650,11 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) **/ /* ---ifcfg-rh--- * property: master - * variable: MASTER, TEAM_MASTER, BRIDGE + * variable: MASTER, MASTER_UUID, TEAM_MASTER, TEAM_MASTER_UUID, BRIDGE, BRIDGE_UUID * description: Reference to master connection. The variable used depends on - * the connection type. + * the connection type and the value. In general, if the *_UUID variant is present, + * the variant without *_UUID is ignored. NetworkManager attempts to write both + * for compatibility with legacy tooling. * ---end--- */ g_object_class_install_property @@ -1673,10 +1675,12 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) **/ /* ---ifcfg-rh--- * property: slave-type - * variable: MASTER, TEAM_MASTER, DEVICETYPE, BRIDGE + * variable: MASTER, MASTER_UUID, TEAM_MASTER, TEAM_MASTER_UUID, DEVICETYPE, + * BRIDGE, BRIDGE_UUID * description: Slave type doesn't map directly to a variable, but it is - * recognized using different variables. MASTER for bonding, - * TEAM_MASTER and DEVICETYPE for teaming, BRIDGE for bridging. + * recognized using different variables. MASTER and MASTER_UUID for bonding, + * TEAM_MASTER, TEAM_MASTER_UUID and DEVICETYPE for teaming, BRIDGE + * and BRIDGE_UUID for bridging. * ---end--- */ g_object_class_install_property diff --git a/src/nm-manager.c b/src/nm-manager.c index c3d65cd1e..964c18a6d 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1135,6 +1135,30 @@ nm_manager_get_connection_iface (NMManager *self, } /** + * nm_manager_iface_for_uuid: + * @self: the #NMManager + * @uuid: the connection uuid + * + * Gets a link name for the given UUID. Useful for the settings plugins that + * wish to write configuration files compatible with tooling that can't + * interpret our UUIDs. + * + * Returns: An interface name; %NULL if none matches + */ +const char * +nm_manager_iface_for_uuid (NMManager *self, const char *uuid) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + NMSettingsConnection *connection; + + connection = nm_settings_get_connection_by_uuid (priv->settings, uuid); + if (!connection) + return NULL; + + return nm_connection_get_interface_name (NM_CONNECTION (connection)); +} + +/** * system_create_virtual_device: * @self: the #NMManager * @connection: the connection which might require a virtual device diff --git a/src/nm-manager.h b/src/nm-manager.h index d7aabff16..ce3fa5a5b 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -99,6 +99,9 @@ char * nm_manager_get_connection_iface (NMManager *self, NMDevice **out_parent, GError **error); +const char * nm_manager_iface_for_uuid (NMManager *self, + const char *uuid); + NMActiveConnection *nm_manager_activate_connection (NMManager *manager, NMSettingsConnection *connection, const char *specific_object, diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index 5a351cfa0..825d51ed0 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -227,7 +227,9 @@ make_connection_setting (const char *file, g_strfreev (items); } - value = svGetValue (ifcfg, "BRIDGE", FALSE); + value = svGetValue (ifcfg, "BRIDGE_UUID", FALSE); + if (!value) + value = svGetValue (ifcfg, "BRIDGE", FALSE); if (value) { const char *old_value; @@ -1607,7 +1609,10 @@ check_if_bond_slave (shvarFile *ifcfg, { char *value; - value = svGetValue (ifcfg, "MASTER", FALSE); + value = svGetValue (ifcfg, "MASTER_UUID", FALSE); + if (!value) + value = svGetValue (ifcfg, "MASTER", FALSE); + if (value) { g_object_set (s_con, NM_SETTING_CONNECTION_MASTER, value, NULL); g_object_set (s_con, @@ -1627,9 +1632,12 @@ check_if_team_slave (shvarFile *ifcfg, { gs_free char *value = NULL; - value = svGetValue (ifcfg, "TEAM_MASTER", FALSE); + value = svGetValue (ifcfg, "TEAM_MASTER_UUID", FALSE); + if (!value) + value = svGetValue (ifcfg, "TEAM_MASTER", FALSE); if (!value) return FALSE; + g_object_set (s_con, NM_SETTING_CONNECTION_MASTER, value, NULL); g_object_set (s_con, NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_TEAM_SETTING_NAME, NULL); return TRUE; @@ -4563,7 +4571,9 @@ make_bridge_port_setting (shvarFile *ifcfg) g_return_val_if_fail (ifcfg != NULL, FALSE); - value = svGetValue (ifcfg, "BRIDGE", FALSE); + value = svGetValue (ifcfg, "BRIDGE_UUID", FALSE); + if (!value) + value = svGetValue (ifcfg, "BRIDGE", FALSE); if (value) { g_free (value); diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index dcc48f2ac..dff8f1bc6 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -32,6 +32,7 @@ #include <unistd.h> #include <stdio.h> +#include "nm-manager.h" #include "nm-setting-connection.h" #include "nm-setting-wired.h" #include "nm-setting-wireless.h" @@ -1804,13 +1805,13 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) { guint32 n, i; GString *str; - const char *master, *type; + const char *master, *master_iface = NULL, *type; char *tmp; gint i_int; - const char *v_master = NULL; + const char *v_master = NULL, *v_master_uuid = NULL; + const char *v_bridge = NULL, *v_bridge_uuid = NULL; + const char *v_team_master = NULL, *v_team_master_uuid = NULL; const char *v_slave = NULL; - const char *v_bridge = NULL; - const char *v_team_master = NULL; svSetValue (ifcfg, "NAME", nm_setting_connection_get_id (s_con), FALSE); svSetValue (ifcfg, "UUID", nm_setting_connection_get_uuid (s_con), FALSE); @@ -1878,25 +1879,43 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) master = nm_setting_connection_get_master (s_con); if (master) { + /* The reader prefers the *_UUID variants, however we still try to resolve + * it into an interface name, so that legacy tooling is not confused. */ + if (!nm_utils_get_testing ()) { + /* This is conditional for easier testing. */ + master_iface = nm_manager_iface_for_uuid (nm_manager_get (), master); + } + if (!master_iface) { + master_iface = master; + master = NULL; + + } + if (nm_setting_connection_is_slave_type (s_con, NM_SETTING_BOND_SETTING_NAME)) { - v_master = master; + v_master_uuid = master; + v_master = master_iface; v_slave = "yes"; - } else if (nm_setting_connection_is_slave_type (s_con, NM_SETTING_BRIDGE_SETTING_NAME)) - v_bridge = master; - else if (nm_setting_connection_is_slave_type (s_con, NM_SETTING_TEAM_SETTING_NAME)) { - v_team_master = master; + } else if (nm_setting_connection_is_slave_type (s_con, NM_SETTING_BRIDGE_SETTING_NAME)) { + v_bridge_uuid = master; + v_bridge = master_iface; + } else if (nm_setting_connection_is_slave_type (s_con, NM_SETTING_TEAM_SETTING_NAME)) { + v_team_master_uuid = master; + v_team_master = master_iface; svSetValue (ifcfg, "TYPE", NULL, FALSE); } } + svSetValue (ifcfg, "MASTER_UUID", v_master_uuid, FALSE); svSetValue (ifcfg, "MASTER", v_master, FALSE); svSetValue (ifcfg, "SLAVE", v_slave, FALSE); + svSetValue (ifcfg, "BRIDGE_UUID", v_bridge_uuid, FALSE); svSetValue (ifcfg, "BRIDGE", v_bridge, FALSE); + svSetValue (ifcfg, "TEAM_MASTER_UUID", v_team_master_uuid, FALSE); svSetValue (ifcfg, "TEAM_MASTER", v_team_master, FALSE); if (nm_streq0 (type, NM_SETTING_TEAM_SETTING_NAME)) svSetValue (ifcfg, "DEVICETYPE", TYPE_TEAM, FALSE); - else if (master && nm_setting_connection_is_slave_type (s_con, NM_SETTING_TEAM_SETTING_NAME)) + else if (master_iface && nm_setting_connection_is_slave_type (s_con, NM_SETTING_TEAM_SETTING_NAME)) svSetValue (ifcfg, "DEVICETYPE", TYPE_TEAM_PORT, FALSE); else svSetValue (ifcfg, "DEVICETYPE", NULL, FALSE); |