mirror of https://github.com/apache/cloudstack.git
bug 7722: open vswitch - complete
This commit is contained in:
parent
9d2916ffcc
commit
6f9f8b145b
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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")) {
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue