From 8ac2504387a688b63047c57ad163b4480384b31c Mon Sep 17 00:00:00 2001 From: Jelle van der Waa Date: Mon, 22 Jan 2024 14:05:56 +0100 Subject: [PATCH] btrfs: use libbtrfsutil for get/set default subvolume libbtrfsutil provides it's own error enum for libbtrfsutil functions and as we no longer parse output this introduces a BD_BTRFS_ERROR_NOT_FOUND error type. As the mount point not being found is the most likely failure scenario. --- src/plugins/btrfs.c | 59 +++++++++------------------------------------ src/plugins/btrfs.h | 3 ++- tests/btrfs_test.py | 6 ++++- 3 files changed, 19 insertions(+), 49 deletions(-) diff --git a/src/plugins/btrfs.c b/src/plugins/btrfs.c index 809e3947c..b813019c2 100644 --- a/src/plugins/btrfs.c +++ b/src/plugins/btrfs.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "btrfs.h" #include "check_deps.h" @@ -454,48 +455,14 @@ gboolean bd_btrfs_delete_subvolume (const gchar *mountpoint, const gchar *name, * Tech category: %BD_BTRFS_TECH_SUBVOL-%BD_BTRFS_TECH_MODE_QUERY */ guint64 bd_btrfs_get_default_subvolume_id (const gchar *mountpoint, GError **error) { - GRegex *regex = NULL; - GMatchInfo *match_info = NULL; - gboolean success = FALSE; - gchar *output = NULL; - gchar *match = NULL; + enum btrfs_util_error err; guint64 ret = 0; - const gchar *argv[5] = {"btrfs", "subvol", "get-default", mountpoint, NULL}; - - if (!check_deps (&avail_deps, DEPS_BTRFS_MASK, deps, DEPS_LAST, &deps_check_lock, error) || - !check_module_deps (&avail_module_deps, MODULE_DEPS_BTRFS_MASK, module_deps, MODULE_DEPS_LAST, &deps_check_lock, error)) - return 0; - - regex = g_regex_new ("ID (\\d+) .*", 0, 0, error); - if (!regex) { - bd_utils_log_format (BD_UTILS_LOG_WARNING, "Failed to create new GRegex"); - /* error is already populated */ - return 0; - } - - success = bd_utils_exec_and_capture_output (argv, NULL, &output, error); - if (!success) { - g_regex_unref (regex); - return 0; - } - success = g_regex_match (regex, output, 0, &match_info); - if (!success) { - g_set_error (error, BD_BTRFS_ERROR, BD_BTRFS_ERROR_PARSE, "Failed to parse subvolume's ID"); - g_regex_unref (regex); - g_match_info_free (match_info); - g_free (output); - return 0; + err = btrfs_util_get_default_subvolume (mountpoint, &ret); + if (err) { + g_set_error (error, BD_BTRFS_ERROR, BD_BTRFS_ERROR_NOT_FOUND, "%s: %m", btrfs_util_strerror (err)); } - match = g_match_info_fetch (match_info, 1); - ret = g_ascii_strtoull (match, NULL, 0); - - g_free (match); - g_match_info_free (match_info); - g_regex_unref (regex); - g_free (output); - return ret; } @@ -512,17 +479,15 @@ guint64 bd_btrfs_get_default_subvolume_id (const gchar *mountpoint, GError **err * * Tech category: %BD_BTRFS_TECH_SUBVOL-%BD_BTRFS_TECH_MODE_MODIFY */ -gboolean bd_btrfs_set_default_subvolume (const gchar *mountpoint, guint64 subvol_id, const BDExtraArg **extra, GError **error) { - const gchar *argv[6] = {"btrfs", "subvol", "set-default", NULL, mountpoint, NULL}; +gboolean bd_btrfs_set_default_subvolume (const gchar *mountpoint, guint64 subvol_id, G_GNUC_UNUSED const BDExtraArg **extra, GError **error) { + enum btrfs_util_error err; gboolean ret = FALSE; - if (!check_deps (&avail_deps, DEPS_BTRFS_MASK, deps, DEPS_LAST, &deps_check_lock, error) || - !check_module_deps (&avail_module_deps, MODULE_DEPS_BTRFS_MASK, module_deps, MODULE_DEPS_LAST, &deps_check_lock, error)) - return FALSE; - - argv[3] = g_strdup_printf ("%"G_GUINT64_FORMAT, subvol_id); - ret = bd_utils_exec_and_report_error (argv, extra, error); - g_free ((gchar *) argv[3]); + err = btrfs_util_set_default_subvolume (mountpoint, subvol_id); + if (err) + g_set_error (error, BD_BTRFS_ERROR, BD_BTRFS_ERROR_NOT_FOUND, "%s: %m", btrfs_util_strerror (err)); + else + ret = TRUE; return ret; } diff --git a/src/plugins/btrfs.h b/src/plugins/btrfs.h index b3d9ea99c..1f8c62b0f 100644 --- a/src/plugins/btrfs.h +++ b/src/plugins/btrfs.h @@ -14,6 +14,7 @@ typedef enum { BD_BTRFS_ERROR_TECH_UNAVAIL, BD_BTRFS_ERROR_DEVICE, BD_BTRFS_ERROR_PARSE, + BD_BTRFS_ERROR_NOT_FOUND, } BDBtrfsError; typedef struct BDBtrfsDeviceInfo { @@ -79,7 +80,7 @@ gboolean bd_btrfs_remove_device (const gchar *mountpoint, const gchar *device, c gboolean bd_btrfs_create_subvolume (const gchar *mountpoint, const gchar *name, const BDExtraArg **extra, GError **error); gboolean bd_btrfs_delete_subvolume (const gchar *mountpoint, const gchar *name, const BDExtraArg **extra, GError **error); guint64 bd_btrfs_get_default_subvolume_id (const gchar *mountpoint, GError **error); -gboolean bd_btrfs_set_default_subvolume (const gchar *mountpoint, guint64 subvol_id, const BDExtraArg **extra, GError **error); +gboolean bd_btrfs_set_default_subvolume (const gchar *mountpoint, guint64 subvol_id, G_GNUC_UNUSED const BDExtraArg **extra, GError **error); gboolean bd_btrfs_create_snapshot (const gchar *source, const gchar *dest, gboolean ro, const BDExtraArg **extra, GError **error); BDBtrfsDeviceInfo** bd_btrfs_list_devices (const gchar *device, GError **error); BDBtrfsSubvolumeInfo** bd_btrfs_list_subvolumes (const gchar *mountpoint, gboolean snapshots_only, GError **error); diff --git a/tests/btrfs_test.py b/tests/btrfs_test.py index 16aa90d0d..08036ce13 100644 --- a/tests/btrfs_test.py +++ b/tests/btrfs_test.py @@ -277,7 +277,7 @@ def test_get_default_subvolume_id(self): self.assertTrue(succ) # not mounted yet, should fail - with self.assertRaisesRegex(GLib.GError, r".*(can't|cannot) access.*"): + with self.assertRaisesRegex(GLib.GError, r".*Could not open: No such file or directory.*"): ret = BlockDev.btrfs_get_default_subvolume_id(TEST_MNT) mount(self.loop_dev, TEST_MNT) @@ -292,6 +292,10 @@ def test_set_default_subvolume(self): succ = BlockDev.btrfs_create_volume([self.loop_dev], "myShinyBtrfs", None, None, None) self.assertTrue(succ) + # not mounted yet, should fail + with self.assertRaisesRegex(GLib.GError, r".*Could not open: No such file or directory.*"): + ret = BlockDev.btrfs_get_default_subvolume_id(TEST_MNT) + mount(self.loop_dev, TEST_MNT) ret = BlockDev.btrfs_get_default_subvolume_id(TEST_MNT)