From 020be66f9d8025198e9f6dc0d15d54349eeb61a5 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 8 Feb 2013 18:22:00 -0800 Subject: [PATCH] add copy volume and create volume from snapshot --- .../com/cloud/storage/VolumeApiService.java | 3 +- .../command/user/volume/MigrateVolumeCmd.java | 2 +- .../motion/AncientDataMotionStrategy.java | 58 ++++- .../storage/volume/VolumeServiceImpl.java | 97 +++++++- .../src/com/cloud/storage/VolumeManager.java | 8 +- .../com/cloud/storage/VolumeManagerImpl.java | 212 ++++-------------- .../storage/snapshot/SnapshotManager.java | 3 +- .../storage/snapshot/SnapshotManagerImpl.java | 2 +- .../cloud/vm/VirtualMachineManagerImpl.java | 2 +- 9 files changed, 205 insertions(+), 182 deletions(-) diff --git a/api/src/com/cloud/storage/VolumeApiService.java b/api/src/com/cloud/storage/VolumeApiService.java index 92880f4184d..8517988dfc6 100644 --- a/api/src/com/cloud/storage/VolumeApiService.java +++ b/api/src/com/cloud/storage/VolumeApiService.java @@ -21,6 +21,7 @@ package com.cloud.storage; import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd; import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd; +import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd; import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd; @@ -61,7 +62,7 @@ public interface VolumeApiService { */ Volume resizeVolume(ResizeVolumeCmd cmd); - Volume migrateVolume(Long volumeId, Long storagePoolId) throws ConcurrentOperationException; + Volume migrateVolume(MigrateVolumeCmd cmd) throws ConcurrentOperationException; /** * Uploads the volume to secondary storage diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java index 8c09f8fbb72..287241a8d90 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java @@ -92,7 +92,7 @@ public class MigrateVolumeCmd extends BaseAsyncCmd { public void execute(){ Volume result; try { - result = _volumeService.migrateVolume(getVolumeId(), getStoragePoolId()); + result = _volumeService.migrateVolume(this); if (result != null) { VolumeResponse response = _responseGenerator.createVolumeResponse(result); response.setResponseName(getCommandName()); diff --git a/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java index 70f65c7a5fa..ed3ca6aa8d9 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -329,6 +329,59 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { return errMsg; } + + protected String copyVolumeBetweenPools(DataObject srcData, DataObject destData) { + VolumeInfo volume = (VolumeInfo)srcData; + VolumeInfo destVolume = (VolumeInfo)destData; + String secondaryStorageURL = this.templateMgr.getSecondaryStorageURL(volume + .getDataCenterId()); + StoragePool srcPool = (StoragePool)this.dataStoreMgr.getDataStore(volume + .getPoolId(), DataStoreRole.Primary); + + StoragePool destPool = (StoragePool)this.dataStoreMgr.getDataStore(destVolume.getPoolId(), DataStoreRole.Primary); + + String value = this.configDao.getValue(Config.CopyVolumeWait.toString()); + int _copyvolumewait = NumbersUtil.parseInt(value, + Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); + CopyVolumeCommand cvCmd = new CopyVolumeCommand(volume.getId(), + volume.getPath(), srcPool, secondaryStorageURL, true, + _copyvolumewait); + CopyVolumeAnswer cvAnswer; + try { + cvAnswer = (CopyVolumeAnswer) this.storagMgr.sendToPool(srcPool, cvCmd); + } catch (StorageUnavailableException e1) { + throw new CloudRuntimeException( + "Failed to copy the volume from the source primary storage pool to secondary storage.", + e1); + } + + if (cvAnswer == null || !cvAnswer.getResult()) { + throw new CloudRuntimeException( + "Failed to copy the volume from the source primary storage pool to secondary storage."); + } + + String secondaryStorageVolumePath = cvAnswer.getVolumePath(); + + cvCmd = new CopyVolumeCommand(volume.getId(), + secondaryStorageVolumePath, destPool, + secondaryStorageURL, false, _copyvolumewait); + try { + cvAnswer = (CopyVolumeAnswer) this.storagMgr.sendToPool(destPool, cvCmd); + } catch (StorageUnavailableException e1) { + throw new CloudRuntimeException( + "Failed to copy the volume from secondary storage to the destination primary storage pool."); + } + + if (cvAnswer == null || !cvAnswer.getResult()) { + throw new CloudRuntimeException( + "Failed to copy the volume from secondary storage to the destination primary storage pool."); + } + + VolumeVO destVol = this.volDao.findById(destVolume.getId()); + destVol.setPath(cvAnswer.getVolumePath()); + this.volDao.update(destVol.getId(), destVol); + return null; + } @Override public Void copyAsync(DataObject srcData, DataObject destData, @@ -336,7 +389,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { String errMsg = null; try { if (destData.getType() == DataObjectType.VOLUME - && srcData.getType() == DataObjectType.VOLUME) { + && srcData.getType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.Image) { errMsg = copyVolumeFromImage(srcData, destData); } else if (destData.getType() == DataObjectType.TEMPLATE && srcData.getType() == DataObjectType.TEMPLATE) { @@ -353,6 +406,9 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } else if (srcData.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.VOLUME) { errMsg = cloneVolume(srcData, destData); + } else if (destData.getType() == DataObjectType.VOLUME + && srcData.getType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.Primary) { + errMsg = copyVolumeBetweenPools(srcData, destData); } } catch (Exception e) { s_logger.debug("copy failed", e); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 891ad1249df..ef99a49b809 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -45,12 +45,14 @@ import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.exception.ConcurrentOperationException; +import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; import com.cloud.storage.Volume.Type; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.utils.db.DB; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine; import com.cloud.vm.dao.VMInstanceDao; @@ -420,14 +422,105 @@ public class VolumeServiceImpl implements VolumeService { @Override public AsyncCallFuture createVolumeFromSnapshot( VolumeInfo volume, DataStore store, SnapshotInfo snapshot) { - // TODO Auto-generated method stub + AsyncCallFuture future = new AsyncCallFuture(); + VolumeApiResult result = new VolumeApiResult(volume); return null; } + + protected VolumeVO duplicateVolumeOnAnotherStorage(Volume volume, StoragePool pool) { + Long lastPoolId = volume.getPoolId(); + VolumeVO newVol = new VolumeVO(volume); + newVol.setPoolId(pool.getId()); + newVol.setFolder(pool.getPath()); + newVol.setPodId(pool.getPodId()); + newVol.setPoolId(pool.getId()); + newVol.setLastPoolId(lastPoolId); + newVol.setPodId(pool.getPodId()); + return this.volDao.persist(newVol); + } + + private class CopyVolumeContext extends AsyncRpcConext { + final VolumeInfo srcVolume; + final VolumeInfo destVolume; + final DataStore destStore; + final AsyncCallFuture future; + /** + * @param callback + */ + public CopyVolumeContext(AsyncCompletionCallback callback, AsyncCallFuture future, VolumeInfo srcVolume, VolumeInfo destVolume, + DataStore destStore) { + super(callback); + this.srcVolume = srcVolume; + this.destVolume = destVolume; + this.destStore = destStore; + this.future = future; + } + + } @Override public AsyncCallFuture copyVolume(VolumeInfo srcVolume, DataStore destStore) { - // TODO Auto-generated method stub + AsyncCallFuture future = new AsyncCallFuture(); + VolumeApiResult res = new VolumeApiResult(srcVolume); + try { + if (!this.snapshotMgr.canOperateOnVolume(srcVolume)) { + s_logger.debug( + "There are snapshots creating on this volume, can not move this volume"); + + res.setResult("There are snapshots creating on this volume, can not move this volume"); + future.complete(res); + return future; + } + + VolumeVO destVol = duplicateVolumeOnAnotherStorage(srcVolume, (StoragePool)destStore); + VolumeInfo destVolume = this.volFactory.getVolume(destVol.getId(), destStore); + destVolume.processEvent(Event.CreateOnlyRequested); + srcVolume.processEvent(Event.CopyingRequested); + + CopyVolumeContext context = new CopyVolumeContext(null, future, srcVolume, + destVolume, + destStore); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().copyVolumeCallBack(null, null)) + .setContext(context); + this.motionSrv.copyAsync(srcVolume, destVolume, caller); + } catch (Exception e) { + s_logger.debug("Failed to copy volume", e); + res.setResult(e.toString()); + future.complete(res); + } + return future; + } + + protected Void copyVolumeCallBack(AsyncCallbackDispatcher callback, CopyVolumeContext context) { + VolumeInfo srcVolume = context.srcVolume; + VolumeInfo destVolume = context.destVolume; + CopyCommandResult result = callback.getResult(); + AsyncCallFuture future = context.future; + VolumeApiResult res = new VolumeApiResult(destVolume); + try { + if (result.isFailed()) { + res.setResult(result.getResult()); + destVolume.processEvent(Event.OperationFailed); + srcVolume.processEvent(Event.OperationFailed); + AsyncCallFuture destroyFuture = this.expungeVolumeAsync(destVolume); + destroyFuture.get(); + future.complete(res); + return null; + } + srcVolume.processEvent(Event.OperationSuccessed); + destVolume.processEvent(Event.OperationSuccessed); + AsyncCallFuture destroyFuture = this.expungeVolumeAsync(srcVolume); + destroyFuture.get(); + future.complete(res); + return null; + } catch (Exception e) { + s_logger.debug("Failed to process copy volume callback",e); + res.setResult(e.toString()); + future.complete(res); + } + return null; } diff --git a/server/src/com/cloud/storage/VolumeManager.java b/server/src/com/cloud/storage/VolumeManager.java index 41434f41dcc..ebb9e54cd35 100644 --- a/server/src/com/cloud/storage/VolumeManager.java +++ b/server/src/com/cloud/storage/VolumeManager.java @@ -21,6 +21,7 @@ package com.cloud.storage; import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd; import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd; +import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd; import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; @@ -76,12 +77,11 @@ public interface VolumeManager extends VolumeApiService { void cleanupVolumes(long vmId) throws ConcurrentOperationException; - Volume migrateVolume(Long volumeId, Long storagePoolId) - throws ConcurrentOperationException; + Volume migrateVolume(MigrateVolumeCmd cmd); - boolean StorageMigration( + boolean storageMigration( VirtualMachineProfile vm, - StoragePool destPool) throws ConcurrentOperationException; + StoragePool destPool); void prepareForMigration( VirtualMachineProfile vm, diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 8c0e1428e41..573b8e90e12 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -39,6 +39,7 @@ import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd; import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd; +import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd; import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; @@ -351,11 +352,9 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { throw new CloudRuntimeException( "Failed to find a storage pool with enough capacity to move the volume to."); } - - List vols = new ArrayList(); - vols.add(volume); - migrateVolumes(vols, destPool); - return this.volFactory.getVolume(volume.getId()); + + Volume newVol = migrateVolume(volume, destPool); + return this.volFactory.getVolume(newVol.getId()); } /* @@ -1012,10 +1011,15 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_RESIZE, eventDescription = "resizing volume", async = true) public VolumeVO resizeVolume(ResizeVolumeCmd cmd) { - VolumeVO volume = _volsDao.findById(cmd.getEntityId()); Long newSize = null; boolean shrinkOk = cmd.getShrinkOk(); boolean success = false; + + VolumeVO volume = _volsDao.findById(cmd.getEntityId()); + if (volume == null) { + throw new InvalidParameterValueException("No such volume"); + } + DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume .getDiskOfferingId()); DiskOfferingVO newDiskOffering = null; @@ -1039,9 +1043,6 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { "Cloudstack currently only supports volumes marked as KVM or XenServer hypervisor for resize"); } - if (volume == null) { - throw new InvalidParameterValueException("No such volume"); - } if (volume.getState() != Volume.State.Ready) { throw new InvalidParameterValueException( @@ -1995,8 +1996,10 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { @DB @Override - public Volume migrateVolume(Long volumeId, Long storagePoolId) - throws ConcurrentOperationException { + public Volume migrateVolume(MigrateVolumeCmd cmd) { + Long volumeId = cmd.getVolumeId(); + Long storagePoolId = cmd.getStoragePoolId(); + VolumeVO vol = _volsDao.findById(volumeId); if (vol == null) { throw new InvalidParameterValueException( @@ -2025,171 +2028,36 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { "Migration of volume from local storage pool is not supported"); } - List vols = new ArrayList(); - vols.add(vol); - - migrateVolumes(vols, destPool); - return vol; + Volume newVol = migrateVolume(vol, destPool); + return newVol; } + + @DB - public boolean migrateVolumes(List volumes, StoragePool destPool) - throws ConcurrentOperationException { - Transaction txn = Transaction.currentTxn(); - txn.start(); - - boolean transitResult = false; - long checkPointTaskId = -1; + protected Volume migrateVolume(Volume volume, StoragePool destPool) { + VolumeInfo vol = this.volFactory.getVolume(volume.getId()); + AsyncCallFuture future = this.volService.copyVolume(vol, (DataStore)destPool); try { - List volIds = new ArrayList(); - for (Volume volume : volumes) { - if (!_snapshotMgr.canOperateOnVolume((VolumeVO) volume)) { - throw new CloudRuntimeException( - "There are snapshots creating on this volume, can not move this volume"); - } - - try { - if (!stateTransitTo(volume, Volume.Event.MigrationRequested)) { - throw new ConcurrentOperationException( - "Failed to transit volume state"); - } - } catch (NoTransitionException e) { - s_logger.debug("Failed to set state into migrate: " - + e.toString()); - throw new CloudRuntimeException( - "Failed to set state into migrate: " + e.toString()); - } - volIds.add(volume.getId()); - } - - transitResult = true; - } finally { - if (!transitResult) { - txn.rollback(); - } else { - txn.commit(); + VolumeApiResult result = future.get(); + if (result.isFailed()) { + s_logger.debug("migrate volume failed:" + result.getResult()); + return null; } + return result.getVolume(); + } catch (InterruptedException e) { + s_logger.debug("migrate volume failed", e); + return null; + } catch (ExecutionException e) { + s_logger.debug("migrate volume failed", e); + return null; } - - // At this stage, nobody can modify volumes. Send the copyvolume command - List> destroyCmds = new ArrayList>(); - List answers = new ArrayList(); - try { - for (Volume volume : volumes) { - String secondaryStorageURL = this._tmpltMgr.getSecondaryStorageURL(volume - .getDataCenterId()); - StoragePool srcPool = (StoragePool)this.dataStoreMgr.getDataStore(volume - .getPoolId(), DataStoreRole.Primary); - CopyVolumeCommand cvCmd = new CopyVolumeCommand(volume.getId(), - volume.getPath(), srcPool, secondaryStorageURL, true, - _copyvolumewait); - CopyVolumeAnswer cvAnswer; - try { - cvAnswer = (CopyVolumeAnswer) this.storageMgr.sendToPool(srcPool, cvCmd); - } catch (StorageUnavailableException e1) { - throw new CloudRuntimeException( - "Failed to copy the volume from the source primary storage pool to secondary storage.", - e1); - } - - if (cvAnswer == null || !cvAnswer.getResult()) { - throw new CloudRuntimeException( - "Failed to copy the volume from the source primary storage pool to secondary storage."); - } - - String secondaryStorageVolumePath = cvAnswer.getVolumePath(); - - // Copy the volume from secondary storage to the destination - // storage - // pool - cvCmd = new CopyVolumeCommand(volume.getId(), - secondaryStorageVolumePath, destPool, - secondaryStorageURL, false, _copyvolumewait); - try { - cvAnswer = (CopyVolumeAnswer) this.storageMgr.sendToPool(destPool, cvCmd); - } catch (StorageUnavailableException e1) { - throw new CloudRuntimeException( - "Failed to copy the volume from secondary storage to the destination primary storage pool."); - } - - if (cvAnswer == null || !cvAnswer.getResult()) { - throw new CloudRuntimeException( - "Failed to copy the volume from secondary storage to the destination primary storage pool."); - } - - answers.add(cvAnswer); - destroyCmds.add(new Pair( - srcPool, new DestroyCommand(srcPool, volume, null))); - } - } finally { - if (answers.size() != volumes.size()) { - // this means one of copying volume failed - for (Volume volume : volumes) { - try { - stateTransitTo(volume, Volume.Event.OperationFailed); - } catch (NoTransitionException e) { - s_logger.debug("Failed to change volume state: " - + e.toString()); - } - } - } else { - // Need a transaction, make sure all the volumes get migrated to - // new storage pool - txn = Transaction.currentTxn(); - txn.start(); - - transitResult = false; - try { - for (int i = 0; i < volumes.size(); i++) { - CopyVolumeAnswer answer = answers.get(i); - VolumeVO volume = (VolumeVO) volumes.get(i); - Long oldPoolId = volume.getPoolId(); - volume.setPath(answer.getVolumePath()); - volume.setFolder(destPool.getPath()); - volume.setPodId(destPool.getPodId()); - volume.setPoolId(destPool.getId()); - volume.setLastPoolId(oldPoolId); - volume.setPodId(destPool.getPodId()); - try { - stateTransitTo(volume, - Volume.Event.OperationSucceeded); - } catch (NoTransitionException e) { - s_logger.debug("Failed to change volume state: " - + e.toString()); - throw new CloudRuntimeException( - "Failed to change volume state: " - + e.toString()); - } - } - transitResult = true; - } finally { - if (!transitResult) { - txn.rollback(); - } else { - txn.commit(); - } - } - - } - } - - // all the volumes get migrated to new storage pool, need to delete the - // copy on old storage pool - for (Pair cmd : destroyCmds) { - try { - Answer cvAnswer = this.storageMgr.sendToPool(cmd.first(), cmd.second()); - } catch (StorageUnavailableException e) { - s_logger.debug("Unable to delete the old copy on storage pool: " - + e.toString()); - } - } - return true; } @Override - public boolean StorageMigration( + public boolean storageMigration( VirtualMachineProfile vm, - StoragePool destPool) throws ConcurrentOperationException { + StoragePool destPool) { List vols = _volsDao.findUsableVolumesForInstance(vm.getId()); List volumesNeedToMigrate = new ArrayList(); @@ -2215,7 +2083,13 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { return true; } - return migrateVolumes(volumesNeedToMigrate, destPool); + for (Volume vol : volumesNeedToMigrate) { + Volume result = migrateVolume(vol, destPool); + if (result == null) { + return false; + } + } + return true; } @Override @@ -2452,9 +2326,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { vol = task.volume; } else if (task.type == VolumeTaskType.MIGRATE) { pool = (StoragePool)dataStoreMgr.getDataStore(task.pool.getId(), DataStoreRole.Primary); - List volumes = new ArrayList(); - volumes.add(task.volume); - migrateVolumes(volumes, pool); + migrateVolume(task.volume, pool); vol = task.volume; } else if (task.type == VolumeTaskType.RECREATE) { Pair result = recreateVolume(task.volume, vm, dest); diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManager.java b/server/src/com/cloud/storage/snapshot/SnapshotManager.java index a7692de7107..72e8163c05a 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManager.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManager.java @@ -22,6 +22,7 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.host.HostVO; import com.cloud.storage.SnapshotPolicyVO; import com.cloud.storage.SnapshotVO; +import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; import com.cloud.utils.db.Filter; @@ -138,5 +139,5 @@ public interface SnapshotManager { void deleteSnapshotsDirForVolume(String secondaryStoragePoolUrl, Long dcId, Long accountId, Long volumeId); - boolean canOperateOnVolume(VolumeVO volume); + boolean canOperateOnVolume(Volume volume); } diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 6b48b8237ec..58ca9a41cfa 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -1578,7 +1578,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, } @Override - public boolean canOperateOnVolume(VolumeVO volume) { + public boolean canOperateOnVolume(Volume volume) { List snapshots = _snapshotDao.listByStatus(volume.getId(), Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp); if (snapshots.size() > 0) { diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 5d48f146769..4b7a4dbe111 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -1226,7 +1226,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); boolean migrationResult = false; try { - migrationResult = this.volumeMgr.StorageMigration(profile, destPool); + migrationResult = this.volumeMgr.storageMigration(profile, destPool); if (migrationResult) { //if the vm is migrated to different pod in basic mode, need to reallocate ip