📄 xenddomaininfo.py
字号:
self.info["static_memory_max"] = val changed = True # Check whether image definition has been updated image_sxp = self._readVm('image') if image_sxp and image_sxp != sxp.to_string(self.info.image_sxpr()): self.info.update_with_image_sxp(sxp.from_string(image_sxp)) changed = True # Check if the rtc offset has changes if vm_details.get("rtc/timeoffset", "0") != self.info["platform"].get("rtc_timeoffset", "0"): self.info["platform"]["rtc_timeoffset"] = vm_details.get("rtc/timeoffset", 0) changed = True if changed: # Update the domain section of the store, as this contains some # parameters derived from the VM configuration. self._storeDomDetails() return 1 def _handleShutdownWatch(self, _): log.debug('XendDomainInfo.handleShutdownWatch') reason = self.readDom('control/shutdown') if reason and reason != 'suspend': sst = self.readDom('xend/shutdown_start_time') now = time.time() if sst: self.shutdownStartTime = float(sst) timeout = float(sst) + SHUTDOWN_TIMEOUT - now else: self.shutdownStartTime = now self.storeDom('xend/shutdown_start_time', now) timeout = SHUTDOWN_TIMEOUT log.trace( "Scheduling refreshShutdown on domain %d in %ds.", self.domid, timeout) threading.Timer(timeout, self.refreshShutdown).start() return True # # Public Attributes for the VM # def getDomid(self): return self.domid def setName(self, name, to_store = True): self._checkName(name) self.info['name_label'] = name if to_store: self.storeVm("name", name) def getName(self): return self.info['name_label'] def getDomainPath(self): return self.dompath def getShutdownReason(self): return self.readDom('control/shutdown') def getStorePort(self): """For use only by image.py and XendCheckpoint.py.""" return self.store_port def getConsolePort(self): """For use only by image.py and XendCheckpoint.py""" return self.console_port def getFeatures(self): """For use only by image.py.""" return self.info['features'] def getVCpuCount(self): return self.info['VCPUs_max'] def setVCpuCount(self, vcpus): if vcpus <= 0: raise XendError('Invalid VCPUs') self.info['vcpu_avail'] = (1 << vcpus) - 1 if self.domid >= 0: self.storeVm('vcpu_avail', self.info['vcpu_avail']) # update dom differently depending on whether we are adjusting # vcpu number up or down, otherwise _vcpuDomDetails does not # disable the vcpus if self.info['VCPUs_max'] > vcpus: # decreasing self._writeDom(self._vcpuDomDetails()) self.info['VCPUs_live'] = vcpus else: # same or increasing self.info['VCPUs_live'] = vcpus self._writeDom(self._vcpuDomDetails()) else: if self.info['VCPUs_max'] > vcpus: # decreasing del self.info['cpus'][vcpus:] elif self.info['VCPUs_max'] < vcpus: # increasing for c in range(self.info['VCPUs_max'], vcpus): self.info['cpus'].append(list()) self.info['VCPUs_max'] = vcpus xen.xend.XendDomain.instance().managed_config_save(self) log.info("Set VCPU count on domain %s to %d", self.info['name_label'], vcpus) def getMemoryTarget(self): """Get this domain's target memory size, in KB.""" return self.info['memory_dynamic_max'] / 1024 def getMemoryMaximum(self): """Get this domain's maximum memory size, in KB.""" # remember, info now stores memory in bytes return self.info['memory_static_max'] / 1024 def getResume(self): return str(self._resume) def setResume(self, isresume): self._resume = isresume def getCpus(self): return self.info['cpus'] def setCpus(self, cpumap): self.info['cpus'] = cpumap def getCap(self): return self.info['vcpus_params']['cap'] def setCap(self, cpu_cap): self.info['vcpus_params']['cap'] = cpu_cap def getWeight(self): return self.info['vcpus_params']['weight'] def setWeight(self, cpu_weight): self.info['vcpus_params']['weight'] = cpu_weight def getRestartCount(self): return self._readVm('xend/restart_count') def refreshShutdown(self, xeninfo = None): """ Checks the domain for whether a shutdown is required. Called from XendDomainInfo and also image.py for HVM images. """ # If set at the end of this method, a restart is required, with the # given reason. This restart has to be done out of the scope of # refresh_shutdown_lock. restart_reason = None self.refresh_shutdown_lock.acquire() try: if xeninfo is None: xeninfo = dom_get(self.domid) if xeninfo is None: # The domain no longer exists. This will occur if we have # scheduled a timer to check for shutdown timeouts and the # shutdown succeeded. It will also occur if someone # destroys a domain beneath us. We clean up the domain, # just in case, but we can't clean up the VM, because that # VM may have migrated to a different domain on this # machine. self.cleanupDomain() self._stateSet(DOM_STATE_HALTED) return if xeninfo['dying']: # Dying means that a domain has been destroyed, but has not # yet been cleaned up by Xen. This state could persist # indefinitely if, for example, another domain has some of its # pages mapped. We might like to diagnose this problem in the # future, but for now all we do is make sure that it's not us # holding the pages, by calling cleanupDomain. We can't # clean up the VM, as above. self.cleanupDomain() self._stateSet(DOM_STATE_SHUTDOWN) return elif xeninfo['crashed']: if self.readDom('xend/shutdown_completed'): # We've seen this shutdown already, but we are preserving # the domain for debugging. Leave it alone. return log.warn('Domain has crashed: name=%s id=%d.', self.info['name_label'], self.domid) self._writeVm(LAST_SHUTDOWN_REASON, 'crash') restart_reason = 'crash' self._stateSet(DOM_STATE_HALTED) elif xeninfo['shutdown']: self._stateSet(DOM_STATE_SHUTDOWN) if self.readDom('xend/shutdown_completed'): # We've seen this shutdown already, but we are preserving # the domain for debugging. Leave it alone. return else: reason = shutdown_reason(xeninfo['shutdown_reason']) log.info('Domain has shutdown: name=%s id=%d reason=%s.', self.info['name_label'], self.domid, reason) self._writeVm(LAST_SHUTDOWN_REASON, reason) self._clearRestart() if reason == 'suspend': self._stateSet(DOM_STATE_SUSPENDED) # Don't destroy the domain. XendCheckpoint will do # this once it has finished. However, stop watching # the VM path now, otherwise we will end up with one # watch for the old domain, and one for the new. self._unwatchVm() elif reason in ('poweroff', 'reboot'): restart_reason = reason else: self.destroy() elif self.dompath is None: # We have yet to manage to call introduceDomain on this # domain. This can happen if a restore is in progress, or has # failed. Ignore this domain. pass else: # Domain is alive. If we are shutting it down, log a message # if it seems unresponsive. if xeninfo['paused']: self._stateSet(DOM_STATE_PAUSED) else: self._stateSet(DOM_STATE_RUNNING) if self.shutdownStartTime: timeout = (SHUTDOWN_TIMEOUT - time.time() + self.shutdownStartTime) if (timeout < 0 and not self.readDom('xend/unresponsive')): log.info( "Domain shutdown timeout expired: name=%s id=%s", self.info['name_label'], self.domid) self.storeDom('xend/unresponsive', 'True') finally: self.refresh_shutdown_lock.release() if restart_reason: threading.Thread(target = self._maybeRestart, args = (restart_reason,)).start() # # Restart functions - handling whether we come back up on shutdown. # def _clearRestart(self): self._removeDom("xend/shutdown_start_time") def _maybeDumpCore(self, reason): if reason == 'crash': if xoptions.get_enable_dump() or self.get_on_crash() \ in ['coredump_and_destroy', 'coredump_and_restart']: try: self.dumpCore() except XendError: # This error has been logged -- there's nothing more # we can do in this context. pass def _maybeRestart(self, reason): # Before taking configured action, dump core if configured to do so. # self._maybeDumpCore(reason) # Dispatch to the correct method based upon the configured on_{reason} # behaviour. actions = {"destroy" : self.destroy, "restart" : self._restart, "preserve" : self._preserve, "rename-restart" : self._renameRestart, "coredump-destroy" : self.destroy, "coredump-restart" : self._restart} action_conf = { 'poweroff': 'actions_after_shutdown', 'reboot': 'actions_after_reboot', 'crash': 'actions_after_crash', } action_target = self.info.get(action_conf.get(reason)) func = actions.get(action_target, None) if func and callable(func): func() else: self.destroy() # default to destroy def _renameRestart(self): self._restart(True) def _restart(self, rename = False): """Restart the domain after it has exited. @param rename True if the old domain is to be renamed and preserved, False if it is to be destroyed. """ from xen.xend import XendDomain if self._readVm(RESTART_IN_PROGRESS): log.error('Xend failed during restart of domain %s. ' 'Refusing to restart to avoid loops.', str(self.domid)) self.destroy() return old_domid = self.domid self._writeVm(RESTART_IN_PROGRESS, 'True') now = time.time() rst = self._readVm('xend/previous_restart_time') if rst: rst = float(rst) timeout = now - rst if timeout < MINIMUM_RESTART_TIME: log.error( 'VM %s restarting too fast (%f seconds since the last ' 'restart). Refusing to restart to avoid loops.', self.info['name_label'], timeout) self.destroy() return self._writeVm('xend/previous_restart_time', str(now)) prev_vm_xend = self._listRecursiveVm('xend') new_dom_info = self.info try: if rename: new_dom_info = self._preserveForRestart() else: self._unwatchVm() self.destroy() # new_dom's VM will be the same as this domain's VM, except where # the rename flag has instructed us to call preserveForRestart. # In that case, it is important that we remove the # RESTART_IN_PROGRESS node from the new domain, not the old one, # once
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -