[CRIU] [PATCH] protobuf: Convert mm_entry to PB format

Cyrill Gorcunov gorcunov at openvz.org
Wed Jul 18 12:54:21 EDT 2012


Because the MmEntry has a "repeated" field, we
copy aux vector explicitly and reserve space for
it in task args.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 cr-dump.c          |   22 ++++++++++++++++------
 cr-restore.c       |   25 ++++++++++++++++++++-----
 cr-show.c          |   31 +++++++++++++++++--------------
 include/image.h    |   16 ----------------
 include/restorer.h |    5 ++++-
 protobuf/Makefile  |    1 +
 protobuf/mm.proto  |   16 ++++++++++++++++
 restorer.c         |    4 ++--
 8 files changed, 76 insertions(+), 44 deletions(-)
 create mode 100644 protobuf/mm.proto

diff --git a/cr-dump.c b/cr-dump.c
index 7a8d146..902a642 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -50,6 +50,7 @@
 #include "protobuf/fdinfo.pb-c.h"
 #include "protobuf/fs.pb-c.h"
 #include "protobuf/creds.pb-c.h"
+#include "protobuf/mm.pb-c.h"
 
 #ifndef CONFIG_X86_64
 # error No x86-32 support yet
@@ -157,7 +158,7 @@ int do_dump_gen_file(struct fd_parms *p, int lfd,
 	return pb_write(fdset_fd(cr_fdset, CR_FD_FDINFO), &e, fdinfo_entry);
 }
 
