[CRIU] [PATCH] mount: save relative path in mi->mountpoint

Andrey Vagin avagin at openvz.org
Wed Apr 16 03:48:24 PDT 2014


"relative path" is absolute path with dot at the beginning.

We already use relative paths on restore. In this patch we add "."
on dump too. It's convinient, because we needed to add dot each time
when we want to access this mount point.
Before this patch we had to created a temporary copy.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 include/proc_parse.h |  5 +++++
 mount.c              | 21 ++++++++++-----------
 proc_parse.c         | 15 ++++++++++++---
 3 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/include/proc_parse.h b/include/proc_parse.h
index aba4357..651c6a0 100644
--- a/include/proc_parse.h
+++ b/include/proc_parse.h
@@ -104,6 +104,11 @@ struct mount_info {
 	int		parent_mnt_id;
 	unsigned int	s_dev;
 	char		*root;
+	/*
+	 * mountpoint contains path with dot at the beginning.
+	 * It allows to use openat, statat, etc without creating
+	 * a temporary copy.
+	 */
 	char		*mountpoint;
 	unsigned	flags;
 	int		master_id;
diff --git a/mount.c b/mount.c
index 83fce33..8fb050c 100644
--- a/mount.c
+++ b/mount.c
@@ -48,13 +48,13 @@ static int validate_mounts(struct mount_info *info, bool call_plugins);
 /* Asolute paths are used on dump and relative paths are used on restore */
 static inline int is_root(char *p)
 {
-	return (!strcmp(p, "/") || !strcmp(p, "./"));
+	return (!strcmp(p, "/"));
 }
 
 /* True for the root mount (the topmost one) */
 static inline int is_root_mount(struct mount_info *mi)
 {
-	return is_root(mi->mountpoint);
+	return is_root(mi->mountpoint + 1);
 }
 
 /*
@@ -155,11 +155,11 @@ static struct mount_info *mount_resolve_path(const char *path)
 		list_for_each_entry(c, &m->children, siblings) {
 			size_t n;
 
-			n = strlen(c->mountpoint);
+			n = strlen(c->mountpoint + 1);
 			if (n > pathlen)
 				continue;
 
-			if (strncmp(c->mountpoint, path, min(n, pathlen)))
+			if (strncmp(c->mountpoint + 1, path, min(n, pathlen)))
 				continue;
 			if (n < pathlen && path[n] != '/')
 				continue;
@@ -354,7 +354,7 @@ static int validate_mounts(struct mount_info *info, bool call_plugins)
 				int ret;
 
 				if (call_plugins) {
-					ret = cr_plugin_dump_ext_mount(m->mountpoint, m->mnt_id);
+					ret = cr_plugin_dump_ext_mount(m->mountpoint + 1, m->mnt_id);
 					if (ret == 0)
 						m->need_plugin = true;
 				} else if (m->need_plugin)
@@ -480,7 +480,6 @@ static struct mount_info *mnt_build_tree(struct mount_info *list)
  */
 static DIR *__open_mountpoint(struct mount_info *pm, int mnt_fd)
 {
-	char path[PATH_MAX + 1];
 	struct stat st;
 	DIR *fdir;
 	int ret;
@@ -490,8 +489,8 @@ static DIR *__open_mountpoint(struct mount_info *pm, int mnt_fd)
 
 		mntns_root = get_service_fd(ROOT_FD_OFF);
 
-		snprintf(path, sizeof(path), ".%s", pm->mountpoint);
-		mnt_fd = openat(mntns_root, path, O_RDONLY);
+		/* paths starts from "." on restore and "/" on dump */
+		mnt_fd = openat(mntns_root, pm->mountpoint, O_RDONLY);
 		if (mnt_fd < 0) {
 			pr_perror("Can't open %s", pm->mountpoint);
 			return NULL;
@@ -500,7 +499,7 @@ static DIR *__open_mountpoint(struct mount_info *pm, int mnt_fd)
 
 	ret = fstat(mnt_fd, &st);
 	if (ret < 0) {
-		pr_perror("fstat(%s) failed", path);
+		pr_perror("fstat(%s) failed", pm->mountpoint);
 		goto err;
 	}
 
@@ -817,7 +816,7 @@ static int dump_one_mountpoint(struct mount_info *pm, int fd)
 	me.parent_mnt_id	= pm->parent_mnt_id;
 	me.flags		= pm->flags;
 	me.root			= pm->root;
-	me.mountpoint		= pm->mountpoint;
+	me.mountpoint		= pm->mountpoint + 1;
 	me.source		= pm->source;
 	me.options		= pm->options;
 	me.shared_id		= pm->shared_id;
@@ -1519,7 +1518,7 @@ int prepare_mnt_ns(int ns_pid)
 			return -1;
 		}
 
-		if (mount("none", mi->parent->mountpoint, "none", MS_SLAVE, NULL)) {
+		if (mount("none", mi->parent->mountpoint + 1, "none", MS_SLAVE, NULL)) {
 			pr_perror("Can't remount the parent of the new root with MS_SLAVE");
 			return -1;
 		}
diff --git a/proc_parse.c b/proc_parse.c
index b90a79d..df1153c 100644
--- a/proc_parse.c
+++ b/proc_parse.c
@@ -857,12 +857,21 @@ static int parse_mountinfo_ent(char *str, struct mount_info *new)
 	char *opt;
 	char *fstype;
 
-	ret = sscanf(str, "%i %i %u:%u %ms %ms %ms %n",
+	new->mountpoint = xmalloc(PATH_MAX);
+	if (new->mountpoint == NULL)
+		return -1;
+
+	new->mountpoint[0] = '.';
+	ret = sscanf(str, "%i %i %u:%u %ms %s %ms %n",
 			&new->mnt_id, &new->parent_mnt_id,
-			&kmaj, &kmin, &new->root, &new->mountpoint,
+			&kmaj, &kmin, &new->root, new->mountpoint + 1,
 			&opt, &n);
-	if (ret != 7)
+	if (ret != 7) {
+		xfree(new->mountpoint);
 		return -1;
+	}
+
+	new->mountpoint = xrealloc(new->mountpoint, strlen(new->mountpoint) + 1);
 
 	new->s_dev = MKKDEV(kmaj, kmin);
 	new->flags = 0;
-- 
1.8.5.3



More information about the CRIU mailing list