📄 xenddomaininfo.py
字号:
% (int(dev['domain'],16), int(dev['bus'],16), int(dev['slot'],16), int(dev['func'],16))) self.hvm_destroyPCIDevice(int(vslt, 16)) # Update vslt dev['vslt'] = vslt for n in sxp.children(pci_dev): if(n[0] == 'vslt'): n[1] = vslt # If pci platform does not exist, create and exit. if existing_dev_info is None: self.device_create(dev_sxp) return True # use DevController.reconfigureDevice to change device config dev_control = self.getDeviceController(dev_class) dev_uuid = dev_control.reconfigureDevice(devid, dev_config) if not self.info.is_hvm(): # in PV case, wait until backend state becomes connected. dev_control.waitForDevice_reconfigure(devid) num_devs = dev_control.cleanupDevice(devid) # update XendConfig with new device info if dev_uuid: new_dev_sxp = dev_control.configuration(devid) self.info.device_update(dev_uuid, new_dev_sxp) # If there is no device left, destroy pci and remove config. if num_devs == 0: if self.info.is_hvm(): self.destroyDevice('pci', devid, True) del self.info['devices'][dev_uuid] platform = self.info['platform'] orig_dev_num = len(platform['pci']) # TODO: can use this to keep some info to ask high level # management tools to hot insert a new passthrough dev # after migration if orig_dev_num != 0: #platform['pci'] = ["%dDEVs" % orig_dev_num] platform['pci'] = [] else: self.destroyDevice('pci', devid) del self.info['devices'][dev_uuid] xen.xend.XendDomain.instance().managed_config_save(self) return True def vscsi_device_configure(self, dev_sxp): """Configure an existing vscsi device. quoted pci funciton """ dev_class = sxp.name(dev_sxp) if dev_class != 'vscsi': return False dev_config = self.info.pci_convert_sxp_to_dict(dev_sxp) dev = dev_config['devs'][0] req_devid = sxp.child_value(dev_sxp, 'devid') req_devid = int(req_devid) existing_dev_info = self._getDeviceInfo_vscsi(req_devid, dev['v-dev']) state = sxp.child_value(dev_sxp, 'state') if state == 'Initialising': # new create # If request devid does not exist, create and exit. if existing_dev_info is None: self.device_create(dev_sxp) return True elif existing_dev_info == "exists": raise XendError("The virtual device %s is already defined" % dev['v-dev']) elif state == 'Closing': if existing_dev_info is None: raise XendError("Cannot detach vscsi device does not exist") # use DevController.reconfigureDevice to change device config dev_control = self.getDeviceController(dev_class) dev_uuid = dev_control.reconfigureDevice(req_devid, dev_config) dev_control.waitForDevice_reconfigure(req_devid) num_devs = dev_control.cleanupDevice(req_devid) # update XendConfig with new device info if dev_uuid: new_dev_sxp = dev_control.configuration(req_devid) self.info.device_update(dev_uuid, new_dev_sxp) # If there is no device left, destroy vscsi and remove config. if num_devs == 0: self.destroyDevice('vscsi', req_devid) del self.info['devices'][dev_uuid] return True def device_configure(self, dev_sxp, devid = None): """Configure an existing device. @param dev_config: device configuration @type dev_config: SXP object (parsed config) @param devid: device id @type devid: int @return: Returns True if successfully updated device @rtype: boolean """ # convert device sxp to a dict dev_class = sxp.name(dev_sxp) dev_config = {} if dev_class == 'pci': return self.pci_device_configure(dev_sxp) if dev_class == 'vscsi': return self.vscsi_device_configure(dev_sxp) for opt_val in dev_sxp[1:]: try: dev_config[opt_val[0]] = opt_val[1] except IndexError: pass # use DevController.reconfigureDevice to change device config dev_control = self.getDeviceController(dev_class) dev_uuid = dev_control.reconfigureDevice(devid, dev_config) # update XendConfig with new device info if dev_uuid: self.info.device_update(dev_uuid, dev_sxp) return True def waitForDevices(self): """Wait for this domain's configured devices to connect. @raise VmError: if any device fails to initialise. """ for devclass in XendDevices.valid_devices(): self.getDeviceController(devclass).waitForDevices() def hvm_destroyPCIDevice(self, vslot): log.debug("hvm_destroyPCIDevice called %s", vslot) if not self.info.is_hvm(): raise VmError("hvm_destroyPCIDevice called on non-HVM guest") #all the PCI devs share one conf node devid = '0' vslot = int(vslot) dev_info = self._getDeviceInfo_pci('0')#from self.info['devices'] dev_uuid = sxp.child_value(dev_info, 'uuid') #delete the pci bdf config under the pci device pci_conf = self.info['devices'][dev_uuid][1] pci_len = len(pci_conf['devs']) #find the pass-through device with the virtual slot devnum = 0 for x in pci_conf['devs']: if int(x['vslt'], 16) == vslot: break devnum += 1 if devnum >= pci_len: raise VmError("Device @ vslot 0x%x doesn't exist." % (vslot)) if vslot == 0: raise VmError("Device @ vslot 0x%x do not support hotplug." % (vslot)) bdf_str = "%s:%s:%s.%s" % (x['domain'], x['bus'], x['slot'], x['func']) log.info("hvm_destroyPCIDevice:%s:%s!", x, bdf_str) self.image.signalDeviceModel('pci-rem', 'pci-removed', bdf_str) return 0 def destroyDevice(self, deviceClass, devid, force = False, rm_cfg = False): log.debug("XendDomainInfo.destroyDevice: deviceClass = %s, device = %s", deviceClass, devid) if rm_cfg: # Convert devid to device number. A device number is # needed to remove its configuration. dev = self.getDeviceController(deviceClass).convertToDeviceNumber(devid) # Save current sxprs. A device number and a backend # path are needed to remove its configuration but sxprs # do not have those after calling destroyDevice. sxprs = self.getDeviceSxprs(deviceClass) rc = None if self.domid is not None: rc = self.getDeviceController(deviceClass).destroyDevice(devid, force) if not force and rm_cfg: # The backend path, other than the device itself, # has to be passed because its accompanied frontend # path may be void until its removal is actually # issued. It is probable because destroyDevice is # issued first. for dev_num, dev_info in sxprs: dev_num = int(dev_num) if dev_num == dev: for x in dev_info: if x[0] == 'backend': backend = x[1] break break self._waitForDevice_destroy(deviceClass, devid, backend) if rm_cfg: if deviceClass == 'vif': if self.domid is not None: for dev_num, dev_info in sxprs: dev_num = int(dev_num) if dev_num == dev: for x in dev_info: if x[0] == 'mac': mac = x[1] break break dev_info = self._getDeviceInfo_vif(mac) else: _, dev_info = sxprs[dev] else: # 'vbd' or 'tap' dev_info = self._getDeviceInfo_vbd(dev) # To remove the UUID of the device from refs, # deviceClass must be always 'vbd'. deviceClass = 'vbd' if dev_info is None: raise XendError("Device %s is not defined" % devid) dev_uuid = sxp.child_value(dev_info, 'uuid') del self.info['devices'][dev_uuid] self.info['%s_refs' % deviceClass].remove(dev_uuid) xen.xend.XendDomain.instance().managed_config_save(self) return rc def getDeviceSxprs(self, deviceClass): if deviceClass == 'pci': dev_info = self._getDeviceInfo_pci('0')#from self.info['devices'] if dev_info is None: return [] dev_uuid = sxp.child_value(dev_info, 'uuid') pci_devs = self.info['devices'][dev_uuid][1]['devs'] pci_len = len(pci_devs) return pci_devs if self._stateGet() in (DOM_STATE_RUNNING, DOM_STATE_PAUSED, DOM_STATE_CRASHED): return self.getDeviceController(deviceClass).sxprs() else: sxprs = [] dev_num = 0 for dev_type, dev_info in self.info.all_devices_sxpr(): if dev_type == deviceClass: sxprs.append([dev_num, dev_info]) dev_num += 1 return sxprs def getBlockDeviceClass(self, devid): # To get a device number from the devid, # we temporarily use the device controller of VBD. dev = self.getDeviceController('vbd').convertToDeviceNumber(devid) dev_info = self._getDeviceInfo_vbd(dev) if dev_info: return dev_info[0] def _getDeviceInfo_vif(self, mac): for dev_type, dev_info in self.info.all_devices_sxpr(): if dev_type != 'vif': continue if mac == sxp.child_value(dev_info, 'mac'): return dev_info def _getDeviceInfo_vbd(self, devid): for dev_type, dev_info in self.info.all_devices_sxpr(): if dev_type != 'vbd' and dev_type != 'tap': continue dev = sxp.child_value(dev_info, 'dev') dev = dev.split(':')[0] dev = self.getDeviceController(dev_type).convertToDeviceNumber(dev) if devid == dev: return dev_info def _getDeviceInfo_pci(self, devid): for dev_type, dev_info in self.info.all_devices_sxpr(): if dev_type != 'pci': continue return dev_info return None def _getDeviceInfo_vscsi(self, devid, vdev): devid = int(devid) for dev_type, dev_info in self.info.all_devices_sxpr(): if dev_type != 'vscsi': continue existing_dev_uuid = sxp.child_value(dev_info, 'uuid') existing_conf = self.info['devices'][existing_dev_uuid][1] existing_dev = existing_conf['devs'][0] existing_devid = int(existing_dev['devid']) existing_vdev = existing_dev['v-dev'] if vdev == existing_vdev: return "exists" if devid == existing_devid: return dev_info return None def setMemoryTarget(self, target): """Set the memory target of this domain. @param target: In MiB. """ log.debug("Setting memory target of domain %s (%s) to %d MiB.", self.info['name_label'], str(self.domid), target) MiB = 1024 * 1024 if self.domid == 0: dom0_min_mem = xoptions.get_dom0_min_mem() memory_cur = self.get_memory_dynamic_max() / MiB if target < memory_cur and dom0_min_mem > target: raise XendError("memory_dynamic_max too small") self._safe_set_memory('memory_dynamic_min', target * MiB) self._safe_set_memory('memory_dynamic_max', target * MiB) if self.domid >= 0: self.storeVm("memory", target) self.storeDom("memory/target", target << 10) xen.xend.XendDomain.instance().managed_config_save(self) def setMemoryMaximum(self, limit): """Set the maximum memory limit of this domain @param limit: In MiB. """ log.debug("Setting memory maximum of domain %s (%s) to %d MiB.", self.info['name_label'], str(self.domid), limit) maxmem_cur = self.get_memory_static_max() MiB = 1024 * 1024 self._safe_set_memory('memory_static_max', limit * MiB) if self.domid >= 0: maxmem = int(limit) * 1024 try: return xc.domain_setmaxmem(self.domid, maxmem) except Exception, ex: self._safe_set_memory('memory_static_max', maxmem_cur) raise XendError(str(ex)) xen.xend.XendDomain.instance().managed_config_save(self) def getVCPUInfo(self): try: # We include the domain name and ID, to help xm.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -