virsh: Add --model option for hypervisor-cpu-baseline

This option can be used as a shortcut for creating a single XML with
just a CPU model name and no features:

    $ virsh hypervisor-cpu-baseline --model Skylake-Server
    <cpu mode='custom' match='exact'>
      <model fallback='forbid'>Skylake-Server</model>
      <feature policy='disable' name='avx512f'/>
      <feature policy='disable' name='avx512dq'/>
      <feature policy='disable' name='clwb'/>
      <feature policy='disable' name='avx512cd'/>
      <feature policy='disable' name='avx512bw'/>
      <feature policy='disable' name='avx512vl'/>
      <feature policy='disable' name='pku'/>
    </cpu>

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Jiri Denemark 2022-10-06 16:29:32 +02:00
parent b0ff3af412
commit 268a2708c4
4 changed files with 62 additions and 9 deletions

View File

@ -962,13 +962,18 @@ hypervisor-cpu-baseline
:: ::
hypervisor-cpu-baseline FILE [virttype] [emulator] [arch] [machine] [--features] [--migratable] hypervisor-cpu-baseline [FILE] [virttype] [emulator] [arch] [machine]
[--features] [--migratable] [model]
Compute a baseline CPU which will be compatible with all CPUs defined in an XML Compute a baseline CPU which will be compatible with all CPUs defined in an XML
*file* and with the CPU the hypervisor is able to provide on the host. (This *file* and with the CPU the hypervisor is able to provide on the host. (This
is different from ``cpu-baseline`` which does not consider any hypervisor is different from ``cpu-baseline`` which does not consider any hypervisor
abilities when computing the baseline CPU.) abilities when computing the baseline CPU.)
As an alternative for *FILE* in case the XML would only contain a CPU model
with no additional features the CPU model name itself can be passed as *model*.
Exactly one of *FILE* and *model* must be used.
The XML *FILE* may contain either host or guest CPU definitions describing the The XML *FILE* may contain either host or guest CPU definitions describing the
host CPU model. The host CPU definition is the <cpu> element and its contents host CPU model. The host CPU definition is the <cpu> element and its contents
as printed by ``capabilities`` command. The guest CPU definition may be created as printed by ``capabilities`` command. The guest CPU definition may be created
@ -981,10 +986,13 @@ fail or provide unexpected results.
When *FILE* contains only a single CPU definition, the command will print the When *FILE* contains only a single CPU definition, the command will print the
same CPU with restrictions imposed by the capabilities of the hypervisor. same CPU with restrictions imposed by the capabilities of the hypervisor.
Specifically, running th ``virsh hypervisor-cpu-baseline`` command with no Specifically, running the ``virsh hypervisor-cpu-baseline`` command with no
additional options on the result of ``virsh domcapabilities`` will transform the additional options on the result of ``virsh domcapabilities`` will transform the
host CPU model from domain capabilities XML to a form directly usable in domain host CPU model from domain capabilities XML to a form directly usable in domain
XML. XML. Running the command with *model* (or *FILE* containing just a single CPU
definition with model and no feature elements) which is marked as unusable in
``virsh domcapabilities`` will provide a list of features that block this CPU
model from being usable.
The *virttype* option specifies the virtualization type (usable in the 'type' The *virttype* option specifies the virtualization type (usable in the 'type'
attribute of the <domain> top level element from the domain XML). *emulator* attribute of the <domain> top level element from the domain XML). *emulator*

View File

