[libvirt PATCH 00/16] expose tainting and deprecations in public API

Libvirt has a notion of "tainting" which we use to mark a guest which has some undesirable configuration or behaviour from libvirt's POV. This ends up in the libvirtd logs and in the per-VM log file, but is not exposed to management applications directly. QMP has the ability to report whether a CPU or machine type is deprecated. QEMU itself prints warnings to stderr which end up in the per VM log: 2021-01-22T12:22:53.566239Z qemu-system-x86_64: Machine type 'pc-1.3' is depr= ecated: use a newer machine type instead 2021-01-22T12:22:53.566613Z qemu-system-x86_64: warning: CPU model Icelake-Cl= ient-x86_64-cpu is deprecated -- use Icelake-Server instead We can use the deprecation info from QMP to add tainting to the domain too. This will appear in the pre-VM log file again: 2021-01-22 12:22:53.492+0000: Domain id=3D2 is tainted: deprecated-configurat= ion (machine type 'pc-1.3') 2021-01-22 12:22:53.492+0000: Domain id=3D2 is tainted: deprecated-configurat= ion (CPU model 'Icelake-Client') and more usefully in the libvirtd log 2021-01-22 13:18:09.619+0000: 3299849: warning : qemuDomainObjTaintMsg:6208 : Domain id=3D3 name=3D'demo' uuid=3Deadf8ef0-bf14-4c5f-9708-4a19bacf9e81 is tainted: deprecated-configuration (machine type 'pc-1.3') 2021-01-22 13:18:09.619+0000: 3299849: warning : qemuDomainObjTaintMsg:6208 : Domain id=3D3 name=3D'demo' uuid=3Deadf8ef0-bf14-4c5f-9708-4a19bacf9e81 is tainted: deprecated-configuration (CPU model 'Icelake-Client') This series goes further and also exposes the deprecation info in the capabilities (machine types) or domain capabilities (CPU) XML. This lets mgmt apps avoid using the feature upfront if desired. Finally both deprecation messages and tainting flags are exposed in new public APIs, and wired into virsh $ virsh dominfo demo Id: 3 Name: demo UUID: eadf8ef0-bf14-4c5f-9708-4a19bacf9e81 OS Type: hvm State: running CPU(s): 2 CPU time: 1.3s Max memory: 1536000 KiB Used memory: 1536000 KiB Persistent: yes Autostart: disable Managed save: no Security model: selinux Security DOI: 0 Security label: unconfined_u:unconfined_r:svirt_t:s0:c578,c807 (permissive) Tainting: custom-monitor deprecated-config Deprecations: CPU model 'Icelake-Client' machine type 'pc-1.3' The deprecations API is simple, just returning a list of free form opaque strings, which are eeffectively warning messages. I'm not entirely convinced by tainting API though. I didn't especially want to expose the virDomainTaintFlags enum in the public API since it feels like the enum flags are (almost) all QEMU driver specific. I thus took the approach of having an API return opaque strings which are declared to be hypervisor specific. I'm worried though that mgmt apps will none the less simply match on the strings to detect things, at which point we might as well just use an enum after all. So perhaps it should just be turned into virDomainGetTainting(virDomainPtr obj, int **codes, unsigned int flags); enum virDomainTaintCodes { .... } Daniel P. Berrang=C3=A9 (16): qemu: report whether a CPU model is deprecated in dom capabilities qemu: report whether a machine type is deprecated in capabilities conf: introduce new taint flag for deprecated configuration qemu: add ability to associate a string message with taint warning qemu: taint the VM if it is using a deprecated CPU model qemu: taint the VM if it is using a deprecated machine type conf: record deprecation messages against the domain qemu: record deprecation messages against the domain src: define virDomainGetDeprecations API remote: add RPC support for the virDomainGetDeprecations API qemu: implement virDomainGetDeprecations API tools: report deprecations for 'dominfo' command src: define virDomainGetTainting API remote: add RPC support for the virDomainGetTainting API qemu: implement virDomainGetTainting API tools: report tainting for 'dominfo' command docs/formatdomaincaps.html.in | 10 +- docs/schemas/capability.rng | 8 ++ docs/schemas/domaincaps.rng | 8 ++ include/libvirt/libvirt-domain.h | 7 ++ src/conf/capabilities.c | 2 + src/conf/capabilities.h | 1 + src/conf/domain_capabilities.c | 14 ++- src/conf/domain_capabilities.h | 4 +- src/conf/domain_conf.c | 29 ++++- src/conf/domain_conf.h | 5 + src/driver-hypervisor.h | 11 ++ src/libvirt-domain.c | 95 +++++++++++++++ src/libvirt_private.syms | 1 + src/libvirt_public.syms | 6 + src/qemu/qemu_capabilities.c | 60 +++++++++- src/qemu/qemu_capabilities.h | 6 + src/qemu/qemu_capspriv.h | 3 +- src/qemu/qemu_domain.c | 111 ++++++++++++++++-- src/qemu/qemu_domain.h | 7 ++ src/qemu/qemu_driver.c | 66 +++++++++++ src/qemu/qemu_monitor.c | 1 + src/qemu/qemu_monitor.h | 2 + src/qemu/qemu_monitor_json.c | 8 ++ src/qemu/qemu_process.c | 5 + src/remote/remote_daemon_dispatch.c | 91 ++++++++++++++ src/remote/remote_driver.c | 88 ++++++++++++++ src/remote/remote_protocol.x | 39 +++++- tests/cputest.c | 4 +- .../domaincapsdata/qemu_5.2.0-q35.x86_64.xml | 4 +- .../domaincapsdata/qemu_5.2.0-tcg.x86_64.xml | 4 +- tests/domaincapsdata/qemu_5.2.0.x86_64.xml | 4 +- .../caps_4.1.0.x86_64.xml | 16 +-- .../qemucapabilitiesdata/caps_4.2.0.ppc64.xml | 4 +- .../caps_4.2.0.x86_64.xml | 16 +-- .../caps_5.0.0.x86_64.xml | 16 +-- .../caps_5.1.0.x86_64.xml | 16 +-- .../caps_5.2.0.x86_64.xml | 32 ++--- tests/testutilsqemu.c | 8 +- tools/virsh-domain-monitor.c | 25 ++++ 39 files changed, 745 insertions(+), 92 deletions(-) --=20 2.29.2

