domain_capabilities: Report canonical names of CPU models

Some models are just aliases to other models. Make this relation
available to users via domain capabilities.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Jiri Denemark 2024-11-22 17:45:00 +01:00
parent ca0ea085d7
commit fff2bbee7f
5 changed files with 27 additions and 11 deletions

View File

@ -193,12 +193,12 @@ CPUs <formatdomain.html#cpu-model-and-topology>`__.
<feature policy='require' name='vmx'/> <feature policy='require' name='vmx'/>
</mode> </mode>
<mode name='custom' supported='yes'> <mode name='custom' supported='yes'>
<model usable='no' deprecated='no' vendor='Intel'>Broadwell</model> <model usable='no' deprecated='no' vendor='Intel' canonical='Broadwell-v1'>Broadwell</model>
<blockers model='Broadwell'> <blockers model='Broadwell'>
<feature name='hle'/> <feature name='hle'/>
<feature name='rtm'/> <feature name='rtm'/>
</blockers> </blockers>
<model usable='yes' deprecated='no' vendor='Intel'>Broadwell-noTSX</model> <model usable='yes' deprecated='no' vendor='Intel' canonical='Broadwell-v2'>Broadwell-noTSX</model>
<model usable='no' deprecated='no' vendor='AMD'>EPYC-Milan</model> <model usable='no' deprecated='no' vendor='AMD'>EPYC-Milan</model>
<blockers model='EPYC-Milan'> <blockers model='EPYC-Milan'>
<feature name='clzero'/> <feature name='clzero'/>
@ -265,7 +265,9 @@ more details about it:
the hypervisor's policy on usage of this model :since:`(since 7.1.0)`. The the hypervisor's policy on usage of this model :since:`(since 7.1.0)`. The
``vendor`` attribute :since:`(since 8.9.0)` contains the vendor of the CPU ``vendor`` attribute :since:`(since 8.9.0)` contains the vendor of the CPU
model for users who want to use CPU models with specific vendors only. CPU model for users who want to use CPU models with specific vendors only. CPU
models with undefined vendor will be listed with ``vendor='unkwnown'``. models with undefined vendor will be listed with ``vendor='unkwnown'``. The
``canonical`` attribute :since:`(since 10.10.0)` contains a canonical name of
the CPU model if the model is actually an alias to another one.
I/O Threads I/O Threads
~~~~~~~~~~~ ~~~~~~~~~~~

View File

@ -122,6 +122,7 @@ virDomainCapsCPUModelsDispose(void *obj)
g_free(cpuModels->models[i].name); g_free(cpuModels->models[i].name);
g_strfreev(cpuModels->models[i].blockers); g_strfreev(cpuModels->models[i].blockers);
g_free(cpuModels->models[i].vendor); g_free(cpuModels->models[i].vendor);
g_free(cpuModels->models[i].canonical);
} }
g_free(cpuModels->models); g_free(cpuModels->models);
@ -184,7 +185,8 @@ virDomainCapsCPUModelsCopy(virDomainCapsCPUModels *old)
old->models[i].usable, old->models[i].usable,
old->models[i].blockers, old->models[i].blockers,
old->models[i].deprecated, old->models[i].deprecated,
old->models[i].vendor); old->models[i].vendor,
old->models[i].canonical);
} }
return cpuModels; return cpuModels;
@ -197,7 +199,8 @@ virDomainCapsCPUModelsAdd(virDomainCapsCPUModels *cpuModels,
virDomainCapsCPUUsable usable, virDomainCapsCPUUsable usable,
char **blockers, char **blockers,
bool deprecated, bool deprecated,
const char *vendor) const char *vendor,
const char *canonical)
{ {
virDomainCapsCPUModel *cpu; virDomainCapsCPUModel *cpu;
@ -212,6 +215,7 @@ virDomainCapsCPUModelsAdd(virDomainCapsCPUModels *cpuModels,
cpu->blockers = g_strdupv(blockers); cpu->blockers = g_strdupv(blockers);
cpu->deprecated = deprecated; cpu->deprecated = deprecated;
cpu->vendor = g_strdup(vendor); cpu->vendor = g_strdup(vendor);
cpu->canonical = g_strdup(canonical);
} }
@ -430,6 +434,9 @@ virDomainCapsCPUCustomFormat(virBuffer *buf,
else else
virBufferAddLit(buf, " vendor='unknown'"); virBufferAddLit(buf, " vendor='unknown'");
if (model->canonical)
virBufferAsprintf(buf, " canonical='%s'", model->canonical);
virBufferAsprintf(buf, ">%s</model>\n", model->name); virBufferAsprintf(buf, ">%s</model>\n", model->name);
if (model->blockers) { if (model->blockers) {

View File

@ -189,6 +189,7 @@ struct _virDomainCapsCPUModel {
char **blockers; /* NULL-terminated list of usability blockers */ char **blockers; /* NULL-terminated list of usability blockers */
bool deprecated; bool deprecated;
char *vendor; char *vendor;
char *canonical;
}; };
typedef struct _virDomainCapsCPUModels virDomainCapsCPUModels; typedef struct _virDomainCapsCPUModels virDomainCapsCPUModels;
@ -331,7 +332,8 @@ virDomainCapsCPUModelsAdd(virDomainCapsCPUModels *cpuModels,
virDomainCapsCPUUsable usable, virDomainCapsCPUUsable usable,
char **blockers, char **blockers,
bool deprecated, bool deprecated,
const char *vendor); const char *vendor,
const char *canonical);
virDomainCapsCPUModel * virDomainCapsCPUModel *
virDomainCapsCPUModelsGet(virDomainCapsCPUModels *cpuModels, virDomainCapsCPUModelsGet(virDomainCapsCPUModels *cpuModels,
const char *name); const char *name);

View File

@ -2144,7 +2144,7 @@ virQEMUCapsCPUDefsToModels(virArch arch,
qemuMonitorCPUDefs *defs, qemuMonitorCPUDefs *defs,
const char **modelAllowed, const char **modelAllowed,
const char **modelForbidden, const char **modelForbidden,
bool vendors) bool extraInfo)
{ {
virDomainCapsCPUModels *cpuModels = NULL; virDomainCapsCPUModels *cpuModels = NULL;
size_t i; size_t i;
@ -2155,6 +2155,7 @@ virQEMUCapsCPUDefsToModels(virArch arch,
for (i = 0; i < defs->ncpus; i++) { for (i = 0; i < defs->ncpus; i++) {
qemuMonitorCPUDefInfo *cpu = defs->cpus + i; qemuMonitorCPUDefInfo *cpu = defs->cpus + i;
const char *vendor = NULL; const char *vendor = NULL;
const char *canonical = NULL;
if (modelAllowed && !g_strv_contains(modelAllowed, cpu->name)) if (modelAllowed && !g_strv_contains(modelAllowed, cpu->name))
continue; continue;
@ -2162,11 +2163,14 @@ virQEMUCapsCPUDefsToModels(virArch arch,
if (modelForbidden && g_strv_contains(modelForbidden, cpu->name)) if (modelForbidden && g_strv_contains(modelForbidden, cpu->name))
continue; continue;
if (vendors) if (extraInfo) {
vendor = virCPUGetVendorForModel(arch, cpu->name); vendor = virCPUGetVendorForModel(arch, cpu->name);
canonical = virCPUGetCanonicalModel(arch, cpu->name);
}
virDomainCapsCPUModelsAdd(cpuModels, cpu->name, cpu->usable, virDomainCapsCPUModelsAdd(cpuModels, cpu->name, cpu->usable,
cpu->blockers, cpu->deprecated, vendor); cpu->blockers, cpu->deprecated,
vendor, canonical);
} }
virDomainCapsCPUModelsSort(cpuModels); virDomainCapsCPUModelsSort(cpuModels);

View File

@ -823,7 +823,8 @@ cpuTestUpdateLive(const void *arg)
} }
virDomainCapsCPUModelsAdd(models, expected->model, virDomainCapsCPUModelsAdd(models, expected->model,
usable, blockers, false, expected->vendor); usable, blockers, false,
expected->vendor, NULL);
cpu->fallback = VIR_CPU_FALLBACK_ALLOW; cpu->fallback = VIR_CPU_FALLBACK_ALLOW;
ignore_value(virCPUTranslate(data->arch, cpu, models)); ignore_value(virCPUTranslate(data->arch, cpu, models));
@ -902,7 +903,7 @@ cpuTestInitModels(const char **list)
for (model = list; *model; model++) { for (model = list; *model; model++) {
virDomainCapsCPUModelsAdd(cpus, *model, virDomainCapsCPUModelsAdd(cpus, *model,
VIR_DOMCAPS_CPU_USABLE_UNKNOWN, VIR_DOMCAPS_CPU_USABLE_UNKNOWN,
NULL, false, NULL); NULL, false, NULL, NULL);
} }
return cpus; return cpus;