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:
committed by
Thomas Lamprecht
parent
641146add8
commit
dbad606d57
@ -396,7 +396,7 @@ sub get_sysdir_info {
|
||||
}
|
||||
|
||||
sub get_wear_leveling_info {
|
||||
my ($smartdata, $model) = @_;
|
||||
my ($smartdata) = @_;
|
||||
my $attributes = $smartdata->{attributes};
|
||||
|
||||
if (defined($smartdata->{wearout})) {
|
||||
@ -405,37 +405,35 @@ sub get_wear_leveling_info {
|
||||
|
||||
my $wearout;
|
||||
|
||||
my $vendormap = {
|
||||
'kingston' => 231,
|
||||
'samsung' => 177,
|
||||
'intel' => 233,
|
||||
'sandisk' => 233,
|
||||
'crucial' => 202,
|
||||
'default' => 233,
|
||||
};
|
||||
# Common register names that represent percentage values of potential
|
||||
# failure indicators used in drivedb.h of smartmontool's. Order matters,
|
||||
# as some drives may have multiple definitions
|
||||
my @wearoutregisters = (
|
||||
"Media_Wearout_Indicator",
|
||||
"SSD_Life_Left",
|
||||
"Wear_Leveling_Count",
|
||||
"Perc_Write\/Erase_Ct_BC",
|
||||
"Perc_Rated_Life_Remain",
|
||||
"Remaining_Lifetime_Perc",
|
||||
"Percent_Lifetime_Remain",
|
||||
"Lifetime_Left",
|
||||
"PCT_Life_Remaining",
|
||||
"Lifetime_Remaining",
|
||||
"Percent_Life_Remaining",
|
||||
"Percent_Lifetime_Used",
|
||||
"Perc_Rated_Life_Used"
|
||||
);
|
||||
|
||||
# find target attr id
|
||||
|
||||
my $attrid;
|
||||
|
||||
foreach my $vendor (keys %$vendormap) {
|
||||
if ($model =~ m/$vendor/i) {
|
||||
$attrid = $vendormap->{$vendor};
|
||||
# found the attribute
|
||||
last;
|
||||
# Search for S.M.A.R.T. attributes for known register
|
||||
foreach my $register (@wearoutregisters) {
|
||||
last if defined $wearout;
|
||||
foreach my $attr (@$attributes) {
|
||||
next if $attr->{name} !~ m/$register/;
|
||||
$wearout = $attr->{value};
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$attrid) {
|
||||
$attrid = $vendormap->{default};
|
||||
}
|
||||
|
||||
foreach my $attr (@$attributes) {
|
||||
next if $attr->{id} != $attrid;
|
||||
$wearout = $attr->{value};
|
||||
last;
|
||||
}
|
||||
|
||||
return $wearout;
|
||||
}
|
||||
|
||||
@ -559,7 +557,7 @@ sub get_disks {
|
||||
|
||||
if (is_ssdlike($type)) {
|
||||
# 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);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user