chiark / gitweb /
Handle suspend, shutdown, reboot, etc within elogind
[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
141         if (match)
142                 hashmap = &enumerator->match_sysattr;
143         else
144                 hashmap = &enumerator->nomatch_sysattr;
145
146         r = hashmap_ensure_allocated(hashmap, NULL);
147         if (r < 0)
148                 return r;
149
150         sysattr = strdup(_sysattr);
151         if (!sysattr)
152                 return -ENOMEM;
153
154         if (_value) {
155                 value = strdup(_value);
156                 if (!value)
157                         return -ENOMEM;
158         }
159
160         r = hashmap_put(*hashmap, sysattr, value);
161         if (r < 0)
162                 return r;
163
164         sysattr = NULL;
165         value = NULL;
166
167         enumerator->scan_uptodate = false;
168
169         return 0;
170 }
171
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;
174         int r;
175
176         assert_return(enumerator, -EINVAL);
177         assert_return(_property, -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         if (_value) {
188                 value = strdup(_value);
189                 if (!value)
190                         return -ENOMEM;
191         }
192
193         r = hashmap_put(enumerator->match_property, property, value);
194         if (r < 0)
195                 return r;
196
197         property = NULL;
198         value = NULL;
199
200         enumerator->scan_uptodate = false;
201
202         return 0;
203 }
204
205 _public_ int sd_device_enumerator_add_match_sysname(sd_device_enumerator *enumerator, const char *sysname) {
206         int r;
207
208         assert_return(enumerator, -EINVAL);
209         assert_return(sysname, -EINVAL);
210
211         r = set_ensure_allocated(&enumerator->match_sysname, NULL);
212         if (r < 0)
213                 return r;
214
215         r = set_put_strdup(enumerator->match_sysname, sysname);
216         if (r < 0)
217                 return r;
218
219         enumerator->scan_uptodate = false;
220
221         return 0;
222 }
223
224 _public_ int sd_device_enumerator_add_match_tag(sd_device_enumerator *enumerator, const char *tag) {
225         int r;
226
227         assert_return(enumerator, -EINVAL);
228         assert_return(tag, -EINVAL);
229
230         r = set_ensure_allocated(&enumerator->match_tag, NULL);
231         if (r < 0)
232                 return r;
233
234         r = set_put_strdup(enumerator->match_tag, tag);
235         if (r < 0)
236                 return r;
237
238         enumerator->scan_uptodate = false;
239
240         return 0;
241 }
242
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);
246
247         sd_device_unref(enumerator->match_parent);
248         enumerator->match_parent = sd_device_ref(parent);
249
250         enumerator->scan_uptodate = false;
251
252         return 0;
253 }
254
255 _public_ int sd_device_enumerator_allow_uninitialized(sd_device_enumerator *enumerator) {
256         assert_return(enumerator, -EINVAL);
257
258         enumerator->match_allow_uninitialized = true;
259
260         enumerator->scan_uptodate = false;
261
262         return 0;
263 }
264
265 int device_enumerator_add_match_is_initialized(sd_device_enumerator *enumerator) {
266         assert_return(enumerator, -EINVAL);
267
268         enumerator->match_allow_uninitialized = false;
269
270         enumerator->scan_uptodate = false;
271
272         return 0;
273 }
274
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;
279
280         assert_se(sd_device_get_devpath(a, &devpath_a) >= 0);
281         assert_se(sd_device_get_devpath(b, &devpath_b) >= 0);
282
283         sound_a = strstr(devpath_a, "/sound/card");
284         if (sound_a) {
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, '/');
294
295                 if (sound_a) {
296                         unsigned prefix_len;
297
298                         prefix_len = sound_a - devpath_a;
299
300                         if (strncmp(devpath_a, devpath_b, prefix_len) == 0) {
301                                 const char *sound_b;
302
303                                 sound_b = devpath_b + prefix_len;
304
305                                 if (startswith(sound_a, "/controlC") &&
306                                     !startswith(sound_b, "/contolC"))
307                                         return 1;
308
309                                 if (!startswith(sound_a, "/controlC") &&
310                                     startswith(sound_b, "/controlC"))
311                                         return -1;
312                         }
313                 }
314         }
315
316         /* md and dm devices are enumerated after all other devices */
317         if (strstr(devpath_a, "/block/md") || strstr(devpath_a, "/block/dm-"))
318                 delay_a = true;
319
320         if (strstr(devpath_b, "/block/md") || strstr(devpath_b, "/block/dm-"))
321                 delay_b = true;
322
323         if (delay_a && !delay_b)
324                 return 1;
325
326         if (!delay_a && delay_b)
327                 return -1;
328
329         return strcmp(devpath_a, devpath_b);
330 }
331
332 int device_enumerator_add_device(sd_device_enumerator *enumerator, sd_device *device) {
333         int r;
334
335         assert_return(enumerator, -EINVAL);
336         assert_return(device, -EINVAL);
337
338         r = prioq_ensure_allocated(&enumerator->devices, device_compare);
339         if (r < 0)
340                 return r;
341
342         r = prioq_put(enumerator->devices, device, NULL);
343         if (r < 0)
344                 return r;
345
346         sd_device_ref(device);
347
348         return 0;
349 }
350
351 static bool match_sysattr_value(sd_device *device, const char *sysattr, const char *match_value) {
352         const char *value;
353         int r;
354
355         assert(device);
356         assert(sysattr);
357
358         r = sd_device_get_sysattr_value(device, sysattr, &value);
359         if (r < 0)
360                 return false;
361
362         if (!match_value)
363                 return true;
364
365         if (fnmatch(match_value, value, 0) == 0)
366                 return true;
367
368         return false;
369 }
370
371 static bool match_sysattr(sd_device_enumerator *enumerator, sd_device *device) {
372         const char *sysattr;
373         const char *value;
374         Iterator i;
375
376         assert(enumerator);
377         assert(device);
378
379         HASHMAP_FOREACH_KEY(value, sysattr, enumerator->nomatch_sysattr, i)
380                 if (match_sysattr_value(device, sysattr, value))
381                         return false;
382
383         HASHMAP_FOREACH_KEY(value, sysattr, enumerator->match_sysattr, i)
384                 if (!match_sysattr_value(device, sysattr, value))
385                         return false;
386
387         return true;
388 }
389
390 static bool match_property(sd_device_enumerator *enumerator, sd_device *device) {
391         const char *property;
392         const char *value;
393         Iterator i;
394
395         assert(enumerator);
396         assert(device);
397
398         if (hashmap_isempty(enumerator->match_property))
399                 return true;
400
401         HASHMAP_FOREACH_KEY(value, property, enumerator->match_property, i) {
402                 const char *property_dev, *value_dev;
403
404                 FOREACH_DEVICE_PROPERTY(device, property_dev, value_dev) {
405                         if (fnmatch(property, property_dev, 0) != 0)
406                                 continue;
407
408                         if (!value && !value_dev)
409                                 return true;
410
411                         if (!value || !value_dev)
412                                 continue;
413
414                         if (fnmatch(value, value_dev, 0) == 0)
415                                 return true;
416                 }
417         }
418
419         return false;
420 }
421
422 static bool match_tag(sd_device_enumerator *enumerator, sd_device *device) {
423         const char *tag;
424         Iterator i;
425
426         assert(enumerator);
427         assert(device);
428
429         SET_FOREACH(tag, enumerator->match_tag, i)
430                 if (!sd_device_has_tag(device, tag))
431                         return false;
432
433         return true;
434 }
435
436 static bool match_parent(sd_device_enumerator *enumerator, sd_device *device) {
437         const char *devpath, *devpath_dev;
438         int r;
439
440         assert(enumerator);
441         assert(device);
442
443         if (!enumerator->match_parent)
444                 return true;
445
446         r = sd_device_get_devpath(enumerator->match_parent, &devpath);
447         assert(r >= 0);
448
449         r = sd_device_get_devpath(device, &devpath_dev);
450         assert(r >= 0);
451
452         return startswith(devpath_dev, devpath);
453 }
454
455 static bool match_sysname(sd_device_enumerator *enumerator, const char *sysname) {
456         const char *sysname_match;
457         Iterator i;
458
459         assert(enumerator);
460         assert(sysname);
461
462         if (set_isempty(enumerator->match_sysname))
463                 return true;
464
465         SET_FOREACH(sysname_match, enumerator->match_sysname, i)
466                 if (fnmatch(sysname_match, sysname, 0) == 0)
467                         return true;
468
469         return false;
470 }
471
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;
474         char *path;
475         struct dirent *dent;
476         int r = 0;
477
478         assert(enumerator);
479         assert(basedir);
480
481         path = strjoina("/sys/", basedir, "/");
482
483         if (subdir1)
484                 path = strjoina(path, subdir1, "/");
485
486         if (subdir2)
487                 path = strjoina(path, subdir2, "/");
488
489         dir = opendir(path);
490         if (!dir)
491                 return -errno;
492
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];
496                 dev_t devnum;
497                 int ifindex, initialized, k;
498
499                 if (dent->d_name[0] == '.')
500                         continue;
501
502                 if (!match_sysname(enumerator, dent->d_name))
503                         continue;
504
505                 (void)sprintf(syspath, "%s%s", path, dent->d_name);
506
507                 k = sd_device_new_from_syspath(&device, syspath);
508                 if (k < 0) {
509                         if (k != -ENODEV)
510                                 /* this is necessarily racey, so ignore missing devices */
511                                 r = k;
512
513                         continue;
514                 }
515
516                 k = sd_device_get_devnum(device, &devnum);
517                 if (k < 0) {
518                         r = k;
519                         continue;
520                 }
521
522                 k = sd_device_get_ifindex(device, &ifindex);
523                 if (k < 0) {
524                         r = k;
525                         continue;
526                 }
527
528                 k = sd_device_get_is_initialized(device, &initialized);
529                 if (k < 0) {
530                         r = k;
531                         continue;
532                 }
533
534                 /*
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.
539                  *
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.
543                  */
544                 if (!enumerator->match_allow_uninitialized &&
545                     !initialized &&
546                     (major(devnum) > 0 || ifindex > 0))
547                         continue;
548
549                 if (!match_parent(enumerator, device))
550                         continue;
551
552                 if (!match_tag(enumerator, device))
553                         continue;
554
555                 if (!match_property(enumerator, device))
556                         continue;
557
558                 if (!match_sysattr(enumerator, device))
559                         continue;
560
561                 k = device_enumerator_add_device(enumerator, device);
562                 if (k < 0)
563                         r = k;
564         }
565
566         return r;
567 }
568
569 static bool match_subsystem(sd_device_enumerator *enumerator, const char *subsystem) {
570         const char *subsystem_match;
571         Iterator i;
572
573         assert(enumerator);
574
575         if (!subsystem)
576                 return false;
577
578         SET_FOREACH(subsystem_match, enumerator->nomatch_subsystem, i)
579                 if (fnmatch(subsystem_match, subsystem, 0) == 0)
580                         return false;
581
582         if (set_isempty(enumerator->match_subsystem))
583                 return true;
584
585         SET_FOREACH(subsystem_match, enumerator->match_subsystem, i)
586                 if (fnmatch(subsystem_match, subsystem, 0) == 0)
587                         return true;
588
589         return false;
590 }
591
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;
594         char *path;
595         struct dirent *dent;
596         int r = 0;
597
598         path = strjoina("/sys/", basedir);
599
600         dir = opendir(path);
601         if (!dir)
602                 return -errno;
603
604         log_debug("  device-enumerator: scanning %s", path);
605
606         FOREACH_DIRENT_ALL(dent, dir, return -errno) {
607                 int k;
608
609                 if (dent->d_name[0] == '.')
610                         continue;
611
612                 if (!match_subsystem(enumerator, subsystem ? : dent->d_name))
613                         continue;
614
615                 k = enumerator_scan_dir_and_add_devices(enumerator, basedir, dent->d_name, subdir);
616                 if (k < 0)
617                         r = k;
618         }
619
620         return r;
621 }
622
623 static int enumerator_scan_devices_tag(sd_device_enumerator *enumerator, const char *tag) {
624         _cleanup_closedir_ DIR *dir = NULL;
625         char *path;
626         struct dirent *dent;
627         int r = 0;
628
629         assert(enumerator);
630         assert(tag);
631
632         path = strjoina("/run/udev/tags/", tag);
633
634         dir = opendir(path);
635         if (!dir) {
636                 if (errno == ENOENT)
637                         return 0;
638                 else {
639                         log_error("sd-device-enumerator: could not open tags directory %s: %m", path);
640                         return -errno;
641                 }
642         }
643
644         /* TODO: filter away subsystems? */
645
646         FOREACH_DIRENT_ALL(dent, dir, return -errno) {
647                 _cleanup_device_unref_ sd_device *device = NULL;
648                 const char *subsystem, *sysname;
649                 int k;
650
651                 if (dent->d_name[0] == '.')
652                         continue;
653
654                 k = sd_device_new_from_device_id(&device, dent->d_name);
655                 if (k < 0) {
656                         if (k != -ENODEV)
657                                 /* this is necessarily racy, so ignore missing devices */
658                                 r = k;
659
660                         continue;
661                 }
662
663                 k = sd_device_get_subsystem(device, &subsystem);
664                 if (k < 0) {
665                         r = k;
666                         continue;
667                 }
668
669                 if (!match_subsystem(enumerator, subsystem))
670                         continue;
671
672                 k = sd_device_get_sysname(device, &sysname);
673                 if (k < 0) {
674                         r = k;
675                         continue;
676                 }
677
678                 if (!match_sysname(enumerator, sysname))
679                         continue;
680
681                 if (!match_parent(enumerator, device))
682                         continue;
683
684                 if (!match_property(enumerator, device))
685                         continue;
686
687                 if (!match_sysattr(enumerator, device))
688                         continue;
689
690                 k = device_enumerator_add_device(enumerator, device);
691                 if (k < 0) {
692                         r = k;
693                         continue;
694                 }
695         }
696
697         return r;
698 }
699
700 static int enumerator_scan_devices_tags(sd_device_enumerator *enumerator) {
701         const char *tag;
702         Iterator i;
703         int r;
704
705         assert(enumerator);
706
707         SET_FOREACH(tag, enumerator->match_tag, i) {
708                 r = enumerator_scan_devices_tag(enumerator, tag);
709                 if (r < 0)
710                         return r;
711         }
712
713         return 0;
714 }
715
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;
719         int r;
720
721         r = sd_device_new_from_syspath(&device, path);
722         if (r == -ENODEV)
723                 /* this is necessarily racy, so ignore missing devices */
724                 return 0;
725         else if (r < 0)
726                 return r;
727
728         r = sd_device_get_subsystem(device, &subsystem);
729         if (r < 0)
730                 return r;
731
732         if (!match_subsystem(enumerator, subsystem))
733                 return 0;
734
735         r = sd_device_get_sysname(device, &sysname);
736         if (r < 0)
737                 return r;
738
739         if (!match_sysname(enumerator, sysname))
740                 return 0;
741
742         if (!match_property(enumerator, device))
743                 return 0;
744
745         if (!match_sysattr(enumerator, device))
746                 return 0;
747
748         r = device_enumerator_add_device(enumerator, device);
749         if (r < 0)
750                 return r;
751
752         return 1;
753 }
754
755 static int parent_crawl_children(sd_device_enumerator *enumerator, const char *path, unsigned maxdepth) {
756         _cleanup_closedir_ DIR *dir = NULL;
757         struct dirent *dent;
758         int r = 0;
759
760         dir = opendir(path);
761         if (!dir) {
762                 log_debug("sd-device-enumerate: could not open parent directory %s: %m", path);
763                 return -errno;
764         }
765
766         FOREACH_DIRENT_ALL(dent, dir, return -errno) {
767                 _cleanup_free_ char *child = NULL;
768                 int k;
769
770                 if (dent->d_name[0] == '.')
771                         continue;
772
773                 if (dent->d_type != DT_DIR)
774                         continue;
775
776                 child = strjoin(path, "/", dent->d_name, NULL);
777                 if (!child)
778                         return -ENOMEM;
779
780                 k = parent_add_child(enumerator, child);
781                 if (k < 0)
782                         r = k;
783
784                 if (maxdepth > 0)
785                         parent_crawl_children(enumerator, child, maxdepth - 1);
786                 else
787                         log_debug("device-enumerate: max depth reached, %s: ignoring devices", child);
788         }
789
790         return r;
791 }
792
793 static int enumerator_scan_devices_children(sd_device_enumerator *enumerator) {
794         const char *path;
795         int r = 0, k;
796
797         r = sd_device_get_syspath(enumerator->match_parent, &path);
798         if (r < 0)
799                 return r;
800
801         k = parent_add_child(enumerator, path);
802         if (k < 0)
803                 r = k;
804
805         k = parent_crawl_children(enumerator, path, DEVICE_ENUMERATE_MAX_DEPTH);
806         if (k < 0)
807                 r = k;
808
809         return r;
810 }
811
812 static int enumerator_scan_devices_all(sd_device_enumerator *enumerator) {
813         int r = 0;
814
815         log_debug("device-enumerator: scan all dirs");
816
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);
820                 if (r < 0) {
821                         log_debug("device-enumerator: failed to scan /sys/subsystem: %s", strerror(-r));
822                         return r;
823                 }
824         } else {
825                 int k;
826
827                 k = enumerator_scan_dir(enumerator, "bus", "devices", NULL);
828                 if (k < 0) {
829                         log_debug_errno(k, "device-enumerator: failed to scan /sys/bus: %m");
830                         r = k;
831                 }
832
833                 k = enumerator_scan_dir(enumerator, "class", NULL, NULL);
834                 if (k < 0) {
835                         log_debug_errno(k, "device-enumerator: failed to scan /sys/class: %m");
836                         r = k;
837                 }
838         }
839
840         return r;
841 }
842
843 int device_enumerator_scan_devices(sd_device_enumerator *enumerator) {
844         sd_device *device;
845         int r;
846
847         assert(enumerator);
848
849         if (enumerator->scan_uptodate &&
850             enumerator->type == DEVICE_ENUMERATION_TYPE_DEVICES)
851                 return 0;
852
853         while ((device = prioq_pop(enumerator->devices)))
854                 sd_device_unref(device);
855
856         if (!set_isempty(enumerator->match_tag)) {
857                 r = enumerator_scan_devices_tags(enumerator);
858                 if (r < 0)
859                         return r;
860         } else if (enumerator->match_parent) {
861                 r = enumerator_scan_devices_children(enumerator);
862                 if (r < 0)
863                         return r;
864         } else {
865                 r = enumerator_scan_devices_all(enumerator);
866                 if (r < 0)
867                         return r;
868         }
869
870         enumerator->scan_uptodate = true;
871
872         return 0;
873 }
874
875 _public_ sd_device *sd_device_enumerator_get_device_first(sd_device_enumerator *enumerator) {
876         int r;
877
878         assert_return(enumerator, NULL);
879
880         r = device_enumerator_scan_devices(enumerator);
881         if (r < 0)
882                 return NULL;
883
884         enumerator->type = DEVICE_ENUMERATION_TYPE_DEVICES;
885
886         return prioq_peek(enumerator->devices);
887 }
888
889 _public_ sd_device *sd_device_enumerator_get_device_next(sd_device_enumerator *enumerator) {
890         assert_return(enumerator, NULL);
891
892         if (!enumerator->scan_uptodate ||
893             enumerator->type != DEVICE_ENUMERATION_TYPE_DEVICES)
894                 return NULL;
895
896         sd_device_unref(prioq_pop(enumerator->devices));
897
898         return prioq_peek(enumerator->devices);
899 }
900
901 int device_enumerator_scan_subsystems(sd_device_enumerator *enumerator) {
902         sd_device *device;
903         const char *subsysdir;
904         int r = 0, k;
905
906         assert(enumerator);
907
908         if (enumerator->scan_uptodate &&
909             enumerator->type == DEVICE_ENUMERATION_TYPE_SUBSYSTEMS)
910                 return 0;
911
912         while ((device = prioq_pop(enumerator->devices)))
913                 sd_device_unref(device);
914
915         /* modules */
916         if (match_subsystem(enumerator, "module")) {
917                 k = enumerator_scan_dir_and_add_devices(enumerator, "module", NULL, NULL);
918                 if (k < 0) {
919                         log_debug_errno(k, "device-enumerator: failed to scan modules: %m");
920                         r = k;
921                 }
922         }
923
924         if (access("/sys/subsystem", F_OK) >= 0)
925                 subsysdir = "subsystem";
926         else
927                 subsysdir = "bus";
928
929         /* subsystems (only buses support coldplug) */
930         if (match_subsystem(enumerator, "subsystem")) {
931                 k = enumerator_scan_dir_and_add_devices(enumerator, subsysdir, NULL, NULL);
932                 if (k < 0) {
933                         log_debug_errno(k, "device-enumerator: failed to scan subsystems: %m");
934                         r = k;
935                 }
936         }
937
938         /* subsystem drivers */
939         if (match_subsystem(enumerator, "drivers")) {
940                 k = enumerator_scan_dir(enumerator, subsysdir, "drivers", "drivers");
941                 if (k < 0) {
942                         log_debug_errno(k, "device-enumerator: failed to scan drivers: %m");
943                         r = k;
944                 }
945         }
946
947         enumerator->scan_uptodate = true;
948
949         return r;
950 }
951
952 _public_ sd_device *sd_device_enumerator_get_subsystem_first(sd_device_enumerator *enumerator) {
953         int r;
954
955         assert_return(enumerator, NULL);
956
957         r = device_enumerator_scan_subsystems(enumerator);
958         if (r < 0)
959                 return NULL;
960
961         enumerator->type = DEVICE_ENUMERATION_TYPE_SUBSYSTEMS;
962
963         return prioq_peek(enumerator->devices);
964 }
965
966 _public_ sd_device *sd_device_enumerator_get_subsystem_next(sd_device_enumerator *enumerator) {
967         assert_return(enumerator, NULL);
968
969         if (enumerator->scan_uptodate ||
970             enumerator->type != DEVICE_ENUMERATION_TYPE_SUBSYSTEMS)
971                 return NULL;
972
973         sd_device_unref(prioq_pop(enumerator->devices));
974
975         return prioq_peek(enumerator->devices);
976 }
977
978 sd_device *device_enumerator_get_first(sd_device_enumerator *enumerator) {
979         assert_return(enumerator, NULL);
980
981         return prioq_peek(enumerator->devices);
982 }
983
984 sd_device *device_enumerator_get_next(sd_device_enumerator *enumerator) {
985         assert_return(enumerator, NULL);
986
987         sd_device_unref(prioq_pop(enumerator->devices));
988
989         return prioq_peek(enumerator->devices);
990 }