mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-18 00:58:31 +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:
parent
bee835ebeb
commit
d27f5391d5
1 changed files with 29 additions and 5 deletions
34
mount.c
34
mount.c
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue