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 test_matches(
551 sd_device_enumerator
*enumerator
,
553 bool ignore_parent_match
) {
560 /* Checks all matches, except for the sysname match (which the caller should check beforehand) */
562 r
= match_initialized(enumerator
, device
);
566 if (!ignore_parent_match
&&
567 !device_match_parent(device
, enumerator
->match_parent
, NULL
))
570 if (!match_tag(enumerator
, device
))
573 if (!match_property(enumerator
, device
))
576 if (!device_match_sysattr(device
, enumerator
->match_sysattr
, enumerator
->nomatch_sysattr
))
582 static bool match_subsystem(sd_device_enumerator
*enumerator
, const char *subsystem
) {
583 const char *subsystem_match
;
590 SET_FOREACH(subsystem_match
, enumerator
->nomatch_subsystem
)
591 if (fnmatch(subsystem_match
, subsystem
, 0) == 0)
594 if (set_isempty(enumerator
->match_subsystem
))
597 SET_FOREACH(subsystem_match
, enumerator
->match_subsystem
)
598 if (fnmatch(subsystem_match
, subsystem
, 0) == 0)
604 static int enumerator_add_parent_devices(
605 sd_device_enumerator
*enumerator
,
607 bool ignore_parent_match
) {
615 const char *ss
, *usn
;
617 k
= sd_device_get_parent(device
, &device
);
618 if (k
== -ENOENT
) /* Reached the top? */
625 k
= sd_device_get_subsystem(device
, &ss
);
626 if (k
== -ENOENT
) /* Has no subsystem? */
633 if (!match_subsystem(enumerator
, ss
))
636 k
= sd_device_get_sysname(device
, &usn
);
642 if (!match_sysname(enumerator
, usn
))
645 k
= test_matches(enumerator
, device
, ignore_parent_match
);
653 k
= device_enumerator_add_device(enumerator
, device
);
658 if (k
== 0) /* Exists already? Then no need to go further up. */
665 int device_enumerator_add_parent_devices(sd_device_enumerator
*enumerator
, sd_device
*device
) {
666 return enumerator_add_parent_devices(enumerator
, device
, /* ignore_parent_match = */ true);
669 static bool relevant_sysfs_subdir(const struct dirent
*de
) {
672 if (de
->d_name
[0] == '.')
675 /* Also filter out regular files and such, i.e. stuff that definitely isn't a kobject path. (Note
676 * that we rely on the fact that sysfs fills in d_type here, i.e. doesn't do DT_UNKNOWN) */
677 return IN_SET(de
->d_type
, DT_DIR
, DT_LNK
);
680 static int enumerator_scan_dir_and_add_devices(
681 sd_device_enumerator
*enumerator
,
684 const char *subdir2
) {
686 _cleanup_closedir_
DIR *dir
= NULL
;
693 path
= strjoina("/sys/", basedir
, "/");
696 path
= strjoina(path
, subdir1
, "/");
699 path
= strjoina(path
, subdir2
, "/");
703 /* this is necessarily racey, so ignore missing directories */
704 return (errno
== ENOENT
&& (subdir1
|| subdir2
)) ? 0 : -errno
;
706 FOREACH_DIRENT_ALL(de
, dir
, return -errno
) {
707 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
708 char syspath
[strlen(path
) + 1 + strlen(de
->d_name
) + 1];
710 if (!relevant_sysfs_subdir(de
))
713 if (!match_sysname(enumerator
, de
->d_name
))
716 (void) sprintf(syspath
, "%s%s", path
, de
->d_name
);
718 k
= sd_device_new_from_syspath(&device
, syspath
);
721 /* this is necessarily racey, so ignore missing devices */
727 k
= test_matches(enumerator
, device
, /* ignore_parent_match = */ false);
734 k
= device_enumerator_add_device(enumerator
, device
);
738 /* Also include all potentially matching parent devices in the enumeration. These are things
739 * like root busses — e.g. /sys/devices/pci0000:00/ or /sys/devices/pnp0/, which ar not
740 * linked from /sys/class/ or /sys/bus/, hence pick them up explicitly here. */
741 k
= enumerator_add_parent_devices(enumerator
, device
, /* ignore_parent_match = */ false);
749 static int enumerator_scan_dir(
750 sd_device_enumerator
*enumerator
,
753 const char *subsystem
) {
755 _cleanup_closedir_
DIR *dir
= NULL
;
759 path
= strjoina("/sys/", basedir
);
765 log_debug("sd-device-enumerator: Scanning %s", path
);
767 FOREACH_DIRENT_ALL(de
, dir
, return -errno
) {
770 if (!relevant_sysfs_subdir(de
))
773 if (!match_subsystem(enumerator
, subsystem
? : de
->d_name
))
776 k
= enumerator_scan_dir_and_add_devices(enumerator
, basedir
, de
->d_name
, subdir
);
784 static int enumerator_scan_devices_tag(sd_device_enumerator
*enumerator
, const char *tag
) {
785 _cleanup_closedir_
DIR *dir
= NULL
;
792 path
= strjoina("/run/udev/tags/", tag
);
797 return log_debug_errno(errno
, "sd-device-enumerator: Failed to open tags directory %s: %m", path
);
801 /* TODO: filter away subsystems? */
803 FOREACH_DIRENT_ALL(de
, dir
, return -errno
) {
804 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
805 const char *subsystem
, *sysname
;
808 if (de
->d_name
[0] == '.')
811 k
= sd_device_new_from_device_id(&device
, de
->d_name
);
814 /* this is necessarily racy, so ignore missing devices */
820 k
= sd_device_get_subsystem(device
, &subsystem
);
823 /* this is necessarily racy, so ignore missing devices */
828 if (!match_subsystem(enumerator
, subsystem
))
831 k
= sd_device_get_sysname(device
, &sysname
);
837 if (!match_sysname(enumerator
, sysname
))
840 if (!device_match_parent(device
, enumerator
->match_parent
, NULL
))
843 if (!match_property(enumerator
, device
))
846 if (!device_match_sysattr(device
, enumerator
->match_sysattr
, enumerator
->nomatch_sysattr
))
849 k
= device_enumerator_add_device(enumerator
, device
);
859 static int enumerator_scan_devices_tags(sd_device_enumerator
*enumerator
) {
865 SET_FOREACH(tag
, enumerator
->match_tag
) {
868 k
= enumerator_scan_devices_tag(enumerator
, tag
);
876 static int parent_add_child(sd_device_enumerator
*enumerator
, const char *path
) {
877 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
878 const char *subsystem
, *sysname
;
881 r
= sd_device_new_from_syspath(&device
, path
);
883 /* this is necessarily racy, so ignore missing devices */
888 r
= sd_device_get_subsystem(device
, &subsystem
);
894 if (!match_subsystem(enumerator
, subsystem
))
897 r
= sd_device_get_sysname(device
, &sysname
);
901 if (!match_sysname(enumerator
, sysname
))
904 if (!match_property(enumerator
, device
))
907 if (!device_match_sysattr(device
, enumerator
->match_sysattr
, enumerator
->nomatch_sysattr
))
910 r
= device_enumerator_add_device(enumerator
, device
);
917 static int parent_crawl_children(sd_device_enumerator
*enumerator
, const char *path
, unsigned maxdepth
) {
918 _cleanup_closedir_
DIR *dir
= NULL
;
923 return log_debug_errno(errno
, "sd-device-enumerator: Failed to open parent directory %s: %m", path
);
925 FOREACH_DIRENT_ALL(de
, dir
, return -errno
) {
926 _cleanup_free_
char *child
= NULL
;
929 if (de
->d_name
[0] == '.')
932 if (de
->d_type
!= DT_DIR
)
935 child
= path_join(path
, de
->d_name
);
939 k
= parent_add_child(enumerator
, child
);
944 parent_crawl_children(enumerator
, child
, maxdepth
- 1);
946 log_debug("sd-device-enumerator: Max depth reached, %s: ignoring devices", child
);
952 static int enumerator_scan_devices_children(sd_device_enumerator
*enumerator
) {
956 SET_FOREACH(path
, enumerator
->match_parent
) {
957 k
= parent_add_child(enumerator
, path
);
961 k
= parent_crawl_children(enumerator
, path
, DEVICE_ENUMERATE_MAX_DEPTH
);
969 static int enumerator_scan_devices_all(sd_device_enumerator
*enumerator
) {
972 log_debug("sd-device-enumerator: Scan all dirs");
974 k
= enumerator_scan_dir(enumerator
, "bus", "devices", NULL
);
976 r
= log_debug_errno(k
, "sd-device-enumerator: Failed to scan /sys/bus: %m");
978 k
= enumerator_scan_dir(enumerator
, "class", NULL
, NULL
);
980 r
= log_debug_errno(k
, "sd-device-enumerator: Failed to scan /sys/class: %m");
985 int device_enumerator_scan_devices(sd_device_enumerator
*enumerator
) {
990 if (enumerator
->scan_uptodate
&&
991 enumerator
->type
== DEVICE_ENUMERATION_TYPE_DEVICES
)
994 device_enumerator_unref_devices(enumerator
);
996 if (!set_isempty(enumerator
->match_tag
)) {
997 k
= enumerator_scan_devices_tags(enumerator
);
1000 } else if (enumerator
->match_parent
) {
1001 k
= enumerator_scan_devices_children(enumerator
);
1005 k
= enumerator_scan_devices_all(enumerator
);
1010 enumerator
->scan_uptodate
= true;
1011 enumerator
->type
= DEVICE_ENUMERATION_TYPE_DEVICES
;
1016 _public_ sd_device
*sd_device_enumerator_get_device_first(sd_device_enumerator
*enumerator
) {
1017 assert_return(enumerator
, NULL
);
1019 if (device_enumerator_scan_devices(enumerator
) < 0)
1022 if (enumerator_sort_devices(enumerator
) < 0)
1025 enumerator
->current_device_index
= 0;
1027 if (enumerator
->n_devices
== 0)
1030 return enumerator
->devices
[0];
1033 _public_ sd_device
*sd_device_enumerator_get_device_next(sd_device_enumerator
*enumerator
) {
1034 assert_return(enumerator
, NULL
);
1036 if (!enumerator
->scan_uptodate
||
1037 !enumerator
->sorted
||
1038 enumerator
->type
!= DEVICE_ENUMERATION_TYPE_DEVICES
||
1039 enumerator
->current_device_index
+ 1 >= enumerator
->n_devices
)
1042 return enumerator
->devices
[++enumerator
->current_device_index
];
1045 int device_enumerator_scan_subsystems(sd_device_enumerator
*enumerator
) {
1050 if (enumerator
->scan_uptodate
&&
1051 enumerator
->type
== DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
)
1054 device_enumerator_unref_devices(enumerator
);
1057 if (match_subsystem(enumerator
, "module")) {
1058 k
= enumerator_scan_dir_and_add_devices(enumerator
, "module", NULL
, NULL
);
1060 r
= log_debug_errno(k
, "sd-device-enumerator: Failed to scan modules: %m");
1063 /* subsystems (only buses support coldplug) */
1064 if (match_subsystem(enumerator
, "subsystem")) {
1065 k
= enumerator_scan_dir_and_add_devices(enumerator
, "bus", NULL
, NULL
);
1067 r
= log_debug_errno(k
, "sd-device-enumerator: Failed to scan subsystems: %m");
1070 /* subsystem drivers */
1071 if (match_subsystem(enumerator
, "drivers")) {
1072 k
= enumerator_scan_dir(enumerator
, "bus", "drivers", "drivers");
1074 r
= log_debug_errno(k
, "sd-device-enumerator: Failed to scan drivers: %m");
1077 enumerator
->scan_uptodate
= true;
1078 enumerator
->type
= DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
;
1083 _public_ sd_device
*sd_device_enumerator_get_subsystem_first(sd_device_enumerator
*enumerator
) {
1084 assert_return(enumerator
, NULL
);
1086 if (device_enumerator_scan_subsystems(enumerator
) < 0)
1089 if (enumerator_sort_devices(enumerator
) < 0)
1092 enumerator
->current_device_index
= 0;
1094 if (enumerator
->n_devices
== 0)
1097 return enumerator
->devices
[0];
1100 _public_ sd_device
*sd_device_enumerator_get_subsystem_next(sd_device_enumerator
*enumerator
) {
1101 assert_return(enumerator
, NULL
);
1103 if (!enumerator
->scan_uptodate
||
1104 !enumerator
->sorted
||
1105 enumerator
->type
!= DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
||
1106 enumerator
->current_device_index
+ 1 >= enumerator
->n_devices
)
1109 return enumerator
->devices
[++enumerator
->current_device_index
];
1112 int device_enumerator_scan_devices_and_subsystems(sd_device_enumerator
*enumerator
) {
1117 if (enumerator
->scan_uptodate
&&
1118 enumerator
->type
== DEVICE_ENUMERATION_TYPE_ALL
)
1121 device_enumerator_unref_devices(enumerator
);
1123 if (!set_isempty(enumerator
->match_tag
))
1124 r
= enumerator_scan_devices_tags(enumerator
);
1125 else if (enumerator
->match_parent
)
1126 r
= enumerator_scan_devices_children(enumerator
);
1130 r
= enumerator_scan_devices_all(enumerator
);
1132 if (match_subsystem(enumerator
, "module")) {
1133 k
= enumerator_scan_dir_and_add_devices(enumerator
, "module", NULL
, NULL
);
1135 r
= log_debug_errno(k
, "sd-device-enumerator: Failed to scan modules: %m");
1137 if (match_subsystem(enumerator
, "subsystem")) {
1138 k
= enumerator_scan_dir_and_add_devices(enumerator
, "bus", NULL
, NULL
);
1140 r
= log_debug_errno(k
, "sd-device-enumerator: Failed to scan subsystems: %m");
1143 if (match_subsystem(enumerator
, "drivers")) {
1144 k
= enumerator_scan_dir(enumerator
, "bus", "drivers", "drivers");
1146 r
= log_debug_errno(k
, "sd-device-enumerator: Failed to scan drivers: %m");
1150 enumerator
->scan_uptodate
= true;
1151 enumerator
->type
= DEVICE_ENUMERATION_TYPE_ALL
;
1156 sd_device
*device_enumerator_get_first(sd_device_enumerator
*enumerator
) {
1157 assert_return(enumerator
, NULL
);
1159 if (!enumerator
->scan_uptodate
)
1162 if (enumerator_sort_devices(enumerator
) < 0)
1165 enumerator
->current_device_index
= 0;
1167 if (enumerator
->n_devices
== 0)
1170 return enumerator
->devices
[0];
1173 sd_device
*device_enumerator_get_next(sd_device_enumerator
*enumerator
) {
1174 assert_return(enumerator
, NULL
);
1176 if (!enumerator
->scan_uptodate
||
1177 !enumerator
->sorted
||
1178 enumerator
->current_device_index
+ 1 >= enumerator
->n_devices
)
1181 return enumerator
->devices
[++enumerator
->current_device_index
];
1184 sd_device
**device_enumerator_get_devices(sd_device_enumerator
*enumerator
, size_t *ret_n_devices
) {
1186 assert(ret_n_devices
);
1188 if (!enumerator
->scan_uptodate
)
1191 if (enumerator_sort_devices(enumerator
) < 0)
1194 *ret_n_devices
= enumerator
->n_devices
;
1195 return enumerator
->devices
;