]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/device.c
Merge pull request #8523 from keszybz/oss-fuzz-fixes
[thirdparty/systemd.git] / src / core / device.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
a7334b09
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2010 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
a7334b09
LP
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 15 Lesser General Public License for more details.
a7334b09 16
5430f7f2 17 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
25ac040b 21#include <errno.h>
f94ea366 22#include <sys/epoll.h>
25ac040b 23
b4bbcaa9
TA
24#include "libudev.h"
25
b5efdb8a 26#include "alloc-util.h"
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"
8fcde012 32#include "stat-util.h"
07630cea
LP
33#include "string-util.h"
34#include "swap.h"
718db961 35#include "udev-util.h"
07630cea 36#include "unit-name.h"
9670d583 37#include "unit.h"
5cb5a6ff 38
f50e0a01
LP
39static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = {
40 [DEVICE_DEAD] = UNIT_INACTIVE,
628c89cc
LP
41 [DEVICE_TENTATIVE] = UNIT_ACTIVATING,
42 [DEVICE_PLUGGED] = UNIT_ACTIVE,
f50e0a01
LP
43};
44
718db961
LP
45static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
46
8fe914ec 47static void device_unset_sysfs(Device *d) {
f1421cc6 48 Hashmap *devices;
8fe914ec
LP
49 Device *first;
50
51 assert(d);
52
a7f241db
LP
53 if (!d->sysfs)
54 return;
55
56 /* Remove this unit from the chain of devices which share the
57 * same sysfs path. */
f1421cc6
LP
58 devices = UNIT(d)->manager->devices_by_sysfs;
59 first = hashmap_get(devices, d->sysfs);
71fda00f 60 LIST_REMOVE(same_sysfs, first, d);
8fe914ec 61
a7f241db 62 if (first)
f1421cc6 63 hashmap_remove_and_replace(devices, d->sysfs, first->sysfs, first);
a7f241db 64 else
f1421cc6 65 hashmap_remove(devices, d->sysfs);
a7f241db 66
a1e58e8e 67 d->sysfs = mfree(d->sysfs);
8fe914ec
LP
68}
69
628c89cc
LP
70static int device_set_sysfs(Device *d, const char *sysfs) {
71 Device *first;
72 char *copy;
73 int r;
74
75 assert(d);
76
77 if (streq_ptr(d->sysfs, sysfs))
78 return 0;
79
548f6937 80 r = hashmap_ensure_allocated(&UNIT(d)->manager->devices_by_sysfs, &path_hash_ops);
628c89cc
LP
81 if (r < 0)
82 return r;
83
84 copy = strdup(sysfs);
85 if (!copy)
86 return -ENOMEM;
87
88 device_unset_sysfs(d);
89
90 first = hashmap_get(UNIT(d)->manager->devices_by_sysfs, sysfs);
91 LIST_PREPEND(same_sysfs, first, d);
92
93 r = hashmap_replace(UNIT(d)->manager->devices_by_sysfs, copy, first);
94 if (r < 0) {
95 LIST_REMOVE(same_sysfs, first, d);
96 free(copy);
97 return r;
98 }
99
100 d->sysfs = copy;
101
102 return 0;
103}
104
faf919f1
LP
105static void device_init(Unit *u) {
106 Device *d = DEVICE(u);
107
108 assert(d);
1124fe6f 109 assert(UNIT(d)->load_state == UNIT_STUB);
faf919f1 110
8fe914ec
LP
111 /* In contrast to all other unit types we timeout jobs waiting
112 * for devices by default. This is because they otherwise wait
35b8ca3a 113 * indefinitely for plugged in devices, something which cannot
8fe914ec
LP
114 * happen for the other units since their operations time out
115 * anyway. */
d9732d78 116 u->job_running_timeout = u->manager->default_timeout_start_usec;
c8f4d764 117
f1421cc6 118 u->ignore_on_isolate = 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
605405c6 243 j = strjoin(model, " ", label);
965e5c5d 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) {
de040543 260 const char *wants, *property;
965e5c5d
LP
261 int r;
262
263 assert(u);
264 assert(dev);
265
463d0d15 266 property = MANAGER_IS_USER(u->manager) ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS";
de040543 267
b2fadec6 268 wants = udev_device_get_property_value(dev, property);
de040543
LP
269 if (!wants)
270 return 0;
271
272 for (;;) {
ceed8f0c 273 _cleanup_free_ char *word = NULL, *k = NULL;
965e5c5d 274
de040543 275 r = extract_first_word(&wants, &word, NULL, EXTRACT_QUOTES);
ceed8f0c
ZJS
276 if (r == 0)
277 return 0;
278 if (r == -ENOMEM)
279 return log_oom();
280 if (r < 0)
dcebc9ba 281 return log_unit_error_errno(u, r, "Failed to parse property %s with value %s: %m", property, wants);
965e5c5d 282
dcebc9ba
LP
283 if (unit_name_is_valid(word, UNIT_NAME_TEMPLATE) && DEVICE(u)->sysfs) {
284 _cleanup_free_ char *escaped = NULL;
285
286 /* If the unit name is specified as template, then automatically fill in the sysfs path of the
287 * device as instance name, properly escaped. */
288
289 r = unit_name_path_escape(DEVICE(u)->sysfs, &escaped);
290 if (r < 0)
291 return log_unit_error_errno(u, r, "Failed to escape %s: %m", DEVICE(u)->sysfs);
292
293 r = unit_name_replace_instance(word, escaped, &k);
294 if (r < 0)
295 return log_unit_error_errno(u, r, "Failed to build %s instance of template %s: %m", escaped, word);
296 } else {
297 /* If this is not a template, then let's mangle it so, that it becomes a valid unit name. */
298
299 r = unit_name_mangle(word, UNIT_NAME_NOGLOB, &k);
300 if (r < 0)
301 return log_unit_error_errno(u, r, "Failed to mangle unit name \"%s\": %m", word);
302 }
965e5c5d 303
eef85c4a 304 r = unit_add_dependency_by_name(u, UNIT_WANTS, k, NULL, true, UNIT_DEPENDENCY_UDEV);
965e5c5d 305 if (r < 0)
de040543 306 return log_unit_error_errno(u, r, "Failed to add Wants= dependency: %m");
965e5c5d 307 }
965e5c5d
LP
308}
309
40b1a32c 310static bool device_is_bound_by_mounts(Device *d, struct udev_device *dev) {
ebc8968b 311 const char *bound_by;
40b1a32c 312 int r;
ebc8968b
FB
313
314 assert(d);
315 assert(dev);
316
317 bound_by = udev_device_get_property_value(dev, "SYSTEMD_MOUNT_DEVICE_BOUND");
40b1a32c
LP
318 if (bound_by) {
319 r = parse_boolean(bound_by);
320 if (r < 0)
321 log_warning_errno(r, "Failed to parse SYSTEMD_MOUNT_DEVICE_BOUND='%s' udev property of %s, ignoring: %m", bound_by, strna(d->sysfs));
ebc8968b 322
40b1a32c
LP
323 d->bind_mounts = r > 0;
324 } else
325 d->bind_mounts = false;
326
327 return d->bind_mounts;
ebc8968b
FB
328}
329
330static int device_upgrade_mount_deps(Unit *u) {
331 Unit *other;
332 Iterator i;
eef85c4a 333 void *v;
ebc8968b
FB
334 int r;
335
eef85c4a
LP
336 /* Let's upgrade Requires= to BindsTo= on us. (Used when SYSTEMD_MOUNT_DEVICE_BOUND is set) */
337
338 HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_REQUIRED_BY], i) {
ebc8968b
FB
339 if (other->type != UNIT_MOUNT)
340 continue;
341
eef85c4a 342 r = unit_add_dependency(other, UNIT_BINDS_TO, u, true, UNIT_DEPENDENCY_UDEV);
ebc8968b
FB
343 if (r < 0)
344 return r;
345 }
346 return 0;
347}
348
628c89cc
LP
349static int device_setup_unit(Manager *m, struct udev_device *dev, const char *path, bool main) {
350 _cleanup_free_ char *e = NULL;
2005219f 351 const char *sysfs = NULL;
25ac040b 352 Unit *u = NULL;
25ac040b 353 bool delete;
965e5c5d 354 int r;
25ac040b
LP
355
356 assert(m);
965e5c5d 357 assert(path);
25ac040b 358
2005219f
MP
359 if (dev) {
360 sysfs = udev_device_get_syspath(dev);
361 if (!sysfs)
362 return 0;
363 }
7f275a9f 364
7410616c
LP
365 r = unit_name_from_path(path, ".device", &e);
366 if (r < 0)
7f629b74 367 return log_error_errno(r, "Failed to generate unit name from device path: %m");
628c89cc
LP
368
369 u = manager_get_unit(m, e);
38b9b72e
LP
370 if (u) {
371 /* The device unit can still be present even if the device was unplugged: a mount unit can reference it hence
372 * preventing the GC to have garbaged it. That's desired since the device unit may have a dependency on the
373 * mount unit which was added during the loading of the later. */
374 if (dev && DEVICE(u)->state == DEVICE_PLUGGED) {
375
376 /* This unit is in plugged state: we're sure it's attached to a device. */
377 if (!path_equal(DEVICE(u)->sysfs, sysfs)) {
378 log_unit_debug(u, "Dev %s appeared twice with different sysfs paths %s and %s",
379 e, DEVICE(u)->sysfs, sysfs);
380 return -EEXIST;
381 }
ac9d396b 382 }
25ac040b 383
38b9b72e
LP
384 delete = false;
385
386 /* Let's remove all dependencies generated due to udev properties. We'll readd whatever is configured
387 * now below. */
388 unit_remove_dependencies(u, UNIT_DEPENDENCY_UDEV);
389 } else {
aab14b13
LP
390 delete = true;
391
a581e45a 392 r = unit_new_for_name(m, sizeof(Device), e, &u);
7d17cfbc 393 if (r < 0)
25ac040b
LP
394 goto fail;
395
ee6cb288 396 unit_add_to_load_queue(u);
38b9b72e 397 }
ee6cb288
LP
398
399 /* If this was created via some dependency and has not
400 * actually been seen yet ->sysfs will not be
401 * initialized. Hence initialize it if necessary. */
2005219f
MP
402 if (sysfs) {
403 r = device_set_sysfs(DEVICE(u), sysfs);
404 if (r < 0)
405 goto fail;
ee6cb288 406
2005219f 407 (void) device_update_description(u, dev, path);
aab14b13 408
2005219f
MP
409 /* The additional systemd udev properties we only interpret
410 * for the main object */
411 if (main)
412 (void) device_add_udev_wants(u, dev);
413 }
25ac040b 414
eef85c4a
LP
415 /* So the user wants the mount units to be bound to the device but a mount unit might has been seen by systemd
416 * before the device appears on its radar. In this case the device unit is partially initialized and includes
417 * the deps on the mount unit but at that time the "bind mounts" flag wasn't not present. Fix this up now. */
40b1a32c 418 if (dev && device_is_bound_by_mounts(DEVICE(u), dev))
ebc8968b 419 device_upgrade_mount_deps(u);
f94ea366 420
38b9b72e 421 /* Note that this won't dispatch the load queue, the caller has to do that if needed and appropriate */
f1421cc6 422
c1e1601e 423 unit_add_to_dbus_queue(u);
25ac040b
LP
424 return 0;
425
426fail:
f2341e0a 427 log_unit_warning_errno(u, r, "Failed to set up device unit: %m");
ee5f3479 428
c9d5c9c0 429 if (delete)
25ac040b 430 unit_free(u);
ee5f3479 431
25ac040b
LP
432 return r;
433}
434
628c89cc 435static int device_process_new(Manager *m, struct udev_device *dev) {
f1421cc6 436 const char *sysfs, *dn, *alias;
8fe914ec 437 struct udev_list_entry *item = NULL, *first = NULL;
003ac9d0 438 int r;
8fe914ec
LP
439
440 assert(m);
441
718db961
LP
442 sysfs = udev_device_get_syspath(dev);
443 if (!sysfs)
f1421cc6 444 return 0;
8fe914ec
LP
445
446 /* Add the main unit named after the sysfs path */
628c89cc 447 r = device_setup_unit(m, dev, sysfs, true);
003ac9d0
HH
448 if (r < 0)
449 return r;
8fe914ec
LP
450
451 /* Add an additional unit for the device node */
f1421cc6
LP
452 dn = udev_device_get_devnode(dev);
453 if (dn)
628c89cc 454 (void) device_setup_unit(m, dev, dn, false);
8fe914ec
LP
455
456 /* Add additional units for all symlinks */
457 first = udev_device_get_devlinks_list_entry(dev);
458 udev_list_entry_foreach(item, first) {
459 const char *p;
5845b46b 460 struct stat st;
8fe914ec
LP
461
462 /* Don't bother with the /dev/block links */
463 p = udev_list_entry_get_name(item);
464
465 if (path_startswith(p, "/dev/block/") ||
466 path_startswith(p, "/dev/char/"))
467 continue;
468
5845b46b
LP
469 /* Verify that the symlink in the FS actually belongs
470 * to this device. This is useful to deal with
471 * conflicting devices, e.g. when two disks want the
472 * same /dev/disk/by-label/xxx link because they have
473 * the same label. We want to make sure that the same
474 * device that won the symlink wins in systemd, so we
ee33e53a 475 * check the device node major/minor */
5845b46b
LP
476 if (stat(p, &st) >= 0)
477 if ((!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) ||
478 st.st_rdev != udev_device_get_devnum(dev))
479 continue;
480
628c89cc 481 (void) device_setup_unit(m, dev, p, false);
8fe914ec
LP
482 }
483
f1421cc6
LP
484 /* Add additional units for all explicitly configured
485 * aliases */
486 alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS");
ceed8f0c 487 for (;;) {
8fb242ab 488 _cleanup_free_ char *word = NULL;
8fe914ec 489
ceed8f0c
ZJS
490 r = extract_first_word(&alias, &word, NULL, EXTRACT_QUOTES);
491 if (r == 0)
492 return 0;
493 if (r == -ENOMEM)
494 return log_oom();
495 if (r < 0)
496 return log_warning_errno(r, "Failed to add parse SYSTEMD_ALIAS for %s: %m", sysfs);
f1421cc6 497
ceed8f0c
ZJS
498 if (path_is_absolute(word))
499 (void) device_setup_unit(m, dev, word, false);
500 else
501 log_warning("SYSTEMD_ALIAS for %s is not an absolute path, ignoring: %s", sysfs, word);
8fe914ec 502 }
8fe914ec
LP
503}
504
628c89cc 505static void device_update_found_one(Device *d, bool add, DeviceFound found, bool now) {
f6200941 506 DeviceFound n, previous;
628c89cc
LP
507
508 assert(d);
509
510 n = add ? (d->found | found) : (d->found & ~found);
511 if (n == d->found)
512 return;
513
f6200941 514 previous = d->found;
628c89cc
LP
515 d->found = n;
516
f6200941
LP
517 if (!now)
518 return;
519
4b58153d
LP
520 /* Didn't exist before, but does now? if so, generate a new invocation ID for it */
521 if (previous == DEVICE_NOT_FOUND && d->found != DEVICE_NOT_FOUND)
522 (void) unit_acquire_invocation_id(UNIT(d));
523
f6200941
LP
524 if (d->found & DEVICE_FOUND_UDEV)
525 /* When the device is known to udev we consider it
526 * plugged. */
527 device_set_state(d, DEVICE_PLUGGED);
528 else if (d->found != DEVICE_NOT_FOUND && (previous & DEVICE_FOUND_UDEV) == 0)
529 /* If the device has not been seen by udev yet, but is
530 * now referenced by the kernel, then we assume the
531 * kernel knows it now, and udev might soon too. */
532 device_set_state(d, DEVICE_TENTATIVE);
05e33aa1 533 else {
f6200941
LP
534 /* If nobody sees the device, or if the device was
535 * previously seen by udev and now is only referenced
536 * from the kernel, then we consider the device is
537 * gone, the kernel just hasn't noticed it yet. */
05e33aa1 538
f6200941 539 device_set_state(d, DEVICE_DEAD);
05e33aa1
MS
540 device_unset_sysfs(d);
541 }
542
628c89cc
LP
543}
544
545static int device_update_found_by_sysfs(Manager *m, const char *sysfs, bool add, DeviceFound found, bool now) {
cc0df6cc 546 Device *d, *l, *n;
25ac040b
LP
547
548 assert(m);
628c89cc 549 assert(sysfs);
25ac040b 550
628c89cc
LP
551 if (found == DEVICE_NOT_FOUND)
552 return 0;
25ac040b 553
f1421cc6 554 l = hashmap_get(m->devices_by_sysfs, sysfs);
cc0df6cc 555 LIST_FOREACH_SAFE(same_sysfs, d, n, l)
628c89cc
LP
556 device_update_found_one(d, add, found, now);
557
558 return 0;
25ac040b
LP
559}
560
628c89cc
LP
561static int device_update_found_by_name(Manager *m, const char *path, bool add, DeviceFound found, bool now) {
562 _cleanup_free_ char *e = NULL;
563 Unit *u;
7410616c 564 int r;
f94ea366
LP
565
566 assert(m);
628c89cc 567 assert(path);
f94ea366 568
628c89cc
LP
569 if (found == DEVICE_NOT_FOUND)
570 return 0;
f94ea366 571
7410616c
LP
572 r = unit_name_from_path(path, ".device", &e);
573 if (r < 0)
574 return log_error_errno(r, "Failed to generate unit name from device path: %m");
f94ea366 575
628c89cc
LP
576 u = manager_get_unit(m, e);
577 if (!u)
578 return 0;
579
580 device_update_found_one(DEVICE(u), add, found, now);
f94ea366
LP
581 return 0;
582}
583
f1421cc6
LP
584static bool device_is_ready(struct udev_device *dev) {
585 const char *ready;
586
587 assert(dev);
588
589 ready = udev_device_get_property_value(dev, "SYSTEMD_READY");
590 if (!ready)
591 return true;
592
593 return parse_boolean(ready) != 0;
594}
595
a7f241db
LP
596static Unit *device_following(Unit *u) {
597 Device *d = DEVICE(u);
598 Device *other, *first = NULL;
599
600 assert(d);
601
ac155bb8 602 if (startswith(u->id, "sys-"))
a7f241db
LP
603 return NULL;
604
605 /* Make everybody follow the unit that's named after the sysfs path */
606 for (other = d->same_sysfs_next; other; other = other->same_sysfs_next)
1124fe6f 607 if (startswith(UNIT(other)->id, "sys-"))
a7f241db
LP
608 return UNIT(other);
609
610 for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev) {
1124fe6f 611 if (startswith(UNIT(other)->id, "sys-"))
a7f241db
LP
612 return UNIT(other);
613
614 first = other;
615 }
616
617 return UNIT(first);
618}
619
f1421cc6
LP
620static int device_following_set(Unit *u, Set **_set) {
621 Device *d = DEVICE(u), *other;
622 Set *set;
6210e7fc
LP
623 int r;
624
625 assert(d);
f1421cc6 626 assert(_set);
6210e7fc 627
f1421cc6
LP
628 if (LIST_JUST_US(same_sysfs, d)) {
629 *_set = NULL;
6210e7fc
LP
630 return 0;
631 }
632
d5099efc 633 set = set_new(NULL);
f1421cc6 634 if (!set)
6210e7fc
LP
635 return -ENOMEM;
636
f1421cc6
LP
637 LIST_FOREACH_AFTER(same_sysfs, other, d) {
638 r = set_put(set, other);
639 if (r < 0)
6210e7fc 640 goto fail;
f1421cc6 641 }
6210e7fc 642
f1421cc6
LP
643 LIST_FOREACH_BEFORE(same_sysfs, other, d) {
644 r = set_put(set, other);
645 if (r < 0)
6210e7fc 646 goto fail;
f1421cc6 647 }
6210e7fc 648
f1421cc6 649 *_set = set;
6210e7fc
LP
650 return 1;
651
652fail:
f1421cc6 653 set_free(set);
6210e7fc
LP
654 return r;
655}
656
25ac040b
LP
657static void device_shutdown(Manager *m) {
658 assert(m);
659
718db961
LP
660 m->udev_event_source = sd_event_source_unref(m->udev_event_source);
661
a16e1123 662 if (m->udev_monitor) {
f94ea366 663 udev_monitor_unref(m->udev_monitor);
a16e1123
LP
664 m->udev_monitor = NULL;
665 }
f94ea366 666
525d3cc7 667 m->devices_by_sysfs = hashmap_free(m->devices_by_sysfs);
25ac040b
LP
668}
669
ba64af90 670static void device_enumerate(Manager *m) {
718db961 671 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
25ac040b 672 struct udev_list_entry *item = NULL, *first = NULL;
718db961 673 int r;
25ac040b
LP
674
675 assert(m);
676
9670d583 677 if (!m->udev_monitor) {
718db961
LP
678 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
679 if (!m->udev_monitor) {
ba64af90 680 log_oom();
a16e1123
LP
681 goto fail;
682 }
f94ea366 683
47ae6e67
LP
684 /* This will fail if we are unprivileged, but that
685 * should not matter much, as user instances won't run
686 * during boot. */
8fa158e7 687 (void) udev_monitor_set_receive_buffer_size(m->udev_monitor, 128*1024*1024);
99448c1f 688
718db961 689 r = udev_monitor_filter_add_match_tag(m->udev_monitor, "systemd");
ba64af90
LP
690 if (r < 0) {
691 log_error_errno(r, "Failed to add udev tag match: %m");
e1ce2c27 692 goto fail;
ba64af90 693 }
e1ce2c27 694
718db961 695 r = udev_monitor_enable_receiving(m->udev_monitor);
ba64af90
LP
696 if (r < 0) {
697 log_error_errno(r, "Failed to enable udev event reception: %m");
a16e1123 698 goto fail;
ba64af90 699 }
f94ea366 700
151b9b96 701 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
702 if (r < 0) {
703 log_error_errno(r, "Failed to watch udev file descriptor: %m");
718db961 704 goto fail;
ba64af90 705 }
7dfbe2e3
TG
706
707 (void) sd_event_source_set_description(m->udev_event_source, "device");
a16e1123 708 }
f94ea366 709
718db961
LP
710 e = udev_enumerate_new(m->udev);
711 if (!e) {
ba64af90 712 log_oom();
4f2d528d
LP
713 goto fail;
714 }
718db961
LP
715
716 r = udev_enumerate_add_match_tag(e, "systemd");
ba64af90
LP
717 if (r < 0) {
718 log_error_errno(r, "Failed to create udev tag enumeration: %m");
e1ce2c27 719 goto fail;
ba64af90 720 }
25ac040b 721
e1202047 722 r = udev_enumerate_add_match_is_initialized(e);
ba64af90
LP
723 if (r < 0) {
724 log_error_errno(r, "Failed to install initialization match into enumeration: %m");
e1202047 725 goto fail;
ba64af90 726 }
e1202047 727
718db961 728 r = udev_enumerate_scan_devices(e);
ba64af90
LP
729 if (r < 0) {
730 log_error_errno(r, "Failed to enumerate devices: %m");
4f2d528d 731 goto fail;
ba64af90 732 }
25ac040b 733
4f2d528d 734 first = udev_enumerate_get_list_entry(e);
628c89cc
LP
735 udev_list_entry_foreach(item, first) {
736 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
737 const char *sysfs;
738
739 sysfs = udev_list_entry_get_name(item);
740
741 dev = udev_device_new_from_syspath(m->udev, sysfs);
742 if (!dev) {
743 log_oom();
744 continue;
745 }
746
747 if (!device_is_ready(dev))
748 continue;
749
750 (void) device_process_new(m, dev);
751
752 device_update_found_by_sysfs(m, sysfs, true, DEVICE_FOUND_UDEV, false);
753 }
25ac040b 754
ba64af90 755 return;
25ac040b
LP
756
757fail:
25ac040b 758 device_shutdown(m);
5cb5a6ff
LP
759}
760
718db961
LP
761static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
762 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
718db961 763 Manager *m = userdata;
628c89cc 764 const char *action, *sysfs;
718db961 765 int r;
f94ea366
LP
766
767 assert(m);
99448c1f 768
718db961 769 if (revents != EPOLLIN) {
99448c1f
KS
770 static RATELIMIT_DEFINE(limit, 10*USEC_PER_SEC, 5);
771
772 if (!ratelimit_test(&limit))
56f64d95 773 log_error_errno(errno, "Failed to get udev event: %m");
718db961
LP
774 if (!(revents & EPOLLIN))
775 return 0;
99448c1f 776 }
f94ea366 777
718db961
LP
778 /*
779 * libudev might filter-out devices which pass the bloom
780 * filter, so getting NULL here is not necessarily an error.
781 */
782 dev = udev_monitor_receive_device(m->udev_monitor);
783 if (!dev)
784 return 0;
f94ea366 785
628c89cc
LP
786 sysfs = udev_device_get_syspath(dev);
787 if (!sysfs) {
788 log_error("Failed to get udev sys path.");
789 return 0;
790 }
791
718db961
LP
792 action = udev_device_get_action(dev);
793 if (!action) {
f94ea366 794 log_error("Failed to get udev action string.");
718db961 795 return 0;
f94ea366
LP
796 }
797
f332611a 798 if (streq(action, "change")) {
f332611a 799 Unit *u;
bf70ff2c 800 Device *d, *l, *n;
f332611a 801
bf70ff2c
JR
802 l = hashmap_get(m->devices_by_sysfs, sysfs);
803 LIST_FOREACH_SAFE(same_sysfs, d, n, l) {
804 u = &d->meta;
f332611a
JR
805 if (u && UNIT_VTABLE(u)->active_state(u) == UNIT_ACTIVE) {
806 r = manager_propagate_reload(m, u, JOB_REPLACE, NULL);
807 if (r < 0)
808 log_error_errno(r, "Failed to propagate reload: %m");
809 }
810 }
811 }
812
813 /* A change event can signal that a device is becoming ready, in particular if
814 * the device is using the SYSTEMD_READY logic in udev
815 * so we need to reach the else block of the follwing if, even for change events */
6d445911 816 if (streq(action, "remove")) {
628c89cc 817 r = swap_process_device_remove(m, dev);
9670d583 818 if (r < 0)
da927ba9 819 log_error_errno(r, "Failed to process swap device remove event: %m");
9670d583 820
628c89cc
LP
821 /* If we get notified that a device was removed by
822 * udev, then it's completely gone, hence unset all
823 * found bits */
824 device_update_found_by_sysfs(m, sysfs, false, DEVICE_FOUND_UDEV|DEVICE_FOUND_MOUNT|DEVICE_FOUND_SWAP, true);
f1421cc6 825
628c89cc
LP
826 } else if (device_is_ready(dev)) {
827
828 (void) device_process_new(m, dev);
829
830 r = swap_process_device_new(m, dev);
9670d583 831 if (r < 0)
da927ba9 832 log_error_errno(r, "Failed to process swap device new event: %m");
9670d583 833
f1421cc6
LP
834 manager_dispatch_load_queue(m);
835
628c89cc
LP
836 /* The device is found now, set the udev found bit */
837 device_update_found_by_sysfs(m, sysfs, true, DEVICE_FOUND_UDEV, true);
838
839 } else {
840 /* The device is nominally around, but not ready for
841 * us. Hence unset the udev bit, but leave the rest
842 * around. */
843
844 device_update_found_by_sysfs(m, sysfs, false, DEVICE_FOUND_UDEV, true);
f94ea366
LP
845 }
846
718db961 847 return 0;
f94ea366
LP
848}
849
1c2e9646 850static bool device_supported(void) {
0faacd47 851 static int read_only = -1;
0faacd47
LP
852
853 /* If /sys is read-only we don't support device units, and any
854 * attempts to start one should fail immediately. */
855
856 if (read_only < 0)
857 read_only = path_is_read_only_fs("/sys");
858
859 return read_only <= 0;
860}
861
628c89cc
LP
862int device_found_node(Manager *m, const char *node, bool add, DeviceFound found, bool now) {
863 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
864 struct stat st;
865
866 assert(m);
867 assert(node);
868
4c6d20de
LP
869 if (!device_supported())
870 return 0;
871
628c89cc
LP
872 /* This is called whenever we find a device referenced in
873 * /proc/swaps or /proc/self/mounts. Such a device might be
874 * mounted/enabled at a time where udev has not finished
875 * probing it yet, and we thus haven't learned about it
876 * yet. In this case we will set the device unit to
877 * "tentative" state. */
878
879 if (add) {
880 if (!path_startswith(node, "/dev"))
881 return 0;
882
f6200941
LP
883 /* We make an extra check here, if the device node
884 * actually exists. If it's missing, then this is an
885 * indication that device was unplugged but is still
886 * referenced in /proc/swaps or
887 * /proc/self/mountinfo. Note that this check doesn't
888 * really cover all cases where a device might be gone
889 * away, since drives that can have a medium inserted
890 * will still have a device node even when the medium
891 * is not there... */
892
2005219f
MP
893 if (stat(node, &st) >= 0) {
894 if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode))
628c89cc
LP
895 return 0;
896
2005219f
MP
897 dev = udev_device_new_from_devnum(m->udev, S_ISBLK(st.st_mode) ? 'b' : 'c', st.st_rdev);
898 if (!dev && errno != ENOENT)
899 return log_error_errno(errno, "Failed to get udev device from devnum %u:%u: %m", major(st.st_rdev), minor(st.st_rdev));
628c89cc 900
2005219f
MP
901 } else if (errno != ENOENT)
902 return log_error_errno(errno, "Failed to stat device node file %s: %m", node);
628c89cc
LP
903
904 /* If the device is known in the kernel and newly
905 * appeared, then we'll create a device unit for it,
906 * under the name referenced in /proc/swaps or
907 * /proc/self/mountinfo. */
908
909 (void) device_setup_unit(m, dev, node, false);
910 }
911
912 /* Update the device unit's state, should it exist */
913 return device_update_found_by_name(m, node, add, found, now);
914}
915
ebc8968b
FB
916bool device_shall_be_bound_by(Unit *device, Unit *u) {
917
918 if (u->type != UNIT_MOUNT)
919 return false;
920
921 return DEVICE(device)->bind_mounts;
922}
923
87f0e418 924const UnitVTable device_vtable = {
7d17cfbc 925 .object_size = sizeof(Device),
f975e971
LP
926 .sections =
927 "Unit\0"
928 "Device\0"
929 "Install\0",
5cb5a6ff 930
c5a97ed1
LP
931 .gc_jobs = true,
932
faf919f1 933 .init = device_init,
034c6ed7 934 .done = device_done,
718db961
LP
935 .load = unit_load_fragment_and_dropin_optional,
936
f50e0a01
LP
937 .coldplug = device_coldplug,
938
f6200941
LP
939 .serialize = device_serialize,
940 .deserialize_item = device_deserialize_item,
941
5cb5a6ff
LP
942 .dump = device_dump,
943
f50e0a01 944 .active_state = device_active_state,
10a94420 945 .sub_state_to_string = device_sub_state_to_string,
25ac040b 946
718db961 947 .bus_vtable = bus_device_vtable,
4139c1b2 948
a7f241db 949 .following = device_following,
6210e7fc 950 .following_set = device_following_set,
a7f241db 951
f50e0a01 952 .enumerate = device_enumerate,
c6918296 953 .shutdown = device_shutdown,
0faacd47 954 .supported = device_supported,
c6918296
MS
955
956 .status_message_formats = {
957 .starting_stopping = {
958 [0] = "Expecting device %s...",
959 },
960 .finished_start_job = {
961 [JOB_DONE] = "Found device %s.",
962 [JOB_TIMEOUT] = "Timed out waiting for device %s.",
963 },
964 },
5cb5a6ff 965};