mirror of
https://github.com/systemd/systemd.git
synced 2024-12-25 01:34:28 +03:00
Merge pull request #23893 from yuwata/core-mount-re-read-mountinfo
core/mount: adjust deserialized state based on if the corresponding mountinfo entry exists or not
This commit is contained in:
commit
712e0b4792
@ -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) {
|
||||
@ -762,23 +765,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)
|
||||
@ -789,15 +786,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;
|
||||
@ -2227,6 +2261,7 @@ const UnitVTable mount_vtable = {
|
||||
.done = mount_done,
|
||||
|
||||
.coldplug = mount_coldplug,
|
||||
.catchup = mount_catchup,
|
||||
|
||||
.dump = mount_dump,
|
||||
|
||||
|
@ -202,6 +202,45 @@ EOF
|
||||
}
|
||||
}
|
||||
|
||||
test_issue_23796() {
|
||||
local mount_path mount_mytmpfs
|
||||
|
||||
mount_path="$(command -v mount 2>/dev/null)"
|
||||
mount_mytmpfs="${mount_path/\/bin/\/sbin}.mytmpfs"
|
||||
cat >"$mount_mytmpfs" <<EOF
|
||||
#!/bin/bash
|
||||
sleep ".\$RANDOM"
|
||||
exec -- $mount_path -t tmpfs tmpfs "\$2"
|
||||
EOF
|
||||
chmod +x "$mount_mytmpfs"
|
||||
|
||||
mkdir -p /run/systemd/system
|
||||
cat >/run/systemd/system/tmp-hoge.mount <<EOF
|
||||
[Mount]
|
||||
What=mytmpfs
|
||||
Where=/tmp/hoge
|
||||
Type=mytmpfs
|
||||
EOF
|
||||
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -f /run/systemd/system/tmp-hoge.mount '$mount_mytmpfs'" RETURN
|
||||
|
||||
for ((i = 0; i < 10; i++)); do
|
||||
systemctl --no-block start tmp-hoge.mount
|
||||
sleep ".$RANDOM"
|
||||
systemctl daemon-reexec
|
||||
|
||||
sleep 1
|
||||
|
||||
if [[ "$(systemctl is-failed tmp-hoge.mount)" == "failed" ]] || \
|
||||
journalctl -u tmp-hoge.mount -q --grep "but there is no mount"; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
systemctl stop tmp-hoge.mount
|
||||
done
|
||||
}
|
||||
|
||||
: >/failed
|
||||
|
||||
systemd-analyze log-level debug
|
||||
@ -263,6 +302,9 @@ test_dependencies
|
||||
# test that handling of mount start jobs is delayed when /proc/self/mouninfo monitor is rate limited
|
||||
test_issue_20329
|
||||
|
||||
# test for reexecuting with background mount job
|
||||
test_issue_23796
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
touch /testok
|
||||
|
Loading…
Reference in New Issue
Block a user