This is an automated email from the ASF dual-hosted git repository.
bhaisaab pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/master by this push:
new 0c6cf69 CLOUDSTACK-9717: [VMware] RVRs have mismatching MAC addresses
for extra public NICs. (#1878)
0c6cf69 is described below
commit 0c6cf69eeec940345a6ee01b7d03a184e3c31398
Author: sureshanaparti <[email protected]>
AuthorDate: Mon Aug 21 14:34:20 2017 +0530
CLOUDSTACK-9717: [VMware] RVRs have mismatching MAC addresses for extra
public NICs. (#1878)
Fix: When RVR is enabled and Peer Router is available, get the MAC
addresses of the extra public NICs from the Peer Router and set them to the
router.
---
engine/schema/src/com/cloud/vm/dao/NicDao.java | 2 +
engine/schema/src/com/cloud/vm/dao/NicDaoImpl.java | 20 +++++++
.../src/com/cloud/hypervisor/guru/VMwareGuru.java | 17 ++++++
.../hypervisor/vmware/resource/VmwareResource.java | 65 ++++++++++++++++++++++
.../vmware/resource/VmwareResourceTest.java | 34 +++++++++++
5 files changed, 138 insertions(+)
diff --git a/engine/schema/src/com/cloud/vm/dao/NicDao.java
b/engine/schema/src/com/cloud/vm/dao/NicDao.java
index d31a165..797f002 100644
--- a/engine/schema/src/com/cloud/vm/dao/NicDao.java
+++ b/engine/schema/src/com/cloud/vm/dao/NicDao.java
@@ -77,5 +77,7 @@ public interface NicDao extends GenericDao<NicVO, Long> {
NicVO getControlNicForVM(long vmId);
+ Long getPeerRouterId(String publicMacAddress, long routerId);
+
List<NicVO> listByVmIdAndKeyword(long instanceId, String keyword);
}
diff --git a/engine/schema/src/com/cloud/vm/dao/NicDaoImpl.java
b/engine/schema/src/com/cloud/vm/dao/NicDaoImpl.java
index a5edf58..daf773a 100644
--- a/engine/schema/src/com/cloud/vm/dao/NicDaoImpl.java
+++ b/engine/schema/src/com/cloud/vm/dao/NicDaoImpl.java
@@ -45,6 +45,7 @@ public class NicDaoImpl extends GenericDaoBase<NicVO, Long>
implements NicDao {
private SearchBuilder<NicVO> NonReleasedSearch;
private GenericSearchBuilder<NicVO, Integer> deviceIdSearch;
private GenericSearchBuilder<NicVO, Integer> CountByForStartingVms;
+ private SearchBuilder<NicVO> PeerRouterSearch;
@Inject
VMInstanceDao _vmDao;
@@ -94,6 +95,12 @@ public class NicDaoImpl extends GenericDaoBase<NicVO, Long>
implements NicDao {
join1.and("state", join1.entity().getState(), Op.EQ);
CountByForStartingVms.join("vm", join1,
CountByForStartingVms.entity().getInstanceId(), join1.entity().getId(),
JoinBuilder.JoinType.INNER);
CountByForStartingVms.done();
+
+ PeerRouterSearch = createSearchBuilder();
+ PeerRouterSearch.and("instanceId",
PeerRouterSearch.entity().getInstanceId(), Op.NEQ);
+ PeerRouterSearch.and("macAddress",
PeerRouterSearch.entity().getMacAddress(), Op.EQ);
+ PeerRouterSearch.and("vmType", PeerRouterSearch.entity().getVmType(),
Op.EQ);
+ PeerRouterSearch.done();
}
@Override
@@ -313,6 +320,19 @@ public class NicDaoImpl extends GenericDaoBase<NicVO,
Long> implements NicDao {
}
@Override
+ public Long getPeerRouterId(String publicMacAddress, final long routerId) {
+ final SearchCriteria<NicVO> sc = PeerRouterSearch.create();
+ sc.setParameters("instanceId", routerId);
+ sc.setParameters("macAddress", publicMacAddress);
+ sc.setParameters("vmType", VirtualMachine.Type.DomainRouter);
+ NicVO nicVo = findOneBy(sc);
+ if (nicVo != null) {
+ return nicVo.getInstanceId();
+ }
+ return null;
+ }
+
+ @Override
public List<NicVO> listByVmIdAndKeyword(long instanceId, String keyword) {
SearchCriteria<NicVO> sc = AllFieldsSearch.create();
sc.setParameters("instance", instanceId);
diff --git
a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
index 668f4ac..7b6accf 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
@@ -94,6 +94,7 @@ import com.cloud.utils.Pair;
import com.cloud.utils.db.DB;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.NicProfile;
import com.cloud.vm.NicVO;
import com.cloud.vm.SecondaryStorageVmVO;
@@ -101,6 +102,7 @@ import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.Type;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.VmDetailConstants;
+import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.VMInstanceDao;
@@ -128,6 +130,8 @@ public class VMwareGuru extends HypervisorGuruBase
implements HypervisorGuru, Co
@Inject
private NicDao _nicDao;
@Inject
+ private DomainRouterDao _domainRouterDao;
+ @Inject
private PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao;
@Inject
private VMInstanceDao _vmDao;
@@ -296,6 +300,19 @@ public class VMwareGuru extends HypervisorGuruBase
implements HypervisorGuru, Co
}
to.setNics(expandedNics);
+
+ VirtualMachine router = vm.getVirtualMachine();
+ DomainRouterVO routerVO =
_domainRouterDao.findById(router.getId());
+ if (routerVO != null && routerVO.getIsRedundantRouter()) {
+ Long peerRouterId =
_nicDao.getPeerRouterId(publicNicProfile.getMacAddress(), router.getId());
+ DomainRouterVO peerRouterVO = null;
+ if (peerRouterId != null) {
+ peerRouterVO = _domainRouterDao.findById(peerRouterId);
+ if (peerRouterVO != null) {
+ details.put("PeerRouterInstanceName",
peerRouterVO.getInstanceName());
+ }
+ }
+ }
}
StringBuffer sbMacSequence = new StringBuffer();
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 bddd61a..142d341 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
@@ -46,6 +46,7 @@ import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.apache.log4j.NDC;
+import org.apache.commons.lang.StringUtils;
import com.google.gson.Gson;
import com.vmware.vim25.AboutInfo;
@@ -1959,6 +1960,40 @@ public class VmwareResource implements
StoragePoolResource, ServerResource, Vmwa
VirtualDevice nic;
int nicMask = 0;
int nicCount = 0;
+
+ if (vmSpec.getType() == VirtualMachine.Type.DomainRouter) {
+ int extraPublicNics = mgr.getRouterExtraPublicNics();
+ if (extraPublicNics > 0 &&
vmSpec.getDetails().containsKey("PeerRouterInstanceName")) {
+ //Set identical MAC address for RvR on extra public
interfaces
+ String peerRouterInstanceName =
vmSpec.getDetails().get("PeerRouterInstanceName");
+
+ VirtualMachineMO peerVmMo =
hyperHost.findVmOnHyperHost(peerRouterInstanceName);
+ if (peerVmMo == null) {
+ peerVmMo =
hyperHost.findVmOnPeerHyperHost(peerRouterInstanceName);
+ }
+
+ if (peerVmMo != null) {
+ String oldMacSequence = generateMacSequence(nics);
+
+ for (int nicIndex = nics.length - extraPublicNics;
nicIndex < nics.length; nicIndex++) {
+ VirtualDevice nicDevice =
peerVmMo.getNicDeviceByIndex(nics[nicIndex].getDeviceId());
+ if (nicDevice != null) {
+ String mac =
((VirtualEthernetCard)nicDevice).getMacAddress();
+ if (mac != null) {
+ s_logger.info("Use same MAC as previous
RvR, the MAC is " + mac + " for extra NIC with device id: " +
nics[nicIndex].getDeviceId());
+ nics[nicIndex].setMac(mac);
+ }
+ }
+ }
+
+ if (!StringUtils.isBlank(vmSpec.getBootArgs())) {
+ String newMacSequence = generateMacSequence(nics);
+
vmSpec.setBootArgs(replaceNicsMacSequenceInBootArgs(oldMacSequence,
newMacSequence, vmSpec));
+ }
+ }
+ }
+ }
+
VirtualEthernetCardType nicDeviceType =
VirtualEthernetCardType.valueOf(vmSpec.getDetails().get(VmDetailConstants.NIC_ADAPTER));
if (s_logger.isDebugEnabled())
s_logger.debug("VM " + vmInternalCSName + " will be started
with NIC device type: " + nicDeviceType);
@@ -2167,6 +2202,36 @@ public class VmwareResource implements
StoragePoolResource, ServerResource, Vmwa
/**
+ * Generate the mac sequence from the nics.
+ */
+ protected String generateMacSequence(NicTO[] nics) {
+ if (nics.length == 0) {
+ return "";
+ }
+
+ StringBuffer sbMacSequence = new StringBuffer();
+ for (NicTO nicTo : sortNicsByDeviceId(nics)) {
+ sbMacSequence.append(nicTo.getMac()).append("|");
+ }
+ if (!sbMacSequence.toString().isEmpty()) {
+ sbMacSequence.deleteCharAt(sbMacSequence.length() - 1); //Remove
extra '|' char appended at the end
+ }
+
+ return sbMacSequence.toString();
+ }
+
+ /**
+ * Update boot args with the new nic mac addresses.
+ */
+ protected String replaceNicsMacSequenceInBootArgs(String oldMacSequence,
String newMacSequence, VirtualMachineTO vmSpec) {
+ String bootArgs = vmSpec.getBootArgs();
+ if (!StringUtils.isBlank(bootArgs) &&
!StringUtils.isBlank(oldMacSequence) && !StringUtils.isBlank(newMacSequence)) {
+ return bootArgs.replace(oldMacSequence, newMacSequence);
+ }
+ return "";
+ }
+
+ /**
* Sets video card memory to the one provided in detail svga.vramSize (if
provided) on {@code vmConfigSpec}.
* 64MB was always set before.
* Size must be in KB.
diff --git
a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java
b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java
index 744c93a..c2b3f36 100644
---
a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java
+++
b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java
@@ -58,11 +58,13 @@ import com.vmware.vim25.VirtualDevice;
import com.vmware.vim25.VirtualDeviceConfigSpec;
import com.vmware.vim25.VirtualMachineConfigSpec;
import com.vmware.vim25.VirtualMachineVideoCard;
+
import com.cloud.agent.api.Command;
import com.cloud.agent.api.ScaleVmAnswer;
import com.cloud.agent.api.ScaleVmCommand;
import com.cloud.agent.api.to.DataTO;
import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.api.to.VolumeTO;
import com.cloud.hypervisor.vmware.mo.DatacenterMO;
@@ -216,6 +218,38 @@ public class VmwareResourceTest {
}
@Test
+ public void testGenerateMacSequence() {
+ final NicTO nicTo1 = new NicTO();
+ nicTo1.setMac("01:23:45:67:89:AB");
+ nicTo1.setDeviceId(1);
+
+ final NicTO nicTo2 = new NicTO();
+ nicTo2.setMac("02:00:65:b5:00:03");
+ nicTo2.setDeviceId(0);
+
+ //final NicTO [] nicTOs = {nicTO1, nicTO2, nicTO3};
+ //final NicTO[] nics = new NicTO[]{nic};
+ final NicTO[] nics = new NicTO[] {nicTo1, nicTo2};
+
+ String macSequence = _resource.generateMacSequence(nics);
+ assertEquals(macSequence, "02:00:65:b5:00:03|01:23:45:67:89:AB");
+ }
+
+ @Test
+ public void testReplaceNicsMacSequenceInBootArgs() {
+ String bootArgs =
"nic_macs=02:00:65:b5:00:03|7C02:00:4f:1b:00:15|7C1e:00:54:00:00:0f|7C02:00:35:fa:00:11|7C02:00:47:40:00:12";
+ doReturn(bootArgs).when(vmSpec).getBootArgs();
+
+ String oldMacSequence = "7C02:00:35:fa:00:11|7C02:00:47:40:00:12";
+ String newMacSequence = "7C02:00:0c:1d:00:1d|7C02:00:68:0f:00:1e";
+
+ String updatedBootArgs =
_resource.replaceNicsMacSequenceInBootArgs(oldMacSequence, newMacSequence,
vmSpec);
+
+ String newBootArgs =
"nic_macs=02:00:65:b5:00:03|7C02:00:4f:1b:00:15|7C1e:00:54:00:00:0f|7C02:00:0c:1d:00:1d|7C02:00:68:0f:00:1e";
+ assertEquals(newBootArgs, updatedBootArgs);
+ }
+
+ @Test
public void testConfigureVideoCardSvgaVramProvided() throws Exception {
Map<String, String> specDetails = new HashMap<String, String>();
specDetails.put("svga.vramSize", String.valueOf(VRAM_MEMORY_SIZE));
--
To stop receiving notification emails like this one, please contact
['"[email protected]" <[email protected]>'].