[CRIU] [PATCH 7/7] dump: dump signals into core->thread_core->signals
Ruslan Kuprieiev
kupruser at gmail.com
Wed Aug 13 19:33:45 PDT 2014
Every thread has it's own private signals and leader thread has also shared
signals.
Signed-off-by: Ruslan Kuprieiev <kupruser at gmail.com>
---
cr-dump.c | 81 ++++++++++++++++++++++++++++++++++++---------------------------
1 file changed, 46 insertions(+), 35 deletions(-)
diff --git a/cr-dump.c b/cr-dump.c
index 74a8b4c..a3a0aa9 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -1168,11 +1168,12 @@ err:
return ret;
}
-static int dump_signal_queue(pid_t tid, int fd, bool group)
+static int dump_signal_queue(pid_t tid, SignalQueueEntry **sqe, bool group)
{
struct ptrace_peeksiginfo_args arg;
siginfo_t siginfo[32]; /* One page or all non-rt signals */
int ret, i = 0, j, nr;
+ SignalQueueEntry *queue = NULL;
pr_debug("Dump %s signals of %d\n", group ? "shared" : "private", tid);
@@ -1181,6 +1182,12 @@ static int dump_signal_queue(pid_t tid, int fd, bool group)
if (group)
arg.flags |= PTRACE_PEEKSIGINFO_SHARED;
+ queue = xmalloc(sizeof(*queue));
+ if (!queue)
+ return -1;
+
+ signal_queue_entry__init(queue);
+
for (; ; ) {
arg.off = i;
@@ -1198,50 +1205,54 @@ static int dump_signal_queue(pid_t tid, int fd, bool group)
break;
nr = ret;
- for (j = 0; j < nr; j++) {
- SiginfoEntry sie = SIGINFO_ENTRY__INIT;
+ queue->n_signals += nr;
+ queue->signals = xrealloc(queue->signals, sizeof(*queue->signals) * queue->n_signals);
+ if (!queue->signals) {
+ ret = -1;
+ break;
+ }
- sie.siginfo.len = sizeof(siginfo_t);
- sie.siginfo.data = (void *) (siginfo + j);
+ for (j = queue->n_signals - nr; j < queue->n_signals; j++) {
+ queue->signals[j]->siginfo.len = sizeof(siginfo_t);
+ queue->signals[j]->siginfo.data = (void *) (siginfo + j);
- ret = pb_write_one(fd, &sie, PB_SIGINFO);
- if (ret < 0)
- break;
i++;
}
}
+ *sqe = queue;
+
return ret;
}
-static int dump_thread_signals(struct pid *tid)
+static int dump_task_signals(pid_t pid, struct pstree_item *item)
{
- int fd, ret;
+ int i, ret;
+ SignalsEntry *signals = NULL;
- fd = open_image(CR_FD_PSIGNAL, O_DUMP, tid->virt);
- if (fd < 0)
- return -1;
- ret = dump_signal_queue(tid->real, fd, false);
- close(fd);
+ /* Dump private signals for each thread */
+ for (i = 0; i < item->nr_threads; i++) {
+ signals = xmalloc(sizeof(*signals));
+ if (!signals)
+ return -1;
- return ret;
-}
+ signals_entry__init(signals);
-static int dump_task_signals(pid_t pid, struct pstree_item *item,
- struct cr_fdset *cr_fdset)
-{
- int i, ret;
+ ret = dump_signal_queue(item->threads[i].real, &signals->p, false);
+ if (ret) {
+ pr_err("Can't dump private signals for thread %d\n", item->threads[i].real);
+ return -1;
+ }
- ret = dump_signal_queue(pid, fdset_fd(cr_fdset, CR_FD_SIGNAL), true);
- if (ret) {
- pr_err("Can't dump pending signals (pid: %d)\n", pid);
- return -1;
+ item->core[i]->thread_core->signals = signals;
}
- for (i = 0; i < item->nr_threads; i++) {
- ret = dump_thread_signals(&item->threads[i]);
- if (ret)
- return -1;
+ /* Dump shared signals */
+ signals = item->core[0]->thread_core->signals;
+ ret = dump_signal_queue(pid, &signals->s, true);
+ if (ret) {
+ pr_err("Can't dump shared signals (pid: %d)\n", pid);
+ return -1;
}
return 0;
@@ -1501,6 +1512,12 @@ static int dump_one_task(struct pstree_item *item)
goto err;
}
+ ret = dump_task_signals(pid, item);
+ if (ret) {
+ pr_err("Dump %d signals failed %d\n", pid, ret);
+ goto err;
+ }
+
ret = -1;
parasite_ctl = parasite_infect_seized(pid, item, &vmas, dfds, proc_args.timer_n);
if (!parasite_ctl) {
@@ -1635,12 +1652,6 @@ static int dump_one_task(struct pstree_item *item)
goto err;
}
- ret = dump_task_signals(pid, item, cr_fdset);
- if (ret) {
- pr_err("Dump %d signals failed %d\n", pid, ret);
- goto err;
- }
-
close_cr_fdset(&cr_fdset);
err:
close_pid_proc();
--
1.9.1
More information about the CRIU
mailing list