⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 image.py

📁 xen 3.2.2 源码
💻 PY
📖 第 1 页 / 共 2 页
字号:
#============================================================================# 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) 2005 Mike Wray <mike.wray@hp.com># Copyright (C) 2005-2007 XenSource Ltd#============================================================================import os, os.path, stringimport reimport mathimport timeimport signalimport xen.lowlevel.xcfrom xen.xend.XendConstants import *from xen.xend.XendError import VmError, XendError, HVMRequiredfrom xen.xend.XendLogging import logfrom xen.xend.XendOptions import instance as xenoptsfrom xen.xend.xenstore.xstransact import xstransactfrom xen.xend.xenstore.xswatch import xswatchfrom xen.xend import archfrom xen.xend import XendOptionsxc = xen.lowlevel.xc.xc()MAX_GUEST_CMDLINE = 1024def create(vm, vmConfig):    """Create an image handler for a vm.    @return ImageHandler instance    """    return findImageHandlerClass(vmConfig)(vm, vmConfig)class ImageHandler:    """Abstract base class for image handlers.    createImage() is called to configure and build the domain from its    kernel image and ramdisk etc.    The method buildDomain() is used to build the domain, and must be    defined in a subclass.  Usually this is the only method that needs    defining in a subclass.    The method createDeviceModel() is called to create the domain device    model.    The method destroyDeviceModel() is called to reap the device model    """    ostype = None    def __init__(self, vm, vmConfig):        self.vm = vm        self.bootloader = False        self.kernel = None        self.ramdisk = None        self.cmdline = None        self.configure(vmConfig)    def configure(self, vmConfig):        """Config actions common to all unix-like domains."""        if '_temp_using_bootloader' in vmConfig:            self.bootloader = True            self.kernel = vmConfig['_temp_kernel']            self.cmdline = vmConfig['_temp_args']            self.ramdisk = vmConfig['_temp_ramdisk']        else:            self.kernel = vmConfig['PV_kernel']            self.cmdline = vmConfig['PV_args']            self.ramdisk = vmConfig['PV_ramdisk']        self.vm.storeVm(("image/ostype", self.ostype),                        ("image/kernel", self.kernel),                        ("image/cmdline", self.cmdline),                        ("image/ramdisk", self.ramdisk))        self.device_model = vmConfig['platform'].get('device_model')        self.display = vmConfig['platform'].get('display')        self.xauthority = vmConfig['platform'].get('xauthority')        self.vncconsole = vmConfig['platform'].get('vncconsole')        self.dmargs = self.parseDeviceModelArgs(vmConfig)        self.pid = None    def cleanupBootloading(self):        if self.bootloader:            self.unlink(self.kernel)            self.unlink(self.ramdisk)    def unlink(self, f):        if not f: return        try:            os.unlink(f)        except OSError, ex:            log.warning("error removing bootloader file '%s': %s", f, ex)    def createImage(self):        """Entry point to create domain memory image.        Override in subclass  if needed.        """        return self.createDomain()    def createDomain(self):        """Build the domain boot image.        """        # Set params and call buildDomain().        if not os.path.isfile(self.kernel):            raise VmError('Kernel image does not exist: %s' % self.kernel)        if self.ramdisk and not os.path.isfile(self.ramdisk):            raise VmError('Kernel ramdisk does not exist: %s' % self.ramdisk)        if len(self.cmdline) >= MAX_GUEST_CMDLINE:            log.warning('kernel cmdline too long, domain %d',                        self.vm.getDomid())                log.info("buildDomain os=%s dom=%d vcpus=%d", self.ostype,                 self.vm.getDomid(), self.vm.getVCpuCount())        result = self.buildDomain()        if isinstance(result, dict):            return result        else:            raise VmError('Building domain failed: ostype=%s dom=%d err=%s'                          % (self.ostype, self.vm.getDomid(), str(result)))    def getRequiredAvailableMemory(self, mem_kb):        """@param mem_kb The configured maxmem or memory, in KiB.        @return The corresponding required amount of memory for the domain,        also in KiB.  This is normally the given mem_kb, but architecture- or        image-specific code may override this to add headroom where        necessary."""        return mem_kb    def getRequiredInitialReservation(self):        """@param mem_kb The configured memory, in KiB.        @return The corresponding required amount of memory to be free, also        in KiB. This is normally the same as getRequiredAvailableMemory, but        architecture- or image-specific code may override this to        add headroom where necessary."""        return self.getRequiredAvailableMemory(self.vm.getMemoryTarget())    def getRequiredMaximumReservation(self):        """@param mem_kb The maximum possible memory, in KiB.        @return The corresponding required amount of memory to be free, also        in KiB. This is normally the same as getRequiredAvailableMemory, but        architecture- or image-specific code may override this to        add headroom where necessary."""        return self.getRequiredAvailableMemory(self.vm.getMemoryMaximum())    def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):        """@param shadow_mem_kb The configured shadow memory, in KiB.        @param maxmem_kb The configured maxmem, in KiB.        @return The corresponding required amount of shadow memory, also in        KiB."""        # PV domains don't need any shadow memory        return 0    def buildDomain(self):        """Build the domain. Define in subclass."""        raise NotImplementedError()    # Return a list of cmd line args to the device models based on the    # xm config file    def parseDeviceModelArgs(self, vmConfig):        ret = ["-domain-name", str(self.vm.info['name_label'])]        # Find RFB console device, and if it exists, make QEMU enable        # the VNC console.        if int(vmConfig['platform'].get('nographic', 0)) != 0:            # skip vnc init if nographic is set            ret.append('-nographic')            return ret        vnc_config = {}        has_vnc = int(vmConfig['platform'].get('vnc', 0)) != 0        has_sdl = int(vmConfig['platform'].get('sdl', 0)) != 0        for dev_uuid in vmConfig['console_refs']:            dev_type, dev_info = vmConfig['devices'][dev_uuid]            if dev_type == 'vfb':                vfb_type = dev_info.get('type', {})                if vfb_type == 'sdl':                    self.display = dev_info.get('display', {})                    self.xauthority = dev_info.get('xauthority', {})                    has_sdl = True                else:                    vnc_config = dev_info.get('other_config', {})                    has_vnc = True                break        keymap = vmConfig['platform'].get("keymap")        if keymap:            ret.append("-k")            ret.append(keymap)        if has_vnc:            if not vnc_config:                for key in ('vncunused', 'vnclisten', 'vncdisplay',                            'vncpasswd'):                    if key in vmConfig['platform']:                        vnc_config[key] = vmConfig['platform'][key]            if vnc_config.has_key("vncpasswd"):                passwd = vnc_config["vncpasswd"]            else:                passwd = XendOptions.instance().get_vncpasswd_default()            vncopts = ""            if passwd:                self.vm.storeVm("vncpasswd", passwd)                vncopts = vncopts + ",password"                log.debug("Stored a VNC password for vfb access")            else:                log.debug("No VNC passwd configured for vfb access")            if XendOptions.instance().get_vnc_tls():                vncx509certdir = XendOptions.instance().get_vnc_x509_cert_dir()                vncx509verify = XendOptions.instance().get_vnc_x509_verify()                if not os.path.exists(vncx509certdir):                    raise VmError("VNC x509 certificate dir %s does not exist" % vncx509certdir)                if vncx509verify:                    vncopts = vncopts + ",tls,x509verify=%s" % vncx509certdir                else:                    vncopts = vncopts + ",tls,x509=%s" % vncx509certdir            vnclisten = vnc_config.get('vnclisten',                                       XendOptions.instance().get_vnclisten_address())            vncdisplay = vnc_config.get('vncdisplay', 0)            ret.append('-vnc')            ret.append("%s:%s%s" % (vnclisten, vncdisplay, vncopts))            if vnc_config.get('vncunused', 0):                ret.append('-vncunused')        elif has_sdl:            # SDL is default in QEMU.            pass        else:            ret.append('-nographic')        if int(vmConfig['platform'].get('monitor', 0)) != 0:            ret = ret + ['-monitor', 'vc']        return ret    def getDeviceModelArgs(self, restore = False):        args = [self.device_model]        args = args + ([ "-d",  "%d" % self.vm.getDomid() ])        args = args + self.dmargs        return args    def createDeviceModel(self, restore = False):        if self.device_model is None:            return        if self.pid:            return        # Execute device model.        #todo: Error handling        args = self.getDeviceModelArgs(restore)        env = dict(os.environ)        if self.display:            env['DISPLAY'] = self.display        if self.xauthority:            env['XAUTHORITY'] = self.xauthority        if self.vncconsole:            args = args + ([ "-vncviewer" ])        log.info("spawning device models: %s %s", self.device_model, args)        # keep track of pid and spawned options to kill it later        self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env)        self.vm.storeDom("image/device-model-pid", self.pid)        log.info("device model pid: %d", self.pid)    def saveDeviceModel(self):        if self.device_model is None:            return        # Signal the device model to pause itself and save its state        xstransact.Store("/local/domain/0/device-model/%i"                         % self.vm.getDomid(), ('command', 'save'))        # Wait for confirmation.  Could do this with a watch but we'd        # still end up spinning here waiting for the watch to fire.         state = ''        count = 0        while state != 'paused':            state = xstransact.Read("/local/domain/0/device-model/%i/state"                                    % self.vm.getDomid())            time.sleep(0.1)            count += 1            if count > 100:                raise VmError('Timed out waiting for device model to save')    def resumeDeviceModel(self):        if self.device_model is None:            return        # Signal the device model to resume activity after pausing to save.        xstransact.Store("/local/domain/0/device-model/%i"                         % self.vm.getDomid(), ('command', 'continue'))    def recreate(self):        if self.device_model is None:            return        self.pid = self.vm.gatherDom(('image/device-model-pid', int))    def destroyDeviceModel(self):        if self.device_model is None:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -