btrbk: run_cmd: return array of stdout lines instead of scalar

pull/299/head
Axel Burri 2019-08-18 12:59:12 +02:00
parent 6227bb591a
commit 3798677893
1 changed files with 22 additions and 22 deletions

44
btrbk
View File

@ -813,21 +813,22 @@ sub run_cmd(@)
if($dryrun && $destructive) { if($dryrun && $destructive) {
DEBUG "### (dryrun) $cmd"; DEBUG "### (dryrun) $cmd";
return ""; return [];
} }
DEBUG "### $cmd"; DEBUG "### $cmd";
# execute command # execute command
my ($pid, $out_fh, $err_fh, $stdout, @stderr); my ($pid, $out_fh, $err_fh, @stdout, @stderr);
$err_fh = gensym; $err_fh = gensym;
if(eval_quiet { $pid = open3(undef, $out_fh, $err_fh, $cmd); }) { if(eval_quiet { $pid = open3(undef, $out_fh, $err_fh, $cmd); }) {
$stdout = do { local $/; scalar readline $out_fh }; chomp(@stdout = readline($out_fh));
@stderr = readline $err_fh; chomp(@stderr = readline($err_fh));
waitpid($pid, 0); waitpid($pid, 0);
chomp(@stderr); if($loglevel >= 4) {
TRACE "Command stdout:\n$stdout" if(($loglevel >= 4) && defined($stdout)); TRACE "[stdout] $_" foreach(@stdout);
TRACE "Command stderr:\n" . join("\n", @stderr) if(($loglevel >= 4) && scalar(@stderr)); TRACE "[stderr] $_" foreach(@stderr);
}
} }
else { else {
ERROR "Command execution failed ($!): `$cmd`"; ERROR "Command execution failed ($!): `$cmd`";
@ -872,7 +873,7 @@ sub run_cmd(@)
else { else {
DEBUG "Command execution successful"; DEBUG "Command execution successful";
} }
return $stdout; return \@stdout;
} }
@ -909,7 +910,7 @@ sub btrfs_filesystem_usage($)
return undef unless(defined($ret)); return undef unless(defined($ret));
my %detail; my %detail;
foreach (split("\n", $ret)) { foreach(@$ret) {
if(/^\s+Device size:\s+(\S+)/) { if(/^\s+Device size:\s+(\S+)/) {
$detail{device_size} = $1; $detail{device_size} = $1;
} }
@ -996,8 +997,7 @@ sub btrfs_subvolume_show($;@)
return undef unless(defined($ret)); return undef unless(defined($ret));
my @ret_lines = split("\n", $ret); unless(scalar(@$ret)) {
unless(@ret_lines) {
ERROR "Failed to parse subvolume detail (unsupported btrfs-progs) for: $vol->{PRINT}"; ERROR "Failed to parse subvolume detail (unsupported btrfs-progs) for: $vol->{PRINT}";
return undef; return undef;
} }
@ -1007,7 +1007,7 @@ sub btrfs_subvolume_show($;@)
# - btrfs-progs >= 4.12 prints the relative path to btrfs root (or "/" if it is the root) # - btrfs-progs >= 4.12 prints the relative path to btrfs root (or "/" if it is the root)
my %detail; my %detail;
if($ret_lines[0] =~ / is (btrfs root|toplevel subvolume)$/) { if($ret->[0] =~ / is (btrfs root|toplevel subvolume)$/) {
# btrfs-progs < 4.4 prints: "<subvol> is btrfs root" # btrfs-progs < 4.4 prints: "<subvol> is btrfs root"
# btrfs-progs >= 4.4 prints: "<subvol> is toplevel subvolume" # btrfs-progs >= 4.4 prints: "<subvol> is toplevel subvolume"
# btrfs-progs >= 4.8.3 does not enter here, as output shares format with regular subvolumes # btrfs-progs >= 4.8.3 does not enter here, as output shares format with regular subvolumes
@ -1033,7 +1033,7 @@ sub btrfs_subvolume_show($;@)
"Top level ID" => "top_level", # btrfs-progs >= 4.1 "Top level ID" => "top_level", # btrfs-progs >= 4.1
"Flags" => "flags", "Flags" => "flags",
); );
foreach (@ret_lines) { foreach(@$ret) {
next unless /^\s+(.+):\s+(.*)$/; next unless /^\s+(.+):\s+(.*)$/;
my ($key, $value) = ($1, $2); my ($key, $value) = ($1, $2);
if($trans{$key}) { if($trans{$key}) {
@ -1107,7 +1107,7 @@ sub btrfs_subvolume_list_readonly_flag($)
return undef unless(defined($ret)); return undef unless(defined($ret));
my %ro; my %ro;
foreach (split(/\n/, $ret)) foreach(@$ret)
{ {
die("Failed to parse line: \"$_\"") unless(/^ID\s+([0-9]+)\s+gen\s+[0-9]+\s+top level\s+[0-9]+\s+path\s/); die("Failed to parse line: \"$_\"") unless(/^ID\s+([0-9]+)\s+gen\s+[0-9]+\s+top level\s+[0-9]+\s+path\s/);
$ro{$1} = 1; $ro{$1} = 1;
@ -1136,7 +1136,7 @@ sub btrfs_subvolume_list($;@)
return undef unless(defined($ret)); return undef unless(defined($ret));
my @nodes; my @nodes;
foreach (split(/\n/, $ret)) foreach(@$ret)
{ {
my %node; my %node;
# NOTE: btrfs-progs >= 4.13.2 pads uuid's with 36 whitespaces # NOTE: btrfs-progs >= 4.13.2 pads uuid's with 36 whitespaces
@ -1225,7 +1225,7 @@ sub btrfs_subvolume_find_new($$;$)
my %files; my %files;
my $parse_errors = 0; my $parse_errors = 0;
my $transid_marker; my $transid_marker;
foreach (split(/\n/, $ret)) foreach(@$ret)
{ {
if(/^inode \S+ file offset (\S+) len (\S+) disk start \S+ offset \S+ gen (\S+) flags (\S+) (.+)$/) { if(/^inode \S+ file offset (\S+) len (\S+) disk start \S+ offset \S+ gen (\S+) flags (\S+) (.+)$/) {
my $file_offset = $1; my $file_offset = $1;
@ -1706,7 +1706,7 @@ sub btrfs_send_to_file($$$;$$)
name => $kdf_backend_name name => $kdf_backend_name
); );
return undef unless(defined($kdf_values)); return undef unless(defined($kdf_values));
foreach(split("\n", $kdf_values)) { foreach(@$kdf_values) {
chomp; chomp;
next if /^\s*$/; # ignore empty lines next if /^\s*$/; # ignore empty lines
if(/^KEY=([0-9a-fA-f]+)/) { if(/^KEY=([0-9a-fA-f]+)/) {
@ -1844,7 +1844,7 @@ sub system_list_mountinfo($)
return undef unless(defined($ret)); return undef unless(defined($ret));
my @mountinfo; my @mountinfo;
foreach (split(/\n/, $ret)) foreach(@$ret)
{ {
# https://www.kernel.org/doc/Documentation/filesystems/proc.txt # https://www.kernel.org/doc/Documentation/filesystems/proc.txt
unless(/^(?<mount_id>[0-9]+) # mount ID: unique identifier of the mount (may be reused after umount) unless(/^(?<mount_id>[0-9]+) # mount ID: unique identifier of the mount (may be reused after umount)
@ -1893,8 +1893,8 @@ sub system_realpath($)
); );
return undef unless(defined($ret)); return undef unless(defined($ret));
unless($ret =~ /^($file_match)$/) { unless(scalar(@$ret) && ($ret->[0] =~ /^($file_match)$/)) {
ERROR "Failed to parse output of `realpath` for \"$vol->{PRINT}\": \"$ret\""; ERROR "Failed to parse output of `realpath` for \"$vol->{PRINT}\": \"$ret->[0]\"";
return undef; return undef;
} }
my $realpath = $1; # untaint argument my $realpath = $1; # untaint argument
@ -2029,7 +2029,7 @@ sub system_read_raw_info_dir($)
my @raw_targets; my @raw_targets;
my $cur_target; my $cur_target;
foreach (split("\n", $ret)) foreach(@$ret)
{ {
if(/^INFO_FILE=/) { if(/^INFO_FILE=/) {
push @raw_targets, $cur_target if($cur_target); push @raw_targets, $cur_target if($cur_target);
@ -2095,7 +2095,7 @@ sub system_read_raw_info_dir($)
return undef; return undef;
} }
my $deprecated_found = 0; my $deprecated_found = 0;
foreach (split("\n", $ret)) foreach(@$ret)
{ {
unless(/^($file_match)$/) { unless(/^($file_match)$/) {
DEBUG "Skipping non-parseable file: \"$_\""; DEBUG "Skipping non-parseable file: \"$_\"";