[CRIU] [PATCH 1/2] mount: fix parent shared group dependency in can_mount_now

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Fri Oct 20 10:24:27 MSK 2017


What we do before patch:

1) If we are NOT in the same shared group - if we have some parent's
shared group member unmounted, we just wait for it.
2) If we are in the same group - we wait only for members with root
path len shorter than ours.

That is done to make child mount propagate in all shared group,
but I think it is wrong, e.g.:

mkdir -p /dir/a/b/c /d /e /f
mount --bind /dir/a /d
mount --bind /dir/a/b /e
mount --bind /f /e/c

Before c/r we have:

507 114 182:1017985 / / rw,relatime shared:63 master:60 - ext4 /dev/ploop63624p1 rw,data=ordered,balloon_ino=12
144 507 182:1017985 /dir/a /d rw,relatime shared:63 master:60 - ext4 /dev/ploop63624p1 rw,data=ordered,balloon_ino=12
146 507 182:1017985 /dir/a/b /e rw,relatime shared:63 master:60 - ext4 /dev/ploop63624p1 rw,data=ordered,balloon_ino=12
148 146 182:1017985 /f /e/c rw,relatime shared:63 master:60 - ext4 /dev/ploop63624p1 rw,data=ordered,balloon_ino=12
150 507 182:1017985 /f /dir/a/b/c rw,relatime shared:63 master:60 - ext4 /dev/ploop63624p1 rw,data=ordered,balloon_ino=12
149 144 182:1017985 /f /d/b/c rw,relatime shared:63 master:60 - ext4 /dev/ploop63624p1 rw,data=ordered,balloon_ino=12

After c/r we have:

600 132 182:1017985 / / rw,relatime shared:63 master:60 - ext4 /dev/ploop63624p1 rw,data=ordered,balloon_ino=12
602 600 182:1017985 /f /dir/a/b/c rw,relatime shared:63 master:60 - ext4 /dev/ploop63624p1 rw,data=ordered,balloon_ino=12
603 600 182:1017985 /dir/a /d rw,relatime shared:63 master:60 - ext4 /dev/ploop63624p1 rw,data=ordered,balloon_ino=12
604 600 182:1017985 /dir/a/b /e rw,relatime shared:63 master:60 - ext4 /dev/ploop63624p1 rw,data=ordered,balloon_ino=12

There is no propagation as all mounts are in same shared group and
602(150) has shorter root than 603(144) and 604(146).

What we should do:

Wait member of our parent's shared group only if it has our 'sibling'
mount in it. Sibling mount is the one which had propagated to shared
mount of our parent for us when we were mounted. We need to enforce
propagation only for these case.

https://jira.sw.ru/browse/PSBM-69501
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
 criu/mount.c | 31 ++++++++++++++++++++-----------
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/criu/mount.c b/criu/mount.c
index 22497f52e..f2487fcfb 100644
--- a/criu/mount.c
+++ b/criu/mount.c
@@ -2133,18 +2133,27 @@ static bool can_mount_now(struct mount_info *mi)
 
 shared:
 	if (mi->parent->shared_id) {
-		struct mount_info *p = mi->parent, *n;
+		struct mount_info *n;
 
-		if (mi->parent->shared_id == mi->shared_id) {
-			int rlen = strlen(mi->root);
-			list_for_each_entry(n, &p->mnt_share, mnt_share)
-				if (strlen(n->root) < rlen && !n->mounted)
-					return false;
-		} else {
-			list_for_each_entry(n, &p->mnt_share, mnt_share)
-				if (!n->mounted)
-					return false;
-		}
+		list_for_each_entry(n, &mi->parent->mnt_share, mnt_share)
+			/*
+			 * All mounts from mi's parent shared group which
+			 * have mi's 'sibling' should receive it through
+			 * mount propagation, so all such mounts in parent
+			 * shared group should be mounted beforehand.
+			 */
+			if (!n->mounted) {
+				char path[PATH_MAX], *mp;
+				struct mount_info *c;
+
+				mp = mnt_get_sibling_path(mi, n, path, sizeof(path));
+				if (mp == NULL)
+					continue;
+
+				list_for_each_entry(c, &n->children, siblings)
+					if (mounts_equal(mi, c) && !strcmp(mp, c->mountpoint))
+						return false;
+			}
 	}
 
 	return true;
-- 
2.13.5



More information about the CRIU mailing list