mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-01 06:45:35 +00:00
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: Pavel Emelyanov <xemul@parallels.com> Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
This commit is contained in:
@@ -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)
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
|
|
||||||
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;
|
|||||||
#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)
|
|||||||
|
|
||||||
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 @@
|
|||||||
|
|
||||||
#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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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 {
|
|||||||
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 {
|
||||||
|
Reference in New Issue
Block a user