On Tue, Mar 12, 2024 at 18:06:41 +0100, Jiri Denemark wrote:
> This is not a good idea in general, but we can (and have to) do it in
> specific cases when a feature has always been part of a CPU model in
> hypervisor's definition, but we ignored it and did not include the
> feature in our definition.
>
> Blindly adding the features to the CPU map and not adding them to
> existing CPU models breaks migration between old and new libvirt in both
> directions. New libvirt would complain the features got unexpectedly
> enabled (as they were not mentioned in the incoming domain XML) even
> though they were also enabled on the source and the old libvirt just
> didn't know about them. On the other hand, old libvirt would refuse to
> accept incoming migration of a domain started by new libvirt because the
> domain XML would contain CPU features unknown to the old libvirt.
>
> This is exactly what happened when several vmx-* features were added a
> few releases back. Migration between libvirt releases before and after
> the addition is now broken.
>
> This patch adds support for added these features to existing CPU models
> by marking them with added='yes'. The features will not be considered
> part of the CPU model and will be described explicitly via additional
> <feature/> elements, but the compatibility check will not complain if
> they are enabled by the hypervisor even though they were not explicitly
> mentioned in the CPU definition and incoming migration from old libvirt
> will succeed.
>
> To fix outgoing migration to old libvirt, we also need to drop all those
> features from domain XML unless they were explicitly requested by the
> user. This will be handled by a later patch.
>
> Signed-off-by: Jiri Denemark <[email protected]>
> ---
> src/cpu/cpu_x86.c | 69 ++++++++++++++++++++++++++++++++++++++--
> src/cpu/cpu_x86.h | 3 ++
> src/libvirt_private.syms | 1 +
> 3 files changed, 70 insertions(+), 3 deletions(-)
> @@ -3030,11 +3057,13 @@ virCPUx86UpdateLive(virCPUDef *cpu,
[...]
Even in the context of virCPUx86UpdateLive this conidtion is getting a
bit overcrowded with the extra check. Please add a comment at least
stating that this specifically ignores the features added later.
> if (expected == VIR_CPU_FEATURE_DISABLE &&
> x86DataIsSubset(&enabled, &feature->data)) {
> VIR_DEBUG("Feature '%s' enabled by the hypervisor",
> feature->name);
> - if (cpu->check == VIR_CPU_CHECK_FULL)
> + if (cpu->check == VIR_CPU_CHECK_FULL &&
> + !g_strv_contains((const char **) model->addedFeatures,
> feature->name)) {
> virBufferAsprintf(&bufAdded, "%s,", feature->name);
> - else if (virCPUDefUpdateFeature(cpu, feature->name,
> - VIR_CPU_FEATURE_REQUIRE) < 0)
> + } else if (virCPUDefUpdateFeature(cpu, feature->name,
> + VIR_CPU_FEATURE_REQUIRE) < 0) {
> return -1;
> + }
> }
>
> if (x86DataIsSubset(&disabled, &feature->data) ||
> @@ -3499,6 +3528,40 @@ virCPUx86FeatureFilterDropMSR(const char *name,
> }
>
>
> +/**
> + * virCPUx86GetAddedFeatures:
> + * @modelName: CPU model
> + * @features: where to store a pointer to the list of added features
> + *
> + * Gets a list of features added to a specified CPU model after its original
> + * version was already released. The @features will be set to NULL if the
> list
> + * is empty or it will point to internal structures and thus it must not be
> + * freed or modified by the caller. The pointer is valid for the whole
> lifetime
> + * of the process.
> + *
> + * Returns 0 on success, -1 otherwise.
> + */
> +int
> +virCPUx86GetAddedFeatures(const char *modelName,
> + const char * const **features)
> +{
> + virCPUx86Map *map;
> + virCPUx86Model *model;
> +
> + if (!(map = virCPUx86GetMap()))
> + return -1;
> +
> + if (!(model = x86ModelFind(map, modelName))) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("unknown CPU model %1$s"), modelName);
While I didn't yet check where this is used using INTERNAL_ERROR for a
CPU model which most likely came from the user is weird. Consider using
VIR_ERR_INVALID_ARG.
Reviewed-by: Peter Krempa <[email protected]>
_______________________________________________
Devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]