network gc

This commit is contained in:
Alex Huang 2010-12-12 10:06:34 -08:00
parent b1d50a4abe
commit 39cc371e78
5 changed files with 106 additions and 72 deletions

View File

@ -112,4 +112,6 @@ public interface Network extends ControlledEntity {
String getDisplayText();
boolean isShared();
String getReservationId();
}

View File

@ -157,6 +157,7 @@ public enum Config {
CheckPodCIDRs("Advanced", ManagementServer.class, String.class, "check.pod.cidrs", "true", "If true, different pods must belong to different CIDR subnets.", "true,false"),
MD5Hashed("Advanced", ManagementServer.class, Boolean.class, "security.password.md5hashed", "true", "If set to false password is sent in clear text or else md5hashed", null),
NetworkGcWait("Advanced", ManagementServer.class, Integer.class, "network.gc.wait", "600", "Seconds to wait before shutting down a network that's not in used", null),
NetworkGcInterval("Advanced", ManagementServer.class, Integer.class, "network.gc.interval", "600", "Seconds to wait before checking for networks to shutdown", null),
ControlCidr("Advanced", ManagementServer.class, String.class, "control.cidr", "169.254.0.0/16", "Changes the cidr for the control network traffic. Defaults to using link local. Must be unique within pods", null),
ControlGateway("Advanced", ManagementServer.class, String.class, "control.gateway", "169.254.0.1", "gateway for the control network traffic", null),

View File

@ -26,7 +26,9 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
@ -121,6 +123,7 @@ import com.cloud.utils.Pair;
import com.cloud.utils.component.Adapters;
import com.cloud.utils.component.Inject;
import com.cloud.utils.component.Manager;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.JoinBuilder;
@ -192,6 +195,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
SearchBuilder<IPAddressVO> AssignIpAddressSearch;
SearchBuilder<IPAddressVO> IpAddressSearch;
int _networkGcWait;
int _networkGcInterval;
private Map<String, String> _configs;
@ -754,6 +758,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
virtualNetworkVlanSB.and("vlanType", virtualNetworkVlanSB.entity().getVlanType(), Op.EQ);
IpAddressSearch.join("virtualNetworkVlanSB", virtualNetworkVlanSB, IpAddressSearch.entity().getVlanId(), virtualNetworkVlanSB.entity().getId(), JoinBuilder.JoinType.INNER);
IpAddressSearch.done();
_executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Network-Scavenger"));
s_logger.info("Network Manager is configured.");
@ -767,6 +773,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
@Override
public boolean start() {
_executor.scheduleWithFixedDelay(new NetworkGarbageCollector(), _networkGcInterval, _networkGcInterval, TimeUnit.SECONDS);
return true;
}
@ -1958,15 +1965,21 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
}
txn.start();
if (success) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Unsuccessfully shutdown the network.");
}
NetworkGuru guru = _networkGurus.get(network.getGuruName());
guru.destroy(network, _networkOfferingDao.findById(network.getNetworkOfferingId()));
network.setState(Network.State.Allocated);
_networksDao.update(network.getId(), network);
_networksDao.clearCheckForGc(networkId);
} else {
network.setState(Network.State.Implemented);
_networksDao.update(network.getId(), network);
}
txn.commit();
}
@ -2000,32 +2013,40 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
@Override
public void run() {
List<Long> shutdownList = new ArrayList<Long>();
long currentTime = System.currentTimeMillis() >> 10;
HashMap<Long, Long> stillFree = new HashMap<Long, Long>();
List<Long> networkIds = _networksDao.findNetworksToGarbageCollect();
for (Long networkId : networkIds) {
Long time = _lastNetworkIdsToFree.remove(networkId);
if (time == null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("We found network " + networkId + " to be free for the first time. Adding it to the list: " + currentTime);
try {
List<Long> shutdownList = new ArrayList<Long>();
long currentTime = System.currentTimeMillis() >> 10;
HashMap<Long, Long> stillFree = new HashMap<Long, Long>();
List<Long> networkIds = _networksDao.findNetworksToGarbageCollect();
for (Long networkId : networkIds) {
Long time = _lastNetworkIdsToFree.remove(networkId);
if (time == null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("We found network " + networkId + " to be free for the first time. Adding it to the list: " + currentTime);
}
stillFree.put(networkId, currentTime);
} else if (time < (currentTime + _networkGcWait)) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Network " + networkId + " is still free but it's not time to shutdown yet: " + time);
}
stillFree.put(networkId, time);
} else {
shutdownList.add(networkId);
}
stillFree.put(networkId, currentTime);
} else if (time < (currentTime + _networkGcWait)) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Network " + networkId + " is still free but it's not time to shutdown yet: " + time);
}
stillFree.put(networkId, time);
} else {
shutdownList.add(networkId);
}
}
_lastNetworkIdsToFree = stillFree;
for (Long networkId : shutdownList) {
shutdownNetwork(networkId);
_lastNetworkIdsToFree = stillFree;
for (Long networkId : shutdownList) {
try {
shutdownNetwork(networkId);
} catch (Exception e) {
s_logger.warn("Unable to shutdown network: " + networkId);
}
}
} catch (Exception e) {
s_logger.warn("Caught exception while running network gc: ", e);
}
}
}

