summaryrefslogtreecommitdiff
path: root/libudev/libudev-enumerate.c
diff options
context:
space:
mode:
Diffstat (limited to 'libudev/libudev-enumerate.c')
-rw-r--r--libudev/libudev-enumerate.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/libudev/libudev-enumerate.c b/libudev/libudev-enumerate.c
index 363d445f90..e46bc087fa 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;
};
/**
@@ -457,6 +458,32 @@ int udev_enumerate_add_match_tag(struct udev_enumerate *udev_enumerate, const ch
}
/**
+ * 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
* @sysname: filter for the name of the device to include in the list
@@ -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))