aboutsummaryrefslogtreecommitdiff
path: root/src/mm-plugin-manager.c
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2020-10-24 15:40:57 +0200
committerAleksander Morgado <aleksander@aleksander.es>2020-11-13 08:57:06 +0000
commit71f5c975430b0455e7ca81b2d2d1bef0174d0be2 (patch)
tree1992d85df2913b7f624ab58b9fc8aa3d04cf0f4f /src/mm-plugin-manager.c
parent950abbf8ee8624827d63a0d0186beac81232e8f6 (diff)
base-manager: automatic required subsystem detection
Instead of assuming we require a fixed set of subsystems to monitor, compile the full list based on what the plugins have requested themselves.
Diffstat (limited to 'src/mm-plugin-manager.c')
-rw-r--r--src/mm-plugin-manager.c98
1 files changed, 69 insertions, 29 deletions
diff --git a/src/mm-plugin-manager.c b/src/mm-plugin-manager.c
index e76c9a82..ed7a96ff 100644
--- a/src/mm-plugin-manager.c
+++ b/src/mm-plugin-manager.c
@@ -62,6 +62,9 @@ struct _MMPluginManagerPrivate {
/* List of ongoing device support checks */
GList *device_contexts;
+
+ /* Full list of subsystems requested by the registered plugins */
+ gchar **subsystems;
};
/*****************************************************************************/
@@ -1601,6 +1604,14 @@ mm_plugin_manager_peek_plugin (MMPluginManager *self,
/*****************************************************************************/
+const gchar **
+mm_plugin_manager_get_subsystems (MMPluginManager *self)
+{
+ return (const gchar **) self->priv->subsystems;
+}
+
+/*****************************************************************************/
+
static void
register_plugin_whitelist_tags (MMPluginManager *self,
MMPlugin *plugin)
@@ -1765,15 +1776,17 @@ out:
}
static gboolean
-load_plugins (MMPluginManager *self,
- GError **error)
+load_plugins (MMPluginManager *self,
+ GError **error)
{
- GDir *dir = NULL;
- const gchar *fname;
- gchar *plugindir_display = NULL;
- GList *shared_paths = NULL;
- GList *plugin_paths = NULL;
- GList *l;
+ GDir *dir = NULL;
+ const gchar *fname;
+ GList *shared_paths = NULL;
+ GList *plugin_paths = NULL;
+ GList *l;
+ GPtrArray *subsystems = NULL;
+ g_autofree gchar *subsystems_str = NULL;
+ g_autofree gchar *plugindir_display = NULL;
if (!g_module_supported ()) {
g_set_error (error,
@@ -1811,21 +1824,41 @@ load_plugins (MMPluginManager *self,
load_shared (self, (const gchar *)(l->data));
/* Load all plugins */
+ subsystems = g_ptr_array_new ();
for (l = plugin_paths; l; l = g_list_next (l)) {
- MMPlugin *plugin;
+ MMPlugin *plugin;
+ const gchar **plugin_subsystems;
+ guint i;
plugin = load_plugin (self, (const gchar *)(l->data));
if (!plugin)
continue;
+ /* Ignore plugins that don't specify subsystems */
+ plugin_subsystems = mm_plugin_get_allowed_subsystems (plugin);
+ if (!plugin_subsystems) {
+ mm_obj_warn (self, "plugin '%s' doesn't specify allowed subsystems: ignored",
+ mm_plugin_get_name (plugin));
+ continue;
+ }
+
+ /* Process generic plugin */
if (mm_plugin_is_generic (plugin)) {
- if (self->priv->generic)
- mm_obj_warn (self, "cannot register more than one generic plugin");
- else
- self->priv->generic = plugin;
+ if (self->priv->generic) {
+ mm_obj_warn (self, "plugin '%s' is generic and another one is already registered: ignored",
+ mm_plugin_get_name (plugin));
+ continue;
+ }
+ self->priv->generic = plugin;
} else
self->priv->plugins = g_list_append (self->priv->plugins, plugin);
+ /* Track required subsystems, avoiding duplicates in the list */
+ for (i = 0; plugin_subsystems[i]; i++) {
+ if (!g_ptr_array_find_with_equal_func (subsystems, plugin_subsystems[i], g_str_equal, NULL))
+ g_ptr_array_add (subsystems, g_strdup (plugin_subsystems[i]));
+ }
+
/* Register plugin whitelist rules in filter, if any */
register_plugin_whitelist_tags (self, plugin);
register_plugin_whitelist_vendor_ids (self, plugin);
@@ -1846,15 +1879,28 @@ load_plugins (MMPluginManager *self,
goto out;
}
- mm_obj_dbg (self, "successfully loaded %u plugins",
- g_list_length (self->priv->plugins) + !!self->priv->generic);
+ /* Validate required subsystems */
+ if (!subsystems->len) {
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_NO_PLUGINS,
+ "empty list of subsystems required by plugins");
+ goto out;
+ }
+ /* Add trailing NULL and store as GStrv */
+ g_ptr_array_add (subsystems, NULL);
+ self->priv->subsystems = (gchar **) g_ptr_array_free (subsystems, FALSE);
+ subsystems_str = g_strjoinv (", ", self->priv->subsystems);
+
+ mm_obj_dbg (self, "successfully loaded %u plugins registering %u subsystems: %s",
+ g_list_length (self->priv->plugins) + !!self->priv->generic,
+ g_strv_length (self->priv->subsystems), subsystems_str);
out:
g_list_free_full (shared_paths, g_free);
g_list_free_full (plugin_paths, g_free);
if (dir)
g_dir_close (dir);
- g_free (plugindir_display);
/* Return TRUE if at least one plugin found */
return (self->priv->plugins || self->priv->generic);
@@ -1884,12 +1930,12 @@ mm_plugin_manager_new (const gchar *plugin_dir,
}
static void
-mm_plugin_manager_init (MMPluginManager *manager)
+mm_plugin_manager_init (MMPluginManager *self)
{
/* Initialize opaque pointer to private data */
- manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
- MM_TYPE_PLUGIN_MANAGER,
- MMPluginManagerPrivate);
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ MM_TYPE_PLUGIN_MANAGER,
+ MMPluginManagerPrivate);
}
static void
@@ -1949,17 +1995,11 @@ dispose (GObject *object)
{
MMPluginManager *self = MM_PLUGIN_MANAGER (object);
- /* Cleanup list of plugins */
- if (self->priv->plugins) {
- g_list_free_full (self->priv->plugins, g_object_unref);
- self->priv->plugins = NULL;
- }
+ g_list_free_full (g_steal_pointer (&self->priv->plugins), g_object_unref);
g_clear_object (&self->priv->generic);
-
- g_free (self->priv->plugin_dir);
- self->priv->plugin_dir = NULL;
-
+ g_clear_pointer (&self->priv->plugin_dir, g_free);
g_clear_object (&self->priv->filter);
+ g_clear_pointer (&self->priv->subsystems, g_strfreev);
G_OBJECT_CLASS (mm_plugin_manager_parent_class)->dispose (object);
}