]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/device.c
tree-wide: drop license boilerplate
[thirdparty/systemd.git] / src / core / device.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2010 Lennart Poettering
6 ***/
7
8 #include <errno.h>
9 #include <sys/epoll.h>
10
11 #include "libudev.h"
12
13 #include "alloc-util.h"
14 #include "dbus-device.h"
15 #include "device.h"
16 #include "log.h"
17 #include "parse-util.h"
18 #include "path-util.h"
19 #include "stat-util.h"
20 #include "string-util.h"
21 #include "swap.h"
22 #include "udev-util.h"
23 #include "unit-name.h"
24 #include "unit.h"
25
26 static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = {
27 [DEVICE_DEAD] = UNIT_INACTIVE,
28 [DEVICE_TENTATIVE] = UNIT_ACTIVATING,
29 [DEVICE_PLUGGED] = UNIT_ACTIVE,
30 };
31
32 static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
33
34 static void device_unset_sysfs(Device *d) {
35 Hashmap *devices;
36 Device *first;
37
38 assert(d);
39
40 if (!d->sysfs)
41 return;
42
43 /* Remove this unit from the chain of devices which share the
44 * same sysfs path. */
45 devices = UNIT(d)->manager->devices_by_sysfs;
46 first = hashmap_get(devices, d->sysfs);
47 LIST_REMOVE(same_sysfs, first, d);
48
49 if (first)
50 hashmap_remove_and_replace(devices, d->sysfs, first->sysfs, first);
51 else
52 hashmap_remove(devices, d->sysfs);
53
54 d->sysfs = mfree(d->sysfs);
55 }
56
57 static int device_set_sysfs(Device *d, const char *sysfs) {
58 Device *first;
59 char *copy;
60 int r;
61
62 assert(d);
63
64 if (streq_ptr(d->sysfs, sysfs))
65 return 0;
66
67 r = hashmap_ensure_allocated(&UNIT(d)->manager->devices_by_sysfs, &path_hash_ops);
68 if (r < 0)
69 return r;
70
71 copy = strdup(sysfs);
72 if (!copy)
73 return -ENOMEM;
74
75 device_unset_sysfs(d);
76
77 first = hashmap_get(UNIT(d)->manager->devices_by_sysfs, sysfs);
78 LIST_PREPEND(same_sysfs, first, d);
79
80 r = hashmap_replace(UNIT(d)->manager->devices_by_sysfs, copy, first);
81 if (r < 0) {
82 LIST_REMOVE(same_sysfs, first, d);
83 free(copy);
84 return r;
85 }
86
87 d->sysfs = copy;
88
89 return 0;
90 }
91
92 static void device_init(Unit *u) {
93 Device *d = DEVICE(u);
94
95 assert(d);
96 assert(UNIT(d)->load_state == UNIT_STUB);
97
98 /* In contrast to all other unit types we timeout jobs waiting
99 * for devices by default. This is because they otherwise wait
100 * indefinitely for plugged in devices, something which cannot
101 * happen for the other units since their operations time out
102 * anyway. */
103 u->job_running_timeout = u->manager->default_timeout_start_usec;
104
105 u->ignore_on_isolate = true;
106 }
107
108 static void device_done(Unit *u) {
109 Device *d = DEVICE(u);
110
111 assert(d);
112
113 device_unset_sysfs(d);
114 }
115
116 static void device_set_state(Device *d, DeviceState state) {
117 DeviceState old_state;
118 assert(d);
119
120 old_state = d->state;
121 d->state = state;
122
123 if (state != old_state)
124 log_unit_debug(UNIT(d), "Changed %s -> %s", device_state_to_string(old_state), device_state_to_string(state));
125
126 unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], true);
127 }
128
129 static int device_coldplug(Unit *u) {
130 Device *d = DEVICE(u);
131
132 assert(d);
133 assert(d->state == DEVICE_DEAD);
134
135 if (d->found & DEVICE_FOUND_UDEV)
136 /* If udev says the device is around, it's around */
137 device_set_state(d, DEVICE_PLUGGED);
138 else if (d->found != DEVICE_NOT_FOUND && d->deserialized_state != DEVICE_PLUGGED)
139 /* If a device is found in /proc/self/mountinfo or
140 * /proc/swaps, and was not yet announced via udev,
141 * it's "tentatively" around. */
142 device_set_state(d, DEVICE_TENTATIVE);
143
144 return 0;
145 }
146
147 static int device_serialize(Unit *u, FILE *f, FDSet *fds) {
148 Device *d = DEVICE(u);
149
150 assert(u);
151 assert(f);
152 assert(fds);
153
154 unit_serialize_item(u, f, "state", device_state_to_string(d->state));
155
156 return 0;
157 }
158
159 static int device_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
160 Device *d = DEVICE(u);
161
162 assert(u);
163 assert(key);
164 assert(value);
165 assert(fds);
166
167 if (streq(key, "state")) {
168 DeviceState state;
169
170 state = device_state_from_string(value);
171 if (state < 0)
172 log_unit_debug(u, "Failed to parse state value: %s", value);
173 else
174 d->deserialized_state = state;
175 } else
176 log_unit_debug(u, "Unknown serialization key: %s", key);
177
178 return 0;
179 }
180
181 static void device_dump(Unit *u, FILE *f, const char *prefix) {
182 Device *d = DEVICE(u);
183
184 assert(d);
185
186 fprintf(f,
187 "%sDevice State: %s\n"
188 "%sSysfs Path: %s\n",
189 prefix, device_state_to_string(d->state),
190 prefix, strna(d->sysfs));
191 }
192
193 _pure_ static UnitActiveState device_active_state(Unit *u) {
194 assert(u);
195
196 return state_translation_table[DEVICE(u)->state];
197 }
198
199 _pure_ static const char *device_sub_state_to_string(Unit *u) {
200 assert(u);
201
202 return device_state_to_string(DEVICE(u)->state);
203 }
204
205 static int device_update_description(Unit *u, struct udev_device *dev, const char *path) {
206 const char *model;
207 int r;
208
209 assert(u);
210 assert(dev);
211 assert(path);
212
213 model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE");
214 if (!model)
215 model = udev_device_get_property_value(dev, "ID_MODEL");
216
217 if (model) {
218 const char *label;
219
220 /* Try to concatenate the device model string with a label, if there is one */
221 label = udev_device_get_property_value(dev, "ID_FS_LABEL");
222 if (!label)
223 label = udev_device_get_property_value(dev, "ID_PART_ENTRY_NAME");
224 if (!label)
225 label = udev_device_get_property_value(dev, "ID_PART_ENTRY_NUMBER");
226
227 if (label) {
228 _cleanup_free_ char *j;
229
230 j = strjoin(model, " ", label);
231 if (j)
232 r = unit_set_description(u, j);
233 else
234 r = -ENOMEM;
235 } else
236 r = unit_set_description(u, model);
237 } else
238 r = unit_set_description(u, path);
239
240 if (r < 0)
241 log_unit_error_errno(u, r, "Failed to set device description: %m");
242
243 return r;
244 }
245
246 static int device_add_udev_wants(Unit *u, struct udev_device *dev) {
247 const char *wants, *property;
248 int r;
249
250 assert(u);
251 assert(dev);
252
253 property = MANAGER_IS_USER(u->manager) ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS";
254
255 wants = udev_device_get_property_value(dev, property);
256 if (!wants)
257 return 0;
258
259 for (;;) {
260 _cleanup_free_ char *word = NULL, *k = NULL;
261
262 r = extract_first_word(&wants, &word, NULL, EXTRACT_QUOTES);
263 if (r == 0)
264 return 0;
265 if (r == -ENOMEM)
266 return log_oom();
267 if (r < 0)
268 return log_unit_error_errno(u, r, "Failed to parse property %s with value %s: %m", property, wants);
269
270 if (unit_name_is_valid(word, UNIT_NAME_TEMPLATE) && DEVICE(u)->sysfs) {
271 _cleanup_free_ char *escaped = NULL;
272
273 /* If the unit name is specified as template, then automatically fill in the sysfs path of the
274 * device as instance name, properly escaped. */
275
276 r = unit_name_path_escape(DEVICE(u)->sysfs, &escaped);
277 if (r < 0)
278 return log_unit_error_errno(u, r, "Failed to escape %s: %m", DEVICE(u)->sysfs);
279
280 r = unit_name_replace_instance(word, escaped, &k);
281 if (r < 0)
282 return log_unit_error_errno(u, r, "Failed to build %s instance of template %s: %m", escaped, word);
283 } else {
284 /* If this is not a template, then let's mangle it so, that it becomes a valid unit name. */
285
286 r = unit_name_mangle(word, UNIT_NAME_MANGLE_WARN, &k);
287 if (r < 0)
288 return log_unit_error_errno(u, r, "Failed to mangle unit name \"%s\": %m", word);
289 }
290
291 r = unit_add_dependency_by_name(u, UNIT_WANTS, k, NULL, true, UNIT_DEPENDENCY_UDEV);
292 if (r < 0)
293 return log_unit_error_errno(u, r, "Failed to add Wants= dependency: %m");
294 }
295 }
296
297 static bool device_is_bound_by_mounts(Device *d, struct udev_device *dev) {
298 const char *bound_by;
299 int r;
300
301 assert(d);
302 assert(dev);
303
304 bound_by = udev_device_get_property_value(dev, "SYSTEMD_MOUNT_DEVICE_BOUND");
305 if (bound_by) {
306 r = parse_boolean(bound_by);
307 if (r < 0)
308 log_warning_errno(r, "Failed to parse SYSTEMD_MOUNT_DEVICE_BOUND='%s' udev property of %s, ignoring: %m", bound_by, strna(d->sysfs));
309
310 d->bind_mounts = r > 0;
311 } else
312 d->bind_mounts = false;
313
314 return d->bind_mounts;
315 }
316
317 static int device_upgrade_mount_deps(Unit *u) {
318 Unit *other;
319 Iterator i;
320 void *v;
321 int r;
322
323 /* Let's upgrade Requires= to BindsTo= on us. (Used when SYSTEMD_MOUNT_DEVICE_BOUND is set) */
324
325 HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_REQUIRED_BY], i) {
326 if (other->type != UNIT_MOUNT)
327 continue;
328
329 r = unit_add_dependency(other, UNIT_BINDS_TO, u, true, UNIT_DEPENDENCY_UDEV);
330 if (r < 0)
331 return r;
332 }
333 return 0;
334 }
335
336 static int device_setup_unit(Manager *m, struct udev_device *dev, const char *path, bool main) {
337 _cleanup_free_ char *e = NULL;
338 const char *sysfs = NULL;
339 Unit *u = NULL;
340 bool delete;
341 int r;
342
343 assert(m);
344 assert(path);
345
346 if (dev) {
347 sysfs = udev_device_get_syspath(dev);
348 if (!sysfs)
349 return 0;
350 }
351
352 r = unit_name_from_path(path, ".device", &e);
353 if (r < 0)
354 return log_error_errno(r, "Failed to generate unit name from device path: %m");
355
356 u = manager_get_unit(m, e);
357 if (u) {
358 /* The device unit can still be present even if the device was unplugged: a mount unit can reference it hence
359 * preventing the GC to have garbaged it. That's desired since the device unit may have a dependency on the
360 * mount unit which was added during the loading of the later. */
361 if (dev && DEVICE(u)->state == DEVICE_PLUGGED) {
362
363 /* This unit is in plugged state: we're sure it's attached to a device. */
364 if (!path_equal(DEVICE(u)->sysfs, sysfs)) {
365 log_unit_debug(u, "Dev %s appeared twice with different sysfs paths %s and %s",
366 e, DEVICE(u)->sysfs, sysfs);
367 return -EEXIST;
368 }
369 }
370
371 delete = false;
372
373 /* Let's remove all dependencies generated due to udev properties. We'll readd whatever is configured
374 * now below. */
375 unit_remove_dependencies(u, UNIT_DEPENDENCY_UDEV);
376 } else {
377 delete = true;
378
379 r = unit_new_for_name(m, sizeof(Device), e, &u);
380 if (r < 0)
381 goto fail;
382
383 unit_add_to_load_queue(u);
384 }
385
386 /* If this was created via some dependency and has not
387 * actually been seen yet ->sysfs will not be
388 * initialized. Hence initialize it if necessary. */
389 if (sysfs) {
390 r = device_set_sysfs(DEVICE(u), sysfs);
391 if (r < 0)
392 goto fail;
393
394 (void) device_update_description(u, dev, path);
395
396 /* The additional systemd udev properties we only interpret
397 * for the main object */
398 if (main)
399 (void) device_add_udev_wants(u, dev);
400 }
401
402 /* So the user wants the mount units to be bound to the device but a mount unit might has been seen by systemd
403 * before the device appears on its radar. In this case the device unit is partially initialized and includes
404 * the deps on the mount unit but at that time the "bind mounts" flag wasn't not present. Fix this up now. */
405 if (dev && device_is_bound_by_mounts(DEVICE(u), dev))
406 device_upgrade_mount_deps(u);
407
408 /* Note that this won't dispatch the load queue, the caller has to do that if needed and appropriate */
409
410 unit_add_to_dbus_queue(u);
411 return 0;
412
413 fail:
414 log_unit_warning_errno(u, r, "Failed to set up device unit: %m");
415
416 if (delete)
417 unit_free(u);
418
419 return r;
420 }
421
422 static int device_process_new(Manager *m, struct udev_device *dev) {
423 const char *sysfs, *dn, *alias;
424 struct udev_list_entry *item = NULL, *first = NULL;
425 int r;
426
427 assert(m);
428
429 sysfs = udev_device_get_syspath(dev);
430 if (!sysfs)
431 return 0;
432
433 /* Add the main unit named after the sysfs path */
434 r = device_setup_unit(m, dev, sysfs, true);
435 if (r < 0)
436 return r;
437
438 /* Add an additional unit for the device node */
439 dn = udev_device_get_devnode(dev);
440 if (dn)
441 (void) device_setup_unit(m, dev, dn, false);
442
443 /* Add additional units for all symlinks */
444 first = udev_device_get_devlinks_list_entry(dev);
445 udev_list_entry_foreach(item, first) {
446 const char *p;
447 struct stat st;
448
449 /* Don't bother with the /dev/block links */
450 p = udev_list_entry_get_name(item);
451
452 if (path_startswith(p, "/dev/block/") ||
453 path_startswith(p, "/dev/char/"))
454 continue;
455
456 /* Verify that the symlink in the FS actually belongs
457 * to this device. This is useful to deal with
458 * conflicting devices, e.g. when two disks want the
459 * same /dev/disk/by-label/xxx link because they have
460 * the same label. We want to make sure that the same
461 * device that won the symlink wins in systemd, so we
462 * check the device node major/minor */
463 if (stat(p, &st) >= 0)
464 if ((!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) ||
465 st.st_rdev != udev_device_get_devnum(dev))
466 continue;
467
468 (void) device_setup_unit(m, dev, p, false);
469 }
470
471 /* Add additional units for all explicitly configured
472 * aliases */
473 alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS");
474 for (;;) {
475 _cleanup_free_ char *word = NULL;
476
477 r = extract_first_word(&alias, &word, NULL, EXTRACT_QUOTES);
478 if (r == 0)
479 return 0;
480 if (r == -ENOMEM)
481 return log_oom();
482 if (r < 0)
483 return log_warning_errno(r, "Failed to add parse SYSTEMD_ALIAS for %s: %m", sysfs);
484
485 if (path_is_absolute(word))
486 (void) device_setup_unit(m, dev, word, false);
487 else
488 log_warning("SYSTEMD_ALIAS for %s is not an absolute path, ignoring: %s", sysfs, word);
489 }
490 }
491
492 static void device_update_found_one(Device *d, bool add, DeviceFound found, bool now) {
493 DeviceFound n, previous;
494
495 assert(d);
496
497 n = add ? (d->found | found) : (d->found & ~found);
498 if (n == d->found)
499 return;
500
501 previous = d->found;
502 d->found = n;
503
504 if (!now)
505 return;
506
507 /* Didn't exist before, but does now? if so, generate a new invocation ID for it */
508 if (previous == DEVICE_NOT_FOUND && d->found != DEVICE_NOT_FOUND)
509 (void) unit_acquire_invocation_id(UNIT(d));
510
511 if (d->found & DEVICE_FOUND_UDEV)
512 /* When the device is known to udev we consider it
513 * plugged. */
514 device_set_state(d, DEVICE_PLUGGED);
515 else if (d->found != DEVICE_NOT_FOUND && (previous & DEVICE_FOUND_UDEV) == 0)
516 /* If the device has not been seen by udev yet, but is
517 * now referenced by the kernel, then we assume the
518 * kernel knows it now, and udev might soon too. */
519 device_set_state(d, DEVICE_TENTATIVE);
520 else {
521 /* If nobody sees the device, or if the device was
522 * previously seen by udev and now is only referenced
523 * from the kernel, then we consider the device is
524 * gone, the kernel just hasn't noticed it yet. */
525
526 device_set_state(d, DEVICE_DEAD);
527 device_unset_sysfs(d);
528 }
529
530 }
531
532 static int device_update_found_by_sysfs(Manager *m, const char *sysfs, bool add, DeviceFound found, bool now) {
533 Device *d, *l, *n;
534
535 assert(m);
536 assert(sysfs);
537
538 if (found == DEVICE_NOT_FOUND)
539 return 0;
540
541 l = hashmap_get(m->devices_by_sysfs, sysfs);
542 LIST_FOREACH_SAFE(same_sysfs, d, n, l)
543 device_update_found_one(d, add, found, now);
544
545 return 0;
546 }
547
548 static int device_update_found_by_name(Manager *m, const char *path, bool add, DeviceFound found, bool now) {
549 _cleanup_free_ char *e = NULL;
550 Unit *u;
551 int r;
552
553 assert(m);
554 assert(path);
555
556 if (found == DEVICE_NOT_FOUND)
557 return 0;
558
559 r = unit_name_from_path(path, ".device", &e);
560 if (r < 0)
561 return log_error_errno(r, "Failed to generate unit name from device path: %m");
562
563 u = manager_get_unit(m, e);
564 if (!u)
565 return 0;
566
567 device_update_found_one(DEVICE(u), add, found, now);
568 return 0;
569 }
570
571 static bool device_is_ready(struct udev_device *dev) {
572 const char *ready;
573
574 assert(dev);
575
576 ready = udev_device_get_property_value(dev, "SYSTEMD_READY");
577 if (!ready)
578 return true;
579
580 return parse_boolean(ready) != 0;
581 }
582
583 static Unit *device_following(Unit *u) {
584 Device *d = DEVICE(u);
585 Device *other, *first = NULL;
586
587 assert(d);
588
589 if (startswith(u->id, "sys-"))
590 return NULL;
591
592 /* Make everybody follow the unit that's named after the sysfs path */
593 for (other = d->same_sysfs_next; other; other = other->same_sysfs_next)
594 if (startswith(UNIT(other)->id, "sys-"))
595 return UNIT(other);
596
597 for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev) {
598 if (startswith(UNIT(other)->id, "sys-"))
599 return UNIT(other);
600
601 first = other;
602 }
603
604 return UNIT(first);
605 }
606
607 static int device_following_set(Unit *u, Set **_set) {
608 Device *d = DEVICE(u), *other;
609 Set *set;
610 int r;
611
612 assert(d);
613 assert(_set);
614
615 if (LIST_JUST_US(same_sysfs, d)) {
616 *_set = NULL;
617 return 0;
618 }
619
620 set = set_new(NULL);
621 if (!set)
622 return -ENOMEM;
623
624 LIST_FOREACH_AFTER(same_sysfs, other, d) {
625 r = set_put(set, other);
626 if (r < 0)
627 goto fail;
628 }
629
630 LIST_FOREACH_BEFORE(same_sysfs, other, d) {
631 r = set_put(set, other);
632 if (r < 0)
633 goto fail;
634 }
635
636 *_set = set;
637 return 1;
638
639 fail:
640 set_free(set);
641 return r;
642 }
643
644 static void device_shutdown(Manager *m) {
645 assert(m);
646
647 m->udev_event_source = sd_event_source_unref(m->udev_event_source);
648 m->udev_monitor = udev_monitor_unref(m->udev_monitor);
649 m->devices_by_sysfs = hashmap_free(m->devices_by_sysfs);
650 }
651
652 static void device_enumerate(Manager *m) {
653 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
654 struct udev_list_entry *item = NULL, *first = NULL;
655 int r;
656
657 assert(m);
658
659 if (!m->udev_monitor) {
660 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
661 if (!m->udev_monitor) {
662 log_oom();
663 goto fail;
664 }
665
666 /* This will fail if we are unprivileged, but that
667 * should not matter much, as user instances won't run
668 * during boot. */
669 (void) udev_monitor_set_receive_buffer_size(m->udev_monitor, 128*1024*1024);
670
671 r = udev_monitor_filter_add_match_tag(m->udev_monitor, "systemd");
672 if (r < 0) {
673 log_error_errno(r, "Failed to add udev tag match: %m");
674 goto fail;
675 }
676
677 r = udev_monitor_enable_receiving(m->udev_monitor);
678 if (r < 0) {
679 log_error_errno(r, "Failed to enable udev event reception: %m");
680 goto fail;
681 }
682
683 r = sd_event_add_io(m->event, &m->udev_event_source, udev_monitor_get_fd(m->udev_monitor), EPOLLIN, device_dispatch_io, m);
684 if (r < 0) {
685 log_error_errno(r, "Failed to watch udev file descriptor: %m");
686 goto fail;
687 }
688
689 (void) sd_event_source_set_description(m->udev_event_source, "device");
690 }
691
692 e = udev_enumerate_new(m->udev);
693 if (!e) {
694 log_oom();
695 goto fail;
696 }
697
698 r = udev_enumerate_add_match_tag(e, "systemd");
699 if (r < 0) {
700 log_error_errno(r, "Failed to create udev tag enumeration: %m");
701 goto fail;
702 }
703
704 r = udev_enumerate_add_match_is_initialized(e);
705 if (r < 0) {
706 log_error_errno(r, "Failed to install initialization match into enumeration: %m");
707 goto fail;
708 }
709
710 r = udev_enumerate_scan_devices(e);
711 if (r < 0) {
712 log_error_errno(r, "Failed to enumerate devices: %m");
713 goto fail;
714 }
715
716 first = udev_enumerate_get_list_entry(e);
717 udev_list_entry_foreach(item, first) {
718 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
719 const char *sysfs;
720
721 sysfs = udev_list_entry_get_name(item);
722
723 dev = udev_device_new_from_syspath(m->udev, sysfs);
724 if (!dev) {
725 log_oom();
726 continue;
727 }
728
729 if (!device_is_ready(dev))
730 continue;
731
732 (void) device_process_new(m, dev);
733
734 device_update_found_by_sysfs(m, sysfs, true, DEVICE_FOUND_UDEV, false);
735 }
736
737 return;
738
739 fail:
740 device_shutdown(m);
741 }
742
743 static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
744 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
745 Manager *m = userdata;
746 const char *action, *sysfs;
747 int r;
748
749 assert(m);
750
751 if (revents != EPOLLIN) {
752 static RATELIMIT_DEFINE(limit, 10*USEC_PER_SEC, 5);
753
754 if (!ratelimit_test(&limit))
755 log_error_errno(errno, "Failed to get udev event: %m");
756 if (!(revents & EPOLLIN))
757 return 0;
758 }
759
760 /*
761 * libudev might filter-out devices which pass the bloom
762 * filter, so getting NULL here is not necessarily an error.
763 */
764 dev = udev_monitor_receive_device(m->udev_monitor);
765 if (!dev)
766 return 0;
767
768 sysfs = udev_device_get_syspath(dev);
769 if (!sysfs) {
770 log_error("Failed to get udev sys path.");
771 return 0;
772 }
773
774 action = udev_device_get_action(dev);
775 if (!action) {
776 log_error("Failed to get udev action string.");
777 return 0;
778 }
779
780 if (streq(action, "change")) {
781 Unit *u;
782 Device *d, *l, *n;
783
784 l = hashmap_get(m->devices_by_sysfs, sysfs);
785 LIST_FOREACH_SAFE(same_sysfs, d, n, l) {
786 u = &d->meta;
787 if (u && UNIT_VTABLE(u)->active_state(u) == UNIT_ACTIVE) {
788 r = manager_propagate_reload(m, u, JOB_REPLACE, NULL);
789 if (r < 0)
790 log_error_errno(r, "Failed to propagate reload: %m");
791 }
792 }
793 }
794
795 /* A change event can signal that a device is becoming ready, in particular if
796 * the device is using the SYSTEMD_READY logic in udev
797 * so we need to reach the else block of the follwing if, even for change events */
798 if (streq(action, "remove")) {
799 r = swap_process_device_remove(m, dev);
800 if (r < 0)
801 log_error_errno(r, "Failed to process swap device remove event: %m");
802
803 /* If we get notified that a device was removed by
804 * udev, then it's completely gone, hence unset all
805 * found bits */
806 device_update_found_by_sysfs(m, sysfs, false, DEVICE_FOUND_UDEV|DEVICE_FOUND_MOUNT|DEVICE_FOUND_SWAP, true);
807
808 } else if (device_is_ready(dev)) {
809
810 (void) device_process_new(m, dev);
811
812 r = swap_process_device_new(m, dev);
813 if (r < 0)
814 log_error_errno(r, "Failed to process swap device new event: %m");
815
816 manager_dispatch_load_queue(m);
817
818 /* The device is found now, set the udev found bit */
819 device_update_found_by_sysfs(m, sysfs, true, DEVICE_FOUND_UDEV, true);
820
821 } else {
822 /* The device is nominally around, but not ready for
823 * us. Hence unset the udev bit, but leave the rest
824 * around. */
825
826 device_update_found_by_sysfs(m, sysfs, false, DEVICE_FOUND_UDEV, true);
827 }
828
829 return 0;
830 }
831
832 static bool device_supported(void) {
833 static int read_only = -1;
834
835 /* If /sys is read-only we don't support device units, and any
836 * attempts to start one should fail immediately. */
837
838 if (read_only < 0)
839 read_only = path_is_read_only_fs("/sys");
840
841 return read_only <= 0;
842 }
843
844 int device_found_node(Manager *m, const char *node, bool add, DeviceFound found, bool now) {
845 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
846 struct stat st;
847
848 assert(m);
849 assert(node);
850
851 if (!device_supported())
852 return 0;
853
854 /* This is called whenever we find a device referenced in
855 * /proc/swaps or /proc/self/mounts. Such a device might be
856 * mounted/enabled at a time where udev has not finished
857 * probing it yet, and we thus haven't learned about it
858 * yet. In this case we will set the device unit to
859 * "tentative" state. */
860
861 if (add) {
862 if (!path_startswith(node, "/dev"))
863 return 0;
864
865 /* We make an extra check here, if the device node
866 * actually exists. If it's missing, then this is an
867 * indication that device was unplugged but is still
868 * referenced in /proc/swaps or
869 * /proc/self/mountinfo. Note that this check doesn't
870 * really cover all cases where a device might be gone
871 * away, since drives that can have a medium inserted
872 * will still have a device node even when the medium
873 * is not there... */
874
875 if (stat(node, &st) >= 0) {
876 if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode))
877 return 0;
878
879 dev = udev_device_new_from_devnum(m->udev, S_ISBLK(st.st_mode) ? 'b' : 'c', st.st_rdev);
880 if (!dev && errno != ENOENT)
881 return log_error_errno(errno, "Failed to get udev device from devnum %u:%u: %m", major(st.st_rdev), minor(st.st_rdev));
882
883 } else if (errno != ENOENT)
884 return log_error_errno(errno, "Failed to stat device node file %s: %m", node);
885
886 /* If the device is known in the kernel and newly
887 * appeared, then we'll create a device unit for it,
888 * under the name referenced in /proc/swaps or
889 * /proc/self/mountinfo. */
890
891 (void) device_setup_unit(m, dev, node, false);
892 }
893
894 /* Update the device unit's state, should it exist */
895 return device_update_found_by_name(m, node, add, found, now);
896 }
897
898 bool device_shall_be_bound_by(Unit *device, Unit *u) {
899
900 if (u->type != UNIT_MOUNT)
901 return false;
902
903 return DEVICE(device)->bind_mounts;
904 }
905
906 const UnitVTable device_vtable = {
907 .object_size = sizeof(Device),
908 .sections =
909 "Unit\0"
910 "Device\0"
911 "Install\0",
912
913 .gc_jobs = true,
914
915 .init = device_init,
916 .done = device_done,
917 .load = unit_load_fragment_and_dropin_optional,
918
919 .coldplug = device_coldplug,
920
921 .serialize = device_serialize,
922 .deserialize_item = device_deserialize_item,
923
924 .dump = device_dump,
925
926 .active_state = device_active_state,
927 .sub_state_to_string = device_sub_state_to_string,
928
929 .bus_vtable = bus_device_vtable,
930
931 .following = device_following,
932 .following_set = device_following_set,
933
934 .enumerate = device_enumerate,
935 .shutdown = device_shutdown,
936 .supported = device_supported,
937
938 .status_message_formats = {
939 .starting_stopping = {
940 [0] = "Expecting device %s...",
941 },
942 .finished_start_job = {
943 [JOB_DONE] = "Found device %s.",
944 [JOB_TIMEOUT] = "Timed out waiting for device %s.",
945 },
946 },
947 };