move SMART error handling into get_disks
because we never ever want to die in get_disks because of a single disk, but the nodes/xyz/disks/smart API path is allowed to fail if a disk device is unsupported by smartctl or something else goes wrong.
This commit is contained in:
committed by
Dietmar Maurer
parent
d547f26c7d
commit
acd3d91649
@ -138,6 +138,8 @@ __PACKAGE__->register_method ({
|
|||||||
$result = PVE::Diskmanage::get_smart_data($disk);
|
$result = PVE::Diskmanage::get_smart_data($disk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$result->{health} = 'UNKOWN' if !defined $result->{health};
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}});
|
}});
|
||||||
|
|
||||||
|
|||||||
@ -110,7 +110,6 @@ sub get_smart_data {
|
|||||||
if ((defined($returncode) && ($returncode & 0b00000011)) || $err) {
|
if ((defined($returncode) && ($returncode & 0b00000011)) || $err) {
|
||||||
die "Error getting S.M.A.R.T. data: Exit code: $returncode\n";
|
die "Error getting S.M.A.R.T. data: Exit code: $returncode\n";
|
||||||
}
|
}
|
||||||
$smartdata->{health} = 'UNKOWN' if !defined $smartdata->{health};
|
|
||||||
return $smartdata;
|
return $smartdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,22 +118,19 @@ sub get_smart_health {
|
|||||||
|
|
||||||
return "NOT A DEVICE" if !assert_blockdev($disk, 1);
|
return "NOT A DEVICE" if !assert_blockdev($disk, 1);
|
||||||
|
|
||||||
my $message = "UNKOWN";
|
my $message;
|
||||||
|
|
||||||
eval {
|
run_command([$SMARTCTL, '-H', $disk], noerr => 1, outfunc => sub {
|
||||||
run_command([$SMARTCTL, '-H', $disk], noerr => 1, outfunc => sub {
|
my ($line) = @_;
|
||||||
my ($line) = @_;
|
|
||||||
|
|
||||||
if ($line =~ m/test result: (.*)$/) {
|
if ($line =~ m/test result: (.*)$/) {
|
||||||
$message = $1;
|
$message = $1;
|
||||||
} elsif ($line =~ m/open device: (.*) failed: (.*)$/) {
|
} elsif ($line =~ m/open device: (.*) failed: (.*)$/) {
|
||||||
$message = "FAILED TO OPEN";
|
$message = "FAILED TO OPEN";
|
||||||
} elsif ($line =~ m/^SMART Disabled/) {
|
} elsif ($line =~ m/^SMART Disabled/) {
|
||||||
$message = "SMART DISABLED";
|
$message = "SMART DISABLED";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
|
||||||
# we ignore errors here because by default we want to return UNKNOWN
|
|
||||||
|
|
||||||
return $message;
|
return $message;
|
||||||
}
|
}
|
||||||
@ -366,29 +362,30 @@ sub get_disks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my $health;
|
my $health = 'UNKNOWN';
|
||||||
my $wearout;
|
my $wearout;
|
||||||
if ($type eq 'ssd' && !defined($disk)) {
|
eval {
|
||||||
# if we have an ssd we try to get the wearout indicator
|
if ($type eq 'ssd' && !defined($disk)) {
|
||||||
my $smartdata = get_smart_data($devpath);
|
# if we have an ssd we try to get the wearout indicator
|
||||||
$health = $smartdata->{health};
|
$wearout = 'N/A';
|
||||||
foreach my $attr (@{$smartdata->{attributes}}) {
|
my $smartdata = get_smart_data($devpath);
|
||||||
# ID 233 is media wearout indicator on intel and sandisk
|
$health = $smartdata->{health};
|
||||||
# ID 177 is media wearout indicator on samsung
|
foreach my $attr (@{$smartdata->{attributes}}) {
|
||||||
next if ($attr->{id} != 233 && $attr->{id} != 177);
|
# ID 233 is media wearout indicator on intel and sandisk
|
||||||
next if ($attr->{name} !~ m/wear/i);
|
# ID 177 is media wearout indicator on samsung
|
||||||
$wearout = $attr->{value};
|
next if ($attr->{id} != 233 && $attr->{id} != 177);
|
||||||
|
next if ($attr->{name} !~ m/wear/i);
|
||||||
|
$wearout = $attr->{value};
|
||||||
|
|
||||||
# prefer the 233 value
|
# prefer the 233 value
|
||||||
last if ($attr->{id} == 233);
|
last if ($attr->{id} == 233);
|
||||||
|
}
|
||||||
|
} elsif (!defined($disk)) {
|
||||||
|
# we do not need smart data if we check a single disk
|
||||||
|
# because this functionality is only for disk_is_used
|
||||||
|
$health = get_smart_health($devpath) if !defined($disk);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
$wearout = 'N/A' if !defined($wearout);
|
|
||||||
} elsif (!defined($disk)) {
|
|
||||||
# we do not need smart data if we check a single disk
|
|
||||||
# because this functionality is only for disk_is_used
|
|
||||||
$health = get_smart_health($devpath) if !defined($disk);
|
|
||||||
}
|
|
||||||
|
|
||||||
my $used;
|
my $used;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user