vserver 2.0-pre4
[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 %s with %d\n",
33                         name, argv[1], argv[2],
34                         sync?"sync":"async", ret);
35         }
36         vxdprintk(VXD_CBIT(switch, 1),
37                 "%s: (%s %s) returned %s with %d",
38                 name, argv[1], argv[2], sync?"sync":"async", ret);
39         return ret;
40 }
41
42 /*
43  *      vshelper path is set via /proc/sys
44  *      invoked by vserver sys_reboot(), with
45  *      the following arguments
46  *
47  *      argv [0] = vshelper_path;
48  *      argv [1] = action: "restart", "halt", "poweroff", ...
49  *      argv [2] = context identifier
50  *
51  *      envp [*] = type-specific parameters
52  */
53
54 long vs_reboot(unsigned int cmd, void * arg)
55 {
56         char id_buf[8], cmd_buf[16];
57         char uid_buf[16], pid_buf[16];
58
59         char *argv[] = {vshelper_path, NULL, id_buf, 0};
60         char *envp[] = {"HOME=/", "TERM=linux",
61                         "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
62                         uid_buf, pid_buf, cmd_buf, 0};
63
64         snprintf(id_buf, sizeof(id_buf)-1, "%d", vx_current_xid());
65
66         snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
67         snprintf(uid_buf, sizeof(uid_buf)-1, "VS_UID=%d", current->uid);
68         snprintf(pid_buf, sizeof(pid_buf)-1, "VS_PID=%d", current->pid);
69
70         switch (cmd) {
71         case LINUX_REBOOT_CMD_RESTART:
72                 argv[1] = "restart";
73                 break;
74
75         case LINUX_REBOOT_CMD_HALT:
76                 argv[1] = "halt";
77                 break;
78
79         case LINUX_REBOOT_CMD_POWER_OFF:
80                 argv[1] = "poweroff";
81                 break;
82
83         case LINUX_REBOOT_CMD_SW_SUSPEND:
84                 argv[1] = "swsusp";
85                 break;
86
87         default:
88                 return 0;
89         }
90
91         if (do_vshelper(vshelper_path, argv, envp, 1))
92                 return -EPERM;
93         return 0;
94 }
95
96
97 /*
98  *      argv [0] = vshelper_path;
99  *      argv [1] = action: "startup", "shutdown"
100  *      argv [2] = context identifier
101  *
102  *      envp [*] = type-specific parameters
103  */
104
105 long vs_state_change(struct vx_info *vxi, unsigned int cmd)
106 {
107         char id_buf[8], cmd_buf[16];
108         char *argv[] = {vshelper_path, NULL, id_buf, 0};
109         char *envp[] = {"HOME=/", "TERM=linux",
110                         "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
111
112         snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id);
113         snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
114
115         switch (cmd) {
116         case VSC_STARTUP:
117                 argv[1] = "startup";
118                 break;
119         case VSC_SHUTDOWN:
120                 argv[1] = "shutdown";
121                 break;
122         default:
123                 return 0;
124         }
125
126         do_vshelper(vshelper_path, argv, envp, 1);
127         return 0;
128 }
129