📄 xenddomaininfo.py
字号:
except: if new_dom: new_dom._removeVm(RESTART_IN_PROGRESS) new_dom.destroy() else: self._removeVm(RESTART_IN_PROGRESS) raise except: log.exception('Failed to restart domain %s.', str(old_domid)) def _preserveForRestart(self): """Preserve a domain that has been shut down, by giving it a new UUID, cloning the VM details, and giving it a new name. This allows us to keep this domain for debugging, but restart a new one in its place preserving the restart semantics (name and UUID preserved). """ new_uuid = uuid.createString() new_name = 'Domain-%s' % new_uuid log.info("Renaming dead domain %s (%d, %s) to %s (%s).", self.info['name_label'], self.domid, self.info['uuid'], new_name, new_uuid) self._unwatchVm() self._releaseDevices() self.info['name_label'] = new_name self.info['uuid'] = new_uuid self.vmpath = XS_VMROOT + new_uuid self._storeVmDetails() self._preserve() def _preserve(self): log.info("Preserving dead domain %s (%d).", self.info['name_label'], self.domid) self._unwatchVm() self.storeDom('xend/shutdown_completed', 'True') self._stateSet(DOM_STATE_HALTED) # # Debugging .. # def dumpCore(self, corefile = None): """Create a core dump for this domain. @raise: XendError if core dumping failed. """ try: if not corefile: this_time = time.strftime("%Y-%m%d-%H%M.%S", time.localtime()) corefile = "/var/xen/dump/%s-%s.%s.core" % (this_time, self.info['name_label'], self.domid) if os.path.isdir(corefile): raise XendError("Cannot dump core in a directory: %s" % corefile) xc.domain_dumpcore(self.domid, corefile) except RuntimeError, ex: corefile_incomp = corefile+'-incomplete' os.rename(corefile, corefile_incomp) log.exception("XendDomainInfo.dumpCore failed: id = %s name = %s", self.domid, self.info['name_label']) raise XendError("Failed to dump core: %s" % str(ex)) # # Device creation/deletion functions # def _createDevice(self, deviceClass, devConfig): return self.getDeviceController(deviceClass).createDevice(devConfig) def _waitForDevice(self, deviceClass, devid): return self.getDeviceController(deviceClass).waitForDevice(devid) def _waitForDeviceUUID(self, dev_uuid): deviceClass, config = self.info['devices'].get(dev_uuid) self._waitForDevice(deviceClass, config['devid']) def _waitForDevice_destroy(self, deviceClass, devid, backpath): return self.getDeviceController(deviceClass).waitForDevice_destroy( devid, backpath) def _reconfigureDevice(self, deviceClass, devid, devconfig): return self.getDeviceController(deviceClass).reconfigureDevice( devid, devconfig) def _createDevices(self): """Create the devices for a vm. @raise: VmError for invalid devices """ ordered_refs = self.info.ordered_device_refs() for dev_uuid in ordered_refs: devclass, config = self.info['devices'][dev_uuid] if devclass in XendDevices.valid_devices(): log.info("createDevice: %s : %s" % (devclass, scrub_password(config))) dev_uuid = config.get('uuid') devid = self._createDevice(devclass, config) # store devid in XendConfig for caching reasons if dev_uuid in self.info['devices']: self.info['devices'][dev_uuid][1]['devid'] = devid if self.image: self.image.createDeviceModel() def _releaseDevices(self, suspend = False): """Release all domain's devices. Nothrow guarantee.""" if self.image: try: log.debug("Destroying device model") self.image.destroyDeviceModel() except Exception, e: log.exception("Device model destroy failed %s" % str(e)) else: log.debug("No device model") log.debug("Releasing devices") t = xstransact("%s/device" % self.dompath) try: for devclass in XendDevices.valid_devices(): for dev in t.list(devclass): try: log.debug("Removing %s", dev); self.destroyDevice(devclass, dev, False); except: # Log and swallow any exceptions in removal -- # there's nothing more we can do. log.exception("Device release failed: %s; %s; %s", self.info['name_label'], devclass, dev) finally: t.abort() def getDeviceController(self, name): """Get the device controller for this domain, and if it doesn't exist, create it. @param name: device class name @type name: string @rtype: subclass of DevController """ if name not in self._deviceControllers: devController = XendDevices.make_controller(name, self) if not devController: raise XendError("Unknown device type: %s" % name) self._deviceControllers[name] = devController return self._deviceControllers[name] # # Migration functions (public) # def testMigrateDevices(self, network, dst): """ Notify all device about intention of migration @raise: XendError for a device that cannot be migrated """ for (n, c) in self.info.all_devices_sxpr(): rc = self.migrateDevice(n, c, network, dst, DEV_MIGRATE_TEST, self.getName()) if rc != 0: raise XendError("Device of type '%s' refuses migration." % n) def migrateDevices(self, network, dst, step, domName=''): """Notify the devices about migration """ ctr = 0 try: for (dev_type, dev_conf) in self.info.all_devices_sxpr(): self.migrateDevice(dev_type, dev_conf, network, dst, step, domName) ctr = ctr + 1 except: for dev_type, dev_conf in self.info.all_devices_sxpr(): if ctr == 0: step = step - 1 ctr = ctr - 1 self._recoverMigrateDevice(dev_type, dev_conf, network, dst, step, domName) raise def migrateDevice(self, deviceClass, deviceConfig, network, dst, step, domName=''): return self.getDeviceController(deviceClass).migrate(deviceConfig, network, dst, step, domName) def _recoverMigrateDevice(self, deviceClass, deviceConfig, network, dst, step, domName=''): return self.getDeviceController(deviceClass).recover_migrate( deviceConfig, network, dst, step, domName) ## private: def _constructDomain(self): """Construct the domain. @raise: VmError on error """ log.debug('XendDomainInfo.constructDomain') self.shutdownStartTime = None hvm = self.info.is_hvm() if hvm: info = xc.xeninfo() if 'hvm' not in info['xen_caps']: raise VmError("HVM guest support is unavailable: is VT/AMD-V " "supported by your CPU and enabled in your " "BIOS?") # Hack to pre-reserve some memory for initial domain creation. # There is an implicit memory overhead for any domain creation. This # overhead is greater for some types of domain than others. For # example, an x86 HVM domain will have a default shadow-pagetable # allocation of 1MB. We free up 2MB here to be on the safe side. balloon.free(2*1024) # 2MB should be plenty ssidref = 0 if security.on(): ssidref = security.calc_dom_ssidref_from_info(self.info) if security.has_authorization(ssidref) == False: raise VmError("VM is not authorized to run.") try: self.domid = xc.domain_create( domid = 0, ssidref = ssidref, handle = uuid.fromString(self.info['uuid']), hvm = int(hvm)) except Exception, e: # may get here if due to ACM the operation is not permitted if security.on(): raise VmError('Domain in conflict set with running domain?') if self.domid < 0: raise VmError('Creating domain failed: name=%s' % self.info['name_label']) self.dompath = GetDomainPath(self.domid) self._recreateDom() # Set timer configration of domain timer_mode = self.info["platform"].get("timer_mode") if hvm and timer_mode is not None: xc.hvm_set_param(self.domid, HVM_PARAM_TIMER_MODE, long(timer_mode)) # Set maximum number of vcpus in domain xc.domain_max_vcpus(self.domid, int(self.info['VCPUs_max'])) # Test whether the devices can be assigned with VT-d pci_str = str(self.info["platform"].get("pci")) if hvm and pci_str: bdf = xc.test_assign_device(self.domid, pci_str) if bdf != 0: 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 VT-d is " "not enabled, or the device is not exist, or it " "has already been assigned to other domain" % (bus, dev, func)) # register the domain in the list from xen.xend import XendDomain XendDomain.instance().add_domain(self) def _introduceDomain(self): assert self.domid is not None assert self.store_mfn is not None assert self.store_port is not None try: IntroduceDomain(self.domid, self.store_mfn, self.store_port) except RuntimeError, exn: raise XendError(str(exn)) def _initDomain(self): log.debug('XendDomainInfo.initDomain: %s %s', self.domid, self.info['vcpus_params']['weight']) self._configureBootloader() try: if self.info['platform'].get('localtime', 0): if time.localtime(time.time())[8]: self.info['platform']['rtc_timeoffset'] = -time.altzone else: self.info['platform']['rtc_timeoffset'] = -time.timezone self.image = image.create(self, self.info) xc.domain_setcpuweight(self.domid, \ self.info['vcpus_params']['weight']) # repin domain vcpus if a restricted cpus list is provided # this is done prior to memory allocation to aide in memory # distribution for NUMA systems. if self.info['cpus'] is not None and len(self.info['cpus']) > 0: for v in range(0, self.info['VCPUs_max']): xc.vcpu_setaffinity(self.domid, v, self.info['cpus']) # Use architecture- and image-specific calculations to determine # the various headrooms necessary, given the raw configured # values. maxmem, memory, and shadow are all in KiB. # but memory_static_max etc are all stored in bytes now. memory = self.image.getRequiredAvailableMemory( self.info['memory_dynamic_max'] / 1024) maxmem = self.image.getRequiredAvailableMemory( self.info['memory_static_max'] / 1024) shadow = self.image.getRequiredShadowMemory( self.info['shadow_memory'] * 1024, self.info['memory_static_max'] / 1024) log.debug("_initDomain:shadow_memory=0x%x, memory_static_max=0x%x, memory_static_min=0x%x.", self.info['shadow_memory'], self.info['memory_static_max'], self.info['memory_static_min'],) # Round shadow up to a multiple of a MiB, as shadow_mem_control # takes MiB and we must not round down and end up under-providing. shadow = ((shadow + 1023) / 1024) * 1024 # set memory limit xc.domain_setmaxmem(self.domid, maxmem) # Make sure there's enough RAM available for the domain balloon.free(memory + shadow) # Set up the shadow memory shadow_cur = xc.shadow_mem_control(self.domid, shadow / 1024) self.info['shadow_memory'] = shadow_cur self._createChannels() channel_details = self.image.createImage() self.store_mfn = channel_details['store_mfn'] if 'console_mfn' in channel_details: self.console_mfn = channel_details['console_mfn'] if 'notes' in channel_details: self.info.set_notes(channel_details['notes']) if 'native_protocol' in channel_details: self.native_protocol = channel_details['native_protocol']; self._introduceDomain() self._createDevices() self.i
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -