X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=namedev.c;h=137446e255322143a08fc424c6907d87695fe9bd;hb=eb7a964a7c66e5aff8147026a60c99258454b612;hp=0e1af9385fac995862570c30bddd9c464f63c287;hpb=8ffb636f013a193688b132b8512e77b0747c41a1;p=elogind.git diff --git a/namedev.c b/namedev.c index 0e1af9385..137446e25 100644 --- a/namedev.c +++ b/namedev.c @@ -29,12 +29,14 @@ #include #include #include +#include #include #include #include "list.h" #include "udev.h" #include "udev_version.h" +#include "logging.h" #include "namedev.h" #include "libsysfs/libsysfs.h" #include "klibc_fixups.h" @@ -195,16 +197,6 @@ static void apply_format(struct udevice *udev, unsigned char *string) strcat(pos, udev->kernel_number); dbg("substitute kernel number '%s'", udev->kernel_number); break; - case 'D': - if (strlen(udev->kernel_number) == 0) { - strcat(pos, "disc"); - dbg("substitute devfs disc"); - break; - } - strcat(pos, "part"); - strcat(pos, udev->kernel_number); - dbg("substitute devfs part '%s'", udev->kernel_number); - break; case 'm': sprintf(pos, "%u", udev->minor); dbg("substitute minor number '%u'", udev->minor); @@ -294,12 +286,12 @@ static void wait_for_device_to_initialize(struct sysfs_device *sysfs_device) /* sleep to give the kernel a chance to create the file */ sleep(1); } - dbg("Timed out waiting for '%s' file, continuing on anyway...", b->file); + dbg("timed out waiting for '%s' file, continuing on anyway...", b->file); goto exit; } b++; } - dbg("Did not find bus type '%s' on list of bus_id_files, contact greg@kroah.com", sysfs_device->bus); + dbg("did not find bus type '%s' on list of bus_id_files, contact greg@kroah.com", sysfs_device->bus); exit: return; /* here to prevent compiler warning... */ } @@ -514,11 +506,8 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de { struct sysfs_device *sysfs_device; struct sysfs_class_device *class_dev_parent; + struct timespec tspec; int loop; - char filename[SYSFS_PATH_MAX + 6]; - int retval; - char *temp; - int partition = 0; /* Figure out where the device symlink is at. For char devices this will * always be in the class_dev->path. But for block devices, it's different. @@ -529,69 +518,54 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de * symlink yet. We do sit and spin on waiting for them right now, we should * possibly have a whitelist for these devices here... */ - strcpy(filename, class_dev->path); - dbg("filename = %s", filename); - if (strcmp(class_dev->classname, SYSFS_BLOCK_NAME) == 0) { - if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { - temp = strrchr(filename, '/'); - if (temp) { - char *temp2 = strrchr(filename, '/'); - partition = 1; - *temp = 0x00; - dbg("temp2 = %s", temp2); - if (temp2 && (strcmp(temp2, "/block") == 0)) { - /* oops, we have no parent block device, so go back to original directory */ - strcpy(filename, class_dev->path); - partition = 0; - } - } - } - } - strcat(filename, "/device"); + class_dev_parent = sysfs_get_classdev_parent(class_dev); + if (class_dev_parent) + dbg("Really a partition"); - loop = 2; + tspec.tv_sec = 0; + tspec.tv_nsec = 10000000; /* sleep 10 millisec */ + loop = 10; while (loop--) { - struct stat buf; - dbg("looking for '%s'", filename); - retval = stat(filename, &buf); - if (!retval) - break; - /* sleep to give the kernel a chance to create the device file */ - sleep(1); - } + nanosleep(&tspec, NULL); + if (class_dev_parent) + sysfs_device = sysfs_get_classdev_device(class_dev_parent); + else + sysfs_device = sysfs_get_classdev_device(class_dev); - loop = 1; /* FIXME put a real value in here for when everything is fixed... */ - while (loop--) { - /* find the sysfs_device for this class device */ - /* Wouldn't it really be nice if libsysfs could do this for us? */ - sysfs_device = sysfs_get_classdev_device(class_dev); if (sysfs_device != NULL) - goto exit; - - /* if it's a partition, we need to get the parent device */ - if (partition) { - /* FIXME HACK HACK HACK HACK - * for some reason partitions need this extra sleep here, in order - * to wait for the device properly. Once the libsysfs code is - * fixed properly, this sleep should go away, and we can just loop above. - */ - sleep(1); - dbg("really is a partition"); - class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent == NULL) { - dbg("sysfs_get_classdev_parent for class device '%s' failed", class_dev->name); - } else { - dbg("class_dev_parent->name='%s'", class_dev_parent->name); - sysfs_device = sysfs_get_classdev_device(class_dev_parent); - if (sysfs_device != NULL) - goto exit; - } + goto device_found; + } + dbg("timed out waiting for device symlink, continuing on anyway..."); + +device_found: + /* We have another issue with just the wait above - the sysfs part of + * the kernel may not be quick enough to have created the link to the + * device under the "bus" subsystem. Due to this, the sysfs_device->bus + * will not contain the actual bus name :( + * + * Libsysfs now provides a new API sysfs_get_device_bus(), so use it + * if needed + */ + if (sysfs_device) { + + if (sysfs_device->bus[0] != '\0') + goto bus_found; + + loop = 10; + tspec.tv_nsec = 10000000; + while (loop--) { + nanosleep(&tspec, NULL); + sysfs_get_device_bus(sysfs_device); + + if (sysfs_device->bus[0] != '\0') + goto bus_found; } - /* sleep to give the kernel a chance to create the link */ - /* FIXME remove comment... - sleep(1); */ + dbg("timed out waiting to find the device bus, continuing on anyway"); + goto exit; +bus_found: + dbg("device %s is registered with bus '%s'", + sysfs_device->name, sysfs_device->bus); } - dbg("Timed out waiting for device symlink, continuing on anyway..."); exit: return sysfs_device; } @@ -721,7 +695,8 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud } /* Yup, this rule belongs to us! */ - dbg("found matching rule, '%s' becomes '%s'", dev->kernel, dev->name); + info("configured rule in '%s' at line %i applied, '%s' becomes '%s'", + udev_rules_filename, dev->config_line, udev->kernel_name, dev->name); strfieldcpy(udev->name, dev->name); strfieldcpy(udev->symlink, dev->symlink); goto found;