Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:42.1:Rings:1-MinimalX
systemd
0003-device-rework-how-we-enter-tentative-state...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0003-device-rework-how-we-enter-tentative-state.patch of Package systemd
Based on f62009410a72f5a89bfb8fdd7e48d9d472a6887b Mon Sep 17 00:00:00 2001 From: Lennart Poettering <lennart@poettering.net> Date: Fri, 24 Apr 2015 12:29:05 +0200 Subject: [PATCH] device: rework how we enter tentative state This reworks how we enter tentative state and does so only when a device was previously not announced via udev. The previous check actually just checked whether a new state bit was set, which is not correct. Also, to be able to reliably maintain the tentative state across daemon reloads, we need to serialize and deserialize it. --- src/core/device.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++-------- src/core/device.h | 2 - 2 files changed, 69 insertions(+), 12 deletions(-) --- src/core/device.c +++ src/core/device.c 2015-06-16 00:00:00.000000000 +0000 @@ -149,14 +149,49 @@ static int device_coldplug(Unit *u) { if (d->found & DEVICE_FOUND_UDEV) /* If udev says the device is around, it's around */ device_set_state(d, DEVICE_PLUGGED); - else if (d->found != DEVICE_NOT_FOUND) + else if (d->found != DEVICE_NOT_FOUND && d->deserialized_state != DEVICE_PLUGGED) /* If a device is found in /proc/self/mountinfo or - * /proc/swaps, it's "tentatively" around. */ + * /proc/swaps, and was not yet announced via udev, + * it's "tentatively" around. */ device_set_state(d, DEVICE_TENTATIVE); return 0; } +static int device_serialize(Unit *u, FILE *f, FDSet *fds) { + Device *d = DEVICE(u); + + assert(u); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", device_state_to_string(d->state)); + + return 0; +} + +static int device_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Device *d = DEVICE(u); + + assert(u); + assert(key); + assert(value); + assert(fds); + + if (streq(key, "state")) { + DeviceState state; + + state = device_state_from_string(value); + if (state < 0) + log_debug_unit(u->id, "Failed to parse state value %s", value); + else + d->deserialized_state = state; + } else + log_debug_unit(u->id, "Unknown serialization key '%s'", key); + + return 0; +} + static void device_dump(Unit *u, FILE *f, const char *prefix) { Device *d = DEVICE(u); @@ -409,7 +444,7 @@ static int device_process_new(Manager *m } static void device_update_found_one(Device *d, bool add, DeviceFound found, bool now) { - DeviceFound n; + DeviceFound n, previous; assert(d); @@ -417,16 +452,27 @@ static void device_update_found_one(Devi if (n == d->found) return; + previous = d->found; d->found = n; - if (now) { - if (d->found & DEVICE_FOUND_UDEV) - device_set_state(d, DEVICE_PLUGGED); - else if (add && d->found != DEVICE_NOT_FOUND) - device_set_state(d, DEVICE_TENTATIVE); - else - device_set_state(d, DEVICE_DEAD); - } + if (!now) + return; + + if (d->found & DEVICE_FOUND_UDEV) + /* When the device is known to udev we consider it + * plugged. */ + device_set_state(d, DEVICE_PLUGGED); + else if (d->found != DEVICE_NOT_FOUND && (previous & DEVICE_FOUND_UDEV) == 0) + /* If the device has not been seen by udev yet, but is + * now referenced by the kernel, then we assume the + * kernel knows it now, and udev might soon too. */ + device_set_state(d, DEVICE_TENTATIVE); + else + /* If nobody sees the device, or if the device was + * previously seen by udev and now is only referenced + * from the kernel, then we consider the device is + * gone, the kernel just hasn't noticed it yet. */ + device_set_state(d, DEVICE_DEAD); } static int device_update_found_by_sysfs(Manager *m, const char *sysfs, bool add, DeviceFound found, bool now) { @@ -723,6 +769,16 @@ int device_found_node(Manager *m, const if (!path_startswith(node, "/dev")) return 0; + /* We make an extra check here, if the device node + * actually exists. If it's missing, then this is an + * indication that device was unplugged but is still + * referenced in /proc/swaps or + * /proc/self/mountinfo. Note that this check doesn't + * really cover all cases where a device might be gone + * away, since drives that can have a medium inserted + * will still have a device node even when the medium + * is not there... */ + if (stat(node, &st) < 0) { if (errno == ENOENT) return 0; @@ -777,6 +833,9 @@ const UnitVTable device_vtable = { .coldplug = device_coldplug, + .serialize = device_serialize, + .deserialize_item = device_deserialize_item, + .dump = device_dump, .active_state = device_active_state, --- src/core/device.h +++ src/core/device.h 2015-06-16 00:00:00.000000000 +0000 @@ -53,7 +53,7 @@ struct Device { devices for the same sysfs path. We chain them up here. */ LIST_FIELDS(struct Device, same_sysfs); - DeviceState state; + DeviceState state, deserialized_state; }; extern const UnitVTable device_vtable;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor