CLOUDSTACK-8319. For both 'MigrateVolume' and 'MigrateVMWithVolumes, ensure VM's vconfiguration files are migrated along with VM's root volume.

This commit is contained in:
Likitha Shetty 2015-03-05 14:24:46 +05:30
parent adc836cc5e
commit bdd28a45ed
4 changed files with 63 additions and 13 deletions

View File

@ -22,6 +22,7 @@ package com.cloud.agent.api.storage;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.storage.StoragePool;
import com.cloud.storage.Volume;
public class MigrateVolumeCommand extends Command {
@ -29,6 +30,7 @@ public class MigrateVolumeCommand extends Command {
String volumePath;
StorageFilerTO pool;
String attachedVmName;
Volume.Type volumeType;
public MigrateVolumeCommand(long volumeId, String volumePath, StoragePool pool, int timeout) {
this.volumeId = volumeId;
@ -37,11 +39,12 @@ public class MigrateVolumeCommand extends Command {
this.setWait(timeout);
}
public MigrateVolumeCommand(long volumeId, String volumePath, StoragePool pool, String attachedVmName, int timeout) {
public MigrateVolumeCommand(long volumeId, String volumePath, StoragePool pool, String attachedVmName, Volume.Type volumeType, int timeout) {
this.volumeId = volumeId;
this.volumePath = volumePath;
this.pool = new StorageFilerTO(pool);
this.attachedVmName = attachedVmName;
this.volumeType = volumeType;
this.setWait(timeout);
}
@ -65,4 +68,8 @@ public class MigrateVolumeCommand extends Command {
public String getAttachedVmName() {
return attachedVmName;
}
public Volume.Type getVolumeType() {
return volumeType;
}
}

View File

@ -389,7 +389,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
VolumeInfo volume = (VolumeInfo)srcData;
StoragePool destPool = (StoragePool)dataStoreMgr.getDataStore(destData.getDataStore().getId(), DataStoreRole.Primary);
MigrateVolumeCommand command = new MigrateVolumeCommand(volume.getId(), volume.getPath(), destPool, volume.getAttachedVmName(), waitInterval);
MigrateVolumeCommand command = new MigrateVolumeCommand(volume.getId(), volume.getPath(), destPool, volume.getAttachedVmName(), volume.getVolumeType(), waitInterval);
EndPoint ep = selector.select(srcData, StorageAction.MIGRATEVOLUME);
Answer answer = null;
if (ep == null) {

View File

@ -3023,7 +3023,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
List<VirtualMachineRelocateSpecDiskLocator> diskLocators = new ArrayList<VirtualMachineRelocateSpecDiskLocator>();
VirtualMachineRelocateSpecDiskLocator diskLocator = null;
boolean isFirstDs = true;
String tgtDsName = "";
String tgtDsHost;
String tgtDsPath;
@ -3112,9 +3111,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
morTgtDatastore = morDsAtSource;
}
if (isFirstDs) {
if (volume.getType() == Volume.Type.ROOT) {
relocateSpec.setDatastore(morTgtDatastore);
isFirstDs = false;
}
diskLocator = new VirtualMachineRelocateSpecDiskLocator();
diskLocator.setDatastore(morTgtDatastore);
@ -3124,6 +3122,18 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
diskLocators.add(diskLocator);
volumeDeviceKey.put(volume.getId(), diskId);
}
// If a target datastore is provided for the VM, then by default all volumes associated with the VM will be migrated to that target datastore.
// Hence set the existing datastore as target datastore for volumes that are not to be migrated.
List<Pair<Integer, ManagedObjectReference>> diskDatastores = vmMo.getAllDiskDatastores();
for (Pair<Integer, ManagedObjectReference> diskDatastore : diskDatastores) {
if (!volumeDeviceKey.containsValue(diskDatastore.first().intValue())) {
diskLocator = new VirtualMachineRelocateSpecDiskLocator();
diskLocator.setDiskId(diskDatastore.first().intValue());
diskLocator.setDatastore(diskDatastore.second());
diskLocators.add(diskLocator);
}
}
relocateSpec.getDisk().addAll(diskLocators);
// Prepare network at target before migration
@ -3225,6 +3235,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
private Answer execute(MigrateVolumeCommand cmd) {
String volumePath = cmd.getVolumePath();
StorageFilerTO poolTo = cmd.getPool();
Volume.Type volumeType = cmd.getVolumeType();
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource MigrateVolumeCommand: " + _gson.toJson(cmd));
@ -3271,9 +3282,23 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
diskLocator = new VirtualMachineRelocateSpecDiskLocator();
diskLocator.setDatastore(morDs);
diskLocator.setDiskId(diskId);
diskLocators.add(diskLocator);
relocateSpec.getDisk().add(diskLocator);
if (cmd.getVolumeType() == Volume.Type.ROOT) {
relocateSpec.setDatastore(morDs);
// If a target datastore is provided for the VM, then by default all volumes associated with the VM will be migrated to that target datastore.
// Hence set the existing datastore as target datastore for volumes that are not to be migrated.
List<Pair<Integer, ManagedObjectReference>> diskDatastores = vmMo.getAllDiskDatastores();
for (Pair<Integer, ManagedObjectReference> diskDatastore : diskDatastores) {
if (diskDatastore.first().intValue() != diskId) {
diskLocator = new VirtualMachineRelocateSpecDiskLocator();
diskLocator.setDiskId(diskDatastore.first().intValue());
diskLocator.setDatastore(diskDatastore.second());
diskLocators.add(diskLocator);
}
}
}
relocateSpec.getDisk().addAll(diskLocators);
// Change datastore
if (!vmMo.changeDatastore(relocateSpec)) {
@ -3286,12 +3311,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
// In case of a linked clone VM, if VM's disks are not consolidated,
// further volume operations on the ROOT volume such as volume snapshot etc. will result in DB inconsistencies.
String apiVersion = HypervisorHostHelper.getVcenterApiVersion(vmMo.getContext());
if (apiVersion.compareTo("5.0") >= 0) {
if (!vmMo.consolidateVmDisks()) {
s_logger.warn("VM disk consolidation failed after storage migration.");
} else {
s_logger.debug("Successfully consolidated disks of VM " + vmName + ".");
}
if (!vmMo.consolidateVmDisks()) {
s_logger.warn("VM disk consolidation failed after storage migration.");
} else {
s_logger.debug("Successfully consolidated disks of VM " + vmName + ".");
}
// Update and return volume path because that could have changed after migration

View File

@ -2069,6 +2069,26 @@ public class VirtualMachineMO extends BaseMO {
return builder;
}
public List<Pair<Integer, ManagedObjectReference>> getAllDiskDatastores() throws Exception {
List<Pair<Integer, ManagedObjectReference>> disks = new ArrayList<Pair<Integer, ManagedObjectReference>>();
List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device");
if (devices != null && devices.size() > 0) {
for (VirtualDevice device : devices) {
if (device instanceof VirtualDisk) {
VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking();
if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
disks.add(new Pair<Integer, ManagedObjectReference>(new Integer(device.getKey()), diskBackingInfo.getDatastore()));
}
}
}
}
return disks;
}
@Deprecated
public List<Pair<String, ManagedObjectReference>> getDiskDatastorePathChain(VirtualDisk disk, boolean followChain) throws Exception {
VirtualDeviceBackingInfo backingInfo = disk.getBacking();