From d70d2f82d41637fadf088fce22d159617ec9f2e4 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Wed, 6 Jun 2012 16:49:16 -0700 Subject: [PATCH] StartRouter: set only control nic during the initial router start; plug exising public and guest nics after the router is started with control nic --- .../VirtualNetworkApplianceManagerImpl.java | 85 +++++++++++++------ .../cloud/vm/VirtualMachineManagerImpl.java | 46 +++++----- server/src/com/cloud/vm/dao/NicDao.java | 2 + server/src/com/cloud/vm/dao/NicDaoImpl.java | 16 ++++ wscript | 2 +- 5 files changed, 103 insertions(+), 48 deletions(-) diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index b28e193b6b0..f79eabf5bbc 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -201,6 +201,7 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.MacAddress; import com.cloud.utils.net.NetUtils; import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; import com.cloud.vm.ReservationContext; @@ -1565,7 +1566,10 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian String defaultDns1 = null; String defaultDns2 = null; - for (NicProfile nic : profile.getNics()) { + + Iterator it = profile.getNics().iterator(); + while (it.hasNext()) { + NicProfile nic = it.next(); int deviceId = nic.getDeviceId(); buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address()); buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask()); @@ -1600,6 +1604,10 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian buf.append(" localgw=").append(dest.getPod().getGateway()); } } + } else { + //Remove public and guest nics from the profile + s_logger.debug("Removing nic of type " + nic.getTrafficType() + " from virtual machine profile " + profile.getVirtualMachine()); + it.remove(); } } @@ -1893,15 +1901,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian ReservationContext context) { DomainRouterVO router = profile.getVirtualMachine(); - //Get guest nic info - List routerNics = profile.getNics(); - List guestNetworks = new ArrayList(); - for (NicProfile routerNic : routerNics) { - if (routerNic.getTrafficType() == TrafficType.Guest) { - guestNetworks.add(_networkMgr.getNetwork(routerNic.getNetworkId())); - } - } - boolean result = true; Answer answer = cmds.getAnswer("checkSsh"); @@ -1917,6 +1916,23 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian if (result == false) { return result; } + + //Get guest nic info + Map guestNics = new HashMap(); + Map publicNics = new HashMap(); + List guestNetworks = new ArrayList(); + + List routerNics = _nicDao.listByVmId(profile.getId()); + for (Nic routerNic : routerNics) { + Network network = _networkMgr.getNetwork(routerNic.getNetworkId()); + if (network.getTrafficType() == TrafficType.Guest) { + guestNics.put(routerNic, network); + guestNetworks.add(network); + } else if (network.getTrafficType() == TrafficType.Public) { + publicNics.put(routerNic, network); + } + } + answer = cmds.getAnswer("getDomRVersion"); if (answer != null && answer instanceof GetDomRVersionAnswer) { GetDomRVersionAnswer versionAnswer = (GetDomRVersionAnswer)answer; @@ -1931,6 +1947,30 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } else { result = false; } + + try { + //add router to public and guest networks + for (Nic publicNic : publicNics.keySet()) { + Network publicNtwk = publicNics.get(publicNic); + if (!addRouterToPublicNetwork(router, publicNtwk, _ipAddressDao.findByIpAndSourceNetworkId(publicNtwk.getId(), + publicNic.getIp4Address()))) { + s_logger.warn("Failed to plug nic " + publicNic + " to router " + router); + return false; + } + } + + for (Nic guestNic : guestNics.keySet()) { + Network guestNtwk = guestNics.get(guestNic); + if (!addRouterToGuestNetwork(router, guestNtwk, false)) { + s_logger.warn("Failed to plug nic " + guestNic + " to router " + router); + return false; + } + } + } catch (Exception ex) { + s_logger.warn("Failed to plug nic for router " + router + " due to exception ", ex); + return false; + } + return result; } @@ -3051,7 +3091,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } NicVO nic = _nicDao.findByInstanceIdAndNetworkId(network.getId(), router.getId()); - NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, + NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), _networkMgr.getNetworkRate(network.getId(), router.getId()), _networkMgr.isSecurityGroupSupportedInNetwork(network), _networkMgr.getNetworkTag(router.getHypervisorType(), network)); SetupGuestNetworkCommand setupCmd = new SetupGuestNetworkCommand(dhcpRange, networkDomain, isRedundant, priority, @@ -3086,12 +3126,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return false; } - //Check if router is already a part of the Guest network - if (_networkMgr.isVmPartOfNetwork(router.getId(), network.getId())) { - s_logger.debug("Router " + router + " is already part of the Guest network " + network); - return true; - } - //Add router to the Guest network boolean result = true; try { @@ -3155,7 +3189,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return result; } - protected boolean addRouterToPublicNetwork(VirtualRouter router, Network publicNetwork, IpAddress sourceNatIp) + protected boolean addRouterToPublicNetwork(VirtualRouter router, Network publicNetwork, IpAddress publicIpAddr) throws ConcurrentOperationException,ResourceUnavailableException, InsufficientCapacityException { if (publicNetwork.getTrafficType() != TrafficType.Public) { @@ -3163,12 +3197,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return false; } - //Check if router is already a part of the Public network - if (_networkMgr.isVmPartOfNetwork(router.getId(), publicNetwork.getId())) { - s_logger.debug("Router " + router + " is already part of the Public network " + publicNetwork); - return true; - } - //Add router to the Public network boolean result = true; try { @@ -3176,8 +3204,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian NicProfile publicNic = _itMgr.addVmToNetwork(router, publicNetwork); //setup public network if (publicNic != null) { - if (sourceNatIp != null) { - IPAddressVO ipVO = _ipAddressDao.findById(sourceNatIp.getId()); + if (publicIpAddr != null) { + IPAddressVO ipVO = _ipAddressDao.findById(publicIpAddr.getId()); PublicIp publicIp = new PublicIp(ipVO, _vlanDao.findById(ipVO.getVlanId()), NetUtils.createSequenceBasedMacAddress(ipVO.getMacAddress())); result = setupPublicNetwork(publicNetwork, router, false, publicIp); @@ -3242,10 +3270,11 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return result; } - protected boolean setupPublicNetwork(Network network, VirtualRouter router, boolean add, PublicIp sourceNatIp) + protected boolean setupPublicNetwork(Network network, VirtualRouter router, boolean add, PublicIp ipAddress) throws ConcurrentOperationException, ResourceUnavailableException{ List publicIps = new ArrayList(1); + publicIps.add(ipAddress); Commands cmds = new Commands(OnError.Stop); createAssociateIPCommands(router, publicIps, cmds, 0); sendCommandsToRouter(router, cmds); @@ -3254,7 +3283,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian IpAssocAnswer ipAssocAnswer = cmds.getAnswer(IpAssocAnswer.class); String setup = add ? "set" : "destroy"; if (!(ipAssocAnswer != null && ipAssocAnswer.getResult())) { - s_logger.warn("Unable to " + setup + " guest network on router " + router); + s_logger.warn("Unable to " + setup + " public network on router " + router); result = false; } diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 5dee3d1e9ee..11cb7337dd3 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -2448,31 +2448,40 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene Host host = _hostDao.findById(vm.getHostId()); DeployDestination dest = new DeployDestination(dc, null, null, host); - s_logger.debug("Adding vm " + vm + " to network " + network); + NicProfile nic = null; + NicVO nicVO = _nicsDao.findByInstanceIdAndNetworkId(network.getId(), vm.getId()); + if (nicVO != null) { + nic = new NicProfile(nicVO, network, nicVO.getBroadcastUri(), nicVO.getIsolationUri(), _networkMgr.getNetworkRate(network.getId(), vm.getId()), + _networkMgr.isSecurityGroupSupportedInNetwork(network), _networkMgr.getNetworkTag(vm.getHypervisorType(), network)); + } - Transaction txn = Transaction.currentTxn(); - txn.start(); - //1) allocate nic - NicProfile nic = _networkMgr.allocateNic(null, network, false, - 100, vmProfile).first(); + if (nic == null) { + s_logger.debug("Allocating nic for the " + vm + " in network " + network); + Transaction txn = Transaction.currentTxn(); + txn.start(); + //1) allocate nic and prepare nic if needed + int deviceId = _nicsDao.countNics(vm.getId()); + + nic = _networkMgr.allocateNic(null, network, false, + deviceId, vmProfile).first(); + + s_logger.debug("Nic is allocated successfully for vm " + vm + " in network " + network); + + nic = _networkMgr.prepareNic(vmProfile, dest, context, nic.getId(), networkVO); + + s_logger.debug("Nic is prepared successfully for vm " + vm + " in network " + network); + + txn.commit(); + } - s_logger.debug("Nic is allocated successfully for vm " + vm + " in network " + network); - - //2) Prepare nic - nic = _networkMgr.prepareNic(vmProfile, dest, context, nic.getId(), networkVO); - - s_logger.debug("Nic is prepared successfully for vm " + vm + " in network " + network); - - txn.commit(); - - //3) Convert vmProfile to vmTO + //2) Convert vmProfile to vmTO HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType()); VirtualMachineTO vmTO = hvGuru.implement(vmProfile); - //4) Convert nicProfile to NicTO + //3) Convert nicProfile to NicTO NicTO nicTO = toNicTO(nic, vmProfile.getVirtualMachine().getHypervisorType()); - //5) plug the nic to the vm + //4) plug the nic to the vm VirtualMachineGuru vmGuru = getVmGuru(vmVO); if (vmGuru.plugNic(network, nicTO, vmTO, context, dest)) { @@ -2482,7 +2491,6 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene s_logger.warn("Failed to plug nic to the vm " + vm + " in network " + network); return null; } - } @Override diff --git a/server/src/com/cloud/vm/dao/NicDao.java b/server/src/com/cloud/vm/dao/NicDao.java index deb302f4e3e..9a62467cfa6 100644 --- a/server/src/com/cloud/vm/dao/NicDao.java +++ b/server/src/com/cloud/vm/dao/NicDao.java @@ -46,4 +46,6 @@ public interface NicDao extends GenericDao { NicVO findNonReleasedByInstanceIdAndNetworkId(long networkId, long instanceId); String getIpAddress(long networkId, long instanceId); + + int countNics(long instanceId); } diff --git a/server/src/com/cloud/vm/dao/NicDaoImpl.java b/server/src/com/cloud/vm/dao/NicDaoImpl.java index 09786ca10d6..baa75cd5d2b 100644 --- a/server/src/com/cloud/vm/dao/NicDaoImpl.java +++ b/server/src/com/cloud/vm/dao/NicDaoImpl.java @@ -32,6 +32,8 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { private final SearchBuilder AllFieldsSearch; private final GenericSearchBuilder IpSearch; private final SearchBuilder NonReleasedSearch; + final GenericSearchBuilder CountBy; + protected NicDaoImpl() { super(); @@ -55,6 +57,12 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { NonReleasedSearch.and("network", NonReleasedSearch.entity().getNetworkId(), Op.EQ); NonReleasedSearch.and("state", NonReleasedSearch.entity().getState(), Op.NOTIN); NonReleasedSearch.done(); + + CountBy = createSearchBuilder(Integer.class); + CountBy.select(null, Func.COUNT, CountBy.entity().getId()); + CountBy.and("vmId", CountBy.entity().getInstanceId(), Op.EQ); + CountBy.and("removed", CountBy.entity().getRemoved(), Op.NULL); + CountBy.done(); } @Override @@ -150,4 +158,12 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { return findOneBy(sc).getIp4Address(); } + @Override + public int countNics(long instanceId) { + SearchCriteria sc = CountBy.create(); + sc.setParameters("vmId", instanceId); + List results = customSearch(sc, null); + return results.get(0); + } + } diff --git a/wscript b/wscript index d5628386c56..4ef4e365f14 100644 --- a/wscript +++ b/wscript @@ -4,7 +4,7 @@ # the following two variables are used by the target "waf dist" # if you change 'em here, you need to change it also in cloud.spec, add a %changelog entry there, and add an entry in debian/changelog -VERSION = '3.0.3.2012-06-06T23:35:14Z' +VERSION = '3.0.3.2012-06-06T23:43:59Z' APPNAME = 'cloud' import shutil,os