X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=kernel%2Fvserver%2Fsignal.c;h=963cc06513ebf97be645b191833cf3bb6a0fcf75;hb=8e8ece46a861c84343256819eaec77e608ff9217;hp=464ea1be4f3ae9134c5d145cc7bedc954f365d01;hpb=b76fcd5f0c655b6e3e9bf534594357025421c66a;p=linux-2.6.git diff --git a/kernel/vserver/signal.c b/kernel/vserver/signal.c index 464ea1be4..963cc0651 100644 --- a/kernel/vserver/signal.c +++ b/kernel/vserver/signal.c @@ -3,7 +3,7 @@ * * Virtual Server: Signal Support * - * Copyright (C) 2003-2004 Herbert Pötzl + * Copyright (C) 2003-2005 Herbert Pötzl * * V0.01 broken out from vcontext V0.05 * @@ -15,65 +15,59 @@ #include #include -#include -#include +#include +#include int vc_ctx_kill(uint32_t id, void __user *data) { int retval, count=0; struct vcmd_ctx_kill_v0 vc_data; - struct siginfo info; struct task_struct *p; struct vx_info *vxi; + unsigned long priv = 0; if (!vx_check(0, VX_ADMIN)) return -ENOSYS; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - - info.si_signo = vc_data.sig; - info.si_errno = 0; - info.si_code = SI_USER; - info.si_pid = current->pid; - info.si_uid = current->uid; - - vxi = find_vx_info(id); + + vxi = locate_vx_info(id); if (!vxi) return -ESRCH; retval = -ESRCH; read_lock(&tasklist_lock); switch (vc_data.pid) { - case -1: case 0: + priv = 1; + case -1: for_each_process(p) { int err = 0; if (vx_task_xid(p) != id || p->pid <= 1 || - (vc_data.pid && vxi->vx_initpid == p->pid) || - !thread_group_leader(p)) + (vc_data.pid && vxi->vx_initpid == p->pid)) continue; - err = send_sig_info(vc_data.sig, &info, p); + err = group_send_sig_info(vc_data.sig, (void*)priv, p); ++count; if (err != -EPERM) retval = err; } break; - + + case 1: + if (vxi->vx_initpid) { + vc_data.pid = vxi->vx_initpid; + priv = 1; + } + /* fallthrough */ default: - p = find_task_by_pid(vc_data.pid); + p = find_task_by_real_pid(vc_data.pid); if (p) { - if (!thread_group_leader(p)) { - struct task_struct *tg; - - tg = find_task_by_pid(p->tgid); - if (tg) - p = tg; - } if ((id == -1) || (vx_task_xid(p) == id)) - retval = send_sig_info(vc_data.sig, &info, p); + retval = group_send_sig_info(vc_data.sig, + (void*)priv, p); } break; } @@ -83,3 +77,43 @@ int vc_ctx_kill(uint32_t id, void __user *data) } +static int __wait_exit(struct vx_info *vxi) +{ + DECLARE_WAITQUEUE(wait, current); + int ret = 0; + + add_wait_queue(&vxi->vx_wait, &wait); + set_current_state(TASK_INTERRUPTIBLE); + +wait: + if (vx_info_state(vxi, VXS_SHUTDOWN|VXS_HASHED) == VXS_SHUTDOWN) + goto out; + if (signal_pending(current)) { + ret = -ERESTARTSYS; + goto out; + } + schedule(); + goto wait; + +out: + set_current_state(TASK_RUNNING); + remove_wait_queue(&vxi->vx_wait, &wait); + return ret; +} + + + +int vc_wait_exit(uint32_t id, void __user *data) +{ + struct vx_info *vxi; + int ret; + + vxi = locate_vx_info(id); + if (!vxi) + return -ESRCH; + + ret = __wait_exit(vxi); + put_vx_info(vxi); + return ret; +} +