QEMU has the ability to mark CPUs as deprecated. This should be exposed to management applications in the domain capabilities. This attribute is only set when the model is actually deprecated. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- docs/formatdomaincaps.html.in | 10 ++++++---- docs/schemas/domaincaps.rng | 8 ++++++++ src/conf/domain_capabilities.c | 14 ++++++++++---- src/conf/domain_capabilities.h | 4 +++- src/qemu/qemu_capabilities.c | 10 +++++++++- src/qemu/qemu_monitor.c | 1 + src/qemu/qemu_monitor.h | 1 + src/qemu/qemu_monitor_json.c | 4 ++++ tests/cputest.c | 4 ++-- tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml | 4 ++-- tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml | 4 ++-- tests/domaincapsdata/qemu_5.2.0.x86_64.xml | 4 ++-- tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml | 16 ++++++++-------- 13 files changed, 58 insertions(+), 26 deletions(-) diff --git a/docs/formatdomaincaps.html.in b/docs/formatdomaincaps.html.in index 65ab5574d3..8df88f5355 100644 --- a/docs/formatdomaincaps.html.in +++ b/docs/formatdomaincaps.html.in @@ -214,9 +214,9 @@ <feature policy='require' name='vmx'/> </mode> <mode name='custom' supported='yes'> - <model usable='no'>Broadwell</model> - <model usable='yes'>Broadwell-noTSX</model> - <model usable='no'>Haswell</model> + <model usable='no' deprecated='no'>Broadwell</model> + <model usable='yes' deprecated='no'>Broadwell-noTSX</model> + <model usable='no' deprecated='yes'>Haswell</model> ... </mode> </cpu> @@ -262,7 +262,9 @@ cannot be used without disabling some features that the CPU of such model is expected to have. A special value <code>unknown</code> indicates libvirt does not have enough information to provide the - usability data. + usability data. The <code>deprecated</code> attribute reflects + the hypervisor's policy on usage of this model + <span class="since">(since 7.1.0)</span>. </dd> </dl> diff --git a/docs/schemas/domaincaps.rng b/docs/schemas/domaincaps.rng index 0dbffb28ac..a57ef715c3 100644 --- a/docs/schemas/domaincaps.rng +++ b/docs/schemas/domaincaps.rng @@ -138,6 +138,14 @@ <value>unknown</value> </choice> </attribute> + <optional> + <attribute name="deprecated"> + <choice> + <value>yes</value> + <value>no</value> + </choice> + </attribute> + </optional> <text/> </element> </zeroOrMore> diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c index 8130311590..cdb1b31af6 100644 --- a/src/conf/domain_capabilities.c +++ b/src/conf/domain_capabilities.c @@ -175,7 +175,8 @@ virDomainCapsCPUModelsCopy(virDomainCapsCPUModelsPtr old) if (virDomainCapsCPUModelsAdd(cpuModels, old->models[i].name, old->models[i].usable, - old->models[i].blockers) < 0) + old->models[i].blockers, + old->models[i].deprecated) < 0) goto error; } @@ -191,7 +192,8 @@ int virDomainCapsCPUModelsAdd(virDomainCapsCPUModelsPtr cpuModels, const char *name, virDomainCapsCPUUsable usable, - char **blockers) + char **blockers, + bool deprecated) { g_autofree char * nameCopy = NULL; virDomainCapsCPUModelPtr cpu; @@ -208,6 +210,7 @@ virDomainCapsCPUModelsAdd(virDomainCapsCPUModelsPtr cpuModels, cpu->usable = usable; cpu->name = g_steal_pointer(&nameCopy); cpu->blockers = g_strdupv(blockers); + cpu->deprecated = deprecated; return 0; } @@ -388,8 +391,11 @@ virDomainCapsCPUCustomFormat(virBufferPtr buf, for (i = 0; i < custom->nmodels; i++) { virDomainCapsCPUModelPtr model = custom->models + i; - virBufferAsprintf(buf, "<model usable='%s'>%s</model>\n", - virDomainCapsCPUUsableTypeToString(model->usable), + virBufferAsprintf(buf, "<model usable='%s'", + virDomainCapsCPUUsableTypeToString(model->usable)); + if (model->deprecated) + virBufferAddLit(buf, " deprecated='yes'"); + virBufferAsprintf(buf, ">%s</model>\n", model->name); } diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h index b22d40abb2..f454780185 100644 --- a/src/conf/domain_capabilities.h +++ b/src/conf/domain_capabilities.h @@ -146,6 +146,7 @@ struct _virDomainCapsCPUModel { char *name; virDomainCapsCPUUsable usable; char **blockers; /* NULL-terminated list of usability blockers */ + bool deprecated; }; typedef struct _virDomainCapsCPUModels virDomainCapsCPUModels; @@ -228,7 +229,8 @@ virDomainCapsCPUModelsPtr virDomainCapsCPUModelsCopy(virDomainCapsCPUModelsPtr o int virDomainCapsCPUModelsAdd(virDomainCapsCPUModelsPtr cpuModels, const char *name, virDomainCapsCPUUsable usable, - char **blockers); + char **blockers, + bool deprecated); virDomainCapsCPUModelPtr virDomainCapsCPUModelsGet(virDomainCapsCPUModelsPtr cpuModels, const char *name); diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index d656732c3e..61467eb6c2 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -2176,7 +2176,7 @@ virQEMUCapsCPUDefsToModels(qemuMonitorCPUDefsPtr defs, continue; if (virDomainCapsCPUModelsAdd(cpuModels, cpu->name, cpu->usable, - cpu->blockers) < 0) + cpu->blockers, cpu->deprecated) < 0) return NULL; } @@ -3896,6 +3896,7 @@ virQEMUCapsLoadCPUModels(virQEMUCapsAccelPtr caps, int usable = VIR_DOMCAPS_CPU_USABLE_UNKNOWN; g_autofree char * strUsable = NULL; g_autofree xmlNodePtr * blockerNodes = NULL; + g_autofree char *deprecated = NULL; int nblockers; if ((strUsable = virXMLPropString(nodes[i], "usable")) && @@ -3940,6 +3941,11 @@ virQEMUCapsLoadCPUModels(virQEMUCapsAccelPtr caps, } } } + + deprecated = virXMLPropString(nodes[i], "deprecated"); + if (deprecated && + STREQ(deprecated, "yes")) + cpu->deprecated = true; } caps->cpuModels = g_steal_pointer(&defs); @@ -4448,6 +4454,8 @@ virQEMUCapsFormatCPUModels(virQEMUCapsAccelPtr caps, virBufferAsprintf(buf, " usable='%s'", virDomainCapsCPUUsableTypeToString(cpu->usable)); } + if (cpu->deprecated) + virBufferAddLit(buf, " deprecated='yes'"); if (cpu->blockers) { size_t j; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 09b8617097..990519252e 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3673,6 +3673,7 @@ qemuMonitorCPUDefsCopy(qemuMonitorCPUDefsPtr src) cpuDst->name = g_strdup(cpuSrc->name); cpuDst->type = g_strdup(cpuSrc->type); cpuDst->blockers = g_strdupv(cpuSrc->blockers); + cpuDst->deprecated = cpuSrc->deprecated; } return g_steal_pointer(&defs); diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index a07617ec28..67f149ebde 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -1193,6 +1193,7 @@ struct _qemuMonitorCPUDefInfo { char *name; char *type; char **blockers; /* NULL-terminated string list */ + bool deprecated; }; typedef struct _qemuMonitorCPUDefs qemuMonitorCPUDefs; diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 8a75a2734e..6534878d45 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -5896,6 +5896,10 @@ qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon, cpu->usable = VIR_DOMCAPS_CPU_USABLE_NO; } + + if (virJSONValueObjectHasKey(child, "deprecated") && + virJSONValueObjectGetBoolean(child, "deprecated", &cpu->deprecated) < 0) + return -1; } *cpuDefs = g_steal_pointer(&defs); diff --git a/tests/cputest.c b/tests/cputest.c index 4c75ee535f..593861dfe9 100644 --- a/tests/cputest.c +++ b/tests/cputest.c @@ -846,7 +846,7 @@ cpuTestUpdateLive(const void *arg) } if (virDomainCapsCPUModelsAdd(models, expected->model, - usable, blockers) < 0) + usable, blockers, false) < 0) goto cleanup; cpu->fallback = VIR_CPU_FALLBACK_ALLOW; @@ -953,7 +953,7 @@ cpuTestInitModels(const char **list) for (model = list; *model; model++) { if (virDomainCapsCPUModelsAdd(cpus, *model, - VIR_DOMCAPS_CPU_USABLE_UNKNOWN, NULL) < 0) + VIR_DOMCAPS_CPU_USABLE_UNKNOWN, NULL, false) < 0) goto error; } diff --git a/tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml index 7111bdf2c5..5a5232751d 100644 --- a/tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml @@ -91,8 +91,8 @@ <model usable='no'>IvyBridge</model> <model usable='no'>Icelake-Server-noTSX</model> <model usable='no'>Icelake-Server</model> - <model usable='no'>Icelake-Client-noTSX</model> - <model usable='no'>Icelake-Client</model> + <model usable='no' deprecated='yes'>Icelake-Client-noTSX</model> + <model usable='no' deprecated='yes'>Icelake-Client</model> <model usable='no'>Haswell-noTSX-IBRS</model> <model usable='no'>Haswell-noTSX</model> <model usable='no'>Haswell-IBRS</model> diff --git a/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml index 9d2e870b1c..63546dc0a5 100644 --- a/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml @@ -96,8 +96,8 @@ <model usable='no'>IvyBridge</model> <model usable='no'>Icelake-Server-noTSX</model> <model usable='no'>Icelake-Server</model> - <model usable='no'>Icelake-Client-noTSX</model> - <model usable='no'>Icelake-Client</model> + <model usable='no' deprecated='yes'>Icelake-Client-noTSX</model> + <model usable='no' deprecated='yes'>Icelake-Client</model> <model usable='no'>Haswell-noTSX-IBRS</model> <model usable='no'>Haswell-noTSX</model> <model usable='no'>Haswell-IBRS</model> diff --git a/tests/domaincapsdata/qemu_5.2.0.x86_64.xml b/tests/domaincapsdata/qemu_5.2.0.x86_64.xml index d8113c4e92..efc21244b3 100644 --- a/tests/domaincapsdata/qemu_5.2.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.2.0.x86_64.xml @@ -90,8 +90,8 @@ <model usable='no'>IvyBridge</model> <model usable='no'>Icelake-Server-noTSX</model> <model usable='no'>Icelake-Server</model> - <model usable='no'>Icelake-Client-noTSX</model> - <model usable='no'>Icelake-Client</model> + <model usable='no' deprecated='yes'>Icelake-Client-noTSX</model> + <model usable='no' deprecated='yes'>Icelake-Client</model> <model usable='no'>Haswell-noTSX-IBRS</model> <model usable='no'>Haswell-noTSX</model> <model usable='no'>Haswell-IBRS</model> diff --git a/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml index dea2ff4b54..7f15bcda09 100644 --- a/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml @@ -1055,7 +1055,7 @@ <blocker name='avx512f'/> <blocker name='pku'/> </cpu> - <cpu type='kvm' name='Icelake-Client-v2' typename='Icelake-Client-v2-x86_64-cpu' usable='no'> + <cpu type='kvm' name='Icelake-Client-v2' typename='Icelake-Client-v2-x86_64-cpu' usable='no' deprecated='yes'> <blocker name='pcid'/> <blocker name='erms'/> <blocker name='invpcid'/> @@ -1071,7 +1071,7 @@ <blocker name='spec-ctrl'/> <blocker name='pku'/> </cpu> - <cpu type='kvm' name='Icelake-Client-v1' typename='Icelake-Client-v1-x86_64-cpu' usable='no'> + <cpu type='kvm' name='Icelake-Client-v1' typename='Icelake-Client-v1-x86_64-cpu' usable='no' deprecated='yes'> <blocker name='pcid'/> <blocker name='hle'/> <blocker name='erms'/> @@ -1089,7 +1089,7 @@ <blocker name='spec-ctrl'/> <blocker name='pku'/> </cpu> - <cpu type='kvm' name='Icelake-Client-noTSX' typename='Icelake-Client-noTSX-x86_64-cpu' usable='no'> + <cpu type='kvm' name='Icelake-Client-noTSX' typename='Icelake-Client-noTSX-x86_64-cpu' usable='no' deprecated='yes'> <blocker name='pcid'/> <blocker name='erms'/> <blocker name='invpcid'/> @@ -1105,7 +1105,7 @@ <blocker name='spec-ctrl'/> <blocker name='pku'/> </cpu> - <cpu type='kvm' name='Icelake-Client' typename='Icelake-Client-x86_64-cpu' usable='no'> + <cpu type='kvm' name='Icelake-Client' typename='Icelake-Client-x86_64-cpu' usable='no' deprecated='yes'> <blocker name='pcid'/> <blocker name='hle'/> <blocker name='erms'/> @@ -2429,7 +2429,7 @@ <blocker name='wbnoinvd'/> <blocker name='xsavec'/> </cpu> - <cpu type='tcg' name='Icelake-Client-v2' typename='Icelake-Client-v2-x86_64-cpu' usable='no'> + <cpu type='tcg' name='Icelake-Client-v2' typename='Icelake-Client-v2-x86_64-cpu' usable='no' deprecated='yes'> <blocker name='fma'/> <blocker name='pcid'/> <blocker name='x2apic'/> @@ -2454,7 +2454,7 @@ <blocker name='wbnoinvd'/> <blocker name='xsavec'/> </cpu> - <cpu type='tcg' name='Icelake-Client-v1' typename='Icelake-Client-v1-x86_64-cpu' usable='no'> + <cpu type='tcg' name='Icelake-Client-v1' typename='Icelake-Client-v1-x86_64-cpu' usable='no' deprecated='yes'> <blocker name='fma'/> <blocker name='pcid'/> <blocker name='x2apic'/> @@ -2481,7 +2481,7 @@ <blocker name='wbnoinvd'/> <blocker name='xsavec'/> </cpu> - <cpu type='tcg' name='Icelake-Client-noTSX' typename='Icelake-Client-noTSX-x86_64-cpu' usable='no'> + <cpu type='tcg' name='Icelake-Client-noTSX' typename='Icelake-Client-noTSX-x86_64-cpu' usable='no' deprecated='yes'> <blocker name='fma'/> <blocker name='pcid'/> <blocker name='x2apic'/> @@ -2506,7 +2506,7 @@ <blocker name='wbnoinvd'/> <blocker name='xsavec'/> </cpu> - <cpu type='tcg' name='Icelake-Client' typename='Icelake-Client-x86_64-cpu' usable='no'> + <cpu type='tcg' name='Icelake-Client' typename='Icelake-Client-x86_64-cpu' usable='no' deprecated='yes'> <blocker name='fma'/> <blocker name='pcid'/> <blocker name='x2apic'/> -- 2.29.2

On a Friday in 2021, Daniel P. Berrangé wrote:
QEMU has the ability to mark CPUs as deprecated. This should be exposed to management applications in the domain capabilities.
This attribute is only set when the model is actually deprecated.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- docs/formatdomaincaps.html.in | 10 ++++++---- docs/schemas/domaincaps.rng | 8 ++++++++ src/conf/domain_capabilities.c | 14 ++++++++++---- src/conf/domain_capabilities.h | 4 +++- src/qemu/qemu_capabilities.c | 10 +++++++++- src/qemu/qemu_monitor.c | 1 + src/qemu/qemu_monitor.h | 1 + src/qemu/qemu_monitor_json.c | 4 ++++ tests/cputest.c | 4 ++-- tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml | 4 ++-- tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml | 4 ++-- tests/domaincapsdata/qemu_5.2.0.x86_64.xml | 4 ++-- tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml | 16 ++++++++-------- 13 files changed, 58 insertions(+), 26 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

