Re-enable by-path links for ata device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello, just created a patch for openSUSE to re-enable by-path links for
ata devices. The patch is based on handle_scsi_default function, but
instead of using "host{NUMBER}", but "ata{NUMBER}" and it works almost
the same as for scsi devices.

The patch is not the best or the cleanest, but it works.

Index: udev-182/src/udev-builtin-path_id.c
===================================================================
--- udev-182.orig/src/udev-builtin-path_id.c
+++ udev-182/src/udev-builtin-path_id.c
@@ -286,6 +286,85 @@ out:
         return hostdev;
 }
 
+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;
@@ -322,16 +401,8 @@ static struct udev_device *handle_scsi(s
                 goto out;
         }
 
-        /*
-         * We do not support the ATA transport class, it creates duplicated link
-         * names as the fake SCSI host adapters are all separated, they are all
-         * re-based as host == 0. ATA should just stop faking two duplicated
-         * hierarchies for a single topology and leave the SCSI stuff alone;
-         * until that happens, there are no by-path/ links for ATA devices behind
-         * an ATA transport class.
-         */
         if (strstr(name, "/ata") != NULL) {
-                parent = NULL;
+                parent = handle_ata(parent, path);
                 goto out;
         }

NOTE: The patch is for udev 182, but its easy to adapt this to systemd
187.
--
To unsubscribe from this list: send the line "unsubscribe linux-hotplug" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel]     [Linux DVB]     [Asterisk Internet PBX]     [DCCP]     [Netdev]     [X.org]     [Util Linux NG]     [Fedora Women]     [ALSA Devel]     [Linux USB]

  Powered by Linux