Add Start()/Stop() methods to MDRaid D-Bus interface
authorDavid Zeuthen <zeuthen@gmail.com>
Tue, 11 Sep 2012 16:56:42 +0000 (12:56 -0400)
committerDavid Zeuthen <zeuthen@gmail.com>
Tue, 11 Sep 2012 16:56:42 +0000 (12:56 -0400)
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 <zeuthen@gmail.com>
data/org.freedesktop.UDisks2.xml
data/org.freedesktop.udisks2.policy.in
src/udiskslinuxmdraid.c
udisks/udisksclient.c

index 3110bf9..5c5a294 100644 (file)
     -->
     <property name="Degraded" type="u" access="read"/>
 
-    <!-- TODO: start/stop methods -->
+    <!--
+        Start:
+        @options: Options (currently unused except for <link linkend="udisks-std-options">standard options</link>).
+
+        Starts the RAID array.
+    -->
+    <method name="Start">
+      <arg name="options" direction="in" type="a{sv}"/>
+    </method>
+
+    <!--
+        Stop:
+        @options: Options (currently unused except for <link linkend="udisks-std-options">standard options</link>).
+
+        Stops the RAID array.
+    -->
+    <method name="Stop">
+      <arg name="options" direction="in" type="a{sv}"/>
+    </method>
 
   </interface>
 
index d9f4c19..6e7d5bc 100644 (file)
   </action>
 
   <!-- ###################################################################### -->
+  <!-- Manage MD-RAID -->
+
+  <action id="org.freedesktop.udisks2.manage-md-raid">
+    <_description>Manage RAID arrays</_description>
+    <_message>Authentication is required to manage RAID arrays</_message>
+    <defaults>
+      <allow_any>auth_admin</allow_any>
+      <allow_inactive>auth_admin</allow_inactive>
+      <allow_active>auth_admin_keep</allow_active>
+    </defaults>
+  </action>
+
+  <!-- ###################################################################### -->
   <!-- Eject media from a drive -->
 
   <action id="org.freedesktop.udisks2.eject-media">
index 302a336..685db1a 100644 (file)
@@ -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;
 }
index 8835b46..b0778b3 100644 (file)
@@ -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);
     }