]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Unify cached caps validity checks
authorJiri Denemark <jdenemar@redhat.com>
Thu, 27 Oct 2016 09:13:28 +0000 (11:13 +0200)
committerJiri Denemark <jdenemar@redhat.com>
Fri, 4 Nov 2016 08:38:25 +0000 (09:38 +0100)
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 <jdenemar@redhat.com>
src/qemu/qemu_capabilities.c
src/qemu/qemu_capabilities.h

index 2af441803cfcc5d570472b5b47e2f17b87789ef0..ffe7bcdf43dfcc5ac1bb7babe37004e169102548 100644 (file)
@@ -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)
+    if (!ctime) {
+        struct stat sb;
+
+        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 sb.st_ctime == qemuCaps->ctime;
+    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);
index 983ea758744e4762235d2ceadaa84a620cda56ae..d1044043f64a140aa0b4f714c0da87f287daa201 100644 (file)
@@ -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);