public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Lucas Barros <lucasbarros.kam@gmail.com>
To: pve-devel@lists.proxmox.com
Subject: [PATCH storage] fix #8211: disks: detect SAS hard disks as hdd
Date: Sat,  7 Nov 2026 19:08:58 -0300	[thread overview]
Message-ID: <20261107220858.12119-1-lucasbarros.kam@gmail.com> (raw)

SAS hard disks were listed with type 'unknown' and rpm -1. For a
rotational device the type 'hdd' is only set if a rotation rate is
known, and that rate is only read from the ID_ATA_ROTATION_RATE_RPM
udev property, which only exists for ATA devices.

SCSI devices report their nominal rotation rate in the block device
characteristics VPD page (0xb1), which the kernel exposes as
device/vpd_pgb1 in sysfs. Use that as a fallback if udev does not
provide a rotation rate, so SAS hard disks are listed as 'hdd' with
their actual rpm. Devices without that page, or which do not report a
rotation rate there, keep the current behavior.

Add a test case for a SAS hard disk with such a VPD page.

Signed-off-by: Lucas Barros <lucasbarros.kam@gmail.com>
---

Tested with the disk list tests in src/test (disklist_test.pm), including
the new sas_hdd case, which fails without this change. Not tested on
real SAS hardware, the VPD page layout is taken from SBC (Block Device
Characteristics VPD page, medium rotation rate in bytes 4-5); the
kernel exposes it as device/vpd_pgb1 since 5.19.
The fixture contains a small binary file (the raw VPD page).

This patch was prepared with the help of an LLM based coding assistant;
I reviewed the change and ran the tests mentioned above myself.

 src/PVE/Diskmanage.pm                         |  13 ++++++++
 src/test/disk_tests/sas_hdd/disklist          |   1 +
 .../disk_tests/sas_hdd/disklist_expected.json |  18 ++++++++++
 src/test/disk_tests/sas_hdd/sda/device/model  |   1 +
 src/test/disk_tests/sas_hdd/sda/device/vendor |   1 +
 .../disk_tests/sas_hdd/sda/device/vpd_pgb1    | Bin 0 -> 64 bytes
 .../disk_tests/sas_hdd/sda/queue/rotational   |   1 +
 src/test/disk_tests/sas_hdd/sda/size          |   1 +
 src/test/disk_tests/sas_hdd/sda_udevadm       |  31 ++++++++++++++++++
 9 files changed, 67 insertions(+)
 create mode 100644 src/test/disk_tests/sas_hdd/disklist
 create mode 100644 src/test/disk_tests/sas_hdd/disklist_expected.json
 create mode 100644 src/test/disk_tests/sas_hdd/sda/device/model
 create mode 100644 src/test/disk_tests/sas_hdd/sda/device/vendor
 create mode 100644 src/test/disk_tests/sas_hdd/sda/device/vpd_pgb1
 create mode 100644 src/test/disk_tests/sas_hdd/sda/queue/rotational
 create mode 100644 src/test/disk_tests/sas_hdd/sda/size
 create mode 100644 src/test/disk_tests/sas_hdd/sda_udevadm

diff --git a/src/PVE/Diskmanage.pm b/src/PVE/Diskmanage.pm
index d5bd147..13a9702 100644
--- a/src/PVE/Diskmanage.pm
+++ b/src/PVE/Diskmanage.pm
@@ -416,6 +416,18 @@ sub get_sysdir_info {
         $data->{$attr} = trim(file_read_firstline("$sysdir/device/$attr")) || 'unknown';
     }
 
+    # SCSI devices do not have the ATA rotation rate in udev, but report it in
+    # bytes 4-5 of the block device characteristics VPD page (0xb1), where
+    # values from 0x0401 to 0xfffe are the nominal rotation rate in rpm
+    my $vpd_pgb1 = "$sysdir/device/vpd_pgb1";
+    if (-f $vpd_pgb1) {
+        my $raw = eval { file_get_contents($vpd_pgb1, 4096) } // '';
+        if (length($raw) >= 6) {
+            my $rate = unpack('n', substr($raw, 4, 2));
+            $data->{rpm} = $rate if $rate >= 0x0401 && $rate <= 0xfffe;
+        }
+    }
+
     return $data;
 }
 
