core: add support for internal device factories
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
@@ -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__ */
|
||||
|
@@ -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,
|
||||
|
@@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user