Skip to content

Commit bff610e

Browse files
shwstpprrohityadavcloud
authored andcommitted
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 9da94a2 commit bff610e

File tree

3 files changed

+78
-17
lines changed

3 files changed

+78
-17
lines changed

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

+9-14
Original file line numberDiff line numberDiff line change
@@ -1807,7 +1807,7 @@ private Pair<Long, Long> findClusterAndHostIdForVm(VMInstanceVO vm) {
18071807
if (clusterId == null && hostId != null) {
18081808
HostVO host = _hostDao.findById(hostId);
18091809
if (host != null) {
1810-
clusterId = host.getId();
1810+
clusterId = host.getClusterId();
18111811
}
18121812
}
18131813
return new Pair<>(clusterId, hostId);
@@ -1827,7 +1827,7 @@ private void migrateThroughHypervisorOrStorage(VMInstanceVO vm, Map<Volume, Stor
18271827
s_logger.debug("Storage migration failed");
18281828
}
18291829
} else {
1830-
postHypervisorMigrationCleanup(vm, volumeToPool, hypervisorMigrationResults);
1830+
postHypervisorMigrationCleanup(vm, volumeToPool, sourceClusterId, hypervisorMigrationResults);
18311831
}
18321832
}
18331833

@@ -1931,7 +1931,7 @@ private Answer[] attemptHypervisorMigration(VMInstanceVO vm, Map<Volume, Storage
19311931
return null;
19321932
}
19331933

1934-
private void postHypervisorMigrationCleanup(VMInstanceVO vm, Map<Volume, StoragePool> volumeToPool, Answer[] hypervisorMigrationResults) throws InsufficientCapacityException {
1934+
private void postHypervisorMigrationCleanup(VMInstanceVO vm, Map<Volume, StoragePool> volumeToPool, Long sourceClusterId, Answer[] hypervisorMigrationResults) throws InsufficientCapacityException {
19351935
if(s_logger.isDebugEnabled()) {
19361936
String msg = String.format("Cleaning up after hypervisor pool migration volumes for VM %s(%s)", vm.getInstanceName(), vm.getUuid());
19371937
s_logger.debug(msg);
@@ -1944,19 +1944,14 @@ private void postHypervisorMigrationCleanup(VMInstanceVO vm, Map<Volume, Storage
19441944
}
19451945
}
19461946
setDestinationPoolAndReallocateNetwork(rootVolumePool, vm);
1947-
// OfflineVmwareMigration: don't set this to null or have another way to address the command; twice migrating will lead to an NPE
1948-
Long destPodId = rootVolumePool != null ? rootVolumePool.getPodId() : null;
1949-
Long vmPodId = vm.getPodIdToDeployIn();
1950-
if (destPodId == null || ! destPodId.equals(vmPodId)) {
1951-
if(s_logger.isDebugEnabled()) {
1952-
String msg = String.format("Resetting lastHost for VM %s(%s) as pod (%s) is no good.", vm.getInstanceName(), vm.getUuid(), destPodId);
1953-
s_logger.debug(msg);
1947+
Long destClusterId = rootVolumePool != null ? rootVolumePool.getClusterId() : null;
1948+
if (destClusterId != null && !destClusterId.equals(sourceClusterId)) {
1949+
if (s_logger.isDebugEnabled()) {
1950+
s_logger.debug(String.format("Resetting lastHost for VM %s(%s)", vm.getInstanceName(), vm.getUuid()));
19541951
}
1955-
19561952
vm.setLastHostId(null);
1957-
vm.setPodIdToDeployIn(destPodId);
1958-
// OfflineVmwareMigration: a consecutive migration will fail probably (no host not pod)
1959-
}// else keep last host set for this vm
1953+
vm.setPodIdToDeployIn(rootVolumePool.getPodId());
1954+
}
19601955
markVolumesInPool(vm, hypervisorMigrationResults);
19611956
// OfflineVmwareMigration: deal with answers, if (hypervisorMigrationResults.length > 0)
19621957
// OfflineVmwareMigration: iterate over the volumes for data updates

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

+9-1
Original file line numberDiff line numberDiff line change
@@ -3585,9 +3585,17 @@ private Answer migrateVolume(MigrateVolumeCommand cmd) {
35853585
throw new CloudRuntimeException(msg);
35863586
}
35873587
targetDsMo = new DatastoreMO(dsHost.getContext(), morTargetDS);
3588+
String hardwareVersion = null;
3589+
if (hostInTargetCluster != null) {
3590+
Integer sourceHardwareVersion = HypervisorHostHelper.getHostHardwareVersion(hyperHost);
3591+
Integer destinationHardwareVersion = HypervisorHostHelper.getHostHardwareVersion(dsHost);
3592+
if (sourceHardwareVersion != null && destinationHardwareVersion != null && !sourceHardwareVersion.equals(destinationHardwareVersion)) {
3593+
hardwareVersion = String.valueOf(Math.min(sourceHardwareVersion, destinationHardwareVersion));
3594+
}
3595+
}
35883596
s_logger.info("Create worker VM " + vmName);
35893597
// OfflineVmwareMigration: 2. create the worker with access to the data(store)
3590-
vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, sourceDsMo, vmName, null);
3598+
vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, sourceDsMo, vmName, hardwareVersion);
35913599
if (vmMo == null) {
35923600
// OfflineVmwareMigration: don't throw a general Exception but think of a specific one
35933601
throw new CloudRuntimeException("Unable to create a worker VM for volume operation");

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

+60-2
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222
import java.security.InvalidParameterException;
2323
import java.util.ArrayList;
2424
import java.util.Arrays;
25+
import java.util.HashMap;
2526
import java.util.List;
2627
import java.util.Map;
2728

28-
import com.cloud.utils.StringUtils;
2929
import org.apache.log4j.Logger;
3030

3131
import com.cloud.exception.CloudException;
@@ -34,6 +34,7 @@
3434
import com.cloud.network.Networks.BroadcastDomainType;
3535
import com.cloud.utils.ActionDelegate;
3636
import com.cloud.utils.Pair;
37+
import com.cloud.utils.StringUtils;
3738
import com.cloud.utils.cisco.n1kv.vsm.NetconfHelper;
3839
import com.cloud.utils.cisco.n1kv.vsm.PolicyMap;
3940
import com.cloud.utils.cisco.n1kv.vsm.PortProfile;
@@ -49,12 +50,12 @@
4950
import com.vmware.vim25.BoolPolicy;
5051
import com.vmware.vim25.ClusterConfigInfoEx;
5152
import com.vmware.vim25.CustomFieldStringValue;
52-
import com.vmware.vim25.DatacenterConfigInfo;
5353
import com.vmware.vim25.DVPortSetting;
5454
import com.vmware.vim25.DVPortgroupConfigInfo;
5555
import com.vmware.vim25.DVPortgroupConfigSpec;
5656
import com.vmware.vim25.DVSSecurityPolicy;
5757
import com.vmware.vim25.DVSTrafficShapingPolicy;
58+
import com.vmware.vim25.DatacenterConfigInfo;
5859
import com.vmware.vim25.DynamicProperty;
5960
import com.vmware.vim25.HostNetworkSecurityPolicy;
6061
import com.vmware.vim25.HostNetworkTrafficShapingPolicy;
@@ -104,6 +105,48 @@ public class HypervisorHostHelper {
104105
// make vmware-base loosely coupled with cloud-specific stuff, duplicate VLAN.UNTAGGED constant here
105106
private static final String UNTAGGED_VLAN_NAME = "untagged";
106107

108+
protected final static Map<String, Integer> apiVersionHardwareVersionMap;
109+
110+
static {
111+
apiVersionHardwareVersionMap = new HashMap<String, Integer>();
112+
apiVersionHardwareVersionMap.put("3.5", 4);
113+
apiVersionHardwareVersionMap.put("3.6", 4);
114+
apiVersionHardwareVersionMap.put("3.7", 4);
115+
apiVersionHardwareVersionMap.put("3.8", 4);
116+
apiVersionHardwareVersionMap.put("3.9", 4);
117+
apiVersionHardwareVersionMap.put("4.0", 7);
118+
apiVersionHardwareVersionMap.put("4.1", 7);
119+
apiVersionHardwareVersionMap.put("4.2", 7);
120+
apiVersionHardwareVersionMap.put("4.3", 7);
121+
apiVersionHardwareVersionMap.put("4.4", 7);
122+
apiVersionHardwareVersionMap.put("4.5", 7);
123+
apiVersionHardwareVersionMap.put("4.6", 7);
124+
apiVersionHardwareVersionMap.put("4.7", 7);
125+
apiVersionHardwareVersionMap.put("4.8", 7);
126+
apiVersionHardwareVersionMap.put("4.9", 7);
127+
apiVersionHardwareVersionMap.put("5.0", 8);
128+
apiVersionHardwareVersionMap.put("5.1", 9);
129+
apiVersionHardwareVersionMap.put("5.2", 9);
130+
apiVersionHardwareVersionMap.put("5.3", 9);
131+
apiVersionHardwareVersionMap.put("5.4", 9);
132+
apiVersionHardwareVersionMap.put("5.5", 10);
133+
apiVersionHardwareVersionMap.put("5.6", 10);
134+
apiVersionHardwareVersionMap.put("5.7", 10);
135+
apiVersionHardwareVersionMap.put("5.8", 10);
136+
apiVersionHardwareVersionMap.put("5.9", 10);
137+
apiVersionHardwareVersionMap.put("6.0", 11);
138+
apiVersionHardwareVersionMap.put("6.1", 11);
139+
apiVersionHardwareVersionMap.put("6.2", 11);
140+
apiVersionHardwareVersionMap.put("6.3", 11);
141+
apiVersionHardwareVersionMap.put("6.4", 11);
142+
apiVersionHardwareVersionMap.put("6.5", 13);
143+
apiVersionHardwareVersionMap.put("6.6", 13);
144+
apiVersionHardwareVersionMap.put("6.7", 14);
145+
apiVersionHardwareVersionMap.put("6.8", 14);
146+
apiVersionHardwareVersionMap.put("6.9", 14);
147+
apiVersionHardwareVersionMap.put("7.0", 17);
148+
}
149+
107150
public static VirtualMachineMO findVmFromObjectContent(VmwareContext context, ObjectContent[] ocs, String name, String instanceNameCustomField) {
108151

109152
if (ocs != null && ocs.length > 0) {
@@ -1661,4 +1704,19 @@ public static boolean isIdeController(String controller) {
16611704
return DiskControllerType.getType(controller) == DiskControllerType.ide;
16621705
}
16631706

1707+
public static Integer getHostHardwareVersion(VmwareHypervisorHost host) {
1708+
Integer version = null;
1709+
HostMO hostMo = new HostMO(host.getContext(), host.getMor());
1710+
String hostApiVersion = "";
1711+
try {
1712+
hostApiVersion = hostMo.getHostAboutInfo().getApiVersion();
1713+
} catch (Exception ignored) {
1714+
}
1715+
if (hostApiVersion == null) {
1716+
hostApiVersion = "";
1717+
}
1718+
version = apiVersionHardwareVersionMap.get(hostApiVersion);
1719+
return version;
1720+
}
1721+
16641722
}

0 commit comments

Comments
 (0)