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_is_initialized;
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);
140 assert_return(_value, -EINVAL);
143 hashmap = &enumerator->match_sysattr;
145 hashmap = &enumerator->nomatch_sysattr;
147 r = hashmap_ensure_allocated(hashmap, NULL);
151 sysattr = strdup(_sysattr);
155 value = strdup(_value);
159 r = hashmap_put(*hashmap, sysattr, value);
166 enumerator->scan_uptodate = false;
171 _public_ int sd_device_enumerator_add_match_property(sd_device_enumerator *enumerator, const char *_property, const char *_value) {
172 _cleanup_free_ char *property = NULL, *value = NULL;
175 assert_return(enumerator, -EINVAL);
176 assert_return(_property, -EINVAL);
177 assert_return(_value, -EINVAL);
179 r = hashmap_ensure_allocated(&enumerator->match_property, NULL);
183 property = strdup(_property);
187 value = strdup(_value);
191 r = hashmap_put(enumerator->match_property, property, value);
198 enumerator->scan_uptodate = false;
203 _public_ int sd_device_enumerator_add_match_sysname(sd_device_enumerator *enumerator, const char *sysname) {
206 assert_return(enumerator, -EINVAL);
207 assert_return(sysname, -EINVAL);
209 r = set_ensure_allocated(&enumerator->match_sysname, NULL);
213 r = set_put_strdup(enumerator->match_sysname, sysname);
217 enumerator->scan_uptodate = false;
222 _public_ int sd_device_enumerator_add_match_tag(sd_device_enumerator *enumerator, const char *tag) {
225 assert_return(enumerator, -EINVAL);
226 assert_return(tag, -EINVAL);
228 r = set_ensure_allocated(&enumerator->match_tag, NULL);
232 r = set_put_strdup(enumerator->match_tag, tag);
236 enumerator->scan_uptodate = false;
241 _public_ int sd_device_enumerator_add_match_parent(sd_device_enumerator *enumerator, sd_device *parent) {
242 assert_return(enumerator, -EINVAL);
243 assert_return(parent, -EINVAL);
245 sd_device_unref(enumerator->match_parent);
246 enumerator->match_parent = sd_device_ref(parent);
248 enumerator->scan_uptodate = false;
253 _public_ int sd_device_enumerator_add_match_is_initialized(sd_device_enumerator *enumerator) {
254 assert_return(enumerator, -EINVAL);
256 enumerator->match_is_initialized = true;
258 enumerator->scan_uptodate = false;
263 static int device_compare(const void *_a, const void *_b) {
264 sd_device *a = (sd_device *)_a, *b = (sd_device *)_b;
265 const char *devpath_a, *devpath_b, *sound_a;
266 bool delay_a = false, delay_b = false;
268 assert_se(sd_device_get_devpath(a, &devpath_a) >= 0);
269 assert_se(sd_device_get_devpath(b, &devpath_b) >= 0);
271 sound_a = strstr(devpath_a, "/sound/card");
273 /* For sound cards the control device must be enumerated last to
274 * make sure it's the final device node that gets ACLs applied.
275 * Applications rely on this fact and use ACL changes on the
276 * control node as an indicator that the ACL change of the
277 * entire sound card completed. The kernel makes this guarantee
278 * when creating those devices, and hence we should too when
279 * enumerating them. */
280 sound_a += strlen("/sound/card");
281 sound_a = strchr(sound_a, '/');
286 prefix_len = sound_a - devpath_a;
288 if (strncmp(devpath_a, devpath_b, prefix_len) == 0) {
291 sound_b = devpath_b + prefix_len;
293 if (startswith(sound_a, "/controlC") &&
294 !startswith(sound_b, "/contolC"))
297 if (!startswith(sound_a, "/controlC") &&
298 startswith(sound_b, "/controlC"))
304 /* md and dm devices are enumerated after all other devices */
305 if (strstr(devpath_a, "/block/md") || strstr(devpath_a, "/block/dm-"))
308 if (strstr(devpath_b, "/block/md") || strstr(devpath_b, "/block/dm-"))
311 if (delay_a && !delay_b)
314 if (!delay_a && delay_b)
317 return strcmp(devpath_a, devpath_b);
320 int device_enumerator_add_device(sd_device_enumerator *enumerator, sd_device *device) {
323 assert_return(enumerator, -EINVAL);
324 assert_return(device, -EINVAL);
326 r = prioq_ensure_allocated(&enumerator->devices, device_compare);
330 r = prioq_put(enumerator->devices, device, NULL);
334 sd_device_ref(device);
339 static bool match_sysattr_value(sd_device *device, const char *sysattr, const char *match_value) {
346 r = sd_device_get_sysattr_value(device, sysattr, &value);
353 if (fnmatch(match_value, value, 0) == 0)
359 static bool match_sysattr(sd_device_enumerator *enumerator, sd_device *device) {
367 HASHMAP_FOREACH_KEY(sysattr, value, enumerator->nomatch_sysattr, i)
368 if (match_sysattr_value(device, sysattr, value))
371 HASHMAP_FOREACH_KEY(sysattr, value, enumerator->match_sysattr, i)
372 if (!match_sysattr_value(device, sysattr, value))
378 static bool match_property(sd_device_enumerator *enumerator, sd_device *device) {
379 const char *property;
386 if (hashmap_isempty(enumerator->match_property))
389 HASHMAP_FOREACH_KEY(property, value, enumerator->match_property, i) {
390 const char *property_dev, *value_dev;
392 FOREACH_DEVICE_PROPERTY(device, property_dev, value_dev) {
393 if (fnmatch(property, property_dev, 0) != 0)
396 if (!value && !value_dev)
399 if (!value || !value_dev)
402 if (fnmatch(value, value_dev, 0) == 0)
410 static bool match_tag(sd_device_enumerator *enumerator, sd_device *device) {
417 SET_FOREACH(tag, enumerator->match_tag, i)
418 if (!sd_device_has_tag(device, tag))
424 static bool match_parent(sd_device_enumerator *enumerator, sd_device *device) {
425 const char *devpath, *devpath_dev;
431 if (!enumerator->match_parent)
434 r = sd_device_get_devpath(enumerator->match_parent, &devpath);
437 r = sd_device_get_devpath(device, &devpath_dev);
440 return startswith(devpath_dev, devpath);
443 static bool match_sysname(sd_device_enumerator *enumerator, const char *sysname) {
444 const char *sysname_match;
450 if (set_isempty(enumerator->match_sysname))
453 SET_FOREACH(sysname_match, enumerator->match_sysname, i)
454 if (fnmatch(sysname_match, sysname, 0) == 0)
460 static int enumerator_scan_dir_and_add_devices(sd_device_enumerator *enumerator, const char *basedir, const char *subdir1, const char *subdir2) {
461 _cleanup_closedir_ DIR *dir = NULL;
469 path = strjoina("/sys/", basedir, "/");
472 path = strjoina(path, subdir1, "/");
475 path = strjoina(path, subdir2, "/");
481 FOREACH_DIRENT_ALL(dent, dir, return -errno) {
482 _cleanup_device_unref_ sd_device *device = NULL;
483 char syspath[strlen(path) + 1 + strlen(dent->d_name) + 1];
485 int ifindex, initialized, k;
487 if (dent->d_name[0] == '.')
490 if (!match_sysname(enumerator, dent->d_name))
493 (void)sprintf(syspath, "%s%s", path, dent->d_name);
495 k = sd_device_new_from_syspath(&device, syspath);
497 log_debug_errno(k, "device-enumerator: failed to create device from syspath %s: %m", syspath);
502 k = sd_device_get_devnum(device, &devnum);
508 k = sd_device_get_ifindex(device, &ifindex);
514 k = sd_device_get_is_initialized(device, &initialized);
521 * All devices with a device node or network interfaces
522 * possibly need udev to adjust the device node permission
523 * or context, or rename the interface before it can be
524 * reliably used from other processes.
526 * For now, we can only check these types of devices, we
527 * might not store a database, and have no way to find out
528 * for all other types of devices.
530 if (enumerator->match_is_initialized &&
532 (major(devnum) > 0 || ifindex > 0))
535 if (!match_parent(enumerator, device))
538 if (!match_tag(enumerator, device))
541 if (!match_property(enumerator, device))
544 if (!match_sysattr(enumerator, device))
547 k = device_enumerator_add_device(enumerator, device);
555 static bool match_subsystem(sd_device_enumerator *enumerator, const char *subsystem) {
556 const char *subsystem_match;
564 SET_FOREACH(subsystem_match, enumerator->nomatch_subsystem, i)
565 if (fnmatch(subsystem_match, subsystem, 0) == 0)
568 if (set_isempty(enumerator->match_subsystem))
571 SET_FOREACH(subsystem_match, enumerator->match_subsystem, i)
572 if (fnmatch(subsystem_match, subsystem, 0) == 0)
578 static int enumerator_scan_dir(sd_device_enumerator *enumerator, const char *basedir, const char *subdir, const char *subsystem) {
579 _cleanup_closedir_ DIR *dir = NULL;
584 path = strjoina("/sys/", basedir);
590 log_debug(" device-enumerator: scanning %s", path);
592 FOREACH_DIRENT_ALL(dent, dir, return -errno) {
595 if (dent->d_name[0] == '.')
598 if (!match_subsystem(enumerator, subsystem ? : dent->d_name))
601 k = enumerator_scan_dir_and_add_devices(enumerator, basedir, dent->d_name, subdir);
609 static int enumerator_scan_devices_tag(sd_device_enumerator *enumerator, const char *tag) {
610 _cleanup_closedir_ DIR *dir = NULL;
618 path = strjoina("/run/udev/tags/", tag);
625 log_error("sd-device-enumerator: could not open tags directory %s: %m", path);
630 /* TODO: filter away subsystems? */
632 FOREACH_DIRENT_ALL(dent, dir, return -errno) {
633 _cleanup_device_unref_ sd_device *device = NULL;
634 const char *subsystem, *sysname;
637 if (dent->d_name[0] == '.')
640 k = sd_device_new_from_device_id(&device, dent->d_name);
646 k = sd_device_get_subsystem(device, &subsystem);
652 if (!match_subsystem(enumerator, subsystem))
655 k = sd_device_get_sysname(device, &sysname);
661 if (!match_sysname(enumerator, sysname))
664 if (!match_parent(enumerator, device))
667 if (!match_property(enumerator, device))
670 if (!match_sysattr(enumerator, device))
673 k = device_enumerator_add_device(enumerator, device);
683 static int enumerator_scan_devices_tags(sd_device_enumerator *enumerator) {
690 SET_FOREACH(tag, enumerator->match_tag, i) {
691 r = enumerator_scan_devices_tag(enumerator, tag);
699 static int parent_add_child(sd_device_enumerator *enumerator, const char *path) {
700 _cleanup_device_unref_ sd_device *device = NULL;
701 const char *subsystem, *sysname;
704 r = sd_device_new_from_syspath(&device, path);
710 r = sd_device_get_subsystem(device, &subsystem);
714 if (!match_subsystem(enumerator, subsystem))
717 r = sd_device_get_sysname(device, &sysname);
721 if (!match_sysname(enumerator, sysname))
724 if (!match_property(enumerator, device))
727 if (!match_sysattr(enumerator, device))
730 r = device_enumerator_add_device(enumerator, device);
737 static int parent_crawl_children(sd_device_enumerator *enumerator, const char *path, unsigned maxdepth) {
738 _cleanup_closedir_ DIR *dir = NULL;
744 log_debug("sd-device-enumerate: could not open parent directory %s: %m", path);
748 FOREACH_DIRENT_ALL(dent, dir, return -errno) {
749 _cleanup_free_ char *child = NULL;
752 if (dent->d_name[0] == '.')
755 if (dent->d_type != DT_DIR)
758 k = asprintf(&child, "%s/%s", path, dent->d_name);
762 k = parent_add_child(enumerator, child);
767 parent_crawl_children(enumerator, child, maxdepth - 1);
769 log_debug("device-enumerate: max depth reached, %s: ignoring devices", child);
775 static int enumerator_scan_devices_children(sd_device_enumerator *enumerator) {
779 r = sd_device_get_syspath(enumerator->match_parent, &path);
783 k = parent_add_child(enumerator, path);
787 k = parent_crawl_children(enumerator, path, DEVICE_ENUMERATE_MAX_DEPTH);
794 static int enumerator_scan_devices_all(sd_device_enumerator *enumerator) {
797 log_debug("device-enumerator: scan all dirs");
799 if (access("/sys/subsystem", F_OK) >= 0) {
800 /* we have /subsystem/, forget all the old stuff */
801 r = enumerator_scan_dir(enumerator, "subsystem", "devices", NULL);
803 log_debug("device-enumerator: failed to scan /sys/subsystem: %s", strerror(-r));
809 k = enumerator_scan_dir(enumerator, "bus", "devices", NULL);
811 log_debug_errno(k, "device-enumerator: failed to scan /sys/bus: %m");
815 k = enumerator_scan_dir(enumerator, "class", NULL, NULL);
817 log_debug_errno(k, "device-enumerator: failed to scan /sys/class: %m");
825 int device_enumerator_scan_devices(sd_device_enumerator *enumerator) {
831 if (enumerator->scan_uptodate &&
832 enumerator->type == DEVICE_ENUMERATION_TYPE_DEVICES)
835 while ((device = prioq_pop(enumerator->devices)))
836 sd_device_unref(device);
838 if (!set_isempty(enumerator->match_tag)) {
839 r = enumerator_scan_devices_tags(enumerator);
842 } else if (enumerator->match_parent) {
843 r = enumerator_scan_devices_children(enumerator);
847 r = enumerator_scan_devices_all(enumerator);
852 enumerator->scan_uptodate = true;
857 _public_ sd_device *sd_device_enumerator_get_device_first(sd_device_enumerator *enumerator) {
860 assert_return(enumerator, NULL);
862 r = device_enumerator_scan_devices(enumerator);
866 enumerator->type = DEVICE_ENUMERATION_TYPE_DEVICES;
868 return prioq_peek(enumerator->devices);
871 _public_ sd_device *sd_device_enumerator_get_device_next(sd_device_enumerator *enumerator) {
872 assert_return(enumerator, NULL);
874 if (!enumerator->scan_uptodate ||
875 enumerator->type != DEVICE_ENUMERATION_TYPE_DEVICES)
878 sd_device_unref(prioq_pop(enumerator->devices));
880 return prioq_peek(enumerator->devices);
883 int device_enumerator_scan_subsystems(sd_device_enumerator *enumerator) {
885 const char *subsysdir;
890 if (enumerator->scan_uptodate &&
891 enumerator->type == DEVICE_ENUMERATION_TYPE_SUBSYSTEMS)
894 while ((device = prioq_pop(enumerator->devices)))
895 sd_device_unref(device);
898 if (match_subsystem(enumerator, "module")) {
899 k = enumerator_scan_dir_and_add_devices(enumerator, "module", NULL, NULL);
901 log_debug_errno(k, "device-enumerator: failed to scan modules: %m");
906 if (access("/sys/subsystem", F_OK) >= 0)
907 subsysdir = "subsystem";
911 /* subsystems (only buses support coldplug) */
912 if (match_subsystem(enumerator, "subsystem")) {
913 k = enumerator_scan_dir_and_add_devices(enumerator, subsysdir, NULL, NULL);
915 log_debug_errno(k, "device-enumerator: failed to scan subsystems: %m");
920 /* subsystem drivers */
921 if (match_subsystem(enumerator, "drivers")) {
922 k = enumerator_scan_dir(enumerator, subsysdir, "drivers", "drivers");
924 log_debug_errno(k, "device-enumerator: failed to scan drivers: %m");
929 enumerator->scan_uptodate = true;
934 _public_ sd_device *sd_device_enumerator_get_subsystem_first(sd_device_enumerator *enumerator) {
937 assert_return(enumerator, NULL);
939 r = device_enumerator_scan_subsystems(enumerator);
943 enumerator->type = DEVICE_ENUMERATION_TYPE_SUBSYSTEMS;
945 return prioq_peek(enumerator->devices);
948 _public_ sd_device *sd_device_enumerator_get_subsystem_next(sd_device_enumerator *enumerator) {
949 assert_return(enumerator, NULL);
951 if (enumerator->scan_uptodate ||
952 enumerator->type != DEVICE_ENUMERATION_TYPE_SUBSYSTEMS)
955 sd_device_unref(prioq_pop(enumerator->devices));
957 return prioq_peek(enumerator->devices);
960 sd_device *device_enumerator_get_first(sd_device_enumerator *enumerator) {
961 assert_return(enumerator, NULL);
963 return prioq_peek(enumerator->devices);
966 sd_device *device_enumerator_get_next(sd_device_enumerator *enumerator) {
967 assert_return(enumerator, NULL);
969 sd_device_unref(prioq_pop(enumerator->devices));
971 return prioq_peek(enumerator->devices);