diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index b506858b2377..7f867eb01a97 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -3201,6 +3201,7 @@ public Volume migrateVolume(MigrateVolumeCmd cmd) { VMInstanceVO vm = null; if (instanceId != null) { vm = _vmInstanceDao.findById(instanceId); + checkVmStateForMigration(vm, vol); } // Check that Vm to which this volume is attached does not have VM Snapshots @@ -3398,6 +3399,22 @@ public Volume migrateVolume(MigrateVolumeCmd cmd) { return orchestrateMigrateVolume(vol, destPool, liveMigrateVolume, newDiskOffering); } + private void checkVmStateForMigration(VMInstanceVO vm, VolumeVO vol) { + List suitableVmStatesForMigration = List.of(State.Stopped, State.Running, State.Shutdown); + + if (!suitableVmStatesForMigration.contains(vm.getState())) { + s_logger.debug(String.format( + "Unable to migrate volume: [%s] Id: [%s] because the VM: [%s] Id: [%s] is in state [%s], which is not supported for migration.", + vol.getName(), vol.getId(), vm.getInstanceName(), vm.getUuid(), vm.getState() + )); + + throw new CloudRuntimeException(String.format( + "Volume migration is not allowed when the VM is in the %s state. Supported states are: %s.", + vm.getState(), suitableVmStatesForMigration + )); + } + } + private boolean isSourceOrDestNotOnStorPool(StoragePoolVO storagePoolVO, StoragePoolVO destinationStoragePoolVo) { return storagePoolVO.getPoolType() != Storage.StoragePoolType.StorPool || destinationStoragePoolVo.getPoolType() != Storage.StoragePoolType.StorPool;