[CRIU] [PATCH 05/10] crtools: dump pending signals (v3)

Andrew Vagin avagin at parallels.com
Tue Mar 5 11:59:33 EST 2013


On Tue, Mar 05, 2013 at 08:11:00PM +0400, Pavel Emelyanov wrote:
> On 03/05/2013 06:54 PM, Andrey Vagin wrote:
> > signalfd is used for received pending signals, 
> 
> Signalfd STILL?

I forgot to correct the message.

PTRACE_PEEKSIGINFO is used for received pending signals

> 
> > then all signal are sent back and saved in a image.
> > 
> > v2: rework according with the new kernel interface
> > v3: rework according with the newrest kernel interface
> > 
> > Signed-off-by: Andrey Vagin <avagin at openvz.org>
> > ---
> >  cr-dump.c        | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
> >  include/ptrace.h | 13 +++++++++++
> >  2 files changed, 81 insertions(+), 3 deletions(-)
> > 
> > diff --git a/cr-dump.c b/cr-dump.c
> > index aff3e0c..8b10f6f 100644
> > --- a/cr-dump.c
> > +++ b/cr-dump.c
> > @@ -28,6 +28,7 @@
> >  #include "protobuf/core.pb-c.h"
> >  #include "protobuf/file-lock.pb-c.h"
> >  #include "protobuf/rlimit.pb-c.h"
> > +#include "protobuf/siginfo.pb-c.h"
> >  
> >  #include "asm/types.h"
> >  #include "list.h"
> > @@ -1164,6 +1165,62 @@ err:
> >  	return ret;
> >  }
> >  
> > +static int dump_signal_queue(pid_t tid, int fd, bool group)
> > +{
> > +	struct ptrace_peeksiginfo_args arg;
> > +	siginfo_t siginfo[32]; /* One page or all non-rt signals */
> > +	int ret, i = 0, j, nr;
> > +
> > +	arg.nr = sizeof(siginfo) / sizeof(siginfo_t);
> > +	arg.flags = 0;
> > +	if (group)
> > +		arg.flags |= PTRACE_PEEKSIGINFO_SHARED;
> > +
> > +	for (; ; ) {
> > +		arg.off = i;
> > +
> > +		ret = ptrace(PTRACE_PEEKSIGINFO, tid, &arg, siginfo);
> > +		if (ret <= 0)
> > +			break;
> > +		nr = ret;
> > +
> > +		for (j = 0; j < nr; j++) {
> > +			SiginfoEntry sie = SIGINFO_ENTRY__INIT;
> > +
> > +			sie.siginfo.len = sizeof(siginfo_t);
> > +			sie.siginfo.data = (void *) (siginfo + j);
> > +
> > +			ret = pb_write_one(fd, &sie, PB_SIGINFO);
> > +			if (ret < 0)
> > +				break;
> > +			i++;
> > +		}
> > +		if (ret < 0) {
> > +			if (errno == EIO) {
> > +				pr_warn("ptrace doesn't support PTRACE_PEEKSIGINFO\n");
> > +				ret = 0;
> > +			} else
> > +				pr_perror("ptrace");
> > +			break;
> > +		}
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +static int dump_thread_signals(struct pid *tid)
> > +{
> > +	int fd, ret;
> > +
> > +	fd = open_image(CR_FD_PSIGNAL, O_DUMP, tid->virt);
> > +	if (fd < 0)
> > +		return -1;
> > +	ret = dump_signal_queue(tid->real, fd, 0);
> > +	close(fd);
> > +
> > +	return ret;
> > +}
> > +
> >  static struct proc_pid_stat pps_buf;
> >  
> >  static int dump_task_threads(struct parasite_ctl *parasite_ctl,
> > @@ -1173,12 +1230,14 @@ static int dump_task_threads(struct parasite_ctl *parasite_ctl,
> >  
> >  	for (i = 0; i < item->nr_threads; i++) {
> >  		/* Leader is already dumped */
> > -		if (item->pid.real == item->threads[i].real) {
> > +		if (item->pid.real == item->threads[i].real)
> >  			item->threads[i].virt = item->pid.virt;
> > -			continue;
> > +		else {
> > +			if (dump_task_thread(parasite_ctl, &item->threads[i]))
> > +				return -1;
> >  		}
> >  
> > -		if (dump_task_thread(parasite_ctl, &item->threads[i]))
> > +		if (dump_thread_signals(&item->threads[i]))
> >  			return -1;
> >  	}
> >  
> > @@ -1428,6 +1487,12 @@ static int dump_one_task(struct pstree_item *item)
> >  		goto err;
> >  	}
> >  
> > +	ret = dump_signal_queue(pid, fdset_fd(cr_fdset, CR_FD_SIGNAL), 1);
> > +	if (ret) {
> > +		pr_err("Can't dump pending signals (pid: %d)\n", pid);
> > +		goto err_cure;
> > +	}
> > +
> >  	close_cr_fdset(&cr_fdset);
> >  err:
> >  	close_pid_proc();
> > diff --git a/include/ptrace.h b/include/ptrace.h
> > index ea45d20..4d1bc92 100644
> > --- a/include/ptrace.h
> > +++ b/include/ptrace.h
> > @@ -1,6 +1,7 @@
> >  #ifndef __CR_SEIZE_H__
> >  #define __CR_SEIZE_H__
> >  
> > +#include <linux/types.h>
> >  #include <sys/ptrace.h>
> >  
> >  /* some constants for ptrace */
> > @@ -14,6 +15,18 @@
> >  
> >  #define PTRACE_LISTEN		0x4208
> >  
> > +#ifndef PTRACE_PEEKSIGINFO
> > +#define PTRACE_PEEKSIGINFO      0x4209
> > +struct ptrace_peeksiginfo_args {
> > +        __u64 off;	/* from which siginfo to start */
> > +        __u32 flags;
> > +        __u32 nr;	/* how may siginfos to take */
> > +};
> > +
> > +/* Read signals from a shared (process wide) queue */
> > +#define PTRACE_PEEKSIGINFO_SHARED       (1 << 0)
> > +#endif
> > +
> >  #define PTRACE_SEIZE_DEVEL	0x80000000
> >  
> >  #define PTRACE_EVENT_FORK	1
> > 
> 
> 


More information about the CRIU mailing list