Skip to content

Commit 8c6bac8

Browse files
committed
orchestration: fix post storage migration (#39)
Detaching volume after cross-cluster storage migration of a stopped was resulting in failure. This PR fixes it by clearing last_host_id value and setting pod_id(podIdToDeployIn) in the database on cluster change when hypervisor migration strategy is used. Also, backports worker VM hardware version changes during volume migration from community PR, apache#4385 Signed-off-by: Abhishek Kumar <[email protected]>
1 parent e8e3f54 commit 8c6bac8

File tree

3 files changed

+84
-24
lines changed

3 files changed

+84
-24
lines changed

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

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,7 +2032,7 @@ private Pair<Long, Long> findClusterAndHostIdForVm(VMInstanceVO vm) {
20322032
if (clusterId == null && hostId != null) {
20332033
HostVO host = _hostDao.findById(hostId);
20342034
if (host != null) {
2035-
clusterId = host.getId();
2035+
clusterId = host.getClusterId();
20362036
}
20372037
}
20382038
return new Pair<>(clusterId, hostId);
@@ -2052,7 +2052,7 @@ private void migrateThroughHypervisorOrStorage(VMInstanceVO vm, Map<Volume, Stor
20522052
s_logger.debug("Storage migration failed");
20532053
}
20542054
} else {
2055-
postHypervisorMigrationCleanup(vm, volumeToPool, hypervisorMigrationResults);
2055+
postHypervisorMigrationCleanup(vm, volumeToPool, sourceClusterId, hypervisorMigrationResults);
20562056
}
20572057
}
20582058

@@ -2156,7 +2156,7 @@ private Answer[] attemptHypervisorMigration(VMInstanceVO vm, Map<Volume, Storage
21562156
return null;
21572157
}
21582158

2159-
private void postHypervisorMigrationCleanup(VMInstanceVO vm, Map<Volume, StoragePool> volumeToPool, Answer[] hypervisorMigrationResults) throws InsufficientCapacityException {
2159+
private void postHypervisorMigrationCleanup(VMInstanceVO vm, Map<Volume, StoragePool> volumeToPool, Long sourceClusterId, Answer[] hypervisorMigrationResults) throws InsufficientCapacityException {
21602160
if(s_logger.isDebugEnabled()) {
21612161
String msg = String.format("Cleaning up after hypervisor pool migration volumes for VM %s(%s)", vm.getInstanceName(), vm.getUuid());
21622162
s_logger.debug(msg);
@@ -2169,19 +2169,14 @@ private void postHypervisorMigrationCleanup(VMInstanceVO vm, Map<Volume, Storage
21692169
}
21702170
}
21712171
setDestinationPoolAndReallocateNetwork(rootVolumePool, vm);
2172-
// OfflineVmwareMigration: don't set this to null or have another way to address the command; twice migrating will lead to an NPE
2173-
Long destPodId = rootVolumePool != null ? rootVolumePool.getPodId() : null;
2174-
Long vmPodId = vm.getPodIdToDeployIn();
2175-
if (destPodId == null || ! destPodId.equals(vmPodId)) {
2176-
if(s_logger.isDebugEnabled()) {
2177-
String msg = String.format("Resetting lastHost for VM %s(%s) as pod (%s) is no good.", vm.getInstanceName(), vm.getUuid(), destPodId);
2178-
s_logger.debug(msg);
2172+
Long destClusterId = rootVolumePool != null ? rootVolumePool.getClusterId() : null;
2173+
if (destClusterId != null && !destClusterId.equals(sourceClusterId)) {
2174+
if (s_logger.isDebugEnabled()) {
2175+
s_logger.debug(String.format("Resetting lastHost for VM %s(%s)", vm.getInstanceName(), vm.getUuid()));
21792176
}
2180-
21812177
vm.setLastHostId(null);
2182-
vm.setPodIdToDeployIn(destPodId);
2183-
// OfflineVmwareMigration: a consecutive migration will fail probably (no host not pod)
2184-
}// else keep last host set for this vm
2178+
vm.setPodIdToDeployIn(rootVolumePool.getPodId());
2179+
}
21852180
markVolumesInPool(vm, hypervisorMigrationResults);
21862181
// OfflineVmwareMigration: deal with answers, if (hypervisorMigrationResults.length > 0)
21872182
// OfflineVmwareMigration: iterate over the volumes for data updates

plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4024,9 +4024,17 @@ private Answer migrateVolume(MigrateVolumeCommand cmd) {
40244024
throw new CloudRuntimeException(msg);
40254025
}
40264026
targetDsMo = new DatastoreMO(dsHost.getContext(), morTargetDS);
4027+
String hardwareVersion = null;
4028+
if (hostInTargetCluster != null) {
4029+
Integer sourceHardwareVersion = HypervisorHostHelper.getHostHardwareVersion(hyperHost);
4030+
Integer destinationHardwareVersion = HypervisorHostHelper.getHostHardwareVersion(dsHost);
4031+
if (sourceHardwareVersion != null && destinationHardwareVersion != null && !sourceHardwareVersion.equals(destinationHardwareVersion)) {
4032+
hardwareVersion = String.valueOf(Math.min(sourceHardwareVersion, destinationHardwareVersion));
4033+
}
4034+
}
40274035
s_logger.info("Create worker VM " + vmName);
40284036
// OfflineVmwareMigration: 2. create the worker with access to the data(store)
4029-
vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, sourceDsMo, vmName, null);
4037+
vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, sourceDsMo, vmName, hardwareVersion);
40304038
if (vmMo == null) {
40314039
// OfflineVmwareMigration: don't throw a general Exception but think of a specific one
40324040
throw new CloudRuntimeException("Unable to create a worker VM for volume operation");

vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.io.ByteArrayInputStream;
2020
import java.io.File;
21+
import java.io.FileWriter;
2122
import java.io.IOException;
2223
import java.io.StringWriter;
2324
import java.net.URI;
@@ -28,6 +29,7 @@
2829
import java.util.HashMap;
2930
import java.util.List;
3031
import java.util.Map;
32+
import java.util.UUID;
3133

3234
import javax.xml.parsers.DocumentBuilderFactory;
3335
import javax.xml.parsers.ParserConfigurationException;
@@ -37,8 +39,6 @@
3739
import javax.xml.transform.dom.DOMSource;
3840
import javax.xml.transform.stream.StreamResult;
3941

40-
import com.vmware.vim25.ClusterConfigInfoEx;
41-
import com.vmware.vim25.DatacenterConfigInfo;
4242
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
4343
import org.apache.commons.lang.StringUtils;
4444
import org.apache.log4j.Logger;
@@ -69,16 +69,16 @@
6969
import com.cloud.utils.exception.CloudRuntimeException;
7070
import com.cloud.utils.net.NetUtils;
7171
import com.cloud.utils.nicira.nvp.plugin.NiciraNvpApiVersion;
72-
import com.vmware.vim25.OvfCreateDescriptorParams;
73-
import com.vmware.vim25.OvfCreateDescriptorResult;
7472
import com.vmware.vim25.AlreadyExistsFaultMsg;
7573
import com.vmware.vim25.BoolPolicy;
74+
import com.vmware.vim25.ClusterConfigInfoEx;
7675
import com.vmware.vim25.CustomFieldStringValue;
7776
import com.vmware.vim25.DVPortSetting;
7877
import com.vmware.vim25.DVPortgroupConfigInfo;
7978
import com.vmware.vim25.DVPortgroupConfigSpec;
8079
import com.vmware.vim25.DVSSecurityPolicy;
8180
import com.vmware.vim25.DVSTrafficShapingPolicy;
81+
import com.vmware.vim25.DatacenterConfigInfo;
8282
import com.vmware.vim25.DynamicProperty;
8383
import com.vmware.vim25.HostNetworkSecurityPolicy;
8484
import com.vmware.vim25.HostNetworkTrafficShapingPolicy;
@@ -95,10 +95,12 @@
9595
import com.vmware.vim25.NumericRange;
9696
import com.vmware.vim25.ObjectContent;
9797
import com.vmware.vim25.OptionValue;
98+
import com.vmware.vim25.OvfCreateDescriptorParams;
99+
import com.vmware.vim25.OvfCreateDescriptorResult;
98100
import com.vmware.vim25.OvfCreateImportSpecParams;
99101
import com.vmware.vim25.OvfCreateImportSpecResult;
100-
import com.vmware.vim25.OvfFileItem;
101102
import com.vmware.vim25.OvfFile;
103+
import com.vmware.vim25.OvfFileItem;
102104
import com.vmware.vim25.ParaVirtualSCSIController;
103105
import com.vmware.vim25.VMwareDVSConfigSpec;
104106
import com.vmware.vim25.VMwareDVSPortSetting;
@@ -108,25 +110,23 @@
108110
import com.vmware.vim25.VirtualBusLogicController;
109111
import com.vmware.vim25.VirtualController;
110112
import com.vmware.vim25.VirtualDevice;
111-
import com.vmware.vim25.VirtualDisk;
112113
import com.vmware.vim25.VirtualDeviceConfigSpec;
113114
import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
115+
import com.vmware.vim25.VirtualDisk;
114116
import com.vmware.vim25.VirtualIDEController;
115117
import com.vmware.vim25.VirtualLsiLogicController;
116118
import com.vmware.vim25.VirtualLsiLogicSASController;
117119
import com.vmware.vim25.VirtualMachineConfigSpec;
118120
import com.vmware.vim25.VirtualMachineFileInfo;
119121
import com.vmware.vim25.VirtualMachineGuestOsIdentifier;
122+
import com.vmware.vim25.VirtualMachineImportSpec;
120123
import com.vmware.vim25.VirtualMachineVideoCard;
121124
import com.vmware.vim25.VirtualSCSIController;
122125
import com.vmware.vim25.VirtualSCSISharing;
123-
import com.vmware.vim25.VirtualMachineImportSpec;
124126
import com.vmware.vim25.VmwareDistributedVirtualSwitchPvlanSpec;
125127
import com.vmware.vim25.VmwareDistributedVirtualSwitchTrunkVlanSpec;
126128
import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec;
127129
import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanSpec;
128-
import java.io.FileWriter;
129-
import java.util.UUID;
130130

131131
public class HypervisorHostHelper {
132132
private static final Logger s_logger = Logger.getLogger(HypervisorHostHelper.class);
@@ -138,6 +138,48 @@ public class HypervisorHostHelper {
138138
private static final String VMDK_PACK_DIR = "ova";
139139
private static final String OVA_OPTION_KEY_BOOTDISK = "cloud.ova.bootdisk";
140140

141+
protected final static Map<String, Integer> apiVersionHardwareVersionMap;
142+
143+
static {
144+
apiVersionHardwareVersionMap = new HashMap<String, Integer>();
145+
apiVersionHardwareVersionMap.put("3.5", 4);
146+
apiVersionHardwareVersionMap.put("3.6", 4);
147+
apiVersionHardwareVersionMap.put("3.7", 4);
148+
apiVersionHardwareVersionMap.put("3.8", 4);
149+
apiVersionHardwareVersionMap.put("3.9", 4);
150+
apiVersionHardwareVersionMap.put("4.0", 7);
151+
apiVersionHardwareVersionMap.put("4.1", 7);
152+
apiVersionHardwareVersionMap.put("4.2", 7);
153+
apiVersionHardwareVersionMap.put("4.3", 7);
154+
apiVersionHardwareVersionMap.put("4.4", 7);
155+
apiVersionHardwareVersionMap.put("4.5", 7);
156+
apiVersionHardwareVersionMap.put("4.6", 7);
157+
apiVersionHardwareVersionMap.put("4.7", 7);
158+
apiVersionHardwareVersionMap.put("4.8", 7);
159+
apiVersionHardwareVersionMap.put("4.9", 7);
160+
apiVersionHardwareVersionMap.put("5.0", 8);
161+
apiVersionHardwareVersionMap.put("5.1", 9);
162+
apiVersionHardwareVersionMap.put("5.2", 9);
163+
apiVersionHardwareVersionMap.put("5.3", 9);
164+
apiVersionHardwareVersionMap.put("5.4", 9);
165+
apiVersionHardwareVersionMap.put("5.5", 10);
166+
apiVersionHardwareVersionMap.put("5.6", 10);
167+
apiVersionHardwareVersionMap.put("5.7", 10);
168+
apiVersionHardwareVersionMap.put("5.8", 10);
169+
apiVersionHardwareVersionMap.put("5.9", 10);
170+
apiVersionHardwareVersionMap.put("6.0", 11);
171+
apiVersionHardwareVersionMap.put("6.1", 11);
172+
apiVersionHardwareVersionMap.put("6.2", 11);
173+
apiVersionHardwareVersionMap.put("6.3", 11);
174+
apiVersionHardwareVersionMap.put("6.4", 11);
175+
apiVersionHardwareVersionMap.put("6.5", 13);
176+
apiVersionHardwareVersionMap.put("6.6", 13);
177+
apiVersionHardwareVersionMap.put("6.7", 14);
178+
apiVersionHardwareVersionMap.put("6.8", 14);
179+
apiVersionHardwareVersionMap.put("6.9", 14);
180+
apiVersionHardwareVersionMap.put("7.0", 17);
181+
}
182+
141183
public static VirtualMachineMO findVmFromObjectContent(VmwareContext context, ObjectContent[] ocs, String name, String instanceNameCustomField) {
142184

143185
if (ocs != null && ocs.length > 0) {
@@ -2080,4 +2122,19 @@ public static boolean isIdeController(String controller) {
20802122
return DiskControllerType.getType(controller) == DiskControllerType.ide;
20812123
}
20822124

2125+
public static Integer getHostHardwareVersion(VmwareHypervisorHost host) {
2126+
Integer version = null;
2127+
HostMO hostMo = new HostMO(host.getContext(), host.getMor());
2128+
String hostApiVersion = "";
2129+
try {
2130+
hostApiVersion = hostMo.getHostAboutInfo().getApiVersion();
2131+
} catch (Exception ignored) {
2132+
}
2133+
if (hostApiVersion == null) {
2134+
hostApiVersion = "";
2135+
}
2136+
version = apiVersionHardwareVersionMap.get(hostApiVersion);
2137+
return version;
2138+
}
2139+
20832140
}

0 commit comments

Comments
 (0)