-static int dump_task_exe_link(pid_t pid, struct mm_entry *mm)
+static int dump_task_exe_link(pid_t pid, MmEntry *mm)
 {
 	struct fd_parms params = FD_PARMS_INIT;
 	int fd, ret;
@@ -502,7 +503,7 @@ static int dump_task_creds(pid_t pid, const struct parasite_dump_misc *misc,
 #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))
 
-static int get_task_auxv(pid_t pid, struct mm_entry *mm)
+static int get_task_auxv(pid_t pid, MmEntry *mm)
 {
 	int fd, ret, i;
 
@@ -534,7 +535,8 @@ err:
 static int dump_task_mm(pid_t pid, const struct proc_pid_stat *stat,
 		const struct parasite_dump_misc *misc, const struct cr_fdset *fdset)
 {
-	struct mm_entry mme;
+	MmEntry mme = MM_ENTRY__INIT;
+	int ret = -1;
 
 	mme.mm_start_code = stat->start_code;
 	mme.mm_end_code = stat->end_code;
@@ -550,14 +552,22 @@ static int dump_task_mm(pid_t pid, const struct proc_pid_stat *stat,
 
 	mme.mm_brk = misc->brk;
 
+	mme.n_mm_saved_auxv = AT_VECTOR_SIZE;
+	mme.mm_saved_auxv = xmalloc(pb_repeated_size(&mme, mm_saved_auxv));
+	if (!mme.mm_saved_auxv)
+		goto out;
+
 	if (get_task_auxv(pid, &mme))
-		return -1;
+		goto out;
 	pr_info("OK\n");
 
 	if (dump_task_exe_link(pid, &mme))
-		return -1;
+		goto out;
 
-	return write_img(fdset_fd(fdset, CR_FD_MM), &mme);
+	ret = pb_write(fdset_fd(fdset, CR_FD_MM), &mme, mm_entry);
+	xfree(mme.mm_saved_auxv);
+out:
+	return ret;
 }
 
 static int get_task_personality(pid_t pid, u32 *personality)
diff --git a/cr-restore.c b/cr-restore.c
index beffb26..6d7b6d0 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -1093,23 +1093,38 @@ 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;
+	int fd, exe_fd, ret = -1;
+	MmEntry *mm;
 
 	fd = open_image_ro(CR_FD_MM, pid);
 	if (fd < 0)
 		return -1;
 
-	if (read_img(fd, &args->mm) < 0)
+	if (pb_read(fd, &mm, mm_entry) < 0)
 		return -1;
 
+	args->mm = *mm;
+	args->mm.n_mm_saved_auxv = 0;
+	args->mm.mm_saved_auxv = NULL;
+
+	if (mm->n_mm_saved_auxv != AT_VECTOR_SIZE) {
+		pr_err("Image corrupted on pid %d\n", pid);
+		goto out;
+	}
+
+	memcpy(args->mm_saved_auxv, mm->mm_saved_auxv,
+	       pb_repeated_size(mm, mm_saved_auxv));
+
 	exe_fd = open_reg_by_id(args->mm.exe_file_id);
 	if (exe_fd < 0)
-		return -1;
+		goto out;
 
 	args->fd_exe_link = exe_fd;
-
+	ret = 0;
+out:
+	mm_entry__free_unpacked(mm, NULL);
 	close(fd);
-	return 0;
+	return ret;
 }
 
 static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
diff --git a/cr-show.c b/cr-show.c
index a484b0c..fe657a3 100644
--- a/cr-show.c
+++ b/cr-show.c
@@ -39,6 +39,7 @@
 #include "protobuf/itimer.pb-c.h"
 #include "protobuf/vma.pb-c.h"
 #include "protobuf/page.pb-c.h"
+#include "protobuf/mm.pb-c.h"
 
 #define DEF_PAGES_PER_LINE	6
 
@@ -614,25 +615,27 @@ out:
 
 void show_mm(int fd_mm, struct cr_options *o)
 {
-	struct mm_entry mme;
+	MmEntry *mme;
 
 	pr_img_head(CR_FD_MM);
 
-	if (read_img(fd_mm, &mme) < 0)
+	if (pb_read(fd_mm, &mme, mm_entry) < 0)
 		goto out;
 
-	pr_msg("\tBrk:          0x%lx\n", mme.mm_brk);
-	pr_msg("\tStart code:   0x%lx\n", mme.mm_start_code);
-	pr_msg("\tEnd code:     0x%lx\n", mme.mm_end_code);
-	pr_msg("\tStart stack:  0x%lx\n", mme.mm_start_stack);
-	pr_msg("\tStart data:   0x%lx\n", mme.mm_start_data);
-	pr_msg("\tEnd data:     0x%lx\n", mme.mm_end_data);
-	pr_msg("\tStart brk:    0x%lx\n", mme.mm_start_brk);
-	pr_msg("\tArg start:    0x%lx\n", mme.mm_arg_start);
-	pr_msg("\tArg end:      0x%lx\n", mme.mm_arg_end);
-	pr_msg("\tEnv start:    0x%lx\n", mme.mm_env_start);
-	pr_msg("\tEnv end:      0x%lx\n", mme.mm_env_end);
-	pr_msg("\tExe file ID   %#x\n", mme.exe_file_id);
+	pr_msg("\tBrk:          0x%lx\n", mme->mm_brk);
+	pr_msg("\tStart code:   0x%lx\n", mme->mm_start_code);
+	pr_msg("\tEnd code:     0x%lx\n", mme->mm_end_code);
+	pr_msg("\tStart stack:  0x%lx\n", mme->mm_start_stack);
+	pr_msg("\tStart data:   0x%lx\n", mme->mm_start_data);
+	pr_msg("\tEnd data:     0x%lx\n", mme->mm_end_data);
+	pr_msg("\tStart brk:    0x%lx\n", mme->mm_start_brk);
+	pr_msg("\tArg start:    0x%lx\n", mme->mm_arg_start);
+	pr_msg("\tArg end:      0x%lx\n", mme->mm_arg_end);
+	pr_msg("\tEnv start:    0x%lx\n", mme->mm_env_start);
+	pr_msg("\tEnv end:      0x%lx\n", mme->mm_env_end);
+	pr_msg("\tExe file ID   %#x\n", mme->exe_file_id);
+
+	mm_entry__free_unpacked(mme, NULL);
 out:
 	pr_img_tail(CR_FD_MM);
 }
diff --git a/include/image.h b/include/image.h
index e2d88db..9798d01 100644
--- a/include/image.h
+++ b/include/image.h
@@ -221,22 +221,6 @@ struct task_core_entry {
 	u64				blk_sigset;
 };
 
-struct mm_entry {
-	u64	mm_start_code;
-	u64	mm_end_code;
-	u64	mm_start_data;
-	u64	mm_end_data;
-	u64	mm_start_stack;
-	u64	mm_start_brk;
-	u64	mm_brk;
-	u64	mm_arg_start;
-	u64	mm_arg_end;
-	u64	mm_env_start;
-	u64	mm_env_end;
-	u64	mm_saved_auxv[AT_VECTOR_SIZE];
-	u32	exe_file_id;
-} __packed;
-
 struct core_ids_entry {
 	u32	vm_id;
 	u32	files_id;
diff --git a/include/restorer.h b/include/restorer.h
index 9373661..235c2c4 100644
--- a/include/restorer.h
+++ b/include/restorer.h
@@ -12,6 +12,7 @@
 #include "crtools.h"
 
 #include "../protobuf/vma.pb-c.h"
+#include "../protobuf/mm.pb-c.h"
 
 #ifndef CONFIG_X86_64
 # error Only x86-64 is supported
@@ -86,7 +87,9 @@ struct task_restore_core_args {
 	struct itimerval		itimers[3];
 
 	struct creds_entry		creds;
-	struct mm_entry			mm;
+
+	MmEntry				mm;
+	u64				mm_saved_auxv[AT_VECTOR_SIZE];
 } __aligned(sizeof(long));
 
 struct pt_regs {
diff --git a/protobuf/Makefile b/protobuf/Makefile
index 9957cad..b8d11cc 100644
--- a/protobuf/Makefile
+++ b/protobuf/Makefile
@@ -49,6 +49,7 @@ PROTO_FILES	+= itimer.proto
 PROTO_FILES	+= creds.proto
 PROTO_FILES	+= vma.proto
 PROTO_FILES	+= page.proto
+PROTO_FILES	+= mm.proto
 
 HDRS	:= $(patsubst %.proto,%.pb-c.h,$(PROTO_FILES))
 SRCS	:= $(patsubst %.proto,%.pb-c.c,$(PROTO_FILES))
diff --git a/protobuf/mm.proto b/protobuf/mm.proto
new file mode 100644
index 0000000..d366562
--- /dev/null
+++ b/protobuf/mm.proto
@@ -0,0 +1,16 @@
+message mm_entry {
+	required uint64	mm_start_code	=  1;
+	required uint64	mm_end_code	=  2;
+	required uint64	mm_start_data	=  3;
+	required uint64	mm_end_data	=  4;
+	required uint64	mm_start_stack	=  5;
+	required uint64	mm_start_brk	=  6;
+	required uint64	mm_brk		=  7;
+	required uint64	mm_arg_start	=  8;
+	required uint64	mm_arg_end	=  9;
+	required uint64	mm_env_start	= 10;
+	required uint64	mm_env_end	= 11;
+	required uint32	exe_file_id	= 12;
+
+	repeated uint64	mm_saved_auxv	= 13;
+}
diff --git a/restorer.c b/restorer.c
index 5af316b..d56b3f2 100644
--- a/restorer.c
+++ b/restorer.c
@@ -459,8 +459,8 @@ long __export_restore_task(struct task_restore_core_args *args)
 	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_ARG_END,	(long)args->mm.mm_arg_end, 0);
 	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_ENV_START,	(long)args->mm.mm_env_start, 0);
 	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_ENV_END,	(long)args->mm.mm_env_end, 0);
-	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_AUXV,	(long)args->mm.mm_saved_auxv,
-								sizeof(args->mm.mm_saved_auxv));
+	ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_AUXV,	(long)args->mm_saved_auxv,
+								sizeof(args->mm_saved_auxv));
 	if (ret)
 		goto core_restore_end;
 
-- 
1.7.7.6



More information about the CRIU mailing list