提交 270583ed 编写于 作者: C Cole Robinson

qemu: conf: Cache domCaps in qemuCaps

qemuCaps is tied to a binary on disk. domCaps is tied to a combo
of binary+machine+arch+virttype values. For the qemu driver this almost
entirely translates to a permutation of qemuCaps though

Upcoming patches want to use the domCaps data store at XML validate
time, but we need to cache the data so we aren't repeatedly
regenerating it.

Add a domCapsCache hash table to qemuCaps. This ensures that the domCaps
cache is blown away whenever qemuCaps needs to be regenerated. Similarly
when qemuCaps is invalidated, the next call to virQEMUCapsCacheLookup
will unref qemuCaps and free our cache as well.

Adjust virQEMUDriverGetDomainCapabilities to search the cache and add
to it if we don't find a hit.
Signed-off-by: NCole Robinson <crobinso@redhat.com>
Reviewed-by: NReviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Reviewed-by: NMichal Privoznik <mprivozn@redhat.com>
上级 d05bdff7
...@@ -595,6 +595,7 @@ struct _virQEMUCaps { ...@@ -595,6 +595,7 @@ struct _virQEMUCaps {
virArch arch; virArch arch;
virHashTablePtr domCapsCache;
virDomainCapsCPUModelsPtr kvmCPUModels; virDomainCapsCPUModelsPtr kvmCPUModels;
virDomainCapsCPUModelsPtr tcgCPUModels; virDomainCapsCPUModelsPtr tcgCPUModels;
...@@ -1509,6 +1510,9 @@ virQEMUCapsNew(void) ...@@ -1509,6 +1510,9 @@ virQEMUCapsNew(void)
if (!(qemuCaps->flags = virBitmapNew(QEMU_CAPS_LAST))) if (!(qemuCaps->flags = virBitmapNew(QEMU_CAPS_LAST)))
goto error; goto error;
if (!(qemuCaps->domCapsCache = virHashCreate(5, virObjectFreeHashData)))
goto error;
return qemuCaps; return qemuCaps;
error: error:
...@@ -1661,6 +1665,7 @@ void virQEMUCapsDispose(void *obj) ...@@ -1661,6 +1665,7 @@ void virQEMUCapsDispose(void *obj)
} }
VIR_FREE(qemuCaps->machineTypes); VIR_FREE(qemuCaps->machineTypes);
virHashFree(qemuCaps->domCapsCache);
virObjectUnref(qemuCaps->kvmCPUModels); virObjectUnref(qemuCaps->kvmCPUModels);
virObjectUnref(qemuCaps->tcgCPUModels); virObjectUnref(qemuCaps->tcgCPUModels);
...@@ -1823,6 +1828,12 @@ const char *virQEMUCapsGetPackage(virQEMUCapsPtr qemuCaps) ...@@ -1823,6 +1828,12 @@ const char *virQEMUCapsGetPackage(virQEMUCapsPtr qemuCaps)
} }
virHashTablePtr virQEMUCapsGetDomainCapsCache(virQEMUCapsPtr qemuCaps)
{
return qemuCaps->domCapsCache;
}
int int
virQEMUCapsAddCPUDefinitions(virQEMUCapsPtr qemuCaps, virQEMUCapsAddCPUDefinitions(virQEMUCapsPtr qemuCaps,
virDomainVirtType type, virDomainVirtType type,
......
...@@ -549,6 +549,7 @@ const char *virQEMUCapsGetBinary(virQEMUCapsPtr qemuCaps); ...@@ -549,6 +549,7 @@ const char *virQEMUCapsGetBinary(virQEMUCapsPtr qemuCaps);
virArch virQEMUCapsGetArch(virQEMUCapsPtr qemuCaps); virArch virQEMUCapsGetArch(virQEMUCapsPtr qemuCaps);
unsigned int virQEMUCapsGetVersion(virQEMUCapsPtr qemuCaps); unsigned int virQEMUCapsGetVersion(virQEMUCapsPtr qemuCaps);
const char *virQEMUCapsGetPackage(virQEMUCapsPtr qemuCaps); const char *virQEMUCapsGetPackage(virQEMUCapsPtr qemuCaps);
virHashTablePtr virQEMUCapsGetDomainCapsCache(virQEMUCapsPtr qemuCaps);
unsigned int virQEMUCapsGetKVMVersion(virQEMUCapsPtr qemuCaps); unsigned int virQEMUCapsGetKVMVersion(virQEMUCapsPtr qemuCaps);
int virQEMUCapsAddCPUDefinitions(virQEMUCapsPtr qemuCaps, int virQEMUCapsAddCPUDefinitions(virQEMUCapsPtr qemuCaps,
virDomainVirtType type, virDomainVirtType type,
......
...@@ -1364,10 +1364,39 @@ virCapsPtr virQEMUDriverGetCapabilities(virQEMUDriverPtr driver, ...@@ -1364,10 +1364,39 @@ virCapsPtr virQEMUDriverGetCapabilities(virQEMUDriverPtr driver,
} }
struct virQEMUDriverSearchDomcapsData {
const char *path;
const char *machine;
virArch arch;
virDomainVirtType virttype;
};
static int
virQEMUDriverSearchDomcaps(const void *payload,
const void *name ATTRIBUTE_UNUSED,
const void *opaque)
{
virDomainCapsPtr domCaps = (virDomainCapsPtr) payload;
struct virQEMUDriverSearchDomcapsData *data = (struct virQEMUDriverSearchDomcapsData *) opaque;
if (STREQ_NULLABLE(data->path, domCaps->path) &&
STREQ_NULLABLE(data->machine, domCaps->machine) &&
data->arch == domCaps->arch &&
data->virttype == domCaps->virttype)
return 1;
return 0;
}
/** /**
* virQEMUDriverGetDomainCapabilities: * virQEMUDriverGetDomainCapabilities:
* *
* Build a virDomainCapsPtr instance for the passed data. * Get a reference to the virDomainCapsPtr instance from the virQEMUCapsPtr
* domCapsCache. If there's no domcaps in the cache, create a new instance,
* add it to the cache, and return a reference.
*
* The caller must release the reference with virObjetUnref
* *
* Returns: a reference to a virDomainCapsPtr instance or NULL * Returns: a reference to a virDomainCapsPtr instance or NULL
*/ */
...@@ -1381,18 +1410,35 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriverPtr driver, ...@@ -1381,18 +1410,35 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriverPtr driver,
virDomainCapsPtr ret = NULL, domCaps = NULL; virDomainCapsPtr ret = NULL, domCaps = NULL;
virCapsPtr caps = NULL; virCapsPtr caps = NULL;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
virHashTablePtr domCapsCache = virQEMUCapsGetDomainCapsCache(qemuCaps);
struct virQEMUDriverSearchDomcapsData data = {
.path = virQEMUCapsGetBinary(qemuCaps),
.machine = machine,
.arch = arch,
.virttype = virttype,
};
if (!(caps = virQEMUDriverGetCapabilities(driver, false))) if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
goto cleanup; goto cleanup;
if (!(domCaps = virDomainCapsNew(virQEMUCapsGetBinary(qemuCaps), machine, domCaps = virHashSearch(domCapsCache,
arch, virttype))) virQEMUDriverSearchDomcaps, &data, NULL);
goto cleanup; if (!domCaps) {
/* hash miss, build new domcaps */
if (!(domCaps = virDomainCapsNew(data.path, data.machine,
data.arch, data.virttype)))
goto cleanup;
if (virQEMUCapsFillDomainCaps(caps, domCaps, qemuCaps, driver->privileged, if (virQEMUCapsFillDomainCaps(caps, domCaps, qemuCaps,
cfg->firmwares, cfg->nfirmwares) < 0) driver->privileged,
goto cleanup; cfg->firmwares, cfg->nfirmwares) < 0)
goto cleanup;
if (virHashAddEntry(domCapsCache, machine, domCaps) < 0)
goto cleanup;
}
virObjectRef(domCaps);
VIR_STEAL_PTR(ret, domCaps); VIR_STEAL_PTR(ret, domCaps);
cleanup: cleanup:
virObjectUnref(domCaps); virObjectUnref(domCaps);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册