[CRIU] [PATCH 5/7] restore: restore signals from core->thread_core->signals, if available

Ruslan Kuprieiev kupruser at gmail.com
Wed Aug 13 19:33:43 PDT 2014


In order to save backward compatibility, criu will try to open signal*.img,
if no core->thread_core->signals is found.

Signed-off-by: Ruslan Kuprieiev <kupruser at gmail.com>
---
 cr-restore.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 58 insertions(+), 16 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index a39ec69..da3fb4c 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -91,7 +91,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core);
 static int prepare_restorer_blob(void);
 static int prepare_rlimits(int pid, CoreEntry *core);
 static int prepare_posix_timers(int pid, CoreEntry *core);
-static int prepare_signals(int pid);
+static int prepare_signals(int pid, CoreEntry *core);
 
 static int shmem_remap(void *old_addr, void *new_addr, unsigned long size)
 {
@@ -793,7 +793,7 @@ static int restore_one_alive_task(int pid, CoreEntry *core)
 	if (open_cores(pid, core))
 		return -1;
 
-	if (prepare_signals(pid))
+	if (prepare_signals(pid, core))
 		return -1;
 
 	if (prepare_posix_timers(pid, core))
@@ -2353,6 +2353,20 @@ static int prepare_rlimits(int pid, CoreEntry *core)
 	return 0;
 }
 
+static int signal_to_mem(SiginfoEntry *sie)
+{
+	siginfo_t *info, *t;
+
+	info = (siginfo_t *) sie->siginfo.data;
+	t = rst_mem_alloc(sizeof(siginfo_t), RM_PRIVATE);
+	if (!t)
+		return -1;
+
+	memcpy(t, info, sizeof(*info));
+
+	return 0;
+}
+
 static int open_signal_image(int type, pid_t pid, unsigned int *nr)
 {
 	int fd, ret;
@@ -2368,7 +2382,6 @@ static int open_signal_image(int type, pid_t pid, unsigned int *nr)
 	*nr = 0;
 	while (1) {
 		SiginfoEntry *sie;
-		siginfo_t *info, *t;
 
 		ret = pb_read_one_eof(fd, &sie, PB_SIGINFO);
 		if (ret <= 0)
@@ -2378,14 +2391,11 @@ static int open_signal_image(int type, pid_t pid, unsigned int *nr)
 			ret = -1;
 			break;
 		}
-		info = (siginfo_t *) sie->siginfo.data;
-		t = rst_mem_alloc(sizeof(siginfo_t), RM_PRIVATE);
-		if (!t) {
-			ret = -1;
+
+		ret = signal_to_mem(sie);
+		if (ret)
 			break;
-		}
 
-		memcpy(t, info, sizeof(*info));
 		(*nr)++;
 
 		siginfo_entry__free_unpacked(sie, NULL);
@@ -2396,10 +2406,23 @@ static int open_signal_image(int type, pid_t pid, unsigned int *nr)
 	return ret ? : 0;
 }
 
+static int prepare_one_signal_queue(SignalQueueEntry *sqe, unsigned int *nr)
+{
+	int i;
+
+	for (i = 0; i < sqe->n_signals; i++)
+		if (signal_to_mem(sqe->signals[i]))
+			return -1;
+
+	*nr = sqe->n_signals;
+
+	return 0;
+}
+
 static unsigned long siginfo_cpos;
 static unsigned int siginfo_nr, *siginfo_priv_nr;
 
-static int prepare_signals(int pid)
+static int prepare_signals(int pid, CoreEntry *leader_core)
 {
 	int ret = -1, i;
 
@@ -2408,15 +2431,34 @@ static int prepare_signals(int pid)
 	if (siginfo_priv_nr == NULL)
 		goto out;
 
-	ret = open_signal_image(CR_FD_SIGNAL, pid, &siginfo_nr);
-	if (ret < 0)
-		goto out;
+	if (!leader_core->thread_core->signals) {/*backward compatibility*/
+		ret = open_signal_image(CR_FD_SIGNAL, pid, &siginfo_nr);
+		if (ret < 0)
+			goto out;
 
-	for (i = 0; i < current->nr_threads; i++) {
-		ret = open_signal_image(CR_FD_PSIGNAL,
-				current->threads[i].virt, &siginfo_priv_nr[i]);
+		for (i = 0; i < current->nr_threads; i++) {
+			ret = open_signal_image(CR_FD_PSIGNAL,
+					current->threads[i].virt, &siginfo_priv_nr[i]);
+			if (ret < 0)
+				goto out;
+		}
+	} else {
+		if (!leader_core->thread_core->signals->s) {
+			pr_err("Leader core has no shared signals entry\n");
+			ret = -1;
+			goto out;
+		}
+
+		ret = prepare_one_signal_queue(leader_core->thread_core->signals->s, &siginfo_nr);
 		if (ret < 0)
 			goto out;
+
+		for (i = 0; i < current->nr_threads; i++) {
+			ret = prepare_one_signal_queue(current->core[i]->thread_core->signals->p,
+										&siginfo_priv_nr[i]);
+			if (ret < 0)
+				goto out;
+		}
 	}
 out:
 	return ret;
-- 
1.9.1



More information about the CRIU mailing list