mirror of https://github.com/digint/btrbk
btrbk: validate output of "btrfs subvolume show"; also return uuid for btrfs root (if present)
Filesystems created with btrfs-progs < 4.16 have valid UUID, while others have not [1]. Validate output of "btrfs subvolume show", and provide uuid for btrfs root (id=5) only if it is valid. [1]: 0a0a03554a: btrfs-progs: mkfs: add uuid and otime to ROOT_ITEM of, FS_TREEpull/245/head
parent
9c70231859
commit
177671e920
48
btrbk
48
btrbk
|
@ -874,8 +874,10 @@ sub btrfs_filesystem_usage($)
|
|||
}
|
||||
|
||||
|
||||
# returns hashref with keys: (name uuid parent_uuid id gen cgen top_level)
|
||||
# returns hashref with keys: (uuid parent_uuid id gen cgen top_level)
|
||||
# for btrfs root, returns at least: (id is_root)
|
||||
# for btrfs-progs >= 4.1, also returns key: "received_uuid"
|
||||
# if present, also returns (unvalidated) keys: (name creation_time flags)
|
||||
sub btrfs_subvolume_show($)
|
||||
{
|
||||
my $vol = shift || die;
|
||||
|
@ -935,9 +937,6 @@ sub btrfs_subvolume_show($)
|
|||
$detail{id} = 5;
|
||||
}
|
||||
else {
|
||||
# NOTE: received_uuid is not required here, as btrfs-progs < 4.1 does not give us that information.
|
||||
# no worries, we get this from btrfs_subvolume_list() for all subvols.
|
||||
my @required_keys = qw(name uuid parent_uuid id gen cgen top_level readonly);
|
||||
my %trans = (
|
||||
"Name" => "name",
|
||||
"uuid" => "uuid",
|
||||
|
@ -968,24 +967,45 @@ sub btrfs_subvolume_show($)
|
|||
}
|
||||
DEBUG "Parsed " . scalar(keys %detail) . " subvolume detail items: $vol->{PRINT}";
|
||||
|
||||
# validate required keys
|
||||
unless((defined($detail{parent_uuid}) && (($detail{parent_uuid} eq '-') || ($detail{parent_uuid} =~ /^$uuid_match$/))) &&
|
||||
(defined($detail{id}) && ($detail{id} =~ /^\d+$/) && ($detail{id} >= 5)) &&
|
||||
(defined($detail{gen}) && ($detail{gen} =~ /^\d+$/)) &&
|
||||
(defined($detail{cgen}) && ($detail{cgen} =~ /^\d+$/)) &&
|
||||
(defined($detail{top_level}) && ($detail{top_level} =~ /^\d+$/)))
|
||||
{
|
||||
ERROR "Failed to parse subvolume detail (unsupported btrfs-progs) for: $vol->{PRINT}";
|
||||
return undef;
|
||||
}
|
||||
|
||||
# NOTE: filesystems created with btrfs-progs < 4.16 have no UUID for subvolid=5,
|
||||
# assert {uuid} is either valid or undef
|
||||
if(defined($detail{uuid}) && ($detail{uuid} !~ /^$uuid_match$/)) {
|
||||
if($detail{id} == 5) {
|
||||
DEBUG "No UUID on btrfs root (id=5): $vol->{PRINT}";
|
||||
} else {
|
||||
ERROR "Failed to parse subvolume detail (unsupported btrfs-progs) for: $vol->{PRINT}";
|
||||
return undef;
|
||||
}
|
||||
delete $detail{uuid};
|
||||
}
|
||||
|
||||
# NOTE: received_uuid is not required here, as btrfs-progs < 4.1 does not give us that information.
|
||||
# no worries, we get this from btrfs_subvolume_list() for all subvols.
|
||||
if(defined($detail{received_uuid}) && ($detail{received_uuid} ne '-') && ($detail{received_uuid} !~ /^$uuid_match$/)) {
|
||||
ERROR "Failed to parse subvolume detail (unsupported btrfs-progs) for: $vol->{PRINT}";
|
||||
return undef;
|
||||
}
|
||||
|
||||
# NOTE: as of btrfs-progs v4.6.1, flags are either "-" or "readonly"
|
||||
$detail{readonly} = ($detail{flags} =~ /readonly/) ? 1 : 0;
|
||||
|
||||
VINFO(\%detail, "detail") if($loglevel >=4);
|
||||
foreach(@required_keys) {
|
||||
unless(defined($detail{$_})) {
|
||||
ERROR "Failed to parse subvolume detail (unsupported btrfs-progs) for: $vol->{PRINT}";
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($detail{id} == 5) {
|
||||
# NOTE: as of btrfs-progs v4.8.3, we get full output for root
|
||||
# subvolume, with lots of '0' and '-' (especially uuid='-').
|
||||
# This breaks things, set $detail to sane values:
|
||||
DEBUG "found btrfs root: $vol->{PRINT}";
|
||||
%detail = ( id => 5, is_root => 1 );
|
||||
$detail{is_root} = 1;
|
||||
}
|
||||
|
||||
return \%detail;
|
||||
|
|
Loading…
Reference in New Issue