X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fudev%2Fudev-builtin-path_id.c;h=df996cb17aca160fd4496b6769adf82a62f52826;hb=73ae2b7dade339c8a258dcf4fa2b302e238117e1;hp=3ca59e011373a963d0282f01e32be33dfcc24a4c;hpb=bf81e792f3c0aed54edf004c1c95cc6f6d81d0ee;p=elogind.git diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c index 3ca59e011..df996cb17 100644 --- a/src/udev/udev-builtin-path_id.c +++ b/src/udev/udev-builtin-path_id.c @@ -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,8 +64,7 @@ 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 */ @@ -76,8 +74,7 @@ static int format_lun_number(struct udev_device *dev, char **path) 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, bool *supported_parent) { const char *devtype; const char *name; const char *id; @@ -354,6 +346,7 @@ static struct udev_device *handle_scsi(struct udev_device *parent, char **path) if (id != NULL) { parent = skip_subsystem(parent, "scsi"); path_prepend(path, "ieee1394-0x%s", id); + *supported_parent = true; goto out; } @@ -362,16 +355,19 @@ static struct udev_device *handle_scsi(struct udev_device *parent, char **path) if (strstr(name, "/rport-") != NULL) { parent = handle_scsi_fibre_channel(parent, path); + *supported_parent = true; goto out; } if (strstr(name, "/end_device-") != NULL) { parent = handle_scsi_sas(parent, path); + *supported_parent = true; goto out; } if (strstr(name, "/session") != NULL) { parent = handle_scsi_iscsi(parent, path); + *supported_parent = true; goto out; } @@ -401,8 +397,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 +410,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 +424,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 +446,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 +458,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 +482,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); @@ -515,48 +506,63 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool } else if (streq(subsys, "scsi_tape")) { handle_scsi_tape(parent, &path); } else if (streq(subsys, "scsi")) { - parent = handle_scsi(parent, &path); - some_transport = true; + parent = handle_scsi(parent, &path, &supported_parent); + 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"); + 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 not return devices with an unknown parent device type. They + * might produce conflicting IDs if the parent does not provide a + * unique and predictable name. */ - if (!some_transport && streq(udev_device_get_subsystem(dev), "block")) { + if (!supported_parent) { + free(path); + path = NULL; + } + + /* + * Do not return block devices without a well-known transport. Some + * devices do not expose their buses and do not provide a unique + * and predictable name that way. + */ + if (streq(udev_device_get_subsystem(dev), "block") && !supported_transport) { free(path); path = NULL; }