Compare commits

...

954 Commits

Author SHA1 Message Date
Axel Burri ba3c36c984 btrbk: fix duplicate cmdline option -l in lsbtr 2025-07-06 01:09:14 +02:00
Axel Burri c69f70e1d0 btrbk: fix loglevel along with verbose 2025-07-06 00:56:29 +02:00
Axel Burri 18ddc65979 documentation: fix stream_compress_adapt 2023-08-28 19:14:35 +02:00
Axel Burri 225f60f565 btrbk: remove handling of deprecated options before v0.23
After 7 years and a lot of warnings we can drop this code. Note that
most of those refer to `upgrade_to_v0.23.0.md`, which was removed in
16364e2.
2023-08-28 18:55:47 +02:00
Axel Burri f7e1265e7a documentation: remove upgrade_to_v0.23.0.md from Makefile
Forgotten after removal in:

   16364e2833 documentation: remove obsolete upgrade_to_v0.23.0.md
2023-08-28 18:42:42 +02:00
Axel Burri a4d4dff0d1 btrbk_restore_raw.py: fix spelling 2023-08-05 20:56:39 +02:00
Axel Burri d819f17e44 kdf_pbkdf2.py: fix spelling 2023-08-05 20:56:39 +02:00
Axel Burri 1807ad5cee btrbk-mail: fix spelling 2023-08-05 20:56:39 +02:00
Axel Burri b139875e2b btrbk: fix spelling 2023-08-05 20:56:39 +02:00
Axel Burri f6bdab143b documentation: fix spelling 2023-08-05 20:56:39 +02:00
Axel Burri 16364e2833 documentation: remove obsolete upgrade_to_v0.23.0.md 2023-08-05 20:56:34 +02:00
Axel Burri efa4d13111 ChangeLog: fix spelling 2023-08-05 20:56:34 +02:00
Yaroslav Halchenko dac6350b5d github: actions: add codespell master on push and PRs 2023-08-05 20:28:41 +02:00
oldherl a488096869 doc: README.md: fix typo 2023-07-14 19:40:18 +02:00
Sam James 9dfee7bc32 doc: allow asciidoc again
This effectively reverts 0e63843195 and
173319e7e1.

asciidoc has been revived (for a while now) and doesn't require Python 2. We
still prefer asciidoctor and fallback to asciidoc/a2x if it's not available.

Comparing the asciidoc and asciidoctor man pages, everything looks OK.

Python tends to be available more readily in distribution build environments
rather than the Ruby stack. Also, the pregenerated man pages are gone as of
f132c94c65.

Signed-off-by: Sam James <sam@gentoo.org>
2023-07-14 18:55:05 +02:00
Axel Burri db45f0b09c btrbk-mail: add example to enable all rsync 2023-07-07 01:53:15 +02:00
Axel Burri fa704c3185 btrbk-mail: add missing declare 2023-07-07 01:45:32 +02:00
Axel Burri b63609c298 btrbk-mail: declare associative arrays 2023-06-08 00:27:16 +02:00
Axel Burri 98580418e3 btrbk: fix displaying excluded in summary
- fix framework
 - print source excluded by archive_exclude in summary
 - fix exclude list in summary
2023-04-22 16:53:13 +02:00
Axel Burri 135edabc71 btrbk: rephrase warnings on unexpected (foreign) location 2023-04-22 16:51:32 +02:00
Axel Burri 4ba944e6a5 btrbk: fix exit status for action usage 2023-04-22 16:51:32 +02:00
Axel Burri dd7149b111 btrbk: improve error message 2023-04-22 16:51:32 +02:00
Axel Burri ed33db523c btrbk: add reason text to filter statements 2023-04-22 16:51:32 +02:00
Axel Burri 15a6b98a08 btrbk: print "create" action in schedule 2023-04-22 16:51:32 +02:00
Axel Burri eff9af34bc btrbk: fix print schedule if deletion is skipped
If deletion is skipped, we don't have a schedule call on the target,
which is used for --print-schedule text. Add some (rather hacky) code
to be able to also use the schedule result of the backup process.
2023-04-22 16:51:32 +02:00
Axel Burri 468ca1eae5 btrbk: tidy logging
Especially corrects $svol->{PRINT} where not applicable.
2023-04-22 16:51:32 +02:00
Axel Burri cca200707d btrbk: set subvolume url to /dev/null on archive
This should not be printed anywhere. If it is, it's a bug.
2023-04-22 16:51:32 +02:00
Axel Burri d4ab986245 btrbk: skip subvolume init on archive 2023-04-22 16:51:32 +02:00
Axel Burri 6f1145c279 btrbk: add archive related summary
Note that "no target action" for archive is replaced by "<no_action>",
for consistency with action run:

   [-] /path/to/target/snapshot_basename.*

is now displayed as:

   <no_action>
2023-04-22 16:51:32 +02:00
Axel Burri 6d047cbaec btrbk: disable target_create_dir for user; fix dryrun 2023-04-22 16:51:32 +02:00
Axel Burri e737927bd9 btrbk: tidy variable names 2023-04-22 16:51:32 +02:00
Axel Burri 053cd7a59c btrbk: use parser function for assembling archive config 2023-04-22 16:51:32 +02:00
Axel Burri 443cb1891b btrbk: action_archive: no strict_related parent search
strict_related parent search does not make much sense on archive: on
targets, parent_uuid chain is broken after first prune.

Ref: 318126b831
2023-04-22 16:51:32 +02:00
Axel Burri ac0f7e3b91 btrbk: action_archive: honor archive_exclude_older in backup step 2023-04-22 16:51:32 +02:00
Axel Burri d12241fcfc btrbk: action_archive: use correct config_preserve_hash 2023-04-22 16:51:32 +02:00
Axel Burri 1465a1ecc2 btrbk: use same code for backup and archive
Note that some functionality breaks with this commit. Specific
adaptions are done in following commits.
2023-04-22 16:51:32 +02:00
Axel Burri c385b0b731 btrbk: create dir if target_create_dir is set 2023-04-22 16:51:32 +02:00
Axel Burri 7aece45dbf btrbk: add vinfo_mkdir 2023-04-22 16:51:32 +02:00
Axel Burri 2bdd5eb8fc btrbk: use vinfo_realpath 2023-04-22 16:51:32 +02:00
Axel Burri 30b22d49d2 btrbk: add vinfo_realpath 2023-04-22 16:51:32 +02:00
Axel Burri 544d95e094 btrbk: add comment 2023-04-22 16:51:32 +02:00
Axel Burri fe137bd19c btrbk: honor --exclude on delete 2023-04-22 16:51:32 +02:00
Axel Burri 6d57aa4dbe documentation: honor --exclude on backup candidates 2023-04-22 16:51:32 +02:00
Axel Burri 4c174c8f72 btrbk: honor --exclude on backup candidates 2023-04-22 16:51:32 +02:00
Axel Burri c0da910276 btrbk: on resume, abort on unexpected if receive target is not present
A more sophisticated implementation would be to check this after
scheduling, only if the target really needs to be backuped.

We could as well automatically trigger a `btrfs snapshot -r` on target
in these cases, but this seems counter-intuitive.
2023-04-22 16:51:32 +02:00
Axel Burri d498dbb5c3 btrbk: list unexpected archive targets when aborting 2023-04-22 16:51:32 +02:00
Axel Burri 61691abbfc documentation: update deletion of raw targets 2023-04-22 16:51:32 +02:00
Axel Burri c4bf7b0c5a btrbk: use depends callback for raw depends 2023-04-22 16:51:32 +02:00
Axel Burri 6373e32875 btrbk: add depends callback to scheduler 2023-04-22 16:51:32 +02:00
Axel Burri 2a1a42e824 btrbk: related_nodes: add fatal option 2023-04-22 16:51:32 +02:00
Axel Burri e93952b08b btrbk: related_nodes: return reference instead of array
Preparatory for adding fatal option returning undef.
2023-04-22 16:51:32 +02:00
Axel Burri 131e75376f btrbk: fix raw parent_uuid 2023-04-22 16:51:32 +02:00
Axel Burri b77abb3eff btrbk: abort if cmdline specified config not found 2023-04-22 16:51:32 +02:00
Axel Burri 799d235218 btrbk: remove double-slash from file arguments
Sanitize file (or subvolume path) arguments in safe_cmd, effectively
removing leading double slash.

Files originating from "volume /" can be assembled as "//some/subvol",
which is useful internally but undesired as command arguments, as
ancient systems might interpret leading double slash "//" in a special
way.

Posix states:

> A pathname that begins with two successive slashes may be
> interpreted in an implementation-defined manner, although more than
> two leading slashes shall be treated as a single slash.
2023-04-22 16:51:32 +02:00
Axel Burri b9c5e3fc29 btrbk: bump version to 0.33.0-dev 2023-04-22 16:51:32 +02:00
Axel Burri 73c5d180f6 documentation: rephrase lockfile 2023-04-22 16:51:32 +02:00
Axel Burri ac42b29b0a bump copyright year 2023-04-10 16:04:27 +02:00
Axel Burri 5e44bc6a3e change version to 0.32.6; update Changelog 2023-03-25 17:19:14 +01:00
Christoph Anton Mitterer 7adb32c7e9 ssh_filter_btrbk.sh: further harden the shell execution environment
• In principle the special `IFS`-variable could be set to some unexpected non-
  standard value.
  Unsetting it causes its default to be used.
• Locales and in particular their characters sets are quite complex in POSIX and
  may have many subtle implications.
  For example, the pattern matching notation (used in `case`-compound-commands
  or some forms of parameter expansion) are in principle only defined for
  character strings. While some shells handle it gracefully, the behaviour is
  undefined if, for example, the character set is UTF-8 and a variable contains
  bytes that do not form valid caracters in that.
  Actually, there are quite some more implications.

  Also, pathnames, in POSIX, are strings of bytes excluding 0x0.

  For these reasons, the locale is set to the `C`/`POSIX`-locale.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-03-25 16:02:04 +01:00
Christoph Anton Mitterer 5b8c1f8f7a ssh_filter_btrbk.sh: minor improvements
• Set shell options in one command.
• Homogeneously use local variables for function positional parameters in all
  places.
• In redirections, omit `1` for standard output.
• Homogeneously use `if`-compount-commands instead of `[ … ] && …` in all
  places.
• Homogeneously use curly brackets with parameter expansion.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-03-25 16:02:04 +01:00
Christoph Anton Mitterer b274bd1d50 ssh_filter_btrbk.sh: replace OpenSSH’s deprecated SSH_CLIENT
OpenSSH’s environment variable `SSH_CLIENT` has been deprecated in upstream
commit f37e246f858cdd79be4f4e158b7b04778d1cb7e9 (2002-09-19) and replaced by
`SSH_CONNECTION`.

Both contain more than just the remote information, thus adapted the log message
to reflect that.

Since this might be used by 3rd-party programs (like fail2ban), added a specific
note to the changelog.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-03-25 16:02:04 +01:00
Christoph Anton Mitterer ee5a543e0b ssh_filter_btrbk.sh: use printf instead of echo
In spirit, POSIX considers `echo` rather obsolete (it was just kept because of
its widespread use).

It’s also not possible to use `echo` portably unless it’s `-n`-option (as the
first argument) and escape sequences are omitted.
While neither was the case here, it’s better style to just always use `printf`
in order to avoid any future confusion when both are used.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-03-25 16:02:04 +01:00
Christoph Anton Mitterer ddc9b810de ssh_filter_btrbk.sh: convert to POSIX sh
This commit finishes the work from the previous one and converts
ssh_filter_btrbk.sh to (mostly) pure POSIX Shell Command Language.

Instead of bash’s `=~`-operator for its `[[ … ]]`-compound-command it uses
`grep`.
At the time of writing, bash has at least the `nocasematch`-shell-option which
would have a negatve security impact for this program. While it’s not enabled
per default single users could potentially change that, not realising the
consequences.
Thus, moving away from this may also provide some hardening.

Unlike bash’s `=~`-operator, which matches against the whole string at once,
`grep` matches the pattern against each line of input.
This would allow for attacks by including a newline in the SSH command like in:
    SSH_ORIGINAL_COMMAND="readlink /dev/stdout
    cat /etc/shadow"
but is prevented by the general exclusion of newlines in commit TODO.

`grep` may return an exit status of `0` when used with its `-q`-option, even
when an error occurred.
Since this program is intended specifically for security purposes this shall be
avoided, even if such case is unlikely, and therefore its standard output and
standard error are redirected to `/dev/null` instead.

Further, using just:
    local formatted_restrict_path_list="$(printf '%s' "$restrict_path_list" | sed 's/|/", "/g')"
rather than:
    local formatted_restrict_path_list=""; formatted_restrict_path_list="$(printf '%s' "$restrict_path_list" | sed 's/|/", "/g')"
prevent `set -e` to take effect if the pipeline within the command substitution
fails, as the returned exit status of the whole command is the result of
`local`, not that of the assignment.
This is however no security problem here, as `formatted_restrict_path_list` is
only used for informative pruposes.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-03-25 16:02:04 +01:00
Christoph Anton Mitterer ac1fd38beb ssh_filter_btrbk.sh: remove unnecessary bashishms
ssh_filter_btrbk.sh is mainly intended for security purposes and should
therefore itself be written with that in mind.
It is written for bash, which greatly extends the POSIX Shell Command Language
and is incompatible with it in some niche cases.

For several reasons, it seems a good idea to convert the program to (mostly)
pure POSIX Shell Command Language:
• People may try to use the program with other shells (for example when bash is
  not available) and make errors.
More pure `sh` implementations like dash …
• … have far less code and also less dependencies, which possibly also reduces
  the chance for bugs or exploits,
• … are less dynamic in development (and have thus possibly a lower chance of
 incompatible changes) …
• … and may run faster.

This commit replaces any unnecessary “bashishms” with purely POSIX compatible
code, with the exception of the `local`-built-in, which is however supported by
most POSIX compatible shells (including dash, klibc-utils’s `sh` and BusyBox’
`sh`) in some way.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-03-25 16:02:04 +01:00
Christoph Anton Mitterer 5d79c012c4 ssh_filter_btrbk.sh: double quote variables expansions
Double quote any variable expansions that might ever contain field separators.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-03-25 16:02:04 +01:00
Christoph Anton Mitterer 1980c1d939 ssh_filter_btrbk.sh: use single quotes where possible
In strings that don’t contain `'` nor do any expansions, use single quotes to
avoid any future unintended expansions or escapes.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2023-03-25 16:02:04 +01:00
Axel Burri a75765cc9a btrbk: process all snapshots in snapdir (not only related ones) 2022-12-04 01:46:31 +01:00
Axel Burri 335e19e238 btrbk: allow quotes for all config values
Regression of:

   9d217857 btrbk: fix parsing of quoted "target" config line
2022-12-04 00:50:21 +01:00
Axel Burri f107507876 documentation: install add quick wget example in install 2022-12-03 12:10:05 +01:00
Axel Burri 1477fe5181 documentation: install: mention asciidoctor 2022-12-03 12:10:05 +01:00
Axel Burri 91b29ce32c documentation: install: fix broken link to fedora rpms 2022-12-03 12:10:05 +01:00
Axel Burri 6b95250b84 documentation: install: move gentoo down
Trying to more or less sort by popularity / relevance.
Sadly Gentoo is not on the top list any more these days.
2022-12-03 12:10:05 +01:00
Christoph Anton Mitterer 36d6ba7d07 ssh_filter_btrbk.sh: disallow newlines in the SSH command
This disallows newline (that is: LF characters) in the SSH command, which could
have been exploited for arbitrary code execution, since commit
77a39282de.

Example:
    # export SSH_ORIGINAL_COMMAND=$'readlink /dev/stdout\ncat /etc/shadow'
    # ssh_filter_btrbk.sh

Since `readlink` is a generally allowed command, this works with any of
ssh_filter_btrbk.sh’s options.
But most likely, other commands that are “added” via `allow_cmd()` can be used,
too.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>

# Please enter the commit message for your changes. Lines starting
# with '#' will be kept; you may remove them yourself if you want to.
# An empty message aborts the commit.
#
# Date:      Wed Nov 30 04:29:53 2022 +0100
#
# On branch fix-remote-code-execution
# Your branch and 'origin/fix-remote-code-execution' have diverged,
# and have 1 and 1 different commits each, respectively.
#   (use "git pull" to merge the remote branch into yours)
#
# Changes to be committed:
#	modified:   ssh_filter_btrbk.sh
#
# Untracked files:
#	ORIG
#
2022-12-02 01:43:29 +01:00
Axel Burri fa7ef1bf63 documentation: ssh_filter_btrbk: add note on --restrict-path 2022-11-21 13:10:42 +01:00
Axel Burri f9c7a47b6a btrbk: use substitutions in printf
Avoid possible interpreted sequence from values (e.g. from FILE).
2022-11-20 15:57:25 +01:00
Axel Burri b800d1bb10 btrbk: strict input validation from kdf backend 2022-11-20 15:49:31 +01:00
Axel Burri a622fded5a btrbk: strict input validation from raw sidecar 2022-11-20 12:29:54 +01:00
Axel Burri f8280f591f btrbk: ignore redundand FILE from raw sidecar
If present, check against name calculated from raw info file name.
2022-11-20 11:19:49 +01:00
Axel Burri 7ad4ebe0af btrbk: make safe_commands more restrictive 2022-11-20 11:19:14 +01:00
Axel Burri 7a4a54db97 btrbk: disallow newline in files
While most functionality works fine, raw backups fail to write correct
"FILE=" information in info sidecar.

Disallowing newlines in files is a good idea in general.
2022-11-20 02:40:15 +01:00
Axel Burri 87ed9ffeb5 btrbk: improve raw sidecar files parsing 2022-11-20 02:40:15 +01:00
Axel Burri 9d0468070d btrbk-verify: do not use echo -e 2022-11-20 00:09:50 +01:00
Axel Burri 65886f10fd btrbk-mail: do not use echo -e 2022-11-20 00:09:32 +01:00
Axel Burri f52de197d6 btrbk: use printf instead of echo
Posix echo does not know about -e, -n flags, use printf instead.
2022-11-16 02:31:13 +01:00
Axel Burri 5c561d8c14 documentation: tidy --dry-run, --print-schedule examples 2022-11-16 01:37:12 +01:00
Axel Burri 125b37468a btrbk: tidy comments 2022-11-16 00:45:39 +01:00
Christoph Anton Mitterer 914f9286c7 btrbk: add bzip3 compression
This adds support for bzip3 [1].

 [1] https://github.com/kspalaiologos/bzip3

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>

Cosmetics: swap order pbzip2 / bzip3

Signed-off-by: Axel Burri <axel@tty0.ch>
2022-11-16 00:45:39 +01:00
Axel Burri af86dc8c52 btrbk: allow compressors not to have a compression level
Not all compressors support compression level (option `-#`): print a
warning if compress_level is set, and ignore its value for such
compressors.
2022-11-16 00:44:53 +01:00
Christoph Anton Mitterer af2d7b2c99 documentation: use "example.org" in examples
`mydomain.com` is actually a real domain and shouln’t be used in examples.

RFC 2606 (respectively RFC 6761) reserves `example.org` (and others) for that
purpose.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2022-11-12 15:19:24 +01:00
Christoph Anton Mitterer 1287547df0 documentation: use "restrict" in authorized_keys for further hardening
Since `btrbk` executes only commands, it shouldn’t need any of what’s currently
disabled with the `restrict` flag in the `authorized_keys` file, that is:
Port-, agent- and X11-forwarding as well as PTY allocation and execution of
`~/.ssh/rc`.

Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
2022-11-12 15:17:28 +01:00
Axel Burri 9166d73be7 documentation: add send_protocol, send_compressed_data 2022-10-30 17:08:06 +01:00
Axel Burri cc08cef27c btrbk: add send_protocol and send_compressed_data config options
support btrfs send protocol v2
2022-10-30 17:08:06 +01:00
Axel Burri 1f7aa7e247 btrbk: unify btrfs send options 2022-10-30 17:08:06 +01:00
Axel Burri af4681319c btrbk: bump version to 0.32.6-dev 2022-10-30 17:08:05 +01:00
Axel Burri 58fffab405 change version to 0.32.5; update Changelog 2022-10-23 12:37:28 +02:00
Axel Burri dcee6222be btrbk: append to info file instead of rewriting
A redirection (e.g. `echo foo > bar.info`) can cause empty (zero-size)
files in some circumstances.

We still write INCOMPLETE=1 to the info file before send/receive, but
instead of re-creating it without the INCOMPLETE flag, we append
INCOMPLETE=0 (keeping up compatibility with old versions of btrbk).

Ref: 4e5ae975d8 btrbk: ignore zero-size info files
2022-10-19 11:38:11 +02:00
Axel Burri 51b2a5a9f5 btrbk: tidy comments 2022-10-19 11:38:11 +02:00
Axel Burri 25c8eb1705 btrbk: add timestamp to info file on write 2022-10-19 11:38:11 +02:00
Axel Burri 08cb900a9e btrbk: add append option to system_write_raw_info 2022-10-19 11:38:11 +02:00
Axel Burri 89c0aa31d7 btrbk: tidy raw info file parsing 2022-10-19 11:37:45 +02:00
Axel Burri d6910e43ea btrbk: add append_to_file option in run_cmd 2022-10-19 11:33:40 +02:00
Matthieu Patou 4e5ae975d8 btrbk: ignore zero-size info files
When backuping from devices that have configured to use raw backup and
that might disconnect from the network (ie. laptops) you end up once in
a while with 0 size info file (and backup file).
btrbk don't know how to handle 0 file and stop backing up until the zero
size file is removed.
With this change 0 size info file will be ignored, and hence the backup
for the given backup will be redone.

Signed-off-by: Matthieu Patou <mat@matws.net>
2022-10-18 11:46:32 +02:00
Axel Burri f77a33b340 btrbk: bump version to 0.32.5-dev 2022-10-18 11:08:31 +02:00
Axel Burri 6877825708 change version to 0.32.4; update Changelog 2022-08-20 14:26:36 +02:00
Axel Burri 116aface3c btrbk: fix regression: wrong deprecation warnings
Warning for btrfs_commit_delete is always printed, regardless of the
(possibly valid) values.

regression in btrbk-0.32.3

   687e0508b7 btrbk: tidy deprecation warnings
2022-08-20 14:24:17 +02:00
Axel Burri 411034e93f change version to 0.32.3; update Changelog 2022-08-07 11:04:39 +02:00
xskoak 3149aa9e10 btrbk.conf.example: fix spelling 2022-07-28 13:59:01 +02:00
Axel Burri 79b6a662f2 btrbk: fix missing error in action "ls" 2022-07-28 13:44:42 +02:00
Axel Burri cf2065df30 btrbk: hint missing ssh_identity on errors
It is perfectly ok to run btrbk without ssh_identity (using ssh
defaults), printing a warning if the option is not set is wrong.
Instead, hackily check for ssh_identity on ssh errors, and give a hint
in the error message.
2022-07-28 13:44:37 +02:00
Axel Burri 67020797ff btrbk.conf.example: tidy ssh_identity, add backend_local_user 2022-07-28 13:02:22 +02:00
Axel Burri a5dd4dd7b9 btrbk.conf.example: add local user on demand with ssh-agent 2022-07-28 13:01:56 +02:00
Axel Burri 19727e913b documentation: drop deprecation notice
gt 2 years, deprecated since v0.28.0
2022-07-28 12:18:04 +02:00
Axel Burri 588fc7faa8 documentation: tidy man reference 2022-07-28 12:18:04 +02:00
Axel Burri dc7b11653d documentation: adapt ssh_identity and ssh_user option
also mention ssh-agent for ssh_identity option.
2022-07-28 12:17:16 +02:00
Axel Burri 2621fb38ba btrbk: allow ssh_user=no 2022-07-28 12:10:06 +02:00
Axel Burri dd638ec9f4 btrbk: allow ssh_identity=no 2022-07-28 12:06:22 +02:00
Axel Burri f467de6c19 btrbk.conf.example: adapt btrfs_commit_delete 2022-07-28 12:06:22 +02:00
Axel Burri c5dff6afda documentation: adapt btrfs_commit_delete
Also move item down, closer to other delete-related options.
2022-07-27 20:41:59 +02:00
Axel Burri 6b465bf06b btrbk: never delete multiple subvolumes at once
Deleting multiple subvolumes at once always caused the problem that we
need to parse stderr of "rm" and "btrfs subvolume delete" in order to
know which subvolume actually failed, which is problematic (version
dependent, language dependent). Also, we would need to restrict the
number of subvolumes based on the maximum allowed length for shell
commands, which is system-dependent (check `getconf ARG_MAX`).

Deleting subvolumes sequentially has slightly negative impact on
execution time (multiple rsh commands), with the benefit of being more
robust and reducing the codesize.
2022-07-27 20:41:25 +02:00
Axel Burri b7df717611 btrbk: hide only fully deprecated keys when dumping 2022-07-27 18:36:20 +02:00
Axel Burri 687e0508b7 btrbk: tidy deprecation warnings 2022-07-27 18:20:33 +02:00
Axel Burri c5cb919f6c btrbk: tidy log functions 2022-07-27 18:19:46 +02:00
Axel Burri 805ab93fef btrbk: fix function argument
Does not trigger a bug in current program logic.

Ref: 3ea7746700 btrbk: cosmetics: separate get_btrbk_date function
2022-07-27 14:35:24 +02:00
Axel Burri 43a125d4e1 btrbk: bump version to 0.32.3-dev 2022-07-27 14:35:15 +02:00
Axel Burri bdc1f5caba change version to 0.32.2; update Changelog 2022-06-25 18:52:11 +02:00
Axel Burri 054146ac00 btrbk: keep quotes intact when removing comments in config 2022-06-06 22:00:46 +02:00
Axel Burri 9d21785778 btrbk: fix parsing of quoted "target" config line
Quotes were removed before passing value to parse_config_line,
resulting in failuer of parsing target url if quoted.
2022-06-06 21:59:11 +02:00
Axel Burri fb13848faf btrbk: tidy function prototype 2022-06-06 21:02:13 +02:00
Axel Burri f169456613 btrbk: tidy logging 2022-06-06 18:31:45 +02:00
Axel Burri a062f42344 documentation: allow multiple gpg_recipient 2022-05-29 21:44:11 +02:00
Axel Burri a70248376f btrbk: use no-default-recipient on gpg encrypt
In case the user has set a default recipient in his gpg config file,
ignore it.
2022-05-29 21:34:43 +02:00
Steven Brudenell b824d62449 btrbk: support multiple gpg recipients 2022-05-29 21:34:43 +02:00
Asbjørn Apeland b618c2dd90 contrib: bash: completion.bash: complete options without =
Currently, option arguments are only completed after =. For example:

	$ btrbk --loglevel=<TAB>
	debug  error  info   trace  warn
	$ btrbk --loglevel <TAB>
	archive   diff      extents   ls        prune     run
	stats     clean     dryrun    list      origin    resume
	snapshot  usage

This commit makes it so that both option styles are recognized:

	$ btrbk --loglevel=<TAB>
	debug  error  info   trace  warn
	$ btrbk --loglevel <TAB>
	debug  error  info   trace  warn

This was the intention all along, but it was implemented incorrectly.
2022-05-29 18:03:36 +02:00
Merlin Büge a8a5051f79 documentation: README.md: replace "resume" with "robust recovery"
There was some confusion about it, see the discussion in
https://github.com/digint/btrbk/issues/196
2022-05-29 17:45:10 +02:00
Merlin Büge 1d4a502ee3 documentation: fix small typos and rephrase some parts 2022-05-29 17:21:29 +02:00
Axel Burri 0b41942251 github: add FUNDING.yml 2022-05-29 16:21:38 +02:00
Axel Burri 9e32df5f90 documentaion: README.md: rephrase donate section 2022-05-29 16:02:00 +02:00
Axel Burri eadeb89232 btrbk: check results of btrfs filesystem usage 2022-05-29 14:32:27 +02:00
Axel Burri 691885e6b8 documentation: add compat=ignore_receive_errors option 2022-05-29 13:53:56 +02:00
Axel Burri b8464119f6 btrbk: add compat=ignore_receive_errors option 2022-05-29 12:29:19 +02:00
Axel Burri 023d75f7a5 documentation: cosmetics 2022-05-29 12:29:16 +02:00
Axel Burri 619403c9ad documentation: fix action "config print" 2022-05-29 12:29:13 +02:00
Axel Burri 527d1bf74f btrbk: improve action "config print"
- honor overrides
 - print unset lines as comments
 - skip lines on forbidden context
 - fix values "no" and "<unset>"
2022-05-29 12:26:37 +02:00
Axel Burri f187d6f6ee btrbk: tidy formatting 2022-05-29 12:26:37 +02:00
Axel Burri 321f3783d5 btrbk: use split in ssh_cipher_spec config definition 2022-05-29 12:21:39 +02:00
Axel Burri ce2afb427d btrbk: split all config values with same regex 2022-05-28 21:28:42 +02:00
Axel Burri ba3ee70d38 btrbk: tidy config options definition 2022-05-28 21:28:39 +02:00
Axel Burri 823419d510 btrbk: tidy config options parser
- handle regex within accept list
 - handle numeric as regex
 - split before checking accept
2022-05-28 21:27:39 +02:00
Axel Burri 90c5d119f6 documentation: clarify btrfs_commit_delete 2022-05-27 20:14:02 +02:00
Axel Burri 267cbcacdc documentation: clarify filter statement match multiple times 2022-05-27 19:31:48 +02:00
Axel Burri 04e0695429 btrbk: tidy logging 2022-05-27 19:31:48 +02:00
Axel Burri 12f608d828 btrbk: fix regression: clear realpath cache on mkdir
On btrbk archive, after creating a directory without dry-run, the
archive target is skipped with "Failed to fetch subvolume detail" due
to caching of realpath.

Regression in btrbk-0.32.0:

    eb69bc883e btrbk: refactor mountinfo
2022-05-27 19:31:48 +02:00
Axel Burri 4fcbbad802 btrbk: print version and help to stdout 2022-03-25 15:20:20 +01:00
Axel Burri be07f1908a btrbk: print shorter error help message 2022-03-25 15:20:14 +01:00
Axel Burri fc49abbbf8 btrbk: bump version to 0.32.2-dev 2022-03-25 15:19:59 +01:00
Axel Burri 593fa6b254 change version to 0.32.1; update Changelog 2022-02-26 18:35:09 +01:00
Axel Burri d9b9f20899 bump copyright year 2022-02-26 18:35:02 +01:00
Axel Burri 795418ebe1 btrbk.conf.example: remove timestamp_format
Now that timestamp_format defaults to "long", it seems no longer
needed to even mention it here. Setting to "short" or "long-iso" is
only required in rather special use cases.
2022-02-26 18:11:09 +01:00
Axel Burri 671df969a1 documentation: rephrase timestamp_format notes on preserve_hour_of_day 2022-02-26 18:11:09 +01:00
Axel Burri 047d3a1a65 btrbk: allow directory traversal for subvol_args 2022-02-26 18:11:09 +01:00
Axel Burri a25486336b btrbk: fix regression: filter paths for action "ls"
regression from: eb69bc883e btrbk: refactor mountinfo
2022-02-26 18:11:09 +01:00
Axel Burri ff0a887c32 btrbk: call filesystem usage from mount point 2022-02-22 20:28:23 +01:00
Axel Burri e9fe2cb5f5 btrbk: display all source subvolumes in btrbk usage 2022-02-22 20:28:17 +01:00
Axel Burri 31ce14e4c2 btrbk: handle errors from btrfs filesystem usage
Fix `btrbk usage` unhandled error case if usage data cannot be
retrieved, e.g.:

   ERROR: Failed to fetch btrfs filesystem usage for: example.com:/mnt/btr_pool
   ERROR: ... sh: ssh -i 'XXX' btrbk@example.com 'btrfs-filesystem-usage '\''/mnt/btr_pool'\'''
   ERROR: ... cannot access '/mnt/btr_pool': Permission denied
2022-02-22 20:28:01 +01:00
Axel Burri 0388cf4b2d documentation: add backend btrbk-progs-doas 2022-02-08 01:20:24 +01:00
Axel Burri 177f8547e3 btrbk: add backend btrfs-progs-doas 2022-02-08 01:06:04 +01:00
Axel Burri d3b7540b87 btrbk: tidy backend command map 2022-02-08 01:05:59 +01:00
Axel Burri db7082b4bc btrbk: add config_key_lru comfort function 2022-02-06 17:44:30 +01:00
Axel Burri 68d5fe3f55 btrbk: add match argument in config_key 2022-02-06 17:44:30 +01:00
Axel Burri e6ed21343c btrbk: remove dead code 2022-02-06 16:05:12 +01:00
Axel Burri 0172e4a240 btrbk: fix mountinfo tree root detection
Set node as tree root if mount_id == parent_id. For some reasons this
is never the case on my (mostly gentoo) systems.

Regression from: eb69bc88 btrbk: refactor mountinfo
2022-02-06 12:35:57 +01:00
Axel Burri ed8142ed9d btrbk: bump version to 0.32.1-dev 2022-02-06 12:35:53 +01:00
Axel Burri 8676191d45 change version to 0.32.0; update Changelog 2022-02-05 19:34:54 +01:00
Axel Burri 8cc74fecc1 btrbk: default timestamp_format=long
This is a relict of early days of btrbk, and I have already hesitated
for too long to change the default from legacy "short" to sane "long"
format.

Tests show that the scheduling behaves in a sane/expected way if this
change is applied unattended. I suppose everybody who has
preserve_hour_of_day set is already using timestamp_format=long.
2022-02-05 18:47:49 +01:00
znerol c5273a8745 documentation: fix openssh website URL 2021-11-06 17:24:52 +01:00
Axel Burri ca166d47b6 btrbk: add safe_commands config option
For the paranoid. For convenience, filename checking was removed in
[1], and quoting was (hopefully) implemented correctly in [2].

Allowing special characters as well as UTF8 leave behind a bad
feeling, as there are many special cases that needs to be taken care
of (e.g. newlines in file names, right-to-left encoding, etc.). In
order to mitigate attacks expoiting these error classes, leave an
option to power users which do only allow "sane" characters in their
filename hierarchy.

  [1] 6a29b08f00 btrbk: remove filename restrictions
  [2] acc7f9fc83 btrbk: quote unsafe characters in shell commands
2021-11-06 16:40:47 +01:00
Axel Burri 4f72ad123f btrbk: tidy error message 2021-11-06 16:09:51 +01:00
Axel Burri 2b21d1528c documentation: add "reference time" subsection 2021-11-06 13:50:38 +01:00
Axel Burri ed814aed5a documentation: rephrase retention policy 2021-11-06 13:27:22 +01:00
Axel Burri cb38b7efa4 btrbk: parse additional "btrfs subvolume show" lines from btrfs-progs-5.14.2 2021-10-24 10:39:16 +02:00
Axel Burri c538702d8c btrbk: abort on unexpected only if receive target is not present 2021-10-04 19:17:36 +02:00
Axel Burri 4234fb2965 btrbk-verify: cleanup 2021-09-04 17:15:56 +02:00
Axel Burri d554afab10 btrbk-verify: allow ssh-user without ssh-identity
Required e.g. if a ssh-agent is already running, and we want to set
user=root for rsync.
2021-09-04 16:57:05 +02:00
Axel Burri bef13275d3 btrbk: fix regression: print quoted rsh command in table output
regression from: 27388c7589 btrbk: treat all filenames as unsafe
2021-09-04 15:46:57 +02:00
Axel Burri 1bda5fd978 btrbk: tidy safe_cmd; die if quoting leading dash for command
This should never happen, as all our filenames are checked to be
absolute.
2021-09-04 15:46:09 +02:00
Axel Burri d1247359f8 btrbk: always return abort key 2021-08-28 14:49:12 +02:00
Axel Burri faec607d02 btrbk: drop deprecated -r,--resume-only argument
Deprecated as of btrbk v0.26.0 (more than 3 years ago).
2021-08-28 14:06:10 +02:00
Axel Burri 3f84345bed btrbk: tidy logging 2021-08-28 14:06:10 +02:00
Axel Burri 5dc2375a75 btrbk: fix raw file deletion 2021-08-28 14:06:10 +02:00
Axel Burri 424127441d btrbk: fix unsafe path for btrfs send to file 2021-08-28 14:06:10 +02:00
Axel Burri fe53198661 btrbk: drop support for deprecated raw format
Raw backups created by btrbk < 0.26.0 are now ignored:

   *.btrfs_<received_uuid>[@<parent_uuid>][.gz|bz2|xz][.gpg][.split][.part]
2021-08-28 14:06:02 +02:00
Axel Burri d7653a9e0a documentation: add incremental_prefs; adapt incremental_clones 2021-08-27 17:20:47 +02:00
Axel Burri 85c2d14287 btrbk: change incremental_prefs defaults
New defaults gives the btrbk_direct_leaf snapshots higher preference
than the global ones resolved by parent-uuid (which are best-guess).

This way the parent has a higher chance of being a backup created by
btrbk, which results in "btrfs receive" to start work on a snapshot of
this (and preferably not on the "best-guess" ones).
2021-08-27 17:20:47 +02:00
Axel Burri bde0c10a6c btrbk: add incremental_prefs config option 2021-08-27 17:20:47 +02:00
Axel Burri 6ca00feeb6 btrbk: tidy parent selection
Preparatory for incremental_prefs feature, no functional changes.
2021-08-27 17:20:47 +02:00
Axel Burri 10a6f51730 btrbk: remove deprecation on incremental_clones
btrbk does not set config defaults to global scope for deprecated
keys.
2021-08-27 17:20:47 +02:00
Axel Burri 9f877a4670 btrbk: remove extra clone source, deprecate numeric incremental_clones 2021-08-27 17:20:47 +02:00
Axel Burri 1cb958ee30 btrbk: add "match" target for deprecated options 2021-08-27 17:20:39 +02:00
Axel Burri ad6298bf37 btrbk: add global split_match (cosmetics) 2021-08-19 17:16:50 +02:00
Axel Burri eb69bc883e btrbk: refactor mountinfo
- Create tree from /proc/self/mountinfo, and use it to find mount
  points.

- Populate realpath cache from mount points, possibly reducing calls
  to `realpath`.

- Replace btrfs_mountpoint with vinfo_mountpoint(fs_type => 'btrfs)

- Tidy action "ls".

- Move code
2021-08-18 13:14:10 +02:00
Axel Burri 063c25ad24 btrbk: add sanity checks on mountinfo list 2021-08-18 13:14:10 +02:00
Axel Burri 2556492ec6 documentation: btrbk.conf.5: remove paragraph on filename restrictions 2021-08-18 13:14:10 +02:00
Axel Burri 6a29b08f00 btrbk: remove filename restrictions 2021-08-18 13:14:10 +02:00
Axel Burri b8370de9de documentation: terminate options using double dash "--" 2021-08-18 13:14:10 +02:00
Axel Burri 4b7b7cfc06 documentation: btrbk.1: rephrase --format=raw 2021-08-18 02:08:28 +02:00
Axel Burri af5d25c5a9 btrbk-verify: expect single quotes from btrbk raw table output 2021-08-18 02:08:28 +02:00
Axel Burri 81a04e4287 btrbk: use single quotes for raw table format 2021-08-18 02:08:28 +02:00
Axel Burri 48bf4f05b9 btrbk: fix table output for utf8 characters (require Text::CharWidth)
Use Text::CharWidth::mbswidth() if installed, fallback to
length(Encode::decode_utf8()), fallback to length().

 - Text::CharWidth handles wide chars (e.g. asian, taking up two
   columns on the terminal) correctly.

 - length(Encode::decode_utf8()) handles single-width chars only, and
   should be installed on most systems (perl >= v5.7.3).

 - langth() counts bytes, as we do not convert anything to UTF-8 in
   btrbk (NOT using `perl -CIOEioA` or binmode(STDOUT, ":utf8"))
2021-08-18 02:08:28 +02:00
Axel Burri 94a415e420 btrbk: check/sanitize leading/trailing whitespace on files 2021-08-18 02:08:28 +02:00
Axel Burri 77a39282de ssh_filter_btrbk.sh: allow quoted files 2021-08-18 02:08:28 +02:00
Axel Burri f7d3823d5d ssh_filter_btrbk.sh: fix files are always absolute 2021-08-18 02:08:28 +02:00
Axel Burri 3e9b581a54 btrbk: add --unsafe-filenames option 2021-08-18 02:08:28 +02:00
Axel Burri 1a7bbff767 btrbk: tidy run_cmd calls 2021-08-18 02:08:28 +02:00
Axel Burri 27388c7589 btrbk: treat all filenames as unsafe 2021-08-18 02:08:28 +02:00
Axel Burri 2933e65cbe btrbk: adapt usage of unsafe arguments for run_cmd 2021-08-18 02:08:28 +02:00
Axel Burri acc7f9fc83 btrbk: quote unsafe characters in shell commands
As filenames can contain meta characters like '$', we can't just put
ssh commands in double quotes. E.g. the following would trigger
variable expansion on local shell:

    ssh example.com "ls -l 'evil$x'"

Instead, we quote the ssh using single quotes (adding the need to
escape single quotes), while also quoting unsafe filenames using
single quotes. The above becomes:

    ssh example.com 'ls -l '\''evil$x'\'''

Or more complex, for a file named "file with'single quotes'":

    ssh example.com 'ls -l '\''file with'\''\'\'''\''single quotes'\''\'\'''\'''\'''

On the remote shell, this will expand to:

    ls -l 'file with'\''single quotes'\'''
2021-08-18 02:08:28 +02:00
Axel Burri d7f6d5fecf btrbk: accept quoted values in config 2021-08-18 02:08:28 +02:00
Axel Burri 5d94de9142 btrbk: use File::Spec for relative file arguments 2021-08-18 02:08:28 +02:00
Axel Burri eccb24ecd7 btrbk: fix action "usage"
Regression from:

   b658fba08c btrbk: print snapdir and targets for action "usage"
2021-08-18 02:08:28 +02:00
Axel Burri 3cf69f3537 btrbk: add missing table ralign 2021-08-18 02:08:28 +02:00
Axel Burri 2f88d5ab4c btrbk: check for deleted subvol before panicking 2021-08-18 02:08:28 +02:00
Axel Burri 6e7c8c409b btrbk: cosmetics: fix trace log 2021-08-18 02:08:28 +02:00
Axel Burri 808633a3ae btrbk-verify: remove workarounds for old versions; tidy eval 2021-08-09 19:06:20 +02:00
Axel Burri d9958cbbc1 btrbk-verify: use new raw table format keys 2021-08-09 19:06:20 +02:00
Axel Burri 9278211123 btrbk: fix resolved ambiguity in raw table formats
rename snapshot_path -> snapshot_subvolume
rename target_path   -> target_subvolume

These point to subvolumes, not paths containing subvolumes.
2021-08-09 19:06:20 +02:00
Axel Burri 2347163780 btrbk: table formats: replace source_path with source_subvolume 2021-08-09 19:06:20 +02:00
Axel Burri e6106c3cda documentation: btrbk.conf.5: optional volume section 2021-08-09 19:06:20 +02:00
Axel Burri 9a806d85ef btrbk.conf.example: add simple (non-volume) example; cleanup 2021-08-09 19:06:20 +02:00
Axel Burri 89ea680ce2 documentation: README.md: consequently depict commands with hash 2021-08-09 19:06:20 +02:00
Axel Burri 1eee2c0d2e documentation: README.md: add non-volume examples 2021-08-09 19:06:20 +02:00
Axel Burri b658fba08c btrbk: print snapdir and targets for action "usage" 2021-08-09 19:06:20 +02:00
Axel Burri 7603e03aad btrbk: never match dummy volume section 2021-08-09 19:06:20 +02:00
Axel Burri e1c5fd0029 btrbk: remove superfluous checks on volume 2021-08-09 19:06:20 +02:00
Axel Burri 47ea1f9481 btrbk: fix action "config print" for dummy volume section 2021-08-09 19:06:20 +02:00
Axel Burri e257077241 btrbk: allow subvolume context without volume (add dummy section)
Unfortunately the framework relies on "url" for the volume. This
should not be printed anywhere, using "/dev/null" should be fine.
2021-08-09 19:06:20 +02:00
Axel Burri e2de9de440 btrbk: expand subvolume globs independent of volume 2021-08-09 19:06:20 +02:00
Axel Burri 3b4f275126 btrbk: accept absolute path for subvolume 2021-08-09 19:06:20 +02:00
Axel Burri d40d75ef76 btrbk: accept absolute path for snapshot_dir 2021-08-09 19:06:20 +02:00
Axel Burri 5b2644f12a btrbk: fix check_file: accept both relative and absolute options 2021-08-09 19:06:20 +02:00
Axel Burri d3d04f2252 btrbk: remove subvolume_path from schedule table
This is the only format where SUBVOL_PATH is displayed. As SUBVOL_PATH
is only available for vinfo_child, this can not be used in global
scope.
2021-08-09 19:06:20 +02:00
Axel Burri c1610c754d btrbk: cleanup: add config_subsection 2021-08-09 19:06:20 +02:00
Axel Burri 247cb37acf btrbk: add comment on vinfo_child specific keys 2021-08-09 19:06:20 +02:00
Axel Burri 2d854c7327 btrbk: add comment on clone source from different mount point 2021-08-09 19:06:20 +02:00
Axel Burri 86e902cebc btrbk: remove dead code 2021-08-09 19:06:20 +02:00
Axel Burri ce9c21bd24 btrbk: tidy check for btrbk subvolume
The original idea was probably to have a trace log for skipped
subvols.
2021-08-09 19:06:20 +02:00
Axel Burri f86c563715 btrbk: tidy superfluous subvol_dir argument 2021-08-09 19:06:20 +02:00
Axel Burri 2da30f6b96 btrbk: bump version to 0.32.0-dev 2021-08-09 19:06:20 +02:00
Ingmar Lippert fa3204cd7e documentation: README.md: fix spelling
spelling correction
2021-08-08 20:36:23 +02:00
Axel Burri feba54a68d change version to 0.31.3; update ChangeLog 2021-08-07 00:13:21 +02:00
Axel Burri bddd7a1d69 Makefile: add btrbk_restore_raw.py to script install targets 2021-08-06 23:33:17 +02:00
fr3aker 82860f0f4c btrbk_restore_raw.py: add script for restoring raw backups 2021-08-06 23:33:17 +02:00
ullr23@gmail.com 322ae2c78f btrbk: add support for zstd adaptive compression
Requires zstd version >= 1.3.6
2021-08-06 17:51:20 +02:00
Axel Burri 907a5065ab documentation: add "resume" example; rephrase "ondemand" example 2021-08-06 16:55:53 +02:00
Axel Burri bf0b5997e8 btrbk: allow relative path arg for actions: archive, extents, diff, origin 2021-08-01 14:11:50 +02:00
Axel Burri 16cec0f6d4 btrbk: tidy map relative subvol argument 2021-07-25 13:32:27 +02:00
Axel Burri 2824668c0e btrbk: fix path sanitizer
Sanitize "/././" -> "/"
2021-07-24 14:40:30 +02:00
Axel Burri 2616028326 documentation: README.md: rephrase note on ubuntu @subvol notation 2021-07-17 15:36:59 +02:00
Axel Burri 712910b440 btrbk.conf.example: tidy spacing 2021-07-16 13:20:25 +02:00
Axel Burri 346f08220e btrbk.conf.example: revert to sane non-@subvol notation
We don't want to promote weird naming conventions here.

The idea behind the change in the previous commit [1] was to get rid
of confused people asking me: "hey, I don't have a subvolume for my
rootfs, all I see is @ and @home".

Left an example for "subvolume @" which should be clear to Ubuntu
people out there.

  [1] de6c7ab586 btrbk.conf.example: use @subvol notation
2021-07-16 13:12:03 +02:00
Axel Burri de6c7ab586 btrbk.conf.example: use @subvol notation 2021-07-15 14:51:30 +02:00
Axel Burri ff9e4b5b5f btrbk.conf.example: add timestamp_format 2021-07-15 14:51:30 +02:00
Axel Burri f1a92e4141 btrbk.conf.example: add comments 2021-07-15 14:51:30 +02:00
Axel Burri e110cc3e91 documentation: README.md: mention mandatory mounting of subvolid=5 2021-07-15 14:51:30 +02:00
Axel Burri 5524d16707 btrbk: add warn_unknown_targets config option 2021-07-15 14:11:03 +02:00
Axel Burri 54bb876b85 btrbk: tidy check_file 2021-07-15 14:11:03 +02:00
Axel Burri 47a3aa5849 btrbk: tidy assemble piped command; remove dead code 2021-07-15 14:11:03 +02:00
Axel Burri af6d719acc btrbk: fix: ignore mount points with unsupported filename in action "ls"
Mount points with illegal characters would die in vinfo. Print error
and ignore.
2021-07-15 14:11:03 +02:00
Axel Burri 12f6c5b69f btrbk: tidy mountinfo comments 2021-07-15 14:11:03 +02:00
Axel Burri 6c13a64459 btrbk: fix mountinfo parsing (octal encoded chars)
Making sure this is done after splitting, as encoded value could be a
comma.

After some testing it shows that the kernel [1] produces ambigous
output in "super options" if a subvolume containing a comma is mounted
using "-o subvolid=" (tried hard to mount with "-o subvol=", seems not
possible via shell):

    # btrfs sub create /tmp/btrbk_unittest/mnt_source/svol\,comma
    # mount /dev/loop0 -o subvolid=282 '/tmp/btrbk_unittest/mount,comma'
    # cat /proc/self/mountinfo
    [...]
    48 40 0:319 /svol,comma /tmp/btrbk_unittest/mount,comma rw,relatime - btrfs /dev/loop0 rw,ssd,noacl,space_cache,subvolid=282,subvol=/svol,comma
                                                                                                                                ^^^^^^^^^^^^^^^^^^

  [1] sys-kernel/gentoo-sources-5.10.45
2021-07-15 14:11:03 +02:00
Axel Burri eac9ef9828 btrbk: print non-parseable btrfs mountpoint info only once 2021-07-15 14:11:03 +02:00
Axel Burri db4f96ba65 btrbk: add function INFO_ONCE 2021-07-15 14:10:59 +02:00
Axel Burri f5657bffc0 documentation: add -1,--single-column option 2021-07-15 13:50:11 +02:00
Axel Burri 2c19c501a7 btrbk: add "-1,--single-column" command-line option 2021-07-15 13:50:11 +02:00
Axel Burri e82836be47 btrbk: add single_column output format 2021-07-15 13:50:11 +02:00
Axel Burri c06d94543c btrbk: add "backups" output format
Preparatory for single-column patchset.
2021-07-15 13:50:11 +02:00
Axel Burri d80a8abb8a btrbk: add "latest" output format
Same as "resolved", but hides target if none present.
2021-07-15 13:50:11 +02:00
Axel Burri d7902fb30c btrbk: rename action_list table formats 2021-07-15 13:50:11 +02:00
Axel Burri f197a08650 btrbk: tidy table_formats 2021-07-15 13:50:11 +02:00
Axel Burri bd68b15ebc btrbk: tidy print_formatted 2021-07-15 13:50:11 +02:00
Axel Burri 37ef87ddaf btrbk: add url to fs_list raw format 2021-07-15 13:50:11 +02:00
Axel Burri cd69d29705 btrbk: tidy variable name
Duplicate use (not a bug)
2021-07-15 13:50:04 +02:00
Axel Burri 043e270522 btrbk: change version to 0.31.3-dev 2021-05-27 23:26:38 +02:00
Axel Burri 88d4cc76f3 documentation: move to irc.libera.chat 2021-05-27 23:26:38 +02:00
Axel Burri c511fc9dd0 documentation: lsbtr.1: copy --format from btrbk.1 2021-04-20 21:02:51 +02:00
Axel Burri fb792f67a3 documentation: README.md: mention common subvol naming 2021-04-20 21:02:51 +02:00
Axel Burri e6cec73c8f documentation: README.md: mention btr_pool mount point 2021-04-20 21:02:51 +02:00
Axel Burri d2522c5836 documentation: mention preserve all snapshots on errors 2021-04-20 21:02:51 +02:00
Axel Burri e8622fc6be change version to 0.31.2; update ChangeLog 2021-03-21 13:34:26 +01:00
Axel Burri 3ba8c41e2f documentation: README.md: rephrase ssh setup
- move ssh_filter_btrbk down
 - move "further considerations" to "restrict access"
2021-03-21 13:28:18 +01:00
Axel Burri 58212de771 ssh_filter_btrbk.sh: fix alternation regex
Security vulnerability fixed in alternation regex. Specialy crafted
commands may be executed without being propely checked.

Affects all versions >= btrbk-v0.23.0

Regression from:

   ccb5ed5e71 ssh_filter_btrbk: allow "realpath" and "cat /proc/self/mounts" on targets

Reported by: @protree (responsible disclosure)
2021-03-21 13:24:59 +01:00
Axel Burri adc269a3dc documentation: ssh_filter_btrbk: fix required commands 2021-03-20 15:49:08 +01:00
Axel Burri fb11acf991 documentation: README.md: capital words in titles 2021-03-20 15:49:05 +01:00
Axel Burri 7f721afff5 documentation: README.md: improve ssh setup section 2021-03-20 15:46:13 +01:00
Axel Burri c1fa4aa73e documentation: README.md: rephrase time-machine example 2021-03-20 13:56:37 +01:00
Olivier Croquette 3bba963784 documentation: README.md: put simple example first
Until now the main README.md started with a pretty complex example, making
the learning curve unnecessary steep for new users. Start instead with the
simplier example with the local snapshots of 'home'. It was even simplified
a bit more to serve as good introduction, and step-by-step instructions were
added.
2021-03-20 13:56:37 +01:00
Axel Burri ef7ad3205e documentation: README.md: rephrase dryrun recommentation 2021-03-20 13:55:58 +01:00
Axel Burri b8a6aaf799 btrbk: warn if no subvolume is configured 2021-03-18 20:03:03 +01:00
Axel Burri a8341659be btrbk: change version to 0.31.2-dev 2021-03-18 19:56:43 +01:00
Axel Burri 8402195487 change version to 0.31.1; update ChangeLog 2021-03-07 17:49:26 +01:00
Axel Burri 25c5e7b538 btrbk-mail: optionally prefix command output lines
Add configurable prefix for each line of command output. Seems wrong,
but outsmarts the mail clients.

The problem is that some (most?) mail clients outsmart the specs and
replace text/plain mails by quotations, emoticons, emphasis, ...
The only "correct" solution is to disable these features in the mail
client.

Acceptable workaround for #376.
2021-03-07 17:18:39 +01:00
Axel Burri db8cc1cd14 btrbk: collapse empty column in total of action "stats" 2021-02-27 13:26:31 +01:00
Axel Burri 713fe50372 btrbk: add empty_cell_char argument to print_formatted 2021-02-27 13:26:03 +01:00
Axel Burri f3eb1ecb95 documentation: fix changed semantics in action "list snapshots" 2021-02-27 13:26:03 +01:00
Axel Burri fe75b336be documentation: add section for manually renamed snapshots 2021-02-26 19:58:29 +01:00
Axel Burri cee6553a49 btrbk: fix duplicate snapshot location check
If snapshot_create=no, no snapshot is created and thus should be
excluded from "duplicate snapshot locations" check.
2021-02-14 15:05:03 +01:00
Axel Burri 8d25852ce2 btrbk: fix action "list all" 2021-02-14 14:23:17 +01:00
Axel Burri 9c2e4e1ee2 btrbk: change version to 0.31.1-dev 2021-01-16 20:40:49 +01:00
Axel Burri 4c0f7317fd documentation: btrbk.conf.5: cleanup 2021-01-16 19:10:08 +01:00
Axel Burri 87623a80f5 documentation: btrbk.conf.5: fix cache_dir option 2021-01-16 19:10:08 +01:00
Axel Burri 7dc827bdc3 change version to 0.31.0; update ChangeLog 2021-01-10 16:54:53 +01:00
Axel Burri 28e5e08305 bump copyright year 2021-01-10 16:54:50 +01:00
Axel Burri d8f95bb49e documentation: btrbk.1: fix indentation 2021-01-10 16:54:50 +01:00
Axel Burri 82866e5b39 documentation: btrbk.conf.5: add reference to filter statements 2021-01-10 16:23:00 +01:00
Axel Burri d0cf56fb67 documentation: rephrase key features; mention offline storage 2021-01-10 16:23:00 +01:00
Axel Burri 359c240108 documentation: mention action "extents" in key features 2021-01-10 16:22:54 +01:00
Axel Burri ec0d201e2d documentation: btrbk.1: mention lsbtr in action ls 2020-12-31 16:59:57 +01:00
Axel Burri e0b8c0b34f btrbk: consistently return array
While returning an arrayref might be slightly faster, consistently
return an array in all node lookup functions.
2020-12-30 17:57:39 +01:00
Axel Burri 42dd296ce7 btrbk: make related_nodes and correlated_nodes functions operate on nodes only 2020-12-30 17:57:23 +01:00
Lukas Straub dd5991099a btrbk: add suport for zstd long distance matching 2020-12-26 15:46:47 +01:00
Lukas Straub 3562e75a70 btrbk: add support for zstandard (zstd) compression 2020-12-26 15:46:20 +01:00
Axel Burri 3adf2f873b documentation: describe columns of action "diff" 2020-12-21 00:33:23 +01:00
Axel Burri 6cce65e1eb btrbk: remove big header in action "diff" 2020-12-21 00:30:06 +01:00
Axel Burri c7dd838a81 btrbk: simplify action "diff" 2020-12-21 00:20:15 +01:00
Axel Burri d0c5205fcb documentation: custom table format 2020-12-20 20:12:46 +01:00
Axel Burri 2c4827ca9f btrbk: support custom table format 2020-12-20 20:12:20 +01:00
Axel Burri 792c3de6c0 btrbk: separate format for "ist snapshots"
Make sure target_subvolume is always printed for "resolved" format.
2020-12-20 18:32:47 +01:00
Axel Burri 28d4ec6a0b btrbk: print latest snapshot after latest correlated 2020-12-20 18:20:43 +01:00
Axel Burri 7340bdb5d6 contrib: bash: completion.bash: add action "list all" 2020-12-20 18:13:57 +01:00
Axel Burri 497b4e132e contrib: bash: completion.bash: add action "extents" 2020-12-20 18:13:30 +01:00
Axel Burri 4fa6dfde25 btrbk: add target_type to "list config" table 2020-12-20 13:45:30 +01:00
Axel Burri 4f8274b28e btrbk: collapse all target columns for "resolved" format 2020-12-20 13:45:30 +01:00
Axel Burri 1bd902d955 btrbk: collapse host columns for most formats 2020-12-20 13:45:30 +01:00
Axel Burri a414a10448 documentation: adapt "list" command 2020-12-20 13:44:45 +01:00
Axel Burri bba7c06486 btrbk: refactor action list and stats; add "list all" 2020-12-20 13:30:50 +01:00
Gavin Yancey 31475a303f btrbk: look in the correct directory for btrbk list snapshots 2020-12-20 13:27:21 +01:00
Axel Burri 6669855936 btrbk: add source and target url to resolved raw format 2020-12-13 17:33:15 +01:00
Axel Burri 3ff42c60d1 btrbk: move snapshot_preserve column towards target_preserve 2020-12-13 17:29:48 +01:00
Axel Burri 4b7f4f6d81 btrbk: always collapse port and rsh columns 2020-12-13 17:29:05 +01:00
Axel Burri 16746caa16 btrbk: fix target_type column for "list backups" action 2020-12-13 15:07:29 +01:00
Axel Burri 557f2f5387 btrbk: add rsh column to list actions with format=long 2020-12-13 14:42:38 +01:00
Axel Burri bda59056e8 btrbk: more accurate wording on type values for action list
Terminology for "backup" is specified in btrbk(1), use it:

  Backup is a btrbk terminology for a "read-only subvolume created
  with send/receive" (showing a received-uuid).
2020-12-13 14:05:34 +01:00
Axel Burri 33e3dee046 btrbk: fix action origin and ls
Regression:

  a96c613ab8 btrbk: add subvol_args_init: map subvol_args cmdline arguments into vinfo
2020-12-12 21:43:23 +01:00
Axel Burri 53d5536929 btrbk: fix fs_path
Fixes action "origin" and logging.

Regression:

  cc3f6c95b9 btrbk: return array in _fs_path
2020-12-12 21:43:23 +01:00
Axel Burri 8026fa3349 documentation: extents-diff: rephrase extents section 2020-12-12 21:43:23 +01:00
Axel Burri db7e92b134 btrbk: extents-diff: add extents list command 2020-12-12 21:43:23 +01:00
Axel Burri b01a97c36f btrbk: extents-diff: more logging 2020-12-12 21:43:23 +01:00
Axel Burri f9cc5af7b9 btrbk: extents-diff: add ID to long format 2020-12-12 21:43:23 +01:00
Axel Burri 63def23feb btrbk: extents-diff: always display set-exclusive size 2020-12-12 21:43:23 +01:00
Axel Burri e3987866d3 btrbk: extents-diff: fix logging, documentation 2020-12-12 21:43:23 +01:00
Axel Burri 59ee4d6ebf documentation: better extents-diff documentation 2020-12-12 21:43:23 +01:00
Axel Burri 22b71bf7da btrbk: extents-diff: list all related (not only older) 2020-12-12 21:43:23 +01:00
Axel Burri 208fc36231 btrbk: extents-diff: add (hidden) option: ignore_extent_data_inline 2020-12-12 21:43:23 +01:00
Axel Burri 0719fc415d btrbk: cleanup aio extentmap 2020-12-12 21:43:23 +01:00
Axel Burri dc1b7f1b5c extents map: add alternative implementation using IO::AIO (slightly faster) 2020-12-12 21:43:23 +01:00
Axel Burri 70cdcb01c6 btrbk: cosmetics: fix spelling 2020-12-12 21:43:23 +01:00
Axel Burri 74a84f715b btrbk: extents-diff: remove blocksize from regions
`filefrag -b1` effectively calculates byte regions.
2020-12-12 21:43:23 +01:00
Axel Burri 0977cb3184 documentation: btrbk.1: add action "extents-diff" (flagged as experimental) 2020-12-12 21:43:23 +01:00
Axel Burri afd6f80739 btrbk: extents-diff: calculate exclusive size; add "exclusive" option 2020-12-12 21:43:23 +01:00
Axel Burri ea2ec1ceaa btrbk: print_formatted: allow custom format 2020-12-12 21:43:23 +01:00
Axel Burri 7facb44833 btrbk: add extentmap_cache (new cache_dir option) 2020-12-12 21:43:23 +01:00
Axel Burri c6375967b8 btrbk: add action "extents-diff" 2020-12-12 21:43:23 +01:00
Axel Burri 1a96216e7b btrbk: add subvol_args_init: map subvol_args cmdline arguments into vinfo
Preparatory for extents-diff command
2020-12-12 21:43:23 +01:00
Axel Burri a8e82a6b2c btrbk: add extentmap framework (filefrag)
Preparatory for extents-diff command
2020-12-12 21:43:23 +01:00
Axel Burri 3cbcc74bc3 btrbk: run_cmd: add large_output option (suppress stdout dump of command) 2020-12-12 21:43:23 +01:00
Axel Burri 03f7a8113d btrbk-mail: cosmetics: fix documentation 2020-12-02 20:39:33 +01:00
Axel Burri 15d4a01b37 documentation: README.md: rephrase backup from non-btrfs source 2020-12-02 20:39:33 +01:00
Axel Burri 7b652b6227 documentation: strictly use capital letter at beginning of sentence 2020-12-02 20:09:00 +01:00
Asbjørn Apeland ce660a4989 contrib: bash: completion.bash: complete options everywhere 2020-11-01 13:44:46 +01:00
Asbjørn Apeland e4f27632a0 contrib: bash: completion.bash: add completion for lsbtr 2020-10-31 15:41:26 +01:00
Asbjørn Apeland 32c04e0b07 contrib: bash: completion.bash: complete commands 2020-10-31 15:27:50 +01:00
Asbjørn Apeland ae67a670f0 contrib: bash: completion.bash: complete option values 2020-10-31 15:27:50 +01:00
Asbjørn Apeland ac323e8b4b contrib: bash: completion.bash: add Bash completion for options 2020-10-31 15:27:50 +01:00
Axel Burri a99292aba8 btrbk: fix alignment if no header is printed 2020-10-30 19:09:50 +01:00
Axel Burri 528a152d6d btrbk: action "diff": use print framework; convert units 2020-10-30 19:09:26 +01:00
Axel Burri 4866ec5cb0 btrbk: add print_size, and command line option modifier 2020-10-30 18:35:52 +01:00
Xiretza f391c92d60 Makefile: fix race condition in `make install`
If run with -j, it's possible for install-bin-links to run before
install-bin and subsequently fail because $(BINDIR) hasn't been created
yet.
2020-10-30 16:43:02 +01:00
Axel Burri 81c92940c1 btrbk: fix unitialized value in warning
Regression from: 5c32ced7d6
2020-10-19 00:34:11 +02:00
Axel Burri eb852271b6 btrbk: change version to 0.30.1-dev 2020-10-19 00:33:20 +02:00
Axel Burri f40e3adce3 change version to 0.30.0; update ChangeLog 2020-09-23 15:48:44 +02:00
Axel Burri 838e132942 Makefile: change BINDIR from "/usr/sbin" to "/usr/bin"
With "backend btrfs-progs-btrbk" and "backend btrfs-progs-sudo", btrbk
does not necessarily need to be run as root.
2020-09-23 14:37:42 +02:00
Axel Burri 4d1b911947 documentation: btrbk.conf.5: clarify preserve_min 2020-09-23 12:59:50 +02:00
Axel Burri 373add933a documentation: bump distro repository names 2020-09-23 12:59:50 +02:00
Axel Burri e605bc7b42 btrbk: add backend_local_user config option 2020-09-23 12:59:50 +02:00
Axel Burri 13708abd00 btrbk: consequently fence all trace logs (for performance) 2020-08-29 13:29:17 +02:00
Axel Burri 5d81632b5d btrbk: cosmetics on logging 2020-08-29 13:28:32 +02:00
Axel Burri 5c32ced7d6 btrbk: show paths from all mounts in fs_path; add _fs_info node resolver
Reference complete mountinfo in nodes, instead of { file, subvolid }.
2020-08-29 13:28:32 +02:00
Axel Burri cc3f6c95b9 btrbk: return array in _fs_path 2020-08-29 13:28:32 +02:00
Axel Burri fbfd1edc3d btrbk: move mount info to front in fs_list table format 2020-08-29 13:28:32 +02:00
Axel Burri 739645444e btrbk: dont show subvolume_rel_path in fs_list table format 2020-08-29 13:28:32 +02:00
Axel Burri 9415214bc0 btrbk: reword/fix verbose and loglevel options 2020-08-29 13:28:32 +02:00
Axel Burri 670170c3db documentation: add lsbtr man page 2020-08-29 13:07:57 +02:00
Axel Burri ec9998e866 btrbk: add lsbtr symlink 2020-08-29 13:07:57 +02:00
Axel Burri 3b2fad928b Makefile: create "lsbtr" symlink on "install" build target 2020-08-29 13:07:57 +02:00
Axel Burri 910274f814 btrbk: support lsbtr symlink (alias for "btrbk ls")
If called via "lsbtr" symlink (program name):

 - Provide user-friendly table options
 - Assume "./" as path if no path arguments are given
2020-08-29 13:07:57 +02:00
Axel Burri dff05bc6d7 documentation: README.md: add common rsync options 2020-08-29 12:34:49 +02:00
Axel Burri c2308a52a6 btrbk-mail: add more elaborated email and rsync options
- If rsync is enabled, show number of created/deleted/transferred
  files in mail subject.
- Add options to show summary and/or detail message in mail body.
- Add option to skip btrbk if no files were transferred via rsync.
- Add option to call sync(1) prior to running btrbk.
- Add option to skip btrbk execution if no files were transferred.
2020-08-29 12:31:18 +02:00
Axel Burri ec037952cf btrbk: add "compat" config option (busybox: add test -d command)
Add compat, compat_local, compat_remote configuration options.

Used for busybox: instead of running `readlink -e` (which is not
available on busybox), run `readlink -f` followed by `test -d`.
2020-08-28 21:19:21 +02:00
Axel Burri 52a823bb93 btrbk: rename context "root" to "global"
Use same naming as in documentation: btrbk.conf.5
2020-08-28 20:49:28 +02:00
Axel Burri c81e390415 btrbk: cosmetics: capitalize debug logs 2020-08-28 20:48:17 +02:00
Axel Burri a140cbd898 btrbk: case-insensitive match hostname/ipv6 in filter statement 2020-08-27 10:38:23 +02:00
Axel Burri 61419d420a btrbk: add support for ipv6 addresses 2020-08-27 10:38:23 +02:00
Axel Burri 2f7e79ace6 documentation: mention up-to-date status 2020-08-20 18:53:46 +02:00
Axel Burri 12d80ee30b btrbk: fix check on host 2020-08-20 17:02:45 +02:00
Axel Burri b80d7e84de btrbk: cosmetics on logging 2020-08-20 17:02:45 +02:00
Axel Burri 952e41443a btrbk: always log target before source
Consistent for send/receive and send-to-raw.
2020-08-20 17:01:25 +02:00
Axel Burri c11ab1507d btrbk: sanitize url on PRINT
For consistency with PATH and URL, $vol->{PRINT} was not sanitized
(trailing "//" if parent is "/"). This is now dropped, as this is more
confusing than useful.
2020-05-24 02:48:12 +02:00
Axel Burri 936f88a68f btrbk: action ls: support url argument; fix duplicates / sorting 2020-05-24 02:48:00 +02:00
Axel Burri 30edf5b766 btrbk: action ls: fix match on child subvols of "/"
If PATH contains double slash (intentional behavior of vinfo_child),
the match on root_path fails. Fixed by removing "//" from path.
2020-03-07 01:11:52 +01:00
Axel Burri cb7d49d075 btrbk: change version to 0.29.2-dev 2020-02-29 17:40:55 +01:00
Axel Burri e920283434 change version to 0.29.1; update ChangeLog 2020-02-09 16:18:00 +01:00
Axel Burri 73b339fe01 documentation: fix spelling 2020-02-09 16:14:50 +01:00
Axel Burri d9e9f01e51 documentation: README.md: rewrite "restoring backups" chapter 2020-01-07 23:16:44 +01:00
Axel Burri 0c77219a62 documentation: README.md: fix backup restore example
Especially dont recommend deleting the transferred subvolume, this
would break incremental chain for subsequent backups.
2020-01-05 00:04:55 +01:00
Axel Burri 1b533f2340 documentation: README.md: add instructions for downloading latest master 2020-01-02 17:59:20 +01:00
Axel Burri c03e960d90 ssh_filter_btrbk.sh: exclude "btrfs subvolume show|list" from restrict-path
btrbk requires "btrfs subvolume list|show" queries from the mount
point in order to build btrfs trees. This conflicts with tightly set
--restrict-path.
2020-01-02 17:56:03 +01:00
Axel Burri 5407b863df documentation: btrbk.1: add missing option -L, --long 2020-01-02 16:58:07 +01:00
Axel Burri 0d19b0243e btrbk: action ls: change default output to format=short 2020-01-02 16:58:07 +01:00
Axel Burri c5b3ebb808 btrbk: action ls: allow multiple path arguments; soft fail on errors 2020-01-02 16:58:07 +01:00
Axel Burri 73c24e0495 documentation: btrbk.conf.5: explain stream_buffer_remote 2020-01-02 16:58:07 +01:00
Axel Burri 631a4c30fe btrbk: fix @stderr propagation from vinfo_init_root
As we print @stderr in warnings if vinfo_init_root() function fails,
we need to make sure that @stderr contains sane values.

Clearing @stderr is required when calling caching functions!
2019-12-15 20:03:37 +01:00
Axel Burri 67d24695f1 btrbk: logging prints "..." on consecutive lines 2019-12-15 20:03:37 +01:00
Axel Burri 1f7773dddc btrbk: try readlink only once per url
Change semantics of %realpath_cache: if "" (empty string), do not try
to run readlink shell command again on same URL.
2019-12-15 19:12:14 +01:00
Axel Burri 8c11c2eb7d btrbk: run_cmd: fix regression: dont print ssh errors
Explicitely printing ssh errors (or even warnings) is
inconsistent. stderr is printed outside the run_cmd framework if
needed.

reverts a80e05984a btrbk: catch ssh errors

See ssh(1):

    ssh exits with the exit status of the remote command or with 255
    if an error occurred.

Note that this includes network errors as well as dns failures
2019-12-15 19:12:06 +01:00
Axel Burri 9e13dbd933 btrbk: init sroot as late as possible when expanding wildcards 2019-12-15 19:10:01 +01:00
Axel Burri 37b30caeb2 btrbk: bugfix: vinfo_match: skip match against invalid paths
Dont check url_regex if $vinfo->{URL} is not a valid path (e.g. when
checking against a "volume" or "subvolume" having wildcards):

    "Use of uninitialized value in join or string" at line 3030
2019-12-14 17:06:15 +01:00
Axel Burri c36890e1eb btrbk: change version to 0.29.1-dev 2019-12-14 17:05:54 +01:00
Axel Burri a447c4b939 documentation: btrbk.conf.5: add note about ssh_compression / stream_compress relation 2019-12-07 14:07:56 +01:00
asymmetric 3694a38670 documentation: README.md: replace pv with mbuffer
Since 0.29, mbuffer is used instead of pv.
2019-10-30 18:24:35 +01:00
Axel Burri b64ffbacf5 change version to 0.29.0; update ChangeLog 2019-10-27 14:00:40 +01:00
Ryan Young 0f21df15c2 ssh_filter_btrbk.sh: whitelist mkdir for 'btrbk archive' operations 2019-10-27 12:24:00 +01:00
Asbjørn Apeland 2d7f5ec5fe contrib: systemd: btrbk.timer: change install target
Using `WantedBy=multi-user.target` makes boot wait for btrbk.service
before it's considered "finished". This can be checked by running
`systemd-analyze` or checking the system log using `journalctl`.

Timers should use the "timers.target" target, see systemd.special(7).
2019-10-27 12:24:00 +01:00
Axel Burri a109a58b35 documentation: btrbk.1: cosmetics 2019-09-08 18:23:30 +02:00
Axel Burri 3631cf6c7f ssh_filter_btrbk.sh: cosmetics: show unsafe character 2019-09-08 18:23:30 +02:00
Axel Burri 8551a9f52a btrbk: consistently use "subvolume" (instead of "subvol") for table headings 2019-09-08 18:23:30 +02:00
Axel Burri 5e87e8248b btrbk: add --pretty option: print lowercase column headings with separator line 2019-09-08 18:23:30 +02:00
Axel Burri 4629d5ae11 btrbk: change table output format: remove separator line, uppercase column headings
Print table output column headings single-line uppercase instead of
lowercase and underlined.

This is common ascii table format, is easy parseable and offers better
readability e.g. in pager.
2019-09-08 18:23:30 +02:00
Axel Burri 485bc3ab0c btrbk: use global stderr (replace err); refeactor filter_stderr, add fatal_stderr
if fatal_stderr is set and returns true, the command exit code is set
to -1, resulting in run_cmd() returning undef.
2019-09-08 18:23:30 +02:00
Axel Burri 360c8918bb btrbk: catch verbose errors from readlink
readlink -v enables "report error messages", printing useful errors
like:

    readlink: /some/dir/: Permission denied
    readlink: /some/dir/: No such file or directory
2019-09-08 18:23:30 +02:00
Axel Burri 6e4aeae323 btrbk: cosmetics: enhance trace log 2019-09-08 18:23:30 +02:00
Axel Burri d0f0c18f64 btrbk: logging functions take array as argument 2019-09-08 18:23:29 +02:00
Axel Burri fa3334cbb7 btrbk: btrfs_subvolume_list_readonly_flag: dont die on parse errors 2019-09-08 18:23:29 +02:00
Axel Burri 3798677893 btrbk: run_cmd: return array of stdout lines instead of scalar 2019-09-08 18:23:29 +02:00
Axel Burri 6227bb591a ssh_filter_btrbk.sh: return exit status 255 on error
This makes btrbk regard ssh_filter_btrbk errors as ssh errors, as ssh
also returns exit status 255 if an error occurred.
2019-09-08 18:23:29 +02:00
Axel Burri 4e39ed0fca btrbk: print ssh errors (remove -q option) 2019-09-08 18:23:29 +02:00
Axel Burri 9f347a1067 btrbk: use open3 in run_cmd: fetch stderr separately 2019-09-08 18:23:29 +02:00
Axel Burri a80e05984a btrbk: catch ssh errors 2019-09-08 18:23:29 +02:00
Axel Burri df471c3692 btrbk: refactor filter_stderr; more flexible error handling in run_cmd; simplify btrfs_subvolume_delete parsing 2019-09-08 18:23:29 +02:00
Axel Burri 8434c6881c btrbk: system_list_mountinfo: also fetch mount_options (not only super_options)
This should have no impact on current code: "subvol" and "subvolid"
are used, which are only in super_options.
2019-09-08 18:23:29 +02:00
Axel Burri 8570ee585d btrbk: fix backup summary: dont display no_action if volume is skipped by --exclude or noauto
The backup summary does not print "<no_action>" if a subvolume is
skipped by --exclude or noauto. Alas, skipped volumes results in
no_action still being printed (see #291). Adding an additional
IS_ABORTED($sroot, "skip_") check fixes this issue.
2019-09-07 13:44:25 +02:00
Axel Burri 2c9f1389a0 btrbk: fix vinfo() prototype; remove dead code; fix scheduler text; fix action diff header text 2019-08-07 21:35:54 +02:00
Axel Burri 4845bc6691 btrbk: print_formatted: fix skip-row-if-empty for --print-schedule
Fix: dont modify "-" %table_formats hash key.

fixes 716d420a40 btrbk: print_formatted: add skip-row-if-empty functionality for table_formats
2019-08-06 17:29:45 +02:00
Axel Burri 3ea7746700 btrbk: cosmetics: separate get_btrbk_date function 2019-08-05 15:15:55 +02:00
Axel Burri ac175c0093 btrbk: cosmetics: rename timestamp_postfix_match -> btrbk_timestamp_match
Take separator match "\." out of statement:

    $timestamp_postfix_match == \.$btrbk_timestamp_match

Remove/Fix unneeded "timestamp" hash key (dead code).
2019-08-05 15:15:55 +02:00
Axel Burri 8b93ef7c82 btrbk: fix fallback_default_config
- add for action-archive
- exit if config is present but has parse errors
2019-08-05 15:15:55 +02:00
Axel Burri 3e40903720 btrbk: add btrbk archive --raw option 2019-08-05 15:15:30 +02:00
Axel Burri dcc57abac4 btrbk: archive: also apply exclude patterns on source subvolumes
Allows patterns like "svol.2019*".

Needs @exclude_vf to be a global variable, which is ok as this only
holds command-line args (and global context for archive_exclude).

Note that adding the same in "create backups" (action run) and
macro_delete() is not a good idea, as this has weird implications on
the "forced: last" snapshot/backup pair.
2019-08-05 14:55:38 +02:00
Axel Burri 6e55e08db7 btrbk: add archive_exclude_older option: skip resume of old backups 2019-08-05 14:55:38 +02:00
Axel Burri 97240de0c9 btrbk: add -L, --long options (shortcut for --format=long) 2019-08-05 14:54:04 +02:00
Axel Burri 66d15d1d64 btrbk: action "ls": add mount_subvol column to long formats 2019-08-05 14:54:04 +02:00
Axel Burri e297d37560 ChangeLog: adapt migration instructions for stream_buffer and rate_limit 2019-08-05 14:54:04 +02:00
Axel Burri 8d0d7edda7 ssh_filter_btrbk.sh: adaptions, use mbuffer for rate_limit 2019-08-05 14:54:04 +02:00
Axel Burri c9fb366d09 btrbk.conf.example: suggest stream_buffer=256m; adapt text; add links 2019-08-04 23:08:11 +02:00
Axel Burri 06a7a53fee documentation: btrbk.conf.5: add rate_limit_remote, fix stream_buffer / rate_limit text 2019-08-04 23:08:11 +02:00
Axel Burri 0435f32619 btrbk: add stream_buffer_remote, rate_limit_remote; run stream_buffer only on local host
Change sematics of stream_buffer: If set, run on local host only. If a
remote stream buffer is required, use stream_buffer_remote /
rate_limit_remote.
2019-08-04 23:08:11 +02:00
Axel Burri 73108d2309 btrbk: fix: "readonly" is required key for "btrfs subvolume show" output
The "Flags: readonly|-" line is present as of btrfs-progs v4.6.1, and
is required in "target metadata check" of btrfs_send_receive().
2019-08-04 13:52:45 +02:00
Axel Burri 74be074e6f btrbk: remove warnings on superfluous "btrfs subvolume show" output
Silently accept compatible versions of btrfs-progs. Required keys are
being checked below, no need to warn here.

e.g. btrfs-progs >= v5.2.1 prints:

    Quota group:            0/258
      Limit referenced:     -
      Limit exclusive:      1.00GiB
      Usage referenced:     16.00KiB
      Usage exclusive:      16.00KiB
2019-08-04 13:29:39 +02:00
Axel Burri 7d656540d7 btrbk: fix btr_tree for subvolumes containing special (unsafe) characters
Note that any action (e.g. btrfs send -p) on a subvolume with unsafe
characters will still fail with:

    ERROR: Unsafe command [...] (offending string: "/tmp/btrfs_pool/svol with spaces")
2019-07-31 13:44:30 +02:00
Axel Burri 10b826b5f3 documentation: btrbk.1: add action "ls" 2019-07-28 19:03:42 +02:00
Axel Burri 7271732f9e btrbk: add action "ls": list all btrfs subvolumes below path
Features:

 - get mounted filesystems from /proc/self/mountinfo
 - fetch subvolumes using "btrfs subvolume list" (fast, needs root)
 - filter and print subvolumes below mount point
2019-07-28 19:03:19 +02:00
Axel Burri d88221e8bc btrbk: add fallback_default_config action option, use for action "diff"
Preparatory for action "ls"
2019-07-28 19:03:19 +02:00
Axel Burri 381a12241b btrbk: add dir_args: relative path arguments for actions reqiring directories
Preparatory for action "ls".
2019-07-28 19:03:19 +02:00
Axel Burri 217317b274 ChangeLog: add migration instructions; add mbuffer changes 2019-07-28 17:25:34 +02:00
Axel Burri dc14611911 documentation: adapt rate_limit and --progress text 2019-07-28 17:25:34 +02:00
Axel Burri 9dc717c701 btrbk: use mbuffer instead of pv; add stream_buffer_sink framework
Add run_cmd option stream_buffer_sink, which handles stream_buffer,
rate_limit as well as --progress.

For rate limiting, run "mbuffer" (on the target host) in combination
with stream_buffer and --progress, instead of running "pv" (on the
source host).

Reasons:

 - mbuffer limits the read rate: For remote targets, we want a stream
   buffer in front of the rsh command pipe, before decompression.
 - For local targets, this can be combined with --process.
 - Combined stream_buffer and rate_limit: less commands in pipe.

Further changes:

 - always set mbuffer -v1 option (never show warnings)
 - restrict raw_target_block_size to "kmgKMG": compatibility to
   stream_compress and rate_limit options, simplicity.
 - use mbuffer blocksize option where applicable
2019-07-28 17:25:34 +02:00
Axel Burri c7a8d0bb11 btrbk: fix naming: compress_cmd -> compress_cmd_text 2019-07-28 17:25:34 +02:00
Axel Burri cf2c314627 btrbk: change version to 0.29.0-dev 2019-07-28 17:25:34 +02:00
Axel Burri 23770f2e67 change version to 0.28.3; update ChangeLog 2019-07-28 15:43:14 +02:00
Axel Burri 8ffd7ac1e9 btrbk: fix mount point resolving
Searching for longest match in mountinfo is plain wrong, as it is
possible (while very uncommon) to have a later mount point shadowing a
longer mount.
2019-07-18 15:34:52 +02:00
Axel Burri fb3d4d96ff btrbk: action origin: print uuid of unknown subvolumes 2019-07-15 18:36:12 +02:00
Axel Burri 5afa270577 btrbk: action origin: correctly handle root subvolumes having uuid 2019-07-15 18:36:06 +02:00
Axel Burri 8de7f45e89 btrbk: remove dead code
setting info{ERROR} does not make sense if info hash is not pushed to
SUBVOL_RECEIVED.

as of: c06bca17
2019-07-15 18:31:07 +02:00
Axel Burri e7787e8a44 btrbk: replace "unrecoverable" hack by FIX_MANUALLY framework 2019-07-15 18:28:31 +02:00
Lubos Kolouch 836efa472b btrbk: return error code 10 if unrecoverable problem
https://github.com/digint/btrbk/issues/285
2019-07-15 18:03:02 +02:00
Axel Burri aaef1cd1e9 btrbk: change version to 0.28.3-dev 2019-07-15 17:50:50 +02:00
Axel Burri 31c25d0ee2 change version to 0.28.2; update ChangeLog 2019-05-23 14:11:33 +02:00
Axel Burri 0439e6079f btrbk: fix vinfo_resolved
Fix for rare cases:
- fix for paths named "0"
- return undef if not strictly below $vol (or allow_equal is set)
2019-05-23 13:14:07 +02:00
Axel Burri 461eaada66 btrbk: rename "get_related_readonly_nodes" to "get_related_nodes"; add readonly and omit_self options 2019-05-23 13:14:07 +02:00
Axel Burri f169ab4482 btrbk: cosmetics: test loglevel before dumping cmd return value (performance) 2019-05-23 13:12:45 +02:00
Axel Burri 45b487707f btrbk: honor incremental_resolve on targets (fix: defaults to "mountpoint" instead of "directory")
Use $resolve_droot instead of $droot for calls to get_best_correlated
(probably missed commit), same as $resolve_sroot.

Fixes possible regression of:

514e69243a btrbk: add "incremental_resolve" configuration option
2019-05-19 19:01:50 +02:00
Axel Burri 01230cde22 btrbk: bugfix: add missing (fake) mountpoint for raw targets
For raw targets, get_best_parent() dies as VINFO_MOUNTPOINT is not
defined on raw vinfo.

Fixes regression of:

d64e237e94 btrbk: get_best_parent: consider all parent/child relations
2019-05-19 15:27:27 +02:00
Axel Burri 538dab5396 btrbk: change version to 0.28.2-dev 2019-05-19 15:17:37 +02:00
Axel Burri f132c94c65 change version to 0.28.1; update ChangeLog 2019-05-16 17:16:52 +02:00
Axel Burri ef69f1ffee documentation: remove pre-generated man pages
Package maintainers like to build everything from scratch, removing
overhead. Again, we apologize for the inconvenience.

Note that reproducible builds are still guaranteed by setting
SOURCE_DATE_EPOCH in doc/Makefile.

Reverts: a6dbd60e5a documentation: add pre-generated man pages: from groff to asciidoc and back again
2019-05-16 17:06:15 +02:00
Axel Burri f54853dd18 btrbk: cosmetics (trace logs) 2019-05-16 17:01:51 +02:00
Axel Burri 10bde449c6 btrbk: remove obsolete "resolve_subdir" option of vinfo_init_root
Removed in: b37ef84e36 btrbk: always read mountpoints
2019-05-16 17:01:51 +02:00
Axel Burri b62bb3b1a8 btrbk: get_related_readonly_nodes: vastly increase abort_distance
It's not uncommon to have a large intact parent-chain on targets
(e.g. target_preserve_min=all).

If this is the case, performance drops a bit on "btrbk archive".
Note that we could limit the search depth in get_best_parent() for
some performance improvements, as this only affects extra clones.
2019-05-03 16:13:24 +02:00
Axel Burri 37b0bd3477 btrbk: bugfix: make get_related_readonly_nodes non-recursive
Perl hates recursions, and dies if recursion depth = 100:

    Deep recursion on subroutine "main::_push_related_children"

Unfortunately this happens before the implemented abort condition
(distance=256).

Fixed by re-implementing get_related_readonly_nodes() non-recursive.

Refs: https://github.com/digint/btrbk/issues/279
2019-05-03 16:10:41 +02:00
Axel Burri 206e706d85 btrbk: allow overriding options with context restrictions
This allows commands like:

    btrbk run mysubvol --override=snapshot_name=mysubvol-oneshot
2019-04-30 13:38:47 +02:00
Axel Burri 3d169d1df4 btrbk: change version to 0.28.1-dev 2019-04-30 13:38:33 +02:00
Axel Burri a6dbd60e5a documentation: add pre-generated man pages: from groff to asciidoc and back again
This reduces build-time dependencies to zero, helping package
maintainers and providing reproducible builds.

NOTE: generated man pages will only be updated on releases. In order
to make sure the docs are correctly rebuilt, run "make clean man". We
apologize for the inconvenience.

From Groff to Asciidoc and Back Again [1]
=========================================

| Comparison                                                               | Links                                                                                                          |
| -------------------------------------------------------------------------| -------------------------------------------------------------------------------------------------------------- |
| **Plain ROFF**                                                           |                                                                                                                |
| +++ Best result for `man` (our main goal!)                               |                                                                                                                |
| - Not supported by github                                                | [btrbk(1) v0.25.1 in plain groff](https://github.com/digint/btrbk/blob/v0.25.1/doc/btrbk.1)                    |
| - No decent converters: e.g. `groff -Txhtml -mandoc`                     | [btrbk(1) v0.25.1 at digint.ch (official site)](https://digint.ch/btrbk/doc/archive/btrbk-0.25.1/btrbk.1.html) |
|                                                                          |                                                                                                                |
| **asciidoc**                                                             |                                                                                                                |
| + Decent (scriptable!) html                                              | [btrbk(1) v0.26.1 at digint.ch (official site)](https://digint.ch/btrbk/doc/archive/btrbk-0.26.1/btrbk.1.html) |
| + Supported by github (helps contributors writing decent documentation)  | [btrbk.1.asciidoc v0.26.1 at github](https://github.com/digint/btrbk/blob/master/doc/btrbk.1.asciidoc)         |
|                                                                          |                                                                                                                |
| **asciidoc (`xmlto`, `atx`)**                                            | http://asciidoc.org/                                                                                           |
| + Good result for `man`                                                  |                                                                                                                |
| - EOL (why care that much? it works fine!)                               | [asciidoc EOL notice at github](https://github.com/asciidoc/asciidoc/releases/tag/8.6.10)                      |
|                                                                          |                                                                                                                |
| **asciidoc (`asciidoctor`)**                                             | https://asciidoctor.org                                                                                        |
| - Pulls in tons of ruby (build depends)                                  | https://bugs.gentoo.org/681056                                                                                 |
| -- Implies to commit a pre-converted `doc/btrbk.1`                       |                                                                                                                |
| + Seems more evolved than `xmlto`, still actively maintained             |                                                                                                                |
|                                                                          |                                                                                                                |
| **rst (`xrst2man.py` from docutils)**                                    |                                                                                                                |
| - Worse result for `man`                                                 |                                                                                                                |
| ++ Good html converters (after having a quick look at it)                |                                                                                                                |
| - Not so well supported by github                                        | [btrbk.1.rst v0.26.1 at github](https://github.com/digint/btrbk/blob/rst2man/doc/btrbk.1.rst)                  |

 [1] https://github.com/digint/btrbk/pull/219 (edited)
2019-04-24 19:45:54 +02:00
Axel Burri fc485565ce change version to 0.28.0; update ChangeLog 2019-04-24 19:45:09 +02:00
Axel Burri 5b34f620aa documentation: reproducible builds: set SOURCE_DATE_EPOCH to "📅" tag 2019-04-24 19:41:14 +02:00
Axel Burri e3176a0027 documentation: asciidoc: add "release-version" attribute, and append it to "man source" attribute 2019-04-24 19:41:14 +02:00
Axel Burri 818cc42d9b documentation: Makefile: dont compress documentation by default
Many (all?) distro builds scripts want to do compression by their own.
2019-04-24 19:41:14 +02:00
Axel Burri 173319e7e1 documentation: Makefile: always build using asciidoctor (remove a2x)
Remove support for man page generation using asciidoc "a2x": The
project is discontinued, and depends on Python 2.7.

As we will provide pre-generated man pages as of btrbk-0.28.0, this is
not needed any more.
2019-04-24 19:40:59 +02:00
Axel Burri d231a955ce documentation: btrbk.conf.5: cosmetics: replace tabs with whitespace 2019-04-24 19:22:30 +02:00
Axel Burri fe9ce255c5 remove experimental tag on "btrbk archive" 2019-04-24 19:22:30 +02:00
Axel Burri 725a284f16 documentation: README.md: adapt indentation in examples 2019-04-24 19:22:30 +02:00
Axel Burri f5c7c74108 documentation: simplify examples, remove optional "send-receive" on "target" declarations 2019-04-24 19:22:29 +02:00
Axel Burri cb1c12a6c1 documentation: btrbk.conf.5: more comprehensive text on "target" declaration 2019-04-24 13:52:05 +02:00
Axel Burri 6115cbdace btrbk: make target_type optional for "target" section 2019-04-24 13:51:52 +02:00
Axel Burri 50267f1ca9 documentation: btrbk.conf.5: add warning on old versions of mbuffer 2019-04-24 12:53:19 +02:00
Axel Burri e7793d9e06 documentation: README.md: add example command line for quick additional snapshot 2019-04-20 14:51:31 +02:00
Axel Burri 88b737d4b7 documentation: README.md: add multiple groups in virtual machine setup 2019-04-20 14:49:05 +02:00
Axel Burri 32d92ff3b7 btrbk: allow space separated groups 2019-04-20 14:05:42 +02:00
Axel Burri 0a2c5dbfb3 btrbk: use transaction for mkdir (cosmetics)
Prints correct "dryrun_success" (instead of "DRYRUN") in transaction
log.
2019-04-18 17:28:15 +02:00
Axel Burri 3d2936d40c btrbk: fix regression for "btrbk archive -n"
resolve by mountpoint needs VINFO_MOUNTPOINT, which was not inserted
on fake mkdir:

514e69243a btrbk: add "incremental_resolve" configuration option
2019-04-18 17:24:38 +02:00
Axel Burri e36289a769 btrbk: use "archive_target" config context for archives
Distinguish normal "target" and (generated) "archive_target"
configuration context (printed in transaction log for
"abort_<context>" actions).
2019-04-18 16:40:25 +02:00
Axel Burri a7da44cf2f btrbk: bugfix: print aborted subvolumes to transaction log
Print all (deferred) actions to transaction log (file, syslog) in
init_transaction_log(), e.g. ABORTED() in "expand subvolume globs".
2019-04-18 16:28:53 +02:00
Axel Burri 25f0a76e28 btrbk: cosmetics: fix error message 2019-04-18 16:28:45 +02:00
Axel Burri 45b24d6477 documentation: btrbk.1: add "exclude" command line option 2019-04-18 15:09:15 +02:00
Axel Burri 14b5edcf68 documentation: btrbk.1: update filter statements section 2019-04-18 15:09:15 +02:00
Axel Burri 95819f03ea documentation: btrbk.1: cosmetics: same order for options in all docs 2019-04-18 15:09:15 +02:00
Axel Burri 66004aeae8 documentation: btrbk.conf.5: add "noauto" option 2019-04-18 15:09:15 +02:00
Axel Burri b6da6b0158 documentation: btrbk.conf.5: cosmetics, delete empty line 2019-04-18 15:09:15 +02:00
Axel Burri b2f434b396 btrbk: add "exclude" command line option 2019-04-18 15:09:15 +02:00
Axel Burri f0cff5ee5a btrbk: add vinfo_filter_statement framework 2019-04-18 15:09:15 +02:00
Axel Burri 6e7d649588 btrbk: add "noauto" configuration option 2019-04-18 15:09:15 +02:00
Axel Burri ae004e48fd btrbk: map empty value to "yes" in configuration 2019-04-18 15:09:15 +02:00
Axel Burri 1503a07ad1 btrbk: enhance ABORTED framework (distinguish skipped and aborted) 2019-04-18 15:09:15 +02:00
Axel Burri 4224577960 btrbk: distinguish filter_args and subvol_args
preparatory for noauto and exclude options
2019-04-18 15:09:11 +02:00
Ian Kelling ce15c19e44 Clarify license is gpl version 3 or later
https://www.gnu.org/licenses/identify-licenses-clearly.en.html
2019-04-16 11:04:16 -04:00
Axel Burri ff23e9605b btrbk: cosmetics: fix snapshot create debug log
Add additional log line, containing context for subsequent lines
2019-04-12 21:04:49 +02:00
Axel Burri 5697c38e4a btrbk: globally rename snapshot_children to related_snapshots
As a consequence, also rename $child -> $snapshot
2019-04-12 21:04:49 +02:00
Axel Burri 0a93f69135 btrbk: treat all related readonly subvolumes within snapdir as "snapshots"
With this, previous snapshots (far relations) are still listed when
restoring a snapshot.

Example (S = source subvolume, readwrite):

  After 3 snapshots:
  A->S, B->S, C->S

  Restore B: `btrfs subvol delete S; btrfs subvol snapshot B S'`
  A->S, B->S, C->S, S'->B

Previous implementation would show now snapshots for S', as no
snapshot has parent_uuid=S'.

New implementation shows A, B, C as snapshots for S', as orphaned
siblings (A, B, C pointing to deleted S) are also related.
2019-04-12 21:04:48 +02:00
Axel Burri adfdf925e2 btrbk: add btrbk_direct_leaf option for vinfo_resolved() 2019-04-12 21:04:48 +02:00
Axel Burri 318126b831 btrbk: disallow unrelated (by parent_uuid) parents for btrfs-send if incremental=strict
Makes sure that if, for whatever reason, a subvolume having correct
btrbk name scheme does NOT share any extents with previous snapshots
is never used as parent.

Note that if a related parent is found, the unrelated closest
older/newer (by btrbk timestamp) subvolumes are still added as clone
sources.
2019-04-12 21:03:40 +02:00
Axel Burri c407d41db2 btrbk: unconditionally add clone sources to btrfs-send if necessary
Preferences for parent (and required clone sources):

 1. closest older in snapdir (by btrbk timestamp), related
 2. closest older related (by cgen)
 3. closest newer related (by cgen)
 4. closest older in snapdir (by btrbk timestamp)
 5. closest newer in snapdir (by btrbk timestamp)

Note: prefering 1 over 2 helps keeping parent-chain within droot on
target (assuming that btrfs always uses correlated parent on
btrfs-receive).

This will e.g. add a clone source on "btrbk resume", if both older AND
newer snapshot/backup pairs exists.

Also makes sure that the closest older btrbk snapshot is always added
as clone source, even if another related subvolume has newer cgen.
2019-04-11 16:19:48 +02:00
Axel Burri 95e25eb2d1 btrbk: fix get_related_subvolume_nodes: add all parents and orphaned siblings
Old implementation was missing last readonly parent in chain, as well
as orphaned siblings.

Also sort all by cgen, not by distance, then cgen.

Also skip self.
2019-04-11 16:16:00 +02:00
Axel Burri 20c390893a btrbk: honor multiple -v command line options (increase loglevel) 2019-04-05 19:29:37 +02:00
Axel Burri 3a753c9140 ChangeLog: add missing changes on btrbk-master (since 0.27.2) 2019-04-05 12:29:47 +02:00
Axel Burri 44edc97aef btrbk: add "incremental_clones" configuration option (btrfs-send <clone-src>) 2019-04-05 12:06:41 +02:00
Axel Burri f38c69316f btrbk: get_best_parent(): add clone_src argument 2019-04-05 12:05:46 +02:00
Axel Burri 7cf1bfb354 btrbk: rename functions (use "correlated" where applicable)
_receive_target_nodes   -> _correlated_nodes
get_best_receive_target -> get_best_correlated_target
2019-04-05 12:05:46 +02:00
Axel Burri ce81350df0 btrbk: remove unused function: vinfo_subvol_list_all_accessible() 2019-04-05 12:05:46 +02:00
Axel Burri 514e69243a btrbk: add "incremental_resolve" configuration option
Allowed values for "incremental_resolve":

 - "mountpoint" (default): Use parents in the filesystem tree below
   mount points of source `<volume-directory>/<snapshot-dir>` and
   target `<target-directory>`.

 - "directory": Use parents strictly below source/target
   directories. Useful when restricting access, e.g. when using
   ssh_filter_btrbk.sh.

 - "_all_accessible" (experimental): Use parents from all mount points.

Note that using "_all_accessible" causes btrfs-progs to fail:

  - btrfs send -p: "ERROR: not on mount point: /path/to/mountpoint"
  - btrfs receive: "ERROR: parent subvol is not reachable from inside the root subvol"

see also: https://github.com/kdave/btrfs-progs/issues/96
2019-04-05 12:05:46 +02:00
Axel Burri d64e237e94 btrbk: get_best_parent: consider all parent/child relations 2019-04-05 12:05:46 +02:00
Axel Burri cb23c65eed btrbk: get_related_subvolumes: add direct children from parent chain 2019-04-05 12:05:46 +02:00
Axel Burri ad91b6f618 Makefile: add contrib/cron/btrbk-verify 2019-04-05 12:05:46 +02:00
Axel Burri c1268cdd66 btrbk: table_format "transaction": make "*host" and "*port" keys skip-row-if-empty (for consistency) 2019-04-04 17:09:59 +02:00
Axel Burri 2e51de1047 documentation: README.md: add example: virtual machine setup 2019-04-01 20:12:38 +02:00
Axel Burri cba4a93152 btrbk: table_formats: add "*port" keys (skip-row-if-empty) 2019-04-01 20:12:33 +02:00
Axel Burri ca3bd505ef btrbk: make check for duplicate snapshot/backup locations aware of shared btr_tree
Build check hash within btr_tree node instead per URL. This makes it
aware of shared btr_tree (different hostname:port pointing to same
btrfs filesystem).
2019-04-01 18:43:53 +02:00
Axel Burri 2f09a9a723 btrbk: virtual machine setups; use MACHINE_ID for caches; use port in URL
Common virtual machine setups have multiple volume sections with same
host, but distinct port numbers for each machine.

- make caches dependent on MACHINE_ID instead of HOST
- append port number to URL
- add MACHINE_ID to vinfo
- use MACHINE_ID where applicable

This even works if virtual machines share the same btrfs filesystems:
If a equal UUID is found on distinct machines, btr_tree() will return
the already present tree, in order to be consistent after node
injections.
2019-04-01 18:43:49 +02:00
Axel Burri d8b7988ffa btrbk: deprecate ssh_port option in favor of ssh://hostname[:port] notation
Setting the ssh port directly in the "volume" / "target" config lines
adds the possibility to have a create a unique "hostname:port"
identifier (preparatory for MACHINE_ID to distinguish virtual machines
on same host with different ports.)
2019-04-01 18:26:07 +02:00
Axel Burri 318e3af088 btrbk: table_formats: add skip-row-if-empty flag on all "*host" 2019-04-01 18:24:30 +02:00
Axel Burri 716d420a40 btrbk: print_formatted: add skip-row-if-empty functionality for table_formats
If the row key is prefixed with "-", and is all <undef>, omit output
of this row.
2019-04-01 18:22:30 +02:00
Axel Burri 805d7f4a0d btrbk-verify: add workaround for btrbk <= 0.27.2 bug: missing target_rsh, target_type
btrbk <= 0.27.2 does not print "target_rsh" and "target_type" when
called with --format=raw, see $table_formats{resolved}. This is fixed
in 0.28.0.

Hardcoding target_type=send-receive is not so bad, as for raw targets
btrbk-verify complains first with:

  btrbk-verify: missing required variable "target_rsh" in btrbk --format=raw line

So we should not run rsync (which is not really a problem, rsync just
fails with "not a directory").
2019-04-01 16:27:49 +02:00
Axel Burri 9ed41c8937 btrbk-verify: tool for automated backup integrity check based on rsync
Compare files and attributes by checksum, using rsync(1) in dry-run
mode with all preserve options enabled.

Resolves snapshot/backup pairs by evaluating the output of
"btrbk list latest [filter...]".

Restrictions:
 - ".d..t...... ./" lines are ignored by default:
   Root folder timestamp always differ.
 - "cd+++++++++ .*" lines are ignored by default:
   Nested subvolumes appear as new empty directories.
 - btrbk raw targets are skipped
 - rsync needs root in most cases (see --ssh-* options)
2019-04-01 16:27:45 +02:00
Axel Burri 0afc455c40 btrbk: fix table format "resolved": add target_type=send-receive|raw; add missing target_rsh
Required for "btrbk-check", which must be able do distinguish between
"send-receive" and "raw" targets.
2019-04-01 16:27:39 +02:00
Axel Burri 0699a860a9 btrbk: cosmetics: remove horizonal line in help message
This was added by mistake in:

96956959 btrbk: cosmetics: use heredocs for the help message
2019-04-01 15:31:58 +02:00
Axel Burri e3a81c8126 btrbk: do not print help message if -q,--quiet is set
When called from another script, we dont want the help message printed
on errors. E.g. when running something like:

    btrbk list snapshots -q filter_which_does_not_match
2019-04-01 15:31:58 +02:00
Axel Burri 6d465da6dc btrbk: change version to 0.28.0-dev; bump copyright year 2019-03-29 04:35:35 +01:00
Axel Burri bb2e9877b0 change version to 0.27.2 2019-03-26 15:08:55 +01:00
Axel Burri dfabd4e856 documentation: btrbk.conf.5: move info about allowed characters to top section 2019-03-26 15:08:55 +01:00
Axel Burri 4a23568c40 documentation: btrbk.conf.5: remove unnecessary "{zwsp}" (zero width space) 2019-03-26 15:08:55 +01:00
Axel Burri 86a930daf1 Makefile: add option to bypass compression (COMPRESS=no)
While on traditional UNIX the documentation (especially the man pages)
are gzip'ed, modern distros have helpers to compress it.

This patch adds an option to disable compression:

    make COMPRESS=no
2019-03-26 15:08:47 +01:00
Axel Burri a412908451 Makefile: add documentation on "all" build target 2019-03-25 14:41:55 +01:00
Axel Burri 0e63843195 doc/Makefile: prefer asciidoctor (fallback to asciidoc) for man page generation
Changed preference for man page generation, as "asciidoc" is
discontinued and relies on python-2.7.
2019-03-25 14:37:35 +01:00
Axel Burri 6f68b713ee btrbk: fix scheduler when overriding "target_preserve_min" in combination with global "target" section
When configuring "target" in a global (or "volume") context, and
overriding target_preserve_min in "subvolume" section, the scheduler
has undefined behavior (mixing up the "min" values).

Fixed by returning a copy of the preserve hash in
config_preserve_hash().
2019-03-04 16:05:38 +01:00
Axel Burri 17957a163a btrbk: trigger autofs mount while resolving mountpoints
If resolved mount point has fs_type=autofs, trigger automount by
calling "btrfs subvolume show" on the mount point, and check mountinfo
again.
2019-01-17 16:43:42 +01:00
Axel Burri f37a638f30 btrbk: bump version to 0.27.2-dev 2019-01-17 16:43:39 +01:00
Axel Burri 8abaed26c5 documentation: README.md: bump dependency >= btrfs-progs-4.12 (as of btrbk-0.27.0)
dependency introduced in:

0acbf74c btrbk: add btrfs_subvolume_list_complete: fetch all subvolumes with all flags
2019-01-04 15:49:10 +01:00
Axel Burri bd66f83663 btrbk: bump to forgotten dependency >= btrfs-progs-4.12 (as of btrbk-0.27.0)
dependency introduced in:

0acbf74c btrbk: add btrfs_subvolume_list_complete: fetch all subvolumes with all flags
2018-12-25 22:20:24 +01:00
Axel Burri e879620195 change version to 0.27.1 2018-12-05 22:18:19 +01:00
Axel Burri e52153e13c ChangeLog: add missing changelog for v0.27.1 2018-12-05 22:17:27 +01:00
Axel Burri 0e6c1f9025 btrbk: fix regression: call "sudo readlink" for backend=btrfs-progs-sudo
It is possible that the subvolume path is not accessible by the user
calling btrbk. When resolving mount points, "readlink" is used on the
path, which also needs to be wrapped with "sudo".
2018-12-05 22:01:07 +01:00
Axel Burri ff011d55af btrbk: fix "config print" command (undefined value in format_preserve_matrix())
regression: 5791d72171 btrbk: add "preserve_hour_of_day" configuration option
2018-12-05 21:43:54 +01:00
Axel Burri de851955b6 btrbk: print_formatted: no blank lines for format: raw,tlog,syslog 2018-10-31 14:33:07 +01:00
Axel Burri ebaaee2139 btrbk: print_formatted: omit title for format: raw,tlog,syslog 2018-10-31 14:06:14 +01:00
Axel Burri 74873081c3 btrbk: bump version to 0.27.1-dev 2018-10-31 13:57:06 +01:00
Axel Burri c59488f405 change version to 0.27.0 2018-10-16 12:19:44 +02:00
Axel Burri 97e4a1e5d3 ChangeLog: add migration documentation regarding scheduler bugfix 2018-10-16 12:04:19 +02:00
Axel Burri 56ee8acf3b btrbk: add "-S" command line option (shortcut for --print-schedule) 2018-10-15 16:25:07 +02:00
Axel Burri 7a8df85f2e btrbk: fix regression: add node to return value of vinfo_resolved()
The FORCE_PRESERVE information is set on the node, and was lost for
"latest common target" as get_receive_targets() returned vinfo without
node information.

fixes regression: 6c502cb btrbk: search complete target tree for correlated subvolumes
2018-10-15 16:19:52 +02:00
Axel Burri 49adbe6e28 documentation: README.md: explain send/receive using parent when restoring backups 2018-10-13 14:24:26 +02:00
Axel Burri 5c434bc197 documentation: cosmetics: delete trainling whitespace 2018-10-13 13:44:04 +02:00
Axel Burri ad20b9a360 documentation: btrbk.1: explain root privileges and snapshot/backup terminology 2018-10-13 13:29:14 +02:00
Axel Burri 37def3dc7e documentation: btrbk.conf.5: adaptions for backend and ssh_user option (cosmetics) 2018-10-13 13:29:14 +02:00
Axel Burri f554a36978 documentation: adaptions for asciidoctor (literal blocks) 2018-10-13 13:29:14 +02:00
Axel Burri d324f0d338 documentation: README.md: remove "upgrading from v0.22.2" section
This is more than two years old, everybody should have newer btrbk
release by now.

Note: "doc/upgrade_to_v0.23.0.md" is still available.
2018-10-13 13:29:14 +02:00
Axel Burri c2a344fed1 documentation: move installation instructions from README.md to doc/install.md 2018-10-13 13:29:08 +02:00
Axel Burri 756e1e9449 documentation: remove broken link to gmane (received_uuid patch in kernel 4.4)
gmane is dead, see kernel patch:

b96b1db039 btrfs: fix resending received snapshot with parent
2018-10-11 16:03:31 +02:00
Axel Burri 0a4fb02eeb documentation: change links to https 2018-10-10 23:11:44 +02:00
Axel Burri 526e332b02 ssh_filter_btrbk.sh: bugfix: ignore --restrict-path for "btrfs subvolume list"
btrbk now runs "btrfs subvolume list" from the mountpoint instead of
the volume path, which for some users is not below --restrict-path. As
the output of "btrfs subvolume list" is the same (complete btrfs tree
for the filesystem), it is ok to ignore the restrict-path here.
2018-10-10 22:51:13 +02:00
Axel Burri f7ef5139de documentation: rephrase ssh setup; cleanup 2018-10-10 00:58:38 +02:00
Axel Burri c087082543 documentation: btrbk.1.asciidoc: add notes on propagation of filter statements 2018-10-09 15:21:30 +02:00
Axel Burri 3528927ea6 btrbk: bugfix: do not keep latest common snapshot for "incremental no"
There is no reason to keep the latest common source snapshot if
"incremental no" is configured (see #252).
2018-10-02 17:28:46 +02:00
Axel Burri 1862bc16d3 documentation: btrbk.1.asciidoc: add note about "prune": source/target must be accessible
Related to: c65f937473
2018-08-27 15:50:36 +02:00
Axel Burri 069304f3bb btrbk: use system_list_mountinfo(), remove system_list_mounts(); rename fs_spec -> mount_source
Reasons for changing to `cat /proc/self/mountinfo`:
 - `/proc/self/mounts` (or `/proc/mounts`) lacks extra info
   (namespaces) and is not documented in kernel (deprecated?).
 - findmnt(8) also uses /proc/self/mountinfo

Refs:
 - https://www.kernel.org/doc/Documentation/filesystems/proc.txt
 - https://bugzilla.redhat.com/show_bug.cgi?id=491924
 - https://git.kernel.org/pub/scm/linux/kernel/git/bwh/linux-stable.git/commit/?id=2d4d4864ac08caff5c204a752bd004eed4f08760
2018-08-27 14:54:32 +02:00
Axel Burri e02c2cf249 btrbk: add system_list_mountinfo: parse /proc/self/mountinfo
preparatory patch for removing system_list_mounts().
2018-08-27 14:52:28 +02:00
Axel Burri 37c0e840e9 btrbk: bugfix: use latest longest match for resolving mount point (e.g. for autofs) 2018-08-27 14:49:04 +02:00
Paride Legovini 3dc06c8067 documentation: btrbk.conf.5: clarify behavior of 'snapshot_create ondemand' when there are multiple targets 2018-07-30 03:28:18 +02:00
Axel Burri 0d124a4373 btrbk: fix regression in get_related_subvolumes(): correctly match same btrbk file name scheme
Since we consider all accessible subvolumes in get_related_subvolumes,
checking for equal BTRBK_BASENAME and empty SUBVOL_DIR does not work
when checking for same btrbk file name scheme.

fixes regression: b37ef84e36 (btrbk: always read mountpoints; include all snapshots from mountpoint as candidates for best common parent)
2018-07-18 16:13:33 +02:00
Axel Burri bf5fd7a90b btrbk: cosmetics: fix prototype of get_related_subvolumes() 2018-07-18 16:13:29 +02:00
Axel Burri 1242913d9b btrbk: cosmetics: rename variables (spec -> fs_spec) 2018-07-12 18:26:35 +02:00
Axel Burri 5b1b99c4ed documentation: btrbk.conf.5: add explanation on hostname and caches 2018-07-12 18:26:35 +02:00
Axel Burri 78cec36e30 ssh_filter_btrbk: tighten decompress match expression 2018-07-12 18:26:35 +02:00
Axel Burri 47f6f730ab btrbk: cosmetics: change error message in btrfs_subvolume_delete; add comments 2018-07-12 18:26:35 +02:00
Axel Burri faec212324 btrbk: check if received subvolume is really garbled before deleting it
Improve error handling in btrfs_send_receive: on error, always try to
read the target subvolume and only delete it automatically if it is
garbled (read/write, no received_uuid).

This is especially important if the target subvolume was already
present before send/receive.

Reverts: 4c4afe77 btrbk: skip target metadata test if send/receive has errors
2018-07-12 18:26:35 +02:00
Axel Burri de57efff82 btrbk: bugfix: print all errors if send/receive fails
If stream_compress is enabled and compress command is not found, we
now print "command not found".
2018-07-12 18:26:34 +02:00
Axel Burri 9aeaf2b15c btrbk: fix regression introduced with btrfs_subvolume_list_complete
If btrfs_subvolume_show($vol, rootid => 5) fails, there are no
"received_uuid" and no "gen" keys in the root node.

Fixes: 0acbf74c57 (btrbk: add btrfs_subvolume_list_complete: fetch all subvolumes with all flags)
2018-07-09 18:46:24 +02:00
Axel Burri 669a34357a btrbk: bugfix: handle corner case: url="ssh://my.host" (without trailing slash)
As we allow <url> to be specified as "<hostname>:<directory>", an URL
"ssh://my.host" (without trailing slash) was parsed as hostname="ssh",
directory="/my.host".
2018-07-09 16:13:48 +02:00
Axel Burri c2022a5b2f documentation: add text for "subvolume ." configuration 2018-07-09 16:13:00 +02:00
Axel Burri 0acbf74c57 btrbk: add btrfs_subvolume_list_complete: fetch all subvolumes with all flags
Wrapper, returns complete list of all subvolumes (including btrfs
root, id=5) with all flags. Requires three calls to btrfs-progs.

Adaptions and cleanup in btr_tree().
2018-07-09 16:13:00 +02:00
Axel Burri d15133b3d4 btrbk: snapshot_name defaults to volume name if subvolume name is "." 2018-07-09 16:13:00 +02:00
Axel Burri 7088a91fa3 btrbk: cosmetics: sanitize trailing "/." in check_file() 2018-07-09 16:13:00 +02:00
Axel Burri de5004c744 btrbk: abort subvolume if it is btrfs root (id=5)
Btrfs root subvolume (id=5) have no UUID and cannot be backed
up. Abort if "subvolume ." is configured on btrfs root, e.g.:

  volume /path/to/btrfs_root
    subvolume .
2018-07-09 16:13:00 +02:00
Axel Burri b0d58fd0f1 btrbk: btr_tree: always read btrfs root node (id=5), hoping to get its uuid
Note that the UUID for btrfs root (id=5) is not always present:

 - btrfs-progs < 4.12 does not support rootid lookup
 - UUID can be missing if filesystem was created with btrfs-progs < 4.16

Still we need to always read it, as the whole tree is cached and we
don't know if it will be used.
2018-07-09 16:13:00 +02:00
Axel Burri cb5e361f7a btrbk: add --rootid command option for "btrfs subvolume show" 2018-07-09 16:13:00 +02:00
Axel Burri 1aa0fe1aad btrbk: remove obsolete realpath_cache update in btrfs_subvolume_show()
Recent btrfs-progs do not print the real path any more, this is now
handled by btrfs_mountpoint() -> system_realpath().
2018-07-09 16:13:00 +02:00
Axel Burri 177671e920 btrbk: validate output of "btrfs subvolume show"; also return uuid for btrfs root (if present)
Filesystems created with btrfs-progs < 4.16 have valid UUID, while
others have not [1]. Validate output of "btrfs subvolume show", and
provide uuid for btrfs root (id=5) only if it is valid.

  [1]: 0a0a03554a: btrfs-progs: mkfs: add uuid and otime to ROOT_ITEM of, FS_TREE
2018-07-09 16:13:00 +02:00
teesid 9c70231859 btrbk: allow backup of subvolume (subvolid != 5) mounted at "/"
It works with the configuration snippet below if subvolid != 5:

```
volume /
  subvolume  .
    snapshot_name  root
```
2018-07-09 16:13:00 +02:00
Axel Burri 2f95baf6f3 documentation: adaptions for asciidoctor (ifdefs, literal blocks)
When using asciidoctor, backend "manpage" (-b manpage) is used, while
a2x converts asciidoc to docbook (xml), then manpage.

Asciidoctor creates ugly indentation for [literal] blocks in SYNOPSIS,
use [verse] instead.
2018-06-25 20:49:24 +02:00
Axel Burri 3e9066337a documentation: fallback to asciidoctor if asciidoc (a2x) is not present
Asciidoc is EOL and only supports python2. Provide a fallback to
Asciidoctor for manpage generation.

Reference: https://github.com/digint/btrbk/pull/219
2018-06-25 20:46:00 +02:00
Axel Burri a0f6b55d28 btrbk: fix regression: undefined array reference when no received_uuid present
fixes #239 (@ian-kelling)
2018-06-25 13:30:14 +02:00
Samantha McVey 211943d4af btrbk: cosmetics: reformat a regex to be much more readable 2018-06-04 11:39:52 +02:00
Samantha McVey 969569592a btrbk: cosmetics: use heredocs for the help message
Avoids use having to use 40 print's and having to quote each line and is
much easier to edit.
2018-06-04 11:39:03 +02:00
Axel Burri 1d0d57ffac documentation: btrbk.conf.5: add more text on file names and urls 2018-05-31 00:36:46 +02:00
Axel Burri 391e50b872 btrbk: do not warn on non-parseable btrfs mountpoint
Many people use whitespace even in mountpoints, silently ignore
(loglevel=info) non-parseable btrfs mountpoints.

Btrbk does not support file names with whitespace or special
characters by design, and specifying such mountpoints in the
configuration file fails anyway.
2018-05-31 00:34:50 +02:00
Axel Burri ffba3e47c6 documentation: ssh_filter_btrbk.1.asciidoc: fixes, cleanup
- add add "always allowed" commands (as bullet list)
- remove deprecated "-c, --compress"
2018-05-15 00:06:53 +02:00
Axel Burri 2f56c55120 btrbk: fix regression: actions "list snapshots/backups" print all snapshots under sroot (not snaproot)
Regression from: c457540ce3
2018-05-14 23:43:13 +02:00
Axel Burri 09918bf5af btrbk: cosmetics: print (fix) reason why snapshots/backups are skipped/preserved 2018-05-11 00:17:52 +02:00
Axel Burri 9ae823a757 btrbk: cosmetics: remove too chatty debug log 2018-05-10 15:44:46 +02:00
Vít Novotný c8fcb01bc2 btrbk: bugfix: do not read target btrfs tree on "btrbk snapshot --preserve"
If running "btrbk snapshot --preserve", there is no need to initialize
targets, and we don't want to warn and fail (exitcode=10) on missing
targets.
2018-05-10 15:18:36 +02:00
Axel Burri 17f41118d3 btrbk: bugfix: compare all mountpoints while resolving
When comparing longest match in mounts, all mountpoints have to be
taken into account (not only the btrfs mount points).
2018-05-10 14:02:44 +02:00
Axel Burri 847be88142 ChangeLog: add changes to internal data structures
Covers commits:

1c83a65 btrbk: add filter capabilities to vinfo_subvol_list
a25487e btrbk: cosmetics (log messages)
ef5c369 btrbk: use _is_same_fs_tree() where applicable
0454f60 btrbk: bugfix: match btrbk_basename in get_latest_snapshot_child()
2c1c3b4 btrbk: cleanup: remove snapshot_dir, rename sroot->snaproot
c457540 btrbk: use separate vinfo for snapshot directory (allows snapshot_dir to be a mountpoint)
f5dc4e0 btrbk: add known mountpoints to btr_tree nodes as anchor for reverse lookup
e9374b3 btrbk: replace url_cache by spec_cache
0ea0430 btrbk: cleanup (cosmetics, documentation)
b37ef84 btrbk: always read mountpoints; include all snapshots from mountpoint as candidates for best common parent
b549e11 btrbk: raw targets: move tree readin to separate function; add caching
7a1bc25 btrbk: raw targets: create fake btr_tree instead of maintaining separate list
6c502cb btrbk: search complete target tree for correlated subvolumes
2018-05-10 12:03:51 +02:00
Axel Burri 1c83a6545d btrbk: add filter capabilities to vinfo_subvol_list
Clean up (and speedup) code by filtering while building the list
instead of checking every item after building.
2018-05-10 11:48:34 +02:00
Axel Burri a25487e873 btrbk: cosmetics (log messages) 2018-05-10 11:48:34 +02:00
Axel Burri ef5c369a37 btrbk: use _is_same_fs_tree() where applicable 2018-05-10 11:48:34 +02:00
Axel Burri 0454f60ad1 btrbk: bugfix: match btrbk_basename in get_latest_snapshot_child() 2018-05-10 11:48:34 +02:00
Axel Burri 2c1c3b4d54 btrbk: cleanup: remove snapshot_dir, rename sroot->snaproot 2018-05-10 11:48:34 +02:00
Axel Burri c457540ce3 btrbk: use separate vinfo for snapshot directory (allows snapshot_dir to be a mountpoint)
Instead of passing snapshot_dir all over the place, use a separate
vinfo for the snapshot directory, accessible by vinfo_snapshot_root().
As it is initialized separately by vinfo_init_root(), it can be on a
different mountpoint.

This also allows us to use different semantics for snapshot_dir in the
future, as it does not need to be relative to the volume directory.
2018-05-10 11:48:34 +02:00
Axel Burri f5dc4e0a36 btrbk: add known mountpoints to btr_tree nodes as anchor for reverse lookup 2018-05-10 11:48:34 +02:00
Axel Burri e9374b3b1d btrbk: replace url_cache by spec_cache 2018-05-10 11:48:34 +02:00
Axel Burri 0ea0430c43 btrbk: cleanup (cosmetics, documentation) 2018-05-10 11:48:34 +02:00
Axel Burri b37ef84e36 btrbk: always read mountpoints; include all snapshots from mountpoint as candidates for best common parent
Dropped readin of subvolid and realpath by btrfs_subvolume_show(), we
now always read /proc/self/mounts (and call readlink).

When picking the best common parent in get_best_parent(), we want to
list as many snapshots as possible. For now, we list all from the
mountpoint of snaproot ($sroot/<snapshot_dir>), due to a bug in
btrfs-progs [1]. Also added code (commented out) to list snapshots
from all known mountpoints.

  [1] https://github.com/kdave/btrfs-progs/issues/96
2018-05-10 11:48:05 +02:00
Axel Burri b549e11b43 btrbk: raw targets: move tree readin to separate function; add caching
Adds new function vinfo_init_raw_root(), similar to vinfo_init_root().
Note that we don't (yet) resolve realpath for raw targets.
2018-05-10 11:36:21 +02:00
Axel Burri 7a1bc257c1 btrbk: raw targets: create fake btr_tree instead of maintaining separate list 2018-05-10 11:36:21 +02:00
Axel Burri 6c502cbdcc btrbk: search complete target tree for correlated subvolumes
- move matching for correlated subvolumes from get_receive_targets
  into new function _receive_target_nodes
- add lookup tables in btr_tree (RECEIVED_UUID_HASH, UUID_HASH),
  allowing for faster matching in _receive_target_nodes
- add vinfo_resolved() for mapping nodes to vinfo
- rename get_latest_common to get_best_parent (while moving some
  functionality to new function get_related)
- cleanup
2018-05-10 11:36:21 +02:00
Axel Burri 490f680f41 btrbk: bugfix: add backend mappings for "btrfs filesystem usage" 2018-04-30 14:15:30 +02:00
Axel Burri c65f937473 documentation: btrbk.1.asciidoc: add note about snapshot deletion for action "snapshot" 2018-04-16 12:27:54 +02:00
Axel Burri 719fb5fb74 btrbk: bugfix: correct scheduling of "first weekly backup in month/year"
In the scheduler, a month (or year) does not start at the first day,
but at the first `preserve_day_of_week`. Make sure that all days
before `preserve_day_of_week` in a month get delta_months+1.

Example (corner case):
  - `preserve_day_of_week  sunday`
  - `target_preserve  *m`
  - no backups in 2018-02
  - backup with timestamp 2018-03-01 (which is a thursday)
  - backup with timestamp 2018-03-04 (which is a sunday)

Without this patch, because there are no sunday backups in 2018-02,
the first backup is considered a weekly (+4d after sunday), and as
such "first weekly of month 2018-03", and the second one is discarded.

With this patch, the first item is considered "first weekly of month
2018-02", and the second gets "first weekly of month 2018-03".

NOTE: This change may result in (previously preserved) backups to be
deleted!
2018-04-05 18:00:29 +02:00
Axel Burri e9c30e91fb documentation: btrbk.conf.5.asciidoc: enhance text on retention policy options 2018-04-05 18:00:29 +02:00
Axel Burri e4a0938712 btrbk: ignore "preserve_hour_of_day" on snapshots/backups having "timestamp_format=short"
Snapshots and backups having no exact time information (created with
"timestamp_format=short") are set to 00:00, which would be regarded as
"previous day" if preserve_hour_of_day is greater than 0. Fix this by
ignoring preserve_hour_of_day in this case.
2018-04-05 18:00:29 +02:00
Axel Burri c89ffd4213 btrbk: schedule: format preserve text only if needed
No functional changes, improves performance of schedule().
2018-04-05 18:00:24 +02:00
Thiodwitnir 5791d72171 btrbk: add "preserve_hour_of_day" configuration option
Introduces the new config option "preserve_hour_of_day" to specify
after what time backups should be considered as dailies.

Based on pull request #204, with changes:
 - calculation of weekly backups
 - change format of preserve_matrix
2018-04-05 16:37:31 +02:00
Axel Burri 951ae256fa btrbk: bump version to 0.27.0-dev 2018-04-05 16:26:57 +02:00
Axel Burri 1fd3a547df change version to 0.26.1; bump copyright year 2018-03-05 11:55:56 +01:00
Axel Burri 821e8bba6a add .gitattributes (export-ignore)
Effectively removes .gitignore files when using `git archive`.
2018-03-05 11:55:56 +01:00
Axel Burri 1cf004533c documentation: replace subvolid=0 with subvolid=5 2018-03-05 11:33:08 +01:00
Axel Burri 6f38536052 btrbk: set c_default for config keys with computed default
Suppress "Option redefined" warning for snapshot_name config option,
which has hardcoded (computed) default already set when checking.

fix regression: 0ebe2ea2e1
2018-02-26 16:06:12 +01:00
Axel Burri e75cf0c72c btrbk: fix exit status and transaction log when archive_exclude is set
Similar to ABORTED=USER_SKIP (active commandline filter), archives
having ABORTED=ARCHIVE_EXCLUDE_SKIP (active archive_exclude
configuration) do not cause exit status 10 and are hidden from
transaction log.
2018-02-26 14:35:26 +01:00
Axel Burri c0e0644eff btrbk.conf.example: add stream_buffer command to example config 2018-02-14 00:25:58 +01:00
Axel Burri 5651c96e4e btrbk: archive: always print "[-]" if no action was performed for target 2018-02-14 00:18:44 +01:00
Axel Burri 8610e75459 btrbk: add archive_exclude configuration option
Support wildcard characters, matches against both "$sroot->{PATH}" and
"$sroot->{PATH}/$snapshot_name".
2018-02-13 22:50:23 +01:00
Axel Burri 0ebe2ea2e1 btrbk: add "allow_multiple" flag for config_options declaration; use for option "group" 2018-02-13 19:30:24 +01:00
Axel Burri 3aaafa3d88 btrbk: add "meta" context for config defaults
Preparatory patch to allow multiple identical config keys in same
section.
2018-02-13 19:28:38 +01:00
Axel Burri b2b43cf199 btrbk: add configurable error_statement for check functions
Corrects error messages from --exclude option.
Applies to in check_file(), check_url() and append_config_option().
2018-02-13 17:40:14 +01:00
Axel Burri db1fe2d11a btrbk: fix output of "btrbk list backups" and "btrbk stats" (match all uuid/received_uuid combinations) 2018-02-07 16:24:49 +01:00
Axel Burri a835241ccf documentation: btrbk.1.asciidoc: add note about listing all snapshots for "btrbk list snapshots" 2018-02-03 13:18:19 +01:00
Axel Burri a3641cff74 btrbk: fix filter statement matching for volume="/"
While $vol->{URL} can contain "//" if volume="/" (intentionally, this
is an assembled path), the filter statements are sanitized using
check_url(). This means we need to match the filter statement against
check_url($vol->{URL}). Same applies to subvol.
2018-02-03 12:55:21 +01:00
Axel Burri 90fed6525e btrbk: bugfix: restrict snapshot_dir and snapshot_create to root/volume/subvolume context 2018-01-31 19:01:00 +01:00
Axel Burri 753d68b2ed btrbk: add documentation on caching in btr_tree() 2018-01-30 14:02:36 +01:00
Axel Burri 84bac59ab4 btrbk: fix parsing of "openssl_iv_size" configuration option 2018-01-21 18:53:29 +01:00
Axel Burri 308444f3ed documentation: FAQ.md: add warning on "dd" usage for disk cloning 2018-01-20 18:05:33 +01:00
Axel Burri b8e88f71a6 contrib: systemd: btrbk.service: add Documentation link to btrbk(1) 2017-10-24 13:29:06 +02:00
Axel Burri 57bc86b7a9 README.md: mention github source code repository 2017-10-13 14:02:50 +02:00
Axel Burri fa5309ee81 README.md: change git clone URL from git:// to https://
For security reasons, using the git:// protocol is discouraged.
2017-10-13 13:51:10 +02:00
Axel Burri 13f37491ed btrbk: cosmetics: change order of commands in help message 2017-10-12 17:08:46 +02:00
Axel Burri 659b7de82f doc/btrbk.conf.5.asciidoc: fix spelling 2017-10-12 17:07:05 +02:00
Axel Burri 79cbf7c0c3 change version to 0.26.0 2017-10-12 00:39:06 +02:00
Axel Burri c445b32459 doc/Makefile: use a2x --no-noxmllint for man page conversion 2017-10-12 00:39:06 +02:00
Axel Burri 780ef57895 documentation: remove experimental status of option "stream_buffer" 2017-10-11 20:54:41 +02:00
Axel Burri 909c68f164 btrbk: transaction_log and transaction_syslog are only allowed in root context 2017-10-11 20:54:41 +02:00
Axel Burri d941ecfce9 documentation: change digint links to https:// 2017-10-11 20:54:41 +02:00
Axel Burri 15dde32126 documentation: fix broken links 2017-10-11 20:54:41 +02:00
Axel Burri fdba94f8c7 documentation: btrbk.1.asciidoc: add action command / result matrix 2017-10-11 20:54:41 +02:00
Axel Burri c44c83bc33 Makefile: call doc/Makefile for installing files from "doc/" folder; use more variables 2017-10-11 20:54:41 +02:00
Axel Burri c26b7d3748 doc/Makefile: generate man pages from asciidoc 2017-10-11 20:54:41 +02:00
Axel Burri 2042c6ccd9 documentation: ssh_filter_btrbk.1.asciidoc: use "ssh_filter_btrbk" (without ".sh") in name section, as this is used as the output filename for asciidoc 2017-10-11 20:54:41 +02:00
Axel Burri c70e9bb757 documentation: ssh_filter_btrbk.1.asciidoc: cleanup 2017-10-11 20:54:41 +02:00
Axel Burri 0231051162 documentation: btrbk.1.asciidoc: cleanup 2017-10-11 20:54:26 +02:00
Axel Burri 3df8984337 documentation: btrbk.conf.5.asciidoc: change options subsections; cosmetics 2017-10-11 18:54:41 +02:00
Axel Burri 43399be0db documentation: btrbk.conf.5.asciidoc: add short descriptions for target raw options 2017-10-11 18:05:51 +02:00
Axel Burri c4ced9d6e4 documentation: convert all groff files (man pages) to asciidoc
- btrbk.conf.5 to btrbk.conf.5.asciidoc
 - btrbk.1 to btrbk.1.asciidoc
 - ssh_filter_btrbk.1 to ssh_filter_btrbk.1.asciidoc
2017-10-11 18:04:25 +02:00
Axel Burri e3ee674085 btrbk: limit search depth to 256 when resolving ancestors
Note that the current implementation is not very optimized, we should
introduce a parent/child hash table for all queries in
get_latest_common().
2017-10-10 16:46:05 +02:00
Axel Burri 3be65b9f67 btrbk: resolve ancestors (recursive on parent_uuid chain) when searching for latest common subvolume 2017-10-10 13:10:33 +02:00
Axel Burri 0799820556 btrbk: support btrfs-progs 4.13.2: adapt parsing of "btrfs subvolume list"
btrfs-progs v4.13.2 changed the output of "btrfs subvolume list", in
order to make the tabular output format look nicer (?!?):

e4c6772f69
2017-10-09 23:04:07 +02:00
Axel Burri e9a517f161 btrbk: add options "{snapshot,target,archive}_qgroup_destroy": destroy qgroups whenever a subvolume is deleted
Btrfs does not destroy qgroups when subvolumes are deleted (see
https://bugzilla.kernel.org/show_bug.cgi?id=91751). As a workaround
for this, btrbk can be configured to always destroy the corresponding
default qgroup "0/<subvol-id>" whenever a subvolume (snapshot, backup
or archive) is deleted.

Added configuration options:
 - snapshot_qgroup_destroy
 - target_qgroup_destroy
 - archive_qgroup_destroy
2017-10-02 16:23:23 +02:00
Axel Burri 6cb98700d8 btrbk: allow archive_preserve_* options in root context only 2017-10-02 13:54:37 +02:00
Axel Burri a5aaffa5b5 documentation: add "prune" to list of affected commands by several options 2017-10-02 13:44:35 +02:00
Axel Burri 2e974c1f4f btrbk: add "--wipe" command line option 2017-09-28 14:17:00 +02:00
Axel Burri 5bdc3e527b btrbk: add "prune" command 2017-09-28 14:17:00 +02:00
Axel Burri 2809dc54c5 btrbk: remove sorting of deleted subvolumes in summary (not needed anymore)
Deleted subvolumes are already sorted by schedule().
Sorting by PATH is bad anyways, as it does not sort _NN postfix
correctly.
2017-09-28 14:17:00 +02:00
Axel Burri 512aca5332 btrbk: parse output of "btrfs subvolume delete"
When doing a batch delete (multiple deletes with one call to "btrfs
subvolume delete"), we want to know which subvolumes have failed. For
this, we need parse the error output.

On any parsing failure, we assume that nothing has been deleted, and
warn accordingly (forward compatibility).
2017-09-28 14:17:00 +02:00
Axel Burri 9d9527ca9a btrbk: simplify transaction function calls
Prefix transaction status with "dryrun_" in start_transaction() /
end_transaction if $dryrun is set.
2017-09-28 14:17:00 +02:00
Axel Burri 422d52c063 btrbk: add key derivation for encrypted raw targets using external backend 2017-09-28 14:17:00 +02:00
Axel Burri de7628ac7c btrbk: add openssl_enc encryption for raw targets; add system_urandom()
Example:

Manually create a key:

    # KEYFILE=/some/secure/place/btrbk.key
    # dd if=/dev/urandom bs=1 count=32 | od -x -A n | tr -d "[:space:]" > $KEYFILE

btrbk.conf:

    volume /mnt/btr_pool
      incremental no
      raw_target_encrypt  openssl_enc
      openssl_ciphername  aes-256-cbc
      openssl_iv_size     16  # NOTE: set to "no" if no IV is needed by the selected cipher
      openssl_keyfile     /some/secure/place/btrbk.key

      subvolume home
        target raw ssh://cloud.example.com/backup
2017-09-28 14:17:00 +02:00
Axel Burri 251c2fb2a1 btrbk: re-enable parsing of deprecated raw file format (uuid suffix) 2017-09-28 14:17:00 +02:00
Axel Burri e804930b5e btrbk: allow deletion of non-incremental raw targets
implemented directly in btrfs_subvolume_delete()
2017-09-28 14:17:00 +02:00
Axel Burri dcb0c5aa28 contrib/migration/raw_suffix2sidecar: add migration tool for creating raw sidecar files from uuid-suffixed raw backup files 2017-09-28 14:17:00 +02:00
Axel Burri cd8d7e3a0a btrbk: use sidecar file "*.info" instead of encoding uuids into filename for raw targets
pros:

 - better forward compatibility, e.g. symmetrical encryption
 - better readability of files

cons:

 - two files per backup
2017-09-28 14:16:53 +02:00
Axel Burri 571dae4428 btrbk: do not run in perl taint mode by default: remove "perl -T" in hashbang; hardcode $PATH only if taint mode is enabled
While taint mode [1] is a nice feature of perl, e.g. it disallows
using variables (such as filenames from the config file) which were
not validated in system() commands, it also treats $PATH as insecure
(which inherently is, as perl cannot know who messed around with it).

  [1] perlsec(1): http://perldoc.perl.org/perlsec.html
  [2] perlrun(1): http://perldoc.perl.org/perlrun.html

Note that btrbk still does all taint checks, and can be run in taint
mode:

  - by executing `perl -T /usr/sbin/btrbk`,
  - or by changing the hashbang to: `!#/usr/bin/perl -T`.
2017-09-25 17:53:35 +02:00
Axel Burri 5f867c2347 btrbk: run_cmd(): catch all possible errors when executing system command 2017-09-25 15:00:40 +02:00
Axel Burri e402435dc8 btrbk: treat deprecated warnings as non-fatal
Despite FATAL warnings are discouraged in perl and may break forward
compatibility [1], we still use it as btrbk is usually run as root and
we really want perl to die on programmatic errors.

  [1] "perldoc warnings"
2017-09-25 15:00:40 +02:00
Enno Boland 62fad0e326 documentation: README.md: mention installation on VoidLinux 2017-09-21 13:49:02 +02:00
Axel Burri 6c2d56d621 btrbk: action "clean": dont list failed deletes in summary 2017-09-21 12:39:48 +02:00
Axel Burri b8a8bc917d documentation: FAQ.md: fix description for removing received_uuid on read-only subvolume 2017-09-11 19:37:09 +02:00
Axel Burri f113436626 btrbk: bugfix: check path when expanding wildcards (warn and ignore if check fails)
Before this patch, btrbk errored (unsafe command), and then died.
Fixes #181.
2017-09-11 18:49:14 +02:00
boerwastaken d265c34149 btrbk: make SSH minimally chatty (always add '-q' option)
Fixes digint/btrbk#179: When SSH is chatty (informing of host key
rollover etc) the remote command output parser borks.
2017-09-04 13:00:19 +02:00
Axel Burri 8eb88a8681 documentation: replace POD header with comments 2017-08-28 20:33:00 +02:00
Axel Burri 88aa8c1fea btrbk: remove "duration" column from transaction_log/transaction_syslog
The "duration" column in the transaction log has proven to be
confusing to some users, especially on errors (e.g. "send-receive
ERROR 27" in issue #177). As it's not really necessary (duration can
be computed from the corresponding "starting" log entry), it's now
being dropped.
2017-08-28 17:55:27 +02:00
Axel Burri 6acea6a08d btrbk: bugfix: print correct time in end_transaction() 2017-08-28 17:54:17 +02:00
Axel Burri b1f3936826 ssh_filter_btrbk: bugfix: use "lzop" instead of "lzo" for lzo compression command 2017-08-21 14:42:01 +02:00
Axel Burri ee17c1a2b4 ssh_filter_btrbk: accept mbuffer command (stream_compress) 2017-08-21 14:39:40 +02:00
Axel Burri 5428e9cd93 btrbk: add "resume" and "snapshot" commands; add --preserve-snapshots and --preserve-backups options; deprecate "-r, --resume-only" command line option 2017-08-21 13:23:20 +02:00
Axel Burri a9f1b6b24a change version to 0.25.1 2017-07-30 16:03:58 +02:00
Axel Burri 6cf5d59644 btrbk: add support for btrfs-progs 4.12: do not fail or set realpath_cache for relative paths in btrfs_subvolume_show()
As of btrfs-progs-v4.12, the "btrfs subvolume show" command does not
print the full (absolute, resolved) path anymore [1]. Instead, it prints
the relative path to btrfs root (or "/" if it is the root).

The impact for btrbk is that we cannot fill our realpath_cache in
btrfs_subvolume_show() anymore. This is not fatal, but has the
following consequences:

  - The "check for duplicate snapshot locations" may now miss
    subvolumes specified by symlinks.

  - If multiple "volume" sections point to the same subvolume (e.g. if
    specified using symlinks) an additional "btrfs subvolume list" is
    called. Note that the subvolume will still be recognized as
    identical, and the btr_tree will not be rebuilt.

  [1] btrfs-progs commit: b7df24aa5cddc4802b9938f56372b73869775cd9
2017-07-30 15:25:32 +02:00
Axel Burri 26682213e2 btrbk: cleanup btrfs_subvolume_list() and comments 2017-07-30 15:03:23 +02:00
Axel Burri 7b50846957 documentation: add more instructions for faulty received_uuid 2017-07-29 20:54:43 +02:00
Axel Burri 356231bc2a btrbk: abort if source subvolume has readonly or received_uuid flag 2017-07-29 19:03:23 +02:00
Michael Goodwin 59cc728d90 documentation: README.md: add fedora instructions and pv prereq 2017-07-21 14:00:49 +02:00
Axel Burri b891617086 documentation: add donate section (paypal) in README.md 2017-07-13 12:54:08 +02:00
Michael Goodwin c5ea0c5c71 Makefile: Preserve timestamps with install -p 2017-07-05 14:02:44 -04:00
Axel Burri 83a38cb390 documentation: FAQ.md: add section "How can I setup a debian pre-install-hook?" 2017-06-25 21:23:55 +02:00
Axel Burri c0c546eb4e btrbk: stats command: show "correlated" status instead of "orphaned" (inverse logic which caused a lot of confusion) 2017-06-25 21:16:08 +02:00
Axel Burri 15bae5e051 btrbk: stats command: print up-to-date status on backups 2017-06-25 21:14:03 +02:00
Axel Burri b2cc99b0fb btrbk: bugfix: accept "no" for "transaction_log", "transaction_syslog" and "lockfile" configuration options 2017-06-25 18:06:06 +02:00
Axel Burri 315b3f24a1 btrbk: add config option "stream_buffer <size>". if set, pipes send stream through "mbuffer -m <size>" 2017-06-08 12:35:22 +02:00
Axel Burri 401b4ac45c documentation: README.md: add warning about using `btrfs property set` when restoring backups 2017-05-08 14:28:17 +02:00
Cerem Cem ASLAN ed80bccc79 documentation: README.md: minor fixes in example 2017-04-29 21:37:39 +02:00
Cerem Cem ASLAN b58817d5af documentation: FAQ.md: improved "changing root subvolume" section
Fixed the default subvolume ID from 0 to 5. Added some tips.
2017-04-29 21:06:18 +02:00
Santiago Castro b4ec8d32a5 Fix broken Markdown headings 2017-04-17 22:52:07 -03:00
Bladtman242 4f05bb78f0 Update README.md
Under "Example: laptop with usb-disk for backups" the readme stated that " snapshot_preserve 14d" will "keep daily snapshots for 14 days [..]". I believe that this is misleading, as it seems to imply that only one snapshot --the latest -- will be kept in that period, when in fact _all_ snapshots will be kept in that period.
2017-03-30 22:34:48 +02:00
Axel Burri 7436d9432c change version to 0.25.0 2017-03-18 16:53:07 +01:00
Axel Burri d31ffb8cb0 btrbk: allow trailing comments in btrbk.conf 2017-03-18 16:34:53 +01:00
Axel Burri 358a2b1169 btrbk: cleanup: btrfs_send_to_file() takes no more additional options (all info is fetched directly from source/target config) 2017-03-18 15:06:48 +01:00
Axel Burri 28c65e4675 btrbk: add raw_target_split option, using "split" instead of "dd" to write raw files 2017-03-18 14:47:43 +01:00
Axel Burri 84e5b6243b documentation: cosmetics: fix typos 2017-03-18 12:19:07 +01:00
Axel Burri 690a8158ed ssh_filter_btrbk: always allow pipes through compression commands 2017-03-18 12:19:07 +01:00
Axel Burri da70158c24 ssh_filter_btrbk: correctly handle --sudo option 2017-03-18 12:19:07 +01:00
Axel Burri 3b7ede773a btrbk: bugfix: make sure rate limiting comes after compression in cmd_pipe 2017-03-18 12:18:47 +01:00
Axel Burri a7f52785bd documentation: add all accepted facility names for transaction_syslog 2017-02-18 13:16:43 +01:00
Axel Burri cb82bd5fa4 btrbk: add supoort for "backend btrfs-progs-sudo" option; adaptions in ssh_filter_btrbk.sh 2017-01-04 15:04:22 +01:00
Ian Kelling d02f67a924 btrbk: get_receive_targets: also match "src.received_uuid == target.uuid"
This gets important when using an old backup disk as source.

In terms of btrfs send/receive, all subvolumes matching "uuid /
received_uuid" are valid backups.

Merged (amend) from pull request: #116

Verified by Axel Burri <axel@tty0.ch>
2017-01-04 12:41:05 +01:00
Axel Burri 2acbe4978e documentation: cosmetics: fix spelling 2017-01-03 13:42:38 +01:00
Axel Burri 79637de5aa btrbk: raw_target_encrypt: always set "gpg --no-random-seed-file": prevents creation of "~/.gnupg/random_seed" with slight perfomance penalty.
We set "--no-random-seed-file" because one of the btrbk
design principles is to not create any files unasked. Enabling
"--no-random-seed-file" creates ~/.gnupg/random_seed, and as
such depends on $HOME to be set correctly (think on running in
cron). From gpg2(1) man page:
  --no-random-seed-file GnuPG uses a file to store its
  internal random pool over invocations This makes random
  generation faster; however sometimes write operations are not
  desired. This option can be used to achieve that with the cost
  of slower random generation.
2017-01-03 13:41:39 +01:00
Axel Burri b69e9ebf34 btrbk: show aggregate "size" and "used" for "usage" action 2016-12-11 15:36:48 +01:00
Axel Burri da849b37ae change version to 0.24.0 2016-11-16 15:32:17 +01:00
Axel Burri ff8815b235 Documentation: btrbk.conf.5: add link to https://github.com/digint/btrfs-progs-btrbk in description of "backend" feature 2016-11-16 15:31:16 +01:00
Axel Burri ec63e9932b btrbk: support for btrfs-progs v4.8.3
Fix parsing of "btrfs sub show" output, which has changed for toplevel
subvolume.
2016-11-16 15:02:49 +01:00
Matt Christian 8432e1b9be Makefile: Add -f option to all gzip commands
Always overwrite destination .gz files during make install.

Otherwise you need to manually answer y to several prompts.
```gzip: /usr/share/doc/btrbk/README.md.gz already exists; do you wish to overwrite (y or n)? y```
2016-11-16 14:10:50 +01:00
Axel Burri 57be688f6b btrbk: bugfix: fix "list latest" with no snapshots 2016-11-12 13:21:33 +01:00
Axel Burri b6defaa37f documentation: add missing documentation of archive_preserve options 2016-08-29 19:44:17 +02:00
Axel Burri a8a311c8c7 btrbk: add "backend" configuration option: support for distinct binaries from btrfs-progs-btrbk
btrfs-progs-btrbk sources (fork of btrfs-progs) can be found at:

https://github.com/digint/btrfs-progs-btrbk
2016-08-29 18:40:42 +02:00
Axel Burri dc5dee3121 btrbk: use loglevel trace (instead of debug) for repeated WARN_ONCE 2016-08-29 15:03:56 +02:00
Axel Burri 1aa208151b btrbk: improve check_file(): sanitize only on demand 2016-08-29 15:03:20 +02:00
Axel Burri 4c4afe776d btrbk: skip target metadata test if send/receive has errors 2016-08-29 15:03:11 +02:00
Axel Burri 961f96833a btrbk: use "dd" for raw target output, with configurable block size (raw_target_block_size)
We use "dd" instead of shell redirections, as it is common to have
special filesystems (like NFS, SMB, FUSE) mounted on the raw target
path. By using "dd" we make sure to write in reasonably large blocks
(default=128K), which is not always the case when using redirections
(e.g. "gpg > outfile" writes in 8K blocks).

Another approach would be to always pipe through "cat", which uses
st_blksize from fstat(2) (with a minimum of 128K) to determine the
block size.
2016-08-25 13:14:01 +02:00
Axel Burri 3dabb507e6 btrbk: do not set "--compress-algo none" on gpg command if raw_target_compress=no
Note that gpg might still compress (according to OpenPGP standard) if
--compress-algo is not set. This is generally a good thing.
2016-08-25 12:53:12 +02:00
Axel Burri b0feaf4413 btrbk: force disabling of ssh compression (ssh -o compression=no) if stream_compress is set 2016-08-25 12:53:12 +02:00
Axel Burri b49ee61ecd btrbk: run_cmd: cosmetics 2016-08-25 12:53:12 +02:00
Axel Burri 5f530e47e5 btrbk: run_cmd: only perform sanity checks on files (hardcoded parts are considered safe) 2016-08-25 12:53:06 +02:00
Axel Burri 96f0d4c175 btrbk: fix and cleanup stream compression 2016-08-24 15:25:48 +02:00
Axel Burri 8f7d3e3c3d ssh_filter_btrbk: bugfix: use eval when running $SSH_ORIGINAL_COMMAND (does not faile with pipes) 2016-08-21 11:51:55 +02:00
Axel Burri 13d27c8616 btrbk: perform extra metadata check on target subvolume after "btrfs receive"
Eliminates error cases where "btrfs receive" input is null, at the
cost of an additional call to "btrfs subvolume show".
2016-08-19 17:41:03 +02:00
Axel Burri deeb12c069 ssh_filter_btrbk: allow stream compression if --compress option is set. 2016-08-19 17:36:40 +02:00
Axel Burri 9913e2785a documentation: add stream_compress documentation, update Changelog 2016-08-19 17:36:33 +02:00
Axel Burri 13887837b1 btrbk: add lz4 compression 2016-08-19 16:58:53 +02:00
Axel Burri 3845fa5ec5 btrbk: use format from %compression hash in $raw_postfix_match 2016-08-19 16:58:53 +02:00
Axel Burri 05c54a2390 btrbk: add compression options: pigz, pbzip2, lzo 2016-08-19 16:58:53 +02:00
Axel Burri a019d8a3e3 btrbk: add configuration option "stream_compress"
- add sophisticated stream compression in run_cmd
- add special "compress" cmd_pipe item
- add special "redirect" cmd_pipe item:
  use shell redirection instead of troublesome "dd of=".
- disable ssh_compression if stream_compression is set
2016-08-19 16:56:38 +02:00
Axel Burri 99ff88f82a btrbk: use (and propagate) CONFIG in vinfo instead of hard-setting RSH 2016-08-19 16:54:49 +02:00
Axel Burri 079b947cd6 btrbk: add function WARN_ONCE 2016-08-19 16:48:45 +02:00
TZdyrski edffbd4af9 ssh_filter_btrbk: update ssh_filter_btrbk.sh to use readlink
bugfix for: 796b6bd9bf

Replace realpath with readlink in allowed commands. Commit 796b6bd substituted readlink for realpath in file "btrbk"; this commit propagates the change to ssh_filter_btrbk.sh.
2016-08-19 01:05:02 +02:00
Axel Burri 708444b096 btrbk-mail, README.md: suggest using "rsync --inplace"
When used without --inplace, rsync creates a new copy of the file and
moves it into place when it is complete, having the effect that btrfs
creates a new extent for the WHOLE file. With --inplace however, rsync
writes the updated data directly to the destination file, having the
effect that btrfs creates a new extent only for the differing part of
the file.
2016-08-17 14:49:27 +02:00
Tobias Grosser 84a5c56a83 btrbk: disable compression in gpg
We already perform compression before gpg, such that compressing in gpg
is just a waste of time. Interestingly, it seems gpg is not trying to
recompress gzip[ed] input streams, as for the default gzip compression
this patch does not change performance. However, it is necessary for
the upcoming lz4 compression to show its real benefit.
2016-08-07 13:40:45 +02:00
Axel Burri 66c36187ed documentation: README.md: remove link to digint-overlay, btrbk is in portage now 2016-07-14 14:19:09 +02:00
Axel Burri e9a72cf097 documentation: README.md: cosmetics 2016-07-14 14:19:08 +02:00
Axel Burri 9a5e8311be change version to 0.23.3 2016-07-14 01:41:45 +02:00
Asbjørn Apeland 16d73b4e5a Makefile: support .in files (use to replace @BINDIR@ in btrbk.service) 2016-07-13 20:56:28 +02:00
Axel Burri 3f2e53ba71 Makefile: compress ChangeLog in install-doc 2016-07-13 20:56:19 +02:00
Craig Andrews 16d8fe36a1 Makefile: include ChangeLog in install-doc
install-doc should install ChangeLog along with the other documentation.
2016-07-13 19:09:05 +02:00
Axel Burri 796b6bd9bf btrbk: replace "realpath -e" with "readlink -e" for mountpoint discovery 2016-06-18 13:04:43 +02:00
Axel Burri 91d02ca97b change version to 0.23.2 2016-06-07 16:41:41 +02:00
Axel Burri 3a8665bce9 documentation: add information about wildcard characters for subvolume section; cleanup 2016-06-07 16:37:32 +02:00
Axel Burri e4a7ba4be5 btrbk: add lockfile support, using perl "flock": add configuration option "lockfile <file>", and command line option "--lockfile"' 2016-06-07 16:17:02 +02:00
Axel Burri 6532229361 documentation: FAQ.md: recent versions of btrfs-progs print "is toplevel subvolume" instead of "is btrfs root" 2016-05-30 13:20:47 +02:00
Axel Burri 36edda5123 documentation: replace wrong "target_min" with "target_preserve_min" in example config 2016-05-30 13:19:07 +02:00
Axel Burri 7326b9816c btrbk: bugfix: raw targets: correctly handle multiple backups in same target directory 2016-05-09 12:42:04 +02:00
Axel Burri eabdba482e btrbk-mail: Use relative instead of absolute calls to system binaries
Make sure to have apropriate PATH set when calling btrbk-mail.
Usually specified in /etc/crontab, and should be correct by default on
all distros.
2016-05-09 12:13:22 +02:00
Benedikt Morbach df7473f7df Makefile: respect BINDIR in systemd service 2016-05-09 12:03:59 +02:00
Axel Burri cb0851c8b6 change version to 0.23.1 2016-05-03 16:21:34 +02:00
Axel Burri 65ebf949d1 documentation: cosmetics: groff: consistently use minus "\-" instead of hyphen "-" where applicable 2016-05-03 16:01:39 +02:00
Axel Burri cb6dcbe58e documentation: cosmetics (no more long lines) 2016-05-03 15:30:06 +02:00
Axel Burri 5cd03a8fbf btrbk: remove absolute path to executables, this caused trouble on some distros 2016-05-03 14:34:04 +02:00
Axel Burri 54b5368309 btrbk: code cleanup (remove unneeded code, rename vars) 2016-05-03 13:19:42 +02:00
Axel Burri 12d435d42a btrbk: explain "orphaned" status in "stats" command, and suppress it on "list backups" command 2016-04-30 13:01:12 +02:00
Axel Burri 46f1e5e2e4 btrbk: only load Data::Dumper if needed (log level "trace", or development version); cosmetics 2016-04-28 13:03:15 +02:00
Axel Burri 49ae46d51d btrbk: do not print headers to transaction_log, these are documented in btrbk.conf(5) 2016-04-28 12:51:00 +02:00
Axel Burri e9e398af37 Merge branch 'syslog' 2016-04-28 12:45:13 +02:00
Axel Burri 7a469597ac documentation: describe transaction log table format; cosmetics 2016-04-28 12:44:33 +02:00
Axel Burri 7e7c28f8f1 btrbk: add eval_quiet(), a simple wrapper around eval, disabling $SIG_(__DIE__) 2016-04-28 12:43:32 +02:00
Axel Burri 082754173c btrbk: bugfix: raw targets: do not inject child if add_btrbk_filename_info() failed 2016-04-25 21:12:33 +02:00
Axel Burri 47eb14f5fb btrbk: syslog: add syslog hack in print_formatted(); remove print-to-scalar hack 2016-04-25 19:40:11 +02:00
Axel Burri c424d917b6 btrbk: syslog: only load Sys::Syslog module if configuration option is set; soft-fail on syslog calls 2016-04-25 18:36:54 +02:00
Hans van Kranenburg 59d96420c8 btrbk: add transaction logging to syslog
Add configuration option transaction_syslog, which can be set to a short
name of a syslog facility, like user or local5. Most of the ones besides
localX do not really make sense, but whatever, let the user decide.

The only logging that is relevant for logging to syslog is the logging
generated inside sub action, so it's easy to hijack all messages in
there and also send them to syslog if needed.

All output is done via print_formatted, which expects a file handle.
So, abuse a file handle to a string to be able to change as less code as
needed for this feature.

Since syslog already adds the timestamps for us, I added a syslog
formatting pattern, which is very similar to tlog, omitting the
timestap.
2016-04-25 17:32:08 +02:00
Axel Burri 81feb41619 ssh_filter_btrbk: allow access to "/" if no path restrictions are set. 2016-04-25 16:58:56 +02:00
Axel Burri 89df601ee5 btrbk: allow "<hostname>:<path>" notation for volume and target sections 2016-04-25 16:34:52 +02:00
Axel Burri 702ee8950e btrbk: bugfix: vinfo(): correctly parse url, using check_url() 2016-04-25 15:10:00 +02:00
Axel Burri 357b72bd3f btrbk: code cleanup: check_file() and check_url() do all the sanitize parts 2016-04-25 14:23:15 +02:00
Axel Burri 191284cd43 btrbk: bugfix: set correct parent section when propagating targets 2016-04-24 15:59:17 +02:00
Axel Burri 4ffaf430c5 change version to 0.23.0 2016-04-23 15:06:57 +02:00
Axel Burri b4c4a96b14 Makefile: add doc/upgrade_to_v0.23.0.md 2016-04-23 15:04:45 +02:00
Axel Burri 2e8e4ddefc btrbk: cosmetics: change info log of send/receive; change topic line; fix typos 2016-04-23 14:58:08 +02:00
Axel Burri efc260ef91 btrbk: add sanity check on timezone offset; add documentation about implications of long-iso time format 2016-04-23 14:49:12 +02:00
Axel Burri c7dd680537 btrbk: make sure that snapshots/backups with date in the future are never deleted 2016-04-22 20:51:31 +02:00
Axel Burri ecb2307b22 btrbk: send/receive: only inject child if target creation was successful 2016-04-22 20:25:30 +02:00
Axel Burri 3ffa63daba btrbk: bugfix: btrfs_subvolume_show(): quote real_path everywhere 2016-04-22 20:17:26 +02:00
Axel Burri c13c99ada5 btrbk: add new time_format "long-iso", with seconds and timezone offset (iso8601 format); add function timestamp(): remove dependency to POSIX 2016-04-22 19:47:01 +02:00
Axel Burri e824c21f50 btrbk: use build-in Time::Local in combination with localtime() instead of Date::Calc; correctly calculate leap hours 2016-04-20 22:45:11 +02:00
Axel Burri c73dffbd25 btrbk: handle missing Data::Dumper gracefully 2016-04-19 22:12:08 +02:00
Axel Burri 829490f963 btrbk: put btrbk filename info directly to tree node (parse only once)
performance win: factor 2.3
2016-04-19 22:04:07 +02:00
Axel Burri c225231742 btrbk: reuse subvol list for get_receive_targets()
performance win: factor 2.6 !
2016-04-19 22:01:23 +02:00
Axel Burri 2b22524ccd btrbk: sane defaults: xxx_preserve_min defaults to "all", xxx_preserve default to "no" (for backwards compatibility with 0.22.0 default) 2016-04-19 21:37:04 +02:00
Axel Burri 29b9c8fc60 btrbk: action "archive": abort if receive targets of archive candidates exist at unexpected location. makes sure we dont have duplicates on our archives 2016-04-19 21:02:51 +02:00
Axel Burri 5e7a6e5ef4 btrbk: action "archive": delete archives according to archive retention policy 2016-04-19 21:02:51 +02:00
Axel Burri 31f0f97ff0 btrbk: fix info logging for send/receive 2016-04-19 21:02:51 +02:00
Axel Burri 7807fface8 btrbk: cosmetics; s/config_override_opts/config_override_cmdline/g 2016-04-19 21:02:51 +02:00
Axel Burri 2c3997ad0a btrbk: bugfix: action "config print": correctly handle undef options; skip deprecated options 2016-04-19 21:02:47 +02:00
Axel Burri 2317580639 documentation: README.md: add update notice (v0.22.2 -> v0.23.0) 2016-04-18 00:16:45 +02:00
Axel Burri a27f99af46 change version to 0.23.0-rc1 2016-04-17 21:46:56 +02:00
Axel Burri bbb18f5af7 btrbk: cosmetics on info warnings 2016-04-17 21:46:53 +02:00
Axel Burri edfebb8193 btrbk: action "origin": use --format options; do not recurse into parent chain 2016-04-16 22:05:26 +02:00
Axel Burri 1151d2c572 btrbk: print_formatted(): honor use_header argument for all table formats 2016-04-16 20:25:22 +02:00
Axel Burri 9afe17f738 btrbk: continue gracefully (skip instead of abort) when resuming subvolume having existing (possibly garbled) target; cosmetics on debug/trace log 2016-04-16 19:31:29 +02:00
Axel Burri ec9dd761b8 btrbk: use "[subvol cmd]" instead of "[btrfs cmd]", and print this as info log 2016-04-16 18:06:55 +02:00
Axel Burri 59b3cde303 Merge branch 'action_archive' into devel 2016-04-16 17:32:07 +02:00
Axel Burri 689d3d1233 btrbk: action "archive": print created subdirectories on summary; cleanup 2016-04-16 17:31:14 +02:00
Axel Burri 5a06a85619 btrbk: moved get_receive_targets_fsroot() out of get_receive_targets(), while cleaning up 2016-04-16 17:25:53 +02:00
Axel Burri 774e6ef842 btrbk: macro_archive_target(): only warn on unexpected targets, not abort 2016-04-16 17:25:53 +02:00
Axel Burri de05b99757 btrbk: rename action "clone" to "archive" (should have been like this from the beginning) 2016-04-16 17:25:51 +02:00
Axel Burri 4bd68a2e35 btrbk: action "clone": abort all as soon as one target aborts 2016-04-16 00:45:16 +02:00
Axel Burri cc20dfb8c3 btrbk: schedule(): use "informative_only" option instead of checking for empty value; make sure real values are always in front 2016-04-15 23:29:47 +02:00
Axel Burri d0cfba7914 btrbk: action "clone": create missing directories 2016-04-15 23:29:47 +02:00
Axel Burri a5c7c53a86 btrbk: action "clone": print scheduler results if --print-schedule option is set 2016-04-15 23:29:47 +02:00
Axel Burri 14de16aabe btrbk: add action "clone": recursively send/receive all backups to an archive directory 2016-04-15 23:29:47 +02:00
Axel Burri 3c9aff4c40 btrbk: enable --override option 2016-04-15 11:10:12 +02:00
Axel Burri e3702305e6 btrbk: bugfix: update uuid_cache after btrfs_subvolume_show() 2016-04-15 11:07:26 +02:00
Axel Burri 6e997674fc btrbk: remove "btrfs_progs_compat" configuration option, from now on we REQUIRE btrfs-progs >= v3.18.2: we rely on received_uuid for most operations 2016-04-15 11:07:16 +02:00
Axel Burri 6aa54b2dd5 btrbk: bugfix: correctly handle NODE_SUBDIR in vinfo_inject_child() 2016-04-14 18:24:11 +02:00
Axel Burri 141b70f26b btrbk: bugfix for subdir resolving: on older kernels, the "subvolid" mount option is not shown: try to read it with btrfs_subvolume_show() 2016-04-14 18:21:00 +02:00
Axel Burri a1ee9d5c6d btrbk: allow "{snapshot,target}_preserve no": disable retention policy 2016-04-14 14:43:43 +02:00
Axel Burri a03c515b0a btrbk: enter failsafe mode on deprecated preserve configuration: at least create the snapshots, and print message to read the upgrade documentation 2016-04-14 13:41:53 +02:00
Axel Burri 73906caacd documentation: update/fix ChangeLog, README.md, btrbk.conf.5; add "doc/upgrade_to_v0.23.0.md" 2016-04-13 22:05:20 +02:00
Axel Burri be608a04b2 documentation: btrbk.conf.example: adaptions for new {snapshot,target}_preserve options 2016-04-13 22:05:20 +02:00
Axel Burri 7c0987bd3c btrbk: be harsh (abort) on deprecated "{snapshot,target}_preserve_{daily,weekly,monthly}" and "resume_missing no" options; change default of snapshot_preserve_min to one day 2016-04-13 22:05:20 +02:00
Axel Burri 36cc96fdb8 btrbk: always preserve latest snapshot/backup pair (instead of latest snapshot and latest backup); remove preserve_latest option of schedule() 2016-04-13 22:05:20 +02:00
Axel Burri 032642751b btrbk: change preserve table text: print latest match instead of earliest match 2016-04-13 22:05:20 +02:00
Axel Burri e200975f32 btrbk: add option "*preserve_min latest"; deny "snapshot_preserve_min no" 2016-04-13 22:05:20 +02:00
Axel Burri d143d75b43 btrbk: rename *preserve_all to *preserve_min 2016-04-13 22:05:20 +02:00
Axel Burri 55b121c372 btrbk: remove resume_missing configuration option 2016-04-13 22:05:20 +02:00
Axel Burri 738178565c btrbk: fix vinfo_inject_child() for raw targets 2016-04-13 22:05:20 +02:00
Axel Burri a76512955a btrbk: add vinfo_inject_child(): add a custom node to btr_tree, with fake id, uuid, gen and cgen; use to inject created snapshots and receive targets 2016-04-13 17:17:23 +02:00
Axel Burri bd34d9f689 btrbk: change preserve logic: keep FIRST present of hour/day/... instead of LAST 2016-04-13 17:17:14 +02:00
Axel Burri 6b07316fef documentation: README.md: use new preserve semantics in examples 2016-04-12 12:07:33 +02:00
Axel Burri 7a334097c1 btrbk: cosmetics (logging and summary text about -p option) 2016-04-12 11:47:41 +02:00
Axel Burri 1e91f179d4 documentation: btrbk.1: update sections containing infos about retention policy; fix documentation of -p option; cosmetics 2016-04-12 11:47:41 +02:00
Axel Burri 326edfcc29 btrbk: change preserve semantics (incompatible):
- add "{snapshot,target}_preserve_all" configuration option

- change semantics of "{snapshot,target}_preserve NNd" to "preserve
  latest daily only"

- change default of "preserve daily,monthly" to 0 (was: all)

- add deprecated warning and enter compatibility mode: preserve
  everything if deprecated {snapshot,target}_preserve_* options are
  encountered
2016-04-12 11:47:28 +02:00
Axel Burri ceb4dbf19c btrbk: add --print-schedule command line option 2016-04-09 14:16:14 +02:00
Axel Burri 78bfc5b885 btrbk: bugfix: use "/bin/false" as RSH if no config is available 2016-04-08 13:38:50 +02:00
Axel Burri ccc2a35520 ChangeLog: update missing items 2016-04-07 15:53:50 +02:00
Axel Burri a887e89732 btrbk: warn on receive targets at unexpected location (whole filesystem) when resuming missing backups (do not abort anymore); 2016-04-07 14:35:27 +02:00
Axel Burri 6b71b68fcb btrbk: bugfix: do not run "rm" command with no arguments (on raw targets) 2016-04-06 20:41:36 +02:00
Axel Burri 5d65748ffe btrbk: call init_transaction_log() at the beginning of every action, instead at global place 2016-04-06 20:27:27 +02:00
Axel Burri 211964f709 btrbk: parse btrbk_basename and btrbk_date in vinfo_child() instead of vinfo_subvol_list() 2016-04-06 20:24:56 +02:00
Axel Burri bfb556757d btrbk: get_latest_common(): use all brothers (snapshots with same parent) as candidates (older first, then newer) instead of only older; as last resort, use subvolumes in snapshot_dir matching btrbk file name scheme as candidates 2016-04-06 15:36:54 +02:00
Axel Burri 46e3aae857 btrbk: get_latest_common(): add strategy to find latest common for readonly and received subvolumes; add helper function cmp_date() 2016-04-06 15:36:51 +02:00
Axel Burri a26e8851b4 btrbk: btr_tree: return already assembled tree if a subvolume is already known in uuid_cache 2016-04-06 15:36:27 +02:00
Axel Burri ac0002bce8 btrbk: get_receive_targets() also returns matching source_received_uuid 2016-04-06 15:36:27 +02:00
Axel Burri 4b1983378f btrbk: add useful flags and parse date and basename of btrbk created files in vinfo_subvol_list(); replace parse_filename() calls by usage of new flags 2016-04-06 13:35:37 +02:00
Axel Burri 0bfb78b842 btrbk: remove trailing slash from NODE_SUBDIR 2016-04-03 21:41:41 +02:00
Axel Burri 899ca92026 btrbk: bugfix: untaint raw backup file list read by "find" command 2016-04-03 21:38:19 +02:00
Axel Burri 023004e9cc btrbk: bugfix: add '=' character to (regression introduced in a7cd4a99) 2016-04-03 21:09:30 +02:00
Axel Burri ea5cd06fbc btrbk: bugfix: get_receive_targets() for BTRFS_PROGS_COMPAT (regression introduced in 207e8868) 2016-04-03 21:09:30 +02:00
Axel Burri 302400d640 btrbk: bugfix: disallow snapshot_preserve_* in target section 2016-04-03 15:13:16 +02:00
Axel Burri a7cd4a994c btrbk: add some extra safety when running shell commands 2016-04-02 14:13:16 +02:00
Axel Burri 86170e6b21 btrbk: bugfix: untaint result of system_realpath() 2016-04-02 14:10:35 +02:00
Axel Burri 407d25f604 ssh_filter_btrbk: cosmetics: fix indentation (remove tabs) 2016-03-31 17:24:24 +02:00
Axel Burri ccb5ed5e71 ssh_filter_btrbk: allow "realpath" and "cat /proc/self/mounts" on targets 2016-03-31 17:24:24 +02:00
Axel Burri 90a3537433 documentation: add documentation for target propagation and target directories 2016-03-31 17:24:24 +02:00
Axel Burri 79caba4267 btrbk: rename %symlink -> %realpath_cache (returning real_path instead of real_url) 2016-03-31 17:24:24 +02:00
Axel Burri 7ee5778dee btrbk: bugfix: print correct target on "same backup target error" 2016-03-31 17:24:24 +02:00
Axel Burri c4073f6c53 btrbk: print target_path instead of target_subvol for "list {target,config}" 2016-03-31 17:24:24 +02:00
Axel Burri 3ada7c174e btrbk: allow targets to be directories (use mountpoint framework) 2016-03-31 17:24:24 +02:00
Axel Burri 06043cf800 btrbk: add btrfs mountpoint resolving functionality 2016-03-31 17:24:23 +02:00
Axel Burri de96f267b8 btrbk: propagate target sections to (sub-)subsections (allow target sections everywhere in the config) 2016-03-31 17:24:18 +02:00
Axel Burri f9ca7504c8 btrbk: add configuration option "rate_limit" (using pv -L)
Original patch provided by @janpascal: "Jan-Pascal van Best"
2016-03-23 11:58:35 +01:00
Axel Burri e6d46e8a02 btrbk: fix regression: correctly handle previously received subvolumes in get_latest_common()
regression from: 8819c67502
2016-03-22 19:30:21 +01:00
Axel Burri 7bb18050f8 btrbk: detect interrupted transfers of raw targets; delete incomplete raw targets on action "clean" 2016-03-22 19:28:05 +01:00
Moritz Ulrich d47cc25f60 btrbk-mail: bugfix: use `btrbk` instead of unbound variable `$btrbk` 2016-03-21 18:52:53 +01:00
Axel Burri c2b11775a0 btrbk: cosmetics: adapt debug/trace messages 2016-03-16 19:21:48 +01:00
Axel Burri 1adb318f02 documentation: cosmetics: change all url from www.digint.ch to digint.ch 2016-03-16 18:34:28 +01:00
Axel Burri cd8ac043a8 ChangeLog: add missing items 2016-03-16 18:34:28 +01:00
Axel Burri 247f023bab btrbk: allow wildcards in subvolume section; add option "wildcards" in check_file() 2016-03-16 18:17:44 +01:00
Axel Burri b9fa3e6e90 btrbk: add init_config(); use default config in action "diff"; use root config context for action "origin" 2016-03-15 16:54:54 +01:00
Axel Burri 8819c67502 btrbk: fixed raw targets 2016-03-15 14:53:51 +01:00
Axel Burri e9bc4950ac btrbk: re-ordering of functions (no functional changes) 2016-03-15 11:21:59 +01:00
Axel Burri 207e8868da btrbk: no more copy of node information in vinfo by vinfo_set_detail(); always use vinfo->{node}{key}; cleanup 2016-03-14 20:21:12 +01:00
Axel Burri 9a68ab6519 btrbk: use symlink hash instead of REAL_URL 2016-03-14 15:56:20 +01:00
Axel Burri cab2a88843 btrbk: move url_cache lookup to vinfo_subvol_list 2016-03-14 12:59:24 +01:00
Axel Burri 14d1ca1976 btrbk: add warning if a receive target of resume candidate exists at unexpected location 2016-03-12 19:16:07 +01:00
Axel Burri 1b45db3c59 btrbk: simplify btr_tree: SUBTREE is now list instead of hash; add TREE_ROOT pointer to every node; cleanup 2016-03-11 14:55:22 +01:00
Axel Burri 97caced09d btrbk: rename %btrfs_tree_cache -> %url_cache, %uuid_info -> %uuid_cache; cleanup 2016-03-10 22:21:55 +01:00
Axel Burri 84820933ed btrbk: remove %uuid_url_map (replace by get_cached_url_by_uuid() operating on %btrfs_tree_cache) 2016-03-10 22:21:55 +01:00
Axel Burri 743d7704f5 btrbk: correctly fill cache; fix vinfo_set_detail; add debug functionality (VINFO(), SUBTREE_LIST()); cleanup 2016-03-10 22:21:55 +01:00
Axel Burri e85b6dadf1 btrbk: data structure refactoring:
- remove %subvol_list_cache: may slow down aa bit, but makes possible
  to inject nodes correctly

- simplify subtree list (is now an array as it should have been from
  the beginning); correctly fill tree_cache

- fix vinfo_set_detail; cleanup
2016-03-10 22:19:36 +01:00
Axel Burri 1d054bf04a btrbk: refactoring of add global caches: reduce btrfs-progs calls, and make sure all root vinfo (especially targets) with same URL share the same SUBVOL_LIST reference.
- %btrfs_tree_cache (replaces %root_tree_cache)

- %subvol_list_cache (replaces %vinfo_cache):

- vinfo_init_root() (was: vinfo_root()) now lookups in cache before
  calling btrfs_subvolume_detail()

- vinfo_subvol_list() now lookups in cache before calling
  btrfs_subvolume_list()
2016-03-09 19:52:45 +01:00
Axel Burri ba90c13320 btrbk: fixed schedule() debug text 2016-03-08 18:22:58 +01:00
Axel Burri c1b27c744b btrbk: clone target subvolume tree if same url as other target (less btrfs calls, shared SUBVOL_LIST) 2016-03-08 16:41:02 +01:00
Axel Burri eba08f2ca3 btrbk: add config_preserve_hash(); fix macro_delete() 2016-03-08 15:31:16 +01:00
Axel Burri 5cc908313a btrbk: cleanup trace output; cosmetics 2016-03-08 15:31:08 +01:00
Axel Burri f770488d85 btrbk: adapt all actions to use vinfo_subsection() 2016-03-07 22:54:27 +01:00
Axel Burri fbbd82114d btrbk: move SUBVOL_RECEIVED, SUBVOL_DELETED, SNAPSHOT_CREATED, SNAPSHOT_UP_TO_DATE data from config to corresponding vinfo 2016-03-07 21:45:12 +01:00
Axel Burri 6f1e94eb27 btrbk: adapt action "run" to use vinfo_subsection() 2016-03-07 20:47:24 +01:00
Axel Burri b2be1357eb btrbk: fixed vinfo_set_detail(), while being very paranoid; fixed vinfo_subsection (was: valid_subsection_vinfo); adaptions in vinfo readin (working again) 2016-03-07 20:30:06 +01:00
Axel Burri ab4ded9830 btrbk: ABORTED() now sets $abrt to last message (useful for warnings after abort) 2016-03-07 20:29:57 +01:00
Axel Burri 96faae9659 btrbk: be harsh, remove sroot, droot, svol in config (will break a lot of things!) 2016-03-07 19:15:57 +01:00
Axel Burri d3148851c5 btrbk: first adaptions for vinfo holding config 2016-03-07 17:36:02 +01:00
Axel Burri ceb346db66 btrbk: skeleton for vinfo holding config 2016-03-07 17:35:17 +01:00
Axel Burri 5030d54318 btrbk: split "check for duplicate snapshot locations" from "fill vinfo hash" 2016-03-07 15:33:37 +01:00
Axel Burri 46bd1ad52a btrbk: add function macro_delete(), used by snapshot/backup delete 2016-03-02 00:04:24 +01:00
Axel Burri e806d4812f btrbk: cosmetics: adapt debug text and variable names for macro_send_receive() and similar 2016-03-01 21:55:09 +01:00
Axel Burri 6c9643f2be btrbk: action "diff": print total size 2016-03-01 21:52:06 +01:00
Axel Burri a1124053a7 btrbk: bugfix: sort numerically (low prio, affects only list output) 2016-03-01 19:31:43 +01:00
Axel Burri ac1b7271c4 btrbk: read readonly flag in btrfs_subvolume_list(). this requires an additional call to btrfs-progs. 2016-03-01 15:10:37 +01:00
Axel Burri 9eb38ac9d0 btrbk: add {snapshot,target}_preserve shortcut 2016-03-01 12:30:35 +01:00
Axel Burri b90cc132c1 documentation: add documentation for {snapshot,target}_preserve_yearly 2016-03-01 12:07:37 +01:00
Axel Burri 4aa4be3942 btrbk: different (correct) text output for scheduler results 2016-03-01 11:40:27 +01:00
Axel Burri a049d18b90 btrbk: implement {snapshot,target}_preserve_yearly 2016-03-01 11:40:20 +01:00
Axel Burri cf8e136681 documentation: cosmetics: use "*" instead of "-" for enumerations; two newlines before headings 2016-02-29 14:02:36 +01:00
Axel Burri 4a41413793 documentation: btrbk.1: more precice description of "btrbk list latest" 2016-02-03 12:43:20 +01:00
Axel Burri 8b071c5827 documentation: FAQ: change note about re-sending subvolumes (kernels 4.4 fix the issue) 2016-02-03 12:39:49 +01:00
29 changed files with 10232 additions and 3923 deletions

3
.gitattributes vendored Normal file
View File

@ -0,0 +1,3 @@
# remove files from deployment using `git archive`
.gitattributes export-ignore
.gitignore export-ignore

3
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,3 @@
# These are supported funding model platforms
custom: ['https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WFQSSCD9GNM4S', 'https://btc.com/19DYtoEepxBmn9ZPspJGZrhCtySKCxPcP1']

26
.github/workflows/codespell.yml vendored Normal file
View File

@ -0,0 +1,26 @@
---
name: Codespell
on:
push:
branches: [master]
pull_request:
branches: [master]
permissions:
contents: read
jobs:
codespell:
name: Check for spelling errors
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Codespell
uses: codespell-project/actions-codespell@v2
with:
check_filenames: true
skip: ".git,*.pdf,*.svg"
ignore_words_list: uptodate

397
ChangeLog
View File

@ -1,3 +1,400 @@
btrbk-0.32.6
* Fix backup of unrelated (by parent_uuid) snapshots (close #339).
* Remove echo -e for portability (close #506).
* Support btrfs send protocol v2 (send_protocol and
send_compressed_data config options).
* Add bzip3 support.
* Convert ssh_filter_btrbk.sh to POSIX sh, and harden it.
* Slight change in ssh_filter_btrbk.sh logging output.
* Minor bugfixes, stability and documentation improvements.
btrbk-0.32.5
* Correct handling of zero-size raw info file (close #491).
btrbk-0.32.4
* Fix regression: wrong deprecation warnings in some cases.
btrbk-0.32.3
* Fix deletion of many subvolumes at once (close #476).
* Allow disabling ssh_identity and ssh_user options.
* Minor bugfixes and documentation improvements.
btrbk-0.32.2
* Fix regression: archive on missing target directories.
* Fix action "config print".
* Print version and help message to stdout (close #452).
* Check results of filesystem usage (close #469).
* Add "compat ignore_receive_errors" option (close #383).
* Support multiple gpg recipients (close #471).
* Fix changelog: remove "compat missing_otime" item in v0.32.1.
* Fix changelog: correct "warn_unknown_targets" item in v0.31.3.
* Minor bugfixes and framework improvements.
btrbk-0.32.1
* Fix regression: correctly read mountinfo (close #445).
* Fix regression: filter paths for "lsbtr" (action "ls").
* Add backend btrfs-progs-doas (close #444).
* Allow directory traversal for local command line arguments.
* Display all source subvolumes in "usage" action.
* Handle errors from btrfs filesystem usage.
btrbk-0.32.0
* MIGRATION
- If timestamp_format is not configured, explicitly set
"timestamp_format short" to revert old behavior.
- Update ssh_filter_btrbk.sh on remote hosts.
* Change default for timestamp_format to "long".
* Optional "volume" config section.
* Use "volume" section only for grouping and relative paths.
* Allow absolute path for "subvolume" and "snapshot_dir"
(close #407, #121).
* Support subvolume names with UTF-8 characters (close #392, #213,
#120). Add "safe_commands" option for paranoid people.
* Add "incremental_prefs" configuration option (close #387).
* Change incremental prefs policy, giving snapshots created by btrbk
higher preference than the global ones resolved by parent-uuid.
* Change "incremental_clones" option to boolean.
* Drop support of deprecated raw file format (btrbk < 0.26.0).
* Drop support of deprecated "-r, --resume-only" cmdline option.
* Fix ambiguous naming in --format=raw output of "list" actions.
* Accept quoted values in config.
* Use single quotes for raw table output.
btrbk-0.31.3
* Add "warn_unknown_targets" configuration option (close #393).
* Add -1,--single-column command-line option for listing actions.
* Allow relative path command line argument for all actions.
* Add support for zstd adaptive compression (close #397).
* Add contrib/tools/btrbk_restore_raw.py (close #401).
* Minor bugfixes and framework improvements.
btrbk-0.31.2
* MIGRATION
- Update ssh_filter_btrbk.sh on remote hosts.
* ssh_filter_btrbk.sh: Fix security vulnerability.
Specially crafted commands may be executed without being properly
checked. Applies to remote hosts filtering ssh commands using
ssh_filter_btrbk.sh in authorized_keys.
* Warn if no subvolume defined in config (close #378).
btrbk-0.31.1
* Bugfix: duplicate snapshot location check (close #360).
* Bugfix: action "list all" (close #367).
* btrbk-mail: optionally prefix command output lines.
btrbk-0.31.0
* Add action "extents [diff]": print accurate disk space usage based
on block regions (extent data, FIEMAP ioctl).
* Improve action "list" and "stats" table output (close #334).
* Add subcommand "list all", make default for "list" action.
* Change semantics on output of action "list": show only btrbk
snapshots/backups (close #333).
* Print human readable units in action "diff" (close #345).
* Allow custom table format definitions from command line.
* Add Bash completion (close #343).
* Add support for zstd compression (close #358).
* Bugfix: fs_path fallback for action "origin" and logging.
* Bugfix: makefile bin-links race (close #341).
btrbk-0.30.0
* MIGRATION
- In your scripts (e.g. cron jobs, systemd units), replace
"/usr/sbin/btrbk" with "/usr/bin/btrbk".
* Install to "/usr/bin" instead of "/usr/sbin".
* Support IPv6 addresses (close #332).
* Add "compat busybox" configuration option (close #327).
* Create "lsbtr" symlink (alias for "btrbk ls").
* Improve action "ls" (allow url, bugfixes).
* Add "backend_local_user" configuration option.
* btrbk-mail: add more elaborated email and rsync options.
* Minor bugfixes and framework improvements.
btrbk-0.29.1
* Allow multiple path arguments for action "ls".
* Change default output to format=short for action "ls".
* ssh_filter_btrbk.sh: exclude "btrfs subvolume show|list" from
restrict-path (close #309).
* Bugfix: fix filter statement match on wildcards (close #311).
* Fix regression: print ssh errors only if needed.
btrbk-0.29.0
* MIGRATION
- If stream_buffer or rate_limit is configured, please install
"mbuffer" (version >= 20180505). Note that mbuffer is only
required on remote hosts if stream_buffer_remote or
rate_limit_remote is set.
- In order to mimic old behavior, replace rate_limit with
rate_limit_remote, and read btrbk.conf(5).
- If you are using table output other than --format=raw in your
scripts, note that the column headings changed from pretty
two-line to (uppercase) one-line format. Either add --pretty
option to mimic old behavior, or adapt your scripts.
* Dropped run-time dependency on "pv" (in favor of "mbuffer").
* Combined stream_buffer and rate_limit: for rate_limit, use
"mbuffer" (on local host) instead of "pv" (on source host).
* Add stream_buffer_remote and rate_limit_remote options.
* Use "mbuffer" instead of "pv" for --progress display.
* Add stream_buffer functionality for raw targets.
* Add action "ls": list all btrfs subvolumes below given path.
* Change table output: print single-line, uppercase headings.
* ssh_filter_btrbk.sh: whitelist mkdir if -t,--target option is set,
used by "btrbk archive" action (close #297).
* Bugfix: handle subvolumes with special characters (close #288).
* Bugfix: don't display "<no_action>" in backup summary if volume is
skipped by --exclude or noauto (close #291).
* Bugfix: systemd: Use WantedBy=timers.target instead of
WantedBy=multi-user.target in btrbk.timer (close #293).
btrbk-0.28.3
* Bugfix: return exitcode=10 if action skipped by stray subvolumes
(close: #285).
* Bugfix: correctly handle root subvolumes having uuid.
* Bugfix: fix mount point resolving.
btrbk-0.28.2
* Fix regression: crash if raw target dir is empty (close #281).
* Bugfix: honor incremental_resolve on targets: resolve from
mountpoint instead of directory.
* Bugfix: handle directories named "0" correctly.
btrbk-0.28.1
* Fix regression: crash if deep parent/child relations exceed
depth=100 (close #279).
* Remove pre-generated man pages, requires "asciidoctor" for builds.
btrbk-0.28.0
* MIGRATION
- Replace "ssh_port" options with "ssh://hostname[:port]" notation
on "volume" or "target" declarations.
- Check filter statements in your scripts ("btrbk run <filter>"),
especially when using groups having the same name as subvolumes.
* Fix table format "resolved" (btrbk list snapshots|backups).
* Add btrbk-verify: tool for automated backup integrity check based
on rsync (close #256).
* Use "ssh://hostname[:port]" notation instead of ambiguous
"ssh_port" option (now deprecated).
* Bugfix: correctly handle multiple volume sections with same host,
but distinct port numbers (virtual machines setups, close #233).
* Remove selected rows ("*host", "*port") from table output if all
values are empty.
* Consider all parent/child relations (close #255).
* Disallow unrelated parents for btrfs-send if incremental=strict.
* Add clone sources to btrfs-send if necessary.
* Add "incremental_resolve" configuration option.
* Add "incremental_clones" configuration option.
* Add "noauto" configuration option.
* Add "--exclude" command line option.
* Make target_type optional, defaults to "send-receive".
* Use more sophisticated filter arguments.
* Allow whitespace separated "group" option.
btrbk-0.27.2
* Bump dependency >= btrfs-progs-4.12 (as of btrbk-0.27.0).
* Trigger autofs mount while resolving mountpoints (close #259).
* Bugfix: fix scheduler when overriding "target_preserve_min" in
combination with global "target" section.
btrbk-0.27.1
* MIGRATION
- Update ssh_filter_btrbk.sh on remote hosts if using
backend=btrfs-progs-sudo.
* Bugfix (regression): call "sudo -n readlink" for
backend=btrfs-progs-sudo (close #257).
* Bugfix (regression): fix failing "config print" command.
* Don't print title and blank lines for --format=raw, syslog and
transaction log.
btrbk-0.27.0
* MIGRATION
- Run "btrbk prune --dry-run --print-schedule" and check if any
snapshots/backups would get deleted [1] [2]. If you want to
forcibly preserve a snapshot/backup forever, rename it (btrbk
ignores subvolumes with unknown naming scheme), e.g.:
"mv mysubvol.YYYYMMDD mysubvol.YYYYMMDD.keep_forever"
- Update ssh_filter_btrbk.sh on remote hosts (btrbk always calls
"readlink" and "cat /proc/self/mountinfo").
* Add "preserve_hour_of_day" configuration option (close #202).
* Allow backup of filesystem root using "subvolume ." (close #240).
* Add "-S" command line option (shortcut for --print-schedule).
* Bugfix: correct scheduling of "first weekly backup in month/year"
(close #217) [1] [2].
* Bugfix: add "btrfs filesystem usage" backend mapping (close #222).
* Bugfix: do not fail (exitcode=10) if targets are not accessible on
"btrfs snapshot --preserve".
* Bugfix: if "incremental no" is configured on target, do not keep
latest common snapshot.
* Enhance internal data structures:
- Allow snapshot_dir to be a mountpoint.
- Search complete target tree for correlated subvolumes.
- Include snapshots from all mountpoints as candidates (disabled
due to upstream bug: github.com/kdave/btrfs-progs/issues/96).
- Read /proc/self/mountinfo instead of /proc/self/mounts.
- Always read /proc/self/mountinfo.
- Resolve realpath using readlink(1).
* Fallback to "asciidoctor" for manpage generation (close #219).
[1] https://github.com/digint/btrbk/issues/217
[2] https://github.com/digint/btrbk/commit/719fb5f
btrbk-0.26.1
* Add "archive_exclude" configuration option.
* Add warning on redefined configuration option.
* Bugfix: fix parsing of "openssl_iv_size" configuration option.
* Bugfix: fix filter statement matching for volume=/ (close #209).
btrbk-0.26.0
* MIGRATION
- If you are using raw targets, make sure to run the
"raw_suffix2sidecar" utility in each target directory.
* Support for btrfs-progs v4.13.2: adapt parsing of "btrfs sub list"
output (close #192).
* Add "resume" command, replacement for "-r, --resume-only" command
line option (which is now deprecated).
* Add "snapshot" command (close #150).
* Add "prune" command.
* Add "--preserve-snapshots" and "--preserve-backups" options.
* Add "--wipe" command line option (close #173).
* Change raw backup format (sidecar file instead of uuid in file).
* Honor target_preserve for raw targets (delete raw targets).
* Add symmetric encryption for raw targets (close #157).
* Add "{snapshot,target,archive}_qgroup_destroy" configuration
options (close #49, #189).
* Do not run in "perl taint mode" by default: remove "perl -T" in
hashbang; hardcode $PATH only if taint mode is enabled.
* Remove "duration" column from transaction_log/transaction_syslog.
* Resolve ancestors (recursive on parent_uuid chain) when searching
for latest common subvolume.
* Generate man pages from asciidoc (remove raw groff sources).
* Bugfix: ssh_filter_btrbk: accept mbuffer command (stream_buffer).
* Bugfix: print correct (end-)time in transaction_log.
* Bugfix: check path when expanding wildcards (close #181).
* Bugfix: never show failed deletes in summary (close #183).
btrbk-0.25.1
* Support for btrfs-progs v4.12: fix parsing of "btrfs sub show"
output, which now prints relative paths (close #171).
* Add "stream_buffer" configuration option (close #154).
* Bugfix: accept "no" for "transaction_log", "transaction_syslog"
and "lockfile" configuration options.
* Show "up-to-date" status for backups in "stats" command.
* Show "correlated" status instead of "orphaned" in "stats" command.
* Check source subvolumes for readonly and received_uuid flags, and
abort if one of them is set.
btrbk-0.25.0
* MIGRATION
- If you call ssh_filter_btrbk.sh with "--sudo" option, make sure
to set "backend btrfs-progs-sudo" in btrbk.conf for this host.
- If "rate_limit" is enabled, update ssh_filter_btrbk.sh on remote
source hosts, and make sure the "pv" command is available there.
* Allow converting backup disks to source disks (close #114).
* Add "backend btrfs-progs-sudo" configuration option (close #115).
* Show aggregate "size" and "used" for "usage" action (close #119).
* Add "raw_target_split" configuration option (close #125).
* Allow trailing comments in btrbk.conf (close #129).
* Bugfix: rate limiting must be done after compression (close #134).
* raw_target_encrypt: Always set "gpg --no-random-seed-file":
prevents creation of "~/.gnupg/random_seed" with slight performance
penalty.
btrbk-0.24.0
* MIGRATION
- update ssh_filter_btrbk.sh on remote hosts if "stream_compress"
is enabled. Also add "--compress" option to ssh_filter_btrbk.sh
invocation if "stream_compress" is enabled.
* Add "stream_compress" configuration option.
* Perform extra metadata check on target subvolume after "btrfs
receive" (adds an additional call to "btrfs subvolume show").
* Bugfix: Replace "realpath" with "readlink" in ssh_filter_btrbk.sh
* Add "raw_target_block_size" configuration option (close #105).
* Add "backend" configuration option (experimental).
* Bugfix: fix "list latest" with no snapshots (close #111).
* Support for btrfs-progs v4.8.3: fix parsing of "btrfs sub show"
output, which has changed for toplevel subvolume.
btrbk-0.23.3
* Replace "realpath -e" with "readlink -e" for mountpoint discovery
(close #92).
* Dynamically set BINDIR in btrbk.service by Makefile.
* Add ChangeLog to DOCDIR in Makefile.
btrbk-0.23.2
* Added "lockfile" configuration option and --lockfile command line
option (close: #81).
* Bugfix: raw targets: correctly handle multiple backups in same
target directory (close: #87).
* Use relative instead of absolute binary calls in btrbk-mail.
btrbk-0.23.1
* Bugfix: set correct parent section when propagating targets
(close: #85).
* Add syslog output of transaction log (close #82).
* Do not print headers to transaction log anymore.
* Explain "orphaned" status in "stats" command, and suppress it on
"list backups" command (close: #76).
btrbk-0.23.0
* INCOMPATIBLE CONFIGURATION:
* Please read "doc/upgrade_to_v0.23.0.md" for details on updating
the configuration file (/etc/btrbk/btrbk.conf).
* Dropped "btrfs_progs_compat" option. Need btrfs-progs >= v3.18.
* Removed "resume_missing" configuration option.
* Create backups only if needed to satisfy retention policy.
* Preserve FIRST backup of hour/day/week/month instead of LAST.
* Replaced "{snapshot,target}_preserve_{daily,weekly,monthly}"
configuration options with "{snapshot,target}_preserve_min" and
"{snapshot,target}_preserve NNh NNd NNw NNm NNy" options.
* Added hourly/yearly retention policies (close: #36, #69).
* Allow regular directories for send-receive targets (close: #77).
* Allow wildcards in subvolume section (close: #71).
* Propagate targets defined in "volume" or "root" context to all
"subvolume" sections (close: #78).
* Added "archive" command (close: #79).
* Changed output format of "origin" command, add table formats.
* Added configuration option "rate_limit" (close: #72).
* Added new timestamp_format "long-iso", having a timezone postfix.
* Added "--print-schedule" command line option.
* Detect interrupted transfers of raw targets (close: #75).
* Always read "readonly" flag (additional call to btrfs-progs).
* Warn on receive targets at unexpected location (instead of abort).
* On incremental send/receive, use all snapshots sharing same
parent_uuid as candidates for "-p <parent>" instead of only older
snapshots. As last resort, use subvolumes in snapshot_dir matching
btrbk file name scheme as candidates (which allows incremental
backups after the parent vanished, e.g. after backup restore).
* Use perl built-in Time::Local instead of Date::Calc.
* Improvements of internal data structures.
btrbk-0.22.2 btrbk-0.22.2
* Bugfix: fix checks on "btrfs sub show" output, which resulted in * Bugfix: fix checks on "btrfs sub show" output, which resulted in

114
Makefile
View File

@ -1,47 +1,113 @@
PN = btrbk #
# Btrbk is a single perl script, and does not require any special
# installation procedures or libraries. There is no need to run the
# "all" build target if you don't want to build the man pages (see
# doc/Makefile).
#
# Note: systemd units (file names) are hardcoded in "install-systemd"
# build target for simplicity.
#
BIN = btrbk
BIN_LINKS = lsbtr
CONFIGS = btrbk.conf.example
DOCS = ChangeLog \
README.md
SCRIPTS = ssh_filter_btrbk.sh \
contrib/cron/btrbk-mail \
contrib/cron/btrbk-verify \
contrib/migration/raw_suffix2sidecar \
contrib/crypt/kdf_pbkdf2.py \
contrib/tools/btrbk_restore_raw.py
PN = btrbk
PREFIX ?= /usr PREFIX ?= /usr
CONFDIR = /etc CONFDIR = /etc
CRONDIR = /etc/cron.daily CRONDIR = /etc/cron.daily
BINDIR = $(PREFIX)/sbin BINDIR = $(PREFIX)/bin
DOCDIR = $(PREFIX)/share/doc/$(PN) DOCDIR = $(PREFIX)/share/doc/$(PN)
SCRIPTDIR = $(PREFIX)/share/$(PN)/scripts SCRIPTDIR = $(PREFIX)/share/$(PN)/scripts
SYSTEMDDIR = $(PREFIX)/lib/systemd/system SYSTEMDDIR = $(PREFIX)/lib/systemd/system
BASHCOMPDIR = $(PREFIX)/share/bash-completion/completions
MAN1DIR = $(PREFIX)/share/man/man1 MAN1DIR = $(PREFIX)/share/man/man1
MAN5DIR = $(PREFIX)/share/man/man5 MAN5DIR = $(PREFIX)/share/man/man5
all: ifeq ($(COMPRESS), yes)
@echo 'nothing to do for "all"' DOCS := $(addsuffix .gz,$(DOCS))
endif
replace_vars = sed \
-e "s|@PN@|$(PN)|g" \
-e "s|@CONFDIR@|$(CONFDIR)|g" \
-e "s|@CRONDIR@|$(CRONDIR)|g" \
-e "s|@BINDIR@|$(BINDIR)|g" \
-e "s|@DOCDIR@|$(DOCDIR)|g" \
-e "s|@SCRIPTDIR@|$(SCRIPTDIR)|g" \
-e "s|@SYSTEMDDIR@|$(SYSTEMDDIR)|g" \
-e "s|@BASHCOMPDIR@|$(BASHCOMPDIR)|g" \
-e "s|@MAN1DIR@|$(MAN1DIR)|g" \
-e "s|@MAN5DIR@|$(MAN5DIR)|g"
all: man
install: install-bin install-bin-links install-etc install-completion install-systemd install-share install-man install-doc
install-bin: install-bin:
@echo 'installing main script and config...' @echo 'installing binary...'
install -Dm644 btrbk.conf.example "$(DESTDIR)$(CONFDIR)/btrbk/btrbk.conf.example" install -d -m 755 "$(DESTDIR)$(BINDIR)"
install -Dm755 $(PN) "$(DESTDIR)$(BINDIR)/$(PN)" install -p -m 755 $(BIN) "$(DESTDIR)$(BINDIR)"
install-bin-links: install-bin
@echo 'installing symlinks...'
for name in $(BIN_LINKS); do \
ln -s -n -f $(BIN) "$(DESTDIR)$(BINDIR)/$$name"; \
done
install-etc:
@echo 'installing example configs...'
install -d -m 755 "$(DESTDIR)$(CONFDIR)/btrbk"
install -p -m 644 $(CONFIGS) "$(DESTDIR)$(CONFDIR)/btrbk"
install-completion:
@echo 'installing bash completion...'
install -d -m 755 "$(DESTDIR)$(BASHCOMPDIR)"
install -p -m 644 contrib/bash/completion.bash "$(DESTDIR)$(BASHCOMPDIR)/$(BIN)"
for name in $(BIN_LINKS); do \
ln -s -n -f $(BIN) "$(DESTDIR)$(BASHCOMPDIR)/$$name"; \
done
install-systemd: install-systemd:
@echo 'installing systemd service units...' @echo 'installing systemd service units...'
install -Dm644 contrib/systemd/btrbk.service "$(DESTDIR)$(SYSTEMDDIR)/btrbk.service" install -d -m 755 "$(DESTDIR)$(SYSTEMDDIR)"
install -Dm644 contrib/systemd/btrbk.timer "$(DESTDIR)$(SYSTEMDDIR)/btrbk.timer" $(replace_vars) contrib/systemd/btrbk.service.in > contrib/systemd/btrbk.service.tmp
$(replace_vars) contrib/systemd/btrbk.timer.in > contrib/systemd/btrbk.timer.tmp
install -p -m 644 contrib/systemd/btrbk.service.tmp "$(DESTDIR)$(SYSTEMDDIR)/btrbk.service"
install -p -m 644 contrib/systemd/btrbk.timer.tmp "$(DESTDIR)$(SYSTEMDDIR)/btrbk.timer"
rm contrib/systemd/btrbk.service.tmp
rm contrib/systemd/btrbk.timer.tmp
install-share: install-share:
@echo 'installing auxiliary scripts...' @echo 'installing auxiliary scripts...'
install -Dm755 ssh_filter_btrbk.sh "$(DESTDIR)$(SCRIPTDIR)/ssh_filter_btrbk.sh" install -d -m 755 "$(DESTDIR)$(SCRIPTDIR)"
install -Dm755 contrib/cron/btrbk-mail "$(DESTDIR)$(SCRIPTDIR)/btrbk-mail" install -p -m 755 $(SCRIPTS) "$(DESTDIR)$(SCRIPTDIR)"
install-man: install-man: man
@echo 'installing man pages...' @echo 'installing man pages...'
install -Dm644 doc/btrbk.1 "$(DESTDIR)$(MAN1DIR)/btrbk.1" @$(MAKE) -C doc install-man
install -Dm644 doc/ssh_filter_btrbk.1 "$(DESTDIR)$(MAN1DIR)/ssh_filter_btrbk.1"
install -Dm644 doc/btrbk.conf.5 "$(DESTDIR)$(MAN5DIR)/btrbk.conf.5"
gzip -9 "$(DESTDIR)$(MAN1DIR)/btrbk.1"
gzip -9 "$(DESTDIR)$(MAN1DIR)/ssh_filter_btrbk.1"
gzip -9 "$(DESTDIR)$(MAN5DIR)/btrbk.conf.5"
install-doc: install-doc: $(DOCS)
@echo 'installing documentation...' @echo 'installing documentation...'
install -Dm644 README.md "$(DESTDIR)$(DOCDIR)/README.md" install -d -m 755 "$(DESTDIR)$(DOCDIR)"
install -Dm644 doc/FAQ.md "$(DESTDIR)$(DOCDIR)/FAQ.md" install -p -m 644 $(DOCS) "$(DESTDIR)$(DOCDIR)"
gzip -9 "$(DESTDIR)$(DOCDIR)/README.md" @$(MAKE) -C doc install-doc
gzip -9 "$(DESTDIR)$(DOCDIR)/FAQ.md"
install: install-bin install-systemd install-share install-man install-doc man:
@echo 'generating manpages...'
@$(MAKE) -C doc man
clean:
rm -f *.gz
@$(MAKE) -C doc clean
%.gz : %
gzip -9 -n -c $< > $@

775
README.md
View File

@ -1,7 +1,7 @@
Introduction Introduction
============ ============
btrbk is a backup tool for btrfs subvolumes, taking advantage of btrfs Btrbk is a backup tool for btrfs subvolumes, taking advantage of btrfs
specific capabilities to create atomic snapshots and transfer them specific capabilities to create atomic snapshots and transfer them
incrementally to your backup locations. incrementally to your backup locations.
@ -9,189 +9,264 @@ The source and target locations are specified in a config file, which
allows to easily configure simple scenarios like "laptop with locally allows to easily configure simple scenarios like "laptop with locally
attached backup disks", as well as more complex ones, e.g. "server attached backup disks", as well as more complex ones, e.g. "server
receiving backups from several hosts via ssh, with different retention receiving backups from several hosts via ssh, with different retention
policy". policies".
Key Features: Key Features:
- Atomic snapshots * Atomic snapshots
- Incremental backups * Incremental backups
- Configurable retention policy * Flexible retention policy
- Backups to multiple destinations * Backups to multiple destinations
- Transfer via ssh * Transfer via ssh
- Resume of backups (if backup target was not reachable for a while) * Robust recovery from interrupted backups (for removable and mobile
- Encrypted backups to non-btrfs destinations devices)
- Transaction log * Archive to offline storage
- Display file changes between two backups * Encrypted backups to non-btrfs storage
* Wildcard subvolumes (useful for docker and lxc containers)
* Transaction log
* Comprehensive list and statistics output
* Resolve and trace btrfs parent-child and received-from relationships
* List file changes between backups
* Calculate accurate disk space usage based on block regions
btrbk is intended to be run as a cron job. Btrbk is designed to run as a cron job for triggering periodic
snapshots and backups, as well as from the command line (e.g. for
instantly creating additional snapshots).
Installation Installation
============ ============
btrbk comes as a single executable file (perl script), without the Btrbk is a single perl script, and does not require any special
need of any installation procedures. If you want the package and installation procedures or libraries. Download the latest [btrbk
man-pages properly installed, follow the instructions below. source tarball], or try latest master:
Prerequisites wget https://raw.githubusercontent.com/digint/btrbk/master/btrbk
------------- chmod +x btrbk
sudo ./btrbk ls /
- [btrfs-progs]: Btrfs filesystem utilities (use "btrfs_progs_compat" For more information, read the [installation documentation].
option for hosts running version prior to v3.17)
- Perl interpreter: probably already installed on your system
- [Date::Calc]: Perl module
[btrfs-progs]: http://www.kernel.org/pub/linux/kernel/people/kdave/btrfs-progs/ [btrbk source tarball]: https://digint.ch/download/btrbk/releases/
[Date::Calc]: http://search.cpan.org/perldoc?Date::Calc [installation documentation]: doc/install.md
Instructions
------------
In order to install the btrbk executable along with the man-pages and
an example configuration file, choose one of the following methods:
### Generic Linux System
Download and unpack the newest stable [btrbk source tarball] and type:
sudo make install
### Gentoo Linux
Grab the digint portage overlay from:
`git://dev.tty0.ch/portage/digint-overlay.git`
emerge app-backup/btrbk
### Debian Based Distros
btrbk is in `stretch (testing) (utils)`: https://packages.debian.org/stretch/btrbk
Packages are also available via NeuroDebian: http://neuro.debian.net/pkgs/btrbk.html
### Arch Linux
btrbk is in AUR: https://aur.archlinux.org/packages/btrbk/
### Alpine Linux
btrbk is in `testing`, install with:
apk add btrbk
[btrbk source tarball]: http://www.digint.ch/download/btrbk/releases/ ### Prerequisites
[btrbk debian package]: http://www.digint.ch/download/btrbk/packages/debian/
* [btrfs-progs]: Btrfs filesystem utilities >= v4.12
* [Perl interpreter]: Probably already installed on your system
* [OpenSSH]: If you want to transfer backups from/to remote locations
* [mbuffer]: If you want rate limiting and progress bars
[btrfs-progs]: https://www.kernel.org/pub/linux/kernel/people/kdave/btrfs-progs/
[Perl interpreter]: https://www.perl.org
[OpenSSH]: https://www.openssh.com
[mbuffer]: https://www.maier-komor.de/mbuffer.html
Synopsis Synopsis
======== ========
Please consult the [btrbk(1)] man-page provided with this package for a Please consult the [btrbk(1)] man-page provided with this package for
full description of the command line options. a full description of the command line options.
[btrbk(1)]: http://www.digint.ch/btrbk/doc/btrbk.html [btrbk(1)]: https://digint.ch/btrbk/doc/btrbk.1.html
Configuration File Configuration
================== =============
Before running `btrbk`, you will need to create a configuration Before running `btrbk`, you will need to create a configuration
file. You might want to take a look at `btrbk.conf.example` provided file. You might want to take a look at `btrbk.conf.example` provided
with this package. For a detailed description, please consult the with this package. For a detailed description, please consult the
[btrbk.conf(5)] man-page. [btrbk.conf(5)] man-page.
When playing around with config-files, it is highly recommended to After a configuration change, it is highly recommended to check it by
check the output using the `dryrun` command before executing the running btrbk with the `-n,--dry-run` option:
backups:
btrbk -c myconfig -v dryrun # btrbk -c /path/to/myconfig -v -n run
This will read all btrfs information on the source/target filesystems This will read all btrfs information on the source/target filesystems
and show what actions would be performed (without writing anything to and show what actions would be performed (without writing anything to
the disks). the disks).
[btrbk.conf(5)]: http://www.digint.ch/btrbk/doc/btrbk.conf.html The examples below assume that the btrfs subvolume containing `home`
and `rootfs` is mounted at `/mnt/btr_pool`. This is usually the btrfs
root subvolume, which always has `subvolid=5`.
Mounting `subvolid=5` is *recommended* (mandatory for btrbk < v0.32.0)
if you want to backup your root filesystem `/`.
/etc/fstab:
/dev/sda1 /mnt/btr_pool btrfs subvolid=5,noatime 0 0
Note that some default btrfs installations (e.g. Ubuntu) use subvolume
names `@` for rootfs (mounted at `/`) and `@home` for `/home`, as a
naming convention. If this is the case on your file system, replace
the `subvolume` declarations in the examples accordingly.
[btrbk.conf(5)]: https://digint.ch/btrbk/doc/btrbk.conf.5.html
Example: laptop with usb-disk for backups Example: Local Regular Snapshots (time-machine)
----------------------------------------- -----------------------------------------------
The simplest use case is to only create snapshots of your data. This
will obviously not protect it against hardware failure, but can be
useful for:
* protection against inadvertent changes or deletions
* keeping past states of copies from rsync or similar tools
Let's assume you need regular snapshots of your home directory, which
is located in the subvolume `home` of the volume `/mnt/btr_pool`. The
snapshots are to be stored in `btrbk_snapshots` (on the same volume).
/etc/btrbk/btrbk.conf:
timestamp_format long
snapshot_preserve_min 18h
snapshot_preserve 48h
volume /mnt/btr_pool
snapshot_dir btrbk_snapshots
subvolume home
Notice that the `target` option is not provided, and btrbk will only
manage snapshots located on the same volume in `snapshot_dir`. Btrbk
does not create subdirs by default, the snapshot directory must first
be created manually:
# mkdir /mnt/btr_pool/btrbk_snapshots
The "volume" section is merely used as a specifier for a base
directory, and can be skipped if you prefer to configure everything
using absolute paths. The above configuration can also be written as:
snapshot_dir /mnt/btr_pool/btrbk_snapshots
subvolume /mnt/btr_pool/home
If you don't want to mount the btrfs root filesystem to
`/mnt/btr_pool`, you might as well configure it like this:
snapshot_dir /btrbk_snapshots
subvolume /home
Start a dry run (-n, --dry-run):
# btrbk run -n
Create the first snapshot:
# btrbk run
Print schedule (-S, --print-schedule):
# btrbk run -n -S
If it works as expected, configure a cron job to run btrbk hourly:
/etc/cron.hourly/btrbk:
#!/bin/sh
exec /usr/bin/btrbk -q run
Snapshots will now be created every hour. All snapshots are preserved for at
least 18 hours (`snapshot_preserve_min`), whether they are created by the cron
job or manually by calling `sudo btrbk run` on the command line. Additionally,
48 hourly snapshots are preserved (`snapshot_preserve`).
Example: Backups to USB Disk
----------------------------
In this example, we assume you have a laptop with: In this example, we assume you have a laptop with:
- a disk having a btrfs volume mounted as `/mnt/btr_pool`, containing * a disk having a btrfs root subvolume (subvolid=5) mounted on
a subvolume `rootfs` for the root filesystem and a subvolume `home` `/mnt/btr_pool`, containing a subvolume `rootfs` for the root
for the user data. filesystem (i.e. mounted on `/`) and a subvolume `home` for the
- a backup disk having a btrfs volume mounted as `/mnt/btr_backup`, user data,
containing a subvolume `mylaptop` for the incremental backups. * a directory or subvolume `/mnt/btr_pool/btrbk_snapshots` which
will hold the btrbk snapshots,
* a backup disk having a btrfs volume mounted as `/mnt/btr_backup`,
containing a subvolume or directory `mylaptop` for the incremental
backups.
Retention policy: Retention policy:
- keep snapshots for 14 days (very handy if you are on the road and * keep all snapshots for 2 days, no matter how frequently you (or
the backup disk is not attached) your cron job) run btrbk
- keep monthly backups forever * keep daily snapshots for 14 days (very handy if you are on
- keep weekly backups for 10 weeks the road and the backup disk is not attached)
- keep daily backups for 20 days * keep monthly backups forever
* keep weekly backups for 10 weeks
* keep daily backups for 20 days
/etc/btrbk/btrbk-mylaptop.conf: /etc/btrbk/btrbk-mylaptop.conf:
snapshot_preserve_daily 14 snapshot_preserve_min 2d
snapshot_preserve_weekly 0 snapshot_preserve 14d
snapshot_preserve_monthly 0
target_preserve_daily 20 # Create snapshots only if the backup disk is attached
target_preserve_weekly 10 #snapshot_create ondemand
target_preserve_monthly all
target_preserve_min no
target_preserve 20d 10w *m
snapshot_dir btrbk_snapshots snapshot_dir btrbk_snapshots
volume /mnt/btr_pool volume /mnt/btr_pool
target /mnt/btr_backup/mylaptop
subvolume rootfs subvolume rootfs
target send-receive /mnt/btr_backup/mylaptop
subvolume home subvolume home
target send-receive /mnt/btr_backup/mylaptop [...]
/etc/cron.daily/btrbk: /etc/cron.daily/btrbk:
#!/bin/sh #!/bin/sh
exec /usr/sbin/btrbk -q -c /etc/btrbk/btrbk-mylaptop.conf run exec /usr/bin/btrbk -q -c /etc/btrbk/btrbk-mylaptop.conf run
- This will create snapshots on a daily basis: * This will create snapshots on a daily basis:
- `/mnt/btr_pool/btrbk_snapshots/rootfs.YYYYMMDD` * `/mnt/btr_pool/btrbk_snapshots/rootfs.YYYYMMDD`
- `/mnt/btr_pool/btrbk_snapshots/home.YYYYMMDD` * `/mnt/btr_pool/btrbk_snapshots/home.YYYYMMDD`
- And create incremental backups in: * And create incremental backups in:
- `/mnt/btr_backup/mylaptop/rootfs.YYYYMMDD` * `/mnt/btr_backup/mylaptop/rootfs.YYYYMMDD`
- `/mnt/btr_backup/mylaptop/home.YYYYMMDD` * `/mnt/btr_backup/mylaptop/home.YYYYMMDD`
If you want the snapshots to be created only if the backup disk is If you prefer triggering the backups manually, change the cron command
attached, simply add the following line to the config: to run the `snapshot` action instead of `run`. Start the backups
manually by running:
snapshot_create ondemand # btrbk resume
For a quick additional snapshot of your home, run:
# btrbk snapshot home
Example: host-initiated backup on fileserver Example: Host-initiated Backup on Fileserver
-------------------------------------------- --------------------------------------------
Let's say you have a fileserver at "myserver.mydomain.com" where you Let's say you have a fileserver at "myserver.example.org" where you
want to create backups of your laptop disk, the config would look like want to create backups of your laptop disk. The config could look like
this: this:
ssh_identity /etc/btrbk/ssh/id_rsa ssh_identity /etc/btrbk/ssh/id_rsa
volume /mnt/btr_pool volume /mnt/btr_pool
subvolume rootfs subvolume rootfs
target send-receive /mnt/btr_backup/mylaptop target /mnt/btr_backup/mylaptop
target send-receive ssh://myserver.mydomain.com/mnt/btr_backup/mylaptop target ssh://myserver.example.org/mnt/btr_backup/mylaptop
In addition to the backups on your local usb-disk mounted at In addition to the backups on your local usb-disk mounted at
`/mnt/btr_backup/mylaptop`, incremental backups would also be pushed `/mnt/btr_backup/mylaptop`, incremental backups would also be pushed
to `myserver.mydomain.com`. to `myserver.example.org`.
Example: fileserver-initiated backups from several hosts Example: Fileserver-initiated Backups from Several Hosts
-------------------------------------------------------- --------------------------------------------------------
If you're a sysadmin and want to trigger backups directly from your If you're a sysadmin and want to trigger backups directly from your
@ -199,51 +274,26 @@ fileserver, the config would be something like:
ssh_identity /etc/btrbk/ssh/id_rsa ssh_identity /etc/btrbk/ssh/id_rsa
volume ssh://alpha.mydomain.com/mnt/btr_pool volume ssh://alpha.example.org/mnt/btr_pool
target /mnt/btr_backup/alpha
subvolume rootfs subvolume rootfs
target send-receive /mnt/btr_backup/alpha
subvolume home subvolume home
target send-receive /mnt/btr_backup/alpha
volume ssh://beta.mydomain.com/mnt/btr_pool volume ssh://beta.example.org/mnt/btr_pool
target /mnt/btr_backup/beta
subvolume rootfs subvolume rootfs
target send-receive /mnt/btr_backup/beta
subvolume dbdata subvolume dbdata
target send-receive /mnt/btr_backup/beta
This will pull backups from alpha/beta.mydomain.com and locally create: This will pull backups from alpha/beta.example.org and locally
create:
- `/mnt/btr_backup/alpha/rootfs.YYYYMMDD` * `/mnt/btr_backup/alpha/rootfs.YYYYMMDD`
- `/mnt/btr_backup/alpha/home.YYYYMMDD` * `/mnt/btr_backup/alpha/home.YYYYMMDD`
- `/mnt/btr_backup/beta/rootfs.YYYYMMDD` * `/mnt/btr_backup/beta/rootfs.YYYYMMDD`
- `/mnt/btr_backup/beta/dbdata.YYYYMMDD` * `/mnt/btr_backup/beta/dbdata.YYYYMMDD`
Example: local time-machine (daily snapshots) Example: Multiple Btrbk Instances
---------------------------------------------
If all you want is to create snapshots of your home directory on a
regular basis:
/etc/btrbk/btrbk.conf:
volume /mnt/btr_pool
snapshot_dir btrbk_snapshots
subvolume home
/etc/cron.daily/btrbk:
#!/bin/sh
exec /usr/sbin/btrbk -q run
Note that you can run btrbk more than once a day, e.g. by creating the
above script in `/etc/cron.hourly/btrbk`, or by calling `sudo btrbk
run` from the command line.
Example: multiple btrbk instances
--------------------------------- ---------------------------------
Let's say we have a host (at 192.168.0.42) running btrbk with the Let's say we have a host (at 192.168.0.42) running btrbk with the
@ -252,56 +302,99 @@ to only fetch the snapshots.
/etc/btrbk/btrbk.conf (on backup server): /etc/btrbk/btrbk.conf (on backup server):
target_preserve_min no
target_preserve 0d 10w *m
volume ssh://192.168.0.42/mnt/btr_pool volume ssh://192.168.0.42/mnt/btr_pool
target /mnt/btr_backup/my-laptop
subvolume home subvolume home
snapshot_dir btrbk_snapshots snapshot_dir btrbk_snapshots
snapshot_preserve_daily all snapshot_preserve_min all
snapshot_create no snapshot_create no
resume_missing yes
target_preserve_daily 0 If the server runs btrbk with this config, 10 weeklies and all
target_preserve_weekly 10 monthlies are received from 192.168.0.42. The source filesystem is
target_preserve_monthly all never altered because of `snapshot_preserve_min all`.
target send-receive /mnt/btr_backup/my-laptop.com
If the server runs btrbk with this config, the latest snapshot (which
is *always* transferred), 10 weeklies and all monthlies are received
from 192.168.0.42. The source filesystem is never altered because of
`snapshot_preserve_daily all`.
Example: backup from non-btrfs source Example: Virtual Machine Setup
------------------------------
Common virtual machine setups have multiple volume sections with same
host, but distinct port numbers for each machine.
/etc/btrbk/btrbk.conf:
# This propagates to all subvolume sections:
target /mnt/btr_backup/
volume ssh://localhost:2201/mnt/btr_pool
group vm vm01
subvolume home
snapshot_name vm01-home
subvolume data
snapshot_name vm01-data
volume ssh://localhost:2202/mnt/btr_pool
group vm vm02
subvolume home
snapshot_name vm02-home
volume ssh://localhost:2203/mnt/btr_pool
[...]
This will create `/mnt/btr_backup/vm[NN]-home`, `vm[NN]-data`, ...
Note that btrbk holds a single reference to every btrfs filesystem
tree, regarding UUID's as "globally unique". If the configured
subvolumes point to the same filesystem on different machines (ports),
you will see log lines like this when running `btrbk -v`:
```
Assuming same filesystem: "ssh://localhost:2201/dev/sda1", "ssh://localhost:2202/dev/sda1"
```
Example: Backup from non-btrfs Source
------------------------------------- -------------------------------------
First create a btrfs subvolume on the backup server: If you want to make backups from a filesystem other than btrfs
(e.g. ext4 or reiserfs), you need to create a *synchronization
subvolume* on the backup disk:
# btrfs subvolume create /mnt/btr_backup/myhost_sync # btrfs subvolume create /mnt/btr_backup/myhost_sync
In your daily cron script, prior to running btrbk, sync your source to Configure btrbk to use `myhost_sync` as source subvolume:
`myhost_sync`, something like:
rsync -a --delete -e ssh myhost.mydomain.com://data/ /mnt/btr_backup/myhost_sync/
Then run btrbk, with myhost_sync configured *without any targets* as
follows:
volume /mnt/btr_backup volume /mnt/btr_backup
subvolume myhost_sync subvolume myhost_sync
snapshot_name myhost snapshot_name myhost
snapshot_preserve_daily 14 snapshot_preserve_min latest
snapshot_preserve_weekly 20 snapshot_preserve 14d 20w *m
snapshot_preserve_monthly all
This will produce daily snapshots `/mnt/btr_backup/myhost.20150101`, The btrbk package provides the "btrbk-mail" script, which automates
with retention as defined with the snapshot_preserve_* options. the synchronization using rsync, and can be run as cron job or systemd
timer unit. For configuration details, see the config section in
"/contrib/cron/btrbk-mail".
Note that the provided script: "contrib/cron/btrbk-mail" has support Alternatively, you can run any synchronization software prior to
for this! running btrbk. Something like:
#!/bin/sh
rsync -az --delete \
--inplace --numeric-ids --acls --xattrs \
-e 'ssh -i /etc/btrbk/ssh/id_rsa' \
myhost.example.org:/data/ \
/mnt/btr_backup/myhost_sync/
exec /usr/bin/btrbk -q run
This will produce snapshots `/mnt/btr_backup/myhost.20150101`, with
retention as defined with the snapshot_preserve option.
Example: encrypted backup to non-btrfs target Example: Encrypted Backup to non-btrfs Target
--------------------------------------------- ---------------------------------------------
If your backup server does not support btrfs, you can send your If your backup server does not support btrfs, you can send your
@ -319,7 +412,7 @@ compressed and piped through GnuPG.
raw_target_compress xz raw_target_compress xz
raw_target_encrypt gpg raw_target_encrypt gpg
gpg_keyring /etc/btrbk/gpg/pubring.gpg gpg_keyring /etc/btrbk/gpg/pubring.gpg
gpg_recipient btrbk@mydomain.com gpg_recipient btrbk@example.org
volume /mnt/btr_pool volume /mnt/btr_pool
subvolume home subvolume home
@ -328,138 +421,252 @@ compressed and piped through GnuPG.
# incremental no # incremental no
This will create a GnuPG encrypted, compressed files on the target This will create a GnuPG encrypted, compressed files on the target
host: host. For each backup, two files are created:
- `/backup/home.YYYYMMDD.btrfs_<received_uuid>.xz.gpg` for * `/backup/home.YYYYMMDD.btrfs.xz.gpg`: main data file containing
non-incremental images, the btrfs send-stream,
- `/backup/home.YYYYMMDD.btrfs_<received_uuid>@<parent_uuid>.xz.gpg` * `/backup/home.YYYYMMDD.btrfs.xz.gpg.info`: sidecar file containing
for subsequent incremenal images. metadata used by btrbk.
I you are using raw _incremental_ backups, please make sure you If you are using raw _incremental_ backups, please make sure you
understand the implications (see [btrbk.conf(5)], TARGET TYPES). understand the implications (see [btrbk.conf(5)], TARGET TYPES).
Setting up SSH Setting up SSH
============== ==============
Since btrbk needs root access on the remote side, it is *very Since btrbk needs root access, it is *very advisable* to take all the
advisable* to take all the security precautions you can. Usually security precautions you can. In most cases backups are generated
backups are generated periodically without user interaction, so it is periodically without user interaction, so it is not possible to
not possible to protect your ssh key with a password. The steps below protect your ssh key with a password. The steps below will give you
will give you hints on how to secure your ssh server for a backup hints on how to secure your ssh server for a backup scenario. Note
scenario. Note that the btrbk executable is not needed on the remote that the btrbk package is not required on the remote side, but you
side, but you will need "/sbin/btrfs" from the btrfs-progs package. will need the `btrfs` executable from the [btrfs-progs] package.
btrbk comes with a shell script "ssh_filter_btrbk.sh", which restricts
ssh access to sane calls to the /sbin/btrfs command needed for
snapshot creation and send/receive operations (see
[ssh_filter_btrbk(1)]). Here is an example on how it can be used with
ssh:
**Step 1** (client): Create a ssh key dedicated to btrbk, without ### Create SSH Key Pair
On the client side, create a ssh key dedicated to btrbk, without
password protection: password protection:
ssh-keygen -t rsa -b 2048 -f /etc/btrbk/ssh/id_rsa -C btrbk@mydomain.com -N "" # ssh-keygen -t rsa -b 4096 -f /etc/btrbk/ssh/id_rsa -C btrbk@example.org -N ""
**Step 2** (server): Copy the "ssh_filter_btrbk.sh" from the btrbk The content of the public key (/etc/btrbk/ssh/id_rsa.pub) is used for
project to "/backup/scripts/". authentication in "authorized_keys" on the server side (see [sshd(8)]
for details).
**Step 3** (server): Add contents of the public key
(/etc/btrbk/ssh/id_rsa.pub) to "/root/.ssh/authorized_keys", and ### Allow Root Login
configure "ssh_filter_btrbk.sh" to be executed whenever this key is
used for authentication. Example lines: The most straight forward setup is to allow root login on the remote
host. If this is not an option for you, refer to the more complex
"Dedicated Btrbk User Login" section below.
/etc/ssh/sshd_config:
PermitRootLogin prohibit-password
Add your btrbk public key to "/root/.ssh/authorized_keys" on the
server, and you are good to go.
### Restrict Access
Restrict ssh access to a static IP address within your network. On the
remote host, either add a "Match" block in:
/etc/ssh/sshd_config:
Match Address 192.168.0.42
Or restrict in authorized_keys:
from="192.168.0.42" <pubkey>...
Consult the [sshd_config(5)] man-page for a detailed explanation and
more options.
Dedicated Btrbk User Login (optional)
-------------------------------------
If allowing root login is not an option for you, there are several
ways to restrict SSH access to a regular user.
### Option 1: Use sudo
On the client side, configure btrbk use the sudo backend. This changes
the ssh calls to btrfs commands to `sudo btrfs <subcommand>
<options>`.
/etc/btrbk/btrbk.conf:
backend_remote btrfs-progs-sudo
On the remote host, grant root permissions for the "btrfs" command
groups (subcommands) in "/etc/sudoers". If you are using
[ssh_filter_btrbk(1)], also add the `ssh_filter_btrbk.sh --sudo`
option in "authorized_keys" (see below).
### Option 2: Use btrfs-progs-btrbk
Instead of using the all-inclusive `btrfs` command,
"btrfs-progs-btrbk" allows you to restrict privileges to its
subcommands using linux capabilities(7) or setuid.
Note that the "btrfs-progs-btrbk" package is not available on all
linux distributions, you might need to build and install it on your
own (refer to [btrfs-progs-btrbk] on GitHub for more details).
/etc/btrbk/btrbk.conf:
backend_remote btrfs-progs-btrbk
Make sure that only the required binaries with elevated privileges can
be called by the btrbk user. For example, on a server acting as "btrbk
source", allow only the following binaries for the "btrbk" group:
# getcap /usr/bin/btrfs-*
/usr/bin/btrfs-send cap_dac_read_search,cap_fowner,cap_sys_admin=ep
/usr/bin/btrfs-subvolume-delete cap_dac_override,cap_sys_admin=ep
/usr/bin/btrfs-subvolume-list cap_dac_read_search,cap_fowner,cap_sys_admin=ep
/usr/bin/btrfs-subvolume-show cap_dac_read_search,cap_fowner,cap_sys_admin=ep
/usr/bin/btrfs-subvolume-snapshot cap_dac_override,cap_dac_read_search,cap_fowner,cap_sys_admin=ep
# ls -l /usr/bin/btrfs-*
-rwx--x--- 1 root btrbk /usr/bin/btrfs-send
-rwx--x--- 1 root btrbk /usr/bin/btrfs-subvolume-delete
-rwx--x--- 1 root btrbk /usr/bin/btrfs-subvolume-list
-rwx--x--- 1 root btrbk /usr/bin/btrfs-subvolume-show
-rwx--x--- 1 root btrbk /usr/bin/btrfs-subvolume-snapshot
Restrict Commands with "ssh_filter_btrbk.sh" (optional)
-------------------------------------------------------
Btrbk comes with a shell script "ssh_filter_btrbk.sh", which restricts
ssh access to sane calls to the "btrfs" command needed for snapshot
creation and send/receive operations (see [ssh_filter_btrbk(1)]).
Copy "ssh_filter_btrbk.sh" to "/backup/scripts/", and configure sshd
to run it whenever the key is used for authentication. Example
"/root/.ssh/authorized_keys":
# example backup source (also allowing deletion of old snapshots) # example backup source (also allowing deletion of old snapshots)
command="/backup/scripts/ssh_filter_btrbk.sh -l --source --delete" <pubkey>... command="/backup/scripts/ssh_filter_btrbk.sh -l --source --delete",restrict <pubkey>...
# example backup target (also allowing deletion of old snapshots) # example backup target (also allowing deletion of old snapshots)
command="/backup/scripts/ssh_filter_btrbk.sh -l --target --delete" <pubkey>... command="/backup/scripts/ssh_filter_btrbk.sh -l --target --delete",restrict <pubkey>...
# example fetch-only backup source (snapshot_preserve_daily=all, snapshot_create=no), # example fetch-only backup source (snapshot_preserve_min=all, snapshot_create=no),
# restricted to subvolumes within /home or /data # restricted to subvolumes within /home or /data
command="/backup/scripts/ssh_filter_btrbk.sh -l --send -p /home -p /data" <pubkey>... command="/backup/scripts/ssh_filter_btrbk.sh -l --send -p /home -p /data",restrict <pubkey>...
You might also want to restrict ssh access to a static IP address
within your network:
from="192.168.0.42",command="/backup/scripts/ssh_filter_btrbk.sh [...]" <pubkey>...
Please refer to [ssh_filter_btrbk(1)] for a description of the
"ssh_filter_btrbk.sh" options, as well as [sshd(8)] for a description
of the "authorized_keys" file format.
Also consider setting up ssh access for a user dedicated to btrbk and
either set suid root on ssh_filter_btrbk.sh or use the "--sudo" option
and configure /etc/sudoers accordingly. For even more security, you
can setup a chroot environment in /etc/ssh/sshd_config (see
[sshd_config(5)]).
[ssh_filter_btrbk(1)]: http://www.digint.ch/btrbk/doc/ssh_filter_btrbk.html [ssh_filter_btrbk(1)]: https://digint.ch/btrbk/doc/ssh_filter_btrbk.1.html
[sshd(8)]: http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man8/sshd.8 [sshd(8)]: https://man.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man8/sshd.8
[sshd_config(5)]: http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/sshd_config.5 [sshd_config(5)]: https://man.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/sshd_config
[btrfs-progs-btrbk]: https://github.com/digint/btrfs-progs-btrbk
Restoring Backups Restoring Backups
================= =================
btrbk does not provide any mechanism to restore your backups, this has Btrbk does not provide any mechanism to restore your backups, this has
to be done manually. In the examples below, we assume that you have a to be done manually. In the instructions below, we assume that you
btrfs volume mounted at `/mnt/btr_pool`, and the subvolume you want to have a btrfs volume mounted at `/mnt/btr_pool`, and the subvolume you
have restored is at `/mnt/btr_pool/data`. want to restore is at `/mnt/btr_pool/data`.
Example: Restore a Snapshot **Important**: don't use `btrfs property set` to make a subvolume
----------------------------- read-write after restoring. This is a low-level command, and leaves
"Received UUID" in a false state which causes btrbk to fail on
subsequent incremental backups. Instead, use `btrfs subvolume
snapshot` (without `-r` flag) as described below.
First, pick a snapshot to be restored:
### Step 0: Identify Subvolume
# list snapshots managed by btrbk
btrbk list snapshots btrbk list snapshots
From the list, pick the snapshot you want to restore. Let's say it's # alternative: list all subvolumes
btrbk ls /
btrbk ls -L /
From the list, identify the snapshot you want to restore. Let's say it's
`/mnt/btr_pool/_btrbk_snap/data.20150101`. `/mnt/btr_pool/_btrbk_snap/data.20150101`.
If the broken subvolume is still present, move it away:
mv /mnt/btr_pool/data /mnt/btr_pool/data.BROKEN ### Step 1: Restore Backup
(skip this step if you restore from a snapshot)
Now restore the snapshot:
btrfs subvolume snapshot /mnt/btr_pool/_btrbk_snap/data.20150101 /mnt/btr_pool/data
That's it; your `data` subvolume is restored. If everything went fine,
it's time to nuke the broken subvolume:
btrfs subvolume delete /mnt/btr_pool/data.BROKEN
Example: Restore a Backup
-------------------------
First, pick a backup to be restored:
btrbk list backups
From the list, pick the backup you want to restore. Let's say it's
`/mnt/btr_backup/data.20150101`.
If the broken subvolume is still present, move it away:
mv /mnt/btr_pool/data /mnt/btr_pool/data.BROKEN
Now restore the backup:
# locally mounted backup disk
btrfs send /mnt/btr_backup/data.20150101 | btrfs receive /mnt/btr_pool/ btrfs send /mnt/btr_backup/data.20150101 | btrfs receive /mnt/btr_pool/
# from / to remote host
ssh root@remote btrfs send /mnt/btr_backup/data.20150101 | btrfs receive /mnt/btr_pool/
btrfs send /mnt/btr_backup/data.20150101 | ssh root@remote btrfs receive /mnt/btr_pool/
**Hint**: Try to send-receive backups incrementally if possible. In
case you still have common snapshot / backup pairs (i.e. both
"snapshot_subvol" and "target_subvol" are listed above), use `btrfs
send -p <parent>`.
From this point on, `data.20150101` on both disks can be used as
parents for subsequent send-receive operations, and a *received_uuid*
relationship is established (see below).
### Step 2: Create read-write Subvolume
# if still present, move broken subvolume away
mv /mnt/btr_pool/data /mnt/btr_pool/data.BROKEN
# create read-write subvolume
btrfs subvolume snapshot /mnt/btr_pool/data.20150101 /mnt/btr_pool/data btrfs subvolume snapshot /mnt/btr_pool/data.20150101 /mnt/btr_pool/data
btrfs subvolume delete /mnt/btr_pool/data.20150101
Alternatively, if you're restoring data on a remote host, do something Your `data` subvolume is restored, you can carry on with incremental
like this: backups to `/mnt/btr_backup`.
btrfs send /mnt/btr_backup/data.20150101 | ssh root@my-remote-host.com btrfs receive /mnt/btr_pool/
If everything went fine, nuke the broken subvolume: ### Step 3: Cleanup
# if everything went fine, delete the broken subvolume
btrfs subvolume delete /mnt/btr_pool/data.BROKEN btrfs subvolume delete /mnt/btr_pool/data.BROKEN
Make sure to keep `data.20150101` subvolumes on both disks at least
until you created a new backup using btrbk, in order to keep the
incremental chain alive.
Btrfs Relationship (technical note)
-----------------------------------
btrbk origin -t /mnt/btr_backup/data.20150101
btrbk ls -L /mnt/btr_pool /mnt/btr_backup
* **received_uuid** relationship: *correlated*, *identical*
read-only subvolumes, cross-filesystem.
a.received_uuid = b.received_uuid
a.received_uuid = b.uuid
* Required for subvolumes used as parent (or clone-src) of
send-receive operations.
* Present on subvolumes created by `btrfs send | btrfs receive`.
* `/mnt/btr_pool/data.20150101 === /mnt/btr_backup/data.20150101`
* **parent_uuid** relationship: "is-snapshot-of"
a.parent_uuid = b.uuid
* Present on subvolumes created by `btrfs subvolume snapshot` or
`btrfs send -p | btrfs receive`.
* Used by btrbk to determine best parent.
* `/mnt/btr_pool/data.20150101 <-- /mnt/btr_pool/data`
FAQ FAQ
=== ===
@ -468,16 +675,32 @@ Make sure to also read the [btrbk FAQ page](doc/FAQ.md).
Help improve it by asking! Help improve it by asking!
Donate
======
So btrbk saved your day?
I will definitively continue to develop btrbk for free. If you want to
support my hard work with a donation, you are welcome to do so!
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WFQSSCD9GNM4S)
Development Development
=========== ===========
Source Code Repository Source Code Repository
---------------------- ----------------------
The source code for btrbk is managed using Git. Check out the source The source code for btrbk is managed using Git.
like this:
git clone git://dev.tty0.ch/btrbk.git Official repository:
git clone https://dev.tty0.ch/btrbk.git
Mirror on GitHub:
git clone https://github.com/digint/btrbk.git
How to Contribute How to Contribute
@ -487,23 +710,23 @@ Your contributions are welcome!
If you would like to contribute or have found bugs: If you would like to contribute or have found bugs:
- Visit the [btrbk project page on GitHub] and use the [issues * Visit the [btrbk project page on GitHub] and use the
tracker] there. [issues tracker] there.
- Talk to us on Freenode in `#btrbk`. * Talk to us on [Libera.Chat] in `#btrbk`.
- Contact the author via email (the email address can be found in the * Contact the author via email (the email address can be found in
sources). the sources).
Any feedback is appreciated! Any feedback is appreciated!
[btrbk project page on GitHub]: http://github.com/digint/btrbk [btrbk project page on GitHub]: https://github.com/digint/btrbk
[issues tracker]: http://github.com/digint/btrbk/issues [issues tracker]: https://github.com/digint/btrbk/issues
[Libera.Chat]: https://libera.chat
License License
======= =======
btrbk is free software, available under the [GNU General Public btrbk is free software, available under the [GNU General Public
License, Version 3][GPLv3]. License, Version 3 or later][GPL-3.0-or-later].
[GPLv3]: http://www.gnu.org/licenses/gpl.html
[GPL-3.0-or-later]: https://www.gnu.org/licenses/gpl.html

8246
btrbk

File diff suppressed because it is too large Load Diff

View File

@ -2,16 +2,33 @@
# Example btrbk configuration file # Example btrbk configuration file
# #
# #
# Please refer to the btrbk.conf(5) man-page for more details. # Please refer to the btrbk.conf(5) man-page for a complete
# description of all configuration options.
# For more examples, see README.md included with this package.
# #
# Note that the options can be overridden in the # btrbk.conf(5): <https://digint.ch/btrbk/doc/btrbk.conf.5.html>
# volume/subvolume/target sections. # README.md: <https://digint.ch/btrbk/doc/readme.html>
#
# Note that the options can be overridden per volume/subvolume/target
# in the corresponding sections.
# #
# Enable transaction log # Enable transaction log
transaction_log /var/log/btrbk.log transaction_log /var/log/btrbk.log
# Specify SSH private key for remote connections
ssh_identity /etc/btrbk/ssh/id_ed25519
ssh_user root
# Use sudo if btrbk or lsbtr is run by regular user
backend_local_user btrfs-progs-sudo
# Enable stream buffer. Adding a buffer between the sending and
# receiving side is generally a good idea.
# NOTE: If enabled, make sure to install the "mbuffer" package!
stream_buffer 256m
# Directory in which the btrfs snapshots are created. Relative to # Directory in which the btrfs snapshots are created. Relative to
# <volume-directory> of the volume section. # <volume-directory> of the volume section.
# If not set, the snapshots are created in <volume-directory>. # If not set, the snapshots are created in <volume-directory>.
@ -19,7 +36,7 @@ transaction_log /var/log/btrbk.log
# If you want to set a custom name for the snapshot (and backups), # If you want to set a custom name for the snapshot (and backups),
# use the "snapshot_name" option within the subvolume section. # use the "snapshot_name" option within the subvolume section.
# #
# NOTE: btrbk does not autmatically create this directory, and the # NOTE: btrbk does not automatically create this directory, and the
# snapshot creation will fail if it is not present. # snapshot creation will fail if it is not present.
# #
snapshot_dir _btrbk_snap snapshot_dir _btrbk_snap
@ -33,103 +50,125 @@ snapshot_dir _btrbk_snap
# creation of non-incremental backups if no parent is found). # creation of non-incremental backups if no parent is found).
#incremental yes #incremental yes
# Resume missing backups (set to "no" if you don't want to resume # Specify after what time (in full hours after midnight) backups/
# missing backups). # snapshots are considered as a daily backup/snapshot
#resume_missing yes #preserve_hour_of_day 0
# Specify on which day of week weekly/monthly backups are to be # Specify on which day of week weekly/monthly backups are to be
# preserved. # preserved.
#preserve_day_of_week sunday #preserve_day_of_week sunday
# Preserve matrix for source snapshots: # Preserve all snapshots for a minimum period of time.
#snapshot_preserve_daily all #snapshot_preserve_min 1d
#snapshot_preserve_weekly 0
#snapshot_preserve_monthly all
# Preserve matrix for backup targets: # Retention policy for the source snapshots.
#target_preserve_daily all #snapshot_preserve <NN>h <NN>d <NN>w <NN>m <NN>y
#target_preserve_weekly 0
#target_preserve_monthly all
# Specify SSH private key for "ssh://" volumes / targets: # Preserve all backup targets for a minimum period of time.
#ssh_identity /etc/btrbk/ssh/id_ed25519 #target_preserve_min no
#ssh_user root
#ssh_port default
#ssh_compression no
#ssh_cipher_spec default
# Don't wait for transaction commit on deletion. Set this to "after" # Retention policy for backup targets:
# or "each" to make sure the deletion of subvolumes is committed to #target_preserve <NN>h <NN>d <NN>w <NN>m <NN>y
# disk when btrbk terminates.
# Retention policy for archives ("btrbk archive" command):
#archive_preserve_min no
#archive_preserve <NN>h <NN>d <NN>w <NN>m <NN>y
# Enable compression for remote btrfs send/receive operations:
#stream_compress no
#stream_compress_level default
#stream_compress_threads default
# Enable lock file support: Ensures that only one instance of btrbk
# can be run at a time.
#lockfile /var/lock/btrbk.lock
# Don't wait for transaction commit on deletion. Enable this to make
# sure the deletion of subvolumes is committed to disk when btrbk
# terminates.
#btrfs_commit_delete no #btrfs_commit_delete no
# Set this to "yes" to enable btrfs-progs < 3.17 compatibility.
# Set this either globally or in a specific "target" section.
#btrfs_progs_compat no
# #
# Volume section: "volume <volume-directory>" # Volume section (optional): "volume <volume-directory>"
# #
# <volume-directory> Directory of a btrfs volume (or subvolume) # <volume-directory> Base path within a btrfs filesystem
# containing the subvolume to be backuped # containing the subvolumes to be backuped
# (usually the mount-point of a btrfs filesystem # (usually the mount-point of a btrfs filesystem
# mounted with subvolid=0 option) # mounted with subvolid=5 option).
# #
# Subvolume section: "subvolume <subvolume-name> # Subvolume section: "subvolume <subvolume-name>"
# #
# <subvolume-name> Subvolume to be backuped, relative to # <subvolume-name> Subvolume to be backuped, relative to
# <volume-directory> in volume section. # <volume-directory> in volume section.
# #
# Target section: "target <type> <volume-directory>" # Target section: "target <type> <volume-directory>"
# #
# <type> Backup type, currently only "send-receive". # <type> (optional) type, defaults to "send-receive".
# <volume-directory> Directory of a btrfs volume (or subvolume) # <volume-directory> Directory within a btrfs filesystem
# receiving the backups. # receiving the backups.
# #
# NOTE: The parser does not care about indentation, this is only for # NOTE: The parser does not care about indentation, this is only for
# human readability. The options always apply to the last section # human readability. All options apply to the last section
# encountered, overriding the corresponding option of the upper # encountered, overriding the corresponding option of the upper
# section. This means that the global options must be set before any # section. This means that the global options must be set on top,
# "volume" section. # before any "volume", "subvolume" or "target section.
# #
# #
# Example configuration: # Example retention policy:
# #
snapshot_preserve_daily 14 snapshot_preserve_min 2d
snapshot_preserve_weekly 0 snapshot_preserve 14d
snapshot_preserve_monthly 0
target_preserve_daily 20 target_preserve_min no
target_preserve_weekly 10 target_preserve 20d 10w *m
target_preserve_monthly all
#
# Simple setup: Backup root and home to external disk
#
snapshot_dir /btrbk_snapshots
target /mnt/btr_backup
subvolume /
subvolume /home
#
# Complex setup
#
# In order to keep things organized, it is recommended to use "volume"
# sections and mount the top-level subvolume (subvolid=5):
#
# $ mount -o subvolid=5 /dev/sda1 /mnt/btr_pool
#
# Backup to external disk mounted on /mnt/btr_backup # Backup to external disk mounted on /mnt/btr_backup
volume /mnt/btr_pool volume /mnt/btr_pool
# no action if external disk is not attached # Create snapshots in /mnt/btr_pool/btrbk_snapshots
snapshot_create ondemand snapshot_dir btrbk_snapshots
subvolume root_gentoo # Target for all subvolume sections:
target send-receive /mnt/btr_backup/_btrbk target /mnt/btr_backup
subvolume kvm # Some default btrfs installations (e.g. Ubuntu) use "@" for rootfs
# use different preserve matrix for kvm backups # (mounted at "/") and "@home" (mounted at "/home"). Note that this
target_preserve_daily 7 # is only a naming convention.
target_preserve_weekly 4 #subvolume @
subvolume root
target send-receive /mnt/btr_backup/_btrbk
# Backup to external disk as well as some remote host
volume /mnt/btr_data
subvolume home subvolume home
# always create snapshot, even if targets are unreachable subvolume kvm
# Use different retention policy for kvm backups:
target_preserve 7d 4w
# Backup data to external disk as well as remote host
volume /mnt/btr_data
subvolume data
# Always create snapshot, even if targets are unreachable
snapshot_create always snapshot_create always
target send-receive /mnt/btr_backup/_btrbk target /mnt/btr_backup
target send-receive ssh://backup.my-remote-host.com/mnt/btr_backup target ssh://backup.my-remote-host.com/mnt/btr_backup
# Backup from remote host, with different naming # Backup from remote host, with different naming
@ -137,15 +176,29 @@ volume ssh://my-remote-host.com/mnt/btr_pool
subvolume data_0 subvolume data_0
snapshot_dir snapshots/btrbk snapshot_dir snapshots/btrbk
snapshot_name data_main snapshot_name data_main
target send-receive /mnt/btr_backup/_btrbk/my-remote-host.com target /mnt/btr_backup/my-remote-host.com
# Backup on demand (noauto) to remote host running busybox, login as
# regular user using ssh-agent with current user name (ssh_user no)
# and default credentials (ssh_identity no).
volume /home
noauto yes
compat busybox
backend_remote btrfs-progs-sudo
ssh_user no
ssh_identity no
target ssh://my-user-host.com/mnt/btr_backup/home
subvolume alice
subvolume bob
# Resume backups from remote host which runs its own btrbk instance # Resume backups from remote host which runs its own btrbk instance
# creating snapshots for "home" in "/mnt/btr_pool/btrbk_snapshots". # creating snapshots for "home" in "/mnt/btr_pool/btrbk_snapshots".
volume ssh://my-remote-host.com/mnt/btr_pool volume ssh://my-remote-host.com/mnt/btr_pool
subvolume home
snapshot_dir btrbk_snapshots snapshot_dir btrbk_snapshots
snapshot_preserve_daily all
snapshot_create no snapshot_create no
resume_missing yes snapshot_preserve_min all
target send-receive /mnt/btr_backup/_btrbk/my-remote-host.com subvolume home
target /mnt/btr_backup/my-remote-host.com

View File

@ -0,0 +1,133 @@
_btrbk_init_cmds()
{
# set $cmds to an array of the commands so far
#
# for example, for this command:
#
# btrbk -v --override warn_unknown_targets=yes list config --long
#
# then $cmds is:
#
# cmds=(list config)
#
cmds=()
local i
for ((i = 1; i < cword; i++)); do
case "${words[i-1]}" in
'-c' | '--config' | '--exclude' | '-l' | '--loglevel' | '--format' | '--lockfile' | '--override')
continue
;;
esac
[[ ${words[i]} != -* ]] && cmds+=(${words[i]})
done
return 0
}
_btrbk()
{
local cur prev words cword split cmds
_init_completion -s || return
_btrbk_init_cmds || return
case "$prev" in
'-c' | '--config')
_filedir
return
;;
'--exclude')
return
;;
'-l' | '--loglevel')
COMPREPLY=($(compgen -W 'error warn info debug trace' -- "$cur"))
return
;;
'--format')
COMPREPLY=($(compgen -W 'table long raw' -- "$cur"))
return
;;
'--lockfile')
_filedir
return
;;
'--override')
return
;;
esac
$split && return
if [[ $cur == -* ]]; then
COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur"))
[[ $COMPREPLY == *= ]] && compopt -o nospace
else
if [[ ! -v 'cmds[0]' ]]; then
COMPREPLY=($(compgen -W 'run dryrun snapshot resume prune archive clean stats list usage origin diff extents ls' -- "$cur"))
fi
fi
case "${cmds[0]}" in
'archive')
# <source>
if [[ ! -v 'cmds[1]' ]]; then
_filedir -d
# <target>
elif [[ ! -v 'cmds[2]' ]]; then
_filedir -d
# [--raw]
elif [[ $cur == -* ]]; then
COMPREPLY+=($(compgen -W '--raw' -- "$cur"))
fi
;;
'list')
if [[ ! -v 'cmds[1]' ]]; then
COMPREPLY=($(compgen -W 'all snapshots backups latest config source volume target' -- "$cur"))
fi
;;
'origin')
# <subvolume>
if [[ ! -v 'cmds[1]' ]]; then
_filedir -d
fi
;;
'ls')
# <path>|<url>...
_filedir -d
;;
'extents')
# [diff] <path>... [exclusive] <path>...
if [[ ! -v 'cmds[1]' ]]; then
COMPREPLY+=($(compgen -W 'diff' -- "$cur"))
elif [[ ! ${cmds[*]} =~ (^|[[:space:]])"exclusive"($|[[:space:]]) ]]; then
COMPREPLY+=($(compgen -W 'exclusive' -- "$cur"))
fi
_filedir -d
;;
esac
} && complete -F _btrbk btrbk
_lsbtr()
{
local cur prev words cword split
_init_completion -s || return
case "$prev" in
'-c' | '--config')
_filedir
;;
'--override')
;;
esac
$split && return
if [[ $cur == -* ]]; then
COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur"))
[[ $COMPREPLY == *= ]] && compopt -o nospace
else
# <path>|<url>...
_filedir -d
fi
} && complete -F _lsbtr lsbtr
# ex: filetype=bash

View File

@ -2,152 +2,277 @@
## Wrapper script running "btrbk" and sending email with results ## Wrapper script running "btrbk" and sending email with results
set -uf now=$(date +%Y%m%d)
declare -A rsync_src rsync_dst rsync_log rsync_key rsync_opt
now=$(/bin/date +%Y%m%d)
declare -A rsync_src rsync_dst rsync_log rsync_rsh rsync_opt
declare -A sync_fs_onchange
##### start config section ##### ##### start config section #####
# Email recipients, separated by whitespace: # Email recipients, separated by whitespace:
mailto=$MAILTO mailto=${MAILTO:-root}
# List of mountpoints to be mounted/unmounted (whitespace-separated)
# mount_targets="/mnt/btr_pool /mnt/backup"
mount_targets=
umount_targets=$mount_targets
# btrbk configuration file:
config="/etc/btrbk/btrbk.conf"
# Uncomment this if you only want to receive error messages:
#btrbk_opts="-q"
#skip_empty_mail=yes
# Email subject: # Email subject:
mail_subject_prefix="btrbk <${HOSTNAME:-localhost}>" mail_subject_prefix="btrbk <${HOSTNAME:-localhost}>"
# rsync declarations (repeat complete block for more declarations): # Add summary and/or detail (rsync/btrbk command output) to mail body.
rsync_src[example_data]=user@example.com:/data/ # If both are not set, a mail is only sent on errors.
rsync_dst[example_data]=/mnt/backup/example.com/data/ mail_summary=yes
rsync_log[example_data]=/mnt/backup/example.com/data-${now}.log mail_detail=no
rsync_key[example_data]=/mnt/backup/ssh_keys/id_rsa
rsync_opt[example_data]="-az --delete"
# Enabled rsync declarations (space separated list) # List of mountpoints to be mounted/unmounted (whitespace-separated)
# mount_targets="/mnt/btr_pool /mnt/backup"
mount_targets=
# rsync declarations (repeat complete block for more declarations):
rsync_src[example_data]="user@example.com:/data/"
rsync_dst[example_data]="/mnt/backup/example.com/data/"
rsync_log[example_data]="/mnt/backup/example.com/data-${now}.log"
rsync_rsh[example_data]="ssh -i /mnt/backup/ssh_keys/id_rsa"
rsync_opt[example_data]="-az --delete --inplace --numeric-ids --acls --xattrs"
# If set, add "rsync_dst" to "sync_fs" (see below) if rsync reports files transferred
#sync_fs_onchange[example_data]=yes
# Enable all rsync declarations (all indices of rsync_src array)
#rsync_enable=${!rsync_src[@]}
# Explicitly enable rsync declarations (whitespace-separated list)
#rsync_enable="example_data" #rsync_enable="example_data"
rsync_enable= rsync_enable=
# Log level (1=error, 2=warn, 3=info) # If set, do not run btrbk if rsync reports no changes.
loglevel=2 # If set to "quiet", do not send mail.
#skip_btrbk_if_unchanged=quiet
# Array of directories to sync(1) prior to running btrbk. This is
# useful for source subvolumes having "snapshot_create ondemand"
# configured in btrbk.conf.
#sync_fs=("/mnt/btr_data" "/mnt/btr_pool")
# btrbk command / options:
btrbk_command="run"
btrbk_opts="-c /etc/btrbk/btrbk.conf"
### Layout options:
# Prefix command output: useful when using mail clients displaying
# btrbk summary lines starting with ">>>" as quotations.
#mail_cmd_block_prefix='\\u200B' # zero-width whitespace
#mail_cmd_block_prefix=". "
# Newline character
BR=$'\n'
##### end config section ##### ##### end config section #####
mail_body=""
check_options()
{
[[ -n "$btrbk_command" ]] || die "btrbk_command is not set"
for key in $rsync_enable; do
[[ -n "${rsync_src[$key]}" ]] || die "rsync_src is not set for \"$key\""
[[ -n "${rsync_dst[$key]}" ]] || die "rsync_dst is not set for \"$key\""
[[ -n "${rsync_opt[$key]}" ]] || die "rsync_opt is not set for \"$key\""
done
}
send_mail()
{
# assemble mail subject
local subject="$mail_subject_prefix"
[[ -n "$has_errors" ]] && subject+=" ERROR";
[[ -n "$status" ]] && subject+=" - $status";
[[ -n "$xstatus" ]] && subject+=" (${xstatus:2})";
# assemble mail body
local body=
if [[ -n "$info" ]] && [[ -n "$has_errors" ]] || [[ "${mail_summary:-no}" = "yes" ]]; then
body+="$info"
fi
if [[ -n "$detail" ]] && [[ -n "$has_errors" ]] || [[ "${mail_detail:-no}" = "yes" ]]; then
[[ -n "$body" ]] && body+="${BR}${BR}DETAIL:${BR}"
body+="$detail"
fi
# skip sending mail on empty body
if [[ -z "$body" ]] && [[ -n "$has_errors" ]]; then
body+="FATAL: something went wrong (errors present but empty mail body)${BR}"
fi
[[ -z "$body" ]] && exit 0
# send mail
echo "$body" | mail -s "$subject" $mailto
if [[ $? -ne 0 ]]; then
echo "$0: Failed to send btrbk mail to \"$mailto\", dumping mail:${BR}" 1>&2
echo "<mail_subject>$subject</mail_subject>${BR}<mail_body>${BR}$body</mail_body>" 1>&2
fi
}
einfo()
{
info+="$1${BR}"
}
ebegin()
{
ebtext=$1
detail+="${BR}### $1${BR}"
}
eend()
{
if [[ $1 -eq 0 ]]; then
eetext=${3-success}
detail+="${BR}"
else
has_errors=1
eetext="ERROR (code=$1)"
[[ -n "$2" ]] && eetext+=": $2"
detail+="${BR}### $eetext${BR}"
fi
info+="$ebtext: $eetext${BR}"
return $1
}
die() die()
{ {
/bin/echo "$0 FATAL: $1" 1>&2 einfo "FATAL: ${1}, exiting"
/bin/echo "$0 FATAL: exiting" 1>&2 has_errors=1
send_mail
exit 1 exit 1
} }
log_error() { [ $loglevel -ge 1 ] && /bin/echo "$0 ERROR: $1" 1>&2 ; }
log_warning() { [ $loglevel -ge 2 ] && /bin/echo "$0 WARNING: $1" 1>&2 ; }
log_info() { [ $loglevel -ge 3 ] && /bin/echo "$0 INFO: $1" 1>&2 ; }
run_cmd()
# {
# mount all mountpoints listed in $mount_targets cmd_out=$("$@" 2>&1)
# local ret=$?
for mountpoint in $mount_targets; do detail+="++ ${@@Q}${BR}"
$(/bin/findmnt -r -n -t btrfs $mountpoint 1>&2) if [[ -n "${mail_cmd_block_prefix:-}" ]] && [[ -n "$cmd_out" ]]; then
if [ $? = 0 ]; then detail+=$(echo -n "$cmd_out" | sed "s/^/${mail_cmd_block_prefix}/")
log_warning "btrfs filesystem already mounted: $mountpoint" detail+="${BR}"
else else
log_info "mount $mountpoint" detail+=$cmd_out
$(/bin/mount --target $mountpoint 1>&2) fi
[ $? = 0 ] || log_error "mount failed: $mountpoint" return $ret
}
mount_all()
{
# mount all mountpoints listed in $mount_targets
mounted=""
for mountpoint in $mount_targets; do
ebegin "Mounting $mountpoint"
run_cmd findmnt -n $mountpoint
if [[ $? -eq 0 ]]; then
eend -1 "already mounted"
else
detail+="${BR}"
run_cmd mount --target $mountpoint
eend $? && mounted+=" $mountpoint"
fi fi
done done
}
umount_mounted()
{
for mountpoint in $mounted; do
ebegin "Unmounting $mountpoint"
run_cmd umount $mountpoint
eend $?
done
}
check_options
mount_all
# #
# run rsync for all $rsync_enable # run rsync for all $rsync_enable
# #
for key in $rsync_enable; do for key in $rsync_enable; do
log_info "starting rsync: $key" ebegin "Running rsync[$key]"
if [[ -d "${rsync_dst[$key]}" ]]; then
# There is no proper way to get a proper machine readable
# output of "rsync did not touch anything at destination", so
# we add "--info=stats2" and parse the output.
# NOTE: This also appends the stats to the log file (rsync_log).
# Another approach to count the files would be something like:
# "rsync --out-format='' | wc -l"
run_cmd rsync ${rsync_opt[$key]} \
--info=stats2 \
${rsync_log[$key]:+--log-file="${rsync_log[$key]}"} \
${rsync_rsh[$key]:+-e "${rsync_rsh[$key]}"} \
"${rsync_src[$key]}" \
"${rsync_dst[$key]}"
exitcode=$?
[ -n "${rsync_src[$key]}" ] || die "rsync_src is not set for \"$key\"" # parse stats2 (count created/deleted/transferred files)
[ -n "${rsync_dst[$key]}" ] || die "rsync_dst is not set for \"$key\"" REGEXP=$'\n''Number of created files: ([0-9]+)'
[ -n "${rsync_log[$key]}" ] || die "rsync_log is not set for \"$key\"" REGEXP+='.*'$'\n''Number of deleted files: ([0-9]+)'
[ -n "${rsync_key[$key]}" ] || die "rsync_key is not set for \"$key\"" REGEXP+='.*'$'\n''Number of regular files transferred: ([0-9]+)'
[ -n "${rsync_opt[$key]}" ] || die "rsync_opt is not set for \"$key\"" if [[ $cmd_out =~ $REGEXP ]]; then
rsync_stats="${BASH_REMATCH[1]}/${BASH_REMATCH[2]}/${BASH_REMATCH[3]}"
rsync_header="### rsync ${rsync_opt[$key]} ${rsync_src[$key]} ${rsync_dst[$key]}" rsync_stats_long="${BASH_REMATCH[1]} created, ${BASH_REMATCH[2]} deleted, ${BASH_REMATCH[3]} transferred"
nfiles=$(( ${BASH_REMATCH[1]} + ${BASH_REMATCH[2]} + ${BASH_REMATCH[3]} ))
if [ -d ${rsync_dst[$key]} ]; then
/bin/echo "$rsync_header" >> ${rsync_log[$key]}
ret=$(/usr/bin/rsync ${rsync_opt[$key]} --info=STATS --log-file=${rsync_log[$key]} -e "/usr/bin/ssh -i ${rsync_key[$key]}" ${rsync_src[$key]} ${rsync_dst[$key]})
if [ $? != 0 ]; then
log_error "rsync failed: $key"
ret+="\nERROR: rsync failed with exit code $?\n"
fi
mail_body+="$rsync_header$ret\n\n"
else else
ret="rsync destination directory not found for \"$key\", skipping: ${rsync_dst[$key]}" rsync_stats_long="failed to parse stats, assuming files transferred"
mail_body+="$rsync_header\n$ret\n\n" rsync_stats="-1/-1/-1"
log_error "$ret" nfiles=-1
fi
eend $exitcode "$rsync_stats_long" "$rsync_stats_long"
xstatus+=", rsync[$key]=$rsync_stats"
if [[ $nfiles -ne 0 ]]; then
# NOTE: on error, we assume files are transferred
rsync_files_transferred=1
[[ -n "${sync_fs_onchange[$key]}" ]] && sync_fs+=("${rsync_dst[$key]}")
fi
else
eend -1 "Destination directory not found, skipping: ${rsync_dst[$key]}"
fi fi
done done
# honor skip_btrbk_if_unchanged (only if rsync is enabled and no files were transferred)
if [[ -n "$rsync_enable" ]] && [[ -n "$skip_btrbk_if_unchanged" ]] && [[ -z "$rsync_files_transferred" ]]; then
einfo "No files transferred, exiting"
status="No files transferred"
umount_mounted
if [[ "$skip_btrbk_if_unchanged" != "quiet" ]] || [[ -n "$has_errors" ]]; then
send_mail
fi
exit 0
fi
#
# sync filesystems in sync_fs
#
if [[ ${#sync_fs[@]} -gt 0 ]]; then
ebegin "Syncing filesystems at ${sync_fs[@]}"
run_cmd sync -f "${sync_fs[@]}"
eend $?
fi
# #
# run btrbk # run btrbk
# #
log_info "running btrbk" ebegin "Running btrbk"
ret=$(/usr/sbin/btrbk -c "$config" ${btrbk_opts:-} run 2>&1) run_cmd btrbk ${btrbk_opts:-} ${btrbk_command}
exitcode=$? exitcode=$?
case $exitcode in case $exitcode in
0) status="All backups successful" 0) status="All backups successful"
;; ;;
10) status="ERROR: At least one backup task aborted!" 3) status="Another instance of btrbk is running, no backup tasks performed!"
;; ;;
*) status="ERROR: $btrbk failed with error code $exitcode" 10) status="At least one backup task aborted!"
;;
*) status="btrbk failed with error code $exitcode"
;; ;;
esac esac
eend $exitcode "$status"
mail_body+=$ret umount_mounted
send_mail
if [ "${skip_empty_mail:-no}" = "yes" ] && [ -z "$mail_body" ] && [ $exitcode -eq 0 ]; then
: # skip email sending if skip_empty_mail=yes
else
# send email
/bin/echo -e "$mail_body" | /bin/mail -s "$mail_subject_prefix - $status" $mailto
if [ $? != 0 ]; then
log_error "failed to send btrbk mail to \"$mailto\", dumping mail body:"
/bin/echo -e "$mail_body" 1>&2
fi
fi
#
# sync all mountpoints listed in $umount_targets
#
# exit on failure!
#for mountpoint in $umount_targets; do
# log_info "btrfs filesystem sync $mountpoint"
# $(/sbin/btrfs filesystem sync $mountpoint 1>&2)
# [ $? = 0 ] || die "btrfs filesystem sync failed: $mountpoint"
# sleep 1
#done
#
# unmount all mountpoints listed in $umount_targets
#
for mountpoint in $umount_targets; do
log_info "umount $mountpoint"
$(/bin/umount $mountpoint 1>&2)
[ $? = 0 ] || log_error "umount failed: $mountpoint"
done

424
contrib/cron/btrbk-verify Executable file
View File

@ -0,0 +1,424 @@
#!/bin/bash
#
# NAME
#
# btrbk-verify - check latest btrbk snapshot/backup pairs
#
#
# SYNOPSIS
#
# btrbk-verify [options] <command> [filter...]
#
#
# DESCRIPTION
#
# Compare btrbk backups. Reads all files and attributes, and
# compares checksums of source and target. Uses rsync(1) as backend,
# in dry-run mode with all preserve options enabled.
#
# Resolves snapshot/backup pairs by evaluating the output of
# "btrbk list latest [filter...]". The filter argument is passed
# directly to btrbk, see btrbk(1) FILTER STATEMENTS.
#
# Restrictions:
# - ".d..t...... ./" lines are ignored by default:
# Root folder timestamp always differ.
# - "cd+++++++++ .*" lines are ignored by default:
# Nested subvolumes appear as new empty directories.
# - btrbk raw targets are skipped
# - rsync needs root in most cases (see --ssh-* options)
#
# NOTE: Depending on your setup (hardware, btrfs mount options),
# btrbk-verify may eat all your CPU power and use high bandwidth!
# Consider nice(1), ionice(1).
#
# Incomplete resource eater list:
# - rsync: checksums, heavy disk I/O
# - btrfs: decompression, encryption
# - ssh: compression, encryption
#
#
# EXAMPLES
#
# btrbk-verify latest /mnt/btr_pool
#
# Verify latest backups from targets configured in
# /etc/btrbk/btrbk.conf, matching the "/mnt/btr_pool" filter.
#
# btrbk-verify all
#
# Verify ALL backups from targets in /etc/btrbk/btrbk.conf.
# NOTE: This really re-checksums ALL files FOR EACH BACKUP,
# even if they were not touched between backups!
#
# btrbk-verify latest -n -v -v
#
# Print detailed log as well as command executed by this script,
# without actually executing rsync commands (-n, --dry-run).
#
# btrbk-verify --ssh-agent --ssh-user root --ssh-identity /etc/btrbk/ssh/id_ed25519
#
# Use "ssh -i /etc/btrbk/ssh/id_ed25519 -l root" for rsync rsh
# (override settings from btrbk.conf), start an ssh-agent(1) for
# this session and verify all latest snapshot / backups.
#
#
# SEE ALSO
#
# btrbk(1), btrbk.conf(5), rsync(1), nice(1), ionice(1)
#
#
# AUTHOR
#
# Axel Burri <axel@tty0.ch>
#
set -u
set -e
set -o pipefail
btrbk_version_min='0.32.0'
# defaults: ignore subvol dirs and root folder timestamp change
ignore_nested_subvolume_dir=1
ignore_root_folder_timestamp=1
ssh_identity=
ssh_user=
ssh_start_agent=
verbose=0
stats_enabled=
dryrun=
print_usage()
{
#80-----------------------------------------------------------------------------
cat 1>&2 <<EOF
usage: btrbk-verify [options] <command> [btrbk-list-options...] [filter...]
options:
-h, --help display this help message
-c, --config FILE specify btrbk configuration file
-n, --dry-run perform a trial run without verifying subvolumes
-v, --verbose be verbose (set twice for debug loglevel)
--stats print rsync stats to stderr (--info=stats2)
--strict treat all rsync diffs as errors
--ignore-acls ignore acls when verifying subvolumes
--ignore-xattrs ignore xattrs when verifying subvolumes
--ssh-identity FILE override ssh_identity from btrbk.conf(5) with FILE,
and clear all other ssh_* options (use with --ssh-user)
--ssh-user USER override ssh_user from btrbk.conf(5) with USER, and
clear all other ssh_* options(use with --ssh-identity)
--ssh-agent start ssh-agent(1) and add identity
commands:
latest verify most recent snapshots and backups (btrbk list latest)
all verify all snapshots and backups (btrbk list backups)
For additional information, see <https://digint.ch/btrbk/>
EOF
#80-----------------------------------------------------------------------------
exit ${1:-0}
}
list_subcommand=
btrbk_args=()
rsync_args=(-n --itemize-changes --checksum -a --delete --numeric-ids --hard-links --acls --xattrs --devices --specials)
while [[ "$#" -ge 1 ]]; do
key="$1"
case $key in
latest)
[[ -n "$list_subcommand" ]] && print_usage 2;
list_subcommand="latest"
;;
all)
[[ -n "$list_subcommand" ]] && print_usage 2;
list_subcommand="backups"
;;
-n|--dry-run)
dryrun=1
;;
--stats)
# enable rsync stats2 (transfer statistics)
rsync_args+=(--info=stats2)
stats_enabled=1
;;
--strict)
# treat all rsync diffs as errors:
# - empty directories (nested subvolumes)
# - root folder timestamp mismatch
ignore_nested_subvolume_dir=
ignore_root_folder_timestamp=
;;
--ignore-*) # --ignore-acls, --ignore-xattrs, --ignore-device, ...
# remove "--xxx" flag from rsync_args for --ignore-xxx
rsync_args=(${rsync_args[@]/"--"${key#"--ignore-"}})
;;
--ssh-identity)
# use different ssh identity (-i option) for rsync rsh.
# NOTE: this overrides all btrbk ssh_* options
ssh_identity="$2"
shift
;;
--ssh-user)
# use different ssh user (-l option) for rsync rsh
# NOTE: this overrides all btrbk ssh_* options
ssh_user="$2"
shift
;;
--ssh-agent)
ssh_start_agent=1
;;
-v|--verbose)
verbose=$((verbose+1))
btrbk_args+=("-v")
;;
-h|--help)
print_usage 0
;;
*)
# all other args are passed to btrbk (filter, -c,--config=FILE)
btrbk_args+=("$key")
;;
esac
shift
done
BR=$'\n'
log_line()
{
echo "$@" 1>&2
}
log_stats () { [[ -n "$stats_enabled" ]] && log_line "$@" ; return 0; }
log_verbose() { [[ $verbose -ge 1 ]] && log_line "$@" ; return 0; }
log_debug() { [[ $verbose -ge 2 ]] && log_line "$@" ; return 0; }
log_cmd()
{
local prefix=""
[[ -n "$dryrun" ]] && prefix="(dryrun) "
log_debug "### ${prefix}$@"
}
tlog()
{
# same output as btrbk transaction log
local status=$1
local comment=${2:-}
[[ -n "$dryrun" ]] && [[ "$status" == "starting" ]] && status="dryrun_starting"
local line="$(date --iso-8601=seconds) verify-rsync ${status} ${target} ${source} - -"
[[ -n "$comment" ]] && line="$line # $comment";
tlog_text+="$line${BR}"
log_debug "$line"
}
tlog_print()
{
# tlog goes to stdout
echo "${BR}TRANSACTION LOG${BR}---------------${BR}${tlog_text:-}"
}
# parse "rsync -i,--itemize-changes" output.
# prints ndiffs to stdout, and detailed log messages to stderr
count_rsync_diffs()
{
local nn=0
local rsync_line_match='^(...........) (.*)$'
local dump_stats_mode=
# unset IFS: no word splitting, trimming (read literal line)
while IFS= read -r rsync_line; do
local postfix_txt=""
if [[ -n "$dump_stats_mode" ]]; then
# dump_stats_mode enabled, echo to stderr
log_stats "${rsync_line}"
elif [[ "$rsync_line" == "" ]]; then
# empty line denotes start of --info=stats, enable dump_stats_mode
dump_stats_mode=1
log_stats "--- BEGIN rsync stats2 dump ---"
elif [[ "$rsync_line" =~ $rsync_line_match ]]; then
rl_flags="${BASH_REMATCH[1]}"
rl_path="${BASH_REMATCH[2]}"
if [[ -n "$ignore_root_folder_timestamp" ]] && [[ "$rsync_line" == ".d..t...... ./" ]]; then
# ignore timestamp on root folder, for some reason this does not match
postfix_txt=" # IGNORE reason=ignore_root_folder_timestamp"
elif [[ -n "$ignore_nested_subvolume_dir" ]] && [[ "$rl_flags" == "cd+++++++++" ]]; then
# nested subvolumes appear as new empty directories ("cd+++++++++") in rsync (btrfs bug?)
postfix_txt=" # IGNORE reason=ignore_nested_subvolume_dir"
else
nn=$((nn+1))
postfix_txt=" # FAIL ndiffs=$nn"
fi
log_verbose "[rsync] ${rsync_line}${postfix_txt}"
else
nn=$((nn+1))
log_line "btrbk-verify: ERROR: failed to parse rsync line: ${rsync_line}"
fi
done
[[ -n "$dump_stats_mode" ]] && log_stats "--- END rsync stats2 dump ---"
echo $nn
return 0
}
rsync_rsh()
{
# btrbk v0.27.0 sets source_rsh="ssh [flags...] ssh_user@ssh_host"
# this returns "ssh [flags...] -l ssh_user"
local rsh=$1
local rsh_match="(.*) ([a-z0-9_-]+)@([a-zA-Z0-9.-]+)$"
if [[ -z "$rsh" ]]; then
return
elif [[ -n "$ssh_user" ]] || [[ -n "$ssh_identity" ]]; then
# override btrbk.conf from command line arguments
log_debug "Overriding all ssh_* options from btrbk.conf"
local cmd="ssh -q"
[[ -n "$ssh_identity" ]] && cmd="$cmd -i '$ssh_identity'"
[[ -n "$ssh_user" ]] && cmd="$cmd -l '$ssh_user'"
echo "$cmd"
elif [[ $rsh =~ $rsh_match ]]; then
echo "${BASH_REMATCH[1]} -l ${BASH_REMATCH[2]}"
else
log_line "btrbk-verify: ERROR: failed to parse source_rsh: $rsh"
exit 1
fi
}
kill_ssh_agent()
{
echo "Stopping SSH agent"
eval `ssh-agent -k`
}
start_ssh_agent()
{
if [[ -z "$ssh_identity" ]]; then
log_line "btrbk-verify: ERROR: no SSH identity specified for agent"
print_usage 2
fi
echo "Starting SSH agent"
eval `ssh-agent -s`
ssh_agent_running=1
trap 'exit_trap_action' EXIT
ssh-add "$ssh_identity"
}
eval_btrbk_resolved_line()
{
local line=" $1"
local prefix=$2
local required_keys=$3
# reset all variables first
for vv in $required_keys; do
eval "${prefix}${vv}="
done
for vv in $required_keys; do
# basic input validation, set prefixed variable (eval)
local match=" ${vv}='([^']*('\\\\''[^']*)*)'"
if [[ $line =~ $match ]] ; then
eval "${prefix}${vv}='${BASH_REMATCH[1]}'" || return 1
else
log_line "btrbk-verify: ERROR: Missing variable \"${vv}\""
return 1
fi
done
}
exit_trap_action()
{
[[ -n "${ssh_agent_running:-}" ]] && kill_ssh_agent
[[ $verbose -gt 0 ]] && tlog_print
}
# start ssh-agent(1)
[[ -n "$ssh_start_agent" ]] && start_ssh_agent
# run "btrbk list"
[[ -z "$list_subcommand" ]] && print_usage 2
log_verbose "Resolving btrbk $list_subcommand"
btrbk_cmd=("btrbk" "list" "$list_subcommand" "--format=raw" "-q" "${btrbk_args[@]}")
log_debug "### ${btrbk_cmd[@]}"
btrbk_list=$("${btrbk_cmd[@]}")
btrbk_list_exitstatus=$?
if [[ $btrbk_list_exitstatus -ne 0 ]]; then
log_line "btrbk-verify: ERROR: Command execution failed (status=$btrbk_list_exitstatus): ${btrbk_cmd[@]}"
exit 1
fi
log_debug "--- BEGIN btrbk list $list_subcommand ---"
log_debug "$btrbk_list"
log_debug "--- END btrbk list $list_subcommand ---"
tlog_text=""
exitstatus=0
# trap on EXIT (includes all signals)
trap 'exit_trap_action' EXIT
while read -r btrbk_list_line; do
# set R_xxx variables from format=raw line (table format "resolved")
log_debug "Evaluating [btrbk list] line: $btrbk_list_line"
[[ -z "$btrbk_list_line" ]] && continue
if ! eval_btrbk_resolved_line "$btrbk_list_line" \
"R_" "snapshot_subvolume target_subvolume source_host target_host target_type source_rsh target_rsh"
then
log_line "btrbk-verify: ERROR: Parse error of command output: ${btrbk_cmd[@]}"
log_line "Make sure to have >=btrbk-${btrbk_version_min} installed!"
exitstatus=1
break
fi
source="${R_snapshot_subvolume}/"
target="${R_target_subvolume}/"
[[ -n "$R_source_host" ]] && source="${R_source_host}:${source}"
[[ -n "$R_target_host" ]] && target="${R_target_host}:${target}"
if [[ -z "$R_snapshot_subvolume" ]]; then
log_line "WARNING: Skipping task (missing snapshot): target=$target"
elif [[ -z "$R_target_subvolume" ]]; then
log_line "Skipping task (no target): source=$source"
elif [[ "$R_target_type" != "send-receive" ]]; then
log_line "Skipping task (target_type=$R_target_type): source=$source, target=$target"
elif [[ -n "$R_source_rsh" ]] && [[ -n "$R_target_rsh" ]]; then
log_line "WARNING: Skipping task (SSH for both source and target is not supported): target=$target"
else
log_line "Comparing [rsync] $source $target"
# rsync rsh is either source_rsh or target_rsh or empty
eff_rsh="$R_source_rsh"
[[ -z "$eff_rsh" ]] && eff_rsh="$R_target_rsh"
eff_rsh=$(rsync_rsh "$eff_rsh")
rsync_cmd=("rsync" "${rsync_args[@]}")
[[ -n "$eff_rsh" ]] && rsync_cmd+=("-e" "$eff_rsh")
rsync_cmd+=("${source}" "${target}")
log_cmd "${rsync_cmd[@]}"
[[ -n "$dryrun" ]] && rsync_cmd=("cat" "/dev/null")
#rsync_cmd=("echo" '........... SHOULD/FAIL/'); # simulate failure
#rsync_cmd=("echo" 'cd+++++++++ SHOULD/IGNORE/'); # simulate ignored
# execute rsync
tlog "starting"
set +e
ndiffs=$("${rsync_cmd[@]}" | count_rsync_diffs)
rsync_exitstatus=$?
set -e
if [[ $rsync_exitstatus -ne 0 ]] || [[ -z "$ndiffs" ]]; then
log_line "btrbk-verify: ERROR: Command execution failed (status=$rsync_exitstatus): ${rsync_cmd[@]}"
tlog "ERROR"
exitstatus=10
elif [[ $ndiffs -gt 0 ]]; then
log_line "VERIFY FAIL (ndiffs=$ndiffs): ${source} ${target}"
tlog "fail" "ndiffs=$ndiffs"
exitstatus=10
else
log_verbose "Compare success (ndiffs=$ndiffs)"
tlog "success"
fi
fi
done <<< "$btrbk_list"
#done < <(echo "$btrbk_list") # more posix'ish
# NOTE: this triggers exit_trap_action()
exit $exitstatus

60
contrib/crypt/kdf_pbkdf2.py Executable file
View File

@ -0,0 +1,60 @@
#!/usr/bin/env python3
#
# kdf_pbkdf2.py - (kdf_backend for btrbk)
#
# Copyright (c) 2017 Axel Burri
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# ---------------------------------------------------------------------
# The official btrbk website is located at:
# https://digint.ch/btrbk/
#
# Author:
# Axel Burri <axel@tty0.ch>
# ---------------------------------------------------------------------
import sys
import os
import getpass
import hashlib
def passprompt():
pprompt = lambda: (getpass.getpass("Passphrase: "), getpass.getpass("Retype passphrase: "))
p1, p2 = pprompt()
while p1 != p2:
print("No match, please try again", file=sys.stderr)
p1, p2 = pprompt()
return p1
if len(sys.argv) <= 1:
print("Usage: {} <dklen>".format(sys.argv[0]), file=sys.stderr)
sys.exit(1)
hash_name = "sha256"
iterations = 300000
dklen = int(sys.argv[1])
salt = os.urandom(16)
password = passprompt().encode("utf-8")
dk = hashlib.pbkdf2_hmac(hash_name=hash_name, password=password, salt=salt, iterations=iterations, dklen=dklen)
salt_hex = "".join(["{:02x}".format(x) for x in salt])
dk_hex = "".join(["{:02x}".format(x) for x in dk])
print("KEY=" + dk_hex);
print("algorithm=pbkdf2_hmac");
print("hash_name=" + hash_name);
print("salt=" + salt_hex);
print("iterations=" + str(iterations));

View File

@ -0,0 +1,181 @@
#!/usr/bin/perl
#
# raw_suffix2sidecar - migrate to btrbk raw target sidecar files
#
# Copyright (C) 2017 Axel Burri
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# ---------------------------------------------------------------------
# The official btrbk website is located at:
# https://digint.ch/btrbk/
#
# Author:
# Axel Burri <axel@tty0.ch>
# ---------------------------------------------------------------------
# Create raw sidecar ".info" files from uuid-suffixed raw backup files
# generated by btrbk < v0.26.0.
use strict;
use warnings FATAL => qw( all );
use Getopt::Long qw(GetOptions);
our $VERSION = '0.26.0'; # match btrbk version
our $AUTHOR = 'Axel Burri <axel@tty0.ch>';
our $PROJECT_HOME = '<https://digint.ch/btrbk/>';
my $VERSION_INFO = "raw_suffix2sidecar (btrbk migration script), version $VERSION";
my $compress_format_alt = 'gz|bz2|xz|lzo|lz4';
my $file_match = qr/[0-9a-zA-Z_@\+\-\.\/]+/; # note: ubuntu uses '@' in the subvolume layout: <https://help.ubuntu.com/community/btrfs>
my $uuid_match = qr/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/;
my $timestamp_postfix_match = qr/\.(?<YYYY>[0-9]{4})(?<MM>[0-9]{2})(?<DD>[0-9]{2})(T(?<hh>[0-9]{2})(?<mm>[0-9]{2})((?<ss>[0-9]{2})(?<zz>(Z|[+-][0-9]{4})))?)?(_(?<NN>[0-9]+))?/; # matches "YYYYMMDD[Thhmm[ss+0000]][_NN]"
my $raw_postfix_match = qr/--(?<received_uuid>$uuid_match)(\@(?<parent_uuid>$uuid_match))?\.btrfs?(\.(?<compress>($compress_format_alt)))?(\.(?<encrypt>gpg))?(\.(?<split>split_aa))?(\.(?<incomplete>part))?/; # matches ".btrfs_<received_uuid>[@<parent_uuid>][.gz|.bz2|.xz|...][.gpg][.split_aa][.part]"
my $dryrun;
my %raw_info_sort = (
TYPE => 1,
FILE => 2,
RECEIVED_UUID => 3,
RECEIVED_PARENT_UUID => 4,
INCOMPLETE => 5,
compress => 9,
split => 10,
encrypt => 11,
);
sub VERSION_MESSAGE
{
print STDERR $VERSION_INFO . "\n\n";
}
sub HELP_MESSAGE
{
print STDERR "usage: raw_suffix2sidecar <dir>...\n";
print STDERR "\n";
print STDERR "options:\n";
# "--------------------------------------------------------------------------------"; # 80
print STDERR " -h, --help display this help message\n";
print STDERR " --version display version information\n";
print STDERR " -n, --dry-run perform a trial run with no changes made\n";
print STDERR "\n";
print STDERR "For additional information, see $PROJECT_HOME\n";
}
sub write_raw_info($$)
{
my $file = shift // die;
my $raw_info = shift // die;
my $info_file = $file . '.info';
my @line;
push @line, "#raw_suffix2sidecar-v$VERSION";
push @line, "# Do not edit this file";
# sort by %raw_info_sort, then by key
foreach(sort { (($raw_info_sort{$a} || 99) <=> ($raw_info_sort{$b} || 99)) || ($a cmp $b) } keys %$raw_info) {
push @line, ($_ . '=' . $raw_info->{$_}) if($raw_info->{$_});
}
print "Creating info file: $info_file\n";
unless($dryrun) {
open (INFOFILE, ">> $info_file") || die "Failed to open $info_file";
print INFOFILE join("\n", @line) . "\n";
close(INFOFILE);
}
return $info_file;
}
MAIN:
{
Getopt::Long::Configure qw(gnu_getopt);
unless(GetOptions(
'help|h' => sub { VERSION_MESSAGE(); HELP_MESSAGE(0); exit 0; },
'version' => sub { VERSION_MESSAGE(); exit 0; },
'dry-run|n' => \$dryrun,
))
{
VERSION_MESSAGE();
HELP_MESSAGE(0);
exit 2;
}
unless(@ARGV) {
VERSION_MESSAGE();
HELP_MESSAGE();
exit 1;
}
foreach my $target_dir (@ARGV) {
$target_dir =~ s/\/+$//;
print "Processing directory: $target_dir/\n";
opendir(my($dh), $target_dir) || die "Failed to open directory '$target_dir': $!";
my @files = readdir($dh);
closedir $dh;
my @splitfiles = @files;
foreach my $file (@files) {
if($file =~ /^(?<basename>$file_match$timestamp_postfix_match)$raw_postfix_match$/) {
print "\nProcessing raw backup: $file\n";
my $newname = $+{basename} || die;
my %raw_info = (
TYPE => 'raw',
RECEIVED_UUID => $+{received_uuid},
RECEIVED_PARENT_UUID => $+{parent_uuid},
INCOMPLETE => $+{incomplete} ? 1 : 0,
compress => $+{compress},
split => ($+{split} ? (-s $file) : undef), # file size
encrypt => $+{encrypt},
);
die "Missing received uuid in file: $file" unless $raw_info{RECEIVED_UUID};
$newname .= '.btrfs';
$newname .= '.' . $raw_info{compress} if($raw_info{compress});
$newname .= '.' . $raw_info{encrypt} if($raw_info{encrypt});
$raw_info{FILE} = $newname;
write_raw_info("$target_dir/$newname", \%raw_info);
if($raw_info{split}) {
my $sfile = $file;
$sfile =~ s/_aa$//; # we match on ".split_aa" above
foreach my $splitfile (@splitfiles) {
if($splitfile =~ /^${sfile}(_[a-z]+)$/) {
my $suffix = $1 // die;
print "Renaming file: $target_dir/$splitfile -> $target_dir/$newname.split$suffix\n";
unless($dryrun) {
rename("$target_dir/$splitfile", "$target_dir/$newname.split$suffix") || die "Failed to rename file: $target_dir/$splitfile -> $target_dir/${newname}.split$suffix: $!";
}
}
}
}
else {
print "Renaming file: $target_dir/$file -> $target_dir/$newname\n";
unless($dryrun) {
rename("$target_dir/$file", "$target_dir/$newname") || die "Failed to rename file: $target_dir/$file -> $target_dir/$newname";
}
}
}
}
}
if($dryrun) {
print "\nNOTE: Dryrun was active, none of the operations above were actually executed!\n";
}
}
1;

View File

@ -1,6 +1,7 @@
[Unit] [Unit]
Description=btrbk backup Description=btrbk backup
Documentation=man:btrbk(1)
[Service] [Service]
Type=oneshot Type=oneshot
ExecStart=/usr/sbin/btrbk run ExecStart=@BINDIR@/btrbk run

View File

@ -7,4 +7,4 @@ AccuracySec=10min
Persistent=true Persistent=true
[Install] [Install]
WantedBy=multi-user.target WantedBy=timers.target

View File

@ -0,0 +1,217 @@
#!/usr/bin/env python3
import os
import logging
import subprocess
import argparse
logger = logging.getLogger(__name__)
class TransformProcess:
def run(self, bfile, options, **kw):
return subprocess.Popen(self.get_cmd(bfile, options), **kw)
def get_cmd(self, bfile, options):
raise NotImplementedError()
@classmethod
def add_parser_options(cls, parser):
pass
class TransformOpensslDecrypt(TransformProcess):
@staticmethod
def get_cmd(bfile, options):
return [
'openssl', 'enc', '-d', '-' + bfile.info['cipher'], '-K',
open(options.openssl_keyfile, 'r').read(), '-iv', bfile.info['iv']
]
@staticmethod
def add_parser_options(parser):
parser.add_argument('--openssl-keyfile', help="path to private encryption key file")
class TransformDecompress(TransformProcess):
def __init__(self, program):
self.p = program
def get_cmd(self, bfile, options):
return [self.p, '-d']
class TransformBtrfsReceive(TransformProcess):
@classmethod
def run(cls, bfile, options, **kw):
return subprocess.Popen(cls.get_cmd(bfile, options), **kw)
@staticmethod
def get_cmd(bfile, options):
return ['btrfs', 'receive', options.restore_dir]
TRANSFORMERS = (
TransformOpensslDecrypt, TransformDecompress, TransformBtrfsReceive
)
class BtrfsPipeline:
def __init__(self, bfile):
self.bfile = bfile
self.processors = []
def append(self, transformer):
self.processors.append(transformer)
def run(self, options):
processes = []
with open(self.bfile.data_file, 'rb') as next_input:
for transformer in self.processors:
process = transformer.run(
self.bfile, options,
stdin=next_input, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
next_input = process.stdout
processes.append(process)
btrfs_process = TransformBtrfsReceive.run(
self.bfile, options, stdin=next_input,
stderr=subprocess.PIPE, stdout=subprocess.DEVNULL)
processes.append(btrfs_process)
# warning: the code below is pretty ugly and hacky
terminated = 0
while terminated < len(processes):
for p in processes:
if p.returncode is not None:
continue
msg = None
try:
p.wait(timeout=1)
except subprocess.TimeoutExpired as e:
pass
except Exception as e:
msg = e
else:
msg = p.stderr.read().decode('utf-8').strip()
finally:
if p.returncode is not None:
terminated += 1
if p.returncode != 0:
for p_other in processes:
p_other.terminate()
terminated += 1
if msg:
logger.error(f"error running {p.args}: {msg}")
def get_cmd(self, options):
command_pipe = [['cat', self.bfile.data_file]]
for transformer in self.processors:
command_pipe.append(transformer.get_cmd(self.bfile, options))
command_pipe.append(TransformBtrfsReceive.get_cmd(self.bfile, options))
return ' | '.join(' '.join(x) for x in command_pipe)
class BackupFile:
def __init__(self, path):
assert path.endswith('.info')
self.info_file = path
self.info = self._parse_info()
self.uuid = self.info['RECEIVED_UUID']
self.data_file = os.path.join(os.path.dirname(path), self.info['FILE'])
self.parent = self.info.get('RECEIVED_PARENT_UUID')
self.is_restored = False
def _parse_info(self):
config = {}
with open(self.info_file, 'r') as fh:
# skip command option line
for line in fh.readlines():
if '=' not in line:
continue
key, val = line.strip().split('=', maxsplit=1)
config[key] = val
return config
def get_transformers(self):
if 'encrypt' in self.info:
if self.info['encrypt'] == 'gpg':
raise NotImplementedError('gpg encryption')
elif self.info['encrypt'] == 'openssl_enc':
yield TransformOpensslDecrypt()
else:
raise Exception(f'unknown encryption type: "{self.info["encrypt"]}"')
if 'compress' in self.info:
yield TransformDecompress(self.info['compress'])
def restore_file(self, options):
assert self.info.get('TYPE') == 'raw'
assert not self.info.get('INCOMPLETE')
pipeline = BtrfsPipeline(self)
for transformer in self.get_transformers():
pipeline.append(transformer)
if options.dry_run:
print(pipeline.get_cmd(options))
else:
logger.info(f"restoring backup {os.path.basename(self.data_file)}")
pipeline.run(options)
self.is_restored = True
def restore_from_path(backup, options):
path = os.path.dirname(backup)
info_files = {}
backup_file = BackupFile(backup + '.info')
restored_files = set()
for entry in os.scandir(path):
if entry.is_file() and entry.name.endswith('.info'):
info = BackupFile(entry.path)
info_files[info.uuid] = info
restored_files.update(restore_backup(backup_file, info_files, options))
logger.info(f"finished; restored {len(restored_files)} backup files")
def restore_backup(bfile, parents, options):
if bfile.is_restored:
return
if bfile.parent:
parent = parents.get(bfile.parent)
if not parent:
msg = (f"missing parent {bfile.parent} for"
f"'{os.path.basename(bfile.info_file)}'")
if options.ignore_missing:
logger.warning(msg)
else:
raise Exception(msg)
else:
yield from restore_backup(parent, parents, options)
bfile.restore_file(options)
yield bfile.uuid
def main():
parser = argparse.ArgumentParser(description="restore btrbk raw backup")
parser.add_argument('backup', help="backup file to restore; for incremental"
" backups the parent files must be in the same directory")
parser.add_argument('restore_dir', help="target directory for restored subvolumes"
" (path argument for \"btrfs receive\")")
parser.add_argument('-n', '--dry-run', action='store_true',
help="print commands that would be executed")
parser.add_argument('--ignore-missing', action='store_true',
help="do not fail on missing parent snapshots")
for transformer in TRANSFORMERS:
transformer.add_parser_options(parser)
args = parser.parse_args()
if args.dry_run:
logger.setLevel('ERROR')
restore_from_path(args.backup, args)
if __name__ == '__main__':
logger.setLevel('INFO')
logging.basicConfig(format='%(asctime)s %(levelname)s - %(message)s')
main()

2
doc/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.[1-8]
*.[1-8].gz

View File

@ -19,38 +19,38 @@ FILTER STATEMENTS), which means you can e.g. add "group automount"
tags in your configuration and dump only the volumes of this group: tags in your configuration and dump only the volumes of this group:
`btrbk list volume automount`. `btrbk list volume automount`.
[btrbk(1)]: http://www.digint.ch/btrbk/doc/btrbk.html [btrbk(1)]: https://digint.ch/btrbk/doc/btrbk.1.html
Why is it not possible to backup '/' (btrfs root) ? How can I setup a debian pre-install hook?
------------------------------------------
Create a file `/etc/apt/apt.conf.d/70btrbk`, e.g.:
// create a btrfs snapshot before (un)installing packages
Dpkg::Pre-Invoke {"/usr/bin/btrbk run /mnt/btr_pool/rootfs";};
In order to make sure that the snapshots are always generated and
nothing is deleted, add the btrbk command line options `--preserve
--override=snapshot_create=always`.
Why is "subvolume ." configuration not recommended?
--------------------------------------------------- ---------------------------------------------------
or in other words: why does this config not work: Referring to a btrbk configuration like this:
/etc/btrbk/btrbk.conf:
volume / volume /
subvolume / subvolume .
snapshot_name rootfs snapshot_name rootfs
*ERROR: Only relative files allowed for option "subvolume"*. Btrbk is designed to operate on the subvolumes *within* a root
subvolume. In the config above, the btrbk snapshots would be created
*inside* the source subvolume, altering it (from user perspective).
From btrfs perspective this is not a problem, as the snapshots are
separate subvolumes referring to the source subvolume and mapped into
the file system tree below the source subvolume.
### Answer
btrbk is designed to never alter your source subvolume. In the config
above, the btrbk snapshots would be created *inside* the source
subvolume, altering it.
The same applies to **any "btrfs root" mount point** (subvolid=0). In
the example below, you will **not be able to backup** `/mnt/data`
using btrbk:
/etc/fstab:
/dev/sda1 /mnt/data btrfs subvolid=0 [...]
btrbk is designed to operate on the subvolumes *within* `/mnt/data`.
The recommended way is to split your data into subvolumes, e.g.: The recommended way is to split your data into subvolumes, e.g.:
# btrfs subvolume create /mnt/data/www # btrfs subvolume create /mnt/data/www
@ -73,23 +73,6 @@ The btrbk configuration for this would be:
[...] [...]
### Tech Answer
While *btrfs root* (subvolid=0) is a regular subvolume, it is still
special: being the root node, it does not have a "name" inside the
subvolume tree.
Here, `/mnt/btr_pool` is mounted with `subvolid=0`:
# btrfs sub show /mnt/btr_pool/
/mnt/btr_pool is btrfs root
# btrfs sub show /mnt/btr_pool/rootfs
/mnt/btr_pool/rootfs
Name: rootfs
uuid: [...]
How should I organize my btrfs filesystem? How should I organize my btrfs filesystem?
------------------------------------------ ------------------------------------------
@ -105,7 +88,7 @@ a good entry point.
If your linux root filesystem is btrfs, I recommend booting linux from If your linux root filesystem is btrfs, I recommend booting linux from
a btrfs subvolume, and use the btrfs root only as a container for a btrfs subvolume, and use the btrfs root only as a container for
subvolumes (i.e. NOT booting from "subvolid=0"). This has the big subvolumes (i.e. NOT booting from "subvolid=5"). This has the big
advantage that you can choose the subvolume in which to boot by simply advantage that you can choose the subvolume in which to boot by simply
switching the `rootflags=subvol=<subvolume>` kernel boot option. switching the `rootflags=subvol=<subvolume>` kernel boot option.
@ -124,15 +107,15 @@ have to create a run-time (rw) snapshot before booting into it:
# btrfs subvolume snapshot /mnt/btr_pool/backup/btrbk/rootfs-20150101 /mnt/btr_pool/rootfs_testing # btrfs subvolume snapshot /mnt/btr_pool/backup/btrbk/rootfs-20150101 /mnt/btr_pool/rootfs_testing
How do I convert '/' (subvolid=0) into a subvolume? How do I convert '/' (subvolid=5) into a subvolume?
--------------------------------------------------- ---------------------------------------------------
There's several ways to achieve this, the solution described below is There's several ways to achieve this, the solution described below
that it guarantees not to create new files (extents) on disk. guarantees not to create new files (extents) on disk.
### Step 1: make a snapshot of your root filesystem ### Step 1: make a snapshot of your root filesystem
Assuming that '/' is mounted with `subvolid=0`: Assuming that '/' is mounted with `subvolid=5`:
# btrfs subvolume snapshot / /rootfs # btrfs subvolume snapshot / /rootfs
@ -140,13 +123,17 @@ Note that this command does NOT make any physical copy of the files of
your subvolumes within "/", it will only add some metadata. your subvolumes within "/", it will only add some metadata.
### Step 2: make sure that "/rootfs/etc/fstab" is ok. ### Step 2: (optional) add the toplevel subvolume to fstab
Add mount point for subvolid=0 to fstab, something like this: Add mount point for subvolid=5 to fstab, something like this:
/rootfs/etc/fstab: /rootfs/etc/fstab:
/dev/sda1 /mnt/btr_pool btrfs subvolid=0,noatime 0 0 /dev/sda1 /mnt/btr_pool btrfs subvolid=5,noatime 0 0
> This step is not critical for a proper root change, but will save
> your time by preventing further configurations/reboots and manually
> mounting the toplevel subvolume.
### Step 3: boot from the new subvolume "rootfs". ### Step 3: boot from the new subvolume "rootfs".
@ -156,10 +143,20 @@ Either add `rootflags=subvol=rootfs` to grub.cfg, or set subvolume
# btrfs subvolume set-default <subvolid> / # btrfs subvolume set-default <subvolid> /
You can obtain `<subvolid>` via
`btrfs subvolume show /rootfs | grep "Subvolume ID"`
> Editing grub.cfg manually may lead you some troubles if you perform
> some actions that will fire `grub-mkconfig`.
### Step 4: after reboot, check if everything went fine: ### Step 4: after reboot, check if everything went fine:
First check your **system log** for btrfs errors, then: First check your **system log** for btrfs errors:
cat /var/log/messages | grep -i btrfs | grep -i error
then check if current `/` is our new subvolume:
# btrfs subvolume show / # btrfs subvolume show /
Name: rootfs Name: rootfs
@ -167,38 +164,49 @@ First check your **system log** for btrfs errors, then:
Great, this tells us that we just booted into our new snapshot! Great, this tells us that we just booted into our new snapshot!
# mount /mnt/btr_pool
# btrfs subvolume show /mnt/btr_pool # btrfs subvolume show /mnt/btr_pool
/mnt/btr_pool is btrfs root /mnt/btr_pool is toplevel subvolume
This means that the root volume (subvolid=0) is correctly mounted. This means that the root volume (subvolid=5) is correctly mounted.
### Step 5: delete old (duplicate) files ### Step 5: delete old (duplicate) files
Carefully delete all old files from `/mnt/btr_pool`, except "rootfs" Carefully delete all old files from `/mnt/btr_pool`, except "rootfs"
and all other subvolumes within "/". You can list all these by typing: and any other subvolumes within "/mnt/btr_pool". In other words,
delete any folders that are NOT LISTED by `btrfs subvolume list -a
# btrfs subvolume list -a /mnt/btr_pool /mnt/btr_pool`:
Make sure you do NOT delete anything within the directories listed
here!
something like:
# cd /mnt/btr_pool # cd /mnt/btr_pool
# rm -rf bin sbin usr lib var ... # mkdir TO_BE_REMOVED
# mv bin sbin usr lib var ... TO_BE_REMOVED
Then reboot. If everything went fine, remove the directory:
# cd /mnt/btr_pool
# rm -rf TO_BE_REMOVED
What is the most efficient way to clone btrfs storage? What is the most efficient way to clone btrfs storage?
------------------------------------------------------ ------------------------------------------------------
It is very common (and avisable!) to keep backups on a separate It is very common (and avisable!) to keep backups on a separate
location. In some situations, is is also required to transport the location. In some situations, it is also required to transport the
data physically, either to the datacenter or to your safe in the data physically, either to the datacenter or to your safe in the
basement. basement.
### Answer 1: Use external storage as "stream-fifo"
### Answer 1: Use "btrbk archive"
A robust approach is to use external disks as archives (secondary
backups), and regularly run "btrbk archive" on them. As a nice side
effect, this also detects possible read-errors on your backup targets
(Note that a "btrfs scrub" is still more effective for that purpose).
See **btrbk archive** command in [btrbk(1)] for more details.
### Answer 2: Use external storage as "stream-fifo"
This example uses a USB disk as "stream-fifo" for transferring This example uses a USB disk as "stream-fifo" for transferring
(cloning) of btrfs subvolumes: (cloning) of btrfs subvolumes:
@ -217,29 +225,82 @@ USB disk. This works fine, but be aware that you may run into trouble
if a single stream gets corrupted, making all subsequent streams if a single stream gets corrupted, making all subsequent streams
unusable. unusable.
### Answer 2: Clone btrfs subvolumes
A more robust approach is to use the USB disk as secondary backup. ### Warning: Avoid using "dd" on btrfs filesystems!
This has the advantage that possible errors can already be detected by
btrfs on the source side:
1. Initialize USB disk: If you use `dd` (e.g. in order to clone a partition), make sure you
don't mount the cloned filesystem at the same time as the original
one. You will end up having multiple filesystems **sharing identical
UUID**, which will break things. If you _really_ want to do this, make
sure to run:
`mkfs.btrfs /dev/usbX` btrfstune -u /dev/sdaX
2. For all source subvolumes (in order of generation): which changes the UUID of the given device. Note that the btrfs
subvolumes still share identical UUID's, but at least the kernel can
cope with it (see
[this post on stackexchange](https://unix.stackexchange.com/questions/246976/btrfs-subvolume-uuid-clash)
).
`btrfs send /source/subvolX -p PARENT | btrfs receive /usbdisk/` Btrbk on the other hand relies on subvolume UUID's being *universally
unique*, and uses them as hash keys for identifying and caching
filesystem and subvolume trees, which leads to undefined behavior if
multiple identical UUID's are processed.
3. At the target location (in order of generation):
`btrfs send /usbdisk/subvolX -p PARENT | btrfs receive /target` I'm getting an error: Aborted: "Received UUID" is set
-----------------------------------------------------
If you simply want to have a clone of the source disk, skip step 3 and You probably restored a backup with send-receive, and made it
store your USB disk in a safe. You will be able to use it for read/write using `btrfs property set`. This is bad, as all snapshots
restoring backups later, or *as a replacement for your backup disks*. and backups will inherit this identical "Received UUID", which results
in all these subvolumes will be treated as "containing same data".
**Note that kernels >=4.1 have a bug when re-sending subvolumes**, To fix this, create a "proper" snapshot:
make sure you run a patched kernel or step 3 will fail. Read
[this thread on gmane](http://thread.gmane.org/gmane.comp.file-systems.btrfs/48798) # cd /mnt/btr_pool
(the patch provided is confirmed working on kernels 4.2.x and 4.3). # mv mysubvolume mysubvolume.broken
# btrfs subvolume snapshot mysubvolume.broken mysubvolume
Now, `mysubvolume` should have an empty "Received UUID". Note that in
order to have a clean environment, you also need to fix all subvolumes
(snapshots as well as backups) that you created with the broken
subvolume.
Check if there are more broken subvolumes:
# btrfs subvolume show mysubvolume.broken
# btrfs subvolume list -a -R /mnt/btr_pool | grep <"Received UUID" from above>
# btrfs subvolume list -a -R /mnt/btr_backup | grep <"Received UUID" from above>
Either delete them (they won't be used for incremental send-receive
anyways), or clean them as follows:
# btrfs subvolume snapshot listed_ro_subvol listed_ro_subvol.rw
# btrfs subvolume delete listed_ro_subvol
# btrfs subvolume snapshot -r listed_ro_subvol.rw listed_ro_subvol
# btrfs subvolume delete listed_ro_subvol.rw
Finally, don't forget to delete the broken source subvolume:
# btrfs subvolume delete mysubvolume.broken
You should now have a clean environment, and btrbk will not complain
any more.
I'm getting an error: Aborted: subvolume has no UUID
----------------------------------------------------
If your file system was created with btrfs-progs < 4.16, the btrfs
root subvolume (id=5) has no UUID. You can check this by calling:
# btrfs subvolume show /mnt/btr_pool
/
Name: <FS_TREE>
UUID: -
[...]
Without a UUID, the snapshots would get no parent_uuid, leaving btrbk
unable to track parent/child relationships. In this case, btrbk
refuses to create snapshots and backups.

69
doc/Makefile Normal file
View File

@ -0,0 +1,69 @@
DOCS = FAQ.md
MAN_MAN1 = btrbk.1 \
lsbtr.1 \
ssh_filter_btrbk.1
MAN_MAN5 = btrbk.conf.5
PN = btrbk
PREFIX ?= /usr
DOCDIR = $(PREFIX)/share/doc/$(PN)
MAN1DIR = $(PREFIX)/share/man/man1
MAN5DIR = $(PREFIX)/share/man/man5
ifeq ($(COMPRESS), yes)
DOCS := $(addsuffix .gz,$(DOCS))
MAN_MAN1 := $(addsuffix .gz,$(MAN_MAN1))
MAN_MAN5 := $(addsuffix .gz,$(MAN_MAN5))
endif
# convert using "asciidoctor": <https://asciidoctor.org>
# fallback to "a2x" from asciidoc package: <http://asciidoc.org>
ifneq (, $(shell command -v asciidoctor 2> /dev/null))
ASCIIDOC_MANPAGE = asciidoctor -d manpage -b manpage
ASCIIDOC_HTML = asciidoctor -b html5 -d article
else ifneq (, $(shell command -v a2x 2> /dev/null))
# NOTE: using -L (--no-xmllint), as xmllint is a separate package on many distros.
ASCIIDOC_MANPAGE = a2x -L -d manpage -f manpage
ASCIIDOC_HTML = asciidoc -b html -d article
else
ASCIIDOC_ERR = $(error "please install either asciidoc or asciidoctor")
ASCIIDOC_MANPAGE = $(ASCIIDOC_ERR)
ASCIIDOC_HTML = $(ASCIIDOC_ERR)
endif
# reproducible builds: reference date is ":date:" attribute from asciidoc source
date_attr = $(shell sed -rn 's/:date:\s*//p' $(1))
source_date_epoch = $(shell date +%s -u -d $(call date_attr,$(1)))
all: man
man: man1 man5
man1: $(MAN_MAN1)
man5: $(MAN_MAN5)
install: install-man install-doc
install-man: man
install -d -m 755 "$(DESTDIR)$(MAN1DIR)"
install -d -m 755 "$(DESTDIR)$(MAN5DIR)"
install -p -m 644 $(MAN_MAN1) "$(DESTDIR)$(MAN1DIR)"
install -p -m 644 $(MAN_MAN5) "$(DESTDIR)$(MAN5DIR)"
install-doc: $(DOCS)
install -d -m 755 "$(DESTDIR)$(DOCDIR)"
install -p -m 644 $(DOCS) "$(DESTDIR)$(DOCDIR)"
clean:
rm -f *.md.gz *.[15] *.[15].{gz,html}
%.gz : %
gzip -9 -n -c $< > $@
%.1 : %.1.asciidoc
SOURCE_DATE_EPOCH=$(call source_date_epoch,$<) $(ASCIIDOC_MANPAGE) $<
%.5 : %.5.asciidoc
SOURCE_DATE_EPOCH=$(call source_date_epoch,$<) $(ASCIIDOC_MANPAGE) $<
%.html : %.asciidoc
SOURCE_DATE_EPOCH=$(call source_date_epoch,$<) $(ASCIIDOC_HTML) -o $@ $<

View File

@ -1,302 +0,0 @@
.TH "btrbk" "1" "2016-02-02" "btrbk v0.22.2" ""
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.SH NAME
btrbk \- backup tool for btrfs volumes
.SH SYNOPSIS
.nf
\fBbtrbk\fR [\-h|\-\-help] [\-\-version] [\-c|\-\-config <file>]
[\-n|\-\-dry\-run] [\-p|\-\-preserve] [\-r|\-\-resume\-only]
[\-v|\-\-verbose] [\-q|\-\-quiet] [\-l|\-\-loglevel <level>]
[\-t|\-\-table] [\-\-format <output\-format>]
[\-\-progress]
<command> [<args>]
.fi
.SH DESCRIPTION
\fBbtrbk\fR is a backup tool for btrfs subvolumes, taking advantage of
btrfs specific capabilities to create atomic snapshots and transfer
them incrementally to target volumes. It is able to perform backups
from one source to multiple destinations.
.PP
Snapshots as well as backup subvolume names are created in form:
.PP
.RS 4
<snapshot_name>.<timestamp>[_N]
.RE
.PP
Where <snapshot_name> is identical to the source subvolume name,
unless the configuration option \fIsnapshot_name\fR is set. The
<timestamp> is either "YYYYMMDD" or "YYYYMMDDThhmm" (dependent of the
\fItimestamp_format\fR configuration option), where "YYYY" is the
year, "MM" is the month, "DD" is the day, "hh" is the hour and "mm" is
the minute of the creation time (local time of the host running
btrbk). If multiple snapshots/backups are created on the same
date/time, N will be incremented on each backup, starting at 1.
.SH OPTIONS
.PP
\-h, \-\-help
.RS 4
Prints the synopsis and a list of the commands.
.RE
.PP
\-\-version
.RS 4
Prints the btrbk version.
.RE
.PP
\-n, \-\-dry\-run
.RS 4
Don't run anything that would alter the filesystem, just show the
snapshots and backup subvolumes that would be created/deleted by the
\fBrun\fR and \fBclean\fR commands. Use in conjunction with \fI\-l
debug\fR to see the btrfs commands that would be executed.
.RE
.PP
\-c, \-\-config <file>
.RS 4
Read the configuration from <file>.
.RE
.PP
\-p, \-\-preserve
.RS 4
Preserve all backups. Skips deletion of old backups, even if specified
in the configuration file.
.RE
.PP
\-r, \-\-resume-only
.RS 4
Resume only. Skips snapshot creation, only resumes missing
backups. This only makes sense if the \fIresume_missing\fR option is
set to \[lq]yes\[rq] in the configuration file.
.RE
.PP
\-v, \-\-verbose
.RS 4
Verbose output. Sets "\-l info", and prints detailed scheduler
information on "run" and "dryrun" commands.
.RE
.PP
\-q, \-\-quiet
.RS 4
Quiet operation. If set, btrbk does not print the summary after
executing the "run" command.
.RE
.PP
\-l, \-\-loglevel <level>
.RS 4
Set the level of verbosity. Accepted levels are warn, info, debug,
and trace.
.RE
.PP
\-t, \-\-table
.RS 4
Print output in table format (shortcut for "--format=table").
.RE
.PP
\-\-format table|long|raw
.RS 4
Print output in specified format. If set to "raw", prints
space-separated key="value" pairs (machine-readable). Affects output
format for \fBrun\fR, \fBdryrun\fR, \fBlist\fR and \fBtree\fR
commands. Useful for further exporting/scripting.
.RE
.PP
\-\-progress
.RS 4
Show progress bar on send-receive operation.
.RE
.SH COMMANDS
.PP
.B run
[filter...]
.RS 4
Perform backup operations as specified in the configuration file. If
the optional [filter...] arguments are present, backups are only
performed for the subvolumes/targets matching a \fIFILTER STATEMENT\fR
(see below).
.PP
First, btrbk reads information from the source and target btrfs
filesystems in order to perform sanity checks and identify
parent/child and received-from relationships.
.PP
If the checks succeed, btrbk creates snapshots for all the source
subvolumes specified in the configuration file.
.PP
Then, for each specified target, btrbk creates the backups as follows:
If the \fIresume_missing\fR option is set (the default), btrbk
transfers all missing snapshots needed to satisfy the configured
\fItarget_preserve_{daily,weekly,monthly}\fR retention policy, always
incrementally from the latest common parent subvolume found. If no
common parent subvolume is found, a full backup is created for the
first transfer. Note that the latest snapshot (the one created in the
first step) is always transferred, regardless of the retention policy.
.PP
As a last step, unless the -p (preserve backups) option is set,
snapshots and backup subvolumes that are not preserved by their
configured retention policy will be deleted. Note that the latest
snapshot as well as the latest backup is always preserved, regardless
of the retention policy.
.PP
Use the \fI\-\-format\fR command line option to switch between
different output formats.
.RE
.PP
.B dryrun
[filter...]
.RS 4
Don't run any btrfs commands that would alter the filesystem, just
show the snapshots and backup subvolumes that would be created/deleted
by the \fBrun\fR command. Use in conjunction with \fI\-l debug\fR to
see the btrfs commands that would be executed.
.RE
.PP
.B stats
[filter...]
.RS 4
Print statistics of snapshot and backup subvolumes. Optionally
filtered by [filter...] arguments (see \fIFILTER STATEMENTS\fR below).
.RE
.PP
.B list
<subcommand> [filter...]
.RS 4
Print information defined by <subcommand> in a tabular form. Optionally
filtered by [filter...] arguments (see \fIFILTER STATEMENTS\fR
below).
.PP
Available subcommands:
.TP 11
.B snapshots
All snapshots (and corresponding backups).
.PD 0
.TP 11
.B backups
All backups (and corresponding snapshots).
.TP 11
.B latest
Most recent snapshots and backups.
.TP 11
.B config
Configured source/snapshot/target relations.
.TP 11
.B source
Configured source/snapshot relations.
.TP 11
.B volume
Configured volume sections.
.TP 11
.B target
Configured targets.
.PD
.PP
Use the \fI\-\-format\fR command line option to switch between
different output formats.
.RE
.PP
.B clean
[filter...]
.RS 4
Delete incomplete (garbled) backups. Incomplete backups can be left
behind on network errors or kill signals while a send/receive
operation is ongoing, and are identified by the "received_uuid" flag
not being set on a target (backup) subvolume.
.RE
.PP
.B usage
[filter...]
.RS 4
Print filesystem usage information for all source/target
volumes. Optionally filtered by [filter...] arguments (see \fIFILTER
STATEMENTS\fR below).
.RE
.PP
.B origin
<subvolume>
.RS 4
Print origin information for the given backup subvolume, showing the
parent-child relationship as well as the received-from information.
.RE
.PP
.B diff
<from> <to>
.RS 4
Print new files since subvolume <from> for subvolume <to>.
.RE
.PP
.B config
print|print-all
.RS 4
Prints the parsed configuration file. Use the \fI\-\-format\fR command
line option to switch between different output formats.
.RE
.SH FILTER STATEMENTS
Filter arguments are accepted in form:
.PP
[hostname:]<volume-directory>
.RS 4
Matches all subvolumes and targets of a \fIvolume\fR configuration
section.
.RE
.PP
[hostname:]<volume-directory>/<subvolume-name>
.RS 4
Matches the specified subvolume and all targets of a \fIsubvolume\fR
configuration section.
.RE
.PP
[hostname:]<target-directory>
.RS 4
Matches all targets of a \fItarget\fR configuration section.
.RE
.PP
[hostname:]<target-directory>/<snapshot-name>
.RS 4
Matches a single target of a \fItarget\fR section within a
\fIsubvolume\fR section with given <snapshot-name>.
.RE
.PP
<group-name>
.RS 4
Matches the \fIgroup\fR configuration option of a \fIvolume\fR,
\fIsubvolume\fR or \fItarget\fR section.
.RE
.PP
For convenience, [hostname:] can be specified as either "hostname:" or
"ssh://hostname/".
.SH FILES
.PP
/etc/btrbk.conf
.br
/etc/btrbk/btrbk.conf
.RS 4
Default configuration file. The file format and configuration options
are described in
.BR btrbk.conf (5).
.RE
.PD
.SH EXIT STATUS
\fBbtrbk\fR returns the following error codes:
.IP "0" 4
No problems occurred.
.IP "1" 4
Generic error code.
.IP "2" 4
Parse error: when parsing command-line options or configuration file.
.IP "10" 4
Backup abort: At least one backup task aborted.
.IP "255" 4
Script error.
.SH AVAILABILITY
Please refer to the btrbk project page
\fBhttp://www.digint.ch/btrbk/\fR for further
details.
.SH SEE ALSO
.BR btrbk.conf (5),
.BR btrfs (1)
.PP
For more information about btrfs and incremental backups, see the web
site at https://btrfs.wiki.kernel.org/index.php/Incremental_Backup
.SH AUTHOR
Axel Burri <axel@tty0.ch>

533
doc/btrbk.1.asciidoc Normal file
View File

@ -0,0 +1,533 @@
btrbk(1)
========
:date: 2023-03-25
:release-version: 0.32.6
:man manual: Btrbk Manual
:man source: Btrbk {release-version}
NAME
----
btrbk - backup tool for btrfs subvolumes
SYNOPSIS
--------
[verse]
btrbk [-h|--help] [--version]
[-c|--config <file>] [-n|--dry-run] [--exclude <filter>]
[-p|--preserve] [--preserve-snapshots] [--preserve-backups]
[-v|--verbose] [-q|--quiet] [-l|--loglevel <level>]
[-t|--table] [-L|--long] [-1|--single-column]
[--format <output-format>] [--pretty]
[-S|--print-schedule] [--progress]
[--lockfile <file>]
[--override <config_option>=<value>]
<command> [[--] <filter>...]
DESCRIPTION
-----------
*btrbk* is a backup tool for btrfs subvolumes, taking advantage of
btrfs specific capabilities to create atomic snapshots and transfer
them incrementally to a target btrfs filesystem. It is able to perform
backups from one source to multiple destinations.
For most operations, *btrbk* requires 'root privileges' to run
correctly. Alternatively, consider using "btrfs-progs-sudo" or
"btrfs-progs-btrbk" backends, both of which allows you to run btrbk as
a regular user. Refer to configuration option 'backend' in
btrbk.conf(5) for more details.
=== Snapshots and Backups
Snapshots as well as backup subvolumes are created in the form:
<snapshot-name>.<timestamp>[_N]
Where '<snapshot-name>' is identical to the source subvolume name,
unless the configuration option 'snapshot_name' is set. '<timestamp>'
is a timestamp describing the creation time (local time of the host
running btrbk) of the snapshot/backup. The format can be configured
using the 'timestamp_format' option, refer to btrbk.conf(5) for
details. If multiple snapshots/backups are created on the same
date/time, 'N' will be incremented on each snapshot, starting at 1.
If a snapshot or backup does not match the naming scheme above
(e.g. if it has been renamed manually), btrbk will leave it untouched.
Note that in btrfs terminology, a 'snapshot' is a ``subvolume with
a given initial content of the original subvolume'' (showing a
parent-uuid, see btrfs-subvolume(8)), and they can be read-write
(default) or read-only. In btrbk terminology, 'snapshot' means
``read-only btrfs snapshot'', and 'backup' means ``read-only subvolume
created with send/receive'' (showing a received-uuid).
OPTIONS
-------
-h, --help::
Prints the synopsis and a list of the commands.
--version::
Prints the btrbk version.
-c, --config <file>::
Read the configuration from <file>.
-n, --dry-run::
Don't run anything that would alter the filesystem, just show the
snapshots and backup subvolumes that would be created/deleted by
the *run*, *snapshot*, *resume*, *prune*, *archive* and *clean*
commands. Use in conjunction with '-l debug' to see the btrfs
commands that would be executed.
--exclude <filter>::
Exclude configured sections matching '<filter>' (see
<<_filter_statements,FILTER STATEMENTS>> below), or any specific
snapshot from being backuped or deleted, or any specific backup
from being deleted.
+
Note that excluding specific snapshots from being backuped has impact
on scheduling: e.g. if the "first snapshot of the day" is excluded,
the "second snapshot of the day" shifts to "first", creating a backup
as "first backup of the day".
-p, --preserve::
Preserve all snapshots and backups. Skips deletion of any
snapshots and backups, even if specified in the configuration file
(shortcut for "--preserve-snapshots --preserve-backups").
--preserve-snapshots::
Preserve all snapshots. Skips deletion of any snapshots, even if
specified in the configuration file.
--preserve-backups::
Preserve all backups. Skips deletion of any backups, even if
specified in the configuration file.
--wipe::
Ignore configured snapshot retention policy, delete all but the latest
snapshots instead. All snapshots needed for incremental backup
(latest common) are also preserved. Useful if you are getting low
on disk space (ENOSPC).
-v, --verbose::
Increase the logging level, see "--loglevel".
-q, --quiet::
Quiet operation. If set, btrbk does not print the summary after
executing the *run*, *snapshot*, *resume*, *prune*, or *archive*
commands.
-l, --loglevel <level>::
Set the level of verbosity for the stderr logging. Accepted levels
are: error, warn, info, debug, and trace. Default is info.
-t, --table::
Print output in table format (shortcut for "--format=table").
-L, --long::
Print output in long table format (shortcut for "--format=long").
-1, --single-column::
Print output as single column (not available for all commands).
--format table|long|raw|col:[h:]<columns>::
Print output in specified format. If set to "raw", prints
space-separated, quoted key=value pairs (machine readable).
+
If set to "col:", prints only the <columns> specified (comma-separated
list). Header lines are omitted if the "h:" modifier is present.
Columns prefixed with "-" are collapsed if empty. Columns postfixed
with ":RALIGN" are right-aligned.
--pretty::
Print table output with lowercase, underlined column headings
(instead of single-line uppercase headings).
-S, --print-schedule::
Print detailed scheduler information on *run*, *snapshot*,
*resume*, *prune* and *archive* commands. Use the '--format'
command line option to switch between different output formats.
--progress::
Show progress bar on send-receive operation. Requires "mbuffer"
command (version >= 20180505) installed on the host running btrbk.
--lockfile <file>::
Place an exclusive lock on <file> during program execution, using
flock(2). If the lock is held by another process, exit before
running any actions. Overrides configuration option
"lockfile". Ignored on dryrun ('-n', '--dry-run').
--override <config_option>=<value>::
Override a configuration option <config_option> with
<value>. Globally, for ALL contexts. Use with care!
COMMANDS
--------
=== Actions
The following commands are used to create snapshots and/or
backups. All actions can operate in dry-run mode ('-n', '--dry-run').
Use the '--format' command line option to switch between different
output formats.
See section RETENTION POLICY in *btrbk.conf*(5) for information on
configuring the retention policy.
*run* [filter...]::
Perform snapshot and backup operations as specified in the
configuration file. If the optional [filter...] arguments are
present, snapshots and backups are only performed for the
subvolumes/targets matching a filter statement (see
<<_filter_statements,FILTER STATEMENTS>> below).
+
*Step 0: Read Data*;;
Read information from the source and target btrfs filesystems in
order to perform sanity checks and identify parent/child and
received-from relationships.
+
*Step 1: Create Snapshots*;;
If the checks succeed, btrbk creates snapshots for the source
subvolumes specified in the configuration file, according to the
'snapshot_create' option.
+
*Step 2: Create Backups*;;
For each specified target, btrbk creates the backups as follows:
After comparing the backups to the source snapshots, btrbk
transfers all missing snapshots needed to satisfy the configured
target retention policy, incrementally from the latest common
parent subvolume found. If no common parent subvolume is found (or
if the 'incremental' option is set to ``no''), a full
(non-incremental) backup is created.
+
*Step 3: Delete Backups*;;
Unless the -p, --preserve or --preserve-backups option is set,
backup subvolumes that are not preserved by their configured
retention policy will be deleted. Note that the latest
snapshot/backup pair are always preserved, regardless of the
retention policy.
+
*Step 4: Delete Snapshots*;;
Unless the -p, --preserve or --preserve-snapshots option is set,
snapshots that are not preserved by their configured retention
policy will be deleted. Note that the latest snapshot (the one
created in step 1) as well as the latest snapshot/backup pair are
always preserved, regardless of the retention policy. If any
target is unreachable or has errors, all snapshots are preserved
in order not to break the incremental chain.
*dryrun* [filter...]::
Don't run any btrfs commands that would alter the filesystem, just
show the snapshots and backup subvolumes that would be
created/deleted by the *run* command. Use in conjunction with '-l
debug' to see the btrfs commands that would be executed.
*snapshot* [filter...]::
Snapshot only: skips backup creation and deletion (steps 2 and
3). Use in conjunction with -p, --preserve (or
--preserve-snapshots) if you also want to skip snapshot deletion
(step 4).
+
Note that snapshot deletion is skipped if the target is not
accessible, as it is still required in order to determine the latest
snapshot/backup pair (which is always preserved, regardless of the
retention policy).
*resume* [filter...]::
Resume backups: skips snapshot creation (step 1), transfers and
deletes snapshots/backups in order to satisfy their configured
retention policy. Use in conjunction with -p, --preserve,
--preserve-backups, --preserve-snapshots if you want to skip
backup and/or snapshot deletion (steps 3, 4).
*prune* [filter...]::
Prune snapshots and backups: skips snapshot and backup creation
(steps 1, 2), only deletes snapshots and backups in order to
satisfy their configured retention policy. Useful for cleaning the
disk after changing the retention policy. Use in conjunction with
--preserve-backups, --preserve-snapshots if you want to skip
backup or snapshot deletion (steps 3, 4).
+
Note that deletion is skipped if source or target is not accessible,
as it is still required in order to determine the latest
snapshot/backup pair (which is always preserved, regardless of the
retention policy).
*archive* <source> <target> [--raw]::
Recursively copy all subvolumes created by btrbk from <source> to
<target> directory, optionally rescheduled using
'archive_preserve_*' configuration options. Also creates directory
tree on <target>. Useful for creating extra archive copies
(clones) from your backup disks. Note that you can continue using
btrbk after swapping your backup disk with the archive disk.
+
If you want to use nested subvolumes on the target filesystem, you
need to create them by hand (e.g. by running "btrfs subvolume create
<target>/dir"). Check the output of --dry-run if unsure.
+
Note that this feature needs a *linux kernel >=4.4* to work correctly!
+
If '--raw' option is set, creates raw targets (experimental, see
btrbk.conf(5), TARGET TYPES).
*clean* [filter...]::
Delete incomplete (garbled) backups. Incomplete backups can be
left behind on network errors or kill signals while a send/receive
operation is ongoing, and are identified by the "received_uuid"
flag not being set on a target (backup) subvolume.
The following table gives a quick overview of the action commands and
resulting snapshot creation (S+), backup creation (B+), snapshot
deletion (S-), and backup deletion (B-):
ifdef::backend-docbook,backend-manpage[]
....
Command Option S+ B+ S- B-
--------------------------------------------
run x x x x
run --preserve x x
run --preserve-snapshots x x x
run --preserve-backups x x x
snapshot x x
snapshot --preserve x
resume x x x
resume --preserve x
resume --preserve-snapshots x x
resume --preserve-backups x x
prune x x
prune --preserve-snapshots x
prune --preserve-backups x
....
endif::backend-docbook,backend-manpage[]
ifndef::backend-docbook,backend-manpage[]
[cols="2*<m,4*^", options="header,autowidth,compact", style="monospaced"]
|=======
|Command |Option |S+ |B+ |S- |B-
|run | | x | x | x | x
|run |--preserve | x | x | |
|run |--preserve-snapshots | x | x | | x
|run |--preserve-backups | x | x | x |
|snapshot | | x | | x |
|snapshot |--preserve | x | | |
|resume | | | x | x | x
|resume |--preserve | | x | |
|resume |--preserve-snapshots | | x | | x
|resume |--preserve-backups | | x | x |
|prune | | | | x | x
|prune |--preserve-snapshots | | | | x
|prune |--preserve-backups | | | x |
|=======
endif::backend-docbook,backend-manpage[]
=== Informative Commands
The following commands are informative only, and will not alter the
file system.
*stats* [filter...]::
Print statistics of snapshot and backup subvolumes. Optionally
filtered by [filter...] arguments (see <<_filter_statements,FILTER
STATEMENTS>> below).
*list* <subcommand> [filter...]::
Print information defined by <subcommand> in a tabular
form. Optionally filtered by [filter...] arguments (see
<<_filter_statements,FILTER STATEMENTS>> below).
+
Available subcommands (default ``all''):
+
--
ifndef::backend-docbook,backend-manpage[]
[horizontal]
endif::backend-docbook,backend-manpage[]
*all*;; List all snapshots and backups created by btrbk.
*snapshots*;; List all snapshots created by btrbk.
*backups*;; List all backups (and correlated snapshots) created by
btrbk.
*latest*;; List most recent common snapshot/backup pair, or most
recent snapshot if no common found.
*config*;; List configured source/snapshot/target relations.
*source*;; List configured source/snapshot relations.
*volume*;; List configured volume sections.
*target*;; List configured targets.
--
+
Use the '--format' command line option to switch between different
output formats.
*usage* [filter...]::
Print filesystem usage information for all source/target volumes,
optionally filtered by [filter...] arguments (see
<<_filter_statements,FILTER STATEMENTS>> below). Note that the
"free" value is an estimate of the amount of data that can still
be written to the file system.
*origin* <subvolume>::
Print the subvolume origin tree: Shows the parent-child
relationships as well as the received-from information. Use the
'--format' command line option to switch between different output
formats.
*diff* <from> <to>::
List the modified files since generation (transid) of subvolume
<from> in subvolume <to>. Columns:
+
------------
SIZE file was modified for a total of SIZE bytes
COUNT file was modified in COUNT generations
FLAGS "+" file accessed at offset 0 (at least once)
"c" COMPRESS flag is set (at least once)
"i" INLINE flag is set (at least once)
------------
*extents* [diff] <subvolume>... [exclusive <subvolume>...]::
Print accurate disk space usage and diff based on extent data
(FIEMAP ioctl, slow!).
+
--
Subvolumes following the 'exclusive' keyword are added to a separate
set, and additional set-exclusive data is printed at the end of the
list. This gives a hint of how much data will be freed if deleting all
subvolumes in the set. Example:
btrbk extents diff /backup/data.* exclusive /backup/data.2010*
The EXCLUSIVE column shows the set-exclusive data of all other listed
(!) subvolumes (relative complement of block regions). Provided that
all related subvolumes (holding references to extents) are also
listed, this amount of disk space would be freed when deleting the
subvolume.
The DIFF column shows the data added to the previous subvolume
(relative complement of block regions).
If called with the '--related' option, btrbk also lists all related
subvolumes. This is not recommended for backups, as parent-uuid
relations break for received subvolumes as soon as an intermediate
subvolume is deleted.
Note that reading all extents is a disk-intensive task, expect long
execution times and high ram usage. Consider setting 'cache_dir'.
--
*ls* <path>|<url>...::
List all btrfs subvolumes below <path>. Use the '--format' command
line option to switch between different output formats. See
lsbtr(1).
*config* print|print-all::
Prints the parsed configuration file.
FILTER STATEMENTS
-----------------
Filter arguments are accepted in form:
<group-name>::
Matches the 'group' configuration option of 'volume', 'subvolume'
or 'target' sections.
<hostname>[:<port>]::
Matches the 'hostname' portion from '<url>' of 'volume' or
'target' sections.
<directory>|<url>::
Matches 'volume', 'subvolume' or 'target' sections by either
relative or absolute path (if starting with "/" or "ssh://" or
"<hostname>:/"), accepting wildcard character "*". Relative paths
are matched against the end of the pathname. Either:
+
--
<volume-directory>::
Matches 'volume' sections.
<volume-directory>/<subvolume-name>::
Matches 'subvolume' sections.
<volume-directory>/<snapshot-dir>/<snapshot-name>::
Matches 'subvolume' sections defining snapshots with the
configured 'snapshot_dir' and 'snapshot_name'.
<target-directory>::
Matches 'target' sections.
<target-directory>/<snapshot-name>::
Matches 'target' sections within 'subvolume' sections defining
snapshots with the configured 'snapshot_name'.
Accepted formats for '<url>' are:
ssh://<hostname>[:<port>]/<directory>
<hostname>:<directory>
--
Note that for *run* and *snapshot* commands, a filter matching a
'target' configuration section also enables snapshot creation of the
surrounding 'subvolume' section. If this is not desired, consider
running *snapshot* and *resume* commands separately.
Filter statements can match multiple times (e.g. on group as well as
host name). In such a case, all matches are processed.
FILES
-----
+/etc/btrbk.conf+::
+/etc/btrbk/btrbk.conf+::
Default configuration file. The file format and configuration
options are described in *btrbk.conf*(5).
EXIT STATUS
-----------
*btrbk* returns the following error codes:
ifndef::backend-docbook,backend-manpage[]
[horizontal]
endif::backend-docbook,backend-manpage[]
0:: No problems occurred.
1:: Generic error code.
2:: Parse error: when parsing command-line options or configuration
file.
3:: Lockfile error: if lockfile is present on startup.
10:: Backup abort: At least one backup task aborted.
255:: Script error.
AVAILABILITY
------------
Please refer to the btrbk project page *<https://digint.ch/btrbk/>*
for further details.
SEE ALSO
--------
*btrbk.conf*(5),
*btrfs*(8)
For more information about btrfs and incremental backups, see the web
site at https://btrfs.wiki.kernel.org/index.php/Incremental_Backup
AUTHOR
------
Axel Burri <axel@tty0.ch>

View File

@ -1,291 +0,0 @@
.TH "btrbk.conf" "5" "2016-02-02" "btrbk v0.22.2" ""
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.SH NAME
btrbk.conf \- btrbk configuration file
.SH SYNOPSIS
.B /etc/btrbk.conf
.br
.B /etc/btrbk/btrbk.conf
.SH DESCRIPTION
The btrbk configuration file specifies which btrfs subvolumes on the
filesystem are to be processed, what target subvolumes should be used
to create the backups, and where the snapshots should be
generated. The retention policy, as well as most other options can be
defined either globally or within a section.
.PP
The options specified always apply to the last section encountered,
superseding the values set in upper-level sections. This means that
global options must be set before any sections are defined.
.SH SECTIONS
.PP
\fBvolume\fR <volume-directory>|<url>
.RS 4
Directory of a btrfs volume containing the source subvolume(s) to be
backed up. \fI<volume-directory>\fR must be an absolute path and point
to a btrfs volume (or subvolume). Usually the mount point of a btrfs
filesystem mounted with the \fIsubvolid=0\fR option.
.RE
.PP
\fBsubvolume\fR <subvolume-name>
.RS 4
Subvolume to be backed up, relative to the \fI<volume-directory>\fR
specified in the \fIvolume\fR section. Multiple \fIsubvolume\fR
sections are allowed within \fIvolume\fR sections.
.RE
.PP
\fBtarget\fR <type> <target-directory>|<url>
.RS 4
Target type and directory where the backup subvolumes are to be
created. See the TARGET TYPES section for supported
\fI<type>\fR. Multiple \fItarget\fR sections are allowed within
\fIsubvolume\fR sections.
.RE
.PP
For the \fIvolume\fR and \fItarget\fR sections, you can specify a
ssh-url instead of a local directory. The syntax for \fI<url>\fR is:
.PP
.RS 4
.nf
ssh://host.xz/path/to/volume
.fi
.RE
.PP
Note that btrfs is very picky on file names (mainly for security
reasons), only the characters [0-9] [a-z] [A-Z] and "._+-@" are
allowed.
.RE
.SH OPTIONS
.PP
\fBtransaction_log\fR <file>
.RS 4
If set, all transactions (snapshot create, subvolume send-receive,
subvolume delete) as well as abort messages are logged to <file>, in a
space-separated table format.
.RE
.PP
\fBtimestamp_format\fR short|long
.RS 4
Timestamp format used as postfix for new snapshot subvolume names.
Defaults to \[lq]short\[rq].
.PP
.IP \fBshort\fR
YYYYMMDD[_N] (e.g. "20150825", "20150825_1")
.IP \fBlong\fR
YYYYMMDD<T>hhmm[_N] (e.g. "20150825T1531")
.PP
Note that a postfix "_N" is only appended to the timestamp if a
snapshot/backup already exists with the timestamp of current
date/time.
.RE
.PP
\fBsnapshot_dir\fR <directory>
.RS 4
Directory in which the btrfs snapshots are created, relative to
\fI<volume-directory>\fR of the \fIvolume\fR section. Note that btrbk
does not autmatically create this directory, and the snapshot creation
will fail if it is not present.
.RE
.PP
\fBsnapshot_name\fR <basename>
.RS 4
Base name of the created snapshot (and backup). This option is only
valid in the \fIsubvolume\fR section. Defaults to
\fI<subvolume-name>\fR.
.RE
.PP
\fBsnapshot_create\fR always|ondemand|onchange|no
.RS 4
If set to \[lq]ondemand\[rq], snapshots are only created if the target
subvolume is reachable (useful if you are tight on disk space and you
only need btrbk for backups to an external disk which is not always
connected). If set to \[lq]onchange\[rq], snapshots are only created
if the source subvolume has changed since the last snapshot (more
precisely: if the btrfs generation has been increased since the last
snapshot). If set to \[lq]always\[rq], snapshots are always
created. If set to \[lq]no\[rq], the snapshots are never created
(useful in conjunction with the \fIresume_missing\fR option if another
instance of btrbk is taking care of snapshot creation). Defaults to
\[lq]always\[rq].
.RE
.PP
\fBincremental\fR yes|no|strict
.RS 4
If set, incremental backups are created. If set to \[lq]strict\[rq],
non-incremental (initial) backups are never created. Defaults to
\[lq]yes\[rq].
.RE
.PP
\fBresume_missing\fR yes|no
.RS 4
If set, the backups in the target directory are compared to the source
snapshots, and missing backups are created if needed (complying to the
target preserve matrix). Defaults to \[lq]yes\[rq].
.RE
.PP
\fBtarget_preserve_daily\fR all|<number>
.RS 4
How many days of backups should be preserved. Defaults to \[lq]all\[rq].
.RE
.PP
\fBtarget_preserve_weekly\fR all|<number>
.RS 4
Defines for how many weeks back weekly backups should be
preserved. Every backup created at \fIpreserve_day_of_week\fR (or
the next backup in this week if none was made on the exact day) is
considered as a weekly backup. Defaults to \[lq]0\[rq].
.RE
.PP
\fBtarget_preserve_monthly\fR all|<number>
.RS 4
Defines for how many months back monthly backups should be
preserved. Every last weekly backup in a month is considered a
monthly backup. Defaults to \[lq]all\[rq].
.RE
.PP
\fBsnapshot_preserve_daily\fR
.PD 0
.PP
\fBsnapshot_preserve_weekly\fR
.PP
\fBsnapshot_preserve_monthly\fR
.RS 4
Defines retention policy for the snapshots, with same semantics as the
\fItarget_preserve_*\fR options.
.RE
.PD
.PP
\fBpreserve_day_of_week\fR monday|tuesday|...|sunday
.RS 4
Defines on what day a backup/snapshot is considered as a weekly
backup. Defaults to \[lq]sunday\[rq].
.RE
.PP
\fBgroup\fR <group-name>[,<group-name>]...
.RS 4
Add the current section (volume, subvolume or target) to a
user-defined group, which can be used as filter for several btrbk
commands.
.RE
.PP
\fBssh_identity\fR <file>
.RS 4
Absolute path to a ssh identity file (private key). Note that if the
private key is password protected, btrbk will prompt for user input,
which is usually not desired.
.RE
.PP
\fBssh_user\fR <username>
.RS 4
Remote username for ssh. Defaults to \[lq]root\[rq]. Note that you will
have to make sure that the remote user is able to run /sbin/btrfs
(which needs root privileges).
.RE
.PP
\fBssh_port\fR <port>
.RS 4
Port to connect to on the remote host. Defaults to \[lq]default\[rq]
(the port specified in \fIssh_config\fR, which defaults to 22).
.RE
.PP
\fBssh_compression\fR yes|no
.RS 4
Enables or disables the compression of ssh connections. Defaults to
\[lq]no\[rq].
.RE
.PP
\fBssh_cipher_spec\fR <cipher_spec>
.RS 4
Selects the cipher specification for encrypting the session
(comma-separated list of ciphers in order of preference). See the "-c
cipher_spec" option in ssh(1) for more information. Defaults to
\[lq]default\[rq] (the ciphers specified in \fIssh_config\fR).
.RE
.PP
\fBbtrfs_commit_delete\fR after|each|no
.RS 4
If set, make sure the deletion of snapshot and backup subvolumes are
committed to disk when btrbk terminates. Defaults to \[lq]no\[rq].
.RE
.PP
\fBbtrfs_progs_compat\fR yes|no \fI*experimental*\fR
.RS 4
Enable compatibility mode for btrfs-progs < 3.17 (\fIbtrfs
--version\fR). This option can be set either globally or within a
\fItarget\fR section. If enabled, the latest common snapshots are
determined by subvolume names instead of \fIreceived_uuid\fR, which
can lead to false guesses if the snapshot or target subvolumes are
manipulated by hand (moved, deleted).
.RE
.PP
Lines that contain a hash character (#) in the first column are
treated as comments.
.SH TARGET TYPES
.PP
\fBsend-receive\fR
.RS 4
Backup to a btrfs filesystem, using "btrfs send/receive". This is the
recommended (standard) target type. The \fI<target-directory>\fR must
be an absolute path and point to a btrfs volume (or subvolume). See
btrfs-send(8), btrfs-receive(8).
.RE
.PP
\fBraw\fR \fI*experimental*\fR
.RS 4
Backup to a raw (filesystem independent) file from the output of
btrfs-send(8), with optional compression and encryption.
.PP
Note that the target preserve mechanism is currently disabled for raw
backups (btrbk does not delete any raw files)!
.PP
Additional options for raw targets:
.PP
.RS 4
raw_target_compress gzip|bzip2|xz|no
.PD 0
.PP
raw_target_compress_level default|<number>
.PP
raw_target_compress_threads default|<number>
.PP
raw_target_encrypt gpg|no
.PP
gpg_keyring <file>
.PP
gpg_recipient <name>
.RE
.PD
.PP
Target file name syntax:
.PP
.RS 4
<snapshot-name>--<received_uuid>[@<parent_uuid>].btrfs[.gz|.bz2|.xz][.gpg]
.RE
.PP
The <parent_uuid> is only set on \fIincremental\fR backups, and points
to the <received_uuid> of the previous backup in a incremental backup
chain.
.PP
For \fIincremental\fR backups ("incremental yes"), please note that:
.IP 1. 4
As soon as a single \fIincremental\fR backup file is lost or
corrupted, all later incremental backups become invalid, as there is
no common parent for the subsequent incremental images anymore. This
might be a good compromise for a vacation backup plan, but for the
long term make sure that a non-incremental backup is triggered from
time to time.
.IP 2. 4
There is currently no support for rotation of incremental backups: if
\fIincremental\fR is set, a full backup must be triggered manually
from time to time in order to be able to delete old backups.
.RE
.SH AVAILABILITY
Please refer to the btrbk project page
\fBhttp://www.digint.ch/btrbk/\fR for further
details.
.SH SEE ALSO
.BR btrbk (1)
.SH AUTHOR
Axel Burri <axel@tty0.ch>

705
doc/btrbk.conf.5.asciidoc Normal file
View File

@ -0,0 +1,705 @@
btrbk.conf(5)
=============
:date: 2023-03-25
:release-version: 0.32.6
:man manual: Btrbk Manual
:man source: Btrbk {release-version}
NAME
----
btrbk.conf - btrbk configuration file
SYNOPSIS
--------
[verse]
/etc/btrbk.conf
/etc/btrbk/btrbk.conf
DESCRIPTION
-----------
The btrbk configuration file specifies which btrfs subvolumes on the
filesystem are to be processed, what target subvolumes should be used
to create the backups, and where the snapshots should be
generated. The retention policy, as well as most other options can be
defined either globally or within a section.
The options specified always apply to the last section encountered,
superseding the values set in upper-level sections. This means that
global options must be set before any sections are defined.
Blank lines are ignored. A hash character (#) starts a comment
extending until end of line.
SECTIONS
--------
*volume* <volume-directory>|<url> (optional)::
Absolute path pointing to a btrfs file system containing the
source subvolume(s) to be backed up. Usually the mount point of a
btrfs filesystem mounted with the 'subvolid=5' option.
*subvolume* <subvolume-name>::
Subvolume to be backed up, relative to the '<volume-directory>' of
the 'volume' section, or absolute if the 'volume' section is
omitted. Accepts wildcard character "*".
+
--
Note that if this subvolume is btrfs root (id=5), it needs to have a
valid UUID, which is not the case for file systems created with
btrfs-progs < 4.16.
--
*target* [send-receive|raw] <target-directory>|<url>::
Target directory where the backup subvolumes are to be
created. The optional target type defaults to ``send-receive'',
see <<_target_types,TARGET TYPES>> below for details.
+
--
Multiple 'target' sections are allowed, in any context: a 'target'
defined in 'volume' or global context will be used for all underlying
'subvolume' sections (hint: run "btrbk list" or "btrbk config print"
to see the resulting configuration).
--
If a '<url>' is specified, btrbk actions (shell commands) are executed
remotely via ssh, using the <<_ssh_options,SSH Options>> described
below. Accepted formats are:
ssh://<hostname>[:<port>]/<directory>
<hostname>:<directory>
Where '<hostname>' is either a host name, an IPv4 address in
dotted-decimal form, or an IP literal encapsulated within square
brackets (e.g. "[2001:db8::7]").
If you are connecting to virtual machines, consider configuring
several 'volume' sections for a '<hostname>', with distinct '<port>'
numbers for each machine.
OPTIONS
-------
The options described here can be specified in 'global context' as
well as 'volume', 'subvolume' and 'target' sections, unless stated
otherwise.
=== Basic Options
*timestamp_format* short|long|long-iso::
Timestamp format used as postfix for new snapshot subvolume
names. Defaults to ``long''.
+
--
ifndef::backend-docbook,backend-manpage[]
[horizontal]
endif::backend-docbook,backend-manpage[]
*short*;; +YYYYMMDD[_N]+ (e.g. "20150825", "20150825_1")
*long*;; +YYYYMMDD<T>hhmm[_N]+ (e.g. "20150825T1531")
*long-iso*;; +YYYYMMDD<T>hhmmss&plusmn;hhmm[_N]+ (e.g. "20150825T153123+0200")
--
+
Note that a postfix "_N" is appended to the timestamp if a snapshot or
backup already exists with the timestamp of current date/time.
+
Use ``long-iso'' if you want to make sure that btrbk never
creates ambiguous time stamps (which can happen if multiple
snapshots are created during a daylight saving time clock
change).
+
Note that using ``long-iso'' has implications on the scheduling, see
<<_reference_time,Reference Time>> below.
*snapshot_dir* <directory>::
Directory in which the btrfs snapshots are created, relative to
'<volume-directory>' of the 'volume' section, or absolute if the
'volume' section is omitted. Note that btrbk does not
automatically create this directory, and the snapshot creation
will fail if it is not present.
*snapshot_name* <basename>::
Base name of the created snapshot (and backup). This option is
only valid in the 'subvolume' section. Defaults to
'<subvolume-name>'.
*snapshot_create* always|onchange|ondemand|no::
If set to ``always'', snapshots are always created. If set to
``onchange'', snapshots are only created if the last snapshot is
not up-to-date, i.e. the source subvolume has changed (more
precisely: the btrfs generation has been increased) since the last
snapshot was created. If set to ``ondemand'', snapshots are only
created if at least one target subvolume is reachable (useful if
you are tight on disk space and you only need btrbk for backups to
an external disk which is not always connected). If set to ``no'',
the snapshots are never created (useful if another instance of
btrbk is taking care of snapshot creation). Defaults to
``always''.
*incremental* yes|no|strict::
If set, incremental backups are created. If set to ``strict'',
non-incremental (initial) backups are never created, and
incremental backups are restricted to 'related parents' (by
parent-uuid relationship). Defaults to ``yes''.
+
--
Note that even if the parent-uuid chain is broken, snapshots and
backups can still share data (which is especially true for backups
created with 'incremental' option enabled), and are perfectly suitable
as parents for incremental send-receive operations. But as btrbk can
not be certain about this, such operations are disallowed in
"incremental strict" mode.
--
*noauto* yes|no::
If set, the context is skipped by all btrbk actions unless
explicitly enabled by a matching btrbk '<filter>' command line
argument (e.g. "btrbk run myfilter").
=== Grouping Options
*group* <group-name> [<group-name>]...::
Add the current section (volume, subvolume or target) to
user-defined groups, which can be used as filter for most btrbk
commands (see btrbk(1) FILTER STATEMENTS). This option can be set
multiple times within the same context.
=== Retention Policy Options
*preserve_day_of_week* monday|tuesday|...|sunday::
Defines on what day a snapshot/backup is considered to be a
"weekly" backup. Weekly, monthly and yearly backups are preserved
on this day of week (see <<_retention_policy,RETENTION POLICY>>
below). Defaults to ``sunday''.
*preserve_hour_of_day* [0..23]::
Defines after what time (in full hours since midnight) a
snapshot/backup is considered to be a "daily" backup. Daily,
weekly, monthly and yearly backups are preserved on this hour (see
<<_retention_policy,RETENTION POLICY>> below). Ignored on
snapshots or backups without time information ('timestamp_format
short'). Defaults to ``0''.
*snapshot_preserve* no|<retention_policy>::
Set retention policy for snapshots (see
<<_retention_policy,RETENTION POLICY>> below). If set to ``no'',
preserve snapshots according to 'snapshot_preserve_min'
only. Defaults to ``no''.
+
--
Note that 'snapshot_preserve' has no effect if 'snapshot_preserve_min'
is set to ``all'' (the default).
--
*snapshot_preserve_min* all|latest|<number>{h,d,w,m,y}::
Preserve all snapshots for a minimum amount of hours (h), days
(d), weeks (w), months (m) or years (y), regardless of how many
there are. If set to ``all'', preserve all snapshots forever. If
set to ``latest'', preserve latest snapshot. Defaults to ``all''.
*target_preserve* no|<retention_policy>::
Set retention policy for backups (see
<<_retention_policy,RETENTION POLICY>> below). If set to ``no'',
preserve backups according to 'target_preserve_min' only. Defaults
to ``no''.
+
--
Note that 'target_preserve' has no effect if 'target_preserve_min' is
set to ``all'' (the default).
--
*target_preserve_min* all|latest|no|<number>{h,d,w,m,y}::
Preserve all backups for a minimum amount of hours (h), days (d),
weeks (w), months (m) or years (y), regardless of how many there
are. If set to ``all'', preserve all backups forever. If set to
``latest'', always preserve the latest backup (useful in
conjunction with "target_preserve no", if you want to keep the
latest backup only). If set to ``no'', only the backups following
the 'target_preserve' policy are created. Defaults to ``all''.
*archive_preserve* no|<retention_policy>::
Set retention policy for archives ("btrbk archive" command), with
same semantics as 'target_preserve'.
*archive_preserve_min* all|latest|no|<number>{h,d,w,m,y}::
Set retention policy for archives ("btrbk archive" command), with
same semantics as 'target_preserve_min'.
*archive_exclude* <pattern>::
Exclude subvolumes matching <pattern> from archiving. The pattern
accepts wildcard character "*", and is matched against the end of
the pathname.
=== SSH Options
*ssh_identity* <file>|no::
Absolute path to a ssh identity file (private key). If not set,
the ssh default is used (see ssh(1), "-i identity_file"). Note
that if the identity key is password protected and no
authentication agent is used, btrbk will prompt for user input on
every connection attempt.
*ssh_user* <username>|no::
Remote username for ssh. Defaults to ``root''. Make sure the
remote user is able to run "btrfs" with root privileges (see
option 'backend' for details). If set to ``no'', the ssh default
is used.
*ssh_compression* yes|no::
Enables or disables the compression of ssh connections. Defaults
to ``no''. Note that if *stream_compress* is enabled, ssh
compression will always be disabled for send/receive operations.
*ssh_cipher_spec* default|<cipher_spec>::
Selects the cipher specification for encrypting the session
(comma-separated list of ciphers in order of preference). See the
"-c cipher_spec" option in ssh(1) for more information. Defaults
to ``default'' (the ciphers specified in ssh_config(5)).
=== Data Stream Options
*stream_compress* <compress_command>|no::
Compress the btrfs send stream before transferring it from/to
remote locations. Defaults to ``no''. If enabled, make sure that
'<compress_command>' is available on the source and target
hosts. Supported '<compress_command>': gzip, pigz, bzip2, pbzip2,
bzip3, xz, lzo, lz4, zstd.
*stream_compress_level* default|<number>::
Compression level for the specified '<compress_command>'. Refer to
the related man-page for details (usually [1..9], where 1 means
fastest compression). Defaults to ``default'' (the default
compression level of '<compress_command>').
*stream_compress_long* default|<number>::
Enable long distance matching for the specified
'<compress_command>'. Refer to the related man-page for details.
Only supported for "zstd".
*stream_compress_threads* default|<number>::
Number of threads to use for <compress_command>. Only supported
for "pigz", "pbzip2", "bzip3", "zstd" and recent versions of "xz".
*stream_compress_adapt* yes|no::
Enable adaptive compression for <compress_command>. Only supported
for "zstd" (version >= 1.3.6). Defaults to ``no''.
*stream_buffer* <size>|no::
Add a buffer to the btrfs send stream (locally, on uncompressed
data), with a maximum size of '<size>'. This can give a speed
improvement (measured up to 20%) on both local or remote
operations, but also increases system load. A suffix of "k", "m",
"g", or "%" can be added to '<size>' to denote kilobytes (*1024),
megabytes, gigabytes, or a percentage of total physical
memory. Defaults to ``no''.
+
--
If enabled, make sure that the "mbuffer" command (at least version
20180505) is available on the host running btrbk. As of btrbk-0.29.0,
mbuffer(1) is used for both 'rate_limit' and 'stream_buffer' options:
mbuffer [-m <stream_buffer>] [-r <rate_limit>]
Note that mbuffer(1) always reads defaults from "`/etc/mbuffer.rc"`
and "`~/.mbuffer.rc`".
Leave this option disabled if your main concern is a stable backup
process: while recent versions of mbuffer have proven reliable, it is
often desirable to keep things simple rather than adding an
additional, multi-threaded process to the command pipe.
--
*stream_buffer_remote* <size>|no::
Add a buffer on remote hosts (either source or target). Defaults
to ``no''.
+
--
Enable this if you prefer buffering on the remote side, or even on
both sides: reasons for this depend on available memory, disk and cpu
performance (btrfs send/receive, compression), as well as networking
constraints.
--
*rate_limit* <rate>|no::
Limit the read rate of the btrfs send stream to '<rate>' bytes per
second (locally, on uncompressed send stream). A suffix of "k",
"m", "g", or "t" can be added to denote kilobytes (*1024),
megabytes, and so on. Defaults to ``no''. Note that 'rate_limit'
implicitly adds a stream buffer (see 'stream_buffer' option
above).
*rate_limit_remote* <rate>|no::
Add rate limit on remote hosts (either source or target). Defaults
to ``no''. Note that it usually does not make much sense to enable
both 'rate_limit' and 'rate_limit_remote'.
=== System Options
*transaction_log* <file>|no::
If set, all transactions (snapshot create, subvolume send-receive,
subvolume delete) as well as abort messages are logged to <file>,
in a space-separated table format: "localtime type status
target_url source_url parent_url message".
*transaction_syslog* <facility>|no::
If set, all transactions (as described in 'transaction_log' above)
are logged to syslog. The program name used in the messages is
"btrbk". Accepted parameters for '<facility>': user, mail,
daemon, auth, lpr, news, cron, authpriv, local0..local7.
*lockfile* <file>|no::
Place an exclusive lock on <file> during program execution, using
flock(2). If the lock is held by another process, exit before
running any actions. Ignored on dryrun ('-n', '--dry-run'). See
also '--lockfile' command-line option.
*backend* <backend>::
Backend filesystem utilities to be used for btrfs specific
operations. Available backends:
+
--
*btrfs-progs*::
Default backend, btrfs commands are called as specified in
btrfs(8) (e.g. "btrfs subvolume show").
*btrfs-progs-btrbk*::
btrfs commands are separated by a dash instead of a whitespace
(e.g. "btrfs-subvolume-show" instead of "btrfs subvolume
show"). Useful for setting suid or file capabilities (setcap) on
specific btrfs commands, as implemented in
<https://github.com/digint/btrfs-progs-btrbk>.
*btrfs-progs-sudo*::
btrfs commands are prefixed with "sudo -n" (e.g. "sudo -n btrfs
subvolume show" instead of "btrfs subvolume show"). Make sure to
have appropriate (root) permissions for the "btrfs" command groups
as well as the "readlink" and "test" commands in /etc/sudoers.
*btrfs-progs-doas*::
Similar to btrfs-progs-sudo, using prefix "doas -n".
If you want to set this option for local or remote hosts only, set
*backend_local* or *backend_remote* (e.g. "backend_remote
btrfs-progs-btrbk").
If you want to set this option for regular (non-root) user only, set
*backend_local_user*.
--
*compat* <compat-option>...::
Enable compatibility options. Available 'compat-option':
+
--
*busybox*::
Use busybox compatible commands, at the expense of slight overhead
while reading filesystem information.
*ignore_receive_errors* _*experimental*_::
Tell btrfs-receive(8) to not terminate on errors by setting
"--max-errors=0" option. Print warnings instead.
+
A known use case for this are target hosts lacking xattr support
(e.g. some Synology NAS), while the send-stream contains "lsetxattr"
commands. Another case is targets failing to set otime, complaining
with "ERROR: attribute 12 requested but not present".
+
Note that there is *no guarantee that backups created with this
option enabled can be restored at all*.
If you want to set this option for local or remote hosts only, set
*compat_local* or *compat_remote* (e.g. "compat_remote busybox").
--
*cache_dir* <directory>::
If set, cache extent maps for the "btrbk extents" command.
=== Btrfs Specific Options
*incremental_prefs* <list-spec>[:<amount>]...::
Specify the preferences to determine the best common (correlated)
parent and clone sources for incremental backups, by choosing from
predefined candidate lists.
+
--
The 'list-spec' defines from what candidate list the next
parent/clone-src should be appended to a result list; 'amount' defines
how many (e.g. "sro:1 sro:1" is identical to "sro:2"), or all if
omitted. Any candidate which is already in the results is dropped.
The resulting list of subvolumes is then used as parameters for the
btrfs-send(8) command: the first for "-p <parent>", all others for
"-c <clone-src>".
Available 'list-spec' (candidate lists = filtered subsets of
correlated subvolumes):
*sro*,*srn*:: All from 'snapshot_dir' matching 'snapshot_name', with
parent_uuid relationship, sorted by btrbk timestamp (o=older
n=newer).
*sao*,*san*:: All from 'snapshot_dir' matching 'snapshot_name', sorted
by btrbk timestamp (o=older n=newer).
*aro*,*arn*:: All from 'incremental_resolve', with parent_uuid
relationship, sorted by cgen (o=older n=newer).
Defaults to "sro:1 srn:1 sao:1 san:1 aro:1 arn:1". Note that for
most operations the default resolves a single parent, as there usually
are no newer snapshots, and all "sro:1 sao:1 aro:1" resolve to the
same snapshot.
Example: "defaults,sao,san,aro,arn" takes the defaults, and adds clone
sources for all (!) known candidates on the filesystem.
--
*incremental_clones* yes|no::
If enabled, btrbk adds "-c <clone-src>" to the btrfs-send(8)
command for all correlated subvolumes resolved by
'incremental_prefs'. If disabled, only "-p <parent>" is
used. Defaults to ``yes''.
*incremental_resolve* mountpoint|directory::
Specifies where to search for the best common parent for
incremental backups. If set to ``mountpoint'', use parents in the
filesystem tree below the mount point of the snapshot and target
directory. If set to ``directory'', use parents strictly below
snapshot/target directories. Set this to ``directory'' if you get
access problems (when not running btrbk as root). Defaults to
``mountpoint''.
*btrfs_commit_delete* yes|no::
If set, wait for the transaction commit at the end of each
snapshot or backup deletion (sets '--commit-each' option for
"btrfs subvolume delete"). Defaults to ``no''.
*send_protocol* <number>|no _*experimental*_::
Use btrfs send protocol version N. If enabled on 'target', btrbk
adds "--proto <number>" to the btrfs-send(8) command. Defaults to
``no'' (btrfs default).
*send_compressed_data* yes|no _*experimental*_::
Send data that is compressed on the filesystem directly without
decompressing it. This requires protocol version 2 or higher
(btrfs-progs >= 5.19), and implies "send_protocol 2". If enabled
on 'target', btrbk adds "--compressed-data" to the btrfs-send(8)
command. Defaults to ``no'' (btrfs default).
*snapshot_qgroup_destroy* yes|no _*experimental*_:: {blank}
*target_qgroup_destroy* yes|no _*experimental*_:: {blank}
*archive_qgroup_destroy* yes|no _*experimental*_::
Whenever a subvolume is deleted, also destroy corresponding
default qgroup "+0/<subvol-id>+". Only useful if you have enabled
btrfs quota support. See also:
<https://bugzilla.kernel.org/show_bug.cgi?id=91751>
=== Informative Options
*warn_unknown_targets* yes|no::
If set, prints a warning if btrbk encounters a target subvolume at
a unknown location (i.e. not following btrbk naming scheme, or
outside the target directory). Defaults to ``no''.
RETENTION POLICY
----------------
Retention policies are defined individually for snapshots, backups and
archives (summarized as "backups" in the following text), using a
combination of:
**_preserve_min* all|latest|no|<number>{h,d,w,m,y}::
Amount of time (duration) in which all backups are preserved.
**_preserve* no|<retention_policy>::
Schedule (single points in time) for which individual backups are
preserved.
Note that if "preserve_min" is set to ``all'' (the default), any
setting of "preserve" obviously has no effect.
The format for '<retention_policy>' is:
[<hourly>h] [<daily>d] [<weekly>w] [<monthly>m] [<yearly>y]
*hourly*::
Defines how many hours back hourly backups should be
preserved. The first backup of an hour is considered an hourly
backup.
*daily*::
Defines how many days back daily backups should be preserved. The
first backup of a day (starting at 'preserve_hour_of_day') is
considered a daily backup.
*weekly*::
Defines how many weeks back weekly backups should be
preserved. The first daily backup created at
'preserve_day_of_week' (or the first backup in this week if none
was made on the exact day) is considered as a weekly backup.
*monthly*::
Defines how many months back monthly backups should be
preserved. Every first weekly backup in a month is considered a
monthly backup.
*yearly*::
Defines for how many years back yearly backups should be
preserved. Every first monthly backup in a year is considered a
yearly backup.
Use an asterisk for ``all'' (e.g. "target_preserve 60d *m"
states: "preserve daily backups for 60 days back, and all monthly
backups").
Hint: Run btrbk with the '-S', '--print-schedule' option to get a
comprehensive output of the scheduler results.
=== Reference Time
The local time on the host running btrbk defines the reference time
for all date/time calculations, especially for "beginning of a day",
and as a consequence for the first daily, weekly, monthly or yearly
backups. The local time on remote hosts (ssh source/target) is never
used.
Unless "timestamp_format long-iso" is set, daily backups are preserved
at "preserve_hour_of_day" (defaults to midnight) of the respective
time zone (and not for "00:00 UTC", which would be "14:00" in
Honolulu). This becomes relevant for setups with multiple btrbk
instances, e.g. many snapshot-only instances (spread around the
world), and a fetch-only instance on the backup server.
Caveat:
* If "timestamp_format long-iso" is set, each btrbk instance on has a
different interpretation of "first in day". Make sure to run btrbk
with the same time zone on every host, e.g. by setting the TZ
environment variable (see tzset(3)).
TARGET TYPES
------------
*send-receive*::
Backup to a btrfs filesystem, using "btrfs send/receive". This is
the recommended (standard) target type. The '<target-directory>'
must be an absolute path and point to a subvolume or directory
within a btrfs file system. See btrfs-send(8), btrfs-receive(8).
*raw* _*experimental*_::
Backup to a raw (filesystem independent) file from the output of
btrfs-send(8), with optional compression and encryption.
+
--
Raw backups consist of two files: the main data file containing the
btrfs send stream, and a sidecar file ".info" containing metadata:
<snapshot-name>.<timestamp>[_N].btrfs[.gz|.bz2|...][.gpg]
<snapshot-name>.<timestamp>[_N].btrfs[.gz|.bz2|...][.gpg].info
For 'incremental' backups ("incremental yes"), please note that:
* As soon as a single 'incremental' backup file is lost or corrupted,
all later incremental backups become invalid, as there is no common
parent for the subsequent incremental images anymore. This might be
a good compromise for a vacation backup plan, but for the long term
make sure that a non-incremental backup is triggered from time to
time.
* The scheduler will never delete dependent parents of backups
preserved by the retention policy (run btrbk with the '-S',
'--print-schedule' option to get a comprehensive output of the
scheduler results).
* There is currently no support for rotation of incremental backups:
if 'incremental' is set, a full backup must be triggered manually
from time to time in order to be able to delete old backups.
Additional options for raw targets:
*raw_target_compress* <compress_command>|no::
Compression algorithm to use for raw backup target. Supported
'<compress_command>': gzip, pigz, bzip2, pbzip2, bzip3, xz, lzo,
lz4, zstd.
*raw_target_compress_level* default|<number>::
Compression level for the specified <compress_command>.
*raw_target_compress_long* default|<number>::
Enable long distance matching for the specified
'<compress_command>'.
*raw_target_compress_threads* default|<number>::
Number of threads to use for <compress_command>.
*raw_target_split* <size>|no::
Split the raw backup file into pieces of size '<size>'.
*raw_target_block_size* <number>::
Block size to use for writing the raw backup file. Defaults to
``128K''.
*raw_target_encrypt* gpg|openssl_enc|no::
If enabled, encrypt the target raw file using gpg or openssl_enc.
Additional options for "raw_target_encrypt gpg":
*gpg_keyring* <file>::
Keyring to use for gpg, e.g. "`/etc/btrbk/gpg/pubring.kbx`".
*gpg_recipient* <name>...::
Encrypt for user id '<name>' (email address).
Additional options for "raw_target_encrypt openssl_enc" ('very
experimental'):
*openssl_ciphername*{nbsp}<name>::
Defaults to ``aes-256-cbc''.
*openssl_iv_size* <size-in-bytes>|no::
Depends on selected cipher.
*openssl_keyfile* <file>|no::
Point to a key file in hex (absolute path). Example key file
creation (256bit key):
+
------------
# dd if=/dev/urandom bs=1 count=32 \
| od -x -A n \
| tr -d "[:space:]" > /path/to/keyfile
------------
*kdf_backend* <file>|no::
KDF backend to be executed,
e.g. "`/usr/share/btrbk/scripts/kdf_pbkdf2.py`".
*kdf_keysize* <size-in-bytes>::
Defaults to ``32''.
*kdf_keygen* once|each::
Defaults to ``once''.
--
AVAILABILITY
------------
Please refer to the btrbk project page *<https://digint.ch/btrbk/>*
for further details.
SEE ALSO
--------
*btrbk*(1)
AUTHOR
------
Axel Burri <axel@tty0.ch>

68
doc/install.md Normal file
View File

@ -0,0 +1,68 @@
Installation
============
Btrbk is a single perl script, and does not require any special
installation procedures or libraries. In order to install the btrbk
executable along with the documentation and an example configuration
file, choose one of the following methods:
### Generic Linux System
Install [asciidoctor] or [asciidoc] if you want to build the
documentation.
Download and unpack the latest [btrbk source tarball] and type:
sudo make install
#### Try latest master from Github:
wget https://raw.githubusercontent.com/digint/btrbk/master/btrbk
chmod +x btrbk
sudo ./btrbk ls /
### Debian Based Distros
btrbk is in debian stable (utils): https://packages.debian.org/stable/utils/btrbk
Packages are also available via NeuroDebian: http://neuro.debian.net/pkgs/btrbk.html
### Fedora Linux
btrbk is in the official Fedora repos: https://src.fedoraproject.org/rpms/btrbk
sudo dnf install btrbk
### Arch Linux
btrbk is in AUR: https://aur.archlinux.org/packages/btrbk/
### Alpine Linux
btrbk is in the community repository
apk add btrbk
### Gentoo Linux
btrbk is in portage:
emerge app-backup/btrbk
### Void Linux
btrbk is in Void's `current` repository
xbps-install -S btrbk
[btrbk source tarball]: https://digint.ch/download/btrbk/releases/
[asciidoctor]: https://asciidoctor.org
[asciidoc]: https://asciidoc.org

126
doc/lsbtr.1.asciidoc Normal file
View File

@ -0,0 +1,126 @@
lsbtr(1)
========
:date: 2023-03-25
:release-version: 0.32.6
:man manual: Btrbk Manual
:man source: Btrbk {release-version}
NAME
----
lsbtr - list btrfs subvolumes
SYNOPSIS
--------
[verse]
lsbtr [-h|--help] [--version]
[-l|--long] [-u|--uuid] [-1|--single-column] [--raw]
[--format <output-format>]
[-v|--verbose]
[-c|--config <file>]
[--override <config_option>=<value>]
[[--] <path>|<url>...]
DESCRIPTION
-----------
List btrfs subvolumes and their mount points visible by the file
system below '<path>'.
*lsbtr* is part of *btrbk* (basically a shortcut for "btrbk ls"), and
takes some global configuration options from btrbk.conf(5) if present.
*lsbtr* requires 'root privileges' to run correctly. Alternatively,
consider using "btrfs-progs-sudo" or "btrfs-progs-btrbk" backends,
both of which allows you to run lsbtr as a regular user. Refer to
configuration option 'backend' in btrbk.conf(5) for more details.
OPTIONS
-------
-h, --help::
Prints the synopsis and a list of the commands.
--version::
Prints the btrbk version.
-l, --long::
Print output in long table format (additionally print subvolume
path).
-u, --uuid::
Print UUID table (parent/received relations).
-1, --single-column::
Print path column only (delimited by newline).
--raw::
Print space-separated key="value" pairs (machine readable).
--format table|long|raw|col:[h:]<columns>::
Print output in specified format. If set to "raw", prints
space-separated key="value" pairs (machine readable).
+
If set to "col:", prints only the <columns> specified (comma-separated
list). Header lines are omitted if the "h:" modifier is present.
Columns prefixed with "-" are collapsed if empty. Columns postfixed
with ":RALIGN" are right-aligned.
-v, --verbose::
Increase the level of verbosity.
-c, --config <file>::
Read the configuration from <file>.
--override <config_option>=<value>::
Override a configuration option <config_option> with <value>.
FILES
-----
+/etc/btrbk.conf+::
+/etc/btrbk/btrbk.conf+::
Default configuration file. The file format and configuration
options are described in *btrbk.conf*(5).
EXIT STATUS
-----------
*lsbtr* returns the following error codes:
ifndef::backend-docbook,backend-manpage[]
[horizontal]
endif::backend-docbook,backend-manpage[]
0:: No problems occurred.
1:: Generic error code.
2:: Parse error: when parsing command-line options or configuration
file.
255:: Script error.
AVAILABILITY
------------
Please refer to the btrbk project page *<https://digint.ch/btrbk/>*
for further details.
SEE ALSO
--------
*btrbk*(1),
*btrbk.conf*(5),
*btrfs*(8)
AUTHOR
------
Axel Burri <axel@tty0.ch>

View File

@ -1,97 +0,0 @@
.TH "ssh_filter_btrbk" "1" "2016-02-02" "btrbk v0.22.2" ""
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.SH NAME
ssh_filter_btrbk.sh \- ssh command filter script for btrbk
.SH SYNOPSIS
.nf
\fBssh_filter_btrbk.sh\fR [\-s|\-\-source] [\-t|\-\-target] [\-d|\-\-delete] [\-i|\-\-info]
[\-p|\-\-restrict\-path <path>] [\-l|\-\-log] [\-\-sudo]
.fi
.SH DESCRIPTION
\fBssh_filter_btrbk.sh\fR restricts SSH commands to \fIbtrfs\fR
commands used by \fIbtrbk\fR. It examines the SSH_ORIGINAL_COMMAND
environment variable (set by sshd) and executes it only if it matches
commands used by \fIbtrbk\fR. The accepted commands are specified by
the "\-\-source", "\-\-target", "\-\-delete" and "\-\-info" options.
.PP
Note that the following btrfs commands are always allowed: "btrfs
subvolume show", "btrfs subvolume list".
.PP
Example line in /root/.ssh/authorized_keys on a backup target host:
.PP
.RS 4
.nf
command="ssh_filter_btrbk.sh \-\-target \-\-delete \-\-restrict\-path /mnt/btr_backup" ssh\-rsa AAAAB3NzaC1...hwumXFRQBL btrbk@mydomain.com
.fi
.RE
.SH OPTIONS
.PP
\-s, \-\-source
.RS 4
Allow commands for backup source: "btrfs subvolume snapshot", "btrfs
send". Equivalent to "\-\-snapshot \-\-send".
.RE
.PP
\-t, \-\-target
.RS 4
Allow commands for backup target: "btrfs receive". Equivalent to
"\-\-receive".
.RE
.PP
\-d, \-\-delete
.RS 4
Allow commands for subvolume deletion: "btrfs subvolume delete". This
is used for backup source if \fIsnapshot_preserve_daily\fR is not set
to \[lq]all\[rq], and for backup targets if
\fItarget_preserve_daily\fR is not set to \[lq]all\[rq].
.RE
.PP
\-i, \-\-info
.RS 4
Allow informative commands: "btrfs subvolume find-new", "btrfs
filesystem usage". This is used by btrbk \fIinfo\fR and \fIdiff\fR
commands.
.RE
.PP
\-\-snapshot
.RS 4
Allow btrfs snapshot command: "btrfs subvolume snapshot".
.RE
.PP
\-\-send
.RS 4
Allow btrfs send command: "btrfs send".
.RE
.PP
\-\-receive
.RS 4
Allow btrfs receive command: "btrfs receive".
.RE
.PP
\-p, \-\-restrict\-path <path>
.RS 4
Restrict btrfs commands to <path>.
.RE
.PP
\-l, \-\-log
.RS 4
Log ACCEPT and REJECT messages to the system log.
.RE
.PP
\-\-sudo
.RS 4
Call SSH_ORIGINAL_COMMAND using sudo.
.RE
.SH AVAILABILITY
Please refer to the btrbk project page
\fBhttp://www.digint.ch/btrbk/\fR for further
details.
.SH SEE ALSO
.BR btrbk (1),
.BR btrbk.conf (5),
.BR btrfs (1)
.SH AUTHOR
Axel Burri <axel@tty0.ch>

View File

@ -0,0 +1,117 @@
ssh_filter_btrbk(1)
===================
:date: 2023-03-25
:release-version: 0.32.6
:man manual: Btrbk Manual
:man source: Btrbk {release-version}
NAME
----
ssh_filter_btrbk - ssh command filter script for btrbk
SYNOPSIS
--------
[verse]
ssh_filter_btrbk.sh [-s|--source] [-t|--target] [-d|--delete]
[-i|--info] [--snapshot] [--send] [--receive]
[-p|--restrict-path <path>] [-l|--log] [--sudo]
DESCRIPTION
-----------
*ssh_filter_btrbk.sh* restricts SSH commands to commands used by
'btrbk'. It examines the SSH_ORIGINAL_COMMAND environment variable
(set by sshd) and executes it only if it contains commands used by
'btrbk'.
The accepted commands are specified by the "--source", "--target",
"--delete" and "--info" options.
The following commands are always allowed:
- "btrfs subvolume show" (not affected by "--restrict-path")
- "btrfs subvolume list" (not affected by "--restrict-path")
- "readlink"
- "test -d" (only if "compat busybox" configuration option is set)
- "cat /proc/self/mountinfo"
- pipes through "gzip", "pigz", "bzip2", "pbzip2", "bzip3", "xz",
"lzop", "lz4", "zstd" (stream_compress)
- pipes through "mbuffer" (stream_buffer, rate_limit)
Example line in /root/.ssh/authorized_keys on a backup target host:
command="ssh_filter_btrbk.sh --target --delete --restrict-path /mnt/btr_backup",restrict ssh-rsa AAAAB3NzaC1...hwumXFRQBL btrbk@example.org
OPTIONS
-------
-s, --source::
Allow commands for backup source: "btrfs subvolume snapshot",
"btrfs send". Equivalent to "--snapshot --send".
-t, --target::
Allow commands for backup and archive target: "btrfs receive",
"mkdir".
-d, --delete::
Allow commands for subvolume deletion: "btrfs subvolume
delete". This is used for backup source if
'snapshot_preserve_daily' is not set to ``all'', and for backup
targets if 'target_preserve_daily' is not set to ``all''.
-i, --info::
Allow informative commands: "btrfs subvolume find-new", "btrfs
filesystem usage". This is used by btrbk 'info' and 'diff'
commands.
--snapshot::
Allow btrfs snapshot command: "btrfs subvolume snapshot".
--send::
Allow btrfs send command: "btrfs send".
--receive::
Allow btrfs receive command: "btrfs receive".
-p, --restrict-path <path>::
Restrict commands to <path>. Note that "btrfs subvolume show",
"btrfs subvolume list" are NOT affected by this option.
+
It is not possible to restrict commands to exact subvolume names, as
btrfs-receive(8) takes a <path> as argument (directory, not including
the subvolume file name to be created, this is encoded in the
send-stream).
-l, --log::
Log ACCEPT and REJECT messages to the system log.
--sudo::
Allow btrfs commands to be called via sudo. Enable this if you
have "backend btrfs-progs-sudo" in your btrbk configuration file.
AVAILABILITY
------------
Please refer to the btrbk project page *<https://digint.ch/btrbk/>*
for further details.
SEE ALSO
--------
*btrbk*(1),
*btrbk.conf*(5),
*btrfs*(8)
AUTHOR
------
Axel Burri <axel@tty0.ch>

1
lsbtr Symbolic link
View File

@ -0,0 +1 @@
btrbk

View File

@ -1,79 +1,142 @@
#!/bin/bash #!/bin/sh
set -e # initialise and sanitise the shell execution environment
set -u unset -v IFS
export LC_ALL=C
export PATH='/sbin:/bin:/usr/sbin:/usr/bin'
export PATH=/sbin:/bin:/usr/sbin:/usr/bin set -e -u
enable_log= enable_log=
use_sudo=
restrict_path_list= restrict_path_list=
allow_list= allow_list=
allow_exact_list=
allow_rate_limit=1
allow_stream_buffer=1
allow_compress=1
compress_list='gzip|pigz|bzip2|pbzip2|bzip3|xz|lzop|lz4|zstd'
# note that the backslash is NOT a metacharacter in a POSIX bracket expression!
option_match='-[a-zA-Z0-9=-]+' # matches short as well as long options
file_match_sane='/[0-9a-zA-Z_@+./-]*' # matches file path (equal to ${file_match} in btrbk < 0.32.0)
file_match="/[^']*" # btrbk >= 0.32.0 quotes file arguments: match all but single quote
file_arg_match="('${file_match}'|${file_match_sane})" # support btrbk < 0.32.0
log_cmd() log_cmd()
{ {
if [[ -n "$enable_log" ]]; then local priority="$1"
logger -p $1 -t ssh_filter_btrbk.sh "$2 (Name: ${LOGNAME:-<unknown>}; Remote: ${SSH_CLIENT:-<unknown>})${3:+: $3}: $SSH_ORIGINAL_COMMAND" local authorisation_decision="$2"
local reason="${3-}"
if [ -n "${enable_log}" ]; then
logger -p "${priority}" -t ssh_filter_btrbk.sh "${authorisation_decision} (Name: ${LOGNAME:-<unknown>}; Connection: ${SSH_CONNECTION:-<unknown>})${reason:+: ${reason}}: ${SSH_ORIGINAL_COMMAND}"
fi fi
} }
allow_cmd() allow_cmd()
{ {
allow_list="${allow_list}|$1" local cmd="$1"
allow_list="${allow_list}|${cmd}"
}
allow_exact_cmd()
{
local cmd="$1"
allow_exact_list="${allow_exact_list}|${cmd}"
} }
reject_and_die() reject_and_die()
{ {
local reason=$1 local reason="$1"
log_cmd "auth.err" "btrbk REJECT" "$reason"
echo "ERROR: ssh_filter_btrbk.sh: ssh command rejected: $reason: $SSH_ORIGINAL_COMMAND" 1>&2 log_cmd 'auth.err' 'btrbk REJECT' "${reason}"
exit 1 printf 'ERROR: ssh_filter_btrbk.sh: ssh command rejected: %s: %s\n' "${reason}" "${SSH_ORIGINAL_COMMAND}" >&2
exit 255
} }
run_cmd() run_cmd()
{ {
log_cmd "auth.info" "btrbk ACCEPT" log_cmd 'auth.info' 'btrbk ACCEPT'
$use_sudo $SSH_ORIGINAL_COMMAND eval " ${SSH_ORIGINAL_COMMAND}"
} }
reject_filtered_cmd() reject_filtered_cmd()
{ {
# note that the backslash is NOT a metacharacter in a POSIX bracket expression! if [ -n "${restrict_path_list}" ]; then
option_match='-[a-zA-Z-]+' # matches short as well as long options # match any of restrict_path_list,
file_match='[0-9a-zA-Z_@+./-]+' # matches file path (equal to $file_match in btrbk)
if [[ -n "$restrict_path_list" ]]; then
# match any of restrict_path_list with or without trailing slash,
# or any file/directory (matching file_match) below restrict_path # or any file/directory (matching file_match) below restrict_path
path_match="(${restrict_path_list})(/|/${file_match})?" path_match="'(${restrict_path_list})(${file_match})?'"
path_match_legacy="(${restrict_path_list})(${file_match_sane})?"
else else
# match any absolute file/directory (matching file_match) # match any absolute file/directory (matching file_match)
path_match="/${file_match}" path_match="'${file_match}'"
path_match_legacy="${file_match_sane}"
fi
# btrbk >= 0.32.0 quotes files, allow both (legacy)
path_match="(${path_match}|${path_match_legacy})"
if [ -n "${allow_compress}" ]; then
decompress_match="(${compress_list}) -d -c( -[pT][0-9]+)?"
compress_match="(${compress_list}) -c( -[0-9])?( -[pT][0-9]+)?"
else
decompress_match=
compress_match=
fi
# rate_limit_remote and stream_buffer_remote use combined
# "mbuffer" as of btrbk-0.29.0
if [ -n "${allow_stream_buffer}" ] || [ -n "${allow_rate_limit}" ]; then
mbuffer_match='mbuffer -v 1 -q( -s [0-9]+[kmgKMG]?)?( -m [0-9]+[kmgKMG]?)?( -[rR] [0-9]+[kmgtKMGT]?)?'
else
mbuffer_match=
fi fi
# allow multiple paths (e.g. "btrfs subvolume snapshot <src> <dst>") # allow multiple paths (e.g. "btrfs subvolume snapshot <src> <dst>")
btrfs_cmd_match="^(${allow_list})( ${option_match})*( $path_match)+$" allow_cmd_match="(${allow_list})( ${option_match})*( ${path_match})+"
stream_in_match="(${decompress_match} \| )?(${mbuffer_match} \| )?"
stream_out_match="( \| ${mbuffer_match})?( \| ${compress_match}$)?"
if [[ ! $SSH_ORIGINAL_COMMAND =~ $btrfs_cmd_match ]] ; then # `grep`s `-q`-option is not used as it may cause an exit status of `0` even
reject_and_die "disallowed command${restrict_path_list:+ (restrict-path: \"${restrict_path_list//|/\", \"}\")}" # when an error occurred.
allow_stream_match="^${stream_in_match}${allow_cmd_match}${stream_out_match}"
if printf '%s' "${SSH_ORIGINAL_COMMAND}" | grep -E "${allow_stream_match}" >/dev/null 2>/dev/null; then
return 0
fi fi
exact_cmd_match="^(${allow_exact_list})$";
if printf '%s' "${SSH_ORIGINAL_COMMAND}" | grep -E "${exact_cmd_match}" >/dev/null 2>/dev/null; then
return 0
fi
local formatted_restrict_path_list="$(printf '%s' "${restrict_path_list}" | sed 's/|/", "/g')"
reject_and_die "disallowed command${restrict_path_list:+ (restrict-path: \"${formatted_restrict_path_list}\")}"
} }
# check for "--sudo" option before processing other options
sudo_prefix=
for key in "$@"; do
if [ "${key}" = '--sudo' ]; then
sudo_prefix='sudo -n '
fi
if [ "${key}" = '--doas' ]; then
sudo_prefix='doas -n '
fi
done
allow_cmd "btrfs subvolume show"; # subvolume queries are always allowed while [ "$#" -ge 1 ]; do
allow_cmd "btrfs subvolume list"; # subvolume queries are always allowed
while [[ "$#" -ge 1 ]]; do
key="$1" key="$1"
case $key in case "${key}" in
-l|--log) -l|--log)
enable_log=1 enable_log=1
;; ;;
--sudo) --sudo|--doas)
use_sudo="sudo" # already processed above
;; ;;
-p|--restrict-path) -p|--restrict-path)
@ -82,61 +145,75 @@ while [[ "$#" -ge 1 ]]; do
;; ;;
-s|--source) -s|--source)
allow_cmd "btrfs subvolume snapshot" allow_cmd "${sudo_prefix}btrfs subvolume snapshot"
allow_cmd "btrfs send" allow_cmd "${sudo_prefix}btrfs send"
;; ;;
-t|--target) -t|--target)
allow_cmd "btrfs receive" allow_cmd "${sudo_prefix}btrfs receive"
allow_cmd "${sudo_prefix}mkdir"
;;
-c|--compress)
# deprecated option, compression is always allowed
;; ;;
-d|--delete) -d|--delete)
allow_cmd "btrfs subvolume delete" allow_cmd "${sudo_prefix}btrfs subvolume delete"
;; ;;
-i|--info) -i|--info)
allow_cmd "btrfs subvolume find-new" allow_cmd "${sudo_prefix}btrfs subvolume find-new"
allow_cmd "btrfs filesystem usage" allow_cmd "${sudo_prefix}btrfs filesystem usage"
;; ;;
--snapshot) --snapshot)
allow_cmd "btrfs subvolume snapshot" allow_cmd "${sudo_prefix}btrfs subvolume snapshot"
;; ;;
--send) --send)
allow_cmd "btrfs send" allow_cmd "${sudo_prefix}btrfs send"
;; ;;
--receive) --receive)
allow_cmd "btrfs receive" allow_cmd "${sudo_prefix}btrfs receive"
;; ;;
*) *)
echo "ERROR: ssh_filter_btrbk.sh: failed to parse command line option: $key" 1>&2 printf 'ERROR: ssh_filter_btrbk.sh: failed to parse command line option: %s\n' "${key}" >&2
exit 1 exit 255
;; ;;
esac esac
shift shift
done done
# NOTE: subvolume queries are NOT affected by "--restrict-path":
# btrbk also calls show/list on the mount point of the subvolume
allow_exact_cmd "${sudo_prefix}btrfs subvolume (show|list)( ${option_match})* ${file_arg_match}";
allow_cmd "${sudo_prefix}readlink" # resolve symlink
allow_exact_cmd "${sudo_prefix}test -d ${file_arg_match}" # check directory (only for compat=busybox)
allow_exact_cmd 'cat /proc/self/mountinfo' # resolve mountpoints
allow_exact_cmd 'cat /proc/self/mounts' # legacy, for btrbk < 0.27.0
# remove leading "|" on alternation lists # remove leading "|" on alternation lists
allow_list=${allow_list#\|} allow_list="${allow_list#\|}"
restrict_path_list=${restrict_path_list#\|} allow_exact_list="${allow_exact_list#\|}"
restrict_path_list="${restrict_path_list#\|}"
case "${SSH_ORIGINAL_COMMAND}" in
*\.\./*) reject_and_die 'directory traversal' ;;
*'
'*) reject_and_die 'unsafe character LF' ;;
*\$*) reject_and_die 'unsafe character "$"' ;;
*\&*) reject_and_die 'unsafe character "&"' ;;
*\(*) reject_and_die 'unsafe character "("' ;;
*\{*) reject_and_die 'unsafe character "{"' ;;
*\;*) reject_and_die 'unsafe character ";"' ;;
*\<*) reject_and_die 'unsafe character "<"' ;;
*\>*) reject_and_die 'unsafe character ">"' ;;
*\`*) reject_and_die 'unsafe character "`"' ;;
*\|*) [ -n "${allow_compress}" ] || [ -n "${allow_rate_limit}" ] || [ -n "${allow_stream_buffer}" ] || reject_and_die 'unsafe character "|"' ;;
esac
case "$SSH_ORIGINAL_COMMAND" in
*\$*) reject_and_die "unsafe character" ;;
*\&*) reject_and_die "unsafe character" ;;
*\(*) reject_and_die "unsafe character" ;;
*\{*) reject_and_die "unsafe character" ;;
*\;*) reject_and_die "unsafe character" ;;
*\<*) reject_and_die "unsafe character" ;;
*\>*) reject_and_die "unsafe character" ;;
*\`*) reject_and_die "unsafe character" ;;
*\|*) reject_and_die "unsafe character" ;;
*\.\./*) reject_and_die "directory traversal" ;;
*)
reject_filtered_cmd reject_filtered_cmd
run_cmd run_cmd
;;
esac