summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-06-01 18:03:31 +0200
committerThomas Haller <thaller@redhat.com>2015-06-02 12:57:52 +0200
commit0aed4e2388a4c8ce0f82d87a24ed5e66b76fa4f7 (patch)
tree68ffbeb4dba21b7e852a221e4b03d127eec5451a
parent2e87df84088295be52f68c074cb8799f1d17da44 (diff)
downloadNetworkManager-0aed4e2388a4c8ce0f82d87a24ed5e66b76fa4f7.tar.gz
ifcfg-rh: better detect alias files
Alias files have a ':' to separate the base name from their alias. But we didn't always ensure not to write-out files without colon, and also initscripts doesn't have that restriction. We should detect alias files and handle them properly (e.g. by reloading the base file). This fixes an error that a `nmcli con load` would have tried to load the alias file. Also extend load_connection() to support passing filenames other then the base file. We only have to handle this in plugin.c. Inside reader.c we always have the normalized base filename. Or detection of alias files only looks whether the filename has a ':' and whether a corresponding base file exists.
-rw-r--r--src/settings/plugins/ifcfg-rh/plugin.c48
-rw-r--r--src/settings/plugins/ifcfg-rh/utils.c51
-rw-r--r--src/settings/plugins/ifcfg-rh/utils.h3
3 files changed, 57 insertions, 45 deletions
diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c
index 0d4ad1be35..5dd32af83a 100644
--- a/src/settings/plugins/ifcfg-rh/plugin.c
+++ b/src/settings/plugins/ifcfg-rh/plugin.c
@@ -425,25 +425,13 @@ ifcfg_dir_changed (GFileMonitor *monitor,
gpointer user_data)
{
SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (user_data);
- char *path, *base, *ifcfg_path;
+ char *path, *ifcfg_path;
NMIfcfgConnection *connection;
path = g_file_get_path (file);
- if (utils_should_ignore_file (path, FALSE)) {
- g_free (path);
- return;
- }
-
- _LOGD ("ifcfg_dir_changed(%s) = %d", path, event_type);
- base = g_file_get_basename (file);
- if (utils_is_ifcfg_alias_file (base, NULL)) {
- /* Alias file changed. Get the base ifcfg file from it */
- ifcfg_path = utils_get_ifcfg_from_alias (path);
- } else {
- /* Given any ifcfg, keys, or routes file, get the ifcfg file path */
- ifcfg_path = utils_get_ifcfg_path (path);
- }
+ ifcfg_path = utils_detect_ifcfg_path (path, FALSE);
+ _LOGD ("ifcfg_dir_changed(%s) = %d // %s", path, event_type, ifcfg_path ? ifcfg_path : "(none)");
if (ifcfg_path) {
connection = find_by_path (plugin, ifcfg_path);
switch (event_type) {
@@ -462,7 +450,6 @@ ifcfg_dir_changed (GFileMonitor *monitor,
g_free (ifcfg_path);
}
g_free (path);
- g_free (base);
}
static void
@@ -546,18 +533,14 @@ read_connections (SCPluginIfcfg *plugin)
filenames = g_ptr_array_new_with_free_func (g_free);
while ((item = g_dir_read_name (dir))) {
- char *full_path;
-
- if (utils_should_ignore_file (item, TRUE))
- continue;
- if (utils_is_ifcfg_alias_file (item, NULL))
- continue;
+ char *full_path, *real_path;
full_path = g_build_filename (IFCFG_DIR, item, NULL);
- if (!utils_get_ifcfg_name (full_path, TRUE))
- g_free (full_path);
- else
- g_ptr_array_add (filenames, full_path);
+ real_path = utils_detect_ifcfg_path (full_path, TRUE);
+
+ if (real_path)
+ g_ptr_array_add (filenames, real_path);
+ g_free (full_path);
}
g_dir_close (dir);
@@ -629,20 +612,25 @@ load_connection (NMSystemConfigInterface *config,
SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (config);
NMIfcfgConnection *connection;
int dir_len = strlen (IFCFG_DIR);
+ char *ifcfg_path;
if ( strncmp (filename, IFCFG_DIR, dir_len) != 0
|| filename[dir_len] != '/'
|| strchr (filename + dir_len + 1, '/') != NULL)
return FALSE;
- if (utils_should_ignore_file (filename + dir_len + 1, TRUE))
+ /* get the real ifcfg-path. This allows us to properly
+ * handle load command using a route-* file etc. */
+ ifcfg_path = utils_detect_ifcfg_path (filename, FALSE);
+ if (!ifcfg_path)
return FALSE;
- connection = find_by_path (plugin, filename);
- update_connection (plugin, NULL, filename, connection, TRUE, NULL, NULL);
+ connection = find_by_path (plugin, ifcfg_path);
+ update_connection (plugin, NULL, ifcfg_path, connection, TRUE, NULL, NULL);
if (!connection)
- connection = find_by_path (plugin, filename);
+ connection = find_by_path (plugin, ifcfg_path);
+ g_free (ifcfg_path);
return (connection != NULL);
}
diff --git a/src/settings/plugins/ifcfg-rh/utils.c b/src/settings/plugins/ifcfg-rh/utils.c
index 5519aac716..a793288d91 100644
--- a/src/settings/plugins/ifcfg-rh/utils.c
+++ b/src/settings/plugins/ifcfg-rh/utils.c
@@ -224,6 +224,12 @@ utils_get_ifcfg_name (const char *file, gboolean only_ifcfg)
} \
} G_STMT_END
+ /* Do not detect alias files and return 'eth0:0' instead of 'eth0'.
+ * Unfortunately, we cannot be sure that our files don't contain colons,
+ * so we cannot reject files with colons.
+ *
+ * Instead, you must not call utils_get_ifcfg_name() with an alias file
+ * or files that are ignored. */
MATCH_TAG_AND_RETURN (name, IFCFG_TAG);
if (!only_ifcfg) {
MATCH_TAG_AND_RETURN (name, KEYS_TAG);
@@ -419,26 +425,43 @@ utils_is_ifcfg_alias_file (const char *alias, const char *ifcfg)
}
char *
-utils_get_ifcfg_from_alias (const char *alias)
+utils_detect_ifcfg_path (const char *path, gboolean only_ifcfg)
{
- char *base, *ptr, *ifcfg = NULL;
+ gs_free char *base = NULL;
+ char *ptr, *ifcfg = NULL;
- g_return_val_if_fail (alias != NULL, NULL);
+ g_return_val_if_fail (path != NULL, NULL);
- base = g_path_get_basename (alias);
- g_return_val_if_fail (base != NULL, NULL);
+ if (utils_should_ignore_file (path, only_ifcfg))
+ return NULL;
- if (utils_is_ifcfg_alias_file (base, NULL)) {
- ifcfg = g_strdup (alias);
- ptr = strrchr (ifcfg, ':');
- if (ptr)
- *ptr = '\0';
- else {
+ base = g_path_get_basename (path);
+
+ if (strncmp (base, IFCFG_TAG, STRLEN (IFCFG_TAG)) == 0) {
+ if (base[STRLEN (IFCFG_TAG)] == '\0')
+ return NULL;
+ if (utils_is_ifcfg_alias_file (base, NULL)) {
+ ifcfg = g_strdup (path);
+ ptr = strrchr (ifcfg, ':');
+ if (ptr && ptr > ifcfg) {
+ *ptr = '\0';
+ if (g_file_test (ifcfg, G_FILE_TEST_EXISTS)) {
+ /* the file has a colon, so it is probably an alias.
+ * To be ~more~ certain that this is an alias file,
+ * check whether a corresponding base file exists. */
+ if (only_ifcfg) {
+ g_free (ifcfg);
+ return NULL;
+ }
+ return ifcfg;
+ }
+ }
g_free (ifcfg);
- ifcfg = NULL;
}
+ return g_strdup (path);
}
- g_free (base);
- return ifcfg;
+ if (only_ifcfg)
+ return NULL;
+ return utils_get_ifcfg_path (path);
}
diff --git a/src/settings/plugins/ifcfg-rh/utils.h b/src/settings/plugins/ifcfg-rh/utils.h
index 445437c48b..547bfcb2d7 100644
--- a/src/settings/plugins/ifcfg-rh/utils.h
+++ b/src/settings/plugins/ifcfg-rh/utils.h
@@ -59,7 +59,8 @@ gboolean utils_has_complex_routes (const char *filename);
gboolean utils_ignore_ip_config (NMConnection *connection);
gboolean utils_is_ifcfg_alias_file (const char *alias, const char *ifcfg);
-char *utils_get_ifcfg_from_alias (const char *alias);
+
+char *utils_detect_ifcfg_path (const char *path, gboolean only_ifcfg);
#endif /* _UTILS_H_ */