[CRIU] [PATCH] Moved sigact dump/restore code into separate file.

prakriti goyal prakritigoyal19 at gmail.com
Wed Mar 18 05:19:59 MSK 2020


From: Prakriti <prakritigoyal19 at gmail.com>

I have merged all the patches into a single patch.

In this patch I have moved the sigact dump/restore code into a new file. I have created the file sigaction.c for the same. I removed the function parasite_dump_sigacts_seized() from parasite-syscall.c and prepare_sigactions() and everything it calls from cr-restore.c.

In parasite-syscall.h, I have removed the call for the function deleted in parasite-syscall.c, parasite_dump_sigacts_seized().

I have included the sigaction.h in cr-dump.c, as they call these functions.

I have added a line in Makefile.crtools to create an object file sigaction.o.

Signed-off-by: Prakriti <prakritigoyal19 at gmail.com>
---
 criu/Makefile.crtools           |   1 +
 criu/cr-dump.c                  |   1 +
 criu/cr-restore.c               | 262 +-------------------------
 criu/include/parasite-syscall.h |   1 -
 criu/include/parasite.h         |   3 +
 criu/include/sigaction.h        |  12 ++
 criu/parasite-syscall.c         |  45 +----
 criu/pie/parasite.c             |   1 +
 criu/sigaction.c                | 320 ++++++++++++++++++++++++++++++++
 9 files changed, 343 insertions(+), 303 deletions(-)
 create mode 100644 criu/include/sigaction.h
 create mode 100644 criu/sigaction.c

diff --git a/criu/Makefile.crtools b/criu/Makefile.crtools
index 7ba7137b..a32f86e3 100644
--- a/criu/Makefile.crtools
+++ b/criu/Makefile.crtools
@@ -60,6 +60,7 @@ obj-y			+= protobuf.o
 obj-y			+= pstree.o
 obj-y			+= rbtree.o
 obj-y			+= rst-malloc.o
+obj-y			+= sigaction.o
 obj-y			+= seccomp.o
 obj-y			+= seize.o
 obj-y			+= shmem.o
diff --git a/criu/cr-dump.c b/criu/cr-dump.c
index a8188724..d5efa9fa 100644
--- a/criu/cr-dump.c
+++ b/criu/cr-dump.c
@@ -14,6 +14,7 @@
 #include <sys/vfs.h>
 #include <sys/time.h>
 #include <sys/wait.h>
+#include "sigaction.h"
 
 
 #include <sched.h>
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index e5a82775..613dc1f8 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -68,6 +68,7 @@
 #include "timerfd.h"
 #include "action-scripts.h"
 #include "shmem.h"
+#include <compel/compel.h>
 #include "aio.h"
 #include "lsm.h"
 #include "seccomp.h"
@@ -78,11 +79,13 @@
 #include "memfd.h"
 #include "string.h"
 
+#include "include/parasite-syscall.h"
 #include "parasite-syscall.h"
 #include "files-reg.h"
 #include <compel/plugins/std/syscall-codes.h>
 #include "compel/include/asm/syscall.h"
 
+#include "sigaction.h"
 #include "protobuf.h"
 #include "images/sa.pb-c.h"
 #include "images/timer.pb-c.h"
@@ -415,265 +418,6 @@ static int populate_pid_proc(void)
 	return 0;
 }
 
