[CRIU] [PATCH 18/28] rst: exe migration update
Kinsbursky Stanislav
skinsbursky at openvz.org
Thu Mar 22 13:59:32 EDT 2012
From: Stanislav Kinsbursky <skinsbursky at openvz.org>
This patch does two things:
1) pass opened exe fd to restorer instead of reading and openning it inside.
2) uses new shared files migration engine
Signed-off-by: Stanislav Kinsbursky <skinsbursky at openvz.org>
---
cr-dump.c | 2 +-
cr-restore.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++-----
files.c | 20 ++++++-----------
include/image.h | 4 +--
include/restorer.h | 2 +-
restorer.c | 63 +++-------------------------------------------------
6 files changed, 70 insertions(+), 83 deletions(-)
-------------- next part --------------
diff --git a/cr-dump.c b/cr-dump.c
index 179f49a..f475f77 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -194,7 +194,7 @@ static int dump_task_special_files(pid_t pid, const struct cr_fdset *cr_fdset)
fd = open_proc(pid, "exe");
if (fd < 0)
return -1;
- ret = dump_one_reg_file(&fe, FD_PID_INVALID, fd, 0, cr_fdset, 1);
+ ret = dump_one_reg_file(&fe, pid, fd, 0, cr_fdset, 1);
return ret;
}
diff --git a/cr-restore.c b/cr-restore.c
index 95ca897..1d16e57 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -38,6 +38,7 @@
#include "restorer-blob.h"
#include "crtools.h"
#include "namespaces.h"
+#include "file-ids.h"
/*
* real_pid member formerly served cases when
@@ -1505,6 +1506,48 @@ static int prepare_creds(int pid, struct task_restore_core_args *args)
return ret > 0 ? 0 : -1;
}
+static char *restorer_get_exe_path(int pid)
+{
+ struct fdinfo_entry fe;
+ struct file_info *sfi;
+ char *path = NULL;
+ int fdinfo_fd;
+
+ fdinfo_fd = open_image_ro(CR_FD_FDINFO, pid);
+ if (fdinfo_fd < 0) {
+ pr_perror("Can't open fdinfo-%d", pid);
+ goto err;
+ }
+
+ while (1) {
+ int ret;
+
+ ret = read(fdinfo_fd, &fe, sizeof(fe));
+ if (ret == 0) {
+ pr_err("%d: failed to find exe fd entry\n", pid);
+ goto err;
+ }
+
+ if (ret != sizeof(fe)) {
+ pr_perror("%d: Bad fdinfo entry", pid);
+ goto err;
+ }
+ if (fe.fde.type == FDINFO_EXE)
+ break;
+ }
+
+ sfi = file_search(FDINFO_EXE, fe.fde.id);
+ if (sfi == NULL) {
+ pr_err("Failed to find exe with id %ld\n", fe.fde.id);
+ goto err;
+ }
+
+ path = (char *)sfi->rfe->name;
+err:
+ close_safe(&fdinfo_fd);
+ return path;
+}
+
static int sigreturn_restore(pid_t pid)
{
long restore_code_len, restore_task_vma_len;
@@ -1524,7 +1567,8 @@ static int sigreturn_restore(pid_t pid)
LIST_HEAD(self_vma_list);
struct vma_area *vma_area;
- int fd_fdinfo = -1;
+ int fd_exe = -1;
+ char *path;
int fd_core = -1;
int fd_pages = -1;
int fd_vmas = -1;
@@ -1558,9 +1602,15 @@ 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);
+ path = restorer_get_exe_path(pid);
+ if (path == NULL) {
+ pr_err("%d: failed to find exe path\n", pid);
+ goto err;
+ }
+
+ fd_exe = open(path, O_RDWR, 0744);
+ if (fd_exe < 0) {
+ pr_perror("Can't open exe-%d", pid);
goto err;
}
@@ -1696,7 +1746,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 = fd_exe;
task_args->fd_pages = fd_pages;
ret = prepare_itimers(pid, task_args);
@@ -1773,7 +1823,7 @@ static int sigreturn_restore(pid_t pid)
err:
free_mappings(&self_vma_list);
close_safe(&fd_core);
- close_safe(&fd_fdinfo);
+ close_safe(&fd_exe);
/* Just to be sure */
exit(1);
diff --git a/files.c b/files.c
index b4cc0c3..a2e9e75 100644
--- a/files.c
+++ b/files.c
@@ -219,17 +219,6 @@ static int restore_cwd(int id)
return 0;
}
-static int restore_exe_early(struct fdinfo_entry *fe, int fd)
-{
- /*
- * We restore the EXE symlink at very late stage
- * because of restrictions applied from kernel side,
- * so simply skip it for a while.
- */
- lseek(fd, fe->len, SEEK_CUR);
- return 0;
-}
-
static int receive_shared_fd(int pid, struct file_info *fi, struct fd_entry *fde)
{
int real_fd;
@@ -451,8 +440,6 @@ static int open_special_fdinfo(int pid, struct fdinfo_entry *fe,
if (fe->fde.type == FDINFO_MAP)
return open_fmap(pid, fe, fdinfo_fd);
- if (fe->fde.type == FDINFO_EXE)
- return restore_exe_early(fe, fdinfo_fd);
pr_info("%d: fe->type: %d\n", pid, fe->fde.type);
BUG_ON(1);
@@ -492,6 +479,13 @@ int prepare_fds(int pid)
cwd_id = fe.fde.id;
continue;
}
+ if (fe.fde.type == FDINFO_EXE)
+ /*
+ * We restore the EXE symlink at very late stage
+ * because of restrictions applied from kernel side,
+ * so simply skip it for a while.
+ */
+ continue;
if (fd_is_special(&fe.fde)) {
if (open_special_fdinfo(pid, &fe, fdinfo_fd, state))
diff --git a/include/image.h b/include/image.h
index 685fe06..abc7fd0 100644
--- a/include/image.h
+++ b/include/image.h
@@ -69,9 +69,7 @@ struct fdinfo_entry {
u8 name[0];
} __packed;
-#define fd_is_special(fde) \
- (((fde)->type == FDINFO_MAP) || \
- ((fde)->type == FDINFO_EXE))
+#define fd_is_special(fde) ((fde)->type == FDINFO_MAP)
struct pstree_entry {
u32 pid;
diff --git a/include/restorer.h b/include/restorer.h
index 1ce7ad2..389028e 100644
--- a/include/restorer.h
+++ b/include/restorer.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; /* opened exe path */
int fd_pages; /* opened pages dump file */
int logfd;
bool restore_threads; /* if to restore threads */
diff --git a/restorer.c b/restorer.c
index 043da1a..c6557e7 100644
--- a/restorer.c
+++ b/restorer.c
@@ -235,66 +235,12 @@ 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;
- }
+ int ret;
- if (fe.fde.type == FDINFO_EXE)
- break;
+ write_string("Restoring EXE\n");
- 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) {
- 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);
-
- /* FIXME Once kernel side stabilized -- drop next line */
- ret = 0;
- return ret;
-
-err:
- write_num_n(__LINE__);
- write_num_n(sys_getpid());
+ ret = sys_prctl_safe(PR_SET_MM, PR_SET_MM_EXE_FILE, args->fd_exe, 0);
+ sys_close(args->fd_exe);
return ret;
}
@@ -526,7 +472,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;
More information about the CRIU
mailing list