*
* Virtual Context Support
*
- * Copyright (C) 2004 Herbert Pötzl
+ * Copyright (C) 2004-2005 Herbert Pötzl
*
* V0.01 basic helper
*
#include <linux/errno.h>
#include <linux/reboot.h>
#include <linux/kmod.h>
-#include <linux/vserver.h>
-#include <linux/vs_base.h>
+#include <linux/sched.h>
#include <linux/vs_context.h>
+#include <linux/vs_network.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
char vshelper_path[255] = "/sbin/vshelper";
+int do_vshelper(char *name, char *argv[], char *envp[], int sync)
+{
+ int ret;
+
+ if ((ret = call_usermodehelper(name, argv, envp, sync))) {
+ printk( KERN_WARNING
+ "%s: (%s %s) returned %s with %d\n",
+ name, argv[1], argv[2],
+ sync?"sync":"async", ret);
+ }
+ vxdprintk(VXD_CBIT(switch, 1),
+ "%s: (%s %s) returned %s with %d",
+ name, argv[1], argv[2], sync?"sync":"async", ret);
+ return ret;
+}
+
/*
* vshelper path is set via /proc/sys
* invoked by vserver sys_reboot(), with
* argv [0] = vshelper_path;
* argv [1] = action: "restart", "halt", "poweroff", ...
* argv [2] = context identifier
- * argv [3] = additional argument (restart2)
*
* envp [*] = type-specific parameters
*/
long vs_reboot(unsigned int cmd, void * arg)
{
- char id_buf[8], cmd_buf[32];
- char uid_buf[32], pid_buf[32];
- char buffer[256];
+ char id_buf[8], cmd_buf[16];
+ char uid_buf[16], pid_buf[16];
+ int ret;
- char *argv[] = {vshelper_path, NULL, id_buf, NULL, 0};
+ char *argv[] = {vshelper_path, NULL, id_buf, 0};
char *envp[] = {"HOME=/", "TERM=linux",
"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
uid_buf, pid_buf, cmd_buf, 0};
switch (cmd) {
case LINUX_REBOOT_CMD_RESTART:
argv[1] = "restart";
- break;
+ break;
case LINUX_REBOOT_CMD_HALT:
argv[1] = "halt";
- break;
+ break;
case LINUX_REBOOT_CMD_POWER_OFF:
argv[1] = "poweroff";
- break;
+ break;
case LINUX_REBOOT_CMD_SW_SUSPEND:
argv[1] = "swsusp";
- break;
+ break;
- case LINUX_REBOOT_CMD_RESTART2:
- if (strncpy_from_user(&buffer[0], (char *)arg, sizeof(buffer) - 1) < 0)
- return -EFAULT;
- argv[3] = buffer;
default:
- argv[1] = "restart2";
- break;
+ return 0;
}
- /* maybe we should wait ? */
- if (call_usermodehelper(*argv, argv, envp, 0)) {
- printk( KERN_WARNING
- "vs_reboot(): failed to exec (%s %s %s %s)\n",
- vshelper_path, argv[1], argv[2], argv[3]);
- return -EPERM;
+#ifndef CONFIG_VSERVER_LEGACY
+ ret = do_vshelper(vshelper_path, argv, envp, 1);
+#else
+ ret = do_vshelper(vshelper_path, argv, envp, 0);
+#endif
+ return (ret) ? -EPERM : 0;
+}
+
+
+/*
+ * argv [0] = vshelper_path;
+ * argv [1] = action: "startup", "shutdown"
+ * argv [2] = context identifier
+ *
+ * envp [*] = type-specific parameters
+ */
+
+long vs_state_change(struct vx_info *vxi, unsigned int cmd)
+{
+ char id_buf[8], cmd_buf[16];
+ char *argv[] = {vshelper_path, NULL, id_buf, 0};
+ char *envp[] = {"HOME=/", "TERM=linux",
+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
+
+ if (!vx_info_flags(vxi, VXF_STATE_HELPER, 0))
+ return 0;
+
+ snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id);
+ snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
+
+ switch (cmd) {
+ case VSC_STARTUP:
+ argv[1] = "startup";
+ break;
+ case VSC_SHUTDOWN:
+ argv[1] = "shutdown";
+ break;
+ default:
+ return 0;
}
+
+ do_vshelper(vshelper_path, argv, envp, 1);
+ return 0;
+}
+
+
+/*
+ * argv [0] = vshelper_path;
+ * argv [1] = action: "netup", "netdown"
+ * argv [2] = context identifier
+ *
+ * envp [*] = type-specific parameters
+ */
+
+long vs_net_change(struct nx_info *nxi, unsigned int cmd)
+{
+ char id_buf[8], cmd_buf[16];
+ char *argv[] = {vshelper_path, NULL, id_buf, 0};
+ char *envp[] = {"HOME=/", "TERM=linux",
+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
+
+ if (!nx_info_flags(nxi, NXF_STATE_HELPER, 0))
+ return 0;
+
+ snprintf(id_buf, sizeof(id_buf)-1, "%d", nxi->nx_id);
+ snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
+
+ switch (cmd) {
+ case VSC_NETUP:
+ argv[1] = "netup";
+ break;
+ case VSC_NETDOWN:
+ argv[1] = "netdown";
+ break;
+ default:
+ return 0;
+ }
+
+ do_vshelper(vshelper_path, argv, envp, 1);
return 0;
}