Changeset
docs/news.xml                  |   9 +
include/libvirt/libvirt-host.h |  15 ++
src/bhyve/bhyve_driver.c       |   4 +-
src/cpu/cpu.c                  |  34 ++-
src/cpu/cpu.h                  |  21 +-
src/cpu/cpu_arm.c              |  11 +-
src/cpu/cpu_ppc64.c            |   5 +-
src/cpu/cpu_x86.c              |  35 ++-
src/driver-hypervisor.h        |  20 ++
src/libvirt-host.c             | 161 +++++++++++-
src/libvirt_private.syms       |   2 +-
src/libvirt_public.syms        |   6 +
src/libxl/libxl_driver.c       |   4 +-
src/qemu/qemu_capabilities.c   | 170 +++++++++++++
src/qemu/qemu_capabilities.h   |  12 +
src/qemu/qemu_driver.c         | 241 ++++++++++++------
src/remote/remote_driver.c     |   4 +-
src/remote/remote_protocol.x   |  40 ++-
src/remote_protocol-structs    |  27 ++
src/test/test_driver.c         |   2 +-
src/vz/vz_driver.c             |   2 +-
tests/cputest.c                |   6 +-
tools/virsh-domain.c           | 223 -----------------
tools/virsh-host.c             | 441 +++++++++++++++++++++++++++++++++
tools/virsh.pod                |  90 ++++++-
25 files changed, 1223 insertions(+), 362 deletions(-)
Git apply log
Switched to a new branch 'cover.1526459534.git.jdenemar@redhat.com'
Applying: virsh: Move cpu-{baseline, compare} commands
Applying: virsh: Extract common code from cmdCPU{Compare, Baseline}
Applying: virsh: Enhance documentation of cpu-compare command
Applying: virsh: Enhance documentation of cpu-models command
Applying: Improve documentation of virConnectGetCPUModelNames
Applying: vshExtractCPUDefXML: Accept domain capabilities XML
Applying: qemu_capabilities: Introduce virQEMUCapsCacheLookupDefault
Applying: Introduce virConnectCompareHypervisorCPU public API
Applying: remote: Implement virConnectCompareHypervisorCPU
Applying: virsh: Introduce new hypervisor-cpu-compare command
Applying: qemu: Implement virConnectCompareHypervisorCPU
Applying: Introduce virConnectBaselineHypervisorCPU public API
Applying: remote: Implement virConnectBaselineHypervisorCPU
Applying: virsh: Introduce new hypervisor-cpu-baseline command
Applying: cpu: Rename cpuBaseline as virCPUBaseline
Applying: cpu_x86: Add support for passing guest CPUs to virCPUx86Baseline
Applying: cpu: Add explicit arch parameter for virCPUBaseline
Applying: cpu: Update style in virCPUBaseline
Applying: cpu: Add optional list of allowed features to virCPUBaseline
Applying: qemu_capabilities: Introduce virQEMUCapsGetCPUFeatures
Applying: qemu: Implement virConnectBaselineHypervisorCPU
Applying: news: Mention new CPU related APIs
To https://github.com/patchew-project/libvirt
 + 15e2d65...2105154 patchew/cover.1526459534.git.jdenemar@redhat.com -> patchew/cover.1526459534.git.jdenemar@redhat.com (forced update)
Test passed: syntax-check

loading

[libvirt] [PATCH 00/22] New CPU related APIs
Posted by Jiri Denemark, 6 days ago
The current virConnectCompareCPU and virConnectBaselineCPU APIs are not
very useful because they ignore what a hypervisor can do on the current
host. This series adds two new APIs which are designed to work with
capabilities of a specific hypervisor to provide usable results.

The third CPU related API virConnectGetCPUModelNames is pretty useless
too, but no new API with similar functionality is needed because domain
capabilities XML already contains the relevant data.

Jiri Denemark (22):
  virsh: Move cpu-{baseline,compare} commands
  virsh: Extract common code from cmdCPU{Compare,Baseline}
  virsh: Enhance documentation of cpu-compare command
  virsh: Enhance documentation of cpu-models command
  Improve documentation of virConnectGetCPUModelNames
  vshExtractCPUDefXML: Accept domain capabilities XML
  qemu_capabilities: Introduce virQEMUCapsCacheLookupDefault
  Introduce virConnectCompareHypervisorCPU public API
  remote: Implement virConnectCompareHypervisorCPU
  virsh: Introduce new hypervisor-cpu-compare command
  qemu: Implement virConnectCompareHypervisorCPU
  Introduce virConnectBaselineHypervisorCPU public API
  remote: Implement virConnectBaselineHypervisorCPU
  virsh: Introduce new hypervisor-cpu-baseline command
  cpu: Rename cpuBaseline as virCPUBaseline
  cpu_x86: Add support for passing guest CPUs to virCPUx86Baseline
  cpu: Add explicit arch parameter for virCPUBaseline
  cpu: Update style in virCPUBaseline
  cpu: Add optional list of allowed features to virCPUBaseline
  qemu_capabilities: Introduce virQEMUCapsGetCPUFeatures
  qemu: Implement virConnectBaselineHypervisorCPU
  news: Mention new CPU related APIs

 docs/news.xml                  |   9 +
 include/libvirt/libvirt-host.h |  15 ++
 src/bhyve/bhyve_driver.c       |   4 +-
 src/cpu/cpu.c                  |  34 ++-
 src/cpu/cpu.h                  |  21 +-
 src/cpu/cpu_arm.c              |  11 +-
 src/cpu/cpu_ppc64.c            |   5 +-
 src/cpu/cpu_x86.c              |  35 ++-
 src/driver-hypervisor.h        |  20 ++
 src/libvirt-host.c             | 161 +++++++++++-
 src/libvirt_private.syms       |   2 +-
 src/libvirt_public.syms        |   6 +
 src/libxl/libxl_driver.c       |   4 +-
 src/qemu/qemu_capabilities.c   | 170 +++++++++++++
 src/qemu/qemu_capabilities.h   |  12 +
 src/qemu/qemu_driver.c         | 241 ++++++++++++------
 src/remote/remote_driver.c     |   4 +-
 src/remote/remote_protocol.x   |  40 ++-
 src/remote_protocol-structs    |  27 ++
 src/test/test_driver.c         |   2 +-
 src/vz/vz_driver.c             |   2 +-
 tests/cputest.c                |   6 +-
 tools/virsh-domain.c           | 223 -----------------
 tools/virsh-host.c             | 441 +++++++++++++++++++++++++++++++++
 tools/virsh.pod                |  90 ++++++-
 25 files changed, 1223 insertions(+), 362 deletions(-)

-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 00/22] New CPU related APIs
Posted by Jiri Denemark, 19 hours ago
On Wed, May 16, 2018 at 10:39:19 +0200, Jiri Denemark wrote:
> The current virConnectCompareCPU and virConnectBaselineCPU APIs are not
> very useful because they ignore what a hypervisor can do on the current
> host. This series adds two new APIs which are designed to work with
> capabilities of a specific hypervisor to provide usable results.
> 
> The third CPU related API virConnectGetCPUModelNames is pretty useless
> too, but no new API with similar functionality is needed because domain
> capabilities XML already contains the relevant data.

Any comments? I'd like to have these new APIs in the upcoming 4.4
release.

Jirka

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 00/22] New CPU related APIs
Posted by Collin Walling, 14 hours ago
On 05/22/2018 05:33 AM, Jiri Denemark wrote:
> On Wed, May 16, 2018 at 10:39:19 +0200, Jiri Denemark wrote:
>> The current virConnectCompareCPU and virConnectBaselineCPU APIs are not
>> very useful because they ignore what a hypervisor can do on the current
>> host. This series adds two new APIs which are designed to work with
>> capabilities of a specific hypervisor to provide usable results.
>>
>> The third CPU related API virConnectGetCPUModelNames is pretty useless
>> too, but no new API with similar functionality is needed because domain
>> capabilities XML already contains the relevant data.
> 
> Any comments? I'd like to have these new APIs in the upcoming 4.4
> release.
> 
> Jirka
> 
> --
> libvir-list mailing list
> libvir-list@redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
> 

This is on top of my todo for today.

-- 
Respectfully,
- Collin Walling

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 01/22] virsh: Move cpu-{baseline, compare} commands
Posted by Jiri Denemark, 6 days ago
Similarly to cpu-models these two commands do not operate on a domain
and should be listed in the "Host and Hypervisor" commands section.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 tools/virsh-domain.c | 223 ------------------------------------------
 tools/virsh-host.c   | 224 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 224 insertions(+), 223 deletions(-)

diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 30da953446..3bb894a425 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -7672,217 +7672,6 @@ cmdIOThreadDel(vshControl *ctl, const vshCmd *cmd)
     return ret;
 }
 
-/*
- * "cpu-compare" command
- */
-static const vshCmdInfo info_cpu_compare[] = {
-    {.name = "help",
-     .data = N_("compare host CPU with a CPU described by an XML file")
-    },
-    {.name = "desc",
-     .data = N_("compare CPU with host CPU")
-    },
-    {.name = NULL}
-};
-
-static const vshCmdOptDef opts_cpu_compare[] = {
-    VIRSH_COMMON_OPT_FILE(N_("file containing an XML CPU description")),
-    {.name = "error",
-     .type = VSH_OT_BOOL,
-     .help = N_("report error if CPUs are incompatible")
-    },
-    {.name = NULL}
-};
-
-static bool
-cmdCPUCompare(vshControl *ctl, const vshCmd *cmd)
-{
-    const char *from = NULL;
-    bool ret = false;
-    char *buffer;
-    int result;
-    char *snippet = NULL;
-    unsigned int flags = 0;
-    xmlDocPtr xml = NULL;
-    xmlXPathContextPtr ctxt = NULL;
-    xmlNodePtr node;
-    virshControlPtr priv = ctl->privData;
-
-    if (vshCommandOptBool(cmd, "error"))
-        flags |= VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE;
-
-    if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0)
-        return false;
-
-    if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0)
-        return false;
-
-    /* try to extract the CPU element from as it would appear in a domain XML*/
-    if (!(xml = virXMLParseStringCtxt(buffer, from, &ctxt)))
-        goto cleanup;
-
-    if ((node = virXPathNode("/cpu|"
-                             "/domain/cpu|"
-                              "/capabilities/host/cpu", ctxt))) {
-        if (!(snippet = virXMLNodeToString(xml, node))) {
-            vshSaveLibvirtError();
-            goto cleanup;
-        }
-    } else {
-        vshError(ctl, _("File '%s' does not contain a <cpu> element or is not "
-                        "a valid domain or capabilities XML"), from);
-        goto cleanup;
-    }
-
-    result = virConnectCompareCPU(priv->conn, snippet, flags);
-
-    switch (result) {
-    case VIR_CPU_COMPARE_INCOMPATIBLE:
-        vshPrint(ctl, _("CPU described in %s is incompatible with host CPU\n"),
-                 from);
-        goto cleanup;
-        break;
-
-    case VIR_CPU_COMPARE_IDENTICAL:
-        vshPrint(ctl, _("CPU described in %s is identical to host CPU\n"),
-                 from);
-        break;
-
-    case VIR_CPU_COMPARE_SUPERSET:
-        vshPrint(ctl, _("Host CPU is a superset of CPU described in %s\n"),
-                 from);
-        break;
-
-    case VIR_CPU_COMPARE_ERROR:
-    default:
-        vshError(ctl, _("Failed to compare host CPU with %s"), from);
-        goto cleanup;
-    }
-
-    ret = true;
-
- cleanup:
-    VIR_FREE(buffer);
-    VIR_FREE(snippet);
-    xmlXPathFreeContext(ctxt);
-    xmlFreeDoc(xml);
-
-    return ret;
-}
-
-/*
- * "cpu-baseline" command
- */
-static const vshCmdInfo info_cpu_baseline[] = {
-    {.name = "help",
-     .data = N_("compute baseline CPU")
-    },
-    {.name = "desc",
-     .data = N_("Compute baseline CPU for a set of given CPUs.")
-    },
-    {.name = NULL}
-};
-
-static const vshCmdOptDef opts_cpu_baseline[] = {
-    VIRSH_COMMON_OPT_FILE(N_("file containing XML CPU descriptions")),
-    {.name = "features",
-     .type = VSH_OT_BOOL,
-     .help = N_("Show features that are part of the CPU model type")
-    },
-    {.name = "migratable",
-     .type = VSH_OT_BOOL,
-     .help = N_("Do not include features that block migration")
-    },
-    {.name = NULL}
-};
-
-static bool
-cmdCPUBaseline(vshControl *ctl, const vshCmd *cmd)
-{
-    const char *from = NULL;
-    bool ret = false;
-    char *buffer;
-    char *result = NULL;
-    char **list = NULL;
-    unsigned int flags = 0;
-    int count = 0;
-
-    xmlDocPtr xml = NULL;
-    xmlNodePtr *node_list = NULL;
-    xmlXPathContextPtr ctxt = NULL;
-    virBuffer buf = VIR_BUFFER_INITIALIZER;
-    size_t i;
-    virshControlPtr priv = ctl->privData;
-
-    if (vshCommandOptBool(cmd, "features"))
-        flags |= VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES;
-    if (vshCommandOptBool(cmd, "migratable"))
-        flags |= VIR_CONNECT_BASELINE_CPU_MIGRATABLE;
-
-    if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0)
-        return false;
-
-    if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0)
-        return false;
-
-    /* add a separate container around the xml */
-    virBufferStrcat(&buf, "<container>", buffer, "</container>", NULL);
-    if (virBufferError(&buf))
-        goto no_memory;
-
-    VIR_FREE(buffer);
-    buffer = virBufferContentAndReset(&buf);
-
-
-    if (!(xml = virXMLParseStringCtxt(buffer, from, &ctxt)))
-        goto cleanup;
-
-    if ((count = virXPathNodeSet("//cpu[not(ancestor::cpus)]",
-                                 ctxt, &node_list)) == -1)
-        goto cleanup;
-
-    if (count == 0) {
-        vshError(ctl, _("No host CPU specified in '%s'"), from);
-        goto cleanup;
-    }
-
-    list = vshCalloc(ctl, count, sizeof(const char *));
-
-    for (i = 0; i < count; i++) {
-        if (!(list[i] = virXMLNodeToString(xml, node_list[i]))) {
-            vshSaveLibvirtError();
-            goto cleanup;
-        }
-    }
-
-    result = virConnectBaselineCPU(priv->conn,
-                                   (const char **)list, count, flags);
-
-    if (result) {
-        vshPrint(ctl, "%s", result);
-        ret = true;
-    }
-
- cleanup:
-    xmlXPathFreeContext(ctxt);
-    xmlFreeDoc(xml);
-    VIR_FREE(result);
-    if (list != NULL && count > 0) {
-        for (i = 0; i < count; i++)
-            VIR_FREE(list[i]);
-    }
-    VIR_FREE(list);
-    VIR_FREE(buffer);
-    VIR_FREE(node_list);
-
-    return ret;
-
- no_memory:
-    vshError(ctl, "%s", _("Out of memory"));
-    ret = false;
-    goto cleanup;
-}
-
 /*
  * "cpu-stats" command
  */
@@ -13942,18 +13731,6 @@ const vshCmdDef domManagementCmds[] = {
      .flags = 0
     },
 #endif
