def waitForDevice(self, devid):
        log.debug("Waiting for %s.", devid)

        if not self.hotplug:
            return

        (status, err) = self.waitForBackend(devid)

        if status == Timeout:
            self.destroyDevice(devid, False)
            raise VmError("Device %s (%s) could not be connected. "
                          "Hotplug scripts not working." %
                          (devid, self.deviceClass))

        elif status == Error:
            self.destroyDevice(devid, False)
            if err is None:
                raise VmError("Device %s (%s) could not be connected. "
                              "Backend device not found." %
                              (devid, self.deviceClass))
            else:
                raise VmError("Device %s (%s) could not be connected. "
                              "%s" % (devid, self.deviceClass, err))
        elif status == Missing:
            # Don't try to destroy the device; it's already gone away.
            raise VmError("Device %s (%s) could not be connected. "
                          "Device not found." % (devid, self.deviceClass))

        elif status == Busy:
            self.destroyDevice(devid, False)
            if err is None:
                err = "Busy."
            raise VmError("Device %s (%s) could not be connected.\n%s" %
                          (devid, self.deviceClass, err))
示例#2
0
    def getDeviceDetails(self, config):
        """@see DevController.getDeviceDetails"""
        def get_param(field):
            try:
                val = config.get(field)

                if not val:
                    raise VmError('ioports: Missing %s config setting' % field)

                return parse_ioport(val)
            except:
                raise VmError('ioports: Invalid config setting %s: %s' %
                              (field, val))

        io_from = get_param('from')
        io_to = get_param('to')

        if io_to < io_from or io_to >= 65536:
            raise VmError('ioports: Invalid i/o range: %s - %s' %
                          (io_from, io_to))

        rc = xc.domain_ioport_permission(domid=self.getDomid(),
                                         first_port=io_from,
                                         nr_ports=io_to - io_from + 1,
                                         allow_access=True)

        if rc < 0:
            #todo non-fatal
            raise VmError(
                'ioports: Failed to configure legacy i/o range: %s - %s' %
                (io_from, io_to))

        return (None, {}, {})
示例#3
0
    def configure(self, imageConfig, deviceConfig):
        ImageHandler.configure(self, imageConfig, deviceConfig)

        info = xc.xeninfo()
        if not 'hvm' in info['xen_caps']:
            raise VmError("Not an HVM capable platform, we stop creating!")

        self.dmargs = self.parseDeviceModelArgs(imageConfig, deviceConfig)
        self.device_model = sxp.child_value(imageConfig, 'device_model')
        if not self.device_model:
            raise VmError("hvm: missing device model")
        self.display = sxp.child_value(imageConfig, 'display')
        self.xauthority = sxp.child_value(imageConfig, 'xauthority')

        self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)),
                        ("image/device-model", self.device_model),
                        ("image/display", self.display))

        self.pid = 0

        self.dmargs += self.configVNC(imageConfig)

        self.pae  = int(sxp.child_value(imageConfig, 'pae', 0))

        self.acpi = int(sxp.child_value(imageConfig, 'acpi', 0))
        self.apic = int(sxp.child_value(imageConfig, 'apic', 0))
示例#4
0
    def waitForDevice(self, devid):
        log.debug("Waiting for %s.", devid)
        
        status = self.waitForBackend(devid)

        if status == Timeout:
            self.destroyDevice(devid)
            raise VmError("Device %s (%s) could not be connected. "
                          "Hotplug scripts not working." %
                          (devid, self.deviceClass))

        elif status == Error:
            self.destroyDevice(devid)
            raise VmError("Device %s (%s) could not be connected. "
                          "Backend device not found." %
                          (devid, self.deviceClass))

        elif status == Missing:
            # Don't try to destroy the device; it's already gone away.
            raise VmError("Device %s (%s) could not be connected. "
                          "Device not found." % (devid, self.deviceClass))

        elif status == Busy:
            err = None
            frontpath = self.frontendPath(devid)
            backpath = xstransact.Read(frontpath, "backend")
            if backpath:
                err = xstransact.Read(backpath, HOTPLUG_ERROR_NODE)
            if not err:
                err = "Busy."
                
            self.destroyDevice(devid)
            raise VmError("Device %s (%s) could not be connected.\n%s" %
                          (devid, self.deviceClass, err))
示例#5
0
    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 not self._isValidProtocol(typ):
                    raise VmError('Block device type "%s" is invalid.' % typ)
            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

        bootable = config.get('bootable', None)
        if bootable != None:
            back['bootable'] = str(bootable)

        if security.on() == xsconstants.XS_POLICY_USE:
            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)
示例#6
0
    def getDeviceDetails(self, config):
        """@see DevController.getDeviceDetails"""
        def get_param(field):
            try:
                val = config.get(field)

                if not val:
                    raise VmError('irq: Missing %s config setting' % field)

                if isinstance(val, types.StringType):
                    return int(val, 10)
                    radix = 10
                else:
                    return val
            except:
                raise VmError('irq: Invalid config setting %s: %s' %
                              (field, val))

        pirq = get_param('irq')

        rc = xc.domain_irq_permission(domid=self.getDomid(),
                                      pirq=pirq,
                                      allow_access=True)

        if rc < 0:
            #todo non-fatal
            raise VmError('irq: Failed to configure irq: %d' % (pirq))
        rc = xc.physdev_map_pirq(domid=self.getDomid(), index=pirq, pirq=pirq)
        if rc < 0:
            raise VmError('irq: Failed to map irq %x' % (pirq))
        back = dict([(k, config[k]) for k in self.valid_cfg if k in config])
        return (self.allocateDeviceID(), back, {})
示例#7
0
 def pool_start(cls, poolname):
     pool = cls.lookup_pool(poolname)
     if not pool:
         raise VmError('unknown pool %s' % poolname)
     try:
         pool.activate()
     except XendAPIError, ex:
         raise VmError(ex.get_api_error())
示例#8
0
 def pool_delete(cls, poolname):
     pool = cls.lookup_pool(poolname)
     if not pool:
         raise VmError('unknown pool %s' % poolname)
     try:
         pool.destroy()
     except XendAPIError, ex:
         raise VmError(ex.get_api_error())
示例#9
0
        def get_param(field):
            try:
                val = config.get(field)

                if not val:
                    raise VmError('ioports: Missing %s config setting' % field)

                return parse_ioport(val)
            except:
                raise VmError('ioports: Invalid config setting %s: %s' %
                              (field, val))
示例#10
0
 def pool_cpu_remove(cls, poolname, cpu):
     pool = cls.lookup_pool(poolname)
     if not pool:
         raise VmError('unknown pool %s' % poolname)
     try:
         cpu_ref = cls._cpu_number_to_ref(int(cpu))
         if cpu_ref:
             pool.remove_host_CPU_live(cpu_ref)
         else:
             raise PoolError(XEND_ERROR_INVALID_CPU, 'CPU unknown')
     except XendAPIError, ex:
         raise VmError(ex.get_api_error())
示例#11
0
def findImageHandlerClass(image):
    """Find the image handler class for an image config.

    @param image config
    @return ImageHandler subclass or None
    """
    ty = sxp.name(image)
    if ty is None:
        raise VmError('missing image type')
    imageClass = imageHandlerClasses.get(ty)
    if imageClass is None:
        raise VmError('unknown image type: ' + ty)
    return imageClass
示例#12
0
    def signalDeviceModel(self, cmd, ret, par=None):
        if self.device_model is None:
            return
        # Signal the device model to for action
        if cmd is '' or ret is '':
            raise VmError(
                'need valid command and result when signal device model')

        count = 0
        while True:
            orig_state = xstransact.Read(
                "/local/domain/0/device-model/%i/state" % self.vm.getDomid())
            # This can occur right after start-up
            if orig_state != None:
                break

            log.debug('signalDeviceModel: orig_state is None, retrying')

            time.sleep(0.1)
            count += 1
            if count < 100:
                continue

            raise VmError('Device model isn\'t ready for commands')

        if par is not None:
            xstransact.Store(
                "/local/domain/0/device-model/%i" % self.vm.getDomid(),
                ('parameter', par))

        xstransact.Store(
            "/local/domain/0/device-model/%i" % self.vm.getDomid(),
            ('command', cmd))
        # Wait for confirmation.  Could do this with a watch but we'd
        # still end up spinning here waiting for the watch to fire.
        state = ''
        count = 0
        while state != ret:
            state = xstransact.Read("/local/domain/0/device-model/%i/state" %
                                    self.vm.getDomid())
            time.sleep(0.1)
            count += 1
            if count > 100:
                raise VmError('Timed out waiting for device model action')

        #resotre orig state
        xstransact.Store(
            "/local/domain/0/device-model/%i" % self.vm.getDomid(),
            ('state', orig_state))
        log.info("signalDeviceModel:restore dm state to %s", orig_state)
示例#13
0
 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)
示例#14
0
文件: irqif.py 项目: ProLoDs/XenC3
        def get_param(field):
            try:
                val = config.get(field)

                if not val:
                    raise VmError('irq: Missing %s config setting' % field)

                if isinstance(val, types.StringType):
                    return int(val,10)
                    radix = 10
                else:
                    return val
            except:
                raise VmError('irq: Invalid config setting %s: %s' %
                              (field, val))
示例#15
0
    def reconfigureDevice(self, devid, config):
        """Reconfigure the specified device.

        The implementation here just raises VmError.  This may be overridden
        by those subclasses that can reconfigure their devices.
        """
        raise VmError('%s devices may not be reconfigured' % self.deviceClass)
示例#16
0
 def readBackendTxn(self, transaction, devid, *args):
     backpath = self.readVm(devid, "backend")
     if backpath:
         paths = map(lambda x: backpath + "/" + x, args)
         return transaction.read(*paths)
     else:
         raise VmError("Device %s not connected" % devid)
示例#17
0
 def pool_migrate(cls, domname, poolname):
     dom = XendDomain.instance()
     pool = cls.lookup_pool(poolname)
     if not pool:
         raise VmError('unknown pool %s' % poolname)
     dominfo = dom.domain_lookup_nr(domname)
     if not dominfo:
         raise VmError('unknown domain %s' % domname)
     domid = dominfo.getDomid()
     if domid is not None:
         if domid == 0:
             raise VmError('could not move Domain-0')
         try:
             cls.move_domain(pool.get_uuid(), domid)
         except Exception, ex:
             raise VmError('could not move domain')
示例#18
0
    def CheckSiblingDevices(self, domid, dev):
        """ Check if all sibling devices of dev are owned by pciback or pci-stub
        """
        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,
        for i in group_str.split(','):
            if i == '':
                continue
            pci_dev = parse_pci_name(i)
            pci_dev['domain'] = '%04x' % dev.domain
            try:
                sdev = PciDevice(pci_dev)
            except Exception, e:
                #no dom0 drivers bound to sdev
                continue

            if sdev.driver != 'pciback' and sdev.driver != 'pci-stub':
                raise VmError(("pci: PCI Backend and pci-stub don't "+ \
                    "own sibling device %s of device %s"\
                    )%(sdev.name, dev.name))
示例#19
0
    def getDeviceDetails(self, config):
        """@see DevController.getDeviceDetails"""

        def get_param(field):
            try:
                val = config.get(field)

                if not val:
                    raise VmError('irq: Missing %s config setting' % field)

                if isinstance(val, types.StringType):
                    return int(val,10)
                    radix = 10
                else:
                    return val
            except:
                raise VmError('irq: Invalid config setting %s: %s' %
                              (field, val))
       
        pirq = get_param('irq')

        rc = xc.domain_irq_permission(domid        = self.getDomid(),
                                      pirq         = pirq,
                                      allow_access = True)

        if rc < 0:
            #todo non-fatal
            raise VmError(
                'irq: Failed to configure irq: %d' % (pirq))

        return (None, {}, {})
