LVM snapshots and exclude list #962
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 trying to do a backup:
pf:) and globs (sh:) in my/etc/borgmatic/exclude, which is properly declared in my configuration file.Steps to reproduce
N/A
Actual behavior
I have noticed that some paths are not excluded as they were before I use the new LVM snapshot function.
Expected behavior
Excluded paths should be excluded from the backup whether a snapshot is taken or not.
Other notes / implementation ideas
Borgmatic seem to pass the
/etc/borgmatic/excludefile to theborg createcommand line as is. This exclusion file contains declarations based on the "regular" filesystem, whereas the path under which the LVM snapshot is mounted (and from which the backup is created) is under/tmp/borgmatic-XXXXXXX/borgmatic/lvm-snapshots/....I suspect that the excluded paths are not enforced because they correspond to the path on the regular filesystem, whereas borg probably expect them to match the snapshot mount point.
A solution could be to use a temporary
excludefile, which would be dynamically generated: borgmatic could prefixing the snapshot mount point to the originalexcludefile. This might be a bit tricky, though.I also noticed that the backup target
/home/directory is.... missing since I used the lvm snapshot feature ! This/homeis a backup target, just like/etc,/rootand a few others. But only/home/is missing. I suspect it could be linked to an exclusion glob that do not behave as expected, or due to the fact it's on another partition.borgmatic version
1.9.4 (and 1.9.5)
borgmatic installation method
pipx
Borg version
borg 1.4.0
Python version
Python 3.13.1
Database version (if applicable)
No response
Operating system and version
NAME="Arch Linux" PRETTY_NAME="Arch Linux" ID=arch BUILD_ID=rolling ANSI_COLOR="38;2;23;147;209" HOME_URL="https://archlinux.org/" DOCUMENTATION_URL="https://wiki.archlinux.org/" SUPPORT_URL="https://bbs.archlinux.org/" BUG_REPORT_URL="https://gitlab.archlinux.org/groups/archlinux/-/issues" PRIVACY_POLICY_URL="https://terms.archlinux.org/docs/privacy-policy/" LOGO=archlinux-logo
I can't see any exclusion that would explain the fact that the content of
/homeis missing. However,/homeand the other backup targets are from different logical volume groups:It means, that two snapshots must be taken, one for
/home, the other for the root fs. If only the root fs is snapshotted, then/homeis only the snapshot of a mountpoint, consequently empty, when the backup is started.Hi, I'm observing the same behavior on my system, i.e. borgmatic decides to create only a snapshot of the root logical volume (mounted on '/'), although there's also a home logical volume (mounted on '/home').
Looking into the implementation of get_logical_volumes function shows that the logical volume discovery algorithm is not yet capable to detect such a setup where mount point of one logical volume is located "under" the mount point of another logical volume (i.e. '/' and '/home').
I didn't come up with better/proper implementation yet, but quick and dirty fix for me currently is to not mutate the set of candidated contained directories.My workaround now is to split one single backup into two (one for '/', another for '/home') each having a separate configuration and to set a custom lsblk command for lvm
/etc/borgmatic.d/system_backup_root.yaml
/etc/borgmatic.d/system_backup_home.yaml
/usr/local/bin/lsblk_root
/usr/local/bin/lsblk_home
@aurelg Thanks for taking the time to file this one!
For the exclude issue: Yes, this sounds like an unfortunate interaction between borgmatic's snapshot path rewrite trickery and the traditional exclude feature. I think you are right that borgmatic could in theory solve this by rewriting the exclude paths as well, and in fact there is already some exclude pre-processing in borgmatic where that could be added.
There is however the added complication of the Borg patterns feature, which supports exclude-like functionality inside the patterns themselves. So that would also probably need to be taken into consideration as part of any solution. I'm just not sure that the complexity of borgmatic pre-processing Borg patterns is worth it.
For the
homeissue: Huh, for some reason I was operating under the mistaken assumption that LVM volume mount points couldn't contain other LVM volume mount points. There's logic in some of the other filesystem hooks (ZFS, Btrfs) that might support that kind of nested volumes, so it probably needs to be brought over to the LVM hook to address this oversight.@emilsenan Thanks for weighing in as well—and filing a PR for a potential solution. I'll follow up on it there!
Initial work on a solution to the excludes issue at PR #964. Still a ways to go though.
Okay, the exclude issue is fixed now in main and will be part of the next release. The solution was to unify
source_directories,exclude_patterns,exclude_from,patterns, andpatterns_frominto a single list of patterns—internally within borgmatic. None of the configuration options were actually changed. This allows the LVM hook to rewrite snapshot paths found in all of those configuration options, including the excludes.The documentation for this should be live shortly.
The home / nested LVM mount issue is still to-do.
Thank you so much! I'm very looking forward to being able to test it!
The nested LVM mount issue is fixed in main and will be part of the next release! Thanks for your patience here.
And just released in borgmatic 1.9.6!
UPDATE: Ignore this comment, it only happens as a regression with 2.0.12 (fixed in 2.0.13) see #1195
Fails for me when I prefix all my exclude patterns with
pf:...,sh:..., etc., see borgmatic_fail.logupdate: actually I don't see the path updated with the snapshot mount point even when I remove the
fm:prefix from the entries 🤔 And my borgmatic is 2.0.12Update: But the issue might be deeper, because (as seen in the log) I have an exclude pattern
sh:**/.cacheand then I see all.cachedirectories backed up. Why might this be? A shell pattern starting with**/should surely not care about the mount path.UPDATE: Ignore this comment, it only happens as a regression with 2.0.12 (fixed in 2.0.13) see #1195
I see where the issue is and I think this issue has to be reopened. In my log file you can see:
The issue is that
+ /run/user/0/borgmatic/lvm_snapshots/f667480a34df1550a601/./homeactually applies to now all files within the backed-up directory (i.e. home). So further patterns are not evaluated.The exception is
pf:patterns that are documented to take precedence is all situations. Butfm:andsh:patterns are simply ignored.So a fix would be to remove the
+ source_dirpattern and only leave theR source_dirpattern.If this creates a problem for other combination of options, then an alternative approach is to put the
exclude-fromentries before the+ source_dirpattern.As a workaround, I'll try moving mysource_directoriesinto patterns to avoid this+ ...automatic inclusion.update: Actually this is not a viable workaround because theUpdate2: fixed with+ patternis still inserted at the top. It appears that when snapshot hook is used, then the new mount point is added withinject_patternand it adds the+pattern automatically.50a062611ein 2.0.13 😿I'm attaching a simple borg test script, which demonstrates this pattern order behavior. See
Test 4in it's stdout.UPDATE: this comment is still valid with 2.0.13, tl;dr; excludes should be added to patterns as
fm:matches when pattern prefix is missingWhile on it, another issue I notice is that borgmatic does not include a proper default
fm:pattern prefix when adding theexclude_fromentries to the patterns.fm:is the default prefix for excludes in Borg. But inpatternthe default type issh:. So when the excludes are without the type prefix, they are put into patterns also without prefix (as seen by the log I attached earlier). This is effectively changing the semantics of the patterns invisible to the user.In summary, when an exclude pattern lacks type prefix,
fm:has to be appended before treating it as a pattern.After some more investigation I see two remaining issues:
fm:pattern for excludes that I describe in my previous comment./, then appending the snapshot path fails.Example, if I have specified a pattern
pf:home/myuser/.local/share/baloo, then I see in borgmatic verbose log that it ends up! pf:home/myuser/.local/share/baloo.Here a valid workaround is to specify the pattern as
pf:/home/myuser/.local/share/baloo. According toman borgthe patterns should not start with a leading/but that leading slash is removed automatically so the workaround is viable. Still it will be correct for borgmatic to handle patterns without a leading slash because they seem to be the canonical format.So with
pf:/home/myuser/.local/share/baloo, that is properly later translated to! pf:/run/user/0/borgmatic/lvm_snapshots/f667480a34df1550a601/./home/myuser/.local/share/baloo.Actually current approach may fail with some regular expressions, because for the
re:pattern I don't see Borg removing leading slashes. I didn't test that though.Huh. I can't seem to repro this. When I put a path into
exclude_patterns, borgmatic outputs it with thefm:prefix:Even when I put a subdirectory of an LVM volume into
exclude_patterns, it gets anfm:prefix as well according to borgmatic's computed patterns.Can I see both your config and the verbose borgmatic output, specifically these computed patterns made with borgmatic 2.0.13?
Ah, this is a tricky one. If you don't include a leading slash, borgmatic can't determine whether you're specifying a relative path or an absolute path, and so it can't reliably perform rewrites.
Maybe this limitation just needs to be better documented? Or maybe borgmatic should go so far as to probe for the relative/absolute versions of the path and try to make a call accordingly? Perhaps erroring if both are found and it can't disambiguate?
Also, would you mind filing a new ticket or tickets for these issues? I'm worried that since this ticket is closed, these related issues will get lost.
Moved to #1226, thank you for looking into this!
Thank you for looking, I didn't retest this with 2.0.13, my bad, it is properly prefixing the unprefixed patterns
As far as I read and my testing goes, there are no relative paths in Borg. All paths are absolute and inmost pattern types, a leading
/is removed. So what would a "relative" path mean in this context and do relative paths have a special borgmatic meaning?Thanks for filing that. I'll follow up and answer your question there!