mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-08-03 15:23:04 +00:00
restore: Do fchroot() via proc helpers
There's no such thing as fchroot() in Linux, but we need to do
chroot() into existing file descriptor. Before this patch we did
this by chroot()-ing into /proc/self/fd/$fd. W/o proc mounted it's
no longer possible, so do this like
fchdir(proc_service_fd);
chroot("./self/fd/$root_fd");
fchdir($cwd_fd);
Thanks to Andrey Vagin for this trick ;)
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Acked-by: Andrew Vagin <avagin@parallels.com>
This commit is contained in:
parent
3659d60ab7
commit
701f883765
1 changed files with 28 additions and 18 deletions
46
files.c
46
files.c
|
|
@ -997,13 +997,23 @@ out:
|
|||
static int fchroot(int fd)
|
||||
{
|
||||
char fd_path[PSFDS];
|
||||
int proc;
|
||||
|
||||
/*
|
||||
* There's no such thing in syscalls. We can emulate
|
||||
* it using the /proc/self/fd/ :)
|
||||
*
|
||||
* But since there might be no /proc mount in our mount
|
||||
* namespace, we will have to ... workaround it.
|
||||
*/
|
||||
|
||||
sprintf(fd_path, "/proc/self/fd/%d", fd);
|
||||
proc = get_service_fd(PROC_FD_OFF);
|
||||
if (fchdir(proc) < 0) {
|
||||
pr_perror("Can't chdir to proc");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(fd_path, "./self/fd/%d", fd);
|
||||
pr_debug("Going to chroot into %s\n", fd_path);
|
||||
return chroot(fd_path);
|
||||
}
|
||||
|
|
@ -1020,23 +1030,6 @@ int prepare_fs(int pid)
|
|||
if (pb_read_one(ifd, &fe, PB_FS) < 0)
|
||||
goto out_i;
|
||||
|
||||
/*
|
||||
* Restore CWD
|
||||
*/
|
||||
|
||||
dd = open_reg_by_id(fe->cwd_id);
|
||||
if (dd < 0) {
|
||||
pr_err("Can't open cwd %#x\n", fe->cwd_id);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = fchdir(dd);
|
||||
close(dd);
|
||||
if (ret < 0) {
|
||||
pr_perror("Can't change cwd");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore root
|
||||
*/
|
||||
|
|
@ -1054,6 +1047,23 @@ int prepare_fs(int pid)
|
|||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore CWD
|
||||
*/
|
||||
|
||||
dd = open_reg_by_id(fe->cwd_id);
|
||||
if (dd < 0) {
|
||||
pr_err("Can't open cwd %#x\n", fe->cwd_id);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = fchdir(dd);
|
||||
close(dd);
|
||||
if (ret < 0) {
|
||||
pr_perror("Can't change cwd");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (fe->has_umask) {
|
||||
pr_info("Restoring umask to %o\n", fe->umask);
|
||||
umask(fe->umask);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue