1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
6 Copyright 2014-2015 Tom Gundersen <teg@jklm.no>
11 #include "alloc-util.h"
12 #include "device-enumerator-private.h"
13 #include "device-util.h"
14 #include "dirent-util.h"
18 #include "string-util.h"
22 #define DEVICE_ENUMERATE_MAX_DEPTH 256
24 typedef enum DeviceEnumerationType
{
25 DEVICE_ENUMERATION_TYPE_DEVICES
,
26 DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
,
27 _DEVICE_ENUMERATION_TYPE_MAX
,
28 _DEVICE_ENUMERATION_TYPE_INVALID
= -1,
29 } DeviceEnumerationType
;
31 struct sd_device_enumerator
{
34 DeviceEnumerationType type
;
39 Set
*nomatch_subsystem
;
40 Hashmap
*match_sysattr
;
41 Hashmap
*nomatch_sysattr
;
42 Hashmap
*match_property
;
45 sd_device
*match_parent
;
46 bool match_allow_uninitialized
;
49 _public_
int sd_device_enumerator_new(sd_device_enumerator
**ret
) {
50 _cleanup_(sd_device_enumerator_unrefp
) sd_device_enumerator
*enumerator
= NULL
;
54 enumerator
= new0(sd_device_enumerator
, 1);
58 enumerator
->n_ref
= 1;
59 enumerator
->type
= _DEVICE_ENUMERATION_TYPE_INVALID
;
61 *ret
= TAKE_PTR(enumerator
);
66 _public_ sd_device_enumerator
*sd_device_enumerator_ref(sd_device_enumerator
*enumerator
) {
67 assert_return(enumerator
, NULL
);
69 assert_se((++ enumerator
->n_ref
) >= 2);
74 _public_ sd_device_enumerator
*sd_device_enumerator_unref(sd_device_enumerator
*enumerator
) {
75 if (enumerator
&& (-- enumerator
->n_ref
) == 0) {
78 while ((device
= prioq_pop(enumerator
->devices
)))
79 sd_device_unref(device
);
81 prioq_free(enumerator
->devices
);
83 set_free_free(enumerator
->match_subsystem
);
84 set_free_free(enumerator
->nomatch_subsystem
);
85 hashmap_free_free_free(enumerator
->match_sysattr
);
86 hashmap_free_free_free(enumerator
->nomatch_sysattr
);
87 hashmap_free_free_free(enumerator
->match_property
);
88 set_free_free(enumerator
->match_sysname
);
89 set_free_free(enumerator
->match_tag
);
90 sd_device_unref(enumerator
->match_parent
);
98 _public_
int sd_device_enumerator_add_match_subsystem(sd_device_enumerator
*enumerator
, const char *subsystem
, int match
) {
102 assert_return(enumerator
, -EINVAL
);
103 assert_return(subsystem
, -EINVAL
);
106 set
= &enumerator
->match_subsystem
;
108 set
= &enumerator
->nomatch_subsystem
;
110 r
= set_ensure_allocated(set
, NULL
);
114 r
= set_put_strdup(*set
, subsystem
);
118 enumerator
->scan_uptodate
= false;
123 _public_
int sd_device_enumerator_add_match_sysattr(sd_device_enumerator
*enumerator
, const char *_sysattr
, const char *_value
, int match
) {
124 _cleanup_free_
char *sysattr
= NULL
, *value
= NULL
;
128 assert_return(enumerator
, -EINVAL
);
129 assert_return(_sysattr
, -EINVAL
);
132 hashmap
= &enumerator
->match_sysattr
;
134 hashmap
= &enumerator
->nomatch_sysattr
;
136 r
= hashmap_ensure_allocated(hashmap
, NULL
);
140 sysattr
= strdup(_sysattr
);
145 value
= strdup(_value
);
150 r
= hashmap_put(*hashmap
, sysattr
, value
);
157 enumerator
->scan_uptodate
= false;
162 _public_
int sd_device_enumerator_add_match_property(sd_device_enumerator
*enumerator
, const char *_property
, const char *_value
) {
163 _cleanup_free_
char *property
= NULL
, *value
= NULL
;
166 assert_return(enumerator
, -EINVAL
);
167 assert_return(_property
, -EINVAL
);
169 r
= hashmap_ensure_allocated(&enumerator
->match_property
, NULL
);
173 property
= strdup(_property
);
178 value
= strdup(_value
);
183 r
= hashmap_put(enumerator
->match_property
, property
, value
);
190 enumerator
->scan_uptodate
= false;
195 _public_
int sd_device_enumerator_add_match_sysname(sd_device_enumerator
*enumerator
, const char *sysname
) {
198 assert_return(enumerator
, -EINVAL
);
199 assert_return(sysname
, -EINVAL
);
201 r
= set_ensure_allocated(&enumerator
->match_sysname
, NULL
);
205 r
= set_put_strdup(enumerator
->match_sysname
, sysname
);
209 enumerator
->scan_uptodate
= false;
214 _public_
int sd_device_enumerator_add_match_tag(sd_device_enumerator
*enumerator
, const char *tag
) {
217 assert_return(enumerator
, -EINVAL
);
218 assert_return(tag
, -EINVAL
);
220 r
= set_ensure_allocated(&enumerator
->match_tag
, NULL
);
224 r
= set_put_strdup(enumerator
->match_tag
, tag
);
228 enumerator
->scan_uptodate
= false;
233 _public_
int sd_device_enumerator_add_match_parent(sd_device_enumerator
*enumerator
, sd_device
*parent
) {
234 assert_return(enumerator
, -EINVAL
);
235 assert_return(parent
, -EINVAL
);
237 sd_device_unref(enumerator
->match_parent
);
238 enumerator
->match_parent
= sd_device_ref(parent
);
240 enumerator
->scan_uptodate
= false;
245 _public_
int sd_device_enumerator_allow_uninitialized(sd_device_enumerator
*enumerator
) {
246 assert_return(enumerator
, -EINVAL
);
248 enumerator
->match_allow_uninitialized
= true;
250 enumerator
->scan_uptodate
= false;
255 int device_enumerator_add_match_is_initialized(sd_device_enumerator
*enumerator
) {
256 assert_return(enumerator
, -EINVAL
);
258 enumerator
->match_allow_uninitialized
= false;
260 enumerator
->scan_uptodate
= false;
265 static int device_compare(const void *_a
, const void *_b
) {
266 sd_device
*a
= (sd_device
*)_a
, *b
= (sd_device
*)_b
;
267 const char *devpath_a
, *devpath_b
, *sound_a
;
268 bool delay_a
, delay_b
;
270 assert_se(sd_device_get_devpath(a
, &devpath_a
) >= 0);
271 assert_se(sd_device_get_devpath(b
, &devpath_b
) >= 0);
273 sound_a
= strstr(devpath_a
, "/sound/card");
275 /* For sound cards the control device must be enumerated last to
276 * make sure it's the final device node that gets ACLs applied.
277 * Applications rely on this fact and use ACL changes on the
278 * control node as an indicator that the ACL change of the
279 * entire sound card completed. The kernel makes this guarantee
280 * when creating those devices, and hence we should too when
281 * enumerating them. */
282 sound_a
+= STRLEN("/sound/card");
283 sound_a
= strchr(sound_a
, '/');
288 prefix_len
= sound_a
- devpath_a
;
290 if (strncmp(devpath_a
, devpath_b
, prefix_len
) == 0) {
293 sound_b
= devpath_b
+ prefix_len
;
295 if (startswith(sound_a
, "/controlC") &&
296 !startswith(sound_b
, "/contolC"))
299 if (!startswith(sound_a
, "/controlC") &&
300 startswith(sound_b
, "/controlC"))
306 /* md and dm devices are enumerated after all other devices */
307 delay_a
= strstr(devpath_a
, "/block/md") || strstr(devpath_a
, "/block/dm-");
308 delay_b
= strstr(devpath_b
, "/block/md") || strstr(devpath_b
, "/block/dm-");
309 if (delay_a
!= delay_b
)
310 return delay_a
- delay_b
;
312 return strcmp(devpath_a
, devpath_b
);
315 int device_enumerator_add_device(sd_device_enumerator
*enumerator
, sd_device
*device
) {
318 assert_return(enumerator
, -EINVAL
);
319 assert_return(device
, -EINVAL
);
321 r
= prioq_ensure_allocated(&enumerator
->devices
, device_compare
);
325 r
= prioq_put(enumerator
->devices
, device
, NULL
);
329 sd_device_ref(device
);
334 static bool match_sysattr_value(sd_device
*device
, const char *sysattr
, const char *match_value
) {
341 r
= sd_device_get_sysattr_value(device
, sysattr
, &value
);
348 if (fnmatch(match_value
, value
, 0) == 0)
354 static bool match_sysattr(sd_device_enumerator
*enumerator
, sd_device
*device
) {
362 HASHMAP_FOREACH_KEY(value
, sysattr
, enumerator
->nomatch_sysattr
, i
)
363 if (match_sysattr_value(device
, sysattr
, value
))
366 HASHMAP_FOREACH_KEY(value
, sysattr
, enumerator
->match_sysattr
, i
)
367 if (!match_sysattr_value(device
, sysattr
, value
))
373 static bool match_property(sd_device_enumerator
*enumerator
, sd_device
*device
) {
374 const char *property
;
381 if (hashmap_isempty(enumerator
->match_property
))
384 HASHMAP_FOREACH_KEY(value
, property
, enumerator
->match_property
, i
) {
385 const char *property_dev
, *value_dev
;
387 FOREACH_DEVICE_PROPERTY(device
, property_dev
, value_dev
) {
388 if (fnmatch(property
, property_dev
, 0) != 0)
391 if (!value
&& !value_dev
)
394 if (!value
|| !value_dev
)
397 if (fnmatch(value
, value_dev
, 0) == 0)
405 static bool match_tag(sd_device_enumerator
*enumerator
, sd_device
*device
) {
412 SET_FOREACH(tag
, enumerator
->match_tag
, i
)
413 if (!sd_device_has_tag(device
, tag
))
419 static bool match_parent(sd_device_enumerator
*enumerator
, sd_device
*device
) {
420 const char *devpath
, *devpath_dev
;
426 if (!enumerator
->match_parent
)
429 r
= sd_device_get_devpath(enumerator
->match_parent
, &devpath
);
432 r
= sd_device_get_devpath(device
, &devpath_dev
);
435 return startswith(devpath_dev
, devpath
);
438 static bool match_sysname(sd_device_enumerator
*enumerator
, const char *sysname
) {
439 const char *sysname_match
;
445 if (set_isempty(enumerator
->match_sysname
))
448 SET_FOREACH(sysname_match
, enumerator
->match_sysname
, i
)
449 if (fnmatch(sysname_match
, sysname
, 0) == 0)
455 static int enumerator_scan_dir_and_add_devices(sd_device_enumerator
*enumerator
, const char *basedir
, const char *subdir1
, const char *subdir2
) {
456 _cleanup_closedir_
DIR *dir
= NULL
;
464 path
= strjoina("/sys/", basedir
, "/");
467 path
= strjoina(path
, subdir1
, "/");
470 path
= strjoina(path
, subdir2
, "/");
476 FOREACH_DIRENT_ALL(dent
, dir
, return -errno
) {
477 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
478 char syspath
[strlen(path
) + 1 + strlen(dent
->d_name
) + 1];
480 int ifindex
, initialized
, k
;
482 if (dent
->d_name
[0] == '.')
485 if (!match_sysname(enumerator
, dent
->d_name
))
488 (void)sprintf(syspath
, "%s%s", path
, dent
->d_name
);
490 k
= sd_device_new_from_syspath(&device
, syspath
);
493 /* this is necessarily racey, so ignore missing devices */
499 k
= sd_device_get_devnum(device
, &devnum
);
505 k
= sd_device_get_ifindex(device
, &ifindex
);
511 k
= sd_device_get_is_initialized(device
, &initialized
);
518 * All devices with a device node or network interfaces
519 * possibly need udev to adjust the device node permission
520 * or context, or rename the interface before it can be
521 * reliably used from other processes.
523 * For now, we can only check these types of devices, we
524 * might not store a database, and have no way to find out
525 * for all other types of devices.
527 if (!enumerator
->match_allow_uninitialized
&&
529 (major(devnum
) > 0 || ifindex
> 0))
532 if (!match_parent(enumerator
, device
))
535 if (!match_tag(enumerator
, device
))
538 if (!match_property(enumerator
, device
))
541 if (!match_sysattr(enumerator
, device
))
544 k
= device_enumerator_add_device(enumerator
, device
);
552 static bool match_subsystem(sd_device_enumerator
*enumerator
, const char *subsystem
) {
553 const char *subsystem_match
;
561 SET_FOREACH(subsystem_match
, enumerator
->nomatch_subsystem
, i
)
562 if (fnmatch(subsystem_match
, subsystem
, 0) == 0)
565 if (set_isempty(enumerator
->match_subsystem
))
568 SET_FOREACH(subsystem_match
, enumerator
->match_subsystem
, i
)
569 if (fnmatch(subsystem_match
, subsystem
, 0) == 0)
575 static int enumerator_scan_dir(sd_device_enumerator
*enumerator
, const char *basedir
, const char *subdir
, const char *subsystem
) {
576 _cleanup_closedir_
DIR *dir
= NULL
;
581 path
= strjoina("/sys/", basedir
);
587 log_debug(" device-enumerator: scanning %s", path
);
589 FOREACH_DIRENT_ALL(dent
, dir
, return -errno
) {
592 if (dent
->d_name
[0] == '.')
595 if (!match_subsystem(enumerator
, subsystem
? : dent
->d_name
))
598 k
= enumerator_scan_dir_and_add_devices(enumerator
, basedir
, dent
->d_name
, subdir
);
606 static int enumerator_scan_devices_tag(sd_device_enumerator
*enumerator
, const char *tag
) {
607 _cleanup_closedir_
DIR *dir
= NULL
;
615 path
= strjoina("/run/udev/tags/", tag
);
622 return log_error_errno(errno
, "sd-device-enumerator: could not open tags directory %s: %m", path
);
625 /* TODO: filter away subsystems? */
627 FOREACH_DIRENT_ALL(dent
, dir
, return -errno
) {
628 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
629 const char *subsystem
, *sysname
;
632 if (dent
->d_name
[0] == '.')
635 k
= sd_device_new_from_device_id(&device
, dent
->d_name
);
638 /* this is necessarily racy, so ignore missing devices */
644 k
= sd_device_get_subsystem(device
, &subsystem
);
650 if (!match_subsystem(enumerator
, subsystem
))
653 k
= sd_device_get_sysname(device
, &sysname
);
659 if (!match_sysname(enumerator
, sysname
))
662 if (!match_parent(enumerator
, device
))
665 if (!match_property(enumerator
, device
))
668 if (!match_sysattr(enumerator
, device
))
671 k
= device_enumerator_add_device(enumerator
, device
);
681 static int enumerator_scan_devices_tags(sd_device_enumerator
*enumerator
) {
688 SET_FOREACH(tag
, enumerator
->match_tag
, i
) {
691 k
= enumerator_scan_devices_tag(enumerator
, tag
);
699 static int parent_add_child(sd_device_enumerator
*enumerator
, const char *path
) {
700 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
701 const char *subsystem
, *sysname
;
704 r
= sd_device_new_from_syspath(&device
, path
);
706 /* this is necessarily racy, so ignore missing devices */
711 r
= sd_device_get_subsystem(device
, &subsystem
);
717 if (!match_subsystem(enumerator
, subsystem
))
720 r
= sd_device_get_sysname(device
, &sysname
);
724 if (!match_sysname(enumerator
, sysname
))
727 if (!match_property(enumerator
, device
))
730 if (!match_sysattr(enumerator
, device
))
733 r
= device_enumerator_add_device(enumerator
, device
);
740 static int parent_crawl_children(sd_device_enumerator
*enumerator
, const char *path
, unsigned maxdepth
) {
741 _cleanup_closedir_
DIR *dir
= NULL
;
747 return log_debug_errno(errno
, "sd-device-enumerate: could not open parent directory %s: %m", path
);
749 FOREACH_DIRENT_ALL(dent
, dir
, return -errno
) {
750 _cleanup_free_
char *child
= NULL
;
753 if (dent
->d_name
[0] == '.')
756 if (dent
->d_type
!= DT_DIR
)
759 child
= strjoin(path
, "/", dent
->d_name
);
763 k
= parent_add_child(enumerator
, child
);
768 parent_crawl_children(enumerator
, child
, maxdepth
- 1);
770 log_debug("device-enumerate: max depth reached, %s: ignoring devices", child
);
776 static int enumerator_scan_devices_children(sd_device_enumerator
*enumerator
) {
780 r
= sd_device_get_syspath(enumerator
->match_parent
, &path
);
784 k
= parent_add_child(enumerator
, path
);
788 k
= parent_crawl_children(enumerator
, path
, DEVICE_ENUMERATE_MAX_DEPTH
);
795 static int enumerator_scan_devices_all(sd_device_enumerator
*enumerator
) {
798 log_debug("device-enumerator: scan all dirs");
800 if (access("/sys/subsystem", F_OK
) >= 0) {
801 /* we have /subsystem/, forget all the old stuff */
802 r
= enumerator_scan_dir(enumerator
, "subsystem", "devices", NULL
);
804 return log_debug_errno(r
, "device-enumerator: failed to scan /sys/subsystem: %m");
808 k
= enumerator_scan_dir(enumerator
, "bus", "devices", NULL
);
810 log_debug_errno(k
, "device-enumerator: failed to scan /sys/bus: %m");
814 k
= enumerator_scan_dir(enumerator
, "class", NULL
, NULL
);
816 log_debug_errno(k
, "device-enumerator: failed to scan /sys/class: %m");
824 int device_enumerator_scan_devices(sd_device_enumerator
*enumerator
) {
830 if (enumerator
->scan_uptodate
&&
831 enumerator
->type
== DEVICE_ENUMERATION_TYPE_DEVICES
)
834 while ((device
= prioq_pop(enumerator
->devices
)))
835 sd_device_unref(device
);
837 if (!set_isempty(enumerator
->match_tag
)) {
838 k
= enumerator_scan_devices_tags(enumerator
);
841 } else if (enumerator
->match_parent
) {
842 k
= enumerator_scan_devices_children(enumerator
);
846 k
= enumerator_scan_devices_all(enumerator
);
851 enumerator
->scan_uptodate
= true;
856 _public_ sd_device
*sd_device_enumerator_get_device_first(sd_device_enumerator
*enumerator
) {
859 assert_return(enumerator
, NULL
);
861 r
= device_enumerator_scan_devices(enumerator
);
865 enumerator
->type
= DEVICE_ENUMERATION_TYPE_DEVICES
;
867 return prioq_peek(enumerator
->devices
);
870 _public_ sd_device
*sd_device_enumerator_get_device_next(sd_device_enumerator
*enumerator
) {
871 assert_return(enumerator
, NULL
);
873 if (!enumerator
->scan_uptodate
||
874 enumerator
->type
!= DEVICE_ENUMERATION_TYPE_DEVICES
)
877 sd_device_unref(prioq_pop(enumerator
->devices
));
879 return prioq_peek(enumerator
->devices
);
882 int device_enumerator_scan_subsystems(sd_device_enumerator
*enumerator
) {
884 const char *subsysdir
;
889 if (enumerator
->scan_uptodate
&&
890 enumerator
->type
== DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
)
893 while ((device
= prioq_pop(enumerator
->devices
)))
894 sd_device_unref(device
);
897 if (match_subsystem(enumerator
, "module")) {
898 k
= enumerator_scan_dir_and_add_devices(enumerator
, "module", NULL
, NULL
);
900 log_debug_errno(k
, "device-enumerator: failed to scan modules: %m");
905 if (access("/sys/subsystem", F_OK
) >= 0)
906 subsysdir
= "subsystem";
910 /* subsystems (only buses support coldplug) */
911 if (match_subsystem(enumerator
, "subsystem")) {
912 k
= enumerator_scan_dir_and_add_devices(enumerator
, subsysdir
, NULL
, NULL
);
914 log_debug_errno(k
, "device-enumerator: failed to scan subsystems: %m");
919 /* subsystem drivers */
920 if (match_subsystem(enumerator
, "drivers")) {
921 k
= enumerator_scan_dir(enumerator
, subsysdir
, "drivers", "drivers");
923 log_debug_errno(k
, "device-enumerator: failed to scan drivers: %m");
928 enumerator
->scan_uptodate
= true;
933 _public_ sd_device
*sd_device_enumerator_get_subsystem_first(sd_device_enumerator
*enumerator
) {
936 assert_return(enumerator
, NULL
);
938 r
= device_enumerator_scan_subsystems(enumerator
);
942 enumerator
->type
= DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
;
944 return prioq_peek(enumerator
->devices
);
947 _public_ sd_device
*sd_device_enumerator_get_subsystem_next(sd_device_enumerator
*enumerator
) {
948 assert_return(enumerator
, NULL
);
950 if (enumerator
->scan_uptodate
||
951 enumerator
->type
!= DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
)
954 sd_device_unref(prioq_pop(enumerator
->devices
));
956 return prioq_peek(enumerator
->devices
);
959 sd_device
*device_enumerator_get_first(sd_device_enumerator
*enumerator
) {
960 assert_return(enumerator
, NULL
);
962 return prioq_peek(enumerator
->devices
);
965 sd_device
*device_enumerator_get_next(sd_device_enumerator
*enumerator
) {
966 assert_return(enumerator
, NULL
);
968 sd_device_unref(prioq_pop(enumerator
->devices
));
970 return prioq_peek(enumerator
->devices
);