mirror of https://github.com/digint/btrbk
btrbk: add support for deleting directories in snapshots and set them read-only
parent
2bda102f94
commit
cff6c47900
57
btrbk
57
btrbk
|
|
@ -152,6 +152,7 @@ my %config_options = (
|
|||
send_compressed_data => { default => undef, accept => [qw( yes no )] }, # NOTE: implies send_protocol=2
|
||||
|
||||
snapshot_qgroup_destroy => { default => undef, accept => [qw( yes no )], context => [qw( global volume subvolume )] },
|
||||
snapshot_delete_dir => { default => undef, accept_file => { relative => 1 }, allow_multiple => 1, context => [qw( global volume subvolume )] },
|
||||
target_qgroup_destroy => { default => undef, accept => [qw( yes no )] },
|
||||
archive_qgroup_destroy => { default => undef, accept => [qw( yes no )], context => [qw( global )] },
|
||||
|
||||
|
|
@ -291,10 +292,12 @@ my @btrfs_cmd = (
|
|||
"btrfs receive",
|
||||
"btrfs filesystem usage",
|
||||
"btrfs qgroup destroy",
|
||||
"btrfs property set",
|
||||
);
|
||||
my @system_cmd = (
|
||||
"readlink",
|
||||
"test",
|
||||
"rm",
|
||||
);
|
||||
my %backend_cmd_map = (
|
||||
"btrfs-progs-btrbk" => { map +( $_ => [ s/ /-/gr ] ), @btrfs_cmd },
|
||||
|
|
@ -1365,10 +1368,11 @@ sub btrfs_subvolume_find_new($$;$)
|
|||
|
||||
|
||||
# returns $target, or undef on error
|
||||
sub btrfs_subvolume_snapshot($$)
|
||||
sub btrfs_subvolume_snapshot($$;$)
|
||||
{
|
||||
my $svol = shift || die;
|
||||
my $target_vol = shift // die;
|
||||
my $readonly = shift // 1;
|
||||
my $target_path = $target_vol->{PATH} // die;
|
||||
my $src_path = $svol->{PATH} // die;
|
||||
INFO "[snapshot] source: $svol->{PRINT}";
|
||||
|
|
@ -1377,7 +1381,8 @@ sub btrfs_subvolume_snapshot($$)
|
|||
vinfo_prefixed_keys("target", $target_vol),
|
||||
vinfo_prefixed_keys("source", $svol),
|
||||
);
|
||||
my $ret = run_cmd(cmd => vinfo_cmd($svol, "btrfs subvolume snapshot", '-r', { unsafe => $src_path }, { unsafe => $target_path } ),
|
||||
my @ro_flag = $readonly ? ('-r') : ();
|
||||
my $ret = run_cmd(cmd => vinfo_cmd($svol, "btrfs subvolume snapshot", @ro_flag, { unsafe => $src_path }, { unsafe => $target_path } ),
|
||||
rsh => vinfo_rsh($svol),
|
||||
filter_stderr => \&_btrfs_filter_stderr,
|
||||
);
|
||||
|
|
@ -1390,6 +1395,23 @@ sub btrfs_subvolume_snapshot($$)
|
|||
}
|
||||
|
||||
|
||||
sub btrfs_subvolume_set_readonly($)
|
||||
{
|
||||
my $vol = shift // die;
|
||||
my $path = $vol->{PATH} // die;
|
||||
INFO "[snapshot] set readonly: $vol->{PRINT}";
|
||||
my $ret = run_cmd(cmd => vinfo_cmd($vol, "btrfs property set", { unsafe => $path }, 'ro', 'true'),
|
||||
rsh => vinfo_rsh($vol),
|
||||
filter_stderr => \&_btrfs_filter_stderr,
|
||||
);
|
||||
unless(defined($ret)) {
|
||||
ERROR "Failed to set snapshot read-only: $vol->{PRINT}", @stderr;
|
||||
return undef;
|
||||
}
|
||||
return $vol;
|
||||
}
|
||||
|
||||
|
||||
sub btrfs_subvolume_delete($@)
|
||||
{
|
||||
my $vol = shift // die;
|
||||
|
|
@ -6697,8 +6719,31 @@ MAIN:
|
|||
# finally create the snapshot
|
||||
INFO "Creating subvolume snapshot for: $svol->{PRINT}";
|
||||
my $snapshot = vinfo_child($snaproot, "$snapshot_name");
|
||||
if(btrfs_subvolume_snapshot($svol, $snapshot))
|
||||
my @delete_dirs = @{config_key($svol, "snapshot_delete_dir") // []};
|
||||
my $create_rw = scalar(@delete_dirs) ? 1 : 0;
|
||||
if(btrfs_subvolume_snapshot($svol, $snapshot, !$create_rw))
|
||||
{
|
||||
my $snapshot_ok = 1;
|
||||
if($create_rw) {
|
||||
foreach my $dir (@delete_dirs) {
|
||||
my $dir_path = $snapshot->{PATH} . '/' . $dir;
|
||||
INFO "[snapshot] delete dir: $dir_path";
|
||||
my $ret = run_cmd(cmd => vinfo_cmd($snapshot, "rm", '-rf', { unsafe => $dir_path } ),
|
||||
rsh => vinfo_rsh($snapshot),
|
||||
);
|
||||
unless(defined($ret)) {
|
||||
ERROR "Failed to delete directory \"$dir\" in snapshot: $snapshot->{PRINT}";
|
||||
$snapshot_ok = 0;
|
||||
last;
|
||||
}
|
||||
}
|
||||
if($snapshot_ok) {
|
||||
unless(btrfs_subvolume_set_readonly($snapshot)) {
|
||||
$snapshot_ok = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if($snapshot_ok) {
|
||||
vinfo_inject_child($snaproot, $snapshot, {
|
||||
parent_uuid => $svol->{node}{uuid},
|
||||
received_uuid => '-',
|
||||
|
|
@ -6708,6 +6753,12 @@ MAIN:
|
|||
});
|
||||
$svol->{SNAPSHOT_CREATED} = $snapshot;
|
||||
}
|
||||
else {
|
||||
btrfs_subvolume_delete($snapshot);
|
||||
ABORTED($svol, "Failed to process snapshot: $svol->{PRINT} -> $snapshot->{PRINT}");
|
||||
WARN "Skipping subvolume section: " . ABORTED_TEXT($svol);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ABORTED($svol, "Failed to create snapshot: $svol->{PRINT} -> $snapshot->{PRINT}");
|
||||
WARN "Skipping subvolume section: " . ABORTED_TEXT($svol);
|
||||
|
|
|
|||
|
|
@ -143,6 +143,16 @@ Note that using ``long-iso'' has implications on the scheduling, see
|
|||
btrbk is taking care of snapshot creation). Defaults to
|
||||
``always''.
|
||||
|
||||
*snapshot_delete_dir* <directory>::
|
||||
Delete directory '<directory>' inside newly created snapshots
|
||||
(relative to the snapshot root). This option can be set multiple
|
||||
times, and is available in global, volume and subvolume context.
|
||||
+
|
||||
--
|
||||
If set, btrbk creates the snapshot as read-write, deletes all
|
||||
configured directories, and then sets the snapshot to read-only.
|
||||
--
|
||||
|
||||
*incremental* yes|no|strict::
|
||||
If set, incremental backups are created. If set to ``strict'',
|
||||
non-incremental (initial) backups are never created, and
|
||||
|
|
|
|||
|
|
@ -147,6 +147,8 @@ while [ "$#" -ge 1 ]; do
|
|||
-s|--source)
|
||||
allow_cmd "${sudo_prefix}btrfs subvolume snapshot"
|
||||
allow_cmd "${sudo_prefix}btrfs send"
|
||||
allow_exact_cmd "${sudo_prefix}btrfs property set ${file_arg_match} ro true" # set snapshot read-only
|
||||
allow_exact_cmd "${sudo_prefix}rm -rf ${file_arg_match}" # delete dirs in snapshot
|
||||
;;
|
||||
|
||||
-t|--target)
|
||||
|
|
@ -169,6 +171,8 @@ while [ "$#" -ge 1 ]; do
|
|||
|
||||
--snapshot)
|
||||
allow_cmd "${sudo_prefix}btrfs subvolume snapshot"
|
||||
allow_exact_cmd "${sudo_prefix}btrfs property set ${file_arg_match} ro true" # set snapshot read-only
|
||||
allow_exact_cmd "${sudo_prefix}rm -rf ${file_arg_match}" # delete dirs in snapshot
|
||||
;;
|
||||
|
||||
--send)
|
||||
|
|
|
|||
Loading…
Reference in New Issue