]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev-builtin-path_id: SAS wide ports must have num_phys > 1
authorMartin Wilck <mwilck@suse.com>
Wed, 30 Oct 2024 15:57:39 +0000 (16:57 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 4 Nov 2024 08:55:48 +0000 (09:55 +0100)
Some kernel SAS drivers (e.g. smartpqi) expose ports with num_phys = 0. udev
shouldn't treat these ports as wide ports.  SAS wide ports always have
num_phys > 1. See comments for sas_port_add_phy() in the kernel sources.

Sample data from a smartpqi system to illustrate the issue below.
Here the phy device is attached to port 0:0, which has no end devices attached
and the SAS end device (where sda is attached) is associated with SAS
port 0:1, which has no associated phy device. Thus num_phys for port-0:1 is 0.
This is arguably wrong, but it's how smartpqi has always set up its devices in
sysfs.

/sys/class/sas_phy/phy-0:0 -> ../../devices/pci0000:46/0000:46:02.0/0000:47:00.0/host0/scsi_host/host0/phy-0:0/sas_phy/phy-0:0
/sys/devices/pci0000:46/0000:46:02.0/0000:47:00.0/host0/scsi_host/host0/port-0:0/phy-0:0 -> ../phy-0:0
/sys/devices/pci0000:46/0000:46:02.0/0000:47:00.0/host0/scsi_host/host0/phy-0:0/port -> ../port-0:0

/sys/class/sas_device/end_device-0:1 -> ../../devices/pci0000:46/0000:46:02.0/0000:47:00.0/host0/scsi_host/host0/port-0:1/end_device-0:1/sas_device/end_device-0:1
/sys/class/block/sda -> ../../devices/pci0000:46/0000:46:02.0/0000:47:00.0/host0/scsi_host/host0/port-0:1/end_device-0:1/target0:0:0/0:0:0:0/block/sda

Signed-off-by: Martin Wilck <mwilck@suse.com>
src/udev/udev-builtin-path_id.c

index a23b32db3e9e4b0c9cac5c288eac9dd257e47fdb..77abff004e482f3c3197200a20df1cddd843bfed 100644 (file)
@@ -15,6 +15,7 @@
 #include <unistd.h>
 
 #include "alloc-util.h"
+#include "device-private.h"
 #include "device-util.h"
 #include "dirent-util.h"
 #include "fd-util.h"
@@ -159,7 +160,8 @@ static sd_device *handle_scsi_sas(sd_device *parent, char **path) {
         _cleanup_(sd_device_unrefp) sd_device *target_sasdev = NULL, *expander_sasdev = NULL, *port_sasdev = NULL;
         const char *sas_address = NULL;
         const char *phy_id;
-        const char *phy_count, *sysname;
+        const char *sysname;
+        unsigned num_phys;
         _cleanup_free_ char *lun = NULL;
 
         assert(parent);
@@ -182,11 +184,10 @@ static sd_device *handle_scsi_sas(sd_device *parent, char **path) {
         /* Get port device */
         if (sd_device_new_from_subsystem_sysname(&port_sasdev, "sas_port", sysname) < 0)
                 return NULL;
-        if (sd_device_get_sysattr_value(port_sasdev, "num_phys", &phy_count) < 0)
+        if (device_get_sysattr_unsigned(port_sasdev, "num_phys", &num_phys) < 0)
                 return NULL;
-
-        /* Check if we are simple disk */
-        if (!streq(phy_count, "1"))
+        /* Check if this is a wide port (i.e. num_phys is 2 or higher) */
+        if (num_phys > 1)
                 return handle_scsi_sas_wide_port(parent, path);
 
         /* Get connected phy */