X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=libudev%2Flibudev-enumerate.c;h=e46bc087fa31879573a3107f189be62b6191d9d5;hp=363d445f90a5f63a569cf4d1d15378456b119180;hb=48a0170b111b55e961be769d2cc4890511bcd991;hpb=cad40a5fe75d876af22f68b688494b9cd98cc899 diff --git a/libudev/libudev-enumerate.c b/libudev/libudev-enumerate.c index 363d445f9..e46bc087f 100644 --- a/libudev/libudev-enumerate.c +++ b/libudev/libudev-enumerate.c @@ -57,6 +57,7 @@ struct udev_enumerate { unsigned int devices_cur; unsigned int devices_max; bool devices_uptodate:1; + bool match_is_initialized; }; /** @@ -456,6 +457,32 @@ int udev_enumerate_add_match_tag(struct udev_enumerate *udev_enumerate, const ch return 0; } +/** + * udev_enumerate_add_match_is_initialized: + * @udev_enumerate: context + * + * Match only devices which udev has set up already. This makes + * sure, that the device node permissions and context are properly set + * and that network devices are fully renamed. + * + * Usually, devices which are found in the kernel but not already + * handled by udev, have still pending events. Services should subscribe + * to monitor events and wait for these devices to become ready, instead + * of using uninitialized devices. + * + * For now, this will not affect devices which do not have a device node + * and are not network interfaces. + * + * Returns: 0 on success, otherwise a negative error value. + */ +int udev_enumerate_add_match_is_initialized(struct udev_enumerate *udev_enumerate) +{ + if (udev_enumerate == NULL) + return -EINVAL; + udev_enumerate->match_is_initialized = true; + return 0; +} + /** * udev_enumerate_add_match_sysname: * @udev_enumerate: context @@ -601,6 +628,21 @@ static int scan_dir_and_add_devices(struct udev_enumerate *udev_enumerate, if (dev == NULL) continue; + if (udev_enumerate->match_is_initialized) { + /* + * All devices with a device node or network interfaces + * possibly need udev to adjust the device node permission + * or context, or rename the interface before it can be + * reliably used from other processes. + * + * For now, we can only check these types of devices, we + * might not store a database, and have no way to find out + * for all other types of devices. + */ + if (!udev_device_get_is_initialized(dev) && + (major(udev_device_get_devnum(dev)) > 0 || udev_device_get_ifindex(dev) > 0)) + goto nomatch; + } if (!match_tag(udev_enumerate, dev)) goto nomatch; if (!match_property(udev_enumerate, dev))