- util_strscpyl(base, sizeof(base), udev_get_sys_path(udev), "/subsystem", NULL);
- if (stat(base, &statbuf) == 0) {
- /* we have /subsystem/, forget all the old stuff */
- dbg(udev, "searching '/subsystem/*/devices/*' dir\n");
- scan_dir(udev_enumerate, "subsystem", "devices", NULL);
+
+ if (udev_list_get_entry(&udev_enumerate->tags_match_list) != NULL) {
+ struct udev_list_entry *list_entry;
+
+ /* scan only tagged devices, use tags reverse-index, instead of searching all devices in /sys */
+ udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->tags_match_list)) {
+ DIR *dir;
+ struct dirent *dent;
+ char path[UTIL_PATH_SIZE];
+
+ util_strscpyl(path, sizeof(path), udev_get_dev_path(udev), "/.udev/tags/",
+ udev_list_entry_get_name(list_entry), NULL);
+ dir = opendir(path);
+ if (dir == NULL)
+ continue;
+ for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
+ struct udev_device *dev;
+ char syspath[UTIL_PATH_SIZE];
+ char *s;
+ size_t l;
+ ssize_t len;
+
+ if (dent->d_name[0] == '.')
+ continue;
+
+ s = syspath;
+ l = util_strpcpyl(&s, sizeof(syspath), udev_get_sys_path(udev), NULL);
+ len = readlinkat(dirfd(dir), dent->d_name, s, l);
+ if (len <= 0 || (size_t)len == l)
+ continue;
+ s[len] = '\0';
+
+ dev = udev_device_new_from_syspath(udev_enumerate->udev, syspath);
+ if (dev == NULL)
+ continue;
+ syspath_add(udev_enumerate, udev_device_get_syspath(dev));
+ udev_device_unref(dev);
+ }
+ }