Skip to content

RFC: pool-level default HA restart behavior for VMs with no explicit priority #7196

Description

@olivierlambert

Hi everyone,

I'd like to discuss a quality of life improvement around HA, based on feedback we get regularly from XCP-ng users.

The problem

Today, when you enable HA on a pool, every VM starts with ha_restart_priority = "", meaning "do not restart". If you want a VM to survive a host failure, you have to set the priority on it explicitly, one VM at a time. And you have to remember to do it again for every VM you create afterwards.

In practice, this is backwards compared to what people actually want. When an admin enables HA, the intent is almost always "I want my VMs back if a host dies". The realistic split is:

  • the vast majority of VMs should at least be restarted on a best effort basis
  • a few critical VMs deserve the full "restart" priority with capacity planning
  • almost nobody wants a VM that stays down on purpose

So the current default forces users to do tedious per-VM configuration to get the behavior they wanted in the first place. Worse, it fails silently: a VM someone forgot to configure looks fine every day, until the day a host crashes and that VM just stays down. The failure mode of "forgot to set it" is exactly the disaster HA was enabled to avoid.

Proposal

Add a pool-level setting, something like Pool.ha_default_restart_priority, restricted to "" (current behavior, default) or "best-effort".

The key design point: instead of stamping a default value on VMs at creation time, the setting would be interpreted at planning/restart time. Concretely, in xapi_ha_vm_failover.ml, VMs whose ha_restart_priority is "" would be classified as best-effort when the pool setting says so. VMs explicitly set to "restart" keep their guaranteed behavior, unchanged.

Why interpretation time rather than creation time:

  1. It covers existing VMs immediately. Flip the setting and every unconfigured VM in the pool is protected, which is the actual pain point. A creation-time default would only help future VMs.
  2. No plumbing needed through VM.create, clone, provision, import and migration paths. Most VMs are born from template clones which copy the field anyway, so a VM.create hook would miss the main path.
  3. There's precedent against creation-time pool defaults. Pool.policy_no_vendor_device was exactly that pattern and it was deprecated in 24.14.0 ("No longer considered by VM.create"). I'd rather not reintroduce a pattern the project already walked away from.
  4. It's instantly reversible. Nothing is written into VM records, so turning the setting off restores today's behavior exactly.

Why best-effort only

I would deliberately not allow "restart" as the pool default. Best-effort VMs are restarted after the protected ones and don't participate in the failover plan computation, so this default costs nothing: no capacity reservation, no risk of HA_OPERATION_WOULD_BREAK_FAILOVER_PLAN popping up on unrelated VM starts. A pool-wide "restart" default would silently consume failover headroom with every VM created, which is a footgun I'd rather keep out of reach.

Trade-off

With the setting enabled, "" no longer means "never restart" on that pool. I think that's acceptable because it's opt-in per pool, and "I want this VM to stay down after a host failure" is a rare intent. If people feel that intent needs to stay expressible, we could discuss adding an explicit "never" value to the field, but I'd keep that out of scope for a first iteration.

Happy to get feedback on this. If there's agreement on the approach, we can work on a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions