neil / rpms / udisks2

Forked from rpms/udisks2 a year ago
Clone
55fc26
From 9f749a4ea6129c256bb3522291eaa43f63c961c1 Mon Sep 17 00:00:00 2001
55fc26
From: Marius Vollmer <mvollmer@redhat.com>
55fc26
Date: Tue, 5 Dec 2017 17:17:40 +0200
55fc26
Subject: [PATCH] core: Add Encrypted.Resize method
55fc26
55fc26
To go with Filesystem.Resize.
55fc26
---
55fc26
 data/org.freedesktop.UDisks2.xml          |  16 ++++
55fc26
 doc/udisks2-sections.txt.in.in            |   4 +
55fc26
 src/udiskslinuxencrypted.c                | 134 ++++++++++++++++++++++++++++++
55fc26
 udisks/udisksclient.c                     |   1 +
55fc26
 4 files changed, 155 insertions(+)
55fc26
55fc26
diff --git a/data/org.freedesktop.UDisks2.xml b/data/org.freedesktop.UDisks2.xml
55fc26
index fa53a72..75ec0ea 100644
55fc26
--- a/data/org.freedesktop.UDisks2.xml
55fc26
+++ b/data/org.freedesktop.UDisks2.xml
55fc26
@@ -2059,6 +2059,20 @@
55fc26
       <arg name="options" direction="in" type="a{sv}"/>
55fc26
     </method>
55fc26
55fc26
+    
55fc26
+        Resize:
55fc26
+        @size: The target cleartext size in bytes, 0 for maximum.
55fc26
+        @options: Options (currently unused except for <link linkend="udisks-std-options">standard options</link>).
55fc26
+        @since: 2.7.6
55fc26
+
55fc26
+        Resizes the encrypted device.  The device must be unlocked.
55fc26
+        The given size is the target size for the cleartext device.
55fc26
+    -->
55fc26
+    <method name="Resize">
55fc26
+      <arg name="size" direction="in" type="t"/>
55fc26
+      <arg name="options" direction="in" type="a{sv}"/>
55fc26
+    </method>
55fc26
+
55fc26
   </interface>
55fc26
55fc26
   
55fc26
@@ -2451,6 +2465,8 @@
55fc26
              <listitem><para>Locking encrypted device.</para></listitem></varlistentry>
55fc26
            <varlistentry><term>encrypted-modify</term>
55fc26
              <listitem><para>Modifying encrypted device.</para></listitem></varlistentry>
55fc26
+           <varlistentry><term>encrypted-resize</term>
55fc26
+             <listitem><para>Resizing encrypted device.</para></listitem></varlistentry>
55fc26
            <varlistentry><term>swapspace-start</term>
55fc26
              <listitem><para>Starting swapspace.</para></listitem></varlistentry>
55fc26
            <varlistentry><term>swapspace-stop</term>
55fc26
diff --git a/doc/udisks2-sections.txt.in.in b/doc/udisks2-sections.txt.in.in
55fc26
index 5860d43..13cf728 100644
55fc26
--- a/doc/udisks2-sections.txt.in.in
55fc26
+++ b/doc/udisks2-sections.txt.in.in
55fc26
@@ -1036,6 +1036,10 @@ udisks_encrypted_call_change_passphrase
55fc26
 udisks_encrypted_call_change_passphrase_finish
55fc26
 udisks_encrypted_call_change_passphrase_sync
55fc26
 udisks_encrypted_complete_change_passphrase
55fc26
+udisks_encrypted_call_resize
55fc26
+udisks_encrypted_call_resize_finish
55fc26
+udisks_encrypted_call_resize_sync
55fc26
+udisks_encrypted_complete_resize
55fc26
 UDisksEncryptedProxy
55fc26
 UDisksEncryptedProxyClass
55fc26
 udisks_encrypted_proxy_new
55fc26
diff --git a/src/udiskslinuxencrypted.c b/src/udiskslinuxencrypted.c
55fc26
index 7b19e84..08e59d1 100644
55fc26
--- a/src/udiskslinuxencrypted.c
55fc26
+++ b/src/udiskslinuxencrypted.c
55fc26
@@ -43,6 +43,7 @@
55fc26
 #include "udiskscrypttabentry.h"
55fc26
 #include "udiskscrypttabmonitor.h"
55fc26
 #include "udisksspawnedjob.h"
