mirror of https://github.com/digint/btrbk
btrbk: added "snapshot_create onchange", which skips snapshot creation if the latest snapshot is up-to-date (i.e. has same generation as the source subvolume)
parent
27e150878c
commit
16355b848d
|
@ -1,3 +1,9 @@
|
||||||
|
btrbk-current
|
||||||
|
|
||||||
|
* Added "snapshot_create onchange", which skips snapshot creation if
|
||||||
|
the latest snapshot is up-to-date (i.e. has same generation as the
|
||||||
|
source subvolume)
|
||||||
|
|
||||||
btrbk-0.18.0
|
btrbk-0.18.0
|
||||||
|
|
||||||
* MIGRATION
|
* MIGRATION
|
||||||
|
|
47
btrbk
47
btrbk
|
@ -47,7 +47,7 @@ use Date::Calc qw(Today Delta_Days Day_of_Week);
|
||||||
use Getopt::Std;
|
use Getopt::Std;
|
||||||
use Data::Dumper;
|
use Data::Dumper;
|
||||||
|
|
||||||
our $VERSION = "0.18.0";
|
our $VERSION = "0.19.0-dev";
|
||||||
our $AUTHOR = 'Axel Burri <axel@tty0.ch>';
|
our $AUTHOR = 'Axel Burri <axel@tty0.ch>';
|
||||||
our $PROJECT_HOME = '<http://www.digint.ch/btrbk/>';
|
our $PROJECT_HOME = '<http://www.digint.ch/btrbk/>';
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ my %config_options = (
|
||||||
# NOTE: keys "volume", "subvolume" and "target" are hardcoded
|
# NOTE: keys "volume", "subvolume" and "target" are hardcoded
|
||||||
snapshot_dir => { default => undef, accept_file => { relative => 1 } },
|
snapshot_dir => { default => undef, accept_file => { relative => 1 } },
|
||||||
snapshot_name => { default => undef, accept_file => { name_only => 1 }, context => [ "subvolume" ] },
|
snapshot_name => { default => undef, accept_file => { name_only => 1 }, context => [ "subvolume" ] },
|
||||||
snapshot_create => { default => "always", accept => [ "no", "always", "ondemand" ] },
|
snapshot_create => { default => "always", accept => [ "no", "always", "ondemand", "onchange" ] },
|
||||||
incremental => { default => "yes", accept => [ "yes", "no", "strict" ] },
|
incremental => { default => "yes", accept => [ "yes", "no", "strict" ] },
|
||||||
resume_missing => { default => "yes", accept => [ "yes", "no" ] },
|
resume_missing => { default => "yes", accept => [ "yes", "no" ] },
|
||||||
preserve_day_of_week => { default => "sunday", accept => [ (keys %day_of_week_map) ] },
|
preserve_day_of_week => { default => "sunday", accept => [ (keys %day_of_week_map) ] },
|
||||||
|
@ -1173,6 +1173,27 @@ sub get_latest_common($$$;$)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub get_latest_snapshot_child($$)
|
||||||
|
{
|
||||||
|
my $sroot = shift || die;
|
||||||
|
my $svol = shift // die;
|
||||||
|
my $latest = undef;
|
||||||
|
my $gen = -1;
|
||||||
|
foreach (get_snapshot_children($sroot, $svol)) {
|
||||||
|
if($_->{gen} > $gen) {
|
||||||
|
$latest = $_;
|
||||||
|
$gen = $_->{gen};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($latest) {
|
||||||
|
DEBUG "Latest snapshot child for \"$svol->{PRINT}#$svol->{gen}\" is: $latest->{PRINT}#$latest->{gen}";
|
||||||
|
} else {
|
||||||
|
DEBUG "No latest snapshots found for: $svol->{PRINT}";
|
||||||
|
}
|
||||||
|
return $latest;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sub _origin_tree
|
sub _origin_tree
|
||||||
{
|
{
|
||||||
my $prefix = shift;
|
my $prefix = shift;
|
||||||
|
@ -1782,13 +1803,23 @@ MAIN:
|
||||||
my $snapshot_basename = config_key($config_subvol, "snapshot_name") // die;
|
my $snapshot_basename = config_key($config_subvol, "snapshot_name") // die;
|
||||||
|
|
||||||
# check if we need to create a snapshot
|
# check if we need to create a snapshot
|
||||||
my $snapshot_create = config_key($config_subvol, "snapshot_create") // "no";
|
my $snapshot_create = config_key($config_subvol, "snapshot_create");
|
||||||
if($snapshot_create eq "no") {
|
if(not $snapshot_create) {
|
||||||
DEBUG "Snapshot creation disabled: snapshot_create=no";
|
DEBUG "Snapshot creation disabled (snapshot_create=no)";
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
if($snapshot_create eq "always") {
|
elsif($snapshot_create eq "always") {
|
||||||
DEBUG "Snapshot creation enabled: snapshot_create=always";
|
DEBUG "Snapshot creation enabled (snapshot_create=always)";
|
||||||
|
}
|
||||||
|
elsif($snapshot_create eq "onchange") {
|
||||||
|
# check if latest snapshot is up-to-date with source subvolume (by generation)
|
||||||
|
my $latest = get_latest_snapshot_child($sroot, $svol);
|
||||||
|
if($latest && ($latest->{gen} == $svol->{gen})) {
|
||||||
|
INFO "Snapshot creation skipped: snapshot_create=onchange, snapshot is up-to-date: $latest->{PRINT}";
|
||||||
|
$config_subvol->{SNAPSHOT_UP_TO_DATE} = $latest;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
DEBUG "Snapshot creation enabled: snapshot_create=onchange, gen=$svol->{gen} > snapshot_gen=$latest->{gen}";
|
||||||
}
|
}
|
||||||
elsif($snapshot_create eq "ondemand") {
|
elsif($snapshot_create eq "ondemand") {
|
||||||
my $snapshot_needed = 0;
|
my $snapshot_needed = 0;
|
||||||
|
@ -2106,6 +2137,7 @@ MAIN:
|
||||||
push @subvol_out, "!!! Subvolume \"$svol->{PRINT}\" aborted: $config_subvol->{ABORTED}";
|
push @subvol_out, "!!! Subvolume \"$svol->{PRINT}\" aborted: $config_subvol->{ABORTED}";
|
||||||
$err_count++ unless($config_subvol->{ABORTED_NOERR});
|
$err_count++ unless($config_subvol->{ABORTED_NOERR});
|
||||||
}
|
}
|
||||||
|
push @subvol_out, "=== $config_subvol->{SNAPSHOT_UP_TO_DATE}->{PRINT}" if($config_subvol->{SNAPSHOT_UP_TO_DATE});
|
||||||
push @subvol_out, "+++ $config_subvol->{SNAPSHOT}->{PRINT}" if($config_subvol->{SNAPSHOT});
|
push @subvol_out, "+++ $config_subvol->{SNAPSHOT}->{PRINT}" if($config_subvol->{SNAPSHOT});
|
||||||
if($config_subvol->{SUBVOL_DELETED}) {
|
if($config_subvol->{SUBVOL_DELETED}) {
|
||||||
push @subvol_out, "--- $_->{PRINT}" foreach(sort { $a->{PATH} cmp $b->{PATH} } @{$config_subvol->{SUBVOL_DELETED}});
|
push @subvol_out, "--- $_->{PRINT}" foreach(sort { $a->{PATH} cmp $b->{PATH} } @{$config_subvol->{SUBVOL_DELETED}});
|
||||||
|
@ -2146,6 +2178,7 @@ MAIN:
|
||||||
print " Date: " . localtime($start_time) . "\n";
|
print " Date: " . localtime($start_time) . "\n";
|
||||||
print " Config: $config->{SRC_FILE}\n";
|
print " Config: $config->{SRC_FILE}\n";
|
||||||
print "\nLegend:\n";
|
print "\nLegend:\n";
|
||||||
|
print " === up-to-date subvolume (source snapshot)\n";
|
||||||
print " +++ created subvolume (source snapshot)\n";
|
print " +++ created subvolume (source snapshot)\n";
|
||||||
print " --- deleted subvolume\n";
|
print " --- deleted subvolume\n";
|
||||||
print " *** received subvolume (non-incremental)\n";
|
print " *** received subvolume (non-incremental)\n";
|
||||||
|
|
|
@ -55,15 +55,18 @@ will fail if it is not present.
|
||||||
backup). This option is only valid in the \fItarget\fR
|
backup). This option is only valid in the \fItarget\fR
|
||||||
section. Defaults to \fI<subvolume-name>\fR.
|
section. Defaults to \fI<subvolume-name>\fR.
|
||||||
.TP
|
.TP
|
||||||
\fBsnapshot_create\fR always|ondemand|no
|
\fBsnapshot_create\fR always|ondemand|onchange|no
|
||||||
If set to \[lq]ondemand\[rq], the snapshots are only created if the
|
If set to \[lq]ondemand\[rq], snapshots are only created if the target
|
||||||
target subvolume is reachable (useful if you are tight on disk space
|
subvolume is reachable (useful if you are tight on disk space and you
|
||||||
and you only need btrbk for backups to an external disk which is not
|
only need btrbk for backups to an external disk which is not always
|
||||||
always connected). If set to \[lq]always\[rq], the snapshots are
|
connected). If set to \[lq]onchange\[rq], snapshots are only created
|
||||||
always created, regardless of the target reachability. If set to
|
if the source subvolume has changed since the last snapshot (more
|
||||||
\[lq]no\[rq], the snapshots are never created (useful in conjunction
|
precisely: if the btrfs generation has been increased since the last
|
||||||
with the \fIresume_missing\fR option if another instance of btrbk is
|
snapshot). If set to \[lq]always\[rq], snapshots are always
|
||||||
taking care of snapshot creation). Defaults to \[lq]always\[rq].
|
created. If set to \[lq]no\[rq], the snapshots are never created
|
||||||
|
(useful in conjunction with the \fIresume_missing\fR option if another
|
||||||
|
instance of btrbk is taking care of snapshot creation). Defaults to
|
||||||
|
\[lq]always\[rq].
|
||||||
.TP
|
.TP
|
||||||
\fBincremental\fR yes|no|strict
|
\fBincremental\fR yes|no|strict
|
||||||
If set, incremental backups are created. If set to \[lq]strict\[rq],
|
If set, incremental backups are created. If set to \[lq]strict\[rq],
|
||||||
|
|
Loading…
Reference in New Issue