For the complete documentation index, see llms.txt. This page is also available as Markdown.

VM Fails to Start After Live Migration Failure Due to Fibre Channel BDM Corruption

Problem

After a live migration fails on a host using Fibre Channel block storage, the affected VM shows vm_state: error while power_state remains Running on the original host. The VM continues to run until an operation such as a start, hard reboot, or a second migration attempt is issued. A start or hard reboot then fails during volume disconnect, the domain is destroyed, and the VM does not come back online.

Additional observable symptoms:

  • openstack volume show for a non-multiattach volume lists two or more attachments, each on a different host

  • openstack server event list shows one or more live-migration events with a failure status

  • The launched_at timestamp of the instance predates the failed migrations, indicating the domain never moved

Environment

  • Private Cloud Director Virtualization - All versions

  • Self-Hosted Private Cloud Director Virtualization - All versions

  • Component: Compute Service, Block Storage Service (Fibre Channel — HPE Alletra 9000/MP, Primera, 3PAR)

Cause

During a live migration, the Compute Service runs pre_live_migration on the destination host. This step creates a new volume attachment for the destination host in the Block Storage Service and rewrites the connection_info field of the Block Device Mapping (BDM) record in the nova.block_device_mapping table with the destination host's LUN ID and initiator WWPNs. The attachment_id column of the BDM is repointed to the destination host's attachment.

If the migration fails after pre_live_migration runs and the rollback does not complete, the BDM record is never reverted. The domain still runs on the source host, but the BDM now describes the destination host's view of the volume.

On 3PAR-lineage arrays (HPE Alletra 9000/MP, Primera, 3PAR) each host receives its own VLUN numbering. The same volume can be LUN 59 on one host, 36 on another, and 111 on a third. A LUN number is meaningless outside the host that the LUN was issued for. When the Compute Service later starts or hard-reboots the VM, os-brick builds by-path device names from the stale LUN number and resolves them on the source host. If an unrelated volume occupies that LUN number on the source host, os-brick attempts to flush and delete that volume's multipath map. The map in use protection in multipathd blocks the delete, but SCSI paths of the unrelated volume may already have been removed at that point.

Resetting the VM state to active and retrying the migration clears the symptom without correcting the record. Each additional failed migration attempt leaks one more attachment per volume.

Fibre Channel connection_info embeds the LUN in four fields and identifies the host in two, so a repair that only rewrites target_lun leaves the record inconsistent:

Field
Action
Notes

data.target_lun

Rewrite

Scalar LUN for the host holding the domain

data.targets

Rewrite

Four [target_wwn, lun] pairs

data.initiator_target_map

Rekey

Keyed by initiator WWPN; targets listed per initiator

data.initiator_target_lun_map

Rekey and re-LUN

Drives os-brick path derivation

attachment_id (column)

Repoint

To the attachment whose connector host holds the domain

data.multipath_id

Leave

Array WWID — host-independent

data.device_path

Leave

Derived from the WWID

data.target_wwn

Leave

Array target ports; verify the ports are zoned to the host

volume_id, serial

Leave

Volume identity

Existing records list all four array target WWNs under each initiator, even where a given HBA only sees two of them. That is the 3PAR driver's own convention — replicate that layout rather than modelling per-HBA zoning. Paths that do not resolve are tolerated and only produce a warning.

Diagnostics

While the VM is still Running, every command in this section is read-only and safe. The domain is only alive because nothing has re-read the BDM yet. Capture the live multipath output before anything stops the VM — those paths are the cheapest source of the correct LUN.

1

Step 1 — Confirm the VM state and capture the migration failure

Record the state fields and the host the Compute Service believes is running the VM.

Identify the failed live-migration event and record the reason for the failure. The failure reason does not block the repair, but a repaired VM must not be live-migrated again until the original error is understood.

On the source compute host, search the Compute Service log for the instance and request ID:

A migration that fails with No valid host was found. There are not enough hosts available fails at the scheduler, before a destination is chosen. pre_live_migration never runs in that case and the BDM is intact — those VMs usually need only a state reset. Check such instances with the detection queries in Region-Wide Detection Queries anyway, because an earlier attempt on the same instance may have progressed further. Leaked Placement allocations from prior failed migrations are a common cause of that scheduler message.

2

Step 2 — Locate the running domain

Do not trust the OS-EXT-SRV-ATTR:host value on its own. Run the following on every host that appears as a source or destination in the migration history.

Exactly one host must show the domain. If more than one host has the domain defined, stop and treat the situation as a potential dual-writer before going further.

3

Step 3 — Read the Compute Service BDM record