示例#20
0
    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))
示例#21
0
    def writeBackend(self, devid, *args):
        backpath = self.readVm(devid, "backend")

        if backpath:
            xstransact.Write(backpath, *args)
        else:
            raise VmError("Device %s not connected" % devid)
示例#22
0
 def destroyDevice(self, devid):
     try:
         DevController.destroyDevice(self, int(devid))
         time.sleep(5)
         t = xstransact()
         frontpath = self.frontendPath(int(devid))
         backpath = t.Read(frontpath, "backend")
         if backpath:
             t.Remove(backpath)
             log.debug('in try: removed %s' % backpath)
         t.Remove(frontpath)
         log.debug('in try: removed %s' % frontpath)
     except ValueError:
         devid_end = type(devid) is str and devid.split('/')[-1] or None
         for i in self.deviceIDs():
             d = self.readBackend(i, 'dev')
             if d == devid or (devid_end and d == devid_end):
                 DevController.destroyDevice(self, i)
                 time.sleep(5)
                 frontpath = self.frontendPath(int(devid))
                 backpath = t.Read(frontpath, "backend")
                 if backpath:
                     t.Remove(backpath)
                     log.debug('in err: removed %s' % backpath)
                 t.Remove(frontpath)
                 log.debug('in err: removed %s' % frontpath)
                 return
         raise VmError("Device %s not connected" % devid)
示例#23
0
 def removeBackend(self, devid, *args):
     frontpath = self.frontendPath(devid)
     backpath = xstransact.Read(frontpath, "backend")
     if backpath:
         return xstransact.Remove(backpath, *args)
     else:
         raise VmError("Device %s not connected" % devid)
示例#24
0
 def pool_list(cls, names):
     sxprs = []
     try:
         node = XendNode.instance()
         xd = XendDomain.instance()
         pools = cls.get_all_records()
         for (pool_uuid, pool_vals) in pools.items():
             if pool_vals['name_label'] in names or len(names) == 0:
                 # conv host_cpu refs to cpu number
                 cpus = [
                     node.get_host_cpu_field(cpu_ref, 'number')
                     for cpu_ref in pool_vals['host_CPUs']
                 ]
                 cpus.sort()
                 pool_vals['host_CPU_numbers'] = cpus
                 # query VMs names. Take in account, that a VM
                 # returned by get_all_records could be destroy, now
                 vm_names = [
                     vm.getName() for vm in map(
                         xd.get_vm_by_uuid, pool_vals['started_VMs']) if vm
                 ]
                 pool_vals['started_VM_names'] = vm_names
                 pool_vals['auto_power_on'] = int(
                     pool_vals['auto_power_on'])
                 sxprs += [[pool_uuid] + map2sxp(pool_vals)]
     except XendAPIError, ex:
         raise VmError(ex.get_api_error())
示例#25
0
    def reconfigureDevice(self, _, config):
        """@see DevController.reconfigureDevice"""
        (devid, back, front) = self.getDeviceDetails(config)
        devid = int(devid)
        vscsi_config = config['devs'][0]
        state = vscsi_config.get('state', xenbusState['Unknown'])
        driver_state = self.readBackend(devid, 'state')

        if str(xenbusState['Connected']) != driver_state:
            raise VmError("Driver status is not connected")

        uuid = self.readBackend(devid, 'uuid')
        if state == xenbusState['Initialising']:
            back['uuid'] = uuid
            self.writeBackend(devid, back)

        elif state == xenbusState['Closing']:
            found = False
            devs = self.readBackendList(devid, "vscsi-devs")
            hostmode = int(self.readBackend(devid, 'feature-host'))
            vscsipath = "vscsi-devs/"
            vdev = vscsi_config.get('v-dev', '')

            for dev in devs:
                devpath = vscsipath + dev
                old_vdev = self.readBackend(devid, devpath + '/v-dev')

                if hostmode == 1:
                    #At hostmode, all v-dev that belongs to devid is deleted.
                    found = True
                    self.writeBackend(devid, devpath + '/state', \
                                    str(xenbusState['Closing']))
                elif vdev == old_vdev:
                    found = True
                    self.writeBackend(devid, devpath + '/state', \
                                    str(xenbusState['Closing']))
                    break

            if not found:
                raise VmError("Device %s not connected" % vdev)

        else:
            raise XendError("Error configuring device invalid "
                            "state '%s'" % xenbusState[state])

        self.writeBackend(devid, 'state', str(xenbusState['Reconfiguring']))
        return self.readBackend(devid, 'uuid')
