diff options
author | Tomas Bzatek <tbzatek@redhat.com> | 2014-11-12 17:45:12 +0100 |
---|---|---|
committer | Tomas Bzatek <tbzatek@redhat.com> | 2015-01-19 15:09:31 +0100 |
commit | 725f4a04772b6e36ac8fe0e0f8b526e180352ac9 (patch) | |
tree | b919d8c54c92814ec73ed930ea9133c9ad1bcaac | |
parent | 3793aedc5de4f843266fffd2302a5dde08fb74e8 (diff) |
udisks-modular: Introduce pluggable manager interfaces
This commit brings possibility to export additional interfaces that
will be attached to the master /org/freedesktop/UDisks2/Manager object.
Such interface should typically offer methods for creating new complex
structures like RAID arrays or LVM2 volume groups.
-rw-r--r-- | modules/dummy/Makefile.am | 1 | ||||
-rw-r--r-- | modules/dummy/data/org.freedesktop.UDisks2.dummy.xml | 25 | ||||
-rw-r--r-- | modules/dummy/dummylinuxmanager.c | 115 | ||||
-rw-r--r-- | modules/dummy/dummylinuxmanager.h | 39 | ||||
-rw-r--r-- | modules/dummy/dummymoduleiface.c | 24 | ||||
-rw-r--r-- | modules/dummy/dummytypes.h | 3 | ||||
-rw-r--r-- | modules/udisksmoduleiface.h | 2 | ||||
-rw-r--r-- | modules/udisksmoduleifacetypes.h | 12 | ||||
-rw-r--r-- | src/udiskslinuxprovider.c | 21 | ||||
-rw-r--r-- | src/udisksmodulemanager.c | 34 | ||||
-rw-r--r-- | src/udisksmodulemanager.h | 1 |
11 files changed, 276 insertions, 1 deletions
diff --git a/modules/dummy/Makefile.am b/modules/dummy/Makefile.am index e29718b..96c6bd1 100644 --- a/modules/dummy/Makefile.am +++ b/modules/dummy/Makefile.am @@ -63,6 +63,7 @@ libudisks2_dummy_la_SOURCES = \ dummylinuxdrive.h dummylinuxdrive.c \ dummyloopobject.h dummyloopobject.c \ dummylinuxloop.h dummylinuxloop.c \ + dummylinuxmanager.h dummylinuxmanager.c \ $(NULL) libudisks2_dummy_la_CPPFLAGS = \ diff --git a/modules/dummy/data/org.freedesktop.UDisks2.dummy.xml b/modules/dummy/data/org.freedesktop.UDisks2.dummy.xml index 68a14bd..d3b351b 100644 --- a/modules/dummy/data/org.freedesktop.UDisks2.dummy.xml +++ b/modules/dummy/data/org.freedesktop.UDisks2.dummy.xml @@ -109,6 +109,31 @@ <property name="num_devices" type="i" access="read"/> </interface> + + <!-- ********************************************************************** --> + + <!-- + org.freedesktop.UDisks2.DummyManager: + @short_description: Dummy manager interface that lets you create wonders + + This interface is meant as a supplement to the /org/freedesktop/UDisks2/Manager + object manager. Typically serves the purpose of creating new objects/devices + etc. of a specified type. E.g. new RAID arrays, LVM2 volume groups, etc. + --> + <interface name="org.freedesktop.UDisks2.DummyManager"> + + <!-- + CreateLoopPool: + @name: The name of the pool to create. + + Creates a loop pool (bogus). + --> + <method name="CreateLoopPool"> + <arg name="name" direction="in" type="s"/> + </method> + + </interface> + <!-- ********************************************************************** --> </node> diff --git a/modules/dummy/dummylinuxmanager.c b/modules/dummy/dummylinuxmanager.c new file mode 100644 index 0000000..522e14e --- /dev/null +++ b/modules/dummy/dummylinuxmanager.c @@ -0,0 +1,115 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2014 Tomas Bzatek <tbzatek@redhat.com> + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "config.h" + +#include <sys/types.h> + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +#include <src/udiskslogging.h> +#include <src/udisksdaemon.h> +#include <src/udisksdaemonutil.h> +#include <src/udiskslinuxdevice.h> + +#include "dummytypes.h" +#include "dummylinuxmanager.h" +#include "dummy-generated.h" + +/** + * SECTION:dummylinuxmanager + * @title: DummyLinuxManager + * @short_description: Linux implementation of #DummyLinuxManager + * + * This type provides an implementation of the #DummyLinuxManager + * interface on Linux. + */ + +typedef struct _DummyLinuxManagerClass DummyLinuxManagerClass; + +/** + * DummyLinuxManager: + * + * The #DummyLinuxManager structure contains only private data and should + * only be accessed using the provided API. + */ +struct _DummyLinuxManager +{ + DummyDummyManagerSkeleton parent_instance; +}; + +struct _DummyLinuxManagerClass +{ + DummyDummyManagerSkeletonClass parent_class; +}; + +static void dummy_linux_manager_iface_init (DummyDummyManagerIface *iface); + +G_DEFINE_TYPE_WITH_CODE (DummyLinuxManager, dummy_linux_manager, DUMMY_TYPE_DUMMY_MANAGER_SKELETON, + G_IMPLEMENT_INTERFACE (DUMMY_TYPE_DUMMY_MANAGER, dummy_linux_manager_iface_init)); + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +dummy_linux_manager_init (DummyLinuxManager *manager) +{ +} + +static void +dummy_linux_manager_class_init (DummyLinuxManagerClass *klass) +{ +} + +/** + * dummy_linux_manager_new: + * + * Creates a new #DummyLinuxManager instance. + * + * Returns: A new #DummyLinuxManager. Free with g_object_unref(). + */ +DummyLinuxManager * +dummy_linux_manager_new (void) +{ + return DUMMY_LINUX_MANAGER (g_object_new (DUMMY_TYPE_LINUX_MANAGER, NULL)); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +handle_create_loop_pool (DummyDummyManager *object, + GDBusMethodInvocation *invocation, + const gchar *arg_name) +{ + udisks_notice ("Dummy plugin: called org.freedesktop.UDisks2.DummyManager.CreateLoopPool(name=\"%s\")", arg_name); + + dummy_dummy_manager_complete_create_loop_pool (object, invocation); + + return TRUE; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +dummy_linux_manager_iface_init (DummyDummyManagerIface *iface) +{ + iface->handle_create_loop_pool = handle_create_loop_pool; +} diff --git a/modules/dummy/dummylinuxmanager.h b/modules/dummy/dummylinuxmanager.h new file mode 100644 index 0000000..48d3a86 --- /dev/null +++ b/modules/dummy/dummylinuxmanager.h @@ -0,0 +1,39 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2014 Tomas Bzatek <tbzatek@redhat.com> + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __DUMMY_LINUX_MANAGER_H__ +#define __DUMMY_LINUX_MANAGER_H__ + +#include <src/udisksdaemontypes.h> +#include "dummytypes.h" +#include "dummy-generated.h" + +G_BEGIN_DECLS + +#define DUMMY_TYPE_LINUX_MANAGER (dummy_linux_manager_get_type ()) +#define DUMMY_LINUX_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DUMMY_TYPE_LINUX_MANAGER, DummyLinuxManager)) +#define DUMMY_IS_LINUX_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), DUMMY_TYPE_LINUX_MANAGER)) + +GType dummy_linux_manager_get_type (void) G_GNUC_CONST; +DummyLinuxManager *dummy_linux_manager_new (void); + +G_END_DECLS + +#endif /* __DUMMY_LINUX_MANAGER_H__ */ diff --git a/modules/dummy/dummymoduleiface.c b/modules/dummy/dummymoduleiface.c index 170f9a3..6942ff4 100644 --- a/modules/dummy/dummymoduleiface.c +++ b/modules/dummy/dummymoduleiface.c @@ -37,6 +37,7 @@ #include "dummylinuxblock.h" #include "dummylinuxdrive.h" #include "dummyloopobject.h" +#include "dummylinuxmanager.h" @@ -151,3 +152,26 @@ udisks_module_get_object_new_funcs (void) return funcs; } + +/* ---------------------------------------------------------------------------------------------------- */ + +static GDBusInterfaceSkeleton * +dummy_new_manager_iface (UDisksDaemon *daemon) +{ + DummyLinuxManager *manager; + + manager = dummy_linux_manager_new (); + + return G_DBUS_INTERFACE_SKELETON (manager); +} + +UDisksModuleNewManagerIfaceFunc * +udisks_module_get_new_manager_iface_funcs (void) +{ + UDisksModuleNewManagerIfaceFunc *funcs; + + funcs = g_new0 (UDisksModuleNewManagerIfaceFunc, 2); + funcs[0] = &dummy_new_manager_iface; + + return funcs; +} diff --git a/modules/dummy/dummytypes.h b/modules/dummy/dummytypes.h index 1e9df5c..1d01f36 100644 --- a/modules/dummy/dummytypes.h +++ b/modules/dummy/dummytypes.h @@ -40,4 +40,7 @@ typedef struct _DummyLoopObject DummyLoopObject; struct _DummyLinuxLoop; typedef struct _DummyLinuxLoop DummyLinuxLoop; +struct _DummyLinuxManager; +typedef struct _DummyLinuxManager DummyLinuxManager; + #endif /* __DUMMY_TYPES_H__ */ diff --git a/modules/udisksmoduleiface.h b/modules/udisksmoduleiface.h index 9fc16da..e37cd1c 100644 --- a/modules/udisksmoduleiface.h +++ b/modules/udisksmoduleiface.h @@ -52,6 +52,8 @@ G_MODULE_EXPORT UDisksModuleInterfaceInfo **udisks_module_get_drive_object_iface G_MODULE_EXPORT UDisksModuleObjectNewFunc *udisks_module_get_object_new_funcs (void); +G_MODULE_EXPORT UDisksModuleNewManagerIfaceFunc *udisks_module_get_new_manager_iface_funcs (void); + G_END_DECLS diff --git a/modules/udisksmoduleifacetypes.h b/modules/udisksmoduleifacetypes.h index ee64288..5f26fe8 100644 --- a/modules/udisksmoduleifacetypes.h +++ b/modules/udisksmoduleifacetypes.h @@ -52,10 +52,22 @@ typedef struct typedef GDBusObjectSkeleton* (*UDisksModuleObjectNewFunc) (UDisksDaemon *daemon, UDisksLinuxDevice *device); +/** + * UDisksModuleNewManagerIfaceFunc: + * + * A function prototype that creates new #GDBusInterfaceSkeleton instance + * carrying an interface to be exported on the UDisks manager object. + * + * Returns: A new #GDBusInterfaceSkeleton. Free with g_object_unref(). + */ +typedef GDBusInterfaceSkeleton* (*UDisksModuleNewManagerIfaceFunc) (UDisksDaemon *daemon); + /* Module setup functions */ typedef UDisksModuleInterfaceInfo ** (*UDisksModuleIfaceSetupFunc) (void); typedef UDisksModuleObjectNewFunc * (*UDisksModuleObjectNewSetupFunc) (void); +typedef UDisksModuleNewManagerIfaceFunc * (*UDisksModuleNewManagerIfaceSetupFunc) (void); + G_END_DECLS diff --git a/src/udiskslinuxprovider.c b/src/udiskslinuxprovider.c index 9fee78a..0732eb9 100644 --- a/src/udiskslinuxprovider.c +++ b/src/udiskslinuxprovider.c @@ -401,10 +401,13 @@ udisks_linux_provider_start (UDisksProvider *_provider) UDisksLinuxProvider *provider = UDISKS_LINUX_PROVIDER (_provider); UDisksDaemon *daemon; UDisksManager *manager; + UDisksModuleManager *module_manager; GList *devices; GList *udisks_devices; GList *l; guint n; + GDBusInterfaceSkeleton *iface; + UDisksModuleNewManagerIfaceFunc new_manager_iface_func; provider->coldplug = TRUE; @@ -413,11 +416,29 @@ udisks_linux_provider_start (UDisksProvider *_provider) daemon = udisks_provider_get_daemon (UDISKS_PROVIDER (provider)); + module_manager = udisks_daemon_get_module_manager (daemon); + provider->manager_object = udisks_object_skeleton_new ("/org/freedesktop/UDisks2/Manager"); manager = udisks_linux_manager_new (daemon); udisks_object_skeleton_set_manager (provider->manager_object, manager); g_object_unref (manager); + /* Attach additional interfaces from modules */ + if (module_manager != NULL) + { + l = udisks_module_manager_get_new_manager_iface_funcs (module_manager); + for (; l != NULL; l = l->next) + { + new_manager_iface_func = l->data; + iface = new_manager_iface_func (daemon); + if (iface != NULL) + { + g_dbus_object_skeleton_add_interface (G_DBUS_OBJECT_SKELETON (provider->manager_object), iface); + g_object_unref (iface); + } + } + } + g_dbus_object_manager_server_export (udisks_daemon_get_object_manager (daemon), G_DBUS_OBJECT_SKELETON (provider->manager_object)); diff --git a/src/udisksmodulemanager.c b/src/udisksmodulemanager.c index 2f3639c..e4dab64 100644 --- a/src/udisksmodulemanager.c +++ b/src/udisksmodulemanager.c @@ -65,6 +65,7 @@ struct _UDisksModuleManager GList *block_object_interface_infos; GList *drive_object_interface_infos; GList *module_object_new_funcs; + GList *new_manager_iface_funcs; gboolean modules_ready; }; @@ -123,6 +124,11 @@ udisks_module_manager_finalize (GObject *object) g_list_free (manager->module_object_new_funcs); } + if (manager->new_manager_iface_funcs != NULL) + { + g_list_free (manager->new_manager_iface_funcs); + } + if (manager->modules != NULL) { g_list_foreach (manager->modules, (GFunc) free_module_data, NULL); @@ -148,11 +154,15 @@ load_modules (UDisksModuleManager *manager) GModule *module; ModuleData *module_data; gchar *pth; + UDisksModuleIfaceSetupFunc block_object_iface_setup_func; UDisksModuleIfaceSetupFunc drive_object_iface_setup_func; UDisksModuleObjectNewSetupFunc module_object_new_setup_func; + UDisksModuleNewManagerIfaceSetupFunc module_new_manager_iface_setup_func; + UDisksModuleInterfaceInfo **infos, **infos_i; UDisksModuleObjectNewFunc *module_object_new_funcs, *module_object_new_funcs_i; + UDisksModuleNewManagerIfaceFunc *module_new_manager_iface_funcs, *module_new_manager_iface_funcs_i; error = NULL; @@ -176,7 +186,8 @@ load_modules (UDisksModuleManager *manager) udisks_notice ("Loading module %s...", dent); if (! g_module_symbol (module_data->handle, "udisks_module_get_block_object_iface_setup_entries", (gpointer *) &block_object_iface_setup_func) || ! g_module_symbol (module_data->handle, "udisks_module_get_drive_object_iface_setup_entries", (gpointer *) &drive_object_iface_setup_func) || - ! g_module_symbol (module_data->handle, "udisks_module_get_object_new_funcs", (gpointer *) &module_object_new_setup_func)) + ! g_module_symbol (module_data->handle, "udisks_module_get_object_new_funcs", (gpointer *) &module_object_new_setup_func) || + ! g_module_symbol (module_data->handle, "udisks_module_get_new_manager_iface_funcs", (gpointer *) &module_new_manager_iface_setup_func)) { udisks_warning (" Error importing required symbols from module '%s'", pth); free_module_data (module_data); @@ -198,6 +209,11 @@ load_modules (UDisksModuleManager *manager) manager->module_object_new_funcs = g_list_append (manager->module_object_new_funcs, *module_object_new_funcs_i); g_free (module_object_new_funcs); + module_new_manager_iface_funcs = module_new_manager_iface_setup_func (); + for (module_new_manager_iface_funcs_i = module_new_manager_iface_funcs; module_new_manager_iface_funcs_i && *module_new_manager_iface_funcs_i; module_new_manager_iface_funcs_i++) + manager->new_manager_iface_funcs = g_list_append (manager->new_manager_iface_funcs, *module_new_manager_iface_funcs_i); + g_free (module_new_manager_iface_funcs); + manager->modules = g_list_append (manager->modules, module_data); } } @@ -336,3 +352,19 @@ udisks_module_manager_get_module_object_new_funcs (UDisksModuleManager *manager) return NULL; return manager->module_object_new_funcs; } + +/** + * udisks_module_manager_get_new_manager_iface_funcs: + * @manager: A #UDisksModuleManager. + * + * Gets all module functions that can be used to create new interfaces that are supposed to be attached to the master /org/freedesktop/UDisks2/Manager object. + * + * Returns: (transfer full) (element-type #UDisksModuleNewManagerIfaceFunc): A list of #UDisksModuleNewManagerIfaceFunc function pointers that belongs to the manager and must not be freed. + */ +GList * +udisks_module_manager_get_new_manager_iface_funcs (UDisksModuleManager *manager) +{ + if (! manager->modules_ready) + return NULL; + return manager->new_manager_iface_funcs; +} diff --git a/src/udisksmodulemanager.h b/src/udisksmodulemanager.h index 7f6aae3..38507c1 100644 --- a/src/udisksmodulemanager.h +++ b/src/udisksmodulemanager.h @@ -35,6 +35,7 @@ UDisksModuleManager *udisks_module_manager_new (void); GList *udisks_module_manager_get_block_object_iface_infos (UDisksModuleManager *manager); GList *udisks_module_manager_get_drive_object_iface_infos (UDisksModuleManager *manager); GList *udisks_module_manager_get_module_object_new_funcs (UDisksModuleManager *manager); +GList *udisks_module_manager_get_new_manager_iface_funcs (UDisksModuleManager *manager); G_END_DECLS |