From c29e6d480552053e3a233e63dcb65b07f0a98247 Mon Sep 17 00:00:00 2001 From: Jiri Denemark Date: Thu, 27 Oct 2016 11:13:28 +0200 Subject: [PATCH] qemu: Unify cached caps validity checks Let's keep all run time validation of cached QEMU capabilities in virQEMUCapsIsValid and call it whenever we access the cache. virQEMUCapsInitCached should keep only the checks which do not make sense once the cache is loaded in memory. Signed-off-by: Jiri Denemark --- src/qemu/qemu_capabilities.c | 62 ++++++++++++++++++++++++------------ src/qemu/qemu_capabilities.h | 3 +- 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 2af441803c..ffe7bcdf43 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -3492,25 +3492,21 @@ virQEMUCapsInitCached(virCapsPtr caps, VIR_WARN("Failed to load cached caps from '%s' for '%s': %s", capsfile, qemuCaps->binary, virGetLastErrorMessage()); virResetLastError(); - ret = 0; - virQEMUCapsReset(qemuCaps); - goto cleanup; + goto discard; } + if (!virQEMUCapsIsValid(qemuCaps, qemuctime)) + goto discard; + /* Discard cache if QEMU binary or libvirtd changed */ - if (qemuctime != qemuCaps->ctime || - selfctime != virGetSelfLastChanged() || + if (selfctime != virGetSelfLastChanged() || selfvers != LIBVIR_VERSION_NUMBER) { - VIR_DEBUG("Outdated cached capabilities '%s' for '%s' " - "(%lld vs %lld, %lld vs %lld, %lu vs %lu)", - capsfile, qemuCaps->binary, - (long long)qemuCaps->ctime, (long long)qemuctime, + VIR_DEBUG("Outdated capabilities for '%s': libvirt changed " + "(%lld vs %lld, %lu vs %lu)", + qemuCaps->binary, (long long)selfctime, (long long)virGetSelfLastChanged(), selfvers, (unsigned long)LIBVIR_VERSION_NUMBER); - ignore_value(unlink(capsfile)); - virQEMUCapsReset(qemuCaps); - ret = 0; - goto cleanup; + goto discard; } VIR_DEBUG("Loaded '%s' for '%s' ctime %lld usedQMP=%d", @@ -3524,6 +3520,14 @@ virQEMUCapsInitCached(virCapsPtr caps, VIR_FREE(capsfile); VIR_FREE(capsdir); return ret; + + discard: + VIR_DEBUG("Dropping cached capabilities '%s' for '%s'", + capsfile, qemuCaps->binary); + ignore_value(unlink(capsfile)); + virQEMUCapsReset(qemuCaps); + ret = 0; + goto cleanup; } @@ -4076,17 +4080,35 @@ virQEMUCapsNewForBinary(virCapsPtr caps, } -bool virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps) +bool +virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps, + time_t ctime) { - struct stat sb; - if (!qemuCaps->binary) return true; - if (stat(qemuCaps->binary, &sb) < 0) - return false; + if (!ctime) { + struct stat sb; - return sb.st_ctime == qemuCaps->ctime; + if (stat(qemuCaps->binary, &sb) < 0) { + char ebuf[1024]; + VIR_DEBUG("Failed to stat QEMU binary '%s': %s", + qemuCaps->binary, + virStrerror(errno, ebuf, sizeof(ebuf))); + return false; + } + ctime = sb.st_ctime; + } + + if (ctime != qemuCaps->ctime) { + VIR_DEBUG("Outdated capabilities for '%s': QEMU binary changed " + "(%lld vs %lld)", + qemuCaps->binary, + (long long) ctime, (long long) qemuCaps->ctime); + return false; + } + + return true; } @@ -4179,7 +4201,7 @@ virQEMUCapsCacheLookup(virCapsPtr caps, virMutexLock(&cache->lock); ret = virHashLookup(cache->binaries, binary); if (ret && - !virQEMUCapsIsValid(ret)) { + !virQEMUCapsIsValid(ret, 0)) { 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 983ea75874..d1044043f6 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -451,7 +451,8 @@ int virQEMUCapsGetMachineTypesCaps(virQEMUCapsPtr qemuCaps, size_t *nmachines, virCapsGuestMachinePtr **machines); -bool virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps); +bool virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps, + time_t ctime); void virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps, const char *machineType);