View File

@ -129,6 +129,8 @@ public class NetworkVO implements Network {
@Column(name=GenericDao.CREATED_COLUMN)
Date created;
@Column(name="reservation_id")
String reservationId;
public NetworkVO() {
}
@ -191,6 +193,15 @@ public class NetworkVO implements Network {
this.isShared = isShared;
}
@Override
public String getReservationId() {
return reservationId;
}
public void setReservationId(String reservationId) {
this.reservationId = reservationId;
}
@Override
public State getState() {
return state;

View File

@ -39,7 +39,6 @@ import com.cloud.network.NetworkVO;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.Mode;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.guru.NetworkGuru;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.NetworkOffering.GuestIpType;
import com.cloud.resource.Resource.ReservationStrategy;
@ -87,7 +86,7 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru {
}
DataCenterVO dc = _dcDao.findById(plan.getDataCenterId());
NetworkVO config = new NetworkVO(offering.getTrafficType(), offering.getGuestIpType(), mode, broadcastType, offering.getId(), plan.getDataCenterId());
NetworkVO network = new NetworkVO(offering.getTrafficType(), offering.getGuestIpType(), mode, broadcastType, offering.getId(), plan.getDataCenterId());
if (userSpecified != null) {
if ((userSpecified.getCidr() == null && userSpecified.getGateway() != null) ||
(userSpecified.getCidr() != null && userSpecified.getGateway() == null)) {
@ -95,75 +94,75 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru {
}
if (userSpecified.getCidr() != null) {
config.setCidr(userSpecified.getCidr());
config.setGateway(userSpecified.getGateway());
network.setCidr(userSpecified.getCidr());
network.setGateway(userSpecified.getGateway());
} else {
String guestNetworkCidr = dc.getGuestNetworkCidr();
String[] cidrTuple = guestNetworkCidr.split("\\/");
config.setGateway(NetUtils.getIpRangeStartIpFromCidr(cidrTuple[0], Long.parseLong(cidrTuple[1])));
config.setCidr(guestNetworkCidr);
network.setGateway(NetUtils.getIpRangeStartIpFromCidr(cidrTuple[0], Long.parseLong(cidrTuple[1])));
network.setCidr(guestNetworkCidr);
}
config.setDns1(dc.getDns1());
config.setDns2(dc.getDns2());
network.setDns1(dc.getDns1());
network.setDns2(dc.getDns2());
if (userSpecified.getBroadcastUri() != null) {
config.setBroadcastUri(userSpecified.getBroadcastUri());
config.setState(State.Setup);
network.setBroadcastUri(userSpecified.getBroadcastUri());
network.setState(State.Setup);
}
} else {
String guestNetworkCidr = dc.getGuestNetworkCidr();
String[] cidrTuple = guestNetworkCidr.split("\\/");
config.setGateway(NetUtils.getIpRangeStartIpFromCidr(cidrTuple[0], Long.parseLong(cidrTuple[1])));
config.setCidr(guestNetworkCidr);
config.setDns1(dc.getDns1());
config.setDns2(dc.getDns2());
network.setGateway(NetUtils.getIpRangeStartIpFromCidr(cidrTuple[0], Long.parseLong(cidrTuple[1])));
network.setCidr(guestNetworkCidr);
network.setDns1(dc.getDns1());
network.setDns2(dc.getDns2());
}
return config;
return network;
}
@Override
public void deallocate(Network config, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm) {
public void deallocate(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm) {
}
@Override
public Network implement(Network config, NetworkOffering offering, DeployDestination dest, ReservationContext context) {
assert (config.getState() == State.Allocated) : "Why implement are we implementing " + config;
public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) {
assert (network.getState() == State.Allocated) : "Why implement are we implementing " + network;
long dcId = dest.getDataCenter().getId();
NetworkVO implemented = new NetworkVO(config.getTrafficType(), config.getGuestType(), config.getMode(), config.getBroadcastDomainType(), config.getNetworkOfferingId(), config.getDataCenterId());
NetworkVO implemented = new NetworkVO(network.getTrafficType(), network.getGuestType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), network.getDataCenterId());
if (config.getBroadcastUri() == null) {
String vnet = _dcDao.allocateVnet(dcId, config.getAccountId(), context.getReservationId());
if (network.getBroadcastUri() == null) {
String vnet = _dcDao.allocateVnet(dcId, network.getAccountId(), context.getReservationId());
implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vnet));
} else {
implemented.setBroadcastUri(config.getBroadcastUri());
implemented.setBroadcastUri(network.getBroadcastUri());
}
if (config.getGateway() != null) {
implemented.setGateway(config.getGateway());
if (network.getGateway() != null) {
implemented.setGateway(network.getGateway());
}
if (config.getCidr() != null) {
implemented.setCidr(config.getCidr());
if (network.getCidr() != null) {
implemented.setCidr(network.getCidr());
}
if (config.getDns1() != null) {
implemented.setDns1(config.getDns1());
if (network.getDns1() != null) {
implemented.setDns1(network.getDns1());
}
if (config.getDns2() != null) {
implemented.setDns2(config.getDns2());
if (network.getDns2() != null) {
implemented.setDns2(network.getDns2());
}
return implemented;
}
@Override
public NicProfile allocate(Network config, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm)
public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm)
throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException {
if (config.getTrafficType() != TrafficType.Guest) {
if (network.getTrafficType() != TrafficType.Guest) {
return null;
}
@ -176,9 +175,9 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru {
}
if (nic.getMacAddress() == null) {
nic.setMacAddress(_networkMgr.getNextAvailableMacAddressInNetwork(config.getId()));
nic.setMacAddress(_networkMgr.getNextAvailableMacAddressInNetwork(network.getId()));
if (nic.getMacAddress() == null) {
throw new InsufficientAddressCapacityException("Unable to allocate more mac addresses", Network.class, config.getId());
throw new InsufficientAddressCapacityException("Unable to allocate more mac addresses", Network.class, network.getId());
}
}
@ -186,9 +185,9 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru {
}
@DB
protected String acquireGuestIpAddress(Network config) {
List<String> ips = _nicDao.listIpAddressInNetworkConfiguration(config.getId());
String[] cidr = config.getCidr().split("/");
protected String acquireGuestIpAddress(Network network) {
List<String> ips = _nicDao.listIpAddressInNetworkConfiguration(network.getId());
String[] cidr = network.getCidr().split("/");
Set<Long> allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1]));
Set<Long> usedIps = new TreeSet<Long> ();
for (String ip : ips) {
@ -205,17 +204,17 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru {
}
@Override
public void reserve(NicProfile nic, Network config, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException,
public void reserve(NicProfile nic, Network network, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException,
InsufficientAddressCapacityException {
assert (nic.getReservationStrategy() == ReservationStrategy.Start) : "What can I do for nics that are not allocated at start? ";
nic.setBroadcastUri(config.getBroadcastUri());
nic.setIsolationUri(config.getBroadcastUri());
nic.setGateway(config.getGateway());
nic.setIp4Address(acquireGuestIpAddress(config));
nic.setNetmask(NetUtils.cidr2Netmask(config.getCidr()));
nic.setDns1(config.getDns1());
nic.setDns2(config.getDns2());
nic.setBroadcastUri(network.getBroadcastUri());
nic.setIsolationUri(network.getBroadcastUri());
nic.setGateway(network.getGateway());
nic.setIp4Address(acquireGuestIpAddress(network));
nic.setNetmask(NetUtils.cidr2Netmask(network.getCidr()));
nic.setDns1(network.getDns1());
nic.setDns2(network.getDns2());
}
@Override
@ -226,12 +225,12 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru {
}
@Override
public void destroy(Network config, NetworkOffering offering) {
config.getBroadcastUri();
public void destroy(Network network, NetworkOffering offering) {
_dcDao.releaseVnet(network.getBroadcastUri().getHost(), network.getDataCenterId(), network.getAccountId(), network.getReservationId());
}
@Override
public boolean trash(Network config, NetworkOffering offering, Account owner) {
public boolean trash(Network network, NetworkOffering offering, Account owner) {
return true;
}
}