This is an automated email from the ASF dual-hosted git repository.

shwstppr pushed a commit to branch 4.17
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.17 by this push:
     new a21efe75df vmware: fix vm snapshot with datastore cluster, drs (#6643)
a21efe75df is described below

commit a21efe75dfb41381acc3956235bd30d5c9050c7c
Author: Abhishek Kumar <[email protected]>
AuthorDate: Wed Aug 31 16:00:14 2022 +0530

    vmware: fix vm snapshot with datastore cluster, drs (#6643)
    
    Fixes #6595
    Sync volume datastore, path and chaininfo info while calculating snapshot 
chain size after snapshot operation is complete from vCenter.
---
 .../cloudstack/storage/to/PrimaryDataStoreTO.java  |   7 ++
 .../subsystem/api/storage/PrimaryDataStore.java    |   4 +
 .../vmsnapshot/DefaultVMSnapshotStrategy.java      |  32 ++++--
 .../vmsnapshot/DefaultVMSnapshotStrategyTest.java  | 106 ++++++++++++++++++
 .../storage/vmsnapshot/VMSnapshotStrategyTest.java |   8 ++
 .../storage/datastore/PrimaryDataStoreImpl.java    |  12 ++
 .../vmware/manager/VmwareHostService.java          |   3 +
 .../vmware/manager/VmwareStorageManagerImpl.java   | 111 +++++++++++--------
 .../hypervisor/vmware/resource/VmwareResource.java |   5 +
 .../VmwareSecondaryStorageResourceHandler.java     |  15 ++-
 .../storage/resource/VmwareStorageProcessor.java   | 122 ++++++++++-----------
 11 files changed, 302 insertions(+), 123 deletions(-)

diff --git 
a/core/src/main/java/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java 
b/core/src/main/java/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java
index 9df2a6c955..a6a74176c1 100644
--- 
a/core/src/main/java/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java
+++ 
b/core/src/main/java/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java
@@ -55,6 +55,8 @@ public class PrimaryDataStoreTO implements DataStoreTO {
     private Boolean diskProvisioningStrictnessFlag;
     private final boolean isManaged;
 
+    private final StoragePoolType parentPoolType;
+
     public PrimaryDataStoreTO(PrimaryDataStore dataStore) {
         this.uuid = dataStore.getUuid();
         this.name = dataStore.getName();
@@ -66,6 +68,7 @@ public class PrimaryDataStoreTO implements DataStoreTO {
         this.url = dataStore.getUri();
         this.details = dataStore.getDetails();
         this.isManaged = dataStore.isManaged();
+        this.parentPoolType = dataStore.getParentPoolType();
     }
 
     public long getId() {
@@ -172,4 +175,8 @@ public class PrimaryDataStoreTO implements DataStoreTO {
     public void setDiskProvisioningStrictnessFlag(Boolean 
diskProvisioningStrictnessFlag) {
         this.diskProvisioningStrictnessFlag = diskProvisioningStrictnessFlag;
     }
+
+    public StoragePoolType getParentPoolType() {
+        return parentPoolType;
+    }
 }
diff --git 
a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStore.java
 
b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStore.java
index 5546571ba6..718f63e77f 100644
--- 
a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStore.java
+++ 
b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStore.java
@@ -22,6 +22,8 @@ import java.util.List;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat;
 
+import com.cloud.storage.Storage;
+
 public interface PrimaryDataStore extends DataStore, PrimaryDataStoreInfo {
     DataObject create(DataObject dataObject, String configuration);
 
@@ -38,4 +40,6 @@ public interface PrimaryDataStore extends DataStore, 
PrimaryDataStoreInfo {
     SnapshotInfo getSnapshot(long snapshotId);
 
     DiskFormat getDefaultDiskType();
+
+    Storage.StoragePoolType getParentPoolType();
 }
diff --git 
a/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java
 
b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java
index 90f6ccd1f9..e2815c005c 100644
--- 
a/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java
+++ 
b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java
@@ -25,14 +25,14 @@ import java.util.Map;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import com.cloud.event.UsageEventVO;
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
 import org.apache.cloudstack.engine.subsystem.api.storage.VMSnapshotOptions;
 import org.apache.cloudstack.engine.subsystem.api.storage.VMSnapshotStrategy;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
@@ -45,6 +45,7 @@ import com.cloud.agent.api.RevertToVMSnapshotCommand;
 import com.cloud.agent.api.VMSnapshotTO;
 import com.cloud.event.EventTypes;
 import com.cloud.event.UsageEventUtils;
+import com.cloud.event.UsageEventVO;
 import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.OperationTimedoutException;
 import com.cloud.host.HostVO;
@@ -53,6 +54,7 @@ import com.cloud.storage.DiskOfferingVO;
 import com.cloud.storage.GuestOSHypervisorVO;
 import com.cloud.storage.GuestOSVO;
 import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.StoragePool;
 import com.cloud.storage.VolumeVO;
 import com.cloud.storage.dao.DiskOfferingDao;
 import com.cloud.storage.dao.GuestOSDao;
@@ -97,6 +99,8 @@ public class DefaultVMSnapshotStrategy extends ManagerBase 
implements VMSnapshot
     DiskOfferingDao diskOfferingDao;
     @Inject
     HostDao hostDao;
+    @Inject
+    PrimaryDataStoreDao primaryDataStoreDao;
 
     @Override
     public boolean configure(String name, Map<String, Object> params) throws 
ConfigurationException {
@@ -323,14 +327,26 @@ public class DefaultVMSnapshotStrategy extends 
ManagerBase implements VMSnapshot
         vmSnapshotDao.persist(vmSnapshot);
     }
 
-    private void updateVolumePath(List<VolumeObjectTO> volumeTOs) {
+    protected void updateVolumePath(List<VolumeObjectTO> volumeTOs) {
         for (VolumeObjectTO volume : volumeTOs) {
-            if (volume.getPath() != null) {
-                VolumeVO volumeVO = volumeDao.findById(volume.getId());
+            if (StringUtils.isAllEmpty(volume.getDataStoreUuid(), 
volume.getPath(), volume.getChainInfo())) {
+                continue;
+            }
+            VolumeVO volumeVO = volumeDao.findById(volume.getId());
+            if (StringUtils.isNotEmpty(volume.getDataStoreUuid())) {
+                StoragePool pool = 
primaryDataStoreDao.findPoolByUUID(volume.getDataStoreUuid());
+                if (pool != null && pool.getId() != volumeVO.getPoolId()) {
+                    volumeVO.setPoolId(pool.getId());
+                }
+            }
+            if (StringUtils.isNotEmpty(volume.getPath())) {
                 volumeVO.setPath(volume.getPath());
-                volumeVO.setVmSnapshotChainSize(volume.getSize());
-                volumeDao.persist(volumeVO);
             }
+            if (StringUtils.isNotEmpty(volume.getChainInfo())) {
+                volumeVO.setChainInfo(volume.getChainInfo());
+            }
+            volumeVO.setVmSnapshotChainSize(volume.getSize());
+            volumeDao.persist(volumeVO);
         }
     }
 
diff --git 
a/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategyTest.java
 
b/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategyTest.java
new file mode 100644
index 0000000000..da377f96ec
--- /dev/null
+++ 
b/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategyTest.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.vmsnapshot;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.mockito.stubbing.Answer;
+
+import com.cloud.storage.Storage;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VolumeDao;
+
+@RunWith(MockitoJUnitRunner.class)
+public class DefaultVMSnapshotStrategyTest {
+    @Mock
+    VolumeDao volumeDao;
+    @Mock
+    PrimaryDataStoreDao primaryDataStoreDao;
+
+    @Spy
+    @InjectMocks
+    private final DefaultVMSnapshotStrategy defaultVMSnapshotStrategy = new 
DefaultVMSnapshotStrategy();
+
+    protected List<VolumeVO> persistedVolumes = new ArrayList<>();
+
+
+    private void setupVolumeDaoPersistMock() {
+        persistedVolumes.clear();
+        
Mockito.when(volumeDao.persist(Mockito.any())).thenAnswer((Answer<VolumeVO>) 
invocation -> {
+            VolumeVO volume = (VolumeVO)invocation.getArguments()[0];
+            persistedVolumes.add(volume);
+            return volume;
+        });
+    }
+
+    @Test
+    public void testUpdateVolumePath() {
+        setupVolumeDaoPersistMock();
+        VolumeObjectTO vol1 = Mockito.mock(VolumeObjectTO.class);
+        Mockito.when(vol1.getDataStoreUuid()).thenReturn(null);
+        Mockito.when(vol1.getPath()).thenReturn(null);
+        Mockito.when(vol1.getChainInfo()).thenReturn(null);
+        VolumeObjectTO vol2 = Mockito.mock(VolumeObjectTO.class);
+        Long volumeId = 1L;
+        String newDSUuid = UUID.randomUUID().toString();
+        String oldVolPath = "old";
+        String newVolPath = "new";
+        String oldVolChain = "old-chain";
+        String newVolChain = "new-chain";
+        Long vmSnapshotChainSize = 1000L;
+        Long oldPoolId = 1L;
+        Long newPoolId = 2L;
+        Mockito.when(vol2.getDataStoreUuid()).thenReturn(newDSUuid);
+        Mockito.when(vol2.getPath()).thenReturn(newVolPath);
+        Mockito.when(vol2.getChainInfo()).thenReturn(newVolChain);
+        Mockito.when(vol2.getSize()).thenReturn(vmSnapshotChainSize);
+        Mockito.when(vol2.getId()).thenReturn(volumeId);
+        VolumeVO volumeVO = new VolumeVO("name", 0l, 0l, 0l, 0l, 0l, "folder", 
"path", Storage.ProvisioningType.THIN, 0l, Volume.Type.ROOT);
+        volumeVO.setPoolId(oldPoolId);
+        volumeVO.setChainInfo(oldVolChain);
+        volumeVO.setPath(oldVolPath);
+        Mockito.when(volumeDao.findById(volumeId)).thenReturn(volumeVO);
+        StoragePoolVO storagePoolVO = Mockito.mock(StoragePoolVO.class);
+        Mockito.when(storagePoolVO.getId()).thenReturn(newPoolId);
+        
Mockito.when(primaryDataStoreDao.findPoolByUUID(newDSUuid)).thenReturn(storagePoolVO);
+        Mockito.when(volumeDao.findById(volumeId)).thenReturn(volumeVO);
+        defaultVMSnapshotStrategy.updateVolumePath(List.of(vol1, vol2));
+        Assert.assertEquals(1, persistedVolumes.size());
+        VolumeVO persistedVolume = persistedVolumes.get(0);
+        Assert.assertNotNull(persistedVolume);
+        Assert.assertEquals(newPoolId, persistedVolume.getPoolId());
+        Assert.assertEquals(newVolPath, persistedVolume.getPath());
+        Assert.assertEquals(vmSnapshotChainSize, 
persistedVolume.getVmSnapshotChainSize());
+        Assert.assertEquals(newVolChain, persistedVolume.getChainInfo());
+    }
+}
diff --git 
a/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotStrategyTest.java
 
b/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotStrategyTest.java
index 4420c19d6a..5fd6dee908 100644
--- 
a/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotStrategyTest.java
+++ 
b/engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotStrategyTest.java
@@ -27,6 +27,7 @@ import javax.inject.Inject;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.VMSnapshotStrategy;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.to.VolumeObjectTO;
 import org.apache.cloudstack.test.utils.SpringUtils;
 import org.junit.Before;
@@ -92,6 +93,8 @@ public class VMSnapshotStrategyTest extends TestCase {
     VMSnapshotDao vmSnapshotDao;
     @Inject
     HostDao hostDao;
+    @Inject
+    PrimaryDataStoreDao primaryDataStoreDao;
 
     @Override
     @Before
@@ -304,5 +307,10 @@ public class VMSnapshotStrategyTest extends TestCase {
         public HostDao hostDao() {
             return Mockito.mock(HostDao.class);
         }
+
+        @Bean
+        public PrimaryDataStoreDao primaryDataStoreDao() {
+            return Mockito.mock(PrimaryDataStoreDao.class);
+        }
     }
 }
diff --git 
a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java
 
b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java
index f557ac3517..eba597c3c5 100644
--- 
a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java
+++ 
b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java
@@ -72,6 +72,7 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore 
{
 
     protected PrimaryDataStoreDriver driver;
     protected StoragePoolVO pdsv;
+    protected StoragePoolVO parentStoragePool;
     @Inject
     protected PrimaryDataStoreDao dataStoreDao;
     protected PrimaryDataStoreLifeCycle lifeCycle;
@@ -99,6 +100,9 @@ public class PrimaryDataStoreImpl implements 
PrimaryDataStore {
         this.pdsv = pdsv;
         this.driver = driver;
         this.provider = provider;
+        if (pdsv.getParent() != null && pdsv.getParent() > 0L) {
+            this.parentStoragePool = dataStoreDao.findById(pdsv.getParent());
+        }
     }
 
     public static PrimaryDataStoreImpl createDataStore(StoragePoolVO pdsv, 
PrimaryDataStoreDriver driver, DataStoreProvider provider) {
@@ -447,4 +451,12 @@ public class PrimaryDataStoreImpl implements 
PrimaryDataStore {
         }
         return to;
     }
+
+    @Override
+    public StoragePoolType getParentPoolType() {
+        if (this.parentStoragePool != null) {
+            return this.parentStoragePool.getPoolType();
+        }
+        return null;
+    }
 }
diff --git 
a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
 
b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
index d9ee3c5f5c..4f68096303 100644
--- 
a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
+++ 
b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
@@ -20,6 +20,7 @@ import com.cloud.agent.api.Command;
 import com.cloud.hypervisor.vmware.mo.DatastoreMO;
 import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
 import com.cloud.hypervisor.vmware.util.VmwareContext;
+import com.cloud.storage.resource.VmwareStorageProcessor;
 
 public interface VmwareHostService {
     VmwareContext getServiceContext(Command cmd);
@@ -31,4 +32,6 @@ public interface VmwareHostService {
     String getWorkerName(VmwareContext context, Command cmd, int 
workerSequence, DatastoreMO dsMo) throws Exception;
 
     String createLogMessageException(Throwable e, Command command);
+
+    VmwareStorageProcessor getStorageProcessor();
 }
diff --git 
a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
 
b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
index 3ed9ffffb0..1f57e00979 100644
--- 
a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
+++ 
b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
@@ -28,20 +28,10 @@ import java.util.Map;
 import java.util.Properties;
 import java.util.UUID;
 
-import org.apache.log4j.Logger;
-
-import com.cloud.hypervisor.vmware.mo.DatastoreFile;
-import com.vmware.vim25.FileInfo;
-import com.vmware.vim25.FileQueryFlags;
-import com.vmware.vim25.HostDatastoreBrowserSearchResults;
-import com.vmware.vim25.HostDatastoreBrowserSearchSpec;
-import com.vmware.vim25.ManagedObjectReference;
-import com.vmware.vim25.TaskInfo;
-import com.vmware.vim25.TaskInfoState;
-import com.vmware.vim25.VirtualDisk;
-
+import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
 import org.apache.cloudstack.storage.to.TemplateObjectTO;
 import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.BackupSnapshotAnswer;
@@ -65,10 +55,12 @@ import 
com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
 import com.cloud.agent.api.to.DataObjectType;
 import com.cloud.agent.api.to.DataStoreTO;
 import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
 import com.cloud.agent.api.to.NfsTO;
 import com.cloud.agent.api.to.StorageFilerTO;
 import com.cloud.hypervisor.vmware.mo.CustomFieldConstants;
 import com.cloud.hypervisor.vmware.mo.DatacenterMO;
+import com.cloud.hypervisor.vmware.mo.DatastoreFile;
 import com.cloud.hypervisor.vmware.mo.DatastoreMO;
 import com.cloud.hypervisor.vmware.mo.HostDatastoreBrowserMO;
 import com.cloud.hypervisor.vmware.mo.HostMO;
@@ -78,9 +70,11 @@ import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
 import com.cloud.hypervisor.vmware.util.VmwareContext;
 import com.cloud.hypervisor.vmware.util.VmwareHelper;
 import com.cloud.storage.JavaStorageLayer;
+import com.cloud.storage.Storage;
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.StorageLayer;
 import com.cloud.storage.Volume;
+import com.cloud.storage.resource.VmwareStorageProcessor;
 import com.cloud.storage.template.OVAProcessor;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
@@ -89,6 +83,14 @@ import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.script.Script;
 import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.snapshot.VMSnapshot;
+import com.vmware.vim25.FileInfo;
+import com.vmware.vim25.FileQueryFlags;
+import com.vmware.vim25.HostDatastoreBrowserSearchResults;
+import com.vmware.vim25.HostDatastoreBrowserSearchSpec;
+import com.vmware.vim25.ManagedObjectReference;
+import com.vmware.vim25.TaskInfo;
+import com.vmware.vim25.TaskInfoState;
+import com.vmware.vim25.VirtualDisk;
 
 public class VmwareStorageManagerImpl implements VmwareStorageManager {
 
@@ -1134,6 +1136,28 @@ public class VmwareStorageManagerImpl implements 
VmwareStorageManager {
         return size;
     }
 
+    private boolean isVolumeOnDatastoreCluster(VolumeObjectTO volumeObjectTO) {
+        DataStoreTO dsTO = volumeObjectTO.getDataStore();
+        if (!(dsTO instanceof PrimaryDataStoreTO)) {
+            return false;
+        }
+        PrimaryDataStoreTO primaryDataStoreTO = (PrimaryDataStoreTO)dsTO;
+        return 
Storage.StoragePoolType.DatastoreCluster.equals(primaryDataStoreTO.getPoolType())
 ||
+                
Storage.StoragePoolType.DatastoreCluster.equals(primaryDataStoreTO.getParentPoolType());
+    }
+
+    private void syncVolume(VmwareHostService hostService, VirtualMachineMO 
virtualMachineMO, VmwareContext context,
+                             VmwareHypervisorHost hypervisorHost, 
VolumeObjectTO volumeTO) throws Exception {
+        if (hostService.getStorageProcessor() == null) return;
+        VmwareStorageProcessor storageProcessor = 
hostService.getStorageProcessor();
+        DiskTO disk = new DiskTO();
+        Map<String, String> map = new HashMap<>();
+        map.put(DiskTO.PROTOCOL_TYPE, 
Storage.StoragePoolType.DatastoreCluster.toString());
+        disk.setDetails(map);
+        disk.setData(volumeTO);
+        storageProcessor.getSyncedVolume(virtualMachineMO, context, 
hypervisorHost, disk, volumeTO);
+    }
+
     @Override
     public CreateVMSnapshotAnswer execute(VmwareHostService hostService, 
CreateVMSnapshotCommand cmd) {
         List<VolumeObjectTO> volumeTOs = cmd.getVolumeTOs();
@@ -1181,15 +1205,13 @@ public class VmwareStorageManagerImpl implements 
VmwareStorageManager {
                     return new CreateVMSnapshotAnswer(cmd, false, "Unable to 
create snapshot due to esxi internal failed");
                 }
 
-                Map<String, String> mapNewDisk = getNewDiskMap(vmMo);
-
-                setVolumeToPathAndSize(volumeTOs, mapNewDisk, context, 
hyperHost, cmd.getVmName());
+                setVolumeToPathAndSize(volumeTOs, vmMo, hostService, context, 
hyperHost);
 
                 return new CreateVMSnapshotAnswer(cmd, cmd.getTarget(), 
volumeTOs);
             }
         } catch (Exception e) {
             String msg = e.getMessage();
-            s_logger.error("failed to create snapshot for vm:" + vmName + " 
due to " + msg);
+            s_logger.error("failed to create snapshot for vm:" + vmName + " 
due to " + msg, e);
 
             try {
                 if (vmMo.getSnapshotMor(vmSnapshotName) != null) {
@@ -1248,29 +1270,37 @@ public class VmwareStorageManagerImpl implements 
VmwareStorageManager {
         return mapNewDisk;
     }
 
-    private void setVolumeToPathAndSize(List<VolumeObjectTO> volumeTOs, 
Map<String, String> mapNewDisk, VmwareContext context, VmwareHypervisorHost 
hyperHost, String vmName)
+    private void setVolumeToPathAndSize(List<VolumeObjectTO> volumeTOs, 
VirtualMachineMO vmMo, VmwareHostService hostService, VmwareContext context, 
VmwareHypervisorHost hyperHost)
             throws Exception {
+        String vmName = vmMo.getVmName();
         for (VolumeObjectTO volumeTO : volumeTOs) {
-            String oldPath = volumeTO.getPath();
-
-            final String baseName;
-
-            // if this is managed storage
-            if (oldPath.startsWith("[-iqn.")) { // ex. 
[-iqn.2010-01.com.company:3y8w.vol-10.64-0] 
-iqn.2010-01.com.company:3y8w.vol-10.64-0-000001.vmdk
-                oldPath = oldPath.split(" ")[0]; // ex. 
[-iqn.2010-01.com.company:3y8w.vol-10.64-0]
+            String path = volumeTO.getPath();
+            String baseName;
+            String datastoreUuid = volumeTO.getDataStore().getUuid();
 
-                // remove '[' and ']'
-                baseName = oldPath.substring(1, oldPath.length() - 1);
-            } else {
+            if (isVolumeOnDatastoreCluster(volumeTO)) {
+                syncVolume(hostService, vmMo, context, hyperHost, volumeTO);
+                path = volumeTO.getPath();
                 baseName = 
VmwareHelper.trimSnapshotDeltaPostfix(volumeTO.getPath());
-            }
+                datastoreUuid = volumeTO.getDataStoreUuid();
+            } else {
+                Map<String, String> mapNewDisk = getNewDiskMap(vmMo);
+                // if this is managed storage
+                if (path.startsWith("[-iqn.")) { // ex. 
[-iqn.2010-01.com.company:3y8w.vol-10.64-0] 
-iqn.2010-01.com.company:3y8w.vol-10.64-0-000001.vmdk
+                    path = path.split(" ")[0]; // ex. 
[-iqn.2010-01.com.company:3y8w.vol-10.64-0]
 
-            String newPath = mapNewDisk.get(baseName);
+                    // remove '[' and ']'
+                    baseName = path.substring(1, path.length() - 1);
+                } else {
+                    baseName = VmwareHelper.trimSnapshotDeltaPostfix(path);
+                }
+                path = mapNewDisk.get(baseName);
+                volumeTO.setPath(path);
+            }
 
             // get volume's chain size for this VM snapshot; exclude current 
volume vdisk
-            DataStoreTO store = volumeTO.getDataStore();
-            ManagedObjectReference morDs = 
getDatastoreAsManagedObjectReference(baseName, hyperHost, store);
-            long size = getVMSnapshotChainSize(context, hyperHost, baseName + 
"-*.vmdk", morDs, newPath, vmName);
+            ManagedObjectReference morDs = 
getDatastoreAsManagedObjectReference(baseName, hyperHost, datastoreUuid);
+            long size = getVMSnapshotChainSize(context, hyperHost, baseName + 
"-*.vmdk", morDs, path, vmName);
 
             if (volumeTO.getVolumeType() == Volume.Type.ROOT) {
                 // add memory snapshot size
@@ -1278,11 +1308,10 @@ public class VmwareStorageManagerImpl implements 
VmwareStorageManager {
             }
 
             volumeTO.setSize(size);
-            volumeTO.setPath(newPath);
         }
     }
 
-    private ManagedObjectReference getDatastoreAsManagedObjectReference(String 
baseName, VmwareHypervisorHost hyperHost, DataStoreTO store) throws Exception {
+    private ManagedObjectReference getDatastoreAsManagedObjectReference(String 
baseName, VmwareHypervisorHost hyperHost, String storeUuid) throws Exception {
         try {
             // if baseName equates to a datastore name, this should be managed 
storage
             ManagedObjectReference morDs = 
hyperHost.findDatastoreByName(baseName);
@@ -1295,7 +1324,7 @@ public class VmwareStorageManagerImpl implements 
VmwareStorageManager {
         }
 
         // not managed storage, so use the standard way of getting a 
ManagedObjectReference for a datastore
-        return 
HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, 
store.getUuid());
+        return 
HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, 
storeUuid);
     }
 
     @Override
@@ -1335,15 +1364,13 @@ public class VmwareStorageManagerImpl implements 
VmwareStorageManager {
 
                 // after removed snapshot, the volumes' paths have been 
changed for the VM, needs to report new paths to manager
 
-                Map<String, String> mapNewDisk = getNewDiskMap(vmMo);
-
-                setVolumeToPathAndSize(listVolumeTo, mapNewDisk, context, 
hyperHost, cmd.getVmName());
+                setVolumeToPathAndSize(listVolumeTo, vmMo, hostService, 
context, hyperHost);
 
                 return new DeleteVMSnapshotAnswer(cmd, listVolumeTo);
             }
         } catch (Exception e) {
             String msg = e.getMessage();
-            s_logger.error("failed to delete vm snapshot " + vmSnapshotName + 
" of vm " + vmName + " due to " + msg);
+            s_logger.error("failed to delete vm snapshot " + vmSnapshotName + 
" of vm " + vmName + " due to " + msg, e);
 
             return new DeleteVMSnapshotAnswer(cmd, false, msg);
         }
@@ -1403,9 +1430,7 @@ public class VmwareStorageManagerImpl implements 
VmwareStorageManager {
                 }
 
                 if (result) {
-                    Map<String, String> mapNewDisk = getNewDiskMap(vmMo);
-
-                    setVolumeToPathAndSize(listVolumeTo, mapNewDisk, context, 
hyperHost, cmd.getVmName());
+                    setVolumeToPathAndSize(listVolumeTo, vmMo, hostService, 
context, hyperHost);
 
                     if (!snapshotMemory) {
                         vmState = VirtualMachine.PowerState.PowerOff;
@@ -1418,7 +1443,7 @@ public class VmwareStorageManagerImpl implements 
VmwareStorageManager {
             }
         } catch (Exception e) {
             String msg = "revert vm " + vmName + " to snapshot " + 
snapshotName + " failed due to " + e.getMessage();
-            s_logger.error(msg);
+            s_logger.error(msg, e);
 
             return new RevertToVMSnapshotAnswer(cmd, false, msg);
         }
diff --git 
a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
 
b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index e831f6228e..04e9dd4cc9 100644
--- 
a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ 
b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -7671,4 +7671,9 @@ public class VmwareResource extends ServerResourceBase 
implements StoragePoolRes
             s_logger.error(String.format("Failed to log command %s due to: 
[%s].", cmd.getClass().getSimpleName(), e.getMessage()), e);
         }
     }
+
+    @Override
+    public VmwareStorageProcessor getStorageProcessor() {
+        return _storageProcessor;
+    }
 }
diff --git 
a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
 
b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
index 44bcbf31e1..68947ef690 100644
--- 
a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
+++ 
b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
@@ -18,14 +18,10 @@ package com.cloud.storage.resource;
 
 import java.util.List;
 
-import org.apache.log4j.Logger;
-import org.apache.log4j.NDC;
-
-import com.google.gson.Gson;
-import com.vmware.vim25.ManagedObjectReference;
-
 import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
 import org.apache.cloudstack.storage.resource.SecondaryStorageResourceHandler;
+import org.apache.log4j.Logger;
+import org.apache.log4j.NDC;
 
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.BackupSnapshotCommand;
@@ -52,6 +48,8 @@ import com.cloud.serializer.GsonHelper;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
 import com.cloud.utils.StringUtils;
+import com.google.gson.Gson;
+import com.vmware.vim25.ManagedObjectReference;
 
 public class VmwareSecondaryStorageResourceHandler implements 
SecondaryStorageResourceHandler, VmwareHostService, VmwareStorageMount {
     private static final Logger s_logger = 
Logger.getLogger(VmwareSecondaryStorageResourceHandler.class);
@@ -326,4 +324,9 @@ public class VmwareSecondaryStorageResourceHandler 
implements SecondaryStorageRe
 
         return message;
     }
+
+    @Override
+    public VmwareStorageProcessor getStorageProcessor() {
+        return null;
+    }
 }
diff --git 
a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java
 
b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java
index bdb8eca20e..fd541cca80 100644
--- 
a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java
+++ 
b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java
@@ -2081,33 +2081,17 @@ public class VmwareStorageProcessor implements 
StorageProcessor {
                     datastoreVolumePath = dsMo.getDatastorePath((vmdkPath != 
null ? vmdkPath : dsMo.getName()) + ".vmdk");
                 } else {
                     String datastoreUUID = primaryStore.getUuid();
-                    if (disk.getDetails().get(DiskTO.PROTOCOL_TYPE) != null && 
disk.getDetails().get(DiskTO.PROTOCOL_TYPE).equalsIgnoreCase("DatastoreCluster"))
 {
-                        VirtualMachineDiskInfo matchingExistingDisk = 
getMatchingExistingDisk(hyperHost, context, vmMo, disk);
-                        VirtualMachineDiskInfoBuilder diskInfoBuilder = 
vmMo.getDiskInfoBuilder();
-                        if (diskInfoBuilder != null && matchingExistingDisk != 
null) {
-                            String[] diskChain = 
matchingExistingDisk.getDiskChain();
-                            assert (diskChain.length > 0);
-                            DatastoreFile file = new 
DatastoreFile(diskChain[0]);
-                            if 
(!file.getFileBaseName().equalsIgnoreCase(volumePath)) {
-                                if (s_logger.isInfoEnabled())
-                                    s_logger.info("Detected disk-chain top 
file change on volume: " + volumeTO.getId() + " " + volumePath + " -> " + 
file.getFileBaseName());
-                                volumePathChangeObserved = true;
-                                volumePath = file.getFileBaseName();
-                                volumeTO.setPath(volumePath);
-                                chainInfo = _gson.toJson(matchingExistingDisk);
-                            }
-
-                            DatastoreMO diskDatastoreMofromVM = 
getDiskDatastoreMofromVM(hyperHost, context, vmMo, disk, diskInfoBuilder);
-                            if (diskDatastoreMofromVM != null) {
-                                String actualPoolUuid = 
diskDatastoreMofromVM.getCustomFieldValue(CustomFieldConstants.CLOUD_UUID);
-                                if 
(!actualPoolUuid.equalsIgnoreCase(primaryStore.getUuid())) {
-                                    s_logger.warn(String.format("Volume %s 
found to be in a different storage pool %s", volumePath, actualPoolUuid));
-                                    datastoreChangeObserved = true;
-                                    datastoreUUID = actualPoolUuid;
-                                    chainInfo = 
_gson.toJson(matchingExistingDisk);
-                                }
-                            }
-                        }
+                    Pair<Boolean, Boolean> changes = getSyncedVolume(vmMo, 
context, hyperHost, disk, volumeTO);
+                    volumePathChangeObserved = changes.first();
+                    datastoreChangeObserved = changes.second();
+                    if (datastoreChangeObserved) {
+                        datastoreUUID = volumeTO.getDataStoreUuid();
+                    }
+                    if (volumePathChangeObserved) {
+                        volumePath = volumeTO.getPath();
+                    }
+                    if ((volumePathChangeObserved || datastoreChangeObserved) 
&& StringUtils.isNotEmpty(volumeTO.getChainInfo())) {
+                        chainInfo = volumeTO.getChainInfo();
                     }
                     if (storagePort == DEFAULT_NFS_PORT) {
                         morDs = 
HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, 
isManaged ? VmwareResource.getDatastoreName(diskUuid) : datastoreUUID);
@@ -3862,17 +3846,50 @@ public class VmwareStorageProcessor implements 
StorageProcessor {
         }
     }
 
+    public Pair<Boolean, Boolean> getSyncedVolume(VirtualMachineMO vmMo, 
VmwareContext context,VmwareHypervisorHost hyperHost, DiskTO disk, 
VolumeObjectTO volumeTO) throws Exception {
+        DataStoreTO primaryStore = volumeTO.getDataStore();
+        boolean datastoreChangeObserved = false;
+        boolean volumePathChangeObserved = false;
+        if 
(!"DatastoreCluster".equalsIgnoreCase(disk.getDetails().get(DiskTO.PROTOCOL_TYPE)))
 {
+            return new Pair<>(volumePathChangeObserved, 
datastoreChangeObserved);
+        }
+        VirtualMachineDiskInfo matchingExistingDisk = 
getMatchingExistingDisk(hyperHost, context, vmMo, disk);
+        VirtualMachineDiskInfoBuilder diskInfoBuilder = 
vmMo.getDiskInfoBuilder();
+        if (diskInfoBuilder != null && matchingExistingDisk != null) {
+            String[] diskChain = matchingExistingDisk.getDiskChain();
+            assert (diskChain.length > 0);
+            DatastoreFile file = new DatastoreFile(diskChain[0]);
+            String volumePath = volumeTO.getPath();
+            if (!file.getFileBaseName().equalsIgnoreCase(volumePath)) {
+                if (s_logger.isInfoEnabled()) {
+                    s_logger.info("Detected disk-chain top file change on 
volume: " + volumeTO.getId() + " " + volumePath + " -> " + 
file.getFileBaseName());
+                }
+                volumePathChangeObserved = true;
+                volumePath = file.getFileBaseName();
+                volumeTO.setPath(volumePath);
+                volumeTO.setChainInfo(_gson.toJson(matchingExistingDisk));
+            }
+
+            DatastoreMO diskDatastoreMoFromVM = 
getDiskDatastoreMofromVM(hyperHost, context, vmMo, disk, diskInfoBuilder);
+            if (diskDatastoreMoFromVM != null) {
+                String actualPoolUuid = 
diskDatastoreMoFromVM.getCustomFieldValue(CustomFieldConstants.CLOUD_UUID);
+                if (!actualPoolUuid.equalsIgnoreCase(primaryStore.getUuid())) {
+                    s_logger.warn(String.format("Volume %s found to be in a 
different storage pool %s", volumePath, actualPoolUuid));
+                    datastoreChangeObserved = true;
+                    volumeTO.setDataStoreUuid(actualPoolUuid);
+                    volumeTO.setChainInfo(_gson.toJson(matchingExistingDisk));
+                }
+            }
+        }
+        return new Pair<>(volumePathChangeObserved, datastoreChangeObserved);
+    }
+
     @Override
     public Answer syncVolumePath(SyncVolumePathCommand cmd) {
         DiskTO disk = cmd.getDisk();
         VolumeObjectTO volumeTO = (VolumeObjectTO)disk.getData();
-        DataStoreTO primaryStore = volumeTO.getDataStore();
-        String volumePath = volumeTO.getPath();
         String vmName = volumeTO.getVmName();
 
-        boolean datastoreChangeObserved = false;
-        boolean volumePathChangeObserved = false;
-        String chainInfo = null;
         try {
             VmwareContext context = hostService.getServiceContext(null);
             VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, 
null);
@@ -3885,46 +3902,19 @@ public class VmwareStorageProcessor implements 
StorageProcessor {
                     throw new Exception(msg);
                 }
             }
-
-            String datastoreUUID = primaryStore.getUuid();
-            if (disk.getDetails().get(DiskTO.PROTOCOL_TYPE) != null && 
disk.getDetails().get(DiskTO.PROTOCOL_TYPE).equalsIgnoreCase("DatastoreCluster"))
 {
-                VirtualMachineDiskInfo matchingExistingDisk = 
getMatchingExistingDisk(hyperHost, context, vmMo, disk);
-                VirtualMachineDiskInfoBuilder diskInfoBuilder = 
vmMo.getDiskInfoBuilder();
-                if (diskInfoBuilder != null && matchingExistingDisk != null) {
-                    String[] diskChain = matchingExistingDisk.getDiskChain();
-                    assert (diskChain.length > 0);
-                    DatastoreFile file = new DatastoreFile(diskChain[0]);
-                    if (!file.getFileBaseName().equalsIgnoreCase(volumePath)) {
-                        if (s_logger.isInfoEnabled())
-                            s_logger.info("Detected disk-chain top file change 
on volume: " + volumeTO.getId() + " " + volumePath + " -> " + 
file.getFileBaseName());
-                        volumePathChangeObserved = true;
-                        volumePath = file.getFileBaseName();
-                        volumeTO.setPath(volumePath);
-                        chainInfo = _gson.toJson(matchingExistingDisk);
-                    }
-
-                    DatastoreMO diskDatastoreMofromVM = 
getDiskDatastoreMofromVM(hyperHost, context, vmMo, disk, diskInfoBuilder);
-                    if (diskDatastoreMofromVM != null) {
-                        String actualPoolUuid = 
diskDatastoreMofromVM.getCustomFieldValue(CustomFieldConstants.CLOUD_UUID);
-                        if 
(!actualPoolUuid.equalsIgnoreCase(primaryStore.getUuid())) {
-                            s_logger.warn(String.format("Volume %s found to be 
in a different storage pool %s", volumePath, actualPoolUuid));
-                            datastoreChangeObserved = true;
-                            datastoreUUID = actualPoolUuid;
-                            chainInfo = _gson.toJson(matchingExistingDisk);
-                        }
-                    }
-                }
-            }
+            Pair<Boolean, Boolean> changes = getSyncedVolume(vmMo, context, 
hyperHost, disk, volumeTO);
+            boolean volumePathChangeObserved = changes.first();
+            boolean datastoreChangeObserved = changes.second();
 
             SyncVolumePathAnswer answer = new SyncVolumePathAnswer(disk);
             if (datastoreChangeObserved) {
-                answer.setContextParam("datastoreName", datastoreUUID);
+                answer.setContextParam("datastoreName", 
volumeTO.getDataStoreUuid());
             }
             if (volumePathChangeObserved) {
-                answer.setContextParam("volumePath", volumePath);
+                answer.setContextParam("volumePath", volumeTO.getPath());
             }
-            if (chainInfo != null && !chainInfo.isEmpty()) {
-                answer.setContextParam("chainInfo", chainInfo);
+            if ((volumePathChangeObserved || datastoreChangeObserved) && 
StringUtils.isNotEmpty(volumeTO.getChainInfo())) {
+                answer.setContextParam("chainInfo", volumeTO.getChainInfo());
             }
 
             return answer;

Reply via email to