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 <sheng.yang@citrix.com>
This commit is contained in:
Bharat Kumar 2013-08-07 10:49:21 +05:30 committed by Sheng Yang
parent 70facdcc58
commit c498d2d786
5 changed files with 70 additions and 76 deletions

View File

@ -388,4 +388,6 @@ public interface NetworkManager {
PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List<Long> vlanDbIds, Long networkId, String requestedIp, boolean isSystem) throws InsufficientAddressCapacityException;
void prepareAllNicsForMigration(VirtualMachineProfile<? extends VMInstanceVO> vm, DeployDestination dest);
void removeDhcpServiceInSubnet(NicVO nic);
}

View File

@ -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<NetworkGuru> _networkGurus;
public List<NetworkGuru> 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 <Network.Capability, String> 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<? extends VMInstanceVO> vm) {
List<NicVO> nics = _nicDao.listByVmIdIncludingRemoved(vm.getId());

View File

@ -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<DeploymentPlanner> _planners;
public List<DeploymentPlanner> 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<T> profile = new VirtualMachineProfileImpl<T>(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<NicVO> 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<NicVO> listLastNicsInSubnet(VirtualMachine vm) {
List<NicVO> nicList = _nicsDao.listByVmId(vm.getId());
List<NicVO> copyOfnicList = new ArrayList<NicVO>(nicList);
for (NicVO nic : nicList) {
Network network = _networkDao.findById(nic.getNetworkId());
DhcpServiceProvider dhcpServiceProvider = _networkMgr.getDhcpServiceProvider(network);
Map <Network.Capability, String> 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());

View File

@ -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<? extends VMInstanceVO> vm,

View File

@ -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<? extends VMInstanceVO> vm,