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 showfor a non-multiattach volume lists two or more attachments, each on a different hostopenstack server event listshows one or morelive-migrationevents with a failure statusThe
launched_attimestamp of the instance predates the failed migrations, indicating the domain never moved
Do not start, hard-reboot, live-migrate, or reset the state of the affected VM before completing the Workaround. Each of these operations reads the corrupt Block Device Mapping and can remove SCSI paths from an unrelated volume that is in use by another VM on the same host.
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:
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.
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:
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.
Step 3 — Read the Compute Service BDM record
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.
Step 6 — Compare the records
Any one of the following three mismatches confirms the corruption:
The BDM
attachment_id(Step 3) resolves to acinder.volume_attachmentrow (Step 4) whose connector host is not the host holding the domain (Step 2)connection_info.data.target_lun(Step 3) differs from theH:C:T:LLUN ofmultipath -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_nameon 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.
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 = attachedanddeleted = 0— the Block Storage Service never ranterminate_connectionfor 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.
Repair the BDM first and reset the VM state last. openstack server set --state active followed by a retry clears the symptom, leaves the cause in place, and turns one leaked attachment per volume into two.
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.
multipath -f on a map that still has live paths removes the device backing a running VM. Confirm the map prints ##,## with no path lines before flushing.
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.
Do not run a global multipath -r. The global reload suspends every map on the host, briefly interrupting every other VM's devices. multipathd picks up new devices from uevents on its own. If a specific map does not reappear after approximately 30 seconds, add only that one map: sudo multipathd add map <WWID>.
Step 3 — Read the true LUN for each volume
Run once per volume, one WWID per invocation.
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.
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>— theidof 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'sdata.target_wwn<INITIATOR_1>and<INITIATOR_2>— the twoport_namevalues from/sys/class/fc_host/on the host holding the domain, from Step 5 of Diagnostics
Repointing attachment_id matters as much as the LUN. If attachment_id is left on the destination's attachment, a later detach or delete removes the wrong attachment and orphans the live VLUN — the same failure in reverse.
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.
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.
Step 9 — Delete the leaked attachments
The incident is not closed until this step runs. A booted VM with the leaked attachments still in place means a non-multiattach volume is exposed read-write to two or three hosts. That is the data-corruption risk the whole repair exists to remove.
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.
Never delete volume_attachment rows with SQL. A database delete skips terminate_connection and orphans the array export permanently, with no record left to clean up from. Editing connection_info is a different and much smaller risk; deleting attachments is not.
Confirm one attachment per volume, on the host holding the domain:
Confirm the maps are gone on each former destination host:
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:
The repair is complete when the VM is ACTIVE, virsh domblklist shows the expected multipath devices, every affected volume shows exactly one attachment on the host holding the domain, no maps for the volume remain on former destination hosts, and every collateral-victim volume shows four active ready running paths.
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:
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.
Related articles
VM Fails to Start After Live Migration Failure Due to iSCSI BDM Corruption — the same failure on NetApp ONTAP iSCSI backends. The SQL in that article patches
target_lunandtarget_lunsonly;target_lunsdoes not exist in Fibre Channel records, so that SQL must not be used for Fibre Channel volumes.How to Identify the LUN ID Associated with an Instance Volume — general procedure for mapping a volume to a LUN ID on a compute host.
Unable to Start VM due to Multipath issue — recovery of stale multipath devices blocking a VM start.
How To Reset Volume States — resetting volumes stuck in intermediate states.
How to Rename iSCSI Initiator Names to the Existing Hypervisors — regenerating duplicate IQNs on cloned hosts.
Last updated