@ -1689,7 +1689,8 @@ static const vshCmdInfo info_hypervisor_cpu_baseline[] = {
}; };
static const vshCmdOptDef opts_hypervisor_cpu_baseline[] = { static const vshCmdOptDef opts_hypervisor_cpu_baseline[] = {
VIRSH_COMMON_OPT_FILE(N_("file containing XML CPU descriptions")), VIRSH_COMMON_OPT_FILE_FULL(N_("file containing XML CPU descriptions"),
false),
{.name = "virttype", {.name = "virttype",
.type = VSH_OT_STRING, .type = VSH_OT_STRING,
.completer = virshDomainVirtTypeCompleter, .completer = virshDomainVirtTypeCompleter,
@ -1716,6 +1717,11 @@ static const vshCmdOptDef opts_hypervisor_cpu_baseline[] = {
.type = VSH_OT_BOOL, .type = VSH_OT_BOOL,
.help = N_("Do not include features that block migration") .help = N_("Do not include features that block migration")
}, },
{.name = "model",
.type = VSH_OT_STRING,
.help = N_("Shortcut for calling the command with a single CPU model "
"and no additional features")
},
{.name = NULL} {.name = NULL}
}; };
@ -1728,6 +1734,7 @@ cmdHypervisorCPUBaseline(vshControl *ctl,
const char *emulator = NULL; const char *emulator = NULL;
const char *arch = NULL; const char *arch = NULL;
const char *machine = NULL; const char *machine = NULL;
const char *model = NULL;
bool ret = false; bool ret = false;
g_autofree char *result = NULL; g_autofree char *result = NULL;
g_auto(GStrv) list = NULL; g_auto(GStrv) list = NULL;
@ -1743,11 +1750,19 @@ cmdHypervisorCPUBaseline(vshControl *ctl,
vshCommandOptStringReq(ctl, cmd, "virttype", &virttype) < 0 || vshCommandOptStringReq(ctl, cmd, "virttype", &virttype) < 0 ||
vshCommandOptStringReq(ctl, cmd, "emulator", &emulator) < 0 || vshCommandOptStringReq(ctl, cmd, "emulator", &emulator) < 0 ||
vshCommandOptStringReq(ctl, cmd, "arch", &arch) < 0 || vshCommandOptStringReq(ctl, cmd, "arch", &arch) < 0 ||
vshCommandOptStringReq(ctl, cmd, "machine", &machine) < 0) vshCommandOptStringReq(ctl, cmd, "machine", &machine) < 0 ||
vshCommandOptStringReq(ctl, cmd, "model", &model) < 0)
return false; return false;
if (!(list = vshExtractCPUDefXMLs(ctl, from))) VSH_ALTERNATIVE_OPTIONS_EXPR("file", from, "model", model);
return false;
if (from) {
if (!(list = vshExtractCPUDefXMLs(ctl, from)))
return false;
} else {
list = g_new0(char *, 2);
list[0] = g_strdup_printf("<cpu><model>%s</model></cpu>", model);
}
result = virConnectBaselineHypervisorCPU(priv->conn, emulator, arch, result = virConnectBaselineHypervisorCPU(priv->conn, emulator, arch,
machine, virttype, machine, virttype,

View File

@ -96,9 +96,12 @@
/* Use this only for files which are existing and used locally by virsh */ /* Use this only for files which are existing and used locally by virsh */
#define VIRSH_COMMON_OPT_FILE(_helpstr) \ #define VIRSH_COMMON_OPT_FILE(_helpstr) \
VIRSH_COMMON_OPT_FILE_FULL(_helpstr, true)
#define VIRSH_COMMON_OPT_FILE_FULL(_helpstr, required) \
{.name = "file", \ {.name = "file", \
.type = VSH_OT_DATA, \ .type = required ? VSH_OT_DATA : VSH_OT_STRING, \
.flags = VSH_OFLAG_REQ, \ .flags = required ? VSH_OFLAG_REQ : VSH_OFLAG_NONE, \
.completer = virshCompletePathLocalExisting, \ .completer = virshCompletePathLocalExisting, \
.help = _helpstr \ .help = _helpstr \
} }

View File

@ -520,6 +520,33 @@ void vshReadlineHistoryAdd(const char *cmd);
#define VSH_EXCLUSIVE_OPTIONS_VAR(VARNAME1, VARNAME2) \ #define VSH_EXCLUSIVE_OPTIONS_VAR(VARNAME1, VARNAME2) \
VSH_EXCLUSIVE_OPTIONS_EXPR(#VARNAME1, VARNAME1, #VARNAME2, VARNAME2) VSH_EXCLUSIVE_OPTIONS_EXPR(#VARNAME1, VARNAME1, #VARNAME2, VARNAME2)
/* Macros to help dealing with alternative mutually exclusive options. */
/* VSH_ALTERNATIVE_OPTIONS_EXPR:
*
* @NAME1: String containing the name of the option.
* @EXPR1: Expression to validate the variable (must evaluate to bool).
* @NAME2: String containing the name of the option.
* @EXPR2: Expression to validate the variable (must evaluate to bool).
*
* Require exactly one of the command options in virsh. Use the provided
* expression to check the variables.
*
* This helper does an early return and therefore it has to be called
* before anything that would require cleanup.
*/
#define VSH_ALTERNATIVE_OPTIONS_EXPR(NAME1, EXPR1, NAME2, EXPR2) \
do { \
bool _expr1 = EXPR1; \
bool _expr2 = EXPR2; \
VSH_EXCLUSIVE_OPTIONS_EXPR(NAME1, _expr1, NAME2, _expr2); \
if (!_expr1 && !_expr2) { \
vshError(ctl, _("Either --%s or --%s must be provided"), \
NAME1, NAME2); \
return false; \
} \
} while (0)
/* Macros to help dealing with required options. */ /* Macros to help dealing with required options. */
/* VSH_REQUIRE_OPTION_EXPR: /* VSH_REQUIRE_OPTION_EXPR: