]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: require qmp on new enough qemu
authorEric Blake <eblake@redhat.com>
Thu, 26 Jan 2012 04:57:38 +0000 (21:57 -0700)
committerEric Blake <eblake@redhat.com>
Fri, 27 Jan 2012 15:45:50 +0000 (08:45 -0700)
The qemu developers have made it clear that modern qemu will no
longer guarantee human monitor command stability; furthermore,
some features, such as async events, are only supported via qmp.
If we are compiled without support for handling JSON, we cannot
expect to sanely interact with modern qemu.

However, things must continue to build on RHEL 5, where qemu
is stuck at 0.10, and where yajl is not available.

Another benefit of this patch: future additions of new monitor
commands need only focus on qemu_monitor_json.c, instead of
also wasting time with qemu_monitor_text.c.

* src/qemu/qemu_capabilities.c (qemuCapsComputeCmdFlags): Report
error if yajl is missing but qemu requires qmp.
(qemuCapsParseHelpStr): Propagate error.
(qemuCapsExtractVersionInfo): Update caller.
* tests/qemuhelptest.c (testHelpStrParsing): Likewise.

src/qemu/qemu_capabilities.c
src/qemu/qemu_capabilities.h
tests/qemuhelptest.c

index c4bad6f02eaa697881d895c44109274d79dc0b02..6dee9d8326bc7a1ca3bf9932ed3a05ba50225a4d 100644 (file)
@@ -982,12 +982,13 @@ virCapsPtr qemuCapsInit(virCapsPtr old_caps)
 }
 
 
-static void
+static int
 qemuCapsComputeCmdFlags(const char *help,
                         unsigned int version,
                         unsigned int is_kvm,
                         unsigned int kvm_version,
-                        virBitmapPtr flags)
+                        virBitmapPtr flags,
+                        bool check_yajl ATTRIBUTE_UNUSED)
 {
     const char *p;
     const char *fsdev;
@@ -1184,6 +1185,24 @@ qemuCapsComputeCmdFlags(const char *help,
         qemuCapsSet(flags, QEMU_CAPS_MONITOR_JSON);
         qemuCapsSet(flags, QEMU_CAPS_NETDEV);
     }
+#else
+    /* Starting with qemu 0.15 and newer, upstream qemu no longer
+     * promises to keep the human interface stable, but requests that
+     * we use QMP (the JSON interface) for everything.  If the user
+     * forgot to include YAJL libraries when building their own
+     * libvirt but is targetting a newer qemu, we are better off
+     * telling them to recompile (the spec file includes the
+     * dependency, so distros won't hit this).  */
+    if (version >= 15000 ||
+        (version >= 12000 && strstr(help, "libvirt"))) {
+        if (check_yajl) {
+            qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                            _("this qemu binary requires libvirt to be "
+                              "compiled with yajl"));
+            return -1;
+        }
+        qemuCapsSet(flags, QEMU_CAPS_NETDEV);
+    }
 #endif
 
     if (version >= 13000)
@@ -1204,6 +1223,7 @@ qemuCapsComputeCmdFlags(const char *help,
 
     if (version >= 11000)
         qemuCapsSet(flags, QEMU_CAPS_CPU_HOST);
+    return 0;
 }
 
 /* We parse the output of 'qemu -help' to get the QEMU
@@ -1235,7 +1255,8 @@ int qemuCapsParseHelpStr(const char *qemu,
                          virBitmapPtr flags,
                          unsigned int *version,
                          unsigned int *is_kvm,
-                         unsigned int *kvm_version)
+                         unsigned int *kvm_version,
+                         bool check_yajl)
 {
     unsigned major, minor, micro;
     const char *p = help;
@@ -1291,7 +1312,9 @@ int qemuCapsParseHelpStr(const char *qemu,
 
     *version = (major * 1000 * 1000) + (minor * 1000) + micro;
 
-    qemuCapsComputeCmdFlags(help, *version, *is_kvm, *kvm_version, flags);
+    if (qemuCapsComputeCmdFlags(help, *version, *is_kvm, *kvm_version,
+                                flags, check_yajl) < 0)
+        goto cleanup;
 
     strflags = virBitmapString(flags);
     VIR_DEBUG("Version %u.%u.%u, cooked version %u, flags %s",
@@ -1314,6 +1337,7 @@ fail:
                     _("cannot parse %s version number in '%s'"),
                     qemu, p ? p : help);
 
+cleanup:
     VIR_FREE(p);
 
     return -1;
@@ -1455,7 +1479,7 @@ int qemuCapsExtractVersionInfo(const char *qemu, const char *arch,
 
     if (!(flags = qemuCapsNew()) ||
         qemuCapsParseHelpStr(qemu, help, flags,
-                             &version, &is_kvm, &kvm_version) == -1)
+                             &version, &is_kvm, &kvm_version, true) == -1)
         goto cleanup;
 
     /* Currently only x86_64 and i686 support PCI-multibus. */
index 8b009f96e1aa15455e3e1c21f97e707530aa4c0a..18d6bc853b9d69d2fb14275ea6e2405a263b271d 100644 (file)
@@ -162,7 +162,8 @@ int qemuCapsParseHelpStr(const char *qemu,
                          virBitmapPtr qemuCaps,
                          unsigned int *version,
                          unsigned int *is_kvm,
-                         unsigned int *kvm_version);
+                         unsigned int *kvm_version,
+                         bool check_yajl);
 int qemuCapsParseDeviceStr(const char *str,
                            virBitmapPtr qemuCaps);
 
index 5ad55bc730b2a216d8b5c776d5249aa01ded617e..370cd0ddc85d333edd03d6935e4cc3e74a6b2b01 100644 (file)
@@ -53,7 +53,7 @@ static int testHelpStrParsing(const void *data)
         goto cleanup;
 
     if (qemuCapsParseHelpStr("QEMU", help, flags,
-                             &version, &is_kvm, &kvm_version) == -1)
+                             &version, &is_kvm, &kvm_version, false) == -1)
         goto cleanup;
 
 # ifndef HAVE_YAJL