X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fdevice.c;h=0f28a168740de09d95bb46c2cbc4165ea11d604a;hb=5261ba901845c084de5a8fd06500ed09bfb0bd80;hp=63d0302d3b48de0367aaa1721dee8c7c5cd15618;hpb=c5ab2e02dc7086c72b23390594944b9278282347;p=elogind.git diff --git a/src/core/device.c b/src/core/device.c index 63d0302d3..0f28a1687 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,87 @@ 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; + const char *word, *state; + size_t l; + int r; + const char *property; + + assert(u); + assert(dev); + + property = u->manager->running_as == SYSTEMD_USER ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS"; + wants = udev_device_get_property_value(dev, property); + if (!wants) + return 0; + + FOREACH_WORD_QUOTED(word, l, wants, state) { + _cleanup_free_ char *n = NULL; + char e[l+1]; + + memcpy(e, word, 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; + } + if (!isempty(state)) + log_warning_unit(u->id, "Property %s on %s has trailing garbage, ignoring.", + property, strna(udev_device_get_syspath(dev))); + + 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 +316,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] = 0; - - 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 @@ -348,13 +395,13 @@ static int device_process_new_device(Manager *m, struct udev_device *dev) { * aliases */ alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS"); if (alias) { - char *state, *w; + const char *word, *state; size_t l; - FOREACH_WORD_QUOTED(w, l, alias, state) { + FOREACH_WORD_QUOTED(word, l, alias, state) { char e[l+1]; - memcpy(e, w, l); + memcpy(e, word, l); e[l] = 0; if (path_is_absolute(e)) @@ -362,6 +409,8 @@ static int device_process_new_device(Manager *m, struct udev_device *dev) { else log_warning("SYSTEMD_ALIAS for %s is not an absolute path, ignoring: %s", sysfs, e); } + if (!isempty(state)) + log_warning("SYSTEMD_ALIAS for %s has trailing garbage, ignoring.", sysfs); } return 0; @@ -502,11 +551,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 +562,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 +582,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 +597,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 +651,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 +701,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,