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

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Tue Jul 10 19:02:25 MSK 2018


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 at virtuozzo.com>
---
 criu/mount.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

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))
-- 
2.17.0



More information about the CRIU mailing list