Skip to content

Commit ab78f7b

Browse files
committed
linstor: add LinstorDataMotionStrategy for live migration
Add a new DataMotionStrategy implementation that enables VM live migration when the destination storage pool is Linstor (DRBD). Without this strategy, CloudStack's storage migration framework had no code path to handle live migrations *to* Linstor pools, leaving three scenarios broken: - Linstor -> Linstor: blocked (no strategy claimed it) - SMP -> Linstor: DEFECT (KvmNonManagedDMS claimed it but generated wrong DiskType=FILE/DriverType=QCOW2 and an invalid device path using the resource group name instead of a DRBD block device path) - StorPool -> Linstor: blocked (no strategy claimed it) How strategy selection works: CloudStack iterates all DataMotionStrategy beans and picks the one returning the highest StrategyPriority from canHandle(). The existing strategies return: - StorPoolDMS: HIGHEST only when ALL dest pools are StorPool - KvmNonManagedDMS: HYPERVISOR only for {NFS, SMP, Filesystem} - StorageSystemDMS: only for managed (isManaged=true) pools - AncientDMS: DEFAULT (fallback, copies via secondary storage) LinstorDataMotionStrategy returns HIGHEST when ALL destination pools are Linstor, giving it priority over KvmNonManagedDMS (HYPERVISOR=2) and AncientDMS (DEFAULT=1), while not conflicting with StorPoolDMS. canHandle semantics: Offline (DataObject, DataObject): Always returns CANT_HANDLE. Offline volume copies continue to use existing paths (AncientDMS or driver canCopy). A native Linstor offline copy (e.g. DRBD clone) can be added in a future commit. Live (Map<VolumeInfo,DataStore>, Host, Host): Returns HIGHEST when ALL destination DataStores are Linstor pools. The source pools can be anything (Linstor, StorPool, SMP, NFS, ...), enabling cross-storage live migration *to* Linstor. Live migration flow (copyAsync with volumeMap): For each volume in the migration set: 1. Create a destination VolumeVO record in the database (duplicateVolumeOnAnotherStorage). 2. If cross-storage (src is not Linstor, or different Linstor controller): create a new DRBD resource via the Linstor REST API (resourceGroupSpawn on the destination pool's resource group). 3. Ensure the resource is available on the destination KVM host (resourceMakeAvailableOnNode). For same-controller Linstor->Linstor, DRBD already has the data replicated so this is a lightweight diskless attach or no-op. 4. Set DRBD allow-two-primaries so both source and destination hosts can have the device open read-write simultaneously during migration. Uses ResourceDefinition-level properties when both nodes are diskless (DRBD client topology), or ResourceConnection-level properties when nodes are hyperconverged (have local disks). 5. Build MigrateDiskInfo with DiskType=BLOCK, DriverType=RAW, Source=DEV, and destPath=/dev/drbd/by-res/<rscName>/0. This tells libvirt's replaceStorage() to modify the VM's disk XML for block-copy migration. 6. Send PrepareForMigrationCommand to destination host, then MigrateCommand (with migrateStorageManaged=true) to source host. Libvirt performs the actual block copy using VIR_MIGRATE_NON_SHARED_DISK. Post-migration success: - Remove allow-two-primaries from all resources - Swap volume UUIDs between source and destination (updateUuid) - Destroy and expunge source volumes - Update snapshot references to point to new volume IDs Post-migration failure: - Remove allow-two-primaries - Delete destination Linstor resources unconditionally (not just diskless) - Delete resource definitions if no resources remain - Expunge destination volumes (DB records) - Rollback PrepareForMigration on destination host Error handling: - On early failure (before MigrateCommand), handlePostMigration(false) is called from the catch block to ensure Linstor resources are cleaned up and not left orphaned. - viewResources API errors are logged as warnings and creation is attempted regardless (rather than silently assuming resource absence). - applyAuxProps errors are logged but non-fatal. Spring context: Register the LinstorDataMotionStrategy bean in spring-storage-volume-linstor-context.xml so StorageStrategyFactoryImpl discovers it via auto-wiring. Files: - NEW: plugins/storage/volume/linstor/src/main/java/org/apache/ cloudstack/storage/motion/LinstorDataMotionStrategy.java - MOD: plugins/storage/volume/linstor/src/main/resources/META-INF/ cloudstack/storage-volume-linstor/ spring-storage-volume-linstor-context.xml
1 parent 13a4950 commit ab78f7b

File tree

2 files changed

+582
-0
lines changed

2 files changed

+582
-0
lines changed

0 commit comments

Comments
 (0)