[CRIU] [PATCH v3 1/5] mount: save the result of mnt_is_overmounted

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Thu Sep 27 12:17:32 MSK 2018


On restore we change mounts tree topology and paths in find_remap_mounts
thus mns_is_overmounted does not account remaped overmounts. So to know
which mounts will be actually overmounted after restore we need two much
effort, better prepare these info in advance.

That also should improve performance of mnt_is_overmounted on dump,
as we reuse calculations from previous calls.

v3: make mnt_is_overmounted boolean again

Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
 criu/include/mount.h |  2 ++
 criu/mount.c         | 34 +++++++++++++++++++++++++++++-----
 2 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/criu/include/mount.h b/criu/include/mount.h
index ca17b059a..e7d026264 100644
--- a/criu/include/mount.h
+++ b/criu/include/mount.h
@@ -70,6 +70,8 @@ struct mount_info {
 
 	struct list_head	postpone;
 
+	int			is_overmounted;
+
 	void			*private;	/* associated filesystem data */
 };
 
diff --git a/criu/mount.c b/criu/mount.c
index 218facb76..29370afc7 100644
--- a/criu/mount.c
+++ b/criu/mount.c
@@ -1156,13 +1156,25 @@ static bool mnt_is_overmounted(struct mount_info *mi)
 {
 	struct mount_info *t, *c, *m = mi;
 
+	if (mi->is_overmounted != -1)
+		goto exit;
+
+	mi->is_overmounted = 0;
+
 	while (m->parent) {
+		if (mi->parent->is_overmounted == 1) {
+			mi->is_overmounted = 1;
+			goto exit;
+		}
+
 		/* Check there is no sibling-overmount */
 		list_for_each_entry(t, &m->parent->children, siblings) {
 			if (m == t)
 				continue;
-			if (issubpath(m->mountpoint, t->mountpoint))
-				return true;
+			if (issubpath(m->mountpoint, t->mountpoint)) {
+				mi->is_overmounted = 1;
+				goto exit;
+			}
 		}
 
 		/*
@@ -1175,10 +1187,19 @@ static bool mnt_is_overmounted(struct mount_info *mi)
 
 	/* Check there is no children-overmount */
 	list_for_each_entry(c, &mi->children, siblings)
-		if (!strcmp(c->mountpoint, mi->mountpoint))
-			return true;
+		if (!strcmp(c->mountpoint, mi->mountpoint)) {
+			mi->is_overmounted = 1;
+			goto exit;
+		}
 
-	return false;
+exit:
+	return mi->is_overmounted;
+}
+
+static int set_is_overmounted(struct mount_info *mi)
+{
+	mnt_is_overmounted(mi);
+	return 0;
 }
 
 /*
@@ -2723,6 +2744,7 @@ struct mount_info *mnt_entry_alloc()
 	new = xzalloc(sizeof(struct mount_info));
 	if (new) {
 		new->fd = -1;
+		new->is_overmounted = -1;
 		INIT_LIST_HEAD(&new->children);
 		INIT_LIST_HEAD(&new->siblings);
 		INIT_LIST_HEAD(&new->mnt_slave_list);
@@ -3160,6 +3182,8 @@ static int populate_mnt_ns(void)
 	if (validate_mounts(mntinfo, false))
 		return -1;
 
+	mnt_tree_for_each(pms, set_is_overmounted);
+
 	if (find_remap_mounts(pms))
 		return -1;
 
-- 
2.17.1



More information about the CRIU mailing list