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