-    {.name = "cpu-baseline",
-     .handler = cmdCPUBaseline,
-     .opts = opts_cpu_baseline,
-     .info = info_cpu_baseline,
-     .flags = 0
-    },
-    {.name = "cpu-compare",
-     .handler = cmdCPUCompare,
-     .opts = opts_cpu_compare,
-     .info = info_cpu_compare,
-     .flags = 0
-    },
     {.name = "cpu-stats",
      .handler = cmdCPUStats,
      .opts = opts_cpu_stats,
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index ecaf830e35..6d6e3cfc85 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -38,6 +38,7 @@
 #include "virxml.h"
 #include "virtypedparam.h"
 #include "virstring.h"
+#include "virfile.h"
 
 /*
  * "capabilities" command
@@ -1105,6 +1106,217 @@ cmdURI(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
     return true;
 }
 
+/*
+ * "cpu-compare" command
+ */
+static const vshCmdInfo info_cpu_compare[] = {
+    {.name = "help",
+     .data = N_("compare host CPU with a CPU described by an XML file")
+    },
+    {.name = "desc",
+     .data = N_("compare CPU with host CPU")
+    },
+    {.name = NULL}
+};
+
+static const vshCmdOptDef opts_cpu_compare[] = {
+    VIRSH_COMMON_OPT_FILE(N_("file containing an XML CPU description")),
+    {.name = "error",
+     .type = VSH_OT_BOOL,
+     .help = N_("report error if CPUs are incompatible")
+    },
+    {.name = NULL}
+};
+
+static bool
+cmdCPUCompare(vshControl *ctl, const vshCmd *cmd)
+{
+    const char *from = NULL;
+    bool ret = false;
+    char *buffer;
+    int result;
+    char *snippet = NULL;
+    unsigned int flags = 0;
+    xmlDocPtr xml = NULL;
+    xmlXPathContextPtr ctxt = NULL;
+    xmlNodePtr node;
+    virshControlPtr priv = ctl->privData;
+
+    if (vshCommandOptBool(cmd, "error"))
+        flags |= VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE;
+
+    if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0)
+        return false;
+
+    if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0)
+        return false;
+
+    /* try to extract the CPU element from as it would appear in a domain XML*/
+    if (!(xml = virXMLParseStringCtxt(buffer, from, &ctxt)))
+        goto cleanup;
+
+    if ((node = virXPathNode("/cpu|"
+                             "/domain/cpu|"
+                              "/capabilities/host/cpu", ctxt))) {
+        if (!(snippet = virXMLNodeToString(xml, node))) {
+            vshSaveLibvirtError();
+            goto cleanup;
+        }
+    } else {
+        vshError(ctl, _("File '%s' does not contain a <cpu> element or is not "
+                        "a valid domain or capabilities XML"), from);
+        goto cleanup;
+    }
+
+    result = virConnectCompareCPU(priv->conn, snippet, flags);
+
+    switch (result) {
+    case VIR_CPU_COMPARE_INCOMPATIBLE:
+        vshPrint(ctl, _("CPU described in %s is incompatible with host CPU\n"),
+                 from);
+        goto cleanup;
+        break;
+
+    case VIR_CPU_COMPARE_IDENTICAL:
+        vshPrint(ctl, _("CPU described in %s is identical to host CPU\n"),
+                 from);
+        break;
+
+    case VIR_CPU_COMPARE_SUPERSET:
+        vshPrint(ctl, _("Host CPU is a superset of CPU described in %s\n"),
+                 from);
+        break;
+
+    case VIR_CPU_COMPARE_ERROR:
+    default:
+        vshError(ctl, _("Failed to compare host CPU with %s"), from);
+        goto cleanup;
+    }
+
+    ret = true;
+
+ cleanup:
+    VIR_FREE(buffer);
+    VIR_FREE(snippet);
+    xmlXPathFreeContext(ctxt);
+    xmlFreeDoc(xml);
+
+    return ret;
+}
+
+/*
+ * "cpu-baseline" command
+ */
+static const vshCmdInfo info_cpu_baseline[] = {
+    {.name = "help",
+     .data = N_("compute baseline CPU")
+    },
+    {.name = "desc",
+     .data = N_("Compute baseline CPU for a set of given CPUs.")
+    },
+    {.name = NULL}
+};
+
+static const vshCmdOptDef opts_cpu_baseline[] = {
+    VIRSH_COMMON_OPT_FILE(N_("file containing XML CPU descriptions")),
+    {.name = "features",
+     .type = VSH_OT_BOOL,
+     .help = N_("Show features that are part of the CPU model type")
+    },
+    {.name = "migratable",
+     .type = VSH_OT_BOOL,
+     .help = N_("Do not include features that block migration")
+    },
+    {.name = NULL}
+};
+
+static bool
+cmdCPUBaseline(vshControl *ctl, const vshCmd *cmd)
+{
+    const char *from = NULL;
+    bool ret = false;
+    char *buffer;
+    char *result = NULL;
+    char **list = NULL;
+    unsigned int flags = 0;
+    int count = 0;
+
+    xmlDocPtr xml = NULL;
+    xmlNodePtr *node_list = NULL;
+    xmlXPathContextPtr ctxt = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    size_t i;
+    virshControlPtr priv = ctl->privData;
+
+    if (vshCommandOptBool(cmd, "features"))
+        flags |= VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES;
+    if (vshCommandOptBool(cmd, "migratable"))
+        flags |= VIR_CONNECT_BASELINE_CPU_MIGRATABLE;
+
+    if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0)
+        return false;
+
+    if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0)
+        return false;
+
+    /* add a separate container around the xml */
+    virBufferStrcat(&buf, "<container>", buffer, "</container>", NULL);
+    if (virBufferError(&buf))
+        goto no_memory;
+
+    VIR_FREE(buffer);
+    buffer = virBufferContentAndReset(&buf);
+
+
+    if (!(xml = virXMLParseStringCtxt(buffer, from, &ctxt)))
+        goto cleanup;
+
+    if ((count = virXPathNodeSet("//cpu[not(ancestor::cpus)]",
+                                 ctxt, &node_list)) == -1)
+        goto cleanup;
+
+    if (count == 0) {
+        vshError(ctl, _("No host CPU specified in '%s'"), from);
+        goto cleanup;
+    }
+
+    list = vshCalloc(ctl, count, sizeof(const char *));
+
+    for (i = 0; i < count; i++) {
+        if (!(list[i] = virXMLNodeToString(xml, node_list[i]))) {
+            vshSaveLibvirtError();
+            goto cleanup;
+        }
+    }
+
+    result = virConnectBaselineCPU(priv->conn,
+                                   (const char **)list, count, flags);
+
+    if (result) {
+        vshPrint(ctl, "%s", result);
+        ret = true;
+    }
+
+ cleanup:
+    xmlXPathFreeContext(ctxt);
+    xmlFreeDoc(xml);
+    VIR_FREE(result);
+    if (list != NULL && count > 0) {
+        for (i = 0; i < count; i++)
+            VIR_FREE(list[i]);
+    }
+    VIR_FREE(list);
+    VIR_FREE(buffer);
+    VIR_FREE(node_list);
+
+    return ret;
+
+ no_memory:
+    vshError(ctl, "%s", _("Out of memory"));
+    ret = false;
+    goto cleanup;
+}
+
 /*
  * "cpu-models" command
  */
@@ -1388,6 +1600,18 @@ const vshCmdDef hostAndHypervisorCmds[] = {
      .info = info_capabilities,
      .flags = 0
     },
+    {.name = "cpu-baseline",
+     .handler = cmdCPUBaseline,
+     .opts = opts_cpu_baseline,
+     .info = info_cpu_baseline,
+     .flags = 0
+    },
+    {.name = "cpu-compare",
+     .handler = cmdCPUCompare,
+     .opts = opts_cpu_compare,
+     .info = info_cpu_compare,
+     .flags = 0
+    },
     {.name = "cpu-models",
      .handler = cmdCPUModelNames,
      .opts = opts_cpu_models,
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 01/22] virsh: Move cpu-{baseline, compare} commands
Posted by Collin Walling, 14 hours ago
On 05/16/2018 04:39 AM, Jiri Denemark wrote:
> Similarly to cpu-models these two commands do not operate on a domain
> and should be listed in the "Host and Hypervisor" commands section.
> 
> Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
> ---
>  tools/virsh-domain.c | 223 ------------------------------------------
>  tools/virsh-host.c   | 224 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 224 insertions(+), 223 deletions(-)
> 

Makes sense to me.

Reviewed-by: Collin Walling <walling@linux.ibm.com>


-- 
Respectfully,
- Collin Walling

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 02/22] virsh: Extract common code from cmdCPU{Compare, Baseline}
Posted by Jiri Denemark, 6 days ago
Both cpu-compare and cpu-baseline commands accept more that just CPU
definition XML(s). For users' convenience they are able to extract the
CPU definition(s) even from domain XML or capabilities XML. The main
differences between the two commands is in the number of CPU definitions
they expect: cpu-compare wants only one CPU definition while
cpu-baseline expects one or more CPUs.

The extracted code forms a new vshExtractCPUDefXML function.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 tools/virsh-host.c | 160 +++++++++++++++++++++------------------------
 1 file changed, 75 insertions(+), 85 deletions(-)

diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index 6d6e3cfc85..51497db385 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -1106,6 +1106,72 @@ cmdURI(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
     return true;
 }
 
+
+/* Extracts the CPU definition XML strings from a file which may contain either
+ *  - just the CPU definitions,
+ *  - domain XMLs, or
+ *  - capabilities XMLs.
+ *
+ * Returns NULL terminated string list.
+ */
+static char **
+vshExtractCPUDefXMLs(vshControl *ctl,
+                     const char *xmlFile)
+{
+    char **cpus = NULL;
+    char *buffer = NULL;
+    char *xmlStr = NULL;
+    xmlDocPtr xml = NULL;
+    xmlXPathContextPtr ctxt = NULL;
+    xmlNodePtr *nodes = NULL;
+    size_t i;
+    int n;
+
+    if (virFileReadAll(xmlFile, VSH_MAX_XML_FILE, &buffer) < 0)
+        goto error;
+
+    if (virAsprintf(&xmlStr, "<container>%s</container>", buffer) < 0)
+        goto error;
+
+    if (!(xml = virXMLParseStringCtxt(xmlStr, xmlFile, &ctxt)))
+        goto error;
+
+    n = virXPathNodeSet("/container/cpu|"
+                        "/container/domain/cpu|"
+                        "/container/capabilities/host/cpu",
+                        ctxt, &nodes);
+    if (n < 0)
+        goto error;
+
+    if (n == 0) {
+        vshError(ctl, _("File '%s' does not contain any <cpu> element or "
+                        "valid domain or capabilities XML"), xmlFile);
+        goto error;
+    }
+
+    cpus = vshCalloc(ctl, n + 1, sizeof(const char *));
+
+    for (i = 0; i < n; i++) {
+        if (!(cpus[i] = virXMLNodeToString(xml, nodes[i]))) {
+            vshSaveLibvirtError();
+            goto error;
+        }
+    }
+
+ cleanup:
+    VIR_FREE(buffer);
+    VIR_FREE(xmlStr);
+    xmlFreeDoc(xml);
+    xmlXPathFreeContext(ctxt);
+    VIR_FREE(nodes);
+    return cpus;
+
+ error:
+    virStringListFree(cpus);
+    goto cleanup;
+}
+
+
 /*
  * "cpu-compare" command
  */
@@ -1133,13 +1199,9 @@ cmdCPUCompare(vshControl *ctl, const vshCmd *cmd)
 {
     const char *from = NULL;
     bool ret = false;
-    char *buffer;
     int result;
-    char *snippet = NULL;
+    char **cpus = NULL;
     unsigned int flags = 0;
-    xmlDocPtr xml = NULL;
-    xmlXPathContextPtr ctxt = NULL;
-    xmlNodePtr node;
     virshControlPtr priv = ctl->privData;
 
     if (vshCommandOptBool(cmd, "error"))
@@ -1148,27 +1210,10 @@ cmdCPUCompare(vshControl *ctl, const vshCmd *cmd)
     if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0)
         return false;
 
-    if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0)
+    if (!(cpus = vshExtractCPUDefXMLs(ctl, from)))
         return false;
 
-    /* try to extract the CPU element from as it would appear in a domain XML*/
-    if (!(xml = virXMLParseStringCtxt(buffer, from, &ctxt)))
-        goto cleanup;
-
-    if ((node = virXPathNode("/cpu|"
-                             "/domain/cpu|"
-                              "/capabilities/host/cpu", ctxt))) {
-        if (!(snippet = virXMLNodeToString(xml, node))) {
-            vshSaveLibvirtError();
-            goto cleanup;
-        }
-    } else {
-        vshError(ctl, _("File '%s' does not contain a <cpu> element or is not "
-                        "a valid domain or capabilities XML"), from);
-        goto cleanup;
-    }
-
-    result = virConnectCompareCPU(priv->conn, snippet, flags);
+    result = virConnectCompareCPU(priv->conn, cpus[0], flags);
 
     switch (result) {
     case VIR_CPU_COMPARE_INCOMPATIBLE:
@@ -1196,10 +1241,7 @@ cmdCPUCompare(vshControl *ctl, const vshCmd *cmd)
     ret = true;
 
  cleanup:
-    VIR_FREE(buffer);
-    VIR_FREE(snippet);
-    xmlXPathFreeContext(ctxt);
-    xmlFreeDoc(xml);
+    virStringListFree(cpus);
 
     return ret;
 }
@@ -1235,17 +1277,9 @@ cmdCPUBaseline(vshControl *ctl, const vshCmd *cmd)
 {
     const char *from = NULL;
     bool ret = false;
-    char *buffer;
     char *result = NULL;
     char **list = NULL;
     unsigned int flags = 0;
-    int count = 0;
-
-    xmlDocPtr xml = NULL;
-    xmlNodePtr *node_list = NULL;
-    xmlXPathContextPtr ctxt = NULL;
-    virBuffer buf = VIR_BUFFER_INITIALIZER;
-    size_t i;
     virshControlPtr priv = ctl->privData;
 
     if (vshCommandOptBool(cmd, "features"))
@@ -1256,65 +1290,21 @@ cmdCPUBaseline(vshControl *ctl, const vshCmd *cmd)
     if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0)
         return false;
 
-    if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0)
+    if (!(list = vshExtractCPUDefXMLs(ctl, from)))
         return false;
 
-    /* add a separate container around the xml */
-    virBufferStrcat(&buf, "<container>", buffer, "</container>", NULL);
-    if (virBufferError(&buf))
-        goto no_memory;
-
-    VIR_FREE(buffer);
-    buffer = virBufferContentAndReset(&buf);
-
-
-    if (!(xml = virXMLParseStringCtxt(buffer, from, &ctxt)))
-        goto cleanup;
-
-    if ((count = virXPathNodeSet("//cpu[not(ancestor::cpus)]",
-                                 ctxt, &node_list)) == -1)
-        goto cleanup;
-
-    if (count == 0) {
-        vshError(ctl, _("No host CPU specified in '%s'"), from);
-        goto cleanup;
-    }
-
-    list = vshCalloc(ctl, count, sizeof(const char *));
-
-    for (i = 0; i < count; i++) {
-        if (!(list[i] = virXMLNodeToString(xml, node_list[i]))) {
-            vshSaveLibvirtError();
-            goto cleanup;
-        }
-    }
-
-    result = virConnectBaselineCPU(priv->conn,
-                                   (const char **)list, count, flags);
+    result = virConnectBaselineCPU(priv->conn, (const char **)list,
+                                   virStringListLength((const char **)list),
+                                   flags);
 
     if (result) {
         vshPrint(ctl, "%s", result);
         ret = true;
     }
 
- cleanup:
-    xmlXPathFreeContext(ctxt);
-    xmlFreeDoc(xml);
     VIR_FREE(result);
-    if (list != NULL && count > 0) {
-        for (i = 0; i < count; i++)
-            VIR_FREE(list[i]);
-    }
-    VIR_FREE(list);
-    VIR_FREE(buffer);
-    VIR_FREE(node_list);
-
+    virStringListFree(list);
     return ret;
-
- no_memory:
-    vshError(ctl, "%s", _("Out of memory"));
-    ret = false;
-    goto cleanup;
 }
 
 /*
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 02/22] virsh: Extract common code from cmdCPU{Compare, Baseline}
Posted by Collin Walling, 7 hours ago
On 05/16/2018 04:39 AM, Jiri Denemark wrote:
> Both cpu-compare and cpu-baseline commands accept more that just CPU
> definition XML(s). For users' convenience they are able to extract the
> CPU definition(s) even from domain XML or capabilities XML. The main
> differences between the two commands is in the number of CPU definitions
> they expect: cpu-compare wants only one CPU definition while
> cpu-baseline expects one or more CPUs.
> 
> The extracted code forms a new vshExtractCPUDefXML function.
> 
> Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
> ---
>  tools/virsh-host.c | 160 +++++++++++++++++++++------------------------
>  1 file changed, 75 insertions(+), 85 deletions(-)
> 
> diff --git a/tools/virsh-host.c b/tools/virsh-host.c
> index 6d6e3cfc85..51497db385 100644
> --- a/tools/virsh-host.c
> +++ b/tools/virsh-host.c
> @@ -1106,6 +1106,72 @@ cmdURI(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
>      return true;
>  }
>  
> +
> +/* Extracts the CPU definition XML strings from a file which may contain either
> + *  - just the CPU definitions,
> + *  - domain XMLs, or
> + *  - capabilities XMLs.
> + *
> + * Returns NULL terminated string list.
> + */
> +static char **
> +vshExtractCPUDefXMLs(vshControl *ctl,
> +                     const char *xmlFile)
> +{
> +    char **cpus = NULL;
> +    char *buffer = NULL;
> +    char *xmlStr = NULL;
> +    xmlDocPtr xml = NULL;
> +    xmlXPathContextPtr ctxt = NULL;
> +    xmlNodePtr *nodes = NULL;
> +    size_t i;
> +    int n;
> +
> +    if (virFileReadAll(xmlFile, VSH_MAX_XML_FILE, &buffer) < 0)
> +        goto error;
> +
> +    if (virAsprintf(&xmlStr, "<container>%s</container>", buffer) < 0)
> +        goto error;
> +

Why wrap the xml in the <container> tags?

> +    if (!(xml = virXMLParseStringCtxt(xmlStr, xmlFile, &ctxt)))
> +        goto error;
> +
> +    n = virXPathNodeSet("/container/cpu|"
> +                        "/container/domain/cpu|"
> +                        "/container/capabilities/host/cpu",
> +                        ctxt, &nodes);
> +    if (n < 0)
> +        goto error;
> +
> +    if (n == 0) {
> +        vshError(ctl, _("File '%s' does not contain any <cpu> element or "
> +                        "valid domain or capabilities XML"), xmlFile);
> +        goto error;
> +    }
> +
> +    cpus = vshCalloc(ctl, n + 1, sizeof(const char *));
> +
> +    for (i = 0; i < n; i++) {
> +        if (!(cpus[i] = virXMLNodeToString(xml, nodes[i]))) {
> +            vshSaveLibvirtError();
> +            goto error;
> +        }
> +    }
> +
> + cleanup:
> +    VIR_FREE(buffer);
> +    VIR_FREE(xmlStr);
> +    xmlFreeDoc(xml);
> +    xmlXPathFreeContext(ctxt);
> +    VIR_FREE(nodes);
> +    return cpus;
> +
> + error:
> +    virStringListFree(cpus);
> +    goto cleanup;
> +}
> +
> +
>  /*
>   * "cpu-compare" command
>   */
> @@ -1133,13 +1199,9 @@ cmdCPUCompare(vshControl *ctl, const vshCmd *cmd)
>  {
>      const char *from = NULL;
>      bool ret = false;
> -    char *buffer;
>      int result;
> -    char *snippet = NULL;
> +    char **cpus = NULL;
>      unsigned int flags = 0;
> -    xmlDocPtr xml = NULL;
> -    xmlXPathContextPtr ctxt = NULL;
> -    xmlNodePtr node;
>      virshControlPtr priv = ctl->privData;
>  
>      if (vshCommandOptBool(cmd, "error"))
> @@ -1148,27 +1210,10 @@ cmdCPUCompare(vshControl *ctl, const vshCmd *cmd)
>      if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0)
>          return false;
>  
> -    if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0)
> +    if (!(cpus = vshExtractCPUDefXMLs(ctl, from)))
>          return false;
>  
> -    /* try to extract the CPU element from as it would appear in a domain XML*/
> -    if (!(xml = virXMLParseStringCtxt(buffer, from, &ctxt)))
> -        goto cleanup;
> -
> -    if ((node = virXPathNode("/cpu|"
> -                             "/domain/cpu|"
> -                              "/capabilities/host/cpu", ctxt))) {
> -        if (!(snippet = virXMLNodeToString(xml, node))) {
> -            vshSaveLibvirtError();
> -            goto cleanup;
> -        }
> -    } else {
> -        vshError(ctl, _("File '%s' does not contain a <cpu> element or is not "
> -                        "a valid domain or capabilities XML"), from);
> -        goto cleanup;
> -    }
> -
> -    result = virConnectCompareCPU(priv->conn, snippet, flags);
> +    result = virConnectCompareCPU(priv->conn, cpus[0], flags);

