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