55fc26
+#include "udiskssimplejob.h"
55fc26
55fc26
 /**
55fc26
  * SECTION:udiskslinuxencrypted
55fc26
@@ -802,10 +803,143 @@ handle_change_passphrase (UDisksEncrypted        *encrypted,
55fc26
55fc26
 /* ---------------------------------------------------------------------------------------------------- */
55fc26
55fc26
+/* runs in thread dedicated to handling method call */
55fc26
+static gboolean
55fc26
+handle_resize (UDisksEncrypted       *encrypted,
55fc26
+               GDBusMethodInvocation *invocation,
55fc26
+               guint64                size,
55fc26
+               GVariant              *options)
55fc26
+{
55fc26
+  UDisksObject *object = NULL;
55fc26
+  UDisksBlock *block;
55fc26
+  UDisksObject *cleartext_object = NULL;
55fc26
+  UDisksBlock *cleartext_block;
55fc26
+  UDisksDaemon *daemon;
55fc26
+  uid_t caller_uid;
55fc26
+  const gchar *action_id = NULL;
55fc26
+  const gchar *message = NULL;
55fc26
+  GError *error = NULL;
55fc26
+  UDisksBaseJob *job = NULL;
55fc26
+
55fc26
+  object = udisks_daemon_util_dup_object (encrypted, &error);
55fc26
+  if (object == NULL)
55fc26
+    {
55fc26
+      g_dbus_method_invocation_take_error (invocation, error);
55fc26
+      goto out;
55fc26
+    }
55fc26
+
55fc26
+  block = udisks_object_peek_block (object);
55fc26
+  daemon = udisks_linux_block_object_get_daemon (UDISKS_LINUX_BLOCK_OBJECT (object));
55fc26
+
55fc26
+  /* Fail if the device is not a LUKS device */
55fc26
+  if (!(g_strcmp0 (udisks_block_get_id_usage (block), "crypto") == 0 &&
55fc26
+        g_strcmp0 (udisks_block_get_id_type (block), "crypto_LUKS") == 0))
55fc26
+    {
55fc26
+      g_dbus_method_invocation_return_error (invocation,
55fc26
+                                             UDISKS_ERROR,
55fc26
+                                             UDISKS_ERROR_FAILED,
55fc26
+                                             "Device %s does not appear to be a LUKS device",
55fc26
+                                             udisks_block_get_device (block));
55fc26
+      goto out;
55fc26
+    }
55fc26
+
55fc26
+  error = NULL;
55fc26
+  if (!udisks_daemon_util_get_caller_uid_sync (daemon, invocation, NULL /* GCancellable */, &caller_uid, NULL, NULL, &error))
55fc26
+    {
55fc26
+      g_dbus_method_invocation_return_gerror (invocation, error);
55fc26
+      g_clear_error (&error);
55fc26
+      goto out;
55fc26
+    }
55fc26
+
55fc26
+  /* Fail if device is not unlocked */
55fc26
+  cleartext_object = udisks_daemon_wait_for_object_sync (daemon,
55fc26
+                                                         wait_for_cleartext_object,
55fc26
+                                                         g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (object))),
55fc26
+                                                         g_free,
55fc26
+                                                         0, /* timeout_seconds */
55fc26
+                                                         NULL); /* error */
55fc26
+  if (cleartext_object == NULL)
55fc26
+    {
55fc26
+      g_dbus_method_invocation_return_error (invocation,
55fc26
+                                             UDISKS_ERROR,
55fc26
+                                             UDISKS_ERROR_FAILED,
55fc26
+                                             "Device %s is not unlocked",
55fc26
+                                             udisks_block_get_device (block));
55fc26
+      goto out;
55fc26
+    }
55fc26
+  cleartext_block = udisks_object_peek_block (cleartext_object);
55fc26
+
55fc26
+  action_id = "org.freedesktop.udisks2.modify-device";
55fc26
+  /* Translators: Shown in authentication dialog when the user
55fc26
+   * requests resizing a encrypted block device.
55fc26
+   *
55fc26
+   * Do not translate $(drive), it's a placeholder and
55fc26
+   * will be replaced by the name of the drive/device in question
55fc26
+   */
55fc26
+  message = N_("Authentication is required to resize the encrypted device $(drive)");
55fc26
+  if (! udisks_daemon_util_setup_by_user (daemon, object, caller_uid))
55fc26
+    {
55fc26
+      if (udisks_block_get_hint_system (block))
55fc26
+        {
55fc26
+          action_id = "org.freedesktop.udisks2.modify-device-system";
55fc26
+        }
55fc26
+      else if (! udisks_daemon_util_on_user_seat (daemon, UDISKS_OBJECT (object), caller_uid))
55fc26
+        {
55fc26
+          action_id = "org.freedesktop.udisks2.modify-device-other-seat";
55fc26
+        }
55fc26
+    }
55fc26
+
55fc26
+  /* Check that the user is actually authorized to resize the device. */
55fc26
+  if (! udisks_daemon_util_check_authorization_sync (daemon,
55fc26
+                                                     object,
55fc26
+                                                     action_id,
55fc26
+                                                     options,
55fc26
+                                                     message,
55fc26
+                                                     invocation))
55fc26
+    goto out;
55fc26
+
55fc26
+  job = udisks_daemon_launch_simple_job (daemon,
55fc26
+                                         UDISKS_OBJECT (object),
55fc26
+                                         "encrypted-resize",
55fc26
+                                         caller_uid,
55fc26
+                                         NULL);
55fc26
+  if (job == NULL)
55fc26
+    {
55fc26
+      g_dbus_method_invocation_return_error (invocation, UDISKS_ERROR, UDISKS_ERROR_FAILED,
55fc26
+                                             "Failed to create a job object");
55fc26
+      goto out;
55fc26
+    }
55fc26
+
55fc26
+  /* TODO: implement progress parsing for udisks_job_set_progress(_valid) */
55fc26
+  if (! bd_crypto_luks_resize (udisks_block_get_device (cleartext_block), size / 512, &error))
55fc26
+    {
55fc26
+      g_dbus_method_invocation_return_error (invocation,
55fc26
+                                             UDISKS_ERROR,
55fc26
+                                             UDISKS_ERROR_FAILED,
55fc26
+                                             "Error resizing encrypted device %s: %s",
55fc26
+                                             udisks_block_get_device (cleartext_block),
55fc26
+                                             error->message);
55fc26
+      udisks_simple_job_complete (UDISKS_SIMPLE_JOB (job), FALSE, error->message);
55fc26
+      goto out;
55fc26
+    }
55fc26
+
55fc26
+  udisks_encrypted_complete_resize (encrypted, invocation);
55fc26
+  udisks_simple_job_complete (UDISKS_SIMPLE_JOB (job), TRUE, NULL);
55fc26
+
55fc26
+ out:
55fc26
+  g_clear_object (&cleartext_object);
55fc26
+  g_clear_object (&object);
55fc26
+  g_clear_error (&error);
55fc26
+  return TRUE; /* returning TRUE means that we handled the method invocation */
55fc26
+}
55fc26
+
55fc26
+/* ---------------------------------------------------------------------------------------------------- */
55fc26
+
55fc26
 static void
55fc26
 encrypted_iface_init (UDisksEncryptedIface *iface)
55fc26
 {
55fc26
   iface->handle_unlock              = handle_unlock;
55fc26
   iface->handle_lock                = handle_lock;
55fc26
   iface->handle_change_passphrase   = handle_change_passphrase;
55fc26
+  iface->handle_resize              = handle_resize;
55fc26
 }
55fc26
diff --git a/udisks/udisksclient.c b/udisks/udisksclient.c
55fc26
index 7bd5684..980c941 100644
55fc26
--- a/udisks/udisksclient.c
55fc26
+++ b/udisks/udisksclient.c
55fc26
@@ -2487,6 +2487,7 @@ udisks_client_get_job_description (UDisksClient   *client,
55fc26
       g_hash_table_insert (hash, (gpointer) "encrypted-unlock",     (gpointer) C_("job", "Unlocking Device"));
55fc26
       g_hash_table_insert (hash, (gpointer) "encrypted-lock",       (gpointer) C_("job", "Locking Device"));
55fc26
       g_hash_table_insert (hash, (gpointer) "encrypted-modify",     (gpointer) C_("job", "Modifying Encrypted Device"));
55fc26
+      g_hash_table_insert (hash, (gpointer) "encrypted-resize",     (gpointer) C_("job", "Resizing Encrypted Device"));
55fc26
       g_hash_table_insert (hash, (gpointer) "swapspace-start",      (gpointer) C_("job", "Starting Swap Device"));
55fc26
       g_hash_table_insert (hash, (gpointer) "swapspace-stop",       (gpointer) C_("job", "Stopping Swap Device"));
55fc26
       g_hash_table_insert (hash, (gpointer) "filesystem-check",     (gpointer) C_("job", "Checking Filesystem"));
55fc26
--
55fc26
1.8.3.1