[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH v3 01/20] Add a qemu capabilities cache manager



From: "Daniel P. Berrange" <berrange redhat com>

Introduce a qemuCapsCachePtr object to provide a global cache
of capabilities for QEMU binaries. The cache auto-populates
on first request for capabilities about a binary, and will
auto-refresh if the binary has changed since a previous cache
was populated

Signed-off-by: Daniel P. Berrange <berrange redhat com>
---
 src/qemu/qemu_capabilities.c | 99 ++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_capabilities.h |  9 ++++
 2 files changed, 108 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 3b08ef8..1163dd8 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -206,6 +206,11 @@ struct _qemuCaps {
     char **machineAliases;
 };
 
+struct _qemuCapsCache {
+    virMutex lock;
+    virHashTablePtr binaries;
+};
+
 
 static virClassPtr qemuCapsClass;
 static void qemuCapsDispose(void *obj);
@@ -1940,6 +1945,10 @@ qemuCapsPtr qemuCapsNewForBinary(const char *binary)
     tmp = strstr(binary, QEMU_SYSTEM_PREFIX);
     if (tmp) {
         tmp += strlen(QEMU_SYSTEM_PREFIX);
+
+        /* For historical compat we uses 'itanium' as arch name */
+        if (STREQ(tmp, "ia64"))
+            tmp = "itanium";
     } else {
         uname_normalize(&ut);
         tmp = ut.machine;
@@ -2048,3 +2057,93 @@ bool qemuCapsIsValid(qemuCapsPtr caps)
 
     return sb.st_mtime == caps->mtime;
 }
+
+
+static void
+qemuCapsHashDataFree(void *payload, const void *key ATTRIBUTE_UNUSED)
+{
+    virObjectUnref(payload);
+}
+
+qemuCapsCachePtr qemuCapsCacheNew(void)
+{
+    qemuCapsCachePtr cache;
+
+    if (VIR_ALLOC(cache) < 0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    if (virMutexInit(&cache->lock) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Unable to initialize mutex"));
+        VIR_FREE(cache);
+        return NULL;
+    }
+
+    if (!(cache->binaries = virHashCreate(10, qemuCapsHashDataFree)))
+        goto error;
+
+    return cache;
+
+error:
+    qemuCapsCacheFree(cache);
+    return NULL;
+}
+
+
+qemuCapsPtr qemuCapsCacheLookup(qemuCapsCachePtr cache, const char *binary)
+{
+    qemuCapsPtr ret = NULL;
+    virMutexLock(&cache->lock);
+    ret = virHashLookup(cache->binaries, binary);
+    if (ret &&
+        !qemuCapsIsValid(ret)) {
+        VIR_DEBUG("Cached capabilities %p no longer valid for %s",
+                  ret, binary);
+        virHashRemoveEntry(cache->binaries, binary);
+        ret = NULL;
+    }
+    if (!ret) {
+        VIR_DEBUG("Creating capabilities for %s",
+                  binary);
+        ret = qemuCapsNewForBinary(binary);
+        if (ret) {
+            VIR_DEBUG("Caching capabilities %p for %s",
+                      ret, binary);
+            if (virHashAddEntry(cache->binaries, binary, ret) < 0) {
+                virObjectUnref(ret);
+                ret = NULL;
+            }
+        }
+    }
+    VIR_DEBUG("Returning caps %p for %s", ret, binary);
+    virObjectRef(ret);
+    virMutexUnlock(&cache->lock);
+    return ret;
+}
+
+
+qemuCapsPtr qemuCapsCacheLookupCopy(qemuCapsCachePtr cache, const char *binary)
+{
+    qemuCapsPtr caps = qemuCapsCacheLookup(cache, binary);
+    qemuCapsPtr ret;
+
+    if (!caps)
+        return NULL;
+
+    ret = qemuCapsNewCopy(caps);
+    virObjectUnref(caps);
+    return ret;
+}
+
+
+void qemuCapsCacheFree(qemuCapsCachePtr cache)
+{
+    if (!cache)
+        return;
+
+    virHashFree(cache->binaries);
+    virMutexDestroy(&cache->lock);
+    VIR_FREE(cache);
+}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 485c297..27ed378 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -154,6 +154,9 @@ enum qemuCapsFlags {
 typedef struct _qemuCaps qemuCaps;
 typedef qemuCaps *qemuCapsPtr;
 
+typedef struct _qemuCapsCache qemuCapsCache;
+typedef qemuCapsCache *qemuCapsCachePtr;
+
 qemuCapsPtr qemuCapsNew(void);
 qemuCapsPtr qemuCapsNewCopy(qemuCapsPtr caps);
 qemuCapsPtr qemuCapsNewForBinary(const char *binary);
@@ -183,6 +186,12 @@ const char *qemuCapsGetCanonicalMachine(qemuCapsPtr caps,
 
 bool qemuCapsIsValid(qemuCapsPtr caps);
 
+
+qemuCapsCachePtr qemuCapsCacheNew(void);
+qemuCapsPtr qemuCapsCacheLookup(qemuCapsCachePtr cache, const char *binary);
+qemuCapsPtr qemuCapsCacheLookupCopy(qemuCapsCachePtr cache, const char *binary);
+void qemuCapsCacheFree(qemuCapsCachePtr cache);
+
 virCapsPtr qemuCapsInit(virCapsPtr old_caps);
 
 int qemuCapsProbeMachineTypes(const char *binary,
-- 
1.7.11.4


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]