mirror of https://github.com/digint/btrbk
btrbk: added "snapshot_name" configuration option
parent
0068e078f2
commit
3413425ed9
|
@ -1,12 +1,12 @@
|
|||
btrbk-current
|
||||
|
||||
* Bugfix: allow "0" as subvolume name (closes: #10)
|
||||
* Added configuration option "snapshot_name" (closes: #5).
|
||||
* Bugfix: allow "0" as subvolume name (closes: #10).
|
||||
* Bugfix: check source AND targets for determining snapshot postfix
|
||||
(closes: #11)
|
||||
(closes: #11).
|
||||
|
||||
btrbk-0.16
|
||||
|
||||
* Bugfix: correctly check retention policy for missing backups
|
||||
* Bugfix: correctly check retention policy for missing backups.
|
||||
|
||||
btrbk-0.15
|
||||
|
||||
|
|
173
btrbk
173
btrbk
|
@ -60,7 +60,8 @@ my %day_of_week_map = ( monday => 1, tuesday => 2, wednesday => 3, thursday => 4
|
|||
my %config_options = (
|
||||
# NOTE: the parser always maps "no" to undef
|
||||
# NOTE: keys "volume", "subvolume" and "target" are hardcoded
|
||||
snapshot_dir => { default => undef, accept_file => { relative => 1 }, append_trailing_slash => 1 },
|
||||
snapshot_dir => { default => undef, accept_file => { relative => 1 } },
|
||||
snapshot_name => { default => undef, accept_file => { name_only => 1 }, context => [ "subvolume" ] },
|
||||
receive_log => { default => undef, accept => [ "sidecar", "no" ], accept_file => { absolute => 1 }, deprecated => "removed" },
|
||||
incremental => { default => "yes", accept => [ "yes", "no", "strict" ] },
|
||||
snapshot_create_always => { default => undef, accept => [ "yes", "no" ] },
|
||||
|
@ -187,7 +188,12 @@ sub vinfo($;$)
|
|||
|
||||
die unless($config);
|
||||
|
||||
my %info = ( URL => $url );
|
||||
my $name = $url;
|
||||
$name =~ s/^.*\///;
|
||||
my %info = (
|
||||
URL => $url,
|
||||
NAME => $name,
|
||||
);
|
||||
|
||||
if($url =~ /^ssh:\/\/(\S+?)(\/\S+)$/) {
|
||||
my ($host, $path) = ($1, $2);
|
||||
|
@ -256,6 +262,14 @@ sub vinfo_read_detail($)
|
|||
}
|
||||
$vol->{$_} = $detail->{$_};
|
||||
}
|
||||
|
||||
if($vol->{RSH_TYPE} && ($vol->{RSH_TYPE} eq "ssh")) {
|
||||
$vol->{REAL_URL} = "ssh://$vol->{HOST}$vol->{REAL_PATH}";
|
||||
} else {
|
||||
$vol->{REAL_URL} = $vol->{REAL_PATH};
|
||||
}
|
||||
|
||||
|
||||
DEBUG "vinfo updated for: $vol->{URL}";
|
||||
TRACE(Data::Dumper->Dump([$vol], ["vinfo{$vol->{URL}}"]));
|
||||
|
||||
|
@ -325,6 +339,12 @@ sub check_file($$;$$)
|
|||
return undef;
|
||||
}
|
||||
}
|
||||
elsif($accept->{name_only}) {
|
||||
if($file =~ /\//) {
|
||||
ERROR "Option \"$key\" is not a valid file name in \"$config_file\" line $.: $file";
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
else {
|
||||
die("accept_type must contain either 'relative' or 'absolute'");
|
||||
}
|
||||
|
@ -395,7 +415,7 @@ sub parse_config(@)
|
|||
{
|
||||
while($cur->{CONTEXT} ne "volume") {
|
||||
if(($cur->{CONTEXT} eq "root") || (not $cur->{PARENT})) {
|
||||
ERROR "subvolume keyword outside volume context, in \"$file\" line $.";
|
||||
ERROR "Subvolume keyword outside volume context, in \"$file\" line $.";
|
||||
return undef;
|
||||
}
|
||||
$cur = $cur->{PARENT} || die;
|
||||
|
@ -406,7 +426,7 @@ sub parse_config(@)
|
|||
$value =~ s/\/+$//; # remove trailing slash
|
||||
$value =~ s/^\/+//; # remove leading slash
|
||||
if($value =~ /\//) {
|
||||
ERROR "subvolume contains slashes: \"$value\" in \"$file\" line $.";
|
||||
ERROR "Subvolume contains slashes: \"$value\" in \"$file\" line $.";
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
@ -427,14 +447,14 @@ sub parse_config(@)
|
|||
DEBUG "config: context changed to: $cur->{CONTEXT}";
|
||||
}
|
||||
if($cur->{CONTEXT} ne "subvolume") {
|
||||
ERROR "target keyword outside subvolume context, in \"$file\" line $.";
|
||||
ERROR "Target keyword outside subvolume context, in \"$file\" line $.";
|
||||
return undef;
|
||||
}
|
||||
if($value =~ /^(\S+)\s+(\S+)$/)
|
||||
{
|
||||
my ($target_type, $droot) = ($1, $2);
|
||||
unless(grep(/^$target_type$/, @config_target_types)) {
|
||||
ERROR "unknown target type \"$target_type\" in \"$file\" line $.";
|
||||
ERROR "Unknown target type \"$target_type\" in \"$file\" line $.";
|
||||
return undef;
|
||||
}
|
||||
# be very strict about file options, for security sake
|
||||
|
@ -474,10 +494,6 @@ sub parse_config(@)
|
|||
TRACE "option \"$key=$value\" is a valid file, accepted";
|
||||
$value =~ s/\/+$//; # remove trailing slash
|
||||
$value =~ s/^\/+/\//; # sanitize leading slash
|
||||
if($config_options{$key}->{append_trailing_slash}) {
|
||||
TRACE "append_trailing_slash is specified for option \"$key\", adding trailing slash";
|
||||
$value .= '/';
|
||||
}
|
||||
}
|
||||
elsif($config_options{$key}->{accept_regexp}) {
|
||||
my $match = $config_options{$key}->{accept_regexp};
|
||||
|
@ -494,6 +510,12 @@ sub parse_config(@)
|
|||
ERROR "Unsupported value \"$value\" for option \"$key\" in \"$file\" line $.";
|
||||
return undef;
|
||||
}
|
||||
|
||||
if($config_options{$key}->{context} && !grep(/^$cur->{CONTEXT}$/, @{$config_options{$key}->{context}})) {
|
||||
ERROR "Option \"$key\" is only allowed in " . join(" or ", map("\"$_\"", @{$config_options{$key}->{context}})) . " context, in \"$file\" line $.";
|
||||
return undef;
|
||||
}
|
||||
|
||||
DEBUG "config: adding option \"$key=$value\" to $cur->{CONTEXT} context";
|
||||
$value = undef if($value eq "no"); # we don't want to check for "no" all the time
|
||||
$cur->{$key} = $value;
|
||||
|
@ -918,7 +940,6 @@ sub btrfs_send_receive($$$)
|
|||
my $target_path = $target->{PATH} // die;
|
||||
my $target_rsh = $target->{RSH} || "";
|
||||
my $parent_path = $parent ? $parent->{PATH} : undef;
|
||||
my $now = localtime;
|
||||
|
||||
my $snapshot_name = $snapshot_path;
|
||||
$snapshot_name =~ s/^.*\///;
|
||||
|
@ -1504,6 +1525,7 @@ MAIN:
|
|||
#
|
||||
# fill vol_info hash, basic checks on configuration
|
||||
#
|
||||
my %snapshot_check;
|
||||
foreach my $config_vol (@{$config->{VOLUME}})
|
||||
{
|
||||
next if($config_vol->{ABORTED});
|
||||
|
@ -1518,6 +1540,19 @@ MAIN:
|
|||
{
|
||||
next if($config_subvol->{ABORTED});
|
||||
my $svol = vinfo($config_subvol->{url}, $config_vol);
|
||||
|
||||
# check for duplicate snapshot locations
|
||||
my $snapdir = config_key($config_subvol, "snapshot_dir") || "";
|
||||
my $snapshot_basename = config_key($config_subvol, "snapshot_name") // $svol->{NAME} // die;
|
||||
my $snapshot_target = "$sroot->{REAL_URL}/$snapdir/$snapshot_basename";
|
||||
if(my $prev = $snapshot_check{$snapshot_target}) {
|
||||
ERROR "Subvolume \"$prev\" and \"$svol->{PRINT}\" will create same snapshot: $snapshot_target";
|
||||
ERROR "Please fix \"snapshot_name\" configuration options!";
|
||||
exit 1;
|
||||
}
|
||||
$snapshot_check{$snapshot_target} = $svol->{PRINT};
|
||||
|
||||
# read subvolume detail
|
||||
unless(vinfo_read_detail($svol)) {
|
||||
$config_subvol->{ABORTED} = "Failed to fetch subvolume detail";
|
||||
WARN "Skipping subvolume \"$svol->{URL}\": $config_subvol->{ABORTED}";
|
||||
|
@ -1529,7 +1564,7 @@ MAIN:
|
|||
next;
|
||||
}
|
||||
|
||||
unless(subvol($sroot, $config_subvol->{rel_path})) { # !!! TODO: maybe check uuid here?
|
||||
unless(subvol($sroot, $config_subvol->{rel_path})) { # !!! TODO: check uuid here!
|
||||
$config_subvol->{ABORTED} = "Subvolume \"$svol->{URL}\" not present in btrfs subvolume list for \"$sroot->{URL}\"";
|
||||
WARN "Skipping subvolume \"$svol->{URL}\": $config_subvol->{ABORTED}";
|
||||
next;
|
||||
|
@ -1543,6 +1578,15 @@ MAIN:
|
|||
next;
|
||||
}
|
||||
|
||||
# check for duplicate snapshot locations
|
||||
my $snapshot_backup_target = "$droot->{REAL_URL}/$snapshot_basename";
|
||||
if(my $prev = $snapshot_check{$snapshot_backup_target}) {
|
||||
ERROR "Subvolume \"$prev\" and \"$svol->{PRINT}\" will create same snapshot: $snapshot_target";
|
||||
ERROR "Please fix \"snapshot_name\" configuration options!";
|
||||
exit 1;
|
||||
}
|
||||
$snapshot_check{$snapshot_backup_target} = $svol->{PRINT};
|
||||
|
||||
unless(vinfo_read_subvolumes($droot)) {
|
||||
$config_target->{ABORTED} = "Failed to fetch subvolume list";
|
||||
WARN "Skipping target \"$droot->{URL}\": $config_target->{ABORTED}";
|
||||
|
@ -1653,7 +1697,6 @@ MAIN:
|
|||
# create snapshots
|
||||
#
|
||||
my $timestamp = sprintf("%04d%02d%02d", @today);
|
||||
my %snapshot_cache;
|
||||
foreach my $config_vol (@{$config->{VOLUME}})
|
||||
{
|
||||
next if($config_vol->{ABORTED});
|
||||
|
@ -1663,44 +1706,13 @@ MAIN:
|
|||
next if($config_subvol->{ABORTED});
|
||||
my $svol = vinfo($config_subvol->{url});
|
||||
my $snapdir = config_key($config_subvol, "snapshot_dir") || "";
|
||||
my $snapshot_name;
|
||||
my $snapshot_basename = $config_subvol->{rel_path}; # !!! TODO: add configuration option for this
|
||||
if($svol->{SNAPSHOT}) # !!! TODO: guess we broke this, rethink what happens if same svol is used on different config lines
|
||||
{
|
||||
$snapshot_name = $svol->{SNAPSHOT}->{NAME};
|
||||
}
|
||||
else
|
||||
{
|
||||
# find unique snapshot name
|
||||
my @lookup = keys %{$sroot->{SUBVOL_INFO}};
|
||||
@lookup = grep s/^$snapdir// , @lookup;
|
||||
foreach my $config_target (@{$config_subvol->{TARGET}}) {
|
||||
my $droot = vinfo($config_target->{url});
|
||||
push(@lookup, keys %{$droot->{SUBVOL_INFO}});
|
||||
}
|
||||
@lookup = grep /^\Q$snapshot_basename.$timestamp\E(_[0-9]+)?$/ ,@lookup;
|
||||
TRACE "Present snapshot names for \"$svol->{URL}\": " . join(', ', @lookup);
|
||||
@lookup = map { /_([0-9]+)$/ ? $1 : 0 } @lookup;
|
||||
@lookup = sort { $b <=> $a } @lookup;
|
||||
my $postfix_counter = $lookup[0] // -1;
|
||||
$postfix_counter++;
|
||||
|
||||
$snapshot_name = $snapshot_basename . '.' . $timestamp . ($postfix_counter ? "_$postfix_counter" : "");
|
||||
}
|
||||
my $snapshot_basename = config_key($config_subvol, "snapshot_name") // $svol->{NAME} // die;
|
||||
|
||||
# check if we need to create a snapshot
|
||||
my $create_snapshot = config_key($config_subvol, "snapshot_create_always");
|
||||
foreach my $config_target (@{$config_subvol->{TARGET}})
|
||||
{
|
||||
foreach my $config_target (@{$config_subvol->{TARGET}}) {
|
||||
next if($config_target->{ABORTED});
|
||||
my $droot = vinfo($config_target->{url});
|
||||
if(subvol($droot, $snapshot_name)) {
|
||||
$config_target->{ABORTED} = "Subvolume already exists at destination: $droot->{URL}/$snapshot_name";
|
||||
WARN "Skipping target: $config_target->{ABORTED}";
|
||||
next;
|
||||
}
|
||||
if($config_target->{target_type} eq "send-receive") {
|
||||
$create_snapshot = 1;
|
||||
}
|
||||
$create_snapshot = 1 if($config_target->{target_type} eq "send-receive");
|
||||
}
|
||||
unless($create_snapshot) {
|
||||
$config_subvol->{ABORTED} = "No targets defined for subvolume: $svol->{URL}";
|
||||
|
@ -1708,20 +1720,29 @@ MAIN:
|
|||
next;
|
||||
}
|
||||
|
||||
# make snapshot of svol, if not already created by another job
|
||||
unless($svol->{SNAPSHOT})
|
||||
{
|
||||
INFO "Creating subvolume snapshot for: $svol->{PRINT}";
|
||||
if(btrfs_snapshot($svol, "$sroot->{PATH}/$snapdir/$snapshot_name")) {
|
||||
my $snapvol = vinfo("$sroot->{URL}/$snapdir/$snapshot_name", $config_vol);
|
||||
$snapvol->{SNAP_BASENAME} = $snapshot_basename;
|
||||
$svol->{SNAPSHOT} = $snapvol;
|
||||
}
|
||||
else {
|
||||
$config_subvol->{ABORTED} = "Failed to create snapshot: $svol->{PRINT} -> $sroot->{PRINT}/$snapdir/$snapshot_name";
|
||||
WARN "Skipping subvolume section: $config_subvol->{ABORTED}";
|
||||
$svol->{SNAPSHOT} = { ERROR => $config_subvol->{ABORTED} };
|
||||
}
|
||||
# find unique snapshot name
|
||||
my @lookup = keys %{$sroot->{SUBVOL_INFO}};
|
||||
@lookup = grep s/^\Q$snapdir\E\/// , @lookup;
|
||||
foreach my $config_target (@{$config_subvol->{TARGET}}) {
|
||||
my $droot = vinfo($config_target->{url});
|
||||
push(@lookup, keys %{$droot->{SUBVOL_INFO}});
|
||||
}
|
||||
@lookup = grep /^\Q$snapshot_basename.$timestamp\E(_[0-9]+)?$/ ,@lookup;
|
||||
TRACE "Present snapshot names for \"$svol->{URL}\": " . join(', ', @lookup);
|
||||
@lookup = map { /_([0-9]+)$/ ? $1 : 0 } @lookup;
|
||||
@lookup = sort { $b <=> $a } @lookup;
|
||||
my $postfix_counter = $lookup[0] // -1;
|
||||
$postfix_counter++;
|
||||
my $snapshot_name = $snapshot_basename . '.' . $timestamp . ($postfix_counter ? "_$postfix_counter" : "");
|
||||
|
||||
# finally create the snapshot
|
||||
INFO "Creating subvolume snapshot for: $svol->{PRINT}";
|
||||
if(btrfs_snapshot($svol, "$sroot->{PATH}/$snapdir/$snapshot_name")) {
|
||||
$config_subvol->{SNAPSHOT} = vinfo("$sroot->{URL}/$snapdir/$snapshot_name", $config_vol);
|
||||
}
|
||||
else {
|
||||
$config_subvol->{ABORTED} = "Failed to create snapshot: $svol->{PRINT} -> $sroot->{PRINT}/$snapdir/$snapshot_name";
|
||||
WARN "Skipping subvolume section: $config_subvol->{ABORTED}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1738,7 +1759,7 @@ MAIN:
|
|||
next if($config_subvol->{ABORTED});
|
||||
my $svol = vinfo($config_subvol->{url});
|
||||
my $snapdir = config_key($config_subvol, "snapshot_dir") || "";
|
||||
my $snapshot_basename = $config_subvol->{rel_path}; # TODO: add configuration option for this, store into svol
|
||||
my $snapshot_basename = config_key($config_subvol, "snapshot_name") // $svol->{NAME} // die;
|
||||
|
||||
foreach my $config_target (@{$config_subvol->{TARGET}})
|
||||
{
|
||||
|
@ -1770,7 +1791,7 @@ MAIN:
|
|||
|
||||
# check if the target would be preserved
|
||||
my ($date, $date_ext) = get_date_tag($child->{SUBVOL_PATH});
|
||||
next unless($date && ($child->{SUBVOL_PATH} =~ /^\Q$snapdir$snapshot_basename.\E/));
|
||||
next unless($date && ($child->{SUBVOL_PATH} =~ /^\Q$snapdir\/$snapshot_basename.\E/));
|
||||
push(@schedule, { value => $child, date => $date, date_ext => $date_ext }),
|
||||
}
|
||||
}
|
||||
|
@ -1828,13 +1849,13 @@ MAIN:
|
|||
|
||||
# skip creation if resume_missing failed
|
||||
next if($config_target->{ABORTED});
|
||||
die unless($svol->{SNAPSHOT});
|
||||
die unless($config_subvol->{SNAPSHOT});
|
||||
|
||||
# finally receive the previously created snapshot
|
||||
INFO "Creating subvolume backup (send-receive) for: $svol->{URL}";
|
||||
my ($latest_common_src, $latest_common_target) = get_latest_common($sroot, $svol, $droot);
|
||||
macro_send_receive($config_target,
|
||||
snapshot => $svol->{SNAPSHOT},
|
||||
snapshot => $config_subvol->{SNAPSHOT},
|
||||
target => $droot,
|
||||
parent => $latest_common_src, # this is <undef> if no common found
|
||||
);
|
||||
|
@ -1897,7 +1918,7 @@ MAIN:
|
|||
my $ret = btrfs_subvolume_delete($config_target, @$delete);
|
||||
if(defined($ret)) {
|
||||
INFO "Deleted $ret subvolumes in: $droot->{URL}/$snapshot_basename.*";
|
||||
$config_target->{subvol_deleted} = $delete;
|
||||
$config_target->{SUBVOL_DELETED} = $delete;
|
||||
}
|
||||
else {
|
||||
$config_target->{ABORTED} = "btrfs subvolume delete command failed";
|
||||
|
@ -1912,11 +1933,11 @@ MAIN:
|
|||
WARN "Skipping cleanup of snapshots for subvolume \"$svol->{URL}\", as at least one target aborted earlier";
|
||||
next;
|
||||
}
|
||||
INFO "Cleaning snapshots: $sroot->{URL}/$snapdir$snapshot_basename.*";
|
||||
INFO "Cleaning snapshots: $sroot->{URL}/$snapdir/$snapshot_basename.*";
|
||||
my @schedule;
|
||||
foreach my $vol (keys %{$sroot->{SUBVOL_INFO}}) {
|
||||
my ($date, $date_ext) = get_date_tag($vol);
|
||||
next unless($date && ($vol =~ /^\Q$snapdir$snapshot_basename.\E/));
|
||||
next unless($date && ($vol =~ /^\Q$snapdir\/$snapshot_basename.\E/));
|
||||
push(@schedule, { value => "$sroot->{URL}/$vol", name => $vol, date => $date, date_ext => $date_ext });
|
||||
}
|
||||
my (undef, $delete) = schedule(
|
||||
|
@ -1930,8 +1951,8 @@ MAIN:
|
|||
);
|
||||
my $ret = btrfs_subvolume_delete($config_subvol, @$delete);
|
||||
if(defined($ret)) {
|
||||
INFO "Deleted $ret subvolumes in: $sroot->{URL}/$snapdir$snapshot_basename.*";
|
||||
$config_subvol->{subvol_deleted} = $delete;
|
||||
INFO "Deleted $ret subvolumes in: $sroot->{URL}/$snapdir/$snapshot_basename.*";
|
||||
$config_subvol->{SUBVOL_DELETED} = $delete;
|
||||
}
|
||||
else {
|
||||
$config_subvol->{ABORTED} = "btrfs subvolume delete command failed";
|
||||
|
@ -1974,9 +1995,9 @@ MAIN:
|
|||
print "!!! Subvolume \"$config_subvol->{rel_path}\" aborted: $config_subvol->{ABORTED}\n";
|
||||
$err_count++ unless($config_subvol->{ABORTED_NOERR});
|
||||
}
|
||||
print "+++ $svol->{SNAPSHOT}->{PRINT}\n" if($svol->{SNAPSHOT}->{PRINT});
|
||||
if($config_subvol->{subvol_deleted}) {
|
||||
print "--- $_\n" foreach(sort { $b cmp $a} @{$config_subvol->{subvol_deleted}});
|
||||
print "+++ $config_subvol->{SNAPSHOT}->{PRINT}\n" if($config_subvol->{SNAPSHOT});
|
||||
if($config_subvol->{SUBVOL_DELETED}) {
|
||||
print "--- $_\n" foreach(sort { $b cmp $a} @{$config_subvol->{SUBVOL_DELETED}});
|
||||
}
|
||||
foreach my $config_target (@{$config_subvol->{TARGET}})
|
||||
{
|
||||
|
@ -1988,8 +2009,8 @@ MAIN:
|
|||
print "$create_mode $_->{received_name}\n";
|
||||
}
|
||||
|
||||
if($config_target->{subvol_deleted}) {
|
||||
print "--- $_\n" foreach(sort { $b cmp $a} @{$config_target->{subvol_deleted}});
|
||||
if($config_target->{SUBVOL_DELETED}) {
|
||||
print "--- $_\n" foreach(sort { $b cmp $a} @{$config_target->{SUBVOL_DELETED}});
|
||||
}
|
||||
|
||||
if($config_target->{ABORTED}) {
|
||||
|
|
|
@ -13,7 +13,7 @@ generated. The retention policy as well as other options can be
|
|||
defined for each backup.
|
||||
.PP
|
||||
The options specified always apply to the last section encountered,
|
||||
overriding the same option of the next higher section. This means that
|
||||
superseding the values set in upper-level sections. This means that
|
||||
global options must be set before any sections are defined.
|
||||
.PP
|
||||
The sections are:
|
||||
|
@ -44,14 +44,15 @@ allowed.
|
|||
The configuration options are:
|
||||
.TP
|
||||
\fBsnapshot_dir\fR <directory>
|
||||
Directory in which the btrfs snapshots are created. Relative to
|
||||
Directory in which the btrfs snapshots are created, relative to
|
||||
\fI<volume-directory>\fR of the \fIvolume\fR section. Note that btrbk
|
||||
does not autmatically create this directory, and the snapshot creation
|
||||
will fail if it is not present.
|
||||
.TP
|
||||
\fBincremental\fR yes|no|strict
|
||||
Perform incremental backups. Defaults to \(lqyes\(rq. If set to
|
||||
\(lqstrict\(rq, non-incremental (initial) backups are never created.
|
||||
\fBsnapshot_name\fR <basename>
|
||||
Base name of the created snapshot (and backup). Defaults to
|
||||
\fI<subvolume-name>\fR. This option is only valid in the \fItarget\fR
|
||||
section.
|
||||
.TP
|
||||
\fBsnapshot_create_always\fR yes|no
|
||||
If set, the snapshots are always created, even if the backup subvolume
|
||||
|
@ -62,6 +63,10 @@ is reachable again. Useful for laptop filesystems in order to make
|
|||
sure the snapshots are created even if you are on the road. Defaults
|
||||
to \(lqno\(rq.
|
||||
.TP
|
||||
\fBincremental\fR yes|no|strict
|
||||
Perform incremental backups. Defaults to \(lqyes\(rq. If set to
|
||||
\(lqstrict\(rq, non-incremental (initial) backups are never created.
|
||||
.TP
|
||||
\fBresume_missing\fR yes|no
|
||||
If set, the backups in the target directory are compared to the source
|
||||
snapshots, and missing backups are created if needed (complying to the
|
||||
|
|
Loading…
Reference in New Issue