Commit 5e9c57a1 authored by Pavel Emelyanov's avatar Pavel Emelyanov

criu: Dump and restore pdeath_sig value

The implementation is pretty straightforward. When dumping per-thread
misc data with parasite, collect one, then write in thread_core_info.

On restore wait for creds restore and put the value back (some creds
changes drop it to zero).
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Acked-by: 's avatarSerge E. Hallyn <serge.hallyn@ubuntu.com>
parent 8e11c8ec
...@@ -689,6 +689,10 @@ int dump_thread_core(int pid, CoreEntry *core, const struct parasite_dump_thread ...@@ -689,6 +689,10 @@ int dump_thread_core(int pid, CoreEntry *core, const struct parasite_dump_thread
CORE_THREAD_ARCH_INFO(core)->clear_tid_addr = encode_pointer(ti->tid_addr); CORE_THREAD_ARCH_INFO(core)->clear_tid_addr = encode_pointer(ti->tid_addr);
BUG_ON(!tc->sas); BUG_ON(!tc->sas);
copy_sas(tc->sas, &ti->sas); copy_sas(tc->sas, &ti->sas);
if (ti->pdeath_sig) {
tc->has_pdeath_sig = true;
tc->pdeath_sig = ti->pdeath_sig;
}
} }
return ret; return ret;
......
...@@ -2557,6 +2557,11 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ...@@ -2557,6 +2557,11 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
thread_args[i].has_futex = true; thread_args[i].has_futex = true;
thread_args[i].futex_rla = tcore->thread_core->futex_rla; thread_args[i].futex_rla = tcore->thread_core->futex_rla;
thread_args[i].futex_rla_len = tcore->thread_core->futex_rla_len; thread_args[i].futex_rla_len = tcore->thread_core->futex_rla_len;
thread_args[i].pdeath_sig = tcore->thread_core->pdeath_sig;
if (tcore->thread_core->pdeath_sig > _KNSIG) {
pr_err("Pdeath signal is too big\n");
goto err;
}
ret = prep_sched_info(&thread_args[i].sp, tcore->thread_core); ret = prep_sched_info(&thread_args[i].sp, tcore->thread_core);
if (ret) if (ret)
......
...@@ -141,6 +141,7 @@ struct parasite_dump_thread { ...@@ -141,6 +141,7 @@ struct parasite_dump_thread {
pid_t tid; pid_t tid;
tls_t tls; tls_t tls;
stack_t sas; stack_t sas;
int pdeath_sig;
}; };
/* /*
......
...@@ -90,6 +90,7 @@ struct thread_restore_args { ...@@ -90,6 +90,7 @@ struct thread_restore_args {
siginfo_t *siginfo; siginfo_t *siginfo;
unsigned int siginfo_nr; unsigned int siginfo_nr;
int pdeath_sig;
} __aligned(64); } __aligned(64);
struct task_restore_args { struct task_restore_args {
......
...@@ -35,6 +35,10 @@ static struct parasite_dump_pages_args *mprotect_args = NULL; ...@@ -35,6 +35,10 @@ static struct parasite_dump_pages_args *mprotect_args = NULL;
#define SPLICE_F_GIFT 0x08 #define SPLICE_F_GIFT 0x08
#endif #endif
#ifndef PR_GET_PDEATHSIG
#define PR_GET_PDEATHSIG 2
#endif
static int mprotect_vmas(struct parasite_dump_pages_args *args) static int mprotect_vmas(struct parasite_dump_pages_args *args)
{ {
struct parasite_vma_entry *vmas, *vma; struct parasite_vma_entry *vmas, *vma;
...@@ -145,9 +149,15 @@ static int dump_thread_common(struct parasite_dump_thread *ti) ...@@ -145,9 +149,15 @@ static int dump_thread_common(struct parasite_dump_thread *ti)
arch_get_tls(&ti->tls); arch_get_tls(&ti->tls);
ret = sys_prctl(PR_GET_TID_ADDRESS, (unsigned long) &ti->tid_addr, 0, 0, 0); ret = sys_prctl(PR_GET_TID_ADDRESS, (unsigned long) &ti->tid_addr, 0, 0, 0);
if (ret == 0) if (ret)
ret = sys_sigaltstack(NULL, &ti->sas); goto out;
ret = sys_sigaltstack(NULL, &ti->sas);
if (ret)
goto out;
ret = sys_prctl(PR_GET_PDEATHSIG, (unsigned long)&ti->pdeath_sig, 0, 0, 0);
out:
return ret; return ret;
} }
......
...@@ -35,6 +35,10 @@ ...@@ -35,6 +35,10 @@
#include "asm/restorer.h" #include "asm/restorer.h"
#ifndef PR_SET_PDEATHSIG
#define PR_SET_PDEATHSIG 1
#endif
#define sys_prctl_safe(opcode, val1, val2, val3) \ #define sys_prctl_safe(opcode, val1, val2, val3) \
({ \ ({ \
long __ret = sys_prctl(opcode, val1, val2, val3, 0); \ long __ret = sys_prctl(opcode, val1, val2, val3, 0); \
...@@ -189,6 +193,20 @@ static int restore_creds(CredsEntry *ce) ...@@ -189,6 +193,20 @@ static int restore_creds(CredsEntry *ce)
return 0; return 0;
} }
/*
* This should be done after creds restore, as
* some creds changes might drop the value back
* to zero.
*/
static inline int restore_pdeath_sig(struct thread_restore_args *ta)
{
if (ta->pdeath_sig)
return sys_prctl(PR_SET_PDEATHSIG, ta->pdeath_sig, 0, 0, 0);
else
return 0;
}
static int restore_dumpable_flag(MmEntry *mme) static int restore_dumpable_flag(MmEntry *mme)
{ {
int current_dumpable; int current_dumpable;
...@@ -349,6 +367,7 @@ long __export_restore_thread(struct thread_restore_args *args) ...@@ -349,6 +367,7 @@ long __export_restore_thread(struct thread_restore_args *args)
goto core_restore_end; goto core_restore_end;
restore_finish_stage(CR_STATE_RESTORE_SIGCHLD); restore_finish_stage(CR_STATE_RESTORE_SIGCHLD);
restore_pdeath_sig(args);
restore_finish_stage(CR_STATE_RESTORE_CREDS); restore_finish_stage(CR_STATE_RESTORE_CREDS);
futex_dec_and_wake(&thread_inprogress); futex_dec_and_wake(&thread_inprogress);
...@@ -1004,6 +1023,7 @@ long __export_restore_task(struct task_restore_args *args) ...@@ -1004,6 +1023,7 @@ long __export_restore_task(struct task_restore_args *args)
ret = restore_creds(&args->creds); ret = restore_creds(&args->creds);
ret = ret || restore_dumpable_flag(&args->mm); ret = ret || restore_dumpable_flag(&args->mm);
ret = ret || restore_pdeath_sig(args->t);
futex_set_and_wake(&thread_inprogress, args->nr_threads); futex_set_and_wake(&thread_inprogress, args->nr_threads);
......
...@@ -48,6 +48,7 @@ message thread_core_entry { ...@@ -48,6 +48,7 @@ message thread_core_entry {
optional uint32 sched_prio = 5; optional uint32 sched_prio = 5;
optional uint64 blk_sigset = 6; optional uint64 blk_sigset = 6;
optional thread_sas_entry sas = 7; optional thread_sas_entry sas = 7;
optional uint32 pdeath_sig = 8;
} }
message task_rlimits_entry { message task_rlimits_entry {
......
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