QEMU has the ability to mark machine types as deprecated. This should be exposed to management applications in the capabilities. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- docs/schemas/capability.rng | 8 ++++++++ src/conf/capabilities.c | 2 ++ src/conf/capabilities.h | 1 + src/qemu/qemu_capabilities.c | 17 ++++++++++++++--- src/qemu/qemu_capspriv.h | 3 ++- src/qemu/qemu_monitor.h | 1 + src/qemu/qemu_monitor_json.c | 4 ++++ .../qemucapabilitiesdata/caps_4.1.0.x86_64.xml | 16 ++++++++-------- tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml | 4 ++-- .../qemucapabilitiesdata/caps_4.2.0.x86_64.xml | 16 ++++++++-------- .../qemucapabilitiesdata/caps_5.0.0.x86_64.xml | 16 ++++++++-------- .../qemucapabilitiesdata/caps_5.1.0.x86_64.xml | 16 ++++++++-------- .../qemucapabilitiesdata/caps_5.2.0.x86_64.xml | 16 ++++++++-------- tests/testutilsqemu.c | 8 +++++--- 14 files changed, 79 insertions(+), 49 deletions(-) diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng index 91a046eb48..c4cafc47ee 100644 --- a/docs/schemas/capability.rng +++ b/docs/schemas/capability.rng @@ -407,6 +407,14 @@ <ref name="unsignedInt"/> </attribute> </optional> + <optional> + <attribute name="deprecated"> + <choice> + <value>yes</value> + <value>no</value> + </choice> + </attribute> + </optional> <text/> </element> </define> diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c index 425f34113a..1ea059ea6f 100644 --- a/src/conf/capabilities.c +++ b/src/conf/capabilities.c @@ -1244,6 +1244,8 @@ virCapabilitiesFormatGuestXML(virCapsGuestPtr *guests, virBufferAsprintf(buf, " canonical='%s'", machine->canonical); if (machine->maxCpus > 0) virBufferAsprintf(buf, " maxCpus='%d'", machine->maxCpus); + if (machine->deprecated) + virBufferAddLit(buf, " deprecated='yes'"); virBufferAsprintf(buf, ">%s</machine>\n", machine->name); } diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h index e2581fac8b..5fd59efc05 100644 --- a/src/conf/capabilities.h +++ b/src/conf/capabilities.h @@ -56,6 +56,7 @@ struct _virCapsGuestMachine { char *name; char *canonical; unsigned int maxCpus; + bool deprecated; }; struct _virCapsGuestDomainInfo { diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 61467eb6c2..e3d1de0779 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -624,6 +624,7 @@ struct _virQEMUCapsMachineType { char *defaultCPU; bool numaMemSupported; char *defaultRAMid; + bool deprecated; }; typedef struct _virQEMUCapsHostCPUData virQEMUCapsHostCPUData; @@ -943,6 +944,7 @@ virQEMUCapsGetMachineTypesCaps(virQEMUCapsPtr qemuCaps, mach->name = g_strdup(accel->machineTypes[i].name); } mach->maxCpus = accel->machineTypes[i].maxCpus; + mach->deprecated = accel->machineTypes[i].deprecated; } /* Make sure all canonical machine types also have their own entry so that @@ -976,6 +978,7 @@ virQEMUCapsGetMachineTypesCaps(virQEMUCapsPtr qemuCaps, } mach->name = g_strdup(machine->canonical); mach->maxCpus = machine->maxCpus; + mach->deprecated = machine->deprecated; i++; } i++; @@ -1874,6 +1877,7 @@ virQEMUCapsAccelCopyMachineTypes(virQEMUCapsAccelPtr dst, dst->machineTypes[i].qemuDefault = src->machineTypes[i].qemuDefault; dst->machineTypes[i].numaMemSupported = src->machineTypes[i].numaMemSupported; dst->machineTypes[i].defaultRAMid = g_strdup(src->machineTypes[i].defaultRAMid); + dst->machineTypes[i].deprecated = src->machineTypes[i].deprecated; } } @@ -2708,7 +2712,8 @@ virQEMUCapsAddMachine(virQEMUCapsPtr qemuCaps, bool hotplugCpus, bool isDefault, bool numaMemSupported, - const char *defaultRAMid) + const char *defaultRAMid, + bool deprecated) { virQEMUCapsAccelPtr accel = virQEMUCapsGetAccel(qemuCaps, virtType); virQEMUCapsMachineTypePtr mach; @@ -2731,6 +2736,7 @@ virQEMUCapsAddMachine(virQEMUCapsPtr qemuCaps, mach->numaMemSupported = numaMemSupported; mach->defaultRAMid = g_strdup(defaultRAMid); + mach->deprecated = deprecated; } /** @@ -2778,7 +2784,8 @@ virQEMUCapsProbeQMPMachineTypes(virQEMUCapsPtr qemuCaps, machines[i]->hotplugCpus, machines[i]->isDefault, machines[i]->numaMemSupported, - machines[i]->defaultRAMid); + machines[i]->defaultRAMid, + machines[i]->deprecated); if (preferredMachine && (STREQ_NULLABLE(machines[i]->alias, preferredMachine) || @@ -4010,6 +4017,7 @@ virQEMUCapsLoadMachines(virQEMUCapsAccelPtr caps, caps->machineTypes[i].defaultCPU = virXMLPropString(nodes[i], "defaultCPU"); caps->machineTypes[i].defaultRAMid = virXMLPropString(nodes[i], "defaultRAMid"); + caps->machineTypes[i].deprecated = virXMLPropString(nodes[i], "deprecated"); } return 0; @@ -4500,6 +4508,8 @@ virQEMUCapsFormatMachines(virQEMUCapsAccelPtr caps, virBufferAddLit(buf, " numaMemSupported='yes'"); virBufferEscapeString(buf, " defaultRAMid='%s'", caps->machineTypes[i].defaultRAMid); + if (caps->machineTypes[i].deprecated) + virBufferAddLit(buf, " deprecated='yes'"); virBufferAddLit(buf, "/>\n"); } } @@ -6324,7 +6334,8 @@ virQEMUCapsStripMachineAliasesForVirtType(virQEMUCapsPtr qemuCaps, if (name) { virQEMUCapsAddMachine(qemuCaps, virtType, name, NULL, mach->defaultCPU, mach->maxCpus, mach->hotplugCpus, mach->qemuDefault, - mach->numaMemSupported, mach->defaultRAMid); + mach->numaMemSupported, mach->defaultRAMid, + mach->deprecated); } } } diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h index 15fc79e88b..90ce35fa5d 100644 --- a/src/qemu/qemu_capspriv.h +++ b/src/qemu/qemu_capspriv.h @@ -120,4 +120,5 @@ virQEMUCapsAddMachine(virQEMUCapsPtr qemuCaps, bool hotplugCpus, bool isDefault, bool numaMemSupported, - const char *defaultRAMid); + const char *defaultRAMid, + bool deprecated); diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 67f149ebde..b0068f2a82 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -1178,6 +1178,7 @@ struct _qemuMonitorMachineInfo { char *defaultCPU; bool numaMemSupported; char *defaultRAMid; + bool deprecated; }; int qemuMonitorGetMachines(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 6534878d45..97c5e5b36c 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -5814,6 +5814,10 @@ int qemuMonitorJSONGetMachines(qemuMonitorPtr mon, info->defaultRAMid = g_strdup(tmp); } + + if (virJSONValueObjectHasKey(child, "deprecated") && + virJSONValueObjectGetBoolean(child, "deprecated", &info->deprecated) < 0) + goto cleanup; } ret = n; diff --git a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml index 28a4b0ede0..b4f2092e7a 100644 --- a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml @@ -859,20 +859,20 @@ <cpu type='kvm' name='486-v1' typename='486-v1-x86_64-cpu' usable='yes'/> <cpu type='kvm' name='486' typename='486-x86_64-cpu' usable='yes'/> <machine type='kvm' name='pc-i440fx-4.1' alias='pc' hotplugCpus='yes' maxCpus='255' default='yes' numaMemSupported='yes'/> - <machine type='kvm' name='pc-0.15' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> + <machine type='kvm' name='pc-0.15' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes' deprecated='yes'/> <machine type='kvm' name='pc-i440fx-2.12' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.0' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.5' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-1.5' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-2.7' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> - <machine type='kvm' name='pc-0.12' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> + <machine type='kvm' name='pc-0.12' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes' deprecated='yes'/> <machine type='kvm' name='pc-i440fx-2.2' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='kvm' name='pc-1.1' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.7' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-2.4' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-2.10' hotplugCpus='yes' maxCpus='288' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-1.7' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> - <machine type='kvm' name='pc-0.14' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> + <machine type='kvm' name='pc-0.14' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes' deprecated='yes'/> <machine type='kvm' name='pc-q35-2.9' hotplugCpus='yes' maxCpus='288' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.11' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-3.1' hotplugCpus='yes' maxCpus='288' numaMemSupported='yes'/> @@ -890,7 +890,7 @@ <machine type='kvm' name='pc-i440fx-2.6' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-4.0.1' hotplugCpus='yes' maxCpus='288' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-1.6' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> - <machine type='kvm' name='pc-0.13' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> + <machine type='kvm' name='pc-0.13' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes' deprecated='yes'/> <machine type='kvm' name='pc-q35-2.8' hotplugCpus='yes' maxCpus='288' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.10' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-3.0' hotplugCpus='yes' maxCpus='288' numaMemSupported='yes'/> @@ -1963,20 +1963,20 @@ <cpu type='tcg' name='486-v1' typename='486-v1-x86_64-cpu' usable='yes'/> <cpu type='tcg' name='486' typename='486-x86_64-cpu' usable='yes'/> <machine type='tcg' name='pc-i440fx-4.1' alias='pc' hotplugCpus='yes' maxCpus='255' default='yes' numaMemSupported='yes'/> - <machine type='tcg' name='pc-0.15' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> + <machine type='tcg' name='pc-0.15' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes' deprecated='yes'/> <machine type='tcg' name='pc-i440fx-2.12' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.0' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.5' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-1.5' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-2.7' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> - <machine type='tcg' name='pc-0.12' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> + <machine type='tcg' name='pc-0.12' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes' deprecated='yes'/> <machine type='tcg' name='pc-i440fx-2.2' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='tcg' name='pc-1.1' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.7' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-2.4' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-2.10' hotplugCpus='yes' maxCpus='288' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-1.7' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> - <machine type='tcg' name='pc-0.14' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> + <machine type='tcg' name='pc-0.14' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes' deprecated='yes'/> <machine type='tcg' name='pc-q35-2.9' hotplugCpus='yes' maxCpus='288' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.11' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-3.1' hotplugCpus='yes' maxCpus='288' numaMemSupported='yes'/> @@ -1994,7 +1994,7 @@ <machine type='tcg' name='pc-i440fx-2.6' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-4.0.1' hotplugCpus='yes' maxCpus='288' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-1.6' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> - <machine type='tcg' name='pc-0.13' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> + <machine type='tcg' name='pc-0.13' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes' deprecated='yes'/> <machine type='tcg' name='pc-q35-2.8' hotplugCpus='yes' maxCpus='288' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.10' hotplugCpus='yes' maxCpus='255' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-3.0' hotplugCpus='yes' maxCpus='288' numaMemSupported='yes'/> diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml index 15eaac77a6..c6c05c5383 100644 --- a/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml +++ b/tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml @@ -649,7 +649,7 @@ <machine type='kvm' name='g3beige' maxCpus='1' defaultCPU='750_v3.1-powerpc64-cpu'/> <machine type='kvm' name='pseries-3.0' hotplugCpus='yes' maxCpus='1024' defaultCPU='host-powerpc64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pseries-2.10' hotplugCpus='yes' maxCpus='1024' defaultCPU='host-powerpc64-cpu' numaMemSupported='yes'/> - <machine type='kvm' name='prep' maxCpus='1' defaultCPU='602-powerpc64-cpu'/> + <machine type='kvm' name='prep' maxCpus='1' defaultCPU='602-powerpc64-cpu' deprecated='yes'/> <machine type='kvm' name='pseries-2.11' hotplugCpus='yes' maxCpus='1024' defaultCPU='host-powerpc64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pseries-2.12' hotplugCpus='yes' maxCpus='1024' defaultCPU='host-powerpc64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pseries-2.9' hotplugCpus='yes' maxCpus='1024' defaultCPU='host-powerpc64-cpu' numaMemSupported='yes'/> @@ -1117,7 +1117,7 @@ <machine type='tcg' name='g3beige' maxCpus='1' defaultCPU='750_v3.1-powerpc64-cpu'/> <machine type='tcg' name='pseries-3.0' hotplugCpus='yes' maxCpus='1024' defaultCPU='power8_v2.0-powerpc64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pseries-2.10' hotplugCpus='yes' maxCpus='1024' defaultCPU='power8_v2.0-powerpc64-cpu' numaMemSupported='yes'/> - <machine type='tcg' name='prep' maxCpus='1' defaultCPU='602-powerpc64-cpu'/> + <machine type='tcg' name='prep' maxCpus='1' defaultCPU='602-powerpc64-cpu' deprecated='yes'/> <machine type='tcg' name='pseries-2.11' hotplugCpus='yes' maxCpus='1024' defaultCPU='power8_v2.0-powerpc64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pseries-2.12' hotplugCpus='yes' maxCpus='1024' defaultCPU='power8_v2.0-powerpc64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pseries-2.9' hotplugCpus='yes' maxCpus='1024' defaultCPU='power8_v2.0-powerpc64-cpu' numaMemSupported='yes'/> diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml index e150741f11..836255f80b 100644 --- a/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml @@ -1114,13 +1114,13 @@ <cpu type='kvm' name='486-v1' typename='486-v1-x86_64-cpu' usable='yes'/> <cpu type='kvm' name='486' typename='486-x86_64-cpu' usable='yes'/> <machine type='kvm' name='pc-i440fx-4.2' alias='pc' hotplugCpus='yes' maxCpus='255' default='yes' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='kvm' name='pc-0.15' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='kvm' name='pc-0.15' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='kvm' name='pc-i440fx-2.12' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-4.2' alias='q35' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.5' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-1.5' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='kvm' name='pc-0.12' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='kvm' name='pc-0.12' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='kvm' name='pc-q35-2.7' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-1.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> @@ -1128,7 +1128,7 @@ <machine type='kvm' name='pc-q35-2.4' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-2.10' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-1.7' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='kvm' name='pc-0.14' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='kvm' name='pc-0.14' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='kvm' name='pc-q35-2.9' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.11' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-3.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> @@ -1147,7 +1147,7 @@ <machine type='kvm' name='pc-i440fx-2.6' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-4.0.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-1.6' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='kvm' name='pc-0.13' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='kvm' name='pc-0.13' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='kvm' name='pc-q35-2.8' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.10' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-3.0' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> @@ -2577,13 +2577,13 @@ <cpu type='tcg' name='486-v1' typename='486-v1-x86_64-cpu' usable='yes'/> <cpu type='tcg' name='486' typename='486-x86_64-cpu' usable='yes'/> <machine type='tcg' name='pc-i440fx-4.2' alias='pc' hotplugCpus='yes' maxCpus='255' default='yes' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='tcg' name='pc-0.15' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='tcg' name='pc-0.15' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='tcg' name='pc-i440fx-2.12' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-4.2' alias='q35' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.5' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-1.5' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='tcg' name='pc-0.12' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='tcg' name='pc-0.12' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='tcg' name='pc-q35-2.7' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-1.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> @@ -2591,7 +2591,7 @@ <machine type='tcg' name='pc-q35-2.4' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-2.10' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-1.7' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='tcg' name='pc-0.14' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='tcg' name='pc-0.14' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='tcg' name='pc-q35-2.9' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.11' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-3.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> @@ -2610,7 +2610,7 @@ <machine type='tcg' name='pc-i440fx-2.6' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-4.0.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-1.6' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='tcg' name='pc-0.13' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='tcg' name='pc-0.13' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='tcg' name='pc-q35-2.8' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.10' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-3.0' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml index 7c56d110f4..c6dcbf1329 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml @@ -1248,7 +1248,7 @@ <machine type='kvm' name='pc-i440fx-1.5' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-2.7' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='kvm' name='pc-1.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='kvm' name='pc-1.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='kvm' name='pc-i440fx-2.7' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-2.4' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-2.10' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> @@ -1258,7 +1258,7 @@ <machine type='kvm' name='pc-q35-3.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-4.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.4' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='kvm' name='pc-1.3' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='kvm' name='pc-1.3' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='kvm' name='pc-i440fx-4.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.9' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='isapc' hotplugCpus='yes' maxCpus='1' defaultCPU='486-x86_64-cpu' numaMemSupported='yes'/> @@ -1267,7 +1267,7 @@ <machine type='kvm' name='pc-i440fx-3.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-2.12' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='kvm' name='pc-1.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='kvm' name='pc-1.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='kvm' name='pc-i440fx-2.6' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-4.0.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-1.6' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> @@ -1278,7 +1278,7 @@ <machine type='kvm' name='pc-q35-4.0' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='microvm' maxCpus='288' defaultCPU='qemu64-x86_64-cpu'/> <machine type='kvm' name='pc-i440fx-2.3' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='kvm' name='pc-1.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='kvm' name='pc-1.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='kvm' name='pc-i440fx-4.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.8' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-2.5' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> @@ -2890,7 +2890,7 @@ <machine type='tcg' name='pc-i440fx-1.5' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-2.7' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='tcg' name='pc-1.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='tcg' name='pc-1.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='tcg' name='pc-i440fx-2.7' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-2.4' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-2.10' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> @@ -2900,7 +2900,7 @@ <machine type='tcg' name='pc-q35-3.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-4.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.4' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='tcg' name='pc-1.3' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='tcg' name='pc-1.3' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='tcg' name='pc-i440fx-4.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.9' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='isapc' hotplugCpus='yes' maxCpus='1' defaultCPU='486-x86_64-cpu' numaMemSupported='yes'/> @@ -2909,7 +2909,7 @@ <machine type='tcg' name='pc-i440fx-3.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-2.12' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='tcg' name='pc-1.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='tcg' name='pc-1.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='tcg' name='pc-i440fx-2.6' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-4.0.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-1.6' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> @@ -2920,7 +2920,7 @@ <machine type='tcg' name='pc-q35-4.0' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='microvm' maxCpus='288' defaultCPU='qemu64-x86_64-cpu'/> <machine type='tcg' name='pc-i440fx-2.3' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='tcg' name='pc-1.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='tcg' name='pc-1.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='tcg' name='pc-i440fx-4.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.8' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-2.5' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> diff --git a/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml index 07466093c9..cded14a96a 100644 --- a/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml @@ -1421,7 +1421,7 @@ <machine type='kvm' name='pc-i440fx-1.5' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-2.7' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='kvm' name='pc-1.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='kvm' name='pc-1.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='kvm' name='pc-i440fx-2.7' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-2.4' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-2.10' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> @@ -1432,7 +1432,7 @@ <machine type='kvm' name='pc-q35-3.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-4.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.4' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='kvm' name='pc-1.3' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='kvm' name='pc-1.3' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='kvm' name='pc-i440fx-4.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.9' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='isapc' hotplugCpus='yes' maxCpus='1' defaultCPU='486-x86_64-cpu'/> @@ -1441,7 +1441,7 @@ <machine type='kvm' name='pc-i440fx-3.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-2.12' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='kvm' name='pc-1.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='kvm' name='pc-1.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='kvm' name='pc-i440fx-2.6' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-q35-4.0.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-1.6' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> @@ -1452,7 +1452,7 @@ <machine type='kvm' name='pc-q35-4.0' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='microvm' maxCpus='288' defaultCPU='qemu64-x86_64-cpu'/> <machine type='kvm' name='pc-i440fx-2.3' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='kvm' name='pc-1.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='kvm' name='pc-1.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='kvm' name='pc-i440fx-4.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-5.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='kvm' name='pc-i440fx-2.8' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> @@ -3156,7 +3156,7 @@ <machine type='tcg' name='pc-i440fx-1.5' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-2.7' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='tcg' name='pc-1.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='tcg' name='pc-1.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='tcg' name='pc-i440fx-2.7' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-2.4' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-2.10' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> @@ -3167,7 +3167,7 @@ <machine type='tcg' name='pc-q35-3.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-4.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.4' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='tcg' name='pc-1.3' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='tcg' name='pc-1.3' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='tcg' name='pc-i440fx-4.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.9' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='isapc' hotplugCpus='yes' maxCpus='1' defaultCPU='486-x86_64-cpu'/> @@ -3176,7 +3176,7 @@ <machine type='tcg' name='pc-i440fx-3.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-2.12' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='tcg' name='pc-1.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='tcg' name='pc-1.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='tcg' name='pc-i440fx-2.6' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-q35-4.0.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-1.6' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> @@ -3187,7 +3187,7 @@ <machine type='tcg' name='pc-q35-4.0' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='microvm' maxCpus='288' defaultCPU='qemu64-x86_64-cpu'/> <machine type='tcg' name='pc-i440fx-2.3' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> - <machine type='tcg' name='pc-1.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> + <machine type='tcg' name='pc-1.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' deprecated='yes'/> <machine type='tcg' name='pc-i440fx-4.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-5.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> <machine type='tcg' name='pc-i440fx-2.8' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes'/> diff --git a/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml index 7f15bcda09..69b1484d8b 100644 --- a/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml @@ -1424,7 +1424,7 @@ <machine type='kvm' name='pc-i440fx-1.5' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='kvm' name='pc-q35-2.7' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='kvm' name='pc-i440fx-2.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> - <machine type='kvm' name='pc-1.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> + <machine type='kvm' name='pc-1.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram' deprecated='yes'/> <machine type='kvm' name='pc-i440fx-2.7' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='kvm' name='pc-q35-2.4' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='kvm' name='pc-q35-2.10' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> @@ -1435,7 +1435,7 @@ <machine type='kvm' name='pc-q35-3.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='kvm' name='pc-q35-4.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='kvm' name='pc-i440fx-2.4' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> - <machine type='kvm' name='pc-1.3' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> + <machine type='kvm' name='pc-1.3' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram' deprecated='yes'/> <machine type='kvm' name='pc-i440fx-4.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='kvm' name='pc-i440fx-5.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' defaultRAMid='pc.ram'/> <machine type='kvm' name='pc-i440fx-2.9' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> @@ -1445,7 +1445,7 @@ <machine type='kvm' name='pc-i440fx-3.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='kvm' name='pc-q35-2.12' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='kvm' name='pc-i440fx-2.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> - <machine type='kvm' name='pc-1.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> + <machine type='kvm' name='pc-1.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram' deprecated='yes'/> <machine type='kvm' name='pc-i440fx-2.6' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='kvm' name='pc-q35-4.0.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='kvm' name='pc-i440fx-1.6' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> @@ -1456,7 +1456,7 @@ <machine type='kvm' name='pc-q35-4.0' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='kvm' name='microvm' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' defaultRAMid='microvm.ram'/> <machine type='kvm' name='pc-i440fx-2.3' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> - <machine type='kvm' name='pc-1.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> + <machine type='kvm' name='pc-1.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram' deprecated='yes'/> <machine type='kvm' name='pc-i440fx-4.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='kvm' name='pc-i440fx-5.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='kvm' name='pc-i440fx-2.8' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> @@ -3162,7 +3162,7 @@ <machine type='tcg' name='pc-i440fx-1.5' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='tcg' name='pc-q35-2.7' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='tcg' name='pc-i440fx-2.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> - <machine type='tcg' name='pc-1.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> + <machine type='tcg' name='pc-1.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram' deprecated='yes'/> <machine type='tcg' name='pc-i440fx-2.7' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='tcg' name='pc-q35-2.4' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='tcg' name='pc-q35-2.10' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> @@ -3173,7 +3173,7 @@ <machine type='tcg' name='pc-q35-3.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='tcg' name='pc-q35-4.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='tcg' name='pc-i440fx-2.4' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> - <machine type='tcg' name='pc-1.3' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> + <machine type='tcg' name='pc-1.3' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram' deprecated='yes'/> <machine type='tcg' name='pc-i440fx-4.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='tcg' name='pc-i440fx-5.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' defaultRAMid='pc.ram'/> <machine type='tcg' name='pc-i440fx-2.9' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> @@ -3183,7 +3183,7 @@ <machine type='tcg' name='pc-i440fx-3.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='tcg' name='pc-q35-2.12' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='tcg' name='pc-i440fx-2.1' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> - <machine type='tcg' name='pc-1.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> + <machine type='tcg' name='pc-1.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram' deprecated='yes'/> <machine type='tcg' name='pc-i440fx-2.6' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='tcg' name='pc-q35-4.0.1' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='tcg' name='pc-i440fx-1.6' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> @@ -3194,7 +3194,7 @@ <machine type='tcg' name='pc-q35-4.0' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='tcg' name='microvm' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' defaultRAMid='microvm.ram'/> <machine type='tcg' name='pc-i440fx-2.3' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> - <machine type='tcg' name='pc-1.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> + <machine type='tcg' name='pc-1.2' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram' deprecated='yes'/> <machine type='tcg' name='pc-i440fx-4.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='tcg' name='pc-i440fx-5.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> <machine type='tcg' name='pc-i440fx-2.8' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/> diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c index cea4f84b14..c2cf3be9ac 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -373,7 +373,8 @@ int qemuTestCapsCacheInsert(virFileCachePtr cache, false, false, true, - defaultRAMid); + defaultRAMid, + false); virQEMUCapsSet(tmpCaps, QEMU_CAPS_TCG); } if (kvm_machines[i] != NULL) { @@ -385,9 +386,10 @@ int qemuTestCapsCacheInsert(virFileCachePtr cache, NULL, 0, false, - false, + false, true, - defaultRAMid); + defaultRAMid, + false); virQEMUCapsSet(tmpCaps, QEMU_CAPS_KVM); } } -- 2.29.2

On a Friday in 2021, Daniel P. Berrangé wrote:
QEMU has the ability to mark machine types as deprecated. This should be exposed to management applications in the capabilities.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- docs/schemas/capability.rng | 8 ++++++++ src/conf/capabilities.c | 2 ++ src/conf/capabilities.h | 1 + src/qemu/qemu_capabilities.c | 17 ++++++++++++++--- src/qemu/qemu_capspriv.h | 3 ++- src/qemu/qemu_monitor.h | 1 + src/qemu/qemu_monitor_json.c | 4 ++++ .../qemucapabilitiesdata/caps_4.1.0.x86_64.xml | 16 ++++++++-------- tests/qemucapabilitiesdata/caps_4.2.0.ppc64.xml | 4 ++-- .../qemucapabilitiesdata/caps_4.2.0.x86_64.xml | 16 ++++++++-------- .../qemucapabilitiesdata/caps_5.0.0.x86_64.xml | 16 ++++++++-------- .../qemucapabilitiesdata/caps_5.1.0.x86_64.xml | 16 ++++++++-------- .../qemucapabilitiesdata/caps_5.2.0.x86_64.xml | 16 ++++++++-------- tests/testutilsqemu.c | 8 +++++--- 14 files changed, 79 insertions(+), 49 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Hypervisors are capable of reporting that some features are deprecated. This should be used to mark a domain as tainted. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/conf/domain_conf.c | 1 + src/conf/domain_conf.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index fcf332fe44..5346c40a81 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -87,6 +87,7 @@ VIR_ENUM_IMPL(virDomainTaint, "custom-dtb", "custom-ga-command", "custom-hypervisor-feature", + "deprecated-config", ); VIR_ENUM_IMPL(virDomainVirt, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index d514f6360f..55abbec0fe 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2757,6 +2757,7 @@ typedef enum { VIR_DOMAIN_TAINT_CUSTOM_DTB, /* Custom device tree blob was specified */ VIR_DOMAIN_TAINT_CUSTOM_GA_COMMAND, /* Custom guest agent command */ VIR_DOMAIN_TAINT_CUSTOM_HYPERVISOR_FEATURE, /* custom hypervisor feature control */ + VIR_DOMAIN_TAINT_DEPRECATED_CONFIG, /* Configuration that is marked deprecated */ VIR_DOMAIN_TAINT_LAST } virDomainTaintFlags; -- 2.29.2

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/qemu/qemu_domain.c | 49 ++++++++++++++++++++++++++++++++++-------- src/qemu/qemu_domain.h | 7 ++++++ 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index dd79cfd9d9..e63bea8b32 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -6166,22 +6166,51 @@ void qemuDomainObjTaint(virQEMUDriverPtr driver, virDomainObjPtr obj, virDomainTaintFlags taint, qemuDomainLogContextPtr logCtxt) +{ + qemuDomainObjTaintMsg(driver, obj, taint, logCtxt, NULL); +} + +void qemuDomainObjTaintMsg(virQEMUDriverPtr driver, + virDomainObjPtr obj, + virDomainTaintFlags taint, + qemuDomainLogContextPtr logCtxt, + const char *fmt, ...) { virErrorPtr orig_err = NULL; g_autofree char *timestamp = NULL; char uuidstr[VIR_UUID_STRING_BUFLEN]; int rc; - - if (!virDomainObjTaint(obj, taint)) - return; + g_autofree char *extra = NULL; + const char *extraprefix = ""; + const char *extramsg = ""; + const char *extrasuffix = ""; + va_list args; + + if (virDomainObjTaint(obj, taint)) { + /* If an extra message was given we must always + * emit the taint warning, otherwise it is a + * one-time only warning per VM + */ + if (!fmt) + return; + } virUUIDFormat(obj->def->uuid, uuidstr); - VIR_WARN("Domain id=%d name='%s' uuid=%s is tainted: %s", + if (fmt) { + va_start(args, fmt); + extraprefix = " ("; + extramsg = extra = g_strdup_vprintf(fmt, args); + extrasuffix = ")"; + va_end(args); + } + + VIR_WARN("Domain id=%d name='%s' uuid=%s is tainted: %s%s%s%s", obj->def->id, obj->def->name, uuidstr, - virDomainTaintTypeToString(taint)); + virDomainTaintTypeToString(taint), + extraprefix, extramsg, extrasuffix); /* We don't care about errors logging taint info, so * preserve original error, and clear any error that @@ -6193,16 +6222,18 @@ void qemuDomainObjTaint(virQEMUDriverPtr driver, if (logCtxt) { rc = qemuDomainLogContextWrite(logCtxt, - "%s: Domain id=%d is tainted: %s\n", + "%s: Domain id=%d is tainted: %s%s%s%s\n", timestamp, obj->def->id, - virDomainTaintTypeToString(taint)); + virDomainTaintTypeToString(taint), + extraprefix, extramsg, extrasuffix); } else { rc = qemuDomainLogAppendMessage(driver, obj, - "%s: Domain id=%d is tainted: %s\n", + "%s: Domain id=%d is tainted: %s%s%s%s\n", timestamp, obj->def->id, - virDomainTaintTypeToString(taint)); + virDomainTaintTypeToString(taint), + extraprefix, extramsg, extrasuffix); } if (rc < 0) diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 154339ef8f..7453881a31 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -565,6 +565,13 @@ void qemuDomainObjTaint(virQEMUDriverPtr driver, virDomainTaintFlags taint, qemuDomainLogContextPtr logCtxt); +void qemuDomainObjTaintMsg(virQEMUDriverPtr driver, + virDomainObjPtr obj, + virDomainTaintFlags taint, + qemuDomainLogContextPtr logCtxt, + const char *msg, + ...) G_GNUC_PRINTF(5, 6); + void qemuDomainObjCheckTaint(virQEMUDriverPtr driver, virDomainObjPtr obj, qemuDomainLogContextPtr logCtxt, -- 2.29.2

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 17 +++++++++++++++++ src/qemu/qemu_capabilities.h | 3 +++ src/qemu/qemu_domain.c | 37 ++++++++++++++++++++++++++++++++---- 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index e3d1de0779..f6d7a222c4 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -2437,6 +2437,23 @@ virQEMUCapsGetMachineDefaultCPU(virQEMUCapsPtr qemuCaps, } +bool +virQEMUCapsIsCPUDeprecated(virQEMUCapsPtr qemuCaps, + virDomainVirtType type, + const char *model) +{ + virQEMUCapsAccelPtr accel = virQEMUCapsGetAccel(qemuCaps, type); + qemuMonitorCPUDefsPtr defs = accel->cpuModels; + size_t i; + + for (i = 0; i < defs->ncpus; i++) { + if (STREQ_NULLABLE(defs->cpus[i].name, model)) + return defs->cpus[i].deprecated; + } + return false; +} + + bool virQEMUCapsGetMachineNumaMemSupported(virQEMUCapsPtr qemuCaps, virDomainVirtType virtType, diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index a14a78f959..a6270edb0e 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -686,6 +686,9 @@ bool virQEMUCapsGetMachineHotplugCpus(virQEMUCapsPtr qemuCaps, const char *virQEMUCapsGetMachineDefaultCPU(virQEMUCapsPtr qemuCaps, const char *name, virDomainVirtType type); +bool virQEMUCapsIsCPUDeprecated(virQEMUCapsPtr qemuCaps, + virDomainVirtType type, + const char *model); bool virQEMUCapsGetMachineNumaMemSupported(virQEMUCapsPtr qemuCaps, virDomainVirtType virtType, const char *name); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index e63bea8b32..ed5fd6aa0d 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -6243,6 +6243,37 @@ void qemuDomainObjTaintMsg(virQEMUDriverPtr driver, virErrorRestore(&orig_err); } +static void +qemuDomainObjCheckCPUTaint(virQEMUDriverPtr driver, + virDomainObjPtr obj, + qemuDomainLogContextPtr logCtxt, + bool incomingMigration) +{ + qemuDomainObjPrivatePtr priv = obj->privateData; + virQEMUCapsPtr qemuCaps = priv->qemuCaps; + + switch (obj->def->cpu->mode) { + case VIR_CPU_MODE_HOST_PASSTHROUGH: + if (incomingMigration) + qemuDomainObjTaint(driver, obj, VIR_DOMAIN_TAINT_HOST_CPU, logCtxt); + break; + case VIR_CPU_MODE_CUSTOM: + if (obj->def->cpu->model && + virQEMUCapsIsCPUDeprecated(qemuCaps, + obj->def->virtType, + obj->def->cpu->model)) { + qemuDomainObjTaintMsg(driver, obj, VIR_DOMAIN_TAINT_DEPRECATED_CONFIG, logCtxt, + _("CPU model '%s'"), + obj->def->cpu->model); + } + break; + case VIR_CPU_MODE_HOST_MODEL: + case VIR_CPU_MODE_LAST: + default: + break; + } +} + void qemuDomainObjCheckTaint(virQEMUDriverPtr driver, virDomainObjPtr obj, @@ -6276,10 +6307,8 @@ void qemuDomainObjCheckTaint(virQEMUDriverPtr driver, VIR_DOMAIN_TAINT_CUSTOM_HYPERVISOR_FEATURE, logCtxt); } - if (obj->def->cpu && - obj->def->cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH && - incomingMigration) - qemuDomainObjTaint(driver, obj, VIR_DOMAIN_TAINT_HOST_CPU, logCtxt); + if (obj->def->cpu) + qemuDomainObjCheckCPUTaint(driver, obj, logCtxt, incomingMigration); for (i = 0; i < obj->def->ndisks; i++) qemuDomainObjCheckDiskTaint(driver, obj, obj->def->disks[i], logCtxt); -- 2.29.2

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/qemu/qemu_capabilities.c | 16 ++++++++++++++++ src/qemu/qemu_capabilities.h | 3 +++ src/qemu/qemu_domain.c | 20 ++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index f6d7a222c4..b6d4c09e7e 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -2454,6 +2454,22 @@ virQEMUCapsIsCPUDeprecated(virQEMUCapsPtr qemuCaps, } +bool +virQEMUCapsIsMachineDeprecated(virQEMUCapsPtr qemuCaps, + virDomainVirtType type, + const char *machine) +{ + virQEMUCapsAccelPtr accel = virQEMUCapsGetAccel(qemuCaps, type); + size_t i; + + for (i = 0; i < accel->nmachineTypes; i++) { + if (STREQ_NULLABLE(accel->machineTypes[i].name, machine)) + return accel->machineTypes[i].deprecated; + } + return false; +} + + bool virQEMUCapsGetMachineNumaMemSupported(virQEMUCapsPtr qemuCaps, virDomainVirtType virtType, diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index a6270edb0e..19e2cd1fff 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -689,6 +689,9 @@ const char *virQEMUCapsGetMachineDefaultCPU(virQEMUCapsPtr qemuCaps, bool virQEMUCapsIsCPUDeprecated(virQEMUCapsPtr qemuCaps, virDomainVirtType type, const char *model); +bool virQEMUCapsIsMachineDeprecated(virQEMUCapsPtr qemuCaps, + virDomainVirtType type, + const char *machine); bool virQEMUCapsGetMachineNumaMemSupported(virQEMUCapsPtr qemuCaps, virDomainVirtType virtType, const char *name); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index ed5fd6aa0d..f00e8d9384 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -6243,6 +6243,24 @@ void qemuDomainObjTaintMsg(virQEMUDriverPtr driver, virErrorRestore(&orig_err); } +static void +qemuDomainObjCheckMachineTaint(virQEMUDriverPtr driver, + virDomainObjPtr obj, + qemuDomainLogContextPtr logCtxt) +{ + qemuDomainObjPrivatePtr priv = obj->privateData; + virQEMUCapsPtr qemuCaps = priv->qemuCaps; + + if (virQEMUCapsIsMachineDeprecated(qemuCaps, + obj->def->virtType, + obj->def->os.machine)) { + qemuDomainObjTaintMsg(driver, obj, VIR_DOMAIN_TAINT_DEPRECATED_CONFIG, logCtxt, + _("machine type '%s'"), + obj->def->os.machine); + } +} + + static void qemuDomainObjCheckCPUTaint(virQEMUDriverPtr driver, virDomainObjPtr obj, @@ -6307,6 +6325,8 @@ void qemuDomainObjCheckTaint(virQEMUDriverPtr driver, VIR_DOMAIN_TAINT_CUSTOM_HYPERVISOR_FEATURE, logCtxt); } + qemuDomainObjCheckMachineTaint(driver, obj, logCtxt); + if (obj->def->cpu) qemuDomainObjCheckCPUTaint(driver, obj, logCtxt, incomingMigration); -- 2.29.2

These messages will be stored in the live status XML. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/conf/domain_conf.c | 28 +++++++++++++++++++++++++--- src/conf/domain_conf.h | 4 ++++ src/libvirt_private.syms | 1 + 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5346c40a81..86c4639bda 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1774,6 +1774,15 @@ bool virDomainObjTaint(virDomainObjPtr obj, } +void virDomainObjDeprecation(virDomainObjPtr obj, + const char *msg) +{ + obj->deprecations = g_renew(char *, obj->deprecations, + obj->ndeprecations + 1); + obj->deprecations[obj->ndeprecations++] = g_strdup(msg); +} + + static void virDomainGraphicsAuthDefClear(virDomainGraphicsAuthDefPtr def) { @@ -21205,7 +21214,8 @@ virDomainObjParseXML(xmlDocPtr xml, int reason = 0; void *parseOpaque = NULL; g_autofree char *tmp = NULL; - g_autofree xmlNodePtr *nodes = NULL; + g_autofree xmlNodePtr *taintNodes = NULL; + g_autofree xmlNodePtr *depNodes = NULL; if (!(obj = virDomainObjNew(xmlopt))) return NULL; @@ -21252,10 +21262,10 @@ virDomainObjParseXML(xmlDocPtr xml, } obj->pid = (pid_t)val; - if ((n = virXPathNodeSet("./taint", ctxt, &nodes)) < 0) + if ((n = virXPathNodeSet("./taint", ctxt, &taintNodes)) < 0) goto error; for (i = 0; i < n; i++) { - char *str = virXMLPropString(nodes[i], "flag"); + char *str = virXMLPropString(taintNodes[i], "flag"); if (str) { int flag = virDomainTaintTypeFromString(str); if (flag < 0) { @@ -21269,6 +21279,13 @@ virDomainObjParseXML(xmlDocPtr xml, } } + if ((n = virXPathNodeSet("./deprecation", ctxt, &depNodes)) < 0) + goto error; + for (i = 0; i < n; i++) { + g_autofree char *str = virXMLNodeContentString(depNodes[i]); + virDomainObjDeprecation(obj, str); + } + if (xmlopt->privateData.parse && xmlopt->privateData.parse(ctxt, obj, &xmlopt->config) < 0) goto error; @@ -29073,6 +29090,11 @@ virDomainObjFormat(virDomainObjPtr obj, virDomainTaintTypeToString(i)); } + for (i = 0; i < obj->ndeprecations; i++) { + virBufferEscapeString(&buf, "<deprecation>%s</deprecation>\n", + obj->deprecations[i]); + } + if (xmlopt->privateData.format && xmlopt->privateData.format(&buf, obj) < 0) return NULL; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 55abbec0fe..9ae1bd3eeb 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2799,6 +2799,8 @@ struct _virDomainObj { void (*privateDataFreeFunc)(void *); int taint; + size_t ndeprecations; + char **deprecations; unsigned long long original_memlock; /* Original RLIMIT_MEMLOCK, zero if no * restore will be required later */ @@ -3056,6 +3058,8 @@ void virDomainObjEndAPI(virDomainObjPtr *vm); bool virDomainObjTaint(virDomainObjPtr obj, virDomainTaintFlags taint); +void virDomainObjDeprecation(virDomainObjPtr obj, + const char *msg); void virDomainObjBroadcast(virDomainObjPtr vm); int virDomainObjWait(virDomainObjPtr vm); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index c325040b60..7a73943ba0 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -547,6 +547,7 @@ virDomainObjAssignDef; virDomainObjBroadcast; virDomainObjCheckActive; virDomainObjCopyPersistentDef; +virDomainObjDeprecation; virDomainObjEndAPI; virDomainObjFormat; virDomainObjGetDefs; -- 2.29.2

These messages are only valid while the domain is running. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/qemu/qemu_domain.c | 5 +++++ src/qemu/qemu_process.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index f00e8d9384..64dc7b5eff 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -6205,6 +6205,11 @@ void qemuDomainObjTaintMsg(virQEMUDriverPtr driver, va_end(args); } + if (taint == VIR_DOMAIN_TAINT_DEPRECATED_CONFIG && + extramsg) { + virDomainObjDeprecation(obj, extramsg); + } + VIR_WARN("Domain id=%d name='%s' uuid=%s is tainted: %s%s%s%s", obj->def->id, obj->def->name, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 202d867289..4a34e5ab9f 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -7856,6 +7856,11 @@ void qemuProcessStop(virQEMUDriverPtr driver, } } + for (i = 0; i < vm->ndeprecations; i++) + g_free(vm->deprecations[i]); + g_free(vm->deprecations); + vm->ndeprecations = 0; + vm->deprecations = NULL; vm->taint = 0; vm->pid = -1; virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason); -- 2.29.2

