[Devel] [PATCH 6/6] [RFC] user-cr: restart: Replace creator pointer with index
Matt Helsley
matthltc at us.ibm.com
Mon Feb 8 13:57:23 PST 2010
Replace the creator field with an index. Since walking the tree table
creator entries can reach the "zero task" we need to replace zero_task
as well.
Place a "zero task" in the tasks_arr rather than keep it as a global.
This completes the transition from using pointers to connect table
entries to using indices.
Signed-off-by: Matt Helsley <matthltc at us.ibm.com>
---
restart.c | 50 ++++++++++++++++++++++++++++----------------------
1 files changed, 28 insertions(+), 22 deletions(-)
diff --git a/restart.c b/restart.c
index e89bf42..61c30a3 100644
--- a/restart.c
+++ b/restart.c
@@ -208,7 +208,7 @@ struct task {
int children; /* pointers to first child, next and prev */
int next_sib; /* sibling, and the creator of a process */
int prev_sib;
- struct task *creator;
+ int creator;
int phantom; /* index of place-holdler task (if any) */
@@ -223,9 +223,6 @@ struct task {
pid_t real_parent; /* pid of task's real parent */
};
-/* zero_task represents creator of root_task (all pids 0) */
-struct task zero_task;
-
#define TASK_ROOT 0x1 /* root task */
#define TASK_GHOST 0x2 /* dead task (pid used as sid/pgid) */
#define TASK_THREAD 0x4 /* thread (non leader) */
@@ -249,7 +246,7 @@ struct ckpt_ctx {
struct task *tasks_arr;
int tasks_nr;
- int tasks_max;
+ int tasks_max; /* also == index of the "zero task" in the task table */
int tasks_pid;
struct hashent **hash_arr;
@@ -1174,7 +1171,7 @@ static int ckpt_build_tree(void)
* placeholder tasks (each session id may have at most one)
*/
ctx.tasks_max = ctx.pids_nr * 4;
- ctx.tasks_arr = malloc(sizeof(*ctx.tasks_arr) * ctx.tasks_max);
+ ctx.tasks_arr = malloc(sizeof(*ctx.tasks_arr) * (ctx.tasks_max + 1));
if (!ctx.tasks_arr) {
perror("malloc tasks array");
return -1;
@@ -1190,7 +1187,7 @@ static int ckpt_build_tree(void)
/* assign a creator to each task */
for (i = 0; i < ctx.tasks_nr; i++) {
task = &ctx.tasks_arr[i];
- if (task->creator)
+ if (task->creator > -1)
continue;
if (ckpt_set_creator(task) < 0) {
free(ctx.tasks_arr);
@@ -1205,7 +1202,7 @@ static int ckpt_build_tree(void)
task = &ctx.tasks_arr[i];
ckpt_dbg("\t[%d] pid %d ppid %d sid %d creator %d",
i, task->pid, task->ppid, task->sid,
- task->creator->pid);
+ ctx.tasks_arr[task->creator].pid);
if (task->next_sib > -1)
ckpt_dbg_cont(" next %d", ctx.tasks_arr[task->next_sib].pid);
if (task->prev_sib > -1)
@@ -1250,8 +1247,8 @@ static int ckpt_setup_task(pid_t pid, pid_t ppid)
task->children = -1;
task->next_sib = -1;
task->prev_sib = -1;
- task->creator = NULL;
task->phantom = -1;
+ task->creator = -1;
task->rpid = -1;
@@ -1358,6 +1355,13 @@ static int ckpt_init_tree(void)
if (root_sid == root_pid)
root_sid = -1;
+ /* Make the dummy "zero" task the last task in the array. */
+ task = &ctx.tasks_arr[ctx.tasks_max];
+ memset(task, sizeof(*task), 0);
+ task->index = ctx.tasks_max;
+ /* unused, but set to "nothing" just in case: */
+ task->prev_sib = task->next_sib = task->phantom = task->creator = -1;
+
/* populate with known tasks */
for (i = 0; i < pids_nr; i++) {
task = &ctx.tasks_arr[i];
@@ -1387,8 +1391,8 @@ static int ckpt_init_tree(void)
task->children = -1;
task->next_sib = -1;
task->prev_sib = -1;
- task->creator = NULL;
task->phantom = -1;
+ task->creator = -1;
task->rpid = -1;
@@ -1464,9 +1468,11 @@ static int ckpt_init_tree(void)
}
}
+ /* "zero_task" represents creator of root_task (all pids 0) */
+
/* mark root task(s), and set its "creator" to be zero_task */
ckpt_init_task()->flags |= TASK_ROOT;
- ckpt_init_task()->creator = &zero_task;
+ ckpt_init_task()->creator = ctx.tasks_max;
ckpt_dbg("total tasks (including ghosts): %d\n", ctx.tasks_nr);
return 0;
@@ -1587,7 +1593,7 @@ static int ckpt_set_creator(struct task *task)
creator = &ctx.tasks_arr[session->phantom];
} else {
/* first make sure we know the session's creator */
- if (!session->creator) {
+ if (session->creator < 0) {
/* (non-session-leader) recursive: session's creator */
ckpt_dbg("pid %d: recursive session creator %d\n",
task->pid, task->sid);
@@ -1595,7 +1601,7 @@ static int ckpt_set_creator(struct task *task)
return -1;
}
/* then use it to decide what to do */
- if (session->creator->pid == task->ppid) {
+ if (ctx.tasks_arr[session->creator].pid == task->ppid) {
/* init must not be sibling creator (CLONE_PARENT) */
if (session == ckpt_init_task()) {
ckpt_err("pid %d: sibling session prohibited"
@@ -1624,7 +1630,7 @@ static int ckpt_set_creator(struct task *task)
}
ckpt_dbg("pid %d: creator set to %d\n", task->pid, creator->pid);
- task->creator = creator;
+ task->creator = creator->index;
creator->children = task->index;
if (task->flags & TASK_SESSION)
@@ -1661,12 +1667,12 @@ static int ckpt_placeholder_task(struct task *task)
holder->children = -1;
holder->next_sib = -1;
holder->prev_sib = -1;
- holder->creator = NULL;
holder->phantom = -1;
+ holder->creator = -1;
holder->rpid = -1;
- holder->creator = session;
+ holder->creator = session->index;
if (session->children > -1) {
holder->next_sib = session->children;
ctx.tasks_arr[session->children].prev_sib = holder->index;
@@ -1679,10 +1685,10 @@ static int ckpt_placeholder_task(struct task *task)
ctx.tasks_arr[task->next_sib].prev_sib = task->prev_sib;
if (task->prev_sib > -1)
ctx.tasks_arr[task->prev_sib].next_sib = task->next_sib;
- if (task->creator)
- task->creator->children = task->next_sib;
+ if (task->creator > -1)
+ ctx.tasks_arr[task->creator].children = task->next_sib;
- task->creator = holder;
+ task->creator = holder->index;
task->next_sib = -1;
task->prev_sib = -1;
@@ -1699,7 +1705,7 @@ static int ckpt_propagate_session(struct task *task)
ckpt_dbg("pid %d: set session\n", task->pid);
task->flags |= TASK_SESSION;
- creator = task->creator;
+ creator = &ctx.tasks_arr[task->creator];
if (creator->pid == 1) {
if (ckpt_placeholder_task(task) < 0)
return -1;
@@ -1708,14 +1714,14 @@ static int ckpt_propagate_session(struct task *task)
ckpt_dbg("pid %d: moving up to %d\n", task->pid, creator->pid);
task = creator;
- if(!task->creator) {
+ if(task->creator < 0) {
if (ckpt_set_creator(task) < 0)
return -1;
}
} while (task->sid != sid &&
task != ckpt_init_task() &&
!(task->flags & TASK_SESSION) &&
- task->creator != session);
+ task->creator != session->index);
return 0;
}
--
1.6.3.3
_______________________________________________
Containers mailing list
Containers at lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers
More information about the Devel
mailing list