mirror of https://github.com/digint/btrbk
btrbk: find latest common snapshot instead of latest dest snapshot
parent
a43b8cc6db
commit
a6017460b2
56
btrbk
56
btrbk
|
@ -89,7 +89,7 @@ sub run_cmd($;$)
|
||||||
my $cmd = shift;
|
my $cmd = shift;
|
||||||
my $always_execute = shift;
|
my $always_execute = shift;
|
||||||
my $ret;
|
my $ret;
|
||||||
DEBUG "CMD: $cmd\n";
|
DEBUG "CMD: $cmd";
|
||||||
if($always_execute || (not $dryrun)) {
|
if($always_execute || (not $dryrun)) {
|
||||||
$ret = `$cmd`;
|
$ret = `$cmd`;
|
||||||
die("command execution failed: \"$cmd\"") if($?);
|
die("command execution failed: \"$cmd\"") if($?);
|
||||||
|
@ -152,19 +152,36 @@ sub send_receive($$;$)
|
||||||
run_cmd("/sbin/btrfs send $parent $src | /sbin/btrfs receive ${dst}/");
|
run_cmd("/sbin/btrfs send $parent $src | /sbin/btrfs receive ${dst}/");
|
||||||
}
|
}
|
||||||
|
|
||||||
sub get_latest($$)
|
sub get_latest_common($$$)
|
||||||
{
|
{
|
||||||
my $vol = shift;
|
my $vol = shift;
|
||||||
my $root = shift;
|
my $sroot = shift;
|
||||||
die("subvolume info not present: $root") unless(exists($vol_info{$root}));
|
my $droot = shift;
|
||||||
|
|
||||||
|
die("source subvolume info not present: $sroot") unless(exists($vol_info{$sroot}));
|
||||||
|
die("target subvolume info not present: $droot") unless(exists($vol_info{$droot}));
|
||||||
my $latest;
|
my $latest;
|
||||||
foreach (@{$vol_info{$root}}) {
|
my @svol_list;
|
||||||
|
foreach (@{$vol_info{$sroot}}) {
|
||||||
|
my $v = $_->{path};
|
||||||
|
next unless($v =~ s/^$src_snapshot_dir\/$vol\./$vol\./);
|
||||||
|
DEBUG "get_latest_common(): found source snapshot: $v";
|
||||||
|
push @svol_list, $v;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (@{$vol_info{$droot}}) {
|
||||||
my $v = $_->{path};
|
my $v = $_->{path};
|
||||||
next unless($v =~ /^$vol\./);
|
next unless($v =~ /^$vol\./);
|
||||||
DEBUG "found snapshot: $v";
|
if(grep {$_ eq $v} @svol_list) {
|
||||||
$latest = $v if((not defined($latest)) || ($latest lt $v));
|
DEBUG "get_latest_common(): found matching dest snapshot: $v";
|
||||||
|
$latest = $v if((not defined($latest)) || ($latest lt $v));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG "get_latest_common(): found non-matching dest snapshot: $v";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
die("no snapshot matching \"${vol}.*\" present in subvolume: $root") unless($latest);
|
die("no common snapshots for \"${vol}.*\" found in \"$sroot/$src_snapshot_dir/\" and \"$droot/\"") unless($latest);
|
||||||
|
DEBUG "get_latest_common(): latest common snapshot: $latest";
|
||||||
return $latest;
|
return $latest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,14 +189,15 @@ MAIN:
|
||||||
{
|
{
|
||||||
$ENV{PATH} = '';
|
$ENV{PATH} = '';
|
||||||
$Getopt::Std::STANDARD_HELP_VERSION = 1;
|
$Getopt::Std::STANDARD_HELP_VERSION = 1;
|
||||||
|
$Data::Dumper::Sortkeys = 1;
|
||||||
|
|
||||||
my %opts;
|
my %opts;
|
||||||
getopts('hivd', \%opts);
|
getopts('hivd', \%opts);
|
||||||
my $sroot = shift @ARGV;
|
my $sroot = shift @ARGV;
|
||||||
my $svol = shift @ARGV;
|
my $svol = shift @ARGV;
|
||||||
my @droot = @ARGV;
|
my @droot_list = @ARGV;
|
||||||
|
|
||||||
if($opts{h} || (not $svol) || (not @droot)) {
|
if($opts{h} || (not $svol) || (not @droot_list)) {
|
||||||
VERSION_MESSAGE();
|
VERSION_MESSAGE();
|
||||||
HELP_MESSAGE(0);
|
HELP_MESSAGE(0);
|
||||||
exit 0;
|
exit 0;
|
||||||
|
@ -195,12 +213,12 @@ MAIN:
|
||||||
|
|
||||||
$vol_info{$sroot} = fetch_subvolume_info($sroot);
|
$vol_info{$sroot} = fetch_subvolume_info($sroot);
|
||||||
|
|
||||||
foreach (@droot) {
|
foreach (@droot_list) {
|
||||||
s/\/+$//; # sanitize
|
s/\/+$//; # sanitize
|
||||||
die if exists $vol_info{$_};
|
die if exists $vol_info{$_};
|
||||||
$vol_info{$_} = fetch_subvolume_info($_);
|
$vol_info{$_} = fetch_subvolume_info($_);
|
||||||
};
|
};
|
||||||
print Data::Dumper->Dump([\%vol_info], ["vol_info"]) if($verbose);
|
DEBUG(Data::Dumper->Dump([\%vol_info], ["vol_info"]));
|
||||||
|
|
||||||
my $postfix = '.' . strftime($time_format, localtime);
|
my $postfix = '.' . strftime($time_format, localtime);
|
||||||
|
|
||||||
|
@ -212,15 +230,17 @@ MAIN:
|
||||||
die("snapshot destination already exists: ${sroot}/${ssnap}") if check_vol($sroot, $ssnap);
|
die("snapshot destination already exists: ${sroot}/${ssnap}") if check_vol($sroot, $ssnap);
|
||||||
snapshot("${sroot}/${svol}", "${sroot}/${ssnap}");
|
snapshot("${sroot}/${svol}", "${sroot}/${ssnap}");
|
||||||
|
|
||||||
foreach (@droot) {
|
foreach (@droot_list)
|
||||||
die("subvolume already exists at destination: $_") if(check_vol($_, "${svol}${postfix}"));
|
{
|
||||||
|
my $droot = $_;
|
||||||
|
die("snapshot already exists at destination: $droot") if(check_vol($droot, "${svol}${postfix}"));
|
||||||
if($incremental) {
|
if($incremental) {
|
||||||
my $dest_latest = get_latest($svol, $_);
|
my $parent_snap = $src_snapshot_dir . '/' . get_latest_common($svol, $sroot, $droot);
|
||||||
die("snapshot parent source does not exists: ${sroot}/${src_snapshot_dir}/${dest_latest}") unless check_vol($sroot, "${src_snapshot_dir}/${dest_latest}");
|
die("snapshot parent source does not exists: ${sroot}/${parent_snap}") unless check_vol($sroot, $parent_snap);
|
||||||
send_receive("${sroot}/${ssnap}", $_, "${sroot}/${src_snapshot_dir}/${dest_latest}");
|
send_receive("${sroot}/${ssnap}", $droot, "${sroot}/${parent_snap}");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
send_receive("${sroot}/${ssnap}", $_);
|
send_receive("${sroot}/${ssnap}", $droot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue