8484import org .apache .cloudstack .utils .reflectiontostringbuilderutils .ReflectionToStringBuilderUtils ;
8585import org .apache .commons .collections .CollectionUtils ;
8686import org .apache .commons .collections .MapUtils ;
87+ import org .apache .commons .lang .BooleanUtils ;
8788import org .apache .commons .lang3 .ObjectUtils ;
8889import org .apache .commons .lang3 .StringUtils ;
8990import org .apache .log4j .Logger ;
@@ -1496,7 +1497,7 @@ public boolean storageMigration(VirtualMachineProfile vm, Map<Volume, StoragePoo
14961497 }
14971498
14981499 @ Override
1499- public void prepareForMigration (VirtualMachineProfile vm , DeployDestination dest ) {
1500+ public void prepareForMigration (VirtualMachineProfile vm , DeployDestination dest , Long srcHostId ) {
15001501 List <VolumeVO > vols = _volsDao .findUsableVolumesForInstance (vm .getId ());
15011502 if (s_logger .isDebugEnabled ()) {
15021503 s_logger .debug (String .format ("Preparing to migrate [%s] volumes for VM [%s]." , vols .size (), vm .getVirtualMachine ()));
@@ -1514,7 +1515,7 @@ public void prepareForMigration(VirtualMachineProfile vm, DeployDestination dest
15141515 // make sure this is done AFTER grantAccess, as grantAccess may change the volume's state
15151516 DataTO volTO = volumeInfo .getTO ();
15161517 DiskTO disk = storageMgr .getDiskWithThrottling (volTO , vol .getVolumeType (), vol .getDeviceId (), vol .getPath (), vm .getServiceOfferingId (), vol .getDiskOfferingId ());
1517- disk .setDetails (getDetails (volumeInfo , dataStore ));
1518+ disk .setDetails (getDetails (volumeInfo , dataStore , vm , srcHostId ));
15181519 vm .addDisk (disk );
15191520 }
15201521
@@ -1527,7 +1528,7 @@ public void prepareForMigration(VirtualMachineProfile vm, DeployDestination dest
15271528 }
15281529 }
15291530
1530- private Map <String , String > getDetails (VolumeInfo volumeInfo , DataStore dataStore ) {
1531+ private Map <String , String > getDetails (VolumeInfo volumeInfo , DataStore dataStore , VirtualMachineProfile vmProfile , Long srcHostId ) {
15311532 Map <String , String > details = new HashMap <String , String >();
15321533
15331534 StoragePoolVO storagePool = _storagePoolDao .findById (dataStore .getId ());
@@ -1560,6 +1561,17 @@ private Map<String, String> getDetails(VolumeInfo volumeInfo, DataStore dataStor
15601561 details .put (DiskTO .CHAP_TARGET_SECRET , chapInfo .getTargetSecret ());
15611562 }
15621563
1564+ // Zone wide storage Solidfire inter-cluster VM migrations needs the destination host mount the LUN before migrating
1565+ if (storagePool .isManaged () && storagePool .getScope () != null && ScopeType .ZONE == storagePool .getScope ()) {
1566+ details .put (DiskTO .SCOPE , storagePool .getScope ().name ());
1567+ if (vmProfile .getHostId () != null && srcHostId != null ) {
1568+ HostVO host = _hostDao .findById (vmProfile .getHostId ());
1569+ HostVO lastHost = _hostDao .findById (srcHostId );
1570+ boolean interClusterMigration = isVmwareInterClusterMigration (lastHost , host );
1571+ details .put (DiskTO .INTER_CLUSTER_MIGRATION , BooleanUtils .toStringTrueFalse (interClusterMigration ));
1572+ }
1573+ }
1574+
15631575 return details ;
15641576 }
15651577
@@ -1937,7 +1949,7 @@ public void prepare(VirtualMachineProfile vm, DeployDestination dest) throws Sto
19371949 DiskTO disk = storageMgr .getDiskWithThrottling (volTO , vol .getVolumeType (), vol .getDeviceId (), vol .getPath (), vm .getServiceOfferingId (), vol .getDiskOfferingId ());
19381950 DataStore dataStore = dataStoreMgr .getDataStore (vol .getPoolId (), DataStoreRole .Primary );
19391951
1940- disk .setDetails (getDetails (volumeInfo , dataStore ));
1952+ disk .setDetails (getDetails (volumeInfo , dataStore , vm , null ));
19411953
19421954 vm .addDisk (disk );
19431955
@@ -2308,4 +2320,52 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
23082320 }
23092321 });
23102322 }
2323+
2324+ protected boolean isVmwareInterClusterMigration (Host lastHost , Host host ) {
2325+ if (ObjectUtils .anyNull (lastHost , host )) {
2326+ return false ;
2327+ }
2328+ if (host .getHypervisorType () != HypervisorType .VMware ) {
2329+ return false ;
2330+ }
2331+ Long lastHostClusterId = lastHost .getClusterId ();
2332+ Long clusterId = host .getClusterId ();
2333+ if (ObjectUtils .anyNull (lastHostClusterId , clusterId )) {
2334+ return false ;
2335+ }
2336+ return lastHostClusterId .compareTo (clusterId ) != 0 ;
2337+ }
2338+
2339+ @ Override
2340+ public List <String > postMigrationReleaseDatastoresOnOriginHost (VirtualMachineProfile profile , long vmId ) {
2341+ List <String > pools = new ArrayList <>();
2342+ if (profile .getVirtualMachine () == null ) {
2343+ s_logger .debug ("Cannot release from source as the virtual machine profile is not set" );
2344+ return pools ;
2345+ }
2346+ HostVO lastHost = _hostDao .findById (profile .getVirtualMachine ().getLastHostId ());
2347+ HostVO host = _hostDao .findById (profile .getHostId ());
2348+
2349+ // Consider only Vmware inter-cluster migration
2350+ if (!isVmwareInterClusterMigration (lastHost , host )) {
2351+ return pools ;
2352+ }
2353+
2354+ List <VolumeVO > volumesForVm = _volsDao .findUsableVolumesForInstance (vmId );
2355+ for (VolumeVO volumeForVm : volumesForVm ) {
2356+ if (volumeForVm .getPoolId () != null ) {
2357+ DataStore dataStore = dataStoreMgr .getDataStore (volumeForVm .getPoolId (), DataStoreRole .Primary );
2358+ PrimaryDataStore primaryDataStore = (PrimaryDataStore ) dataStore ;
2359+ if (primaryDataStore .getScope () != null && primaryDataStore .getScope ().getScopeType () == ScopeType .ZONE ) {
2360+ // Consider zone-wide storage
2361+ PrimaryDataStoreDriver driver = (PrimaryDataStoreDriver ) primaryDataStore .getDriver ();
2362+ if (driver .zoneWideVolumesDatastoreCleanupOnOriginHostAfterInterClusterMigration ()) {
2363+ // Currently enabled for SolidFire only on inter-cluster migrations on zone-wide pools.
2364+ pools .add (volumeForVm .get_iScsiName ());
2365+ }
2366+ }
2367+ }
2368+ }
2369+ return pools ;
2370+ }
23112371}
0 commit comments