Skip to content
This repository was archived by the owner on Jun 15, 2025. It is now read-only.

Commit d75a9b1

Browse files
committed
Adhere to new root find behavior
Between versions 4.6.1 and 4.10.2 the output emitted in case 'btrfs subvolume show' is executed on the root volume changed again. We no longer see a special string but the normal subvolume output. An additional complication is that sometimes this output contains the special name '<FS_TREE>' and sometimes it does not. All that causes our find-root-directory algorithm to no longer work. This change adjusts the program to correctly handle this new behavior. It does so by using the 'btrfs filesystem show' command instead of the subvolume related counterpart. Note that we also drop compatibility with btrfs-progs versions earlier than 3.17.3 which exhibited yet another output.
1 parent 680e4cb commit d75a9b1

File tree

2 files changed

+17
-21
lines changed

2 files changed

+17
-21
lines changed

btrfs-backup/src/deso/btrfs/command.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# command.py
22

33
#/***************************************************************************
4-
# * Copyright (C) 2015 Daniel Mueller (deso@posteo.net) *
4+
# * Copyright (C) 2015,2017 Daniel Mueller (deso@posteo.net) *
55
# * *
66
# * This program is free software: you can redistribute it and/or modify *
77
# * it under the terms of the GNU General Public License as published by *
@@ -123,3 +123,8 @@ def diff(subvolume, generation):
123123
previous generation ID, determines the files that have been changed.
124124
"""
125125
return [_BTRFS, "subvolume", "find-new", subvolume, generation]
126+
127+
128+
def showFilesystem(filesystem):
129+
"""Retrieve the command to show information about a btrfs file system."""
130+
return [_BTRFS, "filesystem", "show", filesystem]

btrfs-backup/src/deso/btrfs/repository.py

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# repository.py
22

33
#/***************************************************************************
4-
# * Copyright (C) 2015-2016 Daniel Mueller (deso@posteo.net) *
4+
# * Copyright (C) 2015-2017 Daniel Mueller (deso@posteo.net) *
55
# * *
66
# * This program is free software: you can redistribute it and/or modify *
77
# * it under the terms of the GNU General Public License as published by *
@@ -39,6 +39,7 @@
3939
deserialize,
4040
diff,
4141
show,
42+
showFilesystem,
4243
serialize,
4344
snapshot as mkSnapshot,
4445
snapshots as listSnapshots,
@@ -94,13 +95,9 @@
9495
# ID A gen B top level C path PATH
9596
_LIST_STRING = r"^ID {nums} gen ({nums}) top level {nums} path ({path})$"
9697
_LIST_REGEX = regex(_LIST_STRING.format(nums=_NUMS_STRING, path=_PATH_STRING))
97-
# The first line in the output generated by executing the command
98-
# returned by the show() should contain the subvolume path if the
99-
# given directory is a subvolume. However, if it is the root of the
100-
# btrfs file system then it will end in 'is btrfs root'. We need to
101-
# detect this case to determine the btrfs root.
102-
_SHOW_IS_ROOT = "is toplevel subvolume"
103-
_SHOW_SUBVOL_NAME_REGEX = regex(r"\s*Name:\s*(.*)")
98+
_SHOW_SUBVOL_NAME = r"\s*Name:\s*(%s)"
99+
_SHOW_SUBVOL_NAME_REGEX = regex(_SHOW_SUBVOL_NAME % ".*")
100+
_SHOW_SUBVOL_ROOT_REGEX = regex(_SHOW_SUBVOL_NAME % "<FS_TREE>")
104101
# The marker ending the file list reported by the diff() function. If
105102
# this marker is the only thing reported then no files have changed.
106103
_DIFF_END_MARKER = "transid marker"
@@ -238,18 +235,10 @@ def _doShow(directory, repository):
238235
def _isRoot(directory, repository):
239236
"""Check if a given directory represents the root of a btrfs file system."""
240237
try:
241-
output = _doShow(directory, repository)
242-
243-
# The output of show() contains multiple lines in case the given
244-
# directory is a subvolume. In case it is an ordinary directory the
245-
# output is a single line and begins with "ERROR:" (but the command
246-
# actually succeeds), and in case of the root directory it will be
247-
# matched here.
248-
return len(output) == 1 and output[0].endswith(_SHOW_IS_ROOT)
238+
cmd = repository.command(showFilesystem, directory)
239+
execute(*cmd, stdout=b"", stderr=repository.stderr)
240+
return True
249241
except ProcessError:
250-
# Starting with btrfs-progs-3.17.3 the show command will return an
251-
# error code in case the supplied directory is not a btrfs
252-
# subvolume which will manifest as an exception here.
253242
return False
254243

255244

@@ -264,7 +253,9 @@ def _isSubvolume(directory, repository):
264253
for line in output:
265254
# We are looking for a line containing the subvolume's name.
266255
m = _SHOW_SUBVOL_NAME_REGEX.match(line)
267-
if m is not None:
256+
# In case of the root we need special treatment. It must not be
257+
# reported as a normal subvolume.
258+
if m is not None and not _isRoot(directory, repository):
268259
name, = m.groups()
269260
return True, name
270261

0 commit comments

Comments
 (0)