mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 06:15:24 +00:00
ns: Restore pid_for_children ns in threads
Threads may have different pid_for_children ns. Allow them to set it after they are created: just get a pid_ns fd from fdstore, and setns() to it, after thread creation. Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
committed by
Andrei Vagin
parent
f39a52923d
commit
ecb7e5801a
@@ -3109,6 +3109,25 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_thread_pid_ns_fd(uint32_t pid_ns_id)
|
||||
{
|
||||
struct ns_id *ns;
|
||||
int fd;
|
||||
|
||||
if (current->pid_for_children_ns->id == pid_ns_id)
|
||||
return -2;
|
||||
|
||||
ns = lookup_ns_by_id(pid_ns_id, &pid_ns_desc);
|
||||
BUG_ON(!ns);
|
||||
|
||||
fd = fdstore_get(ns->pid.nsfd_id);
|
||||
if (fd < 0) {
|
||||
pr_err("Can't get pid_ns fd\n");
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
extern void __gcov_flush(void) __attribute__((weak));
|
||||
void __gcov_flush(void) {}
|
||||
|
||||
@@ -3583,12 +3602,17 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
|
||||
task_args->t = thread_args + i;
|
||||
tcore = core;
|
||||
blkset = (void *)&tcore->tc->blk_sigset;
|
||||
thread_args[i].pfc_ns_fd = get_thread_pid_ns_fd(current->ids->pid_for_children_ns_id);
|
||||
} else {
|
||||
tcore = current->core[i];
|
||||
if (tcore->thread_core->has_blk_sigset)
|
||||
blkset = (void *)&tcore->thread_core->blk_sigset;
|
||||
thread_args[i].pfc_ns_fd = get_thread_pid_ns_fd(tcore->ids->pid_for_children_ns_id);
|
||||
}
|
||||
|
||||
if (thread_args[i].pfc_ns_fd == -1)
|
||||
goto err;
|
||||
|
||||
if ((tcore->tc) && thread_args[i].pid[0] != pid) {
|
||||
pr_err("Thread has optional fields present %d\n",
|
||||
thread_args[i].pid[0]);
|
||||
|
@@ -96,6 +96,7 @@ struct thread_restore_args {
|
||||
unsigned int siginfo_n;
|
||||
|
||||
int pdeath_sig;
|
||||
int pfc_ns_fd;
|
||||
|
||||
struct thread_creds_args *creds_args;
|
||||
} __aligned(64);
|
||||
|
@@ -506,7 +506,7 @@ long __export_restore_thread(struct thread_restore_args *args)
|
||||
k_rtsigset_t to_block;
|
||||
unsigned long new_sp;
|
||||
int my_pid = sys_gettid();
|
||||
int i, ret;
|
||||
int i, fd, ret;
|
||||
|
||||
for (i = 0; i < MAX_NS_NESTING; i++)
|
||||
if (args->pid[i] == 0)
|
||||
@@ -530,6 +530,16 @@ long __export_restore_thread(struct thread_restore_args *args)
|
||||
if (restore_thread_common(args))
|
||||
goto core_restore_end;
|
||||
|
||||
fd = args->pfc_ns_fd;
|
||||
if (fd >= 0) {
|
||||
ret = sys_setns(fd, CLONE_NEWPID);
|
||||
if (ret) {
|
||||
pr_err("Can't setns: ret=%d\n", ret);
|
||||
goto core_restore_end;
|
||||
}
|
||||
sys_close(fd);
|
||||
}
|
||||
|
||||
ret = restore_creds(args->creds_args, args->ta->proc_fd);
|
||||
if (ret)
|
||||
goto core_restore_end;
|
||||
@@ -1190,7 +1200,7 @@ static bool vdso_needs_parking(struct task_restore_args *args)
|
||||
long __export_restore_task(struct task_restore_args *args)
|
||||
{
|
||||
long ret = -1;
|
||||
int i, k;
|
||||
int i, k, fd, self_thread;
|
||||
VmaEntry *vma_entry;
|
||||
unsigned long va;
|
||||
struct restore_vma_io *rio;
|
||||
@@ -1526,15 +1536,16 @@ long __export_restore_task(struct task_restore_args *args)
|
||||
* | thread restore proc | thread1 stack | thread1 rt_sigframe |
|
||||
* +--------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
self_thread = 0;
|
||||
if (args->nr_threads > 1) {
|
||||
struct thread_restore_args *thread_args = args->thread_args;
|
||||
long clone_flags = CLONE_VM | CLONE_FILES | CLONE_SIGHAND |
|
||||
CLONE_THREAD | CLONE_SYSVSEM | CLONE_FS;
|
||||
long last_pid_len;
|
||||
long parent_tid;
|
||||
int i, fd = -1;
|
||||
int i;
|
||||
|
||||
fd = -1;
|
||||
if (thread_args[0].pid[1] == 0) {
|
||||
/* One level pid ns hierarhy */
|
||||
fd = sys_openat(args->proc_fd, LAST_PID_PATH, O_RDWR, 0);
|
||||
@@ -1549,8 +1560,10 @@ 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[0] == args->t->pid[0])
|
||||
if (thread_args[i].pid[0] == args->t->pid[0]) {
|
||||
self_thread = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fd >= 0) {
|
||||
/* One level pid ns hierarhy */
|
||||
@@ -1648,6 +1661,16 @@ long __export_restore_task(struct task_restore_args *args)
|
||||
|
||||
rst_tcp_socks_all(args);
|
||||
|
||||
fd = args->thread_args[self_thread].pfc_ns_fd;
|
||||
if (fd >= 0) {
|
||||
ret = sys_setns(fd, CLONE_NEWPID);
|
||||
if (ret) {
|
||||
pr_err("Can't setns: ret=%d\n", (int)ret);
|
||||
goto core_restore_end;
|
||||
}
|
||||
sys_close(fd);
|
||||
}
|
||||
|
||||
/* The kernel restricts setting seccomp to uid 0 in the current user
|
||||
* ns, so we must do this before restore_creds.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user