Btrfs snapshots of raw subvolume fails #1043
Loading…
x
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What I'm trying to do and why
I am attempting to back up
/mnt/storage/@development
which is a subvolume of/mnt/storage
and is mounted to/home/pbrunner/dev
. (commands below).This is causing borgmatic to try to snapshot
/mnt/storage
with the commandbtrfs -v subvolume snapshot -r /mnt/storage /mnt/storage/.borgmatic-snapshot-28821/mnt/storage
which fails silently withERROR: Could not open: No such file or directory
because/mnt/storage
is not a subvolume.If I change the borgmatic config to backup
/home/pbrunner/dev
it works as expected. It seems to be due to findmnt is not returning the raw subvolume but only/mnt/storage
and/home/pbrunner/dev
.Steps to reproduce
With the following config:
/mnt/storage
is the root volume/mnt/storage/@development
is a subvolume, and/home/me/dev
is a mounted to the@development
subvolume.If run as is, it will not find any files but if I flip the comment (with no other changes to the config) and run it only on
/home/me/dev
it adds everything as expectedActual behavior
Expected behavior
Include all files found in /mnt/storage/@development
Other notes / implementation ideas
One potential solution would be to check if the source directory is itself a subvolume with
btrfs subvolume show /mnt/storage/@development
before searching up the tree to find a parent (sub)volume.borgmatic version
1.9.14
borgmatic installation method
apt
Borg version
borg 1.4.0
Python version
λ python3 --version Python 3.9.10
Database version (if applicable)
No response
Operating system and version
Debian GNU/Linux trixie/sid
This might just be a documentation issue. Or it might be me misunderstanding Btrfs. But the intent of the feature is that you list Btrfs subvolume mount points in
source_directories
. The idea is thatsource_directories
is a list of actual paths to backup, and if one of them just happens to be mounted from a Btrfs subvolume, then borgmatic will transparently take advantage of that fact and make/use a snapshot instead of the mounted source files.Anyway, let me know your thoughts on this. Was it just that you expected
/mnt/storage/@development
to work and were surprised when it didn't, or is there an argument for specifying the subvolume name rather than the mount point?Ah that would be me misunderstanding the documentation then. I was indeed expexting
/mnt/storage/@development
to work.There are two recommended/common patterns for subvolumes in btrfs, nested and flat (some mix them as well). You are describing the nested method where you mount your btrfs root to a point and create snapshots as needed in the tree. On the other hand I was describing the flat approach where you create subvolumes within the btrfs root and then mount those subvolumes to specific points.
The ability to specify the subvolume, instead of the mount, would support the flat layout and follow with that pattern. Not only do you not know all the places it is mounted without investigation, it would break the general idea of the subvolume at
/mnt/storage/@development
being the primary object.ref: https://archive.kernel.org/oldwiki/btrfs.wiki.kernel.org/index.php/SysadminGuide.html#Layout
I've updated the documentation to hopefully more accurately explain the current mount-point-oriented behavior.
Okay, so if I'm understanding what you're saying, it's possible to use the current borgmatic Btrfs hook with the flat layout, but it requires knowing/using a subvolume's mount point—which is not the primary object users think of when trying to snapshot their flat-layout subvolumes.
So let's say that the Btrfs hook adds support for specifying such unmounted subvolumes in
source_directories
. Then what's the extract story like? For instance, right now the idea is that you backup a Btrfs subvolume that's mounted at/home/pbrunner/dev
, it gets stored in the Borg archive at/home/pbrunner/dev
, and then you can easily find and extract it back to/home/pbrunner/dev
later on. But what's the expectation for that user experience if borgmatic is backing up in terms of an unmounted subvolume path like/mnt/storage/@development
and storing it as such in an archive? How would the user extract it?I'm also not sure how I feel about allowing "non-real" file paths in
source_directories
. I can kind of pretend it's okay when implicitly snapshotting a "real" directory with actual files in it. Maybe a list of subvolumes to backup would make more sense as a new option under thebtrfs:
config?A related thought: The existing borgmatic ZFS data source hook supports omitting ZFS datasets from
source_directories
but requesting that they be backed up by adding an application-specific borgmatic property to them, but I don't thinkbtrfs property set
supports application-specific keys. There might be a way to simulate that withsetfattr
though.I'm not 100% versed with ZFS so I'm not sure how much the following is the same.
In btrfs subvolumes are valid paths and actually contain real data (it's just a POSIX directory). I'd expect borgmatic it to store like it normally would a directory
/mnt/storage/@development
and to restore back to the same place. It's also 100% valid to create a subvolume and never mount it. Given that I'm not surebtrfs:
needs any extra config.IMO having the btrfs hook do a first pass of source_directories using
btrfs subvolume show <path>
(and checking forlevel 5
prior to runningfindmnt <path>
would solve this problem and be essentially transparent to users. Point borgmatic to a directory and it will snapshot it if possible or find a parent to snapshot.Got it, thanks for the explanation. Given that the unmounted Btrfs subvolumes have visible files in them, your proposal makes a lot more sense to me now. When I get a chance, I'll have to look into how feasible it would be to implement this, especially given the current mount point reliance in the existing Btrfs hook.