]> xenbits.xensource.com Git - libvirt.git/commitdiff
Make non-KVM machines work with QMP probing
authorMartin Kletzander <mkletzan@redhat.com>
Wed, 31 Oct 2012 07:31:49 +0000 (08:31 +0100)
committerMartin Kletzander <mkletzan@redhat.com>
Wed, 31 Oct 2012 07:31:49 +0000 (08:31 +0100)
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).

src/qemu/qemu_capabilities.c
src/qemu/qemu_capabilities.h
src/qemu/qemu_monitor.c
src/qemu/qemu_monitor.h
src/qemu/qemu_monitor_json.c
src/qemu/qemu_monitor_json.h

index 619431065ee80a12a6b12e550014cf163e982df3..9f151622d654a8f531bdc8336a93e84f2f9be575 100644 (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;
 
index cce372b3acfa960a516af081228d48783b23f5a8..fb88aa13238866b2b376abc347ebb225d66d4340 100644 (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 */
 
index 3126960293c473542aa2ee7c33b106dded483752..a92f74d63ea65dbbd5e715bfdcbe1a607d8ef97c 100644 (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)
 {
index f6a4a47a05b07689e9bb83e55db7094d74ce4bac..dbfab880393fa5fdfc58d2d26087c4a04fd2b92f 100644 (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,
index 9a1f2dc9c2c04b87b74a846c5f88885ec388d52e..e4f21667b93ea871b58efcd7347dd2ab88eea520 100644 (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)
 {
index 2834fed5342391330b2ddd35946b7181310587d5..c62ae249e9830f63032f7af9c532a7188dbb1408 100644 (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);