Self-Hosted only: This step requires direct access to the control plane. SaaS customers cannot perform this step independently — contact Platform9 Support to have this completed on your behalf.

Record, per volume: volume_id, attachment_id, data.target_lun, the keys of data.initiator_target_map, and data.multipath_id. The multipath_id value is the array WWID and is host-independent, so the WWID is a safe lookup key even when every other value in the record is wrong.

4

Step 4 — Read the Block Storage Service attachment records

Self-Hosted only: This step requires direct access to the control plane. SaaS customers cannot perform this step independently — contact Platform9 Support to have this completed on your behalf.

Note every connector host, the attach_status, and the deleted flag. Each row with attach_status: attached on a non-multiattach volume is a live VLUN on the array, not a stale database row.

5

Step 5 — Read the host's storage identity

Run on the host that holds the domain (from Step 2). Use the WWID from data.multipath_id in Step 3.

The last field of the H:C:T:L column on the path lines is the real LUN for this host. The port_name values are the initiator WWPNs of this host.

A multipath -ll entry printing ##,## instead of 3PARdata,VV has lost all paths — multipath cannot read vendor strings without a live path. That is local device state, not an array unmap. If the Block Storage Service still shows the attachment as attached, the array mapping is intact.

6

Step 6 — Compare the records

Any one of the following three mismatches confirms the corruption:

  • The BDM attachment_id (Step 3) resolves to a cinder.volume_attachment row (Step 4) whose connector host is not the host holding the domain (Step 2)

  • connection_info.data.target_lun (Step 3) differs from the H:C:T:L LUN of multipath -ll <WWID> on the host holding the domain (Step 5)

  • The keys of initiator_target_map (Step 3) are WWPNs that do not appear in /sys/class/fc_host/host*/port_name on the host holding the domain (Step 5)

Supporting evidence: a non-multiattach volume with several attached attachment rows (Step 4), and an instance in vm_state: error with power_state: Running whose launched_at predates the migrations.

If all checks above match, proceed to Workaround.

Region-Wide Detection Queries

The Compute Service and Block Storage Service share a MariaDB instance, so every affected instance in a region can be detected with cross-database queries instead of inspecting instances one by one.

Self-Hosted only: These queries require direct access to the control plane. SaaS customers cannot perform this step independently — contact Platform9 Support to have this completed on your behalf.

BDM points at another host's attachment — every row returned is an instance that will fail to boot and will act on an unrelated LUN when a start is attempted:

Leaked multi-host mappings on non-multiattach volumes:

Live migrations that did not complete cleanly — the population at risk:

Resolution

No product fix is tracked for this condition at this time. Correct the BDM record and clear the leaked attachments using the Workaround below.

The workaround does not address the reason the live migration failed. Two failures on one instance mean a third is coming — identify the original migration error from Step 1 of Diagnostics before live-migrating the repaired VM again.

Workaround

The repair path depends on whether the source host's attachment is still alive. From Step 4 of Diagnostics, find the attachment whose connector host is the host holding the domain:

  • attach_status = attached and deleted = 0 — the Block Storage Service never ran terminate_connection for that host, so the VLUN still exists on the array. Any missing paths are local state only, recoverable with an FC rescan. This is the common case, and the steps below apply.

  • No such row, or deleted = 1 — the source attachment and the array VLUN were removed. The mapping must be recreated by the Block Storage Service with a fresh attachment. The steps below do not apply — contact Platform9 Support. See Additional Information.

1

Step 1 — Clear pathless multipath map shells

Run on the host holding the domain. Only remove maps with zero paths, and only once the domain is stopped or already destroyed. A map with live paths is the real mapping — leave that map alone.

2

Step 2 — Rescan the Fibre Channel HBAs

The rescan is additive and safe: the rescan re-probes targets and adds what is found, never removes. The loop is scoped to FC hosts rather than every SCSI host.

3

Step 3 — Read the true LUN for each volume

Run once per volume, one WWID per invocation.

For a general procedure to map a volume to a LUN ID, see How to Identify the LUN ID Associated with an Instance Volume.

Expect four active ready running paths. The last field of H:C:T:L on those path lines is the LUN to write into the BDM record. Never carry a LUN number from another host and never infer one host's LUN from another's.

4

Step 4 — Back up the BDM rows

Self-Hosted only: Steps 4 through 6 require direct access to the control plane. SaaS customers cannot perform these steps independently — contact Platform9 Support to have them completed on your behalf.

The backup is mandatory before the UPDATE.

5

Step 5 — Correct the BDM record

Run one UPDATE per volume. The statement repoints attachment_id at the attachment of the host holding the domain and rewrites all four LUN-bearing fields plus the initiator WWPNs.

