Skip to content

Commit 2bcf8ad

Browse files
Dingane Hlalukunvazquez
authored andcommitted
* Fix worker VM placement algorithm (#9)
* Add VM disk consolidation for OfflineVmware VM migrations * Fix several typos encountered * Improve garbage collection for failed volume migrations
1 parent 3cbac98 commit 2bcf8ad

File tree

13 files changed

+259
-161
lines changed

13 files changed

+259
-161
lines changed

api/src/com/cloud/hypervisor/HypervisorGuru.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public interface HypervisorGuru extends Adapter {
9191
*
9292
* @param vm the stopped vm to migrate
9393
* @param destination the primary storage pool to migrate to
94-
* @return a list of commands to perform for a succesful migration
94+
* @return a list of commands to perform for a successful migration
9595
*/
9696
List<Command> finalizeMigrate(VirtualMachine vm, StoragePool destination);
9797
}

api/src/com/cloud/storage/Volume.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ enum State {
5151
NotUploaded("The volume entry is just created in DB, not yet uploaded"),
5252
UploadInProgress("Volume upload is in progress"),
5353
UploadError("Volume upload encountered some error"),
54-
UploadAbandoned("Volume upload is abandoned since the upload was never initiated within a specificed time");
54+
UploadAbandoned("Volume upload is abandoned since the upload was never initiated within a specified time");
5555

5656
String _description;
5757

api/src/org/apache/cloudstack/api/command/admin/vm/MigrateVMCmd.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545
@APICommand(name = "migrateVirtualMachine",
4646
description = "Attempts Migration of a VM to a different host or Root volume of the vm to a different storage pool",
47-
responseObject = UserVmResponse.class, entityType = {VirtualMachine.class},
47+
responseObject = UserVmResponse.class, entityType = {VirtualMachine.class},
4848
requestHasSensitiveInfo = false,
4949
responseHasSensitiveInfo = true)
5050
public class MigrateVMCmd extends BaseAsyncCmd {
@@ -149,6 +149,7 @@ public void execute() {
149149
CallContext.current().setEventDetails("VM Id: " + getVirtualMachineId() + " to host Id: " + getHostId());
150150
}
151151

152+
// OfflineMigration performed when this parameter is specified
152153
StoragePool destStoragePool = null;
153154
if (getStoragePoolId() != null) {
154155
destStoragePool = _storageService.getStoragePool(getStoragePoolId());

api/src/org/apache/cloudstack/api/command/admin/vm/MigrateVirtualMachineWithVolumeCmd.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646

4747
@APICommand(name = "migrateVirtualMachineWithVolume",
4848
description = "Attempts Migration of a VM with its volumes to a different host",
49-
responseObject = UserVmResponse.class, entityType = {VirtualMachine.class},
49+
responseObject = UserVmResponse.class, entityType = {VirtualMachine.class},
5050
requestHasSensitiveInfo = false,
5151
responseHasSensitiveInfo = true)
5252
public class MigrateVirtualMachineWithVolumeCmd extends BaseAsyncCmd {

core/src/com/cloud/agent/api/MigrateVmToPoolCommand.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
import java.util.Collection;
2424

2525
/**
26-
* used to tell the agent to migrate a vm to a different primare storage pool.
27-
* It is for now only mplemented on Vmware and is supposed to work irrespective of whether the VM is started or not.
26+
* used to tell the agent to migrate a vm to a different primary storage pool.
27+
* It is for now only implemented on Vmware and is supposed to work irrespective of whether the VM is started or not.
2828
*
2929
*/
3030
public class MigrateVmToPoolCommand extends Command {
@@ -39,8 +39,8 @@ protected MigrateVmToPoolCommand() {
3939
/**
4040
*
4141
* @param vmName the name of the VM to migrate
42-
* @param volumes used to suplly feedback on vmware generated names
43-
* @param destinationPool the primare storage pool to migrate the VM to
42+
* @param volumes used to supply feedback on vmware generated names
43+
* @param destinationPool the primary storage pool to migrate the VM to
4444
* @param executeInSequence
4545
*/
4646
public MigrateVmToPoolCommand(String vmName, Collection<VolumeTO> volumes, String destinationPool, boolean executeInSequence) {

engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1813,7 +1813,7 @@ private void preStorageMigrationStateCheck(StoragePool destPool, VMInstanceVO vm
18131813
private void checkDestinationForTags(StoragePool destPool, VMInstanceVO vm) {
18141814
List<VolumeVO> vols = _volsDao.findUsableVolumesForInstance(vm.getId());
18151815

1816-
// OfflineVmwareMigration: itterate over volumes
1816+
// OfflineVmwareMigration: iterate over volumes
18171817
// OfflineVmwareMigration: get disk offering
18181818
List<String> storageTags = storageMgr.getStoragePoolTagList(destPool.getId());
18191819
for(Volume vol : vols) {
@@ -1856,7 +1856,7 @@ private Answer[] attemptHypervisorMigration(StoragePool destPool, VMInstanceVO v
18561856
List<Command> commandsToSend = hvGuru.finalizeMigrate(vm, destPool);
18571857

18581858
Long hostId = vm.getHostId();
1859-
// OfflineVmwareMigration: probaby this is null when vm is stopped
1859+
// OfflineVmwareMigration: probably this is null when vm is stopped
18601860
if(hostId == null) {
18611861
hostId = vm.getLastHostId();
18621862
if (s_logger.isDebugEnabled()) {
@@ -1971,8 +1971,8 @@ private void afterStorageMigrationVmwareVMcleanup(StoragePool destPool, VMInstan
19711971
}
19721972
}
19731973

1974-
// OfflineVmwareMigration: on port forward refator this to be done in two
1975-
// OfflineVmwareMigration: command creation in the guru.migrat method
1974+
// OfflineVmwareMigration: on port forward refactor this to be done in two
1975+
// OfflineVmwareMigration: command creation in the guru.migrate method
19761976
// OfflineVmwareMigration: sending up in the attemptHypevisorMigration with execute in sequence (responsibility of the guru)
19771977
private void removeStaleVmFromSource(VMInstanceVO vm, HostVO srcHost) {
19781978
s_logger.debug("Since VM's storage was successfully migrated across VMware Datacenters, unregistering VM: " + vm.getInstanceName() +

engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,13 @@ private void checkConcurrentJobsPerDatastoreThreshhold(final StoragePool destPoo
955955
@DB
956956
public Volume migrateVolume(Volume volume, StoragePool destPool) throws StorageUnavailableException {
957957
VolumeInfo vol = volFactory.getVolume(volume.getId());
958+
if (vol == null){
959+
throw new CloudRuntimeException("Migrate volume failed because volume object of volume " + volume.getName()+ "is null");
960+
}
961+
962+
if (destPool == null) {
963+
throw new CloudRuntimeException("Migrate volume failed because destination storage pool is not available!!");
964+
}
958965

959966
checkConcurrentJobsPerDatastoreThreshhold(destPool);
960967

engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,17 @@
1818
*/
1919
package org.apache.cloudstack.storage.motion;
2020

21+
import java.util.Date;
2122
import java.util.LinkedList;
2223
import java.util.List;
2324
import java.util.Map;
2425

2526
import javax.inject.Inject;
2627

28+
import com.cloud.storage.Volume;
29+
import com.cloud.storage.VolumeVO;
30+
import com.cloud.storage.dao.VolumeDao;
31+
import org.apache.log4j.Logger;
2732
import org.springframework.stereotype.Component;
2833

2934
import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
@@ -40,10 +45,15 @@
4045
import com.cloud.utils.StringUtils;
4146
import com.cloud.utils.exception.CloudRuntimeException;
4247

48+
4349
@Component
4450
public class DataMotionServiceImpl implements DataMotionService {
51+
private static final Logger LOGGER = Logger.getLogger(DataMotionServiceImpl.class);
52+
4553
@Inject
4654
StorageStrategyFactory storageStrategyFactory;
55+
@Inject
56+
VolumeDao volDao;
4757

4858
@Override
4959
public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback<CopyCommandResult> callback) {
@@ -61,13 +71,33 @@ public void copyAsync(DataObject srcData, DataObject destData, Host destHost, As
6171

6272
DataMotionStrategy strategy = storageStrategyFactory.getDataMotionStrategy(srcData, destData);
6373
if (strategy == null) {
74+
// OfflineVmware volume migration
75+
// Cleanup volumes from target and reset the state of volume at source
76+
cleanUpVolumesForFailedMigrations(srcData, destData);
6477
throw new CloudRuntimeException("Can't find strategy to move data. " + "Source: " + srcData.getType().name() + " '" + srcData.getUuid() + ", Destination: " +
65-
destData.getType().name() + " '" + destData.getUuid() + "'");
78+
destData.getType().name() + " '" + destData.getUuid() + "'");
6679
}
6780

6881
strategy.copyAsync(srcData, destData, destHost, callback);
6982
}
7083

84+
/**
85+
* Offline Vmware volume migration
86+
* Cleanup volumes after failed migrations and reset state of source volume
87+
*
88+
* @param srcData
89+
* @param destData
90+
*/
91+
private void cleanUpVolumesForFailedMigrations(DataObject srcData, DataObject destData) {
92+
VolumeVO destinationVO = volDao.findById(destData.getId());
93+
VolumeVO sourceVO = volDao.findById(srcData.getId());
94+
sourceVO.setState(Volume.State.Ready);
95+
volDao.update(sourceVO.getId(), sourceVO);
96+
destinationVO.setState(Volume.State.Expunged);
97+
destinationVO.setRemoved(new Date());
98+
volDao.update(destinationVO.getId(), destinationVO);
99+
}
100+
71101
@Override
72102
public void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
73103
copyAsync(srcData, destData, null, callback);
@@ -84,7 +114,7 @@ public void copyAsync(Map<VolumeInfo, DataStore> volumeMap, VirtualMachineTO vmT
84114
}
85115

86116
throw new CloudRuntimeException("Can't find strategy to move data. " + "Source Host: " + srcHost.getName() + ", Destination Host: " + destHost.getName() +
87-
", Volume UUIDs: " + StringUtils.join(volumeIds, ","));
117+
", Volume UUIDs: " + StringUtils.join(volumeIds, ","));
88118
}
89119

90120
strategy.copyAsync(volumeMap, vmTo, srcHost, destHost, callback);

0 commit comments

Comments
 (0)