blkif.py

来自「xen虚拟机源代码安装包」· Python 代码 · 共 209 行

PY
209
字号
#============================================================================# 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, 2006 XenSource Inc.#============================================================================import reimport stringfrom xen.util import blkifimport xen.util.xsm.xsm as securityfrom xen.xend.XendError import VmErrorfrom xen.xend.server.DevController import DevControllerfrom xen.util import xsconstantsclass BlkifController(DevController):    """Block device interface controller. Handles all block devices    for a domain.    """    def __init__(self, vm):        """Create a block device controller.        """        DevController.__init__(self, vm)    def getDeviceDetails(self, config):        """@see DevController.getDeviceDetails"""        uname = config.get('uname', '')        dev = config.get('dev', '')                if 'ioemu:' in dev:            (_, dev) = string.split(dev, ':', 1)        try:            (dev, dev_type) = string.split(dev, ':', 1)        except ValueError:            dev_type = "disk"        if not uname:            if dev_type == 'cdrom':                (typ, params) = ("", "")            else:                raise VmError(                    'Block device must have physical details specified')        else:            try:                (typ, params) = string.split(uname, ':', 1)                if typ not in ('phy', 'file', 'tap'):                    raise VmError(                        'Block device must have "phy", "file" or "tap" '                        'specified to type')            except ValueError:                raise VmError(                    'Block device must have physical details specified')        mode = config.get('mode', 'r')        if mode not in ('r', 'w', 'w!'):            raise VmError('Invalid mode')        back = {'dev'    : dev,                'type'   : typ,                'params' : params,                'mode'   : mode,                }        uuid = config.get('uuid')        if uuid:            back['uuid'] = uuid        if security.on() == xsconstants.XS_POLICY_ACM:            self.do_access_control(config, uname)        (device_path, devid) = blkif.blkdev_name_to_number(dev)        if devid is None:            raise VmError('Unable to find number for device (%s)' % (dev))        front = { device_path : "%i" % devid,                  'device-type' : dev_type                }        protocol = config.get('protocol')        if protocol:            front['protocol'] = protocol        return (devid, back, front)    def do_access_control(self, config, uname):        (label, ssidref, policy) = \                             security.get_res_security_details(uname)        domain_label = self.vm.get_security_label()        if domain_label:            rc = security.res_security_check_xapi(label, ssidref, policy,                                                  domain_label)            if rc == 0:                raise VmError("VM's access to block device '%s' denied" %                              uname)        else:            from xen.util.acmpolicy import ACM_LABEL_UNLABELED            if label != ACM_LABEL_UNLABELED:                raise VmError("VM must have a security label to access "                              "block device '%s'" % uname)    def reconfigureDevice(self, _, config):        """@see DevController.reconfigureDevice"""        (devid, new_back, new_front) = self.getDeviceDetails(config)        (dev, mode) = self.readBackend(devid, 'dev', 'mode')        dev_type = self.readFrontend(devid, 'device-type')        if (dev_type == 'cdrom' and new_front['device-type'] == 'cdrom' and            dev == new_back['dev'] and mode == 'r'):            # dummy device            self.writeBackend(devid,                              'type', new_back['type'],                              'params', '')            # new backend-device            self.writeBackend(devid,                              'type', new_back['type'],                              'params', new_back['params'])            return new_back.get('uuid')        else:            raise VmError('Refusing to reconfigure device %s:%d to %s' %                          (self.deviceClass, devid, config))    def getDeviceConfiguration(self, devid, transaction = None):        """Returns the configuration of a device.        @note: Similar to L{configuration} except it returns a dict.        @return: dict        """        config = DevController.getDeviceConfiguration(self, devid, transaction)        if transaction is None:            devinfo = self.readBackend(devid, 'dev', 'type', 'params', 'mode',                                       'uuid')        else:            devinfo = self.readBackendTxn(transaction, devid,                                          'dev', 'type', 'params', 'mode', 'uuid')        dev, typ, params, mode, uuid = devinfo                if dev:            if transaction is None:                dev_type = self.readFrontend(devid, 'device-type')            else:                dev_type = self.readFrontendTxn(transaction, devid, 'device-type')            if dev_type:                dev += ':' + dev_type            config['dev'] = dev        if typ and params:            config['uname'] = typ +':' + params        else:            config['uname'] = None        if mode:            config['mode'] = mode        if uuid:            config['uuid'] = uuid        proto = self.readFrontend(devid, 'protocol')        if proto:            config['protocol'] = proto        return config    def destroyDevice(self, devid, force):        """@see DevController.destroyDevice"""        # vbd device IDs can be either string or integer.  Further, the        # following string values are possible:        #    - devicetype/deviceid (vbd/51728)        #    - devicetype/devicename (/dev/xvdb)        #    - devicename (xvdb)        # Let our superclass handle integer or devicetype/deviceid forms.        # If we are given a device name form, then look up the device ID        # from it, and destroy that ID instead.        try:            DevController.destroyDevice(self, devid, force)        except ValueError:            dev = self.convertToDeviceNumber(devid)            for i in self.deviceIDs():                if i == dev:                    DevController.destroyDevice(self, i, force)                    return            raise VmError("Device %s not connected" % devid)    def convertToDeviceNumber(self, devid):        try:            dev = int(devid)        except ValueError:            if type(devid) is not str:                raise VmError("devid %s is wrong type" % str(devid))            try:                dev = devid.split('/')[-1]                dev = int(dev)            except ValueError:                (device_path, dev) = blkif.blkdev_name_to_number(dev)        return dev

⌨️ 快捷键说明

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