btrbk: added option -p (preserve backups)

pull/30/head
Axel Burri 2015-02-28 12:02:28 +01:00
parent 02f254bdb3
commit 056f6f9120
2 changed files with 75 additions and 62 deletions

128
btrbk
View File

@ -108,6 +108,7 @@ sub HELP_MESSAGE
print STDERR " --help display this help message\n"; print STDERR " --help display this help message\n";
print STDERR " --version display version information\n"; print STDERR " --version display version information\n";
print STDERR " -c FILE specify configuration file\n"; print STDERR " -c FILE specify configuration file\n";
print STDERR " -p preserve all backups (do not delete any old targets)\n";
print STDERR " -v be verbose (set loglevel=info)\n"; print STDERR " -v be verbose (set loglevel=info)\n";
print STDERR " -q be quiet (do not print summary at end of \"run\" command)\n"; print STDERR " -q be quiet (do not print summary at end of \"run\" command)\n";
print STDERR " -l LEVEL set loglevel (warn, info, debug, trace)\n"; print STDERR " -l LEVEL set loglevel (warn, info, debug, trace)\n";
@ -960,6 +961,7 @@ MAIN:
} }
@config_src = ( $opts{c} ) if($opts{c}); @config_src = ( $opts{c} ) if($opts{c});
my $quiet = $opts{q}; my $quiet = $opts{q};
my $preserve_backups = $opts{p};
# check command line options # check command line options
if($opts{h} || (not $command)) { if($opts{h} || (not $command)) {
@ -1439,85 +1441,91 @@ MAIN:
# #
# remove backups following a preserve daily/weekly/monthly scheme # remove backups following a preserve daily/weekly/monthly scheme
# #
foreach my $config_vol (@{$config->{VOLUME}}) if($preserve_backups) {
INFO "Preserving all backups (option \"-p\" present)";
}
else
{ {
next if($config_vol->{ABORTED}); foreach my $config_vol (@{$config->{VOLUME}})
my $sroot = $config_vol->{sroot} || die;
foreach my $config_subvol (@{$config_vol->{SUBVOLUME}})
{ {
next if($config_subvol->{ABORTED}); next if($config_vol->{ABORTED});
my $svol = $config_subvol->{svol} || die; my $sroot = $config_vol->{sroot} || die;
my $snapdir = config_key($config_subvol, "snapshot_dir") || ""; foreach my $config_subvol (@{$config_vol->{SUBVOLUME}})
my $target_aborted = 0;
foreach my $config_target (@{$config_subvol->{TARGET}})
{ {
if($config_target->{ABORTED}) { next if($config_subvol->{ABORTED});
$target_aborted = 1; my $svol = $config_subvol->{svol} || die;
next; my $snapdir = config_key($config_subvol, "snapshot_dir") || "";
my $target_aborted = 0;
foreach my $config_target (@{$config_subvol->{TARGET}})
{
if($config_target->{ABORTED}) {
$target_aborted = 1;
next;
}
my $droot = $config_target->{droot} || die;
#
# delete backups
#
INFO "Cleaning backups of subvolume \"$sroot/$svol\": $droot/$svol.*";
my @schedule;
foreach my $vol (keys %{$vol_info{$droot}}) {
if($vol =~ /^$svol\.([0-9]{4})([0-9]{2})([0-9]{2})/) {
push(@schedule, { name => "$droot/$vol", sort => $vol, date => [ $1, $2, $3 ] });
}
}
my @delete = schedule_deletion(
schedule => \@schedule,
today => \@today,
preserve_day_of_week => config_key($config_target, "preserve_day_of_week"),
preserve_daily => config_key($config_target, "target_preserve_daily"),
preserve_weekly => config_key($config_target, "target_preserve_weekly"),
preserve_monthly => config_key($config_target, "target_preserve_monthly"),
);
my $ret = btrfs_subvolume_delete($config_target, @delete);
if(defined($ret)) {
INFO "Deleted $ret subvolumes in: $droot/$svol.*";
$config_target->{subvol_deleted} = \@delete;
}
else {
$config_target->{ABORTED} = "btrfs subvolume delete command failed";
$target_aborted = 1;
}
$config_target->{schedule} = \@schedule;
} }
my $droot = $config_target->{droot} || die;
# #
# delete backups # delete snapshots
# #
INFO "Cleaning backups of subvolume \"$sroot/$svol\": $droot/$svol.*"; if($target_aborted) {
WARN "Skipping cleanup of snapshots for subvolume \"$sroot/$svol\", as at least one target aborted earlier";
next;
}
INFO "Cleaning snapshots: $sroot/$snapdir$svol.*";
my @schedule; my @schedule;
foreach my $vol (keys %{$vol_info{$droot}}) { foreach my $vol (keys %{$vol_info{$sroot}}) {
if($vol =~ /^$svol\.([0-9]{4})([0-9]{2})([0-9]{2})/) { if($vol =~ /^$snapdir$svol\.([0-9]{4})([0-9]{2})([0-9]{2})/) {
push(@schedule, { name => "$droot/$vol", sort => $vol, date => [ $1, $2, $3 ] }); push(@schedule, { name => "$sroot/$vol", sort => $vol, date => [ $1, $2, $3 ] });
} }
} }
my @delete = schedule_deletion( my @delete = schedule_deletion(
schedule => \@schedule, schedule => \@schedule,
today => \@today, today => \@today,
preserve_day_of_week => config_key($config_target, "preserve_day_of_week"), preserve_day_of_week => config_key($config_subvol, "preserve_day_of_week"),
preserve_daily => config_key($config_target, "target_preserve_daily"), preserve_daily => config_key($config_subvol, "snapshot_preserve_daily"),
preserve_weekly => config_key($config_target, "target_preserve_weekly"), preserve_weekly => config_key($config_subvol, "snapshot_preserve_weekly"),
preserve_monthly => config_key($config_target, "target_preserve_monthly"), preserve_monthly => config_key($config_subvol, "snapshot_preserve_monthly"),
); );
my $ret = btrfs_subvolume_delete($config_target, @delete); my $ret = btrfs_subvolume_delete($config_subvol, @delete);
if(defined($ret)) { if(defined($ret)) {
INFO "Deleted $ret subvolumes in: $droot/$svol.*"; INFO "Deleted $ret subvolumes in: $sroot/$snapdir$svol.*";
$config_target->{subvol_deleted} = \@delete; $config_subvol->{subvol_deleted} = \@delete;
} }
else { else {
$config_target->{ABORTED} = "btrfs subvolume delete command failed"; $config_subvol->{ABORTED} = "btrfs subvolume delete command failed";
$target_aborted = 1;
} }
$config_target->{schedule} = \@schedule; $config_subvol->{schedule} = \@schedule;
} }
#
# delete snapshots
#
if($target_aborted) {
WARN "Skipping cleanup of snapshots for subvolume \"$sroot/$svol\", as at least one target aborted earlier";
next;
}
INFO "Cleaning snapshots: $sroot/$snapdir$svol.*";
my @schedule;
foreach my $vol (keys %{$vol_info{$sroot}}) {
if($vol =~ /^$snapdir$svol\.([0-9]{4})([0-9]{2})([0-9]{2})/) {
push(@schedule, { name => "$sroot/$vol", sort => $vol, date => [ $1, $2, $3 ] });
}
}
my @delete = schedule_deletion(
schedule => \@schedule,
today => \@today,
preserve_day_of_week => config_key($config_subvol, "preserve_day_of_week"),
preserve_daily => config_key($config_subvol, "snapshot_preserve_daily"),
preserve_weekly => config_key($config_subvol, "snapshot_preserve_weekly"),
preserve_monthly => config_key($config_subvol, "snapshot_preserve_monthly"),
);
my $ret = btrfs_subvolume_delete($config_subvol, @delete);
if(defined($ret)) {
INFO "Deleted $ret subvolumes in: $sroot/$snapdir$svol.*";
$config_subvol->{subvol_deleted} = \@delete;
}
else {
$config_subvol->{ABORTED} = "btrfs subvolume delete command failed";
}
$config_subvol->{schedule} = \@schedule;
} }
} }

View File

@ -2,7 +2,7 @@
.SH NAME .SH NAME
btrbk \- backup tool for btrfs volumes btrbk \- backup tool for btrfs volumes
.SH SYNOPSIS .SH SYNOPSIS
\fBbtrbk\fR [\-\-version] [\-\-help] [\-c <file>] [\-v] [\-q] [\-l <level>] <command> [<args>] \fBbtrbk\fR [\-\-version] [\-\-help] [\-c <file>] [\-p] [\-v] [\-q] [\-l <level>] <command> [<args>]
.SH DESCRIPTION .SH DESCRIPTION
\fBbtrbk\fR is a backup tool for btrfs subvolumes, taking advantage of \fBbtrbk\fR is a backup tool for btrfs subvolumes, taking advantage of
btrfs specific capabilities to create atomic snapshots and transfer btrfs specific capabilities to create atomic snapshots and transfer
@ -27,6 +27,10 @@ Prints the synopsis and a list of the commands.
\-c <file> \-c <file>
Read the configuration from <file>. Read the configuration from <file>.
.TP .TP
\-p
Preserve all backups. Skips deletion of old backups, even if specified
in the configuration file.
.TP
\-v \-v
Verbose output. Identical to: \-l info. Verbose output. Identical to: \-l info.
.TP .TP
@ -57,7 +61,8 @@ found. If no common parent subvolume is found, a full backup is
created. created.
.PP .PP
In a last step, previous snapshots and backup subvolumes that are not In a last step, previous snapshots and backup subvolumes that are not
preserved by the current retention policy will be deleted. preserved by the current retention policy will be deleted. This step
will be skipped if the -p (preserve backups) option is present.
.RE .RE
.PP .PP
.B dryrun .B dryrun