[PATCH v1 0/4] Introduce virsh hypervisor-cpu-models

Allows for the query of hypervisor-known CPU models via the simple command: virsh hypervisor-cpu-models. For the QEMU driver, the models are queried via the capabilities file. Each model is printed to the terminal on its own line similar to the cpu-models command, and there is no order to the listing. The models "qemu", "host", and "max" have been excluded from this list since they are not architecture specific. The code can be easily modified to include them if desired. Collin Walling (4): Introduce virConnectGetHypervisorCPUNames public API remote: Implement virConnectGetHypervisorCPUNames virsh: Introduce new hypervisor-cpu-models command qemu_driver: Implement qemuConnectGetHypervisorCPUNames docs/manpages/virsh.rst | 20 ++++++++++ include/libvirt/libvirt-host.h | 6 +++ src/driver-hypervisor.h | 9 +++++ src/libvirt-host.c | 54 ++++++++++++++++++++++++++ src/libvirt_public.syms | 5 +++ src/qemu/qemu_driver.c | 62 ++++++++++++++++++++++++++++++ src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 20 +++++++++- src/remote_protocol-structs | 11 ++++++ tools/virsh-host.c | 70 ++++++++++++++++++++++++++++++++++ 10 files changed, 257 insertions(+), 1 deletion(-) -- 2.39.0

The new API collects a list of CPU model names supported by the specified hypervisor. This is a more useful version of virConnectGetCPUNames, which does not consider any hypervisor capabilities when querying model names. Signed-off-by: Collin Walling <walling@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- include/libvirt/libvirt-host.h | 6 ++++ src/driver-hypervisor.h | 9 ++++++ src/libvirt-host.c | 54 ++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 ++++ 4 files changed, 74 insertions(+) diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h index 3112f2b676..a70a4d9971 100644 --- a/include/libvirt/libvirt-host.h +++ b/include/libvirt/libvirt-host.h @@ -961,6 +961,12 @@ int virConnectGetCPUModelNames(virConnectPtr conn, const char *arch, char ***models, unsigned int flags); +char *virConnectGetHypervisorCPUModelNames(virConnectPtr conn, + const char *emulator, + const char *arch, + const char *machine, + const char *virttype, + unsigned int flags); /** * virConnectBaselineCPUFlags: diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index 5219344b72..725c1db752 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -732,6 +732,14 @@ typedef int char ***models, unsigned int flags); +typedef char * +(*virDrvConnectGetHypervisorCPUModelNames)(virConnectPtr conn, + const char *emulator, + const char *arch, + const char *machine, + const char *virttype, + unsigned int flags); + typedef int (*virDrvDomainGetJobInfo)(virDomainPtr domain, virDomainJobInfoPtr info); @@ -1701,6 +1709,7 @@ struct _virHypervisorDriver { virDrvDomainSetLifecycleAction domainSetLifecycleAction; virDrvConnectCompareHypervisorCPU connectCompareHypervisorCPU; virDrvConnectBaselineHypervisorCPU connectBaselineHypervisorCPU; + virDrvConnectGetHypervisorCPUModelNames connectGetHypervisorCPUModelNames; virDrvNodeGetSEVInfo nodeGetSEVInfo; virDrvDomainGetLaunchSecurityInfo domainGetLaunchSecurityInfo; virDrvDomainSetLaunchSecurityState domainSetLaunchSecurityState; diff --git a/src/libvirt-host.c b/src/libvirt-host.c index a2ba347d54..407d19ffa9 100644 --- a/src/libvirt-host.c +++ b/src/libvirt-host.c @@ -1379,6 +1379,60 @@ virConnectBaselineHypervisorCPU(virConnectPtr conn, } +/** + * virConnectGetHypervisorCPUModelNames: + * + * @conn: pointer to the hypervisor connection + * @emulator: path to the emulator binary + * @arch: CPU architecture + * @machine: machine type + * @virttype: virtualization type + * @flags: extra flags; not used yet, so callers should always pass 0. + * + * Get the list of CPU models recognized by the hypervisor for a specific + * architecture. Note that even if the hypervisor reports a particular CPU + * model, hardware limitations may impose restrictions on which CPU models + * may be supported on the host (e.g. on s390 the hypervisor may report + * model gen15a, but this model will not run on an older machine such as z14). + * + * Returns NULL on error, or a string of CPU models on success. + * + * Since: 9.2.0 + */ +char * +virConnectGetHypervisorCPUModelNames(virConnectPtr conn, + const char *emulator, + const char *arch, + const char *machine, + const char *virttype, + unsigned int flags) +{ + VIR_DEBUG("conn=%p, emulator=%s, arch=%s, machine=%s, virttype=%s", + conn, NULLSTR(emulator), NULLSTR(arch), + NULLSTR(machine), NULLSTR(virttype)); + + virResetLastError(); + virCheckConnectReturn(conn, NULL); + + if (conn->driver->connectGetHypervisorCPUModelNames) { + char *result; + + result = conn->driver->connectGetHypervisorCPUModelNames(conn, emulator, arch, + machine, virttype, flags); + if (!result) + goto error; + + return result; + } + + 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 80742f268e..df8d991cce 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -932,4 +932,9 @@ LIBVIRT_9.0.0 { virDomainFDAssociate; } LIBVIRT_8.5.0; +LIBVIRT_9.2.0 { + global: + virConnectGetHypervisorCPUModelNames; +} LIBVIRT_9.0.0; + # .... define new API here using predicted next version number .... -- 2.39.0

On Wed, Mar 22, 2023 at 11:39:15AM -0400, Collin Walling wrote:
The new API collects a list of CPU model names supported by the specified hypervisor. This is a more useful version of virConnectGetCPUNames, which does not consider any hypervisor capabilities when querying model names.
Signed-off-by: Collin Walling <walling@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- include/libvirt/libvirt-host.h | 6 ++++ src/driver-hypervisor.h | 9 ++++++ src/libvirt-host.c | 54 ++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 ++++ 4 files changed, 74 insertions(+)
diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h index 3112f2b676..a70a4d9971 100644 --- a/include/libvirt/libvirt-host.h +++ b/include/libvirt/libvirt-host.h @@ -961,6 +961,12 @@ int virConnectGetCPUModelNames(virConnectPtr conn, const char *arch, char ***models, unsigned int flags); +char *virConnectGetHypervisorCPUModelNames(virConnectPtr conn, + const char *emulator, + const char *arch, + const char *machine, + const char *virttype, + unsigned int flags);
/** * virConnectBaselineCPUFlags: diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index 5219344b72..725c1db752 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -732,6 +732,14 @@ typedef int char ***models, unsigned int flags);
+typedef char * +(*virDrvConnectGetHypervisorCPUModelNames)(virConnectPtr conn, + const char *emulator, + const char *arch, + const char *machine, + const char *virttype, + unsigned int flags); + typedef int (*virDrvDomainGetJobInfo)(virDomainPtr domain, virDomainJobInfoPtr info); @@ -1701,6 +1709,7 @@ struct _virHypervisorDriver { virDrvDomainSetLifecycleAction domainSetLifecycleAction; virDrvConnectCompareHypervisorCPU connectCompareHypervisorCPU; virDrvConnectBaselineHypervisorCPU connectBaselineHypervisorCPU; + virDrvConnectGetHypervisorCPUModelNames connectGetHypervisorCPUModelNames; virDrvNodeGetSEVInfo nodeGetSEVInfo; virDrvDomainGetLaunchSecurityInfo domainGetLaunchSecurityInfo; virDrvDomainSetLaunchSecurityState domainSetLaunchSecurityState; diff --git a/src/libvirt-host.c b/src/libvirt-host.c index a2ba347d54..407d19ffa9 100644 --- a/src/libvirt-host.c +++ b/src/libvirt-host.c @@ -1379,6 +1379,60 @@ virConnectBaselineHypervisorCPU(virConnectPtr conn, }
+/** + * virConnectGetHypervisorCPUModelNames: + * + * @conn: pointer to the hypervisor connection + * @emulator: path to the emulator binary + * @arch: CPU architecture + * @machine: machine type + * @virttype: virtualization type + * @flags: extra flags; not used yet, so callers should always pass 0. + * + * Get the list of CPU models recognized by the hypervisor for a specific + * architecture. Note that even if the hypervisor reports a particular CPU + * model, hardware limitations may impose restrictions on which CPU models + * may be supported on the host (e.g. on s390 the hypervisor may report + * model gen15a, but this model will not run on an older machine such as z14). + * + * Returns NULL on error, or a string of CPU models on success.
This API appears to be duplicating information that is already made available in the domain capabilities output, except it is worse as this API is actually providing less information. Also returning this as a single newline separated string is making the assumption that the caller merely wishes to print this on the console. With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

Signed-off-by: Collin Walling <walling@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 20 +++++++++++++++++++- src/remote_protocol-structs | 11 +++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index a4c60be3d7..10d10c5464 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8107,6 +8107,7 @@ static virHypervisorDriver hypervisor_driver = { .domainSetLifecycleAction = remoteDomainSetLifecycleAction, /* 3.9.0 */ .connectCompareHypervisorCPU = remoteConnectCompareHypervisorCPU, /* 4.4.0 */ .connectBaselineHypervisorCPU = remoteConnectBaselineHypervisorCPU, /* 4.4.0 */ + .connectGetHypervisorCPUModelNames = remoteConnectGetHypervisorCPUModelNames, /* 9.2.0 */ .nodeGetSEVInfo = remoteNodeGetSEVInfo, /* 4.5.0 */ .domainGetLaunchSecurityInfo = remoteDomainGetLaunchSecurityInfo, /* 4.5.0 */ .domainCheckpointCreateXML = remoteDomainCheckpointCreateXML, /* 5.6.0 */ diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 5d86a51116..ec179e618a 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -3646,6 +3646,18 @@ struct remote_connect_baseline_hypervisor_cpu_ret { remote_nonnull_string cpu; }; +struct remote_connect_get_hypervisor_cpu_model_names_args { + remote_string emulator; + remote_string arch; + remote_string machine; + remote_string virttype; + unsigned int flags; +}; + +struct remote_connect_get_hypervisor_cpu_model_names_ret { + remote_nonnull_string models; +}; + struct remote_node_get_sev_info_args { int nparams; unsigned int flags; @@ -6974,5 +6986,11 @@ enum remote_procedure { * @generate: none * @acl: domain:write */ - REMOTE_PROC_DOMAIN_FD_ASSOCIATE = 443 + REMOTE_PROC_DOMAIN_FD_ASSOCIATE = 443, + + /** + * @generate: both + * @acl: connect:write + */ + REMOTE_PROC_CONNECT_GET_HYPERVISOR_CPU_MODEL_NAMES = 444 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 3c6c230a16..947c95c832 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -3003,6 +3003,16 @@ struct remote_connect_baseline_hypervisor_cpu_args { struct remote_connect_baseline_hypervisor_cpu_ret { remote_nonnull_string cpu; }; +struct remote_connect_get_hypervisor_cpu_model_names_args { + remote_string emulator; + remote_string arch; + remote_string machine; + remote_string virttype; + u_int flags; +}; +struct remote_connect_get_hypervisor_cpu_model_names_ret { + remote_nonnull_string models; +}; struct remote_node_get_sev_info_args { int nparams; u_int flags; @@ -3717,4 +3727,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_RESTORE_PARAMS = 441, REMOTE_PROC_DOMAIN_ABORT_JOB_FLAGS = 442, REMOTE_PROC_DOMAIN_FD_ASSOCIATE = 443, + REMOTE_PROC_CONNECT_GET_HYPERVISOR_CPU_MODEL_NAMES = 444, }; -- 2.39.0

This command is a virsh wrapper for virConnectGetHypervisorCPUNames. Signed-off-by: Collin Walling <walling@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- docs/manpages/virsh.rst | 20 ++++++++++++ tools/virsh-host.c | 70 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst index 26c328d390..c156e60d6e 100644 --- a/docs/manpages/virsh.rst +++ b/docs/manpages/virsh.rst @@ -1004,6 +1004,26 @@ listed in the XML description. If *--migratable* is specified, features that block migration will not be included in the resulting CPU. +hypervisor-cpu-models +--------------------- + +**Syntax:** + +:: + + hypervisor-cpu-models [virttype] [emulator] [arch] [machine] + +Print the list of CPU models known by the hypervisor for the specified architecture. +It is not guaranteed that a listed CPU will run on the host. To determine CPU +model compatibility with the host, see ``virsh hypervisor-cpu-baseline`` and +``virsh hypervisor-cpu-compare``. + +The *virttype* option specifies the virtualization type (usable in the 'type' +attribute of the <domain> top level element from the domain XML). *emulator* +specifies the path to the emulator, *arch* specifies the CPU architecture, and +*machine* specifies the machine type. + + DOMAIN COMMANDS =============== diff --git a/tools/virsh-host.c b/tools/virsh-host.c index 21d479fd01..2eedc1517b 100644 --- a/tools/virsh-host.c +++ b/tools/virsh-host.c @@ -1779,6 +1779,70 @@ cmdHypervisorCPUBaseline(vshControl *ctl, return ret; } +/* + * "hypervisor-cpu-models" command + */ +static const vshCmdInfo info_hypervisor_cpu_models[] = { + {.name = "help", + .data = N_("Hypervisor reported CPU models") + }, + {.name = "desc", + .data = N_("Get the CPU models reported by the hypervisor.") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_hypervisor_cpu_models[] = { + {.name = "virttype", + .type = VSH_OT_STRING, + .completer = virshDomainVirtTypeCompleter, + .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, + .completer = virshArchCompleter, + .help = N_("CPU architecture (/domain/os/type/@arch)"), + }, + {.name = "machine", + .type = VSH_OT_STRING, + .help = N_("machine type (/domain/os/type/@machine)"), + }, + {.name = NULL} +}; + +static bool +cmdHypervisorCPUModelNames(vshControl *ctl, + const vshCmd *cmd) +{ + const char *virttype = NULL; + const char *emulator = NULL; + const char *arch = NULL; + const char *machine = NULL; + g_autofree char *result = NULL; + virshControl *priv = ctl->privData; + + if (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; + + result = virConnectGetHypervisorCPUModelNames(priv->conn, emulator, arch, + machine, virttype, 0); + + if (!result) { + vshError(ctl, "%s", _("failed to get CPU model names")); + return false; + } + + vshPrint(ctl, "%s\n", result); + return true; +} + const vshCmdDef hostAndHypervisorCmds[] = { {.name = "allocpages", @@ -1847,6 +1911,12 @@ const vshCmdDef hostAndHypervisorCmds[] = { .info = info_hypervisor_cpu_compare, .flags = 0 }, + {.name = "hypervisor-cpu-models", + .handler = cmdHypervisorCPUModelNames, + .opts = opts_hypervisor_cpu_models, + .info = info_hypervisor_cpu_models, + .flags = 0 + }, {.name = "maxvcpus", .handler = cmdMaxvcpus, .opts = opts_maxvcpus, -- 2.39.0

On Wed, Mar 22, 2023 at 11:39:17AM -0400, Collin Walling wrote:
This command is a virsh wrapper for virConnectGetHypervisorCPUNames.
Signed-off-by: Collin Walling <walling@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- docs/manpages/virsh.rst | 20 ++++++++++++ tools/virsh-host.c | 70 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst index 26c328d390..c156e60d6e 100644 --- a/docs/manpages/virsh.rst +++ b/docs/manpages/virsh.rst @@ -1004,6 +1004,26 @@ listed in the XML description. If *--migratable* is specified, features that block migration will not be included in the resulting CPU.
+hypervisor-cpu-models +--------------------- + +**Syntax:** + +:: + + hypervisor-cpu-models [virttype] [emulator] [arch] [machine] + +Print the list of CPU models known by the hypervisor for the specified architecture. +It is not guaranteed that a listed CPU will run on the host. To determine CPU +model compatibility with the host, see ``virsh hypervisor-cpu-baseline`` and +``virsh hypervisor-cpu-compare``. + +The *virttype* option specifies the virtualization type (usable in the 'type' +attribute of the <domain> top level element from the domain XML). *emulator* +specifies the path to the emulator, *arch* specifies the CPU architecture, and +*machine* specifies the machine type.
This is redundant IMHO, as domcapabilities already reports, along with info about the usability. $ virsh domcapabilities | xmllint -xpath "//cpu/mode[@name='custom']/model[@usable='yes']/text()" - | sort 486 Broadwell-noTSX Broadwell-noTSX-IBRS Conroe core2duo coreduo Haswell-noTSX Haswell-noTSX-IBRS IvyBridge IvyBridge-IBRS kvm32 kvm64 n270 Nehalem Nehalem-IBRS Opteron_G1 Opteron_G2 Penryn pentium pentium2 pentium3 qemu32 qemu64 SandyBridge SandyBridge-IBRS Skylake-Client-noTSX-IBRS Westmere Westmere-IBRS Admittedly xpath is hairy, but the same info could be got with grep+awk if desired. With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

On 3/22/23 4:53 PM, Daniel P. Berrangé wrote:
On Wed, Mar 22, 2023 at 11:39:17AM -0400, Collin Walling wrote:
This command is a virsh wrapper for virConnectGetHypervisorCPUNames.
Signed-off-by: Collin Walling <walling@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- docs/manpages/virsh.rst | 20 ++++++++++++ tools/virsh-host.c | 70 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst index 26c328d390..c156e60d6e 100644 --- a/docs/manpages/virsh.rst +++ b/docs/manpages/virsh.rst @@ -1004,6 +1004,26 @@ listed in the XML description. If *--migratable* is specified, features that block migration will not be included in the resulting CPU.
+hypervisor-cpu-models +--------------------- + +**Syntax:** + +:: + + hypervisor-cpu-models [virttype] [emulator] [arch] [machine] + +Print the list of CPU models known by the hypervisor for the specified architecture. +It is not guaranteed that a listed CPU will run on the host. To determine CPU +model compatibility with the host, see ``virsh hypervisor-cpu-baseline`` and +``virsh hypervisor-cpu-compare``. + +The *virttype* option specifies the virtualization type (usable in the 'type' +attribute of the <domain> top level element from the domain XML). *emulator* +specifies the path to the emulator, *arch* specifies the CPU architecture, and +*machine* specifies the machine type.
This is redundant IMHO, as domcapabilities already reports, along with info about the usability.
$ virsh domcapabilities | xmllint -xpath "//cpu/mode[@name='custom']/model[@usable='yes']/text()" - | sort 486 Broadwell-noTSX Broadwell-noTSX-IBRS Conroe core2duo coreduo Haswell-noTSX Haswell-noTSX-IBRS IvyBridge IvyBridge-IBRS kvm32 kvm64 n270 Nehalem Nehalem-IBRS Opteron_G1 Opteron_G2 Penryn pentium pentium2 pentium3 qemu32 qemu64 SandyBridge SandyBridge-IBRS Skylake-Client-noTSX-IBRS Westmere Westmere-IBRS
Admittedly xpath is hairy, but the same info could be got with grep+awk if desired.
With regards, Daniel
Isn't the redundancy already existing with "virsh cpu-models"? If users have to use the hypervisor-cpu-* calls and they have used the cpu-* calls before shouldn't the usability be about the same? -- Mit freundlichen Grüßen/Kind regards Boris Fiuczynski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Gregor Pillen Geschäftsführung: David Faller Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294

On Wed, Mar 22, 2023 at 05:13:06PM +0100, Boris Fiuczynski wrote:
On 3/22/23 4:53 PM, Daniel P. Berrangé wrote:
On Wed, Mar 22, 2023 at 11:39:17AM -0400, Collin Walling wrote:
This command is a virsh wrapper for virConnectGetHypervisorCPUNames.
Signed-off-by: Collin Walling <walling@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- docs/manpages/virsh.rst | 20 ++++++++++++ tools/virsh-host.c | 70 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst index 26c328d390..c156e60d6e 100644 --- a/docs/manpages/virsh.rst +++ b/docs/manpages/virsh.rst @@ -1004,6 +1004,26 @@ listed in the XML description. If *--migratable* is specified, features that block migration will not be included in the resulting CPU. +hypervisor-cpu-models +--------------------- + +**Syntax:** + +:: + + hypervisor-cpu-models [virttype] [emulator] [arch] [machine] + +Print the list of CPU models known by the hypervisor for the specified architecture. +It is not guaranteed that a listed CPU will run on the host. To determine CPU +model compatibility with the host, see ``virsh hypervisor-cpu-baseline`` and +``virsh hypervisor-cpu-compare``. + +The *virttype* option specifies the virtualization type (usable in the 'type' +attribute of the <domain> top level element from the domain XML). *emulator* +specifies the path to the emulator, *arch* specifies the CPU architecture, and +*machine* specifies the machine type.
This is redundant IMHO, as domcapabilities already reports, along with info about the usability.
$ virsh domcapabilities | xmllint -xpath "//cpu/mode[@name='custom']/model[@usable='yes']/text()" - | sort 486 Broadwell-noTSX Broadwell-noTSX-IBRS Conroe core2duo coreduo Haswell-noTSX Haswell-noTSX-IBRS IvyBridge IvyBridge-IBRS kvm32 kvm64 n270 Nehalem Nehalem-IBRS Opteron_G1 Opteron_G2 Penryn pentium pentium2 pentium3 qemu32 qemu64 SandyBridge SandyBridge-IBRS Skylake-Client-noTSX-IBRS Westmere Westmere-IBRS
Admittedly xpath is hairy, but the same info could be got with grep+awk if desired.
Isn't the redundancy already existing with "virsh cpu-models"? If users have to use the hypervisor-cpu-* calls and they have used the cpu-* calls before shouldn't the usability be about the same?
The 'cpu-models' commands came first, but its design was rather flawed. It just reported CPU models alone and could not reflect whether they were actually supportable by the hypervisor, and was not extensible to let us fix it. We had to abandon it and switch to the new approach based on domain capabilities which is extensible via the XML. Potentially we could have a virsh hypervisor-cpu-models command that queries the domain capabilities API, rather than adding a new API. With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

This function is hooked into the virsh hypervisor-cpu-models command. The CPU models are read directly from the QEMU capabilities file, which contains a list of all models queried from the hypervisor. Signed-off-by: Collin Walling <walling@linux.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/qemu/qemu_driver.c | 62 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 09ae893daf..e101da4d21 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12400,6 +12400,67 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn, } +static char * +qemuConnectGetHypervisorCPUModelNames(virConnectPtr conn, + const char *emulator, + const char *archStr, + const char *machine, + const char *virttypeStr, + unsigned int flags) +{ + virQEMUDriver *driver = conn->privateData; + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + g_autoptr(virDomainCapsCPUModels) cpuModels = NULL; + g_autoptr(virQEMUCaps) qemuCaps = NULL; + char *modelsstr = g_strdup(""); + virDomainVirtType virttype; + virArch arch; + size_t i; + + virCheckFlags(0, NULL); + + if (virConnectGetHypervisorCPUModelNamesEnsureACL(conn) < 0) + return NULL; + + qemuCaps = virQEMUCapsCacheLookupDefault(driver->qemuCapsCache, + emulator, + archStr, + virttypeStr, + machine, + &arch, &virttype, NULL); + if (!qemuCaps) + return NULL; + + if (!(cpuModels = virQEMUCapsGetCPUModels(qemuCaps, virttype, NULL, NULL)) || + cpuModels->nmodels == 0) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("QEMU '%s' does not support any CPU models for " + "virttype '%s'"), + virQEMUCapsGetBinary(qemuCaps), + virDomainVirtTypeToString(virttype)); + return NULL; + } + + for (i = 0; i < cpuModels->nmodels; i++) { + const char *name = cpuModels->models[i].name; + char *oldstr = modelsstr; + /* + * These models are not architecture-specific, but rather + * generic QEMU models, so let's filter them out + */ + if (STREQ(name, "host") || + STREQ(name, "qemu") || + STREQ(name, "max")) + continue; + + modelsstr = g_strdup_printf("%s\n%s", name, modelsstr); + g_free(oldstr); + } + + return modelsstr; +} + + static int qemuDomainGetJobInfoMigrationStats(virDomainObj *vm, virDomainJobData *jobData) @@ -20814,6 +20875,7 @@ static virHypervisorDriver qemuHypervisorDriver = { .domainSetLifecycleAction = qemuDomainSetLifecycleAction, /* 3.9.0 */ .connectCompareHypervisorCPU = qemuConnectCompareHypervisorCPU, /* 4.4.0 */ .connectBaselineHypervisorCPU = qemuConnectBaselineHypervisorCPU, /* 4.4.0 */ + .connectGetHypervisorCPUModelNames = qemuConnectGetHypervisorCPUModelNames, /* 9.2.0 */ .nodeGetSEVInfo = qemuNodeGetSEVInfo, /* 4.5.0 */ .domainGetLaunchSecurityInfo = qemuDomainGetLaunchSecurityInfo, /* 4.5.0 */ .domainCheckpointCreateXML = qemuDomainCheckpointCreateXML, /* 5.6.0 */ -- 2.39.0

On Wed, 2023-03-22 at 11:39 -0400, Collin Walling wrote:
Allows for the query of hypervisor-known CPU models via the simple command: virsh hypervisor-cpu-models. For the QEMU driver, the models are queried via the capabilities file. Each model is printed to the terminal on its own line similar to the cpu-models command, and there is no order to the listing.
The models "qemu", "host", and "max" have been excluded from this list since they are not architecture specific. The code can be easily modified to include them if desired.
Collin Walling (4): Introduce virConnectGetHypervisorCPUNames public API remote: Implement virConnectGetHypervisorCPUNames virsh: Introduce new hypervisor-cpu-models command qemu_driver: Implement qemuConnectGetHypervisorCPUNames
docs/manpages/virsh.rst | 20 ++++++++++ include/libvirt/libvirt-host.h | 6 +++ src/driver-hypervisor.h | 9 +++++ src/libvirt-host.c | 54 ++++++++++++++++++++++++++ src/libvirt_public.syms | 5 +++ src/qemu/qemu_driver.c | 62 ++++++++++++++++++++++++++++++ src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 20 +++++++++- src/remote_protocol-structs | 11 ++++++ tools/virsh-host.c | 70 ++++++++++++++++++++++++++++++++++ 10 files changed, 257 insertions(+), 1 deletion(-)
-- 2.39.0
Have a look at https://listman.redhat.com/archives/libvir-list/2022-June/232626.html You might be interested in the discussion we had there, about a very similar patch set. - Tim

On 3/22/23 1:00 PM, Tim Wiederhake wrote:
On Wed, 2023-03-22 at 11:39 -0400, Collin Walling wrote:
Allows for the query of hypervisor-known CPU models via the simple command: virsh hypervisor-cpu-models. For the QEMU driver, the models are queried via the capabilities file. Each model is printed to the terminal on its own line similar to the cpu-models command, and there is no order to the listing.
The models "qemu", "host", and "max" have been excluded from this list since they are not architecture specific. The code can be easily modified to include them if desired.
Collin Walling (4): Introduce virConnectGetHypervisorCPUNames public API remote: Implement virConnectGetHypervisorCPUNames virsh: Introduce new hypervisor-cpu-models command qemu_driver: Implement qemuConnectGetHypervisorCPUNames
docs/manpages/virsh.rst | 20 ++++++++++ include/libvirt/libvirt-host.h | 6 +++ src/driver-hypervisor.h | 9 +++++ src/libvirt-host.c | 54 ++++++++++++++++++++++++++ src/libvirt_public.syms | 5 +++ src/qemu/qemu_driver.c | 62 ++++++++++++++++++++++++++++++ src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 20 +++++++++- src/remote_protocol-structs | 11 ++++++ tools/virsh-host.c | 70 ++++++++++++++++++++++++++++++++++ 10 files changed, 257 insertions(+), 1 deletion(-)
-- 2.39.0
Have a look at https://listman.redhat.com/archives/libvir-list/2022-June/232626.html
You might be interested in the discussion we had there, about a very similar patch set.
- Tim
Forgive my ignorance here -- what was the result of the discussion from your patch set? The archives are not showing any responses on my end, but from what I see it accomplishes very much what we'd like to see from this command. -- Collin

On 3/22/23 2:11 PM, Collin Walling wrote:
On 3/22/23 1:00 PM, Tim Wiederhake wrote:
On Wed, 2023-03-22 at 11:39 -0400, Collin Walling wrote:
Allows for the query of hypervisor-known CPU models via the simple command: virsh hypervisor-cpu-models. For the QEMU driver, the models are queried via the capabilities file. Each model is printed to the terminal on its own line similar to the cpu-models command, and there is no order to the listing.
The models "qemu", "host", and "max" have been excluded from this list since they are not architecture specific. The code can be easily modified to include them if desired.
Collin Walling (4): Introduce virConnectGetHypervisorCPUNames public API remote: Implement virConnectGetHypervisorCPUNames virsh: Introduce new hypervisor-cpu-models command qemu_driver: Implement qemuConnectGetHypervisorCPUNames
docs/manpages/virsh.rst | 20 ++++++++++ include/libvirt/libvirt-host.h | 6 +++ src/driver-hypervisor.h | 9 +++++ src/libvirt-host.c | 54 ++++++++++++++++++++++++++ src/libvirt_public.syms | 5 +++ src/qemu/qemu_driver.c | 62 ++++++++++++++++++++++++++++++ src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 20 +++++++++- src/remote_protocol-structs | 11 ++++++ tools/virsh-host.c | 70 ++++++++++++++++++++++++++++++++++ 10 files changed, 257 insertions(+), 1 deletion(-)
-- 2.39.0
Have a look at https://listman.redhat.com/archives/libvir-list/2022-June/232626.html
You might be interested in the discussion we had there, about a very similar patch set.
- Tim
Forgive my ignorance here -- what was the result of the discussion from your patch set? The archives are not showing any responses on my end, but from what I see it accomplishes very much what we'd like to see from this command.
-- Collin
Polite ping. I know it's only been a few days, but I'd like to get involved with the proposed patches from earlier last year and want to make sure there isn't anything I may be missing from the discussion. And if I may ask: what is the proper etiquette for reviving an older thread on the mailing list? Thanks, -- Collin
participants (4)
-
Boris Fiuczynski
-
Collin Walling
-
Daniel P. Berrangé
-
Tim Wiederhake