uml: mconsole exec support Adds the "exec" command to mconsole; the command is passed to /bin/sh -c, so you know its syntax, and can freely use redirections and so on. It uses call_usermodehelper(). Signed-off-by: Paolo 'Blaisorblade' Giarrusso Index: linux-2.6.19/arch/um/drivers/mconsole_kern.c =================================================================== --- linux-2.6.19.orig/arch/um/drivers/mconsole_kern.c +++ linux-2.6.19/arch/um/drivers/mconsole_kern.c @@ -23,6 +23,7 @@ #include "linux/list.h" #include "linux/mm.h" #include "linux/console.h" +#include "linux/kmod.h" #include "asm/irq.h" #include "asm/uaccess.h" #include "user_util.h" @@ -209,6 +210,26 @@ void mconsole_proc(struct mc_request *re } #endif +#ifdef CONFIG_MCONSOLE_EXEC +void mconsole_exec(struct mc_request *req) +{ + int res; + + char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; + char *argv[] = { "/bin/sh", "-c", req->request.data + strlen("exec "), NULL }; + res = call_usermodehelper("/bin/sh", argv, envp, 0); + + if (res < 0) { + char buf[60]; + snprintf(buf, 60, "call_usermodehelper failed in mconsole_exec with error code: %d", -res); + mconsole_reply(req, buf, 1, 0); + return; + } + + mconsole_reply(req, "The command has been started successfully.", 0, 0); +} +#endif + void mconsole_proc(struct mc_request *req) { char path[64]; @@ -264,6 +285,14 @@ void mconsole_proc(struct mc_request *re /* nothing */; } +#ifdef CONFIG_MCONSOLE_EXEC +# define EXEC_HELPTEXT "\ + exec - runs the specified command through /bin/sh -c\n" +#else +# define EXEC_HELPTEXT "" +#endif + + /*exec - execute a command as root inside the UML\n"*/ #define UML_MCONSOLE_HELPTEXT \ "Commands: \n\ version - Get kernel version \n\ @@ -278,7 +307,7 @@ void mconsole_proc(struct mc_request *re cad - invoke the Ctrl-Alt-Del handler \n\ stop - pause the UML; it will do nothing until it receives a 'go' \n\ go - continue the UML after a 'stop' \n\ - log - make UML enter into the kernel log\n\ + log - make UML enter into the kernel log\n" EXEC_HELPTEXT "\ proc - returns the contents of the UML's /proc/\n\ stack - returns the stack of the specified pid\n\ " Index: linux-2.6.19/arch/um/drivers/mconsole_user.c =================================================================== --- linux-2.6.19.orig/arch/um/drivers/mconsole_user.c +++ linux-2.6.19/arch/um/drivers/mconsole_user.c @@ -18,6 +18,7 @@ #include "mconsole.h" #include "umid.h" #include "user_util.h" +#include "uml-config.h" static struct mconsole_command commands[] = { /* With uts namespaces, uts information becomes process-specific, so @@ -38,6 +39,9 @@ static struct mconsole_command commands[ { "log", mconsole_log, MCONSOLE_INTR }, { "proc", mconsole_proc, MCONSOLE_PROC }, { "stack", mconsole_stack, MCONSOLE_INTR }, +#ifdef UML_CONFIG_MCONSOLE_EXEC + { "exec", mconsole_exec, MCONSOLE_PROC }, +#endif }; /* Initialized in mconsole_init, which is an initcall */ Index: linux-2.6.19/arch/um/Kconfig =================================================================== --- linux-2.6.19.orig/arch/um/Kconfig +++ linux-2.6.19/arch/um/Kconfig @@ -189,6 +189,15 @@ config MCONSOLE It is safe to say 'Y' here. +config MCONSOLE_EXEC + bool "Management console 'exec' support" + depends on MCONSOLE + help + Adds the 'exec' command to mconsole, which allows execution of arbitrary command + inside UML. + All its parameters are passed to /bin/sh -c inside UML, so you can use the full + shell syntax, especially redirections. + config MAGIC_SYSRQ bool "Magic SysRq key" depends on MCONSOLE Index: linux-2.6.19/arch/um/include/mconsole.h =================================================================== --- linux-2.6.19.orig/arch/um/include/mconsole.h +++ linux-2.6.19/arch/um/include/mconsole.h @@ -83,6 +83,7 @@ extern void mconsole_cad(struct mc_reque extern void mconsole_stop(struct mc_request *req); extern void mconsole_go(struct mc_request *req); extern void mconsole_log(struct mc_request *req); +extern void mconsole_exec(struct mc_request *req); extern void mconsole_proc(struct mc_request *req); extern void mconsole_stack(struct mc_request *req);