dryang / rpms / systemd

Forked from rpms/systemd a year ago
Clone
923a60
From 8572638ab99090b016ccc28ac1f69aa7759e43cf Mon Sep 17 00:00:00 2001
923a60
From: Robert Milasan <rmilasan@suse.com>
923a60
Date: Thu, 12 Jul 2012 15:56:34 +0000
923a60
Subject: [PATCH] Persistent by_path links for ata devices
923a60
923a60
With newer kernel we have the 'port_no' attribute,
923a60
which allows us to construct a valid ata by-path link.
923a60
923a60
With this patch ATA links of the form
923a60
923a60
ata-<port>.[01]
923a60
923a60
(for master/slave devices) or
923a60
923a60
ata-<port>.<pmp>.0
923a60
923a60
(for devices behind port multipliers)
923a60
are generated.
923a60
923a60
References: bnc#770910,FATE#317063
923a60
923a60
Signed-off-by: Robert Milasan <rmilasan@suse.com>
923a60
Signed-off-by: Hannes Reinecke <hare@suse.de>
923a60
923a60
Downstream patch
923a60
https://build.opensuse.org/package/view_file/Base:System/systemd/1001-re-enable-by_path-links-for-ata-devices.patch
923a60
923a60
Resolves: #1045498
923a60
---
923a60
 src/udev/udev-builtin-path_id.c | 53 +++++++++++++++++++++++++--------
923a60
 1 file changed, 41 insertions(+), 12 deletions(-)
923a60
923a60
diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c
923a60
index b6749aab76..bb0a6242ac 100644
923a60
--- a/src/udev/udev-builtin-path_id.c
923a60
+++ b/src/udev/udev-builtin-path_id.c
923a60
@@ -426,6 +426,46 @@ static struct udev_device *handle_scsi_hyperv(struct udev_device *parent, char *
923a60
         return parent;
923a60
 }
923a60
 
923a60
+static struct udev_device *handle_ata(struct udev_device *parent, char **path)
923a60
+{
923a60
+        struct udev *udev  = udev_device_get_udev(parent);
923a60
+        struct udev_device *hostdev, *portdev;
923a60
+        int host, bus, target, lun, port_no;
923a60
+        const char *name, *atahost, *port;
923a60
+
923a60
+        hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host");
923a60
+        if (hostdev == NULL)
923a60
+                return NULL;
923a60
+
923a60
+        name = udev_device_get_sysname(parent);
923a60
+        if (sscanf(name, "%d:%d:%d:%d", &host, &bus, &target, &lun) != 4)
923a60
+                return NULL;
923a60
+
923a60
+        /* The ata port is the parent of the SCSI host */
923a60
+        hostdev = udev_device_get_parent(hostdev);
923a60
+        atahost = udev_device_get_sysname(hostdev);
923a60
+        if (strncmp(atahost, "ata", 3))
923a60
+                return NULL;
923a60
+
923a60
+        /* ATA port number is found in 'port_no' attribute */
923a60
+        portdev = udev_device_new_from_subsystem_sysname(udev, "ata_port",
923a60
+                                                         atahost);
923a60
+        port = udev_device_get_sysattr_value(portdev, "port_no");
923a60
+        if (!port || sscanf(port, "%d", &port_no) != 1) {
923a60
+                hostdev = NULL;
923a60
+                goto out;
923a60
+        }
923a60
+        if (bus != 0)
923a60
+                /* Devices behind port multiplier have a bus != 0*/
923a60
+                path_prepend(path, "ata-%u.%u.0", port_no, bus);
923a60
+        else
923a60
+                /* Master/slave are distinguished by target id */
923a60
+                path_prepend(path, "ata-%u.%u", port_no, target);
923a60
+out:
923a60
+        udev_device_unref(portdev);
923a60
+        return hostdev;
923a60
+}
923a60
+
923a60
 static struct udev_device *handle_scsi(struct udev_device *parent, char **path, bool *supported_parent) {
923a60
         const char *devtype;
923a60
         const char *name;
923a60
@@ -465,19 +505,8 @@ static struct udev_device *handle_scsi(struct udev_device *parent, char **path,
923a60
                 goto out;
923a60
         }
923a60
 
923a60
-        /*
923a60
-         * We do not support the ATA transport class, it uses global counters
923a60
-         * to name the ata devices which numbers spread across multiple
923a60
-         * controllers.
923a60
-         *
923a60
-         * The real link numbers are not exported. Also, possible chains of ports
923a60
-         * behind port multipliers cannot be composed that way.
923a60
-         *
923a60
-         * Until all that is solved at the kernel level, there are no by-path/
923a60
-         * links for ATA devices.
923a60
-         */
923a60
         if (strstr(name, "/ata") != NULL) {
923a60
-                parent = NULL;
923a60
+                parent = handle_ata(parent, path);
923a60
                 goto out;
923a60
         }
923a60