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 <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
 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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to