From b4ee4acaf3ec807d45ca306bcb370b2be926e10b Mon Sep 17 00:00:00 2001 From: slavkap <51903378+slavkap@users.noreply.github.com> Date: Thu, 22 Apr 2021 12:00:18 +0300 Subject: [PATCH] server: Fix volume state on migrate with migrateVirtualMachineWithVolume API call (#4934) When invoking migrateVirtualMachineWithVolume API call and a strategy isn't found the volumes are left in Migrating state This PR puts back the volumes to Ready state. --- .../storage/motion/DataMotionServiceImpl.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java index ac6c8555da9..4d1de8d7867 100644 --- a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java +++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java @@ -33,6 +33,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.StorageStrategyFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -42,7 +43,6 @@ import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.StringUtils; -import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -57,7 +57,9 @@ public class DataMotionServiceImpl implements DataMotionService { @Override public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback callback) { if (srcData.getDataStore() == null || destData.getDataStore() == null) { - throw new CloudRuntimeException("can't find data store"); + String errMsg = "can't find data store"; + invokeCallback(errMsg, callback); + return; } if (srcData.getDataStore().getDriver().canCopy(srcData, destData)) { @@ -73,8 +75,10 @@ public class DataMotionServiceImpl implements DataMotionService { // OfflineVmware volume migration // Cleanup volumes from target and reset the state of volume at source cleanUpVolumesForFailedMigrations(srcData, destData); - throw new CloudRuntimeException("Can't find strategy to move data. " + "Source: " + srcData.getType().name() + " '" + srcData.getUuid() + ", Destination: " + - destData.getType().name() + " '" + destData.getUuid() + "'"); + String errMsg = "Can't find strategy to move data. " + "Source: " + srcData.getType().name() + " '" + srcData.getUuid() + ", Destination: " + + destData.getType().name() + " '" + destData.getUuid() + "'"; + invokeCallback(errMsg, callback); + return; } strategy.copyAsync(srcData, destData, destHost, callback); @@ -112,10 +116,22 @@ public class DataMotionServiceImpl implements DataMotionService { volumeIds.add(volumeInfo.getUuid()); } - throw new CloudRuntimeException("Can't find strategy to move data. " + "Source Host: " + srcHost.getName() + ", Destination Host: " + destHost.getName() + - ", Volume UUIDs: " + StringUtils.join(volumeIds, ",")); + String errMsg = "Can't find strategy to move data. " + "Source Host: " + srcHost.getName() + ", Destination Host: " + destHost.getName() + + ", Volume UUIDs: " + StringUtils.join(volumeIds, ","); + invokeCallback(errMsg, callback); + return; } strategy.copyAsync(volumeMap, vmTo, srcHost, destHost, callback); } + + private void invokeCallback(String errMsg, AsyncCompletionCallback callback) { + CopyCmdAnswer copyCmdAnswer = new CopyCmdAnswer(errMsg); + + CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer); + + result.setResult(errMsg); + + callback.complete(result); + } }