Commit 8d0e2965 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

dump: Reseve space and construc sigframes for parasites

We're about to implement functionality to allow parasite to
return to dumpee via sigreturn in case crtools suddenly detached
from it. Thus, we need a space for sigframe in shared area.
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 75a3932b
...@@ -16,6 +16,8 @@ struct parasite_thread_ctl ...@@ -16,6 +16,8 @@ struct parasite_thread_ctl
bool use_sig_blocked; bool use_sig_blocked;
void *rstack; void *rstack;
struct rt_sigframe *sigframe;
struct rt_sigframe *rsigframe; /* address in a parasite */
}; };
/* parasite control block */ /* parasite control block */
......
...@@ -75,6 +75,8 @@ struct parasite_init_args { ...@@ -75,6 +75,8 @@ struct parasite_init_args {
int nr_threads; int nr_threads;
k_rtsigset_t sig_blocked; k_rtsigset_t sig_blocked;
struct rt_sigframe *sigframe;
}; };
struct parasite_log_args { struct parasite_log_args {
......
...@@ -25,14 +25,16 @@ ...@@ -25,14 +25,16 @@
#include "net.h" #include "net.h"
#include "mem.h" #include "mem.h"
#include "vdso.h" #include "vdso.h"
#include "restorer.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "asm/parasite-syscall.h" #include "asm/parasite-syscall.h"
#include "asm/dump.h" #include "asm/dump.h"
#include "asm/restorer.h"
#define parasite_size (round_up(sizeof(parasite_blob), sizeof(long))) #define parasite_size (round_up(sizeof(parasite_blob), PAGE_SIZE))
static int can_run_syscall(unsigned long ip, unsigned long start, unsigned long end) static int can_run_syscall(unsigned long ip, unsigned long start, unsigned long end)
{ {
...@@ -387,6 +389,7 @@ static int parasite_init(struct parasite_ctl *ctl, pid_t pid, int nr_threads) ...@@ -387,6 +389,7 @@ static int parasite_init(struct parasite_ctl *ctl, pid_t pid, int nr_threads)
args->h_addr_len = gen_parasite_saddr(&args->h_addr, getpid()); args->h_addr_len = gen_parasite_saddr(&args->h_addr, getpid());
args->p_addr_len = gen_parasite_saddr(&args->p_addr, pid); args->p_addr_len = gen_parasite_saddr(&args->p_addr, pid);
args->nr_threads = nr_threads; args->nr_threads = nr_threads;
args->sigframe = ctl->threads[0].rsigframe;
args->id = 0; args->id = 0;
if (sock == -1) { if (sock == -1) {
...@@ -1068,7 +1071,7 @@ static unsigned long parasite_args_size(struct vm_area_list *vmas, struct parasi ...@@ -1068,7 +1071,7 @@ static unsigned long parasite_args_size(struct vm_area_list *vmas, struct parasi
size = max(size, (unsigned long)drain_fds_size(dfds)); size = max(size, (unsigned long)drain_fds_size(dfds));
size = max(size, (unsigned long)dump_pages_args_size(vmas)); size = max(size, (unsigned long)dump_pages_args_size(vmas));
return size; return round_up(size, PAGE_SIZE);
} }
struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
...@@ -1096,6 +1099,7 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, ...@@ -1096,6 +1099,7 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
ctl->args_size = parasite_args_size(vma_area_list, dfds); ctl->args_size = parasite_args_size(vma_area_list, dfds);
ret = parasite_map_exchange(ctl, parasite_size + ctl->args_size + ret = parasite_map_exchange(ctl, parasite_size + ctl->args_size +
item->nr_threads * RESTORE_STACK_SIGFRAME +
item->nr_threads * PARASITE_STACK_SIZE); item->nr_threads * PARASITE_STACK_SIZE);
if (ret) if (ret)
goto err_restore; goto err_restore;
...@@ -1113,7 +1117,10 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, ...@@ -1113,7 +1117,10 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
struct parasite_thread_ctl *thread = &ctl->threads[i]; struct parasite_thread_ctl *thread = &ctl->threads[i];
thread->rstack = ctl->remote_map + p; thread->rstack = ctl->remote_map + p;
p += PARASITE_STACK_SIZE; thread->rsigframe = ctl->remote_map + p + PARASITE_STACK_SIZE;
thread->sigframe = ctl->local_map + p + PARASITE_STACK_SIZE;
p += PARASITE_STACK_SIZE + RESTORE_STACK_SIGFRAME;
} }
ret = parasite_init(ctl, pid, item->nr_threads); ret = parasite_init(ctl, pid, item->nr_threads);
...@@ -1152,6 +1159,9 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, ...@@ -1152,6 +1159,9 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
&thread->sig_blocked, sizeof(k_rtsigset_t)); &thread->sig_blocked, sizeof(k_rtsigset_t));
item->core[i]->thread_core->has_blk_sigset = true; item->core[i]->thread_core->has_blk_sigset = true;
} }
if (construct_sigframe(thread->sigframe, thread->rsigframe, item->core[i]))
goto err_restore;
} }
return ctl; return ctl;
......
...@@ -26,6 +26,8 @@ static struct tid_state_s { ...@@ -26,6 +26,8 @@ static struct tid_state_s {
bool use_sig_blocked; bool use_sig_blocked;
k_rtsigset_t sig_blocked; k_rtsigset_t sig_blocked;
struct rt_sigframe *sigframe;
} *tid_state; } *tid_state;
static unsigned int nr_tid_state; static unsigned int nr_tid_state;
...@@ -213,6 +215,7 @@ static int init_thread(struct parasite_init_args *args) ...@@ -213,6 +215,7 @@ static int init_thread(struct parasite_init_args *args)
args->sig_blocked = tid_state[next_tid_state].sig_blocked; args->sig_blocked = tid_state[next_tid_state].sig_blocked;
tid_state[next_tid_state].id = next_tid_state; tid_state[next_tid_state].id = next_tid_state;
tid_state[next_tid_state].sigframe = args->sigframe;
futex_set(&tid_state[next_tid_state].cmd, PARASITE_CMD_IDLE); futex_set(&tid_state[next_tid_state].cmd, PARASITE_CMD_IDLE);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment