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/>.
26 #include "sd-device.h"
28 #include "device-util.h"
29 #include "device-enumerator-private.h"
31 #define DEVICE_ENUMERATE_MAX_DEPTH 256
33 typedef enum DeviceEnumerationType {
34 DEVICE_ENUMERATION_TYPE_DEVICES,
35 DEVICE_ENUMERATION_TYPE_SUBSYSTEMS,
36 _DEVICE_ENUMERATION_TYPE_MAX,
37 _DEVICE_ENUMERATION_TYPE_INVALID = -1,
38 } DeviceEnumerationType;
40 struct sd_device_enumerator {
43 DeviceEnumerationType type;
48 Set *nomatch_subsystem;
49 Hashmap *match_sysattr;
50 Hashmap *nomatch_sysattr;
51 Hashmap *match_property;
54 sd_device *match_parent;
55 bool match_allow_uninitialized;
58 _public_ int sd_device_enumerator_new(sd_device_enumerator **ret) {
59 _cleanup_device_enumerator_unref_ sd_device_enumerator *enumerator = NULL;
63 enumerator = new0(sd_device_enumerator, 1);
67 enumerator->n_ref = 1;
68 enumerator->type = _DEVICE_ENUMERATION_TYPE_INVALID;
76 _public_ sd_device_enumerator *sd_device_enumerator_ref(sd_device_enumerator *enumerator) {
77 assert_return(enumerator, NULL);
79 assert_se((++ enumerator->n_ref) >= 2);
84 _public_ sd_device_enumerator *sd_device_enumerator_unref(sd_device_enumerator *enumerator) {
85 if (enumerator && (-- enumerator->n_ref) == 0) {
88 while ((device = prioq_pop(enumerator->devices)))
89 sd_device_unref(device);
91 prioq_free(enumerator->devices);
93 set_free_free(enumerator->match_subsystem);
94 set_free_free(enumerator->nomatch_subsystem);
95 hashmap_free_free_free(enumerator->match_sysattr);
96 hashmap_free_free_free(enumerator->nomatch_sysattr);
97 hashmap_free_free_free(enumerator->match_property);
98 set_free_free(enumerator->match_sysname);
99 set_free_free(enumerator->match_tag);
100 sd_device_unref(enumerator->match_parent);
108 _public_ int sd_device_enumerator_add_match_subsystem(sd_device_enumerator *enumerator, const char *subsystem, int match) {
112 assert_return(enumerator, -EINVAL);
113 assert_return(subsystem, -EINVAL);
116 set = &enumerator->match_subsystem;
118 set = &enumerator->nomatch_subsystem;
120 r = set_ensure_allocated(set, NULL);
124 r = set_put_strdup(*set, subsystem);
128 enumerator->scan_uptodate = false;
133 _public_ int sd_device_enumerator_add_match_sysattr(sd_device_enumerator *enumerator, const char *_sysattr, const char *_value, int match) {
134 _cleanup_free_ char *sysattr = NULL, *value = NULL;
138 assert_return(enumerator, -EINVAL);
139 assert_return(_sysattr, -EINVAL);
142 hashmap = &enumerator->match_sysattr;
144 hashmap = &enumerator->nomatch_sysattr;
146 r = hashmap_ensure_allocated(hashmap, NULL);
150 sysattr = strdup(_sysattr);
155 value = strdup(_value);
160 r = hashmap_put(*hashmap, sysattr, value);
167 enumerator->scan_uptodate = false;
172 _public_ int sd_device_enumerator_add_match_property(sd_device_enumerator *enumerator, const char *_property, const char *_value) {
173 _cleanup_free_ char *property = NULL, *value = NULL;
176 assert_return(enumerator, -EINVAL);
177 assert_return(_property, -EINVAL);
179 r = hashmap_ensure_allocated(&enumerator->match_property, NULL);
183 property = strdup(_property);
188 value = strdup(_value);
193 r = hashmap_put(enumerator->match_property, property, value);
200 enumerator->scan_uptodate = false;
205 _public_ int sd_device_enumerator_add_match_sysname(sd_device_enumerator *enumerator, const char *sysname) {
208 assert_return(enumerator, -EINVAL);
209 assert_return(sysname, -EINVAL);
211 r = set_ensure_allocated(&enumerator->match_sysname, NULL);
215 r = set_put_strdup(enumerator->match_sysname, sysname);
219 enumerator->scan_uptodate = false;
224 _public_ int sd_device_enumerator_add_match_tag(sd_device_enumerator *enumerator, const char *tag) {
227 assert_return(enumerator, -EINVAL);
228 assert_return(tag, -EINVAL);
230 r = set_ensure_allocated(&enumerator->match_tag, NULL);
234 r = set_put_strdup(enumerator->match_tag, tag);
238 enumerator->scan_uptodate = false;
243 _public_ int sd_device_enumerator_add_match_parent(sd_device_enumerator *enumerator, sd_device *parent) {
244 assert_return(enumerator, -EINVAL);
245 assert_return(parent, -EINVAL);
247 sd_device_unref(enumerator->match_parent);
248 enumerator->match_parent = sd_device_ref(parent);
250 enumerator->scan_uptodate = false;
255 _public_ int sd_device_enumerator_allow_uninitialized(sd_device_enumerator *enumerator) {
256 assert_return(enumerator, -EINVAL);
258 enumerator->match_allow_uninitialized = true;
260 enumerator->scan_uptodate = false;
265 int device_enumerator_add_match_is_initialized(sd_device_enumerator *enumerator) {
266 assert_return(enumerator, -EINVAL);
268 enumerator->match_allow_uninitialized = false;
270 enumerator->scan_uptodate = false;
275 static int device_compare(const void *_a, const void *_b) {
276 sd_device *a = (sd_device *)_a, *b = (sd_device *)_b;
277 const char *devpath_a, *devpath_b, *sound_a;
278 bool delay_a = false, delay_b = false;
280 assert_se(sd_device_get_devpath(a, &devpath_a) >= 0);
281 assert_se(sd_device_get_devpath(b, &devpath_b) >= 0);
283 sound_a = strstr(devpath_a, "/sound/card");
285 /* For sound cards the control device must be enumerated last to
286 * make sure it's the final device node that gets ACLs applied.
287 * Applications rely on this fact and use ACL changes on the
288 * control node as an indicator that the ACL change of the
289 * entire sound card completed. The kernel makes this guarantee
290 * when creating those devices, and hence we should too when
291 * enumerating them. */
292 sound_a += strlen("/sound/card");
293 sound_a = strchr(sound_a, '/');
298 prefix_len = sound_a - devpath_a;
300 if (strncmp(devpath_a, devpath_b, prefix_len) == 0) {
303 sound_b = devpath_b + prefix_len;
305 if (startswith(sound_a, "/controlC") &&
306 !startswith(sound_b, "/contolC"))
309 if (!startswith(sound_a, "/controlC") &&
310 startswith(sound_b, "/controlC"))
316 /* md and dm devices are enumerated after all other devices */
317 if (strstr(devpath_a, "/block/md") || strstr(devpath_a, "/block/dm-"))
320 if (strstr(devpath_b, "/block/md") || strstr(devpath_b, "/block/dm-"))
323 if (delay_a && !delay_b)
326 if (!delay_a && delay_b)
329 return strcmp(devpath_a, devpath_b);
332 int device_enumerator_add_device(sd_device_enumerator *enumerator, sd_device *device) {
335 assert_return(enumerator, -EINVAL);
336 assert_return(device, -EINVAL);
338 r = prioq_ensure_allocated(&enumerator->devices, device_compare);
342 r = prioq_put(enumerator->devices, device, NULL);
346 sd_device_ref(device);
351 static bool match_sysattr_value(sd_device *device, const char *sysattr, const char *match_value) {
358 r = sd_device_get_sysattr_value(device, sysattr, &value);
365 if (fnmatch(match_value, value, 0) == 0)
371 static bool match_sysattr(sd_device_enumerator *enumerator, sd_device *device) {
379 HASHMAP_FOREACH_KEY(value, sysattr, enumerator->nomatch_sysattr, i)
380 if (match_sysattr_value(device, sysattr, value))
383 HASHMAP_FOREACH_KEY(value, sysattr, enumerator->match_sysattr, i)
384 if (!match_sysattr_value(device, sysattr, value))
390 static bool match_property(sd_device_enumerator *enumerator, sd_device *device) {
391 const char *property;
398 if (hashmap_isempty(enumerator->match_property))
401 HASHMAP_FOREACH_KEY(value, property, enumerator->match_property, i) {
402 const char *property_dev, *value_dev;
404 FOREACH_DEVICE_PROPERTY(device, property_dev, value_dev) {
405 if (fnmatch(property, property_dev, 0) != 0)
408 if (!value && !value_dev)
411 if (!value || !value_dev)
414 if (fnmatch(value, value_dev, 0) == 0)
422 static bool match_tag(sd_device_enumerator *enumerator, sd_device *device) {
429 SET_FOREACH(tag, enumerator->match_tag, i)
430 if (!sd_device_has_tag(device, tag))
436 static bool match_parent(sd_device_enumerator *enumerator, sd_device *device) {
437 const char *devpath, *devpath_dev;
443 if (!enumerator->match_parent)
446 r = sd_device_get_devpath(enumerator->match_parent, &devpath);
449 r = sd_device_get_devpath(device, &devpath_dev);
452 return startswith(devpath_dev, devpath);
455 static bool match_sysname(sd_device_enumerator *enumerator, const char *sysname) {
456 const char *sysname_match;
462 if (set_isempty(enumerator->match_sysname))
465 SET_FOREACH(sysname_match, enumerator->match_sysname, i)
466 if (fnmatch(sysname_match, sysname, 0) == 0)
472 static int enumerator_scan_dir_and_add_devices(sd_device_enumerator *enumerator, const char *basedir, const char *subdir1, const char *subdir2) {
473 _cleanup_closedir_ DIR *dir = NULL;
481 path = strjoina("/sys/", basedir, "/");
484 path = strjoina(path, subdir1, "/");
487 path = strjoina(path, subdir2, "/");
493 FOREACH_DIRENT_ALL(dent, dir, return -errno) {
494 _cleanup_device_unref_ sd_device *device = NULL;
495 char syspath[strlen(path) + 1 + strlen(dent->d_name) + 1];
497 int ifindex, initialized, k;
499 if (dent->d_name[0] == '.')
502 if (!match_sysname(enumerator, dent->d_name))
505 (void)sprintf(syspath, "%s%s", path, dent->d_name);
507 k = sd_device_new_from_syspath(&device, syspath);
510 /* this is necessarily racey, so ignore missing devices */
516 k = sd_device_get_devnum(device, &devnum);
522 k = sd_device_get_ifindex(device, &ifindex);
528 k = sd_device_get_is_initialized(device, &initialized);
535 * All devices with a device node or network interfaces
536 * possibly need udev to adjust the device node permission
537 * or context, or rename the interface before it can be
538 * reliably used from other processes.
540 * For now, we can only check these types of devices, we
541 * might not store a database, and have no way to find out
542 * for all other types of devices.
544 if (!enumerator->match_allow_uninitialized &&
546 (major(devnum) > 0 || ifindex > 0))
549 if (!match_parent(enumerator, device))
552 if (!match_tag(enumerator, device))
555 if (!match_property(enumerator, device))
558 if (!match_sysattr(enumerator, device))
561 k = device_enumerator_add_device(enumerator, device);
569 static bool match_subsystem(sd_device_enumerator *enumerator, const char *subsystem) {
570 const char *subsystem_match;
578 SET_FOREACH(subsystem_match, enumerator->nomatch_subsystem, i)
579 if (fnmatch(subsystem_match, subsystem, 0) == 0)
582 if (set_isempty(enumerator->match_subsystem))
585 SET_FOREACH(subsystem_match, enumerator->match_subsystem, i)
586 if (fnmatch(subsystem_match, subsystem, 0) == 0)
592 static int enumerator_scan_dir(sd_device_enumerator *enumerator, const char *basedir, const char *subdir, const char *subsystem) {
593 _cleanup_closedir_ DIR *dir = NULL;
598 path = strjoina("/sys/", basedir);
604 log_debug(" device-enumerator: scanning %s", path);
606 FOREACH_DIRENT_ALL(dent, dir, return -errno) {
609 if (dent->d_name[0] == '.')
612 if (!match_subsystem(enumerator, subsystem ? : dent->d_name))
615 k = enumerator_scan_dir_and_add_devices(enumerator, basedir, dent->d_name, subdir);
623 static int enumerator_scan_devices_tag(sd_device_enumerator *enumerator, const char *tag) {
624 _cleanup_closedir_ DIR *dir = NULL;
632 path = strjoina("/run/udev/tags/", tag);
639 log_error("sd-device-enumerator: could not open tags directory %s: %m", path);
644 /* TODO: filter away subsystems? */
646 FOREACH_DIRENT_ALL(dent, dir, return -errno) {
647 _cleanup_device_unref_ sd_device *device = NULL;
648 const char *subsystem, *sysname;
651 if (dent->d_name[0] == '.')
654 k = sd_device_new_from_device_id(&device, dent->d_name);
657 /* this is necessarily racy, so ignore missing devices */
663 k = sd_device_get_subsystem(device, &subsystem);
669 if (!match_subsystem(enumerator, subsystem))
672 k = sd_device_get_sysname(device, &sysname);
678 if (!match_sysname(enumerator, sysname))
681 if (!match_parent(enumerator, device))
684 if (!match_property(enumerator, device))
687 if (!match_sysattr(enumerator, device))
690 k = device_enumerator_add_device(enumerator, device);
700 static int enumerator_scan_devices_tags(sd_device_enumerator *enumerator) {
707 SET_FOREACH(tag, enumerator->match_tag, i) {
708 r = enumerator_scan_devices_tag(enumerator, tag);
716 static int parent_add_child(sd_device_enumerator *enumerator, const char *path) {
717 _cleanup_device_unref_ sd_device *device = NULL;
718 const char *subsystem, *sysname;
721 r = sd_device_new_from_syspath(&device, path);
723 /* this is necessarily racy, so ignore missing devices */
728 r = sd_device_get_subsystem(device, &subsystem);
732 if (!match_subsystem(enumerator, subsystem))
735 r = sd_device_get_sysname(device, &sysname);
739 if (!match_sysname(enumerator, sysname))
742 if (!match_property(enumerator, device))
745 if (!match_sysattr(enumerator, device))
748 r = device_enumerator_add_device(enumerator, device);
755 static int parent_crawl_children(sd_device_enumerator *enumerator, const char *path, unsigned maxdepth) {
756 _cleanup_closedir_ DIR *dir = NULL;
762 log_debug("sd-device-enumerate: could not open parent directory %s: %m", path);
766 FOREACH_DIRENT_ALL(dent, dir, return -errno) {
767 _cleanup_free_ char *child = NULL;
770 if (dent->d_name[0] == '.')
773 if (dent->d_type != DT_DIR)
776 child = strjoin(path, "/", dent->d_name, NULL);
780 k = parent_add_child(enumerator, child);
785 parent_crawl_children(enumerator, child, maxdepth - 1);
787 log_debug("device-enumerate: max depth reached, %s: ignoring devices", child);
793 static int enumerator_scan_devices_children(sd_device_enumerator *enumerator) {
797 r = sd_device_get_syspath(enumerator->match_parent, &path);
801 k = parent_add_child(enumerator, path);
805 k = parent_crawl_children(enumerator, path, DEVICE_ENUMERATE_MAX_DEPTH);
812 static int enumerator_scan_devices_all(sd_device_enumerator *enumerator) {
815 log_debug("device-enumerator: scan all dirs");
817 if (access("/sys/subsystem", F_OK) >= 0) {
818 /* we have /subsystem/, forget all the old stuff */
819 r = enumerator_scan_dir(enumerator, "subsystem", "devices", NULL);
821 log_debug("device-enumerator: failed to scan /sys/subsystem: %s", strerror(-r));
827 k = enumerator_scan_dir(enumerator, "bus", "devices", NULL);
829 log_debug_errno(k, "device-enumerator: failed to scan /sys/bus: %m");
833 k = enumerator_scan_dir(enumerator, "class", NULL, NULL);
835 log_debug_errno(k, "device-enumerator: failed to scan /sys/class: %m");
843 int device_enumerator_scan_devices(sd_device_enumerator *enumerator) {
849 if (enumerator->scan_uptodate &&
850 enumerator->type == DEVICE_ENUMERATION_TYPE_DEVICES)
853 while ((device = prioq_pop(enumerator->devices)))
854 sd_device_unref(device);
856 if (!set_isempty(enumerator->match_tag)) {
857 r = enumerator_scan_devices_tags(enumerator);
860 } else if (enumerator->match_parent) {
861 r = enumerator_scan_devices_children(enumerator);
865 r = enumerator_scan_devices_all(enumerator);
870 enumerator->scan_uptodate = true;
875 _public_ sd_device *sd_device_enumerator_get_device_first(sd_device_enumerator *enumerator) {
878 assert_return(enumerator, NULL);
880 r = device_enumerator_scan_devices(enumerator);
884 enumerator->type = DEVICE_ENUMERATION_TYPE_DEVICES;
886 return prioq_peek(enumerator->devices);
889 _public_ sd_device *sd_device_enumerator_get_device_next(sd_device_enumerator *enumerator) {
890 assert_return(enumerator, NULL);
892 if (!enumerator->scan_uptodate ||
893 enumerator->type != DEVICE_ENUMERATION_TYPE_DEVICES)
896 sd_device_unref(prioq_pop(enumerator->devices));
898 return prioq_peek(enumerator->devices);
901 int device_enumerator_scan_subsystems(sd_device_enumerator *enumerator) {
903 const char *subsysdir;
908 if (enumerator->scan_uptodate &&
909 enumerator->type == DEVICE_ENUMERATION_TYPE_SUBSYSTEMS)
912 while ((device = prioq_pop(enumerator->devices)))
913 sd_device_unref(device);
916 if (match_subsystem(enumerator, "module")) {
917 k = enumerator_scan_dir_and_add_devices(enumerator, "module", NULL, NULL);
919 log_debug_errno(k, "device-enumerator: failed to scan modules: %m");
924 if (access("/sys/subsystem", F_OK) >= 0)
925 subsysdir = "subsystem";
929 /* subsystems (only buses support coldplug) */
930 if (match_subsystem(enumerator, "subsystem")) {
931 k = enumerator_scan_dir_and_add_devices(enumerator, subsysdir, NULL, NULL);
933 log_debug_errno(k, "device-enumerator: failed to scan subsystems: %m");
938 /* subsystem drivers */
939 if (match_subsystem(enumerator, "drivers")) {
940 k = enumerator_scan_dir(enumerator, subsysdir, "drivers", "drivers");
942 log_debug_errno(k, "device-enumerator: failed to scan drivers: %m");
947 enumerator->scan_uptodate = true;
952 _public_ sd_device *sd_device_enumerator_get_subsystem_first(sd_device_enumerator *enumerator) {
955 assert_return(enumerator, NULL);
957 r = device_enumerator_scan_subsystems(enumerator);
961 enumerator->type = DEVICE_ENUMERATION_TYPE_SUBSYSTEMS;
963 return prioq_peek(enumerator->devices);
966 _public_ sd_device *sd_device_enumerator_get_subsystem_next(sd_device_enumerator *enumerator) {
967 assert_return(enumerator, NULL);
969 if (enumerator->scan_uptodate ||
970 enumerator->type != DEVICE_ENUMERATION_TYPE_SUBSYSTEMS)
973 sd_device_unref(prioq_pop(enumerator->devices));
975 return prioq_peek(enumerator->devices);
978 sd_device *device_enumerator_get_first(sd_device_enumerator *enumerator) {
979 assert_return(enumerator, NULL);
981 return prioq_peek(enumerator->devices);
984 sd_device *device_enumerator_get_next(sd_device_enumerator *enumerator) {
985 assert_return(enumerator, NULL);
987 sd_device_unref(prioq_pop(enumerator->devices));
989 return prioq_peek(enumerator->devices);