[CRIU] [PATCH 3/3] mount: handle tracefs more gracefully

Tycho Andersen tycho.andersen at canonical.com
Thu May 5 13:56:58 PDT 2016


See the comment for details, but basically tracefs is automounted by the
kernel, so we can just mount debugfs with MS_REC and get the right result.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
This is kind of similarly ugly to to a cgroup patch I sent earlier, where
we needed some filesystem specific code and checks in various parts of
mount.c. I somehow can't figure out a nicer way to do this, but I am
definitely open to suggestions.
---
 criu/include/proc_parse.h |  1 +
 criu/mount.c              | 20 +++++++++++++++++++-
 criu/proc_parse.c         |  7 +++++++
 images/mnt.proto          |  1 +
 4 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/criu/include/proc_parse.h b/criu/include/proc_parse.h
index 5de5c86..e591200 100644
--- a/criu/include/proc_parse.h
+++ b/criu/include/proc_parse.h
@@ -115,6 +115,7 @@ struct fstype {
 	int (*restore)(struct mount_info *pm);
 	int (*parse)(struct mount_info *pm);
 	mount_fn_t mount;
+	int flags;
 };
 
 struct vm_area_list;
diff --git a/criu/mount.c b/criu/mount.c
index 4a989bf..278538b 100644
--- a/criu/mount.c
+++ b/criu/mount.c
@@ -1730,6 +1730,15 @@ static struct fstype fstypes[32] = {
 	}, {
 		.name = "debugfs",
 		.code = FSTYPE__DEBUGFS,
+		/* debugfs has a child mount tracefs which may or my not be
+		 * mounted. the kernel protects against overmounting, so we
+		 * need to mount debugfs with MS_REC to propagate tracefs if it
+		 * is present.
+		 */
+		.flags = MS_REC,
+	}, {
+		.name = "tracefs",
+		.code = FSTYPE__TRACEFS,
 	}, {
 		.name = "cgroup",
 		.code = FSTYPE__CGROUP,
@@ -2294,6 +2303,11 @@ static int do_new_mount(struct mount_info *mi)
 	if (remount_ro)
 		sflags &= ~MS_RDONLY;
 
+	if (tp->flags) {
+		pr_info("forcing flags: %d\n", tp->flags);
+		sflags |= tp->flags;
+	}
+
 	if (do_mount(mi, src, tp->name, sflags) < 0) {
 		pr_perror("Can't mount at %s", mi->mountpoint);
 		return -1;
@@ -2460,12 +2474,16 @@ do_bind:
 		}
 	}
 
-	if (mount(root, mi->mountpoint, NULL, MS_BIND, NULL) < 0) {
+	if (mount(root, mi->mountpoint, NULL, MS_BIND | mi->fstype->flags, NULL) < 0) {
 		pr_perror("Can't mount at %s", mi->mountpoint);
 		goto err;
 	}
 
 	mflags = mi->flags & (~MS_PROPAGATE);
+	if (mi->fstype->flags) {
+		pr_info("forcing flags: 0x%x\n", mi->fstype->flags);
+		mflags |= mi->fstype->flags;
+	}
 	if (!mi->bind || mflags != (mi->bind->flags & (~MS_PROPAGATE)))
 		if (mount(NULL, mi->mountpoint, NULL, MS_BIND | MS_REMOUNT | mflags, NULL)) {
 			pr_perror("Can't mount at %s", mi->mountpoint);
diff --git a/criu/proc_parse.c b/criu/proc_parse.c
index 65d1fff..16612a8 100644
--- a/criu/proc_parse.c
+++ b/criu/proc_parse.c
@@ -1376,6 +1376,13 @@ struct mount_info *parse_mountinfo(pid_t pid, struct ns_id *nsid, bool for_dump)
 			goto end;
 		}
 
+		if (new->fstype->code == FSTYPE__TRACEFS) {
+			pr_info("\tskipping tracefs mounted at %s\n", new->mountpoint + 1);
+			mnt_entry_free(new);
+			new = NULL;
+			goto end;
+		}
+
 		pr_info("\ttype %s source %s mnt_id %d s_dev %#x %s @ %s flags %#x options %s\n",
 				fsname, new->source,
 				new->mnt_id, new->s_dev, new->root, new->mountpoint,
diff --git a/images/mnt.proto b/images/mnt.proto
index 3902283..5d42f49 100644
--- a/images/mnt.proto
+++ b/images/mnt.proto
@@ -19,6 +19,7 @@ enum fstype {
 	FUSE			= 15;
 	AUTO			= 16;
 	OVERLAYFS		= 17;
+	TRACEFS			= 18;
 };
 
 message mnt_entry {
-- 
2.7.4



More information about the CRIU mailing list