[CRIU] [PATCH v2 54/57] restorer: Set NStids in all pid_ns for thread before we create it.
Kirill Tkhai
ktkhai at virtuozzo.com
Tue Mar 28 08:42:04 PDT 2017
If there is multi-level pid, ask helpers to populate /proc last pids
in their active pid namespaces. So, thread will be created with right
NStids.
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
criu/cr-restore.c | 24 ++++++++++++++++--------
criu/include/restorer.h | 4 +++-
criu/pie/restorer.c | 44 ++++++++++++++++++++++++++++++--------------
3 files changed, 49 insertions(+), 23 deletions(-)
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index e29a5bd9..0ca19ec6 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -3088,12 +3088,13 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
struct vm_area_list self_vmas;
struct vm_area_list *vmas = &rsti(current)->vmas;
- int i, siginfo_n;
+ int i, k, siginfo_n;
unsigned long creds_pos = 0;
unsigned long creds_pos_next;
sigset_t blockmask;
+ struct ns_id *pid_ns;
pr_info("Restore via sigreturn\n");
@@ -3283,6 +3284,12 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
task_args->sigchld_act = sigchld_act;
strncpy(task_args->comm, core->tc->comm, sizeof(task_args->comm));
+ pid_ns = lookup_ns_by_id(current->ids->pid_ns_id, &pid_ns_desc);
+ BUG_ON(!pid_ns);
+ for (i = current->pid->level - 1; i >= 0; i--, pid_ns = pid_ns->parent)
+ task_args->pid_ns_id[i] = pid_ns->id;
+ if (current->pid->level != MAX_NS_NESTING)
+ task_args->pid_ns_id[current->pid->level] = 0; /* Delimiter */
/*
* Fill up per-thread data.
@@ -3294,14 +3301,15 @@ 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]->ns[0].virt;
+ for (k = 0; k < current->pid->level; k++)
+ thread_args[i].pid[k] = current->threads[i]->ns[k].virt;
thread_args[i].siginfo_n = siginfo_priv_nr[i];
thread_args[i].siginfo = task_args->siginfo;
thread_args[i].siginfo += siginfo_n;
siginfo_n += thread_args[i].siginfo_n;
/* skip self */
- if (thread_args[i].pid == pid) {
+ if (thread_args[i].pid[0] == pid) {
task_args->t = thread_args + i;
tcore = core;
blkset = (void *)&tcore->tc->blk_sigset;
@@ -3311,15 +3319,15 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
blkset = (void *)&tcore->thread_core->blk_sigset;
}
- if ((tcore->tc || tcore->ids) && thread_args[i].pid != pid) {
+ if ((tcore->tc || tcore->ids) && thread_args[i].pid[0] != pid) {
pr_err("Thread has optional fields present %d\n",
- thread_args[i].pid);
+ thread_args[i].pid[0]);
ret = -1;
}
if (ret < 0) {
pr_err("Can't read core data for thread %d\n",
- thread_args[i].pid);
+ thread_args[i].pid[0]);
goto err;
}
@@ -3349,7 +3357,7 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
if (construct_sigframe(sigframe, sigframe, blkset, tcore))
goto err;
- if (thread_args[i].pid != pid)
+ if (thread_args[i].pid[0] != pid)
core_entry__free_unpacked(tcore, NULL);
pr_info("Thread %4d stack %8p rt_sigframe %8p\n",
@@ -3406,7 +3414,7 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
"task_args->nr_threads: %d\n"
"task_args->clone_restore_fn: %p\n"
"task_args->thread_args: %p\n",
- task_args, task_args->t->pid,
+ task_args, task_args->t->pid[0],
task_args->nr_threads,
task_args->clone_restore_fn,
task_args->thread_args);
diff --git a/criu/include/restorer.h b/criu/include/restorer.h
index 00291233..701c72ff 100644
--- a/criu/include/restorer.h
+++ b/criu/include/restorer.h
@@ -17,6 +17,7 @@
#include "posix-timer.h"
#include "timerfd.h"
#include "shmem.h"
+#include "namespaces.h"
#include "parasite-vdso.h"
#include "fault-injection.h"
@@ -78,7 +79,7 @@ struct thread_creds_args {
struct thread_restore_args {
struct restore_mem_zone *mz;
- int pid;
+ pid_t pid[MAX_NS_NESTING];
UserRegsEntry gpregs;
u64 clear_tid_addr;
@@ -167,6 +168,7 @@ struct task_restore_args {
auxv_t mm_saved_auxv[AT_VECTOR_SIZE];
u32 mm_saved_auxv_size;
char comm[TASK_COMM_LEN];
+ int pid_ns_id[MAX_NS_NESTING];
/*
* proc_fd is a handle to /proc that the restorer blob can use to open
diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c
index 67d5a013..13e8192c 100644
--- a/criu/pie/restorer.c
+++ b/criu/pie/restorer.c
@@ -480,10 +480,14 @@ long __export_restore_thread(struct thread_restore_args *args)
k_rtsigset_t to_block;
unsigned long new_sp;
int my_pid = sys_gettid();
- int ret;
+ int i, ret;
+
+ for (i = 0; i < MAX_NS_NESTING; i++)
+ if (args->pid[i] == 0)
+ break;
- if (my_pid != args->pid) {
- pr_err("Thread pid mismatch %d/%d\n", my_pid, args->pid);
+ if (my_pid != args->pid[i-1]) {
+ pr_err("Thread pid mismatch %d/%d\n", my_pid, args->pid[i-1]);
goto core_restore_end;
}
@@ -1140,7 +1144,7 @@ static int wait_zombies(struct task_restore_args *task_args)
long __export_restore_task(struct task_restore_args *args)
{
long ret = -1;
- int i;
+ int i, k;
VmaEntry *vma_entry;
unsigned long va;
@@ -1444,20 +1448,32 @@ long __export_restore_task(struct task_restore_args *args)
for (i = 0; i < args->nr_threads; i++) {
char last_pid_buf[16], *s;
-
/* skip self */
- if (thread_args[i].pid == args->t->pid)
+ if (thread_args[i].pid[0] == args->t->pid[0])
continue;
- new_sp = restorer_stack(thread_args[i].mz);
- last_pid_len = std_vprint_num(last_pid_buf, sizeof(last_pid_buf), thread_args[i].pid - 1, &s);
- sys_lseek(fd, 0, SEEK_SET);
- ret = sys_write(fd, s, last_pid_len);
- if (ret < 0) {
- pr_err("Can't set last_pid %ld/%s\n", ret, last_pid_buf);
- sys_close(fd);
- goto core_restore_end;
+ if (thread_args[i].pid[1] == 0) {
+ /* One level pid ns hierarhy */
+ last_pid_len = std_vprint_num(last_pid_buf, sizeof(last_pid_buf), thread_args[i].pid[0] - 1, &s);
+ sys_lseek(fd, 0, SEEK_SET);
+ ret = sys_write(fd, s, last_pid_len);
+ if (ret < 0) {
+ pr_err("Can't set last_pid %ld/%s\n", ret, last_pid_buf);
+ sys_close(fd);
+ goto core_restore_end;
+ }
+ } else {
+ for (k = 0; k < MAX_NS_NESTING; k++) {
+ if (thread_args[i].pid[k] == 0)
+ break;
+ if (request_set_next_pid(args->pid_ns_id[k], thread_args[i].pid[k], args->transport_fd) < 0) {
+ pr_err("Can't request to set pid\n");
+ sys_close(fd);
+ goto core_restore_end;
+ }
+ }
}
+ new_sp = restorer_stack(thread_args[i].mz);
/*
* To achieve functionality like libc's clone()
More information about the CRIU
mailing list