Re: [CRIU] [PATCH 3/3] signalfd: add ability to read siginfo-s without dequeuing signals (v2)
From: Oleg Nesterov <hidden>
Date: 2013-02-11 16:47:27
Also in:
linux-fsdevel, lkml
On 02/10, Andrew Vagin wrote:
On Sat, Feb 09, 2013 at 11:53:04PM +0100, Michael Kerrisk (man-pages) wrote:quoted
This looks promising, but I am not sure I understand the user-space API. Could you explain how it would look to (say) pull all per-thread signals from user space?siginfo_t *signals = malloc(...); ... ret = ptrace(PTRACE_ATTACH, pid, NULL, NULL);
Yes. I assume this should not be a problem since c/r needs to ptrace the task anyway?
For shared (per-process) signals one line should be changed: ret = ptrace(PTRACE_PEEKSIGNAL, pid, PTRACE_PEEK_SHARED + i, signals + i);
Yes. Except I'd say "PTRACE_PEEK_SHARED | i" to clarify that PTRACE_PEEK_SHARED is "flag". Note that we can more flags, say, PTRACE_PEEK_DEQUEUE which obviously means "dequeue signal" (but in this case we should filter out SIGKILL/SIGSTOP). And note that either way (I mean ptrace or signalfd) this can not actually peek a signal which doesn't have the sigqueue (say, SEND_SIG_FORCED). I guess this is not the problem, c/r can look at /proc/pid/status#*Pnd aditionally. OK, you seem to agree with this approach, I'll try to make the working patch tomorrow. At least ptrace_peek_signal() needs another is_compat argument for compat_ptrace_request(). Oleg.
quoted
quoted
--- x/kernel/ptrace.c +++ x/kernel/ptrace.c@@ -618,6 +618,35 @@ static int ptrace_setsiginfo(struct task return error; } +static int ptrace_peek_signal(struct task_struct *child, + unsigned long addr, siginfo_t __user *uinfo) +{ + siginfo_t info; + struct sigpending *pending; + int ret = -ESOMETHING; + + pending = &child->pending; + if (addr & PTRACE_PEEK_SHARED) { + addr &= ~PTRACE_PEEK_SHARED; + pending = &child->signal->shared_pending; + } + + spin_lock_irq(&child->sighand->siglock); + list_for_each_entry(q, &pending->list, list) { + if (!addr--) { + copy_siginfo(info, &q->info); + ret = 0; + break; + } + } + spin_lock_irq(&child->sighand->siglock); + + if (!ret) + ret = copy_siginfo_to_user(uinfo, info); + if (!ret) + ret = __put_user(info, si_code); + return ret; +} #ifdef PTRACE_SINGLESTEP #define is_singlestep(request) ((request) == PTRACE_SINGLESTEP)@@ -742,6 +771,10 @@ int ptrace_request(struct task_struct *c ret = put_user(child->ptrace_message, datalp); break; + case PTRACE_PEEKSIGNAL: + ret = ptrace_peek_signal(child, addr, datavp); + break; + case PTRACE_GETSIGINFO: ret = ptrace_getsiginfo(child, &siginfo); if (!ret)-- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Author of "The Linux Programming Interface"; http://man7.org/tlpi/ _______________________________________________ CRIU mailing list CRIU-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org https://lists.openvz.org/mailman/listinfo/criu