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 <[email protected]>
---
 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
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/containers

_______________________________________________
Devel mailing list
[email protected]
https://openvz.org/mailman/listinfo/devel

Reply via email to