From 267e1f38aac25854834d16b0ead228ba4c1c2f07 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Thu, 30 Jul 2026 15:05:49 +0200 Subject: [PATCH] xenserver/xcpng: do not bypass secondary storage when copy volumes between pools --- .../storage/motion/AncientDataMotionStrategy.java | 8 ++++++++ .../motion/AncientDataMotionStrategyTest.java | 15 +++++++++++++++ 2 files changed, 23 insertions(+) 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 8145158dfa40..c1bcc8ddb9af 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 @@ -472,7 +472,15 @@ private boolean canBypassSecondaryStorage(DataObject srcData, DataObject destDat return true; } + if (Hypervisor.HypervisorType.XenServer.equals(((VolumeInfo) srcData).getHypervisorType())) { + return false; + } + if (destData instanceof VolumeInfo) { + if (Hypervisor.HypervisorType.XenServer.equals(((VolumeInfo) destData).getHypervisorType())) { + return false; + } + Scope srcDataStoreScope = srcData.getDataStore().getScope(); Scope destDataStoreScope = destData.getDataStore().getScope(); logger.info("srcDataStoreScope: {}, srcData pool type: {}; destDataStoreScope: {}, destData pool type: {}", 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 e167cc0a9653..d7ec53702c8c 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 @@ -123,6 +123,7 @@ public void testCanBypassSecondaryStorageForDirectDownload() throws NoSuchMethod @Test public void testCanBypassSecondaryStorageForUnsupportedDataObject() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(srcVolumeInfo).getHypervisorType(); TemplateObject destTemplateInfo = Mockito.spy(new TemplateObject()); @@ -136,12 +137,14 @@ public void testCanBypassSecondaryStorageForUnsupportedDataObject() throws NoSuc @Test public void testCanBypassSecondaryStorageForUnsupportedSrcPoolType() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(srcVolumeInfo).getHypervisorType(); DataStore srcDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ZoneScope(1L)).when(srcDataStore).getScope(); Mockito.doReturn(srcDataStore).when(srcVolumeInfo).getDataStore(); Mockito.doReturn(Storage.StoragePoolType.PowerFlex).when(srcVolumeInfo).getStoragePoolType(); VolumeObject destVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(destVolumeInfo).getHypervisorType(); DataStore destDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ZoneScope(1L)).when(destDataStore).getScope(); Mockito.doReturn(destDataStore).when(destVolumeInfo).getDataStore(); @@ -157,12 +160,14 @@ public void testCanBypassSecondaryStorageForUnsupportedSrcPoolType() throws NoSu @Test public void testCanBypassSecondaryStorageForUnsupportedDestPoolType() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(srcVolumeInfo).getHypervisorType(); DataStore srcDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ZoneScope(1L)).when(srcDataStore).getScope(); Mockito.doReturn(srcDataStore).when(srcVolumeInfo).getDataStore(); Mockito.doReturn(Storage.StoragePoolType.NetworkFilesystem).when(srcVolumeInfo).getStoragePoolType(); VolumeObject destVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(destVolumeInfo).getHypervisorType(); DataStore destDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ZoneScope(1L)).when(destDataStore).getScope(); Mockito.doReturn(destDataStore).when(destVolumeInfo).getDataStore(); @@ -178,12 +183,14 @@ public void testCanBypassSecondaryStorageForUnsupportedDestPoolType() throws NoS @Test public void testCanBypassSecondaryStorageWithZoneWideNFSPoolsInSameZone() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(srcVolumeInfo).getHypervisorType(); DataStore srcDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ZoneScope(1L)).when(srcDataStore).getScope(); Mockito.doReturn(srcDataStore).when(srcVolumeInfo).getDataStore(); Mockito.doReturn(Storage.StoragePoolType.NetworkFilesystem).when(srcVolumeInfo).getStoragePoolType(); VolumeObject destVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(destVolumeInfo).getHypervisorType(); DataStore destDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ZoneScope(1L)).when(destDataStore).getScope(); Mockito.doReturn(destDataStore).when(destVolumeInfo).getDataStore(); @@ -199,12 +206,14 @@ public void testCanBypassSecondaryStorageWithZoneWideNFSPoolsInSameZone() throws @Test public void testCanBypassSecondaryStorageWithClusterWideNFSPoolsInSameCluster() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(srcVolumeInfo).getHypervisorType(); DataStore srcDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ClusterScope(5L, 2L, 1L)).when(srcDataStore).getScope(); Mockito.doReturn(srcDataStore).when(srcVolumeInfo).getDataStore(); Mockito.doReturn(Storage.StoragePoolType.NetworkFilesystem).when(srcVolumeInfo).getStoragePoolType(); VolumeObject destVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(destVolumeInfo).getHypervisorType(); DataStore destDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ClusterScope(5L, 2L, 1L)).when(destDataStore).getScope(); Mockito.doReturn(destDataStore).when(destVolumeInfo).getDataStore(); @@ -220,12 +229,14 @@ public void testCanBypassSecondaryStorageWithClusterWideNFSPoolsInSameCluster() @Test public void testCanBypassSecondaryStorageWithLocalAndClusterWideNFSPoolsInSameCluster() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(srcVolumeInfo).getHypervisorType(); DataStore srcDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new HostScope(1L, 1L, 1L)).when(srcDataStore).getScope(); Mockito.doReturn(srcDataStore).when(srcVolumeInfo).getDataStore(); Mockito.doReturn(Storage.StoragePoolType.Filesystem).when(srcVolumeInfo).getStoragePoolType(); VolumeObject destVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(destVolumeInfo).getHypervisorType(); DataStore destDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ClusterScope(1L, 1L, 1L)).when(destDataStore).getScope(); Mockito.doReturn(destDataStore).when(destVolumeInfo).getDataStore(); @@ -244,12 +255,14 @@ public void testCanBypassSecondaryStorageWithLocalAndClusterWideNFSPoolsInSameCl @Test public void testCanBypassSecondaryStorageWithLocalAndZoneWideNFSPoolsInSameZone() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(srcVolumeInfo).getHypervisorType(); DataStore srcDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new HostScope(1L, 1L, 1L)).when(srcDataStore).getScope(); Mockito.doReturn(srcDataStore).when(srcVolumeInfo).getDataStore(); Mockito.doReturn(Storage.StoragePoolType.Filesystem).when(srcVolumeInfo).getStoragePoolType(); VolumeObject destVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(destVolumeInfo).getHypervisorType(); DataStore destDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ZoneScope(1L)).when(destDataStore).getScope(); Mockito.doReturn(destDataStore).when(destVolumeInfo).getDataStore(); @@ -268,12 +281,14 @@ public void testCanBypassSecondaryStorageWithLocalAndZoneWideNFSPoolsInSameZone( @Test public void testCanBypassSecondaryStorageWithClusterWideNFSAndZoneWideNFSPoolsInSameZone() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(srcVolumeInfo).getHypervisorType(); DataStore srcDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ClusterScope(5L, 2L, 1L)).when(srcDataStore).getScope(); Mockito.doReturn(srcDataStore).when(srcVolumeInfo).getDataStore(); Mockito.doReturn(Storage.StoragePoolType.NetworkFilesystem).when(srcVolumeInfo).getStoragePoolType(); VolumeObject destVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(destVolumeInfo).getHypervisorType(); DataStore destDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ZoneScope(1L)).when(destDataStore).getScope(); Mockito.doReturn(destDataStore).when(destVolumeInfo).getDataStore();