mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
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:
parent
adc836cc5e
commit
bdd28a45ed
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user