Btrfs snapshot does not work when snapshotting subvol at / #959

Closed
opened 2024-12-28 14:43:12 +00:00 by 1over137 · 3 comments

What I'm trying to do and why

I would like to use the newly added btrfs snapshot feature. In 1.9.4 a bug in parsing findmnt output prevented it from working. In 1.9.5, another bug seems to be preventing it from working.

Steps to reproduce

My setup is a flat btrfs layout with these subvolumes:

  • @ (mount to /)
  • @home (mount to /home)
  • @var_log (mount to /var/log)

and a few others for data

/home, /etc/, and /var/log are backed up. btrfs: is added to the config with no extra settings.

Actual behavior

It appears that a directory has been created on the filesystem that's stopping the snapshot from being made.

Log leading up to the failure:

ssh://hetzner/./gentoo: Snapshotting Btrfs subvolumes
findmnt -t btrfs --json --list
btrfs subvolume list /
btrfs subvolume list /.snapshots
btrfs subvolume list /home
btrfs subvolume list /root
btrfs subvolume list /var/log
ssh://hetzner/./gentoo: Creating Btrfs snapshot for / subvolume
btrfs subvolume snapshot -r / /.borgmatic-snapshot-60000/
ERROR: Could not create subvolume: File exists
hetzner: Error running actions for repository
Command 'btrfs subvolume snapshot -r / /.borgmatic-snapshot-60000/' returned non-zero exit status 1.

Expected behavior

Snapshot should be created and backup should run

Other notes / implementation ideas

Below is my guess as to what's wrong.

Digging into the code, I see the following line in the source that seems to be causing this:

os.makedirs(os.path.dirname(snapshot_path), mode=0o700, exist_ok=True)

The snapshot path comes from this function:

def make_snapshot_path(subvolume_path): # pragma: no cover

When the path in question is "/", this probably produces an unintended result: the snapshot path would be /.borgmatic-snapshot-60000/ as indicated in the log. (with trailing slash). However, when os.dirname is called on a path with a trailing slash, it returns the entire path before the trailing slash (/.borgmatic-snapshot-60000). This results in that directory being created, and the snapshot command failing.

borgmatic version

1.9.5

borgmatic installation method

Arch official repo

Borg version

1.4.0

Python version

3.13

Database version (if applicable)

No response

Operating system and version

Arch Linux

### What I'm trying to do and why I would like to use the newly added btrfs snapshot feature. In 1.9.4 a bug in parsing findmnt output prevented it from working. In 1.9.5, another bug seems to be preventing it from working. ### Steps to reproduce My setup is a flat btrfs layout with these subvolumes: - @ (mount to /) - @home (mount to /home) - @var_log (mount to /var/log) and a few others for data /home, /etc/, and /var/log are backed up. `btrfs:` is added to the config with no extra settings. ### Actual behavior It appears that a directory has been created on the filesystem that's stopping the snapshot from being made. Log leading up to the failure: ``` ssh://hetzner/./gentoo: Snapshotting Btrfs subvolumes findmnt -t btrfs --json --list btrfs subvolume list / btrfs subvolume list /.snapshots btrfs subvolume list /home btrfs subvolume list /root btrfs subvolume list /var/log ssh://hetzner/./gentoo: Creating Btrfs snapshot for / subvolume btrfs subvolume snapshot -r / /.borgmatic-snapshot-60000/ ERROR: Could not create subvolume: File exists hetzner: Error running actions for repository Command 'btrfs subvolume snapshot -r / /.borgmatic-snapshot-60000/' returned non-zero exit status 1. ``` ### Expected behavior Snapshot should be created and backup should run ### Other notes / implementation ideas Below is my guess as to what's wrong. Digging into the code, I see the following line in the source that seems to be causing this: https://projects.torsion.org/borgmatic-collective/borgmatic/src/commit/87e77ff2b703d40f03bc5f2fdc9a17975e1f3b5f/borgmatic/hooks/data_source/btrfs.py#L177 The snapshot path comes from this function: https://projects.torsion.org/borgmatic-collective/borgmatic/src/commit/87e77ff2b703d40f03bc5f2fdc9a17975e1f3b5f/borgmatic/hooks/data_source/btrfs.py#L118 When the path in question is "/", this probably produces an unintended result: the snapshot path would be `/.borgmatic-snapshot-60000/` as indicated in the log. (**with trailing slash**). However, when os.dirname is called on a path with a trailing slash, it returns the entire path before the trailing slash (/.borgmatic-snapshot-60000). This results in that directory being created, and the snapshot command failing. ### borgmatic version 1.9.5 ### borgmatic installation method Arch official repo ### Borg version 1.4.0 ### Python version 3.13 ### Database version (if applicable) _No response_ ### Operating system and version Arch Linux
witten added the
bug
label 2024-12-28 17:10:15 +00:00
Owner

Excellent detective work! I appreciate you filing this and diagnosing the problem as well. I don't have a system with a Btrfs root, which is probably why this use case went undetected during testing. I'll look into the code and see if stripping that trailing slash will serve as a fix. I may need to rely on you for actually testing it though...

Excellent detective work! I appreciate you filing this and diagnosing the problem as well. I don't have a system with a Btrfs root, which is probably why this use case went undetected during testing. I'll look into the code and see if stripping that trailing slash will serve as a fix. I may need to rely on you for actually testing it though...
Owner

I believe this is fixed now in main, but I don't have an easy way to test it locally. If you do though, I would appreciate it! The only file changed (besides tests and project metadata) is btrfs.py.

I believe this is fixed now in main, but I don't have an easy way to test it locally. If you do though, I would appreciate it! The only file changed (besides tests and project metadata) is [`btrfs.py`](https://projects.torsion.org/borgmatic-collective/borgmatic/raw/commit/d3409df84c7cbaab5430f7261f4fd78f306acdb6/borgmatic/hooks/data_source/btrfs.py).
Owner

Released in borgmatic 1.9.6!

Released in borgmatic 1.9.6!
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: borgmatic-collective/borgmatic#959
No description provided.