This commit was manufactured by cvs2svn to create branch 'vserver'.
[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  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/vserver.h>
17 #include <linux/vs_base.h>
18 #include <linux/vs_context.h>
19
20 #include <asm/uaccess.h>
21 #include <asm/unistd.h>
22
23
24 char vshelper_path[255] = "/sbin/vshelper";
25
26
27 /*
28  *      vshelper path is set via /proc/sys
29  *      invoked by vserver sys_reboot(), with
30  *      the following arguments
31  *
32  *      argv [0] = vshelper_path;
33  *      argv [1] = action: "restart", "halt", "poweroff", ...
34  *      argv [2] = context identifier
35  *      argv [3] = additional argument (restart2)
36  *
37  *      envp [*] = type-specific parameters
38  */
39
40 long vs_reboot(unsigned int cmd, void * arg)
41 {
42         char id_buf[8], cmd_buf[32];
43         char uid_buf[32], pid_buf[32];
44         char buffer[256];
45
46         char *argv[] = {vshelper_path, NULL, id_buf, NULL, 0};
47         char *envp[] = {"HOME=/", "TERM=linux",
48                         "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
49                         uid_buf, pid_buf, cmd_buf, 0};
50
51         snprintf(id_buf, sizeof(id_buf)-1, "%d", vx_current_xid());
52
53         snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
54         snprintf(uid_buf, sizeof(uid_buf)-1, "VS_UID=%d", current->uid);
55         snprintf(pid_buf, sizeof(pid_buf)-1, "VS_PID=%d", current->pid);
56
57         switch (cmd) {
58         case LINUX_REBOOT_CMD_RESTART:
59                 argv[1] = "restart";
60                 break;  
61
62         case LINUX_REBOOT_CMD_HALT:
63                 argv[1] = "halt";
64                 break;  
65
66         case LINUX_REBOOT_CMD_POWER_OFF:
67                 argv[1] = "poweroff";
68                 break;  
69
70         case LINUX_REBOOT_CMD_SW_SUSPEND:
71                 argv[1] = "swsusp";
72                 break;  
73
74         case LINUX_REBOOT_CMD_RESTART2:
75                 if (strncpy_from_user(&buffer[0], (char *)arg, sizeof(buffer) - 1) < 0)
76                         return -EFAULT;
77                 argv[3] = buffer;
78         default:
79                 argv[1] = "restart2";
80                 break;  
81         }
82
83         /* maybe we should wait ? */
84         if (call_usermodehelper(*argv, argv, envp, 0)) {
85                 printk( KERN_WARNING
86                         "vs_reboot(): failed to exec (%s %s %s %s)\n",
87                         vshelper_path, argv[1], argv[2], argv[3]);
88                 return -EPERM;
89         }
90         return 0;
91 }
92