c5472369a16fada180173214c590066cd6605d55
[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 /*
27  *      vshelper path is set via /proc/sys
28  *      invoked by vserver sys_reboot(), with
29  *      the following arguments
30  *
31  *      argv [0] = vshelper_path;
32  *      argv [1] = action: "restart", "halt", "poweroff", ...
33  *      argv [2] = context identifier
34  *
35  *      envp [*] = type-specific parameters
36  */
37
38 long vs_reboot(unsigned int cmd, void * arg)
39 {
40         char id_buf[8], cmd_buf[16];
41         char uid_buf[16], pid_buf[16];
42
43         char *argv[] = {vshelper_path, NULL, id_buf, 0};
44         char *envp[] = {"HOME=/", "TERM=linux",
45                         "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
46                         uid_buf, pid_buf, cmd_buf, 0};
47
48         snprintf(id_buf, sizeof(id_buf)-1, "%d", vx_current_xid());
49
50         snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
51         snprintf(uid_buf, sizeof(uid_buf)-1, "VS_UID=%d", current->uid);
52         snprintf(pid_buf, sizeof(pid_buf)-1, "VS_PID=%d", current->pid);
53
54         switch (cmd) {
55         case LINUX_REBOOT_CMD_RESTART:
56                 argv[1] = "restart";
57                 break;
58
59         case LINUX_REBOOT_CMD_HALT:
60                 argv[1] = "halt";
61                 break;
62
63         case LINUX_REBOOT_CMD_POWER_OFF:
64                 argv[1] = "poweroff";
65                 break;
66
67         case LINUX_REBOOT_CMD_SW_SUSPEND:
68                 argv[1] = "swsusp";
69                 break;
70
71         default:
72                 argv[1] = "restart2";
73                 break;
74         }
75
76         /* maybe we should wait ? */
77         if (call_usermodehelper(*argv, argv, envp, 1)) {
78                 printk( KERN_WARNING
79                         "vs_reboot(): failed to exec (%s %s %s)\n",
80                         vshelper_path, argv[1], argv[2]);
81                 return -EPERM;
82         }
83         return 0;
84 }
85
86 long vs_context_state(unsigned int cmd)
87 {
88         char id_buf[8], cmd_buf[32];
89
90         char *argv[] = {vshelper_path, NULL, id_buf, NULL, 0};
91         char *envp[] = {"HOME=/", "TERM=linux",
92                         "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
93
94         snprintf(id_buf, sizeof(id_buf)-1, "%d", vx_current_xid());
95         snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
96
97         switch (cmd) {
98         case VS_CONTEXT_CREATED:
99                 argv[1] = "startup";
100                 break;
101         case VS_CONTEXT_DESTROY:
102                 argv[1] = "shutdown";
103                 break;
104         default:
105                 return 0;
106         }
107
108         if (call_usermodehelper(*argv, argv, envp, 1)) {
109                 printk( KERN_WARNING
110                         "vs_context_state(): failed to exec (%s %s %s %s)\n",
111                         vshelper_path, argv[1], argv[2], argv[3]);
112                 return 0;
113         }
114         return 0;
115 }
116