From c498d2d786e29d645a10237d37c71e3a5bb55eac Mon Sep 17 00:00:00 2001 From: Bharat Kumar Date: Wed, 7 Aug 2013 10:49:21 +0530 Subject: [PATCH] CLOUDSTACK-4083 if a failure occurs while adding VM to another network (this should be the first vm in the subnet). The ip alias created as a part of this process is not removed. (Sheng: remove the unnecessary import, remove blank line, upper case the bug id) Signed-off-by: Sheng Yang --- .../src/com/cloud/network/NetworkManager.java | 2 + .../com/cloud/network/NetworkManagerImpl.java | 58 ++++++++++++++ .../cloud/vm/VirtualMachineManagerImpl.java | 76 ------------------- .../cloud/network/MockNetworkManagerImpl.java | 5 ++ .../com/cloud/vpc/MockNetworkManagerImpl.java | 5 ++ 5 files changed, 70 insertions(+), 76 deletions(-) diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index dab7a13b010..6912b2b2bf9 100755 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -388,4 +388,6 @@ public interface NetworkManager { PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List vlanDbIds, Long networkId, String requestedIp, boolean isSystem) throws InsufficientAddressCapacityException; void prepareAllNicsForMigration(VirtualMachineProfile vm, DeployDestination dest); + + void removeDhcpServiceInSubnet(NicVO nic); } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 36e889d52fc..68b1b4f9497 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -37,6 +37,9 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.vm.NicIpAlias; +import com.cloud.vm.dao.NicIpAliasDao; +import com.cloud.vm.dao.NicIpAliasVO; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.region.PortableIp; @@ -266,6 +269,10 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L DataCenterVnetDao _datacenterVnetDao; @Inject NetworkAccountDao _networkAccountDao; + @Inject + protected NicIpAliasDao _nicIpAliasDao; + @Inject + protected IPAddressDao _publicIpAddressDao; List _networkGurus; public List getNetworkGurus() { @@ -2429,6 +2436,11 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L } } + // remove the dhcpservice ip if this is the last nic in subnet. + if (vm.getType() == Type.User && isDhcpAccrossMultipleSubnetsSupported(network) && isLastNicInSubnet(nic) && + network.getTrafficType() == TrafficType.Guest && network.getGuestType() == GuestType.Shared) { + removeDhcpServiceInSubnet(nic); + } NetworkGuru guru = AdapterBase.getAdapterByName(_networkGurus, network.getGuruName()); guru.deallocate(network, profile, vm); _nicDao.remove(nic.getId()); @@ -2439,6 +2451,52 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L } } + public boolean isDhcpAccrossMultipleSubnetsSupported(Network network) { + DhcpServiceProvider dhcpServiceProvider = getDhcpServiceProvider(network); + Map capabilities = dhcpServiceProvider.getCapabilities().get(Network.Service.Dhcp); + String supportsMultipleSubnets = capabilities.get(Network.Capability.DhcpAccrossMultipleSubnets); + if (supportsMultipleSubnets != null && Boolean.valueOf(supportsMultipleSubnets)) { + return true; + } + return false; + } + + private boolean isLastNicInSubnet(NicVO nic) { + if (_nicDao.listByNetworkIdTypeAndGatewayAndBroadcastUri(nic.getNetworkId(), VirtualMachine.Type.User, nic.getGateway(), nic.getBroadcastUri()).size() > 1) { + return false; + } + return true; + } + + @DB + @Override + public void removeDhcpServiceInSubnet(NicVO nic) { + Network network = _networksDao.findById(nic.getNetworkId()); + DhcpServiceProvider dhcpServiceProvider = getDhcpServiceProvider(network); + try { + NicIpAliasVO ipAlias = _nicIpAliasDao.findByGatewayAndNetworkIdAndState(nic.getGateway(), network.getId(), NicIpAlias.state.active); + if (ipAlias != null) { + ipAlias.setState(NicIpAlias.state.revoked); + Transaction txn = Transaction.currentTxn(); + txn.start(); + _nicIpAliasDao.update(ipAlias.getId(),ipAlias); + IPAddressVO aliasIpaddressVo = _publicIpAddressDao.findByIpAndSourceNetworkId(ipAlias.getNetworkId(), ipAlias.getIp4Address()); + _publicIpAddressDao.unassignIpAddress(aliasIpaddressVo.getId()); + txn.commit(); + if (!dhcpServiceProvider.removeDhcpSupportForSubnet(network)) { + s_logger.warn("Failed to remove the ip alias on the router, marking it as removed in db and freed the allocated ip " + ipAlias.getIp4Address()); + } + } + } + catch (ResourceUnavailableException e) { + //failed to remove the dhcpconfig on the router. + s_logger.info ("Unable to delete the ip alias due to unable to contact the virtualrouter."); + } + + } + + + @Override public void expungeNics(VirtualMachineProfile vm) { List nics = _nicDao.listByVmIdIncludingRemoved(vm.getId()); diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index d2a7dbe44f7..6a48e9fb584 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -37,12 +37,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import com.cloud.dc.dao.VlanDao; -import com.cloud.network.Networks; import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.IPAddressVO; -import com.cloud.network.element.DhcpServiceProvider; -import com.cloud.vm.dao.NicIpAliasDao; -import com.cloud.vm.dao.NicIpAliasVO; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -185,14 +180,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; -import org.apache.log4j.Logger; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; -import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; @Local(value = VirtualMachineManager.class) public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMachineManager, Listener { @@ -280,8 +269,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac protected IPAddressDao _publicIpAddressDao; @Inject protected VlanDao _vlanDao; - @Inject - protected NicIpAliasDao _nicIpAliasDao; protected List _planners; public List getPlanners() { @@ -475,10 +462,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac s_logger.debug("Destroying vm " + vm); } - if (vm.getType() == VirtualMachine.Type.User) { - removeDhcpServiceInsubnet(vm); - } - VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); @@ -536,40 +519,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac return true; } - @DB - private void removeDhcpServiceInsubnet(VirtualMachine vm) { - //list all the nics which belong to this vm and are the last nics in the subnets. - //we are using the info in these nics to remove the dhcp sercvice for these subnets. - List nicList = listLastNicsInSubnet(vm); - if(nicList != null && nicList.size() != 0) { - for (NicVO nic : nicList) { - //free the ipalias on the routers corresponding to each of the nics. - Network network = _networkDao.findById(nic.getNetworkId()); - DhcpServiceProvider dhcpServiceProvider = _networkMgr.getDhcpServiceProvider(network); - try { - NicIpAliasVO ipAlias = _nicIpAliasDao.findByGatewayAndNetworkIdAndState(nic.getGateway(), network.getId(), NicIpAlias.state.active); - if (ipAlias != null) { - ipAlias.setState(NicIpAlias.state.revoked); - Transaction txn = Transaction.currentTxn(); - txn.start(); - _nicIpAliasDao.update(ipAlias.getId(),ipAlias); - IPAddressVO aliasIpaddressVo = _publicIpAddressDao.findByIpAndSourceNetworkId(ipAlias.getNetworkId(), ipAlias.getIp4Address()); - _publicIpAddressDao.unassignIpAddress(aliasIpaddressVo.getId()); - txn.commit(); - if (!dhcpServiceProvider.removeDhcpSupportForSubnet(network)) { - s_logger.warn("Failed to remove the ip alias on the router, marking it as removed in db and freed the allocated ip " + ipAlias.getIp4Address()); - } - } - } - catch (ResourceUnavailableException e) { - //failed to remove the dhcpconfig on the router. - s_logger.info ("Unable to delete the ip alias due to unable to contact the virtualrouter."); - } - - } - } - } @Override public boolean start() { @@ -1413,27 +1363,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac return true; } - //list all the nics which belong to this vm and are the last nics in the subnets. - //we are using the info in these nics to remove the dhcp sercvice for these subnets. - private List listLastNicsInSubnet(VirtualMachine vm) { - List nicList = _nicsDao.listByVmId(vm.getId()); - List copyOfnicList = new ArrayList(nicList); - for (NicVO nic : nicList) { - Network network = _networkDao.findById(nic.getNetworkId()); - DhcpServiceProvider dhcpServiceProvider = _networkMgr.getDhcpServiceProvider(network); - Map capabilities = dhcpServiceProvider.getCapabilities().get(Network.Service.Dhcp); - String supportsMultipleSubnets = capabilities.get(Network.Capability.DhcpAccrossMultipleSubnets); - if ((supportsMultipleSubnets != null && Boolean.valueOf(supportsMultipleSubnets) && network.getTrafficType() == Networks.TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared)) { - //including the ip of the vm and the ipAlias - if (_nicsDao.listByNetworkIdTypeAndGatewayAndBroadcastUri(nic.getNetworkId(), VirtualMachine.Type.User, nic.getGateway(), nic.getBroadcastUri()).size() > 1) { - copyOfnicList.remove(nic); - } - } else { - copyOfnicList.remove(nic); - } - } - return copyOfnicList; - } protected boolean checkVmOnHost(VirtualMachine vm, long hostId) throws AgentUnavailableException, OperationTimedoutException { CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer) _agentMgr.send(hostId, new CheckVirtualMachineCommand(vm.getInstanceName())); @@ -3037,11 +2966,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network)); - // Adding this to the dhcpservice config if this is the last nic in subnet. - if (vm.getType() == VirtualMachine.Type.User) { - removeDhcpServiceInsubnet(vm); - } - //1) Unplug the nic if (vm.getState() == State.Running) { NicTO nicTO = toNicTO(nicProfile, vmProfile.getVirtualMachine().getHypervisorType()); diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java index 7f34e5556d7..9358c0070bd 100755 --- a/server/test/com/cloud/network/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java @@ -942,6 +942,11 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage //To change body of implemented methods use File | Settings | File Templates. } + @Override + public void removeDhcpServiceInSubnet(NicVO nic) { + //To change body of implemented methods use File | Settings | File Templates. + } + @Override public void prepareNicForMigration( VirtualMachineProfile vm, diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java index 178ebbad2a9..45d62085bf2 100644 --- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java @@ -1418,6 +1418,11 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage //To change body of implemented methods use File | Settings | File Templates. } + @Override + public void removeDhcpServiceInSubnet(NicVO nic) { + //To change body of implemented methods use File | Settings | File Templates. + } + @Override public void prepareNicForMigration( VirtualMachineProfile vm,