mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 05:48:05 +00:00
pstree: Collect NSpid, NSsid and NStgid when possible
v4: New Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
parent
f334e43bcf
commit
3e6fdadebc
@ -871,7 +871,16 @@ static int dump_task_thread(struct parasite_ctl *parasite_ctl,
|
||||
pr_err("Can't dump thread for pid %d\n", pid);
|
||||
goto err;
|
||||
}
|
||||
tid->ns[0].virt = parasite_tid;
|
||||
|
||||
if (tid->ns[0].virt == -1)
|
||||
tid->ns[0].virt = parasite_tid;
|
||||
else {
|
||||
/* It was collected in parse_pid_status() */
|
||||
if (last_level_pid(tid) != parasite_tid) {
|
||||
pr_err("Parasite and /proc/[pid]/status gave different tids\n");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
pstree_insert_pid(tid, item->ids->pid_ns_id);
|
||||
|
||||
@ -1341,9 +1350,20 @@ static int dump_one_task(struct pstree_item *item)
|
||||
goto err_cure_imgset;
|
||||
}
|
||||
|
||||
vpid(item) = misc.pid;
|
||||
vsid(item) = misc.sid;
|
||||
vpgid(item) = misc.pgid;
|
||||
if (vpid(item) == -1) {
|
||||
vpid(item) = misc.pid;
|
||||
vsid(item) = misc.sid;
|
||||
vpgid(item) = misc.pgid;
|
||||
} else {
|
||||
/* They were collected in parse_pid_status() */
|
||||
if (last_level_pid(item->pid) != misc.pid ||
|
||||
last_level_pid(item->sid) != misc.sid ||
|
||||
last_level_pid(item->pgid) != misc.pgid) {
|
||||
pr_err("Parasite and /proc/[pid]/status gave different pids\n");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
pstree_insert_pid(item->pid, item->ids->pid_ns_id);
|
||||
|
||||
pr_info("sid=%d pgid=%d pid=%d\n", vsid(item), vpgid(item), vpid(item));
|
||||
|
@ -1037,6 +1037,44 @@ static int cap_parse(char *str, unsigned int *res)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_ns_pid(char *str, struct pid **pid_ptr)
|
||||
{
|
||||
pid_t pid[MAX_NS_NESTING];
|
||||
int level, size, skip;
|
||||
pid_t val;
|
||||
|
||||
skip = pid_ns_root_off();
|
||||
|
||||
level = 0;
|
||||
while (sscanf(str, "%d%n", &val, &size) == 1) {
|
||||
if (level == MAX_NS_NESTING) {
|
||||
pr_err("Too nested hierarchy\n");
|
||||
return -1;
|
||||
}
|
||||
str += size;
|
||||
if (skip > 0) {
|
||||
skip--;
|
||||
continue;
|
||||
}
|
||||
pid[level++] = val;
|
||||
}
|
||||
|
||||
if (level == 0) {
|
||||
pr_err("Line can't be collected\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
(*pid_ptr) = xrealloc(*pid_ptr, PID_SIZE(level));
|
||||
if (!*pid_ptr)
|
||||
return -1;
|
||||
|
||||
(*pid_ptr)->level = level;
|
||||
while (level-- > 0)
|
||||
(*pid_ptr)->ns[level].virt = pid[level];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_pid_status(pid_t pid, struct seize_task_status *ss,
|
||||
struct pstree_item *item, struct pid **thread)
|
||||
{
|
||||
@ -1046,6 +1084,7 @@ int parse_pid_status(pid_t pid, struct seize_task_status *ss,
|
||||
int ret = -1;
|
||||
char *str;
|
||||
bool parsed_seccomp = false;
|
||||
int expected_done;
|
||||
|
||||
f.fd = open_proc(pid, "status");
|
||||
if (f.fd < 0)
|
||||
@ -1057,7 +1096,7 @@ int parse_pid_status(pid_t pid, struct seize_task_status *ss,
|
||||
if (bfdopenr(&f))
|
||||
return -1;
|
||||
|
||||
while (done < 12) {
|
||||
while (done < 14) {
|
||||
str = breadline(&f);
|
||||
if (str == NULL)
|
||||
break;
|
||||
@ -1157,10 +1196,43 @@ int parse_pid_status(pid_t pid, struct seize_task_status *ss,
|
||||
done++;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(str, "NSpid:", 6)) {
|
||||
if (get_ns_pid(str + 6, thread ? : &item->pid) < 0) {
|
||||
pr_err("Can't get NSpid\n");
|
||||
goto err_parse;
|
||||
}
|
||||
done++;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(str, "NSpgid:", 7) && !thread) {
|
||||
if (get_ns_pid(str + 7, &item->pgid) < 0) {
|
||||
pr_err("Can't get NSpgid\n");
|
||||
goto err_parse;
|
||||
}
|
||||
done++;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(str, "NSsid:", 6) && !thread) {
|
||||
if (get_ns_pid(str + 6, &item->sid) < 0) {
|
||||
pr_err("Can't get NSsid\n");
|
||||
goto err_parse;
|
||||
}
|
||||
done++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* seccomp is optional */
|
||||
if (done >= 11 || (done == 10 && !parsed_seccomp))
|
||||
if (!thread && (item->pid->level != item->sid->level ||
|
||||
item->pid->level != item->pgid->level)) {
|
||||
pr_err("Level mismatch\n");
|
||||
goto err_parse;
|
||||
}
|
||||
|
||||
/* seccomp and nspids are optional */
|
||||
expected_done = (parsed_seccomp ? 11 : 10);
|
||||
if (kdat.has_nspid)
|
||||
expected_done += (thread ? 1 : 3);
|
||||
if (done == expected_done)
|
||||
ret = 0;
|
||||
|
||||
err_parse:
|
||||
|
Loading…
x
Reference in New Issue
Block a user