summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2019-03-15 11:37:43 +0100
committerYu Watanabe <watanabe.yu+github@gmail.com>2019-03-15 11:47:43 +0100
commitc6e892bc0eebe1d42c282bd2d8bae149fbeba85f (patch)
treeaac822b9c24c4179b244dd4921ba5bf9394fdf9d
parentcore: use TAKE_PTR() at few more places (diff)
downloadsystemd-c6e892bc0eebe1d42c282bd2d8bae149fbeba85f.tar.xz
systemd-c6e892bc0eebe1d42c282bd2d8bae149fbeba85f.zip
core: add Manager::honor_device_enumeration flag
When system manager is started first time or after switching root, then the udev's device tag data do not exist yet. So, let's not honor the enumeration results. Fixes #11997.
-rw-r--r--src/core/device.c6
-rw-r--r--src/core/manager.c19
-rw-r--r--src/core/manager.h2
3 files changed, 26 insertions, 1 deletions
diff --git a/src/core/device.c b/src/core/device.c
index 506bf74478..382c380498 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -666,9 +666,13 @@ static void device_found_changed(Device *d, DeviceFound previous, DeviceFound no
}
static void device_update_found_one(Device *d, DeviceFound found, DeviceFound mask) {
+ Manager *m;
+
assert(d);
- if (MANAGER_IS_RUNNING(UNIT(d)->manager)) {
+ m = UNIT(d)->manager;
+
+ if (MANAGER_IS_RUNNING(m) && (m->honor_device_enumeration || MANAGER_IS_USER(m))) {
DeviceFound n, previous;
/* When we are already running, then apply the new mask right-away, and trigger state changes
diff --git a/src/core/manager.c b/src/core/manager.c
index eecf48dea5..3f4dbe64e3 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -1619,6 +1619,8 @@ static void manager_ready(Manager *m) {
/* Let's finally catch up with any changes that took place while we were reloading/reexecing */
manager_catchup(m);
+
+ m->honor_device_enumeration = true;
}
static Manager* manager_reloading_start(Manager *m) {
@@ -3131,6 +3133,9 @@ int manager_serialize(
(void) serialize_bool(f, "taint-logged", m->taint_logged);
(void) serialize_bool(f, "service-watchdogs", m->service_watchdogs);
+ /* After switching root, udevd has not been started yet. So, enumeration results should not be emitted. */
+ (void) serialize_bool(f, "honor-device-enumeration", !switching_root);
+
t = show_status_to_string(m->show_status);
if (t)
(void) serialize_item(f, "show-status", t);
@@ -3359,6 +3364,15 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
else
m->service_watchdogs = b;
+ } else if ((val = startswith(l, "honor-device-enumeration="))) {
+ int b;
+
+ b = parse_boolean(val);
+ if (b < 0)
+ log_notice("Failed to parse honor-device-enumeration flag '%s', ignoring.", val);
+ else
+ m->honor_device_enumeration = b;
+
} else if ((val = startswith(l, "show-status="))) {
ShowStatus s;
@@ -3549,6 +3563,11 @@ int manager_reload(Manager *m) {
assert(m->n_reloading > 0);
m->n_reloading--;
+ /* On manager reloading, device tag data should exists, thus, we should honor the results of device
+ * enumeration. The flag should be always set correctly by the serialized data, but it may fail. So,
+ * let's always set the flag here for safety. */
+ m->honor_device_enumeration = true;
+
manager_ready(m);
m->send_reloading_done = true;
diff --git a/src/core/manager.h b/src/core/manager.h
index bce8020cfd..86b9ec202d 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -395,6 +395,8 @@ struct Manager {
* multiple times on the same unit. */
unsigned sigchldgen;
unsigned notifygen;
+
+ bool honor_device_enumeration;
};
#define MANAGER_IS_SYSTEM(m) ((m)->unit_file_scope == UNIT_FILE_SYSTEM)