本文地址:http://blog.youkuaiyun.com/spch2008/article/details/9283627
ovs-plugin修改完成后,要改写ovs_agent,用于对openvswitch施行qos规则。
一、创建新类
在计算节点ovs_quantum_agent.py中,增加新类
class OVSQosAgent(object):
def __init__(self, context, plugin_rpc, int_br, agent_id):
self.context = context
self.plugin_rpc = plugin_rpc
self.int_br = int_br
self.agent_id = agent_id
def treat_qos_added(self, device, qos_rule):
vif_port = self.int_br.get_vif_port_by_id(device)
if not vif_port:
LOG.debug("spch_device_not_in")
return
self.int_br.set_interface_qos(vif_port.port_name, qos_rule['rate'], qos_rule['burst'])
def apply_qos_rules(self, devices):
if not devices:
LOG.debug("spch_devices_is_NULL")
for device in devices:
try:
qos_rule = self.plugin_rpc.get_qos_details(self.context,
device,
self.agent_id)
except Exception:
LOG.debug(_("spch_Unable to get port qos details for device_id = %s" % device))
self.treat_qos_added(device, qos_rule)
def refresh_qos(self, port ):
device = port['id']
self.apply_qos_rules(device)
1. 改写ovs_lib,增加qos功能。
quantum\agent\linux\ovs_lib.py中的OVSBridge类中,增加以下两个函数
def set_interface_qos(self, interface, rate, burst):
ingress_policing_rate = "ingress_policing_rate=%s" % rate
ingress_policing_burst = "ingress_policing_burst=%s" % burst
args = ["set", "interface", interface, ingress_policing_rate, ingress_policing_burst]
self.run_vsctl(args)
def clear_interface_qos(self, interface):
ingress_policing_rate = "ingress_policing_rate=0"
ingress_policing_burst = "ingress_policing_burst=0"
args = ["set", "interface", interface, ingress_policing_rate, ingress_policing_burst]
self.run_vsctl(args)
2. 增加远程调用接口,用于向ovs-plugin取得qos规则。
在quantum\agent\rpc.py中
class PluginApi(proxy.RpcProxy):
def get_qos_details(self, context, device, agent_id):
return self.call(context,
self.make_msg('get_qos_details', device=device,
agent_id=agent_id),
topic=self.topic)
3. 上述get_qos_details函数中,调用了控制节点的get_qos_details函数,从数据库中取得规则,返回给ovs-agent。
在控制节点的ovs_quantum_plugin.py中
class OVSRpcCallbacks(dhcp_rpc_base.DhcpRpcCallbackMixin):
def get_qos_details(self, rpc_context, **kwargs):
agent_id = kwargs.get('agent_id')
device = kwargs.get('device')
LOG.debug("spch_get_device=%s" % device)
if device:
binding = ovs_db_v2.get_port_qos_binding(None, device)
if binding:
qos = ovs_db_v2.get_port_qos(None, binding.rule_id)
if qos:
return {'rate':qos.rate, 'burst':qos.burst}
else:
return {'rate':1, 'burst':1}
二、 使用
一中,相应的准备工作一切就绪,剩下的部分只是调用OVSQosAgent相应的操作即可。
在OVSQuantumAgent中__init__中,需要持有OVSQosAgent对象。
self.qos_agent = OVSQosAgent(self.context, self.plugin_rpc, self.int_br, self.agent_id)
nova启动虚拟机的时候会在br-int(ovs网桥)上创建一个端口,ovs-agent会定期检测,当检测到新端口创建,即会调用treat_devices_added进行处理。
所以,添加qos的操作应该treat_devices_added函数中进行。
def treat_devices_added(self, devices):
resync = False
self.qos_agent.apply_qos_rules(devices)
………………
三、总结
当然,这些实现都很简陋,没有相应的删除操作,只是希望能够掌握开发流程。