rustic icon indicating copy to clipboard operation
rustic copied to clipboard

Using `one-file-system = true` with a sources of `/` causes nothing to be found

Open ultimatespirit opened this issue 9 months ago • 2 comments

Seems I've hit a bit of an edge case. I appear to have narrowed it down to the one-file-system option, but it wouldn't surprise me if it has something to do with my excludes too.

Situation: I'm trying to backup my / root directory for a system files backup. I already have other backups for each mounted drive, so I want to use one-file-system so that I don't have to worry about potential leaks into backing up other drives, also virtual file systems. So I construct a Sys.toml as follows:

[repository]
repository = <path to external drive here>

[forget]
# elided

[backup]
exclude-if-present = ["CACHEDIR.TAG"]
one-file-system = true
git-ignore = false

[[backup.snapshots]]
sources = ["/"]
# Exclude system directories that shouldn't be backed up
# Some of these, like /proc or /sys are virtual file systems and therefore
# excluded via `one-file-system`, but we list them anyway
globs = [
    '!/proc',
    '!/sys',
    '!/tmp',
    '!/var/tmp',
    '!/var/cache',
    '!/dev',
    '!/mnt',
    '!/lost+found',
    '!/home/',
]

With a / directory structure as follows

$ ls -l | tail -n +2 | sed 's/\([^ ]\+ \+\)\{8\}//'
bin -> usr/bin
boot  # This is also a mount point
dev
etc
home
lib -> usr/lib
lib64 -> usr/lib
lost+found
mnt
opt
proc
root
run
sbin -> usr/bin
srv
sys
tmp
usr
var

Running rustic -P Sys --log-level debug -n backup as a non-root user leads then to:

$ rustic -P Sys --log-level debug -n backup
[INFO] using config # elided
# elided
[00:00:00] backing up...                  ████████████████████████████████████████        0 B            0 B/s           [DEBUG] (1) globset: built glob set; 9 literals, 0 basenames, 0 extensions, 0 prefixes, 0 suffixes, 0 required extensions, 0 regexes
[DEBUG] (1) ignore::gitignore: opened gitignore file: < global git ignore file >
# A whole lot of debug output about processing my global gitignore, despite explicitly disabling gitignore
[DEBUG] (29) ignore::walk: ignoring /dev: Ignore(IgnoreMatch(Override(Glob(Matched(Glob { from: None, original: "!/dev", actual: "dev", is_whitelist: true, is_only_dir: false })))))
[00:00:00] backing up...                  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░        0 B/7 B        0 B/s        (ETA -)[DEBUG] (41) ignore::walk: ignoring /dev: Ignore(IgnoreMatch(Override(Glob(Matched(Glob { from: None, original: "!/de[00:00:00] backing up...                  ████████████████████████████████████████        7 B/7 B        3.77 KiB/s   (ETA -)[DEBUG] (1) rustic_core::archiver::tree_archiver: unchanged file: "/bin"
[DEBUG] (1) rustic_core::archiver::tree_archiver: unchanged tree: "/boot"
[00:00:00] backing up...                  ████████████████████████████████████████        7 B/7 B        3.04 KiB/s   (ETA -)Files:       0 new, 0 changed, 1 unchanged
Dirs:        0 new, 0 changed, 2 unchanged
[DEBUG] (1) rustic_rs::commands::backup: Data Blobs:  0 new
[DEBUG] (1) rustic_rs::commands::backup: Tree Blobs:  0 new
Added to the repo: 0 B (raw: 0 B)
processed 1 files, 7 B
snapshot 00000000 successfully saved.
[INFO] backup of / done.

(This run was after running once before, so it already has the two files it can do)

So a backup just containing two empty files:

$ rustic -P Sys ls < hash >
...
[INFO] getting snapshot ...
bin
boot

Which is interesting in its own way since I saw there's an open bug about rustic not copying empty directories, and /boot is an empty directory here due to being another mount point.

Removing one-file-system immediately causes the command to do the expected thing, as does not listing /. So for now my solution is to explicitly list out every directory under / to attempt to backup. Note that sources = ['/', '/usr'] for example actually continues to be broken in this manner, so / needs to not be in the sources array.

ultimatespirit avatar Jan 09 '25 08:01 ultimatespirit