[CRIU] [PATCH cr 01/13] ctrools: prepare to dump pid namespace
Andrey Vagin
avagin at openvz.org
Tue Jun 19 07:53:05 EDT 2012
Add struct pid and use it everywhere. This struct contains
two fields: pid and real_pid.
real_pid is a pid outside of the target pid namespace.
pid is in the target pid namespace
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
cr-dump.c | 95 ++++++++++++++++++++++++++++-------------------------
cr-restore.c | 48 ++++++++++++++------------
cr-show.c | 12 +++---
files.c | 4 +-
include/crtools.h | 12 +++++-
5 files changed, 94 insertions(+), 77 deletions(-)
diff --git a/cr-dump.c b/cr-dump.c
index d88537f..065c80e 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -973,31 +973,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++;
}
@@ -1016,7 +1016,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);
@@ -1042,8 +1042,8 @@ static int parse_children(const struct pstree_item *item, u32 **_c, int *_n)
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;
@@ -1106,7 +1106,7 @@ static int get_children(struct pstree_item *item)
ret = -1;
goto free;
}
- c->pid = ch[i];
+ c->pid.real_pid = ch[i];
c->parent = item;
list_add_tail(&c->list, &item->children);
}
@@ -1120,7 +1120,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 */
}
struct pstree_item *pstree_item_next(struct pstree_item *item)
@@ -1159,7 +1159,7 @@ static void pstree_switch_state(struct pstree_item *root_item, 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)
@@ -1172,11 +1172,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;
@@ -1195,10 +1197,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;
@@ -1250,20 +1252,20 @@ static int check_xids(struct pstree_item *root_item)
continue;
/* Easing #1 and #2 for sids */
- if ((p->sid != p->pid) && (p->sid != p->parent->sid)) {
+ if ((p->sid != p->pid.pid) && (p->sid != p->parent->sid)) {
pr_err("SID mismatch on %d (%d/%d)\n",
- p->pid, p->sid, p->parent->sid);
+ p->pid.pid, p->sid, p->parent->sid);
return -1;
}
/* Easing #2 for pgids */
for_each_pstree_item(tmp)
- if (tmp->pid == p->pgid)
+ if (tmp->pid.pid == p->pgid)
break;
if (tmp == NULL) {
pr_err("PGIG mismatch on %d (%d)\n",
- p->pid, p->pgid);
+ p->pid.pid, p->pgid);
return -1;
}
}
@@ -1274,7 +1276,7 @@ static int check_xids(struct pstree_item *root_item)
static int collect_task(struct pstree_item *item)
{
int ret;
- pid_t pid = item->pid;
+ pid_t pid = item->pid.real_pid;
ret = seize_task(pid, item_ppid(item), &item->pgid, &item->sid);
if (ret < 0)
@@ -1297,7 +1299,8 @@ static int collect_task(struct pstree_item *item)
}
close_pid_proc();
- 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 0;
err_close:
@@ -1319,7 +1322,7 @@ static int check_subtree(const struct pstree_item *item)
i = 0;
list_for_each_entry(child, &item->children, list) {
- if (child->pid != ch[i])
+ if (child->pid.real_pid != ch[i])
break;
i++;
if (i > nr)
@@ -1338,7 +1341,7 @@ static int check_subtree(const struct pstree_item *item)
static int collect_subtree(struct pstree_item *item, int leader_only)
{
struct pstree_item *child;
- pid_t pid = item->pid;
+ pid_t pid = item->pid.real_pid;
int ret;
pr_info("Collecting tasks starting from %d\n", pid);
@@ -1372,7 +1375,7 @@ static int collect_pstree(pid_t pid, const struct cr_options *opts)
if (root_item == NULL)
return -1;
- root_item->pid = pid;
+ root_item->pid.real_pid = pid;
INIT_LIST_HEAD(&root_item->list);
ret = collect_subtree(root_item, opts->leader_only);
@@ -1382,7 +1385,7 @@ static int collect_pstree(pid_t pid, const struct cr_options *opts)
* namespaces' reaper. Check this.
*/
if (opts->namespaces_flags & CLONE_NEWPID) {
- BUG_ON(root_item->pid != 1);
+ BUG_ON(root_item->pid.real_pid != 1);
if (check_subtree(root_item))
goto try_again;
@@ -1421,11 +1424,11 @@ static int dump_pstree(struct pstree_item *root_item)
{
struct pstree_item *item = root_item;
struct pstree_entry e;
- int ret = -1;
+ int ret = -1, i;
int pstree_fd;
pr_info("\n");
- pr_info("Dumping pstree (pid: %d)\n", root_item->pid);
+ pr_info("Dumping pstree (pid: %d)\n", root_item->pid.real_pid);
pr_info("----------------------------------------\n");
pstree_fd = open_image(CR_FD_PSTREE, O_DUMP);
@@ -1433,10 +1436,10 @@ static int dump_pstree(struct pstree_item *root_item)
return -1;
for_each_pstree_item(item) {
- pr_info("Process: %d\n", item->pid);
+ pr_info("Process: %d(%d)\n", item->pid.pid, item->pid.real_pid);
- e.pid = item->pid;
- e.ppid = item->parent ? item->parent->pid : 0;
+ e.pid = item->pid.pid;
+ e.ppid = item->parent ? item->parent->pid.pid : 0;
e.pgid = item->pgid;
e.sid = item->sid;
e.nr_threads = item->nr_threads;
@@ -1444,9 +1447,11 @@ static int dump_pstree(struct pstree_item *root_item)
if (write_img(pstree_fd, &e))
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;
@@ -1456,11 +1461,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);
@@ -1515,7 +1521,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;
@@ -1534,24 +1540,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;
@@ -1583,7 +1588,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 2f4f170..1eb1226 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, i, ps_fd;
struct pstree_item *pi, *parent = NULL;
pr_info("Reading image tree\n");
@@ -99,7 +99,7 @@ static int prepare_pstree(void)
if (pi == NULL)
break;
- pi->pid = e.pid;
+ pi->pid.pid = e.pid;
pi->pgid = e.pgid;
pi->sid = e.sid;
@@ -115,18 +115,18 @@ static int prepare_pstree(void)
* and sit among the last item's ancestors.
*/
while (parent) {
- if (parent->pid == e.ppid)
+ if (parent->pid.pid == e.ppid)
break;
parent = parent->parent;
}
if (parent == NULL)
for_each_pstree_item(parent)
- if (parent->pid == e.ppid)
+ if (parent->pid.pid == e.ppid)
break;
if (parent == NULL) {
- pr_err("Can't find a parent for %d", pi->pid);
+ pr_err("Can't find a parent for %d", pi->pid.pid);
xfree(pi);
break;
}
@@ -138,12 +138,16 @@ static int prepare_pstree(void)
parent = pi;
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;
@@ -196,11 +200,11 @@ static int prepare_shared(void)
return -1;
for_each_pstree_item(pi) {
- 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;
}
@@ -492,7 +496,7 @@ static inline int fork_with_pid(struct pstree_item *item, unsigned long ns_clone
char buf[32];
struct cr_clone_arg ca;
void *stack;
- pid_t pid = item->pid;
+ pid_t pid = item->pid.pid;
pr_info("Forking task with %d pid (flags 0x%lx)\n", pid, ns_clone_flags);
@@ -573,8 +577,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);
@@ -594,7 +598,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)
@@ -602,7 +606,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();
}
}
@@ -620,8 +624,8 @@ static int restore_task_with_children(void *_arg)
me = ca->item;
pid = getpid();
- if (me->pid != pid) {
- pr_err("Pid %d do not match expected %d\n", pid, me->pid);
+ if (me->pid.pid != pid) {
+ pr_err("Pid %d do not match expected %d\n", pid, me->pid.pid);
exit(-1);
}
@@ -630,7 +634,7 @@ static int restore_task_with_children(void *_arg)
exit(1);
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);
}
@@ -646,7 +650,7 @@ 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);
}
@@ -662,7 +666,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(struct pstree_item *init, struct cr_options *opts)
@@ -714,7 +718,7 @@ out:
pr_err("Someone can't be restored\n");
for_each_pstree_item(pi)
- kill(pi->pid, SIGKILL);
+ kill(pi->pid.pid, SIGKILL);
return 1;
}
@@ -1133,7 +1137,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 31c1565..f697bcc 100644
--- a/cr-show.c
+++ b/cr-show.c
@@ -426,7 +426,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) {
@@ -446,7 +446,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");
}
@@ -649,7 +649,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;
@@ -657,7 +657,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;
@@ -668,7 +668,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]);
@@ -676,7 +676,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 599281b..f30aee1 100644
--- a/files.c
+++ b/files.c
@@ -663,7 +663,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;
}
@@ -674,7 +674,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 e31503f..6e8ec26 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -175,16 +175,24 @@ struct rst_info {
struct list_head eventpoll;
};
+struct pid
+{
+ union { /* They will be splitted, when crtools will support pid ns */
+ 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;
struct list_head children; /* array of children */
pid_t pgid;
pid_t sid;
int state; /* TASK_XXX constants */
int nr_threads; /* number of threads */
- u32 *threads; /* array of threads */
+ struct pid *threads; /* array of threads */
struct rst_info rst[0];
};
--
1.7.1
More information about the CRIU
mailing list