⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xendpif.py

📁 xen虚拟机源代码安装包
💻 PY
字号:
#============================================================================# This library is free software; you can redistribute it and/or# modify it under the terms of version 2.1 of the GNU Lesser General Public# License as published by the Free Software Foundation.## This library is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU# Lesser General Public License for more details.## You should have received a copy of the GNU Lesser General Public# License along with this library; if not, write to the Free Software# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA#============================================================================# Copyright (c) 2006 Xensource Inc.#============================================================================import commandsimport loggingimport osimport refrom xen.xend import uuid as genuuidfrom xen.xend import XendAPIStorefrom xen.xend.XendBase import XendBasefrom xen.xend.XendPIFMetrics import XendPIFMetricsfrom xen.xend.XendError import *from xen.xend import Vifctllog = logging.getLogger("xend.XendPIF")log.setLevel(logging.TRACE)MAC_RE = re.compile(':'.join(['[0-9a-f]{2}'] * 6))IP_IFACE_RE = re.compile(r'^\d+: (\w+):.*mtu (\d+) .* link/\w+ ([0-9a-f:]+)')Vifctl.network('start')def linux_phy_to_virt(pif_name):    return 'eth' + re.sub(r'^[a-z]+', '', pif_name)def linux_get_phy_ifaces():    """Returns a list of physical interfaces.    Identifies PIFs as those that have a interface name starting with    'peth'.    See /etc/xen/scripts/network-bridge for how the devices are renamed.    @rtype: array of 3-element tuple (name, mtu, mac)    """        ip_cmd = 'ip -o link show'    rc, output = commands.getstatusoutput(ip_cmd)    ifaces = {}    phy_ifaces = []    if rc == 0:        # parse all interfaces into (name, mtu, mac)        for line in output.split('\n'):            has_if = re.search(IP_IFACE_RE, line)            if has_if:                ifaces[has_if.group(1)] = has_if.groups()                        # resolve pifs' mac addresses        for name, mtu, mac in ifaces.values():            if name.startswith('peth'):                bridged_ifname = linux_phy_to_virt(name)                bridged_if = ifaces.get(bridged_ifname)                bridged_mac = ''                if bridged_if:                    bridged_mac = bridged_if[2]                phy_ifaces.append((name, int(mtu), bridged_mac))                    return phy_ifacesdef linux_set_mac(iface, mac):    if not re.search(MAC_RE, mac):        return False    ip_mac_cmd = 'ip link set %s addr %s' % \                 (linux_phy_to_virt(iface), mac)    rc, output = commands.getstatusoutput(ip_mac_cmd)    if rc == 0:        return True    return Falsedef linux_set_mtu(iface, mtu):    try:        ip_mtu_cmd = 'ip link set %s mtu %d' % \                     (linux_phy_to_virt(iface), int(mtu))        rc, output = commands.getstatusoutput(ip_mtu_cmd)        if rc == 0:            return True        return False    except ValueError:        return Falsedef linux_get_mtu(device):    return _linux_get_pif_param(device, 'mtu')def linux_get_mac(device):    return _linux_get_pif_param(device, 'link/ether')def _linux_get_pif_param(device, param_name):    ip_get_dev_data = 'ip link show %s' % device    rc, output = commands.getstatusoutput(ip_get_dev_data)    if rc == 0:        params = output.split(' ')        for i in xrange(len(params)):            if params[i] == param_name:                return params[i+1]    return ''def _create_VLAN(dev, vlan):    rc, _ = commands.getstatusoutput('vconfig add %s %d' %                                     (dev, vlan))    if rc != 0:        return False    rc, _ = commands.getstatusoutput('ifconfig %s.%d up' %                                     (dev, vlan))    return rc == 0def _destroy_VLAN(dev, vlan):    rc, _ = commands.getstatusoutput('ifconfig %s.%d down' %                                     (dev, vlan))    if rc != 0:        return False                                         rc, _ = commands.getstatusoutput('vconfig rem %s.%d' %                                     (dev, vlan))    return rc == 0class XendPIF(XendBase):    """Representation of a Physical Network Interface."""    def getClass(self):        return "PIF"    def getAttrRO(self):        attrRO = ['network',                  'host',                  'metrics',                  'device',                  'VLAN']        return XendBase.getAttrRO() + attrRO        def getAttrRW(self):        attrRW = ['MAC',                  'MTU']        return XendBase.getAttrRW() + attrRW    def getAttrInst(self):        attrInst = ['network',                    'device',                    'MAC',                    'MTU',                    'VLAN']        return attrInst    def getMethods(self):        methods = ['plug',                   'unplug',                   'destroy']        return XendBase.getMethods() + methods    def getFuncs(self):        funcs = ['create_VLAN']        return XendBase.getFuncs() + funcs    getClass    = classmethod(getClass)    getAttrRO   = classmethod(getAttrRO)    getAttrRW   = classmethod(getAttrRW)    getAttrInst = classmethod(getAttrInst)    getMethods  = classmethod(getMethods)    getFuncs    = classmethod(getFuncs)        def create_phy(self, network_uuid, device,                   MAC, MTU):        """        Called when a new physical PIF is found        Could be a VLAN...        """        # Create new uuids        pif_uuid = genuuid.createString()        metrics_uuid = genuuid.createString()        # Create instances        metrics = XendPIFMetrics(metrics_uuid, pif_uuid)        # Is this a VLAN?        VLANdot = device.split(".")        VLANcolon = device.split(":")        if len(VLANdot) > 1:            VLAN = VLANdot[1]            device = VLANdot[0]        elif len(VLANcolon) > 1:            VLAN = VLANcolon[1]            device = VLANcolon[0]         else:            VLAN = -1                    record = {            'network': network_uuid,            'device':  device,            'MAC':     MAC,            'MTU':     MTU,            'VLAN':    VLAN            }        pif = XendPIF(record, pif_uuid, metrics_uuid)        return pif_uuid    def recreate(self, record, uuid):        """Called on xend start / restart"""                pif_uuid = uuid        metrics_uuid = record['metrics']        # Create instances        metrics = XendPIFMetrics(metrics_uuid, pif_uuid)        pif = XendPIF(record, pif_uuid, metrics_uuid)        # If physical PIF, check exists        # If VLAN, create if not exist        ifs = [dev for dev, _1, _2 in linux_get_phy_ifaces()]        if pif.get_VLAN() == -1:            if pif.get_device() not in ifs:                XendBase.destroy(pif)                metrics.destroy()                return None        else:            if pif.get_interface_name() not in ifs:                _create_VLAN(pif.get_device(), pif.get_VLAN())                pif.plug()        return pif_uuid    def create_VLAN(self, device, network_uuid, host_ref, vlan):        """Exposed via API - create a new VLAN from existing VIF"""                ifs = [name for name, _, _ in linux_get_phy_ifaces()]        vlan = int(vlan)        # Check VLAN tag is valid        if vlan < 0 or vlan >= 4096:            raise VLANTagInvalid(vlan)                # Check device exists        if device not in ifs:            raise InvalidDeviceError(device)        # Check VLAN doesn't already exist        if "%s.%d" % (device, vlan) in ifs:            raise DeviceExistsError("%s.%d" % (device, vlan))        # Check network ref is valid        from XendNetwork import XendNetwork        if network_uuid not in XendNetwork.get_all():            raise InvalidHandleError("Network", network_uuid)        # Check host_ref is this host        import XendNode        if host_ref != XendNode.instance().get_uuid():            raise InvalidHandleError("Host", host_ref)        # Create the VLAN        _create_VLAN(device, vlan)        # Create new uuids        pif_uuid = genuuid.createString()        metrics_uuid = genuuid.createString()        # Create the record        record = {            "device":  device,            "MAC":     linux_get_mac('%s.%d' % (device, vlan)),            "MTU":     linux_get_mtu('%s.%d' % (device, vlan)),            "network": network_uuid,            "VLAN":    vlan            }        # Create instances        metrics = XendPIFMetrics(metrics_uuid, pif_uuid)        pif = XendPIF(record, pif_uuid, metrics_uuid)        # Not sure if they should be created plugged or not...        pif.plug()        XendNode.instance().save_PIFs()        return pif_uuid    create_phy  = classmethod(create_phy)    recreate    = classmethod(recreate)    create_VLAN = classmethod(create_VLAN)        def __init__(self, record, uuid, metrics_uuid):        XendBase.__init__(self, uuid, record)        self.metrics = metrics_uuid    def plug(self):        """Plug the PIF into the network"""        network = XendAPIStore.get(self.network,                                   "network")        bridge_name = network.get_name_label()        from xen.util import Brctl        Brctl.vif_bridge_add({            "bridge": bridge_name,            "vif":    self.get_interface_name()            })    def unplug(self):        """Unplug the PIF from the network"""        network = XendAPIStore.get(self.network,                                   "network")        bridge_name = network.get_name_label()        from xen.util import Brctl        Brctl.vif_bridge_rem({            "bridge": bridge_name,            "vif":    self.get_interface_name()            })    def destroy(self):        # Figure out if this is a physical device        if self.get_interface_name() == \           self.get_device():            raise PIFIsPhysical()        self.unplug()        if _destroy_VLAN(self.get_device(), self.get_VLAN()):            XendBase.destroy(self)            import XendNode            XendNode.instance().save_PIFs()        else:            raise NetworkError("Unable to delete VLAN", self.get_uuid())    def get_interface_name(self):        if self.get_VLAN() == -1:            return self.get_device()        else:            return "%s.%d" % (self.get_device(), self.get_VLAN())            def get_device(self):        """        This is the base interface.        For phy if (VLAN == -1) this is same as        if name.        For VLANs, this it the bit before the period        """        return self.device    def get_network(self):        return self.network    def get_host(self):        from xen.xend import XendNode        return XendNode.instance().get_uuid()    def get_metrics(self):        return self.metrics    def get_MAC(self):        return self.MAC    def set_MAC(self, new_mac):        success = linux_set_mac(self.device, new_mac)        if success:            self.MAC = new_mac            import XendNode            XendNode.instance().save_PIFs()        return success    def get_MTU(self):        return self.MTU    def set_MTU(self, new_mtu):        success = linux_set_mtu(self.device, new_mtu)        if success:            self.MTU = new_mtu            import XendNode            XendNode.instance().save_PIFs()        return success    def get_VLAN(self):        return self.VLAN

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -