fix #6405: disks: smart: parse ATA attributes with additional flags

In its brief output format, smartctl prints the attribute flags as six
characters, followed by a seventh one which is a '+' if any other flag
bits are set and a space otherwise, for example:

  5 Reallocated_Sector_Ct   ------+  100   100   050    -    0

The regex for the ATA attributes only accepted exactly six non-space
characters for the flags, so such attribute lines were skipped. For
drives that set those other bits on all attributes, like the SATA SSD
from the bug report, no SMART attributes showed up at all and the
wearout could not be determined either.

Accept an optional '+' after the flags and add the output from the
bug report as test case.

Signed-off-by: Michal Fox <me@dualfroz.com>
This commit is contained in:
dualfroz committed 2026-10-02 16:56:44 +02:00
1 parent 4265fdd04a
commit ab149ea5d1
9 files changed
+244 -1

No files matched your search

+2 -1
View File
@@ -109,6 +109,7 @@ sub get_smart_data {
# ATA SMART attributes, e.g.:
# ID# ATTRIBUTE_NAME FLAGS VALUE WORST THRESH FAIL RAW_VALUE
# 1 Raw_Read_Error_Rate POSR-K 100 100 000 - 0
# 5 Reallocated_Sector_Ct ------+ 100 100 050 - 0
#
# SAS and NVME disks, e.g.:
# Data Units Written: 5,584,952 [2.85 TB]
@@ -118,7 +119,7 @@ sub get_smart_data {
defined($type)
&& $type eq 'ata'
&& $line =~
m/^([ \d]{2}\d)\s+(\S+)\s+(\S{6})\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(.*)$/
m/^([ \d]{2}\d)\s+(\S+)\s+(\S{6}\+?)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(.*)$/
) {
my $entry = {};
+1
View File
@@ -3,3 +3,4 @@ sdb
sdc
sdd
sde
sdf
@@ -73,5 +73,20 @@
"rpm" : 0,
"health" : "PASSED",
"wearout" : "91"
},
"sdf" : {
"type" : "ssd",
"osdid" : -1,
"osdid-list" : null,
"size" : 512000,
"model" : "NT-256 2242",
"devpath" : "/dev/sdf",
"wwn" : "0x0000000000000000",
"vendor" : "ATA",
"serial" : "000000000000",
"gpt" : 1,
"rpm" : 0,
"health" : "PASSED",
"wearout" : "100"
}
}
@@ -0,0 +1 @@
ATA
@@ -0,0 +1 @@
0
+1
View File
@@ -0,0 +1 @@
1000
+31
View File
@@ -0,0 +1,31 @@
smartctl 7.3 2022-02-28 r5338 [x86_64-linux-6.8.12-10-pve] (local build)
Copyright (C) 2002-22, Bruce Allen, Christian Franke, www.smartmontools.org
=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED
SMART Attributes Data Structure revision number: 20
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME FLAGS VALUE WORST THRESH FAIL RAW_VALUE
5 Reallocated_Sector_Ct ------+ 100 100 050 - 0
9 Power_On_Hours ------+ 100 100 000 - 93
12 Power_Cycle_Count ------+ 100 100 000 - 11
167 Unknown_Attribute ------+ 100 100 000 - 0
168 Unknown_Attribute ------+ 100 100 000 - 0
169 Unknown_Attribute ------+ 100 100 010 - 196614
173 Unknown_Attribute ------+ 200 200 000 - 4296343561
175 Program_Fail_Count_Chip ------+ 100 100 010 - 0
180 Unused_Rsvd_Blk_Cnt_Tot ------+ 100 100 000 - 27
192 Power-Off_Retract_Count ------+ 100 100 000 - 7
194 Temperature_Celsius ------+ 040 040 000 - 40 (Min/Max 27/46)
231 Unknown_SSD_Attribute ------+ 100 100 005 - 0
233 Media_Wearout_Indicator ------+ 100 100 000 - 455
234 Unknown_Attribute ------+ 100 100 005 - 159998
241 Total_LBAs_Written ------+ 100 100 000 - 262
242 Total_LBAs_Read ------+ 100 100 000 - 68
||||||_ K auto-keep
|||||__ C event count
||||___ R error rate
|||____ S speed/performance
||_____ O updated online
|______ P prefailure warning
@@ -0,0 +1,182 @@
{
"attributes" : [
{
"id" : " 5",
"name" : "Reallocated_Sector_Ct",
"flags" : "------+",
"value" : 100,
"normalized" : 100,
"worst" : 100,
"threshold" : 50,
"fail" : "-",
"raw" : "0"
},
{
"id" : " 9",
"name" : "Power_On_Hours",
"flags" : "------+",
"value" : 100,
"normalized" : 100,
"worst" : 100,
"threshold" : 0,
"fail" : "-",
"raw" : "93"
},
{
"id" : " 12",
"name" : "Power_Cycle_Count",
"flags" : "------+",
"value" : 100,
"normalized" : 100,
"worst" : 100,
"threshold" : 0,
"fail" : "-",
"raw" : "11"
},
{
"id" : "167",
"name" : "Unknown_Attribute",
"flags" : "------+",
"value" : 100,
"normalized" : 100,
"worst" : 100,
"threshold" : 0,
"fail" : "-",
"raw" : "0"
},
{
"id" : "168",
"name" : "Unknown_Attribute",
"flags" : "------+",
"value" : 100,
"normalized" : 100,
"worst" : 100,
"threshold" : 0,
"fail" : "-",
"raw" : "0"
},
{
"id" : "169",
"name" : "Unknown_Attribute",
"flags" : "------+",
"value" : 100,
"normalized" : 100,
"worst" : 100,
"threshold" : 10,
"fail" : "-",
"raw" : "196614"
},
{
"id" : "173",
"name" : "Unknown_Attribute",
"flags" : "------+",
"value" : 200,
"normalized" : 200,
"worst" : 200,
"threshold" : 0,
"fail" : "-",
"raw" : "4296343561"
},
{
"id" : "175",
"name" : "Program_Fail_Count_Chip",
"flags" : "------+",
"value" : 100,
"normalized" : 100,
"worst" : 100,
"threshold" : 10,
"fail" : "-",
"raw" : "0"
},
{
"id" : "180",
"name" : "Unused_Rsvd_Blk_Cnt_Tot",
"flags" : "------+",
"value" : 100,
"normalized" : 100,
"worst" : 100,
"threshold" : 0,
"fail" : "-",
"raw" : "27"
},
{
"id" : "192",
"name" : "Power-Off_Retract_Count",
"flags" : "------+",
"value" : 100,
"normalized" : 100,
"worst" : 100,
"threshold" : 0,
"fail" : "-",
"raw" : "7"
},
{
"id" : "194",
"name" : "Temperature_Celsius",
"flags" : "------+",
"value" : 40,
"normalized" : 40,
"worst" : 40,
"threshold" : 0,
"fail" : "-",
"raw" : "40 (Min/Max 27/46)"
},
{
"id" : "231",
"name" : "Unknown_SSD_Attribute",
"flags" : "------+",
"value" : 100,
"normalized" : 100,
"worst" : 100,
"threshold" : 5,
"fail" : "-",
"raw" : "0"
},
{
"id" : "233",
"name" : "Media_Wearout_Indicator",
"flags" : "------+",
"value" : 100,
"normalized" : 100,
"worst" : 100,
"threshold" : 0,
"fail" : "-",
"raw" : "455"
},
{
"id" : "234",
"name" : "Unknown_Attribute",
"flags" : "------+",
"value" : 100,
"normalized" : 100,
"worst" : 100,
"threshold" : 5,
"fail" : "-",
"raw" : "159998"
},
{
"id" : "241",
"name" : "Total_LBAs_Written",
"flags" : "------+",
"value" : 100,
"normalized" : 100,
"worst" : 100,
"threshold" : 0,
"fail" : "-",
"raw" : "262"
},
{
"id" : "242",
"name" : "Total_LBAs_Read",
"flags" : "------+",
"value" : 100,
"normalized" : 100,
"worst" : 100,
"threshold" : 0,
"fail" : "-",
"raw" : "68"
}
],
"health" : "PASSED",
"type" : "ata"
}
+10
View File
@@ -0,0 +1,10 @@
E: DEVNAME=/dev/sdf
E: DEVTYPE=disk
E: ID_ATA_ROTATION_RATE_RPM=0
E: ID_BUS=ata
E: ID_MODEL=NT-256 2242
E: ID_PART_TABLE_TYPE=gpt
E: ID_SERIAL=NT-256_2242_000000000000
E: ID_SERIAL_SHORT=000000000000
E: ID_TYPE=disk
E: ID_WWN=0x0000000000000000