core: on each iteration processing /proc/self/mountinfo merge all discovery flags for each path

This extends on d253a45e1c, and instead of
merging just a single flag from previous mount entries of
/proc/self/mountinfo for the same path we merge all three.

This shouldn't change behaviour, but I think make things more readable.

Previously we'd set MOUNT_PROC_IS_MOUNTED unconditionally, we still do.

Previously we'd inherit MOUNT_PROC_JUST_MOUNTED from a previous entry on
the same line, we still do.

MOUNT_PROC_JUST_CHANGED should generally stay set too. Why that? If we
have two mount entries on the same mount point we'd first process one
and then the other, and the almost certainly different mount parameters
of the two would mean we'd set MOUNT_PROC_JUST_CHANGED for the second.
And with this we'll definitely do that still.

This also adds a comment explaining the situation a bit, and why we get
into this situation.
This commit is contained in:
Lennart Poettering 2020-01-14 16:25:45 +01:00
parent dd1b23a313
commit 4bb68f2fee

View file

@ -1550,11 +1550,10 @@ static int mount_setup_existing_unit(
const char *fstype,
MountProcFlags *ret_flags) {
MountProcFlags flags = MOUNT_PROC_IS_MOUNTED;
int r;
assert(u);
assert(flags);
assert(ret_flags);
if (!MOUNT(u)->where) {
MOUNT(u)->where = strdup(where);
@ -1562,13 +1561,27 @@ static int mount_setup_existing_unit(
return -ENOMEM;
}
/* In case we have multiple mounts established on the same mount point, let's merge flags set already
* for the current unit. Note that the flags field is reset on each iteration of reading
* /proc/self/mountinfo, hence we know for sure anything already set here is from the current
* iteration and thus worthy of taking into account. */
MountProcFlags flags =
MOUNT(u)->proc_flags | MOUNT_PROC_IS_MOUNTED;
r = update_parameters_proc_self_mountinfo(MOUNT(u), what, options, fstype);
if (r < 0)
return r;
if (r > 0)
flags |= MOUNT_PROC_JUST_CHANGED;
if (!MOUNT(u)->from_proc_self_mountinfo || FLAGS_SET(MOUNT(u)->proc_flags, MOUNT_PROC_JUST_MOUNTED) || MOUNT(u)->state == MOUNT_MOUNTING)
/* There are two conditions when we consider a mount point just mounted: when we haven't seen it in
* /proc/self/mountinfo before or when MOUNT_MOUNTING is our current state. Why bother with the
* latter? Shouldn't that be covered by the former? No, during reload it is not because we might then
* encounter a new /proc/self/mountinfo in combination with an old mount unit state (since it stems
* from the serialized state), and need to catch up. Since we know that the MOUNT_MOUNTING state is
* reached when we wait for the mount to appear we hence can assume that if we are in it, we are
* actually seeing it established for the first time. */
if (!MOUNT(u)->from_proc_self_mountinfo || MOUNT(u)->state == MOUNT_MOUNTING)
flags |= MOUNT_PROC_JUST_MOUNTED;
MOUNT(u)->from_proc_self_mountinfo = true;