[libvirt PATCH v2 12/14] virsh: Add --model option for hypervisor-cpu-baseline

Jiri Denemark jdenemar at redhat.com
Fri Oct 7 17:21:49 UTC 2022


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 at redhat.com>
---

Notes:
    Version 2:
    - new patch

 docs/manpages/virsh.rst | 14 +++++++++++---
 tools/virsh-host.c      | 23 +++++++++++++++++++----
 tools/virsh.h           |  7 +++++--
 tools/vsh.h             | 27 +++++++++++++++++++++++++++
 4 files changed, 62 insertions(+), 9 deletions(-)

diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index 5d11c48803..61fcb2e9ca 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -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
 *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
 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
 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
@@ -981,10 +986,13 @@ fail or provide unexpected results.
 
 When *FILE* contains only a single CPU definition, the command will print the
 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
 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'
 attribute of the <domain> top level element from the domain XML). *emulator*
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index ead966b500..16c3585a1a 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -1689,7 +1689,8 @@ static const vshCmdInfo info_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",
      .type = VSH_OT_STRING,
      .completer = virshDomainVirtTypeCompleter,
@@ -1716,6 +1717,11 @@ static const vshCmdOptDef opts_hypervisor_cpu_baseline[] = {
      .type = VSH_OT_BOOL,
      .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}
 };
 
@@ -1728,6 +1734,7 @@ cmdHypervisorCPUBaseline(vshControl *ctl,
     const char *emulator = NULL;
     const char *arch = NULL;
     const char *machine = NULL;
+    const char *model = NULL;
     bool ret = false;
     g_autofree char *result = NULL;
     g_auto(GStrv) list = NULL;
@@ -1743,11 +1750,19 @@ cmdHypervisorCPUBaseline(vshControl *ctl,
         vshCommandOptStringReq(ctl, cmd, "virttype", &virttype) < 0 ||
         vshCommandOptStringReq(ctl, cmd, "emulator", &emulator) < 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;
 
-    if (!(list = vshExtractCPUDefXMLs(ctl, from)))
-        return false;
+    VSH_ALTERNATIVE_OPTIONS_EXPR("file", from, "model", model);
+
+    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,
                                              machine, virttype,
diff --git a/tools/virsh.h b/tools/virsh.h
index f9841c8da2..6acefa7f9d 100644
--- a/tools/virsh.h
+++ b/tools/virsh.h
@@ -96,9 +96,12 @@
 
 /* Use this only for files which are existing and used locally by virsh */
 #define VIRSH_COMMON_OPT_FILE(_helpstr) \
+    VIRSH_COMMON_OPT_FILE_FULL(_helpstr, true)
+
+#define VIRSH_COMMON_OPT_FILE_FULL(_helpstr, required) \
     {.name = "file", \
-     .type = VSH_OT_DATA, \
-     .flags = VSH_OFLAG_REQ, \
+     .type = required ? VSH_OT_DATA : VSH_OT_STRING, \
+     .flags = required ? VSH_OFLAG_REQ : VSH_OFLAG_NONE, \
      .completer = virshCompletePathLocalExisting, \
      .help = _helpstr \
     }
diff --git a/tools/vsh.h b/tools/vsh.h
index a43660b63d..657a1e7a93 100644
--- a/tools/vsh.h
+++ b/tools/vsh.h
@@ -520,6 +520,33 @@ void vshReadlineHistoryAdd(const char *cmd);
 #define VSH_EXCLUSIVE_OPTIONS_VAR(VARNAME1, 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. */
 
 /* VSH_REQUIRE_OPTION_EXPR:
-- 
2.38.0



More information about the libvir-list mailing list