]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/device.c
tree-wide: drop license boilerplate
[thirdparty/systemd.git] / src / core / device.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
a7334b09
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2010 Lennart Poettering
a7334b09
LP
6***/
7
25ac040b 8#include <errno.h>
f94ea366 9#include <sys/epoll.h>
25ac040b 10
b4bbcaa9
TA
11#include "libudev.h"
12
b5efdb8a 13#include "alloc-util.h"
4139c1b2 14#include "dbus-device.h"
6bedfcbb 15#include "device.h"
07630cea 16#include "log.h"
6bedfcbb 17#include "parse-util.h"
9eb977db 18#include "path-util.h"
8fcde012 19#include "stat-util.h"
07630cea
LP
20#include "string-util.h"
21#include "swap.h"
718db961 22#include "udev-util.h"
07630cea 23#include "unit-name.h"
9670d583 24#include "unit.h"
5cb5a6ff 25
f50e0a01
LP
26static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = {
27 [DEVICE_DEAD] = UNIT_INACTIVE,
628c89cc
LP
28 [DEVICE_TENTATIVE] = UNIT_ACTIVATING,
29 [DEVICE_PLUGGED] = UNIT_ACTIVE,
f50e0a01
LP
30};
31
718db961
LP
32static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
33
8fe914ec 34static void device_unset_sysfs(Device *d) {
f1421cc6 35 Hashmap *devices;
8fe914ec
LP
36 Device *first;
37
38 assert(d);
39
a7f241db
LP
40 if (!d->sysfs)
41 return;
42
43 /* Remove this unit from the chain of devices which share the
44 * same sysfs path. */
f1421cc6
LP
45 devices = UNIT(d)->manager->devices_by_sysfs;
46 first = hashmap_get(devices, d->sysfs);
71fda00f 47 LIST_REMOVE(same_sysfs, first, d);
8fe914ec 48
a7f241db 49 if (first)
f1421cc6 50 hashmap_remove_and_replace(devices, d->sysfs, first->sysfs, first);
a7f241db 51 else
f1421cc6 52 hashmap_remove(devices, d->sysfs);
a7f241db 53
a1e58e8e 54 d->sysfs = mfree(d->sysfs);
8fe914ec
LP
55}
56
628c89cc
LP
57static 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
548f6937 67 r = hashmap_ensure_allocated(&UNIT(d)->manager->devices_by_sysfs, &path_hash_ops);
628c89cc
LP
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
faf919f1
LP
92static void device_init(Unit *u) {
93 Device *d = DEVICE(u);
94
95 assert(d);
1124fe6f 96 assert(UNIT(d)->load_state == UNIT_STUB);
faf919f1 97
8fe914ec
LP
98 /* In contrast to all other unit types we timeout jobs waiting
99 * for devices by default. This is because they otherwise wait
35b8ca3a 100 * indefinitely for plugged in devices, something which cannot
8fe914ec
LP
101 * happen for the other units since their operations time out
102 * anyway. */
d9732d78 103 u->job_running_timeout = u->manager->default_timeout_start_usec;
c8f4d764 104
f1421cc6 105 u->ignore_on_isolate = true;
faf919f1
LP
106}
107
87f0e418
LP
108static void device_done(Unit *u) {
109 Device *d = DEVICE(u);
034c6ed7
LP
110
111 assert(d);
e537352b 112
8fe914ec 113 device_unset_sysfs(d);
e537352b
LP
114}
115
f50e0a01
LP
116static void device_set_state(Device *d, DeviceState state) {
117 DeviceState old_state;
118 assert(d);
5cb5a6ff 119
f50e0a01
LP
120 old_state = d->state;
121 d->state = state;
5cb5a6ff 122
e537352b 123 if (state != old_state)
f2341e0a 124 log_unit_debug(UNIT(d), "Changed %s -> %s", device_state_to_string(old_state), device_state_to_string(state));
f50e0a01 125
e2f3b44c 126 unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], true);
f50e0a01
LP
127}
128
be847e82 129static int device_coldplug(Unit *u) {
f50e0a01
LP
130 Device *d = DEVICE(u);
131
132 assert(d);
133 assert(d->state == DEVICE_DEAD);
134
628c89cc
LP
135 if (d->found & DEVICE_FOUND_UDEV)
136 /* If udev says the device is around, it's around */
73608ed9 137 device_set_state(d, DEVICE_PLUGGED);
f6200941 138 else if (d->found != DEVICE_NOT_FOUND && d->deserialized_state != DEVICE_PLUGGED)
628c89cc 139 /* If a device is found in /proc/self/mountinfo or
f6200941
LP
140 * /proc/swaps, and was not yet announced via udev,
141 * it's "tentatively" around. */
628c89cc 142 device_set_state(d, DEVICE_TENTATIVE);
f50e0a01
LP
143
144 return 0;
145}
146
f6200941
LP
147static 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));
0108f6ec
DM
155
156 return 0;
f6200941
LP
157}
158
159static 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)
f2341e0a 172 log_unit_debug(u, "Failed to parse state value: %s", value);
f6200941
LP
173 else
174 d->deserialized_state = state;
175 } else
f2341e0a 176 log_unit_debug(u, "Unknown serialization key: %s", key);
f6200941
LP
177
178 return 0;
179}
180
f50e0a01 181static void device_dump(Unit *u, FILE *f, const char *prefix) {
25ac040b 182 Device *d = DEVICE(u);
5cb5a6ff 183
25ac040b 184 assert(d);
5cb5a6ff
LP
185
186 fprintf(f,
25ac040b
LP
187 "%sDevice State: %s\n"
188 "%sSysfs Path: %s\n",
a16e1123 189 prefix, device_state_to_string(d->state),
f50e0a01
LP
190 prefix, strna(d->sysfs));
191}
192
44a6b1b6 193_pure_ static UnitActiveState device_active_state(Unit *u) {
f50e0a01
LP
194 assert(u);
195
196 return state_translation_table[DEVICE(u)->state];
25ac040b
LP
197}
198
44a6b1b6 199_pure_ static const char *device_sub_state_to_string(Unit *u) {
10a94420
LP
200 assert(u);
201
a16e1123 202 return device_state_to_string(DEVICE(u)->state);
10a94420
LP
203}
204
628c89cc 205static int device_update_description(Unit *u, struct udev_device *dev, const char *path) {
965e5c5d 206 const char *model;
628c89cc 207 int r;
965e5c5d
LP
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
605405c6 230 j = strjoin(model, " ", label);
965e5c5d 231 if (j)
628c89cc 232 r = unit_set_description(u, j);
c43b2132
TA
233 else
234 r = -ENOMEM;
628c89cc
LP
235 } else
236 r = unit_set_description(u, model);
237 } else
238 r = unit_set_description(u, path);
965e5c5d 239
628c89cc 240 if (r < 0)
f2341e0a 241 log_unit_error_errno(u, r, "Failed to set device description: %m");
965e5c5d 242
628c89cc 243 return r;
965e5c5d
LP
244}
245
246static int device_add_udev_wants(Unit *u, struct udev_device *dev) {
de040543 247 const char *wants, *property;
965e5c5d
LP
248 int r;
249
250 assert(u);
251 assert(dev);
252
463d0d15 253 property = MANAGER_IS_USER(u->manager) ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS";
de040543 254
b2fadec6 255 wants = udev_device_get_property_value(dev, property);
de040543
LP
256 if (!wants)
257 return 0;
258
259 for (;;) {
ceed8f0c 260 _cleanup_free_ char *word = NULL, *k = NULL;
965e5c5d 261
de040543 262 r = extract_first_word(&wants, &word, NULL, EXTRACT_QUOTES);
ceed8f0c
ZJS
263 if (r == 0)
264 return 0;
265 if (r == -ENOMEM)
266 return log_oom();
267 if (r < 0)
dcebc9ba 268 return log_unit_error_errno(u, r, "Failed to parse property %s with value %s: %m", property, wants);
965e5c5d 269
dcebc9ba
LP
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
37cbc1d5 286 r = unit_name_mangle(word, UNIT_NAME_MANGLE_WARN, &k);
dcebc9ba
LP
287 if (r < 0)
288 return log_unit_error_errno(u, r, "Failed to mangle unit name \"%s\": %m", word);
289 }
965e5c5d 290
eef85c4a 291 r = unit_add_dependency_by_name(u, UNIT_WANTS, k, NULL, true, UNIT_DEPENDENCY_UDEV);
965e5c5d 292 if (r < 0)
de040543 293 return log_unit_error_errno(u, r, "Failed to add Wants= dependency: %m");
965e5c5d 294 }
965e5c5d
LP
295}
296
40b1a32c 297static bool device_is_bound_by_mounts(Device *d, struct udev_device *dev) {
ebc8968b 298 const char *bound_by;
40b1a32c 299 int r;
ebc8968b
FB
300
301 assert(d);
302 assert(dev);
303
304 bound_by = udev_device_get_property_value(dev, "SYSTEMD_MOUNT_DEVICE_BOUND");
40b1a32c
LP
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));
ebc8968b 309
40b1a32c
LP
310 d->bind_mounts = r > 0;
311 } else
312 d->bind_mounts = false;
313
314 return d->bind_mounts;
ebc8968b
FB
315}
316
317static int device_upgrade_mount_deps(Unit *u) {
318 Unit *other;
319 Iterator i;
eef85c4a 320 void *v;
ebc8968b
FB
321 int r;
322
eef85c4a
LP
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) {
ebc8968b
FB
326 if (other->type != UNIT_MOUNT)
327 continue;
328
eef85c4a 329 r = unit_add_dependency(other, UNIT_BINDS_TO, u, true, UNIT_DEPENDENCY_UDEV);
ebc8968b
FB
330 if (r < 0)
331 return r;
332 }
333 return 0;
334}
335
628c89cc
LP
336static int device_setup_unit(Manager *m, struct udev_device *dev, const char *path, bool main) {
337 _cleanup_free_ char *e = NULL;
2005219f 338 const char *sysfs = NULL;
25ac040b 339 Unit *u = NULL;
25ac040b 340 bool delete;
965e5c5d 341 int r;
25ac040b
LP
342
343 assert(m);
965e5c5d 344 assert(path);
25ac040b 345
2005219f
MP
346 if (dev) {
347 sysfs = udev_device_get_syspath(dev);
348 if (!sysfs)
349 return 0;
350 }
7f275a9f 351
7410616c
LP
352 r = unit_name_from_path(path, ".device", &e);
353 if (r < 0)
7f629b74 354 return log_error_errno(r, "Failed to generate unit name from device path: %m");
628c89cc
LP
355
356 u = manager_get_unit(m, e);
38b9b72e
LP
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 }
ac9d396b 369 }
25ac040b 370
38b9b72e
LP
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 {
aab14b13
LP
377 delete = true;
378
a581e45a 379 r = unit_new_for_name(m, sizeof(Device), e, &u);
7d17cfbc 380 if (r < 0)
25ac040b
LP
381 goto fail;
382
ee6cb288 383 unit_add_to_load_queue(u);
38b9b72e 384 }
ee6cb288
LP
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. */
2005219f
MP
389 if (sysfs) {
390 r = device_set_sysfs(DEVICE(u), sysfs);
391 if (r < 0)
392 goto fail;
ee6cb288 393
2005219f 394 (void) device_update_description(u, dev, path);
aab14b13 395
2005219f
MP
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 }
25ac040b 401
eef85c4a
LP
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. */
40b1a32c 405 if (dev && device_is_bound_by_mounts(DEVICE(u), dev))
ebc8968b 406 device_upgrade_mount_deps(u);
f94ea366 407
38b9b72e 408 /* Note that this won't dispatch the load queue, the caller has to do that if needed and appropriate */
f1421cc6 409
c1e1601e 410 unit_add_to_dbus_queue(u);
25ac040b
LP
411 return 0;
412
413fail:
f2341e0a 414 log_unit_warning_errno(u, r, "Failed to set up device unit: %m");
ee5f3479 415
c9d5c9c0 416 if (delete)
25ac040b 417 unit_free(u);
ee5f3479 418
25ac040b
LP
419 return r;
420}
421
628c89cc 422static int device_process_new(Manager *m, struct udev_device *dev) {
f1421cc6 423 const char *sysfs, *dn, *alias;
8fe914ec 424 struct udev_list_entry *item = NULL, *first = NULL;
003ac9d0 425 int r;
8fe914ec
LP
426
427 assert(m);
428
718db961
LP
429 sysfs = udev_device_get_syspath(dev);
430 if (!sysfs)
f1421cc6 431 return 0;
8fe914ec
LP
432
433 /* Add the main unit named after the sysfs path */
628c89cc 434 r = device_setup_unit(m, dev, sysfs, true);
003ac9d0
HH
435 if (r < 0)
436 return r;
8fe914ec
LP
437
438 /* Add an additional unit for the device node */
f1421cc6
LP
439 dn = udev_device_get_devnode(dev);
440 if (dn)
628c89cc 441 (void) device_setup_unit(m, dev, dn, false);
8fe914ec
LP
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;
5845b46b 447 struct stat st;
8fe914ec
LP
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
5845b46b
LP
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
ee33e53a 462 * check the device node major/minor */
5845b46b
LP
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
628c89cc 468 (void) device_setup_unit(m, dev, p, false);
8fe914ec
LP
469 }
470
f1421cc6
LP
471 /* Add additional units for all explicitly configured
472 * aliases */
473 alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS");
ceed8f0c 474 for (;;) {
8fb242ab 475 _cleanup_free_ char *word = NULL;
8fe914ec 476
ceed8f0c
ZJS
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);
f1421cc6 484
ceed8f0c
ZJS
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);
8fe914ec 489 }
8fe914ec
LP
490}
491
628c89cc 492static void device_update_found_one(Device *d, bool add, DeviceFound found, bool now) {
f6200941 493 DeviceFound n, previous;
628c89cc
LP
494
495 assert(d);
496
497 n = add ? (d->found | found) : (d->found & ~found);
498 if (n == d->found)
499 return;
500
f6200941 501 previous = d->found;
628c89cc
LP
502 d->found = n;
503
f6200941
LP
504 if (!now)
505 return;
506
4b58153d
LP
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
f6200941
LP
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);
05e33aa1 520 else {
f6200941
LP
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. */
05e33aa1 525
f6200941 526 device_set_state(d, DEVICE_DEAD);
05e33aa1
MS
527 device_unset_sysfs(d);
528 }
529
628c89cc
LP
530}
531
532static int device_update_found_by_sysfs(Manager *m, const char *sysfs, bool add, DeviceFound found, bool now) {
cc0df6cc 533 Device *d, *l, *n;
25ac040b
LP
534
535 assert(m);
628c89cc 536 assert(sysfs);
25ac040b 537
628c89cc
LP
538 if (found == DEVICE_NOT_FOUND)
539 return 0;
25ac040b 540
f1421cc6 541 l = hashmap_get(m->devices_by_sysfs, sysfs);
cc0df6cc 542 LIST_FOREACH_SAFE(same_sysfs, d, n, l)
628c89cc
LP
543 device_update_found_one(d, add, found, now);
544
545 return 0;
25ac040b
LP
546}
547
628c89cc
LP
548static 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;
7410616c 551 int r;
f94ea366
LP
552
553 assert(m);
628c89cc 554 assert(path);
f94ea366 555
628c89cc
LP
556 if (found == DEVICE_NOT_FOUND)
557 return 0;
f94ea366 558
7410616c
LP
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");
f94ea366 562
628c89cc
LP
563 u = manager_get_unit(m, e);
564 if (!u)
565 return 0;
566
567 device_update_found_one(DEVICE(u), add, found, now);
f94ea366
LP
568 return 0;
569}
570
f1421cc6
LP
571static 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
a7f241db
LP
583static Unit *device_following(Unit *u) {
584 Device *d = DEVICE(u);
585 Device *other, *first = NULL;
586
587 assert(d);
588
ac155bb8 589 if (startswith(u->id, "sys-"))
a7f241db
LP
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)
1124fe6f 594 if (startswith(UNIT(other)->id, "sys-"))
a7f241db
LP
595 return UNIT(other);
596
597 for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev) {
1124fe6f 598 if (startswith(UNIT(other)->id, "sys-"))
a7f241db
LP
599 return UNIT(other);
600
601 first = other;
602 }
603
604 return UNIT(first);
605}
606
f1421cc6
LP
607static int device_following_set(Unit *u, Set **_set) {
608 Device *d = DEVICE(u), *other;
609 Set *set;
6210e7fc
LP
610 int r;
611
612 assert(d);
f1421cc6 613 assert(_set);
6210e7fc 614
f1421cc6
LP
615 if (LIST_JUST_US(same_sysfs, d)) {
616 *_set = NULL;
6210e7fc
LP
617 return 0;
618 }
619
d5099efc 620 set = set_new(NULL);
f1421cc6 621 if (!set)
6210e7fc
LP
622 return -ENOMEM;
623
f1421cc6
LP
624 LIST_FOREACH_AFTER(same_sysfs, other, d) {
625 r = set_put(set, other);
626 if (r < 0)
6210e7fc 627 goto fail;
f1421cc6 628 }
6210e7fc 629
f1421cc6
LP
630 LIST_FOREACH_BEFORE(same_sysfs, other, d) {
631 r = set_put(set, other);
632 if (r < 0)
6210e7fc 633 goto fail;
f1421cc6 634 }
6210e7fc 635
f1421cc6 636 *_set = set;
6210e7fc
LP
637 return 1;
638
639fail:
f1421cc6 640 set_free(set);
6210e7fc
LP
641 return r;
642}
643
25ac040b
LP
644static void device_shutdown(Manager *m) {
645 assert(m);
646
718db961 647 m->udev_event_source = sd_event_source_unref(m->udev_event_source);
66f57304 648 m->udev_monitor = udev_monitor_unref(m->udev_monitor);
525d3cc7 649 m->devices_by_sysfs = hashmap_free(m->devices_by_sysfs);
25ac040b
LP
650}
651
ba64af90 652static void device_enumerate(Manager *m) {
718db961 653 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
25ac040b 654 struct udev_list_entry *item = NULL, *first = NULL;
718db961 655 int r;
25ac040b
LP
656
657 assert(m);
658
9670d583 659 if (!m->udev_monitor) {
718db961
LP
660 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
661 if (!m->udev_monitor) {
ba64af90 662 log_oom();
a16e1123
LP
663 goto fail;
664 }
f94ea366 665
47ae6e67
LP
666 /* This will fail if we are unprivileged, but that
667 * should not matter much, as user instances won't run
668 * during boot. */
8fa158e7 669 (void) udev_monitor_set_receive_buffer_size(m->udev_monitor, 128*1024*1024);
99448c1f 670
718db961 671 r = udev_monitor_filter_add_match_tag(m->udev_monitor, "systemd");
ba64af90
LP
672 if (r < 0) {
673 log_error_errno(r, "Failed to add udev tag match: %m");
e1ce2c27 674 goto fail;
ba64af90 675 }
e1ce2c27 676
718db961 677 r = udev_monitor_enable_receiving(m->udev_monitor);
ba64af90
LP
678 if (r < 0) {
679 log_error_errno(r, "Failed to enable udev event reception: %m");
a16e1123 680 goto fail;
ba64af90 681 }
f94ea366 682
151b9b96 683 r = sd_event_add_io(m->event, &m->udev_event_source, udev_monitor_get_fd(m->udev_monitor), EPOLLIN, device_dispatch_io, m);
ba64af90
LP
684 if (r < 0) {
685 log_error_errno(r, "Failed to watch udev file descriptor: %m");
718db961 686 goto fail;
ba64af90 687 }
7dfbe2e3
TG
688
689 (void) sd_event_source_set_description(m->udev_event_source, "device");
a16e1123 690 }
f94ea366 691
718db961
LP
692 e = udev_enumerate_new(m->udev);
693 if (!e) {
ba64af90 694 log_oom();
4f2d528d
LP
695 goto fail;
696 }
718db961
LP
697
698 r = udev_enumerate_add_match_tag(e, "systemd");
ba64af90
LP
699 if (r < 0) {
700 log_error_errno(r, "Failed to create udev tag enumeration: %m");
e1ce2c27 701 goto fail;
ba64af90 702 }
25ac040b 703
e1202047 704 r = udev_enumerate_add_match_is_initialized(e);
ba64af90
LP
705 if (r < 0) {
706 log_error_errno(r, "Failed to install initialization match into enumeration: %m");
e1202047 707 goto fail;
ba64af90 708 }
e1202047 709
718db961 710 r = udev_enumerate_scan_devices(e);
ba64af90
LP
711 if (r < 0) {
712 log_error_errno(r, "Failed to enumerate devices: %m");
4f2d528d 713 goto fail;
ba64af90 714 }
25ac040b 715
4f2d528d 716 first = udev_enumerate_get_list_entry(e);
628c89cc
LP
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 }
25ac040b 736
ba64af90 737 return;
25ac040b
LP
738
739fail:
25ac040b 740 device_shutdown(m);
5cb5a6ff
LP
741}
742
718db961
LP
743static 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;
718db961 745 Manager *m = userdata;
628c89cc 746 const char *action, *sysfs;
718db961 747 int r;
f94ea366
LP
748
749 assert(m);
99448c1f 750
718db961 751 if (revents != EPOLLIN) {
99448c1f
KS
752 static RATELIMIT_DEFINE(limit, 10*USEC_PER_SEC, 5);
753
754 if (!ratelimit_test(&limit))
56f64d95 755 log_error_errno(errno, "Failed to get udev event: %m");
718db961
LP
756 if (!(revents & EPOLLIN))
757 return 0;
99448c1f 758 }
f94ea366 759
718db961
LP
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;
f94ea366 767
628c89cc
LP
768 sysfs = udev_device_get_syspath(dev);
769 if (!sysfs) {
770 log_error("Failed to get udev sys path.");
771 return 0;
772 }
773
718db961
LP
774 action = udev_device_get_action(dev);
775 if (!action) {
f94ea366 776 log_error("Failed to get udev action string.");
718db961 777 return 0;
f94ea366
LP
778 }
779
f332611a 780 if (streq(action, "change")) {
f332611a 781 Unit *u;
bf70ff2c 782 Device *d, *l, *n;
f332611a 783
bf70ff2c
JR
784 l = hashmap_get(m->devices_by_sysfs, sysfs);
785 LIST_FOREACH_SAFE(same_sysfs, d, n, l) {
786 u = &d->meta;
f332611a
JR
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 */
6d445911 798 if (streq(action, "remove")) {
628c89cc 799 r = swap_process_device_remove(m, dev);
9670d583 800 if (r < 0)
da927ba9 801 log_error_errno(r, "Failed to process swap device remove event: %m");
9670d583 802
628c89cc
LP
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);
f1421cc6 807
628c89cc
LP
808 } else if (device_is_ready(dev)) {
809
810 (void) device_process_new(m, dev);
811
812 r = swap_process_device_new(m, dev);
9670d583 813 if (r < 0)
da927ba9 814 log_error_errno(r, "Failed to process swap device new event: %m");
9670d583 815
f1421cc6
LP
816 manager_dispatch_load_queue(m);
817
628c89cc
LP
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);
f94ea366
LP
827 }
828
718db961 829 return 0;
f94ea366
LP
830}
831
1c2e9646 832static bool device_supported(void) {
0faacd47 833 static int read_only = -1;
0faacd47
LP
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
628c89cc
LP
844int 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
4c6d20de
LP
851 if (!device_supported())
852 return 0;
853
628c89cc
LP
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
f6200941
LP
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
2005219f
MP
875 if (stat(node, &st) >= 0) {
876 if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode))
628c89cc
LP
877 return 0;
878
2005219f
MP
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));
628c89cc 882
2005219f
MP
883 } else if (errno != ENOENT)
884 return log_error_errno(errno, "Failed to stat device node file %s: %m", node);
628c89cc
LP
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
ebc8968b
FB
898bool 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
87f0e418 906const UnitVTable device_vtable = {
7d17cfbc 907 .object_size = sizeof(Device),
f975e971
LP
908 .sections =
909 "Unit\0"
910 "Device\0"
911 "Install\0",
5cb5a6ff 912
c5a97ed1
LP
913 .gc_jobs = true,
914
faf919f1 915 .init = device_init,
034c6ed7 916 .done = device_done,
718db961
LP
917 .load = unit_load_fragment_and_dropin_optional,
918
f50e0a01
LP
919 .coldplug = device_coldplug,
920
f6200941
LP
921 .serialize = device_serialize,
922 .deserialize_item = device_deserialize_item,
923
5cb5a6ff
LP
924 .dump = device_dump,
925
f50e0a01 926 .active_state = device_active_state,
10a94420 927 .sub_state_to_string = device_sub_state_to_string,
25ac040b 928
718db961 929 .bus_vtable = bus_device_vtable,
4139c1b2 930
a7f241db 931 .following = device_following,
6210e7fc 932 .following_set = device_following_set,
a7f241db 933
f50e0a01 934 .enumerate = device_enumerate,
c6918296 935 .shutdown = device_shutdown,
0faacd47 936 .supported = device_supported,
c6918296
MS
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 },
5cb5a6ff 947};