106 lines
4.0 KiB
Diff
106 lines
4.0 KiB
Diff
From e5c023a1c20058703f1517a48848b4ecec563db6 Mon Sep 17 00:00:00 2001
|
|
From: xujing <xujing99@huawei.com>
|
|
Date: Mon, 10 Jan 2022 22:42:30 +0800
|
|
Subject: [PATCH] core: skip change device to dead in manager_catchup during
|
|
booting
|
|
|
|
There is a problem during booting as follows:
|
|
1.systemd is processing all udev devices state but not finished
|
|
2.now calling daemon-reload, it will serialize and deserialize the device state
|
|
3.after deserialize, some devices is processed finished, it will cause devices
|
|
state changed when calling manager_catchup and then set device to DEVICE_DEAD
|
|
later which will cause some fs unmounted.
|
|
|
|
This patch just fix that fs will not unmounted during booting when calling
|
|
daemon-reload, if boot time is more than 10min, just ensure fs will not
|
|
unmounted during 10min after booting.
|
|
---
|
|
src/core/device.c | 16 ++++++++++++++++-
|
|
src/core/manager.c | 5 +++++
|
|
src/core/manager.h | 1 +
|
|
3 files changed, 21 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/src/core/device.c b/src/core/device.c
|
|
index 8f30c4e..71cb2a1 100644
|
|
--- a/src/core/device.c
|
|
+++ b/src/core/device.c
|
|
@@ -646,7 +647,10 @@ static int device_process_new(Manager *m, sd_device *dev) {
|
|
}
|
|
|
|
static void device_found_changed(Device *d, DeviceFound previous, DeviceFound now) {
|
|
+ Manager *m;
|
|
+
|
|
assert(d);
|
|
+ m = UNIT(d)->manager;
|
|
|
|
/* Didn't exist before, but does now? if so, generate a new invocation ID for it */
|
|
if (previous == DEVICE_NOT_FOUND && now != DEVICE_NOT_FOUND)
|
|
@@ -659,10 +663,21 @@ static void device_found_changed(Device *d, DeviceFound previous, DeviceFound no
|
|
/* 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
|
|
+ else {
|
|
+ if (m->in_manager_catchup && !MANAGER_IS_FINISHED(m)) {
|
|
+ dual_timestamp boot_timestamp;
|
|
+
|
|
+ dual_timestamp_get(&boot_timestamp);
|
|
+ if (boot_timestamp.monotonic < 10*USEC_PER_MINUTE) {
|
|
+ log_info("Want to change device to dead in manager_catchup during booting, skipping!");
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
/* 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 void device_update_found_one(Device *d, DeviceFound found, DeviceFound mask) {
|
|
diff --git a/src/core/manager.c b/src/core/manager.c
|
|
index 41b7cf7..b948ac6 100644
|
|
--- a/src/core/manager.c
|
|
+++ b/src/core/manager.c
|
|
@@ -788,6 +788,7 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager
|
|
.test_run_flags = test_run_flags,
|
|
|
|
.default_oom_policy = OOM_STOP,
|
|
+ .in_manager_catchup = false,
|
|
};
|
|
|
|
#if ENABLE_EFI
|
|
@@ -1475,6 +1476,8 @@ static void manager_catchup(Manager *m) {
|
|
|
|
log_debug("Invoking unit catchup() handlers…");
|
|
|
|
+ m->in_manager_catchup = true;
|
|
+
|
|
/* Let's catch up on any state changes that happened while we were reloading/reexecing */
|
|
HASHMAP_FOREACH_KEY(u, k, m->units) {
|
|
|
|
@@ -1484,6 +1487,8 @@ static void manager_catchup(Manager *m) {
|
|
|
|
unit_catchup(u);
|
|
}
|
|
+
|
|
+ m->in_manager_catchup = false;
|
|
}
|
|
|
|
static void manager_distribute_fds(Manager *m, FDSet *fds) {
|
|
diff --git a/src/core/manager.h b/src/core/manager.h
|
|
index d1e540a..73c149f 100644
|
|
--- a/src/core/manager.h
|
|
+++ b/src/core/manager.h
|
|
@@ -423,6 +423,7 @@ struct Manager {
|
|
unsigned notifygen;
|
|
|
|
bool honor_device_enumeration;
|
|
+ bool in_manager_catchup;
|
|
|
|
VarlinkServer *varlink_server;
|
|
/* Only systemd-oomd should be using this to subscribe to changes in ManagedOOM settings */
|
|
--
|
|
2.23.0
|
|
|