From 80ef8fd2fbd55419dc1aca824b2bfb06e39ff874 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Mon, 17 Aug 2015 23:09:48 +0300 Subject: [PATCH] mount: Handle deleted bindmounts To handle deleted bindmounts we simply create the former directory bindmount lived at, mount the target and remove the directory back. For this sake we add @deleted entry into the image. Signed-off-by: Cyrill Gorcunov Acked-by: Tycho Andersen Signed-off-by: Pavel Emelyanov --- include/mount.h | 1 + mount.c | 23 +++++++++++++++++++++-- proc_parse.c | 9 +++++++++ protobuf/mnt.proto | 2 ++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/include/mount.h b/include/mount.h index 8dcb0eadc..d0a28d81a 100644 --- a/include/mount.h +++ b/include/mount.h @@ -58,6 +58,7 @@ struct mount_info { }; bool need_plugin; bool is_ns_root; + bool deleted; struct mount_info *next; struct ns_id *nsid; diff --git a/mount.c b/mount.c index c047a1313..04b99d990 100644 --- a/mount.c +++ b/mount.c @@ -1590,6 +1590,10 @@ static int dump_one_mountpoint(struct mount_info *pm, struct cr_img *img) me.has_with_plugin = true; me.with_plugin = true; } + if (pm->deleted) { + me.has_deleted = true; + me.deleted = true; + } if (pm->internal_sharing) { me.has_internal_sharing = true; @@ -1990,11 +1994,25 @@ static int do_bind_mount(struct mount_info *mi) root = rpath; do_bind: pr_info("\tBind %s to %s\n", root, mi->mountpoint); - if (mount(root, mi->mountpoint, NULL, - MS_BIND, NULL) < 0) { + + if (unlikely(mi->deleted)) { + if (mkdir(root, 0700)) { + pr_perror("Can't re-create deleted %s\n", root); + return -1; + } + } + + if (mount(root, mi->mountpoint, NULL, MS_BIND, NULL) < 0) { pr_perror("Can't mount at %s", mi->mountpoint); return -1; } + + if (unlikely(mi->deleted)) { + if (rmdir(root)) { + pr_perror("Can't remove deleted %s\n", root); + return -1; + } + } } else { if (restore_ext_mount(mi)) return -1; @@ -2308,6 +2326,7 @@ static int collect_mnt_from_image(struct mount_info **pms, struct ns_id *nsid) pm->shared_id = me->shared_id; pm->master_id = me->master_id; pm->need_plugin = me->with_plugin; + pm->deleted = me->deleted; pm->is_ns_root = is_root(me->mountpoint); pr_debug("\t\tGetting source for %d\n", pm->mnt_id); diff --git a/proc_parse.c b/proc_parse.c index 306e0f076..cf70a92d0 100644 --- a/proc_parse.c +++ b/proc_parse.c @@ -29,6 +29,7 @@ #include "sysfs_parse.h" #include "seccomp.h" #include "namespaces.h" +#include "files-reg.h" #include "protobuf.h" #include "protobuf/fdinfo.pb-c.h" @@ -1008,6 +1009,7 @@ replace: static int parse_mountinfo_ent(char *str, struct mount_info *new, char **fsname) { + struct fd_link root_link; unsigned int kmaj, kmin; int ret, n; char *sub, *opt = NULL; @@ -1027,6 +1029,13 @@ static int parse_mountinfo_ent(char *str, struct mount_info *new, char **fsname) cure_path(new->mountpoint); cure_path(new->root); + root_link.len = strlen(new->root); + strcpy(root_link.name, new->root); + if (strip_deleted(&root_link)) { + strcpy(new->root, root_link.name); + new->deleted = true; + } + new->mountpoint = xrealloc(new->mountpoint, strlen(new->mountpoint) + 1); if (!new->mountpoint) goto err; diff --git a/protobuf/mnt.proto b/protobuf/mnt.proto index 6e58e1d6e..f79ae4619 100644 --- a/protobuf/mnt.proto +++ b/protobuf/mnt.proto @@ -41,4 +41,6 @@ message mnt_entry { optional string fsname = 14; optional bool internal_sharing = 15; + + optional bool deleted = 16; }