Diskmanage: Use S.M.A.R.T. attributes for SSDs wearout lookup

This replaces a locally maintained hardware map in
get_wear_leveling_info() by commonly used register names of
smartmontool. Smartmontool maintains a labeled register database that
contains a majority of drives (including versions). The current lookup
produces false estimates, this approach hopefully provides more reliable
data.

Signed-off-by: Jan-Jonas Sämann <sprinterfreak@binary-kitchen.de>
This commit is contained in:
Jan-Jonas Sämann
2020-10-30 04:57:22 +01:00
committed by Thomas Lamprecht
parent 641146add8
commit dbad606d57

View File

@ -396,7 +396,7 @@ sub get_sysdir_info {
} }
sub get_wear_leveling_info { sub get_wear_leveling_info {
my ($smartdata, $model) = @_; my ($smartdata) = @_;
my $attributes = $smartdata->{attributes}; my $attributes = $smartdata->{attributes};
if (defined($smartdata->{wearout})) { if (defined($smartdata->{wearout})) {
@ -405,36 +405,34 @@ sub get_wear_leveling_info {
my $wearout; my $wearout;
my $vendormap = { # Common register names that represent percentage values of potential
'kingston' => 231, # failure indicators used in drivedb.h of smartmontool's. Order matters,
'samsung' => 177, # as some drives may have multiple definitions
'intel' => 233, my @wearoutregisters = (
'sandisk' => 233, "Media_Wearout_Indicator",
'crucial' => 202, "SSD_Life_Left",
'default' => 233, "Wear_Leveling_Count",
}; "Perc_Write\/Erase_Ct_BC",
"Perc_Rated_Life_Remain",
# find target attr id "Remaining_Lifetime_Perc",
"Percent_Lifetime_Remain",
my $attrid; "Lifetime_Left",
"PCT_Life_Remaining",
foreach my $vendor (keys %$vendormap) { "Lifetime_Remaining",
if ($model =~ m/$vendor/i) { "Percent_Life_Remaining",
$attrid = $vendormap->{$vendor}; "Percent_Lifetime_Used",
# found the attribute "Perc_Rated_Life_Used"
last; );
}
}
if (!$attrid) {
$attrid = $vendormap->{default};
}
# Search for S.M.A.R.T. attributes for known register
foreach my $register (@wearoutregisters) {
last if defined $wearout;
foreach my $attr (@$attributes) { foreach my $attr (@$attributes) {
next if $attr->{id} != $attrid; next if $attr->{name} !~ m/$register/;
$wearout = $attr->{value}; $wearout = $attr->{value};
last; last;
} }
}
return $wearout; return $wearout;
} }
@ -559,7 +557,7 @@ sub get_disks {
if (is_ssdlike($type)) { if (is_ssdlike($type)) {
# if we have an ssd we try to get the wearout indicator # if we have an ssd we try to get the wearout indicator
my $wearval = get_wear_leveling_info($smartdata, $data->{model} || $sysdata->{model}); my $wearval = get_wear_leveling_info($smartdata);
$wearout = $wearval if defined($wearval); $wearout = $wearval if defined($wearval);
} }
}; };