From: Michal Fox <me@dualfroz.com>
To: pve-devel@lists.proxmox.com
Subject: [PATCH storage] fix #6405: disks: smart: parse ATA attributes with additional flags
Date: Sat, 3 Oct 2026 11:21:22 +0000 [thread overview]
Message-ID: <20261003112122.6-1-me@dualfroz.com> (raw)
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
reply other threads:[~2026-10-06 8:54 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261003112122.6-1-me@dualfroz.com \
--to=me@dualfroz.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox