mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
Merge pull request #8675 from fbuihuu/make-sure-device-enter-in-plugged-state
device: make sure to always retroactively start device dependencies
This commit is contained in:
commit
d2bc13bde8
@ -17,6 +17,7 @@
|
|||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
#include "stat-util.h"
|
#include "stat-util.h"
|
||||||
|
#include "string-table.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "swap.h"
|
#include "swap.h"
|
||||||
#include "udev-util.h"
|
#include "udev-util.h"
|
||||||
@ -132,6 +133,13 @@ static int device_coldplug(Unit *u) {
|
|||||||
assert(d);
|
assert(d);
|
||||||
assert(d->state == DEVICE_DEAD);
|
assert(d->state == DEVICE_DEAD);
|
||||||
|
|
||||||
|
/* This should happen only when we reexecute PID1 from an old version
|
||||||
|
* which didn't serialize d->found. In this case simply assume that the
|
||||||
|
* device was in plugged state right before we started reexecuting which
|
||||||
|
* might be a wrong assumption. */
|
||||||
|
if (d->found == DEVICE_FOUND_UDEV_DB)
|
||||||
|
d->found = DEVICE_FOUND_UDEV;
|
||||||
|
|
||||||
if (d->found & DEVICE_FOUND_UDEV)
|
if (d->found & DEVICE_FOUND_UDEV)
|
||||||
/* If udev says the device is around, it's around */
|
/* If udev says the device is around, it's around */
|
||||||
device_set_state(d, DEVICE_PLUGGED);
|
device_set_state(d, DEVICE_PLUGGED);
|
||||||
@ -152,6 +160,7 @@ static int device_serialize(Unit *u, FILE *f, FDSet *fds) {
|
|||||||
assert(fds);
|
assert(fds);
|
||||||
|
|
||||||
unit_serialize_item(u, f, "state", device_state_to_string(d->state));
|
unit_serialize_item(u, f, "state", device_state_to_string(d->state));
|
||||||
|
unit_serialize_item(u, f, "found", device_found_to_string(d->found));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -164,6 +173,18 @@ static int device_deserialize_item(Unit *u, const char *key, const char *value,
|
|||||||
assert(value);
|
assert(value);
|
||||||
assert(fds);
|
assert(fds);
|
||||||
|
|
||||||
|
/* The device was known at the time units were serialized but it's not
|
||||||
|
* anymore at the time units are deserialized. This happens when PID1 is
|
||||||
|
* re-executed after having switched to the new rootfs: devices were
|
||||||
|
* enumerated but udevd wasn't running yet thus the list of devices
|
||||||
|
* (handled by systemd) to initialize was empty. In such case we wait
|
||||||
|
* for the device events to be re-triggered by udev so device units are
|
||||||
|
* properly re-initialized. */
|
||||||
|
if (d->found == DEVICE_NOT_FOUND) {
|
||||||
|
assert(d->sysfs == NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (streq(key, "state")) {
|
if (streq(key, "state")) {
|
||||||
DeviceState state;
|
DeviceState state;
|
||||||
|
|
||||||
@ -172,6 +193,16 @@ static int device_deserialize_item(Unit *u, const char *key, const char *value,
|
|||||||
log_unit_debug(u, "Failed to parse state value: %s", value);
|
log_unit_debug(u, "Failed to parse state value: %s", value);
|
||||||
else
|
else
|
||||||
d->deserialized_state = state;
|
d->deserialized_state = state;
|
||||||
|
|
||||||
|
} else if (streq(key, "found")) {
|
||||||
|
DeviceFound found;
|
||||||
|
|
||||||
|
found = device_found_from_string(value);
|
||||||
|
if (found < 0)
|
||||||
|
log_unit_debug(u, "Failed to parse found value: %s", value);
|
||||||
|
else
|
||||||
|
d->found = found;
|
||||||
|
|
||||||
} else
|
} else
|
||||||
log_unit_debug(u, "Unknown serialization key: %s", key);
|
log_unit_debug(u, "Unknown serialization key: %s", key);
|
||||||
|
|
||||||
@ -731,7 +762,7 @@ static void device_enumerate(Manager *m) {
|
|||||||
|
|
||||||
(void) device_process_new(m, dev);
|
(void) device_process_new(m, dev);
|
||||||
|
|
||||||
device_update_found_by_sysfs(m, sysfs, true, DEVICE_FOUND_UDEV, false);
|
device_update_found_by_sysfs(m, sysfs, true, DEVICE_FOUND_UDEV_DB, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -903,6 +934,16 @@ bool device_shall_be_bound_by(Unit *device, Unit *u) {
|
|||||||
return DEVICE(device)->bind_mounts;
|
return DEVICE(device)->bind_mounts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* const device_found_table[] = {
|
||||||
|
[DEVICE_NOT_FOUND] = "not-found",
|
||||||
|
[DEVICE_FOUND_UDEV] = "found-udev",
|
||||||
|
[DEVICE_FOUND_UDEV_DB] = "found-udev-db",
|
||||||
|
[DEVICE_FOUND_MOUNT] = "found-mount",
|
||||||
|
[DEVICE_FOUND_SWAP] = "found-swap",
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_STRING_TABLE_LOOKUP(device_found, DeviceFound);
|
||||||
|
|
||||||
const UnitVTable device_vtable = {
|
const UnitVTable device_vtable = {
|
||||||
.object_size = sizeof(Device),
|
.object_size = sizeof(Device),
|
||||||
.sections =
|
.sections =
|
||||||
|
@ -10,10 +10,11 @@
|
|||||||
typedef struct Device Device;
|
typedef struct Device Device;
|
||||||
|
|
||||||
typedef enum DeviceFound {
|
typedef enum DeviceFound {
|
||||||
DEVICE_NOT_FOUND = 0,
|
DEVICE_NOT_FOUND = 0,
|
||||||
DEVICE_FOUND_UDEV = 1,
|
DEVICE_FOUND_UDEV = 1 << 1,
|
||||||
DEVICE_FOUND_MOUNT = 2,
|
DEVICE_FOUND_UDEV_DB = 1 << 2,
|
||||||
DEVICE_FOUND_SWAP = 4,
|
DEVICE_FOUND_MOUNT = 1 << 3,
|
||||||
|
DEVICE_FOUND_SWAP = 1 << 4,
|
||||||
} DeviceFound;
|
} DeviceFound;
|
||||||
|
|
||||||
struct Device {
|
struct Device {
|
||||||
@ -36,3 +37,6 @@ extern const UnitVTable device_vtable;
|
|||||||
|
|
||||||
int device_found_node(Manager *m, const char *node, bool add, DeviceFound found, bool now);
|
int device_found_node(Manager *m, const char *node, bool add, DeviceFound found, bool now);
|
||||||
bool device_shall_be_bound_by(Unit *device, Unit *u);
|
bool device_shall_be_bound_by(Unit *device, Unit *u);
|
||||||
|
|
||||||
|
const char *device_found_to_string(DeviceFound f) _const_;
|
||||||
|
DeviceFound device_found_from_string(const char *s) _pure_;
|
||||||
|
Loading…
Reference in New Issue
Block a user