neil / rpms / udisks2

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