Skip to content

Commit

Permalink
mount: Handle deleted bindmounts for regular files
Browse files Browse the repository at this point in the history
1) Deleted bindmount for files should be restored
   by creating temp file. The kernel doesn't permit
   to mix bindmount in terms of file/dir relationship:
   either both source and target should be files or
   directories.

   Thus we can call stat on the target and figure out
   what kind of source we had.

2) Even for deleted entries better to use permissions
   from the target's stat call, this makes result close
   to how would it look if program hadn't been checkpointed.

Reported-by: Andrey Wagin <avagin@gmail.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Acked-by: Tycho Andersen <tycho.andersen@canonical.com>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
  • Loading branch information
Cyrill Gorcunov authored and xemul committed Sep 2, 2015
1 parent bee835e commit d27f539
Showing 1 changed file with 29 additions and 5 deletions.
34 changes: 29 additions & 5 deletions mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -1970,6 +1970,7 @@ static int do_bind_mount(struct mount_info *mi)
{
bool shared = 0;
bool force_private_remount = false;
struct stat st;

if (!mi->need_plugin) {
char *root, *cut_root, rpath[PATH_MAX];
Expand All @@ -1996,8 +1997,24 @@ static int do_bind_mount(struct mount_info *mi)
pr_info("\tBind %s to %s\n", root, mi->mountpoint);

if (unlikely(mi->deleted)) {
if (mkdir(root, 0700)) {
pr_perror("Can't re-create deleted %s\n", root);
if (stat(mi->mountpoint, &st)) {
pr_perror("Can't fetch stat on %s", mi->mountpoint);
return -1;
}

if (S_ISDIR(st.st_mode)) {
if (mkdir(root, (st.st_mode & ~S_IFMT))) {
pr_perror("Can't re-create deleted directory %s\n", root);
return -1;
}
} else if (S_ISREG(st.st_mode)) {
if (open(root, O_WRONLY | O_CREAT | O_TRUNC, (st.st_mode & ~S_IFMT)) < 0) {
pr_perror("Can't re-create deleted file %s\n", root);
return -1;
}
} else {
pr_err("Unsupported st_mode 0%o deleted root %s\n",
(int)st.st_mode, root);
return -1;
}
}
Expand All @@ -2008,9 +2025,16 @@ static int do_bind_mount(struct mount_info *mi)
}

if (unlikely(mi->deleted)) {
if (rmdir(root)) {
pr_perror("Can't remove deleted %s\n", root);
return -1;
if (S_ISDIR(st.st_mode)) {
if (rmdir(root)) {
pr_perror("Can't remove deleted directory %s\n", root);
return -1;
}
} else if (S_ISREG(st.st_mode)) {
if (unlink(root)) {
pr_perror("Can't unlink deleted file %s\n", root);
return -1;
}
}
}
} else {
Expand Down

0 comments on commit d27f539

Please sign in to comment.