Skip to content

Commit

Permalink
Merge pull request #1006 from jelly/btrfs-list-all
Browse files Browse the repository at this point in the history
btrfs: make btrfs subvolume listing consistent
  • Loading branch information
vojtechtrefny authored Mar 13, 2024
2 parents d82706c + 397ee84 commit ed47e6c
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 7 deletions.
10 changes: 5 additions & 5 deletions src/plugins/btrfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -643,15 +643,15 @@ BDBtrfsDeviceInfo** bd_btrfs_list_devices (const gchar *device, GError **error)
* Tech category: %BD_BTRFS_TECH_SUBVOL-%BD_BTRFS_TECH_MODE_QUERY
*/
BDBtrfsSubvolumeInfo** bd_btrfs_list_subvolumes (const gchar *mountpoint, gboolean snapshots_only, GError **error) {
const gchar *argv[7] = {"btrfs", "subvol", "list", "-p", NULL, NULL, NULL};
const gchar *argv[8] = {"btrfs", "subvol", "list", "-a", "-p", NULL, NULL, NULL};
gchar *output = NULL;
gboolean success = FALSE;
gchar **lines = NULL;
gchar **line_p = NULL;
gchar const * const pattern = "ID\\s+(?P<id>\\d+)\\s+gen\\s+\\d+\\s+(cgen\\s+\\d+\\s+)?" \
"parent\\s+(?P<parent_id>\\d+)\\s+top\\s+level\\s+\\d+\\s+" \
"(otime\\s+(\\d{4}-\\d{2}-\\d{2}\\s+\\d\\d:\\d\\d:\\d\\d|-)\\s+)?"\
"path\\s+(?P<path>\\S+)";
"path\\s+(<FS_TREE>/)?(?P<path>\\S+)";
GRegex *regex = NULL;
GMatchInfo *match_info = NULL;
guint64 i = 0;
Expand All @@ -668,10 +668,10 @@ BDBtrfsSubvolumeInfo** bd_btrfs_list_subvolumes (const gchar *mountpoint, gboole
return NULL;

if (snapshots_only) {
argv[4] = "-s";
argv[5] = mountpoint;
argv[5] = "-s";
argv[6] = mountpoint;
} else
argv[4] = mountpoint;
argv[5] = mountpoint;

regex = g_regex_new (pattern, G_REGEX_EXTENDED, 0, error);
if (!regex) {
Expand Down
36 changes: 34 additions & 2 deletions tests/btrfs_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,13 +347,45 @@ def test_list_subvolumes(self):
succ = BlockDev.btrfs_create_subvolume(TEST_MNT, "subvol1", None)
self.assertTrue(succ)

succ = BlockDev.btrfs_create_subvolume(TEST_MNT, "subvol1/bar", None)
self.assertTrue(succ)

subvols = BlockDev.btrfs_list_subvolumes(TEST_MNT, False)
self.assertEqual(len(subvols), 1)
self.assertEqual(len(subvols), 2)
self.assertEqual(subvols[0].parent_id, 5)
self.assertEqual(subvols[0].path, "subvol1")
self.assertEqual(subvols[1].path, "subvol1/bar")

class BtrfsTestFilesystemInfo(BtrfsTestCase):
@tag_test(TestTags.CORE)
def test_list_subvolumes_different_mount(self):
"""Verify that it is possible get to info about subvolumes with subvol= mount option"""

succ = BlockDev.btrfs_create_volume([self.loop_dev], "myShinyBtrfs", None, None, None)
self.assertTrue(succ)

mount(self.loop_dev, TEST_MNT)

succ = BlockDev.btrfs_create_subvolume(TEST_MNT, "one", None)
self.assertTrue(succ)
succ = BlockDev.btrfs_create_subvolume(TEST_MNT, "one/two", None)
self.assertTrue(succ)

os.system("mkdir -p mkdir -p %s/one/two/one/two" % (TEST_MNT))

succ = BlockDev.btrfs_create_subvolume(TEST_MNT, "one/two/one/two/three", None)
self.assertTrue(succ)

umount(TEST_MNT)
os.makedirs(TEST_MNT)
os.system("mount -o subvol=%s %s %s" % ("one/two", self.loop_dev, TEST_MNT))

subvols = BlockDev.btrfs_list_subvolumes(TEST_MNT, False)
self.assertEqual(len(subvols), 3)
self.assertEqual(subvols[0].path, "one")
self.assertEqual(subvols[1].path, "one/two")
self.assertEqual(subvols[2].path, "one/two/one/two/three")

class BtrfsTestFilesystemInfo(BtrfsTestCase):
def test_filesystem_info(self):
"""Verify that it is possible to get filesystem info"""

Expand Down

0 comments on commit ed47e6c

Please sign in to comment.