pciif.py

来自「xen虚拟机源代码安装包」· Python 代码 · 共 567 行 · 第 1/2 页

PY
567
字号
#============================================================================# 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) 2004, 2005 Mike Wray <mike.wray@hp.com># Copyright (C) 2005 XenSource Ltd#============================================================================import typesimport timefrom xen.xend import sxpfrom xen.xend import archfrom xen.xend.XendError import VmErrorfrom xen.xend.XendLogging import logfrom xen.xend.server.DevController import DevController, xenbusStateimport xen.lowlevel.xcfrom xen.util.pci import *import resourceimport refrom xen.xend.server.pciquirk import *xc = xen.lowlevel.xc.xc()#Calculate PAGE_SHIFT: number of bits to shift an address to get the page numberPAGE_SIZE = resource.getpagesize()PAGE_SHIFT = 0t = PAGE_SIZEwhile not (t&1):    t>>=1    PAGE_SHIFT+=1def parse_hex(val):    try:        if isinstance(val, types.StringTypes):            return int(val, 16)        else:            return val    except ValueError:        return Noneclass PciController(DevController):    def __init__(self, vm):        DevController.__init__(self, vm)    def getDeviceDetails(self, config):        """@see DevController.getDeviceDetails"""        back = {}        pcidevid = 0        vslots = ""        for pci_config in config.get('devs', []):            domain = parse_hex(pci_config.get('domain', 0))            bus = parse_hex(pci_config.get('bus', 0))            slot = parse_hex(pci_config.get('slot', 0))            func = parse_hex(pci_config.get('func', 0))                        vslt = pci_config.get('vslt')            if vslt is not None:                vslots = vslots + vslt + ";"            back['dev-%i' % pcidevid] = "%04x:%02x:%02x.%01x" % \                                        (domain, bus, slot, func)            back['uuid-%i' % pcidevid] = pci_config.get('uuid', '')            pcidevid += 1        if vslots != "":            back['vslots'] = vslots        back['num_devs']=str(pcidevid)        back['uuid'] = config.get('uuid','')        return (0, back, {})    def reconfigureDevice(self, _, config):        """@see DevController.reconfigureDevice"""        (devid, back, front) = self.getDeviceDetails(config)        num_devs = int(back['num_devs'])        states = config.get('states', [])        old_vslots = self.readBackend(devid, 'vslots')        if old_vslots is None:            old_vslots = ''        num_olddevs = int(self.readBackend(devid, 'num_devs'))        for i in range(num_devs):            try:                dev = back['dev-%i' % i]                state = states[i]                uuid = back['uuid-%i' %i]            except:                raise XendError('Error reading config')            if state == 'Initialising':                # PCI device attachment                for j in range(num_olddevs):                    if dev == self.readBackend(devid, 'dev-%i' % j):                        raise XendError('Device %s is already connected.' % dev)                log.debug('Attaching PCI device %s.' % dev)                (domain, bus, slotfunc) = dev.split(':')                (slot, func) = slotfunc.split('.')                domain = parse_hex(domain)                bus = parse_hex(bus)                slot = parse_hex(slot)                func = parse_hex(func)                self.setupOneDevice(domain, bus, slot, func)                self.writeBackend(devid, 'dev-%i' % (num_olddevs + i), dev)                self.writeBackend(devid, 'state-%i' % (num_olddevs + i),                                  str(xenbusState['Initialising']))                self.writeBackend(devid, 'uuid-%i' % (num_olddevs + i), uuid)                self.writeBackend(devid, 'num_devs', str(num_olddevs + i + 1))                # Update vslots                if back['vslots'] is not None:                    vslots = old_vslots + back['vslots']                    self.writeBackend(devid, 'vslots', vslots)            elif state == 'Closing':                # PCI device detachment                found = False                for j in range(num_olddevs):                    if dev == self.readBackend(devid, 'dev-%i' % j):                        found = True                        log.debug('Detaching device %s' % dev)                        self.writeBackend(devid, 'state-%i' % j,                                          str(xenbusState['Closing']))                if not found:                    raise XendError('Device %s is not connected' % dev)                # Update vslots                if back.get('vslots') is not None:                    vslots = old_vslots                    for vslt in back['vslots'].split(';'):                        if vslt != '':                            vslots = vslots.replace(vslt + ';', '', 1)                    if vslots == '':                        self.removeBackend(devid, 'vslots')                    else:                        self.writeBackend(devid, 'vslots', vslots)            else:                raise XendError('Error configuring device %s: invalid state %s'                                % (dev,state))        self.writeBackend(devid, 'state', str(xenbusState['Reconfiguring']))        return self.readBackend(devid, 'uuid')    def getDeviceConfiguration(self, devid, transaction = None):        result = DevController.getDeviceConfiguration(self, devid, transaction)        num_devs = self.readBackend(devid, 'num_devs')        pci_devs = []                vslots = self.readBackend(devid, 'vslots')        if vslots is not None:            if vslots[-1] == ";":                vslots = vslots[:-1]            slot_list = vslots.split(';')        for i in range(int(num_devs)):            dev_config = self.readBackend(devid, 'dev-%d' % i)            pci_match = re.match(r"((?P<domain>[0-9a-fA-F]{1,4})[:,])?" +                                 r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" +                                  r"(?P<slot>[0-9a-fA-F]{1,2})[.,]" +                                  r"(?P<func>[0-7]{1,2})$", dev_config)                        if pci_match!=None:                pci_dev_info = pci_match.groupdict()                dev_dict = {'domain': '0x%(domain)s' % pci_dev_info,                                 'bus': '0x%(bus)s' % pci_dev_info,                                 'slot': '0x%(slot)s' % pci_dev_info,                                 'func': '0x%(func)s' % pci_dev_info}                # Per device uuid info                dev_dict['uuid'] = self.readBackend(devid, 'uuid-%d' % i)                #append vslot info                if vslots is not None:                    try:                        dev_dict['vslt'] = slot_list[i]                    except IndexError:                        dev_dict['vslt'] = '0x0'                pci_devs.append(dev_dict)        result['devs'] = pci_devs        result['uuid'] = self.readBackend(devid, 'uuid')        return result    def configuration(self, devid, transaction = None):        """Returns SXPR for devices on domain.        @note: we treat this dict especially to convert to        SXP because it is not a straight dict of strings."""                configDict = self.getDeviceConfiguration(devid, transaction)        sxpr = [self.deviceClass]        # remove devs        devs = configDict.pop('devs', [])                for dev in devs:            dev_sxpr = ['dev']            for dev_item in dev.items():                dev_sxpr.append(list(dev_item))            sxpr.append(dev_sxpr)                for key, val in configDict.items():            if type(val) == type(list()):                for v in val:                    sxpr.append([key, v])            else:                sxpr.append([key, val])        return sxpr        def CheckSiblingDevices(self, domid, dev):        """ Check if all sibling devices of dev are owned by pciback        """        if not self.vm.info.is_hvm():            return        group_str = xc.get_device_group(domid, dev.domain, dev.bus, dev.slot, dev.func)        if group_str == "":            return        #group string format xx:xx.x,xx:xx.x,        devstr_len = group_str.find(',')        for i in range(0, len(group_str), devstr_len + 1):            (bus, slotfunc) = group_str[i:i + devstr_len].split(':')            (slot, func) = slotfunc.split('.')            b = parse_hex(bus)            d = parse_hex(slot)            f = parse_hex(func)            try:                sdev = PciDevice(dev.domain, b, d, f)            except Exception, e:                #no dom0 drivers bound to sdev                continue            if sdev.driver!='pciback':                raise VmError(("pci: PCI Backend does not own\n "+ \                    "sibling device %s of device %s\n"+ \                    "See the pciback.hide kernel "+ \                    "command-line parameter or\n"+ \                    "bind your slot/device to the PCI backend using sysfs" \                    )%(sdev.name, dev.name))        return    def setupOneDevice(self, domain, bus, slot, func):        """ Attach I/O resources for device to frontend domain        """        fe_domid = self.getDomid()        try:            dev = PciDevice(domain, bus, slot, func)        except Exception, e:            raise VmError("pci: failed to locate device and "+                    "parse it's resources - "+str(e))        if dev.driver!='pciback':            raise VmError(("pci: PCI Backend does not own device "+ \                    "%s\n"+ \                    "See the pciback.hide kernel "+ \                    "command-line parameter or\n"+ \

⌨️ 快捷键说明

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