I wonder if it's worth commenting here or adding to the cpu compare docs that comparison only
compares the host CPU with the _first_ cpu found in the XML file?

>  
>      switch (result) {
>      case VIR_CPU_COMPARE_INCOMPATIBLE:
> @@ -1196,10 +1241,7 @@ cmdCPUCompare(vshControl *ctl, const vshCmd *cmd)
>      ret = true;
>  
>   cleanup:
> -    VIR_FREE(buffer);
> -    VIR_FREE(snippet);
> -    xmlXPathFreeContext(ctxt);
> -    xmlFreeDoc(xml);
> +    virStringListFree(cpus);
>  
>      return ret;
>  }
[...]

The rest of this patch looks good... I'd like to take another look tomorrow in case I missed
anything subtle.


-- 
Respectfully,
- Collin Walling

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 03/22] virsh: Enhance documentation of cpu-compare command
Posted by Jiri Denemark, 6 days ago
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 tools/virsh.pod | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/virsh.pod b/tools/virsh.pod
index 929958a953..5f72e11dec 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -589,7 +589,9 @@ Compare CPU definition from XML <file> with host CPU. The XML <file> may
 contain either host or guest CPU definition. The host CPU definition is the
 <cpu> element and its contents as printed by B<capabilities> command. The
 guest CPU definition is the <cpu> element and its contents from domain XML
-definition. For more information on guest CPU definition see:
+definition. In addition to the <cpu> element itself, this command accepts
+full domain or capabilities XML containing the <cpu> element. For more
+information on guest CPU definition see:
 L<https://libvirt.org/formatdomain.html#elementsCPU>. If I<--error> is
 specified, the command will return an error when the given CPU is
 incompatible with host CPU and a message providing more details about the
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 03/22] virsh: Enhance documentation of cpu-compare command
Posted by Collin Walling, 7 hours ago
On 05/16/2018 04:39 AM, Jiri Denemark wrote:
> Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
> ---
>  tools/virsh.pod | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/virsh.pod b/tools/virsh.pod
> index 929958a953..5f72e11dec 100644
> --- a/tools/virsh.pod
> +++ b/tools/virsh.pod
> @@ -589,7 +589,9 @@ Compare CPU definition from XML <file> with host CPU. The XML <file> may
>  contain either host or guest CPU definition. The host CPU definition is the
>  <cpu> element and its contents as printed by B<capabilities> command. The
>  guest CPU definition is the <cpu> element and its contents from domain XML
> -definition. For more information on guest CPU definition see:
> +definition. In addition to the <cpu> element itself, this command accepts
> +full domain or capabilities XML containing the <cpu> element. For more
> +information on guest CPU definition see:
>  L<https://libvirt.org/formatdomain.html#elementsCPU>. If I<--error> is
>  specified, the command will return an error when the given CPU is
>  incompatible with host CPU and a message providing more details about the
> 

Reviewed-by: Collin Walling <walling@linux.ibm.com>

-- 
Respectfully,
- Collin Walling

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 04/22] virsh: Enhance documentation of cpu-models command
Posted by Jiri Denemark, 6 days ago
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 tools/virsh.pod | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/tools/virsh.pod b/tools/virsh.pod
index 5f72e11dec..5fc8201893 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -599,7 +599,13 @@ incompatibility will be printed out.
 
 =item B<cpu-models> I<arch>
 
-Print the list of CPU models known for the specified architecture.
+Print the list of CPU models known by libvirt for the specified architecture.
+Whether a specific hypervisor is able to create a domain which uses any of
+the printed CPU models is a separate question which can be answered by
+looking the domain capabilities XML returned by B<domcapabilities> command.
+Moreover, for some architectures libvirt does not know any CPU models and
+the usable CPU models are only limited by the hypervisor. This command will
+print that all CPU models are accepted for these architectures.
 
 =item B<echo> [I<--shell>] [I<--xml>] [I<arg>...]
 
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 04/22] virsh: Enhance documentation of cpu-models command
Posted by Collin Walling, 7 hours ago
On 05/16/2018 04:39 AM, Jiri Denemark wrote:
> Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
> ---
>  tools/virsh.pod | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/virsh.pod b/tools/virsh.pod
> index 5f72e11dec..5fc8201893 100644
> --- a/tools/virsh.pod
> +++ b/tools/virsh.pod
> @@ -599,7 +599,13 @@ incompatibility will be printed out.
>  
>  =item B<cpu-models> I<arch>
>  
> -Print the list of CPU models known for the specified architecture.
> +Print the list of CPU models known by libvirt for the specified architecture.
> +Whether a specific hypervisor is able to create a domain which uses any of
> +the printed CPU models is a separate question which can be answered by
> +looking the domain capabilities XML returned by B<domcapabilities> command.
> +Moreover, for some architectures libvirt does not know any CPU models and
> +the usable CPU models are only limited by the hypervisor. This command will
> +print that all CPU models are accepted for these architectures.
>  
>  =item B<echo> [I<--shell>] [I<--xml>] [I<arg>...]
>  
>
Reviewed-by: Collin Walling <walling@linux.ibm.com>

-- 
Respectfully,
- Collin Walling

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 05/22] Improve documentation of virConnectGetCPUModelNames
Posted by Jiri Denemark, 6 days ago
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/libvirt-host.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/libvirt-host.c b/src/libvirt-host.c
index 76087badd8..ed689b9ec2 100644
--- a/src/libvirt-host.c
+++ b/src/libvirt-host.c
@@ -1003,7 +1003,13 @@ virConnectCompareCPU(virConnectPtr conn,
  *          NULL if only the list length is needed.
  * @flags: extra flags; not used yet, so callers should always pass 0.
  *
- * Get the list of supported CPU models for a specific architecture.
+ * Get the list of CPU models supported by libvirt for a specific architecture.
+ *
+ * The returned list limits CPU models usable with libvirt (empty list means,
+ * there's no limit imposed by libvirt) and it does not reflect capabalities of
+ * any hypervisor. See the XML returned by virConnectGetDomainCapabilities()
+ * for a list of CPU models supported by libvirt for domains created on a
+ * specific hypervisor.
  *
  * Returns -1 on error, number of elements in @models on success (0 means
  * libvirt accepts any CPU model).
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 05/22] Improve documentation of virConnectGetCPUModelNames
Posted by Collin Walling, 7 hours ago
On 05/16/2018 04:39 AM, Jiri Denemark wrote:
> Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
> ---
>  src/libvirt-host.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/src/libvirt-host.c b/src/libvirt-host.c
> index 76087badd8..ed689b9ec2 100644
> --- a/src/libvirt-host.c
> +++ b/src/libvirt-host.c
> @@ -1003,7 +1003,13 @@ virConnectCompareCPU(virConnectPtr conn,
>   *          NULL if only the list length is needed.
>   * @flags: extra flags; not used yet, so callers should always pass 0.
>   *
> - * Get the list of supported CPU models for a specific architecture.
> + * Get the list of CPU models supported by libvirt for a specific architecture.
> + *
> + * The returned list limits CPU models usable with libvirt (empty list means,
> + * there's no limit imposed by libvirt) and it does not reflect capabalities of

s/capabalities/capabilities

> + * any hypervisor. See the XML returned by virConnectGetDomainCapabilities()
> + * for a list of CPU models supported by libvirt for domains created on a
> + * specific hypervisor.
>   *
>   * Returns -1 on error, number of elements in @models on success (0 means
>   * libvirt accepts any CPU model).
> 

Other than that:

Reviewed-by: Collin Walling <walling@linux.ibm.com>

-- 
Respectfully,
- Collin Walling

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 06/22] vshExtractCPUDefXML: Accept domain capabilities XML
Posted by Jiri Denemark, 6 days ago
The domain capabilities XML contains host CPU model tailored to a
specific hypervisor and since it's enclosed in <mode name='host-model'>
element rather then the required <cpu> it's impossible to directly use
the host CPU model as an input to, e.g., cpu-compare command. To make
this more convenient, vshExtractCPUDefXML now accepts full domain
capabilities XML and automatically transforms the host CPU models into
the form accepted by libvirt APIs.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 tools/virsh-host.c | 26 ++++++++++++++++++++++----
 tools/virsh.pod    |  8 +++++---
 2 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index 51497db385..ea2c411c02 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -1109,8 +1109,9 @@ cmdURI(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
 
 /* Extracts the CPU definition XML strings from a file which may contain either
  *  - just the CPU definitions,
- *  - domain XMLs, or
- *  - capabilities XMLs.
+ *  - domain XMLs,
+ *  - capabilities XMLs, or
+ *  - domain capabilities XMLs.
  *
  * Returns NULL terminated string list.
  */
@@ -1138,20 +1139,37 @@ vshExtractCPUDefXMLs(vshControl *ctl,
 
     n = virXPathNodeSet("/container/cpu|"
                         "/container/domain/cpu|"
-                        "/container/capabilities/host/cpu",
+                        "/container/capabilities/host/cpu|"
+                        "/container/domainCapabilities/cpu/"
+                            "mode[@name='host-model' and @supported='yes']",
                         ctxt, &nodes);
     if (n < 0)
         goto error;
 
     if (n == 0) {
         vshError(ctl, _("File '%s' does not contain any <cpu> element or "
-                        "valid domain or capabilities XML"), xmlFile);
+                        "valid domain XML, host capabilities XML, or "
+                        "domain capabilities XML"), xmlFile);
         goto error;
     }
 
     cpus = vshCalloc(ctl, n + 1, sizeof(const char *));
 
     for (i = 0; i < n; i++) {
+        /* If the user provided domain capabilities XML, we need to replace
+         * <mode ...> element with <cpu>. */
+        if (xmlStrEqual(nodes[i]->name, BAD_CAST "mode")) {
+            xmlNodeSetName(nodes[i], (const xmlChar *)"cpu");
+            while (nodes[i]->properties) {
+                if (xmlRemoveProp(nodes[i]->properties) < 0) {
+                    vshError(ctl,
+                             _("Cannot extract CPU definition from domain "
+                               "capabilities XML"));
+                    goto error;
+                }
+            }
+        }
+
         if (!(cpus[i] = virXMLNodeToString(xml, nodes[i]))) {
             vshSaveLibvirtError();
             goto error;
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 5fc8201893..ea10e1ad43 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -589,9 +589,11 @@ Compare CPU definition from XML <file> with host CPU. The XML <file> may
 contain either host or guest CPU definition. The host CPU definition is the
 <cpu> element and its contents as printed by B<capabilities> command. The
 guest CPU definition is the <cpu> element and its contents from domain XML
-definition. In addition to the <cpu> element itself, this command accepts
-full domain or capabilities XML containing the <cpu> element. For more
-information on guest CPU definition see:
+definition or the CPU definition created from the host CPU model found in
+domain capabilities XML (printed by B<domcapabilities> command). In
+addition to the <cpu> element itself, this command accepts
+full domain XML, capabilities XML, or domain capabilities XML containing
+the CPU definition. For more information on guest CPU definition see:
 L<https://libvirt.org/formatdomain.html#elementsCPU>. If I<--error> is
 specified, the command will return an error when the given CPU is
 incompatible with host CPU and a message providing more details about the
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 06/22] vshExtractCPUDefXML: Accept domain capabilities XML
Posted by Collin Walling, 6 hours ago
On 05/16/2018 04:39 AM, Jiri Denemark wrote:
> The domain capabilities XML contains host CPU model tailored to a
> specific hypervisor and since it's enclosed in <mode name='host-model'>
> element rather then the required <cpu> it's impossible to directly use
> the host CPU model as an input to, e.g., cpu-compare command. To make
> this more convenient, vshExtractCPUDefXML now accepts full domain
> capabilities XML and automatically transforms the host CPU models into
> the form accepted by libvirt APIs.
> 
> Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
> ---
>  tools/virsh-host.c | 26 ++++++++++++++++++++++----
>  tools/virsh.pod    |  8 +++++---
>  2 files changed, 27 insertions(+), 7 deletions(-)
> 
> diff --git a/tools/virsh-host.c b/tools/virsh-host.c
> index 51497db385..ea2c411c02 100644
> --- a/tools/virsh-host.c
> +++ b/tools/virsh-host.c
> @@ -1109,8 +1109,9 @@ cmdURI(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
>  
>  /* Extracts the CPU definition XML strings from a file which may contain either
>   *  - just the CPU definitions,
> - *  - domain XMLs, or
> - *  - capabilities XMLs.
> + *  - domain XMLs,
> + *  - capabilities XMLs, or
> + *  - domain capabilities XMLs.
>   *
>   * Returns NULL terminated string list.
>   */
> @@ -1138,20 +1139,37 @@ vshExtractCPUDefXMLs(vshControl *ctl,
>  
>      n = virXPathNodeSet("/container/cpu|"
>                          "/container/domain/cpu|"
> -                        "/container/capabilities/host/cpu",
> +                        "/container/capabilities/host/cpu|"
> +                        "/container/domainCapabilities/cpu/"
> +                            "mode[@name='host-model' and @supported='yes']",
>                          ctxt, &nodes);
>      if (n < 0)
>          goto error;
>  
>      if (n == 0) {
>          vshError(ctl, _("File '%s' does not contain any <cpu> element or "
> -                        "valid domain or capabilities XML"), xmlFile);
> +                        "valid domain XML, host capabilities XML, or "
> +                        "domain capabilities XML"), xmlFile);
>          goto error;
>      }
>  
>      cpus = vshCalloc(ctl, n + 1, sizeof(const char *));
>  
>      for (i = 0; i < n; i++) {
> +        /* If the user provided domain capabilities XML, we need to replace
> +         * <mode ...> element with <cpu>. */
> +        if (xmlStrEqual(nodes[i]->name, BAD_CAST "mode")) {
> +            xmlNodeSetName(nodes[i], (const xmlChar *)"cpu");
> +            while (nodes[i]->properties) {
> +                if (xmlRemoveProp(nodes[i]->properties) < 0) {
> +                    vshError(ctl,
> +                             _("Cannot extract CPU definition from domain "
> +                               "capabilities XML"));
> +                    goto error;
> +                }
> +            }
> +        }
> +
>          if (!(cpus[i] = virXMLNodeToString(xml, nodes[i]))) {
>              vshSaveLibvirtError();
>              goto error;
> diff --git a/tools/virsh.pod b/tools/virsh.pod
> index 5fc8201893..ea10e1ad43 100644
> --- a/tools/virsh.pod
> +++ b/tools/virsh.pod
> @@ -589,9 +589,11 @@ Compare CPU definition from XML <file> with host CPU. The XML <file> may
>  contain either host or guest CPU definition. The host CPU definition is the
>  <cpu> element and its contents as printed by B<capabilities> command. The
>  guest CPU definition is the <cpu> element and its contents from domain XML
> -definition. In addition to the <cpu> element itself, this command accepts
> -full domain or capabilities XML containing the <cpu> element. For more
> -information on guest CPU definition see:
> +definition or the CPU definition created from the host CPU model found in
> +domain capabilities XML (printed by B<domcapabilities> command). In
> +addition to the <cpu> element itself, this command accepts
> +full domain XML, capabilities XML, or domain capabilities XML containing
> +the CPU definition. For more information on guest CPU definition see:
>  L<https://libvirt.org/formatdomain.html#elementsCPU>. If I<--error> is
>  specified, the command will return an error when the given CPU is
>  incompatible with host CPU and a message providing more details about the
> 

Reviewed-by: Collin Walling <walling@linux.ibm.com>

-- 
Respectfully,
- Collin Walling

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 07/22] qemu_capabilities: Introduce virQEMUCapsCacheLookupDefault
Posted by Jiri Denemark, 6 days ago
virConnectGetDomainCapabilities needs to lookup QEMU capabilities
matching a specified binary, architecture, virt type, and machine type
while using default values when any of the parameters are not provided
by the user. Let's extract the lookup code into
virQEMUCapsCacheLookupDefault to make it reusable.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/qemu/qemu_capabilities.c | 118 +++++++++++++++++++++++++++++++++++
 src/qemu/qemu_capabilities.h |   8 +++
 src/qemu/qemu_driver.c       |  86 ++++---------------------
 3 files changed, 137 insertions(+), 75 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index a5cb24fec6..77a4b4154e 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4546,6 +4546,124 @@ virQEMUCapsCacheLookupByArch(virFileCachePtr cache,
 }
 
 
+/**
+ * virQEMUCapsCacheLookupDefault:
+ * @cache: QEMU capabilities cache
+ * @binary: optional path to QEMU binary
+ * @archStr: optional guest architecture
+ * @virttypeStr: optional virt type
+ * @machine: optional machine type
+ * @retArch: if non-NULL, guest architecture will be returned here
+ * @retVirttype: if non-NULL, domain virt type will be returned here
+ * @retMachine: if non-NULL, canonical machine type will be returned here
+ *
+ * Looks up the QEMU binary specified by @binary and @archStr, checks it can
+ * provide the required @virttypeStr and @machine and returns its capabilities.
+ * Sensible defaults are used for any argument which is NULL (the function can
+ * even be called with all NULL arguments).
+ *
+ * Returns QEMU capabilities matching the requirements, NULL on error.
+ */
+virQEMUCapsPtr
+virQEMUCapsCacheLookupDefault(virFileCachePtr cache,
+                              const char *binary,
+                              const char *archStr,
+                              const char *virttypeStr,
+                              const char *machine,
+                              virArch *retArch,
+                              virDomainVirtType *retVirttype,
+                              const char **retMachine)
+{
+    int virttype = VIR_DOMAIN_VIRT_NONE;
+    int arch = virArchFromHost();
+    virDomainVirtType capsType;
+    virQEMUCapsPtr qemuCaps = NULL;
+    virQEMUCapsPtr ret = NULL;
+
+    if (virttypeStr &&
+        (virttype = virDomainVirtTypeFromString(virttypeStr)) < 0) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("unknown virttype: %s"), virttypeStr);
+        goto cleanup;
+    }
+
+    if (archStr &&
+        (arch = virArchFromString(archStr)) == VIR_ARCH_NONE) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("unknown architecture: %s"), archStr);
+        goto cleanup;
+    }
+
+    if (binary) {
+        virArch arch_from_caps;
+
+        if (!(qemuCaps = virQEMUCapsCacheLookup(cache, binary)))
+            goto cleanup;
+
+        arch_from_caps = virQEMUCapsGetArch(qemuCaps);
+
+        if (arch_from_caps != arch &&
+            !((ARCH_IS_X86(arch) && ARCH_IS_X86(arch_from_caps)) ||
+              (ARCH_IS_PPC(arch) && ARCH_IS_PPC(arch_from_caps)) ||
+              (ARCH_IS_ARM(arch) && ARCH_IS_ARM(arch_from_caps)) ||
+              (ARCH_IS_S390(arch) && ARCH_IS_S390(arch_from_caps)))) {
+            virReportError(VIR_ERR_INVALID_ARG,
+                           _("architecture from emulator '%s' doesn't "
+                             "match given architecture '%s'"),
+                           virArchToString(arch_from_caps),
+                           virArchToString(arch));
+            goto cleanup;
+        }
+    } else {
+        if (!(qemuCaps = virQEMUCapsCacheLookupByArch(cache, arch)))
+            goto cleanup;
+
+        binary = virQEMUCapsGetBinary(qemuCaps);
+    }
+
+    if (machine) {
+        /* Turn @machine into canonical name */
+        machine = virQEMUCapsGetCanonicalMachine(qemuCaps, machine);
+
+        if (!virQEMUCapsIsMachineSupported(qemuCaps, machine)) {
+            virReportError(VIR_ERR_INVALID_ARG,
+                           _("the machine '%s' is not supported by emulator '%s'"),
+                           machine, binary);
+            goto cleanup;
+        }
+    } else {
+        machine = virQEMUCapsGetDefaultMachine(qemuCaps);
+    }
+
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
+        capsType = VIR_DOMAIN_VIRT_KVM;
+    else
+        capsType = VIR_DOMAIN_VIRT_QEMU;
+
+    if (virttype == VIR_DOMAIN_VIRT_NONE)
+        virttype = capsType;
+
+    if (virttype == VIR_DOMAIN_VIRT_KVM && capsType == VIR_DOMAIN_VIRT_QEMU) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("KVM is not supported by '%s' on this host"),
+                       binary);
+        goto cleanup;
+    }
+
+    if (retArch)
+        *retArch = arch;
+    if (retVirttype)
+        *retVirttype = virttype;
+    if (retMachine)
+        *retMachine = machine;
+
+    VIR_STEAL_PTR(ret, qemuCaps);
+
+ cleanup:
+    virObjectUnref(qemuCaps);
+    return ret;
+}
+
 bool
 virQEMUCapsSupportsVmport(virQEMUCapsPtr qemuCaps,
                           const virDomainDef *def)
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index d23c34c24d..6f095bfbfe 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -559,6 +559,14 @@ virQEMUCapsPtr virQEMUCapsCacheLookupCopy(virFileCachePtr cache,
                                           const char *machineType);
 virQEMUCapsPtr virQEMUCapsCacheLookupByArch(virFileCachePtr cache,
                                             virArch arch);
