This patch adds 'kvm sandbox' which is a wrapper on top of 'kvm run' which allows the user to easily specify sandboxed command to run in a custom rootfs guest. Example usage: kvm sandbox -d test_guest -k some_kernel -- do_something_in_guest Suggested-by: Pekka Enberg <penberg@xxxxxxxxxxxxxx> Signed-off-by: Sasha Levin <levinsasha928@xxxxxxxxx> --- tools/kvm/Documentation/kvm-sandbox.txt | 16 ++++++++++ tools/kvm/Makefile | 1 + tools/kvm/builtin-run.c | 49 +++++++++++++++++++++++++++++- tools/kvm/builtin-sandbox.c | 9 ++++++ tools/kvm/command-list.txt | 1 + tools/kvm/include/kvm/builtin-run.h | 2 + tools/kvm/include/kvm/builtin-sandbox.h | 6 ++++ tools/kvm/kvm-cmd.c | 2 + 8 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 tools/kvm/Documentation/kvm-sandbox.txt create mode 100644 tools/kvm/builtin-sandbox.c create mode 100644 tools/kvm/include/kvm/builtin-sandbox.h diff --git a/tools/kvm/Documentation/kvm-sandbox.txt b/tools/kvm/Documentation/kvm-sandbox.txt new file mode 100644 index 0000000..8f24fc7 --- /dev/null +++ b/tools/kvm/Documentation/kvm-sandbox.txt @@ -0,0 +1,16 @@ +kvm-sandbox(1) +================ + +NAME +---- +kvm-sandbox - Run a command in a sandboxed guest + +SYNOPSIS +-------- +[verse] +'kvm sandbox ['kvm run' arguments] -- [sandboxed command]' + +DESCRIPTION +----------- +The sandboxed command will run in a guest as part of it's init +command. diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile index ece3306..24af1d0 100644 --- a/tools/kvm/Makefile +++ b/tools/kvm/Makefile @@ -85,6 +85,7 @@ OBJS += hw/vesa.o OBJS += hw/i8042.o OBJS += hw/pci-shmem.o OBJS += kvm-ipc.o +OBJS += builtin-sandbox.o FLAGS_BFD := $(CFLAGS) -lbfd has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD)) diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c index 5db6995..7a57b5c 100644 --- a/tools/kvm/builtin-run.c +++ b/tools/kvm/builtin-run.c @@ -53,6 +53,7 @@ #define DEFAULT_GUEST_MAC "02:15:15:15:15:15" #define DEFAULT_HOST_MAC "02:01:01:01:01:01" #define DEFAULT_SCRIPT "none" +const char *DEFAULT_SANDBOX_FILENAME = "guest/sandbox.sh"; #define MB_SHIFT (20) #define KB_SHIFT (10) @@ -94,6 +95,7 @@ static bool custom_rootfs; static bool no_net; static bool no_dhcp; extern bool ioport_debug; +static int kvm_run_wrapper; extern int active_console; extern int debug_iodelay; @@ -107,6 +109,15 @@ static const char * const run_usage[] = { NULL }; +enum { + KVM_RUN_SANDBOX, +}; + +void kvm_run_set_wrapper_sandbox(void) +{ + kvm_run_wrapper = KVM_RUN_SANDBOX; +} + static int img_name_parser(const struct option *opt, const char *arg, int unset) { char *sep; @@ -755,6 +766,35 @@ static int kvm_run_set_sandbox(void) return symlink(script, path); } +static void kvm_run_write_sandbox_cmd(const char **argv, int argc) +{ + const char script_hdr[] = "#! /bin/bash\n\n"; + int fd; + + remove(sandbox); + + fd = open(sandbox, O_RDWR | O_CREAT, 0777); + if (fd < 0) + die("Failed creating sandbox script"); + + if (write(fd, script_hdr, sizeof(script_hdr) - 1) <= 0) + die("Failed writing sandbox script"); + + while (argc) { + if (write(fd, argv[0], strlen(argv[0])) <= 0) + die("Failed writing sandbox script"); + if (argc - 1) + if (write(fd, " ", 1) <= 0) + die("Failed writing sandbox script"); + argv++; + argc--; + } + if (write(fd, "\n", 1) <= 0) + die("Failed writing sandbox script"); + + close(fd); +} + int kvm_cmd_run(int argc, const char **argv, const char *prefix) { static char real_cmdline[2048], default_name[20]; @@ -780,8 +820,13 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix) PARSE_OPT_KEEP_DASHDASH); if (argc != 0) { /* Cusrom options, should have been handled elsewhere */ - if (strcmp(argv[0], "--") == 0) - break; + if (strcmp(argv[0], "--") == 0) { + if (kvm_run_wrapper == KVM_RUN_SANDBOX) { + sandbox = DEFAULT_SANDBOX_FILENAME; + kvm_run_write_sandbox_cmd(argv+1, argc-1); + break; + } + } if (kernel_filename) { fprintf(stderr, "Cannot handle parameter: " diff --git a/tools/kvm/builtin-sandbox.c b/tools/kvm/builtin-sandbox.c new file mode 100644 index 0000000..433f536 --- /dev/null +++ b/tools/kvm/builtin-sandbox.c @@ -0,0 +1,9 @@ +#include "kvm/builtin-sandbox.h" +#include "kvm/builtin-run.h" + +int kvm_cmd_sandbox(int argc, const char **argv, const char *prefix) +{ + kvm_run_set_wrapper_sandbox(); + + return kvm_cmd_run(argc, argv, prefix); +} diff --git a/tools/kvm/command-list.txt b/tools/kvm/command-list.txt index 0d16c62..53469ab 100644 --- a/tools/kvm/command-list.txt +++ b/tools/kvm/command-list.txt @@ -12,3 +12,4 @@ kvm-debug common kvm-balloon common kvm-stop common kvm-stat common +kvm-sandbox common diff --git a/tools/kvm/include/kvm/builtin-run.h b/tools/kvm/include/kvm/builtin-run.h index d056ad4..c4b8ccb 100644 --- a/tools/kvm/include/kvm/builtin-run.h +++ b/tools/kvm/include/kvm/builtin-run.h @@ -4,4 +4,6 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix); void kvm_run_help(void); +void kvm_run_set_wrapper_sandbox(void); + #endif diff --git a/tools/kvm/include/kvm/builtin-sandbox.h b/tools/kvm/include/kvm/builtin-sandbox.h new file mode 100644 index 0000000..98cd6be --- /dev/null +++ b/tools/kvm/include/kvm/builtin-sandbox.h @@ -0,0 +1,6 @@ +#ifndef KVM__SANDBOX_H +#define KVM__SANDBOX_H + +int kvm_cmd_sandbox(int argc, const char **argv, const char *prefix); + +#endif diff --git a/tools/kvm/kvm-cmd.c b/tools/kvm/kvm-cmd.c index 96108a8..604dce4 100644 --- a/tools/kvm/kvm-cmd.c +++ b/tools/kvm/kvm-cmd.c @@ -15,6 +15,7 @@ #include "kvm/builtin-stop.h" #include "kvm/builtin-stat.h" #include "kvm/builtin-help.h" +#include "kvm/builtin-sandbox.h" #include "kvm/kvm-cmd.h" #include "kvm/builtin-run.h" #include "kvm/util.h" @@ -32,6 +33,7 @@ struct cmd_struct kvm_commands[] = { { "help", kvm_cmd_help, NULL, 0 }, { "setup", kvm_cmd_setup, kvm_setup_help, 0 }, { "run", kvm_cmd_run, kvm_run_help, 0 }, + { "sandbox", kvm_cmd_sandbox, kvm_run_help, 0 }, { NULL, NULL, NULL, 0 }, }; -- 1.7.8 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html