[3/9] mount: fix can_mount_now to wait children of master's share properly

Submitted by Pavel Tikhomirov on July 10, 2018, 4:02 p.m.

Details

Message ID 20180710160231.1292-4-ptikhomirov@virtuozzo.com
State Accepted
Series "mount: better handling of mount propagation"
Commit 3a02362c5be169da70f5eae1ab2e0cdfbf366216
Headers show

Commit Message

Pavel Tikhomirov July 10, 2018, 4:02 p.m.
We should not use ->bind link for checking master's children. As if we
have two slaves shared between each other, the one mounted first will
replace ->bind link for the other - that will break restore.

Also while on it, if we do not want doubled mounts and want to
prohibit propagation to slaves on restore we likely want all children of
the whole master's share mounted before slave.

JFYI: Actually these restriction is very strict and some cases will fail
to restore, for instance (hope nobody does so):

mkdir /test
mount -t tmpfs test /test
mount --make-private /test
mkdir /test/{share,slave}
mount -t tmpfs share /test/share --make-shared
mount --bind /test/share/ /test/slave/
mount --make-slave  /test/slave
mount --make-shared /test/slave
mkdir /test/share/slave
mount --bind /test/slave/ /test/share/slave/

cat /proc/self/mountinfo | grep test
524 612 0:69 / /test rw,relatime - tmpfs test rw
570 524 0:73 / /test/share rw,relatime shared:879 - tmpfs share rw
571 524 0:73 / /test/slave rw,relatime shared:942 master:879 - tmpfs share rw
602 570 0:73 / /test/share/slave rw,relatime shared:942 master:879 - tmpfs share rw
603 571 0:73 / /test/slave/slave rw,relatime shared:943 master:942 - tmpfs share rw

Here 603 is a propagation of 602 from master 570 to slave 571, and it is
the only way to get such a mount as 571 and 602 are in one shared group
now and all later mounts to them will propagate between them and create
dublicated mounts. So to create real 603 without dups we need to have
/test/slave mounted before /test/share/slave, which contradicts with
current assumption.

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
---
 criu/mount.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/mount.c b/criu/mount.c
index 2d3752b20..637aebfd9 100644
--- a/criu/mount.c
+++ b/criu/mount.c
@@ -2365,19 +2365,23 @@  static bool can_mount_now(struct mount_info *mi)
 	/*
 	 * We're the slave peer:
 	 *   - Make sure the master peer is already mounted
-	 *   - Make sure all children are mounted as well to
-	 *     eliminate mounts duplications
+	 *   - Make sure all children of master's share are
+	 *   mounted as well to eliminate mounts duplications
 	 */
 	if (mi->master_id > 0) {
-		struct mount_info *c;
+		struct mount_info *c, *s;
 
 		if (mi->bind == NULL)
 			return false;
 
-		list_for_each_entry(c, &mi->bind->children, siblings) {
+		list_for_each_entry(c, &mi->mnt_master->children, siblings)
 			if (!c->mounted)
 				return false;
-		}
+
+		list_for_each_entry(s, &mi->mnt_master->mnt_share, mnt_share)
+			list_for_each_entry(c, &s->children, siblings)
+				if (!c->mounted)
+					return false;
 	}
 
 	if (!fsroot_mounted(mi) && (mi->bind == NULL && !mi->need_plugin))