chiark / gitweb /
sd-device: uniformly handle missing devices
[elogind.git] / src / libsystemd / sd-device / device-enumerator.c
1 /***
2   This file is part of systemd.
3
4   Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
5   Copyright 2014-2015 Tom Gundersen <teg@jklm.no>
6
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.
11
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.
16
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/>.
19 ***/
20
21 #include "util.h"
22 #include "prioq.h"
23 #include "strv.h"
24 #include "set.h"
25
26 #include "sd-device.h"
27
28 #include "device-util.h"
29 #include "device-enumerator-private.h"
30
31 #define DEVICE_ENUMERATE_MAX_DEPTH 256
32
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;
39
40 struct sd_device_enumerator {
41         unsigned n_ref;
42
43         DeviceEnumerationType type;
44         Prioq *devices;
45         bool scan_uptodate;
46
47         Set *match_subsystem;
48         Set *nomatch_subsystem;
49         Hashmap *match_sysattr;
50         Hashmap *nomatch_sysattr;
51         Hashmap *match_property;
52         Set *match_sysname;
53         Set *match_tag;
54         sd_device *match_parent;
55         bool match_allow_uninitialized;
56 };
57
58 _public_ int sd_device_enumerator_new(sd_device_enumerator **ret) {
59         _cleanup_device_enumerator_unref_ sd_device_enumerator *enumerator = NULL;
60
61         assert(ret);
62
63         enumerator = new0(sd_device_enumerator, 1);
64         if (!enumerator)
65                 return -ENOMEM;
66
67         enumerator->n_ref = 1;
68         enumerator->type = _DEVICE_ENUMERATION_TYPE_INVALID;
69
70         *ret = enumerator;
71         enumerator = NULL;
72
73         return 0;
74 }
75
76 _public_ sd_device_enumerator *sd_device_enumerator_ref(sd_device_enumerator *enumerator) {
77         assert_return(enumerator, NULL);
78
79         assert_se((++ enumerator->n_ref) >= 2);
80
81         return enumerator;
82 }
83
84 _public_ sd_device_enumerator *sd_device_enumerator_unref(sd_device_enumerator *enumerator) {
85         if (enumerator && (-- enumerator->n_ref) == 0) {
86                 sd_device *device;
87
88                 while ((device = prioq_pop(enumerator->devices)))
89                         sd_device_unref(device);
90
91                 prioq_free(enumerator->devices);
92
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);
101
102                 free(enumerator);
103         }
104
105         return NULL;
106 }
107
108 _public_ int sd_device_enumerator_add_match_subsystem(sd_device_enumerator *enumerator, const char *subsystem, int match) {
109         Set **set;
110         int r;
111
112         assert_return(enumerator, -EINVAL);
113         assert_return(subsystem, -EINVAL);
114
115         if (match)
116                 set = &enumerator->match_subsystem;
117         else
118                 set = &enumerator->nomatch_subsystem;
119
120         r = set_ensure_allocated(set, NULL);
121         if (r < 0)
122                 return r;
123
124         r = set_put_strdup(*set, subsystem);
125         if (r < 0)
126                 return r;
127
128         enumerator->scan_uptodate = false;
129
130         return 0;
131 }
132
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;
135         Hashmap **hashmap;
136         int r;
137
138         assert_return(enumerator, -EINVAL);
139         assert_return(_sysattr, -EINVAL);
140         assert_return(_value, -EINVAL);
141
142         if (match)
143                 hashmap = &enumerator->match_sysattr;
144         else
145                 hashmap = &enumerator->nomatch_sysattr;
146
147         r = hashmap_ensure_allocated(hashmap, NULL);
148         if (r < 0)
149                 return r;
150
151         sysattr = strdup(_sysattr);
152         if (!sysattr)
153                 return -ENOMEM;
154
155         value = strdup(_value);
156         if (!value)
157                 return -ENOMEM;
158
159         r = hashmap_put(*hashmap, sysattr, value);
160         if (r < 0)
161                 return r;
162
163         sysattr = NULL;
164         value = NULL;
165
166         enumerator->scan_uptodate = false;
167
168         return 0;
169 }
170
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;
173         int r;
174
175         assert_return(enumerator, -EINVAL);
176         assert_return(_property, -EINVAL);
177         assert_return(_value, -EINVAL);
178
179         r = hashmap_ensure_allocated(&enumerator->match_property, NULL);
180         if (r < 0)
181                 return r;
182
183         property = strdup(_property);
184         if (!property)
185                 return -ENOMEM;
186
187         value = strdup(_value);
188         if (!value)
189                 return -ENOMEM;
190
191         r = hashmap_put(enumerator->match_property, property, value);
192         if (r < 0)
193                 return r;
194
195         property = NULL;
196         value = NULL;
197
198         enumerator->scan_uptodate = false;
199
200         return 0;
201 }
202
203 _public_ int sd_device_enumerator_add_match_sysname(sd_device_enumerator *enumerator, const char *sysname) {
204         int r;
205
206         assert_return(enumerator, -EINVAL);
207         assert_return(sysname, -EINVAL);
208
209         r = set_ensure_allocated(&enumerator->match_sysname, NULL);
210         if (r < 0)
211                 return r;
212
213         r = set_put_strdup(enumerator->match_sysname, sysname);
214         if (r < 0)
215                 return r;
216
217         enumerator->scan_uptodate = false;
218
219         return 0;
220 }
221
222 _public_ int sd_device_enumerator_add_match_tag(sd_device_enumerator *enumerator, const char *tag) {
223         int r;
224
225         assert_return(enumerator, -EINVAL);
226         assert_return(tag, -EINVAL);
227
228         r = set_ensure_allocated(&enumerator->match_tag, NULL);
229         if (r < 0)
230                 return r;
231
232         r = set_put_strdup(enumerator->match_tag, tag);
233         if (r < 0)
234                 return r;
235
236         enumerator->scan_uptodate = false;
237
238         return 0;
239 }
240
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);
244
245         sd_device_unref(enumerator->match_parent);
246         enumerator->match_parent = sd_device_ref(parent);
247
248         enumerator->scan_uptodate = false;
249
250         return 0;
251 }
252
253 _public_ int sd_device_enumerator_allow_uninitialized(sd_device_enumerator *enumerator) {
254         assert_return(enumerator, -EINVAL);
255
256         enumerator->match_allow_uninitialized = true;
257
258         enumerator->scan_uptodate = false;
259
260         return 0;
261 }
262
263 int device_enumerator_add_match_is_initialized(sd_device_enumerator *enumerator) {
264         assert_return(enumerator, -EINVAL);
265
266         enumerator->match_allow_uninitialized = false;
267
268         enumerator->scan_uptodate = false;
269
270         return 0;
271 }
272
273 static int device_compare(const void *_a, const void *_b) {
274         sd_device *a = (sd_device *)_a, *b = (sd_device *)_b;
275         const char *devpath_a, *devpath_b, *sound_a;
276         bool delay_a = false, delay_b = false;
277
278         assert_se(sd_device_get_devpath(a, &devpath_a) >= 0);
279         assert_se(sd_device_get_devpath(b, &devpath_b) >= 0);
280
281         sound_a = strstr(devpath_a, "/sound/card");
282         if (sound_a) {
283                 /* For sound cards the control device must be enumerated last to
284                  * make sure it's the final device node that gets ACLs applied.
285                  * Applications rely on this fact and use ACL changes on the
286                  * control node as an indicator that the ACL change of the
287                  * entire sound card completed. The kernel makes this guarantee
288                  * when creating those devices, and hence we should too when
289                  * enumerating them. */
290                 sound_a += strlen("/sound/card");
291                 sound_a = strchr(sound_a, '/');
292
293                 if (sound_a) {
294                         unsigned prefix_len;
295
296                         prefix_len = sound_a - devpath_a;
297
298                         if (strncmp(devpath_a, devpath_b, prefix_len) == 0) {
299                                 const char *sound_b;
300
301                                 sound_b = devpath_b + prefix_len;
302
303                                 if (startswith(sound_a, "/controlC") &&
304                                     !startswith(sound_b, "/contolC"))
305                                         return 1;
306
307                                 if (!startswith(sound_a, "/controlC") &&
308                                     startswith(sound_b, "/controlC"))
309                                         return -1;
310                         }
311                 }
312         }
313
314         /* md and dm devices are enumerated after all other devices */
315         if (strstr(devpath_a, "/block/md") || strstr(devpath_a, "/block/dm-"))
316                 delay_a = true;
317
318         if (strstr(devpath_b, "/block/md") || strstr(devpath_b, "/block/dm-"))
319                 delay_b = true;
320
321         if (delay_a && !delay_b)
322                 return 1;
323
324         if (!delay_a && delay_b)
325                 return -1;
326
327         return strcmp(devpath_a, devpath_b);
328 }
329
330 int device_enumerator_add_device(sd_device_enumerator *enumerator, sd_device *device) {
331         int r;
332
333         assert_return(enumerator, -EINVAL);
334         assert_return(device, -EINVAL);
335
336         r = prioq_ensure_allocated(&enumerator->devices, device_compare);
337         if (r < 0)
338                 return r;
339
340         r = prioq_put(enumerator->devices, device, NULL);
341         if (r < 0)
342                 return r;
343
344         sd_device_ref(device);
345
346         return 0;
347 }
348
349 static bool match_sysattr_value(sd_device *device, const char *sysattr, const char *match_value) {
350         const char *value;
351         int r;
352
353         assert(device);
354         assert(sysattr);
355
356         r = sd_device_get_sysattr_value(device, sysattr, &value);
357         if (r < 0)
358                 return false;
359
360         if (!match_value)
361                 return true;
362
363         if (fnmatch(match_value, value, 0) == 0)
364                 return true;
365
366         return false;
367 }
368
369 static bool match_sysattr(sd_device_enumerator *enumerator, sd_device *device) {
370         const char *sysattr;
371         const char *value;
372         Iterator i;
373
374         assert(enumerator);
375         assert(device);
376
377         HASHMAP_FOREACH_KEY(sysattr, value, enumerator->nomatch_sysattr, i)
378                 if (match_sysattr_value(device, sysattr, value))
379                         return false;
380
381         HASHMAP_FOREACH_KEY(sysattr, value, enumerator->match_sysattr, i)
382                 if (!match_sysattr_value(device, sysattr, value))
383                         return false;
384
385         return true;
386 }
387
388 static bool match_property(sd_device_enumerator *enumerator, sd_device *device) {
389         const char *property;
390         const char *value;
391         Iterator i;
392
393         assert(enumerator);
394         assert(device);
395
396         if (hashmap_isempty(enumerator->match_property))
397                 return true;
398
399         HASHMAP_FOREACH_KEY(property, value, enumerator->match_property, i) {
400                 const char *property_dev, *value_dev;
401
402                 FOREACH_DEVICE_PROPERTY(device, property_dev, value_dev) {
403                         if (fnmatch(property, property_dev, 0) != 0)
404                                 continue;
405
406                         if (!value && !value_dev)
407                                 return true;
408
409                         if (!value || !value_dev)
410                                 continue;
411
412                         if (fnmatch(value, value_dev, 0) == 0)
413                                 return true;
414                 }
415         }
416
417         return false;
418 }
419
420 static bool match_tag(sd_device_enumerator *enumerator, sd_device *device) {
421         const char *tag;
422         Iterator i;
423
424         assert(enumerator);
425         assert(device);
426
427         SET_FOREACH(tag, enumerator->match_tag, i)
428                 if (!sd_device_has_tag(device, tag))
429                         return false;
430
431         return true;
432 }
433
434 static bool match_parent(sd_device_enumerator *enumerator, sd_device *device) {
435         const char *devpath, *devpath_dev;
436         int r;
437
438         assert(enumerator);
439         assert(device);
440
441         if (!enumerator->match_parent)
442                 return true;
443
444         r = sd_device_get_devpath(enumerator->match_parent, &devpath);
445         assert(r >= 0);
446
447         r = sd_device_get_devpath(device, &devpath_dev);
448         assert(r >= 0);
449
450         return startswith(devpath_dev, devpath);
451 }
452
453 static bool match_sysname(sd_device_enumerator *enumerator, const char *sysname) {
454         const char *sysname_match;
455         Iterator i;
456
457         assert(enumerator);
458         assert(sysname);
459
460         if (set_isempty(enumerator->match_sysname))
461                 return true;
462
463         SET_FOREACH(sysname_match, enumerator->match_sysname, i)
464                 if (fnmatch(sysname_match, sysname, 0) == 0)
465                         return true;
466
467         return false;
468 }
469
470 static int enumerator_scan_dir_and_add_devices(sd_device_enumerator *enumerator, const char *basedir, const char *subdir1, const char *subdir2) {
471         _cleanup_closedir_ DIR *dir = NULL;
472         char *path;
473         struct dirent *dent;
474         int r = 0;
475
476         assert(enumerator);
477         assert(basedir);
478
479         path = strjoina("/sys/", basedir, "/");
480
481         if (subdir1)
482                 path = strjoina(path, subdir1, "/");
483
484         if (subdir2)
485                 path = strjoina(path, subdir2, "/");
486
487         dir = opendir(path);
488         if (!dir)
489                 return -errno;
490
491         FOREACH_DIRENT_ALL(dent, dir, return -errno) {
492                 _cleanup_device_unref_ sd_device *device = NULL;
493                 char syspath[strlen(path) + 1 + strlen(dent->d_name) + 1];
494                 dev_t devnum;
495                 int ifindex, initialized, k;
496
497                 if (dent->d_name[0] == '.')
498                         continue;
499
500                 if (!match_sysname(enumerator, dent->d_name))
501                         continue;
502
503                 (void)sprintf(syspath, "%s%s", path, dent->d_name);
504
505                 k = sd_device_new_from_syspath(&device, syspath);
506                 if (k < 0) {
507                         if (k != -ENODEV)
508                                 /* this is necessarily racey, so ignore missing devices */
509                                 r = k;
510
511                         continue;
512                 }
513
514                 k = sd_device_get_devnum(device, &devnum);
515                 if (k < 0) {
516                         r = k;
517                         continue;
518                 }
519
520                 k = sd_device_get_ifindex(device, &ifindex);
521                 if (k < 0) {
522                         r = k;
523                         continue;
524                 }
525
526                 k = sd_device_get_is_initialized(device, &initialized);
527                 if (k < 0) {
528                         r = k;
529                         continue;
530                 }
531
532                 /*
533                  * All devices with a device node or network interfaces
534                  * possibly need udev to adjust the device node permission
535                  * or context, or rename the interface before it can be
536                  * reliably used from other processes.
537                  *
538                  * For now, we can only check these types of devices, we
539                  * might not store a database, and have no way to find out
540                  * for all other types of devices.
541                  */
542                 if (!enumerator->match_allow_uninitialized &&
543                     !initialized &&
544                     (major(devnum) > 0 || ifindex > 0))
545                         continue;
546
547                 if (!match_parent(enumerator, device))
548                         continue;
549
550                 if (!match_tag(enumerator, device))
551                         continue;
552
553                 if (!match_property(enumerator, device))
554                         continue;
555
556                 if (!match_sysattr(enumerator, device))
557                         continue;
558
559                 k = device_enumerator_add_device(enumerator, device);
560                 if (k < 0)
561                         r = k;
562         }
563
564         return r;
565 }
566
567 static bool match_subsystem(sd_device_enumerator *enumerator, const char *subsystem) {
568         const char *subsystem_match;
569         Iterator i;
570
571         assert(enumerator);
572
573         if (!subsystem)
574                 return false;
575
576         SET_FOREACH(subsystem_match, enumerator->nomatch_subsystem, i)
577                 if (fnmatch(subsystem_match, subsystem, 0) == 0)
578                         return false;
579
580         if (set_isempty(enumerator->match_subsystem))
581                 return true;
582
583         SET_FOREACH(subsystem_match, enumerator->match_subsystem, i)
584                 if (fnmatch(subsystem_match, subsystem, 0) == 0)
585                         return true;
586
587         return false;
588 }
589
590 static int enumerator_scan_dir(sd_device_enumerator *enumerator, const char *basedir, const char *subdir, const char *subsystem) {
591         _cleanup_closedir_ DIR *dir = NULL;
592         char *path;
593         struct dirent *dent;
594         int r = 0;
595
596         path = strjoina("/sys/", basedir);
597
598         dir = opendir(path);
599         if (!dir)
600                 return -errno;
601
602         log_debug("  device-enumerator: scanning %s", path);
603
604         FOREACH_DIRENT_ALL(dent, dir, return -errno) {
605                 int k;
606
607                 if (dent->d_name[0] == '.')
608                         continue;
609
610                 if (!match_subsystem(enumerator, subsystem ? : dent->d_name))
611                         continue;
612
613                 k = enumerator_scan_dir_and_add_devices(enumerator, basedir, dent->d_name, subdir);
614                 if (k < 0)
615                         r = k;
616         }
617
618         return r;
619 }
620
621 static int enumerator_scan_devices_tag(sd_device_enumerator *enumerator, const char *tag) {
622         _cleanup_closedir_ DIR *dir = NULL;
623         char *path;
624         struct dirent *dent;
625         int r = 0;
626
627         assert(enumerator);
628         assert(tag);
629
630         path = strjoina("/run/udev/tags/", tag);
631
632         dir = opendir(path);
633         if (!dir) {
634                 if (errno == ENOENT)
635                         return 0;
636                 else {
637                         log_error("sd-device-enumerator: could not open tags directory %s: %m", path);
638                         return -errno;
639                 }
640         }
641
642         /* TODO: filter away subsystems? */
643
644         FOREACH_DIRENT_ALL(dent, dir, return -errno) {
645                 _cleanup_device_unref_ sd_device *device = NULL;
646                 const char *subsystem, *sysname;
647                 int k;
648
649                 if (dent->d_name[0] == '.')
650                         continue;
651
652                 k = sd_device_new_from_device_id(&device, dent->d_name);
653                 if (k < 0) {
654                         if (k != -ENODEV)
655                                 /* this is necessarily racy, so ignore missing devices */
656                                 r = k;
657
658                         continue;
659                 }
660
661                 k = sd_device_get_subsystem(device, &subsystem);
662                 if (k < 0) {
663                         r = k;
664                         continue;
665                 }
666
667                 if (!match_subsystem(enumerator, subsystem))
668                         continue;
669
670                 k = sd_device_get_sysname(device, &sysname);
671                 if (k < 0) {
672                         r = k;
673                         continue;
674                 }
675
676                 if (!match_sysname(enumerator, sysname))
677                         continue;
678
679                 if (!match_parent(enumerator, device))
680                         continue;
681
682                 if (!match_property(enumerator, device))
683                         continue;
684
685                 if (!match_sysattr(enumerator, device))
686                         continue;
687
688                 k = device_enumerator_add_device(enumerator, device);
689                 if (k < 0) {
690                         r = k;
691                         continue;
692                 }
693         }
694
695         return r;
696 }
697
698 static int enumerator_scan_devices_tags(sd_device_enumerator *enumerator) {
699         const char *tag;
700         Iterator i;
701         int r;
702
703         assert(enumerator);
704
705         SET_FOREACH(tag, enumerator->match_tag, i) {
706                 r = enumerator_scan_devices_tag(enumerator, tag);
707                 if (r < 0)
708                         return r;
709         }
710
711         return 0;
712 }
713
714 static int parent_add_child(sd_device_enumerator *enumerator, const char *path) {
715         _cleanup_device_unref_ sd_device *device = NULL;
716         const char *subsystem, *sysname;
717         int r;
718
719         r = sd_device_new_from_syspath(&device, path);
720         if (r == -ENODEV)
721                 /* this is necessarily racy, so ignore missing devices */
722                 return 0;
723         else if (r < 0)
724                 return r;
725
726         r = sd_device_get_subsystem(device, &subsystem);
727         if (r < 0)
728                 return r;
729
730         if (!match_subsystem(enumerator, subsystem))
731                 return 0;
732
733         r = sd_device_get_sysname(device, &sysname);
734         if (r < 0)
735                 return r;
736
737         if (!match_sysname(enumerator, sysname))
738                 return 0;
739
740         if (!match_property(enumerator, device))
741                 return 0;
742
743         if (!match_sysattr(enumerator, device))
744                 return 0;
745
746         r = device_enumerator_add_device(enumerator, device);
747         if (r < 0)
748                 return r;
749
750         return 1;
751 }
752
753 static int parent_crawl_children(sd_device_enumerator *enumerator, const char *path, unsigned maxdepth) {
754         _cleanup_closedir_ DIR *dir = NULL;
755         struct dirent *dent;
756         int r = 0;
757
758         dir = opendir(path);
759         if (!dir) {
760                 log_debug("sd-device-enumerate: could not open parent directory %s: %m", path);
761                 return -errno;
762         }
763
764         FOREACH_DIRENT_ALL(dent, dir, return -errno) {
765                 _cleanup_free_ char *child = NULL;
766                 int k;
767
768                 if (dent->d_name[0] == '.')
769                         continue;
770
771                 if (dent->d_type != DT_DIR)
772                         continue;
773
774                 k = asprintf(&child, "%s/%s", path, dent->d_name);
775                 if (k < 0)
776                         return -errno;
777
778                 k = parent_add_child(enumerator, child);
779                 if (k < 0)
780                         r = k;
781
782                 if (maxdepth > 0)
783                         parent_crawl_children(enumerator, child, maxdepth - 1);
784                 else
785                         log_debug("device-enumerate: max depth reached, %s: ignoring devices", child);
786         }
787
788         return r;
789 }
790
791 static int enumerator_scan_devices_children(sd_device_enumerator *enumerator) {
792         const char *path;
793         int r = 0, k;
794
795         r = sd_device_get_syspath(enumerator->match_parent, &path);
796         if (r < 0)
797                 return r;
798
799         k = parent_add_child(enumerator, path);
800         if (k < 0)
801                 r = k;
802
803         k = parent_crawl_children(enumerator, path, DEVICE_ENUMERATE_MAX_DEPTH);
804         if (k < 0)
805                 r = k;
806
807         return r;
808 }
809
810 static int enumerator_scan_devices_all(sd_device_enumerator *enumerator) {
811         int r = 0;
812
813         log_debug("device-enumerator: scan all dirs");
814
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);
818                 if (r < 0) {
819                         log_debug("device-enumerator: failed to scan /sys/subsystem: %s", strerror(-r));
820                         return r;
821                 }
822         } else {
823                 int k;
824
825                 k = enumerator_scan_dir(enumerator, "bus", "devices", NULL);
826                 if (k < 0) {
827                         log_debug_errno(k, "device-enumerator: failed to scan /sys/bus: %m");
828                         r = k;
829                 }
830
831                 k = enumerator_scan_dir(enumerator, "class", NULL, NULL);
832                 if (k < 0) {
833                         log_debug_errno(k, "device-enumerator: failed to scan /sys/class: %m");
834                         r = k;
835                 }
836         }
837
838         return r;
839 }
840
841 int device_enumerator_scan_devices(sd_device_enumerator *enumerator) {
842         sd_device *device;
843         int r;
844
845         assert(enumerator);
846
847         if (enumerator->scan_uptodate &&
848             enumerator->type == DEVICE_ENUMERATION_TYPE_DEVICES)
849                 return 0;
850
851         while ((device = prioq_pop(enumerator->devices)))
852                 sd_device_unref(device);
853
854         if (!set_isempty(enumerator->match_tag)) {
855                 r = enumerator_scan_devices_tags(enumerator);
856                 if (r < 0)
857                         return r;
858         } else if (enumerator->match_parent) {
859                 r = enumerator_scan_devices_children(enumerator);
860                 if (r < 0)
861                         return r;
862         } else {
863                 r = enumerator_scan_devices_all(enumerator);
864                 if (r < 0)
865                         return r;
866         }
867
868         enumerator->scan_uptodate = true;
869
870         return 0;
871 }
872
873 _public_ sd_device *sd_device_enumerator_get_device_first(sd_device_enumerator *enumerator) {
874         int r;
875
876         assert_return(enumerator, NULL);
877
878         r = device_enumerator_scan_devices(enumerator);
879         if (r < 0)
880                 return NULL;
881
882         enumerator->type = DEVICE_ENUMERATION_TYPE_DEVICES;
883
884         return prioq_peek(enumerator->devices);
885 }
886
887 _public_ sd_device *sd_device_enumerator_get_device_next(sd_device_enumerator *enumerator) {
888         assert_return(enumerator, NULL);
889
890         if (!enumerator->scan_uptodate ||
891             enumerator->type != DEVICE_ENUMERATION_TYPE_DEVICES)
892                 return NULL;
893
894         sd_device_unref(prioq_pop(enumerator->devices));
895
896         return prioq_peek(enumerator->devices);
897 }
898
899 int device_enumerator_scan_subsystems(sd_device_enumerator *enumerator) {
900         sd_device *device;
901         const char *subsysdir;
902         int r = 0, k;
903
904         assert(enumerator);
905
906         if (enumerator->scan_uptodate &&
907             enumerator->type == DEVICE_ENUMERATION_TYPE_SUBSYSTEMS)
908                 return 0;
909
910         while ((device = prioq_pop(enumerator->devices)))
911                 sd_device_unref(device);
912
913         /* modules */
914         if (match_subsystem(enumerator, "module")) {
915                 k = enumerator_scan_dir_and_add_devices(enumerator, "module", NULL, NULL);
916                 if (k < 0) {
917                         log_debug_errno(k, "device-enumerator: failed to scan modules: %m");
918                         r = k;
919                 }
920         }
921
922         if (access("/sys/subsystem", F_OK) >= 0)
923                 subsysdir = "subsystem";
924         else
925                 subsysdir = "bus";
926
927         /* subsystems (only buses support coldplug) */
928         if (match_subsystem(enumerator, "subsystem")) {
929                 k = enumerator_scan_dir_and_add_devices(enumerator, subsysdir, NULL, NULL);
930                 if (k < 0) {
931                         log_debug_errno(k, "device-enumerator: failed to scan subsystems: %m");
932                         r = k;
933                 }
934         }
935
936         /* subsystem drivers */
937         if (match_subsystem(enumerator, "drivers")) {
938                 k = enumerator_scan_dir(enumerator, subsysdir, "drivers", "drivers");
939                 if (k < 0) {
940                         log_debug_errno(k, "device-enumerator: failed to scan drivers: %m");
941                         r = k;
942                 }
943         }
944
945         enumerator->scan_uptodate = true;
946
947         return r;
948 }
949
950 _public_ sd_device *sd_device_enumerator_get_subsystem_first(sd_device_enumerator *enumerator) {
951         int r;
952
953         assert_return(enumerator, NULL);
954
955         r = device_enumerator_scan_subsystems(enumerator);
956         if (r < 0)
957                 return NULL;
958
959         enumerator->type = DEVICE_ENUMERATION_TYPE_SUBSYSTEMS;
960
961         return prioq_peek(enumerator->devices);
962 }
963
964 _public_ sd_device *sd_device_enumerator_get_subsystem_next(sd_device_enumerator *enumerator) {
965         assert_return(enumerator, NULL);
966
967         if (enumerator->scan_uptodate ||
968             enumerator->type != DEVICE_ENUMERATION_TYPE_SUBSYSTEMS)
969                 return NULL;
970
971         sd_device_unref(prioq_pop(enumerator->devices));
972
973         return prioq_peek(enumerator->devices);
974 }
975
976 sd_device *device_enumerator_get_first(sd_device_enumerator *enumerator) {
977         assert_return(enumerator, NULL);
978
979         return prioq_peek(enumerator->devices);
980 }
981
982 sd_device *device_enumerator_get_next(sd_device_enumerator *enumerator) {
983         assert_return(enumerator, NULL);
984
985         sd_device_unref(prioq_pop(enumerator->devices));
986
987         return prioq_peek(enumerator->devices);
988 }