From d87df9bd39bdac2b64284d5ca1a932767abde3bd Mon Sep 17 00:00:00 2001 From: Jiri Denemark Date: Wed, 15 Jun 2016 17:21:08 +0200 Subject: [PATCH] qemu: Discard caps cache when KVM availability changes Since some may depend on the accelerator used when probing QEMU the cache becomes invalid when KVM becomes available or if it is not available anymore. Signed-off-by: Jiri Denemark --- src/qemu/qemu_capabilities.c | 37 +++++++++++++++++++++++++++++++----- src/qemu/qemu_capabilities.h | 4 +++- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 3d62fc520f..ecc1d29bbb 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -3455,7 +3455,9 @@ virQEMUCapsReset(virQEMUCapsPtr qemuCaps) static int virQEMUCapsInitCached(virCapsPtr caps, virQEMUCapsPtr qemuCaps, - const char *cacheDir) + const char *cacheDir, + uid_t runUid, + gid_t runGid) { char *capsdir = NULL; char *capsfile = NULL; @@ -3505,7 +3507,7 @@ virQEMUCapsInitCached(virCapsPtr caps, goto discard; } - if (!virQEMUCapsIsValid(qemuCaps, qemuctime)) + if (!virQEMUCapsIsValid(qemuCaps, qemuctime, runUid, runGid)) goto discard; /* Discard cache if QEMU binary or libvirtd changed */ @@ -4357,7 +4359,8 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps, if (!cacheDir) rv = 0; - else if ((rv = virQEMUCapsInitCached(caps, qemuCaps, cacheDir)) < 0) + else if ((rv = virQEMUCapsInitCached(caps, qemuCaps, cacheDir, + runUid, runGid)) < 0) goto error; if (rv == 0) { @@ -4412,8 +4415,12 @@ virQEMUCapsNewForBinary(virCapsPtr caps, bool virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps, - time_t qemuctime) + time_t qemuctime, + uid_t runUid, + gid_t runGid) { + bool kvmUsable; + if (!qemuCaps->binary) return true; @@ -4438,6 +4445,26 @@ virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps, return false; } + kvmUsable = virFileAccessibleAs("/dev/kvm", R_OK | W_OK, + runUid, runGid) == 0; + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) && + virQEMUCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KVM) && + kvmUsable) { + VIR_DEBUG("KVM was not enabled when probing '%s', " + "but it should be usable now", + qemuCaps->binary); + return false; + } + + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) && + !kvmUsable) { + VIR_DEBUG("KVM was enabled when probing '%s', " + "but it is not available now", + qemuCaps->binary); + return false; + } + return true; } @@ -4531,7 +4558,7 @@ virQEMUCapsCacheLookup(virCapsPtr caps, virMutexLock(&cache->lock); ret = virHashLookup(cache->binaries, binary); if (ret && - !virQEMUCapsIsValid(ret, 0)) { + !virQEMUCapsIsValid(ret, 0, cache->runUid, cache->runGid)) { VIR_DEBUG("Cached capabilities %p no longer valid for %s", ret, binary); virHashRemoveEntry(cache->binaries, binary); diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index cfd00663bf..d44cf2c4d7 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -452,7 +452,9 @@ int virQEMUCapsGetMachineTypesCaps(virQEMUCapsPtr qemuCaps, virCapsGuestMachinePtr **machines); bool virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps, - time_t ctime); + time_t ctime, + uid_t runUid, + gid_t runGid); void virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps, const char *machineType);