2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-31 14:25:49 +00:00

mount: Handle deleted bindmounts for regular files

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>
This commit is contained in:
Cyrill Gorcunov
2015-08-26 17:07:31 +03:00
committed by Pavel Emelyanov
parent bee835ebeb
commit d27f5391d5

34
mount.c
View File

@@ -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];
@@ -1996,8 +1997,24 @@ do_bind:
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;
}
}
@@ -2008,9 +2025,16 @@ do_bind:
}
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 {