示例#26
0
 def createDevice(self, config):
     bridge = config.get('bridge')
     if bridge is not None:
         bridge_result = commands.getstatusoutput("/sbin/ifconfig %s" %
                                                  bridge)
         if bridge_result[0] != 0:
             raise VmError('Network bridge does not exist: %s' % bridge)
     DevController.createDevice(self, config)
示例#27
0
    def waitForDevice_reconfigure(self, devid):
        log.debug("Waiting for %s - reconfigureDevice.", devid)

        (status, err) = self.waitForBackend_reconfigure(devid)

        if status == Timeout:
            raise VmError("Device %s (%s) could not be reconfigured. " %
                          (devid, self.deviceClass))
示例#28
0
    def getDeviceDetails(self, config):
        """@see DevController.getDeviceDetails"""

        script = config.get('script', xoptions.get_vif_script())
        typ = config.get('type')
        bridge = config.get('bridge')
        mac = config.get('mac')
        vifname = config.get('vifname')
        rate = config.get('rate')
        uuid = config.get('uuid')
        ipaddr = config.get('ip')
        model = config.get('model')
        accel = config.get('accel')
        sec_lab = config.get('security_label')

        if not mac:
            raise VmError("MAC address not specified or generated.")

        devid = self.allocateDeviceID()

        back = {'script': script, 'mac': mac}
        if typ:
            back['type'] = typ
        if ipaddr:
            back['ip'] = ipaddr
        if bridge:
            back['bridge'] = bridge
        if vifname:
            back['vifname'] = vifname
        if rate:
            back['rate'] = rate
        if uuid:
            back['uuid'] = uuid
        if model:
            back['model'] = model
        if accel:
            back['accel'] = accel
        if sec_lab:
            back['security_label'] = sec_lab

        config_path = "device/%s/%d/" % (self.deviceClass, devid)
        for x in back:
            self.vm._writeVm(config_path + x, back[x])

        back['handle'] = "%i" % devid
        back['script'] = os.path.join(xoptions.network_script_dir, script)
        if rate:
            back['rate'] = parseRate(rate)

        front = {}
        if typ != 'ioemu':
            front = {'handle': "%i" % devid, 'mac': mac}

        if security.on():
            self.do_access_control(config)

        return (devid, back, front)
示例#29
0
 def pool_new(cls, config):
     try:
         record = sxp2map(config)
         if record.has_key('proposed_CPUs') and \
            not isinstance(record['proposed_CPUs'], types.ListType):
             record['proposed_CPUs'] = [record['proposed_CPUs']]
         new_uuid = cls.create(record)
     except XendAPIError, ex:
         raise VmError(ex.get_api_error())
示例#30
0
 def do_access_control(self, config):
     """ do access control checking. Throws a VMError if access is denied """
     domain_label = self.vm.get_security_label()
     stes = XSPolicyAdminInstance().get_stes_of_vmlabel(domain_label)
     res_label = config.get('security_label')
     if len(stes) > 1 or res_label:
         if not res_label:
             raise VmError("'VIF' must be labeled")
         (label, ssidref, policy) = \
                           security.security_label_to_details(res_label)
         if domain_label:
             rc = security.res_security_check_xapi(label, ssidref, policy,
                                                   domain_label)
             if rc == 0:
                 raise VmError("VM's access to network device denied. "
                               "Check labeling")
         else:
             raise VmError("VM must have a security label to access "
                           "network device")