size_t ngicCapabilities;
virGICCapability *gicCapabilities;
+
+ /* Anything below is not stored in the cache since the values are
+ * re-computed from the other fields or external data sources every
+ * time we probe QEMU or load the results from the cache.
+ */
+ virCPUDefPtr hostCPUModel;
};
struct virQEMUCapsSearchData {
goto error;
}
+ if (qemuCaps->hostCPUModel &&
+ !(ret->hostCPUModel = virCPUDefCopy(qemuCaps->hostCPUModel)))
+ goto error;
+
if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0)
goto error;
ret->nmachineTypes = qemuCaps->nmachineTypes;
VIR_FREE(qemuCaps->binary);
VIR_FREE(qemuCaps->gicCapabilities);
+
+ virCPUDefFree(qemuCaps->hostCPUModel);
}
void
}
+void
+virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
+ virCapsHostPtr host)
+{
+ virCPUDefPtr cpu = NULL;
+
+ if (!virQEMUCapsGuestIsNative(host->arch, qemuCaps->arch))
+ goto error;
+
+ if (host->cpu && host->cpu->model) {
+ if (VIR_ALLOC(cpu) < 0)
+ goto error;
+
+ cpu->sockets = cpu->cores = cpu->threads = 0;
+ cpu->type = VIR_CPU_TYPE_GUEST;
+ cpu->mode = VIR_CPU_MODE_CUSTOM;
+ cpu->match = VIR_CPU_MATCH_EXACT;
+
+ if (virCPUDefCopyModel(cpu, host->cpu, true) < 0)
+ goto error;
+ }
+
+ qemuCaps->hostCPUModel = cpu;
+ return;
+
+ error:
+ virCPUDefFree(cpu);
+ qemuCaps->hostCPUModel = NULL;
+ virResetLastError();
+}
+
+
/*
* Parsing a doc that looks like
*
* </qemuCaps>
*/
int
-virQEMUCapsLoadCache(virQEMUCapsPtr qemuCaps, const char *filename,
- time_t *qemuctime, time_t *selfctime,
+virQEMUCapsLoadCache(virCapsPtr caps,
+ virQEMUCapsPtr qemuCaps,
+ const char *filename,
+ time_t *qemuctime,
+ time_t *selfctime,
unsigned long *selfvers)
{
xmlDocPtr doc = NULL;
}
VIR_FREE(nodes);
+ virQEMUCapsInitHostCPUModel(qemuCaps, &caps->host);
+
ret = 0;
cleanup:
VIR_FREE(str);
static int
-virQEMUCapsInitCached(virQEMUCapsPtr qemuCaps, const char *cacheDir)
+virQEMUCapsInitCached(virCapsPtr caps,
+ virQEMUCapsPtr qemuCaps,
+ const char *cacheDir)
{
char *capsdir = NULL;
char *capsfile = NULL;
goto cleanup;
}
- if (virQEMUCapsLoadCache(qemuCaps, capsfile, &qemuctime, &selfctime,
- &selfvers) < 0) {
+ if (virQEMUCapsLoadCache(caps, qemuCaps, capsfile,
+ &qemuctime, &selfctime, &selfvers) < 0) {
VIR_WARN("Failed to load cached caps from '%s' for '%s': %s",
capsfile, qemuCaps->binary, virGetLastErrorMessage());
virResetLastError();
virQEMUCapsPtr
-virQEMUCapsNewForBinaryInternal(virCapsPtr caps ATTRIBUTE_UNUSED,
+virQEMUCapsNewForBinaryInternal(virCapsPtr caps,
const char *binary,
const char *libDir,
const char *cacheDir,
if (!cacheDir)
rv = 0;
- else if ((rv = virQEMUCapsInitCached(qemuCaps, cacheDir)) < 0)
+ else if ((rv = virQEMUCapsInitCached(caps, qemuCaps, cacheDir)) < 0)
goto error;
if (rv == 0) {
if (cacheDir &&
virQEMUCapsRememberCached(qemuCaps, cacheDir) < 0)
goto error;
+
+ virQEMUCapsInitHostCPUModel(qemuCaps, &caps->host);
}
+ cleanup:
VIR_FREE(qmperr);
return qemuCaps;
error:
- VIR_FREE(qmperr);
virObjectUnref(qemuCaps);
qemuCaps = NULL;
- return NULL;
+ goto cleanup;
}
static virQEMUCapsPtr
virQEMUCapsPtr qemuCaps = NULL;
virDomainCapsLoaderPtr loader = &domCaps->os.loader;
+ if (!(caps = virCapabilitiesNew(domCaps->arch, false, false)) ||
+ fakeHostCPU(caps, domCaps->arch) < 0)
+ goto cleanup;
+
if (virAsprintf(&path, "%s/qemucapabilitiesdata/%s.%s.xml",
abs_srcdir, name, arch) < 0 ||
- !(qemuCaps = qemuTestParseCapabilities(path)))
+ !(qemuCaps = qemuTestParseCapabilities(caps, path)))
goto cleanup;
if (machine &&
virQEMUCapsGetDefaultMachine(qemuCaps)) < 0)
goto cleanup;
- if (!(caps = virCapabilitiesNew(domCaps->arch, false, false)) ||
- fakeHostCPU(caps, domCaps->arch) < 0)
- goto cleanup;
-
if (virQEMUCapsFillDomainCaps(caps, domCaps, qemuCaps,
cfg->firmwares,
cfg->nfirmwares) < 0)