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