+virQEMUCapsPtr virQEMUCapsCacheLookupDefault(virFileCachePtr cache,
+                                             const char *binary,
+                                             const char *archStr,
+                                             const char *virttypeStr,
+                                             const char *machine,
+                                             virArch *retArch,
+                                             virDomainVirtType *retVirttype,
+                                             const char **retMachine);
 
 virCapsPtr virQEMUCapsInit(virFileCachePtr cache);
 
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9037818e2a..6c086b9ef8 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19249,10 +19249,9 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
     char *ret = NULL;
     virQEMUDriverPtr driver = conn->privateData;
     virQEMUCapsPtr qemuCaps = NULL;
-    int virttype = VIR_DOMAIN_VIRT_NONE;
-    virDomainVirtType capsType;
+    virArch arch;
+    virDomainVirtType virttype;
     virDomainCapsPtr domCaps = NULL;
-    int arch = virArchFromHost(); /* virArch */
     virQEMUDriverConfigPtr cfg = NULL;
     virCapsPtr caps = NULL;
 
@@ -19266,80 +19265,17 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
     if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
         goto cleanup;
 
-    if (virttype_str &&
-        (virttype = virDomainVirtTypeFromString(virttype_str)) < 0) {
-        virReportError(VIR_ERR_INVALID_ARG,
-                       _("unknown virttype: %s"),
-                       virttype_str);
+    qemuCaps = virQEMUCapsCacheLookupDefault(driver->qemuCapsCache,
+                                             emulatorbin,
+                                             arch_str,
+                                             virttype_str,
+                                             machine,
+                                             &arch, &virttype, &machine);
+    if (!qemuCaps)
         goto cleanup;
-    }
 
-    if (arch_str && (arch = virArchFromString(arch_str)) == VIR_ARCH_NONE) {
-        virReportError(VIR_ERR_INVALID_ARG,
-                       _("unknown architecture: %s"),
-                       arch_str);
-        goto cleanup;
-    }
-
-    if (emulatorbin) {
-        virArch arch_from_caps;
-
-        if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache,
-                                                emulatorbin)))
-            goto cleanup;
-
-        arch_from_caps = virQEMUCapsGetArch(qemuCaps);
-
-        if (arch_from_caps != arch &&
-            !((ARCH_IS_X86(arch) && ARCH_IS_X86(arch_from_caps)) ||
-              (ARCH_IS_PPC(arch) && ARCH_IS_PPC(arch_from_caps)) ||
-              (ARCH_IS_ARM(arch) && ARCH_IS_ARM(arch_from_caps)) ||
-              (ARCH_IS_S390(arch) && ARCH_IS_S390(arch_from_caps)))) {
-            virReportError(VIR_ERR_INVALID_ARG,
-                           _("architecture from emulator '%s' doesn't "
-                             "match given architecture '%s'"),
-                           virArchToString(arch_from_caps),
-                           virArchToString(arch));
-            goto cleanup;
-        }
-    } else {
-        if (!(qemuCaps = virQEMUCapsCacheLookupByArch(driver->qemuCapsCache,
-                                                      arch)))
-            goto cleanup;
-
-        emulatorbin = virQEMUCapsGetBinary(qemuCaps);
-    }
-
-    if (machine) {
-        /* Turn @machine into canonical name */
-        machine = virQEMUCapsGetCanonicalMachine(qemuCaps, machine);
-
-        if (!virQEMUCapsIsMachineSupported(qemuCaps, machine)) {
-            virReportError(VIR_ERR_INVALID_ARG,
-                           _("the machine '%s' is not supported by emulator '%s'"),
-                           machine, emulatorbin);
-            goto cleanup;
-        }
-    } else {
-        machine = virQEMUCapsGetDefaultMachine(qemuCaps);
-    }
-
-    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
-        capsType = VIR_DOMAIN_VIRT_KVM;
-    else
-        capsType = VIR_DOMAIN_VIRT_QEMU;
-
-    if (virttype == VIR_DOMAIN_VIRT_NONE)
-        virttype = capsType;
-
-    if (virttype == VIR_DOMAIN_VIRT_KVM && capsType == VIR_DOMAIN_VIRT_QEMU) {
-        virReportError(VIR_ERR_INVALID_ARG,
-                       _("KVM is not supported by '%s' on this host"),
-                       emulatorbin);
-        goto cleanup;
-    }
-
-    if (!(domCaps = virDomainCapsNew(emulatorbin, machine, arch, virttype)))
+    if (!(domCaps = virDomainCapsNew(virQEMUCapsGetBinary(qemuCaps), machine,
+                                     arch, virttype)))
         goto cleanup;
 
     if (virQEMUCapsFillDomainCaps(caps, domCaps, qemuCaps,
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 07/22] qemu_capabilities: Introduce virQEMUCapsCacheLookupDefault
Posted by Collin Walling, 6 hours ago
On 05/16/2018 04:39 AM, Jiri Denemark wrote:
> virConnectGetDomainCapabilities needs to lookup QEMU capabilities
> matching a specified binary, architecture, virt type, and machine type
> while using default values when any of the parameters are not provided
> by the user. Let's extract the lookup code into
> virQEMUCapsCacheLookupDefault to make it reusable.
> 
> Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
> ---
>  src/qemu/qemu_capabilities.c | 118 +++++++++++++++++++++++++++++++++++
>  src/qemu/qemu_capabilities.h |   8 +++
>  src/qemu/qemu_driver.c       |  86 ++++---------------------
>  3 files changed, 137 insertions(+), 75 deletions(-)
> 

[...]

>  
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 9037818e2a..6c086b9ef8 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -19249,10 +19249,9 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
>      char *ret = NULL;
>      virQEMUDriverPtr driver = conn->privateData;
>      virQEMUCapsPtr qemuCaps = NULL;
> -    int virttype = VIR_DOMAIN_VIRT_NONE;
> -    virDomainVirtType capsType;
> +    virArch arch;
> +    virDomainVirtType virttype;
>      virDomainCapsPtr domCaps = NULL;
> -    int arch = virArchFromHost(); /* virArch */
>      virQEMUDriverConfigPtr cfg = NULL;
>      virCapsPtr caps = NULL;
>  
> @@ -19266,80 +19265,17 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
>      if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
>          goto cleanup;
>  
> -    if (virttype_str &&
> -        (virttype = virDomainVirtTypeFromString(virttype_str)) < 0) {
> -        virReportError(VIR_ERR_INVALID_ARG,
> -                       _("unknown virttype: %s"),
> -                       virttype_str);
> +    qemuCaps = virQEMUCapsCacheLookupDefault(driver->qemuCapsCache,
> +                                             emulatorbin,
> +                                             arch_str,
> +                                             virttype_str,
> +                                             machine,
> +                                             &arch, &virttype, &machine);
> +    if (!qemuCaps)
>          goto cleanup;
> -    }
>  
> -    if (arch_str && (arch = virArchFromString(arch_str)) == VIR_ARCH_NONE) {
> -        virReportError(VIR_ERR_INVALID_ARG,
> -                       _("unknown architecture: %s"),
> -                       arch_str);
> -        goto cleanup;
> -    }
> -
> -    if (emulatorbin) {
> -        virArch arch_from_caps;
> -
> -        if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache,
> -                                                emulatorbin)))
> -            goto cleanup;
> -
> -        arch_from_caps = virQEMUCapsGetArch(qemuCaps);
> -
> -        if (arch_from_caps != arch &&
> -            !((ARCH_IS_X86(arch) && ARCH_IS_X86(arch_from_caps)) ||
> -              (ARCH_IS_PPC(arch) && ARCH_IS_PPC(arch_from_caps)) ||
> -              (ARCH_IS_ARM(arch) && ARCH_IS_ARM(arch_from_caps)) ||
> -              (ARCH_IS_S390(arch) && ARCH_IS_S390(arch_from_caps)))) {
> -            virReportError(VIR_ERR_INVALID_ARG,
> -                           _("architecture from emulator '%s' doesn't "
> -                             "match given architecture '%s'"),
> -                           virArchToString(arch_from_caps),
> -                           virArchToString(arch));
> -            goto cleanup;
> -        }

Are all these checks necessary? Can't you get away with just checking arch_from_caps != arch?

> -    } else {
> -        if (!(qemuCaps = virQEMUCapsCacheLookupByArch(driver->qemuCapsCache,
> -                                                      arch)))
> -            goto cleanup;
> -
> -        emulatorbin = virQEMUCapsGetBinary(qemuCaps);
> -    }
> -
> -    if (machine) {
> -        /* Turn @machine into canonical name */
> -        machine = virQEMUCapsGetCanonicalMachine(qemuCaps, machine);
> -
> -        if (!virQEMUCapsIsMachineSupported(qemuCaps, machine)) {
> -            virReportError(VIR_ERR_INVALID_ARG,
> -                           _("the machine '%s' is not supported by emulator '%s'"),
> -                           machine, emulatorbin);
> -            goto cleanup;
> -        }
> -    } else {
> -        machine = virQEMUCapsGetDefaultMachine(qemuCaps);
> -    }
> -
> -    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
> -        capsType = VIR_DOMAIN_VIRT_KVM;
> -    else
> -        capsType = VIR_DOMAIN_VIRT_QEMU;
> -
> -    if (virttype == VIR_DOMAIN_VIRT_NONE)
> -        virttype = capsType;
> -
> -    if (virttype == VIR_DOMAIN_VIRT_KVM && capsType == VIR_DOMAIN_VIRT_QEMU) {
> -        virReportError(VIR_ERR_INVALID_ARG,
> -                       _("KVM is not supported by '%s' on this host"),
> -                       emulatorbin);
> -        goto cleanup;
> -    }
> -
> -    if (!(domCaps = virDomainCapsNew(emulatorbin, machine, arch, virttype)))
> +    if (!(domCaps = virDomainCapsNew(virQEMUCapsGetBinary(qemuCaps), machine,
> +                                     arch, virttype)))
>          goto cleanup;
>  
>      if (virQEMUCapsFillDomainCaps(caps, domCaps, qemuCaps,
> 


-- 
Respectfully,
- Collin Walling

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 08/22] Introduce virConnectCompareHypervisorCPU public API
Posted by Jiri Denemark, 6 days ago
This new API compares the given CPU description with the CPU the
specified hypervisor is able to provide on the host. It is a more useful
version of virConnectCompareCPU, which compares the CPU definition with
the host CPU without considering any specific hypervisor and its
abilities.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 include/libvirt/libvirt-host.h |  7 ++++
 src/driver-hypervisor.h        | 10 +++++
 src/libvirt-host.c             | 72 +++++++++++++++++++++++++++++++++-
 src/libvirt_public.syms        |  5 +++
 4 files changed, 93 insertions(+), 1 deletion(-)

diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h
index 07b5d15943..e2054baebc 100644
--- a/include/libvirt/libvirt-host.h
+++ b/include/libvirt/libvirt-host.h
@@ -640,6 +640,13 @@ typedef enum {
 int virConnectCompareCPU(virConnectPtr conn,
                          const char *xmlDesc,
                          unsigned int flags);
+int virConnectCompareHypervisorCPU(virConnectPtr conn,
+                                   const char *emulator,
+                                   const char *arch,
+                                   const char *machine,
+                                   const char *virttype,
+                                   const char *xmlCPU,
+                                   unsigned int flags);
 
 int virConnectGetCPUModelNames(virConnectPtr conn,
                                const char *arch,
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index e71a72a441..d64de2d54c 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -673,6 +673,15 @@ typedef int
                            const char *cpu,
                            unsigned int flags);
 
+typedef int
+(*virDrvConnectCompareHypervisorCPU)(virConnectPtr conn,
+                                     const char *emulator,
+                                     const char *arch,
+                                     const char *machine,
+                                     const char *virttype,
+                                     const char *xmlCPU,
+                                     unsigned int flags);
+
 typedef char *
 (*virDrvConnectBaselineCPU)(virConnectPtr conn,
                             const char **xmlCPUs,
@@ -1532,6 +1541,7 @@ struct _virHypervisorDriver {
     virDrvDomainSetVcpu domainSetVcpu;
     virDrvDomainSetBlockThreshold domainSetBlockThreshold;
     virDrvDomainSetLifecycleAction domainSetLifecycleAction;
+    virDrvConnectCompareHypervisorCPU connectCompareHypervisorCPU;
 };
 
 
diff --git a/src/libvirt-host.c b/src/libvirt-host.c
index ed689b9ec2..17cf183499 100644
--- a/src/libvirt-host.c
+++ b/src/libvirt-host.c
@@ -954,7 +954,11 @@ virConnectIsSecure(virConnectPtr conn)
  * @xmlDesc: XML describing the CPU to compare with host CPU
  * @flags: bitwise-OR of virConnectCompareCPUFlags
  *
- * Compares the given CPU description with the host CPU
+ * Compares the given CPU description with the host CPU.
+ *
+ * See vitConnectCompareHypervisorCPU() if you want to consider hypervisor
+ * abilities and compare the CPU to the CPU which a hypervisor is able to
+ * provide on the host.
  *
  * Returns comparison result according to enum virCPUCompareResult. If
  * VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE is used and @xmlDesc CPU is
@@ -992,6 +996,72 @@ virConnectCompareCPU(virConnectPtr conn,
 }
 
 
+/**
+ * virConnectCompareHypervisorCPU:
+ * @conn: pointer to the hypervisor connection
+ * @emulator: path to the emulator binary
+ * @arch: domain architecture
+ * @machine: machine type
+ * @virttype: virtualization type
+ * @xmlCPU: XML describing the CPU to be compared
+ * @flags: bitwise-OR of virConnectCompareCPUFlags
+ *
+ * Compares the given CPU description with the CPU the specified hypervisor is
+ * able to provide on the host. Any of @emulator, @arch, @machine, and
+ * @virttype parameters may be NULL; libvirt will choose sensible defaults
+ * tailored to the host and its current configuration.
+ *
+ * This is different from virConnectCompareCPU() which compares the CPU
+ * definition with the host CPU without considering any specific hypervisor and
+ * its abilities.
+ *
+ * Returns comparison result according to enum virCPUCompareResult. If
+ * VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE is used and @xmlCPU is
+ * incompatible with the CPU the specified hypervisor is able to provide on the
+ * host, this function will return VIR_CPU_COMPARE_ERROR (instead of
+ * VIR_CPU_COMPARE_INCOMPATIBLE) and the error will use the
+ * VIR_ERR_CPU_INCOMPATIBLE code with a message providing more details about
+ * the incompatibility.
+ */
+int
+virConnectCompareHypervisorCPU(virConnectPtr conn,
+                               const char *emulator,
+                               const char *arch,
+                               const char *machine,
+                               const char *virttype,
+                               const char *xmlCPU,
+                               unsigned int flags)
+{
+    VIR_DEBUG("conn=%p, emulator=%s, arch=%s, machine=%s, "
+              "virttype=%s, xmlCPU=%s, flags=0x%x",
+              conn, NULLSTR(emulator), NULLSTR(arch), NULLSTR(machine),
+              NULLSTR(virttype), NULLSTR(xmlCPU), flags);
+
+    virResetLastError();
+
+    virCheckConnectReturn(conn, VIR_CPU_COMPARE_ERROR);
+    virCheckNonNullArgGoto(xmlCPU, error);
+
+    if (conn->driver->connectCompareHypervisorCPU) {
+        int ret;
+
+        ret = conn->driver->connectCompareHypervisorCPU(conn, emulator, arch,
+                                                        machine, virttype,
+                                                        xmlCPU, flags);
+        if (ret == VIR_CPU_COMPARE_ERROR)
+            goto error;
+
+        return ret;
+    }
+
+    virReportUnsupportedError();
+
+ error:
+    virDispatchError(conn);
+    return VIR_CPU_COMPARE_ERROR;
+}
+
+
 /**
  * virConnectGetCPUModelNames:
  *
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 95df3a0dbc..97597d7708 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -785,4 +785,9 @@ LIBVIRT_4.1.0 {
         virStoragePoolLookupByTargetPath;
 } LIBVIRT_3.9.0;
 
+LIBVIRT_4.4.0 {
+    global:
+        virConnectCompareHypervisorCPU;
+} LIBVIRT_4.1.0;
+
 # .... define new API here using predicted next version number ....
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 08/22] Introduce virConnectCompareHypervisorCPU public API
Posted by Collin Walling, 6 hours ago
On 05/16/2018 04:39 AM, Jiri Denemark wrote:
> This new API compares the given CPU description with the CPU the
> specified hypervisor is able to provide on the host. It is a more useful
> version of virConnectCompareCPU, which compares the CPU definition with
> the host CPU without considering any specific hypervisor and its
> abilities.
> 
> Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
> ---
>  include/libvirt/libvirt-host.h |  7 ++++
>  src/driver-hypervisor.h        | 10 +++++
>  src/libvirt-host.c             | 72 +++++++++++++++++++++++++++++++++-
>  src/libvirt_public.syms        |  5 +++
>  4 files changed, 93 insertions(+), 1 deletion(-)
> 
> diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h
> index 07b5d15943..e2054baebc 100644
> --- a/include/libvirt/libvirt-host.h
> +++ b/include/libvirt/libvirt-host.h
> @@ -640,6 +640,13 @@ typedef enum {
>  int virConnectCompareCPU(virConnectPtr conn,
>                           const char *xmlDesc,
>                           unsigned int flags);
> +int virConnectCompareHypervisorCPU(virConnectPtr conn,
> +                                   const char *emulator,
> +                                   const char *arch,
> +                                   const char *machine,
> +                                   const char *virttype,
> +                                   const char *xmlCPU,
> +                                   unsigned int flags);
>  
>  int virConnectGetCPUModelNames(virConnectPtr conn,
>                                 const char *arch,
> diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
> index e71a72a441..d64de2d54c 100644
> --- a/src/driver-hypervisor.h
> +++ b/src/driver-hypervisor.h
> @@ -673,6 +673,15 @@ typedef int
>                             const char *cpu,
>                             unsigned int flags);
>  
> +typedef int
> +(*virDrvConnectCompareHypervisorCPU)(virConnectPtr conn,
> +                                     const char *emulator,
> +                                     const char *arch,
> +                                     const char *machine,
> +                                     const char *virttype,
> +                                     const char *xmlCPU,
> +                                     unsigned int flags);
> +
>  typedef char *
>  (*virDrvConnectBaselineCPU)(virConnectPtr conn,
>                              const char **xmlCPUs,
> @@ -1532,6 +1541,7 @@ struct _virHypervisorDriver {
>      virDrvDomainSetVcpu domainSetVcpu;
>      virDrvDomainSetBlockThreshold domainSetBlockThreshold;
>      virDrvDomainSetLifecycleAction domainSetLifecycleAction;
> +    virDrvConnectCompareHypervisorCPU connectCompareHypervisorCPU;
>  };
>  
>  
> diff --git a/src/libvirt-host.c b/src/libvirt-host.c
> index ed689b9ec2..17cf183499 100644
> --- a/src/libvirt-host.c
> +++ b/src/libvirt-host.c
> @@ -954,7 +954,11 @@ virConnectIsSecure(virConnectPtr conn)
>   * @xmlDesc: XML describing the CPU to compare with host CPU
>   * @flags: bitwise-OR of virConnectCompareCPUFlags
>   *
> - * Compares the given CPU description with the host CPU
> + * Compares the given CPU description with the host CPU.
> + *
> + * See vitConnectCompareHypervisorCPU() if you want to consider hypervisor
> + * abilities and compare the CPU to the CPU which a hypervisor is able to
> + * provide on the host.
>   *
>   * Returns comparison result according to enum virCPUCompareResult. If
>   * VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE is used and @xmlDesc CPU is
> @@ -992,6 +996,72 @@ virConnectCompareCPU(virConnectPtr conn,
>  }
>  
>  
> +/**
> + * virConnectCompareHypervisorCPU:
> + * @conn: pointer to the hypervisor connection
> + * @emulator: path to the emulator binary
> + * @arch: domain architecture
> + * @machine: machine type
> + * @virttype: virtualization type
> + * @xmlCPU: XML describing the CPU to be compared
> + * @flags: bitwise-OR of virConnectCompareCPUFlags
> + *
> + * Compares the given CPU description with the CPU the specified hypervisor is
> + * able to provide on the host. Any of @emulator, @arch, @machine, and
> + * @virttype parameters may be NULL; libvirt will choose sensible defaults
> + * tailored to the host and its current configuration.
> + *
> + * This is different from virConnectCompareCPU() which compares the CPU
> + * definition with the host CPU without considering any specific hypervisor and
> + * its abilities.
> + *
> + * Returns comparison result according to enum virCPUCompareResult. If
> + * VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE is used and @xmlCPU is
> + * incompatible with the CPU the specified hypervisor is able to provide on the
> + * host, this function will return VIR_CPU_COMPARE_ERROR (instead of
> + * VIR_CPU_COMPARE_INCOMPATIBLE) and the error will use the
> + * VIR_ERR_CPU_INCOMPATIBLE code with a message providing more details about
> + * the incompatibility.
> + */
> +int
> +virConnectCompareHypervisorCPU(virConnectPtr conn,
> +                               const char *emulator,
> +                               const char *arch,
> +                               const char *machine,
> +                               const char *virttype,
> +                               const char *xmlCPU,
> +                               unsigned int flags)
> +{
> +    VIR_DEBUG("conn=%p, emulator=%s, arch=%s, machine=%s, "
> +              "virttype=%s, xmlCPU=%s, flags=0x%x",
> +              conn, NULLSTR(emulator), NULLSTR(arch), NULLSTR(machine),
> +              NULLSTR(virttype), NULLSTR(xmlCPU), flags);
> +
> +    virResetLastError();
> +
> +    virCheckConnectReturn(conn, VIR_CPU_COMPARE_ERROR);
> +    virCheckNonNullArgGoto(xmlCPU, error);
> +
> +    if (conn->driver->connectCompareHypervisorCPU) {
> +        int ret;
> +
> +        ret = conn->driver->connectCompareHypervisorCPU(conn, emulator, arch,
> +                                                        machine, virttype,
> +                                                        xmlCPU, flags);
> +        if (ret == VIR_CPU_COMPARE_ERROR)
> +            goto error;

Admittedly I did not look too closely, but will the compareHypervisorCPU functions actually
return "VIR_CPU_COMPARE_ERROR" on error? If so, wouldn't it be more sensible to return a 
"VIR_HYPERVISOR_CPU_COMPARE_ERROR" instead?

> +
> +        return ret;
> +    }
> +
> +    virReportUnsupportedError();
> +
> + error:
> +    virDispatchError(conn);
> +    return VIR_CPU_COMPARE_ERROR;
> +}
> +
> +
>  /**
>   * virConnectGetCPUModelNames:
>   *
> diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
> index 95df3a0dbc..97597d7708 100644
> --- a/src/libvirt_public.syms
> +++ b/src/libvirt_public.syms
> @@ -785,4 +785,9 @@ LIBVIRT_4.1.0 {
>          virStoragePoolLookupByTargetPath;
>  } LIBVIRT_3.9.0;
>  
> +LIBVIRT_4.4.0 {
> +    global:
> +        virConnectCompareHypervisorCPU;
> +} LIBVIRT_4.1.0;
> +
>  # .... define new API here using predicted next version number ....
> 


-- 
Respectfully,
- Collin Walling

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 09/22] remote: Implement virConnectCompareHypervisorCPU
Posted by Jiri Denemark, 6 days ago
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/remote/remote_driver.c   |  3 ++-
 src/remote/remote_protocol.x | 21 ++++++++++++++++++++-
 src/remote_protocol-structs  | 12 ++++++++++++
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 95437b4365..acefe8c457 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -8448,7 +8448,8 @@ static virHypervisorDriver hypervisor_driver = {
     .domainSetGuestVcpus = remoteDomainSetGuestVcpus, /* 2.0.0 */
     .domainSetVcpu = remoteDomainSetVcpu, /* 3.1.0 */
     .domainSetBlockThreshold = remoteDomainSetBlockThreshold, /* 3.2.0 */
-    .domainSetLifecycleAction = remoteDomainSetLifecycleAction /* 3.9.0 */
+    .domainSetLifecycleAction = remoteDomainSetLifecycleAction, /* 3.9.0 */
+    .connectCompareHypervisorCPU = remoteConnectCompareHypervisorCPU, /* 4.4.0 */
 };
 
 static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 296a087181..0aa123b5ac 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -3448,6 +3448,19 @@ struct remote_domain_set_lifecycle_action_args {
     unsigned int flags;
 };
 
+struct remote_connect_compare_hypervisor_cpu_args {
+    remote_string emulator;
+    remote_string arch;
+    remote_string machine;
+    remote_string virttype;
+    remote_nonnull_string xmlCPU;
+    unsigned int flags;
+};
+
+struct remote_connect_compare_hypervisor_cpu_ret {
+    int result;
+};
+
 /*----- Protocol. -----*/
 
 /* Define the program number, protocol version and procedure numbers here. */
@@ -6135,5 +6148,11 @@ enum remote_procedure {
      * @priority: high
      * @acl: storage_pool:getattr
      */
-    REMOTE_PROC_STORAGE_POOL_LOOKUP_BY_TARGET_PATH = 391
+    REMOTE_PROC_STORAGE_POOL_LOOKUP_BY_TARGET_PATH = 391,
+
+    /**
+     * @generate: both
+     * @acl: connect:write
+     */
+    REMOTE_PROC_CONNECT_COMPARE_HYPERVISOR_CPU = 392
 };
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index fe163db73f..64e48c52ba 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -2877,6 +2877,17 @@ struct remote_domain_set_lifecycle_action_args {
         u_int                      action;
         u_int                      flags;
 };
+struct remote_connect_compare_hypervisor_cpu_args {
+        remote_string              emulator;
+        remote_string              arch;
+        remote_string              machine;
+        remote_string              virttype;
+        remote_nonnull_string      xmlCPU;
+        u_int                      flags;
+};
+struct remote_connect_compare_hypervisor_cpu_ret {
+        int                        result;
+};
 enum remote_procedure {
         REMOTE_PROC_CONNECT_OPEN = 1,
         REMOTE_PROC_CONNECT_CLOSE = 2,
@@ -3269,4 +3280,5 @@ enum remote_procedure {
         REMOTE_PROC_DOMAIN_MANAGED_SAVE_DEFINE_XML = 389,
         REMOTE_PROC_DOMAIN_SET_LIFECYCLE_ACTION = 390,
         REMOTE_PROC_STORAGE_POOL_LOOKUP_BY_TARGET_PATH = 391,
+        REMOTE_PROC_CONNECT_COMPARE_HYPERVISOR_CPU = 392,
 };
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 10/22] virsh: Introduce new hypervisor-cpu-compare command
Posted by Jiri Denemark, 6 days ago
This command is a virsh wrapper for virConnectCompareHypervisorCPU.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 tools/virsh-host.c | 113 +++++++++++++++++++++++++++++++++++++++++++++
 tools/virsh.pod    |  29 +++++++++++-
 2 files changed, 141 insertions(+), 1 deletion(-)

diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index ea2c411c02..1e7cfcbd5e 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -1595,6 +1595,113 @@ cmdNodeMemoryTune(vshControl *ctl, const vshCmd *cmd)
     goto cleanup;
 }
 
+
+/*
+ * "hypervisor-cpu-compare" command
+ */
+static const vshCmdInfo info_hypervisor_cpu_compare[] = {
+    {.name = "help",
+     .data = N_("compare a CPU with the CPU created by a hypervisor on the host")
+    },
+    {.name = "desc",
+     .data = N_("compare CPU with hypervisor CPU")
+    },
+    {.name = NULL}
+};
+
+static const vshCmdOptDef opts_hypervisor_cpu_compare[] = {
+    VIRSH_COMMON_OPT_FILE(N_("file containing an XML CPU description")),
+    {.name = "virttype",
+     .type = VSH_OT_STRING,
+     .help = N_("virtualization type (/domain/@type)"),
+    },
+    {.name = "emulator",
+     .type = VSH_OT_STRING,
+     .help = N_("path to emulator binary (/domain/devices/emulator)"),
+    },
+    {.name = "arch",
+     .type = VSH_OT_STRING,
+     .help = N_("domain architecture (/domain/os/type/@arch)"),
+    },
+    {.name = "machine",
+     .type = VSH_OT_STRING,
+     .help = N_("machine type (/domain/os/type/@machine)"),
+    },
+    {.name = "error",
+     .type = VSH_OT_BOOL,
+     .help = N_("report error if CPUs are incompatible")
+    },
+    {.name = NULL}
+};
+
+static bool
+cmdHypervisorCPUCompare(vshControl *ctl,
+                        const vshCmd *cmd)
+{
+    const char *from = NULL;
+    const char *virttype = NULL;
+    const char *emulator = NULL;
+    const char *arch = NULL;
+    const char *machine = NULL;
+    bool ret = false;
+    int result;
+    char **cpus = NULL;
+    unsigned int flags = 0;
+    virshControlPtr priv = ctl->privData;
+
+    if (vshCommandOptBool(cmd, "error"))
+        flags |= VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE;
+
+    if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0 ||
+        vshCommandOptStringReq(ctl, cmd, "virttype", &virttype) < 0 ||
+        vshCommandOptStringReq(ctl, cmd, "emulator", &emulator) < 0 ||
+        vshCommandOptStringReq(ctl, cmd, "arch", &arch) < 0 ||
+        vshCommandOptStringReq(ctl, cmd, "machine", &machine) < 0)
+        return false;
+
+    if (!(cpus = vshExtractCPUDefXMLs(ctl, from)))
+        return false;
+
+    result = virConnectCompareHypervisorCPU(priv->conn, emulator, arch,
+                                            machine, virttype, cpus[0], flags);
+
+    switch (result) {
+    case VIR_CPU_COMPARE_INCOMPATIBLE:
+        vshPrint(ctl,
+                 _("CPU described in %s is incompatible with the CPU provided "
+                   "by hypervisor on the host\n"),
+                 from);
+        goto cleanup;
+        break;
+
+    case VIR_CPU_COMPARE_IDENTICAL:
+        vshPrint(ctl,
+                 _("CPU described in %s is identical to the CPU provided by "
+                   "hypervisor on the host\n"),
+                 from);
+        break;
+
+    case VIR_CPU_COMPARE_SUPERSET:
+        vshPrint(ctl,
+                 _("The CPU provided by hypervisor on the host is a superset "
+                   "of CPU described in %s\n"),
+                 from);
+        break;
+
+    case VIR_CPU_COMPARE_ERROR:
+    default:
+        vshError(ctl, _("Failed to compare hypervisor CPU with %s"), from);
+        goto cleanup;
+    }
+
+    ret = true;
+
+ cleanup:
+    virStringListFree(cpus);
+    return ret;
+}
+
+
 const vshCmdDef hostAndHypervisorCmds[] = {
     {.name = "allocpages",
      .handler = cmdAllocpages,
@@ -1650,6 +1757,12 @@ const vshCmdDef hostAndHypervisorCmds[] = {
      .info = info_hostname,
      .flags = 0
     },
+    {.name = "hypervisor-cpu-compare",
+     .handler = cmdHypervisorCPUCompare,
+     .opts = opts_hypervisor_cpu_compare,
+     .info = info_hypervisor_cpu_compare,
+     .flags = 0
+    },
     {.name = "maxvcpus",
      .handler = cmdMaxvcpus,
      .opts = opts_maxvcpus,
diff --git a/tools/virsh.pod b/tools/virsh.pod
index ea10e1ad43..1a55092efd 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -585,7 +585,9 @@ features that block migration will not be included in the resulting CPU.
 
 =item B<cpu-compare> I<FILE> [I<--error>]
 
-Compare CPU definition from XML <file> with host CPU. The XML <file> may
+Compare CPU definition from XML <file> with host CPU. (See
+B<hypervisor-cpu-compare> command for comparing the CPU definition with the CPU
+which a specific hypervisor is able to provide on the host.) The XML <file> may
 contain either host or guest CPU definition. The host CPU definition is the
 <cpu> element and its contents as printed by B<capabilities> command. The
 guest CPU definition is the <cpu> element and its contents from domain XML
@@ -616,6 +618,31 @@ specified, then the output will be single-quoted where needed, so that
 it is suitable for reuse in a shell context.  If I<--xml> is
 specified, then the output will be escaped for use in XML.
 
+=item B<hypervisor-cpu-compare> I<FILE> [I<virttype>] [I<emulator>] [I<arch>]
+[I<machine>] [I<--error>]
+
+Compare CPU definition from XML <file> with the CPU the specified hypervisor
+is able to provide on the host. (This is different from B<cpu-compare> which
+compares the CPU definition with the host CPU without considering any specific
+hypervisor and its abilities.)
+
+The XML I<FILE> may contain either host or guest CPU definition. The host CPU
+definition is the <cpu> element and its contents as printed by B<capabilities>
+command. The guest CPU definition is the <cpu> element and its contents from
+domain XML definition or the CPU definition created from the host CPU model
+found in domain capabilities XML (printed by B<domcapabilities> command). In
+addition to the <cpu> element itself, this command accepts full domain XML,
+capabilities XML, or domain capabilities XML containing the CPU definition. For
+more information on guest CPU definition see:
+L<https://libvirt.org/formatdomain.html#elementsCPU>.
+
+The I<virttype> option specifies the virtualization type (usable in the 'type'
+attribute of the <domain> top level element from the domain XML). I<emulator>
+specifies the path to the emulator, I<arch> specifies the CPU architecture, and
+I<machine> specifies the machine type. If I<--error> is specified, the command
+will return an error when the given CPU is incompatible with host CPU and a
+message providing more details about the incompatibility will be printed out.
+
 =back
 
 =head1 DOMAIN COMMANDS
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 10/22] virsh: Introduce new hypervisor-cpu-compare command
Posted by Collin Walling, 6 hours ago
I've applied and looked at the patches up to this point. Things are looking good thus far. Will give
them another once-over tomorrow and continue with the rest of the patches.

-- 
Respectfully,
- Collin Walling

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 11/22] qemu: Implement virConnectCompareHypervisorCPU
Posted by Jiri Denemark, 6 days ago
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/qemu/qemu_driver.c | 60 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6c086b9ef8..4b48afdad1 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13100,6 +13100,65 @@ qemuConnectCompareCPU(virConnectPtr conn,
 }
 
 
+static int
+qemuConnectCompareHypervisorCPU(virConnectPtr conn,
+                                const char *emulator,
+                                const char *archStr,
+                                const char *machine,
+                                const char *virttypeStr,
+                                const char *xmlCPU,
+                                unsigned int flags)
+{
+    int ret = VIR_CPU_COMPARE_ERROR;
+    virQEMUDriverPtr driver = conn->privateData;
+    virQEMUCapsPtr qemuCaps = NULL;
+    bool failIncompatible;
+    virCPUDefPtr hvCPU;
+    virArch arch;
+    virDomainVirtType virttype;
+
+    virCheckFlags(VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE,
+                  VIR_CPU_COMPARE_ERROR);
+
+    if (virConnectCompareHypervisorCPUEnsureACL(conn) < 0)
+        goto cleanup;
+
+    failIncompatible = !!(flags & VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE);
+
+    qemuCaps = virQEMUCapsCacheLookupDefault(driver->qemuCapsCache,
+                                             emulator,
+                                             archStr,
+                                             virttypeStr,
+                                             machine,
+                                             &arch, &virttype, NULL);
+    if (!qemuCaps)
+        goto cleanup;
+
+    hvCPU = virQEMUCapsGetHostModel(qemuCaps, virttype,
+                                    VIR_QEMU_CAPS_HOST_CPU_REPORTED);
+    if (!hvCPU || hvCPU->fallback != VIR_CPU_FALLBACK_FORBID) {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+                       _("QEMU '%s' does not support reporting CPU model for "
+                         "virttype '%s'"),
+                       virQEMUCapsGetBinary(qemuCaps),
+                       virDomainVirtTypeToString(virttype));
+        goto cleanup;
+    }
+
+    if (ARCH_IS_X86(arch)) {
+        ret = virCPUCompareXML(arch, hvCPU, xmlCPU, failIncompatible);
+    } else {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+                       _("comparing hypervisor CPUs is not supported for "
+                         "arch %s"), virArchToString(arch));
+    }
+
+ cleanup:
+    virObjectUnref(qemuCaps);
+    return ret;
+}
+
+
 static char *
 qemuConnectBaselineCPU(virConnectPtr conn ATTRIBUTE_UNUSED,
                        const char **xmlCPUs,
@@ -21326,6 +21385,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
     .domainSetVcpu = qemuDomainSetVcpu, /* 3.1.0 */
     .domainSetBlockThreshold = qemuDomainSetBlockThreshold, /* 3.2.0 */
     .domainSetLifecycleAction = qemuDomainSetLifecycleAction, /* 3.9.0 */
+    .connectCompareHypervisorCPU = qemuConnectCompareHypervisorCPU, /* 4.4.0 */
 };
 
 
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 12/22] Introduce virConnectBaselineHypervisorCPU public API
Posted by Jiri Denemark, 6 days ago
The new API computes the most feature-rich CPU which is compatible with
all given CPUs and can be provided by the specified hypervisor. It is a
more useful version of vitConnectBaselineCPU, which doesn't consider any
hypervisor capabilities when computing the best CPU.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 include/libvirt/libvirt-host.h |  8 ++++
 src/driver-hypervisor.h        | 10 +++++
 src/libvirt-host.c             | 81 ++++++++++++++++++++++++++++++++++
 src/libvirt_public.syms        |  1 +
 4 files changed, 100 insertions(+)

diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h
index e2054baebc..84f4858169 100644
--- a/include/libvirt/libvirt-host.h
+++ b/include/libvirt/libvirt-host.h
@@ -667,6 +667,14 @@ char *virConnectBaselineCPU(virConnectPtr conn,
                             const char **xmlCPUs,
                             unsigned int ncpus,
                             unsigned int flags);
+char *virConnectBaselineHypervisorCPU(virConnectPtr conn,
+                                      const char *emulator,
+                                      const char *arch,
+                                      const char *machine,
+                                      const char *virttype,
+                                      const char **xmlCPUs,
+                                      unsigned int ncpus,
+                                      unsigned int flags);
 
 
 int virNodeGetFreePages(virConnectPtr conn,
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index d64de2d54c..9ce0d7e5de 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -687,6 +687,15 @@ typedef char *
                             const char **xmlCPUs,
                             unsigned int ncpus,
                             unsigned int flags);
+typedef char *
+(*virDrvConnectBaselineHypervisorCPU)(virConnectPtr conn,
+                                      const char *emulator,
+                                      const char *arch,
+                                      const char *machine,
+                                      const char *virttype,
+                                      const char **xmlCPUs,
+                                      unsigned int ncpus,
+                                      unsigned int flags);
 
 typedef int
 (*virDrvConnectGetCPUModelNames)(virConnectPtr conn,
@@ -1542,6 +1551,7 @@ struct _virHypervisorDriver {
     virDrvDomainSetBlockThreshold domainSetBlockThreshold;
     virDrvDomainSetLifecycleAction domainSetLifecycleAction;
     virDrvConnectCompareHypervisorCPU connectCompareHypervisorCPU;
+    virDrvConnectBaselineHypervisorCPU connectBaselineHypervisorCPU;
 };
 
 
diff --git a/src/libvirt-host.c b/src/libvirt-host.c
index 17cf183499..cdbbe35e5a 100644
--- a/src/libvirt-host.c
+++ b/src/libvirt-host.c
@@ -1127,6 +1127,9 @@ virConnectGetCPUModelNames(virConnectPtr conn, const char *arch, char ***models,
  * Computes the most feature-rich CPU which is compatible with all given
  * host CPUs.
  *
+ * See vitConnectBaselineHypervisorCPU() to get a CPU which can be provided
+ * by a specific hypervisor.
+ *
  * If @flags includes VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES then libvirt
  * will explicitly list all CPU features that are part of the host CPU,
  * without this flag features that are part of the CPU model will not be
@@ -1174,6 +1177,84 @@ virConnectBaselineCPU(virConnectPtr conn,
 }
 
 
+/**
+ * virConnectBaselineHypervisorCPU:
+ *
+ * @conn: pointer to the hypervisor connection
+ * @emulator: path to the emulator binary
+ * @arch: domain architecture
+ * @machine: machine type
+ * @virttype: virtualization type
+ * @xmlCPUs: array of XML descriptions of CPUs
+ * @ncpus: number of CPUs in xmlCPUs
+ * @flags: bitwise-OR of virConnectBaselineCPUFlags
+ *
+ * Computes the most feature-rich CPU which is compatible with all given CPUs
+ * and can be provided by the specified hypervisor. For best results the
+ * host-model CPUs as advertised by virConnectGetDomainCapabilities() should be
+ * passed in @xmlCPUs. Any of @emulator, @arch, @machine, and @virttype
+ * parameters may be NULL; libvirt will choose sensible defaults tailored to
+ * the host and its current configuration.
+ *
+ * This is different from vitConnectBaselineCPU() which doesn't consider any
+ * hypervisor abilities when computing the best CPU.
+ *
+ * If @flags includes VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES then libvirt
+ * will explicitly list all CPU features that are part of the computed CPU,
+ * without this flag features that are part of the CPU model will not be
+ * listed.
+ *
+ * If @flags includes VIR_CONNECT_BASELINE_CPU_MIGRATABLE, the resulting
+ * CPU will not include features that block migration.
+ *
+ * Returns XML description of the computed CPU (caller frees) or NULL on error.
+ */
+char *
+virConnectBaselineHypervisorCPU(virConnectPtr conn,
+                                const char *emulator,
+                                const char *arch,
+                                const char *machine,
+                                const char *virttype,
+                                const char **xmlCPUs,
+                                unsigned int ncpus,
+                                unsigned int flags)
+{
+    size_t i;
+
+    VIR_DEBUG("conn=%p, emulator=%s, arch=%s, machine=%s, "
+              "virttype=%s, xmlCPUs=%p, ncpus=%u, flags=0x%x",
+              conn, NULLSTR(emulator), NULLSTR(arch), NULLSTR(machine),
+              NULLSTR(virttype), xmlCPUs, ncpus, flags);
+    if (xmlCPUs) {
+        for (i = 0; i < ncpus; i++)
+            VIR_DEBUG("xmlCPUs[%zu]=%s", i, NULLSTR(xmlCPUs[i]));
+    }
+
+    virResetLastError();
+
+    virCheckConnectReturn(conn, NULL);
+    virCheckNonNullArgGoto(xmlCPUs, error);
+
+    if (conn->driver->connectBaselineHypervisorCPU) {
+        char *cpu;
+
+        cpu = conn->driver->connectBaselineHypervisorCPU(conn, emulator, arch,
+                                                         machine, virttype,
+                                                         xmlCPUs, ncpus, flags);
+        if (!cpu)
+            goto error;
+
+        return cpu;
+    }
+
+    virReportUnsupportedError();
+
+ error:
+    virDispatchError(conn);
+    return NULL;
+}
+
+
 /**
  * virConnectSetKeepAlive:
  * @conn: pointer to a hypervisor connection
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 97597d7708..05ab077fb4 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -788,6 +788,7 @@ LIBVIRT_4.1.0 {
 LIBVIRT_4.4.0 {
     global:
         virConnectCompareHypervisorCPU;
+        virConnectBaselineHypervisorCPU;
 } LIBVIRT_4.1.0;
 
 # .... define new API here using predicted next version number ....
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 13/22] remote: Implement virConnectBaselineHypervisorCPU
Posted by Jiri Denemark, 6 days ago
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/remote/remote_driver.c   |  1 +
 src/remote/remote_protocol.x | 21 ++++++++++++++++++++-
 src/remote_protocol-structs  | 15 +++++++++++++++
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index acefe8c457..d106a18510 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -8450,6 +8450,7 @@ static virHypervisorDriver hypervisor_driver = {
     .domainSetBlockThreshold = remoteDomainSetBlockThreshold, /* 3.2.0 */
     .domainSetLifecycleAction = remoteDomainSetLifecycleAction, /* 3.9.0 */
     .connectCompareHypervisorCPU = remoteConnectCompareHypervisorCPU, /* 4.4.0 */
+    .connectBaselineHypervisorCPU = remoteConnectBaselineHypervisorCPU, /* 4.4.0 */
 };
 
 static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 0aa123b5ac..ff28cec50f 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -3461,6 +3461,19 @@ struct remote_connect_compare_hypervisor_cpu_ret {
     int result;
 };
 
+struct remote_connect_baseline_hypervisor_cpu_args {
+    remote_string emulator;
+    remote_string arch;
+    remote_string machine;
+    remote_string virttype;
+    remote_nonnull_string xmlCPUs<REMOTE_CPU_BASELINE_MAX>; /* (const char **) */
+    unsigned int flags;
+};
+
+struct remote_connect_baseline_hypervisor_cpu_ret {
+    remote_nonnull_string cpu;
+};
+
 /*----- Protocol. -----*/
 
 /* Define the program number, protocol version and procedure numbers here. */
@@ -6154,5 +6167,11 @@ enum remote_procedure {
      * @generate: both
      * @acl: connect:write
      */
-    REMOTE_PROC_CONNECT_COMPARE_HYPERVISOR_CPU = 392
+    REMOTE_PROC_CONNECT_COMPARE_HYPERVISOR_CPU = 392,
+
+    /**
+     * @generate: both
+     * @acl: connect:write
+     */
+    REMOTE_PROC_CONNECT_BASELINE_HYPERVISOR_CPU = 393
 };
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 64e48c52ba..99251ac0e8 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -2888,6 +2888,20 @@ struct remote_connect_compare_hypervisor_cpu_args {
 struct remote_connect_compare_hypervisor_cpu_ret {
         int                        result;
 };
+struct remote_connect_baseline_hypervisor_cpu_args {
+        remote_string              emulator;
+        remote_string              arch;
+        remote_string              machine;
+        remote_string              virttype;
+        struct {
+                u_int              xmlCPUs_len;
+                remote_nonnull_string * xmlCPUs_val;
+        } xmlCPUs;
+        u_int                      flags;
+};
+struct remote_connect_baseline_hypervisor_cpu_ret {
+        remote_nonnull_string      cpu;
+};
 enum remote_procedure {
         REMOTE_PROC_CONNECT_OPEN = 1,
         REMOTE_PROC_CONNECT_CLOSE = 2,
@@ -3281,4 +3295,5 @@ enum remote_procedure {
         REMOTE_PROC_DOMAIN_SET_LIFECYCLE_ACTION = 390,
         REMOTE_PROC_STORAGE_POOL_LOOKUP_BY_TARGET_PATH = 391,
         REMOTE_PROC_CONNECT_COMPARE_HYPERVISOR_CPU = 392,
+        REMOTE_PROC_CONNECT_BASELINE_HYPERVISOR_CPU = 393,
 };
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 14/22] virsh: Introduce new hypervisor-cpu-baseline command
Posted by Jiri Denemark, 6 days ago
This command is a virsh wrapper for virConnectBaselineHypervisorCPU.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 tools/virsh-host.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++
 tools/virsh.pod    | 47 ++++++++++++++++++++---
 2 files changed, 137 insertions(+), 6 deletions(-)

diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index 1e7cfcbd5e..8fde5da50e 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -1702,6 +1702,96 @@ cmdHypervisorCPUCompare(vshControl *ctl,
 }
 
 
+/*
+ * "hypervisor-cpu-baseline" command
+ */
+static const vshCmdInfo info_hypervisor_cpu_baseline[] = {
+    {.name = "help",
+     .data = N_("compute baseline CPU usable by a specific hypervisor")
+    },
+    {.name = "desc",
+     .data = N_("Compute baseline CPU for a set of given CPUs. The result "
+                "will be tailored to the specified hypervisor.")
+    },
+    {.name = NULL}
+};
+
+static const vshCmdOptDef opts_hypervisor_cpu_baseline[] = {
+    VIRSH_COMMON_OPT_FILE(N_("file containing XML CPU descriptions")),
+    {.name = "virttype",
+     .type = VSH_OT_STRING,
+     .help = N_("virtualization type (/domain/@type)"),
+    },
+    {.name = "emulator",
+     .type = VSH_OT_STRING,
+     .help = N_("path to emulator binary (/domain/devices/emulator)"),
+    },
+    {.name = "arch",
+     .type = VSH_OT_STRING,
+     .help = N_("domain architecture (/domain/os/type/@arch)"),
+    },
+    {.name = "machine",
+     .type = VSH_OT_STRING,
+     .help = N_("machine type (/domain/os/type/@machine)"),
+    },
+    {.name = "features",
+     .type = VSH_OT_BOOL,
+     .help = N_("Show features that are part of the CPU model type")
+    },
+    {.name = "migratable",
+     .type = VSH_OT_BOOL,
+     .help = N_("Do not include features that block migration")
+    },
+    {.name = NULL}
+};
+
+static bool
+cmdHypervisorCPUBaseline(vshControl *ctl,
+                         const vshCmd *cmd)
+{
+    const char *from = NULL;
+    const char *virttype = NULL;
+    const char *emulator = NULL;
+    const char *arch = NULL;
+    const char *machine = NULL;
+    bool ret = false;
+    char *result = NULL;
+    char **list = NULL;
+    unsigned int flags = 0;
+    virshControlPtr priv = ctl->privData;
+
+    if (vshCommandOptBool(cmd, "features"))
+        flags |= VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES;
+    if (vshCommandOptBool(cmd, "migratable"))
+        flags |= VIR_CONNECT_BASELINE_CPU_MIGRATABLE;
+
+    if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0 ||
+        vshCommandOptStringReq(ctl, cmd, "virttype", &virttype) < 0 ||
+        vshCommandOptStringReq(ctl, cmd, "emulator", &emulator) < 0 ||
+        vshCommandOptStringReq(ctl, cmd, "arch", &arch) < 0 ||
+        vshCommandOptStringReq(ctl, cmd, "machine", &machine) < 0)
+        return false;
+
+    if (!(list = vshExtractCPUDefXMLs(ctl, from)))
+        return false;
+
+    result = virConnectBaselineHypervisorCPU(priv->conn, emulator, arch,
+                                             machine, virttype,
+                                             (const char **)list,
+                                             virStringListLength((const char **)list),
+                                             flags);
+
+    if (result) {
+        vshPrint(ctl, "%s", result);
+        ret = true;
+    }
+
+    VIR_FREE(result);
+    virStringListFree(list);
+    return ret;
+}
+
+
 const vshCmdDef hostAndHypervisorCmds[] = {
     {.name = "allocpages",
      .handler = cmdAllocpages,
@@ -1757,6 +1847,12 @@ const vshCmdDef hostAndHypervisorCmds[] = {
      .info = info_hostname,
      .flags = 0
     },
+    {.name = "hypervisor-cpu-baseline",
+     .handler = cmdHypervisorCPUBaseline,
+     .opts = opts_hypervisor_cpu_baseline,
+     .info = info_hypervisor_cpu_baseline,
+     .flags = 0
+    },
     {.name = "hypervisor-cpu-compare",
      .handler = cmdHypervisorCPUCompare,
      .opts = opts_hypervisor_cpu_compare,
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 1a55092efd..d57ebadee6 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -574,12 +574,13 @@ I<--all> which executes the modification on all NUMA cells.
 =item B<cpu-baseline> I<FILE> [I<--features>] [I<--migratable>]
 
 Compute baseline CPU which will be supported by all host CPUs given in <file>.
-The list of host CPUs is built by extracting all <cpu> elements from the
-<file>. Thus, the <file> can contain either a set of <cpu> elements separated
-by new lines or even a set of complete <capabilities> elements printed by
-B<capabilities> command.  If I<--features> is specified then the
-resulting XML description will explicitly include all features that make
-up the CPU, without this option features that are part of the CPU model
+(See B<hypervisor-cpu-baseline> command to get a CPU which can be provided by a
+specific hypervisor.) The list of host CPUs is built by extracting all <cpu>
+elements from the <file>. Thus, the <file> can contain either a set of <cpu>
+elements separated by new lines or even a set of complete <capabilities>
+elements printed by B<capabilities> command.  If I<--features> is specified
+then the resulting XML description will explicitly include all features that
+make up the CPU, without this option features that are part of the CPU model
 will not be listed in the XML description.   If I<--migratable> is specified,
 features that block migration will not be included in the resulting CPU.
 
@@ -643,6 +644,40 @@ I<machine> specifies the machine type. If I<--error> is specified, the command
 will return an error when the given CPU is incompatible with host CPU and a
 message providing more details about the incompatibility will be printed out.
 
+=item B<hypervisor-cpu-baseline> I<FILE> [I<virttype>] [I<emulator>] [I<arch>]
+[I<machine>] [I<--features>] [I<--migratable>]
+
+Compute baseline CPU which will be compatible with all CPUs given in I<FILE>
+and can be provided by the specified hypervisor. (This is different from
+B<cpu-baseline> which does not consider any hypervisor abilities when computing
+the baseline CPU.)
+
+The XML I<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 B<capabilities> command. The guest CPU definition may be created
+from the host CPU model found in domain capabilities XML (printed by
+B<domcapabilities> command). In addition to the <cpu> elements, this command
+accepts full capabilities XMLs, or domain capabilities XMLs containing the CPU
+definitions. For best results, use only the CPU definitions from domain
+capabilities.
+
+When I<FILE> contains only a single CPU definition, the command will print the
+same CPU updated according to additional options and restricted to the
+capabilities of the specified hypervisor. Specifically, running
+B<virsh hypervisor-cpu-baseline> command with no additional options on the
+result of B<virsh domcapabilities> will return transform the host CPU model
+from domain capabilities XML to the form directly usable in domain XML.
+
+The I<virttype> option specifies the virtualization type (usable in the 'type'
+attribute of the <domain> top level element from the domain XML). I<emulator>
+specifies the path to the emulator, I<arch> specifies the CPU architecture, and
+I<machine> specifies the machine type. If I<--features> is specified then the
+resulting XML description will explicitly include all features that make up the
+CPU, without this option features that are part of the CPU model will not be
+listed in the XML description. If I<--migratable> is specified, features that
+block migration will not be included in the resulting CPU.
+
+
 =back
 
 =head1 DOMAIN COMMANDS
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 15/22] cpu: Rename cpuBaseline as virCPUBaseline
Posted by Jiri Denemark, 6 days ago
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/bhyve/bhyve_driver.c |  4 ++--
 src/cpu/cpu.c            | 10 +++++-----
 src/cpu/cpu.h            | 18 +++++++++---------
 src/cpu/cpu_arm.c        | 10 +++++-----
 src/cpu/cpu_ppc64.c      |  4 ++--
 src/cpu/cpu_x86.c        | 10 +++++-----
 src/libvirt_private.syms |  2 +-
 src/libxl/libxl_driver.c |  4 ++--
 src/qemu/qemu_driver.c   |  4 ++--
 src/test/test_driver.c   |  2 +-
 src/vz/vz_driver.c       |  2 +-
 tests/cputest.c          |  6 +++---
 12 files changed, 38 insertions(+), 38 deletions(-)

diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c
index d2a538337f..72c51434c7 100644
--- a/src/bhyve/bhyve_driver.c
+++ b/src/bhyve/bhyve_driver.c
@@ -1398,8 +1398,8 @@ bhyveConnectBaselineCPU(virConnectPtr conn,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(cpu = cpuBaseline(cpus, ncpus, NULL,
-                            !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE))))
+    if (!(cpu = virCPUBaseline(cpus, ncpus, NULL,
+                               !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE))))
         goto cleanup;
 
     if ((flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) &&
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 047e3b1112..81b93a991b 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -479,7 +479,7 @@ virCPUProbeHost(virArch arch)
 
 
 /**
- * cpuBaseline:
+ * virCPUBaseline:
  *
  * @cpus: list of host CPU definitions
  * @ncpus: number of CPUs in @cpus
@@ -494,10 +494,10 @@ virCPUProbeHost(virArch arch)
  * Returns baseline CPU definition or NULL on error.
  */
 virCPUDefPtr
-cpuBaseline(virCPUDefPtr *cpus,
-            unsigned int ncpus,
-            virDomainCapsCPUModelsPtr models,
-            bool migratable)
+virCPUBaseline(virCPUDefPtr *cpus,
+               unsigned int ncpus,
+               virDomainCapsCPUModelsPtr models,
+               bool migratable)
 {
     struct cpuArchDriver *driver;
     size_t i;
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 83d5bcb63f..529068a618 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -73,10 +73,10 @@ typedef int
                      virDomainCapsCPUModelsPtr models);
 
 typedef virCPUDefPtr
-(*cpuArchBaseline)  (virCPUDefPtr *cpus,
-                     unsigned int ncpus,
-                     virDomainCapsCPUModelsPtr models,
-                     bool migratable);
+(*virCPUArchBaseline)(virCPUDefPtr *cpus,
+                      unsigned int ncpus,
+                      virDomainCapsCPUModelsPtr models,
+                      bool migratable);
 
 typedef int
 (*virCPUArchUpdate)(virCPUDefPtr guest,
@@ -129,7 +129,7 @@ struct cpuArchDriver {
     cpuArchEncode       encode;
     cpuArchDataFree     dataFree;
     virCPUArchGetHost   getHost;
-    cpuArchBaseline     baseline;
+    virCPUArchBaseline baseline;
     virCPUArchUpdate    update;
     virCPUArchUpdateLive updateLive;
     virCPUArchCheckFeature checkFeature;
@@ -194,10 +194,10 @@ virCPUDefPtr
 virCPUProbeHost(virArch arch);
 
 virCPUDefPtr
-cpuBaseline (virCPUDefPtr *cpus,
-             unsigned int ncpus,
-             virDomainCapsCPUModelsPtr models,
-             bool migratable);
+virCPUBaseline(virCPUDefPtr *cpus,
+               unsigned int ncpus,
+               virDomainCapsCPUModelsPtr models,
+               bool migratable);
 
 int
 virCPUUpdate(virArch arch,
diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c
index 44cb4fea68..a9aa065f9f 100644
--- a/src/cpu/cpu_arm.c
+++ b/src/cpu/cpu_arm.c
@@ -73,10 +73,10 @@ virCPUarmUpdate(virCPUDefPtr guest,
 
 
 static virCPUDefPtr
-armBaseline(virCPUDefPtr *cpus,
-            unsigned int ncpus ATTRIBUTE_UNUSED,
-            virDomainCapsCPUModelsPtr models ATTRIBUTE_UNUSED,
-            bool migratable ATTRIBUTE_UNUSED)
+virCPUarmBaseline(virCPUDefPtr *cpus,
+                  unsigned int ncpus ATTRIBUTE_UNUSED,
+                  virDomainCapsCPUModelsPtr models ATTRIBUTE_UNUSED,
+                  bool migratable ATTRIBUTE_UNUSED)
 {
     virCPUDefPtr cpu = NULL;
 
@@ -107,6 +107,6 @@ struct cpuArchDriver cpuDriverArm = {
     .compare = virCPUarmCompare,
     .decode = NULL,
     .encode = NULL,
-    .baseline = armBaseline,
+    .baseline = virCPUarmBaseline,
     .update = virCPUarmUpdate,
 };
diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c
index 76582d4083..c213245fc9 100644
--- a/src/cpu/cpu_ppc64.c
+++ b/src/cpu/cpu_ppc64.c
@@ -767,7 +767,7 @@ virCPUppc64Update(virCPUDefPtr guest,
 }
 
 static virCPUDefPtr
-ppc64DriverBaseline(virCPUDefPtr *cpus,
+virCPUppc64Baseline(virCPUDefPtr *cpus,
                     unsigned int ncpus,
                     virDomainCapsCPUModelsPtr models ATTRIBUTE_UNUSED,
                     bool migratable ATTRIBUTE_UNUSED)
@@ -901,7 +901,7 @@ struct cpuArchDriver cpuDriverPPC64 = {
     .encode     = NULL,
     .dataFree   = virCPUppc64DataFree,
     .getHost    = virCPUppc64GetHost,
-    .baseline   = ppc64DriverBaseline,
+    .baseline   = virCPUppc64Baseline,
     .update     = virCPUppc64Update,
     .getModels  = virCPUppc64DriverGetModels,
     .convertLegacy = virCPUppc64ConvertLegacy,
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index b2398c5ad2..188d1eba75 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -2464,10 +2464,10 @@ virCPUx86GetHost(virCPUDefPtr cpu,
 
 
 static virCPUDefPtr
-x86Baseline(virCPUDefPtr *cpus,
-            unsigned int ncpus,
-            virDomainCapsCPUModelsPtr models,
-            bool migratable)
+virCPUx86Baseline(virCPUDefPtr *cpus,
+                  unsigned int ncpus,
+                  virDomainCapsCPUModelsPtr models,
+                  bool migratable)
 {
     virCPUx86MapPtr map = NULL;
     virCPUx86ModelPtr base_model = NULL;
@@ -3050,7 +3050,7 @@ struct cpuArchDriver cpuDriverX86 = {
 #if defined(__i386__) || defined(__x86_64__)
     .getHost    = virCPUx86GetHost,
 #endif
-    .baseline   = x86Baseline,
+    .baseline   = virCPUx86Baseline,
     .update     = virCPUx86Update,
     .updateLive = virCPUx86UpdateLive,
     .checkFeature = virCPUx86CheckFeature,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3dece252df..912676ec7a 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1139,9 +1139,9 @@ virStoragePoolObjVolumeListExport;
 
 
 # cpu/cpu.h
-cpuBaseline;
 cpuDecode;
 cpuEncode;
+virCPUBaseline;
 virCPUCheckFeature;
 virCPUCompare;
 virCPUCompareXML;
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index df53dead0a..e11969dca7 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -6349,8 +6349,8 @@ libxlConnectBaselineCPU(virConnectPtr conn,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(cpu = cpuBaseline(cpus, ncpus, NULL,
-                            !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE))))
+    if (!(cpu = virCPUBaseline(cpus, ncpus, NULL,
+                               !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE))))
         goto cleanup;
 
     if ((flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) &&
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 4b48afdad1..17167129da 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13179,8 +13179,8 @@ qemuConnectBaselineCPU(virConnectPtr conn ATTRIBUTE_UNUSED,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(baseline = cpuBaseline(cpus, ncpus, NULL,
-                                 !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE))))
+    if (!(baseline = virCPUBaseline(cpus, ncpus, NULL,
+                                    !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE))))
         goto cleanup;
 
     if (!(cpu = virCPUDefCopyWithoutModel(baseline)))
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 467587b19f..abb856a5b2 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -1536,7 +1536,7 @@ testConnectBaselineCPU(virConnectPtr conn ATTRIBUTE_UNUSED,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(cpu = cpuBaseline(cpus, ncpus, NULL, false)))
+    if (!(cpu = virCPUBaseline(cpus, ncpus, NULL, false)))
         goto cleanup;
 
     if ((flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) &&
diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index 48a9a866d9..d4cf2d5f62 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -934,7 +934,7 @@ vzConnectBaselineCPU(virConnectPtr conn,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(cpu = cpuBaseline(cpus, ncpus, NULL, false)))
+    if (!(cpu = virCPUBaseline(cpus, ncpus, NULL, false)))
         goto cleanup;
 
     if ((flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) &&
diff --git a/tests/cputest.c b/tests/cputest.c
index e86cd0b9bc..beb9afabdf 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -321,8 +321,8 @@ cpuTestBaseline(const void *arg)
     if (!(cpus = cpuTestLoadMultiXML(data->arch, data->name, &ncpus)))
         goto cleanup;
 
-    baseline = cpuBaseline(cpus, ncpus, NULL,
-                           !!(data->flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE));
+    baseline = virCPUBaseline(cpus, ncpus, NULL,
+                              !!(data->flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE));
 
     if (baseline &&
         (data->flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) &&
@@ -337,7 +337,7 @@ cpuTestBaseline(const void *arg)
             ret = 0;
         } else {
             VIR_TEST_VERBOSE("\n%-70s... ",
-                    "cpuBaseline was expected to fail but it succeeded");
+                    "virCPUBaseline was expected to fail but it succeeded");
         }
         goto cleanup;
     }
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 16/22] cpu_x86: Add support for passing guest CPUs to virCPUx86Baseline
Posted by Jiri Denemark, 6 days ago
Modern host CPU models from domain capabilities XMLs are reported as
guest CPU definitions with feature policies. This patch updates
virCPUx86Baseline to properly handle such CPU models.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/cpu/cpu_x86.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 188d1eba75..6bef4089e9 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -2482,13 +2482,12 @@ virCPUx86Baseline(virCPUDefPtr *cpus,
     if (!(map = virCPUx86GetMap()))
         goto error;
 
-    if (!(base_model = x86ModelFromCPU(cpus[0], map, VIR_CPU_FEATURE_REQUIRE)))
+    if (!(base_model = x86ModelFromCPU(cpus[0], map, -1)))
         goto error;
 
     if (VIR_ALLOC(cpu) < 0)
         goto error;
 
-    cpu->arch = cpus[0]->arch;
     cpu->type = VIR_CPU_TYPE_GUEST;
     cpu->match = VIR_CPU_MATCH_EXACT;
 
@@ -2513,7 +2512,7 @@ virCPUx86Baseline(virCPUDefPtr *cpus,
             }
         }
 
-        if (!(model = x86ModelFromCPU(cpus[i], map, VIR_CPU_FEATURE_REQUIRE)))
+        if (!(model = x86ModelFromCPU(cpus[i], map, -1)))
             goto error;
 
         if (cpus[i]->vendor && model->vendor &&
@@ -2570,8 +2569,6 @@ virCPUx86Baseline(virCPUDefPtr *cpus,
     if (!outputVendor)
         VIR_FREE(cpu->vendor);
 
-    cpu->arch = VIR_ARCH_NONE;
-
  cleanup:
     x86ModelFree(base_model);
 
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 17/22] cpu: Add explicit arch parameter for virCPUBaseline
Posted by Jiri Denemark, 6 days ago
This is required for virCPUBaseline to accept a list of guest CPU
definitions since they do not have arch set.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/bhyve/bhyve_driver.c |  2 +-
 src/cpu/cpu.c            | 16 +++++++++++-----
 src/cpu/cpu.h            |  3 ++-
 src/libxl/libxl_driver.c |  2 +-
 src/qemu/qemu_driver.c   |  2 +-
 src/test/test_driver.c   |  2 +-
 src/vz/vz_driver.c       |  2 +-
 tests/cputest.c          |  2 +-
 8 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c
index 72c51434c7..26047d31e2 100644
--- a/src/bhyve/bhyve_driver.c
+++ b/src/bhyve/bhyve_driver.c
@@ -1398,7 +1398,7 @@ bhyveConnectBaselineCPU(virConnectPtr conn,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(cpu = virCPUBaseline(cpus, ncpus, NULL,
+    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL,
                                !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE))))
         goto cleanup;
 
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 81b93a991b..2c60d27b17 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -481,20 +481,22 @@ virCPUProbeHost(virArch arch)
 /**
  * virCPUBaseline:
  *
+ * @arch: CPU architecture, use VIR_ARCH_NONE to autodetect from @cpus
  * @cpus: list of host CPU definitions
  * @ncpus: number of CPUs in @cpus
  * @models: list of CPU models that can be considered for the baseline CPU
  * @migratable: requests non-migratable features to be removed from the result
  *
  * Computes the most feature-rich CPU which is compatible with all given
- * host CPUs. If @models is NULL, all models supported by libvirt will
+ * CPUs. If @models is NULL, all models supported by libvirt will
  * be considered when computing the baseline CPU model, otherwise the baseline
  * CPU model will be one of the provided CPU @models.
  *
  * Returns baseline CPU definition or NULL on error.
  */
 virCPUDefPtr
-virCPUBaseline(virCPUDefPtr *cpus,
+virCPUBaseline(virArch arch,
+               virCPUDefPtr *cpus,
                unsigned int ncpus,
                virDomainCapsCPUModelsPtr models,
                bool migratable)
@@ -502,7 +504,8 @@ virCPUBaseline(virCPUDefPtr *cpus,
     struct cpuArchDriver *driver;
     size_t i;
 
-    VIR_DEBUG("ncpus=%u, models=%p, migratable=%d", ncpus, models, migratable);
+    VIR_DEBUG("arch=%s, ncpus=%u, models=%p, migratable=%d",
+              virArchToString(arch), ncpus, models, migratable);
     if (cpus) {
         for (i = 0; i < ncpus; i++)
             VIR_DEBUG("cpus[%zu]=%p", i, cpus[i]);
@@ -536,13 +539,16 @@ virCPUBaseline(virCPUDefPtr *cpus,
         }
     }
 
-    if ((driver = cpuGetSubDriver(cpus[0]->arch)) == NULL)
+    if (arch == VIR_ARCH_NONE)
+        arch = cpus[0]->arch;
+
+    if ((driver = cpuGetSubDriver(arch)) == NULL)
         return NULL;
 
     if (driver->baseline == NULL) {
         virReportError(VIR_ERR_NO_SUPPORT,
                        _("cannot compute baseline CPU of %s architecture"),
-                       virArchToString(cpus[0]->arch));
+                       virArchToString(arch));
         return NULL;
     }
 
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 529068a618..8c45bf8b31 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -194,7 +194,8 @@ virCPUDefPtr
 virCPUProbeHost(virArch arch);
 
 virCPUDefPtr
-virCPUBaseline(virCPUDefPtr *cpus,
+virCPUBaseline(virArch arch,
+               virCPUDefPtr *cpus,
                unsigned int ncpus,
                virDomainCapsCPUModelsPtr models,
                bool migratable);
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index e11969dca7..a85ce84404 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -6349,7 +6349,7 @@ libxlConnectBaselineCPU(virConnectPtr conn,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(cpu = virCPUBaseline(cpus, ncpus, NULL,
+    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL,
                                !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE))))
         goto cleanup;
 
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 17167129da..b95e1f5296 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13179,7 +13179,7 @@ qemuConnectBaselineCPU(virConnectPtr conn ATTRIBUTE_UNUSED,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(baseline = virCPUBaseline(cpus, ncpus, NULL,
+    if (!(baseline = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL,
                                     !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE))))
         goto cleanup;
 
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index abb856a5b2..3b4acaf7fe 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -1536,7 +1536,7 @@ testConnectBaselineCPU(virConnectPtr conn ATTRIBUTE_UNUSED,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(cpu = virCPUBaseline(cpus, ncpus, NULL, false)))
+    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL, false)))
         goto cleanup;
 
     if ((flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) &&
diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index d4cf2d5f62..50cd0acfdf 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -934,7 +934,7 @@ vzConnectBaselineCPU(virConnectPtr conn,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(cpu = virCPUBaseline(cpus, ncpus, NULL, false)))
+    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL, false)))
         goto cleanup;
 
     if ((flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) &&
diff --git a/tests/cputest.c b/tests/cputest.c
index beb9afabdf..9b84ffea86 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -321,7 +321,7 @@ cpuTestBaseline(const void *arg)
     if (!(cpus = cpuTestLoadMultiXML(data->arch, data->name, &ncpus)))
         goto cleanup;
 
-    baseline = virCPUBaseline(cpus, ncpus, NULL,
+    baseline = virCPUBaseline(data->arch, cpus, ncpus, NULL,
                               !!(data->flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE));
 
     if (baseline &&
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 18/22] cpu: Update style in virCPUBaseline
Posted by Jiri Denemark, 6 days ago
To make it more consistent with the rest of the CPU driver code.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/cpu/cpu.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 2c60d27b17..b6c1695f2a 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -515,14 +515,14 @@ virCPUBaseline(virArch arch,
             VIR_DEBUG("models[%zu]=%s", i, models->models[i].name);
     }
 
-    if (cpus == NULL && ncpus != 0) {
+    if (!cpus && ncpus != 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        "%s", _("nonzero ncpus doesn't match with NULL cpus"));
         return NULL;
     }
 
     if (ncpus < 1) {
-        virReportError(VIR_ERR_INVALID_ARG, "%s", _("No CPUs given"));
+        virReportError(VIR_ERR_INVALID_ARG, "%s", _("no CPUs given"));
         return NULL;
     }
 
@@ -542,10 +542,10 @@ virCPUBaseline(virArch arch,
     if (arch == VIR_ARCH_NONE)
         arch = cpus[0]->arch;
 
-    if ((driver = cpuGetSubDriver(arch)) == NULL)
+    if (!(driver = cpuGetSubDriver(arch)))
         return NULL;
 
-    if (driver->baseline == NULL) {
+    if (!driver->baseline) {
         virReportError(VIR_ERR_NO_SUPPORT,
                        _("cannot compute baseline CPU of %s architecture"),
                        virArchToString(arch));
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 19/22] cpu: Add optional list of allowed features to virCPUBaseline
Posted by Jiri Denemark, 6 days ago
When computing a baseline CPU for a specific hypervisor we have to make
sure to include only CPU features supported by the hypervisor. Otherwise
the computed CPU could not be used for starting a new domain.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/bhyve/bhyve_driver.c |  2 +-
 src/cpu/cpu.c            |  8 +++++---
 src/cpu/cpu.h            |  2 ++
 src/cpu/cpu_arm.c        |  1 +
 src/cpu/cpu_ppc64.c      |  1 +
 src/cpu/cpu_x86.c        | 18 ++++++++++++++++++
 src/libxl/libxl_driver.c |  2 +-
 src/qemu/qemu_driver.c   |  2 +-
 src/test/test_driver.c   |  2 +-
 src/vz/vz_driver.c       |  2 +-
 tests/cputest.c          |  2 +-
 11 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c
index 26047d31e2..97e8d4eb37 100644
--- a/src/bhyve/bhyve_driver.c
+++ b/src/bhyve/bhyve_driver.c
@@ -1398,7 +1398,7 @@ bhyveConnectBaselineCPU(virConnectPtr conn,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL,
+    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL, NULL,
                                !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE))))
         goto cleanup;
 
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index b6c1695f2a..cc93c49418 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -485,6 +485,7 @@ virCPUProbeHost(virArch arch)
  * @cpus: list of host CPU definitions
  * @ncpus: number of CPUs in @cpus
  * @models: list of CPU models that can be considered for the baseline CPU
+ * @features: optional NULL terminated list of allowed features
  * @migratable: requests non-migratable features to be removed from the result
  *
  * Computes the most feature-rich CPU which is compatible with all given
@@ -499,13 +500,14 @@ virCPUBaseline(virArch arch,
                virCPUDefPtr *cpus,
                unsigned int ncpus,
                virDomainCapsCPUModelsPtr models,
+               const char **features,
                bool migratable)
 {
     struct cpuArchDriver *driver;
     size_t i;
 
-    VIR_DEBUG("arch=%s, ncpus=%u, models=%p, migratable=%d",
-              virArchToString(arch), ncpus, models, migratable);
+    VIR_DEBUG("arch=%s, ncpus=%u, models=%p, features=%p, migratable=%d",
+              virArchToString(arch), ncpus, models, features, migratable);
     if (cpus) {
         for (i = 0; i < ncpus; i++)
             VIR_DEBUG("cpus[%zu]=%p", i, cpus[i]);
@@ -552,7 +554,7 @@ virCPUBaseline(virArch arch,
         return NULL;
     }
 
-    return driver->baseline(cpus, ncpus, models, migratable);
+    return driver->baseline(cpus, ncpus, models, features, migratable);
 }
 
 
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 8c45bf8b31..81119b6aeb 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -76,6 +76,7 @@ typedef virCPUDefPtr
 (*virCPUArchBaseline)(virCPUDefPtr *cpus,
                       unsigned int ncpus,
                       virDomainCapsCPUModelsPtr models,
+                      const char **features,
                       bool migratable);
 
 typedef int
@@ -198,6 +199,7 @@ virCPUBaseline(virArch arch,
                virCPUDefPtr *cpus,
                unsigned int ncpus,
                virDomainCapsCPUModelsPtr models,
+               const char **features,
                bool migratable);
 
 int
diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c
index a9aa065f9f..cc7da44ac4 100644
--- a/src/cpu/cpu_arm.c
+++ b/src/cpu/cpu_arm.c
@@ -76,6 +76,7 @@ static virCPUDefPtr
 virCPUarmBaseline(virCPUDefPtr *cpus,
                   unsigned int ncpus ATTRIBUTE_UNUSED,
                   virDomainCapsCPUModelsPtr models ATTRIBUTE_UNUSED,
+                  const char **features ATTRIBUTE_UNUSED,
                   bool migratable ATTRIBUTE_UNUSED)
 {
     virCPUDefPtr cpu = NULL;
diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c
index c213245fc9..d562677fa3 100644
--- a/src/cpu/cpu_ppc64.c
+++ b/src/cpu/cpu_ppc64.c
@@ -770,6 +770,7 @@ static virCPUDefPtr
 virCPUppc64Baseline(virCPUDefPtr *cpus,
                     unsigned int ncpus,
                     virDomainCapsCPUModelsPtr models ATTRIBUTE_UNUSED,
+                    const char **features ATTRIBUTE_UNUSED,
                     bool migratable ATTRIBUTE_UNUSED)
 {
     struct ppc64_map *map;
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 6bef4089e9..809da94117 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -2467,6 +2467,7 @@ static virCPUDefPtr
 virCPUx86Baseline(virCPUDefPtr *cpus,
                   unsigned int ncpus,
                   virDomainCapsCPUModelsPtr models,
+                  const char **features,
                   bool migratable)
 {
     virCPUx86MapPtr map = NULL;
@@ -2478,6 +2479,7 @@ virCPUx86Baseline(virCPUDefPtr *cpus,
     bool outputVendor = true;
     const char *modelName;
     bool matchingNames = true;
+    virCPUDataPtr featData = NULL;
 
     if (!(map = virCPUx86GetMap()))
         goto error;
@@ -2550,6 +2552,21 @@ virCPUx86Baseline(virCPUDefPtr *cpus,
         model = NULL;
     }
 
+    if (features) {
+        virCPUx86FeaturePtr feat;
+
+        if (!(featData = virCPUDataNew(archs[0])))
+            goto cleanup;
+
+        for (i = 0; features[i]; i++) {
+            if ((feat = x86FeatureFind(map, features[i])) &&
+                x86DataAdd(&featData->data.x86, &feat->data) < 0)
+                goto cleanup;
+        }
+
+        x86DataIntersect(&base_model->data, &featData->data.x86);
+    }
+
     if (x86DataIsEmpty(&base_model->data)) {
         virReportError(VIR_ERR_OPERATION_FAILED,
                        "%s", _("CPUs are incompatible"));
@@ -2571,6 +2588,7 @@ virCPUx86Baseline(virCPUDefPtr *cpus,
 
  cleanup:
     x86ModelFree(base_model);
+    virCPUx86DataFree(featData);
 
     return cpu;
 
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index a85ce84404..8c40661e5a 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -6349,7 +6349,7 @@ libxlConnectBaselineCPU(virConnectPtr conn,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL,
+    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL, NULL,
                                !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE))))
         goto cleanup;
 
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b95e1f5296..e036764f92 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13179,7 +13179,7 @@ qemuConnectBaselineCPU(virConnectPtr conn ATTRIBUTE_UNUSED,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(baseline = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL,
+    if (!(baseline = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL, NULL,
                                     !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE))))
         goto cleanup;
 
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 3b4acaf7fe..09f17bc8f9 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -1536,7 +1536,7 @@ testConnectBaselineCPU(virConnectPtr conn ATTRIBUTE_UNUSED,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL, false)))
+    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL, NULL, false)))
         goto cleanup;
 
     if ((flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) &&
diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index 50cd0acfdf..c9520d4a58 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -934,7 +934,7 @@ vzConnectBaselineCPU(virConnectPtr conn,
     if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_HOST)))
         goto cleanup;
 
-    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL, false)))
+    if (!(cpu = virCPUBaseline(VIR_ARCH_NONE, cpus, ncpus, NULL, NULL, false)))
         goto cleanup;
 
     if ((flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) &&
diff --git a/tests/cputest.c b/tests/cputest.c
index 9b84ffea86..baf2b3c648 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -321,7 +321,7 @@ cpuTestBaseline(const void *arg)
     if (!(cpus = cpuTestLoadMultiXML(data->arch, data->name, &ncpus)))
         goto cleanup;
 
-    baseline = virCPUBaseline(data->arch, cpus, ncpus, NULL,
+    baseline = virCPUBaseline(data->arch, cpus, ncpus, NULL, NULL,
                               !!(data->flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE));
 
     if (baseline &&
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 20/22] qemu_capabilities: Introduce virQEMUCapsGetCPUFeatures
Posted by Jiri Denemark, 6 days ago
The function creates a lost of all (or migratable only) CPU features
supported by QEMU. It works by looking at the CPU model info returned by
query-cpu-model-expansion QMP command.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/qemu/qemu_capabilities.c | 52 ++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_capabilities.h |  4 +++
 2 files changed, 56 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 77a4b4154e..e8c5940210 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2367,6 +2367,58 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
     return ret;
 }
 
+
+/**
+ * Get NULL terminated list of features supported by QEMU.
+ *
+ * Returns -1 on error,
+ *          0 on success (@features will be NULL if QEMU does not support this),
+ *          1 when @features is filled in, but migratability info is not available.
+ */
+int
+virQEMUCapsGetCPUFeatures(virQEMUCapsPtr qemuCaps,
+                          virDomainVirtType virtType,
+                          bool migratable,
+                          char ***features)
+{
+    virQEMUCapsHostCPUDataPtr data;
+    char **list;
+    size_t i;
+    size_t n;
+    int ret = -1;
+
+    *features = NULL;
+    data = virQEMUCapsGetHostCPUData(qemuCaps, virtType);
+
+    if (!data->info)
+        return 0;
+
+    if (VIR_ALLOC_N(list, data->info->nprops + 1) < 0)
+        return -1;
+
+    n = 0;
+    for (i = 0; i < data->info->nprops; i++) {
+        qemuMonitorCPUPropertyPtr prop = data->info->props + i;
+
+        if (migratable && prop->migratable == VIR_TRISTATE_BOOL_NO)
+            continue;
+
+        if (VIR_STRDUP(list[n++], prop->name) < 0)
+            goto cleanup;
+    }
+
+    VIR_STEAL_PTR(*features, list);
+    if (migratable && !data->info->migratability)
+        ret = 1;
+    else
+        ret = 0;
+
+ cleanup:
+    virStringListFree(list);
+    return ret;
+}
+
+
 struct tpmTypeToCaps {
     int type;
     virQEMUCapsFlags caps;
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 6f095bfbfe..eee989559e 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -529,6 +529,10 @@ typedef enum {
 virCPUDefPtr virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
                                      virDomainVirtType type,
                                      virQEMUCapsHostCPUType cpuType);
+int virQEMUCapsGetCPUFeatures(virQEMUCapsPtr qemuCaps,
+                              virDomainVirtType virtType,
+                              bool migratable,
+                              char ***features);
 
 bool virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps,
                                    virCapsPtr caps,
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 21/22] qemu: Implement virConnectBaselineHypervisorCPU
Posted by Jiri Denemark, 6 days ago
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/qemu/qemu_driver.c | 91 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e036764f92..d702e8a8ff 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13206,6 +13206,96 @@ qemuConnectBaselineCPU(virConnectPtr conn ATTRIBUTE_UNUSED,
 }
 
 
+static char *
+qemuConnectBaselineHypervisorCPU(virConnectPtr conn,
+                                 const char *emulator,
+                                 const char *archStr,
+                                 const char *machine,
+                                 const char *virttypeStr,
+                                 const char **xmlCPUs,
+                                 unsigned int ncpus,
+                                 unsigned int flags)
+{
+    virQEMUDriverPtr driver = conn->privateData;
+    virCPUDefPtr *cpus = NULL;
+    virQEMUCapsPtr qemuCaps = NULL;
+    virArch arch;
+    virDomainVirtType virttype;
+    virDomainCapsCPUModelsPtr cpuModels;
+    bool migratable;
+    virCPUDefPtr cpu = NULL;
+    char *cpustr = NULL;
+    char **features = NULL;
+
+    virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES |
+                  VIR_CONNECT_BASELINE_CPU_MIGRATABLE, NULL);
+
+    if (virConnectBaselineHypervisorCPUEnsureACL(conn) < 0)
+        goto cleanup;
+
+    migratable = !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE);
+
+    if (!(cpus = virCPUDefListParse(xmlCPUs, ncpus, VIR_CPU_TYPE_AUTO)))
+        goto cleanup;
+
+    qemuCaps = virQEMUCapsCacheLookupDefault(driver->qemuCapsCache,
+                                             emulator,
+                                             archStr,
+                                             virttypeStr,
+                                             machine,
+                                             &arch, &virttype, NULL);
+    if (!qemuCaps)
+        goto cleanup;
+
+    if (!(cpuModels = virQEMUCapsGetCPUDefinitions(qemuCaps, virttype)) ||
+        cpuModels->nmodels == 0) {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+                       _("QEMU '%s' does not support any CPU models for "
+                         "virttype '%s'"),
+                       virQEMUCapsGetBinary(qemuCaps),
+                       virDomainVirtTypeToString(virttype));
+        goto cleanup;
+    }
+
+    if (ARCH_IS_X86(arch)) {
+        int rc = virQEMUCapsGetCPUFeatures(qemuCaps, virttype,
+                                           migratable, &features);
+        if (rc < 0)
+            goto cleanup;
+        if (features && rc == 0) {
+            /* We got only migratable features from QEMU if we asked for them,
+             * no further filtering in virCPUBaseline is desired. */
+            migratable = false;
+        }
+
+        if (!(cpu = virCPUBaseline(arch, cpus, ncpus, cpuModels,
+                                   (const char **)features, migratable)))
+            goto cleanup;
+    } else {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+                       _("computing baseline hypervisor CPU is not supported "
+                         "for arch %s"), virArchToString(arch));
+        goto cleanup;
+    }
+
+    cpu->fallback = VIR_CPU_FALLBACK_FORBID;
+
+    if ((flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) &&
+        virCPUExpandFeatures(arch, cpu) < 0)
+        goto cleanup;
+
+    cpustr = virCPUDefFormat(cpu, NULL);
+
+ cleanup:
+    virCPUDefListFree(cpus);
+    virCPUDefFree(cpu);
+    virObjectUnref(qemuCaps);
+    virStringListFree(features);
+
+    return cpustr;
+}
+
+
 static int
 qemuDomainGetJobInfoMigrationStats(virQEMUDriverPtr driver,
                                    virDomainObjPtr vm,
@@ -21386,6 +21476,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
     .domainSetBlockThreshold = qemuDomainSetBlockThreshold, /* 3.2.0 */
     .domainSetLifecycleAction = qemuDomainSetLifecycleAction, /* 3.9.0 */
     .connectCompareHypervisorCPU = qemuConnectCompareHypervisorCPU, /* 4.4.0 */
+    .connectBaselineHypervisorCPU = qemuConnectBaselineHypervisorCPU, /* 4.4.0 */
 };
 
 
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 22/22] news: Mention new CPU related APIs
Posted by Jiri Denemark, 6 days ago
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 docs/news.xml | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/docs/news.xml b/docs/news.xml
index 7d40e85b9a..bd7885e91a 100644
--- a/docs/news.xml
+++ b/docs/news.xml
@@ -54,6 +54,15 @@
           a QEMU virtual machine.
         </description>
       </change>
+      <change>
+        <summary>
+          Introduce new virConnectBaselineHypervisorCPU and virConnectBaselineHypervisorCPU APIs
+        </summary>
+        <description>
+          Unlike the old virConnectBaselineCPU and virConnectBaselineCPU APIs,
+          both new APIs consider capabilities of a specific hypervisor.
+        </description>
+      </change>
     </section>
     <section title="Improvements">
       <change>
-- 
2.17.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list