You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by de...@apache.org on 2014/05/08 08:49:42 UTC
git commit: updated refs/heads/master to 245b7f4
Repository: cloudstack
Updated Branches:
refs/heads/master b8adb96ae -> 245b7f4c3
CLOUDSTACK-6510: Fix gson serialization exception in storage migration. Gson couldn't serialize
a map with volume and storagepool objects for logging. Fixed by using volume and storage pool
ids instead of objects in the map.
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/245b7f4c
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/245b7f4c
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/245b7f4c
Branch: refs/heads/master
Commit: 245b7f4c39ab8bdb656b733afc4cfc55782d36eb
Parents: b8adb96
Author: Devdeep Singh <de...@gmail.com>
Authored: Mon May 5 16:59:39 2014 +0530
Committer: Devdeep Singh <de...@gmail.com>
Committed: Thu May 8 12:23:46 2014 +0530
----------------------------------------------------------------------
.../src/com/cloud/vm/VirtualMachineManager.java | 3 +-
.../com/cloud/vm/VirtualMachineManagerImpl.java | 61 ++++++++++++--------
.../com/cloud/vm/VmWorkMigrateWithStorage.java | 9 +--
.../cloud/vm/VirtualMachineManagerImplTest.java | 10 ++--
server/src/com/cloud/vm/UserVmManagerImpl.java | 4 +-
5 files changed, 48 insertions(+), 39 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/245b7f4c/engine/api/src/com/cloud/vm/VirtualMachineManager.java
----------------------------------------------------------------------
diff --git a/engine/api/src/com/cloud/vm/VirtualMachineManager.java b/engine/api/src/com/cloud/vm/VirtualMachineManager.java
index f070210..b1e5258 100644
--- a/engine/api/src/com/cloud/vm/VirtualMachineManager.java
+++ b/engine/api/src/com/cloud/vm/VirtualMachineManager.java
@@ -39,7 +39,6 @@ import com.cloud.network.Network;
import com.cloud.offering.DiskOfferingInfo;
import com.cloud.offering.ServiceOffering;
import com.cloud.storage.StoragePool;
-import com.cloud.storage.Volume;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.utils.component.Manager;
import com.cloud.utils.fsm.NoTransitionException;
@@ -113,7 +112,7 @@ public interface VirtualMachineManager extends Manager {
void migrate(String vmUuid, long srcHostId, DeployDestination dest) throws ResourceUnavailableException, ConcurrentOperationException;
- void migrateWithStorage(String vmUuid, long srcId, long destId, Map<Volume, StoragePool> volumeToPool) throws ResourceUnavailableException, ConcurrentOperationException;
+ void migrateWithStorage(String vmUuid, long srcId, long destId, Map<Long, Long> volumeToPool) throws ResourceUnavailableException, ConcurrentOperationException;
void reboot(String vmUuid, Map<VirtualMachineProfile.Param, Object> params) throws InsufficientCapacityException, ResourceUnavailableException;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/245b7f4c/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
index e15d287..8ca7d1e 100755
--- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -26,6 +26,7 @@ import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -1963,24 +1964,26 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
}
- private Map<Volume, StoragePool> getPoolListForVolumesForMigration(VirtualMachineProfile profile, Host host, Map<Volume, StoragePool> volumeToPool) {
+ private Map<Volume, StoragePool> getPoolListForVolumesForMigration(VirtualMachineProfile profile, Host host, Map<Long, Long> volumeToPool) {
List<VolumeVO> allVolumes = _volsDao.findUsableVolumesForInstance(profile.getId());
+ Map<Volume, StoragePool> volumeToPoolObjectMap = new HashMap<Volume, StoragePool> ();
for (VolumeVO volume : allVolumes) {
- StoragePool pool = volumeToPool.get(volume);
- DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
+ Long poolId = volumeToPool.get(Long.valueOf(volume.getId()));
+ StoragePoolVO pool = _storagePoolDao.findById(poolId);
StoragePoolVO currentPool = _storagePoolDao.findById(volume.getPoolId());
+ DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
if (pool != null) {
// Check if pool is accessible from the destination host and disk offering with which the volume was
// created is compliant with the pool type.
if (_poolHostDao.findByPoolHost(pool.getId(), host.getId()) == null || pool.isLocal() != diskOffering.getUseLocalStorage()) {
// Cannot find a pool for the volume. Throw an exception.
throw new CloudRuntimeException("Cannot migrate volume " + volume + " to storage pool " + pool + " while migrating vm to host " + host +
- ". Either the pool is not accessible from the " + "host or because of the offering with which the volume is created it cannot be placed on " +
+ ". Either the pool is not accessible from the host or because of the offering with which the volume is created it cannot be placed on " +
"the given pool.");
} else if (pool.getId() == currentPool.getId()) {
- // If the pool to migrate too is the same as current pool, remove the volume from the list of
- // volumes to be migrated.
- volumeToPool.remove(volume);
+ // If the pool to migrate too is the same as current pool, the volume doesn't need to be migrated.
+ } else {
+ volumeToPoolObjectMap.put(volume, pool);
}
} else {
// Find a suitable pool for the volume. Call the storage pool allocator to find the list of pools.
@@ -1989,23 +1992,33 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
ExcludeList avoid = new ExcludeList();
boolean currentPoolAvailable = false;
+ List<StoragePool> poolList = new ArrayList<StoragePool>();
for (StoragePoolAllocator allocator : _storagePoolAllocators) {
- List<StoragePool> poolList = allocator.allocateToPool(diskProfile, profile, plan, avoid, StoragePoolAllocator.RETURN_UPTO_ALL);
- if (poolList != null && !poolList.isEmpty()) {
- // Volume needs to be migrated. Pick the first pool from the list. Add a mapping to migrate the
- // volume to a pool only if it is required; that is the current pool on which the volume resides
- // is not available on the destination host.
- if (poolList.contains(currentPool)) {
+ List<StoragePool> poolListFromAllocator = allocator.allocateToPool(diskProfile, profile, plan, avoid, StoragePoolAllocator.RETURN_UPTO_ALL);
+ if (poolListFromAllocator != null && !poolListFromAllocator.isEmpty()) {
+ poolList.addAll(poolListFromAllocator);
+ }
+ }
+
+ if (poolList != null && !poolList.isEmpty()) {
+ // Volume needs to be migrated. Pick the first pool from the list. Add a mapping to migrate the
+ // volume to a pool only if it is required; that is the current pool on which the volume resides
+ // is not available on the destination host.
+ Iterator<StoragePool> iter = poolList.iterator();
+ while (iter.hasNext()) {
+ if (currentPool.getId() == iter.next().getId()) {
currentPoolAvailable = true;
- } else {
- volumeToPool.put(volume, _storagePoolDao.findByUuid(poolList.get(0).getUuid()));
+ break;
}
+ }
- break;
+ if (!currentPoolAvailable) {
+ volumeToPoolObjectMap.put(volume, _storagePoolDao.findByUuid(poolList.get(0).getUuid()));
}
}
- if (!currentPoolAvailable && !volumeToPool.containsKey(volume)) {
+
+ if (!currentPoolAvailable && !volumeToPoolObjectMap.containsKey(volume)) {
// Cannot find a pool for the volume. Throw an exception.
throw new CloudRuntimeException("Cannot find a storage pool which is available for volume " + volume + " while migrating virtual machine " +
profile.getVirtualMachine() + " to host " + host);
@@ -2013,7 +2026,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
}
- return volumeToPool;
+ return volumeToPoolObjectMap;
}
private <T extends VMInstanceVO> void moveVmToMigratingState(T vm, Long hostId, ItWorkVO work) throws ConcurrentOperationException {
@@ -2043,7 +2056,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
@Override
- public void migrateWithStorage(String vmUuid, long srcHostId, long destHostId, Map<Volume, StoragePool> volumeToPool)
+ public void migrateWithStorage(String vmUuid, long srcHostId, long destHostId, Map<Long, Long> volumeToPool)
throws ResourceUnavailableException, ConcurrentOperationException {
AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
@@ -2087,7 +2100,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
}
- private void orchestrateMigrateWithStorage(String vmUuid, long srcHostId, long destHostId, Map<Volume, StoragePool> volumeToPool) throws ResourceUnavailableException,
+ private void orchestrateMigrateWithStorage(String vmUuid, long srcHostId, long destHostId, Map<Long, Long> volumeToPool) throws ResourceUnavailableException,
ConcurrentOperationException {
VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
@@ -2103,11 +2116,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
// Create a map of which volume should go in which storage pool.
VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
- volumeToPool = getPoolListForVolumesForMigration(profile, destHost, volumeToPool);
+ Map<Volume, StoragePool> volumeToPoolMap = getPoolListForVolumesForMigration(profile, destHost, volumeToPool);
// If none of the volumes have to be migrated, fail the call. Administrator needs to make a call for migrating
// a vm and not migrating a vm with storage.
- if (volumeToPool.isEmpty()) {
+ if (volumeToPoolMap == null || volumeToPoolMap.isEmpty()) {
throw new InvalidParameterValueException("Migration of the vm " + vm + "from host " + srcHost + " to destination host " + destHost +
" doesn't involve migrating the volumes.");
}
@@ -2137,7 +2150,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
boolean migrated = false;
try {
// Migrate the vm and its volume.
- volumeMgr.migrateVolumes(vm, to, srcHost, destHost, volumeToPool);
+ volumeMgr.migrateVolumes(vm, to, srcHost, destHost, volumeToPoolMap);
// Put the vm back to running state.
moveVmOutofMigratingStateOnSuccess(vm, destHost.getId(), work);
@@ -4717,7 +4730,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
public Outcome<VirtualMachine> migrateVmWithStorageThroughJobQueue(
final String vmUuid, final long srcHostId, final long destHostId,
- final Map<Volume, StoragePool> volumeToPool) {
+ final Map<Long, Long> volumeToPool) {
final CallContext context = CallContext.current();
final User user = context.getCallingUser();
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/245b7f4c/engine/orchestration/src/com/cloud/vm/VmWorkMigrateWithStorage.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkMigrateWithStorage.java b/engine/orchestration/src/com/cloud/vm/VmWorkMigrateWithStorage.java
index ee30c74..52fe9f2 100644
--- a/engine/orchestration/src/com/cloud/vm/VmWorkMigrateWithStorage.java
+++ b/engine/orchestration/src/com/cloud/vm/VmWorkMigrateWithStorage.java
@@ -18,18 +18,15 @@ package com.cloud.vm;
import java.util.Map;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.Volume;
-
public class VmWorkMigrateWithStorage extends VmWork {
private static final long serialVersionUID = -5626053872453569165L;
long srcHostId;
long destHostId;
- Map<Volume, StoragePool> volumeToPool;
+ Map<Long, Long> volumeToPool;
public VmWorkMigrateWithStorage(long userId, long accountId, long vmId, String handlerName, long srcHostId,
- long destHostId, Map<Volume, StoragePool> volumeToPool) {
+ long destHostId, Map<Long, Long> volumeToPool) {
super(userId, accountId, vmId, handlerName);
@@ -46,7 +43,7 @@ public class VmWorkMigrateWithStorage extends VmWork {
return destHostId;
}
- public Map<Volume, StoragePool> getVolumeToPool() {
+ public Map<Long, Long> getVolumeToPool() {
return volumeToPool;
}
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/245b7f4c/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java b/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java
index f6422f4..ae07455 100644
--- a/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java
+++ b/engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java
@@ -89,9 +89,7 @@ import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.Storage.ProvisioningType;
import com.cloud.storage.DiskOfferingVO;
-import com.cloud.storage.StoragePool;
import com.cloud.storage.StoragePoolHostVO;
-import com.cloud.storage.Volume;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.user.Account;
@@ -197,7 +195,7 @@ public class VirtualMachineManagerImplTest {
@Mock
HostVO _destHostMock;
@Mock
- Map<Volume, StoragePool> _volumeToPoolMock;
+ Map<Long, Long> _volumeToPoolMock;
@Mock
EntityManager _entityMgr;
@Mock
@@ -356,11 +354,13 @@ public class VirtualMachineManagerImplTest {
// Mock the disk offering and pool objects for a volume.
when(_volumeMock.getDiskOfferingId()).thenReturn(5L);
when(_volumeMock.getPoolId()).thenReturn(200L);
+ when(_volumeMock.getId()).thenReturn(5L);
when(_diskOfferingDao.findById(anyLong())).thenReturn(_diskOfferingMock);
- when(_storagePoolDao.findById(anyLong())).thenReturn(_srcStoragePoolMock);
+ when(_storagePoolDao.findById(200L)).thenReturn(_srcStoragePoolMock);
+ when(_storagePoolDao.findById(201L)).thenReturn(_destStoragePoolMock);
// Mock the volume to pool mapping.
- when(_volumeToPoolMock.get(_volumeMock)).thenReturn(_destStoragePoolMock);
+ when(_volumeToPoolMock.get(5L)).thenReturn(201L);
when(_destStoragePoolMock.getId()).thenReturn(201L);
when(_srcStoragePoolMock.getId()).thenReturn(200L);
when(_destStoragePoolMock.isLocal()).thenReturn(false);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/245b7f4c/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 5da1875..d323e98 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -4092,7 +4092,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
List<VolumeVO> vmVolumes = _volsDao.findUsableVolumesForInstance(vm.getId());
- Map<Volume, StoragePool> volToPoolObjectMap = new HashMap<Volume, StoragePool>();
+ Map<Long, Long> volToPoolObjectMap = new HashMap<Long, Long>();
if (!isVMUsingLocalStorage(vm) && destinationHost.getClusterId().equals(srcHost.getClusterId())) {
if (volumeToPool.isEmpty()) {
// If the destination host is in the same cluster and volumes do not have to be migrated across pools
@@ -4116,7 +4116,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
if (!vmVolumes.contains(volume)) {
throw new InvalidParameterValueException("There volume " + volume + " doesn't belong to " + "the virtual machine " + vm + " that has to be migrated");
}
- volToPoolObjectMap.put(volume, pool);
+ volToPoolObjectMap.put(Long.valueOf(volume.getId()), Long.valueOf(pool.getId()));
}
}
}