On Tue, Sep 25, 2012 at 12:59 PM, Daniel P. Berrange <berrange@xxxxxxxxxx> wrote: > From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> > > 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@xxxxxxxxxx> > --- > 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 */ s/uses/use/ > + 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) Return type on its own line if I'm recalling the coding std. > +{ > + 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) Again. > +{ > + 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) Again. > +{ > + qemuCapsPtr caps = qemuCapsCacheLookup(cache, binary); > + qemuCapsPtr ret; > + > + if (!caps) > + return NULL; > + > + ret = qemuCapsNewCopy(caps); > + virObjectUnref(caps); > + return ret; > +} > + > + > +void qemuCapsCacheFree(qemuCapsCachePtr cache) Again. > +{ > + 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 > > -- > libvir-list mailing list > libvir-list@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/libvir-list -- Doug Goldstein -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list