mirror of https://github.com/digint/btrbk
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-btrbkpull/106/merge
parent
dc5dee3121
commit
a8a311c8c7
|
@ -9,6 +9,7 @@ btrbk-current
|
||||||
receive" (adds an additional call to "btrfs subvolume show").
|
receive" (adds an additional call to "btrfs subvolume show").
|
||||||
* Bugfix: Replace "realpath" with "readlink" in ssh_filter_btrbk.sh
|
* Bugfix: Replace "realpath" with "readlink" in ssh_filter_btrbk.sh
|
||||||
* Add "raw_target_block_size" configuration option (close #105).
|
* Add "raw_target_block_size" configuration option (close #105).
|
||||||
|
* Add "backend" configuration option (experimental).
|
||||||
|
|
||||||
btrbk-0.23.3
|
btrbk-0.23.3
|
||||||
|
|
||||||
|
|
80
btrbk
80
btrbk
|
@ -124,6 +124,10 @@ my %config_options = (
|
||||||
|
|
||||||
group => { default => undef, accept_regexp => qr/^$group_match(\s*,\s*$group_match)*$/, split => qr/\s*,\s*/ },
|
group => { default => undef, accept_regexp => qr/^$group_match(\s*,\s*$group_match)*$/, split => qr/\s*,\s*/ },
|
||||||
|
|
||||||
|
backend => { default => "btrfs-progs", accept => [ "btrfs-progs", "btrfs-progs-btrbk" ] },
|
||||||
|
backend_local => { default => undef, accept => [ "no", "btrfs-progs", "btrfs-progs-btrbk" ] },
|
||||||
|
backend_remote => { default => undef, accept => [ "no", "btrfs-progs", "btrfs-progs-btrbk" ] },
|
||||||
|
|
||||||
# deprecated options
|
# deprecated options
|
||||||
btrfs_progs_compat => { default => undef, accept => [ "yes", "no" ],
|
btrfs_progs_compat => { default => undef, accept => [ "yes", "no" ],
|
||||||
deprecated => { DEFAULT => { ABORT => 1, warn => 'This feature has been dropped in btrbk-v0.23.0. Please update to newest btrfs-progs, AT LEAST >= $BTRFS_PROGS_MIN' } } },
|
deprecated => { DEFAULT => { ABORT => 1, warn => 'This feature has been dropped in btrbk-v0.23.0. Please update to newest btrfs-progs, AT LEAST >= $BTRFS_PROGS_MIN' } } },
|
||||||
|
@ -207,6 +211,16 @@ my %table_formats = (
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
my %backend_cmd_map = (
|
||||||
|
"btrfs-progs-btrbk" => { "btrfs subvolume list" => [ "btrfs-subvolume-list" ],
|
||||||
|
"btrfs subvolume show" => [ "btrfs-subvolume-show" ],
|
||||||
|
"btrfs subvolume snapshot" => [ "btrfs-subvolume-snapshot" ],
|
||||||
|
"btrfs subvolume delete" => [ "btrfs-subvolume-delete" ],
|
||||||
|
"btrfs send" => [ "btrfs-send" ],
|
||||||
|
"btrfs receive" => [ "btrfs-receive" ],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
my %url_cache; # map URL to btr_tree node
|
my %url_cache; # map URL to btr_tree node
|
||||||
my %fstab_cache; # map HOST to btrfs mount points
|
my %fstab_cache; # map HOST to btrfs mount points
|
||||||
my %uuid_cache; # map UUID to btr_tree node
|
my %uuid_cache; # map UUID to btr_tree node
|
||||||
|
@ -696,19 +710,11 @@ sub add_pv_command($@)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub btrfs_filesystem_show_all_local()
|
|
||||||
{
|
|
||||||
return run_cmd( cmd => [ qw(btrfs filesystem show) ],
|
|
||||||
non_destructive => 1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub btrfs_filesystem_show($)
|
sub btrfs_filesystem_show($)
|
||||||
{
|
{
|
||||||
my $vol = shift || die;
|
my $vol = shift || die;
|
||||||
my $path = $vol->{PATH} // die;
|
my $path = $vol->{PATH} // die;
|
||||||
return run_cmd( cmd => [ qw(btrfs filesystem show), { unsafe => $path } ],
|
return run_cmd( cmd => vinfo_cmd($vol, "btrfs filesystem show", { unsafe => $path } ),
|
||||||
rsh => vinfo_rsh($vol),
|
rsh => vinfo_rsh($vol),
|
||||||
non_destructive => 1
|
non_destructive => 1
|
||||||
);
|
);
|
||||||
|
@ -719,7 +725,7 @@ sub btrfs_filesystem_df($)
|
||||||
{
|
{
|
||||||
my $vol = shift || die;
|
my $vol = shift || die;
|
||||||
my $path = $vol->{PATH} // die;
|
my $path = $vol->{PATH} // die;
|
||||||
return run_cmd( cmd => [qw(btrfs filesystem df), { unsafe => $path }],
|
return run_cmd( cmd => vinfo_cmd($vol, "btrfs filesystem df", { unsafe => $path }),
|
||||||
rsh => vinfo_rsh($vol),
|
rsh => vinfo_rsh($vol),
|
||||||
non_destructive => 1
|
non_destructive => 1
|
||||||
);
|
);
|
||||||
|
@ -730,7 +736,7 @@ sub btrfs_filesystem_usage($)
|
||||||
{
|
{
|
||||||
my $vol = shift || die;
|
my $vol = shift || die;
|
||||||
my $path = $vol->{PATH} // die;
|
my $path = $vol->{PATH} // die;
|
||||||
my $ret = run_cmd( cmd => [ qw(btrfs filesystem usage), { unsafe => $path } ],
|
my $ret = run_cmd( cmd => vinfo_cmd($vol, "btrfs filesystem usage", { unsafe => $path } ),
|
||||||
rsh => vinfo_rsh($vol),
|
rsh => vinfo_rsh($vol),
|
||||||
non_destructive => 1
|
non_destructive => 1
|
||||||
);
|
);
|
||||||
|
@ -786,7 +792,7 @@ sub btrfs_subvolume_show($)
|
||||||
{
|
{
|
||||||
my $vol = shift || die;
|
my $vol = shift || die;
|
||||||
my $path = $vol->{PATH} // die;
|
my $path = $vol->{PATH} // die;
|
||||||
my $ret = run_cmd(cmd => [ qw(btrfs subvolume show), { unsafe => $path }],
|
my $ret = run_cmd(cmd => vinfo_cmd($vol, "btrfs subvolume show", { unsafe => $path }),
|
||||||
rsh => vinfo_rsh($vol),
|
rsh => vinfo_rsh($vol),
|
||||||
non_destructive => 1,
|
non_destructive => 1,
|
||||||
catch_stderr => 1, # hack for shell-based run_cmd()
|
catch_stderr => 1, # hack for shell-based run_cmd()
|
||||||
|
@ -890,7 +896,7 @@ sub btrfs_subvolume_list_readonly_flag($)
|
||||||
my $vol = shift || die;
|
my $vol = shift || die;
|
||||||
my $path = $vol->{PATH} // die;
|
my $path = $vol->{PATH} // die;
|
||||||
|
|
||||||
my $ret = run_cmd(cmd => [ qw(btrfs subvolume list), '-a', '-r', { unsafe => $path } ],
|
my $ret = run_cmd(cmd => vinfo_cmd($vol, "btrfs subvolume list", '-a', '-r', { unsafe => $path } ),
|
||||||
rsh => vinfo_rsh($vol),
|
rsh => vinfo_rsh($vol),
|
||||||
non_destructive => 1,
|
non_destructive => 1,
|
||||||
);
|
);
|
||||||
|
@ -919,7 +925,7 @@ sub btrfs_subvolume_list($;@)
|
||||||
# NOTE: Support for btrfs-progs <= 3.17 has been dropped in
|
# NOTE: Support for btrfs-progs <= 3.17 has been dropped in
|
||||||
# btrbk-0.23, the received_uuid flag very essential!
|
# btrbk-0.23, the received_uuid flag very essential!
|
||||||
my @display_options = ('-c', '-u', '-q', '-R');
|
my @display_options = ('-c', '-u', '-q', '-R');
|
||||||
my $ret = run_cmd(cmd => [ qw(btrfs subvolume list), @filter_options, @display_options, { unsafe => $path } ],
|
my $ret = run_cmd(cmd => vinfo_cmd($vol, "btrfs subvolume list", @filter_options, @display_options, { unsafe => $path } ),
|
||||||
rsh => vinfo_rsh($vol),
|
rsh => vinfo_rsh($vol),
|
||||||
non_destructive => 1,
|
non_destructive => 1,
|
||||||
);
|
);
|
||||||
|
@ -980,7 +986,7 @@ sub btrfs_subvolume_find_new($$;$)
|
||||||
my $vol = shift || die;
|
my $vol = shift || die;
|
||||||
my $path = $vol->{PATH} // die;
|
my $path = $vol->{PATH} // die;
|
||||||
my $lastgen = shift // die;
|
my $lastgen = shift // die;
|
||||||
my $ret = run_cmd(cmd => [ qw(btrfs subvolume find-new), { unsafe => $path }, $lastgen ],
|
my $ret = run_cmd(cmd => vinfo_cmd($vol, "btrfs subvolume find-new", { unsafe => $path }, $lastgen ),
|
||||||
rsh => vinfo_rsh($vol),
|
rsh => vinfo_rsh($vol),
|
||||||
non_destructive => 1,
|
non_destructive => 1,
|
||||||
);
|
);
|
||||||
|
@ -1047,7 +1053,7 @@ sub btrfs_subvolume_snapshot($$)
|
||||||
vinfo_prefixed_keys("target", $target_vol),
|
vinfo_prefixed_keys("target", $target_vol),
|
||||||
vinfo_prefixed_keys("source", $svol),
|
vinfo_prefixed_keys("source", $svol),
|
||||||
);
|
);
|
||||||
my $ret = run_cmd(cmd => [ qw(btrfs subvolume snapshot), '-r', { unsafe => $src_path }, { unsafe => $target_path } ],
|
my $ret = run_cmd(cmd => vinfo_cmd($svol, "btrfs subvolume snapshot", '-r', { unsafe => $src_path }, { unsafe => $target_path } ),
|
||||||
rsh => vinfo_rsh($svol),
|
rsh => vinfo_rsh($svol),
|
||||||
);
|
);
|
||||||
end_transaction("snapshot", ($dryrun ? "DRYRUN" : (defined($ret) ? "success" : "ERROR")));
|
end_transaction("snapshot", ($dryrun ? "DRYRUN" : (defined($ret) ? "success" : "ERROR")));
|
||||||
|
@ -1067,13 +1073,14 @@ sub btrfs_subvolume_delete($@)
|
||||||
die if($commit && ($commit ne "after") && ($commit ne "each"));
|
die if($commit && ($commit ne "after") && ($commit ne "each"));
|
||||||
$targets = [ $targets ] unless(ref($targets) eq "ARRAY");
|
$targets = [ $targets ] unless(ref($targets) eq "ARRAY");
|
||||||
return 0 unless(scalar(@$targets));
|
return 0 unless(scalar(@$targets));
|
||||||
my $rsh = vinfo_rsh($targets->[0]);
|
|
||||||
|
# assert all targets share same HOST
|
||||||
|
# NOTE: rsh and backend command is taken from first target
|
||||||
my $rsh_host_check = $targets->[0]->{HOST} || "";
|
my $rsh_host_check = $targets->[0]->{HOST} || "";
|
||||||
foreach (@$targets) {
|
foreach (@$targets) {
|
||||||
# make sure all targets share same HOST
|
die if($rsh_host_check ne ($_->{HOST} || ""));
|
||||||
my $host = $_->{HOST} || "";
|
|
||||||
die if($rsh_host_check ne $host);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INFO "[delete] options: commit-$commit" if($commit);
|
INFO "[delete] options: commit-$commit" if($commit);
|
||||||
INFO "[delete] target: $_->{PRINT}" foreach(@$targets);
|
INFO "[delete] target: $_->{PRINT}" foreach(@$targets);
|
||||||
my @options;
|
my @options;
|
||||||
|
@ -1082,8 +1089,8 @@ sub btrfs_subvolume_delete($@)
|
||||||
map( { { vinfo_prefixed_keys("target", $_) }; } @$targets)
|
map( { { vinfo_prefixed_keys("target", $_) }; } @$targets)
|
||||||
);
|
);
|
||||||
my @cmd_target_paths = map { { unsafe => $_->{PATH} } } @$targets;
|
my @cmd_target_paths = map { { unsafe => $_->{PATH} } } @$targets;
|
||||||
my $ret = run_cmd(cmd => [ qw(btrfs subvolume delete), @options, @cmd_target_paths ],
|
my $ret = run_cmd(cmd => vinfo_cmd($targets->[0], "btrfs subvolume delete", @options, @cmd_target_paths ),
|
||||||
rsh => $rsh,
|
rsh => vinfo_rsh($targets->[0]),
|
||||||
);
|
);
|
||||||
end_transaction($opts{type} // "delete", ($dryrun ? "DRYRUN" : (defined($ret) ? "success" : "ERROR")));
|
end_transaction($opts{type} // "delete", ($dryrun ? "DRYRUN" : (defined($ret) ? "success" : "ERROR")));
|
||||||
ERROR "Failed to delete btrfs subvolumes: " . join(' ', map( { $_->{PRINT} } @$targets)) unless(defined($ret));
|
ERROR "Failed to delete btrfs subvolumes: " . join(' ', map( { $_->{PRINT} } @$targets)) unless(defined($ret));
|
||||||
|
@ -1119,7 +1126,7 @@ sub btrfs_send_receive($$$$;@)
|
||||||
|
|
||||||
my @cmd_pipe;
|
my @cmd_pipe;
|
||||||
push @cmd_pipe, {
|
push @cmd_pipe, {
|
||||||
cmd => [ qw(btrfs send), @send_options, { unsafe => $snapshot_path } ],
|
cmd => vinfo_cmd($snapshot, "btrfs send", @send_options, { unsafe => $snapshot_path } ),
|
||||||
rsh => vinfo_rsh($snapshot, disable_compression => config_compress_hash($snapshot, "stream_compress")),
|
rsh => vinfo_rsh($snapshot, disable_compression => config_compress_hash($snapshot, "stream_compress")),
|
||||||
rsh_compress_out => config_compress_hash($snapshot, "stream_compress"),
|
rsh_compress_out => config_compress_hash($snapshot, "stream_compress"),
|
||||||
name => "btrfs send",
|
name => "btrfs send",
|
||||||
|
@ -1127,7 +1134,7 @@ sub btrfs_send_receive($$$$;@)
|
||||||
};
|
};
|
||||||
add_pv_command(\@cmd_pipe, show_progress => $show_progress, rate_limit => $opts{rate_limit});
|
add_pv_command(\@cmd_pipe, show_progress => $show_progress, rate_limit => $opts{rate_limit});
|
||||||
push @cmd_pipe, {
|
push @cmd_pipe, {
|
||||||
cmd => [ qw(btrfs receive), @receive_options, { unsafe => $target_path . '/' } ],
|
cmd => vinfo_cmd($target, "btrfs receive", @receive_options, { unsafe => $target_path . '/' } ),
|
||||||
rsh => vinfo_rsh($target, disable_compression => config_compress_hash($target, "stream_compress")),
|
rsh => vinfo_rsh($target, disable_compression => config_compress_hash($target, "stream_compress")),
|
||||||
name => "btrfs receive",
|
name => "btrfs receive",
|
||||||
rsh_compress_in => config_compress_hash($target, "stream_compress"),
|
rsh_compress_in => config_compress_hash($target, "stream_compress"),
|
||||||
|
@ -1257,7 +1264,7 @@ sub btrfs_send_to_file($$$$;@)
|
||||||
|
|
||||||
my @cmd_pipe;
|
my @cmd_pipe;
|
||||||
push @cmd_pipe, {
|
push @cmd_pipe, {
|
||||||
cmd => [ qw(btrfs send), @send_options, { unsafe => $source_path } ],
|
cmd => vinfo_cmd($source, "btrfs send", @send_options, { unsafe => $source_path } ),
|
||||||
rsh => vinfo_rsh($source, disable_compression => $opts{compress} || config_compress_hash($source, "stream_compress")),
|
rsh => vinfo_rsh($source, disable_compression => $opts{compress} || config_compress_hash($source, "stream_compress")),
|
||||||
name => "btrfs send",
|
name => "btrfs send",
|
||||||
rsh_compress_out => $opts{compress} || config_compress_hash($source, "stream_compress"),
|
rsh_compress_out => $opts{compress} || config_compress_hash($source, "stream_compress"),
|
||||||
|
@ -1759,6 +1766,29 @@ sub vinfo_rsh($;@)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub vinfo_cmd($$@)
|
||||||
|
{
|
||||||
|
my $vinfo = shift || die;
|
||||||
|
my $cmd = shift || die;
|
||||||
|
my @cmd_args = @_;
|
||||||
|
my $ret;
|
||||||
|
my $backend = $vinfo->{HOST} ? config_key($vinfo, "backend_remote") : config_key($vinfo, "backend_local");
|
||||||
|
$backend = $backend // config_key($vinfo, "backend") // die;
|
||||||
|
my $cmd_mapped = $backend_cmd_map{$backend}{$cmd};
|
||||||
|
if(defined($cmd_mapped)) {
|
||||||
|
TRACE "vinfo_cmd: found mapping for backend=$backend cmd=\"$cmd\": " . join(' ', @$cmd_mapped);
|
||||||
|
$ret = [ @$cmd_mapped, @cmd_args ];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
my @ret_cmd = split(/\s/, $cmd);
|
||||||
|
die unless($ret_cmd[0] eq 'btrfs');
|
||||||
|
TRACE "vinfo_cmd: no mapping found for backend=$backend cmd=\"$cmd\", assuming btrfs-progs: " . join(' ', @ret_cmd);
|
||||||
|
$ret = [ @ret_cmd, @cmd_args ];
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sub add_btrbk_filename_info($;$)
|
sub add_btrbk_filename_info($;$)
|
||||||
{
|
{
|
||||||
my $node = shift;
|
my $node = shift;
|
||||||
|
|
|
@ -269,6 +269,19 @@ If set, make sure the deletion of snapshot and backup subvolumes are
|
||||||
committed to disk when btrbk terminates. Defaults to \[lq]no\[rq].
|
committed to disk when btrbk terminates. Defaults to \[lq]no\[rq].
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
|
\fBbackend\fR btrfs-progs|btrfs-progs-btrbk \fI*experimental*\fR
|
||||||
|
.RS 4
|
||||||
|
Btrfs filesystem utilities to be used for subvolume operations. If set
|
||||||
|
to \[lq]btrfs-progs-btrbk\[rq], specific btrfs(8) commands groups
|
||||||
|
needs to be 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. For convenience, it is also possible to set
|
||||||
|
\fIbackend_local\fR or \fIbackend_remote\fR, which will override the
|
||||||
|
\fIbackend\fR option for local or remote sources/targets. Defaults to
|
||||||
|
\[lq]btrfs-progs\[rq].
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
Lines that contain a hash character (#) in the first column are
|
Lines that contain a hash character (#) in the first column are
|
||||||
treated as comments.
|
treated as comments.
|
||||||
.SH RETENTION POLICY
|
.SH RETENTION POLICY
|
||||||
|
|
Loading…
Reference in New Issue