Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2566,7 +2566,10 @@ protected void verifyLiveMigrationForKVM(Map<VolumeInfo, DataStore> volumeDataSt
}

boolean isSrcAndDestPoolPowerFlexStorage = srcStoragePoolVO.getPoolType().equals(Storage.StoragePoolType.PowerFlex) && destStoragePoolVO.getPoolType().equals(Storage.StoragePoolType.PowerFlex);
if (srcStoragePoolVO.isManaged() && !isSrcAndDestPoolPowerFlexStorage && srcStoragePoolVO.getId() != destStoragePoolVO.getId()) {
boolean isSrcAndDestPoolFiberChannelStorage = srcStoragePoolVO.getPoolType().equals(Storage.StoragePoolType.FiberChannel) && destStoragePoolVO.getPoolType().equals(Storage.StoragePoolType.FiberChannel);
boolean fiberChannelVmOnline = isSrcAndDestPoolFiberChannelStorage && volumeInfo.getAttachedVM() != null && volumeInfo.getAttachedVM().getState() == VirtualMachine.State.Running;

if (srcStoragePoolVO.isManaged() && !isSrcAndDestPoolPowerFlexStorage && !fiberChannelVmOnline && srcStoragePoolVO.getId() != destStoragePoolVO.getId()) {
throw new CloudRuntimeException("Migrating a volume online with KVM from managed storage is not currently supported.");
}

Expand Down Expand Up @@ -2766,6 +2769,27 @@ private Map<String, String> getVolumeDetails(VolumeInfo volumeInfo) {
return volumeDetails;
}

private boolean shouldAttemptLiveFiberChannelMigration(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo) {
if (srcVolumeInfo == null || destVolumeInfo == null) {
return false;
}

StoragePoolVO srcPool = _storagePoolDao.findById(srcVolumeInfo.getPoolId());
StoragePoolVO destPool = _storagePoolDao.findById(destVolumeInfo.getPoolId());

if (srcPool == null || destPool == null) {
return false;
}

if (srcPool.getPoolType() != StoragePoolType.FiberChannel || destPool.getPoolType() != StoragePoolType.FiberChannel) {
return false;
}

VirtualMachine attachedVm = srcVolumeInfo.getAttachedVM();

return attachedVm != null && attachedVm.getState() == VirtualMachine.State.Running;
}

private Map<String, String> getSnapshotDetails(SnapshotInfo snapshotInfo) {
Map<String, String> snapshotDetails = new HashMap<>();

Expand Down Expand Up @@ -3021,8 +3045,11 @@ private String migrateVolumeForKVM(VolumeInfo srcVolumeInfo, VolumeInfo destVolu

_volumeService.grantAccess(srcVolumeInfo, hostVO, srcVolumeInfo.getDataStore());

boolean fiberChannelOnline = shouldAttemptLiveFiberChannelMigration(srcVolumeInfo, destVolumeInfo);
int waitTimeout = fiberChannelOnline ? StorageManager.KvmStorageOnlineMigrationWait.value() : StorageManager.KvmStorageOfflineMigrationWait.value();

MigrateVolumeCommand migrateVolumeCommand = new MigrateVolumeCommand(srcVolumeInfo.getTO(), destVolumeInfo.getTO(),
srcDetails, destDetails, StorageManager.KvmStorageOfflineMigrationWait.value());
srcDetails, destDetails, waitTimeout);

_volumeService.grantAccess(srcVolumeInfo, hostVO, srcVolumeInfo.getDataStore());
handleQualityOfServiceForVolumeMigration(destVolumeInfo, PrimaryDataStoreDriver.QualityOfServiceState.MIGRATION);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ public class KvmNonManagedStorageSystemDataMotionTest {
Host host1;
@Mock
Host host2;
@Mock
com.cloud.vm.VirtualMachine attachedVm;

Map<VolumeInfo, DataStore> migrationMap;

Expand Down Expand Up @@ -478,6 +480,23 @@ public void testVerifyLiveMigrationMapForKVM() {
kvmNonManagedStorageDataMotionStrategy.verifyLiveMigrationForKVM(migrationMap);
}

@Test
public void testVerifyLiveMigrationMapForKVMManagedFiberChannelAllowed() {
lenient().when(pool1.isManaged()).thenReturn(true);
lenient().when(pool2.isManaged()).thenReturn(true);
lenient().when(pool1.getPoolType()).thenReturn(Storage.StoragePoolType.FiberChannel);
lenient().when(pool2.getPoolType()).thenReturn(Storage.StoragePoolType.FiberChannel);
lenient().when(pool1.getId()).thenReturn(POOL_1_ID);
lenient().when(pool2.getId()).thenReturn(POOL_2_ID);
lenient().when(volumeInfo1.getAttachedVM()).thenReturn(attachedVm);
when(attachedVm.getState()).thenReturn(com.cloud.vm.VirtualMachine.State.Running);

Map<VolumeInfo, DataStore> fiberChannelMigrationMap = new HashMap<>();
fiberChannelMigrationMap.put(volumeInfo1, dataStore2);

kvmNonManagedStorageDataMotionStrategy.verifyLiveMigrationForKVM(fiberChannelMigrationMap);
}

@Test(expected = CloudRuntimeException.class)
public void testVerifyLiveMigrationMapForKVMNotExistingSource() {
when(primaryDataStoreDao.findById(POOL_1_ID)).thenReturn(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import org.springframework.test.util.ReflectionTestUtils;

import com.cloud.agent.AgentManager;
import com.cloud.agent.api.DeleteVMSnapshotAnswer;
Expand Down Expand Up @@ -94,6 +95,10 @@
import com.cloud.vm.snapshot.VMSnapshotVO;
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
import com.cloud.vm.snapshot.dao.VMSnapshotDetailsDao;
import com.cloud.event.dao.UsageEventDao;
import com.cloud.event.UsageEventUtils;
import com.cloud.user.dao.AccountDao;
import com.cloud.dc.dao.DataCenterDao;

import junit.framework.TestCase;

Expand Down Expand Up @@ -144,10 +149,33 @@ public class VMSnapshotStrategyKVMTest extends TestCase{
@Inject
VMSnapshotDetailsDao vmSnapshotDetailsDao;

private UsageEventDao usageEventDao;
private AccountDao accountDao;
private DataCenterDao dataCenterDao;

@Override
@Before
public void setUp() throws Exception {
ComponentContext.initComponentsLifeCycle();
initialiseUsageEventUtils();
}

private void initialiseUsageEventUtils() {
usageEventDao = Mockito.mock(UsageEventDao.class);
accountDao = Mockito.mock(AccountDao.class);
dataCenterDao = Mockito.mock(DataCenterDao.class);
ConfigurationDao configDao = Mockito.mock(ConfigurationDao.class);

UsageEventUtils usageEventUtils = new UsageEventUtils();
ReflectionTestUtils.setField(usageEventUtils, "usageEventDao", usageEventDao);
ReflectionTestUtils.setField(usageEventUtils, "accountDao", accountDao);
ReflectionTestUtils.setField(usageEventUtils, "dcDao", dataCenterDao);
ReflectionTestUtils.setField(usageEventUtils, "configDao", configDao);
ReflectionTestUtils.invokeMethod(usageEventUtils, "init");

Mockito.lenient().when(usageEventDao.persist(Mockito.any())).thenAnswer(invocation -> invocation.getArgument(0));
Mockito.lenient().doNothing().when(usageEventDao).saveDetails(Mockito.anyLong(), Mockito.anyMap());
Mockito.lenient().when(configDao.getValue("publish.usage.events")).thenReturn("false");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,10 @@ public void setSerial(String serial) {
this._serial = serial;
}

public String getSerial() {
return _serial;
}

public void setLibvirtDiskEncryptDetails(LibvirtDiskEncryptDetails details)
{
this.encryptDetails = details;
Expand Down
Loading
Loading