summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2013-10-31 15:17:33 -0400
committerDan Winship <danw@gnome.org>2013-11-15 13:30:13 -0500
commit51c6269d46b8b7eee9d7eae322fb6bfe6db913dd (patch)
treeb49853a6b9f0127511f5081de2b6d7cf1235a7ad
parent65737d9e482d87f6f87f1fe49d484580d2e89a3f (diff)
downloadNetworkManager-51c6269d46b8b7eee9d7eae322fb6bfe6db913dd.tar.gz
core: add o.fd.NM.Settings.LoadConnections
Add a D-Bus method to reload connection files specified by filename, and implement it in the ifcfg-rh and keyfile backends. https://bugzilla.gnome.org/show_bug.cgi?id=709830
-rw-r--r--introspection/nm-settings.xml34
-rw-r--r--src/settings/nm-settings.c64
-rw-r--r--src/settings/nm-system-config-interface.c11
-rw-r--r--src/settings/nm-system-config-interface.h8
-rw-r--r--src/settings/plugins/ifcfg-rh/plugin.c25
-rw-r--r--src/settings/plugins/keyfile/plugin.c28
6 files changed, 163 insertions, 7 deletions
diff --git a/introspection/nm-settings.xml b/introspection/nm-settings.xml
index 0043ec7564..7e02db7216 100644
--- a/introspection/nm-settings.xml
+++ b/introspection/nm-settings.xml
@@ -82,6 +82,40 @@
</arg>
</method>
+ <method name="LoadConnections">
+ <tp:docstring>
+ Loads or reloads the indicated connections from disk. You
+ should call this after making changes directly to an on-disk
+ connection file to make sure that NetworkManager sees the
+ changes. (If "monitor-connection-files" in NetworkManager.conf
+ is "true", then this will have no real effect, but is
+ harmless.) As with AddConnection(), this operation does not
+ necessarily start the network connection.
+ </tp:docstring>
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_load_connections"/>
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg name="filenames" type="as" direction="in">
+ <tp:docstring>
+ Array of paths to on-disk connection profiles in directories
+ monitored by NetworkManager.
+ </tp:docstring>
+ </arg>
+ <arg name="status" type="b" direction="out">
+ <tp:docstring>
+ Success or failure of the operation as a whole. True if
+ NetworkManager at least tried to load the indicated
+ connections, even if it did not succeed. False if an error
+ occurred before trying to load the connections (eg,
+ permission denied).
+ </tp:docstring>
+ </arg>
+ <arg name="failures" type="as" direction="out">
+ <tp:docstring>
+ Paths of connection files that could not be loaded.
+ </tp:docstring>
+ </arg>
+ </method>
+
<method name="ReloadConnections">
<tp:docstring>
Tells NetworkManager to reload all connection files from disk,
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
index 8c29a9111b..be413f8759 100644
--- a/src/settings/nm-settings.c
+++ b/src/settings/nm-settings.c
@@ -104,6 +104,10 @@ static void impl_settings_add_connection_unsaved (NMSettings *self,
GHashTable *settings,
DBusGMethodInvocation *context);
+static void impl_settings_load_connections (NMSettings *self,
+ char **filenames,
+ DBusGMethodInvocation *context);
+
static void impl_settings_reload_connections (NMSettings *self,
DBusGMethodInvocation *context);
@@ -1223,22 +1227,20 @@ impl_settings_add_connection_unsaved (NMSettings *self,
impl_settings_add_connection_helper (self, settings, FALSE, context);
}
-static void
-impl_settings_reload_connections (NMSettings *self,
- DBusGMethodInvocation *context)
+static gboolean
+ensure_root (NMDBusManager *dbus_mgr,
+ DBusGMethodInvocation *context)
{
- NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
- GSList *iter;
gulong caller_uid;
GError *error = NULL;
- if (!nm_dbus_manager_get_caller_info (priv->dbus_mgr, context, NULL, &caller_uid, NULL)) {
+ if (!nm_dbus_manager_get_caller_info (dbus_mgr, context, NULL, &caller_uid, NULL)) {
error = g_error_new_literal (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_PERMISSION_DENIED,
"Unable to determine request UID.");
dbus_g_method_return_error (context, error);
g_error_free (error);
- return;
+ return FALSE;
}
if (caller_uid != 0) {
error = g_error_new_literal (NM_SETTINGS_ERROR,
@@ -1246,9 +1248,57 @@ impl_settings_reload_connections (NMSettings *self,
"Permission denied");
dbus_g_method_return_error (context, error);
g_error_free (error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+impl_settings_load_connections (NMSettings *self,
+ char **filenames,
+ DBusGMethodInvocation *context)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ GPtrArray *failures;
+ GSList *iter;
+ int i;
+
+ if (!ensure_root (priv->dbus_mgr, context))
return;
+
+ failures = g_ptr_array_new ();
+
+ for (i = 0; filenames[i]; i++) {
+ for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
+ NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
+
+ if (nm_system_config_interface_load_connection (plugin, filenames[i]))
+ break;
+ }
+
+ if (!iter) {
+ if (!g_path_is_absolute (filenames[i]))
+ nm_log_warn (LOGD_SETTINGS, "Connection filename '%s' is not an absolute path", filenames[i]);
+ g_ptr_array_add (failures, (char *) filenames[i]);
+ }
}
+ g_ptr_array_add (failures, NULL);
+ dbus_g_method_return (context, failures->len == 1, failures->pdata);
+ g_ptr_array_unref (failures);
+}
+
+static void
+impl_settings_reload_connections (NMSettings *self,
+ DBusGMethodInvocation *context)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ GSList *iter;
+
+ if (!ensure_root (priv->dbus_mgr, context))
+ return;
+
if (!priv->connections_loaded) {
load_connections (self);
} else {
diff --git a/src/settings/nm-system-config-interface.c b/src/settings/nm-system-config-interface.c
index 20e52c7d05..b77ffa7929 100644
--- a/src/settings/nm-system-config-interface.c
+++ b/src/settings/nm-system-config-interface.c
@@ -145,6 +145,17 @@ nm_system_config_interface_get_connections (NMSystemConfigInterface *config)
return NULL;
}
+gboolean
+nm_system_config_interface_load_connection (NMSystemConfigInterface *config,
+ const char *filename)
+{
+ g_return_val_if_fail (config != NULL, NULL);
+
+ if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->load_connection)
+ return NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->load_connection (config, filename);
+ return FALSE;
+}
+
void
nm_system_config_interface_reload_connections (NMSystemConfigInterface *config)
{
diff --git a/src/settings/nm-system-config-interface.h b/src/settings/nm-system-config-interface.h
index 55643ef9f1..76ee168faa 100644
--- a/src/settings/nm-system-config-interface.h
+++ b/src/settings/nm-system-config-interface.h
@@ -90,6 +90,12 @@ struct _NMSystemConfigInterface {
*/
GSList * (*get_connections) (NMSystemConfigInterface *config);
+ /* Requests that the plugin load/reload a single connection, if it
+ * recognizes the filename. Returns success or failure.
+ */
+ gboolean (*load_connection) (NMSystemConfigInterface *config,
+ const char *filename);
+
/* Requests that the plugin reload all connection files from disk,
* and emit signals reflecting new, changed, and removed connections.
*/
@@ -150,6 +156,8 @@ void nm_system_config_interface_init (NMSystemConfigInterface *config,
GSList *nm_system_config_interface_get_connections (NMSystemConfigInterface *config);
+gboolean nm_system_config_interface_load_connection (NMSystemConfigInterface *config,
+ const char *filename);
void nm_system_config_interface_reload_connections (NMSystemConfigInterface *config);
GSList *nm_system_config_interface_get_unmanaged_specs (NMSystemConfigInterface *config);
diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c
index ea0ddf34e2..6024202f92 100644
--- a/src/settings/plugins/ifcfg-rh/plugin.c
+++ b/src/settings/plugins/ifcfg-rh/plugin.c
@@ -512,6 +512,30 @@ get_connections (NMSystemConfigInterface *config)
return list;
}
+static gboolean
+load_connection (NMSystemConfigInterface *config,
+ const char *filename)
+{
+ SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (config);
+ NMIfcfgConnection *connection;
+ int dir_len = strlen (IFCFG_DIR);
+
+ 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))
+ return FALSE;
+
+ connection = find_by_path (plugin, filename);
+ connection_new_or_changed (plugin, filename, connection, NULL);
+ if (!connection)
+ connection = find_by_path (plugin, filename);
+
+ return (connection != NULL);
+}
+
static void
reload_connections (NMSystemConfigInterface *config)
{
@@ -968,6 +992,7 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c
/* interface implementation */
system_config_interface_class->get_connections = get_connections;
system_config_interface_class->add_connection = add_connection;
+ system_config_interface_class->load_connection = load_connection;
system_config_interface_class->reload_connections = reload_connections;
system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs;
system_config_interface_class->get_unrecognized_specs = get_unrecognized_specs;
diff --git a/src/settings/plugins/keyfile/plugin.c b/src/settings/plugins/keyfile/plugin.c
index 950f566b03..3439f55d5e 100644
--- a/src/settings/plugins/keyfile/plugin.c
+++ b/src/settings/plugins/keyfile/plugin.c
@@ -406,6 +406,33 @@ get_connections (NMSystemConfigInterface *config)
return list;
}
+static gboolean
+load_connection (NMSystemConfigInterface *config,
+ const char *filename)
+{
+ SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config);
+ NMKeyfileConnection *connection;
+ int dir_len = strlen (KEYFILE_DIR);
+
+ if ( strncmp (filename, KEYFILE_DIR, dir_len) != 0
+ || filename[dir_len] != '/'
+ || strchr (filename + dir_len + 1, '/') != NULL)
+ return FALSE;
+
+ if (nm_keyfile_plugin_utils_should_ignore_file (filename + dir_len + 1))
+ return FALSE;
+
+ connection = find_by_path (self, filename);
+ if (connection)
+ update_connection (self, connection, filename);
+ else {
+ new_connection (self, filename, NULL);
+ connection = find_by_path (self, filename);
+ }
+
+ return (connection != NULL);
+}
+
static void
reload_connections (NMSystemConfigInterface *config)
{
@@ -705,6 +732,7 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c
{
/* interface implementation */
system_config_interface_class->get_connections = get_connections;
+ system_config_interface_class->load_connection = load_connection;
system_config_interface_class->reload_connections = reload_connections;
system_config_interface_class->add_connection = add_connection;
system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs;