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`.
lsbtr-related
Axel Burri 2020-05-24 00:13:10 +02:00
parent 52a823bb93
commit ec037952cf
4 changed files with 46 additions and 13 deletions

34
btrbk
View File

@ -132,6 +132,10 @@ my %config_options = (
backend_local => { default => undef, accept => [ "no", "btrfs-progs", "btrfs-progs-btrbk", "btrfs-progs-sudo" ] }, backend_local => { default => undef, accept => [ "no", "btrfs-progs", "btrfs-progs-btrbk", "btrfs-progs-sudo" ] },
backend_remote => { default => undef, accept => [ "no", "btrfs-progs", "btrfs-progs-btrbk", "btrfs-progs-sudo" ] }, backend_remote => { default => undef, accept => [ "no", "btrfs-progs", "btrfs-progs-btrbk", "btrfs-progs-sudo" ] },
compat => { default => undef, accept => [ "no", "busybox" ] },
compat_local => { default => undef, accept => [ "no", "busybox" ] },
compat_remote => { default => undef, accept => [ "no", "busybox" ] },
snapshot_qgroup_destroy => { default => undef, accept => [ "yes", "no" ], context => [ "global", "volume", "subvolume" ] }, snapshot_qgroup_destroy => { default => undef, accept => [ "yes", "no" ], context => [ "global", "volume", "subvolume" ] },
target_qgroup_destroy => { default => undef, accept => [ "yes", "no" ] }, target_qgroup_destroy => { default => undef, accept => [ "yes", "no" ] },
archive_qgroup_destroy => { default => undef, accept => [ "yes", "no" ], context => [ "global" ] }, archive_qgroup_destroy => { default => undef, accept => [ "yes", "no" ], context => [ "global" ] },
@ -1883,23 +1887,43 @@ sub system_list_mountinfo($)
} }
sub system_testdir($)
{
my $vol = shift // die;
my $path = $vol->{PATH} // die;
my $ret = run_cmd(cmd => vinfo_cmd($vol, "test", '-d', { unsafe => $path } ),
rsh => vinfo_rsh($vol),
non_destructive => 1,
);
return undef unless(defined($ret));
DEBUG "Directory exists: $vol->{PRINT}";
return 1;
}
sub system_realpath($) sub system_realpath($)
{ {
my $vol = shift // die; my $vol = shift // die;
my $path = $vol->{PATH} // die;
my $path = $vol->{PATH} // die;; my $compat = (($vol->{HOST} && config_key($vol, "compat_remote")) //
my $ret = run_cmd(cmd => vinfo_cmd($vol, "readlink", '-v', '-e', { unsafe => $path } ), config_key($vol, "compat_local") //
config_key($vol, "compat")) // "" eq "busybox";
my @options = ("-v"); # report error messages
push @options, "-e" unless($compat); # all components must exist (not available in busybox!)
push @options, "-f" if($compat); # all but the last component must exist.
my $ret = run_cmd(cmd => vinfo_cmd($vol, "readlink", @options, { unsafe => $path } ),
rsh => vinfo_rsh($vol), rsh => vinfo_rsh($vol),
non_destructive => 1, non_destructive => 1,
); );
return undef unless(defined($ret)); return undef unless(defined($ret));
unless(scalar(@$ret) && ($ret->[0] =~ /^($file_match)$/)) { my $realpath = scalar(@$ret) ? (check_file($ret->[0], { absolute => 1 }) // "") : "";
unless($realpath) {
ERROR "Failed to parse output of `realpath` for \"$vol->{PRINT}\": \"$ret->[0]\""; ERROR "Failed to parse output of `realpath` for \"$vol->{PRINT}\": \"$ret->[0]\"";
return undef; return undef;
} }
my $realpath = $1; # untaint argument
DEBUG "Real path for \"$vol->{PRINT}\" is: $realpath"; DEBUG "Real path for \"$vol->{PRINT}\" is: $realpath";
return undef if($compat && !system_testdir($vol));
return $realpath; return $realpath;
} }

View File

@ -364,6 +364,9 @@ constraints.
*backend* btrfs-progs|btrfs-progs-btrbk|btrfs-progs-sudo:: *backend* btrfs-progs|btrfs-progs-btrbk|btrfs-progs-sudo::
Backend filesystem utilities to be used for btrfs specific Backend filesystem utilities to be used for btrfs specific
operations. Defaults to ``btrfs-progs''. operations. Defaults to ``btrfs-progs''.
If you want to set this option for local or remote hosts only, you
can set *backend_local* or *backend_remote*
(e.g. "backend_remote btrfs-progs-btrbk").
+ +
-- --
btrfs-progs:: btrfs-progs::
@ -381,13 +384,17 @@ btrfs-progs-sudo::
btrfs commands are prefixed with "sudo -n" (e.g. "sudo -n btrfs btrfs commands are prefixed with "sudo -n" (e.g. "sudo -n btrfs
subvolume show" instead of "btrfs subvolume show"). Make sure to subvolume show" instead of "btrfs subvolume show"). Make sure to
have appropriate (root) permissions for the "btrfs" command groups have appropriate (root) permissions for the "btrfs" command groups
and the "readlink" command in /etc/sudoers. as well as the "readlink" and "test" commands in /etc/sudoers.
-- --
+ +
For convenience, it is also possible to set *backend_local* or
*backend_remote* options, which will override the backend only for
local or remote sources/targets (e.g. "backend_remote *compat* busybox|no::
btrfs-progs-btrbk"). If set to ``busybox'', use busybox compatible commands. Defaults
to ``no''.
If you want to set this option for local or remote hosts only, you
can set *compat_local* or *compat_remote*
(e.g. "compat_remote busybox").
=== Btrfs Specific Options === Btrfs Specific Options

View File

@ -37,6 +37,7 @@ The following commands are always allowed:
- "btrfs subvolume show" (not affected by "--restrict-path") - "btrfs subvolume show" (not affected by "--restrict-path")
- "btrfs subvolume list" (not affected by "--restrict-path") - "btrfs subvolume list" (not affected by "--restrict-path")
- "readlink" - "readlink"
- "test -d" (only if "compat busybox" configuration option is set)
- "cat /proc/self/mountinfo" - "cat /proc/self/mountinfo"
- pipes through "gzip", "pigz", "bzip2", "pbzip2", "xz", "lzop", - pipes through "gzip", "pigz", "bzip2", "pbzip2", "xz", "lzop",
"lz4" (stream_compress) "lz4" (stream_compress)

View File

@ -164,9 +164,10 @@ done
# NOTE: subvolume queries are NOT affected by "--restrict-path": # NOTE: subvolume queries are NOT affected by "--restrict-path":
# btrbk also calls show/list on the mount point of the subvolume # btrbk also calls show/list on the mount point of the subvolume
allow_exact_cmd "${sudo_prefix}btrfs subvolume (show|list)( ${option_match})* ${file_match}"; allow_exact_cmd "${sudo_prefix}btrfs subvolume (show|list)( ${option_match})* ${file_match}";
allow_cmd "${sudo_prefix}readlink" # used to resolve mountpoints allow_cmd "${sudo_prefix}readlink" # resolve symlink
allow_exact_cmd "cat /proc/self/mountinfo" # used to resolve mountpoints allow_exact_cmd "${sudo_prefix}test -d ${file_match}" # check directory (only for compat=busybox)
allow_exact_cmd "cat /proc/self/mounts" # legacy, for btrbk < 0.27.0 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#\|}