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