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
1 /*
2  *  linux/kernel/vserver/signal.c
3  *
4  *  Virtual Server: Signal Support
5  *
6  *  Copyright (C) 2003-2005  Herbert Pƶtzl
7  *
8  *  V0.01  broken out from vcontext V0.05
9  *
10  */
11
12 #include <linux/sched.h>
13
14 #include <asm/errno.h>
15 #include <asm/uaccess.h>
16
17 #include <linux/vs_context.h>
18 #include <linux/vserver/signal_cmd.h>
19
20
21 int vx_info_kill(struct vx_info *vxi, int pid, int sig)
22 {
23         int retval, count=0;
24         struct task_struct *p;
25         unsigned long priv = 0;
26
27         retval = -ESRCH;
28         vxdprintk(VXD_CBIT(misc, 4),
29                 "vx_info_kill(%p[#%d],%d,%d)*",
30                 vxi, vxi->vx_id, pid, sig);
31         read_lock(&tasklist_lock);
32         switch (pid) {
33         case  0:
34                 priv = 1;
35         case -1:
36                 for_each_process(p) {
37                         int err = 0;
38
39                         if (vx_task_xid(p) != vxi->vx_id || p->pid <= 1 ||
40                                 (pid && vxi->vx_initpid == p->pid))
41                                 continue;
42
43                         err = group_send_sig_info(sig, (void*)priv, p);
44                         ++count;
45                         if (err != -EPERM)
46                                 retval = err;
47                 }
48                 break;
49
50         case 1:
51                 if (vxi->vx_initpid) {
52                         pid = vxi->vx_initpid;
53                         priv = 1;
54                 }
55                 /* fallthrough */
56         default:
57                 p = find_task_by_real_pid(pid);
58                 if (p) {
59                         if (vx_task_xid(p) == vxi->vx_id)
60                                 retval = group_send_sig_info(sig,
61                                         (void*)priv, p);
62                 }
63                 break;
64         }
65         read_unlock(&tasklist_lock);
66         vxdprintk(VXD_CBIT(misc, 4),
67                 "vx_info_kill(%p[#%d],%d,%d) = %d",
68                 vxi, vxi->vx_id, pid, sig, retval);
69         return retval;
70 }
71
72 int vc_ctx_kill(uint32_t id, void __user *data)
73 {
74         int retval;
75         struct vcmd_ctx_kill_v0 vc_data;
76         struct vx_info *vxi;
77
78         if (!vx_check(0, VX_ADMIN))
79                 return -ENOSYS;
80         if (copy_from_user (&vc_data, data, sizeof(vc_data)))
81                 return -EFAULT;
82
83         vxi = lookup_vx_info(id);
84         if (!vxi)
85                 return -ESRCH;
86
87         retval = vx_info_kill(vxi, vc_data.pid, vc_data.sig);
88         put_vx_info(vxi);
89         return retval;
90 }
91
92
93 static int __wait_exit(struct vx_info *vxi)
94 {
95         DECLARE_WAITQUEUE(wait, current);
96         int ret = 0;
97
98         add_wait_queue(&vxi->vx_wait, &wait);
99         set_current_state(TASK_INTERRUPTIBLE);
100
101 wait:
102         if (vx_info_state(vxi,
103                 VXS_SHUTDOWN|VXS_HASHED|VXS_HELPER) == VXS_SHUTDOWN)
104                 goto out;
105         if (signal_pending(current)) {
106                 ret = -ERESTARTSYS;
107                 goto out;
108         }
109         schedule();
110         goto wait;
111
112 out:
113         set_current_state(TASK_RUNNING);
114         remove_wait_queue(&vxi->vx_wait, &wait);
115         return ret;
116 }
117
118
119
120 int vc_wait_exit(uint32_t id, void __user *data)
121 {
122         struct vx_info *vxi;
123         struct vcmd_wait_exit_v0 vc_data;
124         int ret;
125
126         vxi = lookup_vx_info(id);
127         if (!vxi)
128                 return -ESRCH;
129
130         ret = __wait_exit(vxi);
131         vc_data.reboot_cmd = vxi->reboot_cmd;
132         vc_data.exit_code = vxi->exit_code;
133         put_vx_info(vxi);
134
135         if (copy_to_user (data, &vc_data, sizeof(vc_data)))
136                 ret = -EFAULT;
137         return ret;
138 }
139