btrbk: added optional subvolume argument for run/dryrun actions, for explicit selection of subvolumes to be processed.

pull/30/head
Axel Burri 2015-03-01 14:28:26 +01:00
parent 372ec90685
commit aa8d153a20
2 changed files with 41 additions and 10 deletions

42
btrbk
View File

@ -974,10 +974,13 @@ MAIN:
my ($action_run, $action_info, $action_tree, $action_diff, $action_origin); my ($action_run, $action_info, $action_tree, $action_diff, $action_origin);
my @subvol_args; my @subvol_args;
my $args_expected = 0; my ($args_expected_min, $args_expected_max) = (0, 0);
if(($command eq "run") || ($command eq "dryrun")) { if(($command eq "run") || ($command eq "dryrun")) {
$action_run = 1; $action_run = 1;
$dryrun = 1 if($command eq "dryrun"); $dryrun = 1 if($command eq "dryrun");
$args_expected_min = 0;
$args_expected_max = 9999;
@subvol_args = @ARGV;
} }
elsif ($command eq "info") { elsif ($command eq "info") {
$action_info = 1; $action_info = 1;
@ -987,12 +990,12 @@ MAIN:
} }
elsif ($command eq "diff") { elsif ($command eq "diff") {
$action_diff = 1; $action_diff = 1;
$args_expected = 2; $args_expected_min = $args_expected_max = 2;
@subvol_args = @ARGV; @subvol_args = @ARGV;
} }
elsif ($command eq "origin") { elsif ($command eq "origin") {
$action_origin = 1; $action_origin = 1;
$args_expected = 1; $args_expected_min = $args_expected_max = 1;
@subvol_args = @ARGV; @subvol_args = @ARGV;
} }
else { else {
@ -1000,7 +1003,7 @@ MAIN:
HELP_MESSAGE(0); HELP_MESSAGE(0);
exit 1; exit 1;
} }
if($args_expected != scalar(@ARGV)) { if(($args_expected_min > scalar(@ARGV)) || ($args_expected_max < scalar(@ARGV))) {
ERROR "Incorrect number of arguments"; ERROR "Incorrect number of arguments";
HELP_MESSAGE(0); HELP_MESSAGE(0);
exit 1; exit 1;
@ -1185,13 +1188,29 @@ MAIN:
# #
# fill vol_info hash, basic checks on configuration # fill vol_info hash, basic checks on configuration
# #
my $subvol_filter_count = undef;
foreach my $config_vol (@{$config->{VOLUME}}) foreach my $config_vol (@{$config->{VOLUME}})
{ {
my $sroot = $config_vol->{sroot} || die; my $sroot = $config_vol->{sroot} || die;
$vol_info{$sroot} //= btr_subtree($sroot, $config_vol);
foreach my $config_subvol (@{$config_vol->{SUBVOLUME}}) foreach my $config_subvol (@{$config_vol->{SUBVOLUME}})
{ {
my $svol = $config_subvol->{svol} || die; my $svol = $config_subvol->{svol} || die;
# filter subvolumes matching command line arguments
if($action_run && scalar(@subvol_args)) {
$subvol_filter_count //= 0;
if(grep(/^$sroot\/$svol$/, @subvol_args)) {
$subvol_filter_count++;
}
else {
DEBUG "No match on subvolume command line argument, skipping: $sroot/$svol";
$config_subvol->{ABORTED} = "No match on subvolume command line arguments";
$config_subvol->{ABORTED_NOERR} = 1;
next;
}
}
$vol_info{$sroot} //= btr_subtree($sroot, $config_vol);
unless(subvol($sroot, $svol)) { unless(subvol($sroot, $svol)) {
$config_subvol->{ABORTED} = "Subvolume \"$svol\" not present in btrfs subvolume list for \"$sroot\""; $config_subvol->{ABORTED} = "Subvolume \"$svol\" not present in btrfs subvolume list for \"$sroot\"";
WARN "Skipping subvolume section: $config_subvol->{ABORTED}"; WARN "Skipping subvolume section: $config_subvol->{ABORTED}";
@ -1209,6 +1228,10 @@ MAIN:
} }
} }
} }
if(defined($subvol_filter_count) && ($subvol_filter_count == 0)) {
ERROR "Subvolume command line arguments do not match any volume/subvolume declaration from configuration file, aborting.";
exit 1;
}
TRACE(Data::Dumper->Dump([\%vol_info], ["vol_info"])); TRACE(Data::Dumper->Dump([\%vol_info], ["vol_info"]));
@ -1552,14 +1575,14 @@ MAIN:
{ {
if($config_vol->{ABORTED}) { if($config_vol->{ABORTED}) {
print "!!! $config_vol->{sroot}: ABORTED: $config_vol->{ABORTED}\n"; print "!!! $config_vol->{sroot}: ABORTED: $config_vol->{ABORTED}\n";
$err_count++; $err_count++ unless($config_vol->{ABORTED_NOERR});
} }
foreach my $config_subvol (@{$config_vol->{SUBVOLUME}}) foreach my $config_subvol (@{$config_vol->{SUBVOLUME}})
{ {
print "\n$config_vol->{sroot}/$config_subvol->{svol}\n"; print "\n$config_vol->{sroot}/$config_subvol->{svol}\n";
if($config_subvol->{ABORTED}) { if($config_subvol->{ABORTED}) {
print "!!! Subvolume \"$config_subvol->{svol}\" aborted: $config_subvol->{ABORTED}\n"; print "!!! Subvolume \"$config_subvol->{svol}\" aborted: $config_subvol->{ABORTED}\n";
$err_count++; $err_count++ unless($config_subvol->{ABORTED_NOERR});
} }
# if($config_subvol->{schedule}) { # if($config_subvol->{schedule}) {
# foreach (sort { $a->{sort} cmp $b->{sort} } @{$config_subvol->{schedule}}) { # foreach (sort { $a->{sort} cmp $b->{sort} } @{$config_subvol->{schedule}}) {
@ -1574,7 +1597,7 @@ MAIN:
{ {
if($config_target->{ABORTED}) { if($config_target->{ABORTED}) {
print "!!! Target \"$config_target->{droot}\" aborted: $config_target->{ABORTED}\n"; print "!!! Target \"$config_target->{droot}\" aborted: $config_target->{ABORTED}\n";
$err_count++; $err_count++ unless($config_target->{ABORTED_NOERR});
} }
# if($config_target->{schedule}) { # if($config_target->{schedule}) {
# foreach (sort { $a->{sort} cmp $b->{sort} } @{$config_target->{schedule}}) { # foreach (sort { $a->{sort} cmp $b->{sort} } @{$config_target->{schedule}}) {
@ -1593,6 +1616,9 @@ MAIN:
print "\nNOTE: Some errors occurred, which may result in missing backups!\n"; print "\nNOTE: Some errors occurred, which may result in missing backups!\n";
print "Please check warning and error messages above.\n"; print "Please check warning and error messages above.\n";
} }
if($preserve_backups) {
print "\nNOTE: Preserved all backups (option -p present)\n";
}
if($dryrun) { if($dryrun) {
print "\nNOTE: Dryrun was active, none of the operations above were actually executed!\n"; print "\nNOTE: Dryrun was active, none of the operations above were actually executed!\n";
} }

View File

@ -44,9 +44,13 @@ and trace.
.SH COMMANDS .SH COMMANDS
.PP .PP
.B run .B run
[subvolume...]
.RS 4 .RS 4
Perform backup operations as specified in the configuration Perform backup operations as specified in the configuration file. If
file: the optional [subvolume...] arguments are present, backups are only
performed for the specified subvolumes (which must match a
volume/subvolume declaration in the configuration file), and the -p
(preserve backups) option is implied.
.PP .PP
First, btrbk reads information from the source/target btrfs volumes in First, btrbk reads information from the source/target btrfs volumes in
order to do sanity checks and find out about parent/child as well as order to do sanity checks and find out about parent/child as well as
@ -66,6 +70,7 @@ will be skipped if the -p (preserve backups) option is present.
.RE .RE
.PP .PP
.B dryrun .B dryrun
[subvolume...]
.RS 4 .RS 4
Don't run btrfs commands, just show the snapshots and backup Don't run btrfs commands, just show the snapshots and backup
subvolumes that what would be created/deleted by the \fBrun\fR subvolumes that what would be created/deleted by the \fBrun\fR