[CRIU] [PATCH] img: Move sigactions into core

Pavel Emelyanov xemul at virtuozzo.com
Wed Apr 19 06:51:01 PDT 2017


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: Pavel Emelyanov <xemul at virtuozzo.com>
---
 criu/cr-dump.c                  |  2 +-
 criu/cr-restore.c               | 57 +++++++++++++++++++++++++++++++++++++----
 criu/include/image-desc.h       |  2 +-
 criu/include/parasite-syscall.h |  2 +-
 criu/parasite-syscall.c         | 33 ++++++++++++++----------
 images/core.proto               |  3 ++-
 6 files changed, 77 insertions(+), 22 deletions(-)

diff --git a/criu/cr-dump.c b/criu/cr-dump.c
index 5f1f668..7115288 100644
--- a/criu/cr-dump.c
+++ b/criu/cr-dump.c
@@ -1335,7 +1335,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;
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 7842e16..3da4b84 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -424,6 +424,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)
 {
@@ -456,16 +490,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);
@@ -487,10 +518,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;
 }
 
@@ -1430,7 +1477,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)) {
diff --git a/criu/include/image-desc.h b/criu/include/image-desc.h
index 3fad408..fda5cac 100644
--- a/criu/include/image-desc.h
+++ b/criu/include/image-desc.h
@@ -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,
diff --git a/criu/include/parasite-syscall.h b/criu/include/parasite-syscall.h
index 0f923f3..72cd733 100644
--- a/criu/include/parasite-syscall.h
+++ b/criu/include/parasite-syscall.h
@@ -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;
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
index 30b0a5e..0e68aeb 100644
--- a/criu/parasite-syscall.c
+++ b/criu/parasite-syscall.c
@@ -227,12 +227,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);
 
@@ -240,7 +240,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;
@@ -248,16 +255,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;
diff --git a/images/core.proto b/images/core.proto
index 9c2254d..1f13d44 100644
--- a/images/core.proto
+++ b/images/core.proto
@@ -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 {
-- 
2.5.5


More information about the CRIU mailing list