diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h index 7c5bf4dd7..cfeb65ecb 100644 --- a/lib/guestfs-internal.h +++ b/lib/guestfs-internal.h @@ -796,7 +796,7 @@ void guestfs_int_init_libvirt_backend (void) __attribute__((constructor)); #endif /* qemu.c */ -extern int guestfs_int_platform_has_kvm (guestfs_h *g); +extern int guestfs_int_platform_has_kvm (guestfs_h *g, const char *qemu); extern char *guestfs_int_drive_source_qemu_param (guestfs_h *g, const struct drive_source *src); extern bool guestfs_int_discard_possible (guestfs_h *g, struct drive *drv); extern char *guestfs_int_qemu_escape_param (guestfs_h *g, const char *param); diff --git a/lib/launch-direct.c b/lib/launch-direct.c index d56127f98..b2021ee2c 100644 --- a/lib/launch-direct.c +++ b/lib/launch-direct.c @@ -53,6 +53,7 @@ /* Per-handle data. */ struct backend_direct_data { + const char *qemu; /* Qemu binary name. */ pid_t pid; /* Qemu PID. */ pid_t recoverypid; /* Recovery process PID. */ @@ -499,20 +500,23 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) guestfs_int_launch_send_progress (g, 3); + data->qemu = g->hv ? : get_default_hv_direct (g, data); + debug (g, "chosen qemu: %s", data->qemu); + debug (g, "begin testing qemu features"); /* If debugging, print the qemu version. */ if (g->verbose) { CLEANUP_CMD_CLOSE struct command *cmd = guestfs_int_new_command (g); - guestfs_int_cmd_add_arg (cmd, g->hv); + guestfs_int_cmd_add_arg (cmd, data->qemu); guestfs_int_cmd_add_arg (cmd, "-version"); guestfs_int_cmd_set_stdout_callback (cmd, debug_lines, NULL, 0); guestfs_int_cmd_run (cmd); } /* Work out if KVM is supported or if the user wants to force TCG. */ - if ((has_kvm = guestfs_int_platform_has_kvm (g)) == -1) + if ((has_kvm = guestfs_int_platform_has_kvm (g, data->qemu)) == -1) goto cleanup0; debug (g, "qemu KVM: %s", has_kvm ? "enabled" : "disabled"); @@ -588,7 +592,7 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) perrorf (g, "qemuopts"); goto cleanup0; } - if (qemuopts_set_binary (qopts, g->hv) == -1) goto qemuopts_error; + if (qemuopts_set_binary (qopts, data->qemu) == -1) goto qemuopts_error; /* CVE-2011-4127 mitigation: Disable SCSI ioctls on virtio-blk * devices. @@ -874,8 +878,8 @@ launch_direct (guestfs_h *g, void *datav, const char *arg) if (g->pgroup) setpgid (0, 0); - execve (g->hv, argv, env); /* Run qemu. */ - perror (g->hv); + execvpe (data->qemu, argv, env); /* Run qemu. */ + perror (data->qemu); _exit (EXIT_FAILURE); } @@ -1078,7 +1082,7 @@ shutdown_direct (guestfs_h *g, void *datav, int check_for_errors) if (guestfs_int_wait4 (g, data->pid, &status, &rusage, "qemu") == -1) ret = -1; else if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) { - guestfs_int_external_command_failed (g, status, g->hv, NULL); + guestfs_int_external_command_failed (g, status, data->qemu, NULL); ret = -1; } else diff --git a/lib/qemu.c b/lib/qemu.c index 73fe38ff7..b0284b6d5 100644 --- a/lib/qemu.c +++ b/lib/qemu.c @@ -59,7 +59,8 @@ cleanup_json_object_put (void *ptr) * Run a generic QMP test on the QEMU binary. */ static int -generic_qmp_test (guestfs_h *g, const char *qmp_command, char **outp) +generic_qmp_test (guestfs_h *g, + const char *qemu, const char *qmp_command, char **outp) { CLEANUP_CMD_CLOSE struct command *cmd = guestfs_int_new_command (g); int r, fd; @@ -81,7 +82,7 @@ generic_qmp_test (guestfs_h *g, const char *qmp_command, char **outp) guestfs_int_cmd_add_string_unquoted (cmd, "'{ \"execute\": \"quit\" }' "); guestfs_int_cmd_add_string_unquoted (cmd, " | "); guestfs_int_cmd_add_string_unquoted (cmd, "QEMU_AUDIO_DRV=none "); - guestfs_int_cmd_add_string_quoted (cmd, g->hv); + guestfs_int_cmd_add_string_quoted (cmd, qemu); guestfs_int_cmd_add_string_unquoted (cmd, " -display none"); guestfs_int_cmd_add_string_unquoted (cmd, " -machine none,accel=kvm:hvf:tcg"); guestfs_int_cmd_add_string_unquoted (cmd, " -qmp stdio"); @@ -143,7 +144,7 @@ generic_qmp_test (guestfs_h *g, const char *qmp_command, char **outp) err: errors = guestfs_int_cmd_get_pipe_errors (cmd); - error (g, "%s: %s\nError output of qemu: %s", g->hv, errmsg, errors); + error (g, "%s: %s\nError output of qemu: %s", qemu, errmsg, errors); return -1; } @@ -191,11 +192,11 @@ parse_has_kvm (guestfs_h *g, const char *json) * that command. */ int -guestfs_int_platform_has_kvm (guestfs_h *g) +guestfs_int_platform_has_kvm (guestfs_h *g, const char *qemu) { CLEANUP_FREE char *query_kvm = NULL; - if (generic_qmp_test (g, "query-kvm", &query_kvm) == -1) + if (generic_qmp_test (g, qemu, "query-kvm", &query_kvm) == -1) return -1; return parse_has_kvm (g, query_kvm);