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