[CRIU] [PATCH 10/20] cr-restore.c: introduced the multiarch support.

alekskartashov at parallels.com alekskartashov at parallels.com
Wed Dec 12 08:34:20 EST 2012


From: Alexander Kartashov <alekskartashov at parallels.com>

* Introduced the macro CONFIG_DEBUG_RESTORE to stop restoration after a fork.
* Introduced the macro CORE_GPREGS to access machine general-purpose registers.
* Introduced the macro jump_to_restorer_blob to jump to the restorer blob
  in a machine-dependent way.

Signed-off-by: Alexander Kartashov <alekskartashov at parallels.com>
---
 cr-restore.c |   74 ++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 46 insertions(+), 28 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index 8dd1886..995656e 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -59,6 +59,8 @@
 #include "protobuf/itimer.pb-c.h"
 #include "protobuf/vma.pb-c.h"
 
+#include <arch_restorer.h>
+
 static struct pstree_item *current;
 
 static int restore_task_with_children(void *);
@@ -210,7 +212,7 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void *tgt_addr,
 
 		if (p->vma.end == vma->vma.end &&
 		    p->vma.start == vma->vma.start) {
-			pr_info("COW 0x%016lx-0x%016lx 0x%016lx vma\n",
+			pr_info("COW 0x%016"PRIx64"-0x%016"PRIx64" 0x%016"PRIx64" vma\n",
 				vma->vma.start, vma->vma.end, vma->vma.pgoff);
 			paddr = (void *) vma_premmaped_start(&p->vma);
 			break;
@@ -221,7 +223,7 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void *tgt_addr,
 	*pvma = p;
 
 	if (paddr == NULL) {
-		pr_info("Map 0x%016lx-0x%016lx 0x%016lx vma\n",
+		pr_info("Map 0x%016"PRIx64"-0x%016"PRIx64" 0x%016"PRIx64" vma\n",
 			vma->vma.start, vma->vma.end, vma->vma.pgoff);
 
 		addr = mmap(tgt_addr, vma_entry_len(&vma->vma),
@@ -272,7 +274,7 @@ static int restore_priv_vma_content(pid_t pid)
 	 * Read page contents.
 	 */
 	while (1) {
-		u64 va, page_offset;
+		size_t va, page_offset;
 		char buf[PAGE_SIZE];
 		void *p;
 
@@ -467,7 +469,7 @@ static int open_vmas(int pid)
 		if (!(vma_entry_is(&vma->vma, VMA_AREA_REGULAR)))
 			continue;
 
-		pr_info("Opening 0x%016lx-0x%016lx 0x%016lx (%x) vma\n",
+		pr_info("Opening 0x%016"PRIx64"-0x%016"PRIx64" 0x%016"PRIx64" vma (%x)\n",
 				vma->vma.start, vma->vma.end,
 				vma->vma.pgoff, vma->vma.status);
 
@@ -701,7 +703,7 @@ static int check_core(CoreEntry *core)
 {
 	int ret = -1;
 
-	if (core->mtype != CORE_ENTRY__MARCH__X86_64) {
+	if (core->mtype != CORE_ENTRY__MARCH) {
 		pr_err("Core march mismatch %d\n", (int)core->mtype);
 		goto out;
 	}
@@ -717,7 +719,7 @@ static int check_core(CoreEntry *core)
 			goto out;
 		}
 
-		if (!core->thread_info) {
+		if (!CORE_THREAD_INFO(core)) {
 			pr_err("Core info data missed for non-zombie\n");
 			goto out;
 		}
@@ -998,6 +1000,13 @@ static int restore_task_with_children(void *_arg)
 	int ret;
 	sigset_t blockmask;
 
+#ifdef CONFIG_DEBUG_RESTORE
+	if (kill(getpid(), SIGSTOP) < 0) {
+		pr_err("Failed to stop oneself: %d\n", errno);
+		return -1;
+	}
+#endif
+
 	close_safe(&ca->fd);
 
 	current = ca->item;
@@ -1120,6 +1129,8 @@ static int restore_switch_stage(int next_stage)
 static int restore_root_task(struct pstree_item *init, struct cr_options *opts)
 {
 	int ret;
+
+#ifndef CONFIG_DEBUG_RESTORE
 	struct sigaction act, old_act;
 
 	ret = sigaction(SIGCHLD, NULL, &act);
@@ -1138,6 +1149,7 @@ static int restore_root_task(struct pstree_item *init, struct cr_options *opts)
 		pr_perror("sigaction() failed\n");
 		return -1;
 	}
+#endif
 
 	/*
 	 * FIXME -- currently we assume that all the tasks live
@@ -1183,12 +1195,16 @@ static int restore_root_task(struct pstree_item *init, struct cr_options *opts)
 
 	futex_wait_until(&task_entries->nr_in_progress, 0);
 
+
+#ifndef CONFIG_DEBUG_RESTORE
 	/* Restore SIGCHLD here to skip SIGCHLD from a network sctip */
+
 	ret = sigaction(SIGCHLD, &old_act, NULL);
 	if (ret < 0) {
 		pr_perror("sigaction() failed\n");
 		goto out;
 	}
+#endif
 
 	network_unlock();
 out:
@@ -1248,7 +1264,6 @@ int cr_restore_tasks(pid_t pid, struct cr_options *opts)
 	return restore_root_task(root_item, opts);
 }
 
-#define TASK_SIZE_MAX   ((1UL << 47) - PAGE_SIZE)
 static long restorer_get_vma_hint(pid_t pid, struct list_head *tgt_vma_list,
 		struct list_head *self_vma_list, long vma_len)
 {
@@ -1256,7 +1271,7 @@ static long restorer_get_vma_hint(pid_t pid, struct list_head *tgt_vma_list,
 	long prev_vma_end = 0;
 	struct vma_area end_vma;
 
-	end_vma.vma.start = end_vma.vma.end = TASK_SIZE_MAX;
+	end_vma.vma.start = end_vma.vma.end = TASK_SIZE;
 	prev_vma_end = PAGE_SIZE;
 
 	s_vma = list_first_entry(self_vma_list, struct vma_area, list);
@@ -1456,7 +1471,7 @@ static VmaEntry *vma_list_remap(void *addr, unsigned long len, struct list_head
 
 static int prepare_mm(pid_t pid, struct task_restore_core_args *args)
 {
-	int fd, exe_fd, ret = -1;
+	int fd, exe_fd, i, ret = -1;
 	MmEntry *mm;
 
 	fd = open_image_ro(CR_FD_MM, pid);
@@ -1478,8 +1493,10 @@ static int prepare_mm(pid_t pid, struct task_restore_core_args *args)
 	}
 
 	args->mm_saved_auxv_size = pb_repeated_size(mm, mm_saved_auxv);
-	memcpy(args->mm_saved_auxv, mm->mm_saved_auxv,
-	       args->mm_saved_auxv_size);
+
+	for (i = 0; i < mm->n_mm_saved_auxv; ++i) {
+		args->mm_saved_auxv[i] = (auxv_t)mm->mm_saved_auxv[i];
+	}
 
 	exe_fd = open_reg_by_id(args->mm.exe_file_id);
 	if (exe_fd < 0)
@@ -1649,8 +1666,11 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 			KBYTES(restore_bootstrap_len));
 
 	ret = remap_restorer_blob((void *)exec_mem_hint);
-	if (ret < 0)
+
+	if (ret < 0) {
+		pr_err("Remapping the restorer blob failed\n");
 		goto err;
+	}
 
 	/*
 	 * Prepare a memory map for restorer. Note a thread space
@@ -1727,7 +1747,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 	 * Arguments for task restoration.
 	 */
 
-	BUG_ON(core->mtype != CORE_ENTRY__MARCH__X86_64);
+	BUG_ON(core->mtype != CORE_ENTRY__MARCH);
 
 	task_args->t.pid	= pid;
 	task_args->logfd	= log_get_fd();
@@ -1736,12 +1756,16 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 
 	strncpy(task_args->comm, core->tc->comm, sizeof(task_args->comm));
 
-	task_args->t.clear_tid_addr	= core->thread_info->clear_tid_addr;
+	task_args->t.clear_tid_addr	= CORE_THREAD_INFO(core)->clear_tid_addr;
 	task_args->ids			= *core->ids;
-	task_args->t.gpregs		= *core->thread_info->gpregs;
+	task_args->t.gpregs		= *CORE_GPREGS(core);
 	task_args->t.blk_sigset		= core->tc->blk_sigset;
 	task_args->t.has_blk_sigset	= true;
 
+#ifdef CONFIG_HAS_TLS
+	get_core_tls(core, task_args);
+#endif
+
 	if (core->thread_core) {
 		task_args->t.has_futex		= true;
 		task_args->t.futex_rla		= core->thread_core->futex_rla;
@@ -1810,8 +1834,11 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 		}
 
 		thread_args[i].ta		= task_args;
-		thread_args[i].gpregs		= *core->thread_info->gpregs;
-		thread_args[i].clear_tid_addr	= core->thread_info->clear_tid_addr;
+		thread_args[i].gpregs		= *CORE_GPREGS(core);
+		thread_args[i].clear_tid_addr	= CORE_THREAD_INFO(core)->clear_tid_addr;
+#ifdef CONFIG_HAS_TLS
+		thread_args[i].tls		= CORE_THREAD_INFO(core)->tls;
+#endif
 
 		if (core->thread_core) {
 			thread_args[i].has_futex	= true;
@@ -1850,17 +1877,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 	 * An indirect call to task_restore, note it never resturns
 	 * and restoreing core is extremely destructive.
 	 */
-	asm volatile(
-		"movq %0, %%rbx						\n"
-		"movq %1, %%rax						\n"
-		"movq %2, %%rdi						\n"
-		"movq %%rbx, %%rsp					\n"
-		"callq *%%rax						\n"
-		:
-		: "g"(new_sp),
-		  "g"(restore_task_exec_start),
-		  "g"(task_args)
-		: "rsp", "rdi", "rsi", "rbx", "rax", "memory");
+
+	jump_to_restorer_blob(new_sp, restore_task_exec_start, task_args);
 
 err:
 	free_mappings(&self_vma_list);
-- 
1.7.9.5



More information about the CRIU mailing list