1 /* SPDX-License-Identifier: LGPL-2.1+ */
5 #include "alloc-util.h"
6 #include "device-enumerator-private.h"
7 #include "device-util.h"
8 #include "dirent-util.h"
11 #include "string-util.h"
15 #define DEVICE_ENUMERATE_MAX_DEPTH 256
17 typedef enum DeviceEnumerationType
{
18 DEVICE_ENUMERATION_TYPE_DEVICES
,
19 DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
,
20 _DEVICE_ENUMERATION_TYPE_MAX
,
21 _DEVICE_ENUMERATION_TYPE_INVALID
= -1,
22 } DeviceEnumerationType
;
24 struct sd_device_enumerator
{
27 DeviceEnumerationType type
;
29 size_t n_devices
, n_allocated
, current_device_index
;
33 Set
*nomatch_subsystem
;
34 Hashmap
*match_sysattr
;
35 Hashmap
*nomatch_sysattr
;
36 Hashmap
*match_property
;
39 sd_device
*match_parent
;
40 bool match_allow_uninitialized
;
43 _public_
int sd_device_enumerator_new(sd_device_enumerator
**ret
) {
44 _cleanup_(sd_device_enumerator_unrefp
) sd_device_enumerator
*enumerator
= NULL
;
48 enumerator
= new(sd_device_enumerator
, 1);
52 *enumerator
= (sd_device_enumerator
) {
54 .type
= _DEVICE_ENUMERATION_TYPE_INVALID
,
57 *ret
= TAKE_PTR(enumerator
);
62 static sd_device_enumerator
*device_enumerator_free(sd_device_enumerator
*enumerator
) {
67 for (i
= 0; i
< enumerator
->n_devices
; i
++)
68 sd_device_unref(enumerator
->devices
[i
]);
70 free(enumerator
->devices
);
71 set_free_free(enumerator
->match_subsystem
);
72 set_free_free(enumerator
->nomatch_subsystem
);
73 hashmap_free_free_free(enumerator
->match_sysattr
);
74 hashmap_free_free_free(enumerator
->nomatch_sysattr
);
75 hashmap_free_free_free(enumerator
->match_property
);
76 set_free_free(enumerator
->match_sysname
);
77 set_free_free(enumerator
->match_tag
);
78 sd_device_unref(enumerator
->match_parent
);
80 return mfree(enumerator
);
83 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_device_enumerator
, sd_device_enumerator
, device_enumerator_free
);
85 _public_
int sd_device_enumerator_add_match_subsystem(sd_device_enumerator
*enumerator
, const char *subsystem
, int match
) {
89 assert_return(enumerator
, -EINVAL
);
90 assert_return(subsystem
, -EINVAL
);
93 set
= &enumerator
->match_subsystem
;
95 set
= &enumerator
->nomatch_subsystem
;
97 r
= set_ensure_allocated(set
, NULL
);
101 r
= set_put_strdup(*set
, subsystem
);
105 enumerator
->scan_uptodate
= false;
110 _public_
int sd_device_enumerator_add_match_sysattr(sd_device_enumerator
*enumerator
, const char *_sysattr
, const char *_value
, int match
) {
111 _cleanup_free_
char *sysattr
= NULL
, *value
= NULL
;
115 assert_return(enumerator
, -EINVAL
);
116 assert_return(_sysattr
, -EINVAL
);
119 hashmap
= &enumerator
->match_sysattr
;
121 hashmap
= &enumerator
->nomatch_sysattr
;
123 r
= hashmap_ensure_allocated(hashmap
, NULL
);
127 sysattr
= strdup(_sysattr
);
132 value
= strdup(_value
);
137 r
= hashmap_put(*hashmap
, sysattr
, value
);
144 enumerator
->scan_uptodate
= false;
149 _public_
int sd_device_enumerator_add_match_property(sd_device_enumerator
*enumerator
, const char *_property
, const char *_value
) {
150 _cleanup_free_
char *property
= NULL
, *value
= NULL
;
153 assert_return(enumerator
, -EINVAL
);
154 assert_return(_property
, -EINVAL
);
156 r
= hashmap_ensure_allocated(&enumerator
->match_property
, NULL
);
160 property
= strdup(_property
);
165 value
= strdup(_value
);
170 r
= hashmap_put(enumerator
->match_property
, property
, value
);
177 enumerator
->scan_uptodate
= false;
182 _public_
int sd_device_enumerator_add_match_sysname(sd_device_enumerator
*enumerator
, const char *sysname
) {
185 assert_return(enumerator
, -EINVAL
);
186 assert_return(sysname
, -EINVAL
);
188 r
= set_ensure_allocated(&enumerator
->match_sysname
, NULL
);
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_ensure_allocated(&enumerator
->match_tag
, NULL
);
211 r
= set_put_strdup(enumerator
->match_tag
, tag
);
215 enumerator
->scan_uptodate
= false;
220 _public_
int sd_device_enumerator_add_match_parent(sd_device_enumerator
*enumerator
, sd_device
*parent
) {
221 assert_return(enumerator
, -EINVAL
);
222 assert_return(parent
, -EINVAL
);
224 sd_device_unref(enumerator
->match_parent
);
225 enumerator
->match_parent
= sd_device_ref(parent
);
227 enumerator
->scan_uptodate
= false;
232 _public_
int sd_device_enumerator_allow_uninitialized(sd_device_enumerator
*enumerator
) {
233 assert_return(enumerator
, -EINVAL
);
235 enumerator
->match_allow_uninitialized
= true;
237 enumerator
->scan_uptodate
= false;
242 int device_enumerator_add_match_is_initialized(sd_device_enumerator
*enumerator
) {
243 assert_return(enumerator
, -EINVAL
);
245 enumerator
->match_allow_uninitialized
= false;
247 enumerator
->scan_uptodate
= false;
252 static int device_compare(sd_device
* const *_a
, sd_device
* const *_b
) {
253 sd_device
*a
= *(sd_device
**)_a
, *b
= *(sd_device
**)_b
;
254 const char *devpath_a
, *devpath_b
, *sound_a
;
255 bool delay_a
, delay_b
;
258 assert_se(sd_device_get_devpath(a
, &devpath_a
) >= 0);
259 assert_se(sd_device_get_devpath(b
, &devpath_b
) >= 0);
261 sound_a
= strstr(devpath_a
, "/sound/card");
263 /* For sound cards the control device must be enumerated last to
264 * make sure it's the final device node that gets ACLs applied.
265 * Applications rely on this fact and use ACL changes on the
266 * control node as an indicator that the ACL change of the
267 * entire sound card completed. The kernel makes this guarantee
268 * when creating those devices, and hence we should too when
269 * enumerating them. */
270 sound_a
+= STRLEN("/sound/card");
271 sound_a
= strchr(sound_a
, '/');
276 prefix_len
= sound_a
- devpath_a
;
278 if (strncmp(devpath_a
, devpath_b
, prefix_len
) == 0) {
281 sound_b
= devpath_b
+ prefix_len
;
283 if (startswith(sound_a
, "/controlC") &&
284 !startswith(sound_b
, "/contolC"))
287 if (!startswith(sound_a
, "/controlC") &&
288 startswith(sound_b
, "/controlC"))
294 /* md and dm devices are enumerated after all other devices */
295 delay_a
= strstr(devpath_a
, "/block/md") || strstr(devpath_a
, "/block/dm-");
296 delay_b
= strstr(devpath_b
, "/block/md") || strstr(devpath_b
, "/block/dm-");
297 r
= CMP(delay_a
, delay_b
);
301 return strcmp(devpath_a
, devpath_b
);
304 int device_enumerator_add_device(sd_device_enumerator
*enumerator
, sd_device
*device
) {
305 assert_return(enumerator
, -EINVAL
);
306 assert_return(device
, -EINVAL
);
308 if (!GREEDY_REALLOC(enumerator
->devices
, enumerator
->n_allocated
, enumerator
->n_devices
+ 1))
311 enumerator
->devices
[enumerator
->n_devices
++] = sd_device_ref(device
);
316 static bool match_sysattr_value(sd_device
*device
, const char *sysattr
, const char *match_value
) {
323 r
= sd_device_get_sysattr_value(device
, sysattr
, &value
);
330 if (fnmatch(match_value
, value
, 0) == 0)
336 static bool match_sysattr(sd_device_enumerator
*enumerator
, sd_device
*device
) {
344 HASHMAP_FOREACH_KEY(value
, sysattr
, enumerator
->nomatch_sysattr
, i
)
345 if (match_sysattr_value(device
, sysattr
, value
))
348 HASHMAP_FOREACH_KEY(value
, sysattr
, enumerator
->match_sysattr
, i
)
349 if (!match_sysattr_value(device
, sysattr
, value
))
355 static bool match_property(sd_device_enumerator
*enumerator
, sd_device
*device
) {
356 const char *property
;
363 if (hashmap_isempty(enumerator
->match_property
))
366 HASHMAP_FOREACH_KEY(value
, property
, enumerator
->match_property
, i
) {
367 const char *property_dev
, *value_dev
;
369 FOREACH_DEVICE_PROPERTY(device
, property_dev
, value_dev
) {
370 if (fnmatch(property
, property_dev
, 0) != 0)
373 if (!value
&& !value_dev
)
376 if (!value
|| !value_dev
)
379 if (fnmatch(value
, value_dev
, 0) == 0)
387 static bool match_tag(sd_device_enumerator
*enumerator
, sd_device
*device
) {
394 SET_FOREACH(tag
, enumerator
->match_tag
, i
)
395 if (!sd_device_has_tag(device
, tag
))
401 static bool match_parent(sd_device_enumerator
*enumerator
, sd_device
*device
) {
402 const char *devpath
, *devpath_dev
;
408 if (!enumerator
->match_parent
)
411 r
= sd_device_get_devpath(enumerator
->match_parent
, &devpath
);
414 r
= sd_device_get_devpath(device
, &devpath_dev
);
417 return startswith(devpath_dev
, devpath
);
420 static bool match_sysname(sd_device_enumerator
*enumerator
, const char *sysname
) {
421 const char *sysname_match
;
427 if (set_isempty(enumerator
->match_sysname
))
430 SET_FOREACH(sysname_match
, enumerator
->match_sysname
, i
)
431 if (fnmatch(sysname_match
, sysname
, 0) == 0)
437 static int enumerator_scan_dir_and_add_devices(sd_device_enumerator
*enumerator
, const char *basedir
, const char *subdir1
, const char *subdir2
) {
438 _cleanup_closedir_
DIR *dir
= NULL
;
446 path
= strjoina("/sys/", basedir
, "/");
449 path
= strjoina(path
, subdir1
, "/");
452 path
= strjoina(path
, subdir2
, "/");
458 FOREACH_DIRENT_ALL(dent
, dir
, return -errno
) {
459 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
460 char syspath
[strlen(path
) + 1 + strlen(dent
->d_name
) + 1];
463 if (dent
->d_name
[0] == '.')
466 if (!match_sysname(enumerator
, dent
->d_name
))
469 (void) sprintf(syspath
, "%s%s", path
, dent
->d_name
);
471 k
= sd_device_new_from_syspath(&device
, syspath
);
474 /* this is necessarily racey, so ignore missing devices */
480 initialized
= sd_device_get_is_initialized(device
);
481 if (initialized
< 0) {
487 * All devices with a device node or network interfaces
488 * possibly need udev to adjust the device node permission
489 * or context, or rename the interface before it can be
490 * reliably used from other processes.
492 * For now, we can only check these types of devices, we
493 * might not store a database, and have no way to find out
494 * for all other types of devices.
496 if (!enumerator
->match_allow_uninitialized
&&
498 (sd_device_get_devnum(device
, NULL
) >= 0 ||
499 sd_device_get_ifindex(device
, NULL
) >= 0))
502 if (!match_parent(enumerator
, device
))
505 if (!match_tag(enumerator
, device
))
508 if (!match_property(enumerator
, device
))
511 if (!match_sysattr(enumerator
, device
))
514 k
= device_enumerator_add_device(enumerator
, device
);
522 static bool match_subsystem(sd_device_enumerator
*enumerator
, const char *subsystem
) {
523 const char *subsystem_match
;
531 SET_FOREACH(subsystem_match
, enumerator
->nomatch_subsystem
, i
)
532 if (fnmatch(subsystem_match
, subsystem
, 0) == 0)
535 if (set_isempty(enumerator
->match_subsystem
))
538 SET_FOREACH(subsystem_match
, enumerator
->match_subsystem
, i
)
539 if (fnmatch(subsystem_match
, subsystem
, 0) == 0)
545 static int enumerator_scan_dir(sd_device_enumerator
*enumerator
, const char *basedir
, const char *subdir
, const char *subsystem
) {
546 _cleanup_closedir_
DIR *dir
= NULL
;
551 path
= strjoina("/sys/", basedir
);
557 log_debug("sd-device-enumerator: Scanning %s", path
);
559 FOREACH_DIRENT_ALL(dent
, dir
, return -errno
) {
562 if (dent
->d_name
[0] == '.')
565 if (!match_subsystem(enumerator
, subsystem
? : dent
->d_name
))
568 k
= enumerator_scan_dir_and_add_devices(enumerator
, basedir
, dent
->d_name
, subdir
);
576 static int enumerator_scan_devices_tag(sd_device_enumerator
*enumerator
, const char *tag
) {
577 _cleanup_closedir_
DIR *dir
= NULL
;
585 path
= strjoina("/run/udev/tags/", tag
);
590 return log_debug_errno(errno
, "sd-device-enumerator: Failed to open tags directory %s: %m", path
);
594 /* TODO: filter away subsystems? */
596 FOREACH_DIRENT_ALL(dent
, dir
, return -errno
) {
597 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
598 const char *subsystem
, *sysname
;
601 if (dent
->d_name
[0] == '.')
604 k
= sd_device_new_from_device_id(&device
, dent
->d_name
);
607 /* this is necessarily racy, so ignore missing devices */
613 k
= sd_device_get_subsystem(device
, &subsystem
);
619 if (!match_subsystem(enumerator
, subsystem
))
622 k
= sd_device_get_sysname(device
, &sysname
);
628 if (!match_sysname(enumerator
, sysname
))
631 if (!match_parent(enumerator
, device
))
634 if (!match_property(enumerator
, device
))
637 if (!match_sysattr(enumerator
, device
))
640 k
= device_enumerator_add_device(enumerator
, device
);
650 static int enumerator_scan_devices_tags(sd_device_enumerator
*enumerator
) {
657 SET_FOREACH(tag
, enumerator
->match_tag
, i
) {
660 k
= enumerator_scan_devices_tag(enumerator
, tag
);
668 static int parent_add_child(sd_device_enumerator
*enumerator
, const char *path
) {
669 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
670 const char *subsystem
, *sysname
;
673 r
= sd_device_new_from_syspath(&device
, path
);
675 /* this is necessarily racy, so ignore missing devices */
680 r
= sd_device_get_subsystem(device
, &subsystem
);
686 if (!match_subsystem(enumerator
, subsystem
))
689 r
= sd_device_get_sysname(device
, &sysname
);
693 if (!match_sysname(enumerator
, sysname
))
696 if (!match_property(enumerator
, device
))
699 if (!match_sysattr(enumerator
, device
))
702 r
= device_enumerator_add_device(enumerator
, device
);
709 static int parent_crawl_children(sd_device_enumerator
*enumerator
, const char *path
, unsigned maxdepth
) {
710 _cleanup_closedir_
DIR *dir
= NULL
;
716 return log_debug_errno(errno
, "sd-device-enumerator: Failed to open parent directory %s: %m", path
);
718 FOREACH_DIRENT_ALL(dent
, dir
, return -errno
) {
719 _cleanup_free_
char *child
= NULL
;
722 if (dent
->d_name
[0] == '.')
725 if (dent
->d_type
!= DT_DIR
)
728 child
= strjoin(path
, "/", dent
->d_name
);
732 k
= parent_add_child(enumerator
, child
);
737 parent_crawl_children(enumerator
, child
, maxdepth
- 1);
739 log_debug("sd-device-enumerator: Max depth reached, %s: ignoring devices", child
);
745 static int enumerator_scan_devices_children(sd_device_enumerator
*enumerator
) {
749 r
= sd_device_get_syspath(enumerator
->match_parent
, &path
);
753 k
= parent_add_child(enumerator
, path
);
757 k
= parent_crawl_children(enumerator
, path
, DEVICE_ENUMERATE_MAX_DEPTH
);
764 static int enumerator_scan_devices_all(sd_device_enumerator
*enumerator
) {
767 log_debug("sd-device-enumerator: Scan all dirs");
769 if (access("/sys/subsystem", F_OK
) >= 0) {
770 /* we have /subsystem/, forget all the old stuff */
771 r
= enumerator_scan_dir(enumerator
, "subsystem", "devices", NULL
);
773 return log_debug_errno(r
, "sd-device-enumerator: Failed to scan /sys/subsystem: %m");
777 k
= enumerator_scan_dir(enumerator
, "bus", "devices", NULL
);
779 log_debug_errno(k
, "sd-device-enumerator: Failed to scan /sys/bus: %m");
783 k
= enumerator_scan_dir(enumerator
, "class", NULL
, NULL
);
785 log_debug_errno(k
, "sd-device-enumerator: Failed to scan /sys/class: %m");
793 static void device_enumerator_dedup_devices(sd_device_enumerator
*enumerator
) {
794 sd_device
**a
, **b
, **end
;
798 if (enumerator
->n_devices
<= 1)
801 a
= enumerator
->devices
+ 1;
802 b
= enumerator
->devices
;
803 end
= enumerator
->devices
+ enumerator
->n_devices
;
805 for (; a
< end
; a
++) {
806 const char *devpath_a
, *devpath_b
;
808 assert_se(sd_device_get_devpath(*a
, &devpath_a
) >= 0);
809 assert_se(sd_device_get_devpath(*b
, &devpath_b
) >= 0);
811 if (path_equal(devpath_a
, devpath_b
))
817 enumerator
->n_devices
= b
- enumerator
->devices
+ 1;
820 int device_enumerator_scan_devices(sd_device_enumerator
*enumerator
) {
826 if (enumerator
->scan_uptodate
&&
827 enumerator
->type
== DEVICE_ENUMERATION_TYPE_DEVICES
)
830 for (i
= 0; i
< enumerator
->n_devices
; i
++)
831 sd_device_unref(enumerator
->devices
[i
]);
833 enumerator
->n_devices
= 0;
835 if (!set_isempty(enumerator
->match_tag
)) {
836 k
= enumerator_scan_devices_tags(enumerator
);
839 } else if (enumerator
->match_parent
) {
840 k
= enumerator_scan_devices_children(enumerator
);
844 k
= enumerator_scan_devices_all(enumerator
);
849 typesafe_qsort(enumerator
->devices
, enumerator
->n_devices
, device_compare
);
850 device_enumerator_dedup_devices(enumerator
);
852 enumerator
->scan_uptodate
= true;
853 enumerator
->type
= DEVICE_ENUMERATION_TYPE_DEVICES
;
858 _public_ sd_device
*sd_device_enumerator_get_device_first(sd_device_enumerator
*enumerator
) {
861 assert_return(enumerator
, NULL
);
863 r
= device_enumerator_scan_devices(enumerator
);
867 enumerator
->current_device_index
= 0;
869 if (enumerator
->n_devices
== 0)
872 return enumerator
->devices
[0];
875 _public_ sd_device
*sd_device_enumerator_get_device_next(sd_device_enumerator
*enumerator
) {
876 assert_return(enumerator
, NULL
);
878 if (!enumerator
->scan_uptodate
||
879 enumerator
->type
!= DEVICE_ENUMERATION_TYPE_DEVICES
||
880 enumerator
->current_device_index
+ 1 >= enumerator
->n_devices
)
883 return enumerator
->devices
[++enumerator
->current_device_index
];
886 int device_enumerator_scan_subsystems(sd_device_enumerator
*enumerator
) {
887 const char *subsysdir
;
893 if (enumerator
->scan_uptodate
&&
894 enumerator
->type
== DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
)
897 for (i
= 0; i
< enumerator
->n_devices
; i
++)
898 sd_device_unref(enumerator
->devices
[i
]);
900 enumerator
->n_devices
= 0;
903 if (match_subsystem(enumerator
, "module")) {
904 k
= enumerator_scan_dir_and_add_devices(enumerator
, "module", NULL
, NULL
);
906 log_debug_errno(k
, "sd-device-enumerator: Failed to scan modules: %m");
911 if (access("/sys/subsystem", F_OK
) >= 0)
912 subsysdir
= "subsystem";
916 /* subsystems (only buses support coldplug) */
917 if (match_subsystem(enumerator
, "subsystem")) {
918 k
= enumerator_scan_dir_and_add_devices(enumerator
, subsysdir
, NULL
, NULL
);
920 log_debug_errno(k
, "sd-device-enumerator: Failed to scan subsystems: %m");
925 /* subsystem drivers */
926 if (match_subsystem(enumerator
, "drivers")) {
927 k
= enumerator_scan_dir(enumerator
, subsysdir
, "drivers", "drivers");
929 log_debug_errno(k
, "sd-device-enumerator: Failed to scan drivers: %m");
934 typesafe_qsort(enumerator
->devices
, enumerator
->n_devices
, device_compare
);
935 device_enumerator_dedup_devices(enumerator
);
937 enumerator
->scan_uptodate
= true;
938 enumerator
->type
= DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
;
943 _public_ sd_device
*sd_device_enumerator_get_subsystem_first(sd_device_enumerator
*enumerator
) {
946 assert_return(enumerator
, NULL
);
948 r
= device_enumerator_scan_subsystems(enumerator
);
952 enumerator
->current_device_index
= 0;
954 if (enumerator
->n_devices
== 0)
957 return enumerator
->devices
[0];
960 _public_ sd_device
*sd_device_enumerator_get_subsystem_next(sd_device_enumerator
*enumerator
) {
961 assert_return(enumerator
, NULL
);
963 if (!enumerator
->scan_uptodate
||
964 enumerator
->type
!= DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
||
965 enumerator
->current_device_index
+ 1 >= enumerator
->n_devices
)
968 return enumerator
->devices
[++enumerator
->current_device_index
];
971 sd_device
*device_enumerator_get_first(sd_device_enumerator
*enumerator
) {
972 assert_return(enumerator
, NULL
);
974 if (!enumerator
->scan_uptodate
)
977 enumerator
->current_device_index
= 0;
979 if (enumerator
->n_devices
== 0)
982 return enumerator
->devices
[0];
985 sd_device
*device_enumerator_get_next(sd_device_enumerator
*enumerator
) {
986 assert_return(enumerator
, NULL
);
988 if (!enumerator
->scan_uptodate
||
989 enumerator
->current_device_index
+ 1 >= enumerator
->n_devices
)
992 return enumerator
->devices
[++enumerator
->current_device_index
];
995 sd_device
**device_enumerator_get_devices(sd_device_enumerator
*enumerator
, size_t *ret_n_devices
) {
997 assert(ret_n_devices
);
999 if (!enumerator
->scan_uptodate
)
1002 *ret_n_devices
= enumerator
->n_devices
;
1003 return enumerator
->devices
;