@@ -587,6 +599,7 @@ sub get_disks {
                 $type = 'nvme' if $dev =~ m/^nvme\d+n\d+$/;
                 $data->{rpm} = 0;
             } elsif ($sysdata->{rotational} == 1) {
+                $data->{rpm} = $sysdata->{rpm} if $data->{rpm} == -1 && defined($sysdata->{rpm});
                 if ($data->{rpm} != -1) {
                     $type = 'hdd';
                 } elsif ($data->{usb}) {
diff --git a/src/test/disk_tests/sas_hdd/disklist b/src/test/disk_tests/sas_hdd/disklist
new file mode 100644
index 0000000..9191c61
--- /dev/null
+++ b/src/test/disk_tests/sas_hdd/disklist
@@ -0,0 +1 @@
+sda
diff --git a/src/test/disk_tests/sas_hdd/disklist_expected.json b/src/test/disk_tests/sas_hdd/disklist_expected.json
new file mode 100644
index 0000000..6492219
--- /dev/null
+++ b/src/test/disk_tests/sas_hdd/disklist_expected.json
@@ -0,0 +1,18 @@
+{
+    "sda" : {
+	"gpt" : 1,
+	"devpath" : "/dev/sda",
+	"type" : "hdd",
+	"model" : "MODEL1",
+	"health" : "UNKNOWN",
+	"osdid" : -1,
+	"osdid-list" : null,
+	"wwn" : "0x0000000000000000",
+	"vendor" : "VENDOR1",
+	"rpm" : 10000,
+	"size" : 5120000,
+	"serial" : "SER2",
+	"wearout" : "N/A",
+	"by_id_link" : "/dev/disk/by-id/scsi-00000000000000000"
+    }
+}
diff --git a/src/test/disk_tests/sas_hdd/sda/device/model b/src/test/disk_tests/sas_hdd/sda/device/model
new file mode 100644
index 0000000..6b69674
--- /dev/null
+++ b/src/test/disk_tests/sas_hdd/sda/device/model
@@ -0,0 +1 @@
+MODEL1
diff --git a/src/test/disk_tests/sas_hdd/sda/device/vendor b/src/test/disk_tests/sas_hdd/sda/device/vendor
new file mode 100644
index 0000000..a7894eb
--- /dev/null
+++ b/src/test/disk_tests/sas_hdd/sda/device/vendor
@@ -0,0 +1 @@
+VENDOR1
diff --git a/src/test/disk_tests/sas_hdd/sda/device/vpd_pgb1 b/src/test/disk_tests/sas_hdd/sda/device/vpd_pgb1
new file mode 100644
index 0000000000000000000000000000000000000000..3dbd0c4aa8fc30d5e1c671feca4e93b4b368a342
GIT binary patch
literal 64
QcmZSB$Y7%`z(6(t07mZtB>(^b

literal 0
HcmV?d00001

diff --git a/src/test/disk_tests/sas_hdd/sda/queue/rotational b/src/test/disk_tests/sas_hdd/sda/queue/rotational
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/src/test/disk_tests/sas_hdd/sda/queue/rotational
@@ -0,0 +1 @@
+1
diff --git a/src/test/disk_tests/sas_hdd/sda/size b/src/test/disk_tests/sas_hdd/sda/size
new file mode 100644
index 0000000..5caff40
--- /dev/null
+++ b/src/test/disk_tests/sas_hdd/sda/size
@@ -0,0 +1 @@
+10000
diff --git a/src/test/disk_tests/sas_hdd/sda_udevadm b/src/test/disk_tests/sas_hdd/sda_udevadm
new file mode 100644
index 0000000..ac0744d
--- /dev/null
+++ b/src/test/disk_tests/sas_hdd/sda_udevadm
@@ -0,0 +1,31 @@
+P: /devices/pci0000:00/0000:00:03.0/0000:02:00.0/host4/port-4:0/end_device-4:0/target4:0:0/4:0:0:0/block/sda
+N: sda
+S: disk/by-id/scsi-00000000000000000
+S: disk/by-id/wwn-0x0000000000000000
+S: disk/by-path/pci-0000:02:00.0-sas-0x0000000000000000-lun-0
+E: DEVLINKS=/dev/disk/by-id/scsi-00000000000000000 /dev/disk/by-id/wwn-0x0000000000000000 /dev/disk/by-path/pci-0000:02:00.0-sas-0x0000000000000000-lun-0
+E: DEVNAME=/dev/sda
+E: DEVPATH=/devices/pci0000:00/0000:00:03.0/0000:02:00.0/host4/port-4:0/end_device-4:0/target4:0:0/4:0:0:0/block/sda
+E: DEVTYPE=disk
+E: ID_BUS=scsi
+E: ID_MODEL=MODEL1
+E: ID_MODEL_ENC=MODEL1\x20\x20\x20\x20\x20\x20
+E: ID_PART_TABLE_TYPE=gpt
+E: ID_PART_TABLE_UUID=605740f0-44a1-4dc5-9fea-bde166df963e
+E: ID_PATH=pci-0000:02:00.0-sas-0x0000000000000000-lun-0
+E: ID_PATH_TAG=pci-0000_02_00_0-sas-0x0000000000000000-lun-0
+E: ID_REVISION=ES64
+E: ID_SCSI=1
+E: ID_SCSI_SERIAL=SERIAL
+E: ID_SERIAL=SERIAL2
+E: ID_SERIAL_SHORT=SER2
+E: ID_TYPE=disk
+E: ID_VENDOR=VENDOR1
+E: ID_VENDOR_ENC=VENDOR1\x20
+E: ID_WWN=0x0000000000000000
+E: ID_WWN_WITH_EXTENSION=0x0000000000000000
+E: MAJOR=8
+E: MINOR=0
+E: SUBSYSTEM=block
+E: TAGS=:systemd:
+E: USEC_INITIALIZED=667541
-- 
2.50.1 (Apple Git-155)




                 reply	other threads:[~2026-11-07 22:09 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=20261107220858.12119-1-lucasbarros.kam@gmail.com \
    --to=lucasbarros.kam@gmail.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
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal