提交 85a7b5e1 编写于 作者: D Daniel P. Berrange

Add a qemu capabilities cache manager

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: NDaniel P. Berrange <berrange@redhat.com>
上级 3887afbb
......@@ -207,6 +207,11 @@ struct _qemuCaps {
char **machineAliases;
};
struct _qemuCapsCache {
virMutex lock;
virHashTablePtr binaries;
};
static virClassPtr qemuCapsClass;
static void qemuCapsDispose(void *obj);
......@@ -2055,3 +2060,98 @@ 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);
}
......@@ -155,6 +155,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);
......@@ -184,6 +187,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,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册