[CRIU] [PATCH 6/6] restore: restore signals from core->tc->signals, othrewise -- from signal_p/s*.img

Ruslan Kuprieiev kupruser at gmail.com
Tue Aug 5 01:36:01 PDT 2014


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

diff --git a/cr-restore.c b/cr-restore.c
index c2515bf..b47e4c0 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -89,7 +89,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, SignalsEntry *signals);
 
 static int shmem_remap(void *old_addr, void *new_addr, unsigned long size)
 {
@@ -721,7 +721,7 @@ static int restore_one_alive_task(int pid, CoreEntry *core)
 	if (open_vmas(pid))
 		return -1;
 
-	if (prepare_signals(pid))
+	if (prepare_signals(pid, core->tc->signals))
 		return -1;
 
 	if (prepare_posix_timers(pid, core))
@@ -2264,22 +2264,44 @@ static int prepare_rlimits(int pid, CoreEntry *core)
 	return 0;
 }
 
-static int open_signal_image(int type, pid_t pid, unsigned int *nr)
+static int signals_to_mem(SignalQueueEntry *sqe)
+{
+	int i;
+	siginfo_t *info, *t;
+
+	for (i = 0; i < sqe->n_signals; i++) {
+		info = (siginfo_t *) sqe->signals[i]->siginfo.data;
+		t = rst_mem_alloc(sizeof(siginfo_t), RM_PRIVATE);
+		if (!t)
+			return -1;
+
+		memcpy(t, info, sizeof(*info));
+	}
+
+	return 0;
+}
+
+static SignalQueueEntry *open_signal_image(int type, pid_t pid)
 {
 	int fd, ret;
+	SignalQueueEntry *sqe = NULL;
+
+	sqe = xmalloc(sizeof(*sqe));
+	if (!sqe)
+		return NULL;
+
+	signal_queue_entry__init(sqe);
 
 	fd = open_image(type, O_RSTR | O_OPT, pid);
 	if (fd < 0) {
 		if (fd == -ENOENT) /* backward compatibility */
-			return 0;
+			return sqe;
 		else
-			return -1;
+			return NULL;
 	}
 
-	*nr = 0;
 	while (1) {
 		SiginfoEntry *sie;
-		siginfo_t *info, *t;
 
 		ret = pb_read_one_eof(fd, &sie, PB_SIGINFO);
 		if (ret <= 0)
@@ -2289,43 +2311,58 @@ 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) {
+
+		sqe->n_signals++;
+		sqe->signals = xrealloc(sqe->signals, sizeof(*sqe->signals) * sqe->n_signals);
+		if (!sqe->signals) {
 			ret = -1;
 			break;
 		}
 
-		memcpy(t, info, sizeof(*info));
-		(*nr)++;
-
-		siginfo_entry__free_unpacked(sie, NULL);
+		sqe->signals[sqe->n_signals - 1] = sie;
 	}
 
 	close(fd);
-
-	return ret ? : 0;
+	return ret ? NULL : sqe;
 }
 
 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, SignalsEntry *signals)
 {
 	int ret = -1, i;
+	SignalQueueEntry *queue = NULL;
 
 	siginfo_cpos = rst_mem_cpos(RM_PRIVATE);
 	siginfo_priv_nr = xmalloc(sizeof(int) * current->nr_threads);
 	if (siginfo_priv_nr == NULL)
 		goto out;
 
-	ret = open_signal_image(CR_FD_SIGNAL, pid, &siginfo_nr);
-	if (ret < 0)
+	if (!signals) { /* backward compatibility */
+		queue = open_signal_image(CR_FD_SIGNAL, pid);
+		if (!queue)
+			goto out;
+	} else
+		queue = signals->shared;
+
+	siginfo_nr = queue->n_signals;
+	ret = signals_to_mem(queue);
+	if (ret)
 		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]);
+		if (!signals) { /* backward compatibility */
+			queue = open_signal_image(CR_FD_PSIGNAL, current->threads[i].virt);
+			if (!queue)
+				goto out;
+		} else {
+			queue = signals->private_[i];
+			BUG_ON(signals->n_private_ != current->nr_threads);
+		}
+
+		siginfo_priv_nr[i] = queue->n_signals;
+		ret = signals_to_mem(queue);
 		if (ret < 0)
 			goto out;
 	}
-- 
1.9.1



More information about the CRIU mailing list