diff options
author | Aleksander Morgado <aleksandermj@chromium.org> | 2022-12-08 14:37:56 +0000 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2023-01-03 13:56:25 +0000 |
commit | 1c4da332ee6e0d948f85a63f74cb27e89075c011 (patch) | |
tree | 03a01bf796b4d435cd233c89ed3d05c562ed3fd1 | |
parent | 1dd70be4c834ba025ff16b343aa4032a8c64fb71 (diff) |
build: new option to build plugins within the daemon binary
Instead of creating libmm-plugin* and libmm-shared* libraries that are
dlopen()-ed on runtime, allow incorporating all plugins into the
daemon binary itself.
This makes the startup of the daemon much faster and also avoids
issues with builds that require linker namespace isolation.
Fixes https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/674
-rw-r--r-- | data/tests/meson.build | 7 | ||||
-rw-r--r-- | data/tests/org.freedesktop.ModemManager1.service.in | 2 | ||||
-rw-r--r-- | meson.build | 5 | ||||
-rw-r--r-- | meson_options.txt | 2 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/meson.build | 26 | ||||
-rw-r--r-- | src/mm-base-manager.c | 22 | ||||
-rw-r--r-- | src/mm-base-manager.h | 2 | ||||
-rw-r--r-- | src/mm-context.c | 6 | ||||
-rw-r--r-- | src/mm-context.h | 2 | ||||
-rw-r--r-- | src/mm-plugin-manager.c | 271 | ||||
-rw-r--r-- | src/mm-plugin-manager.h | 10 | ||||
-rw-r--r-- | src/plugins/meson.build | 52 | ||||
-rw-r--r-- | src/plugins/mm-builtin-plugins.c | 273 | ||||
-rw-r--r-- | src/plugins/mm-builtin-plugins.h | 28 | ||||
-rw-r--r-- | src/plugins/mm-plugin-common.h | 25 | ||||
-rw-r--r-- | src/plugins/mm-shared-common.h | 6 |
17 files changed, 594 insertions, 147 deletions
diff --git a/data/tests/meson.build b/data/tests/meson.build index 1cc0826b..3b3ee790 100644 --- a/data/tests/meson.build +++ b/data/tests/meson.build @@ -1,9 +1,14 @@ # SPDX-License-Identifier: GPL-2.0-or-later # Copyright (C) 2022 Aleksander Morgado <aleksander@aleksander.es> +test_plugin_dir = '' +if not enable_builtin_plugins + test_plugin_dir = '--test-plugin-dir="' + build_root + '/src/plugins"' +endif + test_conf = { 'abs_top_builddir': build_root, - 'PLUGIN_BUILD_SUBDIR': 'src/plugins/', + 'test_plugin_dir': test_plugin_dir, } configure_file( diff --git a/data/tests/org.freedesktop.ModemManager1.service.in b/data/tests/org.freedesktop.ModemManager1.service.in index d8a751b4..15fe3c7b 100644 --- a/data/tests/org.freedesktop.ModemManager1.service.in +++ b/data/tests/org.freedesktop.ModemManager1.service.in @@ -2,4 +2,4 @@ [D-BUS Service] Name=org.freedesktop.ModemManager1 -Exec=@abs_top_builddir@/src/ModemManager --test-session --no-auto-scan --test-enable --test-plugin-dir="@abs_top_builddir@/@PLUGIN_BUILD_SUBDIR@" --debug +Exec=@abs_top_builddir@/src/ModemManager --test-session --no-auto-scan --test-enable @test_plugin_dir@ --debug diff --git a/meson.build b/meson.build index cc2191fe..e3550a4d 100644 --- a/meson.build +++ b/meson.build @@ -242,6 +242,10 @@ config_h.set('WITH_POLKIT', enable_polkit) enable_at_command_via_dbus = get_option('at_command_via_dbus') config_h.set('WITH_AT_COMMAND_VIA_DBUS', enable_at_command_via_dbus) +# Builtin plugin support (disabled by default) +enable_builtin_plugins = get_option('builtin_plugins') +config_h.set('WITH_BUILTIN_PLUGINS', enable_builtin_plugins) + # MBIM support (enabled by default) enable_mbim = get_option('mbim') if enable_mbim @@ -444,6 +448,7 @@ summary({ 'powerd suspend/resume': enable_powerd_suspend_resume, 'systemd journal': enable_systemd_journal, 'at command via dbus': enable_at_command_via_dbus, + 'builtin plugins': enable_builtin_plugins, }, section: 'Features') summary(plugins_shared, section: 'Shared utils') diff --git a/meson_options.txt b/meson_options.txt index da105e1d..c560a234 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -17,6 +17,8 @@ option('polkit', type: 'combo', choices: ['strict', 'permissive', 'no'], value: option('at_command_via_dbus', type: 'boolean', value: false, description: 'enable at commands vida d-bus') +option('builtin_plugins', type: 'boolean', value: false, description: 'integrate all built plugins within the daemon binary') + option('mbim', type: 'boolean', value: true, description: 'enable MBIM support') option('qmi', type: 'boolean', value: true, description: 'enable QMI support') option('qrtr', type: 'boolean', value: true, description: 'enable QRTR support') @@ -93,7 +93,9 @@ bus_acquired_cb (GDBusConnection *connection, /* Create Manager object */ g_assert (!manager); manager = mm_base_manager_new (connection, +#if !defined WITH_BUILTIN_PLUGINS mm_context_get_test_plugin_dir (), +#endif !mm_context_get_no_auto_scan (), mm_context_get_filter_policy (), mm_context_get_initial_kernel_events (), diff --git a/src/meson.build b/src/meson.build index 3a7228b8..3b6f7a71 100644 --- a/src/meson.build +++ b/src/meson.build @@ -4,6 +4,7 @@ # helpers library src_inc = include_directories('.') kerneldevice_inc = include_directories('kerneldevice') +plugins_inc = include_directories('plugins') headers = files( 'mm-modem-helpers.h', @@ -177,6 +178,9 @@ libport_dep = declare_dependency( link_with: libport, ) +# Additional vendor plugins +subdir('plugins') + # ModemManager daemon headers = files( 'mm-base-bearer.h', @@ -229,15 +233,14 @@ sources = files( enums_types = 'mm-daemon-enums-types' -daemon_enums_sources = [] -daemon_enums_sources += gnome.mkenums( +sources += gnome.mkenums( enums_types + '.c', sources: headers, c_template: build_aux_dir / enums_types + '.c.template', fhead: '#include "mm-daemon-enums-types.h"', ) -daemon_enums_sources += gnome.mkenums( +sources += gnome.mkenums( enums_types + '.h', sources: headers, h_template: build_aux_dir / enums_types + '.h.template', @@ -309,20 +312,13 @@ if enable_mbim ) endif -# Daemon related variables before processing plugins -daemon_sources = sources + daemon_enums_sources -daemon_deps = deps -daemon_c_args = c_args - -# Additional vendor plugins -subdir('plugins') - executable( 'ModemManager', - sources: daemon_sources, - include_directories: top_inc, - dependencies: daemon_deps, - c_args: daemon_c_args, + sources: [sources, builtin_sources], + include_directories: [ top_inc, plugins_inc ], + dependencies: deps, + c_args: c_args, + link_whole: builtin_plugins, install: true, install_dir: mm_sbindir, ) diff --git a/src/mm-base-manager.c b/src/mm-base-manager.c index 6cdc4ae3..63ca6899 100644 --- a/src/mm-base-manager.c +++ b/src/mm-base-manager.c @@ -68,7 +68,9 @@ enum { PROP_CONNECTION, PROP_AUTO_SCAN, PROP_FILTER_POLICY, +#if !defined WITH_BUILTIN_PLUGINS PROP_PLUGIN_DIR, +#endif PROP_INITIAL_KERNEL_EVENTS, #if defined WITH_TESTS PROP_ENABLE_TEST, @@ -83,8 +85,10 @@ struct _MMBaseManagerPrivate { gboolean auto_scan; /* Filter policy (mask of enabled rules) */ MMFilterRule filter_policy; +#if !defined WITH_BUILTIN_PLUGINS /* Path to look for plugins */ gchar *plugin_dir; +#endif /* Path to the list of initial kernel events */ gchar *initial_kernel_events; /* The authorization provider */ @@ -1380,7 +1384,9 @@ log_object_build_id (MMLogObject *_self) MMBaseManager * mm_base_manager_new (GDBusConnection *connection, +#if !defined WITH_BUILTIN_PLUGINS const gchar *plugin_dir, +#endif gboolean auto_scan, MMFilterRule filter_policy, const gchar *initial_kernel_events, @@ -1395,7 +1401,9 @@ mm_base_manager_new (GDBusConnection *connection, NULL, /* cancellable */ error, MM_BASE_MANAGER_CONNECTION, connection, +#if !defined WITH_BUILTIN_PLUGINS MM_BASE_MANAGER_PLUGIN_DIR, plugin_dir, +#endif MM_BASE_MANAGER_AUTO_SCAN, auto_scan, MM_BASE_MANAGER_FILTER_POLICY, filter_policy, MM_BASE_MANAGER_INITIAL_KERNEL_EVENTS, initial_kernel_events, @@ -1445,10 +1453,12 @@ set_property (GObject *object, case PROP_FILTER_POLICY: self->priv->filter_policy = g_value_get_flags (value); break; +#if !defined WITH_BUILTIN_PLUGINS case PROP_PLUGIN_DIR: g_free (self->priv->plugin_dir); self->priv->plugin_dir = g_value_dup_string (value); break; +#endif case PROP_INITIAL_KERNEL_EVENTS: g_free (self->priv->initial_kernel_events); self->priv->initial_kernel_events = g_value_dup_string (value); @@ -1482,9 +1492,11 @@ get_property (GObject *object, case PROP_FILTER_POLICY: g_value_set_flags (value, self->priv->filter_policy); break; +#if !defined WITH_BUILTIN_PLUGINS case PROP_PLUGIN_DIR: g_value_set_string (value, self->priv->plugin_dir); break; +#endif case PROP_INITIAL_KERNEL_EVENTS: g_value_set_string (value, self->priv->initial_kernel_events); break; @@ -1548,7 +1560,11 @@ initable_init (GInitable *initable, return FALSE; /* Create plugin manager */ - self->priv->plugin_manager = mm_plugin_manager_new (self->priv->plugin_dir, self->priv->filter, error); + self->priv->plugin_manager = mm_plugin_manager_new (self->priv->filter, +#if !defined WITH_BUILTIN_PLUGINS + self->priv->plugin_dir, +#endif + error); if (!self->priv->plugin_manager) return FALSE; @@ -1613,7 +1629,9 @@ finalize (GObject *object) MMBaseManager *self = MM_BASE_MANAGER (object); g_free (self->priv->initial_kernel_events); +#if !defined WITH_BUILTIN_PLUGINS g_free (self->priv->plugin_dir); +#endif g_hash_table_destroy (self->priv->inhibited_devices); g_hash_table_destroy (self->priv->devices); @@ -1704,6 +1722,7 @@ mm_base_manager_class_init (MMBaseManagerClass *manager_class) MM_FILTER_RULE_NONE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +#if !defined WITH_BUILTIN_PLUGINS g_object_class_install_property (object_class, PROP_PLUGIN_DIR, g_param_spec_string (MM_BASE_MANAGER_PLUGIN_DIR, @@ -1711,6 +1730,7 @@ mm_base_manager_class_init (MMBaseManagerClass *manager_class) "Where to look for plugins", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +#endif g_object_class_install_property (object_class, PROP_INITIAL_KERNEL_EVENTS, diff --git a/src/mm-base-manager.h b/src/mm-base-manager.h index 881555c6..47f9d333 100644 --- a/src/mm-base-manager.h +++ b/src/mm-base-manager.h @@ -57,7 +57,9 @@ GType mm_base_manager_get_type (void); G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMBaseManager, g_object_unref) MMBaseManager *mm_base_manager_new (GDBusConnection *bus, +#if !defined WITH_BUILTIN_PLUGINS const gchar *plugin_dir, +#endif gboolean auto_scan, MMFilterRule filter_policy, const gchar *initial_kernel_events, diff --git a/src/mm-context.c b/src/mm-context.c index 883fc2a1..9deeb312 100644 --- a/src/mm-context.c +++ b/src/mm-context.c @@ -229,7 +229,9 @@ static gboolean test_session; #if defined WITH_TESTS static gboolean test_enable; #endif +#if !defined WITH_BUILTIN_PLUGINS static gchar *test_plugin_dir; +#endif #if defined WITH_UDEV static gboolean test_no_udev; #endif @@ -258,11 +260,13 @@ static const GOptionEntry test_entries[] = { NULL }, #endif +#if !defined WITH_BUILTIN_PLUGINS { "test-plugin-dir", 0, 0, G_OPTION_ARG_FILENAME, &test_plugin_dir, "Path to look for plugins", "[PATH]" }, +#endif #if defined WITH_UDEV { "test-no-udev", 0, 0, G_OPTION_ARG_NONE, &test_no_udev, @@ -332,11 +336,13 @@ mm_context_get_test_enable (void) } #endif +#if !defined WITH_BUILTIN_PLUGINS const gchar * mm_context_get_test_plugin_dir (void) { return test_plugin_dir ? test_plugin_dir : PLUGINDIR; } +#endif #if defined WITH_UDEV gboolean diff --git a/src/mm-context.h b/src/mm-context.h index fcca1f65..7ca2b7f4 100644 --- a/src/mm-context.h +++ b/src/mm-context.h @@ -48,7 +48,9 @@ gboolean mm_context_get_test_session (void); #if defined WITH_TESTS gboolean mm_context_get_test_enable (void); #endif +#if !defined WITH_BUILTIN_PLUGINS const gchar *mm_context_get_test_plugin_dir (void); +#endif #if defined WITH_UDEV gboolean mm_context_get_test_no_udev (void); #endif diff --git a/src/mm-plugin-manager.c b/src/mm-plugin-manager.c index 2c22ab23..72127296 100644 --- a/src/mm-plugin-manager.c +++ b/src/mm-plugin-manager.c @@ -33,8 +33,12 @@ #include "mm-utils.h" #include "mm-log-object.h" -#define SHARED_PREFIX "libmm-shared" -#define PLUGIN_PREFIX "libmm-plugin" +#if defined WITH_BUILTIN_PLUGINS +# include "mm-builtin-plugins.h" +#else +# define SHARED_PREFIX "libmm-shared" +# define PLUGIN_PREFIX "libmm-plugin" +#endif static void initable_iface_init (GInitableIface *iface); static void log_object_iface_init (MMLogObjectInterface *iface); @@ -45,14 +49,19 @@ G_DEFINE_TYPE_EXTENDED (MMPluginManager, mm_plugin_manager, G_TYPE_OBJECT, 0, enum { PROP_0, +#if !defined WITH_BUILTIN_PLUGINS PROP_PLUGIN_DIR, +#endif PROP_FILTER, LAST_PROP }; struct _MMPluginManagerPrivate { +#if !defined WITH_BUILTIN_PLUGINS /* Path to look for plugins */ gchar *plugin_dir; +#endif + /* Device filter */ MMFilter *filter; @@ -1681,9 +1690,90 @@ register_plugin_allowlist_subsystem_vendor_ids (MMPluginManager *self, mm_filter_register_plugin_allowlist_subsystem_vendor_id (self->priv->filter, subsystem_vendor_ids[i].l, subsystem_vendor_ids[i].r); } +static gboolean +track_plugin (MMPluginManager *self, + MMPlugin *plugin, + GPtrArray **subsystems, + GError **error) +{ + const gchar **plugin_subsystems; + guint i; + + /* Ignore plugins that don't specify subsystems */ + plugin_subsystems = mm_plugin_get_allowed_subsystems (plugin); + if (!plugin_subsystems) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Allowed subsystems not specified"); + return FALSE; + } + + /* Process generic plugin */ + if (mm_plugin_is_generic (plugin)) { + if (self->priv->generic) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Another generic plugin already registered"); + return FALSE; + } + self->priv->generic = g_object_ref (plugin); + } else + self->priv->plugins = g_list_append (self->priv->plugins, g_object_ref (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 allowlist rules in filter, if any */ + register_plugin_allowlist_tags (self, plugin); + register_plugin_allowlist_vendor_ids (self, plugin); + register_plugin_allowlist_product_ids (self, plugin); + register_plugin_allowlist_subsystem_vendor_ids (self, plugin); + + return TRUE; +} + +static gboolean +validate_tracked_plugins (MMPluginManager *self, + GPtrArray *subsystems_take, + GError **error) +{ + g_autofree gchar *subsystems_str = NULL; + + /* Check the generic plugin once all looped */ + if (!self->priv->generic) + mm_obj_dbg (self, "generic plugin not loaded"); + + /* Treat as error if we don't find any plugin */ + if (!self->priv->plugins && !self->priv->generic) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_NO_PLUGINS, "no plugins found"); + return FALSE; + } + + /* Validate required subsystems */ + if (!subsystems_take->len) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_NO_PLUGINS, + "empty list of subsystems required by plugins"); + return FALSE; + } + + /* Add trailing NULL and store as GStrv */ + g_ptr_array_add (subsystems_take, NULL); + self->priv->subsystems = (gchar **) g_ptr_array_free (subsystems_take, 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); + + return TRUE; +} + +#if !defined WITH_BUILTIN_PLUGINS + static MMPlugin * -load_plugin (MMPluginManager *self, - const gchar *path) +load_external_plugin (MMPluginManager *self, + const gchar *path) { MMPlugin *plugin = NULL; GModule *module; @@ -1729,10 +1819,9 @@ load_plugin (MMPluginManager *self, } plugin = (*plugin_create_func) (); - if (plugin) { + if (plugin) mm_obj_dbg (self, "loaded plugin '%s' from '%s'", mm_plugin_get_name (plugin), path_display); - g_object_weak_ref (G_OBJECT (plugin), (GWeakNotify) g_module_close, module); - } else + else mm_obj_warn (self, "could not load plugin '%s': initialization failed", path_display); out: @@ -1745,8 +1834,8 @@ out: } static void -load_shared (MMPluginManager *self, - const gchar *path) +load_external_shared (MMPluginManager *self, + const gchar *path) { GModule *module; gchar *path_display; @@ -1802,8 +1891,8 @@ out: } static gboolean -load_plugins (MMPluginManager *self, - GError **error) +load_external_plugins (MMPluginManager *self, + GError **error) { GDir *dir = NULL; const gchar *fname; @@ -1811,8 +1900,8 @@ load_plugins (MMPluginManager *self, GList *plugin_paths = NULL; GList *l; GPtrArray *subsystems = NULL; - g_autofree gchar *subsystems_str = NULL; g_autofree gchar *plugindir_display = NULL; + gboolean valid_plugins = FALSE; if (!g_module_supported ()) { g_set_error (error, @@ -1828,11 +1917,8 @@ load_plugins (MMPluginManager *self, mm_obj_dbg (self, "looking for plugins in '%s'", plugindir_display); dir = g_dir_open (self->priv->plugin_dir, 0, NULL); if (!dir) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_NO_PLUGINS, - "plugin directory '%s' not found", - plugindir_display); + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_NO_PLUGINS, + "plugin directory '%s' not found", plugindir_display); goto out; } @@ -1847,81 +1933,23 @@ load_plugins (MMPluginManager *self, /* Load all shared utils */ for (l = shared_paths; l; l = g_list_next (l)) - load_shared (self, (const gchar *)(l->data)); + load_external_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; - const gchar **plugin_subsystems; - guint i; + g_autoptr(MMPlugin) plugin = NULL; + g_autoptr(GError) inner_error = NULL; - plugin = load_plugin (self, (const gchar *)(l->data)); + plugin = load_external_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, "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 allowlist rules in filter, if any */ - register_plugin_allowlist_tags (self, plugin); - register_plugin_allowlist_vendor_ids (self, plugin); - register_plugin_allowlist_product_ids (self, plugin); - register_plugin_allowlist_subsystem_vendor_ids (self, plugin); + if (!track_plugin (self, plugin, &subsystems, &inner_error)) + mm_obj_warn (self, "ignored plugin '%s': %s", mm_plugin_get_name (plugin), inner_error->message); } - /* Check the generic plugin once all looped */ - if (!self->priv->generic) - mm_obj_dbg (self, "generic plugin not loaded"); - - /* Treat as error if we don't find any plugin */ - if (!self->priv->plugins && !self->priv->generic) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_NO_PLUGINS, - "no plugins found in plugin directory '%s'", - plugindir_display); - goto out; - } - - /* 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); + valid_plugins = validate_tracked_plugins (self, subsystems, error); out: g_list_free_full (shared_paths, g_free); @@ -1929,10 +1957,38 @@ out: if (dir) g_dir_close (dir); - /* Return TRUE if at least one plugin found */ - return (self->priv->plugins || self->priv->generic); + return valid_plugins; +} + +#else + +static gboolean +load_builtin_plugins (MMPluginManager *self, + GError **error) +{ + GList *builtin_plugins; + GList *l; + GPtrArray *subsystems = NULL; + + subsystems = g_ptr_array_new (); + + builtin_plugins = mm_builtin_plugins_load (); + for (l = builtin_plugins; l; l = g_list_next (l)) { + gboolean tracked; + MMPlugin *plugin; + + plugin = MM_PLUGIN (l->data); + mm_obj_dbg (self, "loaded builtin plugin '%s'", mm_plugin_get_name (plugin)); + tracked = track_plugin (self, plugin, &subsystems, NULL); + g_assert (tracked); + } + g_list_free_full (builtin_plugins, (GDestroyNotify)g_object_unref); + + return validate_tracked_plugins (self, subsystems, error); } +#endif /* !WITH_BUILTIN_PLUGINS */ + /*****************************************************************************/ static gchar * @@ -1944,15 +2000,19 @@ log_object_build_id (MMLogObject *_self) /*****************************************************************************/ MMPluginManager * -mm_plugin_manager_new (const gchar *plugin_dir, - MMFilter *filter, +mm_plugin_manager_new (MMFilter *filter, +#if !defined WITH_BUILTIN_PLUGINS + const gchar *plugin_dir, +#endif GError **error) { return g_initable_new (MM_TYPE_PLUGIN_MANAGER, NULL, error, + MM_PLUGIN_MANAGER_FILTER, filter, +#if !defined WITH_BUILTIN_PLUGINS MM_PLUGIN_MANAGER_PLUGIN_DIR, plugin_dir, - MM_PLUGIN_MANAGER_FILTER, filter, +#endif NULL); } @@ -1966,18 +2026,20 @@ mm_plugin_manager_init (MMPluginManager *self) } static void -set_property (GObject *object, - guint prop_id, +set_property (GObject *object, + guint prop_id, const GValue *value, - GParamSpec *pspec) + GParamSpec *pspec) { MMPluginManagerPrivate *priv = MM_PLUGIN_MANAGER (object)->priv; switch (prop_id) { +#if !defined WITH_BUILTIN_PLUGINS case PROP_PLUGIN_DIR: g_free (priv->plugin_dir); priv->plugin_dir = g_value_dup_string (value); break; +#endif case PROP_FILTER: priv->filter = g_value_dup_object (value); break; @@ -1988,17 +2050,19 @@ set_property (GObject *object, } static void -get_property (GObject *object, - guint prop_id, - GValue *value, +get_property (GObject *object, + guint prop_id, + GValue *value, GParamSpec *pspec) { MMPluginManagerPrivate *priv = MM_PLUGIN_MANAGER (object)->priv; switch (prop_id) { +#if !defined WITH_BUILTIN_PLUGINS case PROP_PLUGIN_DIR: g_value_set_string (value, priv->plugin_dir); break; +#endif case PROP_FILTER: g_value_set_object (value, priv->filter); break; @@ -2009,12 +2073,16 @@ get_property (GObject *object, } static gboolean -initable_init (GInitable *initable, - GCancellable *cancellable, - GError **error) +initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) { - /* Load the list of plugins */ - return load_plugins (MM_PLUGIN_MANAGER (initable), error); +#if defined WITH_BUILTIN_PLUGINS + return load_builtin_plugins (MM_PLUGIN_MANAGER (initable), error); +#else + /* Load the list of plugins from the filesystem*/ + return load_external_plugins (MM_PLUGIN_MANAGER (initable), error); +#endif } static void @@ -2024,9 +2092,11 @@ dispose (GObject *object) g_list_free_full (g_steal_pointer (&self->priv->plugins), g_object_unref); g_clear_object (&self->priv->generic); - g_clear_pointer (&self->priv->plugin_dir, g_free); g_clear_object (&self->priv->filter); g_clear_pointer (&self->priv->subsystems, g_strfreev); +#if !defined WITH_BUILTIN_PLUGINS + g_clear_pointer (&self->priv->plugin_dir, g_free); +#endif G_OBJECT_CLASS (mm_plugin_manager_parent_class)->dispose (object); } @@ -2056,6 +2126,7 @@ mm_plugin_manager_class_init (MMPluginManagerClass *manager_class) object_class->get_property = get_property; /* Properties */ +#if !defined WITH_BUILTIN_PLUGINS g_object_class_install_property (object_class, PROP_PLUGIN_DIR, g_param_spec_string (MM_PLUGIN_MANAGER_PLUGIN_DIR, @@ -2063,6 +2134,8 @@ mm_plugin_manager_class_init (MMPluginManagerClass *manager_class) "Where to look for plugins", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +#endif + g_object_class_install_property (object_class, PROP_FILTER, g_param_spec_object (MM_PLUGIN_MANAGER_FILTER, diff --git a/src/mm-plugin-manager.h b/src/mm-plugin-manager.h index 79e7c1a1..f1ddcc29 100644 --- a/src/mm-plugin-manager.h +++ b/src/mm-plugin-manager.h @@ -32,7 +32,9 @@ #define MM_IS_PLUGIN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), MM_TYPE_PLUGIN_MANAGER)) #define MM_PLUGIN_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_PLUGIN_MANAGER, MMPluginManagerClass)) -#define MM_PLUGIN_MANAGER_PLUGIN_DIR "plugin-dir" /* Construct-only */ +#if !defined WITH_BUILTIN_PLUGINS +# define MM_PLUGIN_MANAGER_PLUGIN_DIR "plugin-dir" /* Construct-only */ +#endif #define MM_PLUGIN_MANAGER_FILTER "filter" /* Construct-only */ typedef struct _MMPluginManager MMPluginManager; @@ -51,8 +53,10 @@ struct _MMPluginManagerClass { GType mm_plugin_manager_get_type (void); G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMPluginManager, g_object_unref) -MMPluginManager *mm_plugin_manager_new (const gchar *plugindir, - MMFilter *filter, +MMPluginManager *mm_plugin_manager_new (MMFilter *filter, +#if !defined WITH_BUILTIN_PLUGINS + const gchar *plugindir, +#endif GError **error); void mm_plugin_manager_device_support_check (MMPluginManager *self, MMDevice *device, diff --git a/src/plugins/meson.build b/src/plugins/meson.build index bf670864..78adb873 100644 --- a/src/plugins/meson.build +++ b/src/plugins/meson.build @@ -1,8 +1,10 @@ # SPDX-License-Identifier: GPL-2.0-or-later # Copyright (C) 2021 IƱigo Martinez <inigomartinez@gmail.com> -symbol_map = plugins_dir / 'symbol.map' -ldflags = cc.get_supported_link_arguments('-Wl,--version-script,@0@'.format(symbol_map)) +if not enable_builtin_plugins + symbol_map = plugins_dir / 'symbol.map' + ldflags = cc.get_supported_link_arguments('-Wl,--version-script,@0@'.format(symbol_map)) +endif # common service test support plugins_common_test_dep = [] @@ -36,7 +38,6 @@ if enable_tests endif # plugins -plugins_inc = include_directories('.') plugins = {} plugins_data = [] plugins_udev_rules = [] @@ -958,6 +959,13 @@ if plugins_options['zte'] plugins_udev_rules += files('zte/77-mm-zte-port-types.rules') endif +builtin_sources = [] +builtin_plugins = [] + +if enable_builtin_plugins + builtin_sources += files('mm-builtin-plugins.c') +endif + foreach plugin_name, plugin_data: plugins libpluginhelpers = [] if plugin_data.has_key('helper') @@ -969,21 +977,31 @@ foreach plugin_name, plugin_data: plugins endif module_args = plugin_data['module'] - if plugin_data['plugin'] - module_args += { - 'link_args': ldflags, - 'link_depends': symbol_map, - } - endif + if not enable_builtin_plugins + if plugin_data['plugin'] + module_args += { + 'link_args': ldflags, + 'link_depends': symbol_map, + } + endif - shared_module( - 'mm-' + plugin_name, - dependencies: plugins_deps, - link_with: libpluginhelpers, - kwargs: module_args, - install: true, - install_dir: mm_pkglibdir, - ) + shared_module( + 'mm-' + plugin_name, + dependencies: plugins_deps, + link_with: libpluginhelpers, + kwargs: module_args, + install: true, + install_dir: mm_pkglibdir, + ) + else + libplugin = static_library( + 'mm-' + plugin_name, + dependencies: plugins_deps, + link_with: libpluginhelpers, + kwargs: module_args, + ) + builtin_plugins += libplugin + endif if enable_tests if plugin_data.has_key('test') diff --git a/src/plugins/mm-builtin-plugins.c b/src/plugins/mm-builtin-plugins.c new file mode 100644 index 00000000..378a7cba --- /dev/null +++ b/src/plugins/mm-builtin-plugins.c @@ -0,0 +1,273 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2022 Google Inc. + */ + +#include <config.h> +#include <glib.h> + +#include "mm-plugin.h" +#include "mm-builtin-plugins.h" + +#if defined ENABLE_PLUGIN_ALTAIR_LTE +MMPlugin *mm_plugin_create_altair_lte (void); +#endif +#if defined ENABLE_PLUGIN_ANYDATA +MMPlugin *mm_plugin_create_anydata (void); +#endif +#if defined ENABLE_PLUGIN_BROADMOBI +MMPlugin *mm_plugin_create_broadmobi (void); +#endif +#if defined ENABLE_PLUGIN_CINTERION +MMPlugin *mm_plugin_create_cinterion (void); +#endif +#if defined ENABLE_PLUGIN_DELL +MMPlugin *mm_plugin_create_dell (void); +#endif +#if defined ENABLE_PLUGIN_DLINK +MMPlugin *mm_plugin_create_dlink (void); +#endif +#if defined ENABLE_PLUGIN_FIBOCOM +MMPlugin *mm_plugin_create_fibocom (void); +#endif +#if defined ENABLE_PLUGIN_FOXCONN +MMPlugin *mm_plugin_create_foxconn (void); +#endif +#if defined ENABLE_PLUGIN_GENERIC +MMPlugin *mm_plugin_create_generic (void); +#endif +#if defined ENABLE_PLUGIN_GOSUNCN +MMPlugin *mm_plugin_create_gosuncn (void); +#endif +#if defined ENABLE_PLUGIN_HAIER +MMPlugin *mm_plugin_create_haier (void); +#endif +#if defined ENABLE_PLUGIN_HUAWEI +MMPlugin *mm_plugin_create_huawei (void); +#endif +#if defined ENABLE_PLUGIN_INTEL +MMPlugin *mm_plugin_create_intel (void); +#endif +#if defined ENABLE_PLUGIN_IRIDIUM +MMPlugin *mm_plugin_create_iridium (void); +#endif +#if defined ENABLE_PLUGIN_LINKTOP +MMPlugin *mm_plugin_create_linktop (void); +#endif +#if defined ENABLE_PLUGIN_LONGCHEER +MMPlugin *mm_plugin_create_longcheer (void); +#endif +#if defined ENABLE_PLUGIN_MBM +MMPlugin *mm_plugin_create_mbm (void); +#endif +#if defined ENABLE_PLUGIN_MOTOROLA +MMPlugin *mm_plugin_create_motorola (void); +#endif +#if defined ENABLE_PLUGIN_MTK +MMPlugin *mm_plugin_create_mtk (void); +#endif +#if defined ENABLE_PLUGIN_NOKIA +MMPlugin *mm_plugin_create_nokia (void); +#endif +#if defined ENABLE_PLUGIN_NOKIA_ICERA +MMPlugin *mm_plugin_create_nokia_icera (void); +#endif +#if defined ENABLE_PLUGIN_NOVATEL +MMPlugin *mm_plugin_create_novatel (void); +#endif +#if defined ENABLE_PLUGIN_NOVATEL_LTE +MMPlugin *mm_plugin_create_novatel_lte (void); +#endif +#if defined ENABLE_PLUGIN_OPTION +MMPlugin *mm_plugin_create_option (void); +#endif +#if defined ENABLE_PLUGIN_OPTION_HSO +MMPlugin *mm_plugin_create_hso (void); +#endif +#if defined ENABLE_PLUGIN_PANTECH +MMPlugin *mm_plugin_create_pantech (void); +#endif +#if defined ENABLE_PLUGIN_QCOM_SOC +MMPlugin *mm_plugin_create_qcom_soc (void); +#endif +#if defined ENABLE_PLUGIN_QUECTEL +MMPlugin *mm_plugin_create_quectel (void); +#endif +#if defined ENABLE_PLUGIN_SAMSUNG +MMPlugin *mm_plugin_create_samsung (void); +#endif +#if defined ENABLE_PLUGIN_SIERRA +MMPlugin *mm_plugin_create_sierra (void); +#endif +#if defined ENABLE_PLUGIN_SIERRA_LEGACY +MMPlugin *mm_plugin_create_sierra_legacy (void); +#endif +#if defined ENABLE_PLUGIN_SIMTECH +MMPlugin *mm_plugin_create_simtech (void); +#endif +#if defined ENABLE_PLUGIN_TELIT +MMPlugin *mm_plugin_create_telit (void); +#endif +#if defined ENABLE_PLUGIN_THURAYA +MMPlugin *mm_plugin_create_thuraya (void); +#endif +#if defined ENABLE_PLUGIN_TPLINK +MMPlugin *mm_plugin_create_tplink (void); +#endif +#if defined ENABLE_PLUGIN_UBLOX +MMPlugin *mm_plugin_create_ublox (void); +#endif +#if defined ENABLE_PLUGIN_VIA +MMPlugin *mm_plugin_create_via (void); +#endif +#if defined ENABLE_PLUGIN_WAVECOM +MMPlugin *mm_plugin_create_wavecom (void); +#endif +#if defined ENABLE_PLUGIN_X22X +MMPlugin *mm_plugin_create_x22x (void); +#endif +#if defined ENABLE_PLUGIN_ZTE +MMPlugin *mm_plugin_create_zte (void); +#endif + +GList * +mm_builtin_plugins_load (void) +{ + GList *builtin_plugins = NULL; + +#define PREPEND_PLUGIN(my_plugin) \ + builtin_plugins = g_list_prepend (builtin_plugins, mm_plugin_create_##my_plugin ()) + +#if defined ENABLE_PLUGIN_ALTAIR_LTE + PREPEND_PLUGIN (altair_lte); +#endif +#if defined ENABLE_PLUGIN_ANYDATA + PREPEND_PLUGIN (anydata); +#endif +#if defined ENABLE_PLUGIN_BROADMOBI + PREPEND_PLUGIN (broadmobi); +#endif +#if defined ENABLE_PLUGIN_CINTERION + PREPEND_PLUGIN (cinterion); +#endif +#if defined ENABLE_PLUGIN_DELL + PREPEND_PLUGIN (dell); +#endif +#if defined ENABLE_PLUGIN_DLINK + PREPEND_PLUGIN (dlink); +#endif +#if defined ENABLE_PLUGIN_FIBOCOM + PREPEND_PLUGIN (fibocom); +#endif +#if defined ENABLE_PLUGIN_FOXCONN + PREPEND_PLUGIN (foxconn); +#endif +#if defined ENABLE_PLUGIN_GENERIC + PREPEND_PLUGIN (generic); +#endif +#if defined ENABLE_PLUGIN_GOSUNCN + PREPEND_PLUGIN (gosuncn); +#endif +#if defined ENABLE_PLUGIN_HAIER + PREPEND_PLUGIN (haier); +#endif +#if defined ENABLE_PLUGIN_HUAWEI + PREPEND_PLUGIN (huawei); +#endif +#if defined ENABLE_PLUGIN_INTEL + PREPEND_PLUGIN (intel); +#endif +#if defined ENABLE_PLUGIN_IRIDIUM + PREPEND_PLUGIN (iridium); +#endif +#if defined ENABLE_PLUGIN_LINKTOP + PREPEND_PLUGIN (linktop); +#endif +#if defined ENABLE_PLUGIN_LONGCHEER + PREPEND_PLUGIN (longcheer); +#endif +#if defined ENABLE_PLUGIN_MBM + PREPEND_PLUGIN (mbm); +#endif +#if defined ENABLE_PLUGIN_MOTOROLA + PREPEND_PLUGIN (motorola); +#endif +#if defined ENABLE_PLUGIN_MTK + PREPEND_PLUGIN (mtk); +#endif +#if defined ENABLE_PLUGIN_NOKIA + PREPEND_PLUGIN (nokia); +#endif +#if defined ENABLE_PLUGIN_NOKIA_ICERA + PREPEND_PLUGIN (nokia_icera); +#endif +#if defined ENABLE_PLUGIN_NOVATEL + PREPEND_PLUGIN (novatel); +#endif +#if defined ENABLE_PLUGIN_NOVATEL_LTE + PREPEND_PLUGIN (novatel_lte); +#endif +#if defined ENABLE_PLUGIN_OPTION + PREPEND_PLUGIN (option); +#endif +#if defined ENABLE_PLUGIN_OPTION_HSO + PREPEND_PLUGIN (hso); +#endif +#if defined ENABLE_PLUGIN_PANTECH + PREPEND_PLUGIN (pantech); +#endif +#if defined ENABLE_PLUGIN_QCOM_SOC + PREPEND_PLUGIN (qcom_soc); +#endif +#if defined ENABLE_PLUGIN_QUECTEL + PREPEND_PLUGIN (quectel); +#endif +#if defined ENABLE_PLUGIN_SAMSUNG + PREPEND_PLUGIN (samsung); +#endif +#if defined ENABLE_PLUGIN_SIERRA + PREPEND_PLUGIN (sierra); +#endif +#if defined ENABLE_PLUGIN_SIERRA_LEGACY + PREPEND_PLUGIN (sierra_legacy); +#endif +#if defined ENABLE_PLUGIN_SIMTECH + PREPEND_PLUGIN (simtech); +#endif +#if defined ENABLE_PLUGIN_TELIT + PREPEND_PLUGIN (telit); +#endif +#if defined ENABLE_PLUGIN_THURAYA + PREPEND_PLUGIN (thuraya); +#endif +#if defined ENABLE_PLUGIN_TPLINK + PREPEND_PLUGIN (tplink); +#endif +#if defined ENABLE_PLUGIN_UBLOX + PREPEND_PLUGIN (ublox); +#endif +#if defined ENABLE_PLUGIN_VIA + PREPEND_PLUGIN (via); +#endif +#if defined ENABLE_PLUGIN_WAVECOM + PREPEND_PLUGIN (wavecom); +#endif +#if defined ENABLE_PLUGIN_X22X + PREPEND_PLUGIN (x22x); +#endif +#if defined ENABLE_PLUGIN_ZTE + PREPEND_PLUGIN (zte); +#endif +#undef PREPEND_PLUGIN + return builtin_plugins; +} diff --git a/src/plugins/mm-builtin-plugins.h b/src/plugins/mm-builtin-plugins.h new file mode 100644 index 00000000..dac9c3b2 --- /dev/null +++ b/src/plugins/mm-builtin-plugins.h @@ -0,0 +1,28 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2022 Google Inc. + */ + +#ifndef MM_BUILTIN_PLUGINS_H +#define MM_BUILTIN_PLUGINS_H + +#include <config.h> +#include <glib.h> + +#if !defined WITH_BUILTIN_PLUGINS +# error Build with builtin plugins was not enabled +#endif + +GList *mm_builtin_plugins_load (void); + +#endif /* MM_BUILTIN_PLUGINS_H */ diff --git a/src/plugins/mm-plugin-common.h b/src/plugins/mm-plugin-common.h index 607d24db..55e06d7e 100644 --- a/src/plugins/mm-plugin-common.h +++ b/src/plugins/mm-plugin-common.h @@ -26,20 +26,28 @@ #include "mm-plugin.h" -#define MM_PLUGIN_NAMED_CREATOR_SCOPE static +#if defined (G_HAVE_GNUC_VISIBILITY) +# define MM_VISIBILITY __attribute__((visibility("protected"))) +#else +# define MM_VISIBILITY +#endif -#define MM_PLUGIN_CREATOR(my_plugin) \ +#if defined WITH_BUILTIN_PLUGINS +# define MM_PLUGIN_VERSION +# define MM_PLUGIN_NAMED_CREATOR_SCOPE +# define MM_PLUGIN_CREATOR(unused) +#else +# define MM_PLUGIN_VERSION \ + MM_VISIBILITY int mm_plugin_major_version = MM_PLUGIN_MAJOR_VERSION; \ + MM_VISIBILITY int mm_plugin_minor_version = MM_PLUGIN_MINOR_VERSION; +# define MM_PLUGIN_NAMED_CREATOR_SCOPE static +# define MM_PLUGIN_CREATOR(my_plugin) \ G_MODULE_EXPORT MMPlugin *mm_plugin_create (void); \ G_MODULE_EXPORT MMPlugin * \ mm_plugin_create (void) \ { \ return mm_plugin_create_##my_plugin (); \ } - -#if defined (G_HAVE_GNUC_VISIBILITY) -# define MM_VISIBILITY __attribute__((visibility("protected"))) -#else -# define MM_VISIBILITY #endif #define MM_DEFINE_PLUGIN(MY_PLUGIN, my_plugin, MyPlugin) \ @@ -49,8 +57,7 @@ }; \ G_DEFINE_TYPE (MMPlugin##MyPlugin, mm_plugin_##my_plugin, MM_TYPE_PLUGIN) \ \ - MM_VISIBILITY int mm_plugin_major_version = MM_PLUGIN_MAJOR_VERSION; \ - MM_VISIBILITY int mm_plugin_minor_version = MM_PLUGIN_MINOR_VERSION; \ + MM_PLUGIN_VERSION \ \ MM_PLUGIN_NAMED_CREATOR_SCOPE MMPlugin *mm_plugin_create_##my_plugin (void); \ MM_PLUGIN_CREATOR(my_plugin) diff --git a/src/plugins/mm-shared-common.h b/src/plugins/mm-shared-common.h index a9183ee6..d795624f 100644 --- a/src/plugins/mm-shared-common.h +++ b/src/plugins/mm-shared-common.h @@ -33,9 +33,13 @@ #define MM_VISIBILITY #endif -#define MM_DEFINE_SHARED(MyShared) \ +#if defined WITH_BUILTIN_PLUGINS +# define MM_DEFINE_SHARED(unused) +#else +# define MM_DEFINE_SHARED(MyShared) \ MM_VISIBILITY int mm_shared_major_version = MM_SHARED_MAJOR_VERSION; \ MM_VISIBILITY int mm_shared_minor_version = MM_SHARED_MINOR_VERSION; \ MM_VISIBILITY const char *mm_shared_name = #MyShared; +#endif #endif /* MM_SHARED_COMMON_H */ |