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