]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/device.c
core,network: major per-object logging rework
[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
b2fadec6
ZJS
267 property = u->manager->running_as == SYSTEMD_USER ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS";
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;
965e5c5d 295 const char *sysfs;
25ac040b 296 Unit *u = NULL;
25ac040b 297 bool delete;
965e5c5d 298 int r;
25ac040b
LP
299
300 assert(m);
965e5c5d
LP
301 assert(dev);
302 assert(path);
25ac040b 303
b47d419c
ZJS
304 sysfs = udev_device_get_syspath(dev);
305 if (!sysfs)
f1421cc6 306 return 0;
7f275a9f 307
7410616c
LP
308 r = unit_name_from_path(path, ".device", &e);
309 if (r < 0)
7f629b74 310 return log_error_errno(r, "Failed to generate unit name from device path: %m");
628c89cc
LP
311
312 u = manager_get_unit(m, e);
25ac040b 313
628c89cc
LP
314 if (u &&
315 DEVICE(u)->sysfs &&
316 !path_equal(DEVICE(u)->sysfs, sysfs)) {
f2341e0a 317 log_unit_debug(u, "Device %s appeared twice with different sysfs paths %s and %s", e, DEVICE(u)->sysfs, sysfs);
8fe914ec 318 return -EEXIST;
628c89cc 319 }
25ac040b 320
aab14b13
LP
321 if (!u) {
322 delete = true;
323
7d17cfbc
MS
324 u = unit_new(m, sizeof(Device));
325 if (!u)
f1421cc6 326 return log_oom();
25ac040b 327
628c89cc 328 r = unit_add_name(u, e);
7d17cfbc 329 if (r < 0)
25ac040b
LP
330 goto fail;
331
ee6cb288
LP
332 unit_add_to_load_queue(u);
333 } else
334 delete = false;
335
336 /* If this was created via some dependency and has not
337 * actually been seen yet ->sysfs will not be
338 * initialized. Hence initialize it if necessary. */
339
628c89cc
LP
340 r = device_set_sysfs(DEVICE(u), sysfs);
341 if (r < 0)
342 goto fail;
aab14b13 343
628c89cc 344 (void) device_update_description(u, dev, path);
25ac040b 345
628c89cc
LP
346 /* The additional systemd udev properties we only interpret
347 * for the main object */
348 if (main)
349 (void) device_add_udev_wants(u, dev);
f94ea366 350
f1421cc6
LP
351 /* Note that this won't dispatch the load queue, the caller
352 * has to do that if needed and appropriate */
353
c1e1601e 354 unit_add_to_dbus_queue(u);
25ac040b
LP
355 return 0;
356
357fail:
f2341e0a 358 log_unit_warning_errno(u, r, "Failed to set up device unit: %m");
ee5f3479 359
2bb9e620 360 if (delete)
25ac040b 361 unit_free(u);
ee5f3479 362
25ac040b
LP
363 return r;
364}
365
628c89cc 366static int device_process_new(Manager *m, struct udev_device *dev) {
f1421cc6 367 const char *sysfs, *dn, *alias;
8fe914ec 368 struct udev_list_entry *item = NULL, *first = NULL;
003ac9d0 369 int r;
8fe914ec
LP
370
371 assert(m);
372
718db961
LP
373 sysfs = udev_device_get_syspath(dev);
374 if (!sysfs)
f1421cc6 375 return 0;
8fe914ec
LP
376
377 /* Add the main unit named after the sysfs path */
628c89cc 378 r = device_setup_unit(m, dev, sysfs, true);
003ac9d0
HH
379 if (r < 0)
380 return r;
8fe914ec
LP
381
382 /* Add an additional unit for the device node */
f1421cc6
LP
383 dn = udev_device_get_devnode(dev);
384 if (dn)
628c89cc 385 (void) device_setup_unit(m, dev, dn, false);
8fe914ec
LP
386
387 /* Add additional units for all symlinks */
388 first = udev_device_get_devlinks_list_entry(dev);
389 udev_list_entry_foreach(item, first) {
390 const char *p;
5845b46b 391 struct stat st;
8fe914ec
LP
392
393 /* Don't bother with the /dev/block links */
394 p = udev_list_entry_get_name(item);
395
396 if (path_startswith(p, "/dev/block/") ||
397 path_startswith(p, "/dev/char/"))
398 continue;
399
5845b46b
LP
400 /* Verify that the symlink in the FS actually belongs
401 * to this device. This is useful to deal with
402 * conflicting devices, e.g. when two disks want the
403 * same /dev/disk/by-label/xxx link because they have
404 * the same label. We want to make sure that the same
405 * device that won the symlink wins in systemd, so we
ee33e53a 406 * check the device node major/minor */
5845b46b
LP
407 if (stat(p, &st) >= 0)
408 if ((!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) ||
409 st.st_rdev != udev_device_get_devnum(dev))
410 continue;
411
628c89cc 412 (void) device_setup_unit(m, dev, p, false);
8fe914ec
LP
413 }
414
f1421cc6
LP
415 /* Add additional units for all explicitly configured
416 * aliases */
417 alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS");
418 if (alias) {
a2a5291b 419 const char *word, *state;
f1421cc6 420 size_t l;
8fe914ec 421
a2a5291b 422 FOREACH_WORD_QUOTED(word, l, alias, state) {
f1421cc6 423 char e[l+1];
8fe914ec 424
a2a5291b 425 memcpy(e, word, l);
f1421cc6
LP
426 e[l] = 0;
427
428 if (path_is_absolute(e))
628c89cc 429 (void) device_setup_unit(m, dev, e, false);
f1421cc6
LP
430 else
431 log_warning("SYSTEMD_ALIAS for %s is not an absolute path, ignoring: %s", sysfs, e);
432 }
b2fadec6
ZJS
433 if (!isempty(state))
434 log_warning("SYSTEMD_ALIAS for %s has trailing garbage, ignoring.", sysfs);
8fe914ec
LP
435 }
436
437 return 0;
438}
439
628c89cc 440static void device_update_found_one(Device *d, bool add, DeviceFound found, bool now) {
f6200941 441 DeviceFound n, previous;
628c89cc
LP
442
443 assert(d);
444
445 n = add ? (d->found | found) : (d->found & ~found);
446 if (n == d->found)
447 return;
448
f6200941 449 previous = d->found;
628c89cc
LP
450 d->found = n;
451
f6200941
LP
452 if (!now)
453 return;
454
455 if (d->found & DEVICE_FOUND_UDEV)
456 /* When the device is known to udev we consider it
457 * plugged. */
458 device_set_state(d, DEVICE_PLUGGED);
459 else if (d->found != DEVICE_NOT_FOUND && (previous & DEVICE_FOUND_UDEV) == 0)
460 /* If the device has not been seen by udev yet, but is
461 * now referenced by the kernel, then we assume the
462 * kernel knows it now, and udev might soon too. */
463 device_set_state(d, DEVICE_TENTATIVE);
464 else
465 /* If nobody sees the device, or if the device was
466 * previously seen by udev and now is only referenced
467 * from the kernel, then we consider the device is
468 * gone, the kernel just hasn't noticed it yet. */
469 device_set_state(d, DEVICE_DEAD);
628c89cc
LP
470}
471
472static int device_update_found_by_sysfs(Manager *m, const char *sysfs, bool add, DeviceFound found, bool now) {
f1421cc6 473 Device *d, *l;
25ac040b
LP
474
475 assert(m);
628c89cc 476 assert(sysfs);
25ac040b 477
628c89cc
LP
478 if (found == DEVICE_NOT_FOUND)
479 return 0;
25ac040b 480
f1421cc6
LP
481 l = hashmap_get(m->devices_by_sysfs, sysfs);
482 LIST_FOREACH(same_sysfs, d, l)
628c89cc
LP
483 device_update_found_one(d, add, found, now);
484
485 return 0;
25ac040b
LP
486}
487
628c89cc
LP
488static int device_update_found_by_name(Manager *m, const char *path, bool add, DeviceFound found, bool now) {
489 _cleanup_free_ char *e = NULL;
490 Unit *u;
7410616c 491 int r;
f94ea366
LP
492
493 assert(m);
628c89cc 494 assert(path);
f94ea366 495
628c89cc
LP
496 if (found == DEVICE_NOT_FOUND)
497 return 0;
f94ea366 498
7410616c
LP
499 r = unit_name_from_path(path, ".device", &e);
500 if (r < 0)
501 return log_error_errno(r, "Failed to generate unit name from device path: %m");
f94ea366 502
628c89cc
LP
503 u = manager_get_unit(m, e);
504 if (!u)
505 return 0;
506
507 device_update_found_one(DEVICE(u), add, found, now);
f94ea366
LP
508 return 0;
509}
510
f1421cc6
LP
511static 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
a7f241db
LP
523static Unit *device_following(Unit *u) {
524 Device *d = DEVICE(u);
525 Device *other, *first = NULL;
526
527 assert(d);
528
ac155bb8 529 if (startswith(u->id, "sys-"))
a7f241db
LP
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)
1124fe6f 534 if (startswith(UNIT(other)->id, "sys-"))
a7f241db
LP
535 return UNIT(other);
536
537 for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev) {
1124fe6f 538 if (startswith(UNIT(other)->id, "sys-"))
a7f241db
LP
539 return UNIT(other);
540
541 first = other;
542 }
543
544 return UNIT(first);
545}
546
f1421cc6
LP
547static int device_following_set(Unit *u, Set **_set) {
548 Device *d = DEVICE(u), *other;
549 Set *set;
6210e7fc
LP
550 int r;
551
552 assert(d);
f1421cc6 553 assert(_set);
6210e7fc 554
f1421cc6
LP
555 if (LIST_JUST_US(same_sysfs, d)) {
556 *_set = NULL;
6210e7fc
LP
557 return 0;
558 }
559
d5099efc 560 set = set_new(NULL);
f1421cc6 561 if (!set)
6210e7fc
LP
562 return -ENOMEM;
563
f1421cc6
LP
564 LIST_FOREACH_AFTER(same_sysfs, other, d) {
565 r = set_put(set, other);
566 if (r < 0)
6210e7fc 567 goto fail;
f1421cc6 568 }
6210e7fc 569
f1421cc6
LP
570 LIST_FOREACH_BEFORE(same_sysfs, other, d) {
571 r = set_put(set, other);
572 if (r < 0)
6210e7fc 573 goto fail;
f1421cc6 574 }
6210e7fc 575
f1421cc6 576 *_set = set;
6210e7fc
LP
577 return 1;
578
579fail:
f1421cc6 580 set_free(set);
6210e7fc
LP
581 return r;
582}
583
25ac040b
LP
584static void device_shutdown(Manager *m) {
585 assert(m);
586
718db961
LP
587 m->udev_event_source = sd_event_source_unref(m->udev_event_source);
588
a16e1123 589 if (m->udev_monitor) {
f94ea366 590 udev_monitor_unref(m->udev_monitor);
a16e1123
LP
591 m->udev_monitor = NULL;
592 }
f94ea366 593
8fe914ec
LP
594 hashmap_free(m->devices_by_sysfs);
595 m->devices_by_sysfs = NULL;
25ac040b
LP
596}
597
598static int device_enumerate(Manager *m) {
718db961 599 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
25ac040b 600 struct udev_list_entry *item = NULL, *first = NULL;
718db961 601 int r;
25ac040b
LP
602
603 assert(m);
604
9670d583 605 if (!m->udev_monitor) {
718db961
LP
606 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
607 if (!m->udev_monitor) {
a16e1123
LP
608 r = -ENOMEM;
609 goto fail;
610 }
f94ea366 611
47ae6e67
LP
612 /* This will fail if we are unprivileged, but that
613 * should not matter much, as user instances won't run
614 * during boot. */
8fa158e7 615 (void) udev_monitor_set_receive_buffer_size(m->udev_monitor, 128*1024*1024);
99448c1f 616
718db961
LP
617 r = udev_monitor_filter_add_match_tag(m->udev_monitor, "systemd");
618 if (r < 0)
e1ce2c27 619 goto fail;
e1ce2c27 620
718db961
LP
621 r = udev_monitor_enable_receiving(m->udev_monitor);
622 if (r < 0)
a16e1123 623 goto fail;
f94ea366 624
151b9b96 625 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
626 if (r < 0)
627 goto fail;
7dfbe2e3
TG
628
629 (void) sd_event_source_set_description(m->udev_event_source, "device");
a16e1123 630 }
f94ea366 631
718db961
LP
632 e = udev_enumerate_new(m->udev);
633 if (!e) {
4f2d528d
LP
634 r = -ENOMEM;
635 goto fail;
636 }
718db961
LP
637
638 r = udev_enumerate_add_match_tag(e, "systemd");
639 if (r < 0)
e1ce2c27 640 goto fail;
25ac040b 641
e1202047
LP
642 r = udev_enumerate_add_match_is_initialized(e);
643 if (r < 0)
644 goto fail;
645
718db961
LP
646 r = udev_enumerate_scan_devices(e);
647 if (r < 0)
4f2d528d 648 goto fail;
25ac040b 649
4f2d528d 650 first = udev_enumerate_get_list_entry(e);
628c89cc
LP
651 udev_list_entry_foreach(item, first) {
652 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
653 const char *sysfs;
654
655 sysfs = udev_list_entry_get_name(item);
656
657 dev = udev_device_new_from_syspath(m->udev, sysfs);
658 if (!dev) {
659 log_oom();
660 continue;
661 }
662
663 if (!device_is_ready(dev))
664 continue;
665
666 (void) device_process_new(m, dev);
667
668 device_update_found_by_sysfs(m, sysfs, true, DEVICE_FOUND_UDEV, false);
669 }
25ac040b 670
25ac040b
LP
671 return 0;
672
673fail:
628c89cc
LP
674 log_error_errno(r, "Failed to enumerate devices: %m");
675
25ac040b
LP
676 device_shutdown(m);
677 return r;
5cb5a6ff
LP
678}
679
718db961
LP
680static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
681 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
718db961 682 Manager *m = userdata;
628c89cc 683 const char *action, *sysfs;
718db961 684 int r;
f94ea366
LP
685
686 assert(m);
99448c1f 687
718db961 688 if (revents != EPOLLIN) {
99448c1f
KS
689 static RATELIMIT_DEFINE(limit, 10*USEC_PER_SEC, 5);
690
691 if (!ratelimit_test(&limit))
56f64d95 692 log_error_errno(errno, "Failed to get udev event: %m");
718db961
LP
693 if (!(revents & EPOLLIN))
694 return 0;
99448c1f 695 }
f94ea366 696
718db961
LP
697 /*
698 * libudev might filter-out devices which pass the bloom
699 * filter, so getting NULL here is not necessarily an error.
700 */
701 dev = udev_monitor_receive_device(m->udev_monitor);
702 if (!dev)
703 return 0;
f94ea366 704
628c89cc
LP
705 sysfs = udev_device_get_syspath(dev);
706 if (!sysfs) {
707 log_error("Failed to get udev sys path.");
708 return 0;
709 }
710
718db961
LP
711 action = udev_device_get_action(dev);
712 if (!action) {
f94ea366 713 log_error("Failed to get udev action string.");
718db961 714 return 0;
f94ea366
LP
715 }
716
628c89cc
LP
717 if (streq(action, "remove")) {
718 r = swap_process_device_remove(m, dev);
9670d583 719 if (r < 0)
da927ba9 720 log_error_errno(r, "Failed to process swap device remove event: %m");
9670d583 721
628c89cc
LP
722 /* If we get notified that a device was removed by
723 * udev, then it's completely gone, hence unset all
724 * found bits */
725 device_update_found_by_sysfs(m, sysfs, false, DEVICE_FOUND_UDEV|DEVICE_FOUND_MOUNT|DEVICE_FOUND_SWAP, true);
f1421cc6 726
628c89cc
LP
727 } else if (device_is_ready(dev)) {
728
729 (void) device_process_new(m, dev);
730
731 r = swap_process_device_new(m, dev);
9670d583 732 if (r < 0)
da927ba9 733 log_error_errno(r, "Failed to process swap device new event: %m");
9670d583 734
f1421cc6
LP
735 manager_dispatch_load_queue(m);
736
628c89cc
LP
737 /* The device is found now, set the udev found bit */
738 device_update_found_by_sysfs(m, sysfs, true, DEVICE_FOUND_UDEV, true);
739
740 } else {
741 /* The device is nominally around, but not ready for
742 * us. Hence unset the udev bit, but leave the rest
743 * around. */
744
745 device_update_found_by_sysfs(m, sysfs, false, DEVICE_FOUND_UDEV, true);
f94ea366
LP
746 }
747
718db961 748 return 0;
f94ea366
LP
749}
750
1c2e9646 751static bool device_supported(void) {
0faacd47 752 static int read_only = -1;
0faacd47
LP
753
754 /* If /sys is read-only we don't support device units, and any
755 * attempts to start one should fail immediately. */
756
757 if (read_only < 0)
758 read_only = path_is_read_only_fs("/sys");
759
760 return read_only <= 0;
761}
762
628c89cc
LP
763int device_found_node(Manager *m, const char *node, bool add, DeviceFound found, bool now) {
764 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
765 struct stat st;
766
767 assert(m);
768 assert(node);
769
770 /* This is called whenever we find a device referenced in
771 * /proc/swaps or /proc/self/mounts. Such a device might be
772 * mounted/enabled at a time where udev has not finished
773 * probing it yet, and we thus haven't learned about it
774 * yet. In this case we will set the device unit to
775 * "tentative" state. */
776
777 if (add) {
778 if (!path_startswith(node, "/dev"))
779 return 0;
780
f6200941
LP
781 /* We make an extra check here, if the device node
782 * actually exists. If it's missing, then this is an
783 * indication that device was unplugged but is still
784 * referenced in /proc/swaps or
785 * /proc/self/mountinfo. Note that this check doesn't
786 * really cover all cases where a device might be gone
787 * away, since drives that can have a medium inserted
788 * will still have a device node even when the medium
789 * is not there... */
790
628c89cc
LP
791 if (stat(node, &st) < 0) {
792 if (errno == ENOENT)
793 return 0;
794
795 return log_error_errno(errno, "Failed to stat device node file %s: %m", node);
796 }
797
798 if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode))
799 return 0;
800
801 dev = udev_device_new_from_devnum(m->udev, S_ISBLK(st.st_mode) ? 'b' : 'c', st.st_rdev);
802 if (!dev) {
803 if (errno == ENOENT)
804 return 0;
805
806 return log_oom();
807 }
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};