Commit 80ef8fd2 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Pavel Emelyanov

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: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Acked-by: 's avatarTycho Andersen <tycho.andersen@canonical.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 60f6ec7d
...@@ -58,6 +58,7 @@ struct mount_info { ...@@ -58,6 +58,7 @@ struct mount_info {
}; };
bool need_plugin; bool need_plugin;
bool is_ns_root; bool is_ns_root;
bool deleted;
struct mount_info *next; struct mount_info *next;
struct ns_id *nsid; struct ns_id *nsid;
......
...@@ -1590,6 +1590,10 @@ static int dump_one_mountpoint(struct mount_info *pm, struct cr_img *img) ...@@ -1590,6 +1590,10 @@ static int dump_one_mountpoint(struct mount_info *pm, struct cr_img *img)
me.has_with_plugin = true; me.has_with_plugin = true;
me.with_plugin = true; me.with_plugin = true;
} }
if (pm->deleted) {
me.has_deleted = true;
me.deleted = true;
}
if (pm->internal_sharing) { if (pm->internal_sharing) {
me.has_internal_sharing = true; me.has_internal_sharing = true;
...@@ -1990,11 +1994,25 @@ static int do_bind_mount(struct mount_info *mi) ...@@ -1990,11 +1994,25 @@ static int do_bind_mount(struct mount_info *mi)
root = rpath; root = rpath;
do_bind: do_bind:
pr_info("\tBind %s to %s\n", root, mi->mountpoint); 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); pr_perror("Can't mount at %s", mi->mountpoint);
return -1; return -1;
} }
if (unlikely(mi->deleted)) {
if (rmdir(root)) {
pr_perror("Can't remove deleted %s\n", root);
return -1;
}
}
} else { } else {
if (restore_ext_mount(mi)) if (restore_ext_mount(mi))
return -1; return -1;
...@@ -2308,6 +2326,7 @@ static int collect_mnt_from_image(struct mount_info **pms, struct ns_id *nsid) ...@@ -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->shared_id = me->shared_id;
pm->master_id = me->master_id; pm->master_id = me->master_id;
pm->need_plugin = me->with_plugin; pm->need_plugin = me->with_plugin;
pm->deleted = me->deleted;
pm->is_ns_root = is_root(me->mountpoint); pm->is_ns_root = is_root(me->mountpoint);
pr_debug("\t\tGetting source for %d\n", pm->mnt_id); pr_debug("\t\tGetting source for %d\n", pm->mnt_id);
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "sysfs_parse.h" #include "sysfs_parse.h"
#include "seccomp.h" #include "seccomp.h"
#include "namespaces.h" #include "namespaces.h"
#include "files-reg.h"
#include "protobuf.h" #include "protobuf.h"
#include "protobuf/fdinfo.pb-c.h" #include "protobuf/fdinfo.pb-c.h"
...@@ -1008,6 +1009,7 @@ replace: ...@@ -1008,6 +1009,7 @@ replace:
static int parse_mountinfo_ent(char *str, struct mount_info *new, char **fsname) static int parse_mountinfo_ent(char *str, struct mount_info *new, char **fsname)
{ {
struct fd_link root_link;
unsigned int kmaj, kmin; unsigned int kmaj, kmin;
int ret, n; int ret, n;
char *sub, *opt = NULL; char *sub, *opt = NULL;
...@@ -1027,6 +1029,13 @@ static int parse_mountinfo_ent(char *str, struct mount_info *new, char **fsname) ...@@ -1027,6 +1029,13 @@ static int parse_mountinfo_ent(char *str, struct mount_info *new, char **fsname)
cure_path(new->mountpoint); cure_path(new->mountpoint);
cure_path(new->root); 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); new->mountpoint = xrealloc(new->mountpoint, strlen(new->mountpoint) + 1);
if (!new->mountpoint) if (!new->mountpoint)
goto err; goto err;
......
...@@ -41,4 +41,6 @@ message mnt_entry { ...@@ -41,4 +41,6 @@ message mnt_entry {
optional string fsname = 14; optional string fsname = 14;
optional bool internal_sharing = 15; optional bool internal_sharing = 15;
optional bool deleted = 16;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment