chiark / gitweb /
core,logind,networkd: don't pick up devices from udev before they finished udev initi...
[elogind.git] / src / core / device.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <sys/epoll.h>
24 #include <libudev.h>
25
26 #include "strv.h"
27 #include "log.h"
28 #include "unit-name.h"
29 #include "dbus-device.h"
30 #include "def.h"
31 #include "path-util.h"
32 #include "udev-util.h"
33 #include "unit.h"
34 #include "swap.h"
35 #include "device.h"
36
37 static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = {
38         [DEVICE_DEAD] = UNIT_INACTIVE,
39         [DEVICE_PLUGGED] = UNIT_ACTIVE
40 };
41
42 static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
43
44 static void device_unset_sysfs(Device *d) {
45         Hashmap *devices;
46         Device *first;
47
48         assert(d);
49
50         if (!d->sysfs)
51                 return;
52
53         /* Remove this unit from the chain of devices which share the
54          * same sysfs path. */
55         devices = UNIT(d)->manager->devices_by_sysfs;
56         first = hashmap_get(devices, d->sysfs);
57         LIST_REMOVE(same_sysfs, first, d);
58
59         if (first)
60                 hashmap_remove_and_replace(devices, d->sysfs, first->sysfs, first);
61         else
62                 hashmap_remove(devices, d->sysfs);
63
64         free(d->sysfs);
65         d->sysfs = NULL;
66 }
67
68 static void device_init(Unit *u) {
69         Device *d = DEVICE(u);
70
71         assert(d);
72         assert(UNIT(d)->load_state == UNIT_STUB);
73
74         /* In contrast to all other unit types we timeout jobs waiting
75          * for devices by default. This is because they otherwise wait
76          * indefinitely for plugged in devices, something which cannot
77          * happen for the other units since their operations time out
78          * anyway. */
79         u->job_timeout = u->manager->default_timeout_start_usec;
80
81         u->ignore_on_isolate = true;
82         u->ignore_on_snapshot = true;
83 }
84
85 static void device_done(Unit *u) {
86         Device *d = DEVICE(u);
87
88         assert(d);
89
90         device_unset_sysfs(d);
91 }
92
93 static void device_set_state(Device *d, DeviceState state) {
94         DeviceState old_state;
95         assert(d);
96
97         old_state = d->state;
98         d->state = state;
99
100         if (state != old_state)
101                 log_debug_unit(UNIT(d)->id,
102                                "%s changed %s -> %s", UNIT(d)->id,
103                                device_state_to_string(old_state),
104                                device_state_to_string(state));
105
106         unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], true);
107 }
108
109 static int device_coldplug(Unit *u) {
110         Device *d = DEVICE(u);
111
112         assert(d);
113         assert(d->state == DEVICE_DEAD);
114
115         if (d->sysfs)
116                 device_set_state(d, DEVICE_PLUGGED);
117
118         return 0;
119 }
120
121 static void device_dump(Unit *u, FILE *f, const char *prefix) {
122         Device *d = DEVICE(u);
123
124         assert(d);
125
126         fprintf(f,
127                 "%sDevice State: %s\n"
128                 "%sSysfs Path: %s\n",
129                 prefix, device_state_to_string(d->state),
130                 prefix, strna(d->sysfs));
131 }
132
133 _pure_ static UnitActiveState device_active_state(Unit *u) {
134         assert(u);
135
136         return state_translation_table[DEVICE(u)->state];
137 }
138
139 _pure_ static const char *device_sub_state_to_string(Unit *u) {
140         assert(u);
141
142         return device_state_to_string(DEVICE(u)->state);
143 }
144
145 static int device_add_escaped_name(Unit *u, const char *dn) {
146         _cleanup_free_ char *e = NULL;
147         int r;
148
149         assert(u);
150         assert(dn);
151         assert(dn[0] == '/');
152
153         e = unit_name_from_path(dn, ".device");
154         if (!e)
155                 return -ENOMEM;
156
157         r = unit_add_name(u, e);
158         if (r < 0 && r != -EEXIST)
159                 return r;
160
161         return 0;
162 }
163
164 static int device_find_escape_name(Manager *m, const char *dn, Unit **_u) {
165         _cleanup_free_ char *e = NULL;
166         Unit *u;
167
168         assert(m);
169         assert(dn);
170         assert(dn[0] == '/');
171         assert(_u);
172
173         e = unit_name_from_path(dn, ".device");
174         if (!e)
175                 return -ENOMEM;
176
177         u = manager_get_unit(m, e);
178         if (u) {
179                 *_u = u;
180                 return 1;
181         }
182
183         return 0;
184 }
185
186 static int device_update_unit(Manager *m, struct udev_device *dev, const char *path, bool main) {
187         const char *sysfs, *model;
188         Unit *u = NULL;
189         int r;
190         bool delete;
191
192         assert(m);
193
194         sysfs = udev_device_get_syspath(dev);
195         if (!sysfs)
196                 return 0;
197
198         r = device_find_escape_name(m, path, &u);
199         if (r < 0)
200                 return r;
201
202         if (u && DEVICE(u)->sysfs && !path_equal(DEVICE(u)->sysfs, sysfs))
203                 return -EEXIST;
204
205         if (!u) {
206                 delete = true;
207
208                 u = unit_new(m, sizeof(Device));
209                 if (!u)
210                         return log_oom();
211
212                 r = device_add_escaped_name(u, path);
213                 if (r < 0)
214                         goto fail;
215
216                 unit_add_to_load_queue(u);
217         } else
218                 delete = false;
219
220         /* If this was created via some dependency and has not
221          * actually been seen yet ->sysfs will not be
222          * initialized. Hence initialize it if necessary. */
223
224         if (!DEVICE(u)->sysfs) {
225                 Device *first;
226
227                 DEVICE(u)->sysfs = strdup(sysfs);
228                 if (!DEVICE(u)->sysfs) {
229                         r = -ENOMEM;
230                         goto fail;
231                 }
232
233                 r = hashmap_ensure_allocated(&m->devices_by_sysfs, string_hash_func, string_compare_func);
234                 if (r < 0)
235                         goto fail;
236
237                 first = hashmap_get(m->devices_by_sysfs, sysfs);
238                 LIST_PREPEND(same_sysfs, first, DEVICE(u));
239
240                 r = hashmap_replace(m->devices_by_sysfs, DEVICE(u)->sysfs, first);
241                 if (r < 0)
242                         goto fail;
243         }
244
245         if ((model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE")) ||
246             (model = udev_device_get_property_value(dev, "ID_MODEL")))
247                 r = unit_set_description(u, model);
248         else
249                 r = unit_set_description(u, path);
250         if (r < 0)
251                 goto fail;
252
253         if (main) {
254                 const char *wants;
255
256                 /* The additional systemd udev properties we only
257                  * interpret for the main object */
258
259                 wants = udev_device_get_property_value(dev, m->running_as == SYSTEMD_USER ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS");
260                 if (wants) {
261                         char *state, *w;
262                         size_t l;
263
264                         FOREACH_WORD_QUOTED(w, l, wants, state) {
265                                 _cleanup_free_ char *n = NULL;
266                                 char e[l+1];
267
268                                 memcpy(e, w, l);
269                                 e[l] = 0;
270
271                                 n = unit_name_mangle(e);
272                                 if (!n) {
273                                         r = -ENOMEM;
274                                         goto fail;
275                                 }
276
277                                 r = unit_add_dependency_by_name(u, UNIT_WANTS, n, NULL, true);
278                                 if (r < 0)
279                                         goto fail;
280                         }
281                 }
282         }
283
284         /* Note that this won't dispatch the load queue, the caller
285          * has to do that if needed and appropriate */
286
287         unit_add_to_dbus_queue(u);
288         return 0;
289
290 fail:
291         log_warning("Failed to load device unit: %s", strerror(-r));
292
293         if (delete && u)
294                 unit_free(u);
295
296         return r;
297 }
298
299 static int device_process_new_device(Manager *m, struct udev_device *dev) {
300         const char *sysfs, *dn, *alias;
301         struct udev_list_entry *item = NULL, *first = NULL;
302         int r;
303
304         assert(m);
305
306         /* Don't pick up devices before udev finished initialization for them */
307         if (!udev_device_get_is_initialized(dev))
308                 return 0;
309
310         sysfs = udev_device_get_syspath(dev);
311         if (!sysfs)
312                 return 0;
313
314         /* Add the main unit named after the sysfs path */
315         r = device_update_unit(m, dev, sysfs, true);
316         if (r < 0)
317                 return r;
318
319         /* Add an additional unit for the device node */
320         dn = udev_device_get_devnode(dev);
321         if (dn)
322                 device_update_unit(m, dev, dn, false);
323
324         /* Add additional units for all symlinks */
325         first = udev_device_get_devlinks_list_entry(dev);
326         udev_list_entry_foreach(item, first) {
327                 const char *p;
328                 struct stat st;
329
330                 /* Don't bother with the /dev/block links */
331                 p = udev_list_entry_get_name(item);
332
333                 if (path_startswith(p, "/dev/block/") ||
334                     path_startswith(p, "/dev/char/"))
335                         continue;
336
337                 /* Verify that the symlink in the FS actually belongs
338                  * to this device. This is useful to deal with
339                  * conflicting devices, e.g. when two disks want the
340                  * same /dev/disk/by-label/xxx link because they have
341                  * the same label. We want to make sure that the same
342                  * device that won the symlink wins in systemd, so we
343                  * check the device node major/minor*/
344                 if (stat(p, &st) >= 0)
345                         if ((!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) ||
346                             st.st_rdev != udev_device_get_devnum(dev))
347                                 continue;
348
349                 device_update_unit(m, dev, p, false);
350         }
351
352         /* Add additional units for all explicitly configured
353          * aliases */
354         alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS");
355         if (alias) {
356                 char *state, *w;
357                 size_t l;
358
359                 FOREACH_WORD_QUOTED(w, l, alias, state) {
360                         char e[l+1];
361
362                         memcpy(e, w, l);
363                         e[l] = 0;
364
365                         if (path_is_absolute(e))
366                                 device_update_unit(m, dev, e, false);
367                         else
368                                 log_warning("SYSTEMD_ALIAS for %s is not an absolute path, ignoring: %s", sysfs, e);
369                 }
370         }
371
372         return 0;
373 }
374
375 static void device_set_path_plugged(Manager *m, struct udev_device *dev) {
376         const char *sysfs;
377         Device *d, *l;
378
379         assert(m);
380         assert(dev);
381
382         sysfs = udev_device_get_syspath(dev);
383         if (!sysfs)
384                 return;
385
386         l = hashmap_get(m->devices_by_sysfs, sysfs);
387         LIST_FOREACH(same_sysfs, d, l)
388                 device_set_state(d, DEVICE_PLUGGED);
389 }
390
391 static int device_process_removed_device(Manager *m, struct udev_device *dev) {
392         const char *sysfs;
393         Device *d;
394
395         assert(m);
396         assert(dev);
397
398         sysfs = udev_device_get_syspath(dev);
399         if (!sysfs)
400                 return -ENOMEM;
401
402         /* Remove all units of this sysfs path */
403         while ((d = hashmap_get(m->devices_by_sysfs, sysfs))) {
404                 device_unset_sysfs(d);
405                 device_set_state(d, DEVICE_DEAD);
406         }
407
408         return 0;
409 }
410
411 static bool device_is_ready(struct udev_device *dev) {
412         const char *ready;
413
414         assert(dev);
415
416         ready = udev_device_get_property_value(dev, "SYSTEMD_READY");
417         if (!ready)
418                 return true;
419
420         return parse_boolean(ready) != 0;
421 }
422
423 static int device_process_new_path(Manager *m, const char *path) {
424         _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
425
426         assert(m);
427         assert(path);
428
429         dev = udev_device_new_from_syspath(m->udev, path);
430         if (!dev)
431                 return log_oom();
432
433         if (!device_is_ready(dev))
434                 return 0;
435
436         return device_process_new_device(m, dev);
437 }
438
439 static Unit *device_following(Unit *u) {
440         Device *d = DEVICE(u);
441         Device *other, *first = NULL;
442
443         assert(d);
444
445         if (startswith(u->id, "sys-"))
446                 return NULL;
447
448         /* Make everybody follow the unit that's named after the sysfs path */
449         for (other = d->same_sysfs_next; other; other = other->same_sysfs_next)
450                 if (startswith(UNIT(other)->id, "sys-"))
451                         return UNIT(other);
452
453         for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev) {
454                 if (startswith(UNIT(other)->id, "sys-"))
455                         return UNIT(other);
456
457                 first = other;
458         }
459
460         return UNIT(first);
461 }
462
463 static int device_following_set(Unit *u, Set **_set) {
464         Device *d = DEVICE(u), *other;
465         Set *set;
466         int r;
467
468         assert(d);
469         assert(_set);
470
471         if (LIST_JUST_US(same_sysfs, d)) {
472                 *_set = NULL;
473                 return 0;
474         }
475
476         set = set_new(NULL, NULL);
477         if (!set)
478                 return -ENOMEM;
479
480         LIST_FOREACH_AFTER(same_sysfs, other, d) {
481                 r = set_put(set, other);
482                 if (r < 0)
483                         goto fail;
484         }
485
486         LIST_FOREACH_BEFORE(same_sysfs, other, d) {
487                 r = set_put(set, other);
488                 if (r < 0)
489                         goto fail;
490         }
491
492         *_set = set;
493         return 1;
494
495 fail:
496         set_free(set);
497         return r;
498 }
499
500 static void device_shutdown(Manager *m) {
501         assert(m);
502
503         m->udev_event_source = sd_event_source_unref(m->udev_event_source);
504
505         if (m->udev_monitor) {
506                 udev_monitor_unref(m->udev_monitor);
507                 m->udev_monitor = NULL;
508         }
509
510         hashmap_free(m->devices_by_sysfs);
511         m->devices_by_sysfs = NULL;
512 }
513
514 static int device_enumerate(Manager *m) {
515         _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
516         struct udev_list_entry *item = NULL, *first = NULL;
517         int r;
518
519         assert(m);
520
521         if (!m->udev_monitor) {
522                 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
523                 if (!m->udev_monitor) {
524                         r = -ENOMEM;
525                         goto fail;
526                 }
527
528                 /* This will fail if we are unprivileged, but that
529                  * should not matter much, as user instances won't run
530                  * during boot. */
531                 udev_monitor_set_receive_buffer_size(m->udev_monitor, 128*1024*1024);
532
533                 r = udev_monitor_filter_add_match_tag(m->udev_monitor, "systemd");
534                 if (r < 0)
535                         goto fail;
536
537                 r = udev_monitor_enable_receiving(m->udev_monitor);
538                 if (r < 0)
539                         goto fail;
540
541                 r = sd_event_add_io(m->event, udev_monitor_get_fd(m->udev_monitor), EPOLLIN, device_dispatch_io, m, &m->udev_event_source);
542                 if (r < 0)
543                         goto fail;
544         }
545
546         e = udev_enumerate_new(m->udev);
547         if (!e) {
548                 r = -ENOMEM;
549                 goto fail;
550         }
551
552         r = udev_enumerate_add_match_tag(e, "systemd");
553         if (r < 0)
554                 goto fail;
555
556         r = udev_enumerate_scan_devices(e);
557         if (r < 0)
558                 goto fail;
559
560         first = udev_enumerate_get_list_entry(e);
561         udev_list_entry_foreach(item, first)
562                 device_process_new_path(m, udev_list_entry_get_name(item));
563
564         return 0;
565
566 fail:
567         device_shutdown(m);
568         return r;
569 }
570
571 static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
572         _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
573         Manager *m = userdata;
574         const char *action;
575         int r;
576
577         assert(m);
578
579         if (revents != EPOLLIN) {
580                 static RATELIMIT_DEFINE(limit, 10*USEC_PER_SEC, 5);
581
582                 if (!ratelimit_test(&limit))
583                         log_error("Failed to get udev event: %m");
584                 if (!(revents & EPOLLIN))
585                         return 0;
586         }
587
588         /*
589          * libudev might filter-out devices which pass the bloom
590          * filter, so getting NULL here is not necessarily an error.
591          */
592         dev = udev_monitor_receive_device(m->udev_monitor);
593         if (!dev)
594                 return 0;
595
596         action = udev_device_get_action(dev);
597         if (!action) {
598                 log_error("Failed to get udev action string.");
599                 return 0;
600         }
601
602         if (streq(action, "remove") || !device_is_ready(dev))  {
603                 r = device_process_removed_device(m, dev);
604                 if (r < 0)
605                         log_error("Failed to process device remove event: %s", strerror(-r));
606
607                 r = swap_process_removed_device(m, dev);
608                 if (r < 0)
609                         log_error("Failed to process swap device remove event: %s", strerror(-r));
610
611         } else {
612                 r = device_process_new_device(m, dev);
613                 if (r < 0)
614                         log_error("Failed to process device new event: %s", strerror(-r));
615
616                 r = swap_process_new_device(m, dev);
617                 if (r < 0)
618                         log_error("Failed to process swap device new event: %s", strerror(-r));
619
620                 manager_dispatch_load_queue(m);
621
622                 device_set_path_plugged(m, dev);
623         }
624
625         return 0;
626 }
627
628 static const char* const device_state_table[_DEVICE_STATE_MAX] = {
629         [DEVICE_DEAD] = "dead",
630         [DEVICE_PLUGGED] = "plugged"
631 };
632
633 DEFINE_STRING_TABLE_LOOKUP(device_state, DeviceState);
634
635 const UnitVTable device_vtable = {
636         .object_size = sizeof(Device),
637         .sections =
638                 "Unit\0"
639                 "Device\0"
640                 "Install\0",
641
642         .no_instances = true,
643
644         .init = device_init,
645         .done = device_done,
646         .load = unit_load_fragment_and_dropin_optional,
647
648         .coldplug = device_coldplug,
649
650         .dump = device_dump,
651
652         .active_state = device_active_state,
653         .sub_state_to_string = device_sub_state_to_string,
654
655         .bus_interface = "org.freedesktop.systemd1.Device",
656         .bus_changing_properties = bus_device_changing_properties,
657         .bus_vtable = bus_device_vtable,
658
659         .following = device_following,
660         .following_set = device_following_set,
661
662         .enumerate = device_enumerate,
663         .shutdown = device_shutdown,
664
665         .status_message_formats = {
666                 .starting_stopping = {
667                         [0] = "Expecting device %s...",
668                 },
669                 .finished_start_job = {
670                         [JOB_DONE]       = "Found device %s.",
671                         [JOB_TIMEOUT]    = "Timed out waiting for device %s.",
672                 },
673         },
674 };