1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
8 #include "alloc-util.h"
9 #include "device-enumerator-private.h"
10 #include "device-util.h"
11 #include "dirent-util.h"
14 #include "sort-util.h"
15 #include "string-util.h"
18 #define DEVICE_ENUMERATE_MAX_DEPTH 256
20 typedef enum DeviceEnumerationType
{
21 DEVICE_ENUMERATION_TYPE_DEVICES
,
22 DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
,
23 DEVICE_ENUMERATION_TYPE_ALL
,
24 _DEVICE_ENUMERATION_TYPE_MAX
,
25 _DEVICE_ENUMERATION_TYPE_INVALID
= -EINVAL
,
26 } DeviceEnumerationType
;
28 struct sd_device_enumerator
{
31 DeviceEnumerationType type
;
32 Hashmap
*devices_by_syspath
;
34 size_t n_devices
, current_device_index
;
38 char **prioritized_subsystems
;
40 Set
*nomatch_subsystem
;
41 Hashmap
*match_sysattr
;
42 Hashmap
*nomatch_sysattr
;
43 Hashmap
*match_property
;
47 MatchInitializedType match_initialized
;
50 _public_
int sd_device_enumerator_new(sd_device_enumerator
**ret
) {
51 _cleanup_(sd_device_enumerator_unrefp
) sd_device_enumerator
*enumerator
= NULL
;
55 enumerator
= new(sd_device_enumerator
, 1);
59 *enumerator
= (sd_device_enumerator
) {
61 .type
= _DEVICE_ENUMERATION_TYPE_INVALID
,
62 .match_initialized
= MATCH_INITIALIZED_COMPAT
,
65 *ret
= TAKE_PTR(enumerator
);
70 static void device_unref_many(sd_device
**devices
, size_t n
) {
71 assert(devices
|| n
== 0);
73 for (size_t i
= 0; i
< n
; i
++)
74 sd_device_unref(devices
[i
]);
77 static void device_enumerator_unref_devices(sd_device_enumerator
*enumerator
) {
80 hashmap_clear_with_destructor(enumerator
->devices_by_syspath
, sd_device_unref
);
81 device_unref_many(enumerator
->devices
, enumerator
->n_devices
);
82 enumerator
->devices
= mfree(enumerator
->devices
);
83 enumerator
->n_devices
= 0;
86 static sd_device_enumerator
*device_enumerator_free(sd_device_enumerator
*enumerator
) {
89 device_enumerator_unref_devices(enumerator
);
91 hashmap_free(enumerator
->devices_by_syspath
);
92 strv_free(enumerator
->prioritized_subsystems
);
93 set_free(enumerator
->match_subsystem
);
94 set_free(enumerator
->nomatch_subsystem
);
95 hashmap_free(enumerator
->match_sysattr
);
96 hashmap_free(enumerator
->nomatch_sysattr
);
97 hashmap_free(enumerator
->match_property
);
98 set_free(enumerator
->match_sysname
);
99 set_free(enumerator
->match_tag
);
100 set_free(enumerator
->match_parent
);
102 return mfree(enumerator
);
105 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_device_enumerator
, sd_device_enumerator
, device_enumerator_free
);
107 int device_enumerator_add_prioritized_subsystem(sd_device_enumerator
*enumerator
, const char *subsystem
) {
113 if (strv_contains(enumerator
->prioritized_subsystems
, subsystem
))
116 r
= strv_extend(&enumerator
->prioritized_subsystems
, subsystem
);
120 enumerator
->scan_uptodate
= false;
125 _public_
int sd_device_enumerator_add_match_subsystem(sd_device_enumerator
*enumerator
, const char *subsystem
, int match
) {
129 assert_return(enumerator
, -EINVAL
);
130 assert_return(subsystem
, -EINVAL
);
133 set
= &enumerator
->match_subsystem
;
135 set
= &enumerator
->nomatch_subsystem
;
137 r
= set_put_strdup(set
, subsystem
);
141 enumerator
->scan_uptodate
= false;
146 _public_
int sd_device_enumerator_add_match_sysattr(sd_device_enumerator
*enumerator
, const char *sysattr
, const char *value
, int match
) {
150 assert_return(enumerator
, -EINVAL
);
151 assert_return(sysattr
, -EINVAL
);
154 hashmap
= &enumerator
->match_sysattr
;
156 hashmap
= &enumerator
->nomatch_sysattr
;
158 /* Do not use string_has_ops_free_free or hashmap_put_strdup() here, as this may be called
159 * multiple times with the same sysattr but different value. */
160 r
= hashmap_put_strdup_full(hashmap
, &trivial_hash_ops_free_free
, sysattr
, value
);
164 enumerator
->scan_uptodate
= false;
169 _public_
int sd_device_enumerator_add_match_property(sd_device_enumerator
*enumerator
, const char *property
, const char *value
) {
172 assert_return(enumerator
, -EINVAL
);
173 assert_return(property
, -EINVAL
);
175 /* Do not use string_has_ops_free_free or hashmap_put_strdup() here, as this may be called
176 * multiple times with the same property but different value. */
177 r
= hashmap_put_strdup_full(&enumerator
->match_property
, &trivial_hash_ops_free_free
, property
, value
);
181 enumerator
->scan_uptodate
= false;
186 _public_
int sd_device_enumerator_add_match_sysname(sd_device_enumerator
*enumerator
, const char *sysname
) {
189 assert_return(enumerator
, -EINVAL
);
190 assert_return(sysname
, -EINVAL
);
192 r
= set_put_strdup(&enumerator
->match_sysname
, sysname
);
196 enumerator
->scan_uptodate
= false;
201 _public_
int sd_device_enumerator_add_match_tag(sd_device_enumerator
*enumerator
, const char *tag
) {
204 assert_return(enumerator
, -EINVAL
);
205 assert_return(tag
, -EINVAL
);
207 r
= set_put_strdup(&enumerator
->match_tag
, tag
);
211 enumerator
->scan_uptodate
= false;
216 int device_enumerator_add_match_parent_incremental(sd_device_enumerator
*enumerator
, sd_device
*parent
) {
223 r
= sd_device_get_syspath(parent
, &path
);
227 r
= set_put_strdup(&enumerator
->match_parent
, path
);
231 enumerator
->scan_uptodate
= false;
236 _public_
int sd_device_enumerator_add_match_parent(sd_device_enumerator
*enumerator
, sd_device
*parent
) {
237 assert_return(enumerator
, -EINVAL
);
238 assert_return(parent
, -EINVAL
);
240 set_clear(enumerator
->match_parent
);
242 return device_enumerator_add_match_parent_incremental(enumerator
, parent
);
245 _public_
int sd_device_enumerator_allow_uninitialized(sd_device_enumerator
*enumerator
) {
246 assert_return(enumerator
, -EINVAL
);
248 enumerator
->match_initialized
= MATCH_INITIALIZED_ALL
;
250 enumerator
->scan_uptodate
= false;
255 int device_enumerator_add_match_is_initialized(sd_device_enumerator
*enumerator
, MatchInitializedType type
) {
256 assert_return(enumerator
, -EINVAL
);
257 assert_return(type
>= 0 && type
< _MATCH_INITIALIZED_MAX
, -EINVAL
);
259 enumerator
->match_initialized
= type
;
261 enumerator
->scan_uptodate
= false;
266 static int sound_device_compare(const char *devpath_a
, const char *devpath_b
) {
267 const char *sound_a
, *sound_b
;
273 /* For sound cards the control device must be enumerated last to make sure it's the final
274 * device node that gets ACLs applied. Applications rely on this fact and use ACL changes on
275 * the control node as an indicator that the ACL change of the entire sound card completed. The
276 * kernel makes this guarantee when creating those devices, and hence we should too when
277 * enumerating them. */
279 sound_a
= strstr(devpath_a
, "/sound/card");
283 sound_a
+= STRLEN("/sound/card");
284 sound_a
= strchr(devpath_a
, '/');
288 prefix_len
= sound_a
- devpath_a
;
290 if (!strneq(devpath_a
, devpath_b
, prefix_len
))
293 sound_b
= devpath_b
+ prefix_len
;
295 return CMP(!!startswith(sound_a
, "/controlC"),
296 !!startswith(sound_b
, "/controlC"));
299 static bool devpath_is_late_block(const char *devpath
) {
302 return strstr(devpath
, "/block/md") || strstr(devpath
, "/block/dm-");
305 static int device_compare(sd_device
* const *a
, sd_device
* const *b
) {
306 const char *devpath_a
, *devpath_b
;
314 assert_se(sd_device_get_devpath(*(sd_device
**) a
, &devpath_a
) >= 0);
315 assert_se(sd_device_get_devpath(*(sd_device
**) b
, &devpath_b
) >= 0);
317 r
= sound_device_compare(devpath_a
, devpath_b
);
321 /* md and dm devices are enumerated after all other devices */
322 r
= CMP(devpath_is_late_block(devpath_a
), devpath_is_late_block(devpath_b
));
326 return path_compare(devpath_a
, devpath_b
);
329 static int enumerator_sort_devices(sd_device_enumerator
*enumerator
) {
330 size_t n_sorted
= 0, n
= 0;
337 if (enumerator
->sorted
)
340 devices
= new(sd_device
*, hashmap_size(enumerator
->devices_by_syspath
));
344 STRV_FOREACH(prioritized_subsystem
, enumerator
->prioritized_subsystems
) {
350 HASHMAP_FOREACH_KEY(device
, syspath
, enumerator
->devices_by_syspath
) {
351 _cleanup_free_
char *p
= NULL
;
354 if (sd_device_get_subsystem(device
, &subsys
) < 0)
357 if (!streq(subsys
, *prioritized_subsystem
))
360 devices
[n
++] = sd_device_ref(device
);
363 _cleanup_free_
char *q
= NULL
;
365 r
= path_extract_directory(p
?: syspath
, &q
);
366 if (r
== -EADDRNOTAVAIL
)
371 device
= hashmap_get(enumerator
->devices_by_syspath
, q
);
373 devices
[n
++] = sd_device_ref(device
);
375 free_and_replace(p
, q
);
381 /* We cannot remove multiple entries in the loop HASHMAP_FOREACH_KEY() above. */
382 for (size_t i
= m
; i
< n
; i
++) {
383 r
= sd_device_get_syspath(devices
[i
], &syspath
);
387 assert_se(hashmap_remove(enumerator
->devices_by_syspath
, syspath
) == devices
[i
]);
388 sd_device_unref(devices
[i
]);
395 typesafe_qsort(devices
+ n_sorted
, n
- n_sorted
, device_compare
);
399 HASHMAP_FOREACH(device
, enumerator
->devices_by_syspath
)
400 devices
[n
++] = sd_device_ref(device
);
402 /* Move all devices back to the hashmap. Otherwise, devices added by
403 * udev_enumerate_add_syspath() -> device_enumerator_add_device() may not be listed. */
404 for (size_t i
= 0; i
< n_sorted
; i
++) {
407 r
= sd_device_get_syspath(devices
[i
], &syspath
);
411 r
= hashmap_put(enumerator
->devices_by_syspath
, syspath
, devices
[i
]);
416 sd_device_ref(devices
[i
]);
419 typesafe_qsort(devices
+ n_sorted
, n
- n_sorted
, device_compare
);
421 device_unref_many(enumerator
->devices
, enumerator
->n_devices
);
423 enumerator
->n_devices
= n
;
424 free_and_replace(enumerator
->devices
, devices
);
426 enumerator
->sorted
= true;
430 device_unref_many(devices
, n
);
435 int device_enumerator_add_device(sd_device_enumerator
*enumerator
, sd_device
*device
) {
439 assert_return(enumerator
, -EINVAL
);
440 assert_return(device
, -EINVAL
);
442 r
= sd_device_get_syspath(device
, &syspath
);
446 r
= hashmap_ensure_put(&enumerator
->devices_by_syspath
, &string_hash_ops
, syspath
, device
);
447 if (IN_SET(r
, -EEXIST
, 0))
452 sd_device_ref(device
);
454 enumerator
->sorted
= false;
458 static bool match_property(sd_device_enumerator
*enumerator
, sd_device
*device
) {
459 const char *property
;
465 if (hashmap_isempty(enumerator
->match_property
))
468 HASHMAP_FOREACH_KEY(value
, property
, enumerator
->match_property
) {
469 const char *property_dev
, *value_dev
;
471 FOREACH_DEVICE_PROPERTY(device
, property_dev
, value_dev
) {
472 if (fnmatch(property
, property_dev
, 0) != 0)
475 if (!value
&& !value_dev
)
478 if (!value
|| !value_dev
)
481 if (fnmatch(value
, value_dev
, 0) == 0)
489 static bool match_tag(sd_device_enumerator
*enumerator
, sd_device
*device
) {
495 SET_FOREACH(tag
, enumerator
->match_tag
)
496 if (!sd_device_has_tag(device
, tag
))
502 static bool match_sysname(sd_device_enumerator
*enumerator
, const char *sysname
) {
503 const char *sysname_match
;
508 if (set_isempty(enumerator
->match_sysname
))
511 SET_FOREACH(sysname_match
, enumerator
->match_sysname
)
512 if (fnmatch(sysname_match
, sysname
, 0) == 0)
518 static int match_initialized(sd_device_enumerator
*enumerator
, sd_device
*device
) {
524 if (enumerator
->match_initialized
== MATCH_INITIALIZED_ALL
)
527 r
= sd_device_get_is_initialized(device
);
528 if (r
== -ENOENT
) /* this is necessarily racey, so ignore missing devices */
533 if (enumerator
->match_initialized
== MATCH_INITIALIZED_COMPAT
) {
534 /* only devices that have no devnode/ifindex or have a db entry are accepted. */
538 if (sd_device_get_devnum(device
, NULL
) >= 0)
541 if (sd_device_get_ifindex(device
, NULL
) >= 0)
547 return (enumerator
->match_initialized
== MATCH_INITIALIZED_NO
) == (r
== 0);
550 static int enumerator_scan_dir_and_add_devices(sd_device_enumerator
*enumerator
, const char *basedir
, const char *subdir1
, const char *subdir2
) {
551 _cleanup_closedir_
DIR *dir
= NULL
;
558 path
= strjoina("/sys/", basedir
, "/");
561 path
= strjoina(path
, subdir1
, "/");
564 path
= strjoina(path
, subdir2
, "/");
568 /* this is necessarily racey, so ignore missing directories */
569 return (errno
== ENOENT
&& (subdir1
|| subdir2
)) ? 0 : -errno
;
571 FOREACH_DIRENT_ALL(de
, dir
, return -errno
) {
572 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
573 char syspath
[strlen(path
) + 1 + strlen(de
->d_name
) + 1];
575 if (de
->d_name
[0] == '.')
578 if (!match_sysname(enumerator
, de
->d_name
))
581 (void) sprintf(syspath
, "%s%s", path
, de
->d_name
);
583 k
= sd_device_new_from_syspath(&device
, syspath
);
586 /* this is necessarily racey, so ignore missing devices */
592 k
= match_initialized(enumerator
, device
);
599 if (!device_match_parent(device
, enumerator
->match_parent
, NULL
))
602 if (!match_tag(enumerator
, device
))
605 if (!match_property(enumerator
, device
))
608 if (!device_match_sysattr(device
, enumerator
->match_sysattr
, enumerator
->nomatch_sysattr
))
611 k
= device_enumerator_add_device(enumerator
, device
);
619 static bool match_subsystem(sd_device_enumerator
*enumerator
, const char *subsystem
) {
620 const char *subsystem_match
;
627 SET_FOREACH(subsystem_match
, enumerator
->nomatch_subsystem
)
628 if (fnmatch(subsystem_match
, subsystem
, 0) == 0)
631 if (set_isempty(enumerator
->match_subsystem
))
634 SET_FOREACH(subsystem_match
, enumerator
->match_subsystem
)
635 if (fnmatch(subsystem_match
, subsystem
, 0) == 0)
641 static int enumerator_scan_dir(sd_device_enumerator
*enumerator
, const char *basedir
, const char *subdir
, const char *subsystem
) {
642 _cleanup_closedir_
DIR *dir
= NULL
;
646 path
= strjoina("/sys/", basedir
);
652 log_debug("sd-device-enumerator: Scanning %s", path
);
654 FOREACH_DIRENT_ALL(de
, dir
, return -errno
) {
657 if (de
->d_name
[0] == '.')
660 if (!match_subsystem(enumerator
, subsystem
? : de
->d_name
))
663 k
= enumerator_scan_dir_and_add_devices(enumerator
, basedir
, de
->d_name
, subdir
);
671 static int enumerator_scan_devices_tag(sd_device_enumerator
*enumerator
, const char *tag
) {
672 _cleanup_closedir_
DIR *dir
= NULL
;
679 path
= strjoina("/run/udev/tags/", tag
);
684 return log_debug_errno(errno
, "sd-device-enumerator: Failed to open tags directory %s: %m", path
);
688 /* TODO: filter away subsystems? */
690 FOREACH_DIRENT_ALL(de
, dir
, return -errno
) {
691 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
692 const char *subsystem
, *sysname
;
695 if (de
->d_name
[0] == '.')
698 k
= sd_device_new_from_device_id(&device
, de
->d_name
);
701 /* this is necessarily racy, so ignore missing devices */
707 k
= sd_device_get_subsystem(device
, &subsystem
);
710 /* this is necessarily racy, so ignore missing devices */
715 if (!match_subsystem(enumerator
, subsystem
))
718 k
= sd_device_get_sysname(device
, &sysname
);
724 if (!match_sysname(enumerator
, sysname
))
727 if (!device_match_parent(device
, enumerator
->match_parent
, NULL
))
730 if (!match_property(enumerator
, device
))
733 if (!device_match_sysattr(device
, enumerator
->match_sysattr
, enumerator
->nomatch_sysattr
))
736 k
= device_enumerator_add_device(enumerator
, device
);
746 static int enumerator_scan_devices_tags(sd_device_enumerator
*enumerator
) {
752 SET_FOREACH(tag
, enumerator
->match_tag
) {
755 k
= enumerator_scan_devices_tag(enumerator
, tag
);
763 static int parent_add_child(sd_device_enumerator
*enumerator
, const char *path
) {
764 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
765 const char *subsystem
, *sysname
;
768 r
= sd_device_new_from_syspath(&device
, path
);
770 /* this is necessarily racy, so ignore missing devices */
775 r
= sd_device_get_subsystem(device
, &subsystem
);
781 if (!match_subsystem(enumerator
, subsystem
))
784 r
= sd_device_get_sysname(device
, &sysname
);
788 if (!match_sysname(enumerator
, sysname
))
791 if (!match_property(enumerator
, device
))
794 if (!device_match_sysattr(device
, enumerator
->match_sysattr
, enumerator
->nomatch_sysattr
))
797 r
= device_enumerator_add_device(enumerator
, device
);
804 static int parent_crawl_children(sd_device_enumerator
*enumerator
, const char *path
, unsigned maxdepth
) {
805 _cleanup_closedir_
DIR *dir
= NULL
;
810 return log_debug_errno(errno
, "sd-device-enumerator: Failed to open parent directory %s: %m", path
);
812 FOREACH_DIRENT_ALL(de
, dir
, return -errno
) {
813 _cleanup_free_
char *child
= NULL
;
816 if (de
->d_name
[0] == '.')
819 if (de
->d_type
!= DT_DIR
)
822 child
= path_join(path
, de
->d_name
);
826 k
= parent_add_child(enumerator
, child
);
831 parent_crawl_children(enumerator
, child
, maxdepth
- 1);
833 log_debug("sd-device-enumerator: Max depth reached, %s: ignoring devices", child
);
839 static int enumerator_scan_devices_children(sd_device_enumerator
*enumerator
) {
843 SET_FOREACH(path
, enumerator
->match_parent
) {
844 k
= parent_add_child(enumerator
, path
);
848 k
= parent_crawl_children(enumerator
, path
, DEVICE_ENUMERATE_MAX_DEPTH
);
856 static int enumerator_scan_devices_all(sd_device_enumerator
*enumerator
) {
859 log_debug("sd-device-enumerator: Scan all dirs");
861 k
= enumerator_scan_dir(enumerator
, "bus", "devices", NULL
);
863 r
= log_debug_errno(k
, "sd-device-enumerator: Failed to scan /sys/bus: %m");
865 k
= enumerator_scan_dir(enumerator
, "class", NULL
, NULL
);
867 r
= log_debug_errno(k
, "sd-device-enumerator: Failed to scan /sys/class: %m");
872 int device_enumerator_scan_devices(sd_device_enumerator
*enumerator
) {
877 if (enumerator
->scan_uptodate
&&
878 enumerator
->type
== DEVICE_ENUMERATION_TYPE_DEVICES
)
881 device_enumerator_unref_devices(enumerator
);
883 if (!set_isempty(enumerator
->match_tag
)) {
884 k
= enumerator_scan_devices_tags(enumerator
);
887 } else if (enumerator
->match_parent
) {
888 k
= enumerator_scan_devices_children(enumerator
);
892 k
= enumerator_scan_devices_all(enumerator
);
897 enumerator
->scan_uptodate
= true;
898 enumerator
->type
= DEVICE_ENUMERATION_TYPE_DEVICES
;
903 _public_ sd_device
*sd_device_enumerator_get_device_first(sd_device_enumerator
*enumerator
) {
904 assert_return(enumerator
, NULL
);
906 if (device_enumerator_scan_devices(enumerator
) < 0)
909 if (enumerator_sort_devices(enumerator
) < 0)
912 enumerator
->current_device_index
= 0;
914 if (enumerator
->n_devices
== 0)
917 return enumerator
->devices
[0];
920 _public_ sd_device
*sd_device_enumerator_get_device_next(sd_device_enumerator
*enumerator
) {
921 assert_return(enumerator
, NULL
);
923 if (!enumerator
->scan_uptodate
||
924 !enumerator
->sorted
||
925 enumerator
->type
!= DEVICE_ENUMERATION_TYPE_DEVICES
||
926 enumerator
->current_device_index
+ 1 >= enumerator
->n_devices
)
929 return enumerator
->devices
[++enumerator
->current_device_index
];
932 int device_enumerator_scan_subsystems(sd_device_enumerator
*enumerator
) {
937 if (enumerator
->scan_uptodate
&&
938 enumerator
->type
== DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
)
941 device_enumerator_unref_devices(enumerator
);
944 if (match_subsystem(enumerator
, "module")) {
945 k
= enumerator_scan_dir_and_add_devices(enumerator
, "module", NULL
, NULL
);
947 r
= log_debug_errno(k
, "sd-device-enumerator: Failed to scan modules: %m");
950 /* subsystems (only buses support coldplug) */
951 if (match_subsystem(enumerator
, "subsystem")) {
952 k
= enumerator_scan_dir_and_add_devices(enumerator
, "bus", NULL
, NULL
);
954 r
= log_debug_errno(k
, "sd-device-enumerator: Failed to scan subsystems: %m");
957 /* subsystem drivers */
958 if (match_subsystem(enumerator
, "drivers")) {
959 k
= enumerator_scan_dir(enumerator
, "bus", "drivers", "drivers");
961 r
= log_debug_errno(k
, "sd-device-enumerator: Failed to scan drivers: %m");
964 enumerator
->scan_uptodate
= true;
965 enumerator
->type
= DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
;
970 _public_ sd_device
*sd_device_enumerator_get_subsystem_first(sd_device_enumerator
*enumerator
) {
971 assert_return(enumerator
, NULL
);
973 if (device_enumerator_scan_subsystems(enumerator
) < 0)
976 if (enumerator_sort_devices(enumerator
) < 0)
979 enumerator
->current_device_index
= 0;
981 if (enumerator
->n_devices
== 0)
984 return enumerator
->devices
[0];
987 _public_ sd_device
*sd_device_enumerator_get_subsystem_next(sd_device_enumerator
*enumerator
) {
988 assert_return(enumerator
, NULL
);
990 if (!enumerator
->scan_uptodate
||
991 !enumerator
->sorted
||
992 enumerator
->type
!= DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
||
993 enumerator
->current_device_index
+ 1 >= enumerator
->n_devices
)
996 return enumerator
->devices
[++enumerator
->current_device_index
];
999 int device_enumerator_scan_devices_and_subsystems(sd_device_enumerator
*enumerator
) {
1004 if (enumerator
->scan_uptodate
&&
1005 enumerator
->type
== DEVICE_ENUMERATION_TYPE_ALL
)
1008 device_enumerator_unref_devices(enumerator
);
1010 if (!set_isempty(enumerator
->match_tag
)) {
1011 k
= enumerator_scan_devices_tags(enumerator
);
1014 } else if (enumerator
->match_parent
) {
1015 k
= enumerator_scan_devices_children(enumerator
);
1019 k
= enumerator_scan_dir(enumerator
, "class", NULL
, NULL
);
1021 r
= log_debug_errno(k
, "sd-device-enumerator: Failed to scan /sys/class: %m");
1023 k
= enumerator_scan_dir(enumerator
, "bus", "devices", NULL
);
1025 r
= log_debug_errno(k
, "sd-device-enumerator: Failed to scan /sys/bus: %m");
1027 if (match_subsystem(enumerator
, "module")) {
1028 k
= enumerator_scan_dir_and_add_devices(enumerator
, "module", NULL
, NULL
);
1030 r
= log_debug_errno(k
, "sd-device-enumerator: Failed to scan modules: %m");
1032 if (match_subsystem(enumerator
, "subsystem")) {
1033 k
= enumerator_scan_dir_and_add_devices(enumerator
, "bus", NULL
, NULL
);
1035 r
= log_debug_errno(k
, "sd-device-enumerator: Failed to scan subsystems: %m");
1038 if (match_subsystem(enumerator
, "drivers")) {
1039 k
= enumerator_scan_dir(enumerator
, "bus", "drivers", "drivers");
1041 r
= log_debug_errno(k
, "sd-device-enumerator: Failed to scan drivers: %m");
1045 enumerator
->scan_uptodate
= true;
1046 enumerator
->type
= DEVICE_ENUMERATION_TYPE_ALL
;
1051 sd_device
*device_enumerator_get_first(sd_device_enumerator
*enumerator
) {
1052 assert_return(enumerator
, NULL
);
1054 if (!enumerator
->scan_uptodate
)
1057 if (enumerator_sort_devices(enumerator
) < 0)
1060 enumerator
->current_device_index
= 0;
1062 if (enumerator
->n_devices
== 0)
1065 return enumerator
->devices
[0];
1068 sd_device
*device_enumerator_get_next(sd_device_enumerator
*enumerator
) {
1069 assert_return(enumerator
, NULL
);
1071 if (!enumerator
->scan_uptodate
||
1072 !enumerator
->sorted
||
1073 enumerator
->current_device_index
+ 1 >= enumerator
->n_devices
)
1076 return enumerator
->devices
[++enumerator
->current_device_index
];
1079 sd_device
**device_enumerator_get_devices(sd_device_enumerator
*enumerator
, size_t *ret_n_devices
) {
1081 assert(ret_n_devices
);
1083 if (!enumerator
->scan_uptodate
)
1086 if (enumerator_sort_devices(enumerator
) < 0)
1089 *ret_n_devices
= enumerator
->n_devices
;
1090 return enumerator
->devices
;