Even though qemu-kvm binaries can be used in TCG mode, libvirt would only detect them if /dev/kvm was available. Thus, one would need to make a /usr/bin/qemu symlink to be able to use TCG mode with qemu-kvm in an environment without KVM support. And even though QEMU is able to make use of KVM, libvirt would not advertise KVM support unless there was a qemu-kvm symlink available. This patch fixes both issues. --- src/qemu/qemu_capabilities.c | 95 ++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 42 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 9e4d927..cbea365 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -645,6 +645,7 @@ qemuCapsInitGuest(virCapsPtr caps, struct stat st; unsigned int ncpus; virBitmapPtr qemuCaps = NULL; + virBitmapPtr kvmCaps = NULL; int ret = -1; /* Check for existance of base emulator, or alternate base @@ -657,7 +658,12 @@ qemuCapsInitGuest(virCapsPtr caps, binary = virFindFileInPath(info->altbinary); } - /* Can use acceleration for KVM/KQEMU if + /* Ignore binary if extracting version info fails */ + if (binary && + qemuCapsExtractVersionInfo(binary, info->arch, NULL, &qemuCaps) < 0) + VIR_FREE(binary); + + /* qemu-kvm/kvm binaries can only be used if * - host & guest arches match * Or * - hostarch is x86_64 and guest arch is i686 @@ -665,37 +671,44 @@ qemuCapsInitGuest(virCapsPtr caps, */ if (STREQ(info->arch, hostmachine) || (STREQ(hostmachine, "x86_64") && STREQ(info->arch, "i686"))) { - if (access("/dev/kvm", F_OK) == 0) { - const char *const kvmbins[] = { "/usr/libexec/qemu-kvm", /* RHEL */ - "qemu-kvm", /* Fedora */ - "kvm" }; /* Upstream .spec */ + const char *const kvmbins[] = { "/usr/libexec/qemu-kvm", /* RHEL */ + "qemu-kvm", /* Fedora */ + "kvm" }; /* Upstream .spec */ - for (i = 0; i < ARRAY_CARDINALITY(kvmbins); ++i) { - kvmbin = virFindFileInPath(kvmbins[i]); + for (i = 0; i < ARRAY_CARDINALITY(kvmbins); ++i) { + kvmbin = virFindFileInPath(kvmbins[i]); - if (!kvmbin) - continue; + if (!kvmbin) + continue; - haskvm = 1; - if (!binary) - binary = kvmbin; + if (qemuCapsExtractVersionInfo(kvmbin, info->arch, + NULL, &kvmCaps) < 0) { + VIR_FREE(kvmbin); + continue; + } - break; + if (!binary) { + binary = kvmbin; + qemuCaps = kvmCaps; + kvmbin = NULL; + kvmCaps = NULL; } + break; } - - if (access("/dev/kqemu", F_OK) == 0) - haskqemu = 1; } if (!binary) return 0; - /* Ignore binary if extracting version info fails */ - if (qemuCapsExtractVersionInfo(binary, info->arch, NULL, &qemuCaps) < 0) { - ret = 0; - goto cleanup; - } + if (access("/dev/kvm", F_OK) == 0 && + (qemuCapsGet(qemuCaps, QEMU_CAPS_KVM) || + qemuCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KVM) || + kvmbin)) + haskvm = 1; + + if (access("/dev/kqemu", F_OK) == 0 && + qemuCapsGet(qemuCaps, QEMU_CAPS_KQEMU)) + haskqemu = 1; if (stat(binary, &st) == 0) { binary_mtime = st.st_mtime; @@ -787,21 +800,23 @@ qemuCapsInitGuest(virCapsPtr caps, if (haskvm) { virCapsGuestDomainPtr dom; - if (stat(kvmbin, &st) == 0) { - binary_mtime = st.st_mtime; - } else { - char ebuf[1024]; - VIR_WARN("Failed to stat %s, most peculiar : %s", - binary, virStrerror(errno, ebuf, sizeof(ebuf))); - binary_mtime = 0; - } - - if (!STREQ(binary, kvmbin)) { + if (kvmbin) { int probe = 1; + + if (stat(kvmbin, &st) == 0) { + binary_mtime = st.st_mtime; + } else { + char ebuf[1024]; + VIR_WARN("Failed to stat %s, most peculiar : %s", + binary, virStrerror(errno, ebuf, sizeof(ebuf))); + binary_mtime = 0; + } + if (old_caps && binary_mtime) - probe = !qemuCapsGetOldMachines("hvm", info->arch, info->wordsize, - kvmbin, binary_mtime, - old_caps, &machines, &nmachines); + probe = !qemuCapsGetOldMachines("hvm", info->arch, + info->wordsize, kvmbin, + binary_mtime, old_caps, + &machines, &nmachines); if (probe && qemuCapsProbeMachineTypes(kvmbin, qemuCaps, &machines, &nmachines) < 0) @@ -810,7 +825,7 @@ qemuCapsInitGuest(virCapsPtr caps, if ((dom = virCapabilitiesAddGuestDomain(guest, "kvm", - kvmbin, + kvmbin ? kvmbin : binary, NULL, nmachines, machines)) == NULL) { @@ -845,14 +860,10 @@ qemuCapsInitGuest(virCapsPtr caps, ret = 0; cleanup: - if (binary == kvmbin) { - /* don't double free */ - VIR_FREE(binary); - } else { - VIR_FREE(binary); - VIR_FREE(kvmbin); - } + VIR_FREE(binary); + VIR_FREE(kvmbin); qemuCapsFree(qemuCaps); + qemuCapsFree(kvmCaps); return ret; -- 1.7.11.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list