Skip to content

Commit 65eac48

Browse files
committed
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.
1 parent 7cadfa1 commit 65eac48

File tree

3 files changed

+24
-51
lines changed

3 files changed

+24
-51
lines changed

src/plugins/btrfs.c

Lines changed: 17 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818
*/
1919

2020
#include <glib.h>
21+
#include <stdio.h>
2122
#include <string.h>
2223
#include <unistd.h>
2324
#include <blockdev/utils.h>
2425
#include <bs_size.h>
26+
#include <btrfsutil.h>
2527

2628
#include "btrfs.h"
2729
#include "check_deps.h"
@@ -258,6 +260,10 @@ static BDBtrfsFilesystemInfo* get_filesystem_info_from_match (GMatchInfo *match_
258260
return ret;
259261
}
260262

263+
static const char* format_btrfs_error (enum btrfs_util_error err) {
264+
return g_strdup_printf ("%s: %m", btrfs_util_strerror (err));
265+
}
266+
261267
/**
262268
* bd_btrfs_create_volume:
263269
* @devices: (array zero-terminated=1): list of devices to create btrfs volume from
@@ -454,75 +460,37 @@ gboolean bd_btrfs_delete_subvolume (const gchar *mountpoint, const gchar *name,
454460
* Tech category: %BD_BTRFS_TECH_SUBVOL-%BD_BTRFS_TECH_MODE_QUERY
455461
*/
456462
guint64 bd_btrfs_get_default_subvolume_id (const gchar *mountpoint, GError **error) {
457-
GRegex *regex = NULL;
458-
GMatchInfo *match_info = NULL;
459-
gboolean success = FALSE;
460-
gchar *output = NULL;
461-
gchar *match = NULL;
463+
enum btrfs_util_error err;
462464
guint64 ret = 0;
463-
const gchar *argv[5] = {"btrfs", "subvol", "get-default", mountpoint, NULL};
464465

465-
if (!check_deps (&avail_deps, DEPS_BTRFS_MASK, deps, DEPS_LAST, &deps_check_lock, error) ||
466-
!check_module_deps (&avail_module_deps, MODULE_DEPS_BTRFS_MASK, module_deps, MODULE_DEPS_LAST, &deps_check_lock, error))
467-
return 0;
468-
469-
regex = g_regex_new ("ID (\\d+) .*", 0, 0, error);
470-
if (!regex) {
471-
bd_utils_log_format (BD_UTILS_LOG_WARNING, "Failed to create new GRegex");
472-
/* error is already populated */
473-
return 0;
466+
err = btrfs_util_get_default_subvolume (mountpoint, &ret);
467+
if (err) {
468+
g_set_error (error, BD_BTRFS_ERROR, BD_BTRFS_ERROR_NOT_FOUND, format_btrfs_error (err));
474469
}
475470

476-
success = bd_utils_exec_and_capture_output (argv, NULL, &output, error);
477-
if (!success) {
478-
g_regex_unref (regex);
479-
return 0;
480-
}
481-
482-
success = g_regex_match (regex, output, 0, &match_info);
483-
if (!success) {
484-
g_set_error (error, BD_BTRFS_ERROR, BD_BTRFS_ERROR_PARSE, "Failed to parse subvolume's ID");
485-
g_regex_unref (regex);
486-
g_match_info_free (match_info);
487-
g_free (output);
488-
return 0;
489-
}
490-
491-
match = g_match_info_fetch (match_info, 1);
492-
ret = g_ascii_strtoull (match, NULL, 0);
493-
494-
g_free (match);
495-
g_match_info_free (match_info);
496-
g_regex_unref (regex);
497-
g_free (output);
498-
499471
return ret;
500472
}
501473

502474
/**
503475
* bd_btrfs_set_default_subvolume:
504476
* @mountpoint: mountpoint of the volume to set the default subvolume ID of
505477
* @subvol_id: ID of the subvolume to be set as the default subvolume
506-
* @extra: (nullable) (array zero-terminated=1): extra options for the setting (right now
507-
* passed to the 'btrfs' utility)
508478
* @error: (out) (optional): place to store error (if any)
509479
*
510480
* Returns: whether the @mountpoint volume's default subvolume was correctly set
511481
* to @subvol_id or not
512482
*
513483
* Tech category: %BD_BTRFS_TECH_SUBVOL-%BD_BTRFS_TECH_MODE_MODIFY
514484
*/
515-
gboolean bd_btrfs_set_default_subvolume (const gchar *mountpoint, guint64 subvol_id, const BDExtraArg **extra, GError **error) {
516-
const gchar *argv[6] = {"btrfs", "subvol", "set-default", NULL, mountpoint, NULL};
485+
gboolean bd_btrfs_set_default_subvolume (const gchar *mountpoint, guint64 subvol_id, GError **error) {
486+
enum btrfs_util_error err;
517487
gboolean ret = FALSE;
518488

519-
if (!check_deps (&avail_deps, DEPS_BTRFS_MASK, deps, DEPS_LAST, &deps_check_lock, error) ||
520-
!check_module_deps (&avail_module_deps, MODULE_DEPS_BTRFS_MASK, module_deps, MODULE_DEPS_LAST, &deps_check_lock, error))
521-
return FALSE;
522-
523-
argv[3] = g_strdup_printf ("%"G_GUINT64_FORMAT, subvol_id);
524-
ret = bd_utils_exec_and_report_error (argv, extra, error);
525-
g_free ((gchar *) argv[3]);
489+
err = btrfs_util_set_default_subvolume (mountpoint, subvol_id);
490+
if (err)
491+
g_set_error (error, BD_BTRFS_ERROR, BD_BTRFS_ERROR_NOT_FOUND, format_btrfs_error (err));
492+
else
493+
ret = TRUE;
526494

527495
return ret;
528496
}

src/plugins/btrfs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ typedef enum {
1414
BD_BTRFS_ERROR_TECH_UNAVAIL,
1515
BD_BTRFS_ERROR_DEVICE,
1616
BD_BTRFS_ERROR_PARSE,
17+
BD_BTRFS_ERROR_NOT_FOUND,
1718
} BDBtrfsError;
1819

1920
typedef struct BDBtrfsDeviceInfo {
@@ -79,7 +80,7 @@ gboolean bd_btrfs_remove_device (const gchar *mountpoint, const gchar *device, c
7980
gboolean bd_btrfs_create_subvolume (const gchar *mountpoint, const gchar *name, const BDExtraArg **extra, GError **error);
8081
gboolean bd_btrfs_delete_subvolume (const gchar *mountpoint, const gchar *name, const BDExtraArg **extra, GError **error);
8182
guint64 bd_btrfs_get_default_subvolume_id (const gchar *mountpoint, GError **error);
82-
gboolean bd_btrfs_set_default_subvolume (const gchar *mountpoint, guint64 subvol_id, const BDExtraArg **extra, GError **error);
83+
gboolean bd_btrfs_set_default_subvolume (const gchar *mountpoint, guint64 subvol_id, GError **error);
8384
gboolean bd_btrfs_create_snapshot (const gchar *source, const gchar *dest, gboolean ro, const BDExtraArg **extra, GError **error);
8485
BDBtrfsDeviceInfo** bd_btrfs_list_devices (const gchar *device, GError **error);
8586
BDBtrfsSubvolumeInfo** bd_btrfs_list_subvolumes (const gchar *mountpoint, gboolean snapshots_only, GError **error);

tests/btrfs_test.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ def test_get_default_subvolume_id(self):
277277
self.assertTrue(succ)
278278

279279
# not mounted yet, should fail
280-
with self.assertRaisesRegex(GLib.GError, r".*(can't|cannot) access.*"):
280+
with self.assertRaisesRegex(GLib.GError, r".*Could not open: No such file or directory.*"):
281281
ret = BlockDev.btrfs_get_default_subvolume_id(TEST_MNT)
282282

283283
mount(self.loop_dev, TEST_MNT)
@@ -292,6 +292,10 @@ def test_set_default_subvolume(self):
292292
succ = BlockDev.btrfs_create_volume([self.loop_dev], "myShinyBtrfs", None, None, None)
293293
self.assertTrue(succ)
294294

295+
# not mounted yet, should fail
296+
with self.assertRaisesRegex(GLib.GError, r".*Could not open: No such file or directory.*"):
297+
ret = BlockDev.btrfs_get_default_subvolume_id(TEST_MNT)
298+
295299
mount(self.loop_dev, TEST_MNT)
296300

297301
ret = BlockDev.btrfs_get_default_subvolume_id(TEST_MNT)

0 commit comments

Comments
 (0)