diff --git a/criu/action-scripts.c b/criu/action-scripts.c index e3027bd2e..1a1231172 100644 --- a/criu/action-scripts.c +++ b/criu/action-scripts.c @@ -70,7 +70,7 @@ static int run_shell_scripts(const char *action) int pid; char root_item_pid[16]; - pid = root_item->pid.real; + pid = root_item->pid->real; if (pid != -1) { snprintf(root_item_pid, sizeof(root_item_pid), "%d", pid); if (setenv("CRTOOLS_INIT_PID", root_item_pid, 1)) { diff --git a/criu/autofs.c b/criu/autofs.c index 151980d63..934c1e79e 100644 --- a/criu/autofs.c +++ b/criu/autofs.c @@ -579,12 +579,12 @@ static int autofs_dup_pipe(struct pstree_item *task, if (dup_fle(task, ple, new_fd, flags) < 0) { pr_err("Failed to add fd %d to process %d\n", - new_fd, task->pid.virt); + new_fd, task->pid->ns[0].virt); return -1; } pr_info("autofs: added pipe fd %d, flags %#x to %d\n", - new_fd, flags, task->pid.virt); + new_fd, flags, task->pid->ns[0].virt); return new_fd; } @@ -851,12 +851,12 @@ static struct fdinfo_list_entry *autofs_pipe_le(struct pstree_item *master, ple = find_fle_by_fd(&rsti(master)->fds, pipe_fd); if (!ple) { pr_err("Failed to find pipe fd %d in process %d\n", - pipe_fd, master->pid.virt); + pipe_fd, master->pid->ns[0].virt); return NULL; } if (ple->fe->type != FD_TYPES__PIPE) { pr_err("Fd %d in process %d is not a pipe: %d\n", pipe_fd, - master->pid.virt, ple->fe->type); + master->pid->ns[0].virt, ple->fe->type); return NULL; } return ple; @@ -874,7 +874,7 @@ static int autofs_create_fle(struct pstree_item *task, FdinfoEntry *fe, le = (void *)ALIGN((long)le, sizeof(int)); futex_init(&le->real_pid); - le->pid = task->pid.virt; + le->pid = task->pid->ns[0].virt; le->fe = fe; collect_gen_fd(le, rst_info); @@ -955,7 +955,7 @@ static int autofs_add_mount_info(void *data) entry->fd = autofs_dup_pipe(master, ple, entry->fd); if (entry->fd < 0) { pr_err("Failed to find free fd in process %d\n", - master->pid.virt); + master->pid->ns[0].virt); return -1; } } diff --git a/criu/cgroup.c b/criu/cgroup.c index 48850573f..5036be430 100644 --- a/criu/cgroup.c +++ b/criu/cgroup.c @@ -640,7 +640,7 @@ int dump_task_cgroup(struct pstree_item *item, u32 *cg_id, struct parasite_dump_ struct cg_set *cs; if (item) - pid = item->pid.real; + pid = item->pid->real; else pid = getpid(); diff --git a/criu/cr-check.c b/criu/cr-check.c index c10d1ac33..82e5a9d9e 100644 --- a/criu/cr-check.c +++ b/criu/cr-check.c @@ -1095,7 +1095,7 @@ int cr_check(void) if (root_item == NULL) return -1; - root_item->pid.real = getpid(); + root_item->pid->real = getpid(); if (collect_pstree_ids()) return -1; diff --git a/criu/cr-dump.c b/criu/cr-dump.c index 5e708a3f0..6181c3ee9 100644 --- a/criu/cr-dump.c +++ b/criu/cr-dump.c @@ -591,7 +591,7 @@ static int dump_task_kobj_ids(struct pstree_item *item) { int new; struct kid_elem elem; - int pid = item->pid.real; + int pid = item->pid->real; TaskKobjIdsEntry *ids = item->ids; elem.pid = pid; @@ -639,7 +639,7 @@ int get_task_ids(struct pstree_item *item) task_kobj_ids_entry__init(item->ids); - if (item->pid.state != TASK_DEAD) { + if (item->pid->state != TASK_DEAD) { ret = dump_task_kobj_ids(item); if (ret) goto err_free; @@ -694,7 +694,7 @@ static int dump_task_core_all(struct parasite_ctl *ctl, { struct cr_img *img; CoreEntry *core = item->core[0]; - pid_t pid = item->pid.real; + pid_t pid = item->pid->real; int ret = -1; struct proc_status_creds *creds; struct parasite_dump_cgroup_args cgroup_args, *info = NULL; @@ -709,7 +709,7 @@ static int dump_task_core_all(struct parasite_ctl *ctl, creds = dmpi(item)->pi_creds; if (creds->seccomp_mode != SECCOMP_MODE_DISABLED) { - pr_info("got seccomp mode %d for %d\n", creds->seccomp_mode, item->pid.virt); + pr_info("got seccomp mode %d for %d\n", creds->seccomp_mode, item->pid->ns[0].virt); core->tc->has_seccomp_mode = true; core->tc->seccomp_mode = creds->seccomp_mode; @@ -721,7 +721,7 @@ static int dump_task_core_all(struct parasite_ctl *ctl, strlcpy((char *)core->tc->comm, stat->comm, TASK_COMM_LEN); core->tc->flags = stat->flags; - core->tc->task_state = item->pid.state; + core->tc->task_state = item->pid->state; core->tc->exit_code = 0; ret = parasite_dump_thread_leader_seized(ctl, pid, core); @@ -766,24 +766,25 @@ err: static int collect_pstree_ids_predump(void) { struct pstree_item *item; + struct pid pid; struct { struct pstree_item i; struct dmp_info d; - } crt = { }; + } crt = { .i.pid = &pid, }; /* * This thing is normally done inside * write_img_inventory(). */ - crt.i.pid.state = TASK_ALIVE; - crt.i.pid.real = getpid(); + crt.i.pid->state = TASK_ALIVE; + crt.i.pid->real = getpid(); if (predump_task_ns_ids(&crt.i)) return -1; for_each_pstree_item(item) { - if (item->pid.state == TASK_DEAD) + if (item->pid->state == TASK_DEAD) continue; if (predump_task_ns_ids(item)) @@ -827,9 +828,9 @@ static int dump_task_thread(struct parasite_ctl *parasite_ctl, pr_err("Can't dump thread for pid %d\n", pid); goto err; } - pstree_insert_pid(tid->virt, tid); + pstree_insert_pid(tid->ns[0].virt, tid); - img = open_image(CR_FD_CORE, O_DUMP, tid->virt); + img = open_image(CR_FD_CORE, O_DUMP, tid->ns[0].virt); if (!img) goto err; @@ -856,7 +857,7 @@ static int dump_one_zombie(const struct pstree_item *item, core->tc->task_state = TASK_DEAD; core->tc->exit_code = pps->exit_code; - img = open_image(CR_FD_CORE, O_DUMP, item->pid.virt); + img = open_image(CR_FD_CORE, O_DUMP, item->pid->ns[0].virt); if (!img) goto err; @@ -980,8 +981,8 @@ static int dump_task_threads(struct parasite_ctl *parasite_ctl, for (i = 0; i < item->nr_threads; i++) { /* Leader is already dumped */ - if (item->pid.real == item->threads[i].real) { - item->threads[i].virt = item->pid.virt; + if (item->pid->real == item->threads[i].real) { + item->threads[i].ns[0].virt = item->pid->ns[0].virt; continue; } if (dump_task_thread(parasite_ctl, item, i)) @@ -1011,17 +1012,17 @@ static int fill_zombies_pids(struct pstree_item *item) * Pids read here are virtual -- caller has set up * the proc of target pid namespace. */ - if (parse_children(item->pid.virt, &ch, &nr) < 0) + if (parse_children(item->pid->ns[0].virt, &ch, &nr) < 0) return -1; /* * Step 1 -- filter our ch's pid of alive tasks */ list_for_each_entry(child, &item->children, sibling) { - if (child->pid.virt < 0) + if (child->pid->ns[0].virt < 0) continue; for (i = 0; i < nr; i++) { - if (ch[i] == child->pid.virt) { + if (ch[i] == child->pid->ns[0].virt) { ch[i] = -1; break; } @@ -1036,12 +1037,12 @@ static int fill_zombies_pids(struct pstree_item *item) */ i = 0; list_for_each_entry(child, &item->children, sibling) { - if (child->pid.virt > 0) + if (child->pid->ns[0].virt > 0) continue; for (; i < nr; i++) { if (ch[i] < 0) continue; - child->pid.virt = ch[i]; + child->pid->ns[0].virt = ch[i]; ch[i] = -1; break; } @@ -1069,12 +1070,12 @@ static int dump_zombies(void) */ for_each_pstree_item(item) { - if (item->pid.state != TASK_DEAD) + if (item->pid->state != TASK_DEAD) continue; - if (item->pid.virt < 0) { + if (item->pid->ns[0].virt < 0) { if (!pidns) - item->pid.virt = item->pid.real; + item->pid->ns[0].virt = item->pid->real; else if (root_item == item) { pr_err("A root task is dead\n"); goto err; @@ -1083,7 +1084,7 @@ static int dump_zombies(void) } pr_info("Obtaining zombie stat ... \n"); - if (parse_pid_stat(item->pid.virt, &pps_buf) < 0) + if (parse_pid_stat(item->pid->ns[0].virt, &pps_buf) < 0) goto err; item->sid = pps_buf.sid; @@ -1104,7 +1105,7 @@ err: static int pre_dump_one_task(struct pstree_item *item) { - pid_t pid = item->pid.real; + pid_t pid = item->pid->real; struct vm_area_list vmas; struct parasite_ctl *parasite_ctl; int ret = -1; @@ -1118,12 +1119,12 @@ static int pre_dump_one_task(struct pstree_item *item) pr_info("Pre-dumping task (pid: %d)\n", pid); pr_info("========================================\n"); - if (item->pid.state == TASK_STOPPED) { + if (item->pid->state == TASK_STOPPED) { pr_warn("Stopped tasks are not supported\n"); return 0; } - if (item->pid.state == TASK_DEAD) + if (item->pid->state == TASK_DEAD) return 0; ret = collect_mappings(pid, &vmas, NULL); @@ -1157,7 +1158,7 @@ static int pre_dump_one_task(struct pstree_item *item) goto err_cure; } - item->pid.virt = misc.pid; + item->pid->ns[0].virt = misc.pid; mdc.pre_dump = true; @@ -1180,7 +1181,7 @@ err_cure: static int dump_one_task(struct pstree_item *item) { - pid_t pid = item->pid.real; + pid_t pid = item->pid->real; struct vm_area_list vmas; struct parasite_ctl *parasite_ctl; int ret, exit_code = -1; @@ -1197,7 +1198,7 @@ static int dump_one_task(struct pstree_item *item) pr_info("Dumping task (pid: %d)\n", pid); pr_info("========================================\n"); - if (item->pid.state == TASK_DEAD) + if (item->pid->state == TASK_DEAD) /* * zombies are dumped separately in dump_zombies() */ @@ -1286,21 +1287,21 @@ static int dump_one_task(struct pstree_item *item) goto err_cure_imgset; } - item->pid.virt = misc.pid; - pstree_insert_pid(item->pid.virt, &item->pid); + item->pid->ns[0].virt = misc.pid; + pstree_insert_pid(item->pid->ns[0].virt, item->pid); item->sid = misc.sid; item->pgid = misc.pgid; pr_info("sid=%d pgid=%d pid=%d\n", - item->sid, item->pgid, item->pid.virt); + item->sid, item->pgid, item->pid->ns[0].virt); if (item->sid == 0) { pr_err("A session leader of %d(%d) is outside of its pid namespace\n", - item->pid.real, item->pid.virt); + item->pid->real, item->pid->ns[0].virt); goto err_cure; } - cr_imgset = cr_task_imgset_open(item->pid.virt, O_DUMP); + cr_imgset = cr_task_imgset_open(item->pid->ns[0].virt, O_DUMP); if (!cr_imgset) goto err_cure; @@ -1449,9 +1450,9 @@ static int cr_pre_dump_finish(int ret) if (!ctl) continue; - pr_info("\tPre-dumping %d\n", item->pid.virt); + pr_info("\tPre-dumping %d\n", item->pid->ns[0].virt); timing_start(TIME_MEMWRITE); - ret = open_page_xfer(&xfer, CR_FD_PAGEMAP, item->pid.virt); + ret = open_page_xfer(&xfer, CR_FD_PAGEMAP, item->pid->ns[0].virt); if (ret < 0) goto err; @@ -1500,7 +1501,7 @@ int cr_pre_dump_tasks(pid_t pid) root_item = alloc_pstree_item(); if (!root_item) goto err; - root_item->pid.real = pid; + root_item->pid->real = pid; if (!opts.track_mem) { pr_info("Enforcing memory tracking for pre-dump.\n"); @@ -1655,7 +1656,7 @@ int cr_dump_tasks(pid_t pid) root_item = alloc_pstree_item(); if (!root_item) goto err; - root_item->pid.real = pid; + root_item->pid->real = pid; pre_dump_ret = run_scripts(ACT_PRE_DUMP); if (pre_dump_ret != 0) { diff --git a/criu/cr-restore.c b/criu/cr-restore.c index 93289c4ec..bd3ddef61 100644 --- a/criu/cr-restore.c +++ b/criu/cr-restore.c @@ -240,7 +240,7 @@ static int root_prepare_shared(void) } for_each_pstree_item(pi) { - if (pi->pid.state == TASK_HELPER) + if (pi->pid->state == TASK_HELPER) continue; ret = prepare_mm_pid(pi); @@ -348,7 +348,7 @@ static int restore_one_sigaction(int sig, struct cr_img *img, int pid) static int prepare_sigactions(void) { - int pid = current->pid.virt; + int pid = current->pid->ns[0].virt; struct cr_img *img; int sig, rst = 0; int ret = 0; @@ -387,7 +387,7 @@ static int __collect_child_pids(struct pstree_item *p, int state, unsigned int * list_for_each_entry(pi, &p->children, sibling) { pid_t *child; - if (pi->pid.state != state) + if (pi->pid->state != state) continue; child = rst_mem_alloc(sizeof(*child), RM_PRIVATE); @@ -395,7 +395,7 @@ static int __collect_child_pids(struct pstree_item *p, int state, unsigned int * return -1; (*n)++; - *child = pi->pid.virt; + *child = pi->pid->ns[0].virt; } return 0; @@ -414,8 +414,8 @@ static int collect_child_pids(int state, unsigned int *n) if (current == root_item) { for_each_pstree_item(pi) { - if (pi->pid.state != TASK_HELPER && - pi->pid.state != TASK_DEAD) + if (pi->pid->state != TASK_HELPER && + pi->pid->state != TASK_DEAD) continue; if (__collect_child_pids(pi, state, n)) return -1; @@ -464,7 +464,7 @@ static int open_cores(int pid, CoreEntry *leader_core) goto err; for (i = 0; i < current->nr_threads; i++) { - tpid = current->threads[i].virt; + tpid = current->threads[i].ns[0].virt; if (tpid == pid) cores[i] = leader_core; @@ -664,10 +664,10 @@ static int wait_on_helpers_zombies(void) struct pstree_item *pi; list_for_each_entry(pi, ¤t->children, sibling) { - pid_t pid = pi->pid.virt; + pid_t pid = pi->pid->ns[0].virt; int status; - switch (pi->pid.state) { + switch (pi->pid->state) { case TASK_DEAD: if (waitid(P_PID, pid, NULL, WNOWAIT | WEXITED) < 0) { pr_perror("Wait on %d zombie failed", pid); @@ -715,7 +715,7 @@ static int restore_one_zombie(CoreEntry *core) signr = SIGABRT; } - if (kill(current->pid.virt, signr) < 0) + if (kill(current->pid->ns[0].virt, signr) < 0) pr_perror("Can't kill myself, will just exit"); exit_code = 0; @@ -767,9 +767,9 @@ static int restore_one_task(int pid, CoreEntry *core) if (task_alive(current)) ret = restore_one_alive_task(pid, core); - else if (current->pid.state == TASK_DEAD) + else if (current->pid->state == TASK_DEAD) ret = restore_one_zombie(core); - else if (current->pid.state == TASK_HELPER) { + else if (current->pid->state == TASK_HELPER) { sigset_t blockmask, oldmask; sigemptyset(&blockmask); @@ -852,22 +852,22 @@ static inline int fork_with_pid(struct pstree_item *item) { struct cr_clone_arg ca; int ret = -1; - pid_t pid = item->pid.virt; + pid_t pid = item->pid->ns[0].virt; - if (item->pid.state != TASK_HELPER) { + if (item->pid->state != TASK_HELPER) { if (open_core(pid, &ca.core)) return -1; if (check_core(ca.core, item)) return -1; - item->pid.state = ca.core->tc->task_state; + item->pid->state = ca.core->tc->task_state; rsti(item)->cg_set = ca.core->tc->cg_set; rsti(item)->has_seccomp = ca.core->tc->seccomp_mode != SECCOMP_MODE_DISABLED; - if (item->pid.state != TASK_DEAD && !task_alive(item)) { - pr_err("Unknown task state %d\n", item->pid.state); + if (item->pid->state != TASK_DEAD && !task_alive(item)) { + pr_err("Unknown task state %d\n", item->pid->state); return -1; } @@ -937,9 +937,9 @@ static inline int fork_with_pid(struct pstree_item *item) if (item == root_item) { - item->pid.real = ret; + item->pid->real = ret; pr_debug("PID: real %d virt %d\n", - item->pid.real, item->pid.virt); + item->pid->real, item->pid->ns[0].virt); } err_unlock: @@ -966,8 +966,8 @@ static void sigchld_handler(int signal, siginfo_t *siginfo, void *data) status = siginfo->si_status; /* skip scripts */ - if (!current && root_item->pid.real != pid) { - pid = waitpid(root_item->pid.real, &status, WNOHANG); + if (!current && root_item->pid->real != pid) { + pid = waitpid(root_item->pid->real, &status, WNOHANG); if (pid <= 0) return; exit = WIFEXITED(status); @@ -996,11 +996,11 @@ static void sigchld_handler(int signal, siginfo_t *siginfo, void *data) /* Exited (with zero code) helpers are OK */ list_for_each_entry(pi, ¤t->children, sibling) - if (pi->pid.virt == siginfo->si_pid) + if (pi->pid->ns[0].virt == siginfo->si_pid) break; BUG_ON(&pi->sibling == ¤t->children); - if (pi->pid.state != TASK_HELPER) + if (pi->pid->state != TASK_HELPER) break; } @@ -1074,8 +1074,8 @@ static void restore_sid(void) * we can call setpgid() on custom values. */ - if (current->pid.virt == current->sid) { - pr_info("Restoring %d to %d sid\n", current->pid.virt, current->sid); + if (current->pid->ns[0].virt == current->sid) { + pr_info("Restoring %d to %d sid\n", current->pid->ns[0].virt, current->sid); sid = setsid(); if (sid != current->sid) { pr_perror("Can't restore sid (%d)", sid); @@ -1085,7 +1085,7 @@ static void restore_sid(void) sid = getsid(getpid()); if (sid != current->sid) { /* Skip the root task if it's not init */ - if (current == root_item && root_item->pid.virt != INIT_PID) + if (current == root_item && root_item->pid->ns[0].virt != INIT_PID) return; pr_err("Requested sid %d doesn't match inherited %d\n", current->sid, sid); @@ -1108,13 +1108,13 @@ static void restore_pgid(void) pid_t pgid, my_pgid = current->pgid; - pr_info("Restoring %d to %d pgid\n", current->pid.virt, my_pgid); + pr_info("Restoring %d to %d pgid\n", current->pid->ns[0].virt, my_pgid); pgid = getpgrp(); if (my_pgid == pgid) return; - if (my_pgid != current->pid.virt) { + if (my_pgid != current->pid->ns[0].virt) { struct pstree_item *leader; /* @@ -1125,18 +1125,18 @@ static void restore_pgid(void) leader = rsti(current)->pgrp_leader; if (leader) { - BUG_ON(my_pgid != leader->pid.virt); + BUG_ON(my_pgid != leader->pid->ns[0].virt); futex_wait_until(&rsti(leader)->pgrp_set, 1); } } pr_info("\twill call setpgid, mine pgid is %d\n", pgid); if (setpgid(0, my_pgid) != 0) { - pr_perror("Can't restore pgid (%d/%d->%d)", current->pid.virt, pgid, current->pgid); + pr_perror("Can't restore pgid (%d/%d->%d)", current->pid->ns[0].virt, pgid, current->pgid); exit(1); } - if (my_pgid == current->pid.virt) + if (my_pgid == current->pid->ns[0].virt) futex_set_and_wake(&rsti(current)->pgrp_set, 1); } @@ -1229,23 +1229,23 @@ static int restore_task_with_children(void *_arg) } buf[ret] = '\0'; - current->pid.real = atoi(buf); + current->pid->real = atoi(buf); pr_debug("PID: real %d virt %d\n", - current->pid.real, current->pid.virt); + current->pid->real, current->pid->ns[0].virt); } if ( !(ca->clone_flags & CLONE_FILES)) close_safe(&ca->fd); - if (current->pid.state != TASK_HELPER) { + if (current->pid->state != TASK_HELPER) { ret = clone_service_fd(rsti(current)->service_fd_id); if (ret) goto err; } pid = getpid(); - if (current->pid.virt != pid) { - pr_err("Pid %d do not match expected %d\n", pid, current->pid.virt); + if (current->pid->ns[0].virt != pid) { + pr_err("Pid %d do not match expected %d\n", pid, current->pid->ns[0].virt); set_task_cr_err(EEXIST); goto err; } @@ -1349,7 +1349,7 @@ static int restore_task_with_children(void *_arg) if (restore_finish_stage(task_entries, CR_STATE_FORKING) < 0) goto err; - if (restore_one_task(current->pid.virt, ca->core)) + if (restore_one_task(current->pid->ns[0].virt, ca->core)) goto err; return 0; @@ -1420,7 +1420,7 @@ static int attach_to_tasks(bool root_seized) if (!task_alive(item)) continue; - if (parse_threads(item->pid.real, &item->threads, &item->nr_threads)) + if (parse_threads(item->pid->real, &item->threads, &item->nr_threads)) return -1; for (i = 0; i < item->nr_threads; i++) { @@ -1473,7 +1473,7 @@ static int catch_tasks(bool root_seized, enum trace_flags *flag) if (!task_alive(item)) continue; - if (parse_threads(item->pid.real, &item->threads, &item->nr_threads)) + if (parse_threads(item->pid->real, &item->threads, &item->nr_threads)) return -1; for (i = 0; i < item->nr_threads; i++) { @@ -1521,7 +1521,7 @@ static void finalize_restore(void) struct pstree_item *item; for_each_pstree_item(item) { - pid_t pid = item->pid.real; + pid_t pid = item->pid->real; struct parasite_ctl *ctl; if (!task_alive(item)) @@ -1536,9 +1536,9 @@ static void finalize_restore(void) xfree(ctl); - if ((item->pid.state == TASK_STOPPED) || + if ((item->pid->state == TASK_STOPPED) || (opts.final_state == TASK_STOPPED)) - kill(item->pid.real, SIGSTOP); + kill(item->pid->real, SIGSTOP); } } @@ -1617,7 +1617,7 @@ static int write_restored_pid(void) if (!opts.pidfile) return 0; - pid = root_item->pid.real; + pid = root_item->pid->real; if (write_pidfile(pid) < 0) { pr_perror("Can't write pidfile"); @@ -1658,7 +1658,7 @@ static int restore_root_task(struct pstree_item *init) * this later. */ - if (init->pid.virt == INIT_PID) { + if (init->pid->ns[0].virt == INIT_PID) { if (!(root_ns_mask & CLONE_NEWPID)) { pr_err("This process tree can only be restored " "in a new pid namespace.\n" @@ -1703,7 +1703,7 @@ static int restore_root_task(struct pstree_item *init) act.sa_flags &= ~SA_NOCLDSTOP; sigaction(SIGCHLD, &act, NULL); - if (ptrace(PTRACE_SEIZE, init->pid.real, 0, 0)) { + if (ptrace(PTRACE_SEIZE, init->pid->real, 0, 0)) { pr_perror("Can't attach to init"); goto out_kill; } @@ -1722,7 +1722,7 @@ static int restore_root_task(struct pstree_item *init) goto out_kill; if (root_ns_mask & CLONE_NEWNS) { - mnt_ns_fd = open_proc(init->pid.real, "ns/mnt"); + mnt_ns_fd = open_proc(init->pid->real, "ns/mnt"); if (mnt_ns_fd < 0) goto out_kill; } @@ -1765,7 +1765,7 @@ static int restore_root_task(struct pstree_item *init) /* Zombies die after CR_STATE_RESTORE */ for_each_pstree_item(item) { - if (item->pid.state == TASK_DEAD) + if (item->pid->state == TASK_DEAD) task_entries->nr_threads--; } @@ -1875,18 +1875,18 @@ out_kill: int status; /* Kill init */ - if (root_item->pid.real > 0) - kill(root_item->pid.real, SIGKILL); + if (root_item->pid->real > 0) + kill(root_item->pid->real, SIGKILL); - if (waitpid(root_item->pid.real, &status, 0) < 0) + if (waitpid(root_item->pid->real, &status, 0) < 0) pr_warn("Unable to wait %d: %s", - root_item->pid.real, strerror(errno)); + root_item->pid->real, strerror(errno)); } else { struct pstree_item *pi; for_each_pstree_item(pi) - if (pi->pid.virt > 0) - kill(pi->pid.virt, SIGKILL); + if (pi->pid->ns[0].virt > 0) + kill(pi->pid->ns[0].virt, SIGKILL); } out: @@ -2539,7 +2539,7 @@ static int prepare_signals(int pid, struct task_restore_args *ta, CoreEntry *lea for (i = 0; i < current->nr_threads; i++) { if (!current->core[i]->thread_core->signals_p)/*backward compatibility*/ ret = open_signal_image(CR_FD_PSIGNAL, - current->threads[i].virt, &siginfo_priv_nr[i]); + current->threads[i].ns[0].virt, &siginfo_priv_nr[i]); else ret = prepare_one_signal_queue(current->core[i]->thread_core->signals_p, &siginfo_priv_nr[i]); @@ -2944,7 +2944,7 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns struct rt_sigframe *sigframe; k_rtsigset_t *blkset = NULL; - thread_args[i].pid = current->threads[i].virt; + thread_args[i].pid = current->threads[i].ns[0].virt; thread_args[i].siginfo_n = siginfo_priv_nr[i]; thread_args[i].siginfo = task_args->siginfo; thread_args[i].siginfo += siginfo_n; diff --git a/criu/cr-service.c b/criu/cr-service.c index 00a2d07f1..83ff4222d 100644 --- a/criu/cr-service.c +++ b/criu/cr-service.c @@ -195,7 +195,7 @@ int send_criu_rpc_script(enum script_actions act, char *name, int fd) * checking this. */ cn.has_pid = true; - cn.pid = root_item->pid.real; + cn.pid = root_item->pid->real; break; default: break; @@ -568,7 +568,7 @@ static int restore_using_req(int sk, CriuOpts *req) success = true; exit: if (send_criu_restore_resp(sk, success, - root_item ? root_item->pid.real : -1) == -1) { + root_item ? root_item->pid->real : -1) == -1) { pr_perror("Can't send response"); success = false; } diff --git a/criu/file-lock.c b/criu/file-lock.c index d9bda19e0..2d4036c75 100644 --- a/criu/file-lock.c +++ b/criu/file-lock.c @@ -318,11 +318,11 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p) continue; } - fl->real_owner = pid->virt; + fl->real_owner = pid->ns[0].virt; fl->owners_fd = fd; pr_info("Found lock entry %d.%d %d vs %d\n", - pid->real, pid->virt, fd, + pid->real, pid->ns[0].virt, fd, fl->fl_owner); } diff --git a/criu/files-reg.c b/criu/files-reg.c index 8089793ab..4440933d5 100644 --- a/criu/files-reg.c +++ b/criu/files-reg.c @@ -383,7 +383,7 @@ static int open_remap_dead_process(struct reg_file_info *rfi, if (!helper) return -1; - if (helper->pid.state != TASK_UNDEF) { + if (helper->pid->state != TASK_UNDEF) { pr_info("Skipping helper for restoring /proc/%d; pid exists\n", rfe->remap_id); return 0; } @@ -392,11 +392,11 @@ static int open_remap_dead_process(struct reg_file_info *rfi, helper->sid = root_item->sid; helper->pgid = root_item->pgid; - helper->pid.virt = rfe->remap_id; + helper->pid->ns[0].virt = rfe->remap_id; helper->parent = root_item; list_add_tail(&helper->sibling, &root_item->children); - pr_info("Added a helper for restoring /proc/%d\n", helper->pid.virt); + pr_info("Added a helper for restoring /proc/%d\n", helper->pid->ns[0].virt); return 0; } @@ -822,14 +822,14 @@ int dead_pid_conflict(void) * If the dead PID was given to a main thread of another * process, this is handled during restore. */ - item = container_of(node, struct pstree_item, pid); - if (item->pid.real == item->threads[i].real || - item->threads[i].virt != pid) + item = node->item; + if (item->pid->real == item->threads[i].real || + item->threads[i].ns[0].virt != pid) continue; } pr_err("Conflict with a dead task with the same PID as of this thread (virt %d, real %d).\n", - node->virt, node->real); + node->ns[0].virt, node->real); return -1; } diff --git a/criu/files.c b/criu/files.c index f77cf1192..0788cf55c 100644 --- a/criu/files.c +++ b/criu/files.c @@ -322,7 +322,7 @@ static int fill_fd_params(struct pid *owner_pid, int fd, int lfd, { int ret; struct statfs fsbuf; - struct fdinfo_common fdinfo = { .mnt_id = -1, .owner = owner_pid->virt }; + struct fdinfo_common fdinfo = { .mnt_id = -1, .owner = owner_pid->ns[0].virt }; if (fstat(lfd, &p->stat) < 0) { pr_perror("Can't stat fd %d", lfd); @@ -529,7 +529,7 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, int off, nr_fds = min((int) PARASITE_MAX_FDS, dfds->nr_fds); pr_info("\n"); - pr_info("Dumping opened files (pid: %d)\n", item->pid.real); + pr_info("Dumping opened files (pid: %d)\n", item->pid->real); pr_info("----------------------------------------\n"); lfds = xmalloc(nr_fds * sizeof(int)); @@ -555,7 +555,7 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, goto err; for (i = 0; i < nr_fds; i++) { - ret = dump_one_file(&item->pid, dfds->fds[i + off], + ret = dump_one_file(item->pid, dfds->fds[i + off], lfds[i], opts + i, img, ctl); close(lfds[i]); if (ret) @@ -747,7 +747,7 @@ int dup_fle(struct pstree_item *task, struct fdinfo_list_entry *ple, if (!e) return -1; - return collect_fd(task->pid.virt, e, rsti(task)); + return collect_fd(task->pid->ns[0].virt, e, rsti(task)); } int prepare_ctl_tty(int pid, struct rst_info *rst_info, u32 ctl_tty_id) @@ -781,7 +781,7 @@ int prepare_fd_pid(struct pstree_item *item) { int ret = 0; struct cr_img *img; - pid_t pid = item->pid.virt; + pid_t pid = item->pid->ns[0].virt; struct rst_info *rst_info = rsti(item); INIT_LIST_HEAD(&rst_info->used); @@ -793,7 +793,7 @@ int prepare_fd_pid(struct pstree_item *item) if (item->ids == NULL) /* zombie */ return 0; - if (rsti(item)->fdt && rsti(item)->fdt->pid != item->pid.virt) + if (rsti(item)->fdt && rsti(item)->fdt->pid != item->pid->ns[0].virt) return 0; img = open_image(CR_FD_FDINFO, O_RSTR, item->ids->files_id); @@ -1176,7 +1176,7 @@ int prepare_fds(struct pstree_item *me) futex_inc_and_wake(&fdt->fdt_lock); futex_wait_while_lt(&fdt->fdt_lock, fdt->nr); - if (fdt->pid != me->pid.virt) { + if (fdt->pid != me->pid->ns[0].virt) { pr_info("File descriptor table is shared with %d\n", fdt->pid); futex_wait_until(&fdt->fdt_lock, fdt->nr + 1); goto out; @@ -1189,7 +1189,7 @@ int prepare_fds(struct pstree_item *me) continue; } - ret = open_fdinfos(me->pid.virt, &rsti(me)->fds, state); + ret = open_fdinfos(me->pid->ns[0].virt, &rsti(me)->fds, state); if (ret) break; @@ -1197,7 +1197,7 @@ int prepare_fds(struct pstree_item *me) * Now handle TTYs. Slaves are delayed to be sure masters * are already opened. */ - ret = open_fdinfos(me->pid.virt, &rsti(me)->tty_slaves, state); + ret = open_fdinfos(me->pid->ns[0].virt, &rsti(me)->tty_slaves, state); if (ret) break; @@ -1206,7 +1206,7 @@ int prepare_fds(struct pstree_item *me) * to be already restored, thus we store them in a separate * list and restore at the very end. */ - ret = open_fdinfos(me->pid.virt, &rsti(me)->eventpoll, state); + ret = open_fdinfos(me->pid->ns[0].virt, &rsti(me)->eventpoll, state); if (ret) break; } @@ -1224,7 +1224,7 @@ int prepare_fds(struct pstree_item *me) * Opening current TTYs require session to be already set up, * thus slave peers already handled now it's time for cttys, */ - ret = open_fdinfos(me->pid.virt, &rsti(me)->tty_ctty, state); + ret = open_fdinfos(me->pid->ns[0].virt, &rsti(me)->tty_ctty, state); if (ret) break; } @@ -1310,7 +1310,7 @@ out: int prepare_fs_pid(struct pstree_item *item) { - pid_t pid = item->pid.virt; + pid_t pid = item->pid->ns[0].virt; struct rst_info *ri = rsti(item); struct cr_img *img; FsEntry *fe; @@ -1361,15 +1361,15 @@ int shared_fdt_prepare(struct pstree_item *item) futex_init(&fdt->fdt_lock); fdt->nr = 1; - fdt->pid = parent->pid.virt; + fdt->pid = parent->pid->ns[0].virt; } else fdt = rsti(parent)->fdt; rsti(item)->fdt = fdt; rsti(item)->service_fd_id = fdt->nr; fdt->nr++; - if (pid_rst_prio(item->pid.virt, fdt->pid)) - fdt->pid = item->pid.virt; + if (pid_rst_prio(item->pid->ns[0].virt, fdt->pid)) + fdt->pid = item->pid->ns[0].virt; return 0; } @@ -1667,7 +1667,7 @@ int inherit_fd_fini() int open_transport_socket(void) { struct fdt *fdt = rsti(current)->fdt; - pid_t pid = current->pid.virt; + pid_t pid = current->pid->ns[0].virt; struct sockaddr_un saddr; int sock, slen; diff --git a/criu/filesystems.c b/criu/filesystems.c index 554b76776..7fc4c2622 100644 --- a/criu/filesystems.c +++ b/criu/filesystems.c @@ -407,7 +407,7 @@ static int tmpfs_dump(struct mount_info *pm) sprintf(tmpfs_path, "/proc/self/fd/%d", fd); if (root_ns_mask & CLONE_NEWUSER) - userns_pid = root_item->pid.real; + userns_pid = root_item->pid->real; ret = cr_system_userns(-1, img_raw_fd(img), -1, "tar", (char *[]) { "tar", "--create", diff --git a/criu/image.c b/criu/image.c index 11f1e7b6e..9715d1602 100644 --- a/criu/image.c +++ b/criu/image.c @@ -107,10 +107,11 @@ int write_img_inventory(InventoryEntry *he) int prepare_inventory(InventoryEntry *he) { + struct pid pid; struct { struct pstree_item i; struct dmp_info d; - } crt = { }; + } crt = { .i.pid = &pid }; pr_info("Perparing image inventory (version %u)\n", CRTOOLS_IMAGES_V1); @@ -122,8 +123,8 @@ int prepare_inventory(InventoryEntry *he) he->has_lsmtype = true; he->lsmtype = host_lsm_type(); - crt.i.pid.state = TASK_ALIVE; - crt.i.pid.real = getpid(); + crt.i.pid->state = TASK_ALIVE; + crt.i.pid->real = getpid(); if (get_task_ids(&crt.i)) return -1; diff --git a/criu/include/pid.h b/criu/include/pid.h index 772508f96..9ac583ffb 100644 --- a/criu/include/pid.h +++ b/criu/include/pid.h @@ -13,16 +13,17 @@ struct pid { */ pid_t real; + int state; /* TASK_XXX constants */ + /* * The @virt pid is one which used in the image itself and keeps * the pid value to be restored. This pid fetched from the * dumpee context, because the dumpee might have own pid namespace. */ - pid_t virt; - - int state; /* TASK_XXX constants */ - - struct rb_node node; + struct { + pid_t virt; + struct rb_node node; + } ns[1]; /* Must be at the end of struct pid */ }; #define TASK_UNDEF 0x0 diff --git a/criu/include/pstree.h b/criu/include/pstree.h index 569c8d51e..55615fffc 100644 --- a/criu/include/pstree.h +++ b/criu/include/pstree.h @@ -15,7 +15,7 @@ struct pstree_item { struct list_head children; /* list of my children */ struct list_head sibling; /* linkage in my parent's children list */ - struct pid pid; + struct pid *pid; pid_t pgid; pid_t sid; pid_t born_sid; @@ -66,7 +66,7 @@ static inline bool is_alive_state(int state) static inline bool task_alive(struct pstree_item *i) { - return is_alive_state(i->pid.state); + return is_alive_state(i->pid->state); } extern void free_pstree(struct pstree_item *root_item); diff --git a/criu/irmap.c b/criu/irmap.c index a69776c9f..c27fdd720 100644 --- a/criu/irmap.c +++ b/criu/irmap.c @@ -237,7 +237,7 @@ char *irmap_lookup(unsigned int s_dev, unsigned long i_ino) * irmap_predump_prep, so we just go ahead and scan. */ if (!doing_predump && - __mntns_get_root_fd(root_item->pid.real) < 0) + __mntns_get_root_fd(root_item->pid->real) < 0) goto out; timing_start(TIME_IRMAP_RESOLVE); @@ -333,7 +333,7 @@ int irmap_predump_prep(void) */ doing_predump = true; - return __mntns_get_root_fd(root_item->pid.real) < 0 ? -1 : 0; + return __mntns_get_root_fd(root_item->pid->real) < 0 ? -1 : 0; } int irmap_predump_run(void) diff --git a/criu/mem.c b/criu/mem.c index 60d6c8fa5..198e8d784 100644 --- a/criu/mem.c +++ b/criu/mem.c @@ -278,7 +278,7 @@ static int __parasite_dump_pages_seized(struct pstree_item *item, unsigned long pmc_size; pr_info("\n"); - pr_info("Dumping pages (type: %d pid: %d)\n", CR_FD_PAGES, item->pid.real); + pr_info("Dumping pages (type: %d pid: %d)\n", CR_FD_PAGES, item->pid->real); pr_info("----------------------------------------\n"); timing_start(TIME_MEMDUMP); @@ -292,7 +292,7 @@ static int __parasite_dump_pages_seized(struct pstree_item *item, pmc_size = max(vma_area_list->priv_longest, vma_area_list->shared_longest); - if (pmc_init(&pmc, item->pid.real, &vma_area_list->h, + if (pmc_init(&pmc, item->pid->real, &vma_area_list->h, pmc_size * PAGE_SIZE)) return -1; @@ -315,11 +315,11 @@ static int __parasite_dump_pages_seized(struct pstree_item *item, * right here. For pre-dumps the pp will be taken by the * caller and handled later. */ - ret = open_page_xfer(&xfer, CR_FD_PAGEMAP, item->pid.virt); + ret = open_page_xfer(&xfer, CR_FD_PAGEMAP, item->pid->ns[0].virt); if (ret < 0) goto out_pp; } else { - ret = check_parent_page_xfer(CR_FD_PAGEMAP, item->pid.virt); + ret = check_parent_page_xfer(CR_FD_PAGEMAP, item->pid->ns[0].virt); if (ret < 0) goto out_pp; @@ -349,7 +349,7 @@ static int __parasite_dump_pages_seized(struct pstree_item *item, if (!map) goto out_xfer; if (vma_area_is(vma_area, VMA_ANON_SHARED)) - ret = add_shmem_area(item->pid.real, vma_area->e, map); + ret = add_shmem_area(item->pid->real, vma_area->e, map); else { again: ret = generate_iovs(vma_area, pp, map, &off, @@ -382,7 +382,7 @@ again: * Step 4 -- clean up */ - ret = task_reset_dirty_track(item->pid.real); + ret = task_reset_dirty_track(item->pid->real); out_xfer: if (!mdc->pre_dump) xfer.close(&xfer); @@ -445,7 +445,7 @@ int parasite_dump_pages_seized(struct pstree_item *item, int prepare_mm_pid(struct pstree_item *i) { - pid_t pid = i->pid.virt; + pid_t pid = i->pid->ns[0].virt; int ret = -1, vn = 0; struct cr_img *img; struct rst_info *ri = rsti(i); @@ -531,7 +531,7 @@ static int map_private_vma(struct pstree_item *t, struct vma_area *p = *pvma; if (vma_area_is(vma, VMA_FILE_PRIVATE)) { - ret = vma->vm_open(t->pid.virt, vma); + ret = vma->vm_open(t->pid->ns[0].virt, vma); if (ret < 0) { pr_err("Can't fixup VMA's fd\n"); return -1; @@ -695,7 +695,7 @@ static int restore_priv_vma_content(struct pstree_item *t) vma = list_first_entry(vmas, struct vma_area, list); - ret = open_page_read(t->pid.virt, &pr, PR_TASK); + ret = open_page_read(t->pid->ns[0].virt, &pr, PR_TASK); if (ret <= 0) return -1; @@ -913,7 +913,7 @@ int unmap_guard_pages(struct pstree_item *t) int open_vmas(struct pstree_item *t) { - int pid = t->pid.virt; + int pid = t->pid->ns[0].virt; struct vma_area *vma; struct vm_area_list *vmas = &rsti(t)->vmas; diff --git a/criu/mount.c b/criu/mount.c index d03dab4aa..d8de26480 100644 --- a/criu/mount.c +++ b/criu/mount.c @@ -150,9 +150,9 @@ static struct mount_info *__lookup_overlayfs(struct mount_info *list, char *rpat * to make sure we stat the correct file */ if (mntns_root == -1) { - mntns_root = __mntns_get_root_fd(root_item->pid.real); + mntns_root = __mntns_get_root_fd(root_item->pid->real); if (mntns_root < 0) { - pr_err("Unable to get the root file descriptor of pid %d\n", root_item->pid.real); + pr_err("Unable to get the root file descriptor of pid %d\n", root_item->pid->real); return ERR_PTR(-ENOENT); } } @@ -2679,7 +2679,7 @@ static int do_restore_task_mnt_ns(struct ns_id *nsid, struct pstree_item *curren { int fd; - fd = open_proc(root_item->pid.virt, "fd/%d", nsid->mnt.ns_fd); + fd = open_proc(root_item->pid->ns[0].virt, "fd/%d", nsid->mnt.ns_fd); if (fd < 0) return -1; @@ -3196,7 +3196,7 @@ int mntns_get_root_fd(struct ns_id *mntns) if (!mntns->ns_populated) { int fd; - fd = open_proc(root_item->pid.virt, "fd/%d", mntns->mnt.root_fd); + fd = open_proc(root_item->pid->ns[0].virt, "fd/%d", mntns->mnt.root_fd); if (fd < 0) return -1; diff --git a/criu/namespaces.c b/criu/namespaces.c index 412362976..e2954b584 100644 --- a/criu/namespaces.c +++ b/criu/namespaces.c @@ -309,7 +309,7 @@ struct ns_id *rst_new_ns_id(unsigned int id, pid_t pid, int rst_add_ns_id(unsigned int id, struct pstree_item *i, struct ns_desc *nd) { - pid_t pid = i->pid.virt; + pid_t pid = i->pid->ns[0].virt; struct ns_id *nsid; nsid = lookup_ns_by_id(id, nd); @@ -401,7 +401,7 @@ static unsigned int generate_ns_id(int pid, unsigned int kid, struct ns_desc *nd if (pid != getpid()) { type = NS_OTHER; - if (pid == root_item->pid.real) { + if (pid == root_item->pid->real) { BUG_ON(root_ns_mask & nd->cflag); pr_info("Will take %s namespace in the image\n", nd->str); root_ns_mask |= nd->cflag; @@ -549,7 +549,7 @@ static int open_ns_fd(struct file_desc *d) return -1; } - snprintf(path, sizeof(path) - 1, "/proc/%d/ns/%s", item->pid.virt, nd->str); + snprintf(path, sizeof(path) - 1, "/proc/%d/ns/%s", item->pid->ns[0].virt, nd->str); path[sizeof(path) - 1] = '\0'; fd = open(path, nfi->nfe->flags); @@ -593,7 +593,7 @@ struct collect_image_info nsfile_cinfo = { int predump_task_ns_ids(struct pstree_item *item) { - int pid = item->pid.real; + int pid = item->pid->real; if (!__get_ns_id(pid, &net_ns_desc, NULL, &dmpi(item)->netns)) return -1; @@ -606,7 +606,7 @@ int predump_task_ns_ids(struct pstree_item *item) int dump_task_ns_ids(struct pstree_item *item) { - int pid = item->pid.real; + int pid = item->pid->real; TaskKobjIdsEntry *ids = item->ids; ids->has_pid_ns_id = true; @@ -790,7 +790,7 @@ int collect_user_ns(struct ns_id *ns, void *oarg) * mappings, which are used for convirting local id-s to * userns id-s (userns_uid(), userns_gid()) */ - if (dump_user_ns(root_item->pid.real, root_item->ids->user_ns_id)) + if (dump_user_ns(root_item->pid->real, root_item->ids->user_ns_id)) return -1; return 0; @@ -994,7 +994,7 @@ static int do_dump_namespaces(struct ns_id *ns) int dump_namespaces(struct pstree_item *item, unsigned int ns_flags) { - struct pid *ns_pid = &item->pid; + struct pid *ns_pid = item->pid; struct ns_id *ns; int pid, nr = 0; int ret = 0; @@ -1010,9 +1010,9 @@ int dump_namespaces(struct pstree_item *item, unsigned int ns_flags) * net namespace with this is still open */ - pr_info("Dumping %d(%d)'s namespaces\n", ns_pid->virt, ns_pid->real); + pr_info("Dumping %d(%d)'s namespaces\n", ns_pid->ns[0].virt, ns_pid->real); - if ((ns_flags & CLONE_NEWPID) && ns_pid->virt != 1) { + if ((ns_flags & CLONE_NEWPID) && ns_pid->ns[0].virt != 1) { pr_err("Can't dump a pid namespace without the process init\n"); return -1; } @@ -1472,10 +1472,10 @@ int prepare_userns(struct pstree_item *item) if (ret < 0) return -1; - if (write_id_map(item->pid.real, e->uid_map, e->n_uid_map, "uid_map")) + if (write_id_map(item->pid->real, e->uid_map, e->n_uid_map, "uid_map")) return -1; - if (write_id_map(item->pid.real, e->gid_map, e->n_gid_map, "gid_map")) + if (write_id_map(item->pid->real, e->gid_map, e->n_gid_map, "gid_map")) return -1; return 0; @@ -1644,11 +1644,11 @@ err_out: int prepare_namespace(struct pstree_item *item, unsigned long clone_flags) { - pid_t pid = item->pid.virt; + pid_t pid = item->pid->ns[0].virt; int id; pr_info("Restoring namespaces %d flags 0x%lx\n", - item->pid.virt, clone_flags); + item->pid->ns[0].virt, clone_flags); if ((clone_flags & CLONE_NEWUSER) && prepare_userns_creds()) return -1; diff --git a/criu/net.c b/criu/net.c index f3919a7ae..297295b59 100644 --- a/criu/net.c +++ b/criu/net.c @@ -1774,7 +1774,7 @@ int network_lock_internal() "COMMIT\n"; int ret = 0, nsret; - if (switch_ns(root_item->pid.real, &net_ns_desc, &nsret)) + if (switch_ns(root_item->pid->real, &net_ns_desc, &nsret)) return -1; @@ -1798,7 +1798,7 @@ static int network_unlock_internal() "COMMIT\n"; int ret = 0, nsret; - if (switch_ns(root_item->pid.real, &net_ns_desc, &nsret)) + if (switch_ns(root_item->pid->real, &net_ns_desc, &nsret)) return -1; diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c index 0922ae4a2..a51d39687 100644 --- a/criu/parasite-syscall.c +++ b/criu/parasite-syscall.c @@ -652,7 +652,7 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id, return -1; } - tid->virt = args->tid; + tid->ns[0].virt = args->tid; return dump_thread_core(pid, core, args); } diff --git a/criu/proc_parse.c b/criu/proc_parse.c index 8ca7c7ced..6af2a5f10 100644 --- a/criu/proc_parse.c +++ b/criu/proc_parse.c @@ -2220,7 +2220,7 @@ int parse_threads(int pid, struct pid **_t, int *_n) return -1; } t = tmp; - t[nr - 1].virt = -1; + t[nr - 1].ns[0].virt = -1; } t[nr - 1].real = atoi(de->d_name); t[nr - 1].state = TASK_THREAD; diff --git a/criu/pstree.c b/criu/pstree.c index 84747a876..ca09f1ccf 100644 --- a/criu/pstree.c +++ b/criu/pstree.c @@ -143,7 +143,7 @@ int pstree_alloc_cores(struct pstree_item *item) return -1; for (i = 0; i < item->nr_threads; i++) { - if (item->threads[i].real == item->pid.real) + if (item->threads[i].real == item->pid->real) item->core[i] = core_entry_alloc(1, 1); else item->core[i] = core_entry_alloc(1, 0); @@ -196,34 +196,36 @@ struct pstree_item *__alloc_pstree_item(bool rst) int sz; if (!rst) { - sz = sizeof(*item) + sizeof(struct dmp_info); + sz = sizeof(*item) + sizeof(struct dmp_info) + sizeof(struct pid); item = xzalloc(sz); if (!item) return NULL; + item->pid = (void *)item + sizeof(*item) + sizeof(struct dmp_info); } else { - sz = sizeof(*item) + sizeof(struct rst_info); + sz = sizeof(*item) + sizeof(struct rst_info) + sizeof(struct pid); item = shmalloc(sz); if (!item) return NULL; memset(item, 0, sz); vm_area_list_init(&rsti(item)->vmas); + item->pid = (void *)item + sizeof(*item) + sizeof(struct rst_info); } INIT_LIST_HEAD(&item->children); INIT_LIST_HEAD(&item->sibling); - item->pid.virt = -1; - item->pid.real = -1; + item->pid->ns[0].virt = -1; + item->pid->real = -1; item->born_sid = -1; - item->pid.item = item; + item->pid->item = item; return item; } void init_pstree_helper(struct pstree_item *ret) { - ret->pid.state = TASK_HELPER; + ret->pid->state = TASK_HELPER; rsti(ret)->clone_flags = CLONE_FILES | CLONE_FS; task_entries->nr_helpers++; } @@ -267,7 +269,7 @@ int dump_pstree(struct pstree_item *root_item) struct cr_img *img; pr_info("\n"); - pr_info("Dumping pstree (pid: %d)\n", root_item->pid.real); + pr_info("Dumping pstree (pid: %d)\n", root_item->pid->real); pr_info("----------------------------------------\n"); /* @@ -279,10 +281,10 @@ int dump_pstree(struct pstree_item *root_item) * deeper in process tree, thus top-level checking for * leader is enough. */ - if (root_item->pid.virt != root_item->sid) { + if (root_item->pid->ns[0].virt != root_item->sid) { if (!opts.shell_job) { pr_err("The root process %d is not a session leader. " - "Consider using --" OPT_SHELL_JOB " option\n", item->pid.virt); + "Consider using --" OPT_SHELL_JOB " option\n", item->pid->ns[0].virt); return -1; } } @@ -292,10 +294,10 @@ int dump_pstree(struct pstree_item *root_item) return -1; for_each_pstree_item(item) { - pr_info("Process: %d(%d)\n", item->pid.virt, item->pid.real); + pr_info("Process: %d(%d)\n", item->pid->ns[0].virt, item->pid->real); - e.pid = item->pid.virt; - e.ppid = item->parent ? item->parent->pid.virt : 0; + e.pid = item->pid->ns[0].virt; + e.ppid = item->parent ? item->parent->pid->ns[0].virt : 0; e.pgid = item->pgid; e.sid = item->sid; e.n_threads = item->nr_threads; @@ -305,7 +307,7 @@ int dump_pstree(struct pstree_item *root_item) goto err; for (i = 0; i < item->nr_threads; i++) - e.threads[i] = item->threads[i].virt; + e.threads[i] = item->threads[i].ns[0].virt; ret = pb_write_one(img, &e, PB_PSTREE); xfree(e.threads); @@ -334,7 +336,7 @@ static int prepare_pstree_for_shell_job(void) if (!opts.shell_job) return 0; - if (root_item->sid == root_item->pid.virt) + if (root_item->sid == root_item->pid->ns[0].virt) return 0; /* @@ -387,12 +389,12 @@ static struct pid *lookup_create_pid(pid_t pid, struct pid *pid_node) struct rb_node *parent = NULL; while (node) { - struct pid *this = rb_entry(node, struct pid, node); + struct pid *this = rb_entry(node, struct pid, ns[0].node); parent = *new; - if (pid < this->virt) + if (pid < this->ns[0].virt) node = node->rb_left, new = &((*new)->rb_left); - else if (pid > this->virt) + else if (pid > this->ns[0].virt) node = node->rb_right, new = &((*new)->rb_right); else return this; @@ -405,10 +407,10 @@ static struct pid *lookup_create_pid(pid_t pid, struct pid *pid_node) if (item == NULL) return NULL; - item->pid.virt = pid; - pid_node = &item->pid; + item->pid->ns[0].virt = pid; + pid_node = item->pid; } - rb_link_and_balance(&pid_root_rb, &pid_node->node, parent, new); + rb_link_and_balance(&pid_root_rb, &pid_node->ns[0].node, parent, new); return pid_node; } @@ -430,7 +432,7 @@ struct pstree_item *lookup_create_item(pid_t pid) return NULL; BUG_ON(node->state == TASK_THREAD); - return container_of(node, struct pstree_item, pid); + return node->item; } struct pid *pstree_pid_by_virt(pid_t pid) @@ -438,11 +440,11 @@ struct pid *pstree_pid_by_virt(pid_t pid) struct rb_node *node = pid_root_rb.rb_node; while (node) { - struct pid *this = rb_entry(node, struct pid, node); + struct pid *this = rb_entry(node, struct pid, ns[0].node); - if (pid < this->virt) + if (pid < this->ns[0].virt) node = node->rb_left; - else if (pid > this->virt) + else if (pid > this->ns[0].virt) node = node->rb_right; else return this; @@ -455,7 +457,7 @@ static int read_pstree_ids(struct pstree_item *pi) int ret; struct cr_img *img; - img = open_image(CR_FD_IDS, O_RSTR, pi->pid.virt); + img = open_image(CR_FD_IDS, O_RSTR, pi->pid->ns[0].virt); if (!img) return -1; @@ -496,7 +498,7 @@ static int read_pstree_image(pid_t *pid_max) pi = lookup_create_item(e->pid); if (pi == NULL) break; - BUG_ON(pi->pid.state != TASK_UNDEF); + BUG_ON(pi->pid->state != TASK_UNDEF); /* * All pids should be added in the tree to be able to find @@ -509,7 +511,7 @@ static int read_pstree_image(pid_t *pid_max) if (lookup_create_item(e->sid) == NULL) break; - pi->pid.virt = e->pid; + pi->pid->ns[0].virt = e->pid; if (e->pid > *pid_max) *pid_max = e->pid; pi->pgid = e->pgid; @@ -518,7 +520,7 @@ static int read_pstree_image(pid_t *pid_max) pi->sid = e->sid; if (e->sid > *pid_max) *pid_max = e->sid; - pi->pid.state = TASK_ALIVE; + pi->pid->state = TASK_ALIVE; if (e->ppid == 0) { if (root_item) { @@ -534,13 +536,13 @@ static int read_pstree_image(pid_t *pid_max) pid = pstree_pid_by_virt(e->ppid); if (!pid || pid->state == TASK_UNDEF || pid->state == TASK_THREAD) { - pr_err("Can't find a parent for %d\n", pi->pid.virt); + pr_err("Can't find a parent for %d\n", pi->pid->ns[0].virt); pstree_entry__free_unpacked(e, NULL); xfree(pi); goto err; } - parent = container_of(pid, struct pstree_item, pid); + parent = pid->item; pi->parent = parent; list_add(&pi->sibling, &parent->children); } @@ -553,12 +555,12 @@ static int read_pstree_image(pid_t *pid_max) for (i = 0; i < e->n_threads; i++) { struct pid *node; pi->threads[i].real = -1; - pi->threads[i].virt = e->threads[i]; + pi->threads[i].ns[0].virt = e->threads[i]; pi->threads[i].state = TASK_THREAD; pi->threads[i].item = NULL; if (i == 0) continue; /* A thread leader is in a tree already */ - node = lookup_create_pid(pi->threads[i].virt, &pi->threads[i]); + node = lookup_create_pid(pi->threads[i].ns[0].virt, &pi->threads[i]); BUG_ON(node == NULL); if (node != &pi->threads[i]) { @@ -588,20 +590,20 @@ static int get_free_pid() static struct pid *prev, *next; if (prev == NULL) - prev = rb_entry(rb_first(&pid_root_rb), struct pid, node); + prev = rb_entry(rb_first(&pid_root_rb), struct pid, ns[0].node); while (1) { struct rb_node *node; pid_t pid; - pid = prev->virt + 1; + pid = prev->ns[0].virt + 1; pid = pid < RESERVED_PIDS ? RESERVED_PIDS + 1 : pid; - node = rb_next(&prev->node); + node = rb_next(&prev->ns[0].node); if (node == NULL) return pid; - next = rb_entry(node, struct pid, node); - if (next->virt > pid) + next = rb_entry(node, struct pid, ns[0].node); + if (next->ns[0].virt > pid) return pid; prev = next; } @@ -630,12 +632,12 @@ static int prepare_pstree_ids(void) * a session leader himself -- this is a simple case, we * just proceed in a normal way. */ - if (item->sid == root_item->sid || item->sid == item->pid.virt) + if (item->sid == root_item->sid || item->sid == item->pid->ns[0].virt) continue; leader = pstree_item_by_virt(item->sid); BUG_ON(leader == NULL); - if (leader->pid.state != TASK_UNDEF) { + if (leader->pid->state != TASK_UNDEF) { pid_t pid; pid = get_free_pid(); @@ -654,7 +656,7 @@ static int prepare_pstree_ids(void) list_add(&helper->sibling, &leader->children); pr_info("Attach %d to the task %d\n", - helper->pid.virt, leader->pid.virt); + helper->pid->ns[0].virt, leader->pid->ns[0].virt); } else { helper = leader; helper->sid = item->sid; @@ -666,7 +668,7 @@ static int prepare_pstree_ids(void) init_pstree_helper(helper); pr_info("Add a helper %d for restoring SID %d\n", - helper->pid.virt, helper->sid); + helper->pid->ns[0].virt, helper->sid); child = list_entry(item->sibling.prev, struct pstree_item, sibling); item = child; @@ -677,11 +679,11 @@ static int prepare_pstree_ids(void) list_for_each_entry_safe_continue(child, tmp, &root_item->children, sibling) { if (child->sid != helper->sid) continue; - if (child->sid == child->pid.virt) + if (child->sid == child->pid->ns[0].virt) continue; pr_info("Attach %d to the temporary task %d\n", - child->pid.virt, helper->pid.virt); + child->pid->ns[0].virt, helper->pid->ns[0].virt); child->parent = helper; list_move(&child->sibling, &helper->children); @@ -693,10 +695,10 @@ static int prepare_pstree_ids(void) if (!item->parent) /* skip the root task */ continue; - if (item->pid.state == TASK_HELPER) + if (item->pid->state == TASK_HELPER) continue; - if (item->sid != item->pid.virt) { + if (item->sid != item->pid->ns[0].virt) { struct pstree_item *parent; if (item->parent->sid == item->sid) @@ -704,15 +706,15 @@ static int prepare_pstree_ids(void) /* the task could fork a child before and after setsid() */ parent = item->parent; - while (parent && parent->pid.virt != item->sid) { + while (parent && parent->pid->ns[0].virt != item->sid) { if (parent->born_sid != -1 && parent->born_sid != item->sid) { pr_err("Can't determinate with which sid (%d or %d)" "the process %d was born\n", - parent->born_sid, item->sid, parent->pid.virt); + parent->born_sid, item->sid, parent->pid->ns[0].virt); return -1; } parent->born_sid = item->sid; - pr_info("%d was born with sid %d\n", parent->pid.virt, item->sid); + pr_info("%d was born with sid %d\n", parent->pid->ns[0].virt, item->sid); parent = parent->parent; } @@ -732,13 +734,13 @@ static int prepare_pstree_ids(void) for_each_pstree_item(item) { struct pid *pid; - if (!item->pgid || item->pid.virt == item->pgid) + if (!item->pgid || item->pid->ns[0].virt == item->pgid) continue; pid = pstree_pid_by_virt(item->pgid); if (pid->state != TASK_UNDEF) { BUG_ON(pid->state == TASK_THREAD); - rsti(item)->pgrp_leader = container_of(pid, struct pstree_item, pid); + rsti(item)->pgrp_leader = pid->item; continue; } @@ -750,19 +752,19 @@ static int prepare_pstree_ids(void) if (current_pgid == item->pgid) continue; - helper = container_of(pid, struct pstree_item, pid); + helper = pid->item; init_pstree_helper(helper); helper->sid = item->sid; helper->pgid = item->pgid; - helper->pid.virt = item->pgid; + helper->pid->ns[0].virt = item->pgid; helper->parent = item; helper->ids = item->ids; list_add(&helper->sibling, &item->children); rsti(item)->pgrp_leader = helper; pr_info("Add a helper %d for restoring PGID %d\n", - helper->pid.virt, helper->pgid); + helper->pid->ns[0].virt, helper->pgid); } return 0; @@ -964,7 +966,7 @@ struct pstree_item *pstree_item_by_virt(pid_t virt) return NULL; BUG_ON(pid->state == TASK_THREAD); - return container_of(pid, struct pstree_item, pid); + return pid->item; } struct pstree_item *pstree_item_by_real(pid_t real) @@ -972,7 +974,7 @@ struct pstree_item *pstree_item_by_real(pid_t real) struct pstree_item *item; for_each_pstree_item(item) { - if (item->pid.real == real) + if (item->pid->real == real) return item; } return NULL; @@ -984,6 +986,6 @@ int pid_to_virt(pid_t real) item = pstree_item_by_real(real); if (item) - return item->pid.virt; + return item->pid->ns[0].virt; return 0; } diff --git a/criu/seccomp.c b/criu/seccomp.c index 185823370..d906dc057 100644 --- a/criu/seccomp.c +++ b/criu/seccomp.c @@ -49,7 +49,7 @@ static int collect_filter_for_pstree(struct pstree_item *item) struct sock_filter buf[BPF_MAXINSNS]; void *m; - if (item->pid.state == TASK_DEAD || + if (item->pid->state == TASK_DEAD || dmpi(item)->pi_creds->seccomp_mode != SECCOMP_MODE_FILTER) return 0; @@ -57,7 +57,7 @@ static int collect_filter_for_pstree(struct pstree_item *item) int len; struct seccomp_info *info, *inherited = NULL; - len = ptrace(PTRACE_SECCOMP_GET_FILTER, item->pid.real, i, buf); + len = ptrace(PTRACE_SECCOMP_GET_FILTER, item->pid->real, i, buf); if (len < 0) { if (errno == ENOENT) { /* end of the search */ diff --git a/criu/seize.c b/criu/seize.c index bf044a9a1..40381c72e 100644 --- a/criu/seize.c +++ b/criu/seize.c @@ -437,7 +437,7 @@ static inline bool child_collected(struct pstree_item *i, pid_t pid) struct pstree_item *c; list_for_each_entry(c, &i->children, sibling) - if (c->pid.real == pid) + if (c->pid->real == pid) return true; return false; @@ -449,7 +449,7 @@ static int collect_children(struct pstree_item *item) pid_t *ch; int ret, i, nr_children, nr_inprogress; - ret = parse_children(item->pid.real, &ch, &nr_children); + ret = parse_children(item->pid->real, &ch, &nr_children); if (ret < 0) return ret; @@ -488,7 +488,7 @@ static int collect_children(struct pstree_item *item) goto free; } - ret = seize_wait_task(pid, item->pid.real, creds); + ret = seize_wait_task(pid, item->pid->real, creds); if (ret < 0) { /* * Here is a race window between parse_children() and seize(), @@ -509,9 +509,9 @@ static int collect_children(struct pstree_item *item) processes_to_wait--; dmpi(c)->pi_creds = creds; - c->pid.real = pid; + c->pid->real = pid; c->parent = item; - c->pid.state = ret; + c->pid->state = ret; list_add_tail(&c->sibling, &item->children); /* Here is a recursive call (Depth-first search) */ @@ -528,7 +528,7 @@ static void unseize_task_and_threads(const struct pstree_item *item, int st) { int i; - if (item->pid.state == TASK_DEAD) + if (item->pid->state == TASK_DEAD) return; /* @@ -536,7 +536,7 @@ static void unseize_task_and_threads(const struct pstree_item *item, int st) * the item->state is the state task was in when we seized one. */ - unseize_task(item->pid.real, item->pid.state, st); + unseize_task(item->pid->real, item->pid->state, st); if (st == TASK_DEAD) return; @@ -553,7 +553,7 @@ static void pstree_wait(struct pstree_item *root_item) for_each_pstree_item(item) { - if (item->pid.state == TASK_DEAD) + if (item->pid->state == TASK_DEAD) continue; for (i = 0; i < item->nr_threads; i++) { @@ -607,14 +607,14 @@ 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.real : -1; + return item ? item->pid->real : -1; } static inline bool thread_collected(struct pstree_item *i, pid_t tid) { int t; - if (i->pid.real == tid) /* thread leader is collected as task */ + if (i->pid->real == tid) /* thread leader is collected as task */ return true; for (t = 0; t < i->nr_threads; t++) @@ -678,11 +678,11 @@ static int collect_threads(struct pstree_item *item) struct pid *threads = NULL; int nr_threads = 0, i = 0, ret, nr_inprogress, nr_stopped = 0; - ret = parse_threads(item->pid.real, &threads, &nr_threads); + ret = parse_threads(item->pid->real, &threads, &nr_threads); if (ret < 0) goto err; - if ((item->pid.state == TASK_DEAD) && (nr_threads > 1)) { + if ((item->pid->state == TASK_DEAD) && (nr_threads > 1)) { pr_err("Zombies with threads are not supported\n"); goto err; } @@ -693,7 +693,7 @@ static int collect_threads(struct pstree_item *item) return -1; if (item->nr_threads == 0) { - item->threads[0].real = item->pid.real; + item->threads[0].real = item->pid->real; item->nr_threads = 1; item->threads[0].item = NULL; } @@ -709,7 +709,7 @@ static int collect_threads(struct pstree_item *item) nr_inprogress++; pr_info("\tSeizing %d's %d thread\n", - item->pid.real, pid); + item->pid->real, pid); if (!opts.freeze_cgroup && seize_catch_task(pid)) continue; @@ -810,7 +810,7 @@ static int collect_task(struct pstree_item *item) if (ret < 0) goto err_close; - if ((item->pid.state == TASK_DEAD) && !list_empty(&item->children)) { + if ((item->pid->state == TASK_DEAD) && !list_empty(&item->children)) { pr_err("Zombie with children?! O_o Run, run, run!\n"); goto err_close; } @@ -818,7 +818,7 @@ static int collect_task(struct pstree_item *item) if (pstree_alloc_cores(item)) goto err_close; - pr_info("Collected %d in %d state\n", item->pid.real, item->pid.state); + pr_info("Collected %d in %d state\n", item->pid->real, item->pid->state); return 0; err_close: @@ -828,7 +828,7 @@ err_close: int collect_pstree(void) { - pid_t pid = root_item->pid.real; + pid_t pid = root_item->pid->real; int ret = -1; struct proc_status_creds *creds; @@ -863,7 +863,7 @@ int collect_pstree(void) processes_to_wait--; pr_info("Seized task %d, state %d\n", pid, ret); - root_item->pid.state = ret; + root_item->pid->state = ret; dmpi(root_item)->pi_creds = creds; ret = collect_task(root_item); diff --git a/criu/tty.c b/criu/tty.c index fe249a3ca..cead0015a 100644 --- a/criu/tty.c +++ b/criu/tty.c @@ -1001,7 +1001,7 @@ static int pty_open_unpaired_slave(struct file_desc *d, struct tty_info *slave) * checkpoint complete process tree together with * the process which keeps the master peer. */ - if (root_item->sid != root_item->pid.virt) { + if (root_item->sid != root_item->pid->ns[0].virt) { pr_debug("Restore inherited group %d\n", getpgid(getppid())); if (tty_set_prgp(fd, getpgid(getppid()))) @@ -1242,10 +1242,10 @@ static int tty_find_restoring_task(struct tty_info *info) * for us. */ item = find_first_sid(info->tie->sid); - if (item && item->pid.virt == item->sid) { + if (item && item->pid->ns[0].virt == item->sid) { pr_info("Set a control terminal %#x to %d\n", info->tfe->id, info->tie->sid); - return prepare_ctl_tty(item->pid.virt, + return prepare_ctl_tty(item->pid->ns[0].virt, rsti(item), info->tfe->id); } @@ -1651,7 +1651,7 @@ int dump_verify_tty_sids(void) if (!ret && dinfo->sid) { struct pstree_item *item = find_first_sid(dinfo->sid); - if (!item || item->pid.virt != dinfo->sid) { + if (!item || item->pid->ns[0].virt != dinfo->sid) { if (!opts.shell_job) { pr_err("Found dangling tty with sid %d pgid %d (%s) on peer fd %d.\n", dinfo->sid, dinfo->pgrp,