[CRIU] [PATCH RFC] bind mounts: handle non-root bind mounts

Serge Hallyn serge.hallyn at ubuntu.com
Tue Jun 24 16:34:03 PDT 2014


As a non-random example, if /dev/pts is a devpts mount and /dev/pts/ptmx
is bind-mounted onto /dev/ptmx, then mark /dev/ptmx as coming from the
/dev/pts mount, and make sure /dev/pts is mounted before we try to
bind-mount /dev/ptmx.

Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
---
 mount.c | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/mount.c b/mount.c
index 917159c..22e1fda 100644
--- a/mount.c
+++ b/mount.c
@@ -1319,9 +1319,20 @@ static int restore_ext_mount(struct mount_info *mi)
 	return ret;
 }
 
+static int do_mount_one(struct mount_info *mi);
+
 static int do_bind_mount(struct mount_info *mi)
 {
 	bool shared = mi->shared_id && mi->shared_id == mi->bind->shared_id;
+	int ret;
+
+	if (mi->bind && !mi->bind->mounted) {
+		ret = do_mount_one(mi->bind);
+		if (ret)  {
+			pr_debug("Failed to mount bind source");
+			return ret;
+		}
+	}
 
 	if (!mi->need_plugin) {
 		char *root, rpath[PATH_MAX];
@@ -1612,6 +1623,33 @@ static int rst_collect_local_mntns(void)
 	return 0;
 }
 
+static struct mount_info *find_bind_src_dev(struct mount_info *pms, unsigned int dev)
+{
+	struct mount_info *t;
+	for (t = pms; t; t = t->next) {
+		if (t->s_dev != dev)
+			continue;
+		if (strcmp(t->root, "/") == 0)
+			return t;
+	}
+	return NULL;
+}
+
+static void collate_bind_mounts(struct mount_info *pms)
+{
+	struct mount_info *pm, *pm2;
+
+	for (pm = pms;  pm;  pm = pm->next) {
+		if (strcmp(pm->root, "/")) {
+			pm2 = find_bind_src_dev(pms, pm->s_dev);
+			if (pm2) {
+				list_add_tail(&pm->mnt_bind, &pm2->mnt_bind);
+				pm->bind = pm2;
+			}
+		}
+	}
+}
+
 static int collect_mnt_from_image(struct mount_info **pms, struct ns_id *nsid)
 {
 	MntEntry *me = NULL;
@@ -1710,6 +1748,8 @@ static int collect_mnt_from_image(struct mount_info **pms, struct ns_id *nsid)
 		pr_debug("\tRead %d mp @ %s\n", pm->mnt_id, pm->mountpoint);
 	}
 
+	collate_bind_mounts(*pms);
+
 	if (me)
 		mnt_entry__free_unpacked(me, NULL);
 
-- 
2.0.0



More information about the CRIU mailing list