import traceback
import time
import re
-import pickle
import random
+from xml.dom.minidom import getDOMImplementation
+from xml.dom.minidom import parse as parseXML
output_directory = None
db = None
management_pif = None
-dbcache_file = "/etc/ovs-vswitch.dbcache"
-vswitch_config_dir = "/etc/openvswitch"
+vswitch_state_dir = "/var/lib/openvswitch/"
+dbcache_file = vswitch_state_dir + "dbcache"
class Usage(Exception):
def __init__(self, msg):
return None
def get_netdev_by_mac(mac):
- maybe = None
for device in os.listdir("/sys/class/net"):
- dev_mac = get_netdev_by_mac(device)
- if dev_mac and mac.lower() == dev_mac.lower():
- if get_netdev_tx_queue_len(device):
+ dev_mac = get_netdev_mac(device)
+ if (dev_mac and mac.lower() == dev_mac.lower() and
+ get_netdev_tx_queue_len(device)):
return device
- if not maybe:
- # Probably a datapath internal port.
- maybe = device
- return maybe
+ return None
+
+#
+# Helper functions for encoding/decoding database attributes to/from XML.
+#
+def str_to_xml(xml, parent, tag, val):
+ e = xml.createElement(tag)
+ parent.appendChild(e)
+ v = xml.createTextNode(val)
+ e.appendChild(v)
+def str_from_xml(n):
+ def getText(nodelist):
+ rc = ""
+ for node in nodelist:
+ if node.nodeType == node.TEXT_NODE:
+ rc = rc + node.data
+ return rc
+ return getText(n.childNodes).strip()
+
+
+def bool_to_xml(xml, parent, tag, val):
+ if val:
+ str_to_xml(xml, parent, tag, "True")
+ else:
+ str_to_xml(xml, parent, tag, "False")
+def bool_from_xml(n):
+ s = str_from_xml(n)
+ if s == "True":
+ return True
+ elif s == "False":
+ return False
+ else:
+ raise Error("Unknown boolean value %s" % s);
+
+def strlist_to_xml(xml, parent, ltag, itag, val):
+ e = xml.createElement(ltag)
+ parent.appendChild(e)
+ for v in val:
+ c = xml.createElement(itag)
+ e.appendChild(c)
+ cv = xml.createTextNode(v)
+ c.appendChild(cv)
+def strlist_from_xml(n, ltag, itag):
+ ret = []
+ for n in n.childNodes:
+ if n.nodeName == 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)
+ 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):
+ ret = {}
+ for n in n.childNodes:
+ if n.nodeName in attrs:
+ ret[n.nodeName] = str_from_xml(n)
+ return ret
+
+#
+# Definitions of the database objects (and their attributes) used by interface-reconfigure.
+#
+# Each object is defined by a dictionary mapping an attribute name in
+# the xapi database to a tuple containing two items:
+# - a function which takes this attribute and encodes it as XML.
+# - a function which takes XML and decocdes it into a value.
+#
+# other-config attributes are specified as a simple array of strings
+
+PIF_XML_TAG = "pif"
+VLAN_XML_TAG = "vlan"
+BOND_XML_TAG = "bond"
+NETWORK_XML_TAG = "network"
+
+ETHTOOL_OTHERCONFIG_ATTRS = ['ethtool-%s' % x for x in 'autoneg', 'speed', 'duplex', 'rx', 'tx', 'sg', 'tso', 'ufo', 'gso' ]
+
+PIF_ATTRS = { 'uuid': (str_to_xml,str_from_xml),
+ 'management': (bool_to_xml,bool_from_xml),
+ 'network': (str_to_xml,str_from_xml),
+ 'device': (str_to_xml,str_from_xml),
+ 'bond_master_of': (lambda x, p, t, v: strlist_to_xml(x, p, 'bond_master_of', 'slave', v),
+ lambda n: strlist_from_xml(n, 'bond_master_of', 'slave')),
+ 'bond_slave_of': (str_to_xml,str_from_xml),
+ 'VLAN': (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')),
+ 'ip_configuration_mode': (str_to_xml,str_from_xml),
+ 'IP': (str_to_xml,str_from_xml),
+ 'netmask': (str_to_xml,str_from_xml),
+ 'gateway': (str_to_xml,str_from_xml),
+ 'DNS': (str_to_xml,str_from_xml),
+ 'MAC': (str_to_xml,str_from_xml),
+ 'other_config': (lambda x, p, t, v: otherconfig_to_xml(x, p, v, PIF_OTHERCONFIG_ATTRS),
+ lambda n: otherconfig_from_xml(n, PIF_OTHERCONFIG_ATTRS)),
+
+ # Special case: We write the current value
+ # PIF.currently-attached to the cache but since it will
+ # not be valid when we come to use the cache later
+ # (i.e. after a reboot) we always read it as False.
+ 'currently_attached': (bool_to_xml, lambda n: False),
+ }
+
+PIF_OTHERCONFIG_ATTRS = [ 'domain', 'peerdns', 'defaultroute', 'mtu', 'static-routes' ] + \
+ [ 'bond-%s' % x for x in 'mode', 'miimon', 'downdelay', 'updelay', 'use_carrier' ] + \
+ ETHTOOL_OTHERCONFIG_ATTRS
+
+VLAN_ATTRS = { 'uuid': (str_to_xml,str_from_xml),
+ 'tagged_PIF': (str_to_xml,str_from_xml),
+ 'untagged_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),
+ lambda n: strlist_from_xml(n, 'slaves', 'slave')),
+ }
+
+NETWORK_ATTRS = { 'uuid': (str_to_xml,str_from_xml),
+ 'bridge': (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),
+ lambda n: otherconfig_from_xml(n, NETWORK_OTHERCONFIG_ATTRS)),
+ }
+
+NETWORK_OTHERCONFIG_ATTRS = [ 'mtu', 'static-routes' ] + ETHTOOL_OTHERCONFIG_ATTRS
class DatabaseCache(object):
+ def __read_xensource_inventory(self):
+ filename = "/etc/xensource-inventory"
+ f = open(filename, "r")
+ lines = [x.strip("\n") for x in f.readlines()]
+ f.close()
+
+ defs = [ (l[:l.find("=")], l[(l.find("=") + 1):]) for l in lines ]
+ defs = [ (a, b.strip("'")) for (a,b) in defs ]
+
+ return dict(defs)
+ def __pif_on_host(self,pif):
+ return self.__pifs.has_key(pif)
+
+ def __get_pif_records_from_xapi(self, session, host):
+ self.__pifs = {}
+ for (p,rec) in session.xenapi.PIF.get_all_records().items():
+ if rec['host'] != host:
+ continue
+ self.__pifs[p] = {}
+ for f in PIF_ATTRS:
+ 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
+ self.__pifs[p]['other_config'][f] = rec['other_config'][f]
+
+ def __get_vlan_records_from_xapi(self, session):
+ self.__vlans = {}
+ for v in session.xenapi.VLAN.get_all():
+ rec = session.xenapi.VLAN.get_record(v)
+ if not self.__pif_on_host(rec['untagged_PIF']):
+ continue
+ self.__vlans[v] = {}
+ for f in VLAN_ATTRS:
+ self.__vlans[v][f] = rec[f]
+
+ def __get_bond_records_from_xapi(self, session):
+ self.__bonds = {}
+ for b in session.xenapi.Bond.get_all():
+ rec = session.xenapi.Bond.get_record(b)
+ if not self.__pif_on_host(rec['master']):
+ continue
+ self.__bonds[b] = {}
+ for f in BOND_ATTRS:
+ self.__bonds[b][f] = rec[f]
+
+ def __get_network_records_from_xapi(self, session):
+ self.__networks = {}
+ for n in session.xenapi.network.get_all():
+ rec = session.xenapi.network.get_record(n)
+ self.__networks[n] = {}
+ for f in NETWORK_ATTRS:
+ if f == "PIFs":
+ # drop PIFs on other hosts
+ self.__networks[n][f] = [p for p in rec[f] if self.__pif_on_host(p)]
+ else:
+ self.__networks[n][f] = rec[f]
+ self.__networks[n]['other_config'] = {}
+ for f in NETWORK_OTHERCONFIG_ATTRS:
+ if not rec['other_config'].has_key(f): continue
+ self.__networks[n]['other_config'][f] = rec['other_config'][f]
+
+ def __to_xml(self, xml, parent, key, ref, rec, attrs):
+ """Encode a database object as XML"""
+ e = xml.createElement(key)
+ parent.appendChild(e)
+ if ref:
+ e.setAttribute('ref', ref)
+
+ for n,v in rec.items():
+ if attrs.has_key(n):
+ h,_ = attrs[n]
+ h(xml, e, n, v)
+ else:
+ raise Error("Unknown attribute %s" % n)
+ def __from_xml(self, e, attrs):
+ """Decode a database object from XML"""
+ ref = e.attributes['ref'].value
+ rec = {}
+ for n in e.childNodes:
+ if n.nodeName in attrs:
+ _,h = attrs[n.nodeName]
+ rec[n.nodeName] = h(n)
+ return (ref,rec)
+
def __init__(self, session_ref=None, cache_file=None):
if session_ref and cache_file:
raise Error("can't specify session reference and cache file")
-
if cache_file == None:
session = XenAPI.xapi_local()
session._session = session_ref
try:
- self.__vlans = session.xenapi.VLAN.get_all_records()
- self.__bonds = session.xenapi.Bond.get_all_records()
- self.__pifs = session.xenapi.PIF.get_all_records()
- self.__networks = session.xenapi.network.get_all_records()
+
+ inventory = self.__read_xensource_inventory()
+ assert(inventory.has_key('INSTALLATION_UUID'))
+ log("host uuid is %s" % inventory['INSTALLATION_UUID'])
+
+ host = session.xenapi.host.get_by_uuid(inventory['INSTALLATION_UUID'])
+
+ self.__get_pif_records_from_xapi(session, host)
+
+ self.__get_vlan_records_from_xapi(session)
+ self.__get_bond_records_from_xapi(session)
+ self.__get_network_records_from_xapi(session)
finally:
if not session_ref:
session.xenapi.session.logout()
else:
log("Loading xapi database cache from %s" % cache_file)
- f = open(cache_file, 'r')
- members = pickle.load(f)
- self.extras = pickle.load(f)
- f.close()
- self.__vlans = members['vlans']
- self.__bonds = members['bonds']
- self.__pifs = members['pifs']
- self.__networks = members['networks']
+ xml = parseXML(cache_file)
+
+ self.__pifs = {}
+ self.__bonds = {}
+ self.__vlans = {}
+ self.__networks = {}
- def save(self, cache_file, extras):
+ assert(len(xml.childNodes) == 1)
+ toplevel = xml.childNodes[0]
+
+ assert(toplevel.nodeName == "xenserver-network-configuration")
+
+ for n in toplevel.childNodes:
+ if n.nodeName == "#text":
+ pass
+ elif n.nodeName == PIF_XML_TAG:
+ (ref,rec) = self.__from_xml(n, PIF_ATTRS)
+ self.__pifs[ref] = rec
+ elif n.nodeName == BOND_XML_TAG:
+ (ref,rec) = self.__from_xml(n, BOND_ATTRS)
+ self.__bonds[ref] = rec
+ elif n.nodeName == VLAN_XML_TAG:
+ (ref,rec) = self.__from_xml(n, VLAN_ATTRS)
+ self.__vlans[ref] = rec
+ elif n.nodeName == NETWORK_XML_TAG:
+ (ref,rec) = self.__from_xml(n, NETWORK_ATTRS)
+ self.__networks[ref] = rec
+ else:
+ raise Error("Unknown XML element %s" % n.nodeName)
+
+ def save(self, cache_file):
+
+ xml = getDOMImplementation().createDocument(
+ None, "xenserver-network-configuration", None)
+ for (ref,rec) in self.__pifs.items():
+ self.__to_xml(xml, xml.documentElement, PIF_XML_TAG, ref, rec, PIF_ATTRS)
+ for (ref,rec) in self.__bonds.items():
+ 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.__networks.items():
+ self.__to_xml(xml, xml.documentElement, NETWORK_XML_TAG, ref, rec,
+ NETWORK_ATTRS)
+
f = open(cache_file, 'w')
- pickle.dump({'vlans': self.__vlans,
- 'bonds': self.__bonds,
- 'pifs': self.__pifs,
- 'networks': self.__networks}, f)
- pickle.dump(extras, f)
+ f.write(xml.toprettyxml())
f.close()
def get_pif_by_uuid(self, uuid):
return pifs[0]
- def get_pifs_by_record(self, record):
- """record is partial pif record.
- Get the pif(s) whose record matches.
- """
- def match(pifrec):
- for key in record:
- if record[key] != pifrec[key]:
- return False
- return True
-
+ def get_pifs_by_device(self, device):
return map(lambda (ref,rec): ref,
- filter(lambda (ref,rec): match(rec),
+ filter(lambda (ref,rec): rec['device'] == device,
self.__pifs.items()))
- def get_pif_by_record(self, record):
- """record is partial pif record.
- Get the pif whose record matches.
- """
- pifs = self.get_pifs_by_record(record)
- if len(pifs) == 0:
- raise Error("No matching PIF \"%s\"" % str(record))
- elif len(pifs) > 1:
- raise Error("Multiple matching PIFs \"%s\"" % str(record))
-
- return pifs[0]
-
- def get_pif_by_bridge(self, host, bridge):
+ def get_pif_by_bridge(self, bridge):
networks = map(lambda (ref,rec): ref,
filter(lambda (ref,rec): rec['bridge'] == bridge,
self.__networks.items()))
nwrec = self.get_network_record(network)
for pif in nwrec['PIFs']:
pifrec = self.get_pif_record(pif)
- if pifrec['host'] != host:
- continue
if answer:
- raise Error("Multiple PIFs on %s for network %s" % (host, bridge))
+ raise Error("Multiple PIFs on host for network %s" % (bridge))
answer = pif
if not answer:
- raise Error("No PIF on %s for network %s" % (host, bridge))
+ raise Error("No PIF on host for network %s" % (bridge))
return answer
def get_pif_record(self, pif):
if self.__pifs.has_key(pif):
return self.__pifs[pif]
- raise Error("Unknown PIF \"%s\"" % pif)
+ raise Error("Unknown PIF \"%s\" (get_pif_record)" % pif)
def get_all_pifs(self):
return self.__pifs
def pif_exists(self, pif):
return self.__pifs.has_key(pif)
- def get_management_pif(self, host):
+ def get_management_pif(self):
""" Returns the management pif on host
"""
all = self.get_all_pifs()
for pif in all:
pifrec = self.get_pif_record(pif)
- if pifrec['management'] and pifrec['host'] == host :
- return pif
+ if pifrec['management']: return pif
return None
def get_network_record(self, network):
use it.)
"""
+
pifrec = db.get_pif_record(pif)
if pifrec['VLAN'] == '-1':
pifrec = db.get_pif_record(pif)
return bridge_name(pif)
-def physdev_pifs(pif):
+def get_physdev_pifs(pif):
"""Return the PIFs for the physical network device(s) associated with pif.
For a VLAN PIF, this is the VLAN slave's physical device PIF.
For a bond master PIF, these are the bond slave PIFs.
For a non-VLAN, non-bond master PIF, the PIF is its own physical device PIF.
"""
-
pifrec = db.get_pif_record(pif)
if pifrec['VLAN'] != '-1':
- return [get_vlan_slave_of_pif(pif)]
+ return get_physdev_pifs(get_vlan_slave_of_pif(pif))
elif len(pifrec['bond_master_of']) != 0:
return get_bond_slaves_of_pif(pif)
else:
return [pif]
-def physdev_names(pif):
+def get_physdev_names(pif):
"""Return the name(s) of the physical network device(s) associated with pif.
For a VLAN PIF, the physical devices are the VLAN slave's physical devices.
For a bond master PIF, the physical devices are the bond slaves.
For a non-VLAN, non-bond master PIF, the physical device is the PIF itself.
"""
- return [db.get_pif_record(phys)['device'] for phys in physdev_pifs(pif)]
+ return [db.get_pif_record(phys)['device'] for phys in get_physdev_pifs(pif)]
def log_pif_action(action, pif):
pifrec = db.get_pif_record(pif)
- pifrec['action'] = action
- pifrec['interface-name'] = interface_name(pif)
+ rec = {}
+ rec['uuid'] = pifrec['uuid']
+ rec['ip_configuration_mode'] = pifrec['ip_configuration_mode']
+ rec['action'] = action
+ rec['interface-name'] = interface_name(pif)
if action == "rewrite":
- pifrec['message'] = "Rewrite PIF %(uuid)s configuration" % pifrec
+ rec['message'] = "Rewrite PIF %(uuid)s configuration" % rec
else:
- pifrec['message'] = "Bring %(action)s PIF %(uuid)s" % pifrec
- log("%(message)s: %(interface-name)s configured as %(ip_configuration_mode)s" % pifrec)
+ rec['message'] = "Bring %(action)s PIF %(uuid)s" % rec
+ log("%(message)s: %(interface-name)s configured as %(ip_configuration_mode)s" % rec)
def get_bond_masters_of_pif(pif):
"""Returns a list of PIFs which are bond masters of this PIF"""
"""Returns a list of PIFs which make up the given bonded pif."""
pifrec = db.get_pif_record(pif)
- host = pifrec['host']
bmo = pifrec['bond_master_of']
if len(bmo) > 1:
we should bring down that master."""
pifrec = db.get_pif_record(pif)
- host = pifrec['host']
- pifs_on_host = [ __pif for __pif in db.get_all_pifs() if
- db.get_pif_record(__pif)['host'] == host and
+ pifs = [ __pif for __pif in db.get_all_pifs() if
(not __pif in get_bond_masters_of_pif(pif)) ]
peerdns_pif = None
# loop through all the pifs on this host looking for one with
# other-config:peerdns = true, and one with
# other-config:default-route=true
- for __pif in pifs_on_host:
+ for __pif in pifs:
__pifrec = db.get_pif_record(__pif)
__oc = __pifrec['other_config']
if __oc.has_key('peerdns') and __oc['peerdns'] == 'true':
return peerdns_pif, defaultroute_pif
-def ethtool_settings(oc):
- # Options for "ethtool -s"
+def run_ethtool(device, oc):
+ # Run "ethtool -s" if there are any settings.
settings = []
if oc.has_key('ethtool-speed'):
val = oc['ethtool-speed']
settings += ['autoneg', 'off']
else:
log("Invalid value for ethtool-autoneg = %s. Must be on|true|off|false." % val)
+ if settings:
+ run_command(['/sbin/ethtool', '-s', device] + settings)
- # Options for "ethtool -K"
+ # Run "ethtool -K" if there are any offload settings.
offload = []
for opt in ("rx", "tx", "sg", "tso", "ufo", "gso"):
if oc.has_key("ethtool-" + opt):
offload += [opt, 'off']
else:
log("Invalid value for ethtool-%s = %s. Must be on|true|off|false." % (opt, val))
+ if offload:
+ run_command(['/sbin/ethtool', '-K', device] + offload)
- return settings, offload
+def mtu_setting(oc):
+ if oc.has_key('mtu'):
+ try:
+ int(oc['mtu']) # Check that the value is an integer
+ return ['mtu', oc['mtu']]
+ except ValueError, x:
+ log("Invalid value for mtu = %s" % mtu)
+ return []
-def configure_netdev(pif):
+def configure_local_port(pif):
pifrec = db.get_pif_record(pif)
datapath = datapath_name(pif)
ipdev = ipdev_name(pif)
- host = pifrec['host']
nw = pifrec['network']
nwrec = db.get_network_record(nw)
+ pif_oc = pifrec['other_config']
+ nw_oc = nwrec['other_config']
+
+ # IP (except DHCP) and MTU.
ifconfig_argv = ['/sbin/ifconfig', ipdev, 'up']
gateway = ''
if pifrec['ip_configuration_mode'] == "DHCP":
pass
else:
raise Error("Unknown IP-configuration-mode %s" % pifrec['ip_configuration_mode'])
-
- oc = pifrec['other_config']
- if oc.has_key('mtu'):
- try:
- int(oc['mtu']) # Check that the value is an integer
- ifconfig_argv += ['mtu', oc['mtu']]
- except ValueError, x:
- log("Invalid value for mtu = %s" % mtu)
-
+ ifconfig_argv += mtu_setting(nw_oc)
run_command(ifconfig_argv)
(peerdns_pif, defaultroute_pif) = find_distinguished_pifs(pif)
+ # /etc/resolv.conf
if peerdns_pif == pif:
f = ConfigurationFile('resolv.conf', "/etc")
- if oc.has_key('domain'):
- f.write("search %s\n" % oc['domain'])
+ if pif_oc.has_key('domain'):
+ f.write("search %s\n" % pif_oc['domain'])
for dns in pifrec['DNS'].split(","):
f.write("nameserver %s\n" % dns)
f.close()
f.apply()
f.commit()
+ # Routing.
if defaultroute_pif == pif and gateway != '':
run_command(['/sbin/ip', 'route', 'replace', 'default',
'via', gateway, 'dev', ipdev])
-
- if oc.has_key('static-routes'):
- for line in oc['static-routes'].split(','):
+ if nw_oc.has_key('static-routes'):
+ for line in nw_oc['static-routes'].split(','):
network, masklen, gateway = line.split('/')
run_command(['/sbin/ip', 'route', 'add',
- '%s/%s' % (netmask, masklen), 'via', gateway,
+ '%s/%s' % (network, masklen), 'via', gateway,
'dev', ipdev])
- settings, offload = ethtool_settings(oc)
- if settings:
- run_command(['/sbin/ethtool', '-s', ipdev] + settings)
- if offload:
- run_command(['/sbin/ethtool', '-K', ipdev] + offload)
+ # Ethtool.
+ run_ethtool(ipdev, nw_oc)
+ # DHCP.
if pifrec['ip_configuration_mode'] == "DHCP":
print
print "Determining IP information for %s..." % ipdev,
else:
print 'failed.'
+def configure_physdev(pif):
+ pifrec = db.get_pif_record(pif)
+ device = pifrec['device']
+ oc = pifrec['other_config']
+
+ run_command(['/sbin/ifconfig', device, 'up'] + mtu_setting(oc))
+ run_ethtool(device, oc)
+
def modify_config(commands):
run_command(['/root/vswitch/bin/ovs-cfg-mod', '-vANY:console:emer',
'-F', '/etc/ovs-vswitchd.conf']
interface = interface_name(pif)
ipdev = ipdev_name(pif)
datapath = datapath_name(pif)
- physdevs = physdev_names(pif)
+ physdev_names = get_physdev_names(pif)
argv = ['--del-match=bonding.%s.[!0-9]*' % interface]
argv += ["--add=bonding.%s.slave=%s" % (interface, slave)
- for slave in physdevs]
+ for slave in physdev_names]
+ argv += ['--add=bonding.%s.fake-iface=true' % interface]
if pifrec['MAC'] != "":
argv += ['--add=port.%s.mac=%s' % (interface, pifrec['MAC'])]
interface = interface_name(pif)
ipdev = ipdev_name(pif)
datapath = datapath_name(pif)
- physdevs = physdev_names(pif)
+ physdev_pifs = get_physdev_pifs(pif)
+ physdev_names = get_physdev_names(pif)
vlan_slave = None
if pifrec['VLAN'] != '-1':
vlan_slave = get_vlan_slave_of_pif(pif)
# /etc/xensource/scripts/vif needs to know where to add VIFs.
if vlan_slave:
- if not os.path.exists(vswitch_config_dir):
- os.mkdir(vswitch_config_dir)
- br = ConfigurationFile("br-%s" % bridge, vswitch_config_dir)
+ if not os.path.exists(vswitch_state_dir):
+ os.mkdir(vswitch_state_dir)
+ br = ConfigurationFile("br-%s" % bridge, vswitch_state_dir)
br.write("VLAN_SLAVE=%s\n" % datapath)
br.write("VLAN_VID=%s\n" % pifrec['VLAN'])
br.close()
# Check the MAC address of each network device and remap if
# necessary to make names match our expectations.
- for physdev_pif in physdev_pifs(pif):
+ for physdev_pif in physdev_pifs:
remap_pif(physdev_pif)
# "ifconfig down" the network device and delete its IP address, etc.
down_netdev(ipdev)
- for physdev in physdevs:
- down_netdev(physdev)
+ for physdev_name in physdev_names:
+ down_netdev(physdev_name)
# If we are bringing up a bond, remove IP addresses from the
# slaves (because we are implicitly being asked to take them down).
run_command(["/sbin/ifconfig", ipdev_name(bond_pif), '0.0.0.0'])
# Remove all keys related to pif and any bond masters linked to PIF.
- del_ports = [ipdev] + physdevs + bond_masters
+ del_ports = [ipdev] + physdev_names + bond_masters
if vlan_slave and bond_master:
del_ports += [interface_name(bond_master)]
# port.
add_ports = [ipdev, datapath]
if not bond_master:
- add_ports += physdevs
+ add_ports += physdev_names
else:
add_ports += [interface_name(bond_master)]
# - The bond masters for pif. (Ordinarily pif shouldn't have any
# bond masters. If it does then interface-reconfigure is
# implicitly being asked to take them down.)
- del_ports = add_ports + physdevs + bond_masters
+ del_ports = add_ports + physdev_names + bond_masters
# What networks does this datapath carry?
#
# - The networks corresponding to any VLANs attached to the
# datapath's PIF.
network_uuids = []
- for nwpif in db.get_pifs_by_record({'device': pifrec['device'],
- 'host': pifrec['host']}):
+ for nwpif in db.get_pifs_by_device({'device': pifrec['device']}):
net = db.get_pif_record(nwpif)['network']
network_uuids += [db.get_network_record(net)['uuid']]
# enables or disables bond slaves based on whether carrier is
# detected when they are added, and a network device that is down
# always reports "no carrier".
- bond_slave_physdevs = []
+ bond_slave_physdev_pifs = []
for slave in bond_slaves:
- bond_slave_physdevs += physdev_names(slave)
- for slave_physdev in bond_slave_physdevs:
- up_netdev(slave_physdev)
+ bond_slave_physdev_pifs += get_physdev_pifs(slave)
+ for slave_physdev_pif in set(bond_slave_physdev_pifs):
+ configure_physdev(slave_physdev_pif)
# Now modify the ovs-vswitchd config file.
argv = []
argv += ['--add=iface.%s.fake-bridge=true' % (ipdev)]
else:
try:
- os.unlink("%s/br-%s" % (vswitch_config_dir, bridge))
+ os.unlink("%s/br-%s" % (vswitch_state_dir, bridge))
except OSError:
pass
argv += ['--del-match=bridge.%s.xs-network-uuids=*' % datapath]
argv += configure_bond(bond_master)
modify_config(argv)
- # Configure network devices.
- configure_netdev(pif)
-
# Bring up VLAN slave, plus physical devices other than bond
# slaves (which we brought up earlier).
if vlan_slave:
up_netdev(ipdev_name(vlan_slave))
- for physdev in set(physdevs) - set(bond_slave_physdevs):
- up_netdev(physdev)
+ for physdev_pif in set(physdev_pifs) - set(bond_slave_physdev_pifs):
+ configure_physdev(physdev_pif)
+
+ # Configure network device for local port.
+ configure_local_port(pif)
# Update /etc/issue (which contains the IP address of the management interface)
os.system("/sbin/update-issue")
action_force_rewrite(force_interface, force_rewrite_config)
else:
db = DatabaseCache(cache_file=dbcache_file)
- host = db.extras['host']
- pif = db.get_pif_by_bridge(host, force_interface)
- management_pif = db.get_management_pif(host)
+ pif = db.get_pif_by_bridge(force_interface)
+ management_pif = db.get_management_pif()
if action == "up":
action_up(pif)
# pif is not going to be the management pif.
# Search DB cache for pif on same host with management=true
pifrec = db.get_pif_record(pif)
- host = pifrec['host']
- management_pif = db.get_management_pif(host)
+ management_pif = db.get_management_pif()
log_pif_action(action, pif)
# Save cache.
pifrec = db.get_pif_record(pif)
- db.save(dbcache_file, {'host': pifrec['host']})
+ db.save(dbcache_file)
except Usage, err:
print >>sys.stderr, err.msg
"""
pifrec = db.get_pif_record(pif)
- host = pifrec['host']
nw = pifrec['network']
nwrec = db.get_network_record(nw)
oc = None
# This is because when we are called to bring up an interface with a bond master, it is implicit that
# we should bring down that master.
pifs_on_host = [ __pif for __pif in db.get_all_pifs() if
- db.get_pif_record(__pif)['host'] == host and
- (not __pif in get_bond_masters_of_pif(pif)) ]
+ not __pif in get_bond_masters_of_pif(pif) ]
other_pifs_on_host = [ __pif for __pif in pifs_on_host if __pif != pif ]
peerdns_pif = None