From 8df879941df68fdb4e1e9f88eae843f462efd950 Mon Sep 17 00:00:00 2001 From: Andrey Vagin Date: Wed, 16 Apr 2014 14:48:00 +0400 Subject: [PATCH] mount: save relative path in mi->mountpoint "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 Signed-off-by: Pavel Emelyanov --- include/proc_parse.h | 5 +++++ mount.c | 21 +++++++++------------ proc_parse.c | 19 ++++++++++++++----- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/include/proc_parse.h b/include/proc_parse.h index aba4357f8..651c6a031 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 2a49febd2..043b2c385 100644 --- a/mount.c +++ b/mount.c @@ -47,13 +47,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); } /* @@ -142,11 +142,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; @@ -341,7 +341,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) @@ -467,7 +467,6 @@ static struct mount_info *mnt_build_tree(struct mount_info *list) */ static int __open_mountpoint(struct mount_info *pm, int mnt_fd) { - char path[PATH_MAX + 1]; struct stat st; int ret; @@ -476,9 +475,7 @@ static int __open_mountpoint(struct mount_info *pm, int mnt_fd) mntns_root = get_service_fd(ROOT_FD_OFF); - /* paths starts from "." on restore and "/" on dump */ - snprintf(path, sizeof(path), "./%s", pm->mountpoint); - mnt_fd = openat(mntns_root, path, O_RDONLY); + mnt_fd = openat(mntns_root, pm->mountpoint, O_RDONLY); if (mnt_fd < 0) { pr_perror("Can't open %s", pm->mountpoint); return -1; @@ -487,7 +484,7 @@ static int __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; } @@ -793,7 +790,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; @@ -1495,7 +1492,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 2bdcf6bfa..0abacf497 100644 --- a/proc_parse.c +++ b/proc_parse.c @@ -857,13 +857,22 @@ 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->mnt_id, &new->parent_mnt_id, - &kmaj, &kmin, &new->root, &new->mountpoint, - &opt, &n); - if (ret != 7) + 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 + 1, + &opt, &n); + 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; if (parse_mnt_flags(opt, &new->flags))