public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [PATCH storage] fix #6405: disks: smart: parse ATA attributes with additional flags
@ 2026-10-03 11:21 Michal Fox
  0 siblings, 0 replies; only message in thread
From: Michal Fox @ 2026-10-03 11:21 UTC (permalink / raw)
  To: pve-devel

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>
---
 src/PVE/Diskmanage.pm                         |   3 +-
 src/test/disk_tests/ssd_smart/disklist        |   1 +
 .../ssd_smart/disklist_expected.json          |  15 ++
 .../disk_tests/ssd_smart/sdf/device/vendor    |   1 +
 .../disk_tests/ssd_smart/sdf/queue/rotational |   1 +
 src/test/disk_tests/ssd_smart/sdf/size        |   1 +
 src/test/disk_tests/ssd_smart/sdf_smart       |  31 +++
 .../ssd_smart/sdf_smart_expected.json         | 182 ++++++++++++++++++
 src/test/disk_tests/ssd_smart/sdf_udevadm     |  10 +
 9 files changed, 244 insertions(+), 1 deletion(-)
 create mode 100644 src/test/disk_tests/ssd_smart/sdf/device/vendor
 create mode 100644 src/test/disk_tests/ssd_smart/sdf/queue/rotational
 create mode 100644 src/test/disk_tests/ssd_smart/sdf/size
 create mode 100644 src/test/disk_tests/ssd_smart/sdf_smart
 create mode 100644 src/test/disk_tests/ssd_smart/sdf_smart_expected.json
 create mode 100644 src/test/disk_tests/ssd_smart/sdf_udevadm

diff --git a/src/PVE/Diskmanage.pm b/src/PVE/Diskmanage.pm
index d9ce0d0..0d9d6fc 100644
--- a/src/PVE/Diskmanage.pm
+++ b/src/PVE/Diskmanage.pm
@@ -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 = {};
 
diff --git a/src/test/disk_tests/ssd_smart/disklist b/src/test/disk_tests/ssd_smart/disklist
index 18048d5..b5daaf1 100644
--- a/src/test/disk_tests/ssd_smart/disklist
+++ b/src/test/disk_tests/ssd_smart/disklist
@@ -3,3 +3,4 @@ sdb
 sdc
 sdd
 sde
+sdf
diff --git a/src/test/disk_tests/ssd_smart/disklist_expected.json b/src/test/disk_tests/ssd_smart/disklist_expected.json
index 64d2eac..54b56cb 100644
--- a/src/test/disk_tests/ssd_smart/disklist_expected.json
+++ b/src/test/disk_tests/ssd_smart/disklist_expected.json
@@ -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"
     }
 }
diff --git a/src/test/disk_tests/ssd_smart/sdf/device/vendor b/src/test/disk_tests/ssd_smart/sdf/device/vendor
new file mode 100644
index 0000000..531030d
--- /dev/null
+++ b/src/test/disk_tests/ssd_smart/sdf/device/vendor
@@ -0,0 +1 @@
+ATA
diff --git a/src/test/disk_tests/ssd_smart/sdf/queue/rotational b/src/test/disk_tests/ssd_smart/sdf/queue/rotational
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/src/test/disk_tests/ssd_smart/sdf/queue/rotational
@@ -0,0 +1 @@
+0
diff --git a/src/test/disk_tests/ssd_smart/sdf/size b/src/test/disk_tests/ssd_smart/sdf/size
new file mode 100644
index 0000000..83b33d2
--- /dev/null
+++ b/src/test/disk_tests/ssd_smart/sdf/size
@@ -0,0 +1 @@
+1000
diff --git a/src/test/disk_tests/ssd_smart/sdf_smart b/src/test/disk_tests/ssd_smart/sdf_smart
new file mode 100644
index 0000000..220d42c
--- /dev/null
+++ b/src/test/disk_tests/ssd_smart/sdf_smart
@@ -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
diff --git a/src/test/disk_tests/ssd_smart/sdf_smart_expected.json b/src/test/disk_tests/ssd_smart/sdf_smart_expected.json
new file mode 100644
index 0000000..d055711
--- /dev/null
+++ b/src/test/disk_tests/ssd_smart/sdf_smart_expected.json
@@ -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"
+}
diff --git a/src/test/disk_tests/ssd_smart/sdf_udevadm b/src/test/disk_tests/ssd_smart/sdf_udevadm
new file mode 100644
index 0000000..edada33
--- /dev/null
+++ b/src/test/disk_tests/ssd_smart/sdf_udevadm
@@ -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
-- 
2.43.0




^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-10-06  8:54 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-03 11:21 [PATCH storage] fix #6405: disks: smart: parse ATA attributes with additional flags Michal Fox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal