|
|
7a3408 |
From d890a1ebfea47603a67def4658166f061a801313 Mon Sep 17 00:00:00 2001
|
|
|
7a3408 |
Message-Id: <d890a1ebfea47603a67def4658166f061a801313@dist-git>
|
|
|
7a3408 |
From: Andrea Bolognani <abologna@redhat.com>
|
|
|
7a3408 |
Date: Wed, 16 Sep 2015 11:07:42 +0200
|
|
|
7a3408 |
Subject: [PATCH] qemu: Fix using guest architecture as lookup key
|
|
|
7a3408 |
|
|
|
7a3408 |
When looking for a QEMU binary suitable for running ppc64le guests
|
|
|
7a3408 |
we have to take into account the fact that we use the QEMU target
|
|
|
7a3408 |
as key for the hash, so direct comparison is not good enough.
|
|
|
7a3408 |
|
|
|
7a3408 |
Factor out the logic from virQEMUCapsFindBinaryForArch() to a new
|
|
|
7a3408 |
virQEMUCapsFindTarget() function and use that both when looking
|
|
|
7a3408 |
for QEMU binaries available on the system and when looking up
|
|
|
7a3408 |
QEMU capabilities later.
|
|
|
7a3408 |
|
|
|
7a3408 |
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1260753
|
|
|
7a3408 |
(cherry picked from commit eb36666d22d52ecf0a1755dd0a8a45de982e00fb)
|
|
|
7a3408 |
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
|
|
|
7a3408 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
7a3408 |
---
|
|
|
7a3408 |
src/qemu/qemu_capabilities.c | 107 +++++++++++++++++++++++++++++--------------
|
|
|
7a3408 |
1 file changed, 72 insertions(+), 35 deletions(-)
|
|
|
7a3408 |
|
|
|
7a3408 |
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
|
|
|
7a3408 |
index faebeac..5b21307 100644
|
|
|
7a3408 |
--- a/src/qemu/qemu_capabilities.c
|
|
|
7a3408 |
+++ b/src/qemu/qemu_capabilities.c
|
|
|
7a3408 |
@@ -381,6 +381,28 @@ static const char *virQEMUCapsArchToString(virArch arch)
|
|
|
7a3408 |
return virArchToString(arch);
|
|
|
7a3408 |
}
|
|
|
7a3408 |
|
|
|
7a3408 |
+/* Given a host and guest architectures, find a suitable QEMU target.
|
|
|
7a3408 |
+ *
|
|
|
7a3408 |
+ * This is meant to be used as a second attempt if qemu-system-$guestarch
|
|
|
7a3408 |
+ * can't be found, eg. on a x86_64 host you want to use qemu-system-i386,
|
|
|
7a3408 |
+ * if available, instead of qemu-system-x86_64 to run i686 guests */
|
|
|
7a3408 |
+static virArch
|
|
|
7a3408 |
+virQEMUCapsFindTarget(virArch hostarch,
|
|
|
7a3408 |
+ virArch guestarch)
|
|
|
7a3408 |
+{
|
|
|
7a3408 |
+ /* Both ppc64 and ppc64le guests can use the ppc64 target */
|
|
|
7a3408 |
+ if (ARCH_IS_PPC64(guestarch))
|
|
|
7a3408 |
+ guestarch = VIR_ARCH_PPC64;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ /* armv7l guests on aarch64 hosts can use the aarch64 target
|
|
|
7a3408 |
+ * i686 guests on x86_64 hosts can use the x86_64 target */
|
|
|
7a3408 |
+ if ((guestarch == VIR_ARCH_ARMV7L && hostarch == VIR_ARCH_AARCH64) ||
|
|
|
7a3408 |
+ (guestarch == VIR_ARCH_I686 && hostarch == VIR_ARCH_X86_64)) {
|
|
|
7a3408 |
+ return hostarch;
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ return guestarch;
|
|
|
7a3408 |
+}
|
|
|
7a3408 |
|
|
|
7a3408 |
static virCommandPtr
|
|
|
7a3408 |
virQEMUCapsProbeCommand(const char *qemu,
|
|
|
7a3408 |
@@ -685,51 +707,55 @@ virQEMUCapsProbeCPUModels(virQEMUCapsPtr qemuCaps, uid_t runUid, gid_t runGid)
|
|
|
7a3408 |
return ret;
|
|
|
7a3408 |
}
|
|
|
7a3408 |
|
|
|
7a3408 |
+static char *
|
|
|
7a3408 |
+virQEMUCapsFindBinary(const char *format,
|
|
|
7a3408 |
+ const char *archstr)
|
|
|
7a3408 |
+{
|
|
|
7a3408 |
+ char *ret = NULL;
|
|
|
7a3408 |
+ char *binary = NULL;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ if (virAsprintf(&binary, format, archstr) < 0)
|
|
|
7a3408 |
+ goto out;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ ret = virFindFileInPath(binary);
|
|
|
7a3408 |
+ VIR_FREE(binary);
|
|
|
7a3408 |
+ if (ret && virFileIsExecutable(ret))
|
|
|
7a3408 |
+ goto out;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ VIR_FREE(ret);
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ out:
|
|
|
7a3408 |
+ return ret;
|
|
|
7a3408 |
+}
|
|
|
7a3408 |
|
|
|
7a3408 |
static char *
|
|
|
7a3408 |
virQEMUCapsFindBinaryForArch(virArch hostarch,
|
|
|
7a3408 |
virArch guestarch)
|
|
|
7a3408 |
{
|
|
|
7a3408 |
- char *ret;
|
|
|
7a3408 |
+ char *ret = NULL;
|
|
|
7a3408 |
const char *archstr;
|
|
|
7a3408 |
- char *binary;
|
|
|
7a3408 |
+ virArch target;
|
|
|
7a3408 |
|
|
|
7a3408 |
- if (ARCH_IS_PPC64(guestarch))
|
|
|
7a3408 |
- archstr = virQEMUCapsArchToString(VIR_ARCH_PPC64);
|
|
|
7a3408 |
- else
|
|
|
7a3408 |
- archstr = virQEMUCapsArchToString(guestarch);
|
|
|
7a3408 |
+ /* First attempt: try the guest architecture as it is */
|
|
|
7a3408 |
+ archstr = virQEMUCapsArchToString(guestarch);
|
|
|
7a3408 |
+ if ((ret = virQEMUCapsFindBinary("qemu-system-%s", archstr)) != NULL)
|
|
|
7a3408 |
+ goto out;
|
|
|
7a3408 |
|
|
|
7a3408 |
- if (virAsprintf(&binary, "qemu-system-%s", archstr) < 0)
|
|
|
7a3408 |
- return NULL;
|
|
|
7a3408 |
-
|
|
|
7a3408 |
- ret = virFindFileInPath(binary);
|
|
|
7a3408 |
- VIR_FREE(binary);
|
|
|
7a3408 |
- if (ret && !virFileIsExecutable(ret))
|
|
|
7a3408 |
- VIR_FREE(ret);
|
|
|
7a3408 |
-
|
|
|
7a3408 |
- if (guestarch == VIR_ARCH_ARMV7L &&
|
|
|
7a3408 |
- !ret &&
|
|
|
7a3408 |
- hostarch == VIR_ARCH_AARCH64) {
|
|
|
7a3408 |
- ret = virFindFileInPath("qemu-system-aarch64");
|
|
|
7a3408 |
- if (ret && !virFileIsExecutable(ret))
|
|
|
7a3408 |
- VIR_FREE(ret);
|
|
|
7a3408 |
- }
|
|
|
7a3408 |
-
|
|
|
7a3408 |
- if (guestarch == VIR_ARCH_I686 &&
|
|
|
7a3408 |
- !ret &&
|
|
|
7a3408 |
- hostarch == VIR_ARCH_X86_64) {
|
|
|
7a3408 |
- ret = virFindFileInPath("qemu-system-x86_64");
|
|
|
7a3408 |
- if (ret && !virFileIsExecutable(ret))
|
|
|
7a3408 |
- VIR_FREE(ret);
|
|
|
7a3408 |
+ /* Second attempt: try looking up by target instead */
|
|
|
7a3408 |
+ target = virQEMUCapsFindTarget(hostarch, guestarch);
|
|
|
7a3408 |
+ if (target != guestarch) {
|
|
|
7a3408 |
+ archstr = virQEMUCapsArchToString(target);
|
|
|
7a3408 |
+ if ((ret = virQEMUCapsFindBinary("qemu-system-%s", archstr)) != NULL)
|
|
|
7a3408 |
+ goto out;
|
|
|
7a3408 |
}
|
|
|
7a3408 |
|
|
|
7a3408 |
- if (guestarch == VIR_ARCH_I686 &&
|
|
|
7a3408 |
- !ret) {
|
|
|
7a3408 |
- ret = virFindFileInPath("qemu");
|
|
|
7a3408 |
- if (ret && !virFileIsExecutable(ret))
|
|
|
7a3408 |
- VIR_FREE(ret);
|
|
|
7a3408 |
+ /* Third attempt, i686 only: try 'qemu' */
|
|
|
7a3408 |
+ if (guestarch == VIR_ARCH_I686) {
|
|
|
7a3408 |
+ if ((ret = virQEMUCapsFindBinary("%s", "qemu")) != NULL)
|
|
|
7a3408 |
+ goto out;
|
|
|
7a3408 |
}
|
|
|
7a3408 |
|
|
|
7a3408 |
+ out:
|
|
|
7a3408 |
return ret;
|
|
|
7a3408 |
}
|
|
|
7a3408 |
|
|
|
7a3408 |
@@ -3773,13 +3799,24 @@ virQEMUCapsCacheLookupByArch(virQEMUCapsCachePtr cache,
|
|
|
7a3408 |
virArch arch)
|
|
|
7a3408 |
{
|
|
|
7a3408 |
virQEMUCapsPtr ret = NULL;
|
|
|
7a3408 |
+ virArch target;
|
|
|
7a3408 |
struct virQEMUCapsSearchData data = { .arch = arch };
|
|
|
7a3408 |
|
|
|
7a3408 |
virMutexLock(&cache->lock);
|
|
|
7a3408 |
ret = virHashSearch(cache->binaries, virQEMUCapsCompareArch, &data);
|
|
|
7a3408 |
+ if (!ret) {
|
|
|
7a3408 |
+ /* If the first attempt at finding capabilities has failed, try
|
|
|
7a3408 |
+ * again using the QEMU target as lookup key instead */
|
|
|
7a3408 |
+ target = virQEMUCapsFindTarget(virArchFromHost(), data.arch);
|
|
|
7a3408 |
+ if (target != data.arch) {
|
|
|
7a3408 |
+ data.arch = target;
|
|
|
7a3408 |
+ ret = virHashSearch(cache->binaries, virQEMUCapsCompareArch, &data);
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+ virObjectRef(ret);
|
|
|
7a3408 |
+ virMutexUnlock(&cache->lock);
|
|
|
7a3408 |
+
|
|
|
7a3408 |
VIR_DEBUG("Returning caps %p for arch %s", ret, virArchToString(arch));
|
|
|
7a3408 |
- virObjectRef(ret);
|
|
|
7a3408 |
- virMutexUnlock(&cache->lock);
|
|
|
7a3408 |
|
|
|
7a3408 |
return ret;
|
|
|
7a3408 |
}
|
|
|
7a3408 |
--
|
|
|
7a3408 |
2.5.3
|
|
|
7a3408 |
|