This patch adds a '--sandbox' argument when used in conjuction with a custom
rootfs, it allows running a script or an executable in the guest environment
by using executables and other files from the host.

This is useful when testing code that might cause problems on the host, or
to automate kernel testing since it's now easy to link a kvm tools test
script with 'git bisect run'.

Suggested-by: Ingo Molnar <mi...@elte.hu>
Signed-off-by: Sasha Levin <levinsasha...@gmail.com>
---
 tools/kvm/builtin-run.c       |   31 +++++++++++++++++++++++++++++++
 tools/kvm/guest/init_stage2.c |   13 ++++++++++++-
 2 files changed, 43 insertions(+), 1 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index de3001e..cd14159 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -82,6 +82,7 @@ static const char *guest_mac;
 static const char *host_mac;
 static const char *script;
 static const char *guest_name;
+static const char *sandbox;
 static struct virtio_net_params *net_params;
 static bool single_step;
 static bool readonly_image[MAX_DISK_IMAGES];
@@ -420,6 +421,8 @@ static const struct option options[] = {
        OPT_CALLBACK('\0', "tty", NULL, "tty id",
                     "Remap guest TTY into a pty on the host",
                     tty_parser),
+       OPT_STRING('\0', "sandbox", &sandbox, "script",
+                       "Run this script when booting into custom rootfs"),
 
        OPT_GROUP("Kernel options:"),
        OPT_STRING('k', "kernel", &kernel_filename, "kernel",
@@ -727,6 +730,31 @@ static int kvm_custom_stage2(void)
        return r;
 }
 
+static int kvm_run_set_sandbox(void)
+{
+       const char *guestfs_name = "default";
+       char path[PATH_MAX], script[PATH_MAX], *tmp;
+
+       if (image_filename[0])
+               guestfs_name = image_filename[0];
+
+       snprintf(path, PATH_MAX, "%s%s/virt/sandbox.sh", kvm__get_dir(), 
guestfs_name);
+
+       remove(path);
+
+       if (sandbox == NULL)
+               return 0;
+
+       tmp = realpath(sandbox, NULL);
+       if (tmp == NULL)
+               return -ENOMEM;
+
+       snprintf(script, PATH_MAX, "/host/%s", tmp);
+       free(tmp);
+
+       return symlink(script, path);
+}
+
 int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 {
        static char real_cmdline[2048], default_name[20];
@@ -886,7 +914,10 @@ int kvm_cmd_run(int argc, const char **argv, const char 
*prefix)
        if (using_rootfs) {
                strcat(real_cmdline, " root=/dev/root rw 
rootflags=rw,trans=virtio,version=9p2000.L rootfstype=9p");
                if (custom_rootfs) {
+                       kvm_run_set_sandbox();
+
                        strcat(real_cmdline, " init=/virt/init");
+
                        if (!no_dhcp)
                                strcat(real_cmdline, "  ip=dhcp");
                        if (kvm_custom_stage2())
diff --git a/tools/kvm/guest/init_stage2.c b/tools/kvm/guest/init_stage2.c
index af615a0..6489fee 100644
--- a/tools/kvm/guest/init_stage2.c
+++ b/tools/kvm/guest/init_stage2.c
@@ -16,6 +16,14 @@ static int run_process(char *filename)
        return execve(filename, new_argv, new_env);
 }
 
+static int run_process_sandbox(char *filename)
+{
+       char *new_argv[] = { filename, "/virt/sandbox.sh", NULL };
+       char *new_env[] = { "TERM=linux", NULL };
+
+       return execve(filename, new_argv, new_env);
+}
+
 int main(int argc, char *argv[])
 {
        /* get session leader */
@@ -26,7 +34,10 @@ int main(int argc, char *argv[])
 
        puts("Starting '/bin/sh'...");
 
-       run_process("/bin/sh");
+       if (access("/virt/sandbox.sh", R_OK) == 0)
+               run_process_sandbox("/bin/sh");
+       else
+               run_process("/bin/sh");
 
        printf("Init failed: %s\n", strerror(errno));
 
-- 
1.7.8

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to