[CRIU] [PATCH cr 4/8] ctrools: prepare to dump pid namespace

Andrey Vagin avagin at openvz.org
Wed May 16 04:32:37 EDT 2012


Add struct pid and use it everywhere.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 cr-dump.c         |  108 ++++++++++++++++++++++++++++------------------------
 cr-restore.c      |   57 ++++++++++++++++------------
 cr-show.c         |   12 +++---
 files.c           |    4 +-
 include/crtools.h |   14 +++++-
 5 files changed, 110 insertions(+), 85 deletions(-)

diff --git a/cr-dump.c b/cr-dump.c
index aa8ce88..93fb84f 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -974,31 +974,31 @@ err:
 	return ret;
 }
 
-static int parse_threads(const struct pstree_item *item, u32 **_t, int *_n)
+static int parse_threads(const struct pstree_item *item, struct pid **_t, int *_n)
 {
 	struct dirent *de;
 	DIR *dir;
-	u32 *t = NULL;
+	struct pid *t = NULL;
 	int nr = 1;
 
-	dir = opendir_proc(item->pid, "task");
+	dir = opendir_proc(item->pid.real_pid, "task");
 	if (!dir)
 		return -1;
 
 	while ((de = readdir(dir))) {
-		u32 *tmp;
+		struct pid *tmp;
 
 		/* We expect numbers only here */
 		if (de->d_name[0] == '.')
 			continue;
 
-		tmp = xrealloc(t, nr * sizeof(u32));
+		tmp = xrealloc(t, nr * sizeof(struct pid));
 		if (!tmp) {
 			xfree(t);
 			return -1;
 		}
 		t = tmp;
-		t[nr - 1] = atoi(de->d_name);
+		t[nr - 1].real_pid = atoi(de->d_name);
 		nr++;
 	}
 
@@ -1017,7 +1017,7 @@ static int get_threads(struct pstree_item *item)
 
 static int check_threads(const struct pstree_item *item)
 {
-	u32 *t;
+	struct pid *t;
 	int nr, ret;
 
 	ret = parse_threads(item, &t, &nr);
@@ -1035,16 +1035,16 @@ static int check_threads(const struct pstree_item *item)
 	return 0;
 }
 
-static int parse_children(const struct pstree_item *item, u32 **_c, int *_n)
+static int parse_children(const struct pstree_item *item, struct pid **_c, int *_n)
 {
 	FILE *file;
 	char *tok;
-	u32 *ch = NULL;
+	struct pid *ch = NULL;
 	int nr = 1, i;
 
 	for (i = 0; i < item->nr_threads; i++) {
-
-		file = fopen_proc(item->pid, "task/%d/children", item->threads[i]);
+		file = fopen_proc(item->pid.real_pid, "task/%d/children",
+						item->threads[i].real_pid);
 		if (!file)
 			goto err;
 
@@ -1055,11 +1055,11 @@ static int parse_children(const struct pstree_item *item, u32 **_c, int *_n)
 
 		tok = strtok(loc_buf, " \n");
 		while (tok) {
-			u32 *tmp = xrealloc(ch, nr * sizeof(u32));
+			struct pid *tmp = xrealloc(ch, nr * sizeof(struct pid));
 			if (!tmp)
 				goto err;
 			ch = tmp;
-			ch[nr - 1] = atoi(tok);
+			ch[nr - 1].real_pid = atoi(tok);
 			nr++;
 			tok = strtok(NULL, " \n");
 		}
@@ -1086,7 +1086,7 @@ static void unseize_task_and_threads(const struct pstree_item *item, int st)
 	int i;
 
 	for (i = 0; i < item->nr_threads; i++)
-		unseize_task(item->threads[i], st); /* item->pid will be here */
+		unseize_task(item->threads[i].real_pid, st); /* item->pid will be here */
 }
 
 static void pstree_switch_state(const struct list_head *list, int st)
@@ -1101,7 +1101,7 @@ static void pstree_switch_state(const struct list_head *list, int st)
 static pid_t item_ppid(const struct pstree_item *item)
 {
 	item = item->parent;
-	return item ? item->pid : -1;
+	return item ? item->pid.real_pid : -1;
 }
 
 static int seize_threads(const struct pstree_item *item)
@@ -1114,11 +1114,13 @@ static int seize_threads(const struct pstree_item *item)
 	}
 
 	for (i = 0; i < item->nr_threads; i++) {
-		if (item->pid == item->threads[i])
+		pid_t pid = item->threads[i].real_pid;
+		if (item->pid.real_pid == pid)
 			continue;
 
-		pr_info("\tSeizing %d's %d thread\n", item->pid, item->threads[i]);
-		ret = seize_task(item->threads[i], item_ppid(item), NULL, NULL);
+		pr_info("\tSeizing %d's %d thread\n",
+				item->pid.real_pid, pid);
+		ret = seize_task(pid, item_ppid(item), NULL, NULL);
 		if (ret < 0)
 			goto err;
 
@@ -1137,10 +1139,10 @@ static int seize_threads(const struct pstree_item *item)
 
 err:
 	for (i--; i >= 0; i--) {
-		if (item->pid == item->threads[i])
+		if (item->pid.real_pid == item->threads[i].real_pid)
 			continue;
 
-		unseize_task(item->threads[i], TASK_ALIVE);
+		unseize_task(item->threads[i].real_pid, TASK_ALIVE);
 	}
 
 	return -1;
@@ -1192,20 +1194,20 @@ static int check_xids(struct list_head *list)
 			continue;
 
 		/* Easing #1 and #2 for sids */
-		if ((p->sid != p->pid) && (p->sid != p->parent->sid)) {
+		if ((p->sid != p->pid.real_pid) && (p->sid != p->parent->sid)) {
 			pr_err("SID mismatch on %d (%d/%d)\n",
-					p->pid, p->sid, p->parent->sid);
+					p->pid.real_pid, p->sid, p->parent->sid);
 			return -1;
 		}
 
 		/* Easing #2 for pgids */
 		list_for_each_entry(tmp, list, list)
-			if (tmp->pid == p->pgid)
+			if (tmp->pid.real_pid == p->pgid)
 				break;
 
 		if (&tmp->list == list) {
-			pr_err("PGIG mismatch on %d (%d)\n",
-					p->pid, p->pgid);
+			pr_err("PGID mismatch on %d (%d)\n",
+					p->pid.real_pid, p->pgid);
 			return -1;
 		}
 	}
@@ -1222,7 +1224,7 @@ static struct pstree_item *collect_task(pid_t pid, struct pstree_item *parent,
 	if (!item)
 		goto err;
 
-	item->pid = pid;
+	item->pid.real_pid = pid;
 	item->parent = parent;
 
 	ret = seize_task(pid, item_ppid(item), &item->pgid, &item->sid);
@@ -1247,7 +1249,7 @@ static struct pstree_item *collect_task(pid_t pid, struct pstree_item *parent,
 
 	close_pid_proc();
 	list_add_tail(&item->list, list);
-	pr_info("Collected %d in %d state\n", item->pid, item->state);
+	pr_info("Collected %d in %d state\n", item->pid.real_pid, item->state);
 	return item;
 
 err_close:
@@ -1263,7 +1265,7 @@ err:
 
 static int check_subtree(const struct pstree_item *item)
 {
-	u32 *ch;
+	struct pid *ch;
 	int nr, ret;
 
 	ret = parse_children(item, &ch, &nr);
@@ -1285,7 +1287,7 @@ static int collect_subtree(pid_t pid, struct pstree_item *parent,
 		struct list_head *pstree_list, int leader_only)
 {
 	struct pstree_item *item;
-	int i;
+	int i, ret;
 
 	pr_info("Collecting tasks starting from %d\n", pid);
 	item = collect_task(pid, parent, pstree_list);
@@ -1296,7 +1298,9 @@ static int collect_subtree(pid_t pid, struct pstree_item *parent,
 		return 0;
 
 	for (i = 0; i < item->nr_children; i++)
-		if (collect_subtree(item->children[i], item, pstree_list, 0) < 0)
+		ret = collect_subtree(item->children[i].real_pid,
+						item, pstree_list, 0);
+		if (ret < 0)
 			return -1;
 
 	if (check_subtree(item))
@@ -1324,7 +1328,7 @@ static int collect_dump_pstree(pid_t pid, struct list_head *pstree_list,
 			if (opts->namespaces_flags & CLONE_NEWPID) {
 				item = list_first_entry(pstree_list,
 						struct pstree_item, list);
-				BUG_ON(item->pid != 1);
+				BUG_ON(item->pid.real_pid != 1);
 
 				if (check_subtree(item))
 					goto try_again;
@@ -1392,10 +1396,10 @@ static int dump_pstree(pid_t pid, const struct list_head *pstree_list)
 
 	list_for_each_entry(item, pstree_list, list) {
 
-		pr_info("Process: %d (%d children)\n",
-			item->pid, item->nr_children);
+		pr_info("Process: %d(%d) (%d children)\n",
+			item->pid.pid, item->pid.real_pid, item->nr_children);
 
-		e.pid		= item->pid;
+		e.pid		= item->pid.pid;
 		e.pgid		= item->pgid;
 		e.sid		= item->sid;
 		e.nr_children	= item->nr_children;
@@ -1404,13 +1408,17 @@ static int dump_pstree(pid_t pid, const struct list_head *pstree_list)
 		if (write_img(pstree_fd, &e))
 			goto err;
 
-		if (write_img_buf(pstree_fd, item->children,
-					item->nr_children * sizeof(u32)))
-			goto err;
+		for (i = 0; i < item->nr_children; i++) {
+			if (write_img_buf(pstree_fd,
+					  &item->children[i].pid, sizeof(u32)))
+				goto err;
+		}
 
-		if (write_img_buf(pstree_fd, item->threads,
-					item->nr_threads * sizeof(u32)))
-			goto err;
+		for (i = 0; i < item->nr_threads; i++) {
+			if (write_img_buf(pstree_fd,
+					  &item->threads[i].pid, sizeof(u32)))
+				goto err;
+		}
 	}
 	ret = 0;
 
@@ -1420,11 +1428,12 @@ err:
 	return ret;
 }
 
-static int dump_task_thread(struct parasite_ctl *parasite_ctl, pid_t pid)
+static int dump_task_thread(struct parasite_ctl *parasite_ctl, struct pid *tid)
 {
 	struct core_entry *core;
 	int ret = -1, fd_core;
 	unsigned int *taddr;
+	pid_t pid = tid->real_pid;
 
 	pr_info("\n");
 	pr_info("Dumping core for thread (pid: %d)\n", pid);
@@ -1479,7 +1488,7 @@ static int dump_one_zombie(const struct pstree_item *item,
 	core->tc.task_state = TASK_DEAD;
 	core->tc.exit_code = pps->exit_code;
 
-	fd_core = open_image(CR_FD_CORE, O_DUMP, item->pid);
+	fd_core = open_image(CR_FD_CORE, O_DUMP, item->pid.pid);
 	if (fd_core < 0)
 		goto err_free;
 
@@ -1498,24 +1507,23 @@ static int dump_task_threads(struct parasite_ctl *parasite_ctl,
 {
 	int i;
 
-	if (item->nr_threads == 1)
-		return 0;
-
 	for (i = 0; i < item->nr_threads; i++) {
 		/* Leader is already dumped */
-		if (item->pid == item->threads[i])
+		if (item->pid.real_pid == item->threads[i].real_pid) {
+			item->threads[i].pid = item->pid.pid;
 			continue;
+		}
 
-		if (dump_task_thread(parasite_ctl, item->threads[i]))
+		if (dump_task_thread(parasite_ctl, &item->threads[i]))
 			return -1;
 	}
 
 	return 0;
 }
 
-static int dump_one_task(const struct pstree_item *item)
+static int dump_one_task(struct pstree_item *item)
 {
-	pid_t pid = item->pid;
+	pid_t pid = item->pid.real_pid;
 	LIST_HEAD(vma_area_list);
 	struct parasite_ctl *parasite_ctl;
 	int ret = -1;
@@ -1547,7 +1555,7 @@ static int dump_one_task(const struct pstree_item *item)
 		return dump_one_zombie(item, &pps_buf);
 
 	ret = -1;
-	cr_fdset = cr_task_fdset_open(item->pid, O_DUMP);
+	cr_fdset = cr_task_fdset_open(item->pid.pid, O_DUMP);
 	if (!cr_fdset)
 		goto err;
 
diff --git a/cr-restore.c b/cr-restore.c
index fb61492..eb644f6 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -69,7 +69,7 @@ static int shmem_remap(void *old_addr, void *new_addr, unsigned long size)
 
 static int prepare_pstree(void)
 {
-	int ret = 0, ps_fd;
+	int ret = 0, ps_fd, i;
 
 	pr_info("Reading image tree\n");
 
@@ -103,29 +103,37 @@ static int prepare_pstree(void)
 		if (pi->rst == NULL)
 			break;
 
-		pi->pid = e.pid;
+		pi->pid.pid = e.pid;
 		pi->pgid = e.pgid;
 		pi->sid = e.sid;
 
 		ret = -1;
 		pi->nr_children = e.nr_children;
-		pi->children = xmalloc(e.nr_children * sizeof(u32));
+		pi->children = xmalloc(e.nr_children * sizeof(struct pid));
 		if (!pi->children)
 			break;
 
-		ret = read_img_buf(ps_fd, pi->children,
-				e.nr_children * sizeof(u32));
+		ret = 0;
+		for (i = 0; i < e.nr_children; i++) {
+			ret = read_img_buf(ps_fd, &pi->children[i].pid, sizeof(u32));
+			if (ret < 0)
+				break;
+		}
 		if (ret < 0)
 			break;
 
 		ret = -1;
 		pi->nr_threads = e.nr_threads;
-		pi->threads = xmalloc(e.nr_threads * sizeof(u32));
+		pi->threads = xmalloc(e.nr_threads * sizeof(struct pid));
 		if (!pi->threads)
 			break;
 
-		ret = read_img_buf(ps_fd, pi->threads,
-				e.nr_threads * sizeof(u32));
+		ret = 0;
+		for (i = 0; i < e.nr_threads; i++) {
+			ret = read_img_buf(ps_fd, &pi->threads[i].pid, sizeof(u32));
+			if (ret < 0)
+				break;
+		}
 		if (ret < 0)
 			break;
 
@@ -179,11 +187,11 @@ static int prepare_shared(void)
 		return -1;
 
 	list_for_each_entry(pi, &tasks, list) {
-		ret = prepare_shmem_pid(pi->pid);
+		ret = prepare_shmem_pid(pi->pid.pid);
 		if (ret < 0)
 			break;
 
-		ret = prepare_fd_pid(pi->pid, pi->rst);
+		ret = prepare_fd_pid(pi->pid.pid, pi->rst);
 		if (ret < 0)
 			break;
 	}
@@ -556,8 +564,8 @@ static void restore_sid(void)
 	 * we can call setpgid() on custom values.
 	 */
 
-	pr_info("Restoring %d to %d sid\n", me->pid, me->sid);
-	if (me->pid == me->sid) {
+	pr_info("Restoring %d to %d sid\n", me->pid.pid, me->sid);
+	if (me->pid.pid == me->sid) {
 		sid = setsid();
 		if (sid != me->sid) {
 			pr_perror("Can't restore sid (%d)", sid);
@@ -577,7 +585,7 @@ static void restore_pgid(void)
 {
 	pid_t pgid;
 
-	pr_info("Restoring %d to %d pgid\n", me->pid, me->pgid);
+	pr_info("Restoring %d to %d pgid\n", me->pid.pid, me->pgid);
 
 	pgid = getpgrp();
 	if (me->pgid == pgid)
@@ -585,7 +593,7 @@ static void restore_pgid(void)
 
 	pr_info("\twill call setpgid, mine pgid is %d\n", pgid);
 	if (setpgid(0, me->pgid) != 0) {
-		pr_perror("Can't restore pgid (%d/%d->%d)", me->pid, pgid, me->pgid);
+		pr_perror("Can't restore pgid (%d/%d->%d)", me->pid.pid, pgid, me->pgid);
 		xid_fail();
 	}
 }
@@ -610,7 +618,7 @@ static int restore_task_with_children(void *_arg)
 		exit(1);
 
 	list_for_each_entry(me, &tasks, list)
-		if (me->pid == pid)
+		if (me->pid.pid == pid)
 			break;
 
 	if (me == list_entry(&tasks, struct pstree_item, list)) {
@@ -619,7 +627,7 @@ static int restore_task_with_children(void *_arg)
 	}
 
 	if (ca->clone_flags) {
-		ret = prepare_namespace(me->pid, ca->clone_flags);
+		ret = prepare_namespace(me->pid.pid, ca->clone_flags);
 		if (ret)
 			exit(-1);
 	}
@@ -635,13 +643,13 @@ static int restore_task_with_children(void *_arg)
 	sigdelset(&blockmask, SIGCHLD);
 	ret = sigprocmask(SIG_BLOCK, &blockmask, NULL);
 	if (ret) {
-		pr_perror("%d: Can't block signals", me->pid);
+		pr_perror("%d: Can't block signals", me->pid.pid);
 		exit(1);
 	}
 
 	pr_info("Restoring %d children:\n", me->nr_children);
 	for (i = 0; i < me->nr_children; i++) {
-		ret = fork_with_pid(me->children[i], 0);
+		ret = fork_with_pid(me->children[i].pid, 0);
 		if (ret < 0)
 			exit(1);
 	}
@@ -651,7 +659,7 @@ static int restore_task_with_children(void *_arg)
 
 	restore_pgid();
 
-	return restore_one_task(me->pid);
+	return restore_one_task(me->pid.pid);
 }
 
 static int restore_root_task(pid_t pid, struct cr_options *opts)
@@ -675,9 +683,9 @@ static int restore_root_task(pid_t pid, struct cr_options *opts)
 	}
 
 	init = list_first_entry(&tasks, struct pstree_item, list);
-	if (init->pid != pid) {
+	if (init->pid.pid != pid && init->pid.pid != 1) {
 		pr_err("Pids mismatch. Init has pid %d, requested %d\n",
-				init->pid, pid);
+				init->pid.pid, pid);
 		return -1;
 	}
 
@@ -688,7 +696,7 @@ static int restore_root_task(pid_t pid, struct cr_options *opts)
 	 * this later.
 	 */
 
-	ret = fork_with_pid(init->pid, opts->namespaces_flags);
+	ret = fork_with_pid(init->pid.pid, opts->namespaces_flags);
 	if (ret < 0)
 		return -1;
 
@@ -711,7 +719,8 @@ out:
 		struct pstree_item *pi;
 
 		list_for_each_entry(pi, &tasks, list)
-			kill(pi->pid, SIGKILL);
+			if ((int) pi->pid.pid > 0)
+				kill(pi->pid.pid, SIGKILL);
 		return 1;
 	}
 
@@ -1131,7 +1140,7 @@ 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++) {
-		thread_args[i].pid = me->threads[i];
+		thread_args[i].pid = me->threads[i].pid;
 
 		/* skip self */
 		if (thread_args[i].pid == pid)
diff --git a/cr-show.c b/cr-show.c
index b384ca9..5594442 100644
--- a/cr-show.c
+++ b/cr-show.c
@@ -431,7 +431,7 @@ static int show_collect_pstree(int fd_pstree, struct list_head *collect)
 			if (!item)
 				return -1;
 
-			item->pid = e.pid;
+			item->pid.pid = e.pid;
 			item->nr_threads = e.nr_threads;
 			item->threads = xzalloc(sizeof(u32) * e.nr_threads);
 			if (!item->threads) {
@@ -463,7 +463,7 @@ static int show_collect_pstree(int fd_pstree, struct list_head *collect)
 					goto out;
 				pr_msg(" %6d", pid);
 				if (item)
-					item->threads[e.nr_threads] = pid;
+					item->threads[e.nr_threads].pid = pid;
 			}
 			pr_msg("\n");
 		}
@@ -669,7 +669,7 @@ static int cr_show_all(struct cr_options *opts)
 	show_sk_queues(fd, opts);
 	close(fd);
 
-	pid = list_first_entry(&pstree_list, struct pstree_item, list)->pid;
+	pid = list_first_entry(&pstree_list, struct pstree_item, list)->pid.pid;
 	ret = try_show_namespaces(pid, opts);
 	if (ret)
 		goto out;
@@ -677,7 +677,7 @@ static int cr_show_all(struct cr_options *opts)
 	list_for_each_entry(item, &pstree_list, list) {
 		struct cr_fdset *cr_fdset = NULL;
 
-		cr_fdset = cr_task_fdset_open(item->pid, O_SHOW);
+		cr_fdset = cr_task_fdset_open(item->pid.pid, O_SHOW);
 		if (!cr_fdset)
 			goto out;
 
@@ -688,7 +688,7 @@ static int cr_show_all(struct cr_options *opts)
 
 			for (i = 0; i < item->nr_threads; i++) {
 
-				if (item->threads[i] == item->pid)
+				if (item->threads[i].pid == item->pid.pid)
 					continue;
 
 				fd_th = open_image_ro(CR_FD_CORE, item->threads[i]);
@@ -696,7 +696,7 @@ static int cr_show_all(struct cr_options *opts)
 					goto out;
 
 				pr_msg("\n");
-				pr_msg("Thread: %d\n", item->threads[i]);
+				pr_msg("Thread: %d\n", item->threads[i].pid);
 				pr_msg("----------------------------------------\n");
 
 				show_core(fd_th, opts);
diff --git a/files.c b/files.c
index 6ca1978..e98ed20 100644
--- a/files.c
+++ b/files.c
@@ -667,7 +667,7 @@ int prepare_fds(struct pstree_item *me)
 
 	for (state = 0; state < FD_STATE_MAX; state++) {
 		list_for_each_entry(fle, &me->rst->fds, ps_list) {
-			ret = open_fdinfo(me->pid, &fle->fe, state);
+			ret = open_fdinfo(me->pid.pid, &fle->fe, state);
 			if (ret)
 				goto done;
 		}
@@ -678,7 +678,7 @@ int prepare_fds(struct pstree_item *me)
 		 * list and restore at the very end.
 		 */
 		list_for_each_entry(fle, &me->rst->eventpoll, ps_list) {
-			ret = open_fdinfo(me->pid, &fle->fe, state);
+			ret = open_fdinfo(me->pid.pid, &fle->fe, state);
 			if (ret)
 				goto done;
 		}
diff --git a/include/crtools.h b/include/crtools.h
index 52f48cf..652d1ea 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -206,17 +206,25 @@ struct rst_info {
 	struct list_head	eventpoll;
 };
 
+struct pid
+{
+	union {
+	u32 real_pid;
+	u32 pid;
+	};
+};
+
 struct pstree_item {
 	struct list_head	list;
-	pid_t			pid;		/* leader pid */
+	struct pid		pid;		/* leader pid */
 	struct pstree_item	*parent;
 	pid_t			pgid;
 	pid_t			sid;
 	int			state;		/* TASK_XXX constants */
 	int			nr_children;	/* number of children */
 	int			nr_threads;	/* number of threads */
-	u32			*threads;	/* array of threads */
-	u32			*children;	/* array of children */
+	struct pid		*threads;	/* array of threads */
+	struct pid		*children;	/* array of children */
 	struct rst_info		*rst;
 };
 
-- 
1.7.1



More information about the CRIU mailing list