2 * linux/kernel/vserver/signal.c
4 * Virtual Server: Signal Support
6 * Copyright (C) 2003-2007 Herbert Pƶtzl
8 * V0.01 broken out from vcontext V0.05
9 * V0.02 changed vcmds to vxi arg
10 * V0.03 adjusted siginfo for kill
14 #include <linux/sched.h>
15 #include <asm/errno.h>
16 #include <asm/uaccess.h>
18 #include <linux/vs_base.h>
19 #include <linux/vs_context.h>
20 #include <linux/vserver/signal_cmd.h>
23 int vx_info_kill(struct vx_info *vxi, int pid, int sig)
26 struct task_struct *p;
27 struct siginfo *sip = SEND_SIG_PRIV;
30 vxdprintk(VXD_CBIT(misc, 4),
31 "vx_info_kill(%p[#%d],%d,%d)*",
32 vxi, vxi->vx_id, pid, sig);
33 read_lock(&tasklist_lock);
40 if (vx_task_xid(p) != vxi->vx_id || p->pid <= 1 ||
41 (pid && vxi->vx_initpid == p->pid))
44 err = group_send_sig_info(sig, sip, p);
52 if (vxi->vx_initpid) {
53 pid = vxi->vx_initpid;
54 /* for now, only SIGINT to private init ... */
55 if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
56 /* ... as long as there are tasks left */
57 (atomic_read(&vxi->vx_tasks) > 1))
62 p = find_task_by_real_pid(pid);
64 if (vx_task_xid(p) == vxi->vx_id)
65 retval = group_send_sig_info(sig, sip, p);
69 read_unlock(&tasklist_lock);
70 vxdprintk(VXD_CBIT(misc, 4),
71 "vx_info_kill(%p[#%d],%d,%d,%ld) = %d",
72 vxi, vxi->vx_id, pid, sig, (long)sip, retval);
76 int vc_ctx_kill(struct vx_info *vxi, void __user *data)
78 struct vcmd_ctx_kill_v0 vc_data;
80 if (copy_from_user (&vc_data, data, sizeof(vc_data)))
83 /* special check to allow guest shutdown */
84 if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
85 /* forbid killall pid=0 when init is present */
86 (((vc_data.pid < 1) && vxi->vx_initpid) ||
90 return vx_info_kill(vxi, vc_data.pid, vc_data.sig);
94 static int __wait_exit(struct vx_info *vxi)
96 DECLARE_WAITQUEUE(wait, current);
99 add_wait_queue(&vxi->vx_wait, &wait);
100 set_current_state(TASK_INTERRUPTIBLE);
103 if (vx_info_state(vxi,
104 VXS_SHUTDOWN|VXS_HASHED|VXS_HELPER) == VXS_SHUTDOWN)
106 if (signal_pending(current)) {
114 set_current_state(TASK_RUNNING);
115 remove_wait_queue(&vxi->vx_wait, &wait);
121 int vc_wait_exit(struct vx_info *vxi, void __user *data)
123 struct vcmd_wait_exit_v0 vc_data;
126 ret = __wait_exit(vxi);
127 vc_data.reboot_cmd = vxi->reboot_cmd;
128 vc_data.exit_code = vxi->exit_code;
130 if (copy_to_user (data, &vc_data, sizeof(vc_data)))