From 48fa20698e92dc60004cbc97aa9c909f05982121 Mon Sep 17 00:00:00 2001 From: vedulasantosh Date: Thu, 15 Jun 2017 11:37:58 +0530 Subject: [PATCH] CLOUDSTACK-9963 Root Disk controller value is changing while migrating VM --- .../vmware/resource/VmwareResource.java | 2 +- .../vmware/mo/VirtualMachineMO.java | 43 ++++++- .../vmware/mo/VirtualMachineMOTest.java | 120 ++++++++++++++++++ 3 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 vmware-base/test/com/cloud/hypervisor/vmware/mo/VirtualMachineMOTest.java diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 142d341e19e..b8a3495dd6a 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -1518,7 +1518,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } else if (DiskControllerType.getType(scsiDiskController) == DiskControllerType.buslogic) { vmMo.ensureBusLogicDeviceControllers(requiredNumScsiControllers, availableBusNum); } else if (DiskControllerType.getType(scsiDiskController) == DiskControllerType.lsilogic) { - vmMo.ensureScsiDeviceControllers(requiredNumScsiControllers, availableBusNum); + vmMo.ensureLsiLogicDeviceControllers(requiredNumScsiControllers, availableBusNum); } } diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java index 3cf3ad1744f..c7bdbcdf241 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java @@ -2220,7 +2220,48 @@ public class VirtualMachineMO extends BaseMO { if(devices != null && devices.size() > 0) { for(VirtualDevice device : devices) { - if(device instanceof VirtualLsiLogicController) { + if(device instanceof VirtualSCSIController) { + return device.getKey(); + } + } + } + + return -1; + } + + public void ensureLsiLogicDeviceControllers(int count, int availableBusNum) throws Exception { + int scsiControllerKey = getLsiLogicDeviceControllerKeyNoException(); + if (scsiControllerKey < 0) { + VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec(); + + int busNum = availableBusNum; + while (busNum < count) { + VirtualLsiLogicController scsiController = new VirtualLsiLogicController(); + scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING); + scsiController.setBusNumber(busNum); + scsiController.setKey(busNum - VmwareHelper.MAX_SCSI_CONTROLLER_COUNT); + VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec(); + scsiControllerSpec.setDevice(scsiController); + scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD); + + vmConfig.getDeviceChange().add(scsiControllerSpec); + busNum++; + } + if (configureVm(vmConfig)) { + throw new Exception("Unable to add Lsi Logic controllers to the VM " + getName()); + } else { + s_logger.info("Successfully added " + count + " LsiLogic Parallel SCSI controllers."); + } + } + } + + private int getLsiLogicDeviceControllerKeyNoException() throws Exception { + List devices = (List)_context.getVimClient(). + getDynamicProperty(_mor, "config.hardware.device"); + + if (devices != null && devices.size() > 0) { + for (VirtualDevice device : devices) { + if (device instanceof VirtualLsiLogicController) { return device.getKey(); } } diff --git a/vmware-base/test/com/cloud/hypervisor/vmware/mo/VirtualMachineMOTest.java b/vmware-base/test/com/cloud/hypervisor/vmware/mo/VirtualMachineMOTest.java new file mode 100644 index 00000000000..0e61b591bba --- /dev/null +++ b/vmware-base/test/com/cloud/hypervisor/vmware/mo/VirtualMachineMOTest.java @@ -0,0 +1,120 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.hypervisor.vmware.mo; + + +import com.cloud.hypervisor.vmware.util.VmwareClient; +import com.cloud.hypervisor.vmware.util.VmwareContext; +import com.vmware.vim25.ManagedObjectReference; +import com.vmware.vim25.VirtualDevice; +import com.vmware.vim25.VirtualLsiLogicController; +import com.vmware.vim25.VirtualLsiLogicSASController; +import com.vmware.vim25.VirtualSCSIController; +import com.vmware.vim25.VirtualSCSISharing; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.runners.MockitoJUnitRunner; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class VirtualMachineMOTest { + + @Mock + VmwareContext context; + @Mock + VmwareClient client; + @Mock + ManagedObjectReference mor; + + VirtualMachineMO vmMo; + + private List getVirtualScSiDeviceList(Class cls) { + + List deviceList = new ArrayList<>(); + try { + + VirtualSCSIController scsiController = (VirtualSCSIController)cls.newInstance(); + scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING); + scsiController.setBusNumber(0); + scsiController.setKey(1); + deviceList.add(scsiController); + } + catch (Exception ex) { + + } + return deviceList; + } + + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + vmMo = new VirtualMachineMO(context, mor); + when(context.getVimClient()).thenReturn(client); + } + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testEnsureScsiDeviceController() { + try { + when(client.getDynamicProperty(any(ManagedObjectReference.class), any(String.class))).thenReturn(getVirtualScSiDeviceList(VirtualLsiLogicSASController.class)); + vmMo.ensureScsiDeviceController(); + } + catch (Exception e) { + fail("Received exception when success expected: " + e.getMessage()); + } + } + + @Test + public void TestEnsureLsiLogicDeviceControllers() { + try { + when(client.getDynamicProperty(any(ManagedObjectReference.class), any(String.class))).thenReturn(getVirtualScSiDeviceList(VirtualLsiLogicController.class)); + vmMo.ensureLsiLogicDeviceControllers(1, 0); + } + catch (Exception e) { + fail("Received exception when success expected: " + e.getMessage()); + } + + } +} \ No newline at end of file