From 33d2271cd62a634bbd6f31d797e0d2347284ec44 Mon Sep 17 00:00:00 2001 From: Jelle van der Waa Date: Wed, 22 Nov 2023 19:24:17 +0100 Subject: [PATCH] modules/btrfs: add SetDefaultSubvolumeID libblockdev provides a method to set the default subvolume id since 2014. This method does requires administrative privileges as it changes the default mount target subvolume of a btrfs volume. --- .../data/org.freedesktop.UDisks2.btrfs.xml | 15 +++++ modules/btrfs/udiskslinuxfilesystembtrfs.c | 56 +++++++++++++++++++ src/tests/dbus-tests/test_btrfs.py | 9 ++- 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/modules/btrfs/data/org.freedesktop.UDisks2.btrfs.xml b/modules/btrfs/data/org.freedesktop.UDisks2.btrfs.xml index 385886863..7e03c7ce9 100644 --- a/modules/btrfs/data/org.freedesktop.UDisks2.btrfs.xml +++ b/modules/btrfs/data/org.freedesktop.UDisks2.btrfs.xml @@ -233,6 +233,21 @@ + + + + + + diff --git a/modules/btrfs/udiskslinuxfilesystembtrfs.c b/modules/btrfs/udiskslinuxfilesystembtrfs.c index 82e404f55..7a7e354b9 100644 --- a/modules/btrfs/udiskslinuxfilesystembtrfs.c +++ b/modules/btrfs/udiskslinuxfilesystembtrfs.c @@ -705,6 +705,61 @@ handle_get_default_subvolume_id (UDisksFilesystemBTRFS *fs_btrfs, return TRUE; } +static gboolean +handle_set_default_subvolume_id (UDisksFilesystemBTRFS *fs_btrfs, + GDBusMethodInvocation *invocation, + guint arg_id, + GVariant *arg_options) +{ + UDisksLinuxFilesystemBTRFS *l_fs_btrfs = UDISKS_LINUX_FILESYSTEM_BTRFS (fs_btrfs); + UDisksLinuxBlockObject *object = NULL; + GError *error = NULL; + UDisksDaemon *daemon; + gchar *mount_point = NULL; + + object = udisks_daemon_util_dup_object (l_fs_btrfs, &error); + if (! object) + { + g_dbus_method_invocation_take_error (invocation, error); + goto out; + } + + daemon = udisks_module_get_daemon (UDISKS_MODULE (l_fs_btrfs->module)); + + /* Policy check. */ + UDISKS_DAEMON_CHECK_AUTHORIZATION (daemon, + UDISKS_OBJECT (object), + BTRFS_POLICY_ACTION_ID, + arg_options, + N_("Authentication is required to set the default BTRFS subvolume"), + invocation); + + /* Get the mount point for this volume. */ + mount_point = udisks_filesystem_btrfs_get_first_mount_point (fs_btrfs, &error); + if (! mount_point) + { + g_dbus_method_invocation_take_error (invocation, error); + goto out; + } + + if (! bd_btrfs_set_default_subvolume (mount_point, arg_id, NULL, &error)) + { + g_dbus_method_invocation_take_error (invocation, error); + goto out; + } + + /* Complete DBus call. */ + udisks_filesystem_btrfs_complete_set_default_subvolume_id (fs_btrfs, invocation); + +out: + /* Release the resources */ + g_clear_object (&object); + g_free (mount_point); + + /* Indicate that we handled the method invocation */ + return TRUE; +} + static gboolean handle_create_snapshot (UDisksFilesystemBTRFS *fs_btrfs, GDBusMethodInvocation *invocation, @@ -895,6 +950,7 @@ udisks_linux_filesystem_btrfs_iface_init (UDisksFilesystemBTRFSIface *iface) iface->handle_remove_subvolume = handle_remove_subvolume; iface->handle_get_subvolumes = handle_get_subvolumes; iface->handle_get_default_subvolume_id = handle_get_default_subvolume_id; + iface->handle_set_default_subvolume_id = handle_set_default_subvolume_id; iface->handle_create_snapshot = handle_create_snapshot; iface->handle_repair = handle_repair; iface->handle_resize = handle_resize; diff --git a/src/tests/dbus-tests/test_btrfs.py b/src/tests/dbus-tests/test_btrfs.py index 5e179c82f..be781ef06 100644 --- a/src/tests/dbus-tests/test_btrfs.py +++ b/src/tests/dbus-tests/test_btrfs.py @@ -382,7 +382,7 @@ def test_subvolume_mount(self): dbus_mnt = self.ay_to_str(dbus_mounts.value[0]) # mountpoints are arrays of bytes self.assertEqual(dbus_mnt, mnt_path) - def test_get_default_subvolume_id(self): + def test_default_subvolume_id(self): dev = self._get_devices(1)[0] self.addCleanup(self._clean_format, dev.obj) @@ -399,3 +399,10 @@ def test_get_default_subvolume_id(self): default_id = dev.obj.GetDefaultSubvolumeID(self.no_options, dbus_interface=self.iface_prefix + '.Filesystem.BTRFS') self.assertEqual(default_id, 5) + + dev.obj.SetDefaultSubvolumeID(dbus.UInt32(5), self.no_options, + dbus_interface=self.iface_prefix + '.Filesystem.BTRFS') + + default_id = dev.obj.GetDefaultSubvolumeID(self.no_options, + dbus_interface=self.iface_prefix + '.Filesystem.BTRFS') + self.assertEqual(default_id, 5)