Make non-KVM machines work with QMP probing

When there is no 'qemu-kvm' binary and the emulator used for a machine
is, for example, 'qemu-system-x86_64' that, by default, runs without
kvm enabled, libvirt still supplies '-no-kvm' option to this process,
even though it does not recognize such option (making the start of a
domain fail in that case).

This patch fixes building a command-line for QEMU machines without KVM
acceleration and is based on following assumptions:

 - QEMU_CAPS_KVM flag means that QEMU is running KVM accelerated
   machines by default (without explicitly requesting that using a
   command-line option).  It is the closest to the truth according to
   the code with the only exception being the comment next to the
   flag, so it's fixed in this patch as well.

 - QEMU_CAPS_ENABLE_KVM flag means that QEMU is, by default, running
   without KVM acceleration and in case we need KVM acceleration it
   needs to be explicitly instructed to do so.  This is partially
   true for the past (this option essentially means that QEMU
   recognizes the '-enable-kvm' option, even though it's almost the
   same).
This commit is contained in:
Martin Kletzander 2012-10-31 08:31:49 +01:00
parent adaa7ab653
commit 037a49dc66
6 changed files with 113 additions and 2 deletions

View File

@ -2030,6 +2030,33 @@ qemuCapsProbeQMPCPUDefinitions(qemuCapsPtr caps,
}
static int
qemuCapsProbeQMPKVMState(qemuCapsPtr caps,
qemuMonitorPtr mon)
{
bool enabled = false;
bool present = false;
if (!qemuCapsGet(caps, QEMU_CAPS_KVM))
return 0;
if (qemuMonitorGetKVMState(mon, &enabled, &present) < 0)
return -1;
/* The QEMU_CAPS_KVM flag was initially set according to the QEMU
* reporting the recognition of 'query-kvm' QMP command, but the
* flag means whether the KVM is enabled by default and should be
* disabled in case we want SW emulated machine, so let's fix that
* if it's true. */
if (!enabled) {
qemuCapsClear(caps, QEMU_CAPS_KVM);
qemuCapsSet(caps, QEMU_CAPS_ENABLE_KVM);
}
return 0;
}
int qemuCapsProbeQMP(qemuCapsPtr caps,
qemuMonitorPtr mon)
{
@ -2160,7 +2187,6 @@ qemuCapsInitQMPBasic(qemuCapsPtr caps)
qemuCapsSet(caps, QEMU_CAPS_DRIVE_SERIAL);
qemuCapsSet(caps, QEMU_CAPS_MIGRATE_QEMU_UNIX);
qemuCapsSet(caps, QEMU_CAPS_CHARDEV);
qemuCapsSet(caps, QEMU_CAPS_ENABLE_KVM);
qemuCapsSet(caps, QEMU_CAPS_MONITOR_JSON);
qemuCapsSet(caps, QEMU_CAPS_BALLOON);
qemuCapsSet(caps, QEMU_CAPS_DEVICE);
@ -2322,6 +2348,8 @@ qemuCapsInitQMP(qemuCapsPtr caps,
goto cleanup;
if (qemuCapsProbeQMPCPUDefinitions(caps, mon) < 0)
goto cleanup;
if (qemuCapsProbeQMPKVMState(caps, mon) < 0)
goto cleanup;
ret = 0;

View File

@ -45,7 +45,7 @@ enum qemuCapsFlags {
QEMU_CAPS_MIGRATE_QEMU_TCP = 10, /* have qemu tcp migration */
QEMU_CAPS_MIGRATE_QEMU_EXEC = 11, /* have qemu exec migration */
QEMU_CAPS_DRIVE_CACHE_V2 = 12, /* cache= flag wanting new v2 values */
QEMU_CAPS_KVM = 13, /* Whether KVM is compiled in */
QEMU_CAPS_KVM = 13, /* Whether KVM is enabled by default */
QEMU_CAPS_DRIVE_FORMAT = 14, /* Is -drive format= avail */
QEMU_CAPS_VGA = 15, /* Is -vga avail */

View File

@ -3235,6 +3235,29 @@ int qemuMonitorGetEvents(qemuMonitorPtr mon,
}
int qemuMonitorGetKVMState(qemuMonitorPtr mon,
bool *enabled,
bool *present)
{
VIR_DEBUG("mon=%p enabled=%p present=%p",
mon, enabled, present);
if (!mon) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
_("monitor must not be NULL"));
return -1;
}
if (!mon->json) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("JSON monitor is required"));
return -1;
}
return qemuMonitorJSONGetKVMState(mon, enabled, present);
}
int qemuMonitorGetObjectTypes(qemuMonitorPtr mon,
char ***types)
{

View File

@ -620,6 +620,10 @@ int qemuMonitorGetCommands(qemuMonitorPtr mon,
int qemuMonitorGetEvents(qemuMonitorPtr mon,
char ***events);
int qemuMonitorGetKVMState(qemuMonitorPtr mon,
bool *enabled,
bool *present);
int qemuMonitorGetObjectTypes(qemuMonitorPtr mon,
char ***types);
int qemuMonitorGetObjectProps(qemuMonitorPtr mon,

View File

@ -4293,6 +4293,57 @@ cleanup:
}
int qemuMonitorJSONGetKVMState(qemuMonitorPtr mon,
bool *enabled,
bool *present)
{
int ret;
virJSONValuePtr cmd = NULL;
virJSONValuePtr reply = NULL;
virJSONValuePtr data = NULL;
/* Safe defaults */
*enabled = *present = false;
if (!(cmd = qemuMonitorJSONMakeCommand("query-kvm", NULL)))
return -1;
ret = qemuMonitorJSONCommand(mon, cmd, &reply);
if (ret == 0) {
if (qemuMonitorJSONHasError(reply, "CommandNotFound"))
goto cleanup;
ret = qemuMonitorJSONCheckError(cmd, reply);
}
if (ret < 0)
goto cleanup;
ret = -1;
if (!(data = virJSONValueObjectGet(reply, "return"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("query-kvm reply was missing return data"));
goto cleanup;
}
if (virJSONValueObjectGetBoolean(data, "enabled", enabled) < 0 ||
virJSONValueObjectGetBoolean(data, "present", present) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("query-kvm replied unexpected data"));
goto cleanup;
}
ret = 0;
cleanup:
virJSONValueFree(cmd);
virJSONValueFree(reply);
return ret;
}
int qemuMonitorJSONGetObjectTypes(qemuMonitorPtr mon,
char ***types)
{

View File

@ -322,6 +322,11 @@ int qemuMonitorJSONGetEvents(qemuMonitorPtr mon,
char ***events)
ATTRIBUTE_NONNULL(2);
int qemuMonitorJSONGetKVMState(qemuMonitorPtr mon,
bool *enabled,
bool *present)
ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
int qemuMonitorJSONGetObjectTypes(qemuMonitorPtr mon,
char ***types)
ATTRIBUTE_NONNULL(2);