-static rt_sigaction_t sigchld_act;
-/*
- * If parent's sigaction has blocked SIGKILL (which is non-sense),
- * this parent action is non-valid and shouldn't be inherited.
- * Used to mark parent_act* no more valid.
- */
-static rt_sigaction_t parent_act[SIGMAX];
-#ifdef CONFIG_COMPAT
-static rt_sigaction_t_compat parent_act_compat[SIGMAX];
-#endif
-
-static bool sa_inherited(int sig, rt_sigaction_t *sa)
-{
-	rt_sigaction_t *pa;
-	int i;
-
-	if (current == root_item)
-		return false; /* XXX -- inherit from CRIU? */
-
-	pa = &parent_act[sig];
-
-	/* Omitting non-valid sigaction */
-	if (pa->rt_sa_mask.sig[0] & (1 << SIGKILL))
-		return false;
-
-	for (i = 0; i < _KNSIG_WORDS; i++)
-		if (pa->rt_sa_mask.sig[i] != sa->rt_sa_mask.sig[i])
-			return false;
-
-	return pa->rt_sa_handler == sa->rt_sa_handler &&
-		pa->rt_sa_flags == sa->rt_sa_flags &&
-		pa->rt_sa_restorer == sa->rt_sa_restorer;
-}
-
-static int restore_native_sigaction(int sig, SaEntry *e)
-{
-	rt_sigaction_t act;
-	int ret;
-
-	ASSIGN_TYPED(act.rt_sa_handler, decode_pointer(e->sigaction));
-	ASSIGN_TYPED(act.rt_sa_flags, e->flags);
-	ASSIGN_TYPED(act.rt_sa_restorer, decode_pointer(e->restorer));
-	BUILD_BUG_ON(sizeof(e->mask) != sizeof(act.rt_sa_mask.sig));
-	memcpy(act.rt_sa_mask.sig, &e->mask, sizeof(act.rt_sa_mask.sig));
-
-	if (sig == SIGCHLD) {
-		sigchld_act = act;
-		return 0;
-	}
-
-	if (sa_inherited(sig - 1, &act))
-		return 1;
-
-	/*
-	 * A pure syscall is used, because glibc
-	 * sigaction overwrites se_restorer.
-	 */
-	ret = syscall(SYS_rt_sigaction, sig, &act, NULL, sizeof(k_rtsigset_t));
-	if (ret < 0) {
-		pr_perror("Can't restore sigaction");
-		return ret;
-	}
-
-	parent_act[sig - 1] = act;
-	/* Mark SIGKILL blocked which makes compat sigaction non-valid */
-#ifdef CONFIG_COMPAT
-	parent_act_compat[sig - 1].rt_sa_mask.sig[0] |= 1 << SIGKILL;
-#endif
-
-	return 1;
-}
-
-static void *stack32;
-
-#ifdef CONFIG_COMPAT
-static bool sa_compat_inherited(int sig, rt_sigaction_t_compat *sa)
-{
-	rt_sigaction_t_compat *pa;
-	int i;
-
-	if (current == root_item)
-		return false;
-
-	pa = &parent_act_compat[sig];
-
-	/* Omitting non-valid sigaction */
-	if (pa->rt_sa_mask.sig[0] & (1 << SIGKILL))
-		return false;
-
-	for (i = 0; i < _KNSIG_WORDS; i++)
-		if (pa->rt_sa_mask.sig[i] != sa->rt_sa_mask.sig[i])
-			return false;
-
-	return pa->rt_sa_handler == sa->rt_sa_handler &&
-		pa->rt_sa_flags == sa->rt_sa_flags &&
-		pa->rt_sa_restorer == sa->rt_sa_restorer;
-}
-
-static int restore_compat_sigaction(int sig, SaEntry *e)
-{
-	rt_sigaction_t_compat act;
-	int ret;
-
-	ASSIGN_TYPED(act.rt_sa_handler, (u32)e->sigaction);
-	ASSIGN_TYPED(act.rt_sa_flags, e->flags);
-	ASSIGN_TYPED(act.rt_sa_restorer, (u32)e->restorer);
-	BUILD_BUG_ON(sizeof(e->mask) != sizeof(act.rt_sa_mask.sig));
-	memcpy(act.rt_sa_mask.sig, &e->mask, sizeof(act.rt_sa_mask.sig));
-
-	if (sig == SIGCHLD) {
-		memcpy(&sigchld_act, &act, sizeof(rt_sigaction_t_compat));
-		return 0;
-	}
-
-	if (sa_compat_inherited(sig - 1, &act))
-		return 1;
-
-	if (!stack32) {
-		stack32 = alloc_compat_syscall_stack();
-		if (!stack32)
-			return -1;
-	}
-
-	ret = arch_compat_rt_sigaction(stack32, sig, &act);
-	if (ret < 0) {
-		pr_err("Can't restore compat sigaction: %d\n", ret);
-		return ret;
-	}
-
-	parent_act_compat[sig - 1] = act;
-	/* Mark SIGKILL blocked which makes native sigaction non-valid */
-	parent_act[sig - 1].rt_sa_mask.sig[0] |= 1 << SIGKILL;
-
-	return 1;
-}
-#else
-static int restore_compat_sigaction(int sig, SaEntry *e)
-{
-	return -1;
-}
-#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)
-{
-	bool sigaction_is_compat;
-	SaEntry *e;
-	int ret = 0;
-
-	BUG_ON(sig == SIGKILL || sig == SIGSTOP);
-
-	ret = pb_read_one_eof(img, &e, PB_SIGACT);
-	if (ret == 0) {
-		if (sig != SIGMAX_OLD + 1) { /* backward compatibility */
-			pr_err("Unexpected EOF %d\n", sig);
-			return -1;
-		}
-		pr_warn("This format of sigacts-%d.img is deprecated\n", pid);
-		return -1;
-	}
-	if (ret < 0)
-		return ret;
-
-	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);
-
-	sa_entry__free_unpacked(e, NULL);
-
-	return ret;
-}
-
-static int prepare_sigactions_from_image(void)
-{
-	int pid = vpid(current);
-	struct cr_img *img;
-	int sig, rst = 0;
-	int ret = 0;
-
-	pr_info("Restore sigacts for %d\n", pid);
-
-	img = open_image(CR_FD_SIGACT, O_RSTR, pid);
-	if (!img)
-		return -1;
-
-	for (sig = 1; sig <= SIGMAX; sig++) {
-		if (sig == SIGKILL || sig == SIGSTOP)
-			continue;
-
-		ret = restore_one_sigaction(sig, img, pid);
-		if (ret < 0)
-			break;
-		if (ret)
-			rst++;
-	}
-
-	pr_info("Restored %d/%d sigacts\n", rst,
-			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;
-}
-
 static int __collect_child_pids(struct pstree_item *p, int state, unsigned int *n)
 {
 	struct pstree_item *pi;
diff --git a/criu/include/parasite-syscall.h b/criu/include/parasite-syscall.h
index c86a724f..f3a7f0e6 100644
--- a/criu/include/parasite-syscall.h
+++ b/criu/include/parasite-syscall.h
@@ -23,7 +23,6 @@ struct rt_sigframe;
 struct parasite_ctl;
 struct parasite_thread_ctl;
 
-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/include/parasite.h b/criu/include/parasite.h
index d9570948..e1cc72f3 100644
--- a/criu/include/parasite.h
+++ b/criu/include/parasite.h
@@ -9,12 +9,15 @@
 #include <sys/time.h>
 #include <time.h>
 #include <signal.h>
+#include <compel/plugins/std/syscall-types.h>
 
 #include "image.h"
 #include "util-pie.h"
 #include "common/lock.h"
 #include "infect-rpc.h"
 
+#include <compel/asm/infect-types.h>
+#include "types.h"
 #include "images/vma.pb-c.h"
 #include "images/tty.pb-c.h"
 
diff --git a/criu/include/sigaction.h b/criu/include/sigaction.h
new file mode 100644
index 00000000..cc9611ff
--- /dev/null
+++ b/criu/include/sigaction.h
@@ -0,0 +1,12 @@
+#ifndef __CR_SIGACTION_H__
+#define __CR_SIGACTION_H__
+
+#include "parasite-syscall.h"
+#include "pstree.h"
+#include "images/core.pb-c.h"
+
+extern rt_sigaction_t sigchld_act;
+
+int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct pstree_item *item);
+int prepare_sigactions(CoreEntry *core);
+#endif
\ No newline at end of file
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
index b649d1b5..b49d8fdc 100644
--- a/criu/parasite-syscall.c
+++ b/criu/parasite-syscall.c
@@ -8,6 +8,7 @@
 #include "common/config.h"
 #include "common/compiler.h"
 #include "types.h"
+#include "sigaction.h"
 #include "protobuf.h"
 #include "images/sa.pb-c.h"
 #include "images/timer.pb-c.h"
@@ -16,6 +17,7 @@
 #include "images/pagemap.pb-c.h"
 
 #include "imgset.h"
+#include <compel/compel.h>
 #include "parasite-syscall.h"
 #include "parasite.h"
 #include "crtools.h"
@@ -208,49 +210,6 @@ err_rth:
 	return -1;
 }
 
