From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id 012971FF0AA for ; Tue, 06 Oct 2026 10:54:22 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id BFC422159E; Tue, 06 Oct 2026 10:54:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dualfroz.com; s=dkim; t=1791026486; h=from:subject:date:message-id:to:mime-version: content-transfer-encoding; bh=FR/yqmuELSvCxl2V2tlaWcCB4qOZHMXOlQXhgqTHMI0=; b=YQ5kldKrDYyy3Uw+L+u0uWABJW2Vm99OWcT6UZjiS+8hvSWD79tnfTU6KzqWUsCbeW0PvJ SaKGamX4lsL90BnmPRnjCyGO8Bv/O+5msVcKNwVdgp7xNgxbG94Ff4/FRQI3AIiPPQ+3CE 24lSlmb8nEQa/wEbEShjcuHsva0gwInuAy1JqHA6tMVbfSibHjjONlLqY19yT4Otv1kmkX 2X6LHrRo6Ps0z55AhdlPFECbCGrNBUhTkeppR3kFsdERSGXtRz6qnjMfi7SKw2zbNeNC1v iQmDgujsGdegmNrACZaLNhjYXZ+S55DwXTCbZezetRdgbx/CnT8OpNSbht8iRg== From: Michal Fox 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 Message-ID: <20261003112122.6-1-me@dualfroz.com> X-Mailer: git-send-email 2.47.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Last-TLS-Session-Version: TLSv1.3 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.239 Adjusted score from AWL reputation of From: address DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain DKIM_VALID_EF -0.1 Message has a valid DKIM or DK signature from envelope-from domain DMARC_PASS -0.1 DMARC pass policy SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record X-MailFrom: me@dualfroz.com X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation Message-ID-Hash: SDDBNSXPVZYOSY6WQMD3VJ7GIV4TXEXG X-Message-ID-Hash: SDDBNSXPVZYOSY6WQMD3VJ7GIV4TXEXG X-Mailman-Approved-At: Tue, 06 Oct 2026 10:54:04 +0200 X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: 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 --- 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