diff --git a/src/plugins/btrfs.c b/src/plugins/btrfs.c index 809e3947..9f9aae30 100644 --- a/src/plugins/btrfs.c +++ b/src/plugins/btrfs.c @@ -18,10 +18,12 @@ */ #include +#include #include #include #include #include +#include #include "btrfs.h" #include "check_deps.h" @@ -258,6 +260,10 @@ static BDBtrfsFilesystemInfo* get_filesystem_info_from_match (GMatchInfo *match_ return ret; } +static const char* format_btrfs_error (enum btrfs_util_error err) { + return g_strdup_printf ("%s: %m", btrfs_util_strerror (err)); +} + /** * bd_btrfs_create_volume: * @devices: (array zero-terminated=1): list of devices to create btrfs volume from @@ -454,48 +460,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; + err = btrfs_util_get_default_subvolume (mountpoint, &ret); + if (err) { + g_set_error (error, BD_BTRFS_ERROR, BD_BTRFS_ERROR_NOT_FOUND, format_btrfs_error (err)); } - 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; - } - - 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; } @@ -503,8 +475,6 @@ guint64 bd_btrfs_get_default_subvolume_id (const gchar *mountpoint, GError **err * bd_btrfs_set_default_subvolume: * @mountpoint: mountpoint of the volume to set the default subvolume ID of * @subvol_id: ID of the subvolume to be set as the default subvolume - * @extra: (nullable) (array zero-terminated=1): extra options for the setting (right now - * passed to the 'btrfs' utility) * @error: (out) (optional): place to store error (if any) * * Returns: whether the @mountpoint volume's default subvolume was correctly set @@ -512,17 +482,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, 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, format_btrfs_error (err)); + else + ret = TRUE; return ret; } diff --git a/src/plugins/btrfs.h b/src/plugins/btrfs.h index b3d9ea99..3895913b 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, 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 16aa90d0..08036ce1 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)