Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / kernel / vserver / signal.c
index 963cc06..b11a3a3 100644 (file)
@@ -9,7 +9,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/sched.h>
 
 #include <asm/errno.h>
 #include <linux/vserver/signal_cmd.h>
 
 
-int vc_ctx_kill(uint32_t id, void __user *data)
+int vx_info_kill(struct vx_info *vxi, int pid, int sig)
 {
        int retval, count=0;
-       struct vcmd_ctx_kill_v0 vc_data;
        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;
-
-       vxi = locate_vx_info(id);
-       if (!vxi)
-               return -ESRCH;
-
        retval = -ESRCH;
+       vxdprintk(VXD_CBIT(misc, 4),
+               "vx_info_kill(%p[#%d],%d,%d)*",
+               vxi, vxi->vx_id, pid, sig);
        read_lock(&tasklist_lock);
-       switch (vc_data.pid) {
+       switch (pid) {
        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))
+                       if (vx_task_xid(p) != vxi->vx_id || p->pid <= 1 ||
+                               (pid && vxi->vx_initpid == p->pid))
                                continue;
 
-                       err = group_send_sig_info(vc_data.sig, (void*)priv, p);
+                       err = group_send_sig_info(sig, (void*)priv, p);
                        ++count;
                        if (err != -EPERM)
                                retval = err;
@@ -58,20 +49,42 @@ int vc_ctx_kill(uint32_t id, void __user *data)
 
        case 1:
                if (vxi->vx_initpid) {
-                       vc_data.pid = vxi->vx_initpid;
+                       pid = vxi->vx_initpid;
                        priv = 1;
                }
                /* fallthrough */
        default:
-               p = find_task_by_real_pid(vc_data.pid);
+               p = find_task_by_real_pid(pid);
                if (p) {
-                       if ((id == -1) || (vx_task_xid(p) == id))
-                               retval = group_send_sig_info(vc_data.sig,
+                       if (vx_task_xid(p) == vxi->vx_id)
+                               retval = group_send_sig_info(sig,
                                        (void*)priv, p);
                }
                break;
        }
        read_unlock(&tasklist_lock);
+       vxdprintk(VXD_CBIT(misc, 4),
+               "vx_info_kill(%p[#%d],%d,%d) = %d",
+               vxi, vxi->vx_id, pid, sig, retval);
+       return retval;
+}
+
+int vc_ctx_kill(uint32_t id, void __user *data)
+{
+       int retval;
+       struct vcmd_ctx_kill_v0 vc_data;
+       struct vx_info *vxi;
+
+       if (!vx_check(0, VX_ADMIN))
+               return -ENOSYS;
+       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
+               return -EFAULT;
+
+       vxi = lookup_vx_info(id);
+       if (!vxi)
+               return -ESRCH;
+
+       retval = vx_info_kill(vxi, vc_data.pid, vc_data.sig);
        put_vx_info(vxi);
        return retval;
 }
@@ -86,7 +99,8 @@ static int __wait_exit(struct vx_info *vxi)
        set_current_state(TASK_INTERRUPTIBLE);
 
 wait:
-       if (vx_info_state(vxi, VXS_SHUTDOWN|VXS_HASHED) == VXS_SHUTDOWN)
+       if (vx_info_state(vxi,
+               VXS_SHUTDOWN|VXS_HASHED|VXS_HELPER) == VXS_SHUTDOWN)
                goto out;
        if (signal_pending(current)) {
                ret = -ERESTARTSYS;
@@ -106,14 +120,20 @@ out:
 int vc_wait_exit(uint32_t id, void __user *data)
 {
        struct vx_info *vxi;
+       struct vcmd_wait_exit_v0 vc_data;
        int ret;
 
-       vxi = locate_vx_info(id);
+       vxi = lookup_vx_info(id);
        if (!vxi)
                return -ESRCH;
 
        ret = __wait_exit(vxi);
+       vc_data.reboot_cmd = vxi->reboot_cmd;
+       vc_data.exit_code = vxi->exit_code;
        put_vx_info(vxi);
+
+       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
+               ret = -EFAULT;
        return ret;
 }