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