Commit fa1fbe08 authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Andrei Vagin

img: Move sigactions into core

Right now they all sit in a separate file. Since we
don't support CLONE_SIGHAND (and don't plan to) it's
much better to have them in core, all the more so
by the time we dump/restore sigacts, the core entry
is at hands already.
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent acda66c2
......@@ -1332,7 +1332,7 @@ static int dump_one_task(struct pstree_item *item)
if (ret)
goto err_cure;
ret = parasite_dump_sigacts_seized(parasite_ctl, cr_imgset);
ret = parasite_dump_sigacts_seized(parasite_ctl, item);
if (ret) {
pr_err("Can't dump sigactions (pid: %d) with parasite\n", pid);
goto err_cure;
......
......@@ -421,6 +421,40 @@ static int restore_compat_sigaction(int sig, SaEntry *e)
}
#endif
static int prepare_sigactions_from_core(TaskCoreEntry *tc)
{
int sig, i;
if (tc->n_sigactions != SIGMAX - 2) {
pr_err("Bad number of sigactions in the image (%d, want %d)\n",
(int)tc->n_sigactions, SIGMAX - 2);
return -1;
}
pr_info("Restore on-core sigactions for %d\n", vpid(current));
for (sig = 1, i = 0; sig <= SIGMAX; sig++) {
int ret;
SaEntry *e;
bool sigaction_is_compat;
if (sig == SIGKILL || sig == SIGSTOP)
continue;
e = tc->sigactions[i++];
sigaction_is_compat = e->has_compat_sigaction && e->compat_sigaction;
if (sigaction_is_compat)
ret = restore_compat_sigaction(sig, e);
else
ret = restore_native_sigaction(sig, e);
if (ret < 0)
return ret;
}
return 0;
}
/* Returns number of restored signals, -1 or negative errno on fail */
static int restore_one_sigaction(int sig, struct cr_img *img, int pid)
{
......@@ -453,16 +487,13 @@ static int restore_one_sigaction(int sig, struct cr_img *img, int pid)
return ret;
}
static int prepare_sigactions(void)
static int prepare_sigactions_from_image(void)
{
int pid = vpid(current);
struct cr_img *img;
int sig, rst = 0;
int ret = 0;
if (!task_alive(current))
return 0;
pr_info("Restore sigacts for %d\n", pid);
img = open_image(CR_FD_SIGACT, O_RSTR, pid);
......@@ -484,10 +515,26 @@ static int prepare_sigactions(void)
SIGMAX - 3 /* KILL, STOP and CHLD */);
close_image(img);
return ret;
}
static int prepare_sigactions(CoreEntry *core)
{
int ret;
if (!task_alive(current))
return 0;
if (core->tc->n_sigactions != 0)
ret = prepare_sigactions_from_core(core->tc);
else
ret = prepare_sigactions_from_image();
if (stack32) {
free_compat_syscall_stack(stack32);
stack32 = NULL;
}
return ret;
}
......@@ -1442,7 +1489,7 @@ static int restore_task_with_children(void *_arg)
if (prepare_mappings(current))
goto err;
if (prepare_sigactions() < 0)
if (prepare_sigactions(ca->core) < 0)
goto err;
if (fault_injected(FI_RESTORE_ROOT_ONLY)) {
......
......@@ -14,7 +14,6 @@ enum {
CR_FD_CORE,
CR_FD_IDS,
CR_FD_MM,
CR_FD_SIGACT,
CR_FD_CREDS,
CR_FD_FS,
_CR_FD_TASK_TO,
......@@ -89,6 +88,7 @@ enum {
CR_FD_BINFMT_MISC_OLD,
CR_FD_PAGES,
CR_FD_SIGACT,
CR_FD_VMAS,
CR_FD_PAGES_OLD,
CR_FD_SHM_PAGES_OLD,
......
......@@ -22,7 +22,7 @@ struct rt_sigframe;
struct parasite_ctl;
extern int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_imgset *cr_imgset);
extern int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct pstree_item *);
extern int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct pstree_item *);
struct proc_posix_timers_stat;
......
......@@ -215,12 +215,12 @@ err_rth:
return -1;
}
int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_imgset *cr_imgset)
int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct pstree_item *item)
{
TaskCoreEntry *tc = item->core[0]->tc;
struct parasite_dump_sa_args *args;
int ret, sig;
struct cr_img *img;
SaEntry se = SA_ENTRY__INIT;
SaEntry *sa, **psa;
args = compel_parasite_args(ctl, struct parasite_dump_sa_args);
......@@ -228,7 +228,14 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_imgset *cr_
if (ret < 0)
return ret;
img = img_from_set(cr_imgset, CR_FD_SIGACT);
psa = xmalloc((SIGMAX - 2) * (sizeof(SaEntry *) + sizeof(SaEntry)));
if (!psa)
return -1;
sa = (SaEntry *)(psa + SIGMAX - 2);
tc->n_sigactions = SIGMAX - 2;
tc->sigactions = psa;
for (sig = 1; sig <= SIGMAX; sig++) {
int i = sig - 1;
......@@ -236,16 +243,16 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_imgset *cr_
if (sig == SIGSTOP || sig == SIGKILL)
continue;
ASSIGN_TYPED(se.sigaction, encode_pointer(args->sas[i].rt_sa_handler));
ASSIGN_TYPED(se.flags, args->sas[i].rt_sa_flags);
ASSIGN_TYPED(se.restorer, encode_pointer(args->sas[i].rt_sa_restorer));
BUILD_BUG_ON(sizeof(se.mask) != sizeof(args->sas[0].rt_sa_mask.sig));
memcpy(&se.mask, args->sas[i].rt_sa_mask.sig, sizeof(se.mask));
se.has_compat_sigaction = true;
se.compat_sigaction = !compel_mode_native(ctl);
sa_entry__init(sa);
ASSIGN_TYPED(sa->sigaction, encode_pointer(args->sas[i].rt_sa_handler));
ASSIGN_TYPED(sa->flags, args->sas[i].rt_sa_flags);
ASSIGN_TYPED(sa->restorer, encode_pointer(args->sas[i].rt_sa_restorer));
BUILD_BUG_ON(sizeof(sa->mask) != sizeof(args->sas[0].rt_sa_mask.sig));
memcpy(&sa->mask, args->sas[i].rt_sa_mask.sig, sizeof(sa->mask));
sa->has_compat_sigaction = true;
sa->compat_sigaction = !compel_mode_native(ctl);
if (pb_write_one(img, &se, PB_SIGACT) < 0)
return -1;
*(psa++) = sa++;
}
return 0;
......
......@@ -8,7 +8,7 @@ import "core-ppc64.proto";
import "rlimit.proto";
import "timer.proto";
import "creds.proto";
import "sa.proto";
import "siginfo.proto";
import "opts.proto";
......@@ -45,6 +45,7 @@ message task_core_entry {
optional uint32 loginuid = 13;
optional int32 oom_score_adj = 14;
repeated sa_entry sigactions = 15;
}
message task_kobj_ids_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