Substitute every value for the host in front of you:

  • <LUN> — from Step 3

  • <CORRECT_HOST_ATTACHMENT_UUID> — the id of the attachment whose connector host holds the domain, from Step 4 of Diagnostics

  • <TARGET_WWN_1> to <TARGET_WWN_4> — the four array target WWNs already present in the existing record's data.target_wwn

  • <INITIATOR_1> and <INITIATOR_2> — the two port_name values from /sys/class/fc_host/ on the host holding the domain, from Step 5 of Diagnostics

6

Step 6 — Verify the corrected record

Expect the correct attachment, the LUN read from the rescan, and only the local host's initiators.

7

Step 7 — Start the VM while tailing the Compute Service log

In a second session on the host holding the domain, tail the log before issuing any state change:

The VM must be in stopped state before the start. Reset the state only if the VM is in error, then stop, then start.

For background on state resets, see How To Reset Volume States.

The disconnect_volume call inside _hard_reboot is the step that fails on a corrupt record. With the corrected record the call walks the correct LUNs and passes.

8

Step 8 — Confirm the domain's backing devices

Confirm the guest is on the right disks, then confirm the guest answers on its own addresses.

9

Step 9 — Delete the leaked attachments

Delete each attachment belonging to a host that is not holding the domain. Use the API — the API drives the driver's terminate_connection, which is what actually removes the VLUN from the array.

Confirm one attachment per volume, on the host holding the domain:

Confirm the maps are gone on each former destination host:

10

Step 10 — Clear leaked Placement allocations

Self-Hosted only: This step requires direct access to the control plane. SaaS customers cannot perform this step independently — contact Platform9 Support to have this completed on your behalf.

11

Step 11 — Check the collateral victims

If the VM was started or rebooted while the record was corrupt, os-brick removed SCSI paths from whatever volumes occupied the stale LUN numbers on the host. The FC rescan in Step 2 restores those paths, but confirm the path counts — another VM may be running degraded.

Identify what sat at each stale LUN on the host holding the domain, then check that volume's health:

Find which instance owns the victim volume:

Self-Hosted only: This query requires direct access to the control plane. SaaS customers cannot perform this step independently — contact Platform9 Support to have this completed on your behalf.

Additional Information

Source attachment removed (deleted = 1 or no row): When the source host's attachment has been deleted, the array VLUN was removed by terminate_connection and the mapping must be recreated by the Block Storage Service with a fresh attachment rather than a corrected record. This is a longer procedure — contact Platform9 Support. The sequence in that case is: SQL-patch connection_info to a LUN that resolves to nothing on the host so the disconnect no-ops harmlessly, then run nova-manage volume_attachment refresh, then start the VM.

Why nova-manage volume_attachment refresh is the wrong tool for a corrupt record: The command exists to regenerate connection_info from a host connector and would produce correct values, but the command cannot run against a corrupt record. _do_refresh sends remove_volume_connection to the compute host before creating the new attachment, and that disconnect uses the current, wrong connection_info. remove_volume_connection swallows only exception.NotFound, so os-brick's ExceptionChainer propagates and aborts the command. The finally block then leaves the BDM with a blank attachment_id and connection_info = NULL, which is strictly worse: the instance cannot start at all until a refresh succeeds. When the source attachment is intact, correct the record with SQL and skip refresh entirely.

If refresh is run, four traps apply:

Trap
Consequence
Handling

CONF.host read from the wrong config

Exit 7, HostConflict — Private Cloud Director sets instance.host to the host UUID, but nova-manage defaults to /etc/nova/nova.conf and yields the bare hostname

Always pass --config-dir /opt/pf9/etc/nova/conf.d

get_connector has no --path option

Writes nothing; prints the connector

Redirect: get_connector --json > file

enforce_multipath=True is hardcoded

Raises if multipathd is down

Check systemctl is-active multipathd first

Requires vm_state == stopped exactly

Exit 5 on error

Reset to active, then stop

get_connector runs on the hypervisor; refresh needs database and Block Storage Service access, so refresh runs in a Compute Service pod on the control plane. The connector file has to be copied across.

Applicability: The mechanism is the same on any array with per-host LUN numbering, including NetApp ONTAP igroups; only the array-side vocabulary changes. For NetApp iSCSI backends, follow the iSCSI article linked below.

Duplicate iSCSI initiator names: In the originating case, both destination hosts reported the same iSCSI IQN — a cloned host image whose /etc/iscsi/initiatorname.iscsi was never regenerated. Harmless for Fibre Channel, dangerous the day either host touches an iSCSI backend. See the related article below.

Last updated