a41c76
From 0f8f59eee031729fb17dd9b70285665a44517850 Mon Sep 17 00:00:00 2001
a41c76
Message-Id: <0f8f59eee031729fb17dd9b70285665a44517850@dist-git>
a41c76
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
a41c76
Date: Fri, 15 May 2020 19:18:50 +0200
a41c76
Subject: [PATCH] qemu: fixing auto-detecting binary in domain capabilities
a41c76
MIME-Version: 1.0
a41c76
Content-Type: text/plain; charset=UTF-8
a41c76
Content-Transfer-Encoding: 8bit
a41c76
a41c76
The virConnectGetDomainCapabilities API accepts either a binary path
a41c76
to the emulator, or desired guest arch. If guest arch is not given,
a41c76
then the host arch is assumed.
a41c76
a41c76
In the case where the binary is not given, the code tried to find the
a41c76
emulator binary in the existing list of cached emulator capabilities.
a41c76
This is not valid since we switched to lazy population of the cache in:
a41c76
a41c76
  commit 3dd91af01f30c5bda6328454ef49f3afece755d6
a41c76
  Author: Daniel P. Berrangé <berrange@redhat.com>
a41c76
  Date:   Mon Dec 2 13:04:26 2019 +0000
a41c76
a41c76
    qemu: stop creating capabilities at driver startup
a41c76
a41c76
As a result of this change, if there are no persistent guests defined
a41c76
using the requested guest architecture, virConnectGetDomainCapabilities
a41c76
will fail to find an emulator binary.
a41c76
a41c76
The solution is to stop relying on the cached capabilities to find the
a41c76
binary and instead use the same logic we use to pick default a binary
a41c76
per arch when populating capabilities.
a41c76
a41c76
Tested-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
a41c76
Tested-by: Richard W.M. Jones <rjones@redhat.com>
a41c76
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
a41c76
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
a41c76
(cherry picked from commit 6d786f95a366600e7bbae68c1b324a8131f5e2c5)
a41c76
a41c76
https://bugzilla.redhat.com/show_bug.cgi?id=1836351
a41c76
a41c76
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
a41c76
Message-Id: <20200515171850.135870-2-abologna@redhat.com>
a41c76
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
a41c76
---
a41c76
 src/qemu/qemu_capabilities.c | 45 ++++++++++++++++++------------------
a41c76
 1 file changed, 22 insertions(+), 23 deletions(-)
a41c76
a41c76
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
a41c76
index 3bbfb64c03..5b16796c6b 100644
a41c76
--- a/src/qemu/qemu_capabilities.c
a41c76
+++ b/src/qemu/qemu_capabilities.c
a41c76
@@ -5432,10 +5432,13 @@ virQEMUCapsCacheLookupDefault(virFileCachePtr cache,
a41c76
                               const char **retMachine)
a41c76
 {
a41c76
     int virttype = VIR_DOMAIN_VIRT_NONE;
a41c76
-    int arch = virArchFromHost();
a41c76
+    virArch hostarch = virArchFromHost();
a41c76
+    virArch arch = hostarch;
a41c76
     virDomainVirtType capsType;
a41c76
     virQEMUCapsPtr qemuCaps = NULL;
a41c76
     virQEMUCapsPtr ret = NULL;
a41c76
+    virArch arch_from_caps;
a41c76
+    g_autofree char *probedbinary = NULL;
a41c76
 
a41c76
     if (virttypeStr &&
a41c76
         (virttype = virDomainVirtTypeFromString(virttypeStr)) < 0) {
a41c76
@@ -5451,31 +5454,27 @@ virQEMUCapsCacheLookupDefault(virFileCachePtr cache,
a41c76
         goto cleanup;
a41c76
     }
a41c76
 
a41c76
-    if (binary) {
a41c76
-        virArch arch_from_caps;
a41c76
+    if (!binary) {
a41c76
+        probedbinary = virQEMUCapsGetDefaultEmulator(hostarch, arch);
a41c76
+        binary = probedbinary;
a41c76
+    }
a41c76
 
a41c76
-        if (!(qemuCaps = virQEMUCapsCacheLookup(cache, binary)))
a41c76
-            goto cleanup;
a41c76
+    if (!(qemuCaps = virQEMUCapsCacheLookup(cache, binary)))
a41c76
+        goto cleanup;
a41c76
 
a41c76
-        arch_from_caps = virQEMUCapsGetArch(qemuCaps);
a41c76
+    arch_from_caps = virQEMUCapsGetArch(qemuCaps);
a41c76
 
a41c76
-        if (arch_from_caps != arch &&
a41c76
-            !((ARCH_IS_X86(arch) && ARCH_IS_X86(arch_from_caps)) ||
a41c76
-              (ARCH_IS_PPC(arch) && ARCH_IS_PPC(arch_from_caps)) ||
a41c76
-              (ARCH_IS_ARM(arch) && ARCH_IS_ARM(arch_from_caps)) ||
a41c76
-              (ARCH_IS_S390(arch) && ARCH_IS_S390(arch_from_caps)))) {
a41c76
-            virReportError(VIR_ERR_INVALID_ARG,
a41c76
-                           _("architecture from emulator '%s' doesn't "
a41c76
-                             "match given architecture '%s'"),
a41c76
-                           virArchToString(arch_from_caps),
a41c76
-                           virArchToString(arch));
a41c76
-            goto cleanup;
a41c76
-        }
a41c76
-    } else {
a41c76
-        if (!(qemuCaps = virQEMUCapsCacheLookupByArch(cache, arch)))
a41c76
-            goto cleanup;
a41c76
-
a41c76
-        binary = virQEMUCapsGetBinary(qemuCaps);
a41c76
+    if (arch_from_caps != arch &&
a41c76
+        !((ARCH_IS_X86(arch) && ARCH_IS_X86(arch_from_caps)) ||
a41c76
+          (ARCH_IS_PPC(arch) && ARCH_IS_PPC(arch_from_caps)) ||
a41c76
+          (ARCH_IS_ARM(arch) && ARCH_IS_ARM(arch_from_caps)) ||
a41c76
+          (ARCH_IS_S390(arch) && ARCH_IS_S390(arch_from_caps)))) {
a41c76
+        virReportError(VIR_ERR_INVALID_ARG,
a41c76
+                       _("architecture from emulator '%s' doesn't "
a41c76
+                         "match given architecture '%s'"),
a41c76
+                       virArchToString(arch_from_caps),
a41c76
+                       virArchToString(arch));
a41c76
+        goto cleanup;
a41c76
     }
a41c76
 
a41c76
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
a41c76
-- 
a41c76
2.26.2
a41c76