diff --git a/core/src/main/java/org/apache/cloudstack/storage/command/ClvmLockTransferAnswer.java b/core/src/main/java/org/apache/cloudstack/storage/clvm/command/ClvmLockTransferAnswer.java similarity index 98% rename from core/src/main/java/org/apache/cloudstack/storage/command/ClvmLockTransferAnswer.java rename to core/src/main/java/org/apache/cloudstack/storage/clvm/command/ClvmLockTransferAnswer.java index 520839a6a5e..cb6809f3d94 100644 --- a/core/src/main/java/org/apache/cloudstack/storage/command/ClvmLockTransferAnswer.java +++ b/core/src/main/java/org/apache/cloudstack/storage/clvm/command/ClvmLockTransferAnswer.java @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.storage.command; +package org.apache.cloudstack.storage.clvm.command; import com.cloud.agent.api.Answer; diff --git a/core/src/main/java/org/apache/cloudstack/storage/command/ClvmLockTransferCommand.java b/core/src/main/java/org/apache/cloudstack/storage/clvm/command/ClvmLockTransferCommand.java similarity index 98% rename from core/src/main/java/org/apache/cloudstack/storage/command/ClvmLockTransferCommand.java rename to core/src/main/java/org/apache/cloudstack/storage/clvm/command/ClvmLockTransferCommand.java index 0dc80ea790e..d63d189f8a1 100644 --- a/core/src/main/java/org/apache/cloudstack/storage/command/ClvmLockTransferCommand.java +++ b/core/src/main/java/org/apache/cloudstack/storage/clvm/command/ClvmLockTransferCommand.java @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.storage.command; +package org.apache.cloudstack.storage.clvm.command; import com.cloud.agent.api.Command; diff --git a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java index 448c00ab240..4937edd33d1 100644 --- a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java +++ b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java @@ -31,12 +31,6 @@ import java.util.Set; public interface VolumeInfo extends DownloadableDataInfo, Volume { - /** - * Constant for the volume detail key that stores the host ID currently holding the CLVM exclusive lock. - * This is used during lightweight lock migration to determine the source host for lock transfer. - */ - String CLVM_LOCK_HOST_ID = "clvmLockHostId"; - boolean isAttachedVM(); void addPayload(Object data); diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java index 16793ff5c8c..aa0f43dfba8 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -51,7 +51,7 @@ import javax.naming.ConfigurationException; import javax.persistence.EntityExistsException; import com.cloud.agent.api.PostMigrationCommand; -import com.cloud.storage.ClvmLockManager; +import com.cloud.storage.clvm.ClvmPoolManager; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; import org.apache.cloudstack.annotation.AnnotationService; import org.apache.cloudstack.annotation.dao.AnnotationDao; @@ -469,7 +469,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Inject ExtensionDetailsDao extensionDetailsDao; @Inject - ClvmLockManager clvmLockManager; + ClvmPoolManager clvmPoolManager; VmWorkJobHandlerProxy _jobHandlerProxy = new VmWorkJobHandlerProxy(this); @@ -3287,26 +3287,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac logger.warn("Error while checking the vm {} on host {}", vm, dest.getHost(), e); } migrated = true; - if (vm.getHypervisorType() == HypervisorType.KVM && hasClvmVolumes(vm.getId())) { - try { - logger.info("Executing post-migration tasks for VM {} with CLVM volumes on destination host {}", vm.getInstanceName(), dstHostId); - final PostMigrationCommand postMigrationCommand = new PostMigrationCommand(to, vm.getInstanceName()); - final Answer postMigrationAnswer = _agentMgr.send(dstHostId, postMigrationCommand); - - if (postMigrationAnswer == null || !postMigrationAnswer.getResult()) { - final String details = postMigrationAnswer != null ? postMigrationAnswer.getDetails() : "null answer returned"; - logger.warn("Post-migration tasks failed for VM {} on destination host {}: {}. Migration completed but some cleanup may be needed.", - vm.getInstanceName(), dstHostId, details); - } else { - logger.info("Successfully completed post-migration tasks for VM {} on destination host {}", vm.getInstanceName(), dstHostId); - } - } catch (Exception e) { - logger.warn("Exception during post-migration tasks for VM {} on destination host {}: {}. Migration completed but some cleanup may be needed.", - vm.getInstanceName(), dstHostId, e.getMessage(), e); - } - } - - updateClvmLockHostForVmVolumes(vm.getId(), dstHostId); + executePostMigrationCommand(vm, to, dstHostId); } finally { if (!migrated) { logger.info("Migration was unsuccessful. Cleaning up: {}", vm); @@ -3346,6 +3327,29 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } } + private void executePostMigrationCommand(VMInstanceVO vm, VirtualMachineTO to, long dstHostId) { + if (vm.getHypervisorType() == HypervisorType.KVM && hasClvmVolumes(vm.getId())) { + try { + logger.info("Executing post-migration tasks for VM {} with CLVM volumes on destination host {}", vm.getInstanceName(), dstHostId); + final PostMigrationCommand postMigrationCommand = new PostMigrationCommand(to, vm.getInstanceName()); + final Answer postMigrationAnswer = _agentMgr.send(dstHostId, postMigrationCommand); + + if (postMigrationAnswer == null || !postMigrationAnswer.getResult()) { + final String details = postMigrationAnswer != null ? postMigrationAnswer.getDetails() : "null answer returned"; + logger.warn("Post-migration tasks failed for VM {} on destination host {}: {}. Migration completed but some cleanup may be needed.", + vm.getInstanceName(), dstHostId, details); + } else { + logger.info("Successfully completed post-migration tasks for VM {} on destination host {}", vm.getInstanceName(), dstHostId); + } + } catch (Exception e) { + logger.warn("Exception during post-migration tasks for VM {} on destination host {}: {}. Migration completed but some cleanup may be needed.", + vm.getInstanceName(), dstHostId, e.getMessage(), e); + } + } + + updateClvmLockHostForVmVolumes(vm.getId(), dstHostId); + } + /** * Create and set parameters for the {@link MigrateCommand} used in the migration and scaling of VMs. */ @@ -3401,14 +3405,14 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac */ private void updateClvmLockHostForVmVolumes(long vmId, long destHostId) { List volumes = _volsDao.findByInstance(vmId); - if (volumes == null || volumes.isEmpty()) { + if (CollectionUtils.isEmpty(volumes)) { return; } for (VolumeVO volume : volumes) { StoragePoolVO pool = _storagePoolDao.findById(volume.getPoolId()); - if (pool != null && ClvmLockManager.isClvmPoolType(pool.getPoolType())) { - clvmLockManager.setClvmLockHostId(volume.getId(), destHostId); + if (pool != null && ClvmPoolManager.isClvmPoolType(pool.getPoolType())) { + clvmPoolManager.setClvmLockHostId(volume.getId(), destHostId); } } } @@ -6507,7 +6511,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac List volumes = _volsDao.findByInstance(vmId); return volumes.stream() .map(v -> _storagePoolDao.findById(v.getPoolId())) - .anyMatch(pool -> pool != null && ClvmLockManager.isClvmPoolType(pool.getPoolType())); + .anyMatch(pool -> pool != null && ClvmPoolManager.isClvmPoolType(pool.getPoolType())); } private void executePreMigrationCommand(VirtualMachineTO to, String vmInstanceName, long srcHostId) { diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java index 3f018a04ae1..e3300130c37 100644 --- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java +++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java @@ -41,7 +41,7 @@ import javax.naming.ConfigurationException; import com.cloud.agent.AgentManager; import com.cloud.deploy.DeploymentClusterPlanner; import com.cloud.exception.ResourceAllocationException; -import com.cloud.storage.ClvmLockManager; +import com.cloud.storage.clvm.ClvmPoolManager; import com.cloud.resourcelimit.ReservationHelper; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.VMTemplateVO; @@ -278,7 +278,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati @Inject VMInstanceDao vmInstanceDao; @Inject - ClvmLockManager clvmLockManager; + ClvmPoolManager clvmPoolManager; @Inject AgentManager _agentMgr; @@ -756,12 +756,12 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati // For CLVM pools, set the lock host hint so volume is created on the correct host // This avoids the need for shared mode activation and improves performance - if (ClvmLockManager.isClvmPoolType(pool.getPoolType()) && hostId != null) { + if (ClvmPoolManager.isClvmPoolType(pool.getPoolType()) && hostId != null) { logger.info("CLVM pool detected. Setting lock host {} for volume {} to route creation to correct host", hostId, volumeInfo.getUuid()); volumeInfo.setDestinationHostId(hostId); - clvmLockManager.setClvmLockHostId(volumeInfo.getId(), hostId); + clvmPoolManager.setClvmLockHostId(volumeInfo.getId(), hostId); } for (int i = 0; i < 2; i++) { @@ -820,7 +820,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati } StoragePoolVO pool = _storagePoolDao.findById(destPool.getId()); - if (pool == null || !ClvmLockManager.isClvmPoolType(pool.getPoolType())) { + if (pool == null || !ClvmPoolManager.isClvmPoolType(pool.getPoolType())) { return; } @@ -833,7 +833,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati return; } - clvmLockManager.setClvmLockHostId(migratedVolume.getId(), vm.getHostId()); + clvmPoolManager.setClvmLockHostId(migratedVolume.getId(), vm.getHostId()); logger.debug("Updated CLVM_LOCK_HOST_ID for {} volume {} to host {} where VM {} is running", operationType, migratedVolume.getUuid(), vm.getHostId(), vm.getInstanceName()); } @@ -862,8 +862,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati } StoragePoolVO pool = _storagePoolDao.findById(volume.getPoolId()); - if (pool != null && ClvmLockManager.isClvmPoolType(pool.getPoolType())) { - Long lockHostId = clvmLockManager.getClvmLockHostId( + if (pool != null && ClvmPoolManager.isClvmPoolType(pool.getPoolType())) { + Long lockHostId = clvmPoolManager.getClvmLockHostId( volume.getId(), volume.getUuid(), volume.getPath(), @@ -892,11 +892,11 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati } StoragePoolVO pool = _storagePoolDao.findById(volume.getPoolId()); - if (pool == null || !ClvmLockManager.isClvmPoolType(pool.getPoolType())) { + if (pool == null || !ClvmPoolManager.isClvmPoolType(pool.getPoolType())) { continue; } - Long currentLockHost = clvmLockManager.getClvmLockHostId( + Long currentLockHost = clvmPoolManager.getClvmLockHostId( volume.getId(), volume.getUuid(), volume.getPath(), @@ -905,12 +905,12 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati ); if (currentLockHost == null) { - clvmLockManager.setClvmLockHostId(volume.getId(), destHostId); + clvmPoolManager.setClvmLockHostId(volume.getId(), destHostId); } else if (!currentLockHost.equals(destHostId)) { logger.info("CLVM volume {} is locked on host {} but VM {} starting on host {}. Transferring lock.", volume.getUuid(), currentLockHost, vm.getInstanceName(), destHostId); - if (!clvmLockManager.transferClvmVolumeLock(volume.getUuid(), volume.getId(), + if (!clvmPoolManager.transferClvmVolumeLock(volume.getUuid(), volume.getId(), volume.getPath(), pool, currentLockHost, destHostId)) { throw new CloudRuntimeException( String.format("Failed to transfer CLVM lock for volume %s from host %s to host %s", @@ -1338,8 +1338,8 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati Long clusterId = storagePool.getClusterId(); logger.trace("storage-pool {}/{} is associated with cluster {}",storagePool.getName(), storagePool.getUuid(), clusterId); Long hostId = vm.getHostId(); - if (hostId == null && (storagePool.isLocal() || ClvmLockManager.isClvmPoolType(storagePool.getPoolType()))) { - if (ClvmLockManager.isClvmPoolType(storagePool.getPoolType())) { + if (hostId == null && (storagePool.isLocal() || ClvmPoolManager.isClvmPoolType(storagePool.getPoolType()))) { + if (ClvmPoolManager.isClvmPoolType(storagePool.getPoolType())) { hostId = getClvmLockHostFromVmVolumes(vm.getId()); if (hostId != null) { logger.debug("Using CLVM lock host {} from VM {}'s existing volumes for new volume creation", @@ -2012,11 +2012,11 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati // For CLVM pools, set the destination host hint so volume is created on the correct host // This avoids the need for shared mode activation and improves performance StoragePoolVO poolVO = _storagePoolDao.findById(destPool.getId()); - if (poolVO != null && ClvmLockManager.isClvmPoolType(poolVO.getPoolType())) { + if (poolVO != null && ClvmPoolManager.isClvmPoolType(poolVO.getPoolType())) { Long hostId = vm.getVirtualMachine().getHostId(); if (hostId != null) { volume.setDestinationHostId(hostId); - clvmLockManager.setClvmLockHostId(volume.getId(), hostId); + clvmPoolManager.setClvmLockHostId(volume.getId(), hostId); logger.info("CLVM pool detected during volume creation from template. Setting lock host {} for volume {} (persisted to DB) to route creation to correct host", hostId, volume.getUuid()); } diff --git a/engine/orchestration/src/main/resources/META-INF/cloudstack/core/spring-engine-orchestration-core-context.xml b/engine/orchestration/src/main/resources/META-INF/cloudstack/core/spring-engine-orchestration-core-context.xml index 28134f415f1..05bcf4508cd 100644 --- a/engine/orchestration/src/main/resources/META-INF/cloudstack/core/spring-engine-orchestration-core-context.xml +++ b/engine/orchestration/src/main/resources/META-INF/cloudstack/core/spring-engine-orchestration-core-context.xml @@ -44,7 +44,7 @@ value="#{storagePoolAllocatorsRegistry.registered}" /> - + diff --git a/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java b/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java index 2f75b0252c4..c656e1a282a 100644 --- a/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java +++ b/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java @@ -61,7 +61,7 @@ import com.cloud.ha.HighAvailabilityManager; import com.cloud.network.Network; import com.cloud.network.NetworkModel; import com.cloud.resource.ResourceManager; -import com.cloud.storage.ClvmLockManager; +import com.cloud.storage.clvm.ClvmPoolManager; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; @@ -338,6 +338,19 @@ public class VirtualMachineManagerImplTest { } } + private ClvmPoolManager injectMockedClvmPoolManager() { + ClvmPoolManager clvmPoolManagerMock = mock(ClvmPoolManager.class); + ReflectionTestUtils.setField(virtualMachineManagerImpl, "clvmPoolManager", clvmPoolManagerMock); + return clvmPoolManagerMock; + } + + private Method getUpdateClvmLockHostForVmVolumesMethod() throws NoSuchMethodException { + Method method = VirtualMachineManagerImpl.class.getDeclaredMethod( + "updateClvmLockHostForVmVolumes", long.class, long.class); + method.setAccessible(true); + return method; + } + @Test public void testaddHostIpToCertDetailsIfConfigAllows() { Host vmHost = mock(Host.class); @@ -1976,16 +1989,13 @@ public class VirtualMachineManagerImplTest { when(volumeDaoMock.findByInstance(vmId)).thenReturn(Arrays.asList(clvmVolume1, clvmVolume2)); when(storagePoolDaoMock.findById(poolId)).thenReturn(clvmPool); - ClvmLockManager clvmLockManagerMock = mock(ClvmLockManager.class); - ReflectionTestUtils.setField(virtualMachineManagerImpl, "clvmLockManager", clvmLockManagerMock); + ClvmPoolManager clvmPoolManagerMock = injectMockedClvmPoolManager(); - Method method = VirtualMachineManagerImpl.class.getDeclaredMethod( - "updateClvmLockHostForVmVolumes", long.class, long.class); - method.setAccessible(true); + Method method = getUpdateClvmLockHostForVmVolumesMethod(); method.invoke(virtualMachineManagerImpl, vmId, destHostId); - verify(clvmLockManagerMock, times(1)).setClvmLockHostId(1L, destHostId); - verify(clvmLockManagerMock, times(1)).setClvmLockHostId(2L, destHostId); + verify(clvmPoolManagerMock, times(1)).setClvmLockHostId(1L, destHostId); + verify(clvmPoolManagerMock, times(1)).setClvmLockHostId(2L, destHostId); } @Test @@ -2003,15 +2013,12 @@ public class VirtualMachineManagerImplTest { when(volumeDaoMock.findByInstance(vmId)).thenReturn(Arrays.asList(nfsVolume)); when(storagePoolDaoMock.findById(poolId)).thenReturn(nfsPool); - ClvmLockManager clvmLockManagerMock = mock(ClvmLockManager.class); - ReflectionTestUtils.setField(virtualMachineManagerImpl, "clvmLockManager", clvmLockManagerMock); + ClvmPoolManager clvmPoolManagerMock = injectMockedClvmPoolManager(); - Method method = VirtualMachineManagerImpl.class.getDeclaredMethod( - "updateClvmLockHostForVmVolumes", long.class, long.class); - method.setAccessible(true); + Method method = getUpdateClvmLockHostForVmVolumesMethod(); method.invoke(virtualMachineManagerImpl, vmId, destHostId); - verify(clvmLockManagerMock, never()).setClvmLockHostId(anyLong(), anyLong()); + verify(clvmPoolManagerMock, never()).setClvmLockHostId(anyLong(), anyLong()); } @Test @@ -2038,16 +2045,13 @@ public class VirtualMachineManagerImplTest { when(storagePoolDaoMock.findById(clvmPoolId)).thenReturn(clvmPool); when(storagePoolDaoMock.findById(nfsPoolId)).thenReturn(nfsPool); - ClvmLockManager clvmLockManagerMock = mock(ClvmLockManager.class); - ReflectionTestUtils.setField(virtualMachineManagerImpl, "clvmLockManager", clvmLockManagerMock); + ClvmPoolManager clvmPoolManagerMock = injectMockedClvmPoolManager(); - Method method = VirtualMachineManagerImpl.class.getDeclaredMethod( - "updateClvmLockHostForVmVolumes", long.class, long.class); - method.setAccessible(true); + Method method = getUpdateClvmLockHostForVmVolumesMethod(); method.invoke(virtualMachineManagerImpl, vmId, destHostId); - verify(clvmLockManagerMock, times(1)).setClvmLockHostId(1L, destHostId); - verify(clvmLockManagerMock, never()).setClvmLockHostId(2L, destHostId); + verify(clvmPoolManagerMock, times(1)).setClvmLockHostId(1L, destHostId); + verify(clvmPoolManagerMock, never()).setClvmLockHostId(2L, destHostId); } @Test @@ -2057,15 +2061,12 @@ public class VirtualMachineManagerImplTest { when(volumeDaoMock.findByInstance(vmId)).thenReturn(Collections.emptyList()); - ClvmLockManager clvmLockManagerMock = mock(ClvmLockManager.class); - ReflectionTestUtils.setField(virtualMachineManagerImpl, "clvmLockManager", clvmLockManagerMock); + ClvmPoolManager clvmPoolManagerMock = injectMockedClvmPoolManager(); - Method method = VirtualMachineManagerImpl.class.getDeclaredMethod( - "updateClvmLockHostForVmVolumes", long.class, long.class); - method.setAccessible(true); + Method method = getUpdateClvmLockHostForVmVolumesMethod(); method.invoke(virtualMachineManagerImpl, vmId, destHostId); - verify(clvmLockManagerMock, never()).setClvmLockHostId(anyLong(), anyLong()); + verify(clvmPoolManagerMock, never()).setClvmLockHostId(anyLong(), anyLong()); } @Test @@ -2078,16 +2079,13 @@ public class VirtualMachineManagerImplTest { when(volumeDaoMock.findByInstance(vmId)).thenReturn(Arrays.asList(volumeWithoutPool)); - ClvmLockManager clvmLockManagerMock = mock(ClvmLockManager.class); - ReflectionTestUtils.setField(virtualMachineManagerImpl, "clvmLockManager", clvmLockManagerMock); + ClvmPoolManager clvmPoolManagerMock = injectMockedClvmPoolManager(); - Method method = VirtualMachineManagerImpl.class.getDeclaredMethod( - "updateClvmLockHostForVmVolumes", long.class, long.class); - method.setAccessible(true); + Method method = getUpdateClvmLockHostForVmVolumesMethod(); method.invoke(virtualMachineManagerImpl, vmId, destHostId); verify(storagePoolDaoMock, never()).findById(anyLong()); - verify(clvmLockManagerMock, never()).setClvmLockHostId(anyLong(), anyLong()); + verify(clvmPoolManagerMock, never()).setClvmLockHostId(anyLong(), anyLong()); } @Test @@ -2102,15 +2100,12 @@ public class VirtualMachineManagerImplTest { when(volumeDaoMock.findByInstance(vmId)).thenReturn(Arrays.asList(volume)); when(storagePoolDaoMock.findById(poolId)).thenReturn(null); - ClvmLockManager clvmLockManagerMock = mock(ClvmLockManager.class); - ReflectionTestUtils.setField(virtualMachineManagerImpl, "clvmLockManager", clvmLockManagerMock); + ClvmPoolManager clvmPoolManagerMock = injectMockedClvmPoolManager(); - Method method = VirtualMachineManagerImpl.class.getDeclaredMethod( - "updateClvmLockHostForVmVolumes", long.class, long.class); - method.setAccessible(true); + Method method = getUpdateClvmLockHostForVmVolumesMethod(); method.invoke(virtualMachineManagerImpl, vmId, destHostId); - verify(clvmLockManagerMock, never()).setClvmLockHostId(anyLong(), anyLong()); + verify(clvmPoolManagerMock, never()).setClvmLockHostId(anyLong(), anyLong()); } @Test @@ -2141,17 +2136,14 @@ public class VirtualMachineManagerImplTest { when(storagePoolDaoMock.findById(pool1Id)).thenReturn(clvmPool1); when(storagePoolDaoMock.findById(pool2Id)).thenReturn(clvmPool2); - ClvmLockManager clvmLockManagerMock = mock(ClvmLockManager.class); - ReflectionTestUtils.setField(virtualMachineManagerImpl, "clvmLockManager", clvmLockManagerMock); + ClvmPoolManager clvmPoolManagerMock = injectMockedClvmPoolManager(); - Method method = VirtualMachineManagerImpl.class.getDeclaredMethod( - "updateClvmLockHostForVmVolumes", long.class, long.class); - method.setAccessible(true); + Method method = getUpdateClvmLockHostForVmVolumesMethod(); method.invoke(virtualMachineManagerImpl, vmId, destHostId); - verify(clvmLockManagerMock, times(1)).setClvmLockHostId(1L, destHostId); - verify(clvmLockManagerMock, times(1)).setClvmLockHostId(2L, destHostId); - verify(clvmLockManagerMock, times(1)).setClvmLockHostId(3L, destHostId); + verify(clvmPoolManagerMock, times(1)).setClvmLockHostId(1L, destHostId); + verify(clvmPoolManagerMock, times(1)).setClvmLockHostId(2L, destHostId); + verify(clvmPoolManagerMock, times(1)).setClvmLockHostId(3L, destHostId); } } diff --git a/engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestratorTest.java b/engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestratorTest.java index d7d6d8eb9d3..a184b4540a9 100644 --- a/engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestratorTest.java +++ b/engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestratorTest.java @@ -32,7 +32,7 @@ import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.hypervisor.Hypervisor; import com.cloud.offering.DiskOffering; -import com.cloud.storage.ClvmLockManager; +import com.cloud.storage.clvm.ClvmPoolManager; import com.cloud.storage.ScopeType; import com.cloud.storage.DataStoreRole; import com.cloud.storage.Storage; @@ -670,17 +670,17 @@ public class VolumeOrchestratorTest { VMInstanceVO vmInstance = Mockito.mock(VMInstanceVO.class); Mockito.when(vmInstance.getInstanceName()).thenReturn(MOCK_VM_NAME); - ClvmLockManager clvmLockManager = Mockito.mock(ClvmLockManager.class); - Mockito.when(clvmLockManager.getClvmLockHostId(Mockito.eq(101L), Mockito.anyString(), + ClvmPoolManager clvmPoolManager = Mockito.mock(ClvmPoolManager.class); + Mockito.when(clvmPoolManager.getClvmLockHostId(Mockito.eq(101L), Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.eq(true))).thenReturn(currentHostId); - Mockito.when(clvmLockManager.getClvmLockHostId(Mockito.eq(102L), Mockito.anyString(), + Mockito.when(clvmPoolManager.getClvmLockHostId(Mockito.eq(102L), Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.eq(true))).thenReturn(currentHostId); - Mockito.when(clvmLockManager.transferClvmVolumeLock(Mockito.anyString(), Mockito.anyLong(), + Mockito.when(clvmPoolManager.transferClvmVolumeLock(Mockito.anyString(), Mockito.anyLong(), Mockito.anyString(), Mockito.any(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(true); Mockito.when(storagePoolDao.findById(poolId)).thenReturn(clvmPool); - setField(volumeOrchestrator, "clvmLockManager", clvmLockManager); + setField(volumeOrchestrator, "clvmPoolManager", clvmPoolManager); setField(volumeOrchestrator, "_storagePoolDao", storagePoolDao); Method method = VolumeOrchestrator.class.getDeclaredMethod( @@ -689,10 +689,10 @@ public class VolumeOrchestratorTest { method.invoke(volumeOrchestrator, List.of(clvmVolume1, clvmVolume2), destHostId, vmInstance); - Mockito.verify(clvmLockManager, Mockito.times(1)).transferClvmVolumeLock( + Mockito.verify(clvmPoolManager, Mockito.times(1)).transferClvmVolumeLock( Mockito.eq("vol-uuid-1"), Mockito.eq(101L), Mockito.eq("vol-path-1"), Mockito.eq(clvmPool), Mockito.eq(currentHostId), Mockito.eq(destHostId)); - Mockito.verify(clvmLockManager, Mockito.times(1)).transferClvmVolumeLock( + Mockito.verify(clvmPoolManager, Mockito.times(1)).transferClvmVolumeLock( Mockito.eq("vol-uuid-2"), Mockito.eq(102L), Mockito.eq("vol-path-2"), Mockito.eq(clvmPool), Mockito.eq(currentHostId), Mockito.eq(destHostId)); } @@ -710,11 +710,11 @@ public class VolumeOrchestratorTest { VMInstanceVO vmInstance = Mockito.mock(VMInstanceVO.class); - ClvmLockManager clvmLockManager = Mockito.mock(ClvmLockManager.class); + ClvmPoolManager clvmPoolManager = Mockito.mock(ClvmPoolManager.class); Mockito.when(storagePoolDao.findById(poolId)).thenReturn(nfsPool); - setField(volumeOrchestrator, "clvmLockManager", clvmLockManager); + setField(volumeOrchestrator, "clvmPoolManager", clvmPoolManager); setField(volumeOrchestrator, "_storagePoolDao", storagePoolDao); Method method = VolumeOrchestrator.class.getDeclaredMethod( @@ -723,7 +723,7 @@ public class VolumeOrchestratorTest { method.invoke(volumeOrchestrator, List.of(nfsVolume), destHostId, vmInstance); - Mockito.verify(clvmLockManager, Mockito.never()).transferClvmVolumeLock( + Mockito.verify(clvmPoolManager, Mockito.never()).transferClvmVolumeLock( Mockito.anyString(), Mockito.anyLong(), Mockito.anyString(), Mockito.any(), Mockito.anyLong(), Mockito.anyLong()); } @@ -742,13 +742,13 @@ public class VolumeOrchestratorTest { VMInstanceVO vmInstance = Mockito.mock(VMInstanceVO.class); - ClvmLockManager clvmLockManager = Mockito.mock(ClvmLockManager.class); - Mockito.when(clvmLockManager.getClvmLockHostId(Mockito.eq(101L), ArgumentMatchers.nullable(String.class), + ClvmPoolManager clvmPoolManager = Mockito.mock(ClvmPoolManager.class); + Mockito.when(clvmPoolManager.getClvmLockHostId(Mockito.eq(101L), ArgumentMatchers.nullable(String.class), ArgumentMatchers.nullable(String.class), Mockito.any(), Mockito.eq(true))).thenReturn(destHostId); Mockito.when(storagePoolDao.findById(poolId)).thenReturn(clvmPool); - setField(volumeOrchestrator, "clvmLockManager", clvmLockManager); + setField(volumeOrchestrator, "clvmPoolManager", clvmPoolManager); setField(volumeOrchestrator, "_storagePoolDao", storagePoolDao); java.lang.reflect.Method method = VolumeOrchestrator.class.getDeclaredMethod( @@ -757,7 +757,7 @@ public class VolumeOrchestratorTest { method.invoke(volumeOrchestrator, List.of(clvmVolume), destHostId, vmInstance); - Mockito.verify(clvmLockManager, Mockito.never()).transferClvmVolumeLock( + Mockito.verify(clvmPoolManager, Mockito.never()).transferClvmVolumeLock( Mockito.anyString(), Mockito.anyLong(), Mockito.anyString(), Mockito.any(), Mockito.anyLong(), Mockito.anyLong()); } @@ -767,8 +767,8 @@ public class VolumeOrchestratorTest { Long destHostId = 2L; VMInstanceVO vmInstance = Mockito.mock(VMInstanceVO.class); - ClvmLockManager clvmLockManager = Mockito.mock(ClvmLockManager.class); - setField(volumeOrchestrator, "clvmLockManager", clvmLockManager); + ClvmPoolManager clvmPoolManager = Mockito.mock(ClvmPoolManager.class); + setField(volumeOrchestrator, "clvmPoolManager", clvmPoolManager); Method method = VolumeOrchestrator.class.getDeclaredMethod( "transferClvmLocksForVmStart", List.class, Long.class, VMInstanceVO.class); @@ -776,7 +776,7 @@ public class VolumeOrchestratorTest { method.invoke(volumeOrchestrator, new ArrayList(), destHostId, vmInstance); - Mockito.verify(clvmLockManager, Mockito.never()).getClvmLockHostId(Mockito.anyLong(), Mockito.anyString(), + Mockito.verify(clvmPoolManager, Mockito.never()).getClvmLockHostId(Mockito.anyLong(), Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.anyBoolean()); } @@ -789,8 +789,8 @@ public class VolumeOrchestratorTest { VMInstanceVO vmInstance = Mockito.mock(VMInstanceVO.class); - ClvmLockManager clvmLockManager = Mockito.mock(ClvmLockManager.class); - setField(volumeOrchestrator, "clvmLockManager", clvmLockManager); + ClvmPoolManager clvmPoolManager = Mockito.mock(ClvmPoolManager.class); + setField(volumeOrchestrator, "clvmPoolManager", clvmPoolManager); setField(volumeOrchestrator, "_storagePoolDao", storagePoolDao); Method method = VolumeOrchestrator.class.getDeclaredMethod( @@ -816,13 +816,13 @@ public class VolumeOrchestratorTest { VMInstanceVO vmInstance = Mockito.mock(VMInstanceVO.class); - ClvmLockManager clvmLockManager = Mockito.mock(ClvmLockManager.class); - Mockito.when(clvmLockManager.getClvmLockHostId(Mockito.eq(101L), ArgumentMatchers.nullable(String.class), + ClvmPoolManager clvmPoolManager = Mockito.mock(ClvmPoolManager.class); + Mockito.when(clvmPoolManager.getClvmLockHostId(Mockito.eq(101L), ArgumentMatchers.nullable(String.class), ArgumentMatchers.nullable(String.class), Mockito.any(), Mockito.eq(true))).thenReturn(null); Mockito.when(storagePoolDao.findById(poolId)).thenReturn(clvmPool); - setField(volumeOrchestrator, "clvmLockManager", clvmLockManager); + setField(volumeOrchestrator, "clvmPoolManager", clvmPoolManager); setField(volumeOrchestrator, "_storagePoolDao", storagePoolDao); Method method = VolumeOrchestrator.class.getDeclaredMethod( @@ -831,8 +831,8 @@ public class VolumeOrchestratorTest { method.invoke(volumeOrchestrator, List.of(clvmVolume), destHostId, vmInstance); - Mockito.verify(clvmLockManager, Mockito.times(1)).setClvmLockHostId(101L, destHostId); - Mockito.verify(clvmLockManager, Mockito.never()).transferClvmVolumeLock( + Mockito.verify(clvmPoolManager, Mockito.times(1)).setClvmLockHostId(101L, destHostId); + Mockito.verify(clvmPoolManager, Mockito.never()).transferClvmVolumeLock( Mockito.anyString(), Mockito.anyLong(), Mockito.anyString(), Mockito.any(), Mockito.anyLong(), Mockito.anyLong()); } @@ -862,16 +862,16 @@ public class VolumeOrchestratorTest { VMInstanceVO vmInstance = Mockito.mock(VMInstanceVO.class); Mockito.when(vmInstance.getInstanceName()).thenReturn(MOCK_VM_NAME); - ClvmLockManager clvmLockManager = Mockito.mock(ClvmLockManager.class); - Mockito.when(clvmLockManager.getClvmLockHostId(Mockito.eq(101L), Mockito.anyString(), + ClvmPoolManager clvmPoolManager = Mockito.mock(ClvmPoolManager.class); + Mockito.when(clvmPoolManager.getClvmLockHostId(Mockito.eq(101L), Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.eq(true))).thenReturn(currentHostId); - Mockito.when(clvmLockManager.transferClvmVolumeLock(Mockito.anyString(), Mockito.anyLong(), + Mockito.when(clvmPoolManager.transferClvmVolumeLock(Mockito.anyString(), Mockito.anyLong(), Mockito.anyString(), Mockito.any(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(true); Mockito.when(storagePoolDao.findById(clvmPoolId)).thenReturn(clvmPool); Mockito.when(storagePoolDao.findById(nfsPoolId)).thenReturn(nfsPool); - setField(volumeOrchestrator, "clvmLockManager", clvmLockManager); + setField(volumeOrchestrator, "clvmPoolManager", clvmPoolManager); setField(volumeOrchestrator, "_storagePoolDao", storagePoolDao); Method method = VolumeOrchestrator.class.getDeclaredMethod( @@ -880,7 +880,7 @@ public class VolumeOrchestratorTest { method.invoke(volumeOrchestrator, List.of(clvmVolume, nfsVolume), destHostId, vmInstance); - Mockito.verify(clvmLockManager, Mockito.times(1)).transferClvmVolumeLock( + Mockito.verify(clvmPoolManager, Mockito.times(1)).transferClvmVolumeLock( Mockito.eq("clvm-vol-uuid"), Mockito.eq(101L), Mockito.eq("clvm-vol-path"), Mockito.eq(clvmPool), Mockito.eq(currentHostId), Mockito.eq(destHostId)); } @@ -903,15 +903,15 @@ public class VolumeOrchestratorTest { VMInstanceVO vmInstance = Mockito.mock(VMInstanceVO.class); Mockito.when(vmInstance.getInstanceName()).thenReturn(MOCK_VM_NAME); - ClvmLockManager clvmLockManager = Mockito.mock(ClvmLockManager.class); - Mockito.when(clvmLockManager.getClvmLockHostId(Mockito.eq(101L), Mockito.anyString(), + ClvmPoolManager clvmPoolManager = Mockito.mock(ClvmPoolManager.class); + Mockito.when(clvmPoolManager.getClvmLockHostId(Mockito.eq(101L), Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.eq(true))).thenReturn(currentHostId); - Mockito.when(clvmLockManager.transferClvmVolumeLock(Mockito.anyString(), Mockito.anyLong(), + Mockito.when(clvmPoolManager.transferClvmVolumeLock(Mockito.anyString(), Mockito.anyLong(), Mockito.anyString(), Mockito.any(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(false); Mockito.when(storagePoolDao.findById(poolId)).thenReturn(clvmPool); - setField(volumeOrchestrator, "clvmLockManager", clvmLockManager); + setField(volumeOrchestrator, "clvmPoolManager", clvmPoolManager); setField(volumeOrchestrator, "_storagePoolDao", storagePoolDao); Method method = VolumeOrchestrator.class.getDeclaredMethod( diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java index 07d1bc4b389..f5eea5cb334 100644 --- a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -27,7 +27,7 @@ import java.util.Objects; import javax.inject.Inject; import com.cloud.agent.api.to.DiskTO; -import com.cloud.storage.ClvmLockManager; +import com.cloud.storage.clvm.ClvmPoolManager; import com.cloud.storage.Storage; import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; @@ -110,7 +110,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { @Inject VolumeDataStoreDao volumeDataStoreDao; @Inject - ClvmLockManager clvmLockManager; + ClvmPoolManager clvmPoolManager; @Inject StorageManager storageManager; @@ -340,9 +340,9 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { if (ep != null && volObj instanceof VolumeInfo) { VolumeInfo volumeInfo = (VolumeInfo) volObj; StoragePool destPool = (StoragePool) volObj.getDataStore(); - if (destPool != null && ClvmLockManager.isClvmPoolType(destPool.getPoolType())) { + if (destPool != null && ClvmPoolManager.isClvmPoolType(destPool.getPoolType())) { Long hostId = ep.getId(); - Long existingHostId = clvmLockManager.getClvmLockHostId( + Long existingHostId = clvmPoolManager.getClvmLockHostId( volumeInfo.getId(), volumeInfo.getUuid(), volumeInfo.getPath(), @@ -350,7 +350,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { true ); if (existingHostId == null) { - clvmLockManager.setClvmLockHostId(volumeInfo.getId(), hostId); + clvmPoolManager.setClvmLockHostId(volumeInfo.getId(), hostId); logger.debug("Set lock host ID {} for CLVM volume {} being created from snapshot", hostId, volumeInfo.getId()); } } diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java index cba7dbfbea4..5861c26b8b0 100644 --- a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java +++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java @@ -36,7 +36,7 @@ import com.cloud.agent.api.CheckVirtualMachineAnswer; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.PrepareForMigrationAnswer; import com.cloud.resource.ResourceManager; -import com.cloud.storage.ClvmLockManager; +import com.cloud.storage.clvm.ClvmPoolManager; import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; @@ -209,7 +209,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy { @Inject ResourceManager resourceManager; @Inject - private ClvmLockManager clvmLockManager; + private ClvmPoolManager clvmPoolManager; @Override public StrategyPriority canHandle(DataObject srcData, DataObject destData) { @@ -2075,9 +2075,9 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy { setVolumeMigrationOptions(srcVolumeInfo, destVolumeInfo, vmTO, srcHost, destStoragePool, migrationType); - if (ClvmLockManager.isClvmPoolType(destStoragePool.getPoolType())) { + if (ClvmPoolManager.isClvmPoolType(destStoragePool.getPoolType())) { destVolumeInfo.setDestinationHostId(destHost.getId()); - clvmLockManager.setClvmLockHostId(destVolume.getId(), destHost.getId()); + clvmPoolManager.setClvmLockHostId(destVolume.getId(), destHost.getId()); logger.info("Set CLVM lock host {} for volume {} during migration to ensure creation on destination host", destHost.getId(), destVolumeInfo.getUuid()); } @@ -2353,7 +2353,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy { */ protected MigrateCommand.MigrateDiskInfo updateMigrateDiskInfoForBlockDevice(MigrateCommand.MigrateDiskInfo migrateDiskInfo, StoragePoolVO destStoragePool) { - if (ClvmLockManager.isClvmPoolType(destStoragePool.getPoolType())) { + if (ClvmPoolManager.isClvmPoolType(destStoragePool.getPoolType())) { MigrateCommand.MigrateDiskInfo.DriverType driverType = (destStoragePool.getPoolType() == StoragePoolType.CLVM_NG) ? diff --git a/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategyTest.java b/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategyTest.java index 7976db2f007..e84163656b1 100755 --- a/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategyTest.java +++ b/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategyTest.java @@ -28,7 +28,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.never; import static org.mockito.Mockito.any; -import com.cloud.storage.ClvmLockManager; +import com.cloud.storage.clvm.ClvmPoolManager; import com.cloud.storage.Storage; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; @@ -99,6 +99,14 @@ public class AncientDataMotionStrategyTest { f.set(configKey, value); } + private ClvmPoolManager injectMockedClvmPoolManager() throws Exception { + ClvmPoolManager clvmPoolManager = Mockito.mock(ClvmPoolManager.class); + Field clvmPoolManagerField = AncientDataMotionStrategy.class.getDeclaredField("clvmPoolManager"); + clvmPoolManagerField.setAccessible(true); + clvmPoolManagerField.set(strategy, clvmPoolManager); + return clvmPoolManager; + } + @Test public void testAddFullCloneFlagOnVMwareDest(){ strategy.addFullCloneAndDiskprovisiongStrictnessFlagOnVMwareDest(dataTO); @@ -304,11 +312,7 @@ public class AncientDataMotionStrategyTest { EndPoint endPoint = Mockito.mock(EndPoint.class); VolumeInfo volumeInfo = Mockito.mock(VolumeInfo.class); DataStore dataStore = Mockito.mock(DataStore.class, Mockito.withSettings().extraInterfaces(StoragePool.class)); - ClvmLockManager clvmLockManager = Mockito.mock(ClvmLockManager.class); - - Field clvmLockManagerField = AncientDataMotionStrategy.class.getDeclaredField("clvmLockManager"); - clvmLockManagerField.setAccessible(true); - clvmLockManagerField.set(strategy, clvmLockManager); + ClvmPoolManager clvmPoolManager = injectMockedClvmPoolManager(); Long hostId = 123L; Long volumeId = 456L; @@ -320,12 +324,12 @@ public class AncientDataMotionStrategyTest { Mockito.when(volumeInfo.getUuid()).thenReturn(volumeUuid); Mockito.when(volumeInfo.getPath()).thenReturn("test-volume-path"); Mockito.when(((StoragePool) dataStore).getPoolType()).thenReturn(Storage.StoragePoolType.CLVM); - Mockito.when(clvmLockManager.getClvmLockHostId(Mockito.eq(volumeId), Mockito.eq(volumeUuid), + Mockito.when(clvmPoolManager.getClvmLockHostId(Mockito.eq(volumeId), Mockito.eq(volumeUuid), Mockito.anyString(), Mockito.any(StoragePool.class), Mockito.eq(true))).thenReturn(null); method.invoke(strategy, endPoint, volumeInfo); - Mockito.verify(clvmLockManager).setClvmLockHostId(volumeId, hostId); + Mockito.verify(clvmPoolManager).setClvmLockHostId(volumeId, hostId); } @Test @@ -339,11 +343,7 @@ public class AncientDataMotionStrategyTest { EndPoint endPoint = Mockito.mock(EndPoint.class); VolumeInfo volumeInfo = Mockito.mock(VolumeInfo.class); DataStore dataStore = Mockito.mock(DataStore.class, Mockito.withSettings().extraInterfaces(StoragePool.class)); - ClvmLockManager clvmLockManager = Mockito.mock(ClvmLockManager.class); - - Field clvmLockManagerField = AncientDataMotionStrategy.class.getDeclaredField("clvmLockManager"); - clvmLockManagerField.setAccessible(true); - clvmLockManagerField.set(strategy, clvmLockManager); + ClvmPoolManager clvmPoolManager = injectMockedClvmPoolManager(); Long hostId = 789L; Long volumeId = 101L; @@ -355,7 +355,7 @@ public class AncientDataMotionStrategyTest { Mockito.when(volumeInfo.getUuid()).thenReturn(volumeUuid); Mockito.when(volumeInfo.getPath()).thenReturn("test-clvm-ng-volume-path"); Mockito.when(((StoragePool) dataStore).getPoolType()).thenReturn(Storage.StoragePoolType.CLVM_NG); - Mockito.when(clvmLockManager.getClvmLockHostId(Mockito.eq(volumeId), Mockito.eq(volumeUuid), + Mockito.when(clvmPoolManager.getClvmLockHostId(Mockito.eq(volumeId), Mockito.eq(volumeUuid), Mockito.anyString(), Mockito.any(StoragePool.class), Mockito.eq(true))).thenReturn(null); try { @@ -365,7 +365,7 @@ public class AncientDataMotionStrategyTest { throw e; } - Mockito.verify(clvmLockManager).setClvmLockHostId(volumeId, hostId); + Mockito.verify(clvmPoolManager).setClvmLockHostId(volumeId, hostId); } @Test @@ -380,19 +380,15 @@ public class AncientDataMotionStrategyTest { VolumeInfo volumeInfo = Mockito.mock(VolumeInfo.class); // Create mock that implements both DataStore and StoragePool interfaces DataStore dataStore = Mockito.mock(DataStore.class, Mockito.withSettings().extraInterfaces(StoragePool.class)); - ClvmLockManager clvmLockManager = Mockito.mock(ClvmLockManager.class); - - Field clvmLockManagerField = AncientDataMotionStrategy.class.getDeclaredField("clvmLockManager"); - clvmLockManagerField.setAccessible(true); - clvmLockManagerField.set(strategy, clvmLockManager); + ClvmPoolManager clvmPoolManager = injectMockedClvmPoolManager(); Mockito.when(volumeInfo.getDataStore()).thenReturn(dataStore); Mockito.when(((StoragePool) dataStore).getPoolType()).thenReturn(Storage.StoragePoolType.NetworkFilesystem); method.invoke(strategy, endPoint, volumeInfo); - Mockito.verify(clvmLockManager, never()).setClvmLockHostId(any(Long.class), any(Long.class)); - Mockito.verify(clvmLockManager, never()).getClvmLockHostId(any(Long.class), any(String.class), + Mockito.verify(clvmPoolManager, never()).setClvmLockHostId(any(Long.class), any(Long.class)); + Mockito.verify(clvmPoolManager, never()).getClvmLockHostId(any(Long.class), any(String.class), any(String.class), any(StoragePool.class), Mockito.anyBoolean()); } @@ -407,11 +403,7 @@ public class AncientDataMotionStrategyTest { EndPoint endPoint = Mockito.mock(EndPoint.class); VolumeInfo volumeInfo = Mockito.mock(VolumeInfo.class); DataStore dataStore = Mockito.mock(DataStore.class, Mockito.withSettings().extraInterfaces(StoragePool.class)); - ClvmLockManager clvmLockManager = Mockito.mock(ClvmLockManager.class); - - Field clvmLockManagerField = AncientDataMotionStrategy.class.getDeclaredField("clvmLockManager"); - clvmLockManagerField.setAccessible(true); - clvmLockManagerField.set(strategy, clvmLockManager); + ClvmPoolManager clvmPoolManager = injectMockedClvmPoolManager(); Long hostId = 555L; Long existingHostId = 666L; @@ -424,13 +416,13 @@ public class AncientDataMotionStrategyTest { Mockito.when(volumeInfo.getUuid()).thenReturn(volumeUuid); Mockito.when(volumeInfo.getPath()).thenReturn("existing-lock-volume-path"); Mockito.when(((StoragePool) dataStore).getPoolType()).thenReturn(Storage.StoragePoolType.CLVM); - Mockito.when(clvmLockManager.getClvmLockHostId(Mockito.eq(volumeId), Mockito.eq(volumeUuid), + Mockito.when(clvmPoolManager.getClvmLockHostId(Mockito.eq(volumeId), Mockito.eq(volumeUuid), Mockito.anyString(), Mockito.any(StoragePool.class), Mockito.eq(true))).thenReturn(existingHostId); method.invoke(strategy, endPoint, volumeInfo); - Mockito.verify(clvmLockManager, never()).setClvmLockHostId(any(Long.class), any(Long.class)); - Mockito.verify(clvmLockManager).getClvmLockHostId(Mockito.eq(volumeId), Mockito.eq(volumeUuid), + Mockito.verify(clvmPoolManager, never()).setClvmLockHostId(any(Long.class), any(Long.class)); + Mockito.verify(clvmPoolManager).getClvmLockHostId(Mockito.eq(volumeId), Mockito.eq(volumeUuid), Mockito.anyString(), Mockito.any(StoragePool.class), Mockito.eq(true)); } @@ -442,19 +434,13 @@ public class AncientDataMotionStrategyTest { DataObject.class); method.setAccessible(true); - VolumeInfo volumeInfo = - Mockito.mock(VolumeInfo.class); - ClvmLockManager clvmLockManager = - Mockito.mock(ClvmLockManager.class); - - Field clvmLockManagerField = AncientDataMotionStrategy.class.getDeclaredField("clvmLockManager"); - clvmLockManagerField.setAccessible(true); - clvmLockManagerField.set(strategy, clvmLockManager); + VolumeInfo volumeInfo = Mockito.mock(VolumeInfo.class); + ClvmPoolManager clvmPoolManager = injectMockedClvmPoolManager(); method.invoke(strategy, null, volumeInfo); - Mockito.verify(clvmLockManager, never()).setClvmLockHostId(any(Long.class), any(Long.class)); - Mockito.verify(clvmLockManager, never()).getClvmLockHostId(any(Long.class), any(String.class), + Mockito.verify(clvmPoolManager, never()).setClvmLockHostId(any(Long.class), any(Long.class)); + Mockito.verify(clvmPoolManager, never()).getClvmLockHostId(any(Long.class), any(String.class), any(String.class), any(StoragePool.class), Mockito.anyBoolean()); } @@ -466,21 +452,14 @@ public class AncientDataMotionStrategyTest { DataObject.class); method.setAccessible(true); - EndPoint endPoint = - Mockito.mock(EndPoint.class); - SnapshotInfo snapshotInfo = - Mockito.mock(SnapshotInfo.class); - ClvmLockManager clvmLockManager = - Mockito.mock(ClvmLockManager.class); - - Field clvmLockManagerField = AncientDataMotionStrategy.class.getDeclaredField("clvmLockManager"); - clvmLockManagerField.setAccessible(true); - clvmLockManagerField.set(strategy, clvmLockManager); + EndPoint endPoint = Mockito.mock(EndPoint.class); + SnapshotInfo snapshotInfo = Mockito.mock(SnapshotInfo.class); + ClvmPoolManager clvmPoolManager = injectMockedClvmPoolManager(); method.invoke(strategy, endPoint, snapshotInfo); - Mockito.verify(clvmLockManager, never()).setClvmLockHostId(any(Long.class), any(Long.class)); - Mockito.verify(clvmLockManager, never()).getClvmLockHostId(any(Long.class), any(String.class), + Mockito.verify(clvmPoolManager, never()).setClvmLockHostId(any(Long.class), any(Long.class)); + Mockito.verify(clvmPoolManager, never()).getClvmLockHostId(any(Long.class), any(String.class), any(String.class), any(StoragePool.class), Mockito.anyBoolean()); } @@ -492,21 +471,14 @@ public class AncientDataMotionStrategyTest { DataObject.class); method.setAccessible(true); - EndPoint endPoint = - Mockito.mock(EndPoint.class); - VolumeInfo volumeInfo = - Mockito.mock(VolumeInfo.class); - ClvmLockManager clvmLockManager = - Mockito.mock(ClvmLockManager.class); - - Field clvmLockManagerField = AncientDataMotionStrategy.class.getDeclaredField("clvmLockManager"); - clvmLockManagerField.setAccessible(true); - clvmLockManagerField.set(strategy, clvmLockManager); + EndPoint endPoint = Mockito.mock(EndPoint.class); + VolumeInfo volumeInfo = Mockito.mock(VolumeInfo.class); + ClvmPoolManager clvmPoolManager = injectMockedClvmPoolManager(); method.invoke(strategy, endPoint, volumeInfo); - Mockito.verify(clvmLockManager, never()).setClvmLockHostId(any(Long.class), any(Long.class)); - Mockito.verify(clvmLockManager, never()).getClvmLockHostId(any(Long.class), any(String.class), + Mockito.verify(clvmPoolManager, never()).setClvmLockHostId(any(Long.class), any(Long.class)); + Mockito.verify(clvmPoolManager, never()).getClvmLockHostId(any(Long.class), any(String.class), any(String.class), any(StoragePool.class), Mockito.anyBoolean()); } } diff --git a/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/DefaultSnapshotStrategy.java b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/DefaultSnapshotStrategy.java index 030fc31e6b9..d85e862bfb6 100644 --- a/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/DefaultSnapshotStrategy.java +++ b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/DefaultSnapshotStrategy.java @@ -60,7 +60,7 @@ import com.cloud.event.UsageEventUtils; import com.cloud.exception.InvalidParameterValueException; import com.cloud.hypervisor.Hypervisor; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.storage.ClvmLockManager; +import com.cloud.storage.clvm.ClvmPoolManager; import com.cloud.storage.CreateSnapshotPayload; import com.cloud.storage.DataStoreRole; import com.cloud.storage.Snapshot; @@ -711,7 +711,7 @@ public class DefaultSnapshotStrategy extends SnapshotStrategyBase { } StoragePool pool = (StoragePool) dataStoreMgr.getDataStore(poolId, DataStoreRole.Primary); - if (pool == null || !ClvmLockManager.isClvmPoolType(pool.getPoolType())) { + if (pool == null || !ClvmPoolManager.isClvmPoolType(pool.getPoolType())) { return false; } diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index d313cc39ebf..9cf6a33e8a1 100644 --- a/engine/storage/src/main/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -32,7 +32,7 @@ import javax.inject.Inject; import com.cloud.dc.DedicatedResourceVO; import com.cloud.dc.dao.DedicatedResourceDao; -import com.cloud.storage.ClvmLockManager; +import com.cloud.storage.clvm.ClvmPoolManager; import com.cloud.storage.dao.VolumeDetailsDao; import com.cloud.user.Account; import com.cloud.utils.Pair; @@ -84,7 +84,7 @@ public class DefaultEndPointSelector implements EndPointSelector { @Inject private VolumeDetailsDao _volDetailsDao; @Inject - private ClvmLockManager clvmLockManager; + private ClvmPoolManager clvmPoolManager; private static final String VOL_ENCRYPT_COLUMN_NAME = "volume_encryption_support"; private final String findOneHostOnPrimaryStorage = "select t.id from " @@ -287,7 +287,7 @@ public class DefaultEndPointSelector implements EndPointSelector { DataStore srcStore = srcVolume.getDataStore(); if (srcStore.getRole() == DataStoreRole.Primary) { StoragePoolVO pool = _storagePoolDao.findById(srcStore.getId()); - if (pool != null && ClvmLockManager.isClvmPoolType(pool.getPoolType())) { + if (pool != null && ClvmPoolManager.isClvmPoolType(pool.getPoolType())) { Long lockHostId = getClvmLockHostId(srcVolume); if (lockHostId != null) { logger.info("Routing CLVM volume {} copy operation to source lock holder host {}", @@ -445,7 +445,7 @@ public class DefaultEndPointSelector implements EndPointSelector { // Check if this is a CLVM pool StoragePoolVO pool = _storagePoolDao.findById(store.getId()); - if (pool == null || !ClvmLockManager.isClvmPoolType(pool.getPoolType())) { + if (pool == null || !ClvmPoolManager.isClvmPoolType(pool.getPoolType())) { return null; } @@ -507,7 +507,7 @@ public class DefaultEndPointSelector implements EndPointSelector { if (object instanceof VolumeInfo && store.getRole() == DataStoreRole.Primary) { VolumeInfo volume = (VolumeInfo) object; StoragePoolVO pool = _storagePoolDao.findById(store.getId()); - if (pool != null && ClvmLockManager.isClvmPoolType(pool.getPoolType())) { + if (pool != null && ClvmPoolManager.isClvmPoolType(pool.getPoolType())) { Long lockHostId = getClvmLockHostId(volume); if (lockHostId != null) { logger.debug("Routing CLVM volume {} operation to lock holder host {}", @@ -621,7 +621,7 @@ public class DefaultEndPointSelector implements EndPointSelector { DataStore store = volume.getDataStore(); if (store.getRole() == DataStoreRole.Primary) { StoragePoolVO pool = _storagePoolDao.findById(store.getId()); - if (pool != null && ClvmLockManager.isClvmPoolType(pool.getPoolType())) { + if (pool != null && ClvmPoolManager.isClvmPoolType(pool.getPoolType())) { Long lockHostId = getClvmLockHostId(volume); if (lockHostId != null) { logger.info("Routing CLVM volume {} deletion to lock holder host {}", @@ -747,7 +747,7 @@ public class DefaultEndPointSelector implements EndPointSelector { protected Long getClvmLockHostId(VolumeInfo volume) { StoragePoolVO pool = _storagePoolDao.findById(volume.getPoolId()); - Long lockHostId = clvmLockManager.getClvmLockHostId( + Long lockHostId = clvmPoolManager.getClvmLockHostId( volume.getId(), volume.getUuid(), volume.getPath(), diff --git a/engine/storage/src/test/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelectorTest.java b/engine/storage/src/test/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelectorTest.java index aee944ad829..a05adf3a4c8 100644 --- a/engine/storage/src/test/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelectorTest.java +++ b/engine/storage/src/test/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelectorTest.java @@ -20,7 +20,7 @@ package org.apache.cloudstack.storage.endpoint; import com.cloud.host.Host; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor; -import com.cloud.storage.ClvmLockManager; +import com.cloud.storage.clvm.ClvmPoolManager; import com.cloud.storage.DataStoreRole; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.VolumeDetailVO; @@ -82,7 +82,7 @@ public class DefaultEndPointSelectorTest { private EndPoint endPointMock; @Mock - ClvmLockManager clvmLockManager; + ClvmPoolManager clvmPoolManager; @Mock HostDao hostDao; diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java index 4b8c9e3e77a..7644d4688f7 100644 --- a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java +++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java @@ -37,14 +37,13 @@ import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkVO; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; -import com.cloud.storage.ClvmLockManager; +import com.cloud.storage.clvm.ClvmPoolManager; import com.cloud.storage.DataStoreRole; import com.cloud.storage.Storage; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolHostVO; import com.cloud.storage.StorageService; -import com.cloud.storage.VolumeApiServiceImpl; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.utils.exception.CloudRuntimeException; @@ -145,8 +144,8 @@ public class DefaultHostListener implements HypervisorHostListener { // Propagate CLVM secure zero-fill setting to the host // Note: This is done during host connection (agent start, MS restart, host reconnection) // so the setting is non-dynamic. Changes require host reconnection to take effect. - if (ClvmLockManager.isClvmPoolType(pool.getPoolType())) { - Boolean clvmSecureZeroFill = VolumeApiServiceImpl.CLVMSecureZeroFill.valueIn(poolId); + if (ClvmPoolManager.isClvmPoolType(pool.getPoolType())) { + Boolean clvmSecureZeroFill = ClvmPoolManager.CLVMSecureZeroFill.valueIn(poolId); if (clvmSecureZeroFill != null) { detailsMap.put("clvmsecurezerofill", String.valueOf(clvmSecureZeroFill)); logger.debug("Added CLVM secure zero-fill setting: {} for storage pool: {}", clvmSecureZeroFill, pool); diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java index e8934d0ff71..20d677f9013 100644 --- a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -24,6 +24,7 @@ import com.cloud.configuration.Resource.ResourceType; import com.cloud.dc.VsphereStoragePolicyVO; import com.cloud.dc.dao.VsphereStoragePolicyDao; import com.cloud.storage.StorageManager; +import com.cloud.storage.clvm.ClvmPoolManager; import com.cloud.utils.Pair; import com.cloud.utils.db.Transaction; import com.cloud.utils.db.TransactionCallbackNoReturn; @@ -364,12 +365,12 @@ public class VolumeObject implements VolumeInfo { @Override public Long getDestinationHostId() { - // If not in memory, try to load from database (volume_details table) - // For CLVM volumes, this uses the CLVM_LOCK_HOST_ID which serves dual purpose: + // If not in memory, try to load from the database (volume_details table) + // For CLVM volumes, this uses the CLVM_LOCK_HOST_ID, which serves a dual purpose: // 1. During creation: hints where to create the volume // 2. After creation: tracks which host holds the exclusive lock if (destinationHostId == null && volumeVO != null) { - VolumeDetailVO detail = volumeDetailsDao.findDetail(volumeVO.getId(), CLVM_LOCK_HOST_ID); + VolumeDetailVO detail = volumeDetailsDao.findDetail(volumeVO.getId(), ClvmPoolManager.CLVM_LOCK_HOST_ID); if (detail != null && detail.getValue() != null && !detail.getValue().isEmpty()) { try { destinationHostId = Long.parseLong(detail.getValue()); diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index b3fdb04da2c..9bab1813293 100644 --- a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -32,7 +32,7 @@ import java.util.concurrent.ExecutionException; import javax.inject.Inject; -import com.cloud.storage.ClvmLockManager; +import com.cloud.storage.clvm.ClvmPoolManager; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.dao.VMInstanceDao; import org.apache.cloudstack.annotation.AnnotationService; @@ -224,7 +224,7 @@ public class VolumeServiceImpl implements VolumeService { @Inject protected DiskOfferingDao diskOfferingDao; @Inject - ClvmLockManager clvmLockManager; + ClvmPoolManager clvmPoolManager; public VolumeServiceImpl() { } @@ -2979,7 +2979,7 @@ public class VolumeServiceImpl implements VolumeService { logger.info("Transferring CLVM lock for volume {} (pool: {}) from host {} to host {}", volume.getUuid(), pool.getName(), sourceHostId, destHostId); - return clvmLockManager.transferClvmVolumeLock(volume.getUuid(), volume.getId(), volume.getPath(), + return clvmPoolManager.transferClvmVolumeLock(volume.getUuid(), volume.getId(), volume.getPath(), pool, sourceHostId, destHostId); } @@ -2992,7 +2992,7 @@ public class VolumeServiceImpl implements VolumeService { StoragePoolVO pool = storagePoolDao.findById(volume.getPoolId()); - Long lockHostId = clvmLockManager.getClvmLockHostId( + Long lockHostId = clvmPoolManager.getClvmLockHostId( volume.getId(), volume.getUuid(), volume.getPath(), @@ -3077,14 +3077,14 @@ public class VolumeServiceImpl implements VolumeService { logger.debug("Cannot check if both pools are CLVM type: one or both pool types are null"); return false; } - return ClvmLockManager.isClvmPoolType(volumePoolType) && - ClvmLockManager.isClvmPoolType(vmPoolType); + return ClvmPoolManager.isClvmPoolType(volumePoolType) && + ClvmPoolManager.isClvmPoolType(vmPoolType); } @Override public boolean isLockTransferRequired(VolumeInfo volumeToAttach, StoragePoolType volumePoolType, StoragePoolType vmPoolType, Long volumePoolId, Long vmPoolId, Long vmHostId) { - if (volumePoolType != null && !ClvmLockManager.isClvmPoolType(volumePoolType)) { + if (volumePoolType != null && !ClvmPoolManager.isClvmPoolType(volumePoolType)) { return false; } diff --git a/engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/VolumeServiceImplClvmTest.java b/engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/VolumeServiceImplClvmTest.java index 59ff7dc8305..38af2a7550b 100644 --- a/engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/VolumeServiceImplClvmTest.java +++ b/engine/storage/volume/src/test/java/org/apache/cloudstack/storage/volume/VolumeServiceImplClvmTest.java @@ -26,7 +26,7 @@ import static org.mockito.Mockito.eq; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; -import com.cloud.storage.ClvmLockManager; +import com.cloud.storage.clvm.ClvmPoolManager; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.dao.VMInstanceDao; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; @@ -87,7 +87,7 @@ public class VolumeServiceImplClvmTest { private VMInstanceVO vmInstanceVOMock; @Mock - private ClvmLockManager clvmLockManager; + private ClvmPoolManager clvmPoolManager; private static final Long VOLUME_ID = 1L; private static final Long POOL_ID_1 = 100L; @@ -107,7 +107,7 @@ public class VolumeServiceImplClvmTest { volumeService.vmDao = vmDao; volumeService.volFactory = volFactory; volumeService._volumeDao = volumeDao; - volumeService.clvmLockManager = clvmLockManager; + volumeService.clvmPoolManager = clvmPoolManager; } @Test @@ -355,7 +355,7 @@ public class VolumeServiceImplClvmTest { when(volumeInfoMock.getPath()).thenReturn("/dev/vg1/volume-1"); when(storagePoolDao.findById(POOL_ID_1)).thenReturn(storagePoolVOMock); when(storagePoolVOMock.getName()).thenReturn("test-pool"); - when(clvmLockManager.transferClvmVolumeLock( + when(clvmPoolManager.transferClvmVolumeLock( "test-volume-uuid", VOLUME_ID, "/dev/vg1/volume-1", storagePoolVOMock, HOST_ID_1, HOST_ID_2)) .thenReturn(true); @@ -369,7 +369,7 @@ public class VolumeServiceImplClvmTest { when(volumeInfoMock.getPath()).thenReturn("/dev/vg1/volume-1"); when(storagePoolDao.findById(POOL_ID_1)).thenReturn(storagePoolVOMock); when(storagePoolVOMock.getName()).thenReturn("test-pool"); - when(clvmLockManager.transferClvmVolumeLock( + when(clvmPoolManager.transferClvmVolumeLock( "test-volume-uuid", VOLUME_ID, "/dev/vg1/volume-1", storagePoolVOMock, HOST_ID_1, HOST_ID_2)) .thenReturn(false); @@ -394,7 +394,7 @@ public class VolumeServiceImplClvmTest { public void testFindVolumeLockHost_ExplicitLockFound() { when(volumeInfoMock.getPoolId()).thenReturn(POOL_ID_1); when(storagePoolDao.findById(POOL_ID_1)).thenReturn(storagePoolVOMock); - when(clvmLockManager.getClvmLockHostId( + when(clvmPoolManager.getClvmLockHostId( eq(VOLUME_ID), eq("test-volume-uuid"), eq("test-volume-path"), eq(storagePoolVOMock), eq(true))) .thenReturn(HOST_ID_1); @@ -406,7 +406,7 @@ public class VolumeServiceImplClvmTest { public void testFindVolumeLockHost_FromAttachedVM() { when(volumeInfoMock.getPoolId()).thenReturn(POOL_ID_1); when(storagePoolDao.findById(POOL_ID_1)).thenReturn(storagePoolVOMock); - when(clvmLockManager.getClvmLockHostId( + when(clvmPoolManager.getClvmLockHostId( eq(VOLUME_ID), eq("test-volume-uuid"), eq("test-volume-path"), eq(storagePoolVOMock), eq(true))) .thenReturn(null); when(volumeInfoMock.getInstanceId()).thenReturn(100L); @@ -422,7 +422,7 @@ public class VolumeServiceImplClvmTest { public void testFindVolumeLockHost_FallbackToClusterHost() { when(volumeInfoMock.getPoolId()).thenReturn(POOL_ID_1); when(storagePoolDao.findById(POOL_ID_1)).thenReturn(storagePoolVOMock); - when(clvmLockManager.getClvmLockHostId( + when(clvmPoolManager.getClvmLockHostId( eq(VOLUME_ID), eq("test-volume-uuid"), eq("test-volume-path"), eq(storagePoolVOMock), eq(true))) .thenReturn(null); when(volumeInfoMock.getInstanceId()).thenReturn(null); @@ -439,7 +439,7 @@ public class VolumeServiceImplClvmTest { public void testFindVolumeLockHost_NoHostFound() { when(volumeInfoMock.getPoolId()).thenReturn(POOL_ID_1); when(storagePoolDao.findById(POOL_ID_1)).thenReturn(storagePoolVOMock); - when(clvmLockManager.getClvmLockHostId( + when(clvmPoolManager.getClvmLockHostId( eq(VOLUME_ID), eq("test-volume-uuid"), eq("test-volume-path"), eq(storagePoolVOMock), eq(true))) .thenReturn(null); when(volumeInfoMock.getInstanceId()).thenReturn(null); @@ -456,11 +456,11 @@ public class VolumeServiceImplClvmTest { when(volumeInfoMock.getId()).thenReturn(VOLUME_ID); when(volumeInfoMock.getPath()).thenReturn("/dev/vg1/volume-1"); when(storagePoolDao.findById(POOL_ID_1)).thenReturn(storagePoolVOMock); - when(clvmLockManager.getClvmLockHostId( + when(clvmPoolManager.getClvmLockHostId( eq(VOLUME_ID), eq("test-volume-uuid"), eq("/dev/vg1/volume-1"), eq(storagePoolVOMock), eq(true))) .thenReturn(HOST_ID_1); when(storagePoolVOMock.getName()).thenReturn("test-pool"); - when(clvmLockManager.transferClvmVolumeLock( + when(clvmPoolManager.transferClvmVolumeLock( "test-volume-uuid", VOLUME_ID, "/dev/vg1/volume-1", storagePoolVOMock, HOST_ID_1, HOST_ID_2)) .thenReturn(true); when(volFactory.getVolume(VOLUME_ID)).thenReturn(volumeInfoMock); @@ -473,7 +473,7 @@ public class VolumeServiceImplClvmTest { public void testPerformLockMigration_SameHost() { when(volumeInfoMock.getPoolId()).thenReturn(POOL_ID_1); when(storagePoolDao.findById(POOL_ID_1)).thenReturn(storagePoolVOMock); - when(clvmLockManager.getClvmLockHostId( + when(clvmPoolManager.getClvmLockHostId( eq(VOLUME_ID), eq("test-volume-uuid"), eq("test-volume-path"), eq(storagePoolVOMock), eq(true))) .thenReturn(HOST_ID_1); @@ -486,7 +486,7 @@ public class VolumeServiceImplClvmTest { when(volumeInfoMock.getPoolId()).thenReturn(POOL_ID_1); when(volumeInfoMock.getId()).thenReturn(VOLUME_ID); when(storagePoolDao.findById(POOL_ID_1)).thenReturn(storagePoolVOMock); - when(clvmLockManager.getClvmLockHostId( + when(clvmPoolManager.getClvmLockHostId( eq(VOLUME_ID), eq("test-volume-uuid"), eq("test-volume-path"), eq(storagePoolVOMock), eq(true))) .thenReturn(null); when(volumeInfoMock.getInstanceId()).thenReturn(null); @@ -507,11 +507,11 @@ public class VolumeServiceImplClvmTest { when(volumeInfoMock.getId()).thenReturn(VOLUME_ID); when(volumeInfoMock.getPath()).thenReturn("/dev/vg1/volume-1"); when(storagePoolDao.findById(POOL_ID_1)).thenReturn(storagePoolVOMock); - when(clvmLockManager.getClvmLockHostId( + when(clvmPoolManager.getClvmLockHostId( eq(VOLUME_ID), eq("test-volume-uuid"), eq("/dev/vg1/volume-1"), eq(storagePoolVOMock), eq(true))) .thenReturn(HOST_ID_1); when(storagePoolVOMock.getName()).thenReturn("test-pool"); - when(clvmLockManager.transferClvmVolumeLock( + when(clvmPoolManager.transferClvmVolumeLock( "test-volume-uuid", VOLUME_ID, "/dev/vg1/volume-1", storagePoolVOMock, HOST_ID_1, HOST_ID_2)) .thenReturn(false); diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtClvmLockTransferCommandWrapper.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtClvmLockTransferCommandWrapper.java index 8404e93a348..f2bdba3a83e 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtClvmLockTransferCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtClvmLockTransferCommandWrapper.java @@ -21,8 +21,8 @@ import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; import com.cloud.agent.api.Answer; -import org.apache.cloudstack.storage.command.ClvmLockTransferCommand; -import org.apache.cloudstack.storage.command.ClvmLockTransferAnswer; +import org.apache.cloudstack.storage.clvm.command.ClvmLockTransferCommand; +import org.apache.cloudstack.storage.clvm.command.ClvmLockTransferAnswer; import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; import com.cloud.resource.CommandWrapper; import com.cloud.resource.ResourceWrapper; diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java index 21ee26a929a..f2608ba5dca 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java @@ -55,6 +55,7 @@ import javax.xml.xpath.XPathFactory; import com.cloud.agent.api.Command; import com.cloud.hypervisor.kvm.resource.LibvirtXMLParser; +import com.cloud.storage.clvm.ClvmPoolManager; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -138,7 +139,6 @@ import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.DeviceType; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.DiscardType; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.DiskProtocol; -import com.cloud.storage.ClvmLockManager; import com.cloud.storage.JavaStorageLayer; import com.cloud.storage.MigrationOptions; import com.cloud.storage.ScopeType; @@ -623,7 +623,7 @@ public class KVMStorageProcessor implements StorageProcessor { String path = details != null ? details.get(DiskTO.IQN) : null; - if (!ClvmLockManager.isClvmPoolType(primaryStore.getPoolType())) { + if (!ClvmPoolManager.isClvmPoolType(primaryStore.getPoolType())) { storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path, details); } @@ -654,7 +654,7 @@ public class KVMStorageProcessor implements StorageProcessor { final KVMPhysicalDisk newDisk = storagePoolMgr.copyPhysicalDisk(volume, path != null ? path : volumeName, primaryPool, cmd.getWaitInMillSeconds()); resource.createOrUpdateLogFileForCommand(cmd, Command.State.COMPLETED); - if (!ClvmLockManager.isClvmPoolType(primaryStore.getPoolType())) { + if (!ClvmPoolManager.isClvmPoolType(primaryStore.getPoolType())) { storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path); } diff --git a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtClvmLockTransferCommandWrapperTest.java b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtClvmLockTransferCommandWrapperTest.java index 48b72bcd0e7..d534cd29c40 100644 --- a/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtClvmLockTransferCommandWrapperTest.java +++ b/plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtClvmLockTransferCommandWrapperTest.java @@ -24,7 +24,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import org.apache.cloudstack.storage.command.ClvmLockTransferCommand; +import org.apache.cloudstack.storage.clvm.command.ClvmLockTransferCommand; import org.apache.logging.log4j.Logger; import org.junit.Before; import org.junit.Test; diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index ec2dd239cb7..8790afe1738 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -35,6 +35,7 @@ import java.util.stream.Collectors; import javax.inject.Inject; +import com.cloud.storage.clvm.ClvmPoolManager; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.api.InternalIdentity; @@ -371,7 +372,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic @Inject EndPointSelector _epSelector; @Inject - ClvmLockManager clvmLockManager; + ClvmPoolManager clvmPoolManager; @Inject private ReservationDao reservationDao; @Inject @@ -416,8 +417,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic public static final ConfigKey AllowCheckAndRepairVolume = new ConfigKey<>("Advanced", Boolean.class, "volume.check.and.repair.leaks.before.use", "false", "To check and repair the volume if it has any leaks before performing volume attach or VM start operations", true, ConfigKey.Scope.StoragePool); - public static final ConfigKey CLVMSecureZeroFill = new ConfigKey<>("Advanced", Boolean.class, "clvm.secure.zero.fill", "false", - "When enabled, CLVM volumes to be zero-filled at the time of deletion to prevent data from being recovered by VMs reusing the space, as thick LVM volumes write data linearly. Note: This setting is propagated to hosts when they connect to the storage pool. Changing this setting requires disconnecting and reconnecting hosts or restarting the KVM agent for it to take effect.", false, ConfigKey.Scope.StoragePool); + private final StateMachine2 _volStateMachine; @@ -1825,7 +1825,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic // Clean up CLVM lock host tracking detail after successful deletion from primary storage if (DataStoreRole.Primary.equals(role)) { - clvmLockManager.clearClvmLockHostDetail(volume); + clvmPoolManager.clearClvmLockHostDetail(volume); } } } @@ -5737,7 +5737,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic UseHttpsToUpload, WaitDetachDevice, AllowCheckAndRepairVolume, - CLVMSecureZeroFill }; } } diff --git a/server/src/main/java/com/cloud/storage/ClvmLockManager.java b/server/src/main/java/com/cloud/storage/clvm/ClvmPoolManager.java similarity index 88% rename from server/src/main/java/com/cloud/storage/ClvmLockManager.java rename to server/src/main/java/com/cloud/storage/clvm/ClvmPoolManager.java index adcb774c419..e5ce47bdee3 100644 --- a/server/src/main/java/com/cloud/storage/ClvmLockManager.java +++ b/server/src/main/java/com/cloud/storage/clvm/ClvmPoolManager.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package com.cloud.storage; +package com.cloud.storage.clvm; import java.util.Arrays; import java.util.List; @@ -31,16 +31,21 @@ import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor; +import com.cloud.storage.Storage; +import com.cloud.storage.StoragePool; +import com.cloud.storage.VolumeDetailVO; +import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VolumeDetailsDao; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; -import org.apache.cloudstack.storage.command.ClvmLockTransferCommand; -import org.apache.cloudstack.storage.command.ClvmLockTransferAnswer; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; +import org.apache.cloudstack.storage.clvm.command.ClvmLockTransferCommand; +import org.apache.cloudstack.storage.clvm.command.ClvmLockTransferAnswer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.stereotype.Component; @Component -public class ClvmLockManager { +public class ClvmPoolManager implements Configurable { @Inject private VolumeDetailsDao _volsDetailsDao; @Inject @@ -50,6 +55,15 @@ public class ClvmLockManager { protected Logger logger = LogManager.getLogger(getClass()); + /** + * Constant for the volume detail key that stores the host ID currently holding the CLVM exclusive lock. + * This is used during lightweight lock migration to determine the source host for lock transfer. + */ + public static final String CLVM_LOCK_HOST_ID = "clvmLockHostId"; + + public static final ConfigKey CLVMSecureZeroFill = new ConfigKey<>("Advanced", Boolean.class, "clvm.secure.zero.fill", "false", + "When enabled, CLVM volumes to be zero-filled at the time of deletion to prevent data from being recovered by VMs reusing the space, as thick LVM volumes write data linearly. Note: This setting is propagated to hosts when they connect to the storage pool. Changing this setting requires disconnecting and reconnecting hosts or restarting the KVM agent for it to take effect.", false, ConfigKey.Scope.StoragePool); + public static boolean isClvmPoolType(Storage.StoragePoolType poolType) { return Arrays.asList(Storage.StoragePoolType.CLVM, Storage.StoragePoolType.CLVM_NG).contains(poolType); } @@ -63,7 +77,7 @@ public class ClvmLockManager { * @deprecated Use getClvmLockHostId(volumeId, volumeUuid, volumePath, pool, queryActual) instead */ public Long getClvmLockHostId(Long volumeId, String volumeUuid) { - VolumeDetailVO detail = _volsDetailsDao.findDetail(volumeId, VolumeInfo.CLVM_LOCK_HOST_ID); + VolumeDetailVO detail = _volsDetailsDao.findDetail(volumeId, CLVM_LOCK_HOST_ID); if (detail != null && detail.getValue() != null && !detail.getValue().isEmpty()) { try { return Long.parseLong(detail.getValue()); @@ -108,14 +122,14 @@ public class ClvmLockManager { * @param hostId The host ID that holds/should hold the CLVM exclusive lock */ public void setClvmLockHostId(long volumeId, long hostId) { - VolumeDetailVO existingDetail = _volsDetailsDao.findDetail(volumeId, VolumeInfo.CLVM_LOCK_HOST_ID); + VolumeDetailVO existingDetail = _volsDetailsDao.findDetail(volumeId, CLVM_LOCK_HOST_ID); if (existingDetail != null) { existingDetail.setValue(String.valueOf(hostId)); _volsDetailsDao.update(existingDetail.getId(), existingDetail); logger.debug("Updated CLVM_LOCK_HOST_ID for volume {} to host {}", volumeId, hostId); return; } - _volsDetailsDao.addDetail(volumeId, VolumeInfo.CLVM_LOCK_HOST_ID, String.valueOf(hostId), false); + _volsDetailsDao.addDetail(volumeId, CLVM_LOCK_HOST_ID, String.valueOf(hostId), false); logger.debug("Created CLVM_LOCK_HOST_ID for volume {} with host {}", volumeId, hostId); } @@ -199,7 +213,7 @@ public class ClvmLockManager { if (hostname == null || hostname.isEmpty()) { logger.debug("Volume {} is not locked (no exclusive lock held)", volumeUuid); if (updateDatabase) { - VolumeDetailVO detail = _volsDetailsDao.findDetail(volumeId, VolumeInfo.CLVM_LOCK_HOST_ID); + VolumeDetailVO detail = _volsDetailsDao.findDetail(volumeId, CLVM_LOCK_HOST_ID); if (detail != null) { _volsDetailsDao.remove(detail.getId()); } @@ -246,7 +260,7 @@ public class ClvmLockManager { */ public void clearClvmLockHostDetail(VolumeVO volume) { try { - VolumeDetailVO detail = _volsDetailsDao.findDetail(volume.getId(), VolumeInfo.CLVM_LOCK_HOST_ID); + VolumeDetailVO detail = _volsDetailsDao.findDetail(volume.getId(), CLVM_LOCK_HOST_ID); if (detail != null) { logger.debug("Removing CLVM lock host detail for deleted volume {}", volume.getUuid()); _volsDetailsDao.remove(detail.getId()); @@ -331,4 +345,16 @@ public class ClvmLockManager { return false; } } + + @Override + public String getConfigComponentName() { + return ClvmPoolManager.class.getSimpleName(); + } + + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[] { + CLVMSecureZeroFill + }; + } } diff --git a/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml b/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml index ab6eb363be0..a461e60885e 100644 --- a/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml +++ b/server/src/main/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml @@ -183,7 +183,7 @@ - + diff --git a/server/src/test/java/com/cloud/storage/ClvmLockManagerTest.java b/server/src/test/java/com/cloud/storage/ClvmPoolManagerTest.java similarity index 88% rename from server/src/test/java/com/cloud/storage/ClvmLockManagerTest.java rename to server/src/test/java/com/cloud/storage/ClvmPoolManagerTest.java index bec64da0a1b..c67f2300dd6 100644 --- a/server/src/test/java/com/cloud/storage/ClvmLockManagerTest.java +++ b/server/src/test/java/com/cloud/storage/ClvmPoolManagerTest.java @@ -26,10 +26,10 @@ import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor; +import com.cloud.storage.clvm.ClvmPoolManager; import com.cloud.storage.dao.VolumeDetailsDao; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; -import org.apache.cloudstack.storage.command.ClvmLockTransferAnswer; -import org.apache.cloudstack.storage.command.ClvmLockTransferCommand; +import org.apache.cloudstack.storage.clvm.command.ClvmLockTransferAnswer; +import org.apache.cloudstack.storage.clvm.command.ClvmLockTransferCommand; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.junit.Assert; import org.junit.Before; @@ -52,7 +52,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) -public class ClvmLockManagerTest { +public class ClvmPoolManagerTest { @Mock private VolumeDetailsDao volsDetailsDao; @@ -64,7 +64,7 @@ public class ClvmLockManagerTest { private HostDao hostDao; @InjectMocks - private ClvmLockManager clvmLockManager; + private ClvmPoolManager clvmPoolManager; private static final Long VOLUME_ID = 100L; private static final Long HOST_ID_1 = 1L; @@ -82,18 +82,18 @@ public class ClvmLockManagerTest { public void testGetClvmLockHostId_Success() { VolumeDetailVO detail = new VolumeDetailVO(); detail.setValue("123"); - when(volsDetailsDao.findDetail(VOLUME_ID, VolumeInfo.CLVM_LOCK_HOST_ID)).thenReturn(detail); + when(volsDetailsDao.findDetail(VOLUME_ID, ClvmPoolManager.CLVM_LOCK_HOST_ID)).thenReturn(detail); - Long result = clvmLockManager.getClvmLockHostId(VOLUME_ID, VOLUME_UUID); + Long result = clvmPoolManager.getClvmLockHostId(VOLUME_ID, VOLUME_UUID); Assert.assertEquals(Long.valueOf(123), result); } @Test public void testGetClvmLockHostId_NoDetail() { - when(volsDetailsDao.findDetail(VOLUME_ID, VolumeInfo.CLVM_LOCK_HOST_ID)).thenReturn(null); + when(volsDetailsDao.findDetail(VOLUME_ID, ClvmPoolManager.CLVM_LOCK_HOST_ID)).thenReturn(null); - Long result = clvmLockManager.getClvmLockHostId(VOLUME_ID, VOLUME_UUID); + Long result = clvmPoolManager.getClvmLockHostId(VOLUME_ID, VOLUME_UUID); Assert.assertNull(result); } @@ -102,20 +102,20 @@ public class ClvmLockManagerTest { public void testGetClvmLockHostId_InvalidNumber() { VolumeDetailVO detail = new VolumeDetailVO(); detail.setValue("invalid"); - when(volsDetailsDao.findDetail(VOLUME_ID, VolumeInfo.CLVM_LOCK_HOST_ID)).thenReturn(detail); + when(volsDetailsDao.findDetail(VOLUME_ID, ClvmPoolManager.CLVM_LOCK_HOST_ID)).thenReturn(detail); - Long result = clvmLockManager.getClvmLockHostId(VOLUME_ID, VOLUME_UUID); + Long result = clvmPoolManager.getClvmLockHostId(VOLUME_ID, VOLUME_UUID); Assert.assertNull(result); } @Test public void testSetClvmLockHostId_NewDetail() { - when(volsDetailsDao.findDetail(VOLUME_ID, VolumeInfo.CLVM_LOCK_HOST_ID)).thenReturn(null); + when(volsDetailsDao.findDetail(VOLUME_ID, ClvmPoolManager.CLVM_LOCK_HOST_ID)).thenReturn(null); - clvmLockManager.setClvmLockHostId(VOLUME_ID, HOST_ID_1); + clvmPoolManager.setClvmLockHostId(VOLUME_ID, HOST_ID_1); - verify(volsDetailsDao, times(1)).addDetail(eq(VOLUME_ID), eq(VolumeInfo.CLVM_LOCK_HOST_ID), + verify(volsDetailsDao, times(1)).addDetail(eq(VOLUME_ID), eq(ClvmPoolManager.CLVM_LOCK_HOST_ID), eq(String.valueOf(HOST_ID_1)), eq(false)); verify(volsDetailsDao, never()).update(anyLong(), any()); } @@ -124,9 +124,9 @@ public class ClvmLockManagerTest { public void testSetClvmLockHostId_UpdateExisting() { VolumeDetailVO existingDetail = Mockito.mock(VolumeDetailVO.class); when(existingDetail.getId()).thenReturn(50L); - when(volsDetailsDao.findDetail(VOLUME_ID, VolumeInfo.CLVM_LOCK_HOST_ID)).thenReturn(existingDetail); + when(volsDetailsDao.findDetail(VOLUME_ID, ClvmPoolManager.CLVM_LOCK_HOST_ID)).thenReturn(existingDetail); - clvmLockManager.setClvmLockHostId(VOLUME_ID, HOST_ID_2); + clvmPoolManager.setClvmLockHostId(VOLUME_ID, HOST_ID_2); verify(existingDetail, times(1)).setValue(String.valueOf(HOST_ID_2)); verify(volsDetailsDao, times(1)).update(eq(50L), eq(existingDetail)); @@ -141,9 +141,9 @@ public class ClvmLockManagerTest { VolumeDetailVO detail = Mockito.mock(VolumeDetailVO.class); when(detail.getId()).thenReturn(99L); - when(volsDetailsDao.findDetail(VOLUME_ID, VolumeInfo.CLVM_LOCK_HOST_ID)).thenReturn(detail); + when(volsDetailsDao.findDetail(VOLUME_ID, ClvmPoolManager.CLVM_LOCK_HOST_ID)).thenReturn(detail); - clvmLockManager.clearClvmLockHostDetail(volume); + clvmPoolManager.clearClvmLockHostDetail(volume); verify(volsDetailsDao, times(1)).remove(99L); } @@ -152,9 +152,9 @@ public class ClvmLockManagerTest { public void testClearClvmLockHostDetail_NoDetail() { VolumeVO volume = Mockito.mock(VolumeVO.class); when(volume.getId()).thenReturn(VOLUME_ID); - when(volsDetailsDao.findDetail(VOLUME_ID, VolumeInfo.CLVM_LOCK_HOST_ID)).thenReturn(null); + when(volsDetailsDao.findDetail(VOLUME_ID, ClvmPoolManager.CLVM_LOCK_HOST_ID)).thenReturn(null); - clvmLockManager.clearClvmLockHostDetail(volume); + clvmPoolManager.clearClvmLockHostDetail(volume); verify(volsDetailsDao, never()).remove(anyLong()); } @@ -174,7 +174,7 @@ public class ClvmLockManagerTest { when(agentMgr.send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class))).thenReturn(deactivateAnswer); when(agentMgr.send(eq(HOST_ID_2), any(ClvmLockTransferCommand.class))).thenReturn(activateAnswer); - boolean result = clvmLockManager.transferClvmVolumeLock(VOLUME_UUID, VOLUME_ID, + boolean result = clvmPoolManager.transferClvmVolumeLock(VOLUME_UUID, VOLUME_ID, VOLUME_PATH, pool, HOST_ID_1, HOST_ID_2); Assert.assertTrue(result); @@ -183,7 +183,7 @@ public class ClvmLockManagerTest { @Test public void testTransferClvmVolumeLock_NullPool() { - boolean result = clvmLockManager.transferClvmVolumeLock(VOLUME_UUID, VOLUME_ID, + boolean result = clvmPoolManager.transferClvmVolumeLock(VOLUME_UUID, VOLUME_ID, VOLUME_PATH, null, HOST_ID_1, HOST_ID_2); Assert.assertFalse(result); @@ -197,7 +197,7 @@ public class ClvmLockManagerTest { Answer activateAnswer = new Answer(null, true, null); when(agentMgr.send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class))).thenReturn(activateAnswer); - boolean result = clvmLockManager.transferClvmVolumeLock(VOLUME_UUID, VOLUME_ID, + boolean result = clvmPoolManager.transferClvmVolumeLock(VOLUME_UUID, VOLUME_ID, VOLUME_PATH, pool, HOST_ID_1, HOST_ID_1); Assert.assertTrue(result); @@ -212,7 +212,7 @@ public class ClvmLockManagerTest { Answer activateAnswer = new Answer(null, false, "Activation failed"); when(agentMgr.send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class))).thenReturn(activateAnswer); - boolean result = clvmLockManager.transferClvmVolumeLock(VOLUME_UUID, VOLUME_ID, + boolean result = clvmPoolManager.transferClvmVolumeLock(VOLUME_UUID, VOLUME_ID, VOLUME_PATH, pool, HOST_ID_1, HOST_ID_1); Assert.assertFalse(result); @@ -226,7 +226,7 @@ public class ClvmLockManagerTest { when(agentMgr.send(anyLong(), any(ClvmLockTransferCommand.class))) .thenThrow(new AgentUnavailableException("Agent unavailable", HOST_ID_2)); - boolean result = clvmLockManager.transferClvmVolumeLock(VOLUME_UUID, VOLUME_ID, + boolean result = clvmPoolManager.transferClvmVolumeLock(VOLUME_UUID, VOLUME_ID, VOLUME_PATH, pool, HOST_ID_1, HOST_ID_2); Assert.assertFalse(result); @@ -234,7 +234,7 @@ public class ClvmLockManagerTest { @Test public void testQueryCurrentLockHolder_NullPool() { - Long result = clvmLockManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, null, false); + Long result = clvmPoolManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, null, false); Assert.assertNull(result); verify(hostDao, never()).findByClusterId(anyLong(), any()); @@ -249,7 +249,7 @@ public class ClvmLockManagerTest { when(hostDao.findByClusterId(10L, Host.Type.Routing)).thenReturn(Collections.emptyList()); when(hostDao.findByDataCenterId(1L)).thenReturn(Collections.emptyList()); - Long result = clvmLockManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); + Long result = clvmPoolManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); Assert.assertNull(result); verify(hostDao, times(1)).findByClusterId(10L, Host.Type.Routing); @@ -271,7 +271,7 @@ public class ClvmLockManagerTest { when(agentMgr.send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class))).thenReturn(answer); when(hostDao.findByName("host1")).thenReturn(host); - Long result = clvmLockManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); + Long result = clvmPoolManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); Assert.assertEquals(HOST_ID_1, result); verify(hostDao, never()).findByClusterId(anyLong(), any()); @@ -292,7 +292,7 @@ public class ClvmLockManagerTest { when(agentMgr.send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class))).thenReturn(answer); when(hostDao.findByName("host1")).thenReturn(host); - Long result = clvmLockManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); + Long result = clvmPoolManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); Assert.assertEquals(HOST_ID_1, result); verify(agentMgr, times(1)).send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class)); @@ -311,7 +311,7 @@ public class ClvmLockManagerTest { ClvmLockTransferAnswer answer = new ClvmLockTransferAnswer(null, true, null, null, false, false, null); when(agentMgr.send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class))).thenReturn(answer); - Long result = clvmLockManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); + Long result = clvmPoolManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); Assert.assertNull(result); } @@ -329,7 +329,7 @@ public class ClvmLockManagerTest { ClvmLockTransferAnswer answer = new ClvmLockTransferAnswer(null, true, null, "", false, false, null); when(agentMgr.send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class))).thenReturn(answer); - Long result = clvmLockManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); + Long result = clvmPoolManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); Assert.assertNull(result); } @@ -348,7 +348,7 @@ public class ClvmLockManagerTest { when(agentMgr.send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class))).thenReturn(answer); when(hostDao.findByName("unknown-host")).thenReturn(null); - Long result = clvmLockManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); + Long result = clvmPoolManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); Assert.assertNull(result); } @@ -366,7 +366,7 @@ public class ClvmLockManagerTest { Answer failedAnswer = new Answer(null, false, "Query failed"); when(agentMgr.send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class))).thenReturn(failedAnswer); - Long result = clvmLockManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); + Long result = clvmPoolManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); Assert.assertNull(result); } @@ -383,7 +383,7 @@ public class ClvmLockManagerTest { when(agentMgr.send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class))).thenReturn(null); - Long result = clvmLockManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); + Long result = clvmPoolManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); Assert.assertNull(result); } @@ -401,7 +401,7 @@ public class ClvmLockManagerTest { when(agentMgr.send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class))) .thenThrow(new AgentUnavailableException("Host unavailable", HOST_ID_1)); - Long result = clvmLockManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); + Long result = clvmPoolManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); Assert.assertNull(result); } @@ -419,7 +419,7 @@ public class ClvmLockManagerTest { when(agentMgr.send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class))) .thenThrow(new OperationTimedoutException(null, HOST_ID_1, 0, 0, false)); - Long result = clvmLockManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); + Long result = clvmPoolManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); Assert.assertNull(result); } @@ -436,13 +436,13 @@ public class ClvmLockManagerTest { VolumeDetailVO detail = new VolumeDetailVO(); detail.setValue(String.valueOf(HOST_ID_1)); - when(volsDetailsDao.findDetail(VOLUME_ID, VolumeInfo.CLVM_LOCK_HOST_ID)).thenReturn(detail); + when(volsDetailsDao.findDetail(VOLUME_ID, ClvmPoolManager.CLVM_LOCK_HOST_ID)).thenReturn(detail); ClvmLockTransferAnswer answer = new ClvmLockTransferAnswer(null, true, null, "host1", true, false, null); when(agentMgr.send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class))).thenReturn(answer); when(hostDao.findByName("host1")).thenReturn(host); - Long result = clvmLockManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, true); + Long result = clvmPoolManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, true); Assert.assertEquals(HOST_ID_1, result); verify(volsDetailsDao, never()).update(anyLong(), any()); @@ -462,14 +462,14 @@ public class ClvmLockManagerTest { VolumeDetailVO detail = Mockito.mock(VolumeDetailVO.class); detail.setValue(String.valueOf(HOST_ID_1)); - when(volsDetailsDao.findDetail(VOLUME_ID, VolumeInfo.CLVM_LOCK_HOST_ID)).thenReturn(detail); + when(volsDetailsDao.findDetail(VOLUME_ID, ClvmPoolManager.CLVM_LOCK_HOST_ID)).thenReturn(detail); when(detail.getId()).thenReturn(99L); ClvmLockTransferAnswer answer = new ClvmLockTransferAnswer(null, true, null, "host2", true, false, null); when(agentMgr.send(eq(HOST_ID_2), any(ClvmLockTransferCommand.class))).thenReturn(answer); when(hostDao.findByName("host2")).thenReturn(host); - Long result = clvmLockManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, true); + Long result = clvmPoolManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, true); Assert.assertEquals(HOST_ID_2, result); verify(detail, times(1)).setValue(String.valueOf(HOST_ID_2)); @@ -486,16 +486,16 @@ public class ClvmLockManagerTest { HostVO host = createMockHost(HOST_ID_1, "host1", Status.Up, Hypervisor.HypervisorType.KVM); when(hostDao.findByClusterId(10L, Host.Type.Routing)).thenReturn(Collections.singletonList(host)); - when(volsDetailsDao.findDetail(VOLUME_ID, VolumeInfo.CLVM_LOCK_HOST_ID)).thenReturn(null); + when(volsDetailsDao.findDetail(VOLUME_ID, ClvmPoolManager.CLVM_LOCK_HOST_ID)).thenReturn(null); ClvmLockTransferAnswer answer = new ClvmLockTransferAnswer(null, true, null, "host1", true, false, null); when(agentMgr.send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class))).thenReturn(answer); when(hostDao.findByName("host1")).thenReturn(host); - Long result = clvmLockManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, true); + Long result = clvmPoolManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, true); Assert.assertEquals(HOST_ID_1, result); - verify(volsDetailsDao, times(1)).addDetail(eq(VOLUME_ID), eq(VolumeInfo.CLVM_LOCK_HOST_ID), + verify(volsDetailsDao, times(1)).addDetail(eq(VOLUME_ID), eq(ClvmPoolManager.CLVM_LOCK_HOST_ID), eq(String.valueOf(HOST_ID_1)), eq(false)); } @@ -511,12 +511,12 @@ public class ClvmLockManagerTest { VolumeDetailVO detail = Mockito.mock(VolumeDetailVO.class); when(detail.getId()).thenReturn(99L); - when(volsDetailsDao.findDetail(VOLUME_ID, VolumeInfo.CLVM_LOCK_HOST_ID)).thenReturn(detail); + when(volsDetailsDao.findDetail(VOLUME_ID, ClvmPoolManager.CLVM_LOCK_HOST_ID)).thenReturn(detail); ClvmLockTransferAnswer answer = new ClvmLockTransferAnswer(null, true, null, null, false, false, null); when(agentMgr.send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class))).thenReturn(answer); - Long result = clvmLockManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, true); + Long result = clvmPoolManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, true); Assert.assertNull(result); verify(volsDetailsDao, times(1)).remove(99L); @@ -537,7 +537,7 @@ public class ClvmLockManagerTest { when(agentMgr.send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class))).thenReturn(answer); when(hostDao.findByName("kvm-host")).thenReturn(kvmHost); - Long result = clvmLockManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); + Long result = clvmPoolManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); Assert.assertEquals(HOST_ID_1, result); verify(agentMgr, never()).send(eq(10L), any(ClvmLockTransferCommand.class)); @@ -559,7 +559,7 @@ public class ClvmLockManagerTest { when(agentMgr.send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class))).thenReturn(answer); when(hostDao.findByName("up-host")).thenReturn(upHost); - Long result = clvmLockManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); + Long result = clvmPoolManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); Assert.assertEquals(HOST_ID_1, result); verify(agentMgr, never()).send(eq(10L), any(ClvmLockTransferCommand.class)); @@ -580,7 +580,7 @@ public class ClvmLockManagerTest { when(agentMgr.send(eq(HOST_ID_1), any(ClvmLockTransferCommand.class))).thenReturn(answer); when(hostDao.findByName("host1")).thenReturn(host); - Long result = clvmLockManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); + Long result = clvmPoolManager.queryCurrentLockHolder(VOLUME_ID, VOLUME_UUID, VOLUME_PATH, pool, false); Assert.assertEquals(HOST_ID_1, result); } diff --git a/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java b/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java index 6ba9ac9f85f..b2a8050a2c9 100644 --- a/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java +++ b/server/src/test/java/com/cloud/storage/VolumeApiServiceImplTest.java @@ -46,6 +46,7 @@ import com.cloud.host.HostVO; import com.cloud.resourcelimit.CheckedReservation; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.clvm.ClvmPoolManager; import com.cloud.vm.snapshot.VMSnapshot; import com.cloud.vm.snapshot.VMSnapshotDetailsVO; import com.cloud.vm.snapshot.dao.VMSnapshotDetailsDao; @@ -227,7 +228,7 @@ public class VolumeApiServiceImplTest { @Mock VolumeOrchestrationService volumeOrchestrationService; @Mock - ClvmLockManager clvmLockManager; + ClvmPoolManager clvmPoolManager; private DetachVolumeCmd detachCmd = new DetachVolumeCmd();