📄 xenddomaininfo.py
字号:
else: self.domid = domid #REMOVE: uuid is now generated in XendConfig #if not self._infoIsSet('uuid'): # self.info['uuid'] = uuid.toString(uuid.create()) # Find a unique /vm/<uuid>/<integer> path if not specified. # This avoids conflict between pre-/post-migrate domains when doing # localhost relocation. self.vmpath = vmpath i = 0 while self.vmpath == None: self.vmpath = XS_VMROOT + self.info['uuid'] if i != 0: self.vmpath = self.vmpath + '-' + str(i) try: if self._readVm("uuid"): self.vmpath = None i = i + 1 except: pass self.dompath = dompath self.image = None self.store_port = None self.store_mfn = None self.console_port = None self.console_mfn = None self.native_protocol = None self.vmWatch = None self.shutdownWatch = None self.shutdownStartTime = None self._resume = resume self.state_updated = threading.Condition() self.refresh_shutdown_lock = threading.Condition() self._stateSet(DOM_STATE_HALTED) self._deviceControllers = {} for state in DOM_STATES_OLD: self.info[state] = 0 if augment: self._augmentInfo(priv) self._checkName(self.info['name_label']) self.metrics = XendVMMetrics(uuid.createString(), self) # # Public functions available through XMLRPC # def start(self, is_managed = False): """Attempts to start the VM by do the appropriate initialisation if it not started. """ from xen.xend import XendDomain if self._stateGet() in (XEN_API_VM_POWER_STATE_HALTED, XEN_API_VM_POWER_STATE_SUSPENDED, XEN_API_VM_POWER_STATE_CRASHED): try: XendTask.log_progress(0, 30, self._constructDomain) XendTask.log_progress(31, 60, self._initDomain) XendTask.log_progress(61, 70, self._storeVmDetails) XendTask.log_progress(71, 80, self._storeDomDetails) XendTask.log_progress(81, 90, self._registerWatches) XendTask.log_progress(91, 100, self.refreshShutdown) xendomains = XendDomain.instance() xennode = XendNode.instance() # save running configuration if XendDomains believe domain is # persistent if is_managed: xendomains.managed_config_save(self) if xennode.xenschedinfo() == 'credit': xendomains.domain_sched_credit_set(self.getDomid(), self.getWeight(), self.getCap()) except: log.exception('VM start failed') self.destroy() raise else: raise XendError('VM already running') def resume(self): """Resumes a domain that has come back from suspension.""" state = self._stateGet() if state in (DOM_STATE_SUSPENDED, DOM_STATE_HALTED): try: self._constructDomain() self._storeVmDetails() self._createDevices() self._createChannels() self._storeDomDetails() self._endRestore() except: log.exception('VM resume failed') self.destroy() raise else: raise XendError('VM is not suspended; it is %s' % XEN_API_VM_POWER_STATE[state]) def shutdown(self, reason): """Shutdown a domain by signalling this via xenstored.""" log.debug('XendDomainInfo.shutdown(%s)', reason) if self._stateGet() in (DOM_STATE_SHUTDOWN, DOM_STATE_HALTED,): raise XendError('Domain cannot be shutdown') if self.domid == 0: raise XendError('Domain 0 cannot be shutdown') if reason not in DOMAIN_SHUTDOWN_REASONS.values(): raise XendError('Invalid reason: %s' % reason) self._removeVm('xend/previous_restart_time') self.storeDom("control/shutdown", reason) # HVM domain shuts itself down only if it has PV drivers if self.info.is_hvm(): hvm_pvdrv = xc.hvm_get_param(self.domid, HVM_PARAM_CALLBACK_IRQ) if not hvm_pvdrv: code = REVERSE_DOMAIN_SHUTDOWN_REASONS[reason] log.info("HVM save:remote shutdown dom %d!", self.domid) xc.domain_shutdown(self.domid, code) def pause(self): """Pause domain @raise XendError: Failed pausing a domain """ try: xc.domain_pause(self.domid) self._stateSet(DOM_STATE_PAUSED) except Exception, ex: log.exception(ex) raise XendError("Domain unable to be paused: %s" % str(ex)) def unpause(self): """Unpause domain @raise XendError: Failed unpausing a domain """ try: xc.domain_unpause(self.domid) self._stateSet(DOM_STATE_RUNNING) except Exception, ex: log.exception(ex) raise XendError("Domain unable to be unpaused: %s" % str(ex)) def send_sysrq(self, key): """ Send a Sysrq equivalent key via xenstored.""" if self._stateGet() not in (DOM_STATE_RUNNING, DOM_STATE_PAUSED): raise XendError("Domain '%s' is not started" % self.info['name_label']) asserts.isCharConvertible(key) self.storeDom("control/sysrq", '%c' % key) def sync_pcidev_info(self): if not self.info.is_hvm(): return devid = '0' dev_info = self._getDeviceInfo_pci(devid) if dev_info is None: return # get the virtual slot info from xenstore dev_uuid = sxp.child_value(dev_info, 'uuid') pci_conf = self.info['devices'][dev_uuid][1] pci_devs = pci_conf['devs'] count = 0 vslots = None while vslots is None and count < 20: vslots = xstransact.Read("/local/domain/0/backend/pci/%u/%s/vslots" % (self.getDomid(), devid)) time.sleep(0.1) count += 1 if vslots is None: log.error("Device model didn't tell the vslots for PCI device") return #delete last delim if vslots[-1] == ";": vslots = vslots[:-1] slot_list = vslots.split(';') if len(slot_list) != len(pci_devs): log.error("Device model's pci dev num dismatch") return #update the vslot info count = 0; for x in pci_devs: x['vslt'] = slot_list[count] count += 1 def hvm_pci_device_create(self, dev_config): log.debug("XendDomainInfo.hvm_pci_device_create: %s" % scrub_password(dev_config)) if not self.info.is_hvm(): raise VmError("hvm_pci_device_create called on non-HVM guest") #all the PCI devs share one conf node devid = '0' new_dev = dev_config['devs'][0] dev_info = self._getDeviceInfo_pci(devid)#from self.info['devices'] #check conflict before trigger hotplug event if dev_info is not None: dev_uuid = sxp.child_value(dev_info, 'uuid') pci_conf = self.info['devices'][dev_uuid][1] pci_devs = pci_conf['devs'] for x in pci_devs: if (int(x['vslt'], 16) == int(new_dev['vslt'], 16) and int(x['vslt'], 16) != 0 ): raise VmError("vslot %s already have a device." % (new_dev['vslt'])) if (int(x['domain'], 16) == int(new_dev['domain'], 16) and int(x['bus'], 16) == int(new_dev['bus'], 16) and int(x['slot'], 16) == int(new_dev['slot'], 16) and int(x['func'], 16) == int(new_dev['func'], 16) ): raise VmError("device is already inserted") # Test whether the devices can be assigned with VT-d pci_str = "%s, %s, %s, %s" % (new_dev['domain'], new_dev['bus'], new_dev['slot'], new_dev['func']) bdf = xc.test_assign_device(self.domid, pci_str) if bdf != 0: if bdf == -1: raise VmError("failed to assign device: maybe the platform" " doesn't support VT-d, or VT-d isn't enabled" " properly?") bus = (bdf >> 16) & 0xff devfn = (bdf >> 8) & 0xff dev = (devfn >> 3) & 0x1f func = devfn & 0x7 raise VmError("fail to assign device(%x:%x.%x): maybe it has" " already been assigned to other domain, or maybe" " it doesn't exist." % (bus, dev, func)) bdf_str = "%s:%s:%s.%s@%s" % (new_dev['domain'], new_dev['bus'], new_dev['slot'], new_dev['func'], new_dev['vslt']) self.image.signalDeviceModel('pci-ins', 'pci-inserted', bdf_str) def device_create(self, dev_config): """Create a new device. @param dev_config: device configuration @type dev_config: SXP object (parsed config) """ log.debug("XendDomainInfo.device_create: %s" % scrub_password(dev_config)) dev_type = sxp.name(dev_config) dev_uuid = self.info.device_add(dev_type, cfg_sxp = dev_config) dev_config_dict = self.info['devices'][dev_uuid][1] log.debug("XendDomainInfo.device_create: %s" % scrub_password(dev_config_dict)) if self.domid is not None: try: dev_config_dict['devid'] = devid = \ self._createDevice(dev_type, dev_config_dict) self._waitForDevice(dev_type, devid) except VmError, ex: del self.info['devices'][dev_uuid] if dev_type == 'pci': for dev in dev_config_dict['devs']: XendAPIStore.deregister(dev['uuid'], 'DPCI') elif dev_type == 'tap': self.info['vbd_refs'].remove(dev_uuid) else: self.info['%s_refs' % dev_type].remove(dev_uuid) raise ex else: devid = None xen.xend.XendDomain.instance().managed_config_save(self) return self.getDeviceController(dev_type).sxpr(devid) def pci_device_configure(self, dev_sxp, devid = 0): """Configure an existing pci device. @param dev_sxp: device configuration @type dev_sxp: SXP object (parsed config) @param devid: device id @type devid: int @return: Returns True if successfully updated device @rtype: boolean """ log.debug("XendDomainInfo.pci_device_configure: %s" % scrub_password(dev_sxp)) dev_class = sxp.name(dev_sxp) if dev_class != 'pci': return False pci_state = sxp.child_value(dev_sxp, 'state') existing_dev_info = self._getDeviceInfo_pci(devid) if existing_dev_info is None and pci_state != 'Initialising': raise XendError("Cannot detach when pci platform does not exist") pci_dev = sxp.children(dev_sxp, 'dev')[0] dev_config = self.info.pci_convert_sxp_to_dict(dev_sxp) dev = dev_config['devs'][0] # Do HVM specific processing if self.info.is_hvm(): if pci_state == 'Initialising': # HVM PCI device attachment self.hvm_pci_device_create(dev_config) # Update vslt vslt = xstransact.Read("/local/domain/0/device-model/%i/parameter" % self.getDomid()) dev['vslt'] = vslt for n in sxp.children(pci_dev): if(n[0] == 'vslt'): n[1] = vslt else: # HVM PCI device detachment existing_dev_uuid = sxp.child_value(existing_dev_info, 'uuid') existing_pci_conf = self.info['devices'][existing_dev_uuid][1] existing_pci_devs = existing_pci_conf['devs'] vslt = '0x0' for x in existing_pci_devs: if ( int(x['domain'], 16) == int(dev['domain'], 16) and int(x['bus'], 16) == int(dev['bus'], 16) and int(x['slot'], 16) == int(dev['slot'], 16) and int(x['func'], 16) == int(dev['func'], 16) ): vslt = x['vslt'] break if vslt == '0x0': raise VmError("Device %04x:%02x:%02x.%01x is not connected"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -