]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/device.c
core: downgrade warning about duplicate device names
[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 "log.h"
27 #include "unit-name.h"
28 #include "dbus-device.h"
29 #include "path-util.h"
30 #include "udev-util.h"
31 #include "unit.h"
32 #include "swap.h"
33 #include "device.h"
34
35 static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = {
36 [DEVICE_DEAD] = UNIT_INACTIVE,
37 [DEVICE_TENTATIVE] = UNIT_ACTIVATING,
38 [DEVICE_PLUGGED] = UNIT_ACTIVE,
39 };
40
41 static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
42
43 static void device_unset_sysfs(Device *d) {
44 Hashmap *devices;
45 Device *first;
46
47 assert(d);
48
49 if (!d->sysfs)
50 return;
51
52 /* Remove this unit from the chain of devices which share the
53 * same sysfs path. */
54 devices = UNIT(d)->manager->devices_by_sysfs;
55 first = hashmap_get(devices, d->sysfs);
56 LIST_REMOVE(same_sysfs, first, d);
57
58 if (first)
59 hashmap_remove_and_replace(devices, d->sysfs, first->sysfs, first);
60 else
61 hashmap_remove(devices, d->sysfs);
62
63 free(d->sysfs);
64 d->sysfs = NULL;
65 }
66
67 static int device_set_sysfs(Device *d, const char *sysfs) {
68 Device *first;
69 char *copy;
70 int r;
71
72 assert(d);
73
74 if (streq_ptr(d->sysfs, sysfs))
75 return 0;
76
77 r = hashmap_ensure_allocated(&UNIT(d)->manager->devices_by_sysfs, &string_hash_ops);
78 if (r < 0)
79 return r;
80
81 copy = strdup(sysfs);
82 if (!copy)
83 return -ENOMEM;
84
85 device_unset_sysfs(d);
86
87 first = hashmap_get(UNIT(d)->manager->devices_by_sysfs, sysfs);
88 LIST_PREPEND(same_sysfs, first, d);
89
90 r = hashmap_replace(UNIT(d)->manager->devices_by_sysfs, copy, first);
91 if (r < 0) {
92 LIST_REMOVE(same_sysfs, first, d);
93 free(copy);
94 return r;
95 }
96
97 d->sysfs = copy;
98
99 return 0;
100 }
101
102 static void device_init(Unit *u) {
103 Device *d = DEVICE(u);
104
105 assert(d);
106 assert(UNIT(d)->load_state == UNIT_STUB);
107
108 /* In contrast to all other unit types we timeout jobs waiting
109 * for devices by default. This is because they otherwise wait
110 * indefinitely for plugged in devices, something which cannot
111 * happen for the other units since their operations time out
112 * anyway. */
113 u->job_timeout = u->manager->default_timeout_start_usec;
114
115 u->ignore_on_isolate = true;
116 u->ignore_on_snapshot = true;
117 }
118
119 static void device_done(Unit *u) {
120 Device *d = DEVICE(u);
121
122 assert(d);
123
124 device_unset_sysfs(d);
125 }
126
127 static void device_set_state(Device *d, DeviceState state) {
128 DeviceState old_state;
129 assert(d);
130
131 old_state = d->state;
132 d->state = state;
133
134 if (state != old_state)
135 log_unit_debug(UNIT(d)->id,
136 "%s changed %s -> %s", UNIT(d)->id,
137 device_state_to_string(old_state),
138 device_state_to_string(state));
139
140 unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], true);
141 }
142
143 static int device_coldplug(Unit *u, Hashmap *deferred_work) {
144 Device *d = DEVICE(u);
145
146 assert(d);
147 assert(d->state == DEVICE_DEAD);
148
149 if (d->found & DEVICE_FOUND_UDEV)
150 /* If udev says the device is around, it's around */
151 device_set_state(d, DEVICE_PLUGGED);
152 else if (d->found != DEVICE_NOT_FOUND)
153 /* If a device is found in /proc/self/mountinfo or
154 * /proc/swaps, it's "tentatively" around. */
155 device_set_state(d, DEVICE_TENTATIVE);
156
157 return 0;
158 }
159
160 static void device_dump(Unit *u, FILE *f, const char *prefix) {
161 Device *d = DEVICE(u);
162
163 assert(d);
164
165 fprintf(f,
166 "%sDevice State: %s\n"
167 "%sSysfs Path: %s\n",
168 prefix, device_state_to_string(d->state),
169 prefix, strna(d->sysfs));
170 }
171
172 _pure_ static UnitActiveState device_active_state(Unit *u) {
173 assert(u);
174
175 return state_translation_table[DEVICE(u)->state];
176 }
177
178 _pure_ static const char *device_sub_state_to_string(Unit *u) {
179 assert(u);
180
181 return device_state_to_string(DEVICE(u)->state);
182 }
183
184 static int device_update_description(Unit *u, struct udev_device *dev, const char *path) {
185 const char *model;
186 int r;
187
188 assert(u);
189 assert(dev);
190 assert(path);
191
192 model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE");
193 if (!model)
194 model = udev_device_get_property_value(dev, "ID_MODEL");
195
196 if (model) {
197 const char *label;
198
199 /* Try to concatenate the device model string with a label, if there is one */
200 label = udev_device_get_property_value(dev, "ID_FS_LABEL");
201 if (!label)
202 label = udev_device_get_property_value(dev, "ID_PART_ENTRY_NAME");
203 if (!label)
204 label = udev_device_get_property_value(dev, "ID_PART_ENTRY_NUMBER");
205
206 if (label) {
207 _cleanup_free_ char *j;
208
209 j = strjoin(model, " ", label, NULL);
210 if (j)
211 r = unit_set_description(u, j);
212 else
213 r = -ENOMEM;
214 } else
215 r = unit_set_description(u, model);
216 } else
217 r = unit_set_description(u, path);
218
219 if (r < 0)
220 log_unit_error_errno(u->id, r, "Failed to set device description: %m");
221
222 return r;
223 }
224
225 static int device_add_udev_wants(Unit *u, struct udev_device *dev) {
226 const char *wants;
227 const char *word, *state;
228 size_t l;
229 int r;
230 const char *property;
231
232 assert(u);
233 assert(dev);
234
235 property = u->manager->running_as == SYSTEMD_USER ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS";
236 wants = udev_device_get_property_value(dev, property);
237 if (!wants)
238 return 0;
239
240 FOREACH_WORD_QUOTED(word, l, wants, state) {
241 _cleanup_free_ char *n = NULL;
242 char e[l+1];
243
244 memcpy(e, word, l);
245 e[l] = 0;
246
247 n = unit_name_mangle(e, MANGLE_NOGLOB);
248 if (!n)
249 return log_oom();
250
251 r = unit_add_dependency_by_name(u, UNIT_WANTS, n, NULL, true);
252 if (r < 0)
253 return log_unit_error_errno(u->id, r, "Failed to add wants dependency: %m");
254 }
255 if (!isempty(state))
256 log_unit_warning(u->id, "Property %s on %s has trailing garbage, ignoring.", property, strna(udev_device_get_syspath(dev)));
257
258 return 0;
259 }
260
261 static int device_setup_unit(Manager *m, struct udev_device *dev, const char *path, bool main) {
262 _cleanup_free_ char *e = NULL;
263 const char *sysfs;
264 Unit *u = NULL;
265 bool delete;
266 int r;
267
268 assert(m);
269 assert(dev);
270 assert(path);
271
272 sysfs = udev_device_get_syspath(dev);
273 if (!sysfs)
274 return 0;
275
276 e = unit_name_from_path(path, ".device");
277 if (!e)
278 return log_oom();
279
280 u = manager_get_unit(m, e);
281
282 if (u &&
283 DEVICE(u)->sysfs &&
284 !path_equal(DEVICE(u)->sysfs, sysfs)) {
285 log_unit_debug(u->id, "Device %s appeared twice with different sysfs paths %s and %s", e, DEVICE(u)->sysfs, sysfs);
286 return -EEXIST;
287 }
288
289 if (!u) {
290 delete = true;
291
292 u = unit_new(m, sizeof(Device));
293 if (!u)
294 return log_oom();
295
296 r = unit_add_name(u, e);
297 if (r < 0)
298 goto fail;
299
300 unit_add_to_load_queue(u);
301 } else
302 delete = false;
303
304 /* If this was created via some dependency and has not
305 * actually been seen yet ->sysfs will not be
306 * initialized. Hence initialize it if necessary. */
307
308 r = device_set_sysfs(DEVICE(u), sysfs);
309 if (r < 0)
310 goto fail;
311
312 (void) device_update_description(u, dev, path);
313
314 /* The additional systemd udev properties we only interpret
315 * for the main object */
316 if (main)
317 (void) device_add_udev_wants(u, dev);
318
319 /* Note that this won't dispatch the load queue, the caller
320 * has to do that if needed and appropriate */
321
322 unit_add_to_dbus_queue(u);
323 return 0;
324
325 fail:
326 log_unit_warning_errno(u->id, r, "Failed to set up device unit: %m");
327
328 if (delete)
329 unit_free(u);
330
331 return r;
332 }
333
334 static int device_process_new(Manager *m, struct udev_device *dev) {
335 const char *sysfs, *dn, *alias;
336 struct udev_list_entry *item = NULL, *first = NULL;
337 int r;
338
339 assert(m);
340
341 sysfs = udev_device_get_syspath(dev);
342 if (!sysfs)
343 return 0;
344
345 /* Add the main unit named after the sysfs path */
346 r = device_setup_unit(m, dev, sysfs, true);
347 if (r < 0)
348 return r;
349
350 /* Add an additional unit for the device node */
351 dn = udev_device_get_devnode(dev);
352 if (dn)
353 (void) device_setup_unit(m, dev, dn, false);
354
355 /* Add additional units for all symlinks */
356 first = udev_device_get_devlinks_list_entry(dev);
357 udev_list_entry_foreach(item, first) {
358 const char *p;
359 struct stat st;
360
361 /* Don't bother with the /dev/block links */
362 p = udev_list_entry_get_name(item);
363
364 if (path_startswith(p, "/dev/block/") ||
365 path_startswith(p, "/dev/char/"))
366 continue;
367
368 /* Verify that the symlink in the FS actually belongs
369 * to this device. This is useful to deal with
370 * conflicting devices, e.g. when two disks want the
371 * same /dev/disk/by-label/xxx link because they have
372 * the same label. We want to make sure that the same
373 * device that won the symlink wins in systemd, so we
374 * check the device node major/minor */
375 if (stat(p, &st) >= 0)
376 if ((!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) ||
377 st.st_rdev != udev_device_get_devnum(dev))
378 continue;
379
380 (void) device_setup_unit(m, dev, p, false);
381 }
382
383 /* Add additional units for all explicitly configured
384 * aliases */
385 alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS");
386 if (alias) {
387 const char *word, *state;
388 size_t l;
389
390 FOREACH_WORD_QUOTED(word, l, alias, state) {
391 char e[l+1];
392
393 memcpy(e, word, l);
394 e[l] = 0;
395
396 if (path_is_absolute(e))
397 (void) device_setup_unit(m, dev, e, false);
398 else
399 log_warning("SYSTEMD_ALIAS for %s is not an absolute path, ignoring: %s", sysfs, e);
400 }
401 if (!isempty(state))
402 log_warning("SYSTEMD_ALIAS for %s has trailing garbage, ignoring.", sysfs);
403 }
404
405 return 0;
406 }
407
408 static void device_update_found_one(Device *d, bool add, DeviceFound found, bool now) {
409 DeviceFound n;
410
411 assert(d);
412
413 n = add ? (d->found | found) : (d->found & ~found);
414 if (n == d->found)
415 return;
416
417 d->found = n;
418
419 if (now) {
420 if (d->found & DEVICE_FOUND_UDEV)
421 device_set_state(d, DEVICE_PLUGGED);
422 else if (add && d->found != DEVICE_NOT_FOUND)
423 device_set_state(d, DEVICE_TENTATIVE);
424 else
425 device_set_state(d, DEVICE_DEAD);
426 }
427 }
428
429 static int device_update_found_by_sysfs(Manager *m, const char *sysfs, bool add, DeviceFound found, bool now) {
430 Device *d, *l;
431
432 assert(m);
433 assert(sysfs);
434
435 if (found == DEVICE_NOT_FOUND)
436 return 0;
437
438 l = hashmap_get(m->devices_by_sysfs, sysfs);
439 LIST_FOREACH(same_sysfs, d, l)
440 device_update_found_one(d, add, found, now);
441
442 return 0;
443 }
444
445 static int device_update_found_by_name(Manager *m, const char *path, bool add, DeviceFound found, bool now) {
446 _cleanup_free_ char *e = NULL;
447 Unit *u;
448
449 assert(m);
450 assert(path);
451
452 if (found == DEVICE_NOT_FOUND)
453 return 0;
454
455 e = unit_name_from_path(path, ".device");
456 if (!e)
457 return log_oom();
458
459 u = manager_get_unit(m, e);
460 if (!u)
461 return 0;
462
463 device_update_found_one(DEVICE(u), add, found, now);
464 return 0;
465 }
466
467 static bool device_is_ready(struct udev_device *dev) {
468 const char *ready;
469
470 assert(dev);
471
472 ready = udev_device_get_property_value(dev, "SYSTEMD_READY");
473 if (!ready)
474 return true;
475
476 return parse_boolean(ready) != 0;
477 }
478
479 static Unit *device_following(Unit *u) {
480 Device *d = DEVICE(u);
481 Device *other, *first = NULL;
482
483 assert(d);
484
485 if (startswith(u->id, "sys-"))
486 return NULL;
487
488 /* Make everybody follow the unit that's named after the sysfs path */
489 for (other = d->same_sysfs_next; other; other = other->same_sysfs_next)
490 if (startswith(UNIT(other)->id, "sys-"))
491 return UNIT(other);
492
493 for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev) {
494 if (startswith(UNIT(other)->id, "sys-"))
495 return UNIT(other);
496
497 first = other;
498 }
499
500 return UNIT(first);
501 }
502
503 static int device_following_set(Unit *u, Set **_set) {
504 Device *d = DEVICE(u), *other;
505 Set *set;
506 int r;
507
508 assert(d);
509 assert(_set);
510
511 if (LIST_JUST_US(same_sysfs, d)) {
512 *_set = NULL;
513 return 0;
514 }
515
516 set = set_new(NULL);
517 if (!set)
518 return -ENOMEM;
519
520 LIST_FOREACH_AFTER(same_sysfs, other, d) {
521 r = set_put(set, other);
522 if (r < 0)
523 goto fail;
524 }
525
526 LIST_FOREACH_BEFORE(same_sysfs, other, d) {
527 r = set_put(set, other);
528 if (r < 0)
529 goto fail;
530 }
531
532 *_set = set;
533 return 1;
534
535 fail:
536 set_free(set);
537 return r;
538 }
539
540 static void device_shutdown(Manager *m) {
541 assert(m);
542
543 m->udev_event_source = sd_event_source_unref(m->udev_event_source);
544
545 if (m->udev_monitor) {
546 udev_monitor_unref(m->udev_monitor);
547 m->udev_monitor = NULL;
548 }
549
550 hashmap_free(m->devices_by_sysfs);
551 m->devices_by_sysfs = NULL;
552 }
553
554 static int device_enumerate(Manager *m) {
555 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
556 struct udev_list_entry *item = NULL, *first = NULL;
557 int r;
558
559 assert(m);
560
561 if (!m->udev_monitor) {
562 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
563 if (!m->udev_monitor) {
564 r = -ENOMEM;
565 goto fail;
566 }
567
568 /* This will fail if we are unprivileged, but that
569 * should not matter much, as user instances won't run
570 * during boot. */
571 (void) udev_monitor_set_receive_buffer_size(m->udev_monitor, 128*1024*1024);
572
573 r = udev_monitor_filter_add_match_tag(m->udev_monitor, "systemd");
574 if (r < 0)
575 goto fail;
576
577 r = udev_monitor_enable_receiving(m->udev_monitor);
578 if (r < 0)
579 goto fail;
580
581 r = sd_event_add_io(m->event, &m->udev_event_source, udev_monitor_get_fd(m->udev_monitor), EPOLLIN, device_dispatch_io, m);
582 if (r < 0)
583 goto fail;
584 }
585
586 e = udev_enumerate_new(m->udev);
587 if (!e) {
588 r = -ENOMEM;
589 goto fail;
590 }
591
592 r = udev_enumerate_add_match_tag(e, "systemd");
593 if (r < 0)
594 goto fail;
595
596 r = udev_enumerate_add_match_is_initialized(e);
597 if (r < 0)
598 goto fail;
599
600 r = udev_enumerate_scan_devices(e);
601 if (r < 0)
602 goto fail;
603
604 first = udev_enumerate_get_list_entry(e);
605 udev_list_entry_foreach(item, first) {
606 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
607 const char *sysfs;
608
609 sysfs = udev_list_entry_get_name(item);
610
611 dev = udev_device_new_from_syspath(m->udev, sysfs);
612 if (!dev) {
613 log_oom();
614 continue;
615 }
616
617 if (!device_is_ready(dev))
618 continue;
619
620 (void) device_process_new(m, dev);
621
622 device_update_found_by_sysfs(m, sysfs, true, DEVICE_FOUND_UDEV, false);
623 }
624
625 return 0;
626
627 fail:
628 log_error_errno(r, "Failed to enumerate devices: %m");
629
630 device_shutdown(m);
631 return r;
632 }
633
634 static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
635 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
636 Manager *m = userdata;
637 const char *action, *sysfs;
638 int r;
639
640 assert(m);
641
642 if (revents != EPOLLIN) {
643 static RATELIMIT_DEFINE(limit, 10*USEC_PER_SEC, 5);
644
645 if (!ratelimit_test(&limit))
646 log_error_errno(errno, "Failed to get udev event: %m");
647 if (!(revents & EPOLLIN))
648 return 0;
649 }
650
651 /*
652 * libudev might filter-out devices which pass the bloom
653 * filter, so getting NULL here is not necessarily an error.
654 */
655 dev = udev_monitor_receive_device(m->udev_monitor);
656 if (!dev)
657 return 0;
658
659 sysfs = udev_device_get_syspath(dev);
660 if (!sysfs) {
661 log_error("Failed to get udev sys path.");
662 return 0;
663 }
664
665 action = udev_device_get_action(dev);
666 if (!action) {
667 log_error("Failed to get udev action string.");
668 return 0;
669 }
670
671 if (streq(action, "remove")) {
672 r = swap_process_device_remove(m, dev);
673 if (r < 0)
674 log_error_errno(r, "Failed to process swap device remove event: %m");
675
676 /* If we get notified that a device was removed by
677 * udev, then it's completely gone, hence unset all
678 * found bits */
679 device_update_found_by_sysfs(m, sysfs, false, DEVICE_FOUND_UDEV|DEVICE_FOUND_MOUNT|DEVICE_FOUND_SWAP, true);
680
681 } else if (device_is_ready(dev)) {
682
683 (void) device_process_new(m, dev);
684
685 r = swap_process_device_new(m, dev);
686 if (r < 0)
687 log_error_errno(r, "Failed to process swap device new event: %m");
688
689 manager_dispatch_load_queue(m);
690
691 /* The device is found now, set the udev found bit */
692 device_update_found_by_sysfs(m, sysfs, true, DEVICE_FOUND_UDEV, true);
693
694 } else {
695 /* The device is nominally around, but not ready for
696 * us. Hence unset the udev bit, but leave the rest
697 * around. */
698
699 device_update_found_by_sysfs(m, sysfs, false, DEVICE_FOUND_UDEV, true);
700 }
701
702 return 0;
703 }
704
705 static bool device_supported(Manager *m) {
706 static int read_only = -1;
707 assert(m);
708
709 /* If /sys is read-only we don't support device units, and any
710 * attempts to start one should fail immediately. */
711
712 if (read_only < 0)
713 read_only = path_is_read_only_fs("/sys");
714
715 return read_only <= 0;
716 }
717
718 int device_found_node(Manager *m, const char *node, bool add, DeviceFound found, bool now) {
719 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
720 struct stat st;
721
722 assert(m);
723 assert(node);
724
725 /* This is called whenever we find a device referenced in
726 * /proc/swaps or /proc/self/mounts. Such a device might be
727 * mounted/enabled at a time where udev has not finished
728 * probing it yet, and we thus haven't learned about it
729 * yet. In this case we will set the device unit to
730 * "tentative" state. */
731
732 if (add) {
733 if (!path_startswith(node, "/dev"))
734 return 0;
735
736 if (stat(node, &st) < 0) {
737 if (errno == ENOENT)
738 return 0;
739
740 return log_error_errno(errno, "Failed to stat device node file %s: %m", node);
741 }
742
743 if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode))
744 return 0;
745
746 dev = udev_device_new_from_devnum(m->udev, S_ISBLK(st.st_mode) ? 'b' : 'c', st.st_rdev);
747 if (!dev) {
748 if (errno == ENOENT)
749 return 0;
750
751 return log_oom();
752 }
753
754 /* If the device is known in the kernel and newly
755 * appeared, then we'll create a device unit for it,
756 * under the name referenced in /proc/swaps or
757 * /proc/self/mountinfo. */
758
759 (void) device_setup_unit(m, dev, node, false);
760 }
761
762 /* Update the device unit's state, should it exist */
763 return device_update_found_by_name(m, node, add, found, now);
764 }
765
766 static const char* const device_state_table[_DEVICE_STATE_MAX] = {
767 [DEVICE_DEAD] = "dead",
768 [DEVICE_TENTATIVE] = "tentative",
769 [DEVICE_PLUGGED] = "plugged",
770 };
771
772 DEFINE_STRING_TABLE_LOOKUP(device_state, DeviceState);
773
774 const UnitVTable device_vtable = {
775 .object_size = sizeof(Device),
776 .sections =
777 "Unit\0"
778 "Device\0"
779 "Install\0",
780
781 .no_instances = true,
782
783 .init = device_init,
784 .done = device_done,
785 .load = unit_load_fragment_and_dropin_optional,
786
787 .coldplug = device_coldplug,
788
789 .dump = device_dump,
790
791 .active_state = device_active_state,
792 .sub_state_to_string = device_sub_state_to_string,
793
794 .bus_interface = "org.freedesktop.systemd1.Device",
795 .bus_vtable = bus_device_vtable,
796
797 .following = device_following,
798 .following_set = device_following_set,
799
800 .enumerate = device_enumerate,
801 .shutdown = device_shutdown,
802 .supported = device_supported,
803
804 .status_message_formats = {
805 .starting_stopping = {
806 [0] = "Expecting device %s...",
807 },
808 .finished_start_job = {
809 [JOB_DONE] = "Found device %s.",
810 [JOB_TIMEOUT] = "Timed out waiting for device %s.",
811 },
812 },
813 };