[CRIU] Re: Before we do the CRIU v0.1 release

Cyrill Gorcunov gorcunov at openvz.org
Fri Jul 20 06:00:14 EDT 2012


On Fri, Jul 20, 2012 at 01:29:42PM +0400, Pavel Emelyanov wrote:
> 
> Please fix and I apply the patch.

Smth like below?

	Cyrill
-------------- next part --------------
>From a7060ddb4b3f77099d9507d4c8af7ce6979d4ae9 Mon Sep 17 00:00:00 2001
From: Cyrill Gorcunov <gorcunov at openvz.org>
Date: Thu, 19 Jul 2012 13:23:01 +0400
Subject: [PATCH] protobuf: Convert core_entry to PB format v5

This requires some exlanations

 - Since we use protobuf data in restorer
   code we need to carry a copy of appropriate
   PB entities in resident memory. For this
   sake task_restore_core_args and thread_restore_args
   were significantly reworked. In short -- the caller
   code fills PB structures into task arguments space.

v3:
 - Combine everything arch related to thread_info field,
   and make it optional
 - Drop "version" field from message, we check version in
   another specific message
 - Don't forget to call core_entry__free_unpacked where needed
 - We continue dumping FPU state, still it's not yet restored

v4:
 - Don't carry task_core_entry and task_kobs_ids_entry for
   threads, and yield error if present in image.

v5:
 - Allocate core_entry depending on type of task being dumped

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 cr-dump.c           |  274 +++++++++++++++++++++++++++++++++-----------------
 cr-restore.c        |  113 ++++++++++++++-------
 cr-show.c           |  155 ++++++++++++++----------------
 include/image.h     |  119 ----------------------
 include/restorer.h  |   10 ++-
 protobuf/Makefile   |    1 +
 protobuf/core.proto |   80 +++++++++++++++
 restorer.c          |   46 +++-------
 8 files changed, 430 insertions(+), 368 deletions(-)
 create mode 100644 protobuf/core.proto

diff --git a/cr-dump.c b/cr-dump.c
index de1839e..e41654d 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -51,6 +51,7 @@
 #include "protobuf/fs.pb-c.h"
 #include "protobuf/mm.pb-c.h"
 #include "protobuf/creds.pb-c.h"
+#include "protobuf/core.pb-c.h"
 
 #ifndef CONFIG_X86_64
 # error No x86-32 support yet
@@ -490,8 +491,8 @@ static int dump_task_creds(pid_t pid, const struct parasite_dump_misc *misc,
 	return pb_write(fdset_fd(fds, CR_FD_CREDS), &ce, creds_entry);
 }
 
-#define assign_reg(dst, src, e)		dst.e = (__typeof__(dst.e))src.e
-#define assign_array(dst, src, e)	memcpy(&dst.e, &src.e, sizeof(dst.e))
+#define assign_reg(dst, src, e)		dst->e = (__typeof__(dst->e))src.e
+#define assign_array(dst, src, e)	memcpy(dst->e, &src.e, sizeof(src.e))
 
 static int get_task_auxv(pid_t pid, MmEntry *mm)
 {
@@ -585,10 +586,11 @@ err:
 	return ret;
 }
 
-static int get_task_regs(pid_t pid, struct core_entry *core, const struct parasite_ctl *ctl)
+static int get_task_regs(pid_t pid, CoreEntry *core, const struct parasite_ctl *ctl)
 {
 	user_fpregs_struct_t fpregs	= {-1};
 	user_regs_struct_t regs		= {-1};
+
 	int ret = -1;
 
 	pr_info("Dumping GP/FPU registers ... ");
@@ -624,46 +626,51 @@ static int get_task_regs(pid_t pid, struct core_entry *core, const struct parasi
 		}
 	}
 
-	assign_reg(core->arch.gpregs, regs, r15);
-	assign_reg(core->arch.gpregs, regs, r14);
-	assign_reg(core->arch.gpregs, regs, r13);
-	assign_reg(core->arch.gpregs, regs, r12);
-	assign_reg(core->arch.gpregs, regs, bp);
-	assign_reg(core->arch.gpregs, regs, bx);
-	assign_reg(core->arch.gpregs, regs, r11);
-	assign_reg(core->arch.gpregs, regs, r10);
-	assign_reg(core->arch.gpregs, regs, r9);
-	assign_reg(core->arch.gpregs, regs, r8);
-	assign_reg(core->arch.gpregs, regs, ax);
-	assign_reg(core->arch.gpregs, regs, cx);
-	assign_reg(core->arch.gpregs, regs, dx);
-	assign_reg(core->arch.gpregs, regs, si);
-	assign_reg(core->arch.gpregs, regs, di);
-	assign_reg(core->arch.gpregs, regs, orig_ax);
-	assign_reg(core->arch.gpregs, regs, ip);
-	assign_reg(core->arch.gpregs, regs, cs);
-	assign_reg(core->arch.gpregs, regs, flags);
-	assign_reg(core->arch.gpregs, regs, sp);
-	assign_reg(core->arch.gpregs, regs, ss);
-	assign_reg(core->arch.gpregs, regs, fs_base);
-	assign_reg(core->arch.gpregs, regs, gs_base);
-	assign_reg(core->arch.gpregs, regs, ds);
-	assign_reg(core->arch.gpregs, regs, es);
-	assign_reg(core->arch.gpregs, regs, fs);
-	assign_reg(core->arch.gpregs, regs, gs);
-
-	assign_reg(core->arch.fpregs, fpregs, cwd);
-	assign_reg(core->arch.fpregs, fpregs, swd);
-	assign_reg(core->arch.fpregs, fpregs, twd);
-	assign_reg(core->arch.fpregs, fpregs, fop);
-	assign_reg(core->arch.fpregs, fpregs, rip);
-	assign_reg(core->arch.fpregs, fpregs, rdp);
-	assign_reg(core->arch.fpregs, fpregs, mxcsr);
-	assign_reg(core->arch.fpregs, fpregs, mxcsr_mask);
-
-	assign_array(core->arch.fpregs, fpregs,	st_space);
-	assign_array(core->arch.fpregs, fpregs,	xmm_space);
-	assign_array(core->arch.fpregs, fpregs,	padding);
+	assign_reg(core->thread_info->gpregs, regs, r15);
+	assign_reg(core->thread_info->gpregs, regs, r14);
+	assign_reg(core->thread_info->gpregs, regs, r13);
+	assign_reg(core->thread_info->gpregs, regs, r12);
+	assign_reg(core->thread_info->gpregs, regs, bp);
+	assign_reg(core->thread_info->gpregs, regs, bx);
+	assign_reg(core->thread_info->gpregs, regs, r11);
+	assign_reg(core->thread_info->gpregs, regs, r10);
+	assign_reg(core->thread_info->gpregs, regs, r9);
+	assign_reg(core->thread_info->gpregs, regs, r8);
+	assign_reg(core->thread_info->gpregs, regs, ax);
+	assign_reg(core->thread_info->gpregs, regs, cx);
+	assign_reg(core->thread_info->gpregs, regs, dx);
+	assign_reg(core->thread_info->gpregs, regs, si);
+	assign_reg(core->thread_info->gpregs, regs, di);
+	assign_reg(core->thread_info->gpregs, regs, orig_ax);
+	assign_reg(core->thread_info->gpregs, regs, ip);
+	assign_reg(core->thread_info->gpregs, regs, cs);
+	assign_reg(core->thread_info->gpregs, regs, flags);
+	assign_reg(core->thread_info->gpregs, regs, sp);
+	assign_reg(core->thread_info->gpregs, regs, ss);
+	assign_reg(core->thread_info->gpregs, regs, fs_base);
+	assign_reg(core->thread_info->gpregs, regs, gs_base);
+	assign_reg(core->thread_info->gpregs, regs, ds);
+	assign_reg(core->thread_info->gpregs, regs, es);
+	assign_reg(core->thread_info->gpregs, regs, fs);
+	assign_reg(core->thread_info->gpregs, regs, gs);
+
+	assign_reg(core->thread_info->fpregs, fpregs, cwd);
+	assign_reg(core->thread_info->fpregs, fpregs, swd);
+	assign_reg(core->thread_info->fpregs, fpregs, twd);
+	assign_reg(core->thread_info->fpregs, fpregs, fop);
+	assign_reg(core->thread_info->fpregs, fpregs, rip);
+	assign_reg(core->thread_info->fpregs, fpregs, rdp);
+	assign_reg(core->thread_info->fpregs, fpregs, mxcsr);
+	assign_reg(core->thread_info->fpregs, fpregs, mxcsr_mask);
+
+	/* Make sure we have enough space */
+	BUG_ON(core->thread_info->fpregs->n_st_space != ARRAY_SIZE(fpregs.st_space));
+	BUG_ON(core->thread_info->fpregs->n_xmm_space != ARRAY_SIZE(fpregs.xmm_space));
+	BUG_ON(core->thread_info->fpregs->n_padding != ARRAY_SIZE(fpregs.padding));
+
+	assign_array(core->thread_info->fpregs, fpregs,	st_space);
+	assign_array(core->thread_info->fpregs, fpregs,	xmm_space);
+	assign_array(core->thread_info->fpregs, fpregs,	padding);
 
 	ret = 0;
 
