xapi: evacuate non-HA-protected VMs when no host failures are tolerated#7146
xapi: evacuate non-HA-protected VMs when no host failures are tolerated#7146olivierlambert wants to merge 2 commits into
Conversation
| planner's PoV) as the result obtained following a host failure and VM | ||
| restart. When no host failures are tolerated, no capacity is reserved | ||
| for failover, so every VM can be migrated just like in a pool without | ||
| HA. *) |
There was a problem hiding this comment.
I think although the pool doesn't reserve any capacity for failover when the ha_host_failures_to_tolerate is 0, it still can try to restart protected VMs with best effort. In other words, ha_host_failures_to_tolerate = 0 is not equivalent to HA disabled.
The HA guarantee would change due to host.evacuate. This is just like "If the user makes their own poor placement decisions via explicit VM.start/VM.start_on then the plan may evaporate. This is no different to (eg) the user migrating a VM and breaking the plan." In this sense, I think there is no difference between ha_host_failures_to_tolerate = 0 and ha_host_failures_to_tolerate > 0. The problem is that feasible HA plan may "evaporate" after allowing migration of non-protected VMs.
|
Disclaimer: I am not an HA expert and I am still learning the subject, just thinking at loud here... The evacuation code currently treats
|
|
@minglumlu thanks, fair challenge, and you're right on the first point: ftt=0 is not the same as HA disabled. The daemon is still armed and protected VMs are still restarted after a failure, on a best effort basis. My commit message overstated this by calling it "as safe as a pool without HA", I've reworded it. On the second point, I think the VM.start/migrate analogy actually supports keying on ftt once you follow it into the guard. VM.start and VM.migrate don't freely break the plan: they go through So the two regimes really differ. With ftt > 0 we have With ftt = 0 we have So the dividing line isn't "HA on vs off", it's whether there is a reserved plan the pool actively defends. At ftt=0 there isn't. About Would you be more comfortable with this behind a |
7629eeb to
0816fca
Compare
…cted VMs When HA is enabled on the pool, host.evacuate refuses to plan the evacuation of any VM that is not HA-protected, that is, whose ha_restart_priority is not "restart". This is intentional: the HA planner only accounts for protected VMs, so unprotected ones are excluded from the evacuation plan. The problem is the error reported in that case. compute_evacuation_plan_no_wlb marked every unprotected VM with HOST_NOT_ENOUGH_FREE_MEMORY, and host.evacuate then raised it. That error is misleading in two ways: * It blames free memory, so operators look at RAM on the destination hosts (which is usually plentiful) instead of the real cause. * It was raised with a single parameter (the VM reference) while HOST_NOT_ENOUGH_FREE_MEMORY is documented as taking [needed; available], so clients such as Xen Orchestra render the available memory as "<unknown>". This has confused users for years (see issue xapi-project#4323 and the forum reports linked from it): evacuation fails with HOST_NOT_ENOUGH_FREE_MEMORY even when the destination has tens of GB free, purely because a VM is not HA-protected. Introduce a dedicated error, HOST_EVACUATE_VM_NOT_HA_PROTECTED, carrying the VM reference, and raise it instead for unprotected VMs. The message states the real cause and the ways to resolve it (protect the VM, shut it down or suspend it, or disable HA before evacuating). Behaviour is otherwise unchanged: the evacuation still fails for these VMs, it is just reported correctly. Closes xapi-project#4323 Signed-off-by: Olivier Lambert <olivier.lambert@vates.tech>
0816fca to
5c44b1b
Compare
When HA is enabled, host.evacuate excludes every VM that is not HA-protected (ha_restart_priority other than "restart") from the evacuation plan, so the operation fails as soon as such a VM is resident on the host being evacuated. This exclusion exists so that executing the evacuation plan and disabling the host looks the same, to the HA planner, as a host failure followed by VM restart: the planner only accounts for protected VMs, and placing non-protected VMs on the remaining hosts would consume memory it does not reserve and could break the failover plan. That is also why VM.start and VM.migrate of such VMs are blocked with HA_OPERATION_WOULD_BREAK_FAILOVER_PLAN when a plan is reserved. When ha_host_failures_to_tolerate is 0, ha_plan_exists_for is 0 and no capacity is reserved, so there is no such plan to break. HA is not disabled: protected VMs are still restarted after a failure, but only on a best-effort basis, and that best-effort restart can already be degraded by an ordinary VM.start, which is not blocked at ftt = 0. Letting evacuation migrate non-protected VMs is therefore no less safe than operations the pool already permits. This is the common case for small pools (for instance two hosts), where ha_host_failures_to_tolerate is necessarily 0 but administrators still want to put a host into maintenance. Previously such an evacuation failed even though the destination had plenty of free memory. Only partition the VMs into protected and unprotected when HA reserves capacity (ha_host_failures_to_tolerate > 0). Otherwise treat all user VMs as migratable and let the memory binpack place them. When capacity is reserved, the behaviour is unchanged and unprotected VMs are still reported with HOST_EVACUATE_VM_NOT_HA_PROTECTED. Signed-off-by: Olivier Lambert <olivier.lambert@vates.tech>
5c44b1b to
72e9847
Compare
|
@gthvn1 the three tier model you describe is exactly how the restart side works: restart VMs are part of the reserved plan, best-effort VMs are restarted after them if there is room, and "" VMs are ignored. For placement though, the planner only knows two classes, and best-effort falls on the unprotected side. The plan is computed from That is why VM.start and VM.migrate of a best-effort VM are guarded too: What could work as a follow-up is including best-effort (and "") VMs in the evacuation at ftt > 0 whenever their placement passes that same guard, and only reporting the error when it does not. That would unblock most evacuations on pools with spare capacity while keeping the plan safe. It is a bigger change though, since the binpack in |
Why
Even with the clearer error from #7145, evacuating a host under HA still fails
outright as soon as a non-HA-protected VM is resident on it. That is a real
obstacle for small pools: with two hosts,
ha_host_failures_to_tolerateisnecessarily 0, yet administrators routinely need to put a host into maintenance.
Today that fails even though the destination has plenty of free memory.
Excluding non-protected VMs from the evacuation plan only makes sense when HA is
actually reserving capacity for failover. The reason they are excluded is that
the HA planner accounts only for protected VMs, and placing extra VMs on the
remaining hosts could break the failover plan. When
ha_host_failures_to_tolerateis 0, no capacity is reserved for failover at all, so there is no plan to break:
migrating non-protected VMs is then exactly as safe as in a pool without HA.
How
Only partition VMs into protected and unprotected when HA reserves capacity
(
ha_enabled && ha_host_failures_to_tolerate > 0). Otherwise treat all user VMsas migratable and let the existing memory binpack place them, exactly as in a
pool without HA. When capacity is reserved, behaviour is unchanged and
unprotected VMs are still reported with
HOST_EVACUATE_VM_NOT_HA_PROTECTED(from #7145).
Only
ocaml/xapi/xapi_host.mlis touched (incompute_evacuation_plan_no_wlb).Open questions (why this is a draft)
ha_host_failures_to_tolerate = 0the right condition, or should it key offha_overcommitted/ha_plan_exists_forinstead?planner the same as a host failure followed by VM restart. With ftt = 0 there
is no failover reservation, but is there any other place that relies on
non-protected VMs being excluded from the evacuation plan?
xapi_globs.ml(defaulted off)for wider testing first, as suggested in CONTRIBUTING?
Testing
Built and tested on CI (build and test, unit tests, format, CodeChecker and
ShellCheck all green on a fork branch). No automated test is added yet for the
compute_evacuation_plan_no_wlbpaths; the existingtest_ha_vm_failover.mlcovers the binpack layer but not this function. Happy to add coverage once the
approach is agreed.
Depends on #7145.