bug 7722: open vswitch - complete

This commit is contained in:
Frank 2011-01-07 23:06:02 -08:00
parent 9d2916ffcc
commit 6f9f8b145b
10 changed files with 228 additions and 115 deletions

View File

@ -6,6 +6,7 @@ public class OvsSetTagAndFlowCommand extends Command {
String vlans;
String vmName;
String seqno;
String tag;
Long vmId;
@Override
@ -29,8 +30,13 @@ public class OvsSetTagAndFlowCommand extends Command {
return vmId;
}
public OvsSetTagAndFlowCommand(String vmName, String vlans, String seqno, Long vmId) {
public String getTag() {
return tag;
}
public OvsSetTagAndFlowCommand(String vmName, String tag, String vlans, String seqno, Long vmId) {
this.vmName = vmName;
this.tag = tag;
this.vlans = vlans;
this.seqno = seqno;
this.vmId = vmId;

View File

@ -3835,9 +3835,7 @@ public abstract class CitrixResourceBase implements ServerResource {
Connection conn = getConnection();
try {
String nwName = Networks.BroadcastScheme.VSwitch.toString();
Network nw = getNetworkByName(conn, nwName);
assert nw!= null : "Why there is no vswith network ???";
Network nw = setupvSwitchNetwork(conn);
String bridge = nw.getBridge(conn);
String result = callHostPlugin(conn, "vmops", "ovs_delete_flow", "bridge", bridge,
"vmName", cmd.getVmName());
@ -3861,12 +3859,12 @@ public abstract class CitrixResourceBase implements ServerResource {
List<Pair<String, Long>> states = new ArrayList<Pair<String, Long>>();
for (String log: logs){
String [] info = log.split(",");
if (info.length != 4) {
if (info.length != 5) {
s_logger.warn("Wrong element number in ovs log");
continue;
}
//','.join([bridge, vmName, vmId, seqno])
//','.join([bridge, vmName, vmId, seqno, tag])
try {
states.add(new Pair<String,Long>(info[0], Long.parseLong(info[3])));
} catch (NumberFormatException nfe) {
@ -3887,9 +3885,7 @@ public abstract class CitrixResourceBase implements ServerResource {
Connection conn = getConnection();
try {
String nwName = Networks.BroadcastScheme.VSwitch.toString();
Network nw = getNetworkByName(conn, nwName);
assert nw!= null : "Why there is no vswith network ???";
Network nw = setupvSwitchNetwork(conn);
String bridge = nw.getBridge(conn);
/*If VM is domainRouter, this will try to set flow and tag on its
@ -3897,7 +3893,8 @@ public abstract class CitrixResourceBase implements ServerResource {
* plugin side
*/
String result = callHostPlugin(conn, "vmops", "ovs_set_tag_and_flow", "bridge", bridge,
"vmName", cmd.getVmName(), "vlans", cmd.getVlans(), "seqno", cmd.getSeqNo());
"vmName", cmd.getVmName(), "tag", cmd.getTag(),
"vlans", cmd.getVlans(), "seqno", cmd.getSeqNo());
s_logger.debug("set flow for " + cmd.getVmName() + " " + result);
if (result.equalsIgnoreCase("SUCCESS")) {

View File

@ -17,7 +17,7 @@ vSwitchPidFile = "/var/run/openvswitch/ovs-vswitchd.pid"
vsctlPath = "/usr/bin/ovs-vsctl"
vSwitchDaemonName = "ovs-vswitchd"
logFile = "/var/log/cloud/management/vlanRemapUtils.log"
logFile = "/var/log/vlanRemapUtils.log"
fLog = None
global result
@ -256,7 +256,7 @@ def getVifPort(bridge, vifName):
portUuids = getPortsOnBridge(bridge)
if portUuids == None:
log("No ports on bridge %s" % bridge)
return -1
return None
for i in portUuids:
name = getFieldOfPort(i, "name")
@ -335,7 +335,17 @@ def delARPFlow(vlan):
doCmd(delFlow)
def delDHCPFlow(vlan):
param = "dl_type=0x0800 nw_proto=6 tp_src=547 dl_vlan=%s" % vlan
param = "dl_type=0x0800 nw_proto=17 tp_dst=68 dl_vlan=%s" % vlan
delFlow = ["ovs-ofctl del-flows %s" % bridge, '"%s"' % param]
doCmd(delFlow)
def delDHCPClientFlow(vlan):
param = "dl_type=0x0800 nw_proto=17 tp_dst=67 dl_vlan=%s" % vlan
delFlow = ["ovs-ofctl del-flows %s" % bridge, '"%s"' % param]
doCmd(delFlow)
def delDropFlow(vlan):
param = "priority=0 dl_vlan=%s" % vlan
delFlow = ["ovs-ofctl del-flows %s" % bridge, '"%s"' % param]
doCmd(delFlow)
@ -345,7 +355,17 @@ def formatDHCPFlow(bridge, inPort, vlan, ports):
str = "output:%s," % i
outputs += str
outputs = outputs[:-1]
flow = "in_port=%s dl_vlan=%s dl_type=0x0800 nw_proto=6 tp_src=547 idle_timeout=0 hard_timeout=0 \
flow = "in_port=%s dl_vlan=%s dl_type=0x0800 nw_proto=17 tp_dst=67 idle_timeout=0 hard_timeout=0 \
priority=10000 actions=strip_vlan,%s" % (inPort, vlan, outputs)
return flow
def formatDHCPClientFlow(bridge, inPort, vlan, ports):
outputs = ''
for i in ports:
str = "output:%s," % i
outputs += str
outputs = outputs[:-1]
flow = "in_port=%s dl_vlan=%s dl_type=0x0800 nw_proto=17 tp_dst=68 idle_timeout=0 hard_timeout=0 \
priority=10000 actions=strip_vlan,%s" % (inPort, vlan, outputs)
return flow
@ -378,12 +398,7 @@ def createFlow (bridge, vifName, mac, remap):
result = errors["NO_OFPORT"]
return -1
#del old flow here, if any, but in normal there should be no old flow
#maybe we need add check here
delFlow(mac)
#set remap here, remap has format e.g. [1,22,200,13,16]
remap = strip(remap)
log("")
log("Create flow for remap")
noneGreOfPorts = getNoneGreOfPort(bridge)
@ -393,8 +408,6 @@ def createFlow (bridge, vifName, mac, remap):
isARP = False
for j in remap.split("/"):
delARPFlow(j)
delDHCPFlow(j)
for i in inport:
flow = formatDropFlow(i, j)
param = bridge + ' "%s"' % flow
@ -418,6 +431,11 @@ def createFlow (bridge, vifName, mac, remap):
addflow = ["ovs-ofctl add-flow", param]
doCmd (addflow)
flow = formatDHCPClientFlow(bridge, i, j, noneGreOfPorts)
param = bridge + ' "%s"' % flow
addflow = ["ovs-ofctl add-flow", param]
doCmd (addflow)
result = errors["SUCCESS"]
return 0
######################## End Flow creation utils ##########################
@ -463,30 +481,63 @@ remap=%s" % (bridge, vifName, mac, remap))
def doSetTag (bridge, vifName, tag):
setTag(bridge, vifName, tag)
def doDeleteFlow(bridge, vifName, mac, remap):
delFlow(mac)
log("Delete flows for %s" % mac)
def doAskPorts(bridge, vifNames):
vifs = vifNames.split(",")
if len(vifs) == 0:
return ' '
ofports = []
for vif in vifs:
op = getVifPort(bridge, vif)
if op == None:
log("doAskPorts: no port(bridge:%s, vif:%s)" % (bridge, vif))
continue
ofports.append(op)
return ",".join(ofports)
def doDeleteFlow(bridge, ofports, macs, remap):
for i in macs.split(","):
delFlow(i)
log("Delete flows for %s" % i)
remap = strip(remap)
# remove our port from arp flow
inport = getGreOfPorts(bridge)
if len(inport) == 0:
log("WARNING:no inports")
return
mine = getVifPort(bridge, vifName)
noneGreOfPorts = getNoneGreOfPort(bridge)
noneGreOfPorts.remove(mine)
log("Delete ARP flows for(vifname=%s, ofport=%s)" % (vifName, mine))
for i in ofports.split(","):
try:
noneGreOfPorts.remove(i)
except:
log("WARNING:ofport %s is not on bridge %s" % (i, bridge))
log("Delete ARP flows for(ofport=%s)" % i)
for j in remap.split("/"):
delARPFlow(j)
delDHCPFlow(j)
delDHCPClientFlow(j)
delDropFlow(j)
for i in inport:
flow = formatARPFlow(bridge, i, j, noneGreOfPorts)
param = bridge + ' "%s"' % flow
addflow = ["ovs-ofctl add-flow", param]
doCmd (addflow)
flow = formatDHCPFlow(bridge, i, j, noneGreOfPorts)
param = bridge + ' "%s"' % flow
addflow = ["ovs-ofctl add-flow", param]
doCmd (addflow)
flow = formatDHCPClientFlow(bridge, i, j, noneGreOfPorts)
param = bridge + ' "%s"' % flow
addflow = ["ovs-ofctl add-flow", param]
doCmd (addflow)
def checkArgNum(num):
if len (sys.argv) < num:
result = errors["ERR_ARGS_NUM"]
@ -524,16 +575,22 @@ if __name__ == "__main__":
elif op == "deleteFlow":
checkArgNum(6)
bridge = sys.argv[2]
vifName = sys.argv[3]
mac = sys.argv[4]
ofports = sys.argv[3]
macs = sys.argv[4]
remap = sys.argv[5]
doDeleteFlow(bridge, vifName, mac, remap)
doDeleteFlow(bridge, ofports, macs, remap)
elif op == "setTag":
checkArgNum(5)
bridge = sys.argv[2]
vifName = sys.argv[3]
tag = sys.argv[4]
doSetTag(bridge, vifName, tag)
elif op == "askPorts":
checkArgNum(4)
bridge = sys.argv[2]
vifNames = sys.argv[3]
print doAskPorts(bridge, vifNames)
sys.exit(0)
else:
log("WARNING: get an unkown op %s" % op)
result=errors["ERROR_OP"]

View File

@ -147,13 +147,17 @@ def vlanRemapUtils(session, args):
cmd.insert(7, args.pop("remap"))
elif op == "deleteFlow":
cmd.insert(3, args.pop("bridge"))
cmd.insert(4, args.pop("vifName"))
cmd.insert(5, args.pop("mac"))
cmd.insert(4, args.pop("ofports"))
cmd.insert(5, args.pop("macs"))
cmd.insert(6, args.pop("remap"))
elif op == "setTag":
cmd.insert(3, args.pop("bridge"))
cmd.insert(4, args.pop("vifName"))
cmd.insert(5, args.pop("tag"))
elif op == "askPorts":
cmd.insert(3, args.pop("bridge"))
cmd.insert(4, args.pop("vifNames"))
try:
txt = util.pread2(cmd)
@ -592,6 +596,9 @@ def ovs_get_mac_info_from_log(vmName):
def ovs_get_vlans_info_from_log(vmName):
return ovs_get_info_from_log(vmName, 3)
def ovs_get_ofports_info_from_log(vmName):
return ovs_get_info_from_log(vmName, 4)
def ovs_parse_common_info_from_log(vmName, num):
info = ovs_get_common_info_from_log(vmName)
if info == None:
@ -607,6 +614,10 @@ def ovs_get_vm_id_from_log(vmName):
def ovs_get_seqno_from_log(vmName):
return ovs_parse_common_info_from_log(vmName, 3)
def ovs_get_tag_from_log(vmName):
return ovs_parse_common_info_from_log(vmName, 4)
def ovs_handle_rebooted_vm(session, vmName):
curr_domid = '-1'
@ -619,7 +630,7 @@ def ovs_handle_rebooted_vm(session, vmName):
util.SMlog("%s rebooted, reset flow for it" % vmName)
try:
vlans = ovs_get_vlans_info_from_log(vmName)
vlanstr = ovs_get_vlans_info_from_log(vmName)
bridge = ovs_get_bridge_from_log(vmName)
except Exception, e:
util.SMlog(e.__str__())
@ -628,22 +639,23 @@ def ovs_handle_rebooted_vm(session, vmName):
return False
i = 0
if vlans == None:
util.SMlog("OVSErr: cannot get vlans for %s" % vmName)
if vlanstr == None:
util.SMlog("OVSErr: cannot get vlanstr for %s" % vmName)
return False
tag = vlans.split('/')[0]
tag = ovs_get_tag_from_log(vmName)
nics = []
macs = []
for vifr in vifrs:
vifName = "vif" + curr_domid + "." + vifr[0]
vlanRemapUtils(session, {"op":"setTag", "vifName":vifName, "bridge":bridge, "tag":tag})
vlanRemapUtils(session, {"op":"createFlow", "vifName":vifName, "bridge":bridge, "mac":vifr[1], "remap":vlans})
vlanRemapUtils(session, {"op":"createFlow", "vifName":vifName, "bridge":bridge, "mac":vifr[1], "remap":vlanstr})
nics.append(vifName)
macs.append(vifr[1])
i += 1
seqno = ovs_get_seqno_from_log(vmName)
ovs_write_vm_log(bridge, vmName, curr_domid, seqno, nics, macs, vlans)
ofports = ovs_get_ofports_info_from_log(vmName)
ovs_write_vm_log(bridge, vmName, curr_domid, seqno, nics, macs, tag, vlanstr, ofports)
#see if there is rebooted vm to handle
ovs_get_vm_log(session, {"host_uuid":hostuuid})
@ -677,12 +689,12 @@ def ovs_get_vm_log(session, args):
return ";".join(result)
def ovs_write_vm_log(bridge, vmName, vmId, seqno, vifNames, macs, vlans):
def ovs_write_vm_log(bridge, vmName, vmId, seqno, vifNames, macs, tag, vlans, ofports):
logfilename = format_ovs_vm_log_name(vmName)
util.SMlog("Writing ovs log to " + logfilename)
logf = open(logfilename, 'w')
output = ','.join([vmName, bridge, vmId, seqno])
output = ','.join([vmName, bridge, vmId, seqno, tag])
result = True
try:
logf.write(output)
@ -695,6 +707,8 @@ def ovs_write_vm_log(bridge, vmName, vmId, seqno, vifNames, macs, vlans):
logf.write('\n')
logf.write(vlans)
logf.write('\n')
logf.write(ofports)
logf.write('\n')
except:
util.SMlog("Failed to write to ovs log file " + logfilename)
result = False
@ -707,23 +721,17 @@ def ovs_delete_flow(session, args):
bridge = args.pop('bridge')
vm_name = args.pop('vmName')
nicStr = ovs_get_nic_info_from_log(vm_name)
macStr = ovs_get_mac_info_from_log(vm_name)
vlanStr = ovs_get_vlans_info_from_log(vm_name)
macs = ovs_get_mac_info_from_log(vm_name)
vlans = ovs_get_vlans_info_from_log(vm_name)
ofports = ovs_get_ofports_info_from_log(vm_name)
if nicStr == None or macStr == None or vlanStr == None:
if macs == None or vlans == None or ofports == None:
return 'ERROR_LOG'
nics = nicStr.split(',')
macs = macStr.split(',')
if len(nics) != len(macs):
return 'ERROR_LOG'
vlanRemapUtils(session, {"op":"deleteFlow", "bridge":bridge, \
"ofports":ofports, "macs":macs, "remap":vlans})
i = 0
for nic in nics:
vlanRemapUtils(session, {"op":"deleteFlow", "bridge":bridge, \
"vifName":nic, "mac":macs[i], "remap":vlanStr})
i += 1
remove_ovs_log_for_vm(vm_name)
return 'SUCCESS'
def ovs_get_domid_vifrs_hostuuid(session, vm_name):
@ -755,6 +763,7 @@ def ovs_set_tag_and_flow(session, args):
bridge = args.pop('bridge')
vm_name = args.pop('vmName')
vlanStr = args.pop('vlans')
tag = args.pop('tag')
seqno = args.pop('seqno')
(domid, vifrs, hostuuid) = ovs_get_domid_vifrs_hostuuid(session, vm_name)
@ -766,6 +775,9 @@ def ovs_set_tag_and_flow(session, args):
if len(vifrs) == 0:
return 'SUCCESS'
#delete old flows first
ovs_delete_flow(session, {"bridge":bridge, "vmName":vm_name})
if vlanStr.startswith("/"): vlanStr = vlanStr[1:]
if vlanStr.endswith("/"): vlanStr = vlanStr[:-1]
vlans = vlanStr.split("/")
@ -776,10 +788,11 @@ def ovs_set_tag_and_flow(session, args):
vifNames.append(vifName)
mac = vifr[1]
macs.append(mac)
vlanRemapUtils(session, {"op":"setTag", "vifName":vifName, "bridge":bridge, "tag":vlans[0]})
vlanRemapUtils(session, {"op":"setTag", "vifName":vifName, "bridge":bridge, "tag":tag})
vlanRemapUtils(session, {"op":"createFlow", "vifName":vifName, "bridge":bridge, "mac":mac, "remap":vlanStr})
res = ovs_write_vm_log(bridge, vm_name, domid, seqno, vifNames, macs, vlanStr)
ofports = vlanRemapUtils(session, {"op":"askPorts", "bridge":bridge, "vifNames":",".join(vifNames)})
res = ovs_write_vm_log(bridge, vm_name, domid, seqno, vifNames, macs, tag, vlanStr, ofports)
if res == 'false':
return 'CREATE_LOG_FAILED'

View File

@ -15,6 +15,7 @@ import com.cloud.network.PublicIpAddress;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.ovs.OvsNetworkManager;
import com.cloud.network.rules.FirewallRule;
import com.cloud.offering.NetworkOffering;
@ -58,13 +59,12 @@ public class OvsElement extends AdapterBase implements NetworkElement {
InsufficientCapacityException {
VirtualMachine instance = vm.getVirtualMachine();
if (instance.getType() == VirtualMachine.Type.DomainRouter) {
if (network.getTrafficType() != Networks.TrafficType.Guest ||
instance.getType() == VirtualMachine.Type.DomainRouter) {
return true;
}
}
if (network.getTrafficType() == Networks.TrafficType.Guest) {
_ovsNetworkMgr.CheckAndUpdateDhcpFlow(network, vm.getVirtualMachine());
}
//_ovsNetworkMgr.CheckAndUpdateDhcpFlow(network, vm.getVirtualMachine());
return true;
}

View File

@ -195,6 +195,8 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager {
}
String vlans = getVlanMapping(vm.getAccountId());
String tag = Long.toString(_vlanMappingDao.findByAccountIdAndHostId(
vm.getAccountId(), vm.getHostId()).getVlan());
Long agentId = null;
VmFlowLogVO log = _flowLogDao.findByVmId(userVmId);
if (log == null) {
@ -207,7 +209,7 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager {
agentId = vm.getHostId();
if (agentId != null ) {
OvsSetTagAndFlowCommand cmd = new OvsSetTagAndFlowCommand(
vm.getName(), vlans, seqnum.toString(), vm.getId());
vm.getName(), tag, vlans, seqnum.toString(), vm.getId());
Commands cmds = new Commands(cmd);
try {
_agentMgr.send(agentId, cmds, _ovsListener);
@ -273,8 +275,11 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager {
VlanMappingVO newVlan = new VlanMappingVO(accountId, hostId, vlan);
_vlanMappingDao.persist(newVlan);
_vlanMappingDirtyDao.markDirty(accountId);
String s = String.format("allocate a new vlan %1$s(account:%2$s, hostId:%3$s), mark dirty",
vlan, accountId, hostId);
s_logger.debug("OVSDIRTY:" + s);
txn.commit();
return 0;
return vlan;
}
@Override
@ -294,8 +299,8 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager {
assert vlans.size() > 0 : "Vlan map can't be null";
StringBuffer buf = new StringBuffer();
buf.append("/");
for (Long i : vlans) {
buf.append("/");
buf.append(i.toString());
buf.append("/");
}
@ -345,16 +350,10 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager {
_agentMgr.send(i.longValue(), cmd2s , _ovsListener);
s_logger.debug("Ask host " + i.longValue() + " to create gre tunnel to " + hostId);
}
_vlanMappingDirtyDao.markDirty(accountId);
} catch (Exception e) {
e.printStackTrace();
}
}
private String parseVlanAndMapping(String uri) {
String sub = uri.substring(BroadcastDomainType.Vswitch.scheme().length() + "://".length() - 1);
return sub;
}
protected void applyDefaultFlow(Commands cmds,
VMInstanceVO instance, DeployDestination dest) {
@ -368,28 +367,43 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager {
return;
}
List<NicVO> nics = _nicDao.listBy(instance.getId());
if (nics.size() == 0)
String tag = Long.toString(askVlanId(instance.getAccountId(), instance.getHostId()));
String vlans = getVlanMapping(instance.getAccountId());
CheckAndUpdateDhcpFlow(instance);
VmFlowLogVO log = _flowLogDao.findOrNewByVmId(instance.getId(), instance.getName());
cmds.addCommand(new OvsSetTagAndFlowCommand(instance.getName(), tag, vlans,
Long.toString(log.getLogsequence()), instance.getId()));
}
//FIXME: if router has record in database but not start, this will hang 10 secs due to host
//plugin cannot found vif for router.
public void CheckAndUpdateDhcpFlow(VMInstanceVO instance) {
if (!_isEnabled) {
return;
NicVO nic = null;
if (vmType == VirtualMachine.Type.DomainRouter) {
for (NicVO n : nics) {
NetworkVO network = _networkDao.findById(n.getNetworkId());
if (network.getTrafficType() == TrafficType.Guest) {
nic = n;
break;
}
}
} else {
nic = nics.get(0);
}
assert nic!=null : "Why there is no guest network nic???";
String vlans = parseVlanAndMapping(nic.getBroadcastUri().toASCIIString());
VmFlowLogVO log = _flowLogDao.findOrNewByVmId(instance.getId(), instance.getName());
cmds.addCommand(new OvsSetTagAndFlowCommand(instance.getName(), vlans,
Long.toString(log.getLogsequence()), instance.getId()));
long accountId = instance.getAccountId();
DomainRouterVO router = _routerDao.findBy(accountId, instance.getDataCenterId());
if (router == null) {
return;
}
if (!_vlanMappingDirtyDao.isDirty(accountId)) {
return;
}
try {
String vlans = getVlanMapping(accountId);
String tag = Long.toString(_vlanMappingDao.findByAccountIdAndHostId(router.getAccountId(),
router.getHostId()).getVlan());
VmFlowLogVO log = _flowLogDao.findOrNewByVmId(instance.getId(), instance.getName());
_agentMgr.send(router.getHostId(), new OvsSetTagAndFlowCommand(
router.getName(), tag, vlans, Long.toString(log.getLogsequence()), instance.getId()));
s_logger.debug("ask router " + router.getName() + " on host "
+ router.getHostId() + " update vlan map to " + vlans);
} catch (Exception e) {
e.printStackTrace();
}
}
//FIXME: if at this router is not start, this will hang 10 secs due to host
@ -412,9 +426,11 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager {
try {
String vlans = getVlanMapping(accountId);
String tag = Long.toString(_vlanMappingDao.findByAccountIdAndHostId(router.getAccountId(),
router.getHostId()).getVlan());
VmFlowLogVO log = _flowLogDao.findOrNewByVmId(vm.getId(), vm.getName());
_agentMgr.send(router.getHostId(), new OvsSetTagAndFlowCommand(
router.getName(), vlans, Long.toString(log.getLogsequence()), vm.getId()));
router.getName(), tag, vlans, Long.toString(log.getLogsequence()), vm.getId()));
s_logger.debug("ask router " + router.getName() + " on host "
+ router.getHostId() + " update vlan map to " + vlans);
} catch (Exception e) {
@ -479,6 +495,7 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager {
protected Set<Long> getAffectedVms(VMInstanceVO instance) {
long accountId = instance.getAccountId();
if (!_vlanMappingDirtyDao.isDirty(accountId)) {
s_logger.debug("OVSAFFECTED: no VM affected by " + instance.getName());
return null;
}
@ -487,6 +504,13 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager {
for (UserVmVO vm : vms) {
affectedVms.add(new Long(vm.getId()));
}
if (instance.getType() != VirtualMachine.Type.DomainRouter) {
DomainRouterVO router = _routerDao.findBy(accountId, instance.getDataCenterId());
if (router != null) {
affectedVms.add(new Long(router.getId()));
}
}
return affectedVms;
}
@ -494,7 +518,7 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager {
Set<Long> affectedVms = getAffectedVms(instance);
scheduleFlowUpdateToHosts(affectedVms, true, null);
_vlanMappingDirtyDao.clean(instance.getAccountId());
s_logger.debug("Clean dirty for account " + instance.getAccountId());
s_logger.debug("OVSDIRTY:Clean dirty for account " + instance.getAccountId());
}
//TODO: think about lock
@ -508,10 +532,10 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager {
VlanMappingVO vo = _vlanMappingDao.findByAccountIdAndHostId(accountId, hostId);
if (vo.unref() == 0) {
_vlanMappingDao.remove(vo.getId());
s_logger.debug(instance.getName() + " is the last one on host "
+ hostId + " for account " + accountId
+ ", remove vlan in ovs_host_vlan_alloc");
_vlanMappingDirtyDao.markDirty(accountId);
String s = String.format("%1$s is the last VM(host:%2$s, accountId:%3$s), remove vlan",
instance.getName(), hostId, accountId);
s_logger.debug("OVSDIRTY:" + s);
} else {
_vlanMappingDao.update(vo.getId(), vo);
s_logger.debug(instance.getName()

View File

@ -12,21 +12,30 @@ import javax.ejb.Local;
@Local(value = { VlanMappingDao.class })
public class VlanMappingDaoImpl extends GenericDaoBase<VlanMappingVO, Long>
implements VlanMappingDao {
protected final SearchBuilder<VlanMappingVO> AllFieldsSearch;
protected final SearchBuilder<VlanMappingVO> accountIdSearch;
protected final SearchBuilder<VlanMappingVO> hostSearch;
protected final SearchBuilder<VlanMappingVO> accountHostSearch;
public VlanMappingDaoImpl() {
super();
AllFieldsSearch = createSearchBuilder();
AllFieldsSearch.and("host_id", AllFieldsSearch.entity().getHostId(), Op.EQ);
AllFieldsSearch.and("account_id", AllFieldsSearch.entity().getAccountId(), Op.EQ);
AllFieldsSearch.and("vlan", AllFieldsSearch.entity().getAccountId(), Op.EQ);
AllFieldsSearch.done();
accountHostSearch = createSearchBuilder();
accountHostSearch.and("host_id", accountHostSearch.entity().getHostId(), Op.EQ);
accountHostSearch.and("account_id", accountHostSearch.entity().getAccountId(), Op.EQ);
accountHostSearch.done();
accountIdSearch = createSearchBuilder();
accountIdSearch.and("account_id", accountIdSearch.entity().getAccountId(), Op.EQ);
accountIdSearch.done();
hostSearch = createSearchBuilder();
hostSearch.and("host_id", hostSearch.entity().getHostId(), Op.EQ);
hostSearch.done();
}
@Override
public List<VlanMappingVO> listByAccountIdAndHostId(long accountId,
long hostId) {
SearchCriteria<VlanMappingVO> sc = AllFieldsSearch.create();
SearchCriteria<VlanMappingVO> sc = accountHostSearch.create();
sc.setParameters("account_id", accountId);
sc.setParameters("host_id", hostId);
return listBy(sc, null);
@ -34,7 +43,7 @@ public class VlanMappingDaoImpl extends GenericDaoBase<VlanMappingVO, Long>
@Override
public List<VlanMappingVO> listByHostId(long hostId) {
SearchCriteria<VlanMappingVO> sc = AllFieldsSearch.create();
SearchCriteria<VlanMappingVO> sc = hostSearch.create();
sc.setParameters("host_id", hostId);
return listBy(sc, null);
@ -42,7 +51,7 @@ public class VlanMappingDaoImpl extends GenericDaoBase<VlanMappingVO, Long>
@Override
public List<VlanMappingVO> listByAccountId(long accountId) {
SearchCriteria<VlanMappingVO> sc = AllFieldsSearch.create();
SearchCriteria<VlanMappingVO> sc = accountIdSearch.create();
sc.setParameters("account_id", accountId);
return listBy(sc, null);
@ -50,8 +59,9 @@ public class VlanMappingDaoImpl extends GenericDaoBase<VlanMappingVO, Long>
@Override
public VlanMappingVO findByAccountIdAndHostId(long accountId, long hostId) {
SearchCriteria<VlanMappingVO> sc = AllFieldsSearch.create();
SearchCriteria<VlanMappingVO> sc = accountHostSearch.create();
sc.setParameters("account_id", accountId);
sc.setParameters("host_id", hostId);
return findOneBy(sc);
}
}

View File

@ -10,19 +10,18 @@ import com.cloud.utils.db.SearchCriteria.Op;
@Local(value = { VlanMappingDirtyDao.class })
public class VlanMappingDirtyDaoImpl extends
GenericDaoBase<VlanMappingDirtyVO, Long> implements VlanMappingDirtyDao {
protected final SearchBuilder<VlanMappingDirtyVO> AllFieldsSearch;
protected final SearchBuilder<VlanMappingDirtyVO> AccountIdSearch;
public VlanMappingDirtyDaoImpl() {
super();
AllFieldsSearch = createSearchBuilder();
AllFieldsSearch.and("account_id", AllFieldsSearch.entity().getAccountId(), Op.EQ);
AllFieldsSearch.and("dirty", AllFieldsSearch.entity().isDirty(), Op.EQ);
AllFieldsSearch.done();
AccountIdSearch = createSearchBuilder();
AccountIdSearch.and("account_id", AccountIdSearch.entity().getAccountId(), Op.EQ);
AccountIdSearch.done();
}
@Override
public boolean isDirty(long accountId) {
SearchCriteria<VlanMappingDirtyVO> sc = AllFieldsSearch.create();
SearchCriteria<VlanMappingDirtyVO> sc = AccountIdSearch.create();
sc.setParameters("account_id", accountId);
VlanMappingDirtyVO vo = findOneBy(sc);
if (vo == null) {
@ -33,7 +32,7 @@ public class VlanMappingDirtyDaoImpl extends
@Override
public void markDirty(long accountId) {
SearchCriteria<VlanMappingDirtyVO> sc = AllFieldsSearch.create();
SearchCriteria<VlanMappingDirtyVO> sc = AccountIdSearch.create();
sc.setParameters("account_id", accountId);
VlanMappingDirtyVO vo = findOneBy(sc);
if (vo == null) {
@ -47,7 +46,7 @@ public class VlanMappingDirtyDaoImpl extends
@Override
public void clean(long accountId) {
SearchCriteria<VlanMappingDirtyVO> sc = AllFieldsSearch.create();
SearchCriteria<VlanMappingDirtyVO> sc = AccountIdSearch.create();
sc.setParameters("account_id", accountId);
VlanMappingDirtyVO vo = findOneBy(sc);
if (vo == null) {

View File

@ -42,11 +42,14 @@ public class VlanMappingDirtyVO {
return dirty;
}
public void markDirty() {
dirty = true;
public void setDirty(boolean dirty) {
this.dirty = dirty;
}
public void markDirty() {
setDirty(true);
}
public void clean() {
dirty = false;
setDirty(false);
}
}

View File

@ -25,7 +25,7 @@ public class VlanMappingVO {
private long vlan;
@Column(name = "ref")
private int ref;
int ref;
public VlanMappingVO(long accountId, long hostId, long vlan) {
this.hostId = hostId;
@ -58,6 +58,10 @@ public class VlanMappingVO {
return ref;
}
public void setRef(int ref) {
this.ref = ref;
}
public void ref() {
ref++;
}