]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/device.c
treewide: use log_*_errno whenever %m is in the format string
[thirdparty/systemd.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_unit_debug(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_make_description(Unit *u, struct udev_device *dev, const char *path) {
187 const char *model;
188
189 assert(u);
190 assert(dev);
191 assert(path);
192
193 model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE");
194 if (!model)
195 model = udev_device_get_property_value(dev, "ID_MODEL");
196
197 if (model) {
198 const char *label;
199
200 /* Try to concatenate the device model string with a label, if there is one */
201 label = udev_device_get_property_value(dev, "ID_FS_LABEL");
202 if (!label)
203 label = udev_device_get_property_value(dev, "ID_PART_ENTRY_NAME");
204 if (!label)
205 label = udev_device_get_property_value(dev, "ID_PART_ENTRY_NUMBER");
206
207 if (label) {
208 _cleanup_free_ char *j;
209
210 j = strjoin(model, " ", label, NULL);
211 if (j)
212 return unit_set_description(u, j);
213 }
214
215 return unit_set_description(u, model);
216 }
217
218 return unit_set_description(u, path);
219 }
220
221 static int device_add_udev_wants(Unit *u, struct udev_device *dev) {
222 const char *wants;
223 const char *word, *state;
224 size_t l;
225 int r;
226 const char *property;
227
228 assert(u);
229 assert(dev);
230
231 property = u->manager->running_as == SYSTEMD_USER ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS";
232 wants = udev_device_get_property_value(dev, property);
233 if (!wants)
234 return 0;
235
236 FOREACH_WORD_QUOTED(word, l, wants, state) {
237 _cleanup_free_ char *n = NULL;
238 char e[l+1];
239
240 memcpy(e, word, l);
241 e[l] = 0;
242
243 n = unit_name_mangle(e, MANGLE_NOGLOB);
244 if (!n)
245 return -ENOMEM;
246
247 r = unit_add_dependency_by_name(u, UNIT_WANTS, n, NULL, true);
248 if (r < 0)
249 return r;
250 }
251 if (!isempty(state))
252 log_unit_warning(u->id, "Property %s on %s has trailing garbage, ignoring.",
253 property, strna(udev_device_get_syspath(dev)));
254
255 return 0;
256 }
257
258 static int device_update_unit(Manager *m, struct udev_device *dev, const char *path, bool main) {
259 const char *sysfs;
260 Unit *u = NULL;
261 bool delete;
262 int r;
263
264 assert(m);
265 assert(dev);
266 assert(path);
267
268 sysfs = udev_device_get_syspath(dev);
269 if (!sysfs)
270 return 0;
271
272 r = device_find_escape_name(m, path, &u);
273 if (r < 0)
274 return r;
275
276 if (u && DEVICE(u)->sysfs && !path_equal(DEVICE(u)->sysfs, sysfs))
277 return -EEXIST;
278
279 if (!u) {
280 delete = true;
281
282 u = unit_new(m, sizeof(Device));
283 if (!u)
284 return log_oom();
285
286 r = device_add_escaped_name(u, path);
287 if (r < 0)
288 goto fail;
289
290 unit_add_to_load_queue(u);
291 } else
292 delete = false;
293
294 /* If this was created via some dependency and has not
295 * actually been seen yet ->sysfs will not be
296 * initialized. Hence initialize it if necessary. */
297
298 if (!DEVICE(u)->sysfs) {
299 Device *first;
300
301 DEVICE(u)->sysfs = strdup(sysfs);
302 if (!DEVICE(u)->sysfs) {
303 r = -ENOMEM;
304 goto fail;
305 }
306
307 r = hashmap_ensure_allocated(&m->devices_by_sysfs, &string_hash_ops);
308 if (r < 0)
309 goto fail;
310
311 first = hashmap_get(m->devices_by_sysfs, sysfs);
312 LIST_PREPEND(same_sysfs, first, DEVICE(u));
313
314 r = hashmap_replace(m->devices_by_sysfs, DEVICE(u)->sysfs, first);
315 if (r < 0)
316 goto fail;
317 }
318
319 device_make_description(u, dev, path);
320
321 if (main) {
322 /* The additional systemd udev properties we only
323 * interpret for the main object */
324
325 r = device_add_udev_wants(u, dev);
326 if (r < 0)
327 goto fail;
328 }
329
330 /* Note that this won't dispatch the load queue, the caller
331 * has to do that if needed and appropriate */
332
333 unit_add_to_dbus_queue(u);
334 return 0;
335
336 fail:
337 log_warning_errno(r, "Failed to load device unit: %m");
338
339 if (delete && u)
340 unit_free(u);
341
342 return r;
343 }
344
345 static int device_process_new_device(Manager *m, struct udev_device *dev) {
346 const char *sysfs, *dn, *alias;
347 struct udev_list_entry *item = NULL, *first = NULL;
348 int r;
349
350 assert(m);
351
352 sysfs = udev_device_get_syspath(dev);
353 if (!sysfs)
354 return 0;
355
356 /* Add the main unit named after the sysfs path */
357 r = device_update_unit(m, dev, sysfs, true);
358 if (r < 0)
359 return r;
360
361 /* Add an additional unit for the device node */
362 dn = udev_device_get_devnode(dev);
363 if (dn)
364 device_update_unit(m, dev, dn, false);
365
366 /* Add additional units for all symlinks */
367 first = udev_device_get_devlinks_list_entry(dev);
368 udev_list_entry_foreach(item, first) {
369 const char *p;
370 struct stat st;
371
372 /* Don't bother with the /dev/block links */
373 p = udev_list_entry_get_name(item);
374
375 if (path_startswith(p, "/dev/block/") ||
376 path_startswith(p, "/dev/char/"))
377 continue;
378
379 /* Verify that the symlink in the FS actually belongs
380 * to this device. This is useful to deal with
381 * conflicting devices, e.g. when two disks want the
382 * same /dev/disk/by-label/xxx link because they have
383 * the same label. We want to make sure that the same
384 * device that won the symlink wins in systemd, so we
385 * check the device node major/minor*/
386 if (stat(p, &st) >= 0)
387 if ((!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) ||
388 st.st_rdev != udev_device_get_devnum(dev))
389 continue;
390
391 device_update_unit(m, dev, p, false);
392 }
393
394 /* Add additional units for all explicitly configured
395 * aliases */
396 alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS");
397 if (alias) {
398 const char *word, *state;
399 size_t l;
400
401 FOREACH_WORD_QUOTED(word, l, alias, state) {
402 char e[l+1];
403
404 memcpy(e, word, l);
405 e[l] = 0;
406
407 if (path_is_absolute(e))
408 device_update_unit(m, dev, e, false);
409 else
410 log_warning("SYSTEMD_ALIAS for %s is not an absolute path, ignoring: %s", sysfs, e);
411 }
412 if (!isempty(state))
413 log_warning("SYSTEMD_ALIAS for %s has trailing garbage, ignoring.", sysfs);
414 }
415
416 return 0;
417 }
418
419 static void device_set_path_plugged(Manager *m, struct udev_device *dev) {
420 const char *sysfs;
421 Device *d, *l;
422
423 assert(m);
424 assert(dev);
425
426 sysfs = udev_device_get_syspath(dev);
427 if (!sysfs)
428 return;
429
430 l = hashmap_get(m->devices_by_sysfs, sysfs);
431 LIST_FOREACH(same_sysfs, d, l)
432 device_set_state(d, DEVICE_PLUGGED);
433 }
434
435 static int device_process_removed_device(Manager *m, struct udev_device *dev) {
436 const char *sysfs;
437 Device *d;
438
439 assert(m);
440 assert(dev);
441
442 sysfs = udev_device_get_syspath(dev);
443 if (!sysfs)
444 return -ENOMEM;
445
446 /* Remove all units of this sysfs path */
447 while ((d = hashmap_get(m->devices_by_sysfs, sysfs))) {
448 device_unset_sysfs(d);
449 device_set_state(d, DEVICE_DEAD);
450 }
451
452 return 0;
453 }
454
455 static bool device_is_ready(struct udev_device *dev) {
456 const char *ready;
457
458 assert(dev);
459
460 ready = udev_device_get_property_value(dev, "SYSTEMD_READY");
461 if (!ready)
462 return true;
463
464 return parse_boolean(ready) != 0;
465 }
466
467 static int device_process_new_path(Manager *m, const char *path) {
468 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
469
470 assert(m);
471 assert(path);
472
473 dev = udev_device_new_from_syspath(m->udev, path);
474 if (!dev)
475 return log_oom();
476
477 if (!device_is_ready(dev))
478 return 0;
479
480 return device_process_new_device(m, dev);
481 }
482
483 static Unit *device_following(Unit *u) {
484 Device *d = DEVICE(u);
485 Device *other, *first = NULL;
486
487 assert(d);
488
489 if (startswith(u->id, "sys-"))
490 return NULL;
491
492 /* Make everybody follow the unit that's named after the sysfs path */
493 for (other = d->same_sysfs_next; other; other = other->same_sysfs_next)
494 if (startswith(UNIT(other)->id, "sys-"))
495 return UNIT(other);
496
497 for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev) {
498 if (startswith(UNIT(other)->id, "sys-"))
499 return UNIT(other);
500
501 first = other;
502 }
503
504 return UNIT(first);
505 }
506
507 static int device_following_set(Unit *u, Set **_set) {
508 Device *d = DEVICE(u), *other;
509 Set *set;
510 int r;
511
512 assert(d);
513 assert(_set);
514
515 if (LIST_JUST_US(same_sysfs, d)) {
516 *_set = NULL;
517 return 0;
518 }
519
520 set = set_new(NULL);
521 if (!set)
522 return -ENOMEM;
523
524 LIST_FOREACH_AFTER(same_sysfs, other, d) {
525 r = set_put(set, other);
526 if (r < 0)
527 goto fail;
528 }
529
530 LIST_FOREACH_BEFORE(same_sysfs, other, d) {
531 r = set_put(set, other);
532 if (r < 0)
533 goto fail;
534 }
535
536 *_set = set;
537 return 1;
538
539 fail:
540 set_free(set);
541 return r;
542 }
543
544 static void device_shutdown(Manager *m) {
545 assert(m);
546
547 m->udev_event_source = sd_event_source_unref(m->udev_event_source);
548
549 if (m->udev_monitor) {
550 udev_monitor_unref(m->udev_monitor);
551 m->udev_monitor = NULL;
552 }
553
554 hashmap_free(m->devices_by_sysfs);
555 m->devices_by_sysfs = NULL;
556 }
557
558 static int device_enumerate(Manager *m) {
559 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
560 struct udev_list_entry *item = NULL, *first = NULL;
561 int r;
562
563 assert(m);
564
565 if (!m->udev_monitor) {
566 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
567 if (!m->udev_monitor) {
568 r = -ENOMEM;
569 goto fail;
570 }
571
572 /* This will fail if we are unprivileged, but that
573 * should not matter much, as user instances won't run
574 * during boot. */
575 udev_monitor_set_receive_buffer_size(m->udev_monitor, 128*1024*1024);
576
577 r = udev_monitor_filter_add_match_tag(m->udev_monitor, "systemd");
578 if (r < 0)
579 goto fail;
580
581 r = udev_monitor_enable_receiving(m->udev_monitor);
582 if (r < 0)
583 goto fail;
584
585 r = sd_event_add_io(m->event, &m->udev_event_source, udev_monitor_get_fd(m->udev_monitor), EPOLLIN, device_dispatch_io, m);
586 if (r < 0)
587 goto fail;
588 }
589
590 e = udev_enumerate_new(m->udev);
591 if (!e) {
592 r = -ENOMEM;
593 goto fail;
594 }
595
596 r = udev_enumerate_add_match_tag(e, "systemd");
597 if (r < 0)
598 goto fail;
599
600 r = udev_enumerate_add_match_is_initialized(e);
601 if (r < 0)
602 goto fail;
603
604 r = udev_enumerate_scan_devices(e);
605 if (r < 0)
606 goto fail;
607
608 first = udev_enumerate_get_list_entry(e);
609 udev_list_entry_foreach(item, first)
610 device_process_new_path(m, udev_list_entry_get_name(item));
611
612 return 0;
613
614 fail:
615 device_shutdown(m);
616 return r;
617 }
618
619 static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
620 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
621 Manager *m = userdata;
622 const char *action;
623 int r;
624
625 assert(m);
626
627 if (revents != EPOLLIN) {
628 static RATELIMIT_DEFINE(limit, 10*USEC_PER_SEC, 5);
629
630 if (!ratelimit_test(&limit))
631 log_error_errno(errno, "Failed to get udev event: %m");
632 if (!(revents & EPOLLIN))
633 return 0;
634 }
635
636 /*
637 * libudev might filter-out devices which pass the bloom
638 * filter, so getting NULL here is not necessarily an error.
639 */
640 dev = udev_monitor_receive_device(m->udev_monitor);
641 if (!dev)
642 return 0;
643
644 action = udev_device_get_action(dev);
645 if (!action) {
646 log_error("Failed to get udev action string.");
647 return 0;
648 }
649
650 if (streq(action, "remove") || !device_is_ready(dev)) {
651 r = device_process_removed_device(m, dev);
652 if (r < 0)
653 log_error_errno(r, "Failed to process device remove event: %m");
654
655 r = swap_process_removed_device(m, dev);
656 if (r < 0)
657 log_error_errno(r, "Failed to process swap device remove event: %m");
658
659 } else {
660 r = device_process_new_device(m, dev);
661 if (r < 0)
662 log_error_errno(r, "Failed to process device new event: %m");
663
664 r = swap_process_new_device(m, dev);
665 if (r < 0)
666 log_error_errno(r, "Failed to process swap device new event: %m");
667
668 manager_dispatch_load_queue(m);
669
670 device_set_path_plugged(m, dev);
671 }
672
673 return 0;
674 }
675
676 static const char* const device_state_table[_DEVICE_STATE_MAX] = {
677 [DEVICE_DEAD] = "dead",
678 [DEVICE_PLUGGED] = "plugged"
679 };
680
681 DEFINE_STRING_TABLE_LOOKUP(device_state, DeviceState);
682
683 const UnitVTable device_vtable = {
684 .object_size = sizeof(Device),
685 .sections =
686 "Unit\0"
687 "Device\0"
688 "Install\0",
689
690 .no_instances = true,
691
692 .init = device_init,
693 .done = device_done,
694 .load = unit_load_fragment_and_dropin_optional,
695
696 .coldplug = device_coldplug,
697
698 .dump = device_dump,
699
700 .active_state = device_active_state,
701 .sub_state_to_string = device_sub_state_to_string,
702
703 .bus_interface = "org.freedesktop.systemd1.Device",
704 .bus_vtable = bus_device_vtable,
705
706 .following = device_following,
707 .following_set = device_following_set,
708
709 .enumerate = device_enumerate,
710 .shutdown = device_shutdown,
711
712 .status_message_formats = {
713 .starting_stopping = {
714 [0] = "Expecting device %s...",
715 },
716 .finished_start_job = {
717 [JOB_DONE] = "Found device %s.",
718 [JOB_TIMEOUT] = "Timed out waiting for device %s.",
719 },
720 },
721 };