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);
+                }
             }
         }
 

Reply via email to