From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id EAD731FF09B for ; Mon, 09 Nov 2026 14:42:04 +0100 (CET) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 06CF021412; Mon, 09 Nov 2026 14:42:02 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20260707; t=1794231710; x=1794836510; darn=lists.proxmox.com; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=6WYu09et7l6wD28PbZoqhiFYCOY71hPHl76yPHAlO/8=; b=GWPsNSwk8nkJYwVz+zeQmyx0q7jnIvTP80t1ZwkFeHzUrGDrCfaRHei4kT586NA+U4 A/NF6CrjjQ/1Ev+Vyumc+QGKiVE04rJIl74chODP+K/VF8SJuLT42AHoaA68oGYyf7ku weJEX2kmCtwtP1GtZl6GGFugGpsMlAJXpJkNEm4+w+ktWJtS6zjzM1or6+I+h2fcw9V0 Le2sj5UT3Mtd1PZbqhxknO1wgXBhHSS2InOo0SoZtoVLe1gcgY814zHnKaOYrBrdLT7h KdWl/fQCogvJmrWG5eE8b/BP1m3XlJ+66S4phl4m8ka9WD7qUqiJz9o9ChGcU2PrfRYE M4eA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1794231710; x=1794836510; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=6WYu09et7l6wD28PbZoqhiFYCOY71hPHl76yPHAlO/8=; b=BDWehnyVu3e0HNMUNDexBJ5Fz9XUFZVQqae5hDJ97T6AAfT5nSrPr05ONgTpEpIK7e WntPKF4U4bzei+2160CWKZ+IMYUPquYteAG47FZdXEJEpRe7LJPoFKlhiezUe6/P3Jjz mA6jJe3sS9jJsmAzn97ClNU7PhwH0+aNI+B2eMOxUmfHWzKYoLiwkpf+bKJb+C41E2dj k239NP6ANPijc4r2plNm6MTPgutuP22ZDeG5OISl1axfyeFgOW1AMT071rrorZq2HMIA 37ebTpwQD0FQegGvhf0F1u2pts/FX1xz2AUksrUPCRBwGhZGRhhdIkvmi/paF5JHMPvr oSbA== X-Gm-Message-State: APuU4Z/qO3/iMlDyh9cneJKqK+CpVhkc1eaBjgFlJgRKjkQIjpZc5+gC UnuKVKdADO3NQt5FRa03+wm0wO8mi0SQit3b7Y+oIEhnuYPXHjfDplbOI30w2AK6 X-Gm-Gg: AYBFou3n/1pb0fY/T0CJXk2lnOTYPCw51/LMv7WG9ovZEs7tIrYkgnMyGb/1lsBRRvf OOmTX5PHuHqL+R4l9zPahIDnqIcn2sRmU3PGijwU0R62kz6qF3Wve5tJTeDRQNkB/sPZOgP3pc9 dFbBYFqkSlMlUytSu1CsItPmgO412QmrIU1f8VYa7R6wGvcca7ftqHABrif3dHIIbvWtyqj6bMf L7qNUlvDzpKCoZ9CA4bqbdrBI5K61ORx3An/MvHSu2SSQCSWF/oYRSou9KxNqCFIUvOsMD8UZR/ BcCi/zE7fOwCibp8/jveYdyTiHsujRkS5dm2I7/Fsu3RyIXMvVFgnnG05YupEHyEuIqb60DIrrJ yO4BNZmCJ19+OYWXqplaXzMQBlFdH2kDnuocBqARR66qBy5HtvYVFKUkTWmyAN+AM66LSTzlr2G qkD+8r31E37Ga67EruIJ6Zd/pyMJyTBuH1Sx4NsKVwZXy3LVcbdoJqKvhb+zIKRu2HiByCsY+iF Lqe3CteXpeuRAv1YNzep15Z6QcnUdsrGeQspLVomkTCleabXlWQeWS6BgoPhUftouAwG27A6CrW 8ULfbCqgbzt+8quxo0iPEpJvWxDyLyJWhHcu/8CVsgwUZeKj6dsV8dnA/b60UAFPVMXvuhyBctb 7nsZyKKBwnft+YGjEB4tJlUrnB2kl/sGreBfMkiZFejy1dA== X-Received: by 2002:a05:6122:1353:b0:5ec:c180:e1a1 with SMTP id 71dfb90a1353d-5ece7149ddcmr1172746e0c.2.1794231709513; Mon, 09 Nov 2026 05:41:49 -0800 (PST) From: Lucas Barros To: pve-devel@lists.proxmox.com Subject: [PATCH storage v2] fix #8211: disks: detect SAS hard disks as hdd Date: Mon, 9 Nov 2026 10:41:43 -0300 Message-ID: <20261109134143.72587-1-lucasbarros.kam@gmail.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20261107220858.12119-1-lucasbarros.kam@gmail.com> References: <20261107220858.12119-1-lucasbarros.kam@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 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 FREEMAIL_FROM 0.001 Sender email is commonly abused enduser mail provider LOTS_OF_MONEY 0.001 Huge... sums of money POISEN_SPAM_PILL 0.1 Meta: its spam POISEN_SPAM_PILL_1 0.1 random spam to be learned in bayes POISEN_SPAM_PILL_3 0.1 random spam to be learned in bayes RCVD_IN_DNSWL_NONE -0.0001 Sender listed at https://www.dnswl.org/, no trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: KJDXXLFOTGECCSMKVYMMXZYC4HYFLYRV X-Message-ID-Hash: KJDXXLFOTGECCSMKVYMMXZYC4HYFLYRV X-MailFrom: lucasbarros.kam@gmail.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: 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 --- Changes since v1: * run proxmox-perltidy, which wraps the new line in get_disks(); no functional change Tested on a PVE 9 test node with the full test suite of the repo ('make test' in src: 562 tests, disk list tests 7 -> 8, the new sas_hdd case fails without the change). No SAS hardware at hand, so I checked the real kernel interface with a SCSI disk emulated by QEMU (virtio-scsi, scsi-hd with rotation_rate=10000) in a VM with kernel 6.12, which exposes the page in sysfs and has no ATA rotation rate in udev: $ od -An -tx1 -N8 /sys/block/sdb/device/vpd_pgb1 00 b1 00 3c 27 10 00 00 $ cat /sys/block/sdb/queue/rotational 1 Running get_disks() against that sysfs and udevadm data: without the patch: 'type' => 'unknown', 'rpm' => -1 with the patch: 'type' => 'hdd', 'rpm' => 10000 The VPD page layout is from SBC (Block Device Characteristics VPD page, medium rotation rate in bytes 4-5). 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 | 14 ++++++++ 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, 68 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..46abd98 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,8 @@ 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.47.3