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) ...@@ -1474,7 +1474,6 @@ static int sigreturn_restore(pid_t pid)
LIST_HEAD(self_vma_list); LIST_HEAD(self_vma_list);
struct vma_area *vma_area; struct vma_area *vma_area;
int fd_fdinfo = -1;
int fd_core = -1; int fd_core = -1;
int fd_pages = -1; int fd_pages = -1;
int fd_vmas = -1; int fd_vmas = -1;
...@@ -1508,12 +1507,6 @@ static int sigreturn_restore(pid_t pid) ...@@ -1508,12 +1507,6 @@ static int sigreturn_restore(pid_t pid)
goto err; 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); fd_pages = open_image_ro(CR_FD_PAGES, pid);
if (fd_pages < 0) { if (fd_pages < 0) {
pr_perror("Can't open pages-%d", pid); pr_perror("Can't open pages-%d", pid);
...@@ -1646,7 +1639,7 @@ static int sigreturn_restore(pid_t pid) ...@@ -1646,7 +1639,7 @@ static int sigreturn_restore(pid_t pid)
task_args->fd_vmas = fd_vmas; task_args->fd_vmas = fd_vmas;
task_args->logfd = log_get_fd(); task_args->logfd = log_get_fd();
task_args->sigchld_act = sigchld_act; 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; task_args->fd_pages = fd_pages;
ret = prepare_itimers(pid, task_args); ret = prepare_itimers(pid, task_args);
...@@ -1723,7 +1716,6 @@ static int sigreturn_restore(pid_t pid) ...@@ -1723,7 +1716,6 @@ static int sigreturn_restore(pid_t pid)
err: err:
free_mappings(&self_vma_list); free_mappings(&self_vma_list);
close_safe(&fd_core); close_safe(&fd_core);
close_safe(&fd_fdinfo);
/* Just to be sure */ /* Just to be sure */
exit(1); exit(1);
......
...@@ -199,15 +199,27 @@ static int restore_cwd(struct fdinfo_entry *fe, int fd) ...@@ -199,15 +199,27 @@ static int restore_cwd(struct fdinfo_entry *fe, int fd)
return 0; return 0;
} }
int self_exe_fd;
static int restore_exe_early(struct fdinfo_entry *fe, int fd) static int restore_exe_early(struct fdinfo_entry *fe, int fd)
{ {
int tmp;
/* /*
* We restore the EXE symlink at very late stage * We restore the EXE symlink at very late stage
* because of restrictions applied from kernel side, * 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) struct fdinfo_list_entry *find_fdinfo_list_entry(int pid, int fd, struct fdinfo_desc *fi)
......
...@@ -62,6 +62,7 @@ struct cr_options { ...@@ -62,6 +62,7 @@ struct cr_options {
enum { enum {
LOG_FD_OFF = 1, LOG_FD_OFF = 1,
IMG_FD_OFF, IMG_FD_OFF,
SELF_EXE_FD_OFF,
}; };
int get_service_fd(int type); int get_service_fd(int type);
......
...@@ -42,4 +42,6 @@ extern int prepare_fd_pid(int pid); ...@@ -42,4 +42,6 @@ extern int prepare_fd_pid(int pid);
extern int prepare_shared_fdinfo(void); extern int prepare_shared_fdinfo(void);
extern int get_filemap_fd(int pid, struct vma_entry *vma_entry); extern int get_filemap_fd(int pid, struct vma_entry *vma_entry);
extern int self_exe_fd;
#endif /* FILES_H_ */ #endif /* FILES_H_ */
...@@ -66,7 +66,7 @@ struct task_restore_core_args { ...@@ -66,7 +66,7 @@ struct task_restore_core_args {
int pid; /* task pid */ int pid; /* task pid */
int fd_core; /* opened core file */ int fd_core; /* opened core file */
int fd_vmas; /* opened vmas 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 fd_pages; /* opened pages dump file */
int logfd; int logfd;
bool restore_threads; /* if to restore threads */ bool restore_threads; /* if to restore threads */
......
...@@ -235,67 +235,14 @@ core_restore_end: ...@@ -235,67 +235,14 @@ core_restore_end:
static long restore_self_exe_late(struct task_restore_core_args *args) static long restore_self_exe_late(struct task_restore_core_args *args)
{ {
struct fdinfo_entry fe; int fd = args->fd_exe_link;
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;
}
if (sys_read(args->fd_fdinfo, path, fe.len) != fe.len) { write_string("Restoring EXE\n");
sys_munmap(path, fe.len); sys_prctl_safe(PR_SET_MM, PR_SET_MM_EXE_FILE, fd, 0);
write_string("sys_read for exe-path failed\n"); sys_close(fd);
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);
/* FIXME Once kernel side stabilized -- drop next line */ /* FIXME Once kernel side stabilized -- fix error reporting */
ret = 0; return 0;
return ret;
err:
write_num_n(__LINE__);
write_num_n(sys_getpid());
return ret;
} }
static u64 restore_mapping(const struct vma_entry *vma_entry) static u64 restore_mapping(const struct vma_entry *vma_entry)
...@@ -526,7 +473,6 @@ long restore_task(struct task_restore_core_args *args) ...@@ -526,7 +473,6 @@ long restore_task(struct task_restore_core_args *args)
* new ones from image file. * new ones from image file.
*/ */
ret = restore_self_exe_late(args); ret = restore_self_exe_late(args);
sys_close(args->fd_fdinfo);
if (ret) if (ret)
goto core_restore_end; 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