mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	Fix migration from local storage to NFS in KVM (#8909)
* fix migration from local to nfs * remove unused imports * remove dead code
This commit is contained in:
		
							parent
							
								
									f944d4c61d
								
							
						
					
					
						commit
						3e30283500
					
				| @ -70,7 +70,6 @@ import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; | |||||||
| import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; | import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; | ||||||
| import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; | import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; | ||||||
| import org.apache.cloudstack.storage.to.VolumeObjectTO; | import org.apache.cloudstack.storage.to.VolumeObjectTO; | ||||||
| import org.apache.commons.collections.MapUtils; |  | ||||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||||
| import org.apache.log4j.Logger; | import org.apache.log4j.Logger; | ||||||
| 
 | 
 | ||||||
| @ -82,7 +81,6 @@ import com.cloud.agent.api.MigrateCommand.MigrateDiskInfo; | |||||||
| import com.cloud.agent.api.ModifyTargetsAnswer; | import com.cloud.agent.api.ModifyTargetsAnswer; | ||||||
| import com.cloud.agent.api.ModifyTargetsCommand; | import com.cloud.agent.api.ModifyTargetsCommand; | ||||||
| import com.cloud.agent.api.PrepareForMigrationCommand; | import com.cloud.agent.api.PrepareForMigrationCommand; | ||||||
| import com.cloud.agent.api.storage.CheckStorageAvailabilityCommand; |  | ||||||
| import com.cloud.agent.api.storage.CopyVolumeAnswer; | import com.cloud.agent.api.storage.CopyVolumeAnswer; | ||||||
| import com.cloud.agent.api.storage.CopyVolumeCommand; | import com.cloud.agent.api.storage.CopyVolumeCommand; | ||||||
| import com.cloud.agent.api.storage.MigrateVolumeAnswer; | import com.cloud.agent.api.storage.MigrateVolumeAnswer; | ||||||
| @ -1909,7 +1907,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy { | |||||||
|                 throw new CloudRuntimeException("Invalid hypervisor type (only KVM supported for this operation at the time being)"); |                 throw new CloudRuntimeException("Invalid hypervisor type (only KVM supported for this operation at the time being)"); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             verifyLiveMigrationForKVM(volumeDataStoreMap, destHost); |             verifyLiveMigrationForKVM(volumeDataStoreMap); | ||||||
| 
 | 
 | ||||||
|             VMInstanceVO vmInstance = _vmDao.findById(vmTO.getId()); |             VMInstanceVO vmInstance = _vmDao.findById(vmTO.getId()); | ||||||
|             vmTO.setState(vmInstance.getState()); |             vmTO.setState(vmInstance.getState()); | ||||||
| @ -1983,8 +1981,8 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy { | |||||||
| 
 | 
 | ||||||
|                 MigrateCommand.MigrateDiskInfo migrateDiskInfo; |                 MigrateCommand.MigrateDiskInfo migrateDiskInfo; | ||||||
| 
 | 
 | ||||||
|                 boolean isNonManagedNfsToNfsOrSharedMountPointToNfs = supportStoragePoolType(sourceStoragePool.getPoolType()) && destStoragePool.getPoolType() == StoragePoolType.NetworkFilesystem && !managedStorageDestination; |                 boolean isNonManagedToNfs = supportStoragePoolType(sourceStoragePool.getPoolType(), StoragePoolType.Filesystem) && destStoragePool.getPoolType() == StoragePoolType.NetworkFilesystem && !managedStorageDestination; | ||||||
|                 if (isNonManagedNfsToNfsOrSharedMountPointToNfs) { |                 if (isNonManagedToNfs) { | ||||||
|                     migrateDiskInfo = new MigrateCommand.MigrateDiskInfo(srcVolumeInfo.getPath(), |                     migrateDiskInfo = new MigrateCommand.MigrateDiskInfo(srcVolumeInfo.getPath(), | ||||||
|                             MigrateCommand.MigrateDiskInfo.DiskType.FILE, |                             MigrateCommand.MigrateDiskInfo.DiskType.FILE, | ||||||
|                             MigrateCommand.MigrateDiskInfo.DriverType.QCOW2, |                             MigrateCommand.MigrateDiskInfo.DriverType.QCOW2, | ||||||
| @ -2363,9 +2361,8 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy { | |||||||
|     * At a high level: The source storage cannot be managed and |     * At a high level: The source storage cannot be managed and | ||||||
|     *                  the destination storages can be all managed or all not managed, not mixed. |     *                  the destination storages can be all managed or all not managed, not mixed. | ||||||
|     */ |     */ | ||||||
|     protected void verifyLiveMigrationForKVM(Map<VolumeInfo, DataStore> volumeDataStoreMap, Host destHost) { |     protected void verifyLiveMigrationForKVM(Map<VolumeInfo, DataStore> volumeDataStoreMap) { | ||||||
|         Boolean storageTypeConsistency = null; |         Boolean storageTypeConsistency = null; | ||||||
|         Map<String, Storage.StoragePoolType> sourcePools = new HashMap<>(); |  | ||||||
|         for (Map.Entry<VolumeInfo, DataStore> entry : volumeDataStoreMap.entrySet()) { |         for (Map.Entry<VolumeInfo, DataStore> entry : volumeDataStoreMap.entrySet()) { | ||||||
|             VolumeInfo volumeInfo = entry.getKey(); |             VolumeInfo volumeInfo = entry.getKey(); | ||||||
| 
 | 
 | ||||||
| @ -2392,47 +2389,6 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy { | |||||||
|             } else if (storageTypeConsistency != destStoragePoolVO.isManaged()) { |             } else if (storageTypeConsistency != destStoragePoolVO.isManaged()) { | ||||||
|                 throw new CloudRuntimeException("Destination storage pools must be either all managed or all not managed"); |                 throw new CloudRuntimeException("Destination storage pools must be either all managed or all not managed"); | ||||||
|             } |             } | ||||||
| 
 |  | ||||||
|             addSourcePoolToPoolsMap(sourcePools, srcStoragePoolVO, destStoragePoolVO); |  | ||||||
|         } |  | ||||||
|         verifyDestinationStorage(sourcePools, destHost); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Adds source storage pool to the migration map if the destination pool is not managed and it is NFS. |  | ||||||
|      */ |  | ||||||
|     protected void addSourcePoolToPoolsMap(Map<String, Storage.StoragePoolType> sourcePools, StoragePoolVO srcStoragePoolVO, StoragePoolVO destStoragePoolVO) { |  | ||||||
|         if (destStoragePoolVO.isManaged() || !StoragePoolType.NetworkFilesystem.equals(destStoragePoolVO.getPoolType())) { |  | ||||||
|             LOGGER.trace(String.format("Skipping adding source pool [%s] to map due to destination pool [%s] is managed or not NFS.", srcStoragePoolVO, destStoragePoolVO)); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         String sourceStoragePoolUuid = srcStoragePoolVO.getUuid(); |  | ||||||
|         if (!sourcePools.containsKey(sourceStoragePoolUuid)) { |  | ||||||
|             sourcePools.put(sourceStoragePoolUuid, srcStoragePoolVO.getPoolType()); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Perform storage validation on destination host for KVM live storage migrations. |  | ||||||
|      * Validate that volume source storage pools are mounted on the destination host prior the migration |  | ||||||
|      * @throws CloudRuntimeException if any source storage pool is not mounted on the destination host |  | ||||||
|      */ |  | ||||||
|     private void verifyDestinationStorage(Map<String, Storage.StoragePoolType> sourcePools, Host destHost) { |  | ||||||
|         if (MapUtils.isNotEmpty(sourcePools)) { |  | ||||||
|             LOGGER.debug("Verifying source pools are already available on destination host " + destHost.getUuid()); |  | ||||||
|             CheckStorageAvailabilityCommand cmd = new CheckStorageAvailabilityCommand(sourcePools); |  | ||||||
|             try { |  | ||||||
|                 Answer answer = agentManager.send(destHost.getId(), cmd); |  | ||||||
|                 if (answer == null || !answer.getResult()) { |  | ||||||
|                     throw new CloudRuntimeException("Storage verification failed on host " |  | ||||||
|                             + destHost.getUuid() +": " + answer.getDetails()); |  | ||||||
|                 } |  | ||||||
|             } catch (AgentUnavailableException | OperationTimedoutException e) { |  | ||||||
|                 e.printStackTrace(); |  | ||||||
|                 throw new CloudRuntimeException("Cannot perform storage verification on host " + destHost.getUuid() + |  | ||||||
|                         "due to: " + e.getMessage()); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -476,19 +476,19 @@ public class KvmNonManagedStorageSystemDataMotionTest { | |||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|     public void testVerifyLiveMigrationMapForKVM() { |     public void testVerifyLiveMigrationMapForKVM() { | ||||||
|         kvmNonManagedStorageDataMotionStrategy.verifyLiveMigrationForKVM(migrationMap, host2); |         kvmNonManagedStorageDataMotionStrategy.verifyLiveMigrationForKVM(migrationMap); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test(expected = CloudRuntimeException.class) |     @Test(expected = CloudRuntimeException.class) | ||||||
|     public void testVerifyLiveMigrationMapForKVMNotExistingSource() { |     public void testVerifyLiveMigrationMapForKVMNotExistingSource() { | ||||||
|         when(primaryDataStoreDao.findById(POOL_1_ID)).thenReturn(null); |         when(primaryDataStoreDao.findById(POOL_1_ID)).thenReturn(null); | ||||||
|         kvmNonManagedStorageDataMotionStrategy.verifyLiveMigrationForKVM(migrationMap, host2); |         kvmNonManagedStorageDataMotionStrategy.verifyLiveMigrationForKVM(migrationMap); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test(expected = CloudRuntimeException.class) |     @Test(expected = CloudRuntimeException.class) | ||||||
|     public void testVerifyLiveMigrationMapForKVMNotExistingDest() { |     public void testVerifyLiveMigrationMapForKVMNotExistingDest() { | ||||||
|         when(primaryDataStoreDao.findById(POOL_2_ID)).thenReturn(null); |         when(primaryDataStoreDao.findById(POOL_2_ID)).thenReturn(null); | ||||||
|         kvmNonManagedStorageDataMotionStrategy.verifyLiveMigrationForKVM(migrationMap, host2); |         kvmNonManagedStorageDataMotionStrategy.verifyLiveMigrationForKVM(migrationMap); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test(expected = CloudRuntimeException.class) |     @Test(expected = CloudRuntimeException.class) | ||||||
| @ -497,7 +497,7 @@ public class KvmNonManagedStorageSystemDataMotionTest { | |||||||
|         when(pool1.getId()).thenReturn(POOL_1_ID); |         when(pool1.getId()).thenReturn(POOL_1_ID); | ||||||
|         when(pool2.getId()).thenReturn(POOL_2_ID); |         when(pool2.getId()).thenReturn(POOL_2_ID); | ||||||
|         lenient().when(pool2.isManaged()).thenReturn(false); |         lenient().when(pool2.isManaged()).thenReturn(false); | ||||||
|         kvmNonManagedStorageDataMotionStrategy.verifyLiveMigrationForKVM(migrationMap, host2); |         kvmNonManagedStorageDataMotionStrategy.verifyLiveMigrationForKVM(migrationMap); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|  | |||||||
| @ -23,7 +23,6 @@ import static org.junit.Assert.assertFalse; | |||||||
| import static org.mockito.Mockito.doReturn; | import static org.mockito.Mockito.doReturn; | ||||||
| import static org.mockito.Mockito.lenient; | import static org.mockito.Mockito.lenient; | ||||||
| import static org.mockito.Mockito.mock; | import static org.mockito.Mockito.mock; | ||||||
| import static org.mockito.Mockito.never; |  | ||||||
| import static org.mockito.MockitoAnnotations.initMocks; | import static org.mockito.MockitoAnnotations.initMocks; | ||||||
| 
 | 
 | ||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
| @ -48,7 +47,6 @@ import org.mockito.Mock; | |||||||
| import org.mockito.Mockito; | import org.mockito.Mockito; | ||||||
| import org.mockito.Spy; | import org.mockito.Spy; | ||||||
| import org.mockito.runners.MockitoJUnitRunner; | import org.mockito.runners.MockitoJUnitRunner; | ||||||
| import org.mockito.verification.VerificationMode; |  | ||||||
| 
 | 
 | ||||||
| import com.cloud.agent.api.MigrateCommand; | import com.cloud.agent.api.MigrateCommand; | ||||||
| import com.cloud.host.HostVO; | import com.cloud.host.HostVO; | ||||||
| @ -62,7 +60,6 @@ import com.cloud.storage.VolumeVO; | |||||||
| import java.util.AbstractMap; | import java.util.AbstractMap; | ||||||
| import java.util.Arrays; | import java.util.Arrays; | ||||||
| import java.util.HashSet; | import java.util.HashSet; | ||||||
| import java.util.LinkedList; |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
| 
 | 
 | ||||||
| @ -372,72 +369,4 @@ public class StorageSystemDataMotionStrategyTest { | |||||||
| 
 | 
 | ||||||
|         assertFalse(strategy.isStoragePoolTypeInList(StoragePoolType.SharedMountPoint, listTypes)); |         assertFalse(strategy.isStoragePoolTypeInList(StoragePoolType.SharedMountPoint, listTypes)); | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     @Test |  | ||||||
|     public void validateAddSourcePoolToPoolsMapDestinationPoolIsManaged() { |  | ||||||
|         Mockito.doReturn(true).when(destinationStoragePoolVoMock).isManaged(); |  | ||||||
|         strategy.addSourcePoolToPoolsMap(mapStringStoragePoolTypeMock, sourceStoragePoolVoMock, destinationStoragePoolVoMock); |  | ||||||
| 
 |  | ||||||
|         Mockito.verify(destinationStoragePoolVoMock).isManaged(); |  | ||||||
|         Mockito.verifyNoMoreInteractions(mapStringStoragePoolTypeMock, sourceStoragePoolVoMock, destinationStoragePoolVoMock); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Test |  | ||||||
|     public void validateAddSourcePoolToPoolsMapDestinationPoolIsNotNFS() { |  | ||||||
|         List<StoragePoolType> storagePoolTypes = new LinkedList<>(Arrays.asList(StoragePoolType.values())); |  | ||||||
|         storagePoolTypes.remove(StoragePoolType.NetworkFilesystem); |  | ||||||
| 
 |  | ||||||
|         Mockito.doReturn(false).when(destinationStoragePoolVoMock).isManaged(); |  | ||||||
|         storagePoolTypes.forEach(poolType -> { |  | ||||||
|             Mockito.doReturn(poolType).when(destinationStoragePoolVoMock).getPoolType(); |  | ||||||
|             strategy.addSourcePoolToPoolsMap(mapStringStoragePoolTypeMock, sourceStoragePoolVoMock, destinationStoragePoolVoMock); |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         VerificationMode times = Mockito.times(storagePoolTypes.size()); |  | ||||||
|         Mockito.verify(destinationStoragePoolVoMock, times).isManaged(); |  | ||||||
|         Mockito.verify(destinationStoragePoolVoMock, times).getPoolType(); |  | ||||||
|         Mockito.verifyNoMoreInteractions(mapStringStoragePoolTypeMock, sourceStoragePoolVoMock, destinationStoragePoolVoMock); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Test |  | ||||||
|     public void validateAddSourcePoolToPoolsMapMapContainsKey() { |  | ||||||
|         Mockito.doReturn(false).when(destinationStoragePoolVoMock).isManaged(); |  | ||||||
|         Mockito.doReturn(StoragePoolType.NetworkFilesystem).when(destinationStoragePoolVoMock).getPoolType(); |  | ||||||
|         Mockito.doReturn("").when(sourceStoragePoolVoMock).getUuid(); |  | ||||||
|         Mockito.doReturn(true).when(mapStringStoragePoolTypeMock).containsKey(Mockito.anyString()); |  | ||||||
|         strategy.addSourcePoolToPoolsMap(mapStringStoragePoolTypeMock, sourceStoragePoolVoMock, destinationStoragePoolVoMock); |  | ||||||
| 
 |  | ||||||
|         Mockito.verify(destinationStoragePoolVoMock, never()).getScope(); |  | ||||||
|         Mockito.verify(destinationStoragePoolVoMock).isManaged(); |  | ||||||
|         Mockito.verify(destinationStoragePoolVoMock).getPoolType(); |  | ||||||
|         Mockito.verify(sourceStoragePoolVoMock).getUuid(); |  | ||||||
|         Mockito.verify(mapStringStoragePoolTypeMock).containsKey(Mockito.anyString()); |  | ||||||
|         Mockito.verifyNoMoreInteractions(mapStringStoragePoolTypeMock, sourceStoragePoolVoMock, destinationStoragePoolVoMock); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Test |  | ||||||
|     public void validateAddSourcePoolToPoolsMapMapDoesNotContainsKey() { |  | ||||||
|         List<StoragePoolType> storagePoolTypes = new LinkedList<>(Arrays.asList(StoragePoolType.values())); |  | ||||||
| 
 |  | ||||||
|         Mockito.doReturn(false).when(destinationStoragePoolVoMock).isManaged(); |  | ||||||
|         Mockito.doReturn(StoragePoolType.NetworkFilesystem).when(destinationStoragePoolVoMock).getPoolType(); |  | ||||||
|         Mockito.doReturn("").when(sourceStoragePoolVoMock).getUuid(); |  | ||||||
|         Mockito.doReturn(false).when(mapStringStoragePoolTypeMock).containsKey(Mockito.anyString()); |  | ||||||
|         Mockito.doReturn(null).when(mapStringStoragePoolTypeMock).put(Mockito.anyString(), Mockito.any()); |  | ||||||
| 
 |  | ||||||
|         storagePoolTypes.forEach(poolType -> { |  | ||||||
|             Mockito.doReturn(poolType).when(sourceStoragePoolVoMock).getPoolType(); |  | ||||||
|             strategy.addSourcePoolToPoolsMap(mapStringStoragePoolTypeMock, sourceStoragePoolVoMock, destinationStoragePoolVoMock); |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         VerificationMode times = Mockito.times(storagePoolTypes.size()); |  | ||||||
|         Mockito.verify(destinationStoragePoolVoMock, never()).getScope(); |  | ||||||
|         Mockito.verify(destinationStoragePoolVoMock, times).isManaged(); |  | ||||||
|         Mockito.verify(destinationStoragePoolVoMock, times).getPoolType(); |  | ||||||
|         Mockito.verify(sourceStoragePoolVoMock, times).getUuid(); |  | ||||||
|         Mockito.verify(mapStringStoragePoolTypeMock, times).containsKey(Mockito.anyString()); |  | ||||||
|         Mockito.verify(sourceStoragePoolVoMock, times).getPoolType(); |  | ||||||
|         Mockito.verify(mapStringStoragePoolTypeMock, times).put(Mockito.anyString(), Mockito.any()); |  | ||||||
|         Mockito.verifyNoMoreInteractions(mapStringStoragePoolTypeMock, sourceStoragePoolVoMock, destinationStoragePoolVoMock); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user