vserver 2.0-pre1
[linux-2.6.git] / kernel / vserver / helper.c
1 /*
2  *  linux/kernel/vserver/helper.c
3  *
4  *  Virtual Context Support
5  *
6  *  Copyright (C) 2004-2005  Herbert Pƶtzl
7  *
8  *  V0.01  basic helper
9  *
10  */
11
12 #include <linux/config.h>
13 #include <linux/errno.h>
14 #include <linux/reboot.h>
15 #include <linux/kmod.h>
16 #include <linux/sched.h>
17 #include <linux/vs_context.h>
18
19 #include <asm/uaccess.h>
20 #include <asm/unistd.h>
21
22
23 char vshelper_path[255] = "/sbin/vshelper";
24
25
26 int do_vshelper(char *name, char *argv[], char *envp[], int sync)
27 {
28         int ret;
29
30         if ((ret = call_usermodehelper(name, argv, envp, sync))) {
31                 printk( KERN_WARNING
32                         "%s: (%s %s) returned with %d\n",
33                         name, argv[1], argv[2], ret);
34         }
35         vxdprintk(VXD_CBIT(switch, 1),
36                 "%s: (%s %s) returned with %d",
37                 name, argv[1], argv[2], ret);
38         return ret;
39 }
40
41 /*
42  *      vshelper path is set via /proc/sys
43  *      invoked by vserver sys_reboot(), with
44  *      the following arguments
45  *
46  *      argv [0] = vshelper_path;
47  *      argv [1] = action: "restart", "halt", "poweroff", ...
48  *      argv [2] = context identifier
49  *
50  *      envp [*] = type-specific parameters
51  */
52
53 long vs_reboot(unsigned int cmd, void * arg)
54 {
55         char id_buf[8], cmd_buf[16];
56         char uid_buf[16], pid_buf[16];
57
58         char *argv[] = {vshelper_path, NULL, id_buf, 0};
59         char *envp[] = {"HOME=/", "TERM=linux",
60                         "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
61                         uid_buf, pid_buf, cmd_buf, 0};
62
63         snprintf(id_buf, sizeof(id_buf)-1, "%d", vx_current_xid());
64
65         snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
66         snprintf(uid_buf, sizeof(uid_buf)-1, "VS_UID=%d", current->uid);
67         snprintf(pid_buf, sizeof(pid_buf)-1, "VS_PID=%d", current->pid);
68
69         switch (cmd) {
70         case LINUX_REBOOT_CMD_RESTART:
71                 argv[1] = "restart";
72                 break;
73
74         case LINUX_REBOOT_CMD_HALT:
75                 argv[1] = "halt";
76                 break;
77
78         case LINUX_REBOOT_CMD_POWER_OFF:
79                 argv[1] = "poweroff";
80                 break;
81
82         case LINUX_REBOOT_CMD_SW_SUSPEND:
83                 argv[1] = "swsusp";
84                 break;
85         }
86
87         if (do_vshelper(vshelper_path, argv, envp, 1))
88                 return -EPERM;
89         return 0;
90 }
91
92
93 /*
94  *      invoked by vserver sys_reboot(), with
95  *      the following arguments
96  *
97  *      argv [0] = vshelper_path;
98  *      argv [1] = action: "startup", "shutdown"
99  *      argv [2] = context identifier
100  *
101  *      envp [*] = type-specific parameters
102  */
103
104 long vs_context_state(struct vx_info *vxi, unsigned int cmd)
105 {
106         char id_buf[8], cmd_buf[16];
107         char *argv[] = {vshelper_path, NULL, id_buf, 0};
108         char *envp[] = {"HOME=/", "TERM=linux",
109                         "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
110
111         snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id);
112         snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
113
114         switch (cmd) {
115         case VS_CONTEXT_CREATED:
116                 argv[1] = "startup";
117                 break;
118         case VS_CONTEXT_DESTROY:
119                 argv[1] = "shutdown";
120                 break;
121         default:
122                 return 0;
123         }
124
125         do_vshelper(vshelper_path, argv, envp, 1);
126         return 0;
127 }
128