提交 68c70118 编写于 作者: J Jiri Denemark

qemu: Store host-model CPU in qemu capabilities

Host capabilities provide libvirt's view of the host CPU, but for a
useful support for host-model CPUs we really need a hypervisor's view of
the CPU. And since the view can be differ with emulator, qemu
capabilities is the best place to store the host CPU model.

This patch just copies the CPU model from host capabilities, but this
will change in the future.
Signed-off-by: NJiri Denemark <jdenemar@redhat.com>
上级 8fc6e7d8
...@@ -385,6 +385,12 @@ struct _virQEMUCaps { ...@@ -385,6 +385,12 @@ struct _virQEMUCaps {
size_t ngicCapabilities; size_t ngicCapabilities;
virGICCapability *gicCapabilities; 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 { struct virQEMUCapsSearchData {
...@@ -2113,6 +2119,10 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps) ...@@ -2113,6 +2119,10 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
goto error; goto error;
} }
if (qemuCaps->hostCPUModel &&
!(ret->hostCPUModel = virCPUDefCopy(qemuCaps->hostCPUModel)))
goto error;
if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0) if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0)
goto error; goto error;
ret->nmachineTypes = qemuCaps->nmachineTypes; ret->nmachineTypes = qemuCaps->nmachineTypes;
...@@ -2157,6 +2167,8 @@ void virQEMUCapsDispose(void *obj) ...@@ -2157,6 +2167,8 @@ void virQEMUCapsDispose(void *obj)
VIR_FREE(qemuCaps->binary); VIR_FREE(qemuCaps->binary);
VIR_FREE(qemuCaps->gicCapabilities); VIR_FREE(qemuCaps->gicCapabilities);
virCPUDefFree(qemuCaps->hostCPUModel);
} }
void void
...@@ -2902,6 +2914,38 @@ int virQEMUCapsProbeQMP(virQEMUCapsPtr qemuCaps, ...@@ -2902,6 +2914,38 @@ int virQEMUCapsProbeQMP(virQEMUCapsPtr qemuCaps,
} }
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 * Parsing a doc that looks like
* *
...@@ -2920,8 +2964,11 @@ int virQEMUCapsProbeQMP(virQEMUCapsPtr qemuCaps, ...@@ -2920,8 +2964,11 @@ int virQEMUCapsProbeQMP(virQEMUCapsPtr qemuCaps,
* </qemuCaps> * </qemuCaps>
*/ */
int int
virQEMUCapsLoadCache(virQEMUCapsPtr qemuCaps, const char *filename, virQEMUCapsLoadCache(virCapsPtr caps,
time_t *qemuctime, time_t *selfctime, virQEMUCapsPtr qemuCaps,
const char *filename,
time_t *qemuctime,
time_t *selfctime,
unsigned long *selfvers) unsigned long *selfvers)
{ {
xmlDocPtr doc = NULL; xmlDocPtr doc = NULL;
...@@ -3154,6 +3201,8 @@ virQEMUCapsLoadCache(virQEMUCapsPtr qemuCaps, const char *filename, ...@@ -3154,6 +3201,8 @@ virQEMUCapsLoadCache(virQEMUCapsPtr qemuCaps, const char *filename,
} }
VIR_FREE(nodes); VIR_FREE(nodes);
virQEMUCapsInitHostCPUModel(qemuCaps, &caps->host);
ret = 0; ret = 0;
cleanup: cleanup:
VIR_FREE(str); VIR_FREE(str);
...@@ -3344,7 +3393,9 @@ virQEMUCapsReset(virQEMUCapsPtr qemuCaps) ...@@ -3344,7 +3393,9 @@ virQEMUCapsReset(virQEMUCapsPtr qemuCaps)
static int static int
virQEMUCapsInitCached(virQEMUCapsPtr qemuCaps, const char *cacheDir) virQEMUCapsInitCached(virCapsPtr caps,
virQEMUCapsPtr qemuCaps,
const char *cacheDir)
{ {
char *capsdir = NULL; char *capsdir = NULL;
char *capsfile = NULL; char *capsfile = NULL;
...@@ -3386,8 +3437,8 @@ virQEMUCapsInitCached(virQEMUCapsPtr qemuCaps, const char *cacheDir) ...@@ -3386,8 +3437,8 @@ virQEMUCapsInitCached(virQEMUCapsPtr qemuCaps, const char *cacheDir)
goto cleanup; goto cleanup;
} }
if (virQEMUCapsLoadCache(qemuCaps, capsfile, &qemuctime, &selfctime, if (virQEMUCapsLoadCache(caps, qemuCaps, capsfile,
&selfvers) < 0) { &qemuctime, &selfctime, &selfvers) < 0) {
VIR_WARN("Failed to load cached caps from '%s' for '%s': %s", VIR_WARN("Failed to load cached caps from '%s' for '%s': %s",
capsfile, qemuCaps->binary, virGetLastErrorMessage()); capsfile, qemuCaps->binary, virGetLastErrorMessage());
virResetLastError(); virResetLastError();
...@@ -3871,7 +3922,7 @@ virQEMUCapsLogProbeFailure(const char *binary) ...@@ -3871,7 +3922,7 @@ virQEMUCapsLogProbeFailure(const char *binary)
virQEMUCapsPtr virQEMUCapsPtr
virQEMUCapsNewForBinaryInternal(virCapsPtr caps ATTRIBUTE_UNUSED, virQEMUCapsNewForBinaryInternal(virCapsPtr caps,
const char *binary, const char *binary,
const char *libDir, const char *libDir,
const char *cacheDir, const char *cacheDir,
...@@ -3911,7 +3962,7 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps ATTRIBUTE_UNUSED, ...@@ -3911,7 +3962,7 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps ATTRIBUTE_UNUSED,
if (!cacheDir) if (!cacheDir)
rv = 0; rv = 0;
else if ((rv = virQEMUCapsInitCached(qemuCaps, cacheDir)) < 0) else if ((rv = virQEMUCapsInitCached(caps, qemuCaps, cacheDir)) < 0)
goto error; goto error;
if (rv == 0) { if (rv == 0) {
...@@ -3937,16 +3988,18 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps ATTRIBUTE_UNUSED, ...@@ -3937,16 +3988,18 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps ATTRIBUTE_UNUSED,
if (cacheDir && if (cacheDir &&
virQEMUCapsRememberCached(qemuCaps, cacheDir) < 0) virQEMUCapsRememberCached(qemuCaps, cacheDir) < 0)
goto error; goto error;
virQEMUCapsInitHostCPUModel(qemuCaps, &caps->host);
} }
cleanup:
VIR_FREE(qmperr); VIR_FREE(qmperr);
return qemuCaps; return qemuCaps;
error: error:
VIR_FREE(qmperr);
virObjectUnref(qemuCaps); virObjectUnref(qemuCaps);
qemuCaps = NULL; qemuCaps = NULL;
return NULL; goto cleanup;
} }
static virQEMUCapsPtr static virQEMUCapsPtr
......
...@@ -48,7 +48,8 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps, ...@@ -48,7 +48,8 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps,
gid_t runGid, gid_t runGid,
bool qmpOnly); bool qmpOnly);
int virQEMUCapsLoadCache(virQEMUCapsPtr qemuCaps, int virQEMUCapsLoadCache(virCapsPtr caps,
virQEMUCapsPtr qemuCaps,
const char *filename, const char *filename,
time_t *qemuctime, time_t *qemuctime,
time_t *selfctime, time_t *selfctime,
...@@ -60,4 +61,8 @@ char *virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps, ...@@ -60,4 +61,8 @@ char *virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps,
void void
virQEMUCapsSetArch(virQEMUCapsPtr qemuCaps, virQEMUCapsSetArch(virQEMUCapsPtr qemuCaps,
virArch arch); virArch arch);
void
virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
virCapsHostPtr host);
#endif #endif
...@@ -173,9 +173,13 @@ fillQemuCaps(virDomainCapsPtr domCaps, ...@@ -173,9 +173,13 @@ fillQemuCaps(virDomainCapsPtr domCaps,
virQEMUCapsPtr qemuCaps = NULL; virQEMUCapsPtr qemuCaps = NULL;
virDomainCapsLoaderPtr loader = &domCaps->os.loader; 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", if (virAsprintf(&path, "%s/qemucapabilitiesdata/%s.%s.xml",
abs_srcdir, name, arch) < 0 || abs_srcdir, name, arch) < 0 ||
!(qemuCaps = qemuTestParseCapabilities(path))) !(qemuCaps = qemuTestParseCapabilities(caps, path)))
goto cleanup; goto cleanup;
if (machine && if (machine &&
...@@ -188,10 +192,6 @@ fillQemuCaps(virDomainCapsPtr domCaps, ...@@ -188,10 +192,6 @@ fillQemuCaps(virDomainCapsPtr domCaps,
virQEMUCapsGetDefaultMachine(qemuCaps)) < 0) virQEMUCapsGetDefaultMachine(qemuCaps)) < 0)
goto cleanup; goto cleanup;
if (!(caps = virCapabilitiesNew(domCaps->arch, false, false)) ||
fakeHostCPU(caps, domCaps->arch) < 0)
goto cleanup;
if (virQEMUCapsFillDomainCaps(caps, domCaps, qemuCaps, if (virQEMUCapsFillDomainCaps(caps, domCaps, qemuCaps,
cfg->firmwares, cfg->firmwares,
cfg->nfirmwares) < 0) cfg->nfirmwares) < 0)
......
...@@ -97,7 +97,7 @@ testQemuCapsCopy(const void *opaque) ...@@ -97,7 +97,7 @@ testQemuCapsCopy(const void *opaque)
false, false))) false, false)))
goto cleanup; goto cleanup;
if (!(orig = qemuTestParseCapabilities(capsFile))) if (!(orig = qemuTestParseCapabilities(caps, capsFile)))
goto cleanup; goto cleanup;
if (!(copy = virQEMUCapsNewCopy(orig))) if (!(copy = virQEMUCapsNewCopy(orig)))
......
...@@ -347,7 +347,8 @@ testInitQEMUCaps(struct testInfo *info, ...@@ -347,7 +347,8 @@ testInitQEMUCaps(struct testInfo *info,
static int static int
testUpdateQEMUCaps(const struct testInfo *info, testUpdateQEMUCaps(const struct testInfo *info,
virDomainObjPtr vm) virDomainObjPtr vm,
virCapsPtr caps)
{ {
int ret = -1; int ret = -1;
...@@ -356,6 +357,8 @@ testUpdateQEMUCaps(const struct testInfo *info, ...@@ -356,6 +357,8 @@ testUpdateQEMUCaps(const struct testInfo *info,
if (testAddCPUModels(info->qemuCaps, info->skipLegacyCPUs) < 0) if (testAddCPUModels(info->qemuCaps, info->skipLegacyCPUs) < 0)
goto cleanup; goto cleanup;
virQEMUCapsInitHostCPUModel(info->qemuCaps, &caps->host);
virQEMUCapsFilterByMachineType(info->qemuCaps, vm->def->os.machine); virQEMUCapsFilterByMachineType(info->qemuCaps, vm->def->os.machine);
if (ARCH_IS_X86(vm->def->os.arch)) if (ARCH_IS_X86(vm->def->os.arch))
...@@ -448,7 +451,7 @@ testCompareXMLToArgv(const void *data) ...@@ -448,7 +451,7 @@ testCompareXMLToArgv(const void *data)
goto cleanup; goto cleanup;
} }
if (testUpdateQEMUCaps(info, vm) < 0) if (testUpdateQEMUCaps(info, vm, driver.caps) < 0)
goto cleanup; goto cleanup;
log = virTestLogContentAndReset(); log = virTestLogContentAndReset();
......
...@@ -491,7 +491,8 @@ qemuTestSetHostCPU(virCapsPtr caps, ...@@ -491,7 +491,8 @@ qemuTestSetHostCPU(virCapsPtr caps,
virQEMUCapsPtr virQEMUCapsPtr
qemuTestParseCapabilities(const char *capsFile) qemuTestParseCapabilities(virCapsPtr caps,
const char *capsFile)
{ {
virQEMUCapsPtr qemuCaps = NULL; virQEMUCapsPtr qemuCaps = NULL;
time_t qemuctime; time_t qemuctime;
...@@ -499,7 +500,7 @@ qemuTestParseCapabilities(const char *capsFile) ...@@ -499,7 +500,7 @@ qemuTestParseCapabilities(const char *capsFile)
unsigned long version; unsigned long version;
if (!(qemuCaps = virQEMUCapsNew()) || if (!(qemuCaps = virQEMUCapsNew()) ||
virQEMUCapsLoadCache(qemuCaps, capsFile, virQEMUCapsLoadCache(caps, qemuCaps, capsFile,
&qemuctime, &selfctime, &version) < 0) &qemuctime, &selfctime, &version) < 0)
goto error; goto error;
......
...@@ -15,7 +15,8 @@ enum { ...@@ -15,7 +15,8 @@ enum {
virCapsPtr testQemuCapsInit(void); virCapsPtr testQemuCapsInit(void);
virDomainXMLOptionPtr testQemuXMLConfInit(void); virDomainXMLOptionPtr testQemuXMLConfInit(void);
virQEMUCapsPtr qemuTestParseCapabilities(const char *capsFile); virQEMUCapsPtr qemuTestParseCapabilities(virCapsPtr caps,
const char *capsFile);
extern virCPUDefPtr cpuDefault; extern virCPUDefPtr cpuDefault;
extern virCPUDefPtr cpuHaswell; extern virCPUDefPtr cpuHaswell;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册