diff options
author | Dan Williams <dcbw@redhat.com> | 2014-09-05 15:57:40 -0500 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2014-09-11 12:50:15 -0500 |
commit | 0bc1b5138ad8f7a64c74c374c866d615c69887bb (patch) | |
tree | c0f8e059eb06b25a94233e18c21ea7a219baedc6 /src | |
parent | 38b076de8fc0e531ff80e9c9237960e0b2126467 (diff) | |
download | NetworkManager-0bc1b5138ad8f7a64c74c374c866d615c69887bb.tar.gz |
core: add support for internal device factories
Diffstat (limited to 'src')
-rw-r--r-- | src/devices/nm-device-factory.c | 15 | ||||
-rw-r--r-- | src/devices/nm-device-factory.h | 57 | ||||
-rw-r--r-- | src/nm-manager.c | 48 | ||||
-rw-r--r-- | src/tests/Makefile.am | 16 |
4 files changed, 121 insertions, 15 deletions
diff --git a/src/devices/nm-device-factory.c b/src/devices/nm-device-factory.c index dc229bd5c8..80488aec37 100644 --- a/src/devices/nm-device-factory.c +++ b/src/devices/nm-device-factory.c @@ -27,6 +27,21 @@ enum { }; static guint signals[LAST_SIGNAL] = { 0 }; +static GSList *internal_types = NULL; + +void +_nm_device_factory_internal_register_type (GType factory_type) +{ + g_return_if_fail (g_slist_find (internal_types, GUINT_TO_POINTER (factory_type)) == NULL); + internal_types = g_slist_prepend (internal_types, GUINT_TO_POINTER (factory_type)); +} + +const GSList * +nm_device_factory_get_internal_factory_types (void) +{ + return internal_types; +} + gboolean nm_device_factory_emit_component_added (NMDeviceFactory *factory, GObject *component) { diff --git a/src/devices/nm-device-factory.h b/src/devices/nm-device-factory.h index dd8a907961..ce672b8bfb 100644 --- a/src/devices/nm-device-factory.h +++ b/src/devices/nm-device-factory.h @@ -168,5 +168,60 @@ NMDevice * nm_device_factory_create_virtual_device_for_connection (NMDeviceFacto gboolean nm_device_factory_emit_component_added (NMDeviceFactory *factory, GObject *component); -#endif /* __NETWORKMANAGER_DEVICE_FACTORY_H__ */ +/************************************************************************** + * INTERNAL DEVICE FACTORY FUNCTIONS - devices provided by plugins should + * not use these functions. + **************************************************************************/ + +#define DEFINE_DEVICE_FACTORY_INTERNAL(upper, mixed, lower, dfi_code) \ + DEFINE_DEVICE_FACTORY_INTERNAL_WITH_DEVTYPE(upper, mixed, lower, upper, dfi_code) + +#define DEFINE_DEVICE_FACTORY_INTERNAL_WITH_DEVTYPE(upper, mixed, lower, devtype, dfi_code) \ + typedef GObject NM##mixed##Factory; \ + typedef GObjectClass NM##mixed##FactoryClass; \ + \ + static GType nm_##lower##_factory_get_type (void); \ + static void device_factory_interface_init (NMDeviceFactory *factory_iface); \ + \ + G_DEFINE_TYPE_EXTENDED (NM##mixed##Factory, nm_##lower##_factory, G_TYPE_OBJECT, 0, \ + G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_FACTORY, device_factory_interface_init) \ + _nm_device_factory_internal_register_type (g_define_type_id);) \ + \ + /* Use a module constructor to register the factory's GType at load \ + * time, which then calls _nm_device_factory_internal_register_type() \ + * to register the factory's GType with the Manager. \ + */ \ + static void __attribute__((constructor)) \ + register_device_factory_internal_##lower (void) \ + { \ + g_type_init (); \ + g_type_ensure (NM_TYPE_##upper##_FACTORY); \ + } \ + \ + static NMDeviceType \ + get_device_type (NMDeviceFactory *factory) \ + { \ + return NM_DEVICE_TYPE_##devtype; \ + } \ + \ + static void \ + device_factory_interface_init (NMDeviceFactory *factory_iface) \ + { \ + factory_iface->get_device_type = get_device_type; \ + dfi_code \ + } \ + \ + static void \ + nm_##lower##_factory_init (NM##mixed##Factory *self) \ + { \ + } \ + \ + static void \ + nm_##lower##_factory_class_init (NM##mixed##FactoryClass *lower##_class) \ + { \ + } + +void _nm_device_factory_internal_register_type (GType factory_type); +const GSList *nm_device_factory_get_internal_factory_types (void); +#endif /* __NETWORKMANAGER_DEVICE_FACTORY_H__ */ diff --git a/src/nm-manager.c b/src/nm-manager.c index 6dd70eea93..cf7d2f5a9b 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1968,6 +1968,7 @@ NEXT: static gboolean _register_device_factory (NMManager *self, NMDeviceFactory *factory, + gboolean duplicate_check, const char *path, GError **error) { @@ -1975,15 +1976,17 @@ _register_device_factory (NMManager *self, NMDeviceType ftype; GSList *iter; - /* Make sure we don't double-register factories */ - ftype = nm_device_factory_get_device_type (factory); - for (iter = priv->factories; iter; iter = iter->next) { - if (ftype == nm_device_factory_get_device_type (iter->data)) { - g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_INTERNAL, - "multiple plugins for same type (using '%s' instead of '%s')", - (char *) g_object_get_data (G_OBJECT (iter->data), PLUGIN_PATH_TAG), - path); - return FALSE; + if (duplicate_check) { + /* Make sure we don't double-register factories */ + ftype = nm_device_factory_get_device_type (factory); + for (iter = priv->factories; iter; iter = iter->next) { + if (ftype == nm_device_factory_get_device_type (iter->data)) { + g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_INTERNAL, + "multiple plugins for same type (using '%s' instead of '%s')", + (char *) g_object_get_data (G_OBJECT (iter->data), PLUGIN_PATH_TAG), + path); + return FALSE; + } } } @@ -2005,17 +2008,32 @@ _register_device_factory (NMManager *self, static void load_device_factories (NMManager *self) { - char **path; - char **paths; + NMDeviceFactory *factory; + const GSList *iter; + GError *error = NULL; + char **path, **paths; + + /* Register internal factories first */ + for (iter = nm_device_factory_get_internal_factory_types (); iter; iter = iter->next) { + GType ftype = GPOINTER_TO_UINT (iter->data); + + factory = (NMDeviceFactory *) g_object_new (ftype, NULL); + g_assert (factory); + if (_register_device_factory (self, factory, FALSE, "internal", &error)) { + nm_log_dbg (LOGD_HW, "Loaded device plugin: %s", g_type_name (ftype)); + } else { + nm_log_warn (LOGD_HW, "Loading device plugin failed: %s", error->message); + g_object_unref (factory); + g_clear_error (&error); + } + } paths = read_device_factory_paths (); if (!paths) return; for (path = paths; *path; path++) { - GError *error = NULL; GModule *plugin; - NMDeviceFactory *factory; NMDeviceFactoryCreateFunc create_func; const char *item; @@ -2045,7 +2063,7 @@ load_device_factories (NMManager *self) } g_clear_error (&error); - if (_register_device_factory (self, factory, g_module_name (plugin), &error)) { + if (_register_device_factory (self, factory, TRUE, g_module_name (plugin), &error)) { nm_log_info (LOGD_HW, "Loaded device plugin: %s", g_module_name (plugin)); g_module_make_resident (plugin); } else { @@ -2058,6 +2076,8 @@ load_device_factories (NMManager *self) g_strfreev (paths); } +/*******************************************************************/ + static void platform_link_added (NMManager *self, int ifindex, diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index a5824c96a3..221d3f5704 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -95,3 +95,19 @@ TESTS = \ test-general-with-expect \ test-wired-defname + +if ENABLE_TESTS + +check-local: + @for t in ; do \ + # Ensure the device subclass factory registration constructors exist \ + # which could inadvertently break if src/Makefile.am gets changed \ + if ! LC_ALL=C nm $(top_builddir)/src/NetworkManager | LC_ALL=C grep -q "register_device_factory_internal_$$t" ; then \ + echo "Testing device factory symbols... FAILED" ; \ + exit 1 ; \ + fi \ + done + @echo -n "Testing device factory symbols... PASSED" + +endif + |