mirror of
https://github.com/apache/cloudstack
synced 2026-08-02 05:26:35 +00:00
CLVM: Fix volume mapping and disk path matching for storage migration (#13468)
This commit is contained in:
parent
4816e05938
commit
4d54125bb6
@ -3543,7 +3543,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
protected boolean shouldMapVolume(VirtualMachineProfile profile, StoragePoolVO currentPool) {
|
||||
boolean isManaged = currentPool.isManaged();
|
||||
boolean isNotKvm = HypervisorType.KVM != profile.getHypervisorType();
|
||||
return isNotKvm || isManaged;
|
||||
boolean isClvm = ClvmPoolManager.isClvmPoolType(currentPool.getPoolType());
|
||||
return isNotKvm || isManaged || isClvm;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -445,6 +445,9 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
||||
answer = new Answer(cmd, false, errMsg);
|
||||
} else {
|
||||
answer = ep.sendMessage(cmd);
|
||||
if (answer != null && answer.getResult()) {
|
||||
setClvmLockHostIdIfApplicable(destData, ep);
|
||||
}
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
@ -500,6 +503,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
||||
imageStore.delete(objOnImageStore);
|
||||
return answer;
|
||||
}
|
||||
setClvmLockHostIdIfApplicable(destData, ep);
|
||||
} catch (Exception e) {
|
||||
if (imageStore.exists(objOnImageStore)) {
|
||||
objOnImageStore.processEvent(Event.OperationFailed);
|
||||
@ -523,6 +527,9 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
||||
answer = new Answer(cmd, false, errMsg);
|
||||
} else {
|
||||
answer = ep.sendMessage(cmd);
|
||||
if (answer != null && answer.getResult()) {
|
||||
setClvmLockHostIdIfApplicable(destData, ep);
|
||||
}
|
||||
}
|
||||
// delete volume on cache store
|
||||
if (cacheData != null) {
|
||||
@ -532,6 +539,17 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
||||
}
|
||||
}
|
||||
|
||||
private void setClvmLockHostIdIfApplicable(DataObject destData, EndPoint ep) {
|
||||
if (ep == null || !(destData instanceof VolumeInfo)) {
|
||||
return;
|
||||
}
|
||||
VolumeInfo destVolume = (VolumeInfo) destData;
|
||||
if (ClvmPoolManager.isClvmPoolType(destVolume.getStoragePoolType())) {
|
||||
clvmPoolManager.setClvmLockHostId(destVolume.getId(), ep.getId());
|
||||
logger.debug("Set CLVM lock host {} for migrated volume {}", ep.getId(), destVolume.getUuid());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canBypassSecondaryStorage(DataObject srcData, DataObject destData) {
|
||||
if (srcData instanceof VolumeInfo) {
|
||||
if (((VolumeInfo)srcData).isDirectDownload()) {
|
||||
@ -650,6 +668,9 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
||||
if (destPool.getPoolType() == StoragePoolType.CLVM) {
|
||||
volumeVo.setFormat(ImageFormat.RAW);
|
||||
}
|
||||
if (ClvmPoolManager.isClvmPoolType(destPool.getPoolType())) {
|
||||
clvmPoolManager.setClvmLockHostId(volume.getId(), ep.getId());
|
||||
}
|
||||
// For SMB, pool credentials are also stored in the uri query string. We trim the query string
|
||||
// part here to make sure the credentials do not get stored in the db unencrypted.
|
||||
String folder = destPool.getPath();
|
||||
|
||||
@ -3118,6 +3118,12 @@ public class VolumeServiceImpl implements VolumeService {
|
||||
}
|
||||
|
||||
if (volumePoolId == null || !volumePoolId.equals(vmPoolId)) {
|
||||
Long volumeLockHostId = findVolumeLockHost(volumeToAttach);
|
||||
if (volumeLockHostId != null && vmHostId != null && !volumeLockHostId.equals(vmHostId)) {
|
||||
logger.info("CLVM cross-pool lock transfer required: Volume {} on pool {} lock is on host {} but VM is on host {}",
|
||||
volumeToAttach.getUuid(), volumePoolId, volumeLockHostId, vmHostId);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -167,14 +167,49 @@ public class VolumeServiceImplClvmTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsLockTransferRequired_DifferentPools() {
|
||||
public void testIsLockTransferRequired_DifferentPools_LockOnDifferentHost() {
|
||||
when(volumeService.findVolumeLockHost(volumeInfoMock)).thenReturn(HOST_ID_2);
|
||||
|
||||
assertTrue(volumeService.isLockTransferRequired(
|
||||
volumeInfoMock, StoragePoolType.CLVM, StoragePoolType.CLVM,
|
||||
POOL_ID_1, POOL_ID_2, HOST_ID_1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsLockTransferRequired_DifferentPools_LockOnSameHost() {
|
||||
when(volumeService.findVolumeLockHost(volumeInfoMock)).thenReturn(HOST_ID_1);
|
||||
|
||||
assertFalse(volumeService.isLockTransferRequired(
|
||||
volumeInfoMock, StoragePoolType.CLVM, StoragePoolType.CLVM,
|
||||
POOL_ID_1, POOL_ID_2, HOST_ID_1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsLockTransferRequired_NullPoolIds() {
|
||||
public void testIsLockTransferRequired_DifferentPools_NoLockHost() {
|
||||
when(volumeService.findVolumeLockHost(volumeInfoMock)).thenReturn(null);
|
||||
|
||||
assertFalse(volumeService.isLockTransferRequired(
|
||||
volumeInfoMock, StoragePoolType.CLVM, StoragePoolType.CLVM,
|
||||
POOL_ID_1, POOL_ID_2, HOST_ID_1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsLockTransferRequired_NullPoolIds_LockOnDifferentHost() {
|
||||
when(volumeService.findVolumeLockHost(volumeInfoMock)).thenReturn(HOST_ID_2);
|
||||
|
||||
assertTrue(volumeService.isLockTransferRequired(
|
||||
volumeInfoMock, StoragePoolType.CLVM, StoragePoolType.CLVM,
|
||||
null, POOL_ID_1, HOST_ID_1));
|
||||
|
||||
assertTrue(volumeService.isLockTransferRequired(
|
||||
volumeInfoMock, StoragePoolType.CLVM, StoragePoolType.CLVM,
|
||||
POOL_ID_1, null, HOST_ID_1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsLockTransferRequired_NullPoolIds_NoLockHost() {
|
||||
when(volumeService.findVolumeLockHost(volumeInfoMock)).thenReturn(null);
|
||||
|
||||
assertFalse(volumeService.isLockTransferRequired(
|
||||
volumeInfoMock, StoragePoolType.CLVM, StoragePoolType.CLVM,
|
||||
null, POOL_ID_1, HOST_ID_1));
|
||||
|
||||
@ -7038,7 +7038,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
continue;
|
||||
}
|
||||
VolumeObjectTO volumeTO = (VolumeObjectTO) diskTO.getData();
|
||||
if (!diskPath.equals(volumeTO.getPath()) && !diskPath.equals(diskTO.getPath())) {
|
||||
if (!diskPath.substring(diskPath.lastIndexOf(File.separator) + 1).equals(volumeTO.getPath())) {
|
||||
continue;
|
||||
}
|
||||
DataStoreTO dataStore = volumeTO.getDataStore();
|
||||
|
||||
@ -570,7 +570,11 @@ public class KVMStorageProcessor implements StorageProcessor {
|
||||
|
||||
final VolumeObjectTO newVol = new VolumeObjectTO();
|
||||
newVol.setPath(vol.getName());
|
||||
newVol.setSize(volume.getSize());
|
||||
if (StoragePoolType.CLVM_NG.equals(primaryStore.getPoolType()) && vol != null && vol.getVirtualSize() > 0) {
|
||||
newVol.setSize(vol.getVirtualSize());
|
||||
} else {
|
||||
newVol.setSize(volume.getSize());
|
||||
}
|
||||
if (vol.getQemuEncryptFormat() != null) {
|
||||
newVol.setEncryptFormat(vol.getQemuEncryptFormat().toString());
|
||||
}
|
||||
|
||||
@ -436,17 +436,11 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri
|
||||
CommandResult result = new CommandResult();
|
||||
try {
|
||||
EndPoint ep = null;
|
||||
VolumeInfo volumeInfo = volFactory.getVolume(snapshot.getVolumeId(), DataStoreRole.Primary);
|
||||
|
||||
StoragePoolVO storagePool = primaryStoreDao.findById(volumeInfo.getPoolId());
|
||||
if (storagePool != null && storagePool.getPoolType() == StoragePoolType.CLVM) {
|
||||
ep = epSelector.select(volumeInfo);
|
||||
if (snapshotOnPrimaryStore != null) {
|
||||
ep = epSelector.select(snapshotOnPrimaryStore);
|
||||
} else {
|
||||
if (snapshotOnPrimaryStore != null) {
|
||||
ep = epSelector.select(snapshotOnPrimaryStore);
|
||||
} else {
|
||||
ep = epSelector.select(volumeInfo);
|
||||
}
|
||||
VolumeInfo volumeInfo = volFactory.getVolume(snapshot.getVolumeId(), DataStoreRole.Primary);
|
||||
ep = epSelector.select(volumeInfo);
|
||||
}
|
||||
|
||||
if ( ep == null ){
|
||||
|
||||
Loading…
Reference in New Issue
Block a user