btrbk: add configuration option "rate_limit" (using pv -L)

Original patch provided by @janpascal: "Jan-Pascal van Best"
pull/88/head
Axel Burri 2016-03-23 11:58:23 +01:00
parent e6d46e8a02
commit f9ca7504c8
3 changed files with 42 additions and 11 deletions

View File

@ -3,6 +3,7 @@ btrbk-current
* Allow wildcards in subvolume section (close: #71). * Allow wildcards in subvolume section (close: #71).
* Added "{snapshot,target}_preserve NNd NNw NNm NNy" shortcut. * Added "{snapshot,target}_preserve NNd NNw NNm NNy" shortcut.
* Added yearly retention policies (close: #69). * Added yearly retention policies (close: #69).
* Added configuration option "rate_limit" (close: #72).
* Always read "readonly" flag (additional call to btrfs-progs). * Always read "readonly" flag (additional call to btrfs-progs).
* Detect interrupted transfers of raw targets (close: #75). * Detect interrupted transfers of raw targets (close: #75).
* Improvements of internal data structures. * Improvements of internal data structures.

43
btrbk
View File

@ -95,6 +95,7 @@ my %config_options = (
ssh_port => { default => "default", accept => [ "default" ], accept_numeric => 1 }, ssh_port => { default => "default", accept => [ "default" ], accept_numeric => 1 },
ssh_compression => { default => undef, accept => [ "yes", "no" ] }, ssh_compression => { default => undef, accept => [ "yes", "no" ] },
ssh_cipher_spec => { default => "default", accept_regexp => qr/^$ssh_cipher_match(,$ssh_cipher_match)*$/ }, ssh_cipher_spec => { default => "default", accept_regexp => qr/^$ssh_cipher_match(,$ssh_cipher_match)*$/ },
rate_limit => { default => undef, accept => [ "no" ], accept_regexp => qr/^[0-9]+[kmgt]?$/, require_bin => '/usr/bin/pv' },
transaction_log => { default => undef, accept_file => { absolute => 1 } }, transaction_log => { default => undef, accept_file => { absolute => 1 } },
raw_target_compress => { default => undef, accept => [ "no", "gzip", "bzip2", "xz" ] }, raw_target_compress => { default => undef, accept => [ "no", "gzip", "bzip2", "xz" ] },
@ -420,6 +421,25 @@ sub run_cmd(@)
} }
sub add_pv_command($@)
{
my $cmd_pipe = shift || die;
my %opts = @_;
my $rate_limit = $opts{rate_limit};
if($opts{show_progress}) {
if($rate_limit) {
push @$cmd_pipe, { cmd => [ '/usr/bin/pv', '-trab', '-L', $rate_limit ] };
} else {
push @$cmd_pipe, { cmd => [ '/usr/bin/pv', '-trab' ] };
}
}
elsif($rate_limit) {
push @$cmd_pipe, { cmd => [ '/usr/bin/pv', '-q', '-L', $rate_limit ] };
}
}
sub btrfs_filesystem_show_all_local() sub btrfs_filesystem_show_all_local()
{ {
return run_cmd( cmd => [ qw(btrfs filesystem show) ], return run_cmd( cmd => [ qw(btrfs filesystem show) ],
@ -832,12 +852,13 @@ sub btrfs_subvolume_delete($@)
} }
sub btrfs_send_receive($$$$) sub btrfs_send_receive($$$$;@)
{ {
my $snapshot = shift || die; my $snapshot = shift || die;
my $target = shift || die; my $target = shift || die;
my $parent = shift; my $parent = shift;
my $ret_vol_received = shift; my $ret_vol_received = shift;
my %opts = @_;
my $snapshot_path = $snapshot->{PATH} // die; my $snapshot_path = $snapshot->{PATH} // die;
my $target_path = $target->{PATH} // die; my $target_path = $target->{PATH} // die;
my $parent_path = $parent ? $parent->{PATH} : undef; my $parent_path = $parent ? $parent->{PATH} : undef;
@ -866,9 +887,7 @@ sub btrfs_send_receive($$$$)
name => "btrfs send", name => "btrfs send",
catch_stderr => 1, # hack for shell-based run_cmd() catch_stderr => 1, # hack for shell-based run_cmd()
}; };
push @cmd_pipe, { add_pv_command(\@cmd_pipe, show_progress => $show_progress, rate_limit => $opts{rate_limit});
cmd => [ '/usr/bin/pv', '-trab' ],
} if($show_progress);
push @cmd_pipe, { push @cmd_pipe, {
cmd => [ qw(btrfs receive), @receive_options, $target_path . '/' ], cmd => [ qw(btrfs receive), @receive_options, $target_path . '/' ],
rsh => $target->{RSH}, rsh => $target->{RSH},
@ -964,9 +983,7 @@ sub btrfs_send_to_file($$$$;@)
rsh => $source->{RSH}, rsh => $source->{RSH},
name => "btrfs send", name => "btrfs send",
}; };
push @cmd_pipe, { add_pv_command(\@cmd_pipe, show_progress => $show_progress, rate_limit => $opts{rate_limit});
cmd => [ '/usr/bin/pv', '-trab' ],
} if($show_progress);
if($opts{compress}) { if($opts{compress}) {
die unless($compress{$opts{compress}}); die unless($compress{$opts{compress}});
$target_filename .= $compress{$opts{compress}}->{postfix}; $target_filename .= $compress{$opts{compress}}->{postfix};
@ -1785,6 +1802,11 @@ sub append_config_option($$$$;$)
TRACE "splitted option \"$key\": " . join(',', @$value); TRACE "splitted option \"$key\": " . join(',', @$value);
} }
if($opt->{require_bin} && (not -e $opt->{require_bin})) {
WARN "Found option \"$key\"$config_file_statement, but \"$opt->{require_bin}\" does not exist on your system, ignoring";
$value = "no";
}
if($opt->{deprecated}) { if($opt->{deprecated}) {
WARN "Found deprecated option \"$key $value\"" . $config_file_statement . ": " . WARN "Found deprecated option \"$key $value\"" . $config_file_statement . ": " .
($opt->{deprecated}->{$value}->{warn} // $opt->{deprecated}->{DEFAULT}->{warn}); ($opt->{deprecated}->{$value}->{warn} // $opt->{deprecated}->{DEFAULT}->{warn});
@ -2022,7 +2044,7 @@ sub macro_send_receive(@)
my $vol_received; my $vol_received;
if($target_type eq "send-receive") if($target_type eq "send-receive")
{ {
$ret = btrfs_send_receive($source, $target, $parent, \$vol_received); $ret = btrfs_send_receive($source, $target, $parent, \$vol_received, rate_limit => config_key($config_target, "rate_limit"));
ABORTED($config_target, "Failed to send/receive subvolume") unless($ret); ABORTED($config_target, "Failed to send/receive subvolume") unless($ret);
} }
elsif($target_type eq "raw") elsif($target_type eq "raw")
@ -2050,7 +2072,8 @@ sub macro_send_receive(@)
compress => config_key($config_target, "raw_target_compress"), compress => config_key($config_target, "raw_target_compress"),
compress_level => config_key($config_target, "raw_target_compress_level"), compress_level => config_key($config_target, "raw_target_compress_level"),
compress_threads => config_key($config_target, "raw_target_compress_threads"), compress_threads => config_key($config_target, "raw_target_compress_threads"),
encrypt => $encrypt encrypt => $encrypt,
rate_limit => config_key($config_target, "rate_limit"),
); );
ABORTED($config_target, "Failed to send subvolume to raw file") unless($ret); ABORTED($config_target, "Failed to send subvolume to raw file") unless($ret);
} }
@ -2531,7 +2554,7 @@ MAIN:
# check command line options # check command line options
if($show_progress && (not -e '/usr/bin/pv')) { if($show_progress && (not -e '/usr/bin/pv')) {
WARN 'found option "--progress", but "pv" is not present: (please install "pv")'; WARN 'Found option "--progress", but "pv" is not present: (please install "pv")';
$show_progress = 0; $show_progress = 0;
} }
my ($action_run, $action_usage, $action_resolve, $action_diff, $action_origin, $action_config_print, $action_list, $action_clean); my ($action_run, $action_usage, $action_resolve, $action_diff, $action_origin, $action_config_print, $action_list, $action_clean);

View File

@ -1,4 +1,4 @@
.TH "btrbk.conf" "5" "2016-02-29" "btrbk v0.23.0-dev" "" .TH "btrbk.conf" "5" "2016-03-23" "btrbk v0.23.0-dev" ""
.\" disable hyphenation .\" disable hyphenation
.nh .nh
.\" disable justification (adjust text to left margin only) .\" disable justification (adjust text to left margin only)
@ -224,6 +224,13 @@ cipher_spec" option in ssh(1) for more information. Defaults to
\[lq]default\[rq] (the ciphers specified in \fIssh_config\fR). \[lq]default\[rq] (the ciphers specified in \fIssh_config\fR).
.RE .RE
.PP .PP
\fBrate_limit\fR <rate>|no
.RS 4
Limit the transfer to a maximum of \fI<rate>\fR bytes per second. A
suffix of "k", "m", "g", or "t" can be added to denote kilobytes
(*1024), megabytes, and so on. Defaults to \[lq]no\[rq].
.RE
.PP
\fBbtrfs_commit_delete\fR after|each|no \fBbtrfs_commit_delete\fR after|each|no
.RS 4 .RS 4
If set, make sure the deletion of snapshot and backup subvolumes are If set, make sure the deletion of snapshot and backup subvolumes are