Commit 7a451ff1 authored by Pavel Emelyanov's avatar Pavel Emelyanov

rst: Open exe link fd early

Open the exec link at fd restore stage as yet another service fd,
then pass it to restover via args and just call prctl on it.

This is good for several reasons -- the amount of code required for
this is less and opening files should better happen before we switch
to restorer (opening will be complex and it's MUCH easier to open all
we need in one place).
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent e079bf1e
......@@ -1474,7 +1474,6 @@ static int sigreturn_restore(pid_t pid)
LIST_HEAD(self_vma_list);
struct vma_area *vma_area;
int fd_fdinfo = -1;
int fd_core = -1;
int fd_pages = -1;
int fd_vmas = -1;
......@@ -1508,12 +1507,6 @@ static int sigreturn_restore(pid_t pid)
goto err;
}
fd_fdinfo = open_image_ro(CR_FD_FDINFO, pid);
if (fd_fdinfo < 0) {
pr_perror("Can't open fdinfo-%d", pid);
goto err;
}
fd_pages = open_image_ro(CR_FD_PAGES, pid);
if (fd_pages < 0) {
pr_perror("Can't open pages-%d", pid);
......@@ -1646,7 +1639,7 @@ static int sigreturn_restore(pid_t pid)
task_args->fd_vmas = fd_vmas;
task_args->logfd = log_get_fd();
task_args->sigchld_act = sigchld_act;
task_args->fd_fdinfo = fd_fdinfo;
task_args->fd_exe_link = self_exe_fd;
task_args->fd_pages = fd_pages;
ret = prepare_itimers(pid, task_args);
......@@ -1723,7 +1716,6 @@ static int sigreturn_restore(pid_t pid)
err:
free_mappings(&self_vma_list);
close_safe(&fd_core);
close_safe(&fd_fdinfo);
/* Just to be sure */
exit(1);
......
......@@ -199,15 +199,27 @@ static int restore_cwd(struct fdinfo_entry *fe, int fd)
return 0;
}
int self_exe_fd;
static int restore_exe_early(struct fdinfo_entry *fe, int fd)
{
int tmp;
/*
* We restore the EXE symlink at very late stage
* because of restrictions applied from kernel side,
* so simply skip it for a while.
* so keep this fd open till then.
*/
lseek(fd, fe->len, SEEK_CUR);
return 0;
self_exe_fd = get_service_fd(SELF_EXE_FD_OFF);
if (self_exe_fd < 0)
return self_exe_fd;
tmp = open_fe_fd(fe, fd);
if (tmp < 0)
return tmp;
return reopen_fd_as(self_exe_fd, tmp);
}
struct fdinfo_list_entry *find_fdinfo_list_entry(int pid, int fd, struct fdinfo_desc *fi)
......
......@@ -62,6 +62,7 @@ struct cr_options {
enum {
LOG_FD_OFF = 1,
IMG_FD_OFF,
SELF_EXE_FD_OFF,
};
int get_service_fd(int type);
......
......@@ -42,4 +42,6 @@ extern int prepare_fd_pid(int pid);
extern int prepare_shared_fdinfo(void);
extern int get_filemap_fd(int pid, struct vma_entry *vma_entry);
extern int self_exe_fd;
#endif /* FILES_H_ */
......@@ -66,7 +66,7 @@ struct task_restore_core_args {
int pid; /* task pid */
int fd_core; /* opened core file */
int fd_vmas; /* opened vmas file */
int fd_fdinfo; /* opened files dump file */
int fd_exe_link; /* opened self->exe file */
int fd_pages; /* opened pages dump file */
int logfd;
bool restore_threads; /* if to restore threads */
......
......@@ -235,67 +235,14 @@ core_restore_end:
static long restore_self_exe_late(struct task_restore_core_args *args)
{
struct fdinfo_entry fe;
long ret = -1;
char *path;
int fd;
/*
* Path to exe file and its len is in image.
*/
for (;;) {
if (sys_read(args->fd_fdinfo, &fe, sizeof(fe)) != sizeof(fe)) {
write_string("sys_read lookup failed\n");
goto err;
}
if (fe.type == FDINFO_EXE)
break;
if (fe.len)
sys_lseek(args->fd_fdinfo, fe.len, SEEK_CUR);
}
path = (char *)sys_mmap(NULL, fe.len + 1,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if ((long)path < 0) {
write_string("sys_mmap failed\n");
write_num_n(fe.len);
goto err;
}
int fd = args->fd_exe_link;
if (sys_read(args->fd_fdinfo, path, fe.len) != fe.len) {
sys_munmap(path, fe.len);
write_string("sys_read for exe-path failed\n");
goto err;
}
path[fe.len] = '\0';
write_string("Restoring EXE (");
write_string(path);
write_string(")\n");
fd = sys_open(path, fe.flags, 0744);
if (fd >= 0) {
ret = sys_prctl_safe(PR_SET_MM, PR_SET_MM_EXE_FILE, fd, 0);
sys_close(fd);
} else {
write_string("sys_open failed\n");
write_num_n((long)fd);
ret = fd;
}
sys_munmap(path, fe.len + 1);
write_string("Restoring EXE\n");
sys_prctl_safe(PR_SET_MM, PR_SET_MM_EXE_FILE, fd, 0);
sys_close(fd);
/* FIXME Once kernel side stabilized -- drop next line */
ret = 0;
return ret;
err:
write_num_n(__LINE__);
write_num_n(sys_getpid());
return ret;
/* FIXME Once kernel side stabilized -- fix error reporting */
return 0;
}
static u64 restore_mapping(const struct vma_entry *vma_entry)
......@@ -526,7 +473,6 @@ long restore_task(struct task_restore_core_args *args)
* new ones from image file.
*/
ret = restore_self_exe_late(args);
sys_close(args->fd_fdinfo);
if (ret)
goto core_restore_end;
......
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