This API allows fetching a list of deprecation messages against the domain. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- include/libvirt/libvirt-domain.h | 4 +++ src/driver-hypervisor.h | 6 ++++ src/libvirt-domain.c | 47 ++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 ++++ 4 files changed, 62 insertions(+) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index de2456812c..cef16e6361 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -5119,4 +5119,8 @@ int virDomainAuthorizedSSHKeysSet(virDomainPtr domain, unsigned int nkeys, unsigned int flags); +int virDomainGetDeprecations(virDomainPtr domain, + char ***msgs, + unsigned int flags); + #endif /* LIBVIRT_DOMAIN_H */ diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index 9e8fe89921..2f804dba1f 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -1400,6 +1400,11 @@ typedef int unsigned int nkeys, unsigned int flags); +typedef int +(*virDrvDomainGetDeprecations)(virDomainPtr domain, + char ***msgs, + unsigned int flags); + typedef struct _virHypervisorDriver virHypervisorDriver; typedef virHypervisorDriver *virHypervisorDriverPtr; @@ -1665,4 +1670,5 @@ struct _virHypervisorDriver { virDrvDomainBackupGetXMLDesc domainBackupGetXMLDesc; virDrvDomainAuthorizedSSHKeysGet domainAuthorizedSSHKeysGet; virDrvDomainAuthorizedSSHKeysSet domainAuthorizedSSHKeysSet; + virDrvDomainGetDeprecations domainGetDeprecations; }; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index c9f8ffdb56..9e3b118483 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -13102,3 +13102,50 @@ virDomainAuthorizedSSHKeysSet(virDomainPtr domain, virDispatchError(conn); return -1; } + + +/** + * virDomainGetDeprecations: + * @domain: a domain object + * @msgs: pointer to a variable to store deprecation messages + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Fetch a list of all deprecation messages for the VM and + * store them into @msgs array which is allocated upon + * successful return and is NULL terminated. The caller is + * responsible for freeing @msgs when no longer needed. + * + * Note that some hypervisors may only report deprecation + * messages while the VM is in a running state. + * + * Returns: number of messages stored in @msgs, + * -1 otherwise. + */ +int +virDomainGetDeprecations(virDomainPtr domain, + char ***msgs, + unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "msgs=%p, flags=0x%x", msgs, flags); + + virResetLastError(); + + virCheckDomainReturn(domain, -1); + conn = domain->conn; + virCheckNonNullArgGoto(msgs, error); + + if (conn->driver->domainGetDeprecations) { + int ret; + ret = conn->driver->domainGetDeprecations(domain, msgs, flags); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + error: + virDispatchError(conn); + return -1; +} diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index cf31f937d5..345c5685bf 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -879,4 +879,9 @@ LIBVIRT_6.10.0 { virDomainAuthorizedSSHKeysSet; } LIBVIRT_6.0.0; +LIBVIRT_7.1.0 { + global: + virDomainGetDeprecations; +} LIBVIRT_6.10.0; + # .... define new API here using predicted next version number .... -- 2.29.2

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/remote_daemon_dispatch.c | 45 +++++++++++++++++++++++++++++ src/remote/remote_driver.c | 44 ++++++++++++++++++++++++++++ src/remote/remote_protocol.x | 21 +++++++++++++- 3 files changed, 109 insertions(+), 1 deletion(-) diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c index 46683aa4a7..aa6a088222 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -7463,3 +7463,48 @@ remoteDispatchDomainAuthorizedSshKeysSet(virNetServerPtr server G_GNUC_UNUSED, return rv; } + +static int +remoteDispatchDomainGetDeprecations(virNetServerPtr server G_GNUC_UNUSED, + virNetServerClientPtr client, + virNetMessagePtr msg G_GNUC_UNUSED, + virNetMessageErrorPtr rerr, + remote_domain_get_deprecations_args *args, + remote_domain_get_deprecations_ret *ret) +{ + int rv = -1; + virConnectPtr conn = remoteGetHypervisorConn(client); + int nmsgs = 0; + char **msgs = NULL; + virDomainPtr dom = NULL; + + if (!conn) + goto cleanup; + + if (!(dom = get_nonnull_domain(conn, args->dom))) + goto cleanup; + + if ((nmsgs = virDomainGetDeprecations(dom, &msgs, args->flags)) < 0) + goto cleanup; + + if (nmsgs > REMOTE_DOMAIN_DEPRECATIONS_MAX) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Number of msgs %d, which exceeds max limit: %d"), + nmsgs, REMOTE_DOMAIN_DEPRECATIONS_MAX); + goto cleanup; + } + + ret->msgs.msgs_val = g_steal_pointer(&msgs); + ret->msgs.msgs_len = nmsgs; + + rv = nmsgs; + + cleanup: + if (rv < 0) + virNetMessageSaveError(rerr); + if (nmsgs > 0) + virStringListFreeCount(msgs, nmsgs); + virObjectUnref(dom); + + return rv; +} diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 1b784e61c7..009df01a54 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8098,6 +8098,49 @@ remoteDomainAuthorizedSSHKeysSet(virDomainPtr domain, } +static int +remoteDomainGetDeprecations(virDomainPtr domain, + char ***msgs, + unsigned int flags) +{ + int rv = -1; + size_t i; + struct private_data *priv = domain->conn->privateData; + remote_domain_get_deprecations_args args; + remote_domain_get_deprecations_ret ret; + + remoteDriverLock(priv); + + make_nonnull_domain(&args.dom, domain); + args.flags = flags; + memset(&ret, 0, sizeof(ret)); + + if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_DEPRECATIONS, + (xdrproc_t) xdr_remote_domain_get_deprecations_args, (char *)&args, + (xdrproc_t) xdr_remote_domain_get_deprecations_ret, (char *)&ret) == -1) { + goto cleanup; + } + + if (ret.msgs.msgs_len > REMOTE_DOMAIN_DEPRECATIONS_MAX) { + virReportError(VIR_ERR_RPC, "%s", + _("remoteDomainGetDeprecations: " + "returned number of msgs exceeds limit")); + goto cleanup; + } + + *msgs = g_new0(char *, ret.msgs.msgs_len + 1); + for (i = 0; i < ret.msgs.msgs_len; i++) + (*msgs)[i] = g_strdup(ret.msgs.msgs_val[i]); + + rv = ret.msgs.msgs_len; + + cleanup: + remoteDriverUnlock(priv); + xdr_free((xdrproc_t)xdr_remote_domain_get_deprecations_ret, + (char *) &ret); + return rv; +} + /* get_nonnull_domain and get_nonnull_network turn an on-wire * (name, uuid) pair into virDomainPtr or virNetworkPtr object. * These can return NULL if underlying memory allocations fail, @@ -8531,6 +8574,7 @@ static virHypervisorDriver hypervisor_driver = { .domainBackupGetXMLDesc = remoteDomainBackupGetXMLDesc, /* 6.0.0 */ .domainAuthorizedSSHKeysGet = remoteDomainAuthorizedSSHKeysGet, /* 6.10.0 */ .domainAuthorizedSSHKeysSet = remoteDomainAuthorizedSSHKeysSet, /* 6.10.0 */ + .domainGetDeprecations = remoteDomainGetDeprecations, /* 7.1.0 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 2df38cef77..4ddfb09631 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -283,6 +283,9 @@ const REMOTE_NETWORK_PORT_PARAMETERS_MAX = 16; /* Upper limit on number of SSH keys */ const REMOTE_DOMAIN_AUTHORIZED_SSH_KEYS_MAX = 2048; +/* Upper limit on number of deprecation messages */ +const REMOTE_DOMAIN_DEPRECATIONS_MAX = 2048; + /* UUID. VIR_UUID_BUFLEN definition comes from libvirt.h */ typedef opaque remote_uuid[VIR_UUID_BUFLEN]; @@ -3799,6 +3802,16 @@ struct remote_domain_authorized_ssh_keys_set_args { unsigned int flags; }; +struct remote_domain_get_deprecations_args { + remote_nonnull_domain dom; + unsigned int flags; +}; + +struct remote_domain_get_deprecations_ret { + remote_nonnull_string msgs<REMOTE_DOMAIN_DEPRECATIONS_MAX>; +}; + + /*----- Protocol. -----*/ /* Define the program number, protocol version and procedure numbers here. */ @@ -6714,5 +6727,11 @@ enum remote_procedure { * @generate: none * @acl: domain:write */ - REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_SET = 425 + REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_SET = 425, + + /** + * @generate: none + * @acl: domain:read + */ + REMOTE_PROC_DOMAIN_GET_DEPRECATIONS = 426 }; -- 2.29.2

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/qemu/qemu_driver.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 027617deef..43cdb53f22 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -20316,6 +20316,36 @@ qemuDomainAuthorizedSSHKeysSet(virDomainPtr dom, } +static int +qemuDomainGetDeprecations(virDomainPtr dom, + char ***msgs, + unsigned int flags) +{ + virDomainObjPtr vm = NULL; + int rv = -1; + size_t i; + + virCheckFlags(0, -1); + + if (!(vm = qemuDomainObjFromDomain(dom))) + return -1; + + if (virDomainGetDeprecationsEnsureACL(dom->conn, vm->def) < 0) + goto cleanup; + + *msgs = g_new0(char *, vm->ndeprecations + 1); + for (i = 0; i < vm->ndeprecations; i++) { + (*msgs)[i] = g_strdup(vm->deprecations[i]); + } + (*msgs)[vm->ndeprecations] = NULL; + rv = vm->ndeprecations; + + cleanup: + virDomainObjEndAPI(&vm); + return rv; +} + + static virHypervisorDriver qemuHypervisorDriver = { .name = QEMU_DRIVER_NAME, .connectURIProbe = qemuConnectURIProbe, @@ -20557,6 +20587,7 @@ static virHypervisorDriver qemuHypervisorDriver = { .domainBackupGetXMLDesc = qemuDomainBackupGetXMLDesc, /* 6.0.0 */ .domainAuthorizedSSHKeysGet = qemuDomainAuthorizedSSHKeysGet, /* 6.10.0 */ .domainAuthorizedSSHKeysSet = qemuDomainAuthorizedSSHKeysSet, /* 6.10.0 */ + .domainGetDeprecations = qemuDomainGetDeprecations, /* 7.1.0 */ }; -- 2.29.2

$ virsh dominfo demo Id: 2 Name: demo UUID: eadf8ef0-bf14-4c5f-9708-4a19bacf9e81 OS Type: hvm State: running CPU(s): 2 CPU time: 15.8s Max memory: 1536000 KiB Used memory: 1536000 KiB Persistent: yes Autostart: disable Managed save: no Security model: selinux Security DOI: 0 Security label: unconfined_u:unconfined_r:svirt_t:s0:c443,c956 (permissive) Deprecations: machine type 'pc-1.3' CPU model 'Icelake-Client' Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- tools/virsh-domain-monitor.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c index 5d0a03afa9..6b39b60339 100644 --- a/tools/virsh-domain-monitor.c +++ b/tools/virsh-domain-monitor.c @@ -1291,6 +1291,7 @@ cmdDominfo(vshControl *ctl, const vshCmd *cmd) char *str, uuid[VIR_UUID_STRING_BUFLEN]; int has_managed_save = 0; virshControlPtr priv = ctl->privData; + char **deprecations = NULL; if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) return false; @@ -1391,6 +1392,18 @@ cmdDominfo(vshControl *ctl, const vshCmd *cmd) VIR_FREE(seclabel); } } + + if (virDomainGetDeprecations(dom, &deprecations, 0) > 0) { + size_t i; + for (i = 0; deprecations[i] != NULL; i++) { + if (i == 0) { + vshPrint(ctl, "%-15s %s\n", _("Deprecations:"), deprecations[i]); + } else { + vshPrint(ctl, "%-15s %s\n", "", deprecations[i]); + } + } + } + virshDomainFree(dom); return ret; } -- 2.29.2

