summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@redhat.com>2014-11-12 17:45:12 +0100
committerTomas Bzatek <tbzatek@redhat.com>2015-01-19 15:09:31 +0100
commit725f4a04772b6e36ac8fe0e0f8b526e180352ac9 (patch)
treeb919d8c54c92814ec73ed930ea9133c9ad1bcaac
parent3793aedc5de4f843266fffd2302a5dde08fb74e8 (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.am1
-rw-r--r--modules/dummy/data/org.freedesktop.UDisks2.dummy.xml25
-rw-r--r--modules/dummy/dummylinuxmanager.c115
-rw-r--r--modules/dummy/dummylinuxmanager.h39
-rw-r--r--modules/dummy/dummymoduleiface.c24
-rw-r--r--modules/dummy/dummytypes.h3
-rw-r--r--modules/udisksmoduleiface.h2
-rw-r--r--modules/udisksmoduleifacetypes.h12
-rw-r--r--src/udiskslinuxprovider.c21
-rw-r--r--src/udisksmodulemanager.c34
-rw-r--r--src/udisksmodulemanager.h1
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