diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 06f62d7c095..83c288926bd 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -3832,7 +3832,7 @@ public abstract class CitrixResourceBase implements ServerResource { Network nw = setupvSwitchNetwork(conn); String bridge = nw.getBridge(conn); String result = callHostPlugin(conn, "vmops", "ovs_delete_flow", "bridge", bridge, - "vmName", cmd.getVmName()); + "vmName", cmd.getVmName(), "reCreate", "true"); if (result.equalsIgnoreCase("SUCCESS")) { return new Answer(cmd, true, "success to delete flows for " + cmd.getVmName()); diff --git a/scripts/vm/hypervisor/xenserver/vlanRemapUtils.py b/scripts/vm/hypervisor/xenserver/vlanRemapUtils.py index 0f582d89dba..322d347007c 100644 --- a/scripts/vm/hypervisor/xenserver/vlanRemapUtils.py +++ b/scripts/vm/hypervisor/xenserver/vlanRemapUtils.py @@ -506,13 +506,21 @@ def doAskPorts(bridge, vifNames): return ",".join(ofports) -def doDeleteFlow(bridge, ofports, macs, remap): +def doDeleteFlow(bridge, ofports, macs, remap, reCreate): for i in macs.split(","): delFlow(i) log("Delete flows for %s" % i) remap = strip(remap) + if reCreate == "false": + for j in remap.split("/"): + delARPFlow(j) + delDHCPFlow(j) + delDHCPClientFlow(j) + delDropFlow(j) + return + # remove our port from arp flow inport = getGreOfPorts(bridge) if len(inport) == 0: @@ -589,12 +597,13 @@ if __name__ == "__main__": doCreateFlow(bridge, vifName, mac, remap) sys.exit(0) elif op == "deleteFlow": - checkArgNum(6) + checkArgNum(7) bridge = sys.argv[2] ofports = sys.argv[3] macs = sys.argv[4] remap = sys.argv[5] - doDeleteFlow(bridge, ofports, macs, remap) + reCreate = sys.argv[6] + doDeleteFlow(bridge, ofports, macs, remap, reCreate) elif op == "setTag": checkArgNum(5) bridge = sys.argv[2] diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index 69cde7f9880..2781fa081ad 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -723,6 +723,7 @@ def ovs_write_vm_log(bridge, vmName, vmId, seqno, vifNames, macs, tag, vlans, of def ovs_delete_flow(session, args): bridge = args.pop('bridge') vm_name = args.pop('vmName') + reCreate = args.pop('reCreate') macs = ovs_get_mac_info_from_log(vm_name) vlans = ovs_get_vlans_info_from_log(vm_name) @@ -732,7 +733,7 @@ def ovs_delete_flow(session, args): return 'ERROR_LOG' vlanRemapUtils(session, {"op":"deleteFlow", "bridge":bridge, \ - "ofports":ofports, "macs":macs, "remap":vlans}) + "ofports":ofports, "macs":macs, "remap":vlans, "reCreate":reCreate}) remove_ovs_log_for_vm(vm_name) return 'SUCCESS' @@ -779,7 +780,7 @@ def ovs_set_tag_and_flow(session, args): return 'SUCCESS' #delete old flows first - ovs_delete_flow(session, {"bridge":bridge, "vmName":vm_name}) + ovs_delete_flow(session, {"bridge":bridge, "vmName":vm_name, "reCreate":"false"}) if vlanStr.startswith("/"): vlanStr = vlanStr[1:] if vlanStr.endswith("/"): vlanStr = vlanStr[:-1] diff --git a/server/src/com/cloud/network/ovs/OvsNetworkManagerImpl.java b/server/src/com/cloud/network/ovs/OvsNetworkManagerImpl.java index 0481a0d8c64..7dd23eb6170 100644 --- a/server/src/com/cloud/network/ovs/OvsNetworkManagerImpl.java +++ b/server/src/com/cloud/network/ovs/OvsNetworkManagerImpl.java @@ -182,16 +182,20 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { return; } Long userVmId = work.getInstanceId(); - UserVm vm = null; + VirtualMachine vm = null; Long seqnum = null; + Long vmId = work.getInstanceId(); s_logger.info("Ovs working on " + work.toString()); final Transaction txn = Transaction.currentTxn(); txn.start(); try { - vm = _userVMDao.acquireInLockTable(work.getInstanceId()); + vm = _userVMDao.acquireInLockTable(vmId); if (vm == null) { - s_logger.warn("Ovs unable to acquire lock on vm id=" + userVmId); - return ; + vm = _routerDao.acquireInLockTable(vmId); + if (vm == null) { + s_logger.warn("Ovs unable to acquire lock on vm id=" + userVmId); + return ; + } } String vlans = getVlanMapping(vm.getAccountId()); @@ -224,7 +228,14 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { } } finally { if (vm != null) { - _userVMDao.releaseFromLockTable(userVmId); + if (vm.getType() == VirtualMachine.Type.User) { + _userVMDao.releaseFromLockTable(vmId); + } else if (vm.getType() == VirtualMachine.Type.DomainRouter) { + _routerDao.releaseFromLockTable(vmId); + } else { + assert 1 == 0 : "Should not be here"; + } + _workDao.updateStep(work.getId(), Step.Done); } txn.commit(); @@ -382,6 +393,10 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { return; } + if (instance.getType() == VirtualMachine.Type.DomainRouter) { + return; + } + long accountId = instance.getAccountId(); DomainRouterVO router = _routerDao.findBy(accountId, instance.getDataCenterId()); if (router == null) { @@ -452,7 +467,13 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { _workDao.update(work.getId(), work); } finally { if (vm != null) { - _userVMDao.releaseFromLockTable(vmId); + if (vm.getType() == VirtualMachine.Type.User) { + _userVMDao.releaseFromLockTable(vmId); + } else if (vm.getType() == VirtualMachine.Type.DomainRouter) { + _routerDao.releaseFromLockTable(vmId); + } else { + assert 1 == 0 : "Should not be here"; + } } } txn.commit(); @@ -500,6 +521,7 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { final Transaction txn = Transaction.currentTxn(); txn.start(); VlanMappingVO vo = _vlanMappingDao.findByAccountIdAndHostId(accountId, hostId); + assert vo!=null: "Why there is no record for account " + accountId + " host " + hostId; if (vo.unref() == 0) { _vlanMappingDao.remove(vo.getId()); _vlanMappingDirtyDao.markDirty(accountId); @@ -622,7 +644,7 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { } if (vmIds.size() > 0) { - scheduleFlowUpdateToHosts(vmIds, true, null); + scheduleFlowUpdateToHosts(vmIds, false, null); } } diff --git a/server/src/com/cloud/network/ovs/dao/VlanMappingVO.java b/server/src/com/cloud/network/ovs/dao/VlanMappingVO.java index 6f1cbf738be..3376c05e465 100644 --- a/server/src/com/cloud/network/ovs/dao/VlanMappingVO.java +++ b/server/src/com/cloud/network/ovs/dao/VlanMappingVO.java @@ -64,10 +64,12 @@ public class VlanMappingVO { public void ref() { ref++; + setRef(ref); } public int unref() { ref--; - return ref; + setRef(ref); + return getRef(); } }