summaryrefslogtreecommitdiff
path: root/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c')
-rw-r--r--src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c286
1 files changed, 183 insertions, 103 deletions
diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c
index 04d3d3e45..3db06f17d 100644
--- a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c
+++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c
@@ -35,10 +35,12 @@
#include <nm-setting-8021x.h>
#include "common.h"
+#include "nm-config.h"
#include "nm-ifcfg-connection.h"
#include "reader.h"
#include "writer.h"
#include "nm-inotify-helper.h"
+#include "utils.h"
G_DEFINE_TYPE (NMIfcfgConnection, nm_ifcfg_connection, NM_TYPE_SETTINGS_CONNECTION)
@@ -59,12 +61,14 @@ typedef struct {
char *route6file;
int route6file_wd;
- char *unmanaged;
+ char *unmanaged_spec;
+ char *unrecognized_spec;
} NMIfcfgConnectionPrivate;
enum {
PROP_0,
- PROP_UNMANAGED,
+ PROP_UNMANAGED_SPEC,
+ PROP_UNRECOGNIZED_SPEC,
LAST_PROP
};
@@ -96,86 +100,159 @@ files_changed_cb (NMInotifyHelper *ih,
}
NMIfcfgConnection *
-nm_ifcfg_connection_new (const char *full_path,
- NMConnection *source,
+nm_ifcfg_connection_new (NMConnection *source,
+ const char *full_path,
GError **error,
gboolean *ignore_error)
{
GObject *object;
- NMIfcfgConnectionPrivate *priv;
NMConnection *tmp;
- char *unmanaged = NULL;
- char *keyfile = NULL;
- char *routefile = NULL;
- char *route6file = NULL;
- NMInotifyHelper *ih;
+ char *unhandled_spec = NULL;
+ const char *unmanaged_spec = NULL, *unrecognized_spec = NULL;
+ gboolean update_unsaved = TRUE;
- g_return_val_if_fail (full_path != NULL, NULL);
+ g_assert (source || full_path);
/* If we're given a connection already, prefer that instead of re-reading */
if (source)
tmp = g_object_ref (source);
else {
+ char *keyfile = NULL, *routefile = NULL, *route6file = NULL;
+
tmp = connection_from_file (full_path, NULL, NULL, NULL,
- &unmanaged,
+ &unhandled_spec,
&keyfile,
&routefile,
&route6file,
error,
ignore_error);
+ g_free (keyfile);
+ g_free (routefile);
+ g_free (route6file);
if (!tmp)
return NULL;
+
+ /* If we just read the connection from disk, it's clearly not Unsaved */
+ update_unsaved = FALSE;
}
+ if (unhandled_spec && g_str_has_prefix (unhandled_spec, "unmanaged:"))
+ unmanaged_spec = unhandled_spec + strlen ("unmanaged:");
+ else if (unhandled_spec && g_str_has_prefix (unhandled_spec, "unrecognized:"))
+ unrecognized_spec = unhandled_spec + strlen ("unrecognized:");
+
object = (GObject *) g_object_new (NM_TYPE_IFCFG_CONNECTION,
- NM_IFCFG_CONNECTION_UNMANAGED, unmanaged,
+ NM_IFCFG_CONNECTION_UNMANAGED_SPEC, unmanaged_spec,
+ NM_IFCFG_CONNECTION_UNRECOGNIZED_SPEC, unrecognized_spec,
NULL);
- if (!object)
- goto out;
-
- /* Update our settings with what was read from the file */
- if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), tmp, error)) {
- g_object_unref (object);
- object = NULL;
- goto out;
+ if (object) {
+ /* Update our settings with what was read from the file */
+ if (nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object),
+ tmp,
+ update_unsaved,
+ error)) {
+ /* Set the path and start monitoring */
+ if (full_path)
+ nm_ifcfg_connection_set_path (NM_IFCFG_CONNECTION (object), full_path);
+ } else {
+ g_object_unref (object);
+ object = NULL;
+ }
}
- priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
- priv->path = g_strdup (full_path);
+ g_object_unref (tmp);
+ g_free (unhandled_spec);
+ return (NMIfcfgConnection *) object;
+}
+
+const char *
+nm_ifcfg_connection_get_path (NMIfcfgConnection *self)
+{
+ g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), NULL);
+
+ return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->path;
+}
+
+static void
+path_watch_stop (NMIfcfgConnection *self)
+{
+ NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self);
+ NMInotifyHelper *ih;
ih = nm_inotify_helper_get ();
- priv->ih_event_id = g_signal_connect (ih, "event", G_CALLBACK (files_changed_cb), object);
- priv->file_wd = nm_inotify_helper_add_watch (ih, full_path);
+ if (priv->ih_event_id) {
+ g_signal_handler_disconnect (ih, priv->ih_event_id);
+ priv->ih_event_id = 0;
+ }
- priv->keyfile = keyfile;
- priv->keyfile_wd = nm_inotify_helper_add_watch (ih, keyfile);
+ if (priv->file_wd >= 0) {
+ nm_inotify_helper_remove_watch (ih, priv->file_wd);
+ priv->file_wd = -1;
+ }
- priv->routefile = routefile;
- priv->routefile_wd = nm_inotify_helper_add_watch (ih, routefile);
+ g_free (priv->keyfile);
+ priv->keyfile = NULL;
+ if (priv->keyfile_wd >= 0) {
+ nm_inotify_helper_remove_watch (ih, priv->keyfile_wd);
+ priv->keyfile_wd = -1;
+ }
- priv->route6file = route6file;
- priv->route6file_wd = nm_inotify_helper_add_watch (ih, route6file);
+ g_free (priv->routefile);
+ priv->routefile = NULL;
+ if (priv->routefile_wd >= 0) {
+ nm_inotify_helper_remove_watch (ih, priv->routefile_wd);
+ priv->routefile_wd = -1;
+ }
-out:
- g_object_unref (tmp);
- return (NMIfcfgConnection *) object;
+ g_free (priv->route6file);
+ priv->route6file = NULL;
+ if (priv->route6file_wd >= 0) {
+ nm_inotify_helper_remove_watch (ih, priv->route6file_wd);
+ priv->route6file_wd = -1;
+ }
+}
+
+void
+nm_ifcfg_connection_set_path (NMIfcfgConnection *self, const char *ifcfg_path)
+{
+ NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self);
+
+ g_return_if_fail (ifcfg_path != NULL);
+
+ path_watch_stop (self);
+ g_free (priv->path);
+
+ priv->path = g_strdup (ifcfg_path);
+ priv->keyfile = utils_get_keys_path (ifcfg_path);
+ priv->routefile = utils_get_route_path (ifcfg_path);
+ priv->route6file = utils_get_route6_path (ifcfg_path);
+
+ if (nm_config_get_monitor_connection_files (nm_config_get ())) {
+ NMInotifyHelper *ih = nm_inotify_helper_get ();
+
+ priv->ih_event_id = g_signal_connect (ih, "event", G_CALLBACK (files_changed_cb), self);
+ priv->file_wd = nm_inotify_helper_add_watch (ih, ifcfg_path);
+ priv->keyfile_wd = nm_inotify_helper_add_watch (ih, priv->keyfile);
+ priv->routefile_wd = nm_inotify_helper_add_watch (ih, priv->routefile);
+ priv->route6file_wd = nm_inotify_helper_add_watch (ih, priv->route6file);
+ }
}
const char *
-nm_ifcfg_connection_get_path (NMIfcfgConnection *self)
+nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self)
{
g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), NULL);
- return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->path;
+ return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->unmanaged_spec;
}
const char *
-nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self)
+nm_ifcfg_connection_get_unrecognized_spec (NMIfcfgConnection *self)
{
g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), NULL);
- return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->unmanaged;
+ return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->unrecognized_spec;
}
static void
@@ -186,41 +263,50 @@ commit_changes (NMSettingsConnection *connection,
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection);
GError *error = NULL;
NMConnection *reread;
- char *unmanaged = NULL, *keyfile = NULL, *routefile = NULL, *route6file = NULL;
- gboolean same = FALSE;
+ gboolean same = FALSE, success = FALSE;
+ char *ifcfg_path = NULL;
/* To ensure we don't rewrite files that are only changed from other
* processes on-disk, read the existing connection back in and only rewrite
* it if it's really changed.
*/
- reread = connection_from_file (priv->path, NULL, NULL, NULL,
- &unmanaged, &keyfile, &routefile, &route6file,
- NULL, NULL);
- g_free (unmanaged);
- g_free (keyfile);
- g_free (routefile);
- g_free (route6file);
-
- if (reread) {
- same = nm_connection_compare (NM_CONNECTION (connection),
- reread,
- NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS |
- NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS);
- g_object_unref (reread);
-
- /* Don't bother writing anything out if in-memory and on-disk data are the same */
- if (same) {
- /* But chain up to parent to handle success - emits updated signal */
- NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->commit_changes (connection, callback, user_data);
- return;
+ if (priv->path) {
+ reread = connection_from_file (priv->path, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ &error, NULL);
+ g_clear_error (&error);
+ if (reread) {
+ same = nm_connection_compare (NM_CONNECTION (connection),
+ reread,
+ NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS |
+ NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS);
+ g_object_unref (reread);
+
+ /* Don't bother writing anything out if in-memory and on-disk data are the same */
+ if (same) {
+ /* But chain up to parent to handle success - emits updated signal */
+ NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->commit_changes (connection, callback, user_data);
+ return;
+ }
+ }
+
+ success = writer_update_connection (NM_CONNECTION (connection),
+ IFCFG_DIR,
+ priv->path,
+ priv->keyfile,
+ &error);
+ } else {
+ success = writer_new_connection (NM_CONNECTION (connection),
+ IFCFG_DIR,
+ &ifcfg_path,
+ &error);
+ if (success) {
+ nm_ifcfg_connection_set_path (NM_IFCFG_CONNECTION (connection), ifcfg_path);
+ g_free (ifcfg_path);
}
}
- if (writer_update_connection (NM_CONNECTION (connection),
- IFCFG_DIR,
- priv->path,
- priv->keyfile,
- &error)) {
+ if (success) {
/* Chain up to parent to handle success */
NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->commit_changes (connection, callback, user_data);
} else {
@@ -237,14 +323,16 @@ do_delete (NMSettingsConnection *connection,
{
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection);
- g_unlink (priv->path);
- if (priv->keyfile)
- g_unlink (priv->keyfile);
- if (priv->routefile)
- g_unlink (priv->routefile);
+ if (priv->path) {
+ g_unlink (priv->path);
+ if (priv->keyfile)
+ g_unlink (priv->keyfile);
+ if (priv->routefile)
+ g_unlink (priv->routefile);
- if (priv->route6file)
- g_unlink (priv->route6file);
+ if (priv->route6file)
+ g_unlink (priv->route6file);
+ }
NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->delete (connection, callback, user_data);
}
@@ -259,31 +347,10 @@ nm_ifcfg_connection_init (NMIfcfgConnection *connection)
static void
finalize (GObject *object)
{
- NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
- NMInotifyHelper *ih;
-
nm_connection_clear_secrets (NM_CONNECTION (object));
- ih = nm_inotify_helper_get ();
-
- if (priv->ih_event_id)
- g_signal_handler_disconnect (ih, priv->ih_event_id);
-
- g_free (priv->path);
- if (priv->file_wd >= 0)
- nm_inotify_helper_remove_watch (ih, priv->file_wd);
-
- g_free (priv->keyfile);
- if (priv->keyfile_wd >= 0)
- nm_inotify_helper_remove_watch (ih, priv->keyfile_wd);
-
- g_free (priv->routefile);
- if (priv->routefile_wd >= 0)
- nm_inotify_helper_remove_watch (ih, priv->routefile_wd);
-
- g_free (priv->route6file);
- if (priv->route6file_wd >= 0)
- nm_inotify_helper_remove_watch (ih, priv->route6file_wd);
+ path_watch_stop (NM_IFCFG_CONNECTION (object));
+ g_free (NM_IFCFG_CONNECTION_GET_PRIVATE (object)->path);
G_OBJECT_CLASS (nm_ifcfg_connection_parent_class)->finalize (object);
}
@@ -295,8 +362,11 @@ set_property (GObject *object, guint prop_id,
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
switch (prop_id) {
- case PROP_UNMANAGED:
- priv->unmanaged = g_value_dup_string (value);
+ case PROP_UNMANAGED_SPEC:
+ priv->unmanaged_spec = g_value_dup_string (value);
+ break;
+ case PROP_UNRECOGNIZED_SPEC:
+ priv->unrecognized_spec = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -311,8 +381,11 @@ get_property (GObject *object, guint prop_id,
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
switch (prop_id) {
- case PROP_UNMANAGED:
- g_value_set_string (value, priv->unmanaged);
+ case PROP_UNMANAGED_SPEC:
+ g_value_set_string (value, priv->unmanaged_spec);
+ break;
+ case PROP_UNRECOGNIZED_SPEC:
+ g_value_set_string (value, priv->unrecognized_spec);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -337,12 +410,19 @@ nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class)
/* Properties */
g_object_class_install_property
- (object_class, PROP_UNMANAGED,
- g_param_spec_string (NM_IFCFG_CONNECTION_UNMANAGED,
- "Unmanaged",
- "Unmanaged",
+ (object_class, PROP_UNMANAGED_SPEC,
+ g_param_spec_string (NM_IFCFG_CONNECTION_UNMANAGED_SPEC,
+ "Unmanaged spec",
+ "Unmanaged spec",
NULL,
G_PARAM_READWRITE));
+ g_object_class_install_property
+ (object_class, PROP_UNRECOGNIZED_SPEC,
+ g_param_spec_string (NM_IFCFG_CONNECTION_UNRECOGNIZED_SPEC,
+ "Unrecognized spec",
+ "Unrecognized spec",
+ NULL,
+ G_PARAM_READWRITE));
signals[IFCFG_CHANGED] =
g_signal_new ("ifcfg-changed",