[RFC PATCH 5/8] settings: Allow loading plugins after startup



Add nm_settings_add_plugin as a public function so that plugins can be
added after startup is complete.  Specifically this allows a device
plugin to add its own settings plugin.  Making the two plugins
independent binaries is difficult because plugins are loaded with
G_MODULE_BIND_LOCAL and can't see symbols from other plugins, apart from
having to deal with which plugin gets loaded first.
---
 src/settings/nm-settings.c | 66 ++++++++++++++++++++++++++++++----------------
 src/settings/nm-settings.h |  4 +++
 2 files changed, 48 insertions(+), 22 deletions(-)

diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
index 5bb629dca..792dcb736 100644
--- a/src/settings/nm-settings.c
+++ b/src/settings/nm-settings.c
@@ -220,34 +220,41 @@ plugin_connection_added (NMSettingsPlugin *config,
 }
 
 static void
-load_connections (NMSettings *self)
+load_connections (NMSettings *self, NMSettingsPlugin *plugin, gboolean notify)
 {
-       NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
-       GSList *iter;
+       GSList *plugin_connections;
+       GSList *elt;
 
-       for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
-               NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data);
-               GSList *plugin_connections;
-               GSList *elt;
+       plugin_connections = nm_settings_plugin_get_connections (plugin);
 
-               plugin_connections = nm_settings_plugin_get_connections (plugin);
+       // FIXME: ensure connections from plugins loaded with a lower priority
+       // get rejected when they conflict with connections from a higher
+       // priority plugin.
 
-               // FIXME: ensure connections from plugins loaded with a lower priority
-               // get rejected when they conflict with connections from a higher
-               // priority plugin.
+       for (elt = plugin_connections; elt; elt = g_slist_next (elt))
+               claim_connection (self, NM_SETTINGS_CONNECTION (elt->data));
 
-               for (elt = plugin_connections; elt; elt = g_slist_next (elt))
-                       claim_connection (self, NM_SETTINGS_CONNECTION (elt->data));
+       g_slist_free (plugin_connections);
 
-               g_slist_free (plugin_connections);
+       g_signal_connect (plugin, NM_SETTINGS_PLUGIN_CONNECTION_ADDED,
+                         G_CALLBACK (plugin_connection_added), self);
+       g_signal_connect (plugin, NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED,
+                         G_CALLBACK (unmanaged_specs_changed), self);
+       g_signal_connect (plugin, NM_SETTINGS_PLUGIN_UNRECOGNIZED_SPECS_CHANGED,
+                         G_CALLBACK (unrecognized_specs_changed), self);
 
-               g_signal_connect (plugin, NM_SETTINGS_PLUGIN_CONNECTION_ADDED,
-                                 G_CALLBACK (plugin_connection_added), self);
-               g_signal_connect (plugin, NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED,
-                                 G_CALLBACK (unmanaged_specs_changed), self);
-               g_signal_connect (plugin, NM_SETTINGS_PLUGIN_UNRECOGNIZED_SPECS_CHANGED,
-                                 G_CALLBACK (unrecognized_specs_changed), self);
-       }
+       if (notify)
+               _notify (self, PROP_CONNECTIONS);
+}
+
+static void
+load_connections_all (NMSettings *self)
+{
+       NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+       GSList *iter;
+
+       for (iter = priv->plugins; iter; iter = g_slist_next (iter))
+               load_connections (self, NM_SETTINGS_PLUGIN (iter->data), FALSE);
 
        priv->connections_loaded = TRUE;
        _notify (self, PROP_CONNECTIONS);
@@ -812,6 +819,21 @@ load_plugins (NMSettings *self, const char **plugins, GError **error)
        return success;
 }
 
+gboolean
+nm_settings_add_plugin (NMSettings *self, NMSettingsPlugin *plugin)
+{
+       NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+
+       if (!add_plugin (self, plugin))
+               return FALSE;
+
+       /* If load_connections_all already happened, load just the new connections */
+       if (priv->connections_loaded)
+               load_connections (self, plugin, TRUE);
+
+       return TRUE;
+}
+
 static void
 connection_updated (NMSettingsConnection *connection, gboolean by_user, gpointer user_data)
 {
@@ -1822,7 +1844,7 @@ nm_settings_start (NMSettings *self, GError **error)
        if (!load_plugins (self, (const char **) plugins, error))
                return FALSE;
 
-       load_connections (self);
+       load_connections_all (self);
        check_startup_complete (self);
 
        priv->hostname_manager = g_object_ref (nm_hostname_manager_get ());
diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h
index 021512fda..7c5c14f40 100644
--- a/src/settings/nm-settings.h
+++ b/src/settings/nm-settings.h
@@ -28,6 +28,8 @@
 
 #include "nm-connection.h"
 
+#include "nm-settings-plugin.h"
+
 #define NM_TYPE_SETTINGS            (nm_settings_get_type ())
 #define NM_SETTINGS(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS, NMSettings))
 #define NM_SETTINGS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  NM_TYPE_SETTINGS, NMSettingsClass))
@@ -114,4 +116,6 @@ void nm_settings_device_removed (NMSettings *self, NMDevice *device, gboolean qu
 
 gboolean nm_settings_get_startup_complete (NMSettings *self);
 
+gboolean nm_settings_add_plugin (NMSettings *self, NMSettingsPlugin *plugin);
+
 #endif  /* __NM_SETTINGS_H__ */
-- 
2.14.1



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]