2 This file is part of systemd.
4 Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
5 Copyright 2014-2015 Tom Gundersen <teg@jklm.no>
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 #include "sd-device.h"
23 #include "alloc-util.h"
24 #include "device-enumerator-private.h"
25 #include "device-util.h"
26 #include "dirent-util.h"
30 #include "string-util.h"
34 #define DEVICE_ENUMERATE_MAX_DEPTH 256
36 typedef enum DeviceEnumerationType
{
37 DEVICE_ENUMERATION_TYPE_DEVICES
,
38 DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
,
39 _DEVICE_ENUMERATION_TYPE_MAX
,
40 _DEVICE_ENUMERATION_TYPE_INVALID
= -1,
41 } DeviceEnumerationType
;
43 struct sd_device_enumerator
{
46 DeviceEnumerationType type
;
51 Set
*nomatch_subsystem
;
52 Hashmap
*match_sysattr
;
53 Hashmap
*nomatch_sysattr
;
54 Hashmap
*match_property
;
57 sd_device
*match_parent
;
58 bool match_allow_uninitialized
;
61 _public_
int sd_device_enumerator_new(sd_device_enumerator
**ret
) {
62 _cleanup_(sd_device_enumerator_unrefp
) sd_device_enumerator
*enumerator
= NULL
;
66 enumerator
= new0(sd_device_enumerator
, 1);
70 enumerator
->n_ref
= 1;
71 enumerator
->type
= _DEVICE_ENUMERATION_TYPE_INVALID
;
79 _public_ sd_device_enumerator
*sd_device_enumerator_ref(sd_device_enumerator
*enumerator
) {
80 assert_return(enumerator
, NULL
);
82 assert_se((++ enumerator
->n_ref
) >= 2);
87 _public_ sd_device_enumerator
*sd_device_enumerator_unref(sd_device_enumerator
*enumerator
) {
88 if (enumerator
&& (-- enumerator
->n_ref
) == 0) {
91 while ((device
= prioq_pop(enumerator
->devices
)))
92 sd_device_unref(device
);
94 prioq_free(enumerator
->devices
);
96 set_free_free(enumerator
->match_subsystem
);
97 set_free_free(enumerator
->nomatch_subsystem
);
98 hashmap_free_free_free(enumerator
->match_sysattr
);
99 hashmap_free_free_free(enumerator
->nomatch_sysattr
);
100 hashmap_free_free_free(enumerator
->match_property
);
101 set_free_free(enumerator
->match_sysname
);
102 set_free_free(enumerator
->match_tag
);
103 sd_device_unref(enumerator
->match_parent
);
111 _public_
int sd_device_enumerator_add_match_subsystem(sd_device_enumerator
*enumerator
, const char *subsystem
, int match
) {
115 assert_return(enumerator
, -EINVAL
);
116 assert_return(subsystem
, -EINVAL
);
119 set
= &enumerator
->match_subsystem
;
121 set
= &enumerator
->nomatch_subsystem
;
123 r
= set_ensure_allocated(set
, NULL
);
127 r
= set_put_strdup(*set
, subsystem
);
131 enumerator
->scan_uptodate
= false;
136 _public_
int sd_device_enumerator_add_match_sysattr(sd_device_enumerator
*enumerator
, const char *_sysattr
, const char *_value
, int match
) {
137 _cleanup_free_
char *sysattr
= NULL
, *value
= NULL
;
141 assert_return(enumerator
, -EINVAL
);
142 assert_return(_sysattr
, -EINVAL
);
145 hashmap
= &enumerator
->match_sysattr
;
147 hashmap
= &enumerator
->nomatch_sysattr
;
149 r
= hashmap_ensure_allocated(hashmap
, NULL
);
153 sysattr
= strdup(_sysattr
);
158 value
= strdup(_value
);
163 r
= hashmap_put(*hashmap
, sysattr
, value
);
170 enumerator
->scan_uptodate
= false;
175 _public_
int sd_device_enumerator_add_match_property(sd_device_enumerator
*enumerator
, const char *_property
, const char *_value
) {
176 _cleanup_free_
char *property
= NULL
, *value
= NULL
;
179 assert_return(enumerator
, -EINVAL
);
180 assert_return(_property
, -EINVAL
);
182 r
= hashmap_ensure_allocated(&enumerator
->match_property
, NULL
);
186 property
= strdup(_property
);
191 value
= strdup(_value
);
196 r
= hashmap_put(enumerator
->match_property
, property
, value
);
203 enumerator
->scan_uptodate
= false;
208 _public_
int sd_device_enumerator_add_match_sysname(sd_device_enumerator
*enumerator
, const char *sysname
) {
211 assert_return(enumerator
, -EINVAL
);
212 assert_return(sysname
, -EINVAL
);
214 r
= set_ensure_allocated(&enumerator
->match_sysname
, NULL
);
218 r
= set_put_strdup(enumerator
->match_sysname
, sysname
);
222 enumerator
->scan_uptodate
= false;
227 _public_
int sd_device_enumerator_add_match_tag(sd_device_enumerator
*enumerator
, const char *tag
) {
230 assert_return(enumerator
, -EINVAL
);
231 assert_return(tag
, -EINVAL
);
233 r
= set_ensure_allocated(&enumerator
->match_tag
, NULL
);
237 r
= set_put_strdup(enumerator
->match_tag
, tag
);
241 enumerator
->scan_uptodate
= false;
246 _public_
int sd_device_enumerator_add_match_parent(sd_device_enumerator
*enumerator
, sd_device
*parent
) {
247 assert_return(enumerator
, -EINVAL
);
248 assert_return(parent
, -EINVAL
);
250 sd_device_unref(enumerator
->match_parent
);
251 enumerator
->match_parent
= sd_device_ref(parent
);
253 enumerator
->scan_uptodate
= false;
258 _public_
int sd_device_enumerator_allow_uninitialized(sd_device_enumerator
*enumerator
) {
259 assert_return(enumerator
, -EINVAL
);
261 enumerator
->match_allow_uninitialized
= true;
263 enumerator
->scan_uptodate
= false;
268 int device_enumerator_add_match_is_initialized(sd_device_enumerator
*enumerator
) {
269 assert_return(enumerator
, -EINVAL
);
271 enumerator
->match_allow_uninitialized
= false;
273 enumerator
->scan_uptodate
= false;
278 static int device_compare(const void *_a
, const void *_b
) {
279 sd_device
*a
= (sd_device
*)_a
, *b
= (sd_device
*)_b
;
280 const char *devpath_a
, *devpath_b
, *sound_a
;
281 bool delay_a
, delay_b
;
283 assert_se(sd_device_get_devpath(a
, &devpath_a
) >= 0);
284 assert_se(sd_device_get_devpath(b
, &devpath_b
) >= 0);
286 sound_a
= strstr(devpath_a
, "/sound/card");
288 /* For sound cards the control device must be enumerated last to
289 * make sure it's the final device node that gets ACLs applied.
290 * Applications rely on this fact and use ACL changes on the
291 * control node as an indicator that the ACL change of the
292 * entire sound card completed. The kernel makes this guarantee
293 * when creating those devices, and hence we should too when
294 * enumerating them. */
295 sound_a
+= strlen("/sound/card");
296 sound_a
= strchr(sound_a
, '/');
301 prefix_len
= sound_a
- devpath_a
;
303 if (strncmp(devpath_a
, devpath_b
, prefix_len
) == 0) {
306 sound_b
= devpath_b
+ prefix_len
;
308 if (startswith(sound_a
, "/controlC") &&
309 !startswith(sound_b
, "/contolC"))
312 if (!startswith(sound_a
, "/controlC") &&
313 startswith(sound_b
, "/controlC"))
319 /* md and dm devices are enumerated after all other devices */
320 delay_a
= strstr(devpath_a
, "/block/md") || strstr(devpath_a
, "/block/dm-");
321 delay_b
= strstr(devpath_b
, "/block/md") || strstr(devpath_b
, "/block/dm-");
322 if (delay_a
!= delay_b
)
323 return delay_a
- delay_b
;
325 return strcmp(devpath_a
, devpath_b
);
328 int device_enumerator_add_device(sd_device_enumerator
*enumerator
, sd_device
*device
) {
331 assert_return(enumerator
, -EINVAL
);
332 assert_return(device
, -EINVAL
);
334 r
= prioq_ensure_allocated(&enumerator
->devices
, device_compare
);
338 r
= prioq_put(enumerator
->devices
, device
, NULL
);
342 sd_device_ref(device
);
347 static bool match_sysattr_value(sd_device
*device
, const char *sysattr
, const char *match_value
) {
354 r
= sd_device_get_sysattr_value(device
, sysattr
, &value
);
361 if (fnmatch(match_value
, value
, 0) == 0)
367 static bool match_sysattr(sd_device_enumerator
*enumerator
, sd_device
*device
) {
375 HASHMAP_FOREACH_KEY(value
, sysattr
, enumerator
->nomatch_sysattr
, i
)
376 if (match_sysattr_value(device
, sysattr
, value
))
379 HASHMAP_FOREACH_KEY(value
, sysattr
, enumerator
->match_sysattr
, i
)
380 if (!match_sysattr_value(device
, sysattr
, value
))
386 static bool match_property(sd_device_enumerator
*enumerator
, sd_device
*device
) {
387 const char *property
;
394 if (hashmap_isempty(enumerator
->match_property
))
397 HASHMAP_FOREACH_KEY(value
, property
, enumerator
->match_property
, i
) {
398 const char *property_dev
, *value_dev
;
400 FOREACH_DEVICE_PROPERTY(device
, property_dev
, value_dev
) {
401 if (fnmatch(property
, property_dev
, 0) != 0)
404 if (!value
&& !value_dev
)
407 if (!value
|| !value_dev
)
410 if (fnmatch(value
, value_dev
, 0) == 0)
418 static bool match_tag(sd_device_enumerator
*enumerator
, sd_device
*device
) {
425 SET_FOREACH(tag
, enumerator
->match_tag
, i
)
426 if (!sd_device_has_tag(device
, tag
))
432 static bool match_parent(sd_device_enumerator
*enumerator
, sd_device
*device
) {
433 const char *devpath
, *devpath_dev
;
439 if (!enumerator
->match_parent
)
442 r
= sd_device_get_devpath(enumerator
->match_parent
, &devpath
);
445 r
= sd_device_get_devpath(device
, &devpath_dev
);
448 return startswith(devpath_dev
, devpath
);
451 static bool match_sysname(sd_device_enumerator
*enumerator
, const char *sysname
) {
452 const char *sysname_match
;
458 if (set_isempty(enumerator
->match_sysname
))
461 SET_FOREACH(sysname_match
, enumerator
->match_sysname
, i
)
462 if (fnmatch(sysname_match
, sysname
, 0) == 0)
468 static int enumerator_scan_dir_and_add_devices(sd_device_enumerator
*enumerator
, const char *basedir
, const char *subdir1
, const char *subdir2
) {
469 _cleanup_closedir_
DIR *dir
= NULL
;
477 path
= strjoina("/sys/", basedir
, "/");
480 path
= strjoina(path
, subdir1
, "/");
483 path
= strjoina(path
, subdir2
, "/");
489 FOREACH_DIRENT_ALL(dent
, dir
, return -errno
) {
490 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
491 char syspath
[strlen(path
) + 1 + strlen(dent
->d_name
) + 1];
493 int ifindex
, initialized
, k
;
495 if (dent
->d_name
[0] == '.')
498 if (!match_sysname(enumerator
, dent
->d_name
))
501 (void)sprintf(syspath
, "%s%s", path
, dent
->d_name
);
503 k
= sd_device_new_from_syspath(&device
, syspath
);
506 /* this is necessarily racey, so ignore missing devices */
512 k
= sd_device_get_devnum(device
, &devnum
);
518 k
= sd_device_get_ifindex(device
, &ifindex
);
524 k
= sd_device_get_is_initialized(device
, &initialized
);
531 * All devices with a device node or network interfaces
532 * possibly need udev to adjust the device node permission
533 * or context, or rename the interface before it can be
534 * reliably used from other processes.
536 * For now, we can only check these types of devices, we
537 * might not store a database, and have no way to find out
538 * for all other types of devices.
540 if (!enumerator
->match_allow_uninitialized
&&
542 (major(devnum
) > 0 || ifindex
> 0))
545 if (!match_parent(enumerator
, device
))
548 if (!match_tag(enumerator
, device
))
551 if (!match_property(enumerator
, device
))
554 if (!match_sysattr(enumerator
, device
))
557 k
= device_enumerator_add_device(enumerator
, device
);
565 static bool match_subsystem(sd_device_enumerator
*enumerator
, const char *subsystem
) {
566 const char *subsystem_match
;
574 SET_FOREACH(subsystem_match
, enumerator
->nomatch_subsystem
, i
)
575 if (fnmatch(subsystem_match
, subsystem
, 0) == 0)
578 if (set_isempty(enumerator
->match_subsystem
))
581 SET_FOREACH(subsystem_match
, enumerator
->match_subsystem
, i
)
582 if (fnmatch(subsystem_match
, subsystem
, 0) == 0)
588 static int enumerator_scan_dir(sd_device_enumerator
*enumerator
, const char *basedir
, const char *subdir
, const char *subsystem
) {
589 _cleanup_closedir_
DIR *dir
= NULL
;
594 path
= strjoina("/sys/", basedir
);
600 log_debug(" device-enumerator: scanning %s", path
);
602 FOREACH_DIRENT_ALL(dent
, dir
, return -errno
) {
605 if (dent
->d_name
[0] == '.')
608 if (!match_subsystem(enumerator
, subsystem
? : dent
->d_name
))
611 k
= enumerator_scan_dir_and_add_devices(enumerator
, basedir
, dent
->d_name
, subdir
);
619 static int enumerator_scan_devices_tag(sd_device_enumerator
*enumerator
, const char *tag
) {
620 _cleanup_closedir_
DIR *dir
= NULL
;
628 path
= strjoina("/run/udev/tags/", tag
);
635 log_error("sd-device-enumerator: could not open tags directory %s: %m", path
);
640 /* TODO: filter away subsystems? */
642 FOREACH_DIRENT_ALL(dent
, dir
, return -errno
) {
643 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
644 const char *subsystem
, *sysname
;
647 if (dent
->d_name
[0] == '.')
650 k
= sd_device_new_from_device_id(&device
, dent
->d_name
);
653 /* this is necessarily racy, so ignore missing devices */
659 k
= sd_device_get_subsystem(device
, &subsystem
);
665 if (!match_subsystem(enumerator
, subsystem
))
668 k
= sd_device_get_sysname(device
, &sysname
);
674 if (!match_sysname(enumerator
, sysname
))
677 if (!match_parent(enumerator
, device
))
680 if (!match_property(enumerator
, device
))
683 if (!match_sysattr(enumerator
, device
))
686 k
= device_enumerator_add_device(enumerator
, device
);
696 static int enumerator_scan_devices_tags(sd_device_enumerator
*enumerator
) {
703 SET_FOREACH(tag
, enumerator
->match_tag
, i
) {
704 r
= enumerator_scan_devices_tag(enumerator
, tag
);
712 static int parent_add_child(sd_device_enumerator
*enumerator
, const char *path
) {
713 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
714 const char *subsystem
, *sysname
;
717 r
= sd_device_new_from_syspath(&device
, path
);
719 /* this is necessarily racy, so ignore missing devices */
724 r
= sd_device_get_subsystem(device
, &subsystem
);
730 if (!match_subsystem(enumerator
, subsystem
))
733 r
= sd_device_get_sysname(device
, &sysname
);
737 if (!match_sysname(enumerator
, sysname
))
740 if (!match_property(enumerator
, device
))
743 if (!match_sysattr(enumerator
, device
))
746 r
= device_enumerator_add_device(enumerator
, device
);
753 static int parent_crawl_children(sd_device_enumerator
*enumerator
, const char *path
, unsigned maxdepth
) {
754 _cleanup_closedir_
DIR *dir
= NULL
;
760 log_debug("sd-device-enumerate: could not open parent directory %s: %m", path
);
764 FOREACH_DIRENT_ALL(dent
, dir
, return -errno
) {
765 _cleanup_free_
char *child
= NULL
;
768 if (dent
->d_name
[0] == '.')
771 if (dent
->d_type
!= DT_DIR
)
774 child
= strjoin(path
, "/", dent
->d_name
, NULL
);
778 k
= parent_add_child(enumerator
, child
);
783 parent_crawl_children(enumerator
, child
, maxdepth
- 1);
785 log_debug("device-enumerate: max depth reached, %s: ignoring devices", child
);
791 static int enumerator_scan_devices_children(sd_device_enumerator
*enumerator
) {
795 r
= sd_device_get_syspath(enumerator
->match_parent
, &path
);
799 k
= parent_add_child(enumerator
, path
);
803 k
= parent_crawl_children(enumerator
, path
, DEVICE_ENUMERATE_MAX_DEPTH
);
810 static int enumerator_scan_devices_all(sd_device_enumerator
*enumerator
) {
813 log_debug("device-enumerator: scan all dirs");
815 if (access("/sys/subsystem", F_OK
) >= 0) {
816 /* we have /subsystem/, forget all the old stuff */
817 r
= enumerator_scan_dir(enumerator
, "subsystem", "devices", NULL
);
819 return log_debug_errno(r
, "device-enumerator: failed to scan /sys/subsystem: %m");
823 k
= enumerator_scan_dir(enumerator
, "bus", "devices", NULL
);
825 log_debug_errno(k
, "device-enumerator: failed to scan /sys/bus: %m");
829 k
= enumerator_scan_dir(enumerator
, "class", NULL
, NULL
);
831 log_debug_errno(k
, "device-enumerator: failed to scan /sys/class: %m");
839 int device_enumerator_scan_devices(sd_device_enumerator
*enumerator
) {
845 if (enumerator
->scan_uptodate
&&
846 enumerator
->type
== DEVICE_ENUMERATION_TYPE_DEVICES
)
849 while ((device
= prioq_pop(enumerator
->devices
)))
850 sd_device_unref(device
);
852 if (!set_isempty(enumerator
->match_tag
)) {
853 r
= enumerator_scan_devices_tags(enumerator
);
856 } else if (enumerator
->match_parent
) {
857 r
= enumerator_scan_devices_children(enumerator
);
861 r
= enumerator_scan_devices_all(enumerator
);
866 enumerator
->scan_uptodate
= true;
871 _public_ sd_device
*sd_device_enumerator_get_device_first(sd_device_enumerator
*enumerator
) {
874 assert_return(enumerator
, NULL
);
876 r
= device_enumerator_scan_devices(enumerator
);
880 enumerator
->type
= DEVICE_ENUMERATION_TYPE_DEVICES
;
882 return prioq_peek(enumerator
->devices
);
885 _public_ sd_device
*sd_device_enumerator_get_device_next(sd_device_enumerator
*enumerator
) {
886 assert_return(enumerator
, NULL
);
888 if (!enumerator
->scan_uptodate
||
889 enumerator
->type
!= DEVICE_ENUMERATION_TYPE_DEVICES
)
892 sd_device_unref(prioq_pop(enumerator
->devices
));
894 return prioq_peek(enumerator
->devices
);
897 int device_enumerator_scan_subsystems(sd_device_enumerator
*enumerator
) {
899 const char *subsysdir
;
904 if (enumerator
->scan_uptodate
&&
905 enumerator
->type
== DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
)
908 while ((device
= prioq_pop(enumerator
->devices
)))
909 sd_device_unref(device
);
912 if (match_subsystem(enumerator
, "module")) {
913 k
= enumerator_scan_dir_and_add_devices(enumerator
, "module", NULL
, NULL
);
915 log_debug_errno(k
, "device-enumerator: failed to scan modules: %m");
920 if (access("/sys/subsystem", F_OK
) >= 0)
921 subsysdir
= "subsystem";
925 /* subsystems (only buses support coldplug) */
926 if (match_subsystem(enumerator
, "subsystem")) {
927 k
= enumerator_scan_dir_and_add_devices(enumerator
, subsysdir
, NULL
, NULL
);
929 log_debug_errno(k
, "device-enumerator: failed to scan subsystems: %m");
934 /* subsystem drivers */
935 if (match_subsystem(enumerator
, "drivers")) {
936 k
= enumerator_scan_dir(enumerator
, subsysdir
, "drivers", "drivers");
938 log_debug_errno(k
, "device-enumerator: failed to scan drivers: %m");
943 enumerator
->scan_uptodate
= true;
948 _public_ sd_device
*sd_device_enumerator_get_subsystem_first(sd_device_enumerator
*enumerator
) {
951 assert_return(enumerator
, NULL
);
953 r
= device_enumerator_scan_subsystems(enumerator
);
957 enumerator
->type
= DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
;
959 return prioq_peek(enumerator
->devices
);
962 _public_ sd_device
*sd_device_enumerator_get_subsystem_next(sd_device_enumerator
*enumerator
) {
963 assert_return(enumerator
, NULL
);
965 if (enumerator
->scan_uptodate
||
966 enumerator
->type
!= DEVICE_ENUMERATION_TYPE_SUBSYSTEMS
)
969 sd_device_unref(prioq_pop(enumerator
->devices
));
971 return prioq_peek(enumerator
->devices
);
974 sd_device
*device_enumerator_get_first(sd_device_enumerator
*enumerator
) {
975 assert_return(enumerator
, NULL
);
977 return prioq_peek(enumerator
->devices
);
980 sd_device
*device_enumerator_get_next(sd_device_enumerator
*enumerator
) {
981 assert_return(enumerator
, NULL
);
983 sd_device_unref(prioq_pop(enumerator
->devices
));
985 return prioq_peek(enumerator
->devices
);