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