X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=xenserver%2Fopt_xensource_libexec_InterfaceReconfigure.py;h=48b39389a62eb1d11748f8ad0bcda96d28297353;hb=1452b28ca636521b6e16f76787524f83205ec7a3;hp=c7a231a8b5c19559d81e59795658a533176caa49;hpb=b63fadcfdc8a96ddb5e944b60733edf21999a1ad;p=openvswitch diff --git a/xenserver/opt_xensource_libexec_InterfaceReconfigure.py b/xenserver/opt_xensource_libexec_InterfaceReconfigure.py index c7a231a8..48b39389 100644 --- a/xenserver/opt_xensource_libexec_InterfaceReconfigure.py +++ b/xenserver/opt_xensource_libexec_InterfaceReconfigure.py @@ -241,20 +241,26 @@ def _strlist_from_xml(n, ltag, itag): ret.append(_str_from_xml(n)) return ret -def _otherconfig_to_xml(xml, parent, val, attrs): - otherconfig = xml.createElement("other_config") - parent.appendChild(otherconfig) +def _map_to_xml(xml, parent, tag, val, attrs): + e = xml.createElement(tag) + parent.appendChild(e) for n,v in val.items(): if not n in attrs: raise Error("Unknown other-config attribute: %s" % n) - _str_to_xml(xml, otherconfig, n, v) -def _otherconfig_from_xml(n, attrs): + _str_to_xml(xml, e, n, v) + +def _map_from_xml(n, attrs): ret = {} for n in n.childNodes: if n.nodeName in attrs: ret[n.nodeName] = _str_from_xml(n) return ret +def _otherconfig_to_xml(xml, parent, val, attrs): + return _map_to_xml(xml, parent, "other_config", val, attrs) +def _otherconfig_from_xml(n, attrs): + return _map_from_xml(n, attrs) + # # Definitions of the database objects (and their attributes) used by interface-reconfigure. # @@ -267,6 +273,7 @@ def _otherconfig_from_xml(n, attrs): _PIF_XML_TAG = "pif" _VLAN_XML_TAG = "vlan" +_TUNNEL_XML_TAG = "tunnel" _BOND_XML_TAG = "bond" _NETWORK_XML_TAG = "network" @@ -287,6 +294,10 @@ _PIF_ATTRS = { 'uuid': (_str_to_xml,_str_from_xml), 'VLAN_master_of': (_str_to_xml,_str_from_xml), 'VLAN_slave_of': (lambda x, p, t, v: _strlist_to_xml(x, p, 'VLAN_slave_of', 'master', v), lambda n: _strlist_from_xml(n, 'VLAN_slave_Of', 'master')), + 'tunnel_access_PIF_of': (lambda x, p, t, v: _strlist_to_xml(x, p, 'tunnel_access_PIF_of', 'pif', v), + lambda n: _strlist_from_xml(n, 'tunnel_access_PIF_of', 'pif')), + 'tunnel_transport_PIF_of': (lambda x, p, t, v: _strlist_to_xml(x, p, 'tunnel_transport_PIF_of', 'pif', v), + lambda n: _strlist_from_xml(n, 'tunnel_transport_PIF_of', 'pif')), 'ip_configuration_mode': (_str_to_xml,_str_from_xml), 'IP': (_str_to_xml,_str_from_xml), 'netmask': (_str_to_xml,_str_from_xml), @@ -308,6 +319,10 @@ _VLAN_ATTRS = { 'uuid': (_str_to_xml,_str_from_xml), 'untagged_PIF': (_str_to_xml,_str_from_xml), } +_TUNNEL_ATTRS = { 'uuid': (_str_to_xml,_str_from_xml), + 'access_PIF': (_str_to_xml,_str_from_xml), + 'transport_PIF': (_str_to_xml,_str_from_xml), + } _BOND_ATTRS = { 'uuid': (_str_to_xml,_str_from_xml), 'master': (_str_to_xml,_str_from_xml), 'slaves': (lambda x, p, t, v: _strlist_to_xml(x, p, 'slaves', 'slave', v), @@ -318,6 +333,7 @@ _NETWORK_OTHERCONFIG_ATTRS = [ 'mtu', 'static-routes' ] + _ETHTOOL_OTHERCONFIG_A _NETWORK_ATTRS = { 'uuid': (_str_to_xml,_str_from_xml), 'bridge': (_str_to_xml,_str_from_xml), + 'MTU': (_str_to_xml,_str_from_xml), 'PIFs': (lambda x, p, t, v: _strlist_to_xml(x, p, 'PIFs', 'PIF', v), lambda n: _strlist_from_xml(n, 'PIFs', 'PIF')), 'other_config': (lambda x, p, t, v: _otherconfig_to_xml(x, p, v, _NETWORK_OTHERCONFIG_ATTRS), @@ -366,7 +382,12 @@ class DatabaseCache(object): continue self.__pifs[p] = {} for f in _PIF_ATTRS: - self.__pifs[p][f] = rec[f] + if f in [ "tunnel_access_PIF_of", "tunnel_transport_PIF_of" ] and f not in rec: + # XenServer 5.5 network records did not have + # these fields, so allow them to be missing. + pass + else: + self.__pifs[p][f] = rec[f] self.__pifs[p]['other_config'] = {} for f in _PIF_OTHERCONFIG_ATTRS: if not rec['other_config'].has_key(f): continue @@ -382,6 +403,16 @@ class DatabaseCache(object): for f in _VLAN_ATTRS: self.__vlans[v][f] = rec[f] + def __get_tunnel_records_from_xapi(self, session): + self.__tunnels = {} + for t in session.xenapi.tunnel.get_all(): + rec = session.xenapi.tunnel.get_record(t) + if not self.__pif_on_host(rec['transport_PIF']): + continue + self.__tunnels[t] = {} + for f in _TUNNEL_ATTRS: + self.__tunnels[t][f] = rec[f] + def __get_bond_records_from_xapi(self, session): self.__bonds = {} for b in session.xenapi.Bond.get_all(): @@ -401,6 +432,10 @@ class DatabaseCache(object): if f == "PIFs": # drop PIFs on other hosts self.__networks[n][f] = [p for p in rec[f] if self.__pif_on_host(p)] + elif f == "MTU" and f not in rec: + # XenServer 5.5 network records did not have an + # MTU field, so allow this to be missing. + pass else: self.__networks[n][f] = rec[f] self.__networks[n]['other_config'] = {} @@ -454,6 +489,13 @@ class DatabaseCache(object): self.__get_pif_records_from_xapi(session, host) + try: + self.__get_tunnel_records_from_xapi(session) + except XenAPI.Failure, e: + error,details = e.details + if error == "MESSAGE_METHOD_UNKNOWN" and details == "tunnel.get_all": + pass + self.__get_vlan_records_from_xapi(session) self.__get_bond_records_from_xapi(session) self.__get_network_records_from_xapi(session) @@ -468,6 +510,7 @@ class DatabaseCache(object): self.__pifs = {} self.__bonds = {} self.__vlans = {} + self.__tunnels = {} self.__networks = {} assert(len(xml.childNodes) == 1) @@ -487,6 +530,9 @@ class DatabaseCache(object): elif n.nodeName == _VLAN_XML_TAG: (ref,rec) = self.__from_xml(n, _VLAN_ATTRS) self.__vlans[ref] = rec + elif n.nodeName == _TUNNEL_XML_TAG: + (ref,rec) = self.__from_xml(n, _TUNNEL_ATTRS) + self.__vlans[ref] = rec elif n.nodeName == _NETWORK_XML_TAG: (ref,rec) = self.__from_xml(n, _NETWORK_ATTRS) self.__networks[ref] = rec @@ -503,6 +549,8 @@ class DatabaseCache(object): self.__to_xml(xml, xml.documentElement, _BOND_XML_TAG, ref, rec, _BOND_ATTRS) for (ref,rec) in self.__vlans.items(): self.__to_xml(xml, xml.documentElement, _VLAN_XML_TAG, ref, rec, _VLAN_ATTRS) + for (ref,rec) in self.__tunnels.items(): + self.__to_xml(xml, xml.documentElement, _TUNNEL_XML_TAG, ref, rec, _TUNNEL_ATTRS) for (ref,rec) in self.__networks.items(): self.__to_xml(xml, xml.documentElement, _NETWORK_XML_TAG, ref, rec, _NETWORK_ATTRS) @@ -619,13 +667,33 @@ def ethtool_settings(oc): log("Invalid value for ethtool-%s = %s. Must be on|true|off|false." % (opt, val)) return settings,offload -def mtu_setting(oc): +# By default the MTU is taken from the Network.MTU setting for VIF, +# PIF and Bridge. However it is possible to override this by using +# {VIF,PIF,Network}.other-config:mtu. +# +# type parameter is a string describing the object that the oc parameter +# is from. e.g. "PIF", "Network" +def mtu_setting(nw, type, oc): + mtu = None + + nwrec = db().get_network_record(nw) + if nwrec.has_key('MTU'): + mtu = nwrec['MTU'] + else: + mtu = "1500" + if oc.has_key('mtu'): + log("Override Network.MTU setting on bridge %s from %s.MTU is %s" % \ + (nwrec['bridge'], type, mtu)) + mtu = oc['mtu'] + + if mtu is not None: try: - int(oc['mtu']) # Check that the value is an integer - return oc['mtu'] + int(mtu) # Check that the value is an integer + return mtu except ValueError, x: - log("Invalid value for mtu = %s" % oc['mtu']) + log("Invalid value for mtu = %s" % mtu) + return None # @@ -765,6 +833,13 @@ def pif_get_vlan_masters(pif): vlans = [db().get_vlan_record(v) for v in pifrec['VLAN_slave_of']] return [v['untagged_PIF'] for v in vlans if v and db().pif_exists(v['untagged_PIF'])] +# +# Tunnel PIFs +# +def pif_is_tunnel(pif): + rec = db().get_pif_record(pif) + return rec.has_key('tunnel_access_PIF_of') and len(rec['tunnel_access_PIF_of']) > 0 + # # Datapath base class # @@ -778,6 +853,12 @@ class Datapath(object): def __init__(self, pif): self._pif = pif + @classmethod + def rewrite(cls): + """Class method called when write action is called. Can be used + to update any backend specific configuration.""" + pass + def configure_ipdev(self, cfg): """Write ifcfg TYPE field for an IPdev, plus any type specific fields to cfg @@ -825,7 +906,7 @@ class Datapath(object): """ raise NotImplementedError -def DatapathFactory(pif): +def DatapathFactory(): # XXX Need a datapath object for bridgeless PIFs try: @@ -837,9 +918,9 @@ def DatapathFactory(pif): if network_backend == "bridge": from InterfaceReconfigureBridge import DatapathBridge - return DatapathBridge(pif) - elif network_backend == "vswitch": + return DatapathBridge + elif network_backend in ["openvswitch", "vswitch"]: from InterfaceReconfigureVswitch import DatapathVswitch - return DatapathVswitch(pif) + return DatapathVswitch else: raise Error("unknown network backend %s" % network_backend)