X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fdevice.c;h=bffeca0d10c7a857bb4ae1212799ad8fbbacdc42;hp=b5763645e8851fedb87c6daf5bd3d93234eeba13;hb=8f9b6cd9eb049b00b1e9e669d0e35aa415dc8fb0;hpb=99448c1f01d79891e0afdfcf3ec8ed9fa92502ae diff --git a/src/device.c b/src/device.c index b5763645e..bffeca0d1 100644 --- a/src/device.c +++ b/src/device.c @@ -29,6 +29,7 @@ #include "log.h" #include "unit-name.h" #include "dbus-device.h" +#include "def.h" static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = { [DEVICE_DEAD] = UNIT_INACTIVE, @@ -65,10 +66,13 @@ static void device_init(Unit *u) { /* In contrast to all other unit types we timeout jobs waiting * for devices by default. This is because they otherwise wait - * indefinetely for plugged in devices, something which cannot + * indefinitely for plugged in devices, something which cannot * happen for the other units since their operations time out * anyway. */ d->meta.job_timeout = DEFAULT_TIMEOUT_USEC; + + d->meta.ignore_on_isolate = true; + d->meta.ignore_on_snapshot = true; } static void device_done(Unit *u) { @@ -92,7 +96,7 @@ static void device_set_state(Device *d, DeviceState state) { device_state_to_string(old_state), device_state_to_string(state)); - unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state]); + unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], true); } static int device_coldplug(Unit *u) { @@ -468,8 +472,10 @@ static int device_enumerate(Manager *m) { goto fail; } - if (udev_monitor_set_receive_buffer_size(m->udev_monitor, 128*1024*1024) < 0) - log_error("Failed to set udev event buffer size."); + /* This will fail if we are unprivileged, but that + * should not matter much, as user instances won't run + * during boot. */ + udev_monitor_set_receive_buffer_size(m->udev_monitor, 128*1024*1024); if (udev_monitor_filter_add_match_tag(m->udev_monitor, "systemd") < 0) { r = -ENOMEM; @@ -524,7 +530,7 @@ fail: void device_fd_event(Manager *m, int events) { struct udev_device *dev; int r; - const char *action; + const char *action, *ready; assert(m); @@ -533,13 +539,14 @@ void device_fd_event(Manager *m, int events) { if (!ratelimit_test(&limit)) log_error("Failed to get udev event: %m"); - return; + if (!(events & EPOLLIN)) + return; } if (!(dev = udev_monitor_receive_device(m->udev_monitor))) { /* * libudev might filter-out devices which pass the bloom filter, - * so getting NULL here is not neccessarily an error + * so getting NULL here is not necessarily an error */ return; } @@ -549,7 +556,9 @@ void device_fd_event(Manager *m, int events) { goto fail; } - if (streq(action, "remove")) { + ready = udev_device_get_property_value(dev, "SYSTEMD_READY"); + + if (streq(action, "remove") || (ready && parse_boolean(ready) == 0)) { if ((r = device_process_removed_device(m, dev)) < 0) { log_error("Failed to process udev device event: %s", strerror(-r)); goto fail; @@ -574,10 +583,12 @@ DEFINE_STRING_TABLE_LOOKUP(device_state, DeviceState); const UnitVTable device_vtable = { .suffix = ".device", + .sections = + "Unit\0" + "Device\0" + "Install\0", .no_instances = true, - .no_snapshots = true, - .no_isolate = true, .init = device_init,