X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fdevice.c;h=444286e02b2a7bfc14bd3a5b3c6bab6f10f1955b;hb=be8f4e9e8eb3b0c34a49c2e80a5c5b7dc6d175f0;hp=4ed06a6e516166b83b04cf6ef1a11eeced780f7d;hpb=f1421cc67dba47f0fdb1c963cf65115c8a8e72f0;p=elogind.git diff --git a/src/core/device.c b/src/core/device.c index 4ed06a6e5..444286e02 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -23,8 +23,6 @@ #include #include -#include "unit.h" -#include "device.h" #include "strv.h" #include "log.h" #include "unit-name.h" @@ -32,6 +30,9 @@ #include "def.h" #include "path-util.h" #include "udev-util.h" +#include "unit.h" +#include "swap.h" +#include "device.h" static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = { [DEVICE_DEAD] = UNIT_INACTIVE, @@ -182,13 +183,85 @@ static int device_find_escape_name(Manager *m, const char *dn, Unit **_u) { return 0; } +static int device_make_description(Unit *u, struct udev_device *dev, const char *path) { + const char *model; + + assert(u); + assert(dev); + assert(path); + + model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE"); + if (!model) + model = udev_device_get_property_value(dev, "ID_MODEL"); + + if (model) { + const char *label; + + /* Try to concatenate the device model string with a label, if there is one */ + label = udev_device_get_property_value(dev, "ID_FS_LABEL"); + if (!label) + label = udev_device_get_property_value(dev, "ID_PART_ENTRY_NAME"); + if (!label) + label = udev_device_get_property_value(dev, "ID_PART_ENTRY_NUMBER"); + + if (label) { + _cleanup_free_ char *j; + + j = strjoin(model, " ", label, NULL); + if (j) + return unit_set_description(u, j); + } + + return unit_set_description(u, model); + } + + return unit_set_description(u, path); +} + +static int device_add_udev_wants(Unit *u, struct udev_device *dev) { + const char *wants; + char *state, *w; + size_t l; + int r; + + assert(u); + assert(dev); + + wants = udev_device_get_property_value( + dev, + u->manager->running_as == SYSTEMD_USER ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS"); + + if (!wants) + return 0; + + FOREACH_WORD_QUOTED(w, l, wants, state) { + _cleanup_free_ char *n = NULL; + char e[l+1]; + + memcpy(e, w, l); + e[l] = 0; + + n = unit_name_mangle(e, MANGLE_NOGLOB); + if (!n) + return -ENOMEM; + + r = unit_add_dependency_by_name(u, UNIT_WANTS, n, NULL, true); + if (r < 0) + return r; + } + + return 0; +} + static int device_update_unit(Manager *m, struct udev_device *dev, const char *path, bool main) { - const char *sysfs, *model; + const char *sysfs; Unit *u = NULL; - int r; bool delete; + int r; assert(m); + assert(dev); + assert(path); sysfs = udev_device_get_syspath(dev); if (!sysfs) @@ -241,43 +314,15 @@ static int device_update_unit(Manager *m, struct udev_device *dev, const char *p goto fail; } - if ((model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE")) || - (model = udev_device_get_property_value(dev, "ID_MODEL"))) - r = unit_set_description(u, model); - else - r = unit_set_description(u, path); - if (r < 0) - goto fail; + device_make_description(u, dev, path); if (main) { - const char *wants; - /* The additional systemd udev properties we only * interpret for the main object */ - wants = udev_device_get_property_value(dev, m->running_as == SYSTEMD_USER ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS"); - if (wants) { - char *state, *w; - size_t l; - - FOREACH_WORD_QUOTED(w, l, wants, state) { - _cleanup_free_ char *n = NULL; - char e[l+1]; - - memcpy(e, w, l); - e[l] = 1; - - n = unit_name_mangle(e); - if (!n) { - r = -ENOMEM; - goto fail; - } - - r = unit_add_dependency_by_name(u, UNIT_WANTS, n, NULL, true); - if (r < 0) - goto fail; - } - } + r = device_add_udev_wants(u, dev); + if (r < 0) + goto fail; } /* Note that this won't dispatch the load queue, the caller @@ -502,11 +547,6 @@ static void device_shutdown(Manager *m) { m->udev_monitor = NULL; } - if (m->udev) { - udev_unref(m->udev); - m->udev = NULL; - } - hashmap_free(m->devices_by_sysfs); m->devices_by_sysfs = NULL; } @@ -518,11 +558,7 @@ static int device_enumerate(Manager *m) { assert(m); - if (!m->udev) { - m->udev = udev_new(); - if (!m->udev) - return -ENOMEM; - + if (!m->udev_monitor) { m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev"); if (!m->udev_monitor) { r = -ENOMEM; @@ -542,7 +578,7 @@ static int device_enumerate(Manager *m) { if (r < 0) goto fail; - r = sd_event_add_io(m->event, udev_monitor_get_fd(m->udev_monitor), EPOLLIN, device_dispatch_io, m, &m->udev_event_source); + r = sd_event_add_io(m->event, &m->udev_event_source, udev_monitor_get_fd(m->udev_monitor), EPOLLIN, device_dispatch_io, m); if (r < 0) goto fail; } @@ -557,6 +593,10 @@ static int device_enumerate(Manager *m) { if (r < 0) goto fail; + r = udev_enumerate_add_match_is_initialized(e); + if (r < 0) + goto fail; + r = udev_enumerate_scan_devices(e); if (r < 0) goto fail; @@ -607,11 +647,20 @@ static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, r = device_process_removed_device(m, dev); if (r < 0) log_error("Failed to process device remove event: %s", strerror(-r)); + + r = swap_process_removed_device(m, dev); + if (r < 0) + log_error("Failed to process swap device remove event: %s", strerror(-r)); + } else { r = device_process_new_device(m, dev); if (r < 0) log_error("Failed to process device new event: %s", strerror(-r)); + r = swap_process_new_device(m, dev); + if (r < 0) + log_error("Failed to process swap device new event: %s", strerror(-r)); + manager_dispatch_load_queue(m); device_set_path_plugged(m, dev); @@ -648,7 +697,6 @@ const UnitVTable device_vtable = { .sub_state_to_string = device_sub_state_to_string, .bus_interface = "org.freedesktop.systemd1.Device", - .bus_changing_properties = bus_device_changing_properties, .bus_vtable = bus_device_vtable, .following = device_following,