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

Pavel Emelyanov xemul at parallels.com
Thu Mar 14 12:05:55 EDT 2013


> +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)

Some pr_ message would be nice.

> +			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");

If ptrace failed, we don't get here, as if (ret <= 0) check above shoots.

> +				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);

s/0/false/

> +	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);

s/1/true/

> +	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