X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=kernel%2Fvserver%2Fhelper.c;h=e3ab5814fdb9cd99028bf786168082e2efe9b825;hb=8e8ece46a861c84343256819eaec77e608ff9217;hp=880b84335bab9b59685a5828b1518cd6541feb93;hpb=c449269f45c2cdf53af08c8d0af37472f66539d9;p=linux-2.6.git diff --git a/kernel/vserver/helper.c b/kernel/vserver/helper.c index 880b84335..e3ab5814f 100644 --- a/kernel/vserver/helper.c +++ b/kernel/vserver/helper.c @@ -3,7 +3,7 @@ * * Virtual Context Support * - * Copyright (C) 2004 Herbert Pötzl + * Copyright (C) 2004-2005 Herbert Pötzl * * V0.01 basic helper * @@ -13,9 +13,9 @@ #include #include #include -#include -#include +#include #include +#include #include #include @@ -24,6 +24,22 @@ 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 @@ -32,18 +48,17 @@ char vshelper_path[255] = "/sbin/vshelper"; * 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}; @@ -57,36 +72,103 @@ long vs_reboot(unsigned int cmd, void * arg) 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; }