chiark / gitweb /
install: make InstallContext::{will_install,have_installed} OrderedHashmaps
[elogind.git] / src / udev / udev-builtin-path_id.c
index 74763301964d5bb3d2ab3c00cffd85cb9ed1b842..073f05aac31c733752cbccc1d3435750d971b93d 100644 (file)
@@ -33,8 +33,7 @@
 #include "udev.h"
 
 _printf_(2,3)
-static int path_prepend(char **path, const char *fmt, ...)
-{
+static int path_prepend(char **path, const char *fmt, ...) {
         va_list va;
         char *pre;
         int err = 0;
@@ -65,19 +64,17 @@ out:
 ** Linux only supports 32 bit luns.
 ** See drivers/scsi/scsi_scan.c::scsilun_to_int() for more details.
 */
-static int format_lun_number(struct udev_device *dev, char **path)
-{
+static int format_lun_number(struct udev_device *dev, char **path) {
         unsigned long lun = strtoul(udev_device_get_sysnum(dev), NULL, 10);
 
         /* address method 0, peripheral device addressing with bus id of zero */
         if (lun < 256)
-                return path_prepend(path, "lun-%d", lun);
+                return path_prepend(path, "lun-%lu", lun);
         /* handle all other lun addressing methods by using a variant of the original lun format */
-        return path_prepend(path, "lun-0x%04x%04x00000000", (lun & 0xffff), (lun >> 16) & 0xffff);
+        return path_prepend(path, "lun-0x%04lx%04lx00000000", lun & 0xffff, (lun >> 16) & 0xffff);
 }
 
-static struct udev_device *skip_subsystem(struct udev_device *dev, const char *subsys)
-{
+static struct udev_device *skip_subsystem(struct udev_device *dev, const char *subsys) {
         struct udev_device *parent = dev;
 
         while (parent != NULL) {
@@ -92,8 +89,7 @@ static struct udev_device *skip_subsystem(struct udev_device *dev, const char *s
         return dev;
 }
 
-static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent, char **path)
-{
+static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent, char **path) {
         struct udev *udev  = udev_device_get_udev(parent);
         struct udev_device *targetdev;
         struct udev_device *fcdev = NULL;
@@ -122,8 +118,7 @@ out:
         return parent;
 }
 
-static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **path)
-{
+static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **path) {
         struct udev *udev  = udev_device_get_udev(parent);
         struct udev_device *targetdev;
         struct udev_device *target_parent;
@@ -159,8 +154,7 @@ out:
         return parent;
 }
 
-static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **path)
-{
+static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **path) {
         struct udev *udev  = udev_device_get_udev(parent);
         struct udev_device *transportdev;
         struct udev_device *sessiondev = NULL;
@@ -218,8 +212,7 @@ out:
         return parent;
 }
 
-static struct udev_device *handle_scsi_default(struct udev_device *parent, char **path)
-{
+static struct udev_device *handle_scsi_default(struct udev_device *parent, char **path) {
         struct udev_device *hostdev;
         int host, bus, target, lun;
         const char *name;
@@ -339,8 +332,7 @@ static struct udev_device *handle_scsi_hyperv(struct udev_device *parent, char *
         return parent;
 }
 
-static struct udev_device *handle_scsi(struct udev_device *parent, char **path)
-{
+static struct udev_device *handle_scsi(struct udev_device *parent, char **path) {
         const char *devtype;
         const char *name;
         const char *id;
@@ -401,8 +393,7 @@ out:
         return parent;
 }
 
-static struct udev_device *handle_cciss(struct udev_device *parent, char **path)
-{
+static struct udev_device *handle_cciss(struct udev_device *parent, char **path) {
         const char *str;
         unsigned int controller, disk;
 
@@ -415,8 +406,7 @@ static struct udev_device *handle_cciss(struct udev_device *parent, char **path)
         return parent;
 }
 
-static void handle_scsi_tape(struct udev_device *dev, char **path)
-{
+static void handle_scsi_tape(struct udev_device *dev, char **path) {
         const char *name;
 
         /* must be the last device in the syspath */
@@ -430,8 +420,7 @@ static void handle_scsi_tape(struct udev_device *dev, char **path)
                 path_prepend(path, "st%c", name[2]);
 }
 
-static struct udev_device *handle_usb(struct udev_device *parent, char **path)
-{
+static struct udev_device *handle_usb(struct udev_device *parent, char **path) {
         const char *devtype;
         const char *str;
         const char *port;
@@ -453,8 +442,7 @@ static struct udev_device *handle_usb(struct udev_device *parent, char **path)
         return parent;
 }
 
-static struct udev_device *handle_bcma(struct udev_device *parent, char **path)
-{
+static struct udev_device *handle_bcma(struct udev_device *parent, char **path) {
         const char *sysname;
         unsigned int core;
 
@@ -466,8 +454,7 @@ static struct udev_device *handle_bcma(struct udev_device *parent, char **path)
         return parent;
 }
 
-static struct udev_device *handle_ccw(struct udev_device *parent, struct udev_device *dev, char **path)
-{
+static struct udev_device *handle_ccw(struct udev_device *parent, struct udev_device *dev, char **path) {
         struct udev_device *scsi_dev;
 
         scsi_dev = udev_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device");
@@ -491,11 +478,11 @@ out:
         return parent;
 }
 
-static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool test)
-{
+static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool test) {
         struct udev_device *parent;
         char *path = NULL;
-        bool some_transport = false;
+        bool supported_transport = false;
+        bool supported_parent = false;
 
         /* S390 ccw bus */
         parent = udev_device_get_parent_with_subsystem_devtype(dev, "ccw", NULL);
@@ -516,50 +503,62 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool
                         handle_scsi_tape(parent, &path);
                 } else if (streq(subsys, "scsi")) {
                         parent = handle_scsi(parent, &path);
-                        some_transport = true;
+                        supported_transport = true;
                 } else if (streq(subsys, "cciss")) {
                         parent = handle_cciss(parent, &path);
-                        some_transport = true;
+                        supported_transport = true;
                 } else if (streq(subsys, "usb")) {
                         parent = handle_usb(parent, &path);
-                        some_transport = true;
+                        supported_transport = true;
                 } else if (streq(subsys, "bcma")) {
                         parent = handle_bcma(parent, &path);
-                        some_transport = true;
+                        supported_transport = true;
                 } else if (streq(subsys, "serio")) {
                         path_prepend(&path, "serio-%s", udev_device_get_sysnum(parent));
                         parent = skip_subsystem(parent, "serio");
                 } else if (streq(subsys, "pci")) {
                         path_prepend(&path, "pci-%s", udev_device_get_sysname(parent));
                         parent = skip_subsystem(parent, "pci");
+                        supported_parent = true;
                 } else if (streq(subsys, "platform")) {
                         path_prepend(&path, "platform-%s", udev_device_get_sysname(parent));
                         parent = skip_subsystem(parent, "platform");
-                        some_transport = true;
+                        supported_transport = true;
+                        supported_parent = true;
                 } else if (streq(subsys, "acpi")) {
                         path_prepend(&path, "acpi-%s", udev_device_get_sysname(parent));
                         parent = skip_subsystem(parent, "acpi");
+                        supported_parent = true;
                 } else if (streq(subsys, "xen")) {
                         path_prepend(&path, "xen-%s", udev_device_get_sysname(parent));
                         parent = skip_subsystem(parent, "xen");
-                } else if (streq(subsys, "virtio")) {
-                        path_prepend(&path, "virtio-pci-%s", udev_device_get_sysname(parent));
-                        parent = skip_subsystem(parent, "virtio");
+                        supported_parent = true;
                 } else if (streq(subsys, "scm")) {
                         path_prepend(&path, "scm-%s", udev_device_get_sysname(parent));
                         parent = skip_subsystem(parent, "scm");
-                        some_transport = true;
+                        supported_transport = true;
+                        supported_parent = true;
                 }
 
                 parent = udev_device_get_parent(parent);
         }
 
         /*
-         * Do not return a single-parent-device-only for block
-         * devices, they might have entire buses behind it which
-         * do not get unique IDs only by using the parent device.
+         * Do return devices with have an unknown type of parent device, they
+         * might produce conflicting IDs below multiple independent parent
+         * devices.
          */
-        if (!some_transport && streq(udev_device_get_subsystem(dev), "block")) {
+        if (!supported_parent) {
+                free(path);
+                path = NULL;
+        }
+
+        /*
+         * Do not return a have-only a single-parent block devices, some
+         * have entire hidden buses behind it, and not create predictable
+         * IDs that way.
+         */
+        if (streq(udev_device_get_subsystem(dev), "block") && !supported_transport) {
                 free(path);
                 path = NULL;
         }