-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;
-	SaEntry *sa, **psa;
-
-	args = compel_parasite_args(ctl, struct parasite_dump_sa_args);
-
-	ret = compel_rpc_call_sync(PARASITE_CMD_DUMP_SIGACTS, ctl);
-	if (ret < 0)
-		return ret;
-
-	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;
-
-		if (sig == SIGSTOP || sig == SIGKILL)
-			continue;
-
-		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);
-
-		*(psa++) = sa++;
-	}
-
-	return 0;
-}
-
 static void encode_itimer(struct itimerval *v, ItimerEntry *ie)
 {
 	ie->isec = v->it_interval.tv_sec;
diff --git a/criu/pie/parasite.c b/criu/pie/parasite.c
index 64b5bbb3..a21c8469 100644
--- a/criu/pie/parasite.c
+++ b/criu/pie/parasite.c
@@ -20,6 +20,7 @@
 #include "criu-log.h"
 #include "tty.h"
 #include "aio.h"
+#include <compel/plugins/std/syscall-types.h>
 
 #include "asm/parasite.h"
 #include "restorer.h"
diff --git a/criu/sigaction.c b/criu/sigaction.c
new file mode 100644
index 00000000..c0037f85
--- /dev/null
+++ b/criu/sigaction.c
@@ -0,0 +1,320 @@
+#include <unistd.h>
+#include <inttypes.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include "parasite.h"
+#include "parasite-syscall.h"
+#include "pstree.h"
+#include "sigframe.h"
+#include "image.h"
+#include "img-remote.h"
+#include "images/core.pb-c.h"
+#include "images/sa.pb-c.h"
+#include "infect.h"
+#include "protobuf.h"
+#include <compel/compel.h>
+#include "restore.h"
+#include "restorer.h"
+#include "sigaction.h"
+#include <compel/compel.h>
+#include "pie/pie-relocs.h"
+
+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;
+	SaEntry *sa, **psa;
+
+	args = compel_parasite_args(ctl, struct parasite_dump_sa_args);
+
+	ret = compel_rpc_call_sync(PARASITE_CMD_DUMP_SIGACTS, ctl);
+	if (ret < 0)
+		return ret;
+
+	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;
+
+		if (sig == SIGSTOP || sig == SIGKILL)
+			continue;
+
+		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);
+
+		*(psa++) = sa++;
+	}
+	return 0;
+}
+
+rt_sigaction_t sigchld_act;
+/*
+ * If parent's sigaction has blocked SIGKILL (which is non-sense),
+ * this parent action is non-valid and shouldn't be inherited.
+ * Used to mark parent_act* no more valid.
+ */
+static rt_sigaction_t parent_act[SIGMAX];
+#ifdef CONFIG_COMPAT
+static rt_sigaction_t_compat parent_act_compat[SIGMAX];
+#endif
+
+static bool sa_inherited(int sig, rt_sigaction_t *sa)
+{
+	rt_sigaction_t *pa;
+	int i;
+
+	if (current == root_item)
+		return false; /* XXX -- inherit from CRIU? */
+
+	pa = &parent_act[sig];
+
+	/* Omitting non-valid sigaction */
+	if (pa->rt_sa_mask.sig[0] & (1 << SIGKILL))
+		return false;
+
+	for (i = 0; i < _KNSIG_WORDS; i++)
+		if (pa->rt_sa_mask.sig[i] != sa->rt_sa_mask.sig[i])
+			return false;
+
+	return pa->rt_sa_handler == sa->rt_sa_handler &&
+		pa->rt_sa_flags == sa->rt_sa_flags &&
+		pa->rt_sa_restorer == sa->rt_sa_restorer;
+}
+
+static int restore_native_sigaction(int sig, SaEntry *e)
+{
+	rt_sigaction_t act;
+	int ret;
+
+	ASSIGN_TYPED(act.rt_sa_handler, decode_pointer(e->sigaction));
+	ASSIGN_TYPED(act.rt_sa_flags, e->flags);
+	ASSIGN_TYPED(act.rt_sa_restorer, decode_pointer(e->restorer));
+	BUILD_BUG_ON(sizeof(e->mask) != sizeof(act.rt_sa_mask.sig));
+	memcpy(act.rt_sa_mask.sig, &e->mask, sizeof(act.rt_sa_mask.sig));
+
+	if (sig == SIGCHLD) {
+		sigchld_act = act;
+		return 0;
+	}
+
+	if (sa_inherited(sig - 1, &act))
+		return 1;
+
+	/*
+	 * A pure syscall is used, because glibc
+	 * sigaction overwrites se_restorer.
+	 */
+	ret = syscall(SYS_rt_sigaction, sig, &act, NULL, sizeof(k_rtsigset_t));
+	if (ret < 0) {
+		pr_perror("Can't restore sigaction");
+		return ret;
+	}
+
+	parent_act[sig - 1] = act;
+	/* Mark SIGKILL blocked which makes compat sigaction non-valid */
+#ifdef CONFIG_COMPAT
+	parent_act_compat[sig - 1].rt_sa_mask.sig[0] |= 1 << SIGKILL;
+#endif
+
+	return 1;
+}
+
+static void *stack32;
+
+#ifdef CONFIG_COMPAT
+static bool sa_compat_inherited(int sig, rt_sigaction_t_compat *sa)
+{
+	rt_sigaction_t_compat *pa;
+	int i;
+
+	if (current == root_item)
+		return false;
+
+	pa = &parent_act_compat[sig];
+
+	/* Omitting non-valid sigaction */
+	if (pa->rt_sa_mask.sig[0] & (1 << SIGKILL))
+		return false;
+
+	for (i = 0; i < _KNSIG_WORDS; i++)
+		if (pa->rt_sa_mask.sig[i] != sa->rt_sa_mask.sig[i])
+			return false;
+
+	return pa->rt_sa_handler == sa->rt_sa_handler &&
+		pa->rt_sa_flags == sa->rt_sa_flags &&
+		pa->rt_sa_restorer == sa->rt_sa_restorer;
+}
+
+static int restore_compat_sigaction(int sig, SaEntry *e)
+{
+	rt_sigaction_t_compat act;
+	int ret;
+
+	ASSIGN_TYPED(act.rt_sa_handler, (u32)e->sigaction);
+	ASSIGN_TYPED(act.rt_sa_flags, e->flags);
+	ASSIGN_TYPED(act.rt_sa_restorer, (u32)e->restorer);
+	BUILD_BUG_ON(sizeof(e->mask) != sizeof(act.rt_sa_mask.sig));
+	memcpy(act.rt_sa_mask.sig, &e->mask, sizeof(act.rt_sa_mask.sig));
+
+	if (sig == SIGCHLD) {
+		memcpy(&sigchld_act, &act, sizeof(rt_sigaction_t_compat));
+		return 0;
+	}
+
+	if (sa_compat_inherited(sig - 1, &act))
+		return 1;
+
+	if (!stack32) {
+		stack32 = alloc_compat_syscall_stack();
+		if (!stack32)
+			return -1;
+	}
+
+	ret = arch_compat_rt_sigaction(stack32, sig, &act);
+	if (ret < 0) {
+		pr_err("Can't restore compat sigaction: %d\n", ret);
+		return ret;
+	}
+
+	parent_act_compat[sig - 1] = act;
+	/* Mark SIGKILL blocked which makes native sigaction non-valid */
+	parent_act[sig - 1].rt_sa_mask.sig[0] |= 1 << SIGKILL;
+
+	return 1;
+}
+#else
+static int restore_compat_sigaction(int sig, SaEntry *e)
+{
+	return -1;
+}
+#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;
+}
+static int restore_one_sigaction(int sig, struct cr_img *img, int pid)
+{
+	bool sigaction_is_compat;
+	SaEntry *e;
+	int ret = 0;
+
+	BUG_ON(sig == SIGKILL || sig == SIGSTOP);
+
+	ret = pb_read_one_eof(img, &e, PB_SIGACT);
+	if (ret == 0) {
+		if (sig != SIGMAX_OLD + 1) { /* backward compatibility */
+			pr_err("Unexpected EOF %d\n", sig);
+			return -1;
+		}
+		pr_warn("This format of sigacts-%d.img is deprecated\n", pid);
+		return -1;
+	}
+	if (ret < 0)
+		return ret;
+
+	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);
+
+	sa_entry__free_unpacked(e, NULL);
+
+	return ret;
+}
+
+static int prepare_sigactions_from_image(void)
+{
+	int pid = vpid(current);
+	struct cr_img *img;
+	int sig, rst = 0;
+	int ret = 0;
+
+	pr_info("Restore sigacts for %d\n", pid);
+
+	img = open_image(CR_FD_SIGACT, O_RSTR, pid);
+	if (!img)
+		return -1;
+
+	for (sig = 1; sig <= SIGMAX; sig++) {
+		if (sig == SIGKILL || sig == SIGSTOP)
+			continue;
+
+		ret = restore_one_sigaction(sig, img, pid);
+		if (ret < 0)
+			break;
+		if (ret)
+			rst++;
+	}
+
+	pr_info("Restored %d/%d sigacts\n", rst,
+			SIGMAX - 3 /* KILL, STOP and CHLD */);
+
+	close_image(img);
+	return ret;
+}
+
+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;
+}
\ No newline at end of file
-- 
2.17.1



More information about the CRIU mailing list