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