summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-07-06 15:15:09 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2022-07-20 21:06:08 +0900
commit01400460ae16c6522d11d08dd9a4b0928e7980d9 (patch)
tree875f2aeea7a92a2bcc5d3564d5869fa54a01566e
parente1b45a756f71deac8c1aa9a008bd0dab47f64777 (diff)
downloadsystemd-01400460ae16c6522d11d08dd9a4b0928e7980d9.tar.gz
core/mount: adjust deserialized state based on /proc/self/mountinfo
Fixes #23796. Replaces #23803 and #23851.
-rw-r--r--src/core/mount.c55
1 files changed, 45 insertions, 10 deletions
diff --git a/src/core/mount.c b/src/core/mount.c
index 836ba132cb..5ec3526c70 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -51,6 +51,9 @@ static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
+static void mount_enter_dead(Mount *m, MountResult f);
+static void mount_enter_mounted(Mount *m, MountResult f);
+static void mount_cycle_clear(Mount *m);
static int mount_process_proc_self_mountinfo(Manager *m);
static bool MOUNT_STATE_WITH_PROCESS(MountState state) {
@@ -753,23 +756,17 @@ static void mount_set_state(Mount *m, MountState state) {
static int mount_coldplug(Unit *u) {
Mount *m = MOUNT(u);
- MountState new_state = MOUNT_DEAD;
int r;
assert(m);
assert(m->state == MOUNT_DEAD);
- if (m->deserialized_state != m->state)
- new_state = m->deserialized_state;
- else if (m->from_proc_self_mountinfo)
- new_state = MOUNT_MOUNTED;
-
- if (new_state == m->state)
+ if (m->deserialized_state == m->state)
return 0;
if (m->control_pid > 0 &&
pid_is_unwaited(m->control_pid) &&
- MOUNT_STATE_WITH_PROCESS(new_state)) {
+ MOUNT_STATE_WITH_PROCESS(m->deserialized_state)) {
r = unit_watch_pid(UNIT(m), m->control_pid, false);
if (r < 0)
@@ -780,15 +777,52 @@ static int mount_coldplug(Unit *u) {
return r;
}
- if (!IN_SET(new_state, MOUNT_DEAD, MOUNT_FAILED)) {
+ if (!IN_SET(m->deserialized_state, MOUNT_DEAD, MOUNT_FAILED)) {
(void) unit_setup_dynamic_creds(u);
(void) unit_setup_exec_runtime(u);
}
- mount_set_state(m, new_state);
+ mount_set_state(m, m->deserialized_state);
return 0;
}
+static void mount_catchup(Unit *u) {
+ Mount *m = MOUNT(ASSERT_PTR(u));
+
+ assert(m);
+
+ /* Adjust the deserialized state. See comments in mount_process_proc_self_mountinfo(). */
+ if (m->from_proc_self_mountinfo)
+ switch (m->state) {
+ case MOUNT_DEAD:
+ case MOUNT_FAILED:
+ assert(m->control_pid == 0);
+ unit_acquire_invocation_id(u);
+ mount_cycle_clear(m);
+ mount_enter_mounted(m, MOUNT_SUCCESS);
+ break;
+ case MOUNT_MOUNTING:
+ assert(m->control_pid > 0);
+ mount_set_state(m, MOUNT_MOUNTING_DONE);
+ break;
+ default:
+ break;
+ }
+ else
+ switch (m->state) {
+ case MOUNT_MOUNTING_DONE:
+ assert(m->control_pid > 0);
+ mount_set_state(m, MOUNT_MOUNTING);
+ break;
+ case MOUNT_MOUNTED:
+ assert(m->control_pid == 0);
+ mount_enter_dead(m, MOUNT_SUCCESS);
+ break;
+ default:
+ break;
+ }
+}
+
static void mount_dump(Unit *u, FILE *f, const char *prefix) {
Mount *m = MOUNT(u);
MountParameters *p;
@@ -2247,6 +2281,7 @@ const UnitVTable mount_vtable = {
.done = mount_done,
.coldplug = mount_coldplug,
+ .catchup = mount_catchup,
.dump = mount_dump,