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@xxxxxxxxxx> --- 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@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/containers