File 1001-re-enable-by_path-links-for-ata-devices.patch of Package systemd-208

From: Robert Milasan <rmilasan@suse.com>
Date: Thu, 12 Jul 2012 15:56:34 +0000
Subject: re-enable by_path links for ata devices

Fix by-path links for ATA transport (bnc#770910)
---
 src/udev/udev-builtin-path_id.c | 92 +++++++++++++++++++++++++++++++++++------
 1 file changed, 80 insertions(+), 12 deletions(-)

--- systemd-206.orig/src/udev/udev-builtin-path_id.c
+++ systemd-206/src/udev/udev-builtin-path_id.c
@@ -338,6 +338,85 @@ static struct udev_device *handle_scsi_h
         return parent;
 }
 
+static struct udev_device *handle_ata(struct udev_device *parent, char **path)
+{
+        struct udev_device *hostdev;
+        int host, bus, target, lun;
+        const char *name;
+        char *base;
+        char *pos;
+        DIR *dir;
+        struct dirent *dent;
+        int basenum, len;
+
+        hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host");
+        if (hostdev == NULL)
+                return NULL;
+
+        name = udev_device_get_sysname(parent);
+        if (sscanf(name, "%d:%d:%d:%d", &host, &bus, &target, &lun) != 4)
+                return NULL;
+
+        /* rebase ata offset to get the local relative number */
+        basenum = -1;
+        base = strdup(udev_device_get_syspath(hostdev));
+        if (base == NULL)
+                return NULL;
+        pos = strrchr(base, '/');
+        if (pos == NULL) {
+                parent = NULL;
+                goto out;
+        }
+        pos[0] = '\0';
+        len = strlen(base) - 5;
+        if (len <= 0) {
+                parent = NULL;
+                goto out;
+        }
+        base[len] = '\0';
+        dir = opendir(base);
+        if (dir == NULL) {
+                parent = NULL;
+                goto out;
+        }
+        for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
+                char *rest;
+                int i;
+
+                if (dent->d_name[0] == '.')
+                        continue;
+                if (dent->d_type != DT_DIR && dent->d_type != DT_LNK)
+                        continue;
+                if (strncmp(dent->d_name, "ata", 3) != 0)
+                        continue;
+                i = strtoul(&dent->d_name[3], &rest, 10);
+
+                /* ata devices start with 1, so decrease by 1 if i is bigger then 0 */
+                if (i > 0)
+                        i--;
+                if (rest[0] != '\0')
+                        continue;
+                /*
+                 * find the smallest number; the host really needs to export its
+                 * own instance number per parent device; relying on the global host
+                 * enumeration and plainly rebasing the numbers sounds unreliable
+                 */
+                if (basenum == -1 || i < basenum)
+                        basenum = i;
+        }
+        closedir(dir);
+        if (basenum == -1) {
+                parent = NULL;
+                goto out;
+        }
+        host -= basenum;
+
+        path_prepend(path, "scsi-%u:%u:%u:%u", host, bus, target, lun);
+out:
+        free(base);
+        return hostdev;
+}
+
 static struct udev_device *handle_scsi(struct udev_device *parent, char **path)
 {
         const char *devtype;
@@ -374,19 +453,8 @@ static struct udev_device *handle_scsi(s
                 goto out;
         }
 
-        /*
-         * We do not support the ATA transport class, it uses global counters
-         * to name the ata devices which numbers spread across multiple
-         * controllers.
-         *
-         * The real link numbers are not exported. Also, possible chains of ports
-         * behind port multipliers cannot be composed that way.
-         *
-         * Until all that is solved at the kernel level, there are no by-path/
-         * links for ATA devices.
-         */
         if (strstr(name, "/ata") != NULL) {
-                parent = NULL;
+                parent = handle_ata(parent, path);
                 goto out;
         }
 
openSUSE Build Service is sponsored by