CLOUDSTACK-6183: Unplug the nic when all the ips from the public subnet is released

This commit is contained in:
Jayapal 2014-02-27 19:18:04 +05:30
parent 5360ab3d43
commit cb1c287433
2 changed files with 86 additions and 0 deletions

View File

@ -372,6 +372,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
@Override
public ExecutionResult cleanupCommand(NetworkElementCommand cmd) {
if (cmd instanceof IpAssocCommand && !(cmd instanceof IpAssocVpcCommand)) {
return cleanupNetworkElementCommand((IpAssocCommand)cmd);
}
return new ExecutionResult(true, null);
}
@ -1938,6 +1941,24 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
vm.attachDevice(getVifDriver(nicTO.getType()).plug(nicTO, "Other PV (32-bit)").toString());
}
private void vifHotUnPlug (Connect conn, String vmName, String macAddr) throws InternalErrorException, LibvirtException {
Domain vm = null;
vm = getDomain(conn, vmName);
List<InterfaceDef> pluggedNics = getInterfaces(conn, vmName);
for (InterfaceDef pluggedNic : pluggedNics) {
if (pluggedNic.getMacAddress().equalsIgnoreCase(macAddr)) {
vm.detachDevice(pluggedNic.toString());
// We don't know which "traffic type" is associated with
// each interface at this point, so inform all vif drivers
for (VifDriver vifDriver : getAllVifDrivers()) {
vifDriver.unplug(pluggedNic);
}
}
}
}
private PlugNicAnswer execute(PlugNicCommand cmd) {
NicTO nic = cmd.getNic();
String vmName = cmd.getVmName();
@ -2164,6 +2185,65 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
}
protected ExecutionResult cleanupNetworkElementCommand(IpAssocCommand cmd) {
String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
Connect conn;
try{
conn = LibvirtConnection.getConnectionByVmName(routerName);
List<InterfaceDef> nics = getInterfaces(conn, routerName);
Map<String, Integer> broadcastUriAllocatedToVM = new HashMap<String, Integer>();
Integer nicPos = 0;
for (InterfaceDef nic : nics) {
if (nic.getBrName().equalsIgnoreCase(_linkLocalBridgeName)) {
broadcastUriAllocatedToVM.put("LinkLocal", nicPos);
} else {
if (nic.getBrName().equalsIgnoreCase(_publicBridgeName) || nic.getBrName().equalsIgnoreCase(_privBridgeName) ||
nic.getBrName().equalsIgnoreCase(_guestBridgeName)) {
broadcastUriAllocatedToVM.put(BroadcastDomainType.Vlan.toUri(Vlan.UNTAGGED).toString(), nicPos);
} else {
String broadcastUri = getBroadcastUriFromBridge(nic.getBrName());
broadcastUriAllocatedToVM.put(broadcastUri, nicPos);
}
}
nicPos++;
}
IpAddressTO[] ips = cmd.getIpAddresses();
int numOfIps = ips.length;
int nicNum = 0;
for (IpAddressTO ip : ips) {
boolean newNic = false;
if (!broadcastUriAllocatedToVM.containsKey(ip.getBroadcastUri())) {
/* plug a vif into router */
VifHotPlug(conn, routerName, ip.getBroadcastUri(), ip.getVifMacAddress());
broadcastUriAllocatedToVM.put(ip.getBroadcastUri(), nicPos++);
newNic = true;
}
nicNum = broadcastUriAllocatedToVM.get(ip.getBroadcastUri());
if (numOfIps == 1 && !ip.isAdd()) {
vifHotUnPlug(conn, routerName, ip.getVifMacAddress());
networkUsage(routerIp, "deleteVif", "eth" + nicNum);
}
}
} catch (LibvirtException e) {
s_logger.error("ipassoccmd failed", e);
return new ExecutionResult(false, e.getMessage());
} catch (InternalErrorException e) {
s_logger.error("ipassoccmd failed", e);
return new ExecutionResult(false, e.getMessage());
}
return new ExecutionResult(true, null);
}
protected ManageSnapshotAnswer execute(final ManageSnapshotCommand cmd) {
String snapshotName = cmd.getSnapshotName();
String snapshotPath = cmd.getSnapshotPath();

View File

@ -2032,6 +2032,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
try {
IpAddressTO[] ips = cmd.getIpAddresses();
int ipsCount = ips.length;
for (IpAddressTO ip : ips) {
VM router = getVM(conn, routerName);
@ -2060,6 +2061,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
// to remove a VIF
boolean removeVif = false;
//there is only one ip in this public vlan and removing it, so remove the nic
if (ipsCount == 1 && !ip.isAdd()) {
removeVif = true;
}
if (correctVif == null) {
throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with.");
}