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