Updated Branches: refs/heads/4.3 6df86db23 -> fca7dd29a
CloudStackCLOUDSTACK-5350 [Automation] Failed to attach volume to VM, if the vm is created with option startvm=false duplicate of https://issues.apache.org/jira/browse/CLOUDSTACK-4244 merge the fix to 4.3 Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c0724349 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c0724349 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c0724349 Branch: refs/heads/4.3 Commit: c0724349a6761f64bfd8d37c96d82f863bfc6adb Parents: 33ff20e Author: Frank.Zhang <frank.zh...@citrix.com> Authored: Mon Dec 9 14:47:02 2013 -0800 Committer: Frank.Zhang <frank.zh...@citrix.com> Committed: Mon Dec 9 14:47:02 2013 -0800 ---------------------------------------------------------------------- .../com/cloud/storage/VolumeApiServiceImpl.java | 75 +++++++++++++------- 1 file changed, 50 insertions(+), 25 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c0724349/server/src/com/cloud/storage/VolumeApiServiceImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index 6e01893..264f2bd 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -1134,36 +1134,61 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic deviceId = getDeviceId(vmId, deviceId); VolumeInfo volumeOnPrimaryStorage = volume; - if (volume.getState().equals(Volume.State.Allocated) || volume.getState() == Volume.State.Uploaded) { - try { - volumeOnPrimaryStorage = _volumeMgr.createVolumeOnPrimaryStorage(vm, rootVolumeOfVm, volume, rootDiskHyperType); - } catch (NoTransitionException e) { - s_logger.debug("Failed to create volume on primary storage", e); - throw new CloudRuntimeException("Failed to create volume on primary storage", e); - } + + // Check if volume is stored on secondary storage + boolean isVolumeOnSec = false; + VolumeInfo volOnSecondary = volFactory.getVolume(volume.getId(), DataStoreRole.Image); + if (volOnSecondary != null) { + isVolumeOnSec = true; } - // reload the volume from db - volumeOnPrimaryStorage = volFactory.getVolume(volumeOnPrimaryStorage.getId()); - boolean moveVolumeNeeded = needMoveVolume(rootVolumeOfVm, volumeOnPrimaryStorage); + boolean createVolumeOnBackend = true; + if (rootVolumeOfVm.getState() == Volume.State.Allocated) { + createVolumeOnBackend = false; + } - if (moveVolumeNeeded) { - PrimaryDataStoreInfo primaryStore = (PrimaryDataStoreInfo)volumeOnPrimaryStorage.getDataStore(); - if (primaryStore.isLocal()) { - throw new CloudRuntimeException("Failed to attach local data volume " + volume.getName() + " to VM " + vm.getDisplayName() + - " as migration of local data volume is not allowed"); + // Create volume on the backend only when VM's root volume is allocated + if (createVolumeOnBackend) { + if (volume.getState().equals(Volume.State.Allocated) + || volume.getState() == Volume.State.Uploaded) { + try { + volumeOnPrimaryStorage = _volumeMgr.createVolumeOnPrimaryStorage(vm, rootVolumeOfVm, volume, rootDiskHyperType); + } catch (NoTransitionException e) { + s_logger.debug("Failed to create volume on primary storage", e); + throw new CloudRuntimeException("Failed to create volume on primary storage", e); + } } - StoragePoolVO vmRootVolumePool = _storagePoolDao.findById(rootVolumeOfVm.getPoolId()); - try { - volumeOnPrimaryStorage = _volumeMgr.moveVolume(volumeOnPrimaryStorage, vmRootVolumePool.getDataCenterId(), vmRootVolumePool.getPodId(), - vmRootVolumePool.getClusterId(), dataDiskHyperType); - } catch (ConcurrentOperationException e) { - s_logger.debug("move volume failed", e); - throw new CloudRuntimeException("move volume failed", e); - } catch (StorageUnavailableException e) { - s_logger.debug("move volume failed", e); - throw new CloudRuntimeException("move volume failed", e); + // reload the volume from db + volumeOnPrimaryStorage = volFactory.getVolume(volumeOnPrimaryStorage.getId()); + boolean moveVolumeNeeded = needMoveVolume(rootVolumeOfVm, volumeOnPrimaryStorage); + + if (moveVolumeNeeded) { + PrimaryDataStoreInfo primaryStore = (PrimaryDataStoreInfo)volumeOnPrimaryStorage.getDataStore(); + if (primaryStore.isLocal()) { + throw new CloudRuntimeException( + "Failed to attach local data volume " + + volume.getName() + + " to VM " + + vm.getDisplayName() + + " as migration of local data volume is not allowed"); + } + StoragePoolVO vmRootVolumePool = _storagePoolDao + .findById(rootVolumeOfVm.getPoolId()); + + try { + volumeOnPrimaryStorage = _volumeMgr.moveVolume(volumeOnPrimaryStorage, + vmRootVolumePool.getDataCenterId(), + vmRootVolumePool.getPodId(), + vmRootVolumePool.getClusterId(), + dataDiskHyperType); + } catch (ConcurrentOperationException e) { + s_logger.debug("move volume failed", e); + throw new CloudRuntimeException("move volume failed", e); + } catch (StorageUnavailableException e) { + s_logger.debug("move volume failed", e); + throw new CloudRuntimeException("move volume failed", e); + } } }