📄 xenddomaininfo.py
字号:
#===========================================================================# This library is free software; you can redistribute it and/or# modify it under the terms of version 2.1 of the GNU Lesser General Public# License as published by the Free Software Foundation.## This library is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU# Lesser General Public License for more details.## You should have received a copy of the GNU Lesser General Public# License along with this library; if not, write to the Free Software# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA#============================================================================# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com># Copyright (C) 2005-2007 XenSource Ltd#============================================================================"""Representation of a single domain.Includes support for domain construction, usingopen-ended configurations.Author: Mike Wray <mike.wray@hp.com>"""import loggingimport timeimport threadingimport reimport copyimport osimport tracebackfrom types import StringTypesimport xen.lowlevel.xcfrom xen.util import assertsfrom xen.util.blkif import blkdev_uname_to_file, blkdev_uname_to_taptypeimport xen.util.xsm.xsm as securityfrom xen.util import xsconstantsfrom xen.xend import balloon, sxp, uuid, image, arch, osdepfrom xen.xend import XendOptions, XendNode, XendConfigfrom xen.xend.XendConfig import scrub_passwordfrom xen.xend.XendBootloader import bootloader, bootloader_tidyfrom xen.xend.XendError import XendError, VmErrorfrom xen.xend.XendDevices import XendDevicesfrom xen.xend.XendTask import XendTaskfrom xen.xend.xenstore.xstransact import xstransact, completefrom xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain, SetTarget, ResumeDomainfrom xen.xend.xenstore.xswatch import xswatchfrom xen.xend.XendConstants import *from xen.xend.XendAPIConstants import *from xen.xend.XendVMMetrics import XendVMMetricsfrom xen.xend.XendPPCI import XendPPCIfrom xen.xend.XendDPCI import XendDPCIfrom xen.xend import XendAPIStoreMIGRATE_TIMEOUT = 30.0BOOTLOADER_LOOPBACK_DEVICE = '/dev/xvdp'xc = xen.lowlevel.xc.xc()xoptions = XendOptions.instance()log = logging.getLogger("xend.XendDomainInfo")#log.setLevel(logging.TRACE)def create(config): """Creates and start a VM using the supplied configuration. @param config: A configuration object involving lists of tuples. @type config: list of lists, eg ['vm', ['image', 'xen.gz']] @rtype: XendDomainInfo @return: An up and running XendDomainInfo instance @raise VmError: Invalid configuration or failure to start. """ from xen.xend import XendDomain domconfig = XendConfig.XendConfig(sxp_obj = config) othervm = XendDomain.instance().domain_lookup_nr(domconfig["name_label"]) if othervm is None or othervm.domid is None: othervm = XendDomain.instance().domain_lookup_nr(domconfig["uuid"]) if othervm is not None and othervm.domid is not None: raise VmError("Domain '%s' already exists with ID '%d'" % (domconfig["name_label"], othervm.domid)) log.debug("XendDomainInfo.create(%s)", scrub_password(config)) vm = XendDomainInfo(domconfig) try: vm.start() except: log.exception('Domain construction failed') vm.destroy() raise return vmdef create_from_dict(config_dict): """Creates and start a VM using the supplied configuration. @param config_dict: An configuration dictionary. @rtype: XendDomainInfo @return: An up and running XendDomainInfo instance @raise VmError: Invalid configuration or failure to start. """ log.debug("XendDomainInfo.create_from_dict(%s)", scrub_password(config_dict)) vm = XendDomainInfo(XendConfig.XendConfig(xapi = config_dict)) try: vm.start() except: log.exception('Domain construction failed') vm.destroy() raise return vmdef recreate(info, priv): """Create the VM object for an existing domain. The domain must not be dying, as the paths in the store should already have been removed, and asking us to recreate them causes problems. @param xeninfo: Parsed configuration @type xeninfo: Dictionary @param priv: Is a privileged domain (Dom 0) @type priv: bool @rtype: XendDomainInfo @return: A up and running XendDomainInfo instance @raise VmError: Invalid configuration. @raise XendError: Errors with configuration. """ log.debug("XendDomainInfo.recreate(%s)", scrub_password(info)) assert not info['dying'] xeninfo = XendConfig.XendConfig(dominfo = info) xeninfo['is_control_domain'] = priv xeninfo['is_a_template'] = False domid = xeninfo['domid'] uuid1 = uuid.fromString(xeninfo['uuid']) needs_reinitialising = False dompath = GetDomainPath(domid) if not dompath: raise XendError('No domain path in store for existing ' 'domain %d' % domid) log.info("Recreating domain %d, UUID %s. at %s" % (domid, xeninfo['uuid'], dompath)) # need to verify the path and uuid if not Domain-0 # if the required uuid and vm aren't set, then that means # we need to recreate the dom with our own values # # NOTE: this is probably not desirable, really we should just # abort or ignore, but there may be cases where xenstore's # entry disappears (eg. xenstore-rm /) # try: vmpath = xstransact.Read(dompath, "vm") if not vmpath: if not priv: log.warn('/local/domain/%d/vm is missing. recreate is ' 'confused, trying our best to recover' % domid) needs_reinitialising = True raise XendError('reinit') uuid2_str = xstransact.Read(vmpath, "uuid") if not uuid2_str: log.warn('%s/uuid/ is missing. recreate is confused, ' 'trying our best to recover' % vmpath) needs_reinitialising = True raise XendError('reinit') uuid2 = uuid.fromString(uuid2_str) if uuid1 != uuid2: log.warn('UUID in /vm does not match the UUID in /dom/%d.' 'Trying out best to recover' % domid) needs_reinitialising = True except XendError: pass # our best shot at 'goto' in python :) vm = XendDomainInfo(xeninfo, domid, dompath, augment = True, priv = priv, vmpath = vmpath) if needs_reinitialising: vm._recreateDom() vm._removeVm() vm._storeVmDetails() vm._storeDomDetails() vm.image = image.create(vm, vm.info) vm.image.recreate() vm._registerWatches() vm.refreshShutdown(xeninfo) # register the domain in the list from xen.xend import XendDomain XendDomain.instance().add_domain(vm) return vmdef restore(config): """Create a domain and a VM object to do a restore. @param config: Domain SXP configuration @type config: list of lists. (see C{create}) @rtype: XendDomainInfo @return: A up and running XendDomainInfo instance @raise VmError: Invalid configuration or failure to start. @raise XendError: Errors with configuration. """ log.debug("XendDomainInfo.restore(%s)", scrub_password(config)) vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config), resume = True) try: vm.resume() return vm except: vm.destroy() raisedef createDormant(domconfig): """Create a dormant/inactive XenDomainInfo without creating VM. This is for creating instances of persistent domains that are not yet start. @param domconfig: Parsed configuration @type domconfig: XendConfig object @rtype: XendDomainInfo @return: A up and running XendDomainInfo instance @raise XendError: Errors with configuration. """ log.debug("XendDomainInfo.createDormant(%s)", scrub_password(domconfig)) # domid does not make sense for non-running domains. domconfig.pop('domid', None) vm = XendDomainInfo(domconfig) return vm def domain_by_name(name): """Get domain by name @params name: Name of the domain @type name: string @return: XendDomainInfo or None """ from xen.xend import XendDomain return XendDomain.instance().domain_lookup_by_name_nr(name)def shutdown_reason(code): """Get a shutdown reason from a code. @param code: shutdown code @type code: int @return: shutdown reason @rtype: string """ return DOMAIN_SHUTDOWN_REASONS.get(code, "?")def dom_get(dom): """Get info from xen for an existing domain. @param dom: domain id @type dom: int @return: info or None @rtype: dictionary """ try: domlist = xc.domain_getinfo(dom, 1) if domlist and dom == domlist[0]['domid']: return domlist[0] except Exception, err: # ignore missing domain log.trace("domain_getinfo(%d) failed, ignoring: %s", dom, str(err)) return Noneclass XendDomainInfo: """An object represents a domain. @TODO: try to unify dom and domid, they mean the same thing, but xc refers to it as dom, and everywhere else, including xenstore it is domid. The best way is to change xc's python interface. @ivar info: Parsed configuration @type info: dictionary @ivar domid: Domain ID (if VM has started) @type domid: int or None @ivar vmpath: XenStore path to this VM. @type vmpath: string @ivar dompath: XenStore path to this Domain. @type dompath: string @ivar image: Reference to the VM Image. @type image: xen.xend.image.ImageHandler @ivar store_port: event channel to xenstored @type store_port: int @ivar console_port: event channel to xenconsoled @type console_port: int @ivar store_mfn: xenstored mfn @type store_mfn: int @ivar console_mfn: xenconsoled mfn @type console_mfn: int @ivar notes: OS image notes @type notes: dictionary @ivar vmWatch: reference to a watch on the xenstored vmpath @type vmWatch: xen.xend.xenstore.xswatch @ivar shutdownWatch: reference to watch on the xenstored domain shutdown @type shutdownWatch: xen.xend.xenstore.xswatch @ivar shutdownStartTime: UNIX Time when domain started shutting down. @type shutdownStartTime: float or None# @ivar state: Domain state# @type state: enum(DOM_STATE_HALTED, DOM_STATE_RUNNING, ...) @ivar state_updated: lock for self.state @type state_updated: threading.Condition @ivar refresh_shutdown_lock: lock for polling shutdown state @type refresh_shutdown_lock: threading.Condition @ivar _deviceControllers: device controller cache for this domain @type _deviceControllers: dict 'string' to DevControllers """ def __init__(self, info, domid = None, dompath = None, augment = False, priv = False, resume = False, vmpath = None): """Constructor for a domain @param info: parsed configuration @type info: dictionary @keyword domid: Set initial domain id (if any) @type domid: int @keyword dompath: Set initial dompath (if any) @type dompath: string @keyword augment: Augment given info with xenstored VM info @type augment: bool @keyword priv: Is a privileged domain (Dom 0) @type priv: bool @keyword resume: Is this domain being resumed? @type resume: bool """ self.info = info if domid == None: self.domid = self.info.get('domid')
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -