Btrfs snapshots of raw subvolume fails #1043
Reference in New Issue
Block a user
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/@developmentwhich is a subvolume of/mnt/storageand is mounted to/home/pbrunner/dev. (commands below).This is causing borgmatic to try to snapshot
/mnt/storagewith the commandbtrfs -v subvolume snapshot -r /mnt/storage /mnt/storage/.borgmatic-snapshot-28821/mnt/storagewhich fails silently withERROR: Could not open: No such file or directorybecause/mnt/storageis not a subvolume.If I change the borgmatic config to backup
/home/pbrunner/devit works as expected. It seems to be due to findmnt is not returning the raw subvolume but only/mnt/storageand/home/pbrunner/dev.Steps to reproduce
With the following config:
/mnt/storageis the root volume/mnt/storage/@developmentis a subvolume, and/home/me/devis a mounted to the@developmentsubvolume.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/devit 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/@developmentbefore 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_directoriesis 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/@developmentto 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/@developmentto 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/@developmentbeing 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/devlater 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/@developmentand 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_directoriesbut requesting that they be backed up by adding an application-specific borgmatic property to them, but I don't thinkbtrfs property setsupports application-specific keys. There might be a way to simulate that withsetfattrthough.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/@developmentand 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 5prior 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.
Thanks!
For those who come after,
A short term hack I used was to use
findmnt_commandto override findmnt to a bash script that outputs the correct info and it works as expected.FYI I have a proposed WIP implementation of this here: #1113
This is implemented in main and will be part of the next release. The approach I used is to start with
findmntas a way to get a global list of Btrfs mount points (each of which is either a Btrfs subvolume path or a separate mount point), and then callbtrfs subvolume liston each one to discover all the actual Btrfs subvolume paths.As per your use case, that should allow you to include
/mnt/storage/@developmentinsource_directoriessuch that it gets snapshotted and backed up, even if it's mounted elsewhere. And if you find out that that's not the case, please let me know.Released in borgmatic 2.0.7! Feedback welcome.