qemuMonitorCPUDefsPtr cpuModels;
};
+
+typedef struct _virQEMUDomainCapsCache virQEMUDomainCapsCache;
+typedef virQEMUDomainCapsCache *virQEMUDomainCapsCachePtr;
+struct _virQEMUDomainCapsCache {
+ virObjectLockable parent;
+
+ virHashTablePtr cache;
+};
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(virQEMUDomainCapsCache, virObjectUnref);
+
+static virClassPtr virQEMUDomainCapsCacheClass;
+static void virQEMUDomainCapsCacheDispose(void *obj)
+{
+ virQEMUDomainCapsCachePtr cache = obj;
+
+ virHashFree(cache->cache);
+}
+
+
/*
* Update the XML parser/formatter when adding more
* information to this struct so that it gets cached
virArch arch;
- virHashTablePtr domCapsCache;
+ virQEMUDomainCapsCachePtr domCapsCache;
size_t ngicCapabilities;
virGICCapability *gicCapabilities;
if (!VIR_CLASS_NEW(virQEMUCaps, virClassForObject()))
return -1;
+ if (!(VIR_CLASS_NEW(virQEMUDomainCapsCache, virClassForObjectLockable())))
+ return -1;
+
return 0;
}
}
+static virQEMUDomainCapsCachePtr
+virQEMUDomainCapsCacheNew(void)
+{
+ g_autoptr(virQEMUDomainCapsCache) cache = NULL;
+
+ if (virQEMUCapsInitialize() < 0)
+ return NULL;
+
+ if (!(cache = virObjectLockableNew(virQEMUDomainCapsCacheClass)))
+ return NULL;
+
+ if (!(cache->cache = virHashCreate(5, virObjectFreeHashData)))
+ return NULL;
+
+ return g_steal_pointer(&cache);
+}
virQEMUCapsPtr
if (!(qemuCaps->flags = virBitmapNew(QEMU_CAPS_LAST)))
goto error;
- if (!(qemuCaps->domCapsCache = virHashCreate(5, virObjectFreeHashData)))
+ if (!(qemuCaps->domCapsCache = virQEMUDomainCapsCacheNew()))
goto error;
return qemuCaps;
{
virQEMUCapsPtr qemuCaps = obj;
- virHashFree(qemuCaps->domCapsCache);
+ virObjectUnref(qemuCaps->domCapsCache);
virBitmapFree(qemuCaps->flags);
VIR_FREE(qemuCaps->package);
}
-virHashTablePtr virQEMUCapsGetDomainCapsCache(virQEMUCapsPtr qemuCaps)
+struct virQEMUCapsSearchDomcapsData {
+ const char *path;
+ const char *machine;
+ virArch arch;
+ virDomainVirtType virttype;
+};
+
+
+static int
+virQEMUCapsSearchDomcaps(const void *payload,
+ const void *name G_GNUC_UNUSED,
+ const void *opaque)
{
- return qemuCaps->domCapsCache;
+ virDomainCapsPtr domCaps = (virDomainCapsPtr) payload;
+ struct virQEMUCapsSearchDomcapsData *data = (struct virQEMUCapsSearchDomcapsData *) 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;
+}
+
+
+virDomainCapsPtr
+virQEMUCapsGetDomainCapsCache(virQEMUCapsPtr qemuCaps,
+ const char *machine,
+ virArch arch,
+ virDomainVirtType virttype,
+ virArch hostarch,
+ bool privileged,
+ virFirmwarePtr *firmwares,
+ size_t nfirmwares)
+{
+ virQEMUDomainCapsCachePtr cache = qemuCaps->domCapsCache;
+ virDomainCapsPtr domCaps = NULL;
+ const char *path = virQEMUCapsGetBinary(qemuCaps);
+ struct virQEMUCapsSearchDomcapsData data = {
+ .path = path,
+ .machine = machine,
+ .arch = arch,
+ .virttype = virttype,
+ };
+
+ virObjectLock(cache);
+
+ domCaps = virHashSearch(cache->cache, virQEMUCapsSearchDomcaps, &data, NULL);
+
+ if (!domCaps) {
+ g_autoptr(virDomainCaps) tempDomCaps = NULL;
+ g_autofree char *key = NULL;
+
+ /* hash miss, build new domcaps */
+ if (!(tempDomCaps = virDomainCapsNew(path, machine,
+ arch, virttype)))
+ goto cleanup;
+
+ if (virQEMUCapsFillDomainCaps(qemuCaps, hostarch, tempDomCaps,
+ privileged, firmwares, nfirmwares) < 0)
+ goto cleanup;
+
+ key = g_strdup_printf("%d:%d:%s:%s", arch, virttype,
+ NULLSTR(machine), path);
+
+ if (virHashAddEntry(cache->cache, key, tempDomCaps) < 0)
+ goto cleanup;
+
+ domCaps = g_steal_pointer(&tempDomCaps);
+ }
+
+ virObjectRef(domCaps);
+ cleanup:
+ virObjectUnlock(cache);
+ return domCaps;
}
}
-struct virQEMUDriverSearchDomcapsData {
- const char *path;
- const char *machine;
- virArch arch;
- virDomainVirtType virttype;
-};
-
-
-static int
-virQEMUDriverSearchDomcaps(const void *payload,
- const void *name G_GNUC_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:
*
virArch arch,
virDomainVirtType virttype)
{
- g_autoptr(virDomainCaps) domCaps = NULL;
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
- virHashTablePtr domCapsCache = virQEMUCapsGetDomainCapsCache(qemuCaps);
- struct virQEMUDriverSearchDomcapsData data = {
- .path = virQEMUCapsGetBinary(qemuCaps),
- .machine = machine,
- .arch = arch,
- .virttype = virttype,
- };
-
- domCaps = virHashSearch(domCapsCache,
- virQEMUDriverSearchDomcaps, &data, NULL);
- if (!domCaps) {
- g_autofree char *key = NULL;
-
- /* hash miss, build new domcaps */
- if (!(domCaps = virDomainCapsNew(data.path, data.machine,
- data.arch, data.virttype)))
- return NULL;
-
- if (virQEMUCapsFillDomainCaps(qemuCaps, driver->hostarch, domCaps,
- driver->privileged,
- cfg->firmwares, cfg->nfirmwares) < 0)
- return NULL;
-
- key = g_strdup_printf("%d:%d:%s:%s", data.arch, data.virttype,
- NULLSTR(data.machine), NULLSTR(data.path));
-
- if (virHashAddEntry(domCapsCache, key, domCaps) < 0)
- return NULL;
- }
- virObjectRef(domCaps);
- return g_steal_pointer(&domCaps);
+ return virQEMUCapsGetDomainCapsCache(qemuCaps,
+ machine,
+ arch,
+ virttype,
+ driver->hostarch,
+ driver->privileged,
+ cfg->firmwares,
+ cfg->nfirmwares);
}