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-01 19:01:09 +0200
commitead6b1a862e2129e058b50f7e81b3a3105b6bbf6 (patch)
tree93a3c2c8007a0b9ae7c93672f0037d98629735f8
parentf1415039960b87bdeca77cc92ded08a10ee4b619 (diff)
downloadNetworkManager-th/ifcfg-rh-fixes-bgo750231.tar.gz
ifcfg-rh: better detect alias filesth/ifcfg-rh-fixes-bgo750231
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..c7a87cc565 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 reload 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_ */