This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / kernel / vserver / signal.c
index 0499c9e..963cc06 100644 (file)
@@ -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
  *
 #include <asm/errno.h>
 #include <asm/uaccess.h>
 
-#include <linux/vs_base.h>
 #include <linux/vs_context.h>
-#include <linux/vserver/signal.h>
+#include <linux/vserver/signal_cmd.h>
 
 
 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 = locate_vx_info(id);
        if (!vxi)
                return -ESRCH;
@@ -46,35 +39,35 @@ int vc_ctx_kill(uint32_t id, void __user *data)
        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_real_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_real_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;
        }
@@ -89,11 +82,11 @@ static int __wait_exit(struct vx_info *vxi)
        DECLARE_WAITQUEUE(wait, current);
        int ret = 0;
 
-       add_wait_queue(&vxi->vx_exit, &wait);
+       add_wait_queue(&vxi->vx_wait, &wait);
        set_current_state(TASK_INTERRUPTIBLE);
 
 wait:
-       if (vx_info_state(vxi, VXS_DEFUNCT))
+       if (vx_info_state(vxi, VXS_SHUTDOWN|VXS_HASHED) == VXS_SHUTDOWN)
                goto out;
        if (signal_pending(current)) {
                ret = -ERESTARTSYS;
@@ -104,7 +97,7 @@ wait:
 
 out:
        set_current_state(TASK_RUNNING);
-       remove_wait_queue(&vxi->vx_exit, &wait);
+       remove_wait_queue(&vxi->vx_wait, &wait);
        return ret;
 }
 
@@ -112,7 +105,6 @@ out:
 
 int vc_wait_exit(uint32_t id, void __user *data)
 {
-//     struct vcmd_wait_exit_v0 vc_data;
        struct vx_info *vxi;
        int ret;