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 <mingo@xxxxxxx> Signed-off-by: Sasha Levin <levinsasha928@xxxxxxxxx> --- tools/kvm/builtin-run.c | 32 ++++++++++++++++++++++++++++++++ tools/kvm/guest/init.c | 13 ++++++++++++- 2 files changed, 44 insertions(+), 1 deletions(-) diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c index 33de4f6..f5341ae 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", @@ -702,6 +705,32 @@ void kvm_run_help(void) usage_with_options(run_usage, options); } +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]; @@ -861,7 +890,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"); } diff --git a/tools/kvm/guest/init.c b/tools/kvm/guest/init.c index 8975023..b71491c 100644 --- a/tools/kvm/guest/init.c +++ b/tools/kvm/guest/init.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); +} + static void do_mounts(void) { mount("hostfs", "/host", "9p", MS_RDONLY, "trans=virtio,version=9p2000.L"); @@ -38,7 +46,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.rc4 -- 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