mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-01 14:55:39 +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;
|
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));
|
extern void __gcov_flush(void) __attribute__((weak));
|
||||||
void __gcov_flush(void) {}
|
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;
|
task_args->t = thread_args + i;
|
||||||
tcore = core;
|
tcore = core;
|
||||||
blkset = (void *)&tcore->tc->blk_sigset;
|
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 {
|
} else {
|
||||||
tcore = current->core[i];
|
tcore = current->core[i];
|
||||||
if (tcore->thread_core->has_blk_sigset)
|
if (tcore->thread_core->has_blk_sigset)
|
||||||
blkset = (void *)&tcore->thread_core->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) {
|
if ((tcore->tc) && thread_args[i].pid[0] != pid) {
|
||||||
pr_err("Thread has optional fields present %d\n",
|
pr_err("Thread has optional fields present %d\n",
|
||||||
thread_args[i].pid[0]);
|
thread_args[i].pid[0]);
|
||||||
|
@@ -96,6 +96,7 @@ struct thread_restore_args {
|
|||||||
unsigned int siginfo_n;
|
unsigned int siginfo_n;
|
||||||
|
|
||||||
int pdeath_sig;
|
int pdeath_sig;
|
||||||
|
int pfc_ns_fd;
|
||||||
|
|
||||||
struct thread_creds_args *creds_args;
|
struct thread_creds_args *creds_args;
|
||||||
} __aligned(64);
|
} __aligned(64);
|
||||||
|
@@ -506,7 +506,7 @@ long __export_restore_thread(struct thread_restore_args *args)
|
|||||||
k_rtsigset_t to_block;
|
k_rtsigset_t to_block;
|
||||||
unsigned long new_sp;
|
unsigned long new_sp;
|
||||||
int my_pid = sys_gettid();
|
int my_pid = sys_gettid();
|
||||||
int i, ret;
|
int i, fd, ret;
|
||||||
|
|
||||||
for (i = 0; i < MAX_NS_NESTING; i++)
|
for (i = 0; i < MAX_NS_NESTING; i++)
|
||||||
if (args->pid[i] == 0)
|
if (args->pid[i] == 0)
|
||||||
@@ -530,6 +530,16 @@ long __export_restore_thread(struct thread_restore_args *args)
|
|||||||
if (restore_thread_common(args))
|
if (restore_thread_common(args))
|
||||||
goto core_restore_end;
|
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);
|
ret = restore_creds(args->creds_args, args->ta->proc_fd);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto core_restore_end;
|
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 __export_restore_task(struct task_restore_args *args)
|
||||||
{
|
{
|
||||||
long ret = -1;
|
long ret = -1;
|
||||||
int i, k;
|
int i, k, fd, self_thread;
|
||||||
VmaEntry *vma_entry;
|
VmaEntry *vma_entry;
|
||||||
unsigned long va;
|
unsigned long va;
|
||||||
struct restore_vma_io *rio;
|
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 |
|
* | thread restore proc | thread1 stack | thread1 rt_sigframe |
|
||||||
* +--------------------------------------------------------------------------+
|
* +--------------------------------------------------------------------------+
|
||||||
*/
|
*/
|
||||||
|
self_thread = 0;
|
||||||
if (args->nr_threads > 1) {
|
if (args->nr_threads > 1) {
|
||||||
struct thread_restore_args *thread_args = args->thread_args;
|
struct thread_restore_args *thread_args = args->thread_args;
|
||||||
long clone_flags = CLONE_VM | CLONE_FILES | CLONE_SIGHAND |
|
long clone_flags = CLONE_VM | CLONE_FILES | CLONE_SIGHAND |
|
||||||
CLONE_THREAD | CLONE_SYSVSEM | CLONE_FS;
|
CLONE_THREAD | CLONE_SYSVSEM | CLONE_FS;
|
||||||
long last_pid_len;
|
long last_pid_len;
|
||||||
long parent_tid;
|
long parent_tid;
|
||||||
int i, fd = -1;
|
int i;
|
||||||
|
|
||||||
|
fd = -1;
|
||||||
if (thread_args[0].pid[1] == 0) {
|
if (thread_args[0].pid[1] == 0) {
|
||||||
/* One level pid ns hierarhy */
|
/* One level pid ns hierarhy */
|
||||||
fd = sys_openat(args->proc_fd, LAST_PID_PATH, O_RDWR, 0);
|
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++) {
|
for (i = 0; i < args->nr_threads; i++) {
|
||||||
char last_pid_buf[16], *s;
|
char last_pid_buf[16], *s;
|
||||||
/* skip self */
|
/* 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;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
/* One level pid ns hierarhy */
|
/* One level pid ns hierarhy */
|
||||||
@@ -1648,6 +1661,16 @@ long __export_restore_task(struct task_restore_args *args)
|
|||||||
|
|
||||||
rst_tcp_socks_all(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
|
/* The kernel restricts setting seccomp to uid 0 in the current user
|
||||||
* ns, so we must do this before restore_creds.
|
* ns, so we must do this before restore_creds.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user