@@ -671,22 +678,12 @@ err:
 	return ret;
 }
 
-static int dump_task_core(struct core_entry *core, int fd_core)
-{
-	pr_info("Dumping header ... ");
-
-	core->header.arch	= HEADER_ARCH_X86_64;
-	core->header.flags	= 0;
-
-	return write_img(fd_core, core);
-}
-
 static DECLARE_KCMP_TREE(vm_tree, KCMP_VM);
 static DECLARE_KCMP_TREE(fs_tree, KCMP_FS);
 static DECLARE_KCMP_TREE(files_tree, KCMP_FILES);
 static DECLARE_KCMP_TREE(sighand_tree, KCMP_SIGHAND);
 
-static int dump_task_kobj_ids(pid_t pid, struct core_entry *core)
+static int dump_task_kobj_ids(pid_t pid, CoreEntry *core)
 {
 	int new;
 	struct kid_elem elem;
@@ -696,29 +693,29 @@ static int dump_task_kobj_ids(pid_t pid, struct core_entry *core)
 	elem.genid = 0; /* FIXME optimize */
 
 	new = 0;
-	core->ids.vm_id = kid_generate_gen(&vm_tree, &elem, &new);
-	if (!core->ids.vm_id || !new) {
+	core->ids->vm_id = kid_generate_gen(&vm_tree, &elem, &new);
+	if (!core->ids->vm_id || !new) {
 		pr_err("Can't make VM id for %d\n", pid);
 		return -1;
 	}
 
 	new = 0;
-	core->ids.fs_id = kid_generate_gen(&fs_tree, &elem, &new);
-	if (!core->ids.fs_id || !new) {
+	core->ids->fs_id = kid_generate_gen(&fs_tree, &elem, &new);
+	if (!core->ids->fs_id || !new) {
 		pr_err("Can't make FS id for %d\n", pid);
 		return -1;
 	}
 
 	new = 0;
-	core->ids.files_id = kid_generate_gen(&files_tree, &elem, &new);
-	if (!core->ids.files_id || !new) {
+	core->ids->files_id = kid_generate_gen(&files_tree, &elem, &new);
+	if (!core->ids->files_id || !new) {
 		pr_err("Can't make FILES id for %d\n", pid);
 		return -1;
 	}
 
 	new = 0;
-	core->ids.sighand_id = kid_generate_gen(&sighand_tree, &elem, &new);
-	if (!core->ids.sighand_id || !new) {
+	core->ids->sighand_id = kid_generate_gen(&sighand_tree, &elem, &new);
+	if (!core->ids->sighand_id || !new) {
 		pr_err("Can't make IO id for %d\n", pid);
 		return -1;
 	}
@@ -726,21 +723,114 @@ static int dump_task_kobj_ids(pid_t pid, struct core_entry *core)
 	return 0;
 }
 
+static void core_entry_free(CoreEntry *core)
+{
+	if (core) {
+		if (core->thread_info) {
+			if (core->thread_info->fpregs) {
+				xfree(core->thread_info->fpregs->st_space);
+				xfree(core->thread_info->fpregs->xmm_space);
+				xfree(core->thread_info->fpregs->padding);
+			}
+			xfree(core->thread_info->gpregs);
+			xfree(core->thread_info->fpregs);
+		}
+		xfree(core->thread_info);
+		xfree(core->tc);
+		xfree(core->ids);
+	}
+}
+
+static CoreEntry *core_entry_alloc(int alloc_thread_info,
+				   int alloc_tc,
+				   int alloc_ids)
+{
+	CoreEntry *core;
+	ThreadInfoX86 *thread_info;
+	UserX86RegsEntry *gpregs;
+	UserX86FpregsEntry *fpregs;
+	TaskCoreEntry *tc;
+	TaskKobjIdsEntry *ids;
+
+	core = xmalloc(sizeof(*core));
+	if (!core)
+		return NULL;
+	core_entry__init(core);
+
+	core->mtype = CORE_ENTRY__MARCH__X86_64;
+
+	if (alloc_thread_info) {
+		thread_info = xmalloc(sizeof(*thread_info));
+		if (!thread_info)
+			goto err;
+		thread_info_x86__init(thread_info);
+		core->thread_info = thread_info;
+
+		gpregs = xmalloc(sizeof(*gpregs));
+		if (!gpregs)
+			goto err;
+		user_x86_regs_entry__init(gpregs);
+		thread_info->gpregs = gpregs;
+
+		fpregs = xmalloc(sizeof(*fpregs));
+		if (!fpregs)
+			goto err;
+		user_x86_fpregs_entry__init(fpregs);
+		thread_info->fpregs = fpregs;
+
+		/* These are numbers from kernel */
+		fpregs->n_st_space	= 32;
+		fpregs->n_xmm_space	= 64;
+		fpregs->n_padding	= 24;
+
+		fpregs->st_space	= xzalloc(pb_repeated_size(fpregs, st_space));
+		fpregs->xmm_space	= xzalloc(pb_repeated_size(fpregs, xmm_space));
+		fpregs->padding		= xzalloc(pb_repeated_size(fpregs, padding));
+
+		if (!fpregs->st_space || !fpregs->xmm_space || !fpregs->padding)
+			goto err;
+
+	}
+
+	if (alloc_tc) {
+		tc = xzalloc(sizeof(*tc) + TASK_COMM_LEN);
+		if (!tc)
+			goto err;
+		task_core_entry__init(tc);
+		tc->comm = (void *)tc + sizeof(*tc);
+		core->tc = tc;
+	}
+
+	if (alloc_ids) {
+		ids = xmalloc(sizeof(*ids));
+		if (!ids)
+			goto err;
+		task_kobj_ids_entry__init(ids);
+		core->ids = ids;
+	}
+
+	return core;
+err:
+	core_entry_free(core);
+	return NULL;
+}
+
 static int dump_task_core_all(pid_t pid, const struct proc_pid_stat *stat,
 		const struct parasite_dump_misc *misc, const struct parasite_ctl *ctl,
 		const struct cr_fdset *cr_fdset)
 {
-	struct core_entry *core;
+	int fd_core = fdset_fd(cr_fdset, CR_FD_CORE);
+	CoreEntry *core;
 	int ret = -1;
 
+	core = core_entry_alloc(1, 1, 1);
+	if (!core)
+		return -1;
+
 	pr_info("\n");
 	pr_info("Dumping core (pid: %d)\n", pid);
 	pr_info("----------------------------------------\n");
 
-	core = xzalloc(sizeof(*core));
-	if (!core)
-		goto err;
-
 	ret = dump_task_kobj_ids(pid, core);
 	if (ret)
 		goto err_free;
@@ -753,26 +843,27 @@ static int dump_task_core_all(pid_t pid, const struct proc_pid_stat *stat,
 	if (ret)
 		goto err_free;
 
-	ret = get_task_personality(pid, &core->tc.personality);
+	ret = get_task_personality(pid, &core->tc->personality);
 	if (ret)
 		goto err_free;
 
-	strncpy((char *)core->tc.comm, stat->comm, TASK_COMM_LEN);
-	core->tc.flags = stat->flags;
-	BUILD_BUG_ON(sizeof(core->tc.blk_sigset) != sizeof(k_rtsigset_t));
-	memcpy(&core->tc.blk_sigset, &misc->blocked, sizeof(k_rtsigset_t));
+	strncpy((char *)core->tc->comm, stat->comm, TASK_COMM_LEN);
+	core->tc->flags = stat->flags;
+	BUILD_BUG_ON(sizeof(core->tc->blk_sigset) != sizeof(k_rtsigset_t));
+	memcpy(&core->tc->blk_sigset, &misc->blocked, sizeof(k_rtsigset_t));
 
-	core->tc.task_state = TASK_ALIVE;
-	core->tc.exit_code = 0;
+	core->tc->task_state = TASK_ALIVE;
+	core->tc->exit_code = 0;
 
-	ret = dump_task_core(core, fdset_fd(cr_fdset, CR_FD_CORE));
-	if (ret)
+	ret = pb_write(fd_core, core, core_entry);
+	if (ret < 0) {
+		pr_info("ERROR\n");
 		goto err_free;
-	pr_info("OK\n");
+	} else
+		pr_info("OK\n");
 
 err_free:
-	free(core);
-err:
+	core_entry_free(core);
 	pr_info("----------------------------------------\n");
 
 	return ret;
@@ -1121,7 +1212,7 @@ try_again:
 
 static int dump_task_thread(struct parasite_ctl *parasite_ctl, struct pid *tid)
 {
-	struct core_entry *core;
+	CoreEntry *core;
 	int ret = -1, fd_core;
 	unsigned int *taddr;
 	pid_t pid = tid->real;
@@ -1130,7 +1221,7 @@ static int dump_task_thread(struct parasite_ctl *parasite_ctl, struct pid *tid)
 	pr_info("Dumping core for thread (pid: %d)\n", pid);
 	pr_info("----------------------------------------\n");
 
-	core = xzalloc(sizeof(*core));
+	core = core_entry_alloc(1, 0, 0);
 	if (!core)
 		goto err;
 
@@ -1145,22 +1236,19 @@ static int dump_task_thread(struct parasite_ctl *parasite_ctl, struct pid *tid)
 	}
 
 	pr_info("%d: tid_address=%p\n", pid, taddr);
-	core->clear_tid_address = (u64) taddr;
+	core->thread_info->clear_tid_addr = (u64) taddr;
 
 	pr_info("OK\n");
 
-	core->tc.task_state = TASK_ALIVE;
-	core->tc.exit_code = 0;
-
 	fd_core = open_image(CR_FD_CORE, O_DUMP, tid->virt);
 	if (fd_core < 0)
 		goto err_free;
 
-	ret = dump_task_core(core, fd_core);
+	ret = pb_write(fd_core, core, core_entry);
 
 	close(fd_core);
 err_free:
-	free(core);
+	core_entry_free(core);
 err:
 	pr_info("----------------------------------------\n");
 	return ret;
@@ -1169,24 +1257,24 @@ err:
 static int dump_one_zombie(const struct pstree_item *item,
 			   const struct proc_pid_stat *pps)
 {
-	struct core_entry *core;
+	CoreEntry *core;
 	int ret = -1, fd_core;
 
-	core = xzalloc(sizeof(*core));
+	core = core_entry_alloc(0, 1, 0);
 	if (core == NULL)
 		goto err;
 
-	core->tc.task_state = TASK_DEAD;
-	core->tc.exit_code = pps->exit_code;
+	core->tc->task_state = TASK_DEAD;
+	core->tc->exit_code = pps->exit_code;
 
 	fd_core = open_image(CR_FD_CORE, O_DUMP, item->pid);
 	if (fd_core < 0)
 		goto err_free;
 
-	ret = dump_task_core(core, fd_core);
+	ret = pb_write(fd_core, core, core_entry);
 	close(fd_core);
 err_free:
-	xfree(core);
+	core_entry_free(core);
 err:
 	return ret;
 }
diff --git a/cr-restore.c b/cr-restore.c
index d16bf5f..74efc2e 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -57,7 +57,7 @@
 static struct pstree_item *me;
 
 static int restore_task_with_children(void *);
-static int sigreturn_restore(pid_t pid, struct list_head *vmas, int nr_vmas);
+static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *vmas, int nr_vmas);
 
 static int shmem_remap(void *old_addr, void *new_addr, unsigned long size)
 {
@@ -186,7 +186,7 @@ static int read_and_open_vmas(int pid, struct list_head *vmas, int *nr_vmas)
 	return ret;
 }
 
-static int prepare_and_sigreturn(int pid)
+static int prepare_and_sigreturn(int pid, CoreEntry *core)
 {
 	int err, nr_vmas;
 	LIST_HEAD(vma_list);
@@ -195,7 +195,7 @@ static int prepare_and_sigreturn(int pid)
 	if (err)
 		return err;
 
-	return sigreturn_restore(pid, &vma_list, nr_vmas);
+	return sigreturn_restore(pid, core, &vma_list, nr_vmas);
 }
 
 static rt_sigaction_t sigchld_act;
@@ -276,7 +276,7 @@ static int pstree_wait_helpers()
 }
 
 
-static int restore_one_alive_task(int pid)
+static int restore_one_alive_task(int pid, CoreEntry *core)
 {
 	pr_info("Restoring resources\n");
 
@@ -292,7 +292,7 @@ static int restore_one_alive_task(int pid)
 	if (prepare_sigactions(pid))
 		return -1;
 
-	return prepare_and_sigreturn(pid);
+	return prepare_and_sigreturn(pid, core);
 }
 
 static void zombie_prepare_signals(void)
@@ -391,24 +391,19 @@ static int restore_one_zombie(int pid, int exit_code)
 	return -1;
 }
 
-static int check_core_header(int pid, struct task_core_entry *tc)
+static int check_core_header(int pid, CoreEntry *core)
 {
 	int fd = -1, ret = -1;
-	struct image_header hdr;
 
 	fd = open_image_ro(CR_FD_CORE, pid);
 	if (fd < 0)
 		return -1;
 
-	if (read_img(fd, &hdr) < 0)
-		goto out;
-
-	if (hdr.arch != HEADER_ARCH_X86_64) {
-		pr_err("Core arch mismatch %d\n", (int)hdr.arch);
+	if (core->mtype != CORE_ENTRY__MARCH__X86_64) {
+		pr_err("Core march mismatch %d\n", (int)core->mtype);
 		goto out;
 	}
-
-	ret = read_img(fd, tc);
+	ret = 0;
 out:
 	close_safe(&fd);
 	return ret < 0 ? ret : 0;
@@ -416,23 +411,43 @@ out:
 
 static int restore_one_task(int pid)
 {
-	struct task_core_entry tc;
+	int fd, ret;
+	CoreEntry *core;
 
 	if (me->state == TASK_HELPER)
 		return restore_one_fake(pid);
 
-	if (check_core_header(pid, &tc))
+	fd = open_image_ro(CR_FD_CORE, pid);
+	if (fd < 0)
 		return -1;
 
-	switch ((int)tc.task_state) {
+	ret = pb_read(fd, &core, core_entry);
+	close(fd);
+
+	if (ret < 0)
+		return -1;
+
+	if (check_core_header(pid, core)) {
+		ret = -1;
+		goto out;
+	}
+
+	switch ((int)core->tc->task_state) {
 	case TASK_ALIVE:
-		return restore_one_alive_task(pid);
+		ret = restore_one_alive_task(pid, core);
+		break;
 	case TASK_DEAD:
-		return restore_one_zombie(pid, tc.exit_code);
+		ret = restore_one_zombie(pid, core->tc->exit_code);
+		break;
 	default:
-		pr_err("Unknown state in code %d\n", (int)tc.task_state);
-		return -1;
+		pr_err("Unknown state in code %d\n", (int)core->tc->task_state);
+		ret = -1;
+		break;
 	}
+
+out:
+	core_entry__free_unpacked(core, NULL);
+	return ret;
 }
 
 /*
@@ -1117,7 +1132,7 @@ out:
 	return ret;
 }
 
-static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
+static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *tgt_vmas, int nr_vmas)
 {
 	long restore_code_len, restore_task_vma_len;
 	long restore_thread_vma_len, self_vmas_len, vmas_len;
@@ -1134,7 +1149,6 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
 	struct thread_restore_args *thread_args;
 
 	LIST_HEAD(self_vma_list);
-	int fd_core = -1;
 	int fd_pages = -1;
 	int i;
 
@@ -1159,12 +1173,6 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
 	BUILD_BUG_ON(SHMEMS_SIZE % PAGE_SIZE);
 	BUILD_BUG_ON(TASK_ENTRIES_SIZE % PAGE_SIZE);
 
-	fd_core = open_image_ro(CR_FD_CORE, pid);
-	if (fd_core < 0) {
-		pr_perror("Can't open core-out-%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);
@@ -1279,12 +1287,24 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
 	/*
 	 * Arguments for task restoration.
 	 */
+
+	BUG_ON(core->mtype != CORE_ENTRY__MARCH__X86_64);
+
 	task_args->pid		= pid;
-	task_args->fd_core	= fd_core;
 	task_args->logfd	= log_get_fd();
 	task_args->sigchld_act	= sigchld_act;
 	task_args->fd_pages	= fd_pages;
 
+	strncpy(task_args->comm, core->tc->comm, sizeof(task_args->comm));
+
+	task_args->clear_tid_addr	= core->thread_info->clear_tid_addr;
+	task_args->ids			= *core->ids;
+	task_args->gpregs		= *core->thread_info->gpregs;
+	task_args->blk_sigset		= core->tc->blk_sigset;
+
+	/* No longer need it */
+	core_entry__free_unpacked(core, NULL);
+
 	ret = prepare_itimers(pid, task_args);
 	if (ret < 0)
 		goto err;
@@ -1310,18 +1330,40 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
 	 * Fill up per-thread data.
 	 */
 	for (i = 0; i < me->nr_threads; i++) {
+		int fd_core;
 		thread_args[i].pid = me->threads[i].virt;
 
 		/* skip self */
 		if (thread_args[i].pid == pid)
 			continue;
 
-		/* Core files are to be opened */
-		thread_args[i].fd_core = open_image_ro(CR_FD_CORE, thread_args[i].pid);
-		if (thread_args[i].fd_core < 0)
+		fd_core = open_image_ro(CR_FD_CORE, thread_args[i].pid);
+		if (fd_core < 0) {
+			pr_err("Can't open core data for thread %d\n",
+			       thread_args[i].pid);
 			goto err;
+		}
+
+		ret = pb_read(fd_core, &core, core_entry);
+		close(fd_core);
+
+		if (core->tc || core->ids) {
+			pr_err("Thread has optional fields present %d\n",
+			       thread_args[i].pid);
+			ret = -1;
+		}
+
+		if (ret < 0) {
+			pr_err("Can't read core data for thread %d\n",
+			       thread_args[i].pid);
+			goto err;
+		}
+
+		thread_args[i].rst_lock		= &task_args->rst_lock;
+		thread_args[i].gpregs		= *core->thread_info->gpregs;
+		thread_args[i].clear_tid_addr	= core->thread_info->clear_tid_addr;
 
-		thread_args[i].rst_lock = &task_args->rst_lock;
+		core_entry__free_unpacked(core, NULL);
 
 		pr_info("Thread %4d stack %8p heap %8p rt_sigframe %8p\n",
 				i, thread_args[i].mem_zone.stack,
@@ -1334,12 +1376,10 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
 
 	pr_info("task_args: %p\n"
 		"task_args->pid: %d\n"
-		"task_args->fd_core: %d\n"
 		"task_args->nr_threads: %d\n"
 		"task_args->clone_restore_fn: %p\n"
 		"task_args->thread_args: %p\n",
 		task_args, task_args->pid,
-		task_args->fd_core,
 		task_args->nr_threads,
 		task_args->clone_restore_fn,
 		task_args->thread_args);
@@ -1362,7 +1402,6 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
 
 err:
 	free_mappings(&self_vma_list);
-	close_safe(&fd_core);
 
 	/* Just to be sure */
 	exit(1);
diff --git a/cr-show.c b/cr-show.c
index 9703ac2..47fe3ba 100644
--- a/cr-show.c
+++ b/cr-show.c
@@ -40,6 +40,7 @@
 #include "protobuf/mm.pb-c.h"
 #include "protobuf/vma.pb-c.h"
 #include "protobuf/creds.pb-c.h"
+#include "protobuf/core.pb-c.h"
 
 #define DEF_PAGES_PER_LINE	6
 
@@ -51,24 +52,6 @@
 #define PR_SYMBOL(sym)			\
 	(isprint(sym) ? sym : '.')
 
-#define pr_regs4(s, n1, n2, n3, n4)	\
-	pr_msg("%8s: 0x%16lx "		\
-	       "%8s: 0x%16lx "		\
-	       "%8s: 0x%16lx "		\
-	       "%8s: 0x%16lx\n",	\
-	       #n1, s.n1,		\
-	       #n2, s.n2,		\
-	       #n3, s.n3,		\
-	       #n4, s.n4)
-
-#define pr_regs3(s, n1, n2, n3)		\
-	pr_msg("%8s: 0x%16lx "		\
-	       "%8s: 0x%16lx "		\
-	       "%8s: 0x%16lx\n",	\
-	       #n1, s.n1,		\
-	       #n2, s.n2,		\
-	       #n3, s.n3)
-
 static LIST_HEAD(pstree_list);
 
 void show_files(int fd_files, struct cr_options *o)
@@ -370,30 +353,6 @@ void show_pstree(int fd_pstree, struct cr_options *o)
 	show_collect_pstree(fd_pstree, NULL);
 }
 
-static void show_core_regs(int fd_core)
-{
-	struct user_regs_entry regs;
-
-	pr_msg("\n\t---[GP registers set]---\n");
-
-	lseek(fd_core, GET_FILE_OFF(struct core_entry, arch.gpregs), SEEK_SET);
-
-	if (read_img(fd_core, &regs) < 0)
-		goto err;
-
-	pr_regs4(regs, cs, ip, ds, es);
-	pr_regs4(regs, ss, sp, fs, gs);
-	pr_regs4(regs, di, si, dx, cx);
-	pr_regs4(regs, ax, r8, r9, r10);
-	pr_regs4(regs, r11, r12, r13, r14);
-	pr_regs3(regs, r15, bp, bx);
-	pr_regs4(regs, orig_ax, flags, fs_base, gs_base);
-	pr_msg("\n");
-
-err:
-	return;
-}
-
 static inline char *task_state_str(int state)
 {
 	switch (state) {
@@ -406,68 +365,98 @@ static inline char *task_state_str(int state)
 	}
 }
 
-static void show_core_rest(int fd_core)
+static void show_core_rest(TaskCoreEntry *tc)
 {
-	struct task_core_entry tc;
+	if (!tc)
+		return;
 
-	lseek(fd_core, GET_FILE_OFF(struct core_entry, tc), SEEK_SET);
-	if (read_img(fd_core, &tc) < 0)
-		goto err;
-
-	pr_msg("\n\t---[Task parameters]---\n");
-	pr_msg("\tPersonality:  %#x\n", tc.personality);
-	pr_msg("\tCommand:      %s\n", tc.comm);
+	pr_msg("\t---[ Task parameters ]---\n");
+	pr_msg("\tPersonality:  %#x\n", tc->personality);
+	pr_msg("\tCommand:      %s\n", tc->comm);
 	pr_msg("\tState:        %d (%s)\n",
-	       (int)tc.task_state,
-	       task_state_str((int)tc.task_state));
+	       (int)tc->task_state,
+	       task_state_str((int)tc->task_state));
 
 	pr_msg("\t   Exit code: %u\n",
-	       (unsigned int)tc.exit_code);
+	       (unsigned int)tc->exit_code);
 
-	pr_msg("\tBlkSig: 0x%lx\n", tc.blk_sigset);
+	pr_msg("\tBlkSig: 0x%lx\n", tc->blk_sigset);
 	pr_msg("\n");
+}
 
-err:
-	return;
+static void show_core_ids(TaskKobjIdsEntry *ids)
+{
+	if (!ids)
+		return;
+
+	pr_msg("\t---[ Task IDS ]---\n");
+	pr_msg("\tVM:      %#x\n", ids->vm_id);
+	pr_msg("\tFS:      %#x\n", ids->fs_id);
+	pr_msg("\tFILES:   %#x\n", ids->files_id);
+	pr_msg("\tSIGHAND: %#x\n", ids->sighand_id);
 }
 
-static void show_core_ids(int fd)
+static void show_core_regs(UserX86RegsEntry *regs)
 {
-	struct core_ids_entry cie;
+#define pr_regs4(s, n1, n2, n3, n4)	\
+	pr_msg("\t%8s: 0x%-16lx "	\
+	       "%8s: 0x%-16lx "		\
+	       "%8s: 0x%-16lx "		\
+	       "%8s: 0x%-16lx\n",	\
+	       #n1, s->n1,		\
+	       #n2, s->n2,		\
+	       #n3, s->n3,		\
+	       #n4, s->n4)
 
-	lseek(fd, GET_FILE_OFF(struct core_entry, ids), SEEK_SET);
-	if (read_img(fd, &cie) < 0)
-		goto err;
+#define pr_regs3(s, n1, n2, n3)		\
+	pr_msg("\t%8s: 0x%-16lx "	\
+	       "%8s: 0x%-16lx "		\
+	       "%8s: 0x%-16lx\n",	\
+	       #n1, s->n1,		\
+	       #n2, s->n2,		\
+	       #n3, s->n3)
 
-	pr_msg("\tVM:      %#x\n", cie.vm_id);
-	pr_msg("\tFS:      %#x\n", cie.fs_id);
-	pr_msg("\tFILES:   %#x\n", cie.files_id);
-	pr_msg("\tSIGHAND: %#x\n", cie.sighand_id);
-err:
-	return;
+	pr_msg("\t---[ GP registers set ]---\n");
+
+	pr_regs4(regs, cs, ip, ds, es);
+	pr_regs4(regs, ss, sp, fs, gs);
+	pr_regs4(regs, di, si, dx, cx);
+	pr_regs4(regs, ax, r8, r9, r10);
+	pr_regs4(regs, r11, r12, r13, r14);
+	pr_regs3(regs, r15, bp, bx);
+	pr_regs4(regs, orig_ax, flags, fs_base, gs_base);
+	pr_msg("\n");
+}
+
+void show_thread_info(ThreadInfoX86 *thread_info)
+{
+	pr_msg("\t---[ Thread info ]---\n");
+	pr_msg("\tclear_tid_addr:  0x%lx\n", thread_info->clear_tid_addr);
+	pr_msg("\n");
+
+	show_core_regs(thread_info->gpregs);
 }
 
 void show_core(int fd_core, struct cr_options *o)
 {
-	struct stat stat;
-	bool is_thread;
+	CoreEntry *core;
 
-	if (fstat(fd_core, &stat)) {
-		pr_perror("Can't get stat on core file");
-		goto out;
-	}
+	pr_img_head(CR_FD_CORE);
+	if (pb_read_eof(fd_core, &core, core_entry) > 0) {
 
-	is_thread = (stat.st_size == GET_FILE_OFF_AFTER(struct core_entry));
+		pr_msg("\t---[ General ]---\n");
+		pr_msg("\tmtype:           0x%x\n", core->mtype);
+		pr_msg("\n");
 
-	if (is_thread)
-		pr_img_head(CR_FD_CORE, " (thread)");
-	else
-		pr_img_head(CR_FD_CORE);
+		/* Continue if we support it */
+		if (core->mtype == CORE_ENTRY__MARCH__X86_64) {
+			show_thread_info(core->thread_info);
+			show_core_rest(core->tc);
+			show_core_ids(core->ids);
+		}
 
-	show_core_regs(fd_core);
-	show_core_rest(fd_core);
-	show_core_ids(fd_core);
-out:
+		core_entry__free_unpacked(core, NULL);
+	}
 	pr_img_tail(CR_FD_CORE);
 }
 
diff --git a/include/image.h b/include/image.h
index 637e59a..11df0f4 100644
--- a/include/image.h
+++ b/include/image.h
@@ -87,138 +87,19 @@ struct page_entry {
 
 #define CR_CAP_SIZE	2
 
-#define HEADER_ARCH_X86_64	1
-
-struct image_header {
-	u32	arch;
-	u32	flags;
-} __packed;
-
-/*
- * PTRACE_GETREGS
- * PTRACE_GETFPREGS
- * PTRACE_GETFPXREGS		dep CONFIG_X86_32
- * PTRACE_GET_THREAD_AREA	dep CONFIG_X86_32 || CONFIG_IA32_EMULATION
- * PTRACE_GETFDPIC		dep CONFIG_BINFMT_ELF_FDPIC
- *
- * PTRACE_ARCH_PRCTL		dep CONFIG_X86_64
- *  ARCH_SET_GS/ARCH_GET_FS
- *  ARCH_SET_FS/ARCH_GET_GS
- */
-
 #ifdef CONFIG_X86_64
 
-struct user_regs_entry {
-	u64	r15;
-	u64	r14;
-	u64	r13;
-	u64	r12;
-	u64	bp;
-	u64	bx;
-	u64	r11;
-	u64	r10;
-	u64	r9;
-	u64	r8;
-	u64	ax;
-	u64	cx;
-	u64	dx;
-	u64	si;
-	u64	di;
-	u64	orig_ax;
-	u64	ip;
-	u64	cs;
-	u64	flags;
-	u64	sp;
-	u64	ss;
-	u64	fs_base;
-	u64	gs_base;
-	u64	ds;
-	u64	es;
-	u64	fs;
-	u64	gs;
-} __packed;
-
-struct desc_struct {
- union {
-	struct {
-		u32 a;
-		u32 b;
-	} x86_32;
-	u64	base_addr;
- };
-} __packed;
-
-struct user_fpregs_entry {
-	u16	cwd;
-	u16	swd;
-	u16	twd;	/* Note this is not the same as
-			   the 32bit/x87/FSAVE twd */
-	u16	fop;
-	u64	rip;
-	u64	rdp;
-	u32	mxcsr;
-	u32	mxcsr_mask;
-	u32	st_space[32];	/* 8*16 bytes for each FP-reg = 128 bytes */
-	u32	xmm_space[64];	/* 16*16 bytes for each XMM-reg = 256 bytes */
-	u32	padding[24];
-} __packed;
-
 #define GDT_ENTRY_TLS_ENTRIES 3
 #define TASK_COMM_LEN 16
 
 #define TASK_PF_USED_MATH		0x00002000
 
-#define CKPT_ARCH_SIZE			(1 * 4096)
-
-struct ckpt_arch_entry {
-	union {
-		struct {
-			struct user_regs_entry		gpregs;
-			struct user_fpregs_entry	fpregs;
-		};
-		u8 __arch_pad[CKPT_ARCH_SIZE];	/* should be enough for all */
-	};
-};
-
-#define CKPT_CORE_SIZE			(2 * 4096)
-
 #ifdef CONFIG_X86_64
 # define AT_VECTOR_SIZE 44
 #else
 # define AT_VECTOR_SIZE 22		/* Not needed at moment */
 #endif
 
-struct task_core_entry {
-	u8				task_state;
-	u8				pad[3];
-	u32				exit_code;
-
-	u32				personality;
-	u8				comm[TASK_COMM_LEN];
-	u32				flags;
-	u64				blk_sigset;
-};
-
-struct core_ids_entry {
-	u32	vm_id;
-	u32	files_id;
-	u32	fs_id;
-	u32	sighand_id;
-} __packed;
-
-struct core_entry {
-	union {
-		struct {
-			struct image_header	header;
-			struct task_core_entry	tc;
-			struct ckpt_arch_entry	arch;
-			struct core_ids_entry	ids;
-			u64 clear_tid_address;
-		};
-		u8 __core_pad[CKPT_CORE_SIZE];
-	};
-} __packed;
-
 #define TASK_ALIVE		0x1
 #define TASK_DEAD		0x2
 #define TASK_STOPPED		0x3 /* FIXME - implement */
diff --git a/include/restorer.h b/include/restorer.h
index 1be2168..1cf2970 100644
--- a/include/restorer.h
+++ b/include/restorer.h
@@ -14,6 +14,7 @@
 #include "../protobuf/mm.pb-c.h"
 #include "../protobuf/vma.pb-c.h"
 #include "../protobuf/creds.pb-c.h"
+#include "../protobuf/core.pb-c.h"
 
 #ifndef CONFIG_X86_64
 # error Only x86-64 is supported
@@ -60,15 +61,15 @@ struct thread_restore_args {
 	struct restore_mem_zone		mem_zone;
 
 	int				pid;
-	int				fd_core;
 	mutex_t				*rst_lock;
+	UserX86RegsEntry		gpregs;
+	u64				clear_tid_addr;
 } __aligned(sizeof(long));
 
 struct task_restore_core_args {
 	struct restore_mem_zone		mem_zone;
 
 	int				pid;			/* task pid */
-	int				fd_core;		/* opened core file */
 	int				fd_exe_link;		/* opened self->exe file */
 	int				fd_pages;		/* opened pages dump file */
 	int				logfd;
@@ -95,6 +96,11 @@ struct task_restore_core_args {
 
 	MmEntry				mm;
 	u64				mm_saved_auxv[AT_VECTOR_SIZE];
+	u64				clear_tid_addr;
+	u64				blk_sigset;
+	char				comm[TASK_COMM_LEN];
+	TaskKobjIdsEntry		ids;
+	UserX86RegsEntry		gpregs;
 } __aligned(sizeof(long));
 
 struct pt_regs {
diff --git a/protobuf/Makefile b/protobuf/Makefile
index 0b66c3b..1ffa913 100644
--- a/protobuf/Makefile
+++ b/protobuf/Makefile
@@ -51,6 +51,7 @@ PROTO_FILES	+= ipc-sem.proto
 PROTO_FILES	+= utsns.proto
 PROTO_FILES	+= creds.proto
 PROTO_FILES	+= vma.proto
+PROTO_FILES	+= core.proto
 
 HDRS	:= $(patsubst %.proto,%.pb-c.h,$(PROTO_FILES))
 SRCS	:= $(patsubst %.proto,%.pb-c.c,$(PROTO_FILES))
diff --git a/protobuf/core.proto b/protobuf/core.proto
new file mode 100644
index 0000000..4fd5753
--- /dev/null
+++ b/protobuf/core.proto
@@ -0,0 +1,80 @@
+message user_x86_regs_entry {
+	required uint64			r15		=  1;
+	required uint64			r14		=  2;
+	required uint64			r13		=  3;
+	required uint64			r12		=  4;
+	required uint64			bp		=  5;
+	required uint64			bx		=  6;
+	required uint64			r11		=  7;
+	required uint64			r10		=  8;
+	required uint64			r9		=  9;
+	required uint64			r8		= 10;
+	required uint64			ax		= 11;
+	required uint64			cx		= 12;
+	required uint64			dx		= 13;
+	required uint64			si		= 14;
+	required uint64			di		= 15;
+	required uint64			orig_ax	 	= 16;
+	required uint64			ip	 	= 17;
+	required uint64			cs		= 18;
+	required uint64			flags		= 19;
+	required uint64			sp		= 20;
+	required uint64			ss		= 21;
+	required uint64			fs_base		= 22;
+	required uint64			gs_base		= 23;
+	required uint64			ds		= 24;
+	required uint64			es		= 25;
+	required uint64			fs		= 26;
+	required uint64			gs		= 27;
+}
+
+message user_x86_fpregs_entry {
+	required uint32			cwd		=  1;
+	required uint32			swd		=  2;
+	required uint32			twd		=  3;
+	required uint32			fop		=  4;
+	required uint64			rip		=  5;
+	required uint64			rdp		=  6;
+	required uint32			mxcsr		=  7;
+	required uint32			mxcsr_mask	=  8;
+	repeated uint32			st_space	=  9;
+	repeated uint32			xmm_space	= 10;
+	repeated uint32			padding		= 11;
+}
+
+message task_core_entry {
+	required uint32			task_state	= 1;
+	required uint32			exit_code	= 2;
+
+	required uint32			personality	= 3;
+	required uint32			flags		= 4;
+	required uint64			blk_sigset	= 5;
+
+	required string			comm		= 6;
+}
+
+message task_kobj_ids_entry {
+	required uint32			vm_id		= 1;
+	required uint32			files_id	= 2;
+	required uint32			fs_id		= 3;
+	required uint32			sighand_id	= 4;
+}
+
+message thread_info_x86 {
+	required uint64			clear_tid_addr	= 1;
+	required user_x86_regs_entry	gpregs		= 2;
+	required user_x86_fpregs_entry	fpregs		= 3;
+}
+
+message core_entry {
+	enum march {
+		UNKNOWN		= 0;
+		X86_64		= 1;
+	}
+
+	required march			mtype		= 1;
+	optional thread_info_x86	thread_info	= 2;
+
+	optional task_core_entry	tc		= 3;
+	optional task_kobj_ids_entry	ids		= 4;
+}
diff --git a/restorer.c b/restorer.c
index e20a2ab..dfea61a 100644
--- a/restorer.c
+++ b/restorer.c
@@ -131,7 +131,6 @@ static void restore_creds(CredsEntry *ce)
 long __export_restore_thread(struct thread_restore_args *args)
 {
 	long ret = -1;
-	struct core_entry *core_entry;
 	struct rt_sigframe *rt_sigframe;
 	unsigned long new_sp, fsgs_base;
 	int my_pid = sys_gettid();
@@ -143,23 +142,12 @@ long __export_restore_thread(struct thread_restore_args *args)
 		goto core_restore_end;
 	}
 
-	core_entry = (struct core_entry *)&args->mem_zone.heap;
-
-	ret = sys_read(args->fd_core, core_entry, sizeof(*core_entry));
-	if (ret != sizeof(*core_entry)) {
-		write_num_n(__LINE__);
-		goto core_restore_end;
-	}
-
-	/* We're to close it! */
-	sys_close(args->fd_core);
-
-	sys_set_tid_address((int *) core_entry->clear_tid_address);
+	sys_set_tid_address((int *)args->clear_tid_addr);
 
 	rt_sigframe = (void *)args->mem_zone.rt_sigframe + 8;
 
-#define CPREGT1(d)	rt_sigframe->uc.uc_mcontext.d = core_entry->arch.gpregs.d
-#define CPREGT2(d,s)	rt_sigframe->uc.uc_mcontext.d = core_entry->arch.gpregs.s
+#define CPREGT1(d)	rt_sigframe->uc.uc_mcontext.d = args->gpregs.d
+#define CPREGT2(d,s)	rt_sigframe->uc.uc_mcontext.d = args->gpregs.s
 
 	CPREGT1(r8);
 	CPREGT1(r9);
@@ -183,7 +171,7 @@ long __export_restore_thread(struct thread_restore_args *args)
 	CPREGT1(gs);
 	CPREGT1(fs);
 
-	fsgs_base = core_entry->arch.gpregs.fs_base;
+	fsgs_base = args->gpregs.fs_base;
 	ret = sys_arch_prctl(ARCH_SET_FS, fsgs_base);
 	if (ret) {
 		write_num_n(__LINE__);
@@ -191,7 +179,7 @@ long __export_restore_thread(struct thread_restore_args *args)
 		goto core_restore_end;
 	}
 
-	fsgs_base = core_entry->arch.gpregs.gs_base;
+	fsgs_base = args->gpregs.gs_base;
 	ret = sys_arch_prctl(ARCH_SET_GS, fsgs_base);
 	if (ret) {
 		write_num_n(__LINE__);
@@ -294,7 +282,6 @@ static u64 restore_mapping(const VmaEntry *vma_entry)
 long __export_restore_task(struct task_restore_core_args *args)
 {
 	long ret = -1;
-	struct core_entry *core_entry;
 	VmaEntry *vma_entry;
 	u64 va;
 
@@ -310,8 +297,6 @@ long __export_restore_task(struct task_restore_core_args *args)
 
 	restorer_set_logfd(args->logfd);
 
-	core_entry	= first_on_heap(core_entry, args->mem_zone.heap);
-
 #if 0
 	write_hex_n((long)args);
 	write_hex_n((long)args->mem_zone.heap);
@@ -319,12 +304,6 @@ long __export_restore_task(struct task_restore_core_args *args)
 	write_hex_n((long)vma_entry);
 #endif
 
-	ret = sys_read(args->fd_core, core_entry, sizeof(*core_entry));
-	if (ret != sizeof(*core_entry)) {
-		write_num_n(__LINE__);
-		goto core_restore_end;
-	}
-
 	for (vma_entry = args->self_vmas; vma_entry->start != 0; vma_entry++) {
 		if (!vma_entry_is(vma_entry, VMA_AREA_REGULAR))
 			continue;
@@ -412,7 +391,6 @@ long __export_restore_task(struct task_restore_core_args *args)
 
 	sys_munmap(args->tgt_vmas,
 			((void *)(vma_entry + 1) - ((void *)args->tgt_vmas)));
-	sys_close(args->fd_core);
 
 	ret = sys_munmap(args->shmems, SHMEMS_SIZE);
 	if (ret < 0) {
@@ -421,12 +399,12 @@ long __export_restore_task(struct task_restore_core_args *args)
 		goto core_restore_end;
 	}
 
-	sys_set_tid_address((int *) core_entry->clear_tid_address);
+	sys_set_tid_address((int *)args->clear_tid_addr);
 
 	/*
 	 * Tune up the task fields.
 	 */
-	ret |= sys_prctl_safe(PR_SET_NAME, (long)core_entry->tc.comm, 0, 0);
+	ret |= sys_prctl_safe(PR_SET_NAME, (long)args->comm, 0, 0);
 
 	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_CODE,	(long)args->mm.mm_start_code, 0);
 	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_END_CODE,	(long)args->mm.mm_end_code, 0);
@@ -462,8 +440,8 @@ long __export_restore_task(struct task_restore_core_args *args)
 	 */
 	rt_sigframe = (void *)args->mem_zone.rt_sigframe + 8;
 
-#define CPREG1(d)	rt_sigframe->uc.uc_mcontext.d = core_entry->arch.gpregs.d
-#define CPREG2(d,s)	rt_sigframe->uc.uc_mcontext.d = core_entry->arch.gpregs.s
+#define CPREG1(d)	rt_sigframe->uc.uc_mcontext.d = args->gpregs.d
+#define CPREG2(d,s)	rt_sigframe->uc.uc_mcontext.d = args->gpregs.s
 
 	CPREG1(r8);
 	CPREG1(r9);
@@ -487,7 +465,7 @@ long __export_restore_task(struct task_restore_core_args *args)
 	CPREG1(gs);
 	CPREG1(fs);
 
-	fsgs_base = core_entry->arch.gpregs.fs_base;
+	fsgs_base = args->gpregs.fs_base;
 	ret = sys_arch_prctl(ARCH_SET_FS, fsgs_base);
 	if (ret) {
 		write_num_n(__LINE__);
@@ -495,7 +473,7 @@ long __export_restore_task(struct task_restore_core_args *args)
 		goto core_restore_end;
 	}
 
-	fsgs_base = core_entry->arch.gpregs.gs_base;
+	fsgs_base = args->gpregs.gs_base;
 	ret = sys_arch_prctl(ARCH_SET_GS, fsgs_base);
 	if (ret) {
 		write_num_n(__LINE__);
@@ -506,7 +484,7 @@ long __export_restore_task(struct task_restore_core_args *args)
 	/*
 	 * Blocked signals.
 	 */
-	rt_sigframe->uc.uc_sigmask.sig[0] = core_entry->tc.blk_sigset;
+	rt_sigframe->uc.uc_sigmask.sig[0] = args->blk_sigset;
 
 	/*
 	 * Threads restoration. This requires some more comments. This
-- 
1.7.7.6



More information about the CRIU mailing list