mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 05:48:05 +00:00
pstree: Make pstree_item::pid pointer and move virt and node to array
So, after the patch struct pid will look as: struct pid { struct pstree_item *item; pid_t real; int state; struct { pid_t virt; struct rb_node node; } ns[1]; }; travis-ci: success for Make pstree_item::pid allocated dynamically Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com> Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
This commit is contained in:
parent
9af2eff929
commit
e4335cf061
@ -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)) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
32
criu/files.c
32
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;
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
20
criu/mem.c
20
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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
116
criu/pstree.c
116
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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
36
criu/seize.c
36
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);
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user