[libvirt] [PATCH 1/2] qemu: Enhance QMP detection of KVM state

Martin Kletzander mkletzan at redhat.com
Sun Oct 28 12:55:22 UTC 2012


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 adds QMP querying for KVM state using 'query-kvm' state,
but does not set any of QEMU_CAPS_KVM and QEMU_CAPS_ENABLE_KVM flags.
That functionality is done in different patch in order to be able to
compare two possibilities and chose the better one without looking at
the part of the code that's exactly the same for both of them (this
patch).
---
 src/qemu/qemu_capabilities.c | 23 +++++++++++++++++++++
 src/qemu/qemu_monitor.c      | 23 +++++++++++++++++++++
 src/qemu/qemu_monitor.h      |  4 ++++
 src/qemu/qemu_monitor_json.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_monitor_json.h |  5 +++++
 5 files changed, 103 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 115a054..fe462e9 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2026,6 +2026,27 @@ 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;
+
+    /* Youre right, this code does nothing, you must have checked out
+     * some weird commit.  Go back to your room and think about what
+     * you've done, young (wo)man. */
+
+    return 0;
+}
+
+
 int qemuCapsProbeQMP(qemuCapsPtr caps,
                      qemuMonitorPtr mon)
 {
@@ -2318,6 +2339,8 @@ qemuCapsInitQMP(qemuCapsPtr caps,
         goto cleanup;
     if (qemuCapsProbeQMPCPUDefinitions(caps, mon) < 0)
         goto cleanup;
+    if (qemuCapsProbeQMPKVMState(caps, mon) < 0)
+        goto cleanup;

     ret = 0;

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 2d9c44c..2ce52f6 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3183,6 +3183,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)
 {
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 8856d9f..ccc3ab6 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -608,6 +608,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,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index e495c0a..b32cec2 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -4218,6 +4218,54 @@ cleanup:
 }


+int qemuMonitorJSONGetKVMState(qemuMonitorPtr mon,
+                               bool *enabled,
+                               bool *present)
+{
+    int ret;
+    virJSONValuePtr cmd = NULL;
+    virJSONValuePtr reply = NULL;
+    virJSONValuePtr data = NULL;
+
+    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)
 {
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 61127a7..1b83764 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -307,6 +307,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);
--
1.7.12.4




More information about the libvir-list mailing list