This API allows fetching a list of tainting codes against the domain. Internally tainting is defined as a bitmask with enum fields. Most, but not all, of the fields are somewhat QEMU specific in reality though. The idea of exposing the enum in the public API thus feels a little questionable. This API takes the approach of exposing the the string format of the enum codes and declaring the string codes are (potentially) hypervisor specific. IOW, callers of the API can display the codes but should treat them as a opaque strings. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- include/libvirt/libvirt-domain.h | 3 ++ src/driver-hypervisor.h | 5 ++++ src/libvirt-domain.c | 48 ++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + 4 files changed, 57 insertions(+) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index cef16e6361..d04140bf60 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -5122,5 +5122,8 @@ int virDomainAuthorizedSSHKeysSet(virDomainPtr domain, int virDomainGetDeprecations(virDomainPtr domain, char ***msgs, unsigned int flags); +int virDomainGetTainting(virDomainPtr domain, + char ***codes, + unsigned int flags); #endif /* LIBVIRT_DOMAIN_H */ diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index 2f804dba1f..96111cd10a 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -1404,6 +1404,10 @@ typedef int (*virDrvDomainGetDeprecations)(virDomainPtr domain, char ***msgs, unsigned int flags); +typedef int +(*virDrvDomainGetTainting)(virDomainPtr domain, + char ***codes, + unsigned int flags); typedef struct _virHypervisorDriver virHypervisorDriver; typedef virHypervisorDriver *virHypervisorDriverPtr; @@ -1671,4 +1675,5 @@ struct _virHypervisorDriver { virDrvDomainAuthorizedSSHKeysGet domainAuthorizedSSHKeysGet; virDrvDomainAuthorizedSSHKeysSet domainAuthorizedSSHKeysSet; virDrvDomainGetDeprecations domainGetDeprecations; + virDrvDomainGetTainting domainGetTainting; }; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index 9e3b118483..c053f35d3e 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -13149,3 +13149,51 @@ virDomainGetDeprecations(virDomainPtr domain, virDispatchError(conn); return -1; } + + +/** + * virDomainGetTainting: + * @domain: a domain object + * @codes: pointer to a variable to store tainting codes + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Fetch a list of all tainting codes for the VM and + * store them into @msgs array which is allocated upon + * successful return and is NULL terminated. The caller is + * responsible for freeing @msgs when no longer needed. + * + * Note that some hypervisors may only report tainting + * codes while the VM is in a running state. The list + * tainting codes is also hypervisor specific. + * + * Returns: number of messages stored in @msgs, + * -1 otherwise. + */ +int +virDomainGetTainting(virDomainPtr domain, + char ***codes, + unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "codes=%p, flags=0x%x", codes, flags); + + virResetLastError(); + + virCheckDomainReturn(domain, -1); + conn = domain->conn; + virCheckNonNullArgGoto(codes, error); + + if (conn->driver->domainGetTainting) { + int ret; + ret = conn->driver->domainGetTainting(domain, codes, flags); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + error: + virDispatchError(conn); + return -1; +} diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 345c5685bf..246fbaf1dc 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -882,6 +882,7 @@ LIBVIRT_6.10.0 { LIBVIRT_7.1.0 { global: virDomainGetDeprecations; + virDomainGetTainting; } LIBVIRT_6.10.0; # .... define new API here using predicted next version number .... -- 2.29.2

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/remote_daemon_dispatch.c | 46 +++++++++++++++++++++++++++++ src/remote/remote_driver.c | 44 +++++++++++++++++++++++++++ src/remote/remote_protocol.x | 20 ++++++++++++- 3 files changed, 109 insertions(+), 1 deletion(-) diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c index aa6a088222..f2249dfa0f 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -7508,3 +7508,49 @@ remoteDispatchDomainGetDeprecations(virNetServerPtr server G_GNUC_UNUSED, return rv; } + + +static int +remoteDispatchDomainGetTainting(virNetServerPtr server G_GNUC_UNUSED, + virNetServerClientPtr client, + virNetMessagePtr msg G_GNUC_UNUSED, + virNetMessageErrorPtr rerr, + remote_domain_get_tainting_args *args, + remote_domain_get_tainting_ret *ret) +{ + int rv = -1; + virConnectPtr conn = remoteGetHypervisorConn(client); + int ncodes = 0; + char **codes = NULL; + virDomainPtr dom = NULL; + + if (!conn) + goto cleanup; + + if (!(dom = get_nonnull_domain(conn, args->dom))) + goto cleanup; + + if ((ncodes = virDomainGetTainting(dom, &codes, args->flags)) < 0) + goto cleanup; + + if (ncodes > REMOTE_DOMAIN_TAINTING_MAX) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Number of codes %d, which exceeds max limit: %d"), + ncodes, REMOTE_DOMAIN_TAINTING_MAX); + goto cleanup; + } + + ret->codes.codes_val = g_steal_pointer(&codes); + ret->codes.codes_len = ncodes; + + rv = ncodes; + + cleanup: + if (rv < 0) + virNetMessageSaveError(rerr); + if (ncodes > 0) + virStringListFreeCount(codes, ncodes); + virObjectUnref(dom); + + return rv; +} diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 009df01a54..c3cdb751f6 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8141,6 +8141,49 @@ remoteDomainGetDeprecations(virDomainPtr domain, return rv; } +static int +remoteDomainGetTainting(virDomainPtr domain, + char ***codes, + unsigned int flags) +{ + int rv = -1; + size_t i; + struct private_data *priv = domain->conn->privateData; + remote_domain_get_tainting_args args; + remote_domain_get_tainting_ret ret; + + remoteDriverLock(priv); + + make_nonnull_domain(&args.dom, domain); + args.flags = flags; + memset(&ret, 0, sizeof(ret)); + + if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_TAINTING, + (xdrproc_t) xdr_remote_domain_get_tainting_args, (char *)&args, + (xdrproc_t) xdr_remote_domain_get_tainting_ret, (char *)&ret) == -1) { + goto cleanup; + } + + if (ret.codes.codes_len > REMOTE_DOMAIN_TAINTING_MAX) { + virReportError(VIR_ERR_RPC, "%s", + _("remoteDomainGetTainting: " + "returned number of codes exceeds limit")); + goto cleanup; + } + + *codes = g_new0(char *, ret.codes.codes_len + 1); + for (i = 0; i < ret.codes.codes_len; i++) + (*codes)[i] = g_strdup(ret.codes.codes_val[i]); + + rv = ret.codes.codes_len; + + cleanup: + remoteDriverUnlock(priv); + xdr_free((xdrproc_t)xdr_remote_domain_get_tainting_ret, + (char *) &ret); + return rv; +} + /* get_nonnull_domain and get_nonnull_network turn an on-wire * (name, uuid) pair into virDomainPtr or virNetworkPtr object. * These can return NULL if underlying memory allocations fail, @@ -8575,6 +8618,7 @@ static virHypervisorDriver hypervisor_driver = { .domainAuthorizedSSHKeysGet = remoteDomainAuthorizedSSHKeysGet, /* 6.10.0 */ .domainAuthorizedSSHKeysSet = remoteDomainAuthorizedSSHKeysSet, /* 6.10.0 */ .domainGetDeprecations = remoteDomainGetDeprecations, /* 7.1.0 */ + .domainGetTainting = remoteDomainGetTainting, /* 7.1.0 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 4ddfb09631..bcb15b251f 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -286,6 +286,9 @@ const REMOTE_DOMAIN_AUTHORIZED_SSH_KEYS_MAX = 2048; /* Upper limit on number of deprecation messages */ const REMOTE_DOMAIN_DEPRECATIONS_MAX = 2048; +/* Upper limit on number of tainting codes */ +const REMOTE_DOMAIN_TAINTING_MAX = 2048; + /* UUID. VIR_UUID_BUFLEN definition comes from libvirt.h */ typedef opaque remote_uuid[VIR_UUID_BUFLEN]; @@ -3811,6 +3814,15 @@ struct remote_domain_get_deprecations_ret { remote_nonnull_string msgs<REMOTE_DOMAIN_DEPRECATIONS_MAX>; }; +struct remote_domain_get_tainting_args { + remote_nonnull_domain dom; + unsigned int flags; +}; + +struct remote_domain_get_tainting_ret { + remote_nonnull_string codes<REMOTE_DOMAIN_TAINTING_MAX>; +}; + /*----- Protocol. -----*/ @@ -6733,5 +6745,11 @@ enum remote_procedure { * @generate: none * @acl: domain:read */ - REMOTE_PROC_DOMAIN_GET_DEPRECATIONS = 426 + REMOTE_PROC_DOMAIN_GET_DEPRECATIONS = 426, + + /** + * @generate: none + * @acl: domain:read + */ + REMOTE_PROC_DOMAIN_GET_TAINTING = 427 }; -- 2.29.2

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/qemu/qemu_driver.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 43cdb53f22..48d2dafb2f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -20346,6 +20346,40 @@ qemuDomainGetDeprecations(virDomainPtr dom, } +static int +qemuDomainGetTainting(virDomainPtr dom, + char ***codes, + unsigned int flags) +{ + virDomainObjPtr vm = NULL; + int rv = -1; + size_t i, n; + size_t ntaint; + + virCheckFlags(0, -1); + + if (!(vm = qemuDomainObjFromDomain(dom))) + return -1; + + if (virDomainGetTaintingEnsureACL(dom->conn, vm->def) < 0) + goto cleanup; + + ntaint = __builtin_popcount(vm->taint); + *codes = g_new0(char *, ntaint + 1); + for (i = 0, n = 0; i < VIR_DOMAIN_TAINT_LAST && n < ntaint; i++) { + if (vm->taint & (1 << i)) { + (*codes)[n++] = g_strdup(virDomainTaintTypeToString(i)); + } + } + (*codes)[n] = NULL; + rv = ntaint; + + cleanup: + virDomainObjEndAPI(&vm); + return rv; +} + + static virHypervisorDriver qemuHypervisorDriver = { .name = QEMU_DRIVER_NAME, .connectURIProbe = qemuConnectURIProbe, @@ -20588,6 +20622,7 @@ static virHypervisorDriver qemuHypervisorDriver = { .domainAuthorizedSSHKeysGet = qemuDomainAuthorizedSSHKeysGet, /* 6.10.0 */ .domainAuthorizedSSHKeysSet = qemuDomainAuthorizedSSHKeysSet, /* 6.10.0 */ .domainGetDeprecations = qemuDomainGetDeprecations, /* 7.1.0 */ + .domainGetTainting = qemuDomainGetTainting, /* 7.1.0 */ }; -- 2.29.2

$ virsh dominfo demo Id: 2 Name: demo UUID: eadf8ef0-bf14-4c5f-9708-4a19bacf9e81 OS Type: hvm State: running CPU(s): 2 CPU time: 15.8s Max memory: 1536000 KiB Used memory: 1536000 KiB Persistent: yes Autostart: disable Managed save: no Security model: selinux Security DOI: 0 Security label: unconfined_u:unconfined_r:svirt_t:s0:c443,c956 (permissive) Tainting: custom-monitor deprecated-config Deprecations: machine type 'pc-1.3' CPU model 'Icelake-Client' Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- tools/virsh-domain-monitor.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c index 6b39b60339..ca85851810 100644 --- a/tools/virsh-domain-monitor.c +++ b/tools/virsh-domain-monitor.c @@ -1292,6 +1292,7 @@ cmdDominfo(vshControl *ctl, const vshCmd *cmd) int has_managed_save = 0; virshControlPtr priv = ctl->privData; char **deprecations = NULL; + char **tainting = NULL; if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) return false; @@ -1393,6 +1394,17 @@ cmdDominfo(vshControl *ctl, const vshCmd *cmd) } } + if (virDomainGetTainting(dom, &tainting, 0) > 0) { + size_t i; + for (i = 0; tainting[i] != NULL; i++) { + if (i == 0) { + vshPrint(ctl, "%-15s %s\n", _("Tainting:"), tainting[i]); + } else { + vshPrint(ctl, "%-15s %s\n", "", tainting[i]); + } + } + } + if (virDomainGetDeprecations(dom, &deprecations, 0) > 0) { size_t i; for (i = 0; deprecations[i] != NULL; i++) { -- 2.29.2

On a Friday in 2021, Daniel P. Berrangé wrote:
Libvirt has a notion of "tainting" which we use to mark a guest which has some undesirable configuration or behaviour from libvirt's POV. This ends up in the libvirtd logs and in the per-VM log file, but is not exposed to management applications directly.
QMP has the ability to report whether a CPU or machine type is deprecated.
QEMU itself prints warnings to stderr which end up in the per VM log:
2021-01-22T12:22:53.566239Z qemu-system-x86_64: Machine type 'pc-1.3' is depr= ecated: use a newer machine type instead 2021-01-22T12:22:53.566613Z qemu-system-x86_64: warning: CPU model Icelake-Cl= ient-x86_64-cpu is deprecated -- use Icelake-Server instead
We can use the deprecation info from QMP to add tainting to the domain too. This will appear in the pre-VM log file again:
2021-01-22 12:22:53.492+0000: Domain id=3D2 is tainted: deprecated-configurat= ion (machine type 'pc-1.3') 2021-01-22 12:22:53.492+0000: Domain id=3D2 is tainted: deprecated-configurat= ion (CPU model 'Icelake-Client')
and more usefully in the libvirtd log
2021-01-22 13:18:09.619+0000: 3299849: warning : qemuDomainObjTaintMsg:6208 : Domain id=3D3 name=3D'demo' uuid=3Deadf8ef0-bf14-4c5f-9708-4a19bacf9e81 is tainted: deprecated-configuration (machine type 'pc-1.3')
2021-01-22 13:18:09.619+0000: 3299849: warning : qemuDomainObjTaintMsg:6208 : Domain id=3D3 name=3D'demo' uuid=3Deadf8ef0-bf14-4c5f-9708-4a19bacf9e81 is tainted: deprecated-configuration (CPU model 'Icelake-Client')
This series goes further and also exposes the deprecation info in the capabilities (machine types) or domain capabilities (CPU) XML. This lets mgmt apps avoid using the feature upfront if desired.
Finally both deprecation messages and tainting flags are exposed in new public APIs, and wired into virsh
$ virsh dominfo demo Id: 3 Name: demo UUID: eadf8ef0-bf14-4c5f-9708-4a19bacf9e81 OS Type: hvm State: running CPU(s): 2 CPU time: 1.3s Max memory: 1536000 KiB Used memory: 1536000 KiB Persistent: yes Autostart: disable Managed save: no Security model: selinux Security DOI: 0 Security label: unconfined_u:unconfined_r:svirt_t:s0:c578,c807 (permissive) Tainting: custom-monitor deprecated-config Deprecations: CPU model 'Icelake-Client' machine type 'pc-1.3'
The deprecations API is simple, just returning a list of free form opaque strings, which are eeffectively warning messages.
I'm not entirely convinced by tainting API though. I didn't especially want to expose the virDomainTaintFlags enum in the public API since it feels like the enum flags are (almost) all QEMU driver specific. I thus took the approach of having an API return opaque strings which are declared to be hypervisor specific.
I'm worried though that mgmt apps will none the less simply match on the strings to detect things, at which point we might as well just use an enum after all.
Depending on the app, there might be no need to even call GetTainting in the first place - the app already has the power not to use any of the tainted features, with the exception of the newly-added deprecated-config, which can happen after migration to a newer QEMU. So they can just query for deprecations directly. Also, with the deprecations being an opaque string, can the apps take any different action than just passing them to the user? It seems to me the APIs are better for humans and the XML in capabilities is better for apps, but I've never really written one.
So perhaps it should just be turned into
virDomainGetTainting(virDomainPtr obj, int **codes, unsigned int flags);
enum virDomainTaintCodes { .... }
Daniel P. Berrang=C3=A9 (16): qemu: report whether a CPU model is deprecated in dom capabilities qemu: report whether a machine type is deprecated in capabilities conf: introduce new taint flag for deprecated configuration qemu: add ability to associate a string message with taint warning qemu: taint the VM if it is using a deprecated CPU model qemu: taint the VM if it is using a deprecated machine type conf: record deprecation messages against the domain qemu: record deprecation messages against the domain src: define virDomainGetDeprecations API remote: add RPC support for the virDomainGetDeprecations API qemu: implement virDomainGetDeprecations API tools: report deprecations for 'dominfo' command src: define virDomainGetTainting API remote: add RPC support for the virDomainGetTainting API qemu: implement virDomainGetTainting API tools: report tainting for 'dominfo' command
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

On Mon, Jan 25, 2021 at 11:26:08AM +0100, Ján Tomko wrote:
On a Friday in 2021, Daniel P. Berrangé wrote:
Libvirt has a notion of "tainting" which we use to mark a guest which has some undesirable configuration or behaviour from libvirt's POV. This ends up in the libvirtd logs and in the per-VM log file, but is not exposed to management applications directly.
QMP has the ability to report whether a CPU or machine type is deprecated.
QEMU itself prints warnings to stderr which end up in the per VM log:
2021-01-22T12:22:53.566239Z qemu-system-x86_64: Machine type 'pc-1.3' is depr= ecated: use a newer machine type instead 2021-01-22T12:22:53.566613Z qemu-system-x86_64: warning: CPU model Icelake-Cl= ient-x86_64-cpu is deprecated -- use Icelake-Server instead
We can use the deprecation info from QMP to add tainting to the domain too. This will appear in the pre-VM log file again:
2021-01-22 12:22:53.492+0000: Domain id=3D2 is tainted: deprecated-configurat= ion (machine type 'pc-1.3') 2021-01-22 12:22:53.492+0000: Domain id=3D2 is tainted: deprecated-configurat= ion (CPU model 'Icelake-Client')
and more usefully in the libvirtd log
2021-01-22 13:18:09.619+0000: 3299849: warning : qemuDomainObjTaintMsg:6208 : Domain id=3D3 name=3D'demo' uuid=3Deadf8ef0-bf14-4c5f-9708-4a19bacf9e81 is tainted: deprecated-configuration (machine type 'pc-1.3')
2021-01-22 13:18:09.619+0000: 3299849: warning : qemuDomainObjTaintMsg:6208 : Domain id=3D3 name=3D'demo' uuid=3Deadf8ef0-bf14-4c5f-9708-4a19bacf9e81 is tainted: deprecated-configuration (CPU model 'Icelake-Client')
This series goes further and also exposes the deprecation info in the capabilities (machine types) or domain capabilities (CPU) XML. This lets mgmt apps avoid using the feature upfront if desired.
Finally both deprecation messages and tainting flags are exposed in new public APIs, and wired into virsh
$ virsh dominfo demo Id: 3 Name: demo UUID: eadf8ef0-bf14-4c5f-9708-4a19bacf9e81 OS Type: hvm State: running CPU(s): 2 CPU time: 1.3s Max memory: 1536000 KiB Used memory: 1536000 KiB Persistent: yes Autostart: disable Managed save: no Security model: selinux Security DOI: 0 Security label: unconfined_u:unconfined_r:svirt_t:s0:c578,c807 (permissive) Tainting: custom-monitor deprecated-config Deprecations: CPU model 'Icelake-Client' machine type 'pc-1.3'
The deprecations API is simple, just returning a list of free form opaque strings, which are eeffectively warning messages.
I'm not entirely convinced by tainting API though. I didn't especially want to expose the virDomainTaintFlags enum in the public API since it feels like the enum flags are (almost) all QEMU driver specific. I thus took the approach of having an API return opaque strings which are declared to be hypervisor specific.
I'm worried though that mgmt apps will none the less simply match on the strings to detect things, at which point we might as well just use an enum after all.
Depending on the app, there might be no need to even call GetTainting in the first place - the app already has the power not to use any of the tainted features, with the exception of the newly-added deprecated-config, which can happen after migration to a newer QEMU.
So they can just query for deprecations directly.
It probably depends on the mgmt app to some degree. With OpenStack there have been cases where they were using deprecated features because no one told them they were deprecated. We're better at dociumenting this in QEMU release notes, but not every reads this until its too late. In the virt-manager case it will let the user use pretty much anything that exists in QEMU. My thought was that virt-manager could display a "💣" icon next to any VM which is marked as tainted by libvirt, and when opening the VM details, it could display the list of deprecation messages to the user </handwaving>
Also, with the deprecations being an opaque string, can the apps take any different action than just passing them to the user? It seems to me the APIs are better for humans and the XML in capabilities is better for apps, but I've never really written one.
I'm not really expecting apps to make significant functional decisions based on these APIs. By the time the VM is reporting tainting or deprecations, it is too late - the app/user already made the bad decisions. So mostly I think it'll just be displayed to the user "as is", as a way to alert them to something sub-optimal going on. The user can read it and figure out what is wrong. With that in mind, maybe for the tainting we should also just display human readable messages too, rather than codes.
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Although you ACKd this, i'm going to just push the first part which doesn't have public API impact while I think some more. 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 :|

Related question: does libvirt generate any kind of structured log records, or all log examples below are going to be stored in plain text only? On Fri, Jan 22, 2021 at 05:18:20PM +0000, Daniel P. Berrangé wrote: [...]
We can use the deprecation info from QMP to add tainting to the domain too. This will appear in the pre-VM log file again:
2021-01-22 12:22:53.492+0000: Domain id=3D2 is tainted: deprecated-configurat= ion (machine type 'pc-1.3') 2021-01-22 12:22:53.492+0000: Domain id=3D2 is tainted: deprecated-configurat= ion (CPU model 'Icelake-Client')
and more usefully in the libvirtd log
2021-01-22 13:18:09.619+0000: 3299849: warning : qemuDomainObjTaintMsg:6208 : Domain id=3D3 name=3D'demo' uuid=3Deadf8ef0-bf14-4c5f-9708-4a19bacf9e81 is tainted: deprecated-configuration (machine type 'pc-1.3')
2021-01-22 13:18:09.619+0000: 3299849: warning : qemuDomainObjTaintMsg:6208 : Domain id=3D3 name=3D'demo' uuid=3Deadf8ef0-bf14-4c5f-9708-4a19bacf9e81 is tainted: deprecated-configuration (CPU model 'Icelake-Client')
[...] -- Eduardo

On Mon, Jan 25, 2021 at 02:41:06PM -0500, Eduardo Habkost wrote:
Related question: does libvirt generate any kind of structured log records, or all log examples below are going to be stored in plain text only?
Log files are plain text. The API proposals here are what provide any formal data to apps.
On Fri, Jan 22, 2021 at 05:18:20PM +0000, Daniel P. Berrangé wrote: [...]
We can use the deprecation info from QMP to add tainting to the domain too. This will appear in the pre-VM log file again:
2021-01-22 12:22:53.492+0000: Domain id=3D2 is tainted: deprecated-configurat= ion (machine type 'pc-1.3') 2021-01-22 12:22:53.492+0000: Domain id=3D2 is tainted: deprecated-configurat= ion (CPU model 'Icelake-Client')
and more usefully in the libvirtd log
2021-01-22 13:18:09.619+0000: 3299849: warning : qemuDomainObjTaintMsg:6208 : Domain id=3D3 name=3D'demo' uuid=3Deadf8ef0-bf14-4c5f-9708-4a19bacf9e81 is tainted: deprecated-configuration (machine type 'pc-1.3')
2021-01-22 13:18:09.619+0000: 3299849: warning : qemuDomainObjTaintMsg:6208 : Domain id=3D3 name=3D'demo' uuid=3Deadf8ef0-bf14-4c5f-9708-4a19bacf9e81 is tainted: deprecated-configuration (CPU model 'Icelake-Client')
[...]
-- Eduardo
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 :|
participants (3)
-
Daniel P. Berrangé
-
Eduardo Habkost
-
Ján Tomko