1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
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.
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.
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/>.
23 #include <sys/epoll.h>
28 #include "unit-name.h"
29 #include "dbus-device.h"
31 #include "path-util.h"
32 #include "udev-util.h"
37 static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = {
38 [DEVICE_DEAD] = UNIT_INACTIVE,
39 [DEVICE_PLUGGED] = UNIT_ACTIVE
42 static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
44 static void device_unset_sysfs(Device *d) {
53 /* Remove this unit from the chain of devices which share the
55 devices = UNIT(d)->manager->devices_by_sysfs;
56 first = hashmap_get(devices, d->sysfs);
57 LIST_REMOVE(same_sysfs, first, d);
60 hashmap_remove_and_replace(devices, d->sysfs, first->sysfs, first);
62 hashmap_remove(devices, d->sysfs);
68 static void device_init(Unit *u) {
69 Device *d = DEVICE(u);
72 assert(UNIT(d)->load_state == UNIT_STUB);
74 /* In contrast to all other unit types we timeout jobs waiting
75 * for devices by default. This is because they otherwise wait
76 * indefinitely for plugged in devices, something which cannot
77 * happen for the other units since their operations time out
79 u->job_timeout = u->manager->default_timeout_start_usec;
81 u->ignore_on_isolate = true;
82 u->ignore_on_snapshot = true;
85 static void device_done(Unit *u) {
86 Device *d = DEVICE(u);
90 device_unset_sysfs(d);
93 static void device_set_state(Device *d, DeviceState state) {
94 DeviceState old_state;
100 if (state != old_state)
101 log_debug_unit(UNIT(d)->id,
102 "%s changed %s -> %s", UNIT(d)->id,
103 device_state_to_string(old_state),
104 device_state_to_string(state));
106 unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], true);
109 static int device_coldplug(Unit *u) {
110 Device *d = DEVICE(u);
113 assert(d->state == DEVICE_DEAD);
116 device_set_state(d, DEVICE_PLUGGED);
121 static void device_dump(Unit *u, FILE *f, const char *prefix) {
122 Device *d = DEVICE(u);
127 "%sDevice State: %s\n"
128 "%sSysfs Path: %s\n",
129 prefix, device_state_to_string(d->state),
130 prefix, strna(d->sysfs));
133 _pure_ static UnitActiveState device_active_state(Unit *u) {
136 return state_translation_table[DEVICE(u)->state];
139 _pure_ static const char *device_sub_state_to_string(Unit *u) {
142 return device_state_to_string(DEVICE(u)->state);
145 static int device_add_escaped_name(Unit *u, const char *dn) {
146 _cleanup_free_ char *e = NULL;
151 assert(dn[0] == '/');
153 e = unit_name_from_path(dn, ".device");
157 r = unit_add_name(u, e);
158 if (r < 0 && r != -EEXIST)
164 static int device_find_escape_name(Manager *m, const char *dn, Unit **_u) {
165 _cleanup_free_ char *e = NULL;
170 assert(dn[0] == '/');
173 e = unit_name_from_path(dn, ".device");
177 u = manager_get_unit(m, e);
186 static int device_make_description(Unit *u, struct udev_device *dev, const char *path) {
193 model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE");
195 model = udev_device_get_property_value(dev, "ID_MODEL");
200 /* Try to concatenate the device model string with a label, if there is one */
201 label = udev_device_get_property_value(dev, "ID_FS_LABEL");
203 label = udev_device_get_property_value(dev, "ID_PART_ENTRY_NAME");
205 label = udev_device_get_property_value(dev, "ID_PART_ENTRY_NUMBER");
208 _cleanup_free_ char *j;
210 j = strjoin(model, " ", label, NULL);
212 return unit_set_description(u, j);
215 return unit_set_description(u, model);
218 return unit_set_description(u, path);
221 static int device_add_udev_wants(Unit *u, struct udev_device *dev) {
230 wants = udev_device_get_property_value(
232 u->manager->running_as == SYSTEMD_USER ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS");
237 FOREACH_WORD_QUOTED(w, l, wants, state) {
238 _cleanup_free_ char *n = NULL;
244 n = unit_name_mangle(e, MANGLE_NOGLOB);
248 r = unit_add_dependency_by_name(u, UNIT_WANTS, n, NULL, true);
256 static int device_update_unit(Manager *m, struct udev_device *dev, const char *path, bool main) {
266 sysfs = udev_device_get_syspath(dev);
270 r = device_find_escape_name(m, path, &u);
274 if (u && DEVICE(u)->sysfs && !path_equal(DEVICE(u)->sysfs, sysfs))
280 u = unit_new(m, sizeof(Device));
284 r = device_add_escaped_name(u, path);
288 unit_add_to_load_queue(u);
292 /* If this was created via some dependency and has not
293 * actually been seen yet ->sysfs will not be
294 * initialized. Hence initialize it if necessary. */
296 if (!DEVICE(u)->sysfs) {
299 DEVICE(u)->sysfs = strdup(sysfs);
300 if (!DEVICE(u)->sysfs) {
305 r = hashmap_ensure_allocated(&m->devices_by_sysfs, string_hash_func, string_compare_func);
309 first = hashmap_get(m->devices_by_sysfs, sysfs);
310 LIST_PREPEND(same_sysfs, first, DEVICE(u));
312 r = hashmap_replace(m->devices_by_sysfs, DEVICE(u)->sysfs, first);
317 device_make_description(u, dev, path);
320 /* The additional systemd udev properties we only
321 * interpret for the main object */
323 r = device_add_udev_wants(u, dev);
328 /* Note that this won't dispatch the load queue, the caller
329 * has to do that if needed and appropriate */
331 unit_add_to_dbus_queue(u);
335 log_warning("Failed to load device unit: %s", strerror(-r));
343 static int device_process_new_device(Manager *m, struct udev_device *dev) {
344 const char *sysfs, *dn, *alias;
345 struct udev_list_entry *item = NULL, *first = NULL;
350 sysfs = udev_device_get_syspath(dev);
354 /* Add the main unit named after the sysfs path */
355 r = device_update_unit(m, dev, sysfs, true);
359 /* Add an additional unit for the device node */
360 dn = udev_device_get_devnode(dev);
362 device_update_unit(m, dev, dn, false);
364 /* Add additional units for all symlinks */
365 first = udev_device_get_devlinks_list_entry(dev);
366 udev_list_entry_foreach(item, first) {
370 /* Don't bother with the /dev/block links */
371 p = udev_list_entry_get_name(item);
373 if (path_startswith(p, "/dev/block/") ||
374 path_startswith(p, "/dev/char/"))
377 /* Verify that the symlink in the FS actually belongs
378 * to this device. This is useful to deal with
379 * conflicting devices, e.g. when two disks want the
380 * same /dev/disk/by-label/xxx link because they have
381 * the same label. We want to make sure that the same
382 * device that won the symlink wins in systemd, so we
383 * check the device node major/minor*/
384 if (stat(p, &st) >= 0)
385 if ((!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) ||
386 st.st_rdev != udev_device_get_devnum(dev))
389 device_update_unit(m, dev, p, false);
392 /* Add additional units for all explicitly configured
394 alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS");
399 FOREACH_WORD_QUOTED(w, l, alias, state) {
405 if (path_is_absolute(e))
406 device_update_unit(m, dev, e, false);
408 log_warning("SYSTEMD_ALIAS for %s is not an absolute path, ignoring: %s", sysfs, e);
415 static void device_set_path_plugged(Manager *m, struct udev_device *dev) {
422 sysfs = udev_device_get_syspath(dev);
426 l = hashmap_get(m->devices_by_sysfs, sysfs);
427 LIST_FOREACH(same_sysfs, d, l)
428 device_set_state(d, DEVICE_PLUGGED);
431 static int device_process_removed_device(Manager *m, struct udev_device *dev) {
438 sysfs = udev_device_get_syspath(dev);
442 /* Remove all units of this sysfs path */
443 while ((d = hashmap_get(m->devices_by_sysfs, sysfs))) {
444 device_unset_sysfs(d);
445 device_set_state(d, DEVICE_DEAD);
451 static bool device_is_ready(struct udev_device *dev) {
456 ready = udev_device_get_property_value(dev, "SYSTEMD_READY");
460 return parse_boolean(ready) != 0;
463 static int device_process_new_path(Manager *m, const char *path) {
464 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
469 dev = udev_device_new_from_syspath(m->udev, path);
473 if (!device_is_ready(dev))
476 return device_process_new_device(m, dev);
479 static Unit *device_following(Unit *u) {
480 Device *d = DEVICE(u);
481 Device *other, *first = NULL;
485 if (startswith(u->id, "sys-"))
488 /* Make everybody follow the unit that's named after the sysfs path */
489 for (other = d->same_sysfs_next; other; other = other->same_sysfs_next)
490 if (startswith(UNIT(other)->id, "sys-"))
493 for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev) {
494 if (startswith(UNIT(other)->id, "sys-"))
503 static int device_following_set(Unit *u, Set **_set) {
504 Device *d = DEVICE(u), *other;
511 if (LIST_JUST_US(same_sysfs, d)) {
516 set = set_new(NULL, NULL);
520 LIST_FOREACH_AFTER(same_sysfs, other, d) {
521 r = set_put(set, other);
526 LIST_FOREACH_BEFORE(same_sysfs, other, d) {
527 r = set_put(set, other);
540 static void device_shutdown(Manager *m) {
543 m->udev_event_source = sd_event_source_unref(m->udev_event_source);
545 if (m->udev_monitor) {
546 udev_monitor_unref(m->udev_monitor);
547 m->udev_monitor = NULL;
550 hashmap_free(m->devices_by_sysfs);
551 m->devices_by_sysfs = NULL;
554 static int device_enumerate(Manager *m) {
555 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
556 struct udev_list_entry *item = NULL, *first = NULL;
561 if (!m->udev_monitor) {
562 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
563 if (!m->udev_monitor) {
568 /* This will fail if we are unprivileged, but that
569 * should not matter much, as user instances won't run
571 udev_monitor_set_receive_buffer_size(m->udev_monitor, 128*1024*1024);
573 r = udev_monitor_filter_add_match_tag(m->udev_monitor, "systemd");
577 r = udev_monitor_enable_receiving(m->udev_monitor);
581 r = sd_event_add_io(m->event, &m->udev_event_source, udev_monitor_get_fd(m->udev_monitor), EPOLLIN, device_dispatch_io, m);
586 e = udev_enumerate_new(m->udev);
592 r = udev_enumerate_add_match_tag(e, "systemd");
596 r = udev_enumerate_add_match_is_initialized(e);
600 r = udev_enumerate_scan_devices(e);
604 first = udev_enumerate_get_list_entry(e);
605 udev_list_entry_foreach(item, first)
606 device_process_new_path(m, udev_list_entry_get_name(item));
615 static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
616 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
617 Manager *m = userdata;
623 if (revents != EPOLLIN) {
624 static RATELIMIT_DEFINE(limit, 10*USEC_PER_SEC, 5);
626 if (!ratelimit_test(&limit))
627 log_error("Failed to get udev event: %m");
628 if (!(revents & EPOLLIN))
633 * libudev might filter-out devices which pass the bloom
634 * filter, so getting NULL here is not necessarily an error.
636 dev = udev_monitor_receive_device(m->udev_monitor);
640 action = udev_device_get_action(dev);
642 log_error("Failed to get udev action string.");
646 if (streq(action, "remove") || !device_is_ready(dev)) {
647 r = device_process_removed_device(m, dev);
649 log_error("Failed to process device remove event: %s", strerror(-r));
651 r = swap_process_removed_device(m, dev);
653 log_error("Failed to process swap device remove event: %s", strerror(-r));
656 r = device_process_new_device(m, dev);
658 log_error("Failed to process device new event: %s", strerror(-r));
660 r = swap_process_new_device(m, dev);
662 log_error("Failed to process swap device new event: %s", strerror(-r));
664 manager_dispatch_load_queue(m);
666 device_set_path_plugged(m, dev);
672 static const char* const device_state_table[_DEVICE_STATE_MAX] = {
673 [DEVICE_DEAD] = "dead",
674 [DEVICE_PLUGGED] = "plugged"
677 DEFINE_STRING_TABLE_LOOKUP(device_state, DeviceState);
679 const UnitVTable device_vtable = {
680 .object_size = sizeof(Device),
686 .no_instances = true,
690 .load = unit_load_fragment_and_dropin_optional,
692 .coldplug = device_coldplug,
696 .active_state = device_active_state,
697 .sub_state_to_string = device_sub_state_to_string,
699 .bus_interface = "org.freedesktop.systemd1.Device",
700 .bus_vtable = bus_device_vtable,
702 .following = device_following,
703 .following_set = device_following_set,
705 .enumerate = device_enumerate,
706 .shutdown = device_shutdown,
708 .status_message_formats = {
709 .starting_stopping = {
710 [0] = "Expecting device %s...",
712 .finished_start_job = {
713 [JOB_DONE] = "Found device %s.",
714 [JOB_TIMEOUT] = "Timed out waiting for device %s.",