From 7565bdbe884edd9aa8ea26a8348dc800f2b6949a Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Tue, 11 Sep 2012 12:56:42 -0400 Subject: [PATCH] Add Start()/Stop() methods to MDRaid D-Bus interface This makes it possible to start/stop RAID arrays http://people.freedesktop.org/~david/gnome-disks-mdraid-20120911-1.png Signed-off-by: David Zeuthen --- data/org.freedesktop.UDisks2.xml | 20 +++- data/org.freedesktop.udisks2.policy.in | 13 +++ src/udiskslinuxmdraid.c | 203 +++++++++++++++++++++++++++++++++ udisks/udisksclient.c | 2 + 4 files changed, 237 insertions(+), 1 deletion(-) diff --git a/data/org.freedesktop.UDisks2.xml b/data/org.freedesktop.UDisks2.xml index 3110bf9..5c5a294 100644 --- a/data/org.freedesktop.UDisks2.xml +++ b/data/org.freedesktop.UDisks2.xml @@ -1639,7 +1639,25 @@ --> - + + + + + + + + + diff --git a/data/org.freedesktop.udisks2.policy.in b/data/org.freedesktop.udisks2.policy.in index d9f4c19..6e7d5bc 100644 --- a/data/org.freedesktop.udisks2.policy.in +++ b/data/org.freedesktop.udisks2.policy.in @@ -204,6 +204,19 @@ + + + + <_description>Manage RAID arrays + <_message>Authentication is required to manage RAID arrays + + auth_admin + auth_admin + auth_admin_keep + + + + diff --git a/src/udiskslinuxmdraid.c b/src/udiskslinuxmdraid.c index 302a336..685db1a 100644 --- a/src/udiskslinuxmdraid.c +++ b/src/udiskslinuxmdraid.c @@ -184,7 +184,210 @@ udisks_linux_mdraid_update (UDisksLinuxMDRaid *mdraid, /* ---------------------------------------------------------------------------------------------------- */ +static gboolean +handle_start (UDisksMDRaid *_mdraid, + GDBusMethodInvocation *invocation, + GVariant *options) +{ + UDisksLinuxMDRaid *mdraid = UDISKS_LINUX_MDRAID (_mdraid); + UDisksDaemon *daemon; + UDisksLinuxMDRaidObject *object; + const gchar *action_id; + const gchar *message; + uid_t caller_uid; + gid_t caller_gid; + GUdevDevice *raid_device = NULL; + gchar *uuid = NULL; + gchar *escaped_uuid = NULL; + GError *error = NULL; + gchar *error_message = NULL; + + object = udisks_daemon_util_dup_object (mdraid, &error); + if (object == NULL) + { + g_dbus_method_invocation_take_error (invocation, error); + goto out; + } + + daemon = udisks_linux_mdraid_object_get_daemon (object); + + error = NULL; + if (!udisks_daemon_util_get_caller_uid_sync (daemon, + invocation, + NULL /* GCancellable */, + &caller_uid, + &caller_gid, + NULL, + &error)) + { + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); + goto out; + } + + raid_device = udisks_linux_mdraid_object_get_device (object); + if (raid_device != NULL) + { + g_dbus_method_invocation_return_error (invocation, UDISKS_ERROR, UDISKS_ERROR_FAILED, + "RAID Array is already running"); + goto out; + } + + /* Translators: Shown in authentication dialog when the attempts. + * to stop a RAID ARRAY. + */ + /* TODO: variables */ + message = N_("Authentication is required to start a RAID array"); + action_id = "org.freedesktop.udisks2.manage-md-raid"; + if (!udisks_daemon_util_check_authorization_sync (daemon, + UDISKS_OBJECT (object), + action_id, + options, + message, + invocation)) + goto out; + + uuid = udisks_mdraid_dup_uuid (_mdraid); + escaped_uuid = udisks_daemon_util_escape_and_quote (uuid); + + if (!udisks_daemon_launch_spawned_job_sync (daemon, + UDISKS_OBJECT (object), + "md-raid-start", caller_uid, + NULL, /* GCancellable */ + 0, /* uid_t run_as_uid */ + 0, /* uid_t run_as_euid */ + NULL, /* gint *out_status */ + &error_message, + NULL, /* input_string */ + "mdadm --assemble --scan --uuid %s", + escaped_uuid)) + { + g_dbus_method_invocation_return_error (invocation, + UDISKS_ERROR, + UDISKS_ERROR_FAILED, + "Error stopping RAID array with UUID %s: %s", + uuid, + error_message); + goto out; + } + + /* TODO: wait for array to actually show up? */ + + udisks_mdraid_complete_stop (_mdraid, invocation); + + out: + g_free (error_message); + g_free (uuid); + g_free (escaped_uuid); + g_clear_object (&raid_device); + g_clear_object (&object); + return TRUE; /* returning TRUE means that we handled the method invocation */ +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static gboolean +handle_stop (UDisksMDRaid *_mdraid, + GDBusMethodInvocation *invocation, + GVariant *options) +{ + UDisksLinuxMDRaid *mdraid = UDISKS_LINUX_MDRAID (_mdraid); + UDisksDaemon *daemon; + UDisksLinuxMDRaidObject *object; + const gchar *action_id; + const gchar *message; + uid_t caller_uid; + gid_t caller_gid; + GUdevDevice *raid_device = NULL; + const gchar *device_file = NULL; + gchar *escaped_device_file = NULL; + GError *error = NULL; + gchar *error_message = NULL; + + object = udisks_daemon_util_dup_object (mdraid, &error); + if (object == NULL) + { + g_dbus_method_invocation_take_error (invocation, error); + goto out; + } + + daemon = udisks_linux_mdraid_object_get_daemon (object); + + error = NULL; + if (!udisks_daemon_util_get_caller_uid_sync (daemon, + invocation, + NULL /* GCancellable */, + &caller_uid, + &caller_gid, + NULL, + &error)) + { + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); + goto out; + } + + raid_device = udisks_linux_mdraid_object_get_device (object); + if (raid_device == NULL) + { + g_dbus_method_invocation_return_error (invocation, UDISKS_ERROR, UDISKS_ERROR_FAILED, + "RAID Array is not running"); + goto out; + } + + /* Translators: Shown in authentication dialog when the attempts. + * to stop a RAID ARRAY. + */ + /* TODO: variables */ + message = N_("Authentication is required to stop a RAID array"); + action_id = "org.freedesktop.udisks2.manage-md-raid"; + if (!udisks_daemon_util_check_authorization_sync (daemon, + UDISKS_OBJECT (object), + action_id, + options, + message, + invocation)) + goto out; + + device_file = g_udev_device_get_device_file (raid_device); + escaped_device_file = udisks_daemon_util_escape_and_quote (g_udev_device_get_device_file (raid_device)); + + if (!udisks_daemon_launch_spawned_job_sync (daemon, + UDISKS_OBJECT (object), + "md-raid-stop", caller_uid, + NULL, /* GCancellable */ + 0, /* uid_t run_as_uid */ + 0, /* uid_t run_as_euid */ + NULL, /* gint *out_status */ + &error_message, + NULL, /* input_string */ + "mdadm --stop %s", + escaped_device_file)) + { + g_dbus_method_invocation_return_error (invocation, + UDISKS_ERROR, + UDISKS_ERROR_FAILED, + "Error stopping RAID array %s: %s", + device_file, + error_message); + goto out; + } + + udisks_mdraid_complete_stop (_mdraid, invocation); + + out: + g_free (error_message); + g_free (escaped_device_file); + g_clear_object (&raid_device); + g_clear_object (&object); + return TRUE; /* returning TRUE means that we handled the method invocation */ +} + +/* ---------------------------------------------------------------------------------------------------- */ + static void mdraid_iface_init (UDisksMDRaidIface *iface) { + iface->handle_start = handle_start; + iface->handle_stop = handle_stop; } diff --git a/udisks/udisksclient.c b/udisks/udisksclient.c index 8835b46..b0778b3 100644 --- a/udisks/udisksclient.c +++ b/udisks/udisksclient.c @@ -2770,6 +2770,8 @@ udisks_client_get_job_description (UDisksClient *client, g_hash_table_insert (hash, (gpointer) "cleanup", (gpointer) C_("job", "Cleaning Up")); g_hash_table_insert (hash, (gpointer) "ata-secure-erase", (gpointer) C_("job", "ATA Secure Erase")); g_hash_table_insert (hash, (gpointer) "ata-enhanced-secure-erase", (gpointer) C_("job", "ATA Enhanced Secure Erase")); + g_hash_table_insert (hash, (gpointer) "md-raid-stop", (gpointer) C_("job", "Stopping RAID Array")); + g_hash_table_insert (hash, (gpointer) "md-raid-start", (gpointer) C_("job", "Starting RAID Array")); g_once_init_leave (&once, (gsize) 1); } -- 2.7.4