[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] PATCH 9/10: XenD device model re-factoring
This patches adapts XenD so that it is capable of starting a qemu-dm device model for both paravirt and fullyvirt guests. A paravirt guest will only be given a device model if it has a VFB configured, or the user explicitly include the device_model option in the config config. This avoids unneccessary overhead for those wanting a minimal paravirt guest. The bulk of this patch involves moving code from the HVMImageHandler into the base ImageHandler class. The HVMImageHandler and LinuxImageHandler subclasses now merely containing a couple of overrides to set some specific command line flags. The most important is -M xenpv, vs -M xenfv. The XenConfig class has a minor refactoring to add a has_rfb() method to avoid duplicating code in a couple of places. Instead of hardcoding DEFAULT_DM it now uses the xen.util.auxbin APIs to locate it - this works on platforms where qemu-dm is in /usr/lib64 instead of /usr/lib. As before paravirt only gets a default qemu-dm if using a VFB The vfbif.py class is trimmed out since it no longer needs to spawn a daemon. A few other misc fixes deal with qemu-dm interactions when saving/restoring, and in particular recovering from save failures (or checkpointing). XendCheckpoint.py | 5 XendConfig.py | 35 ++-- XendDomainInfo.py | 23 +-- image.py | 382 ++++++++++++++++++++++++++++-------------------------- server/vfbif.py | 108 ++------------- 5 files changed, 251 insertions(+), 302 deletions(-) Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> diff -r f0a3bb81fbe3 tools/python/xen/xend/XendCheckpoint.py --- a/tools/python/xen/xend/XendCheckpoint.py Wed Oct 24 15:31:33 2007 -0400 +++ b/tools/python/xen/xend/XendCheckpoint.py Wed Oct 24 15:57:32 2007 -0400 @@ -6,6 +6,7 @@ # this archive for more details. import os +import os.path import re import string import threading @@ -108,7 +109,7 @@ def save(fd, dominfo, network, live, dst forkHelper(cmd, fd, saveInputHandler, False) # put qemu device model state - if hvm: + if os.path.exists("/var/lib/xen/qemu-save.%d" % dominfo.getDomid()): write_exact(fd, QEMU_SIGNATURE, "could not write qemu signature") qemu_fd = os.open("/var/lib/xen/qemu-save.%d" % dominfo.getDomid(), os.O_RDONLY) @@ -245,6 +246,8 @@ def restore(xd, fd, dominfo = None, paus raise XendError('Could not read console MFN') # get qemu state and create a tmp file for dm restore + # Even PV guests may have QEMU stat, but its not currently + # used so only bother with HVM currently. if is_hvm: qemu_signature = read_exact(fd, len(QEMU_SIGNATURE), "invalid device model signature read") diff -r f0a3bb81fbe3 tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Wed Oct 24 15:31:33 2007 -0400 +++ b/tools/python/xen/xend/XendConfig.py Wed Oct 24 15:31:35 2007 -0400 @@ -32,6 +32,7 @@ from xen.xend.server.netif import random from xen.xend.server.netif import randomMAC from xen.util.blkif import blkdev_name_to_number from xen.util import xsconstants +import xen.util.auxbin log = logging.getLogger("xend.XendConfig") log.setLevel(logging.WARN) @@ -233,8 +234,6 @@ LEGACY_XENSTORE_VM_PARAMS = [ 'on_xend_start', 'on_xend_stop', ] - -DEFAULT_DM = '/usr/lib/xen/bin/qemu-dm' ## ## Config Choices @@ -393,13 +392,14 @@ class XendConfig(dict): self['name_label'] = 'Domain-' + self['uuid'] def _platform_sanity_check(self): + if 'keymap' not in self['platform'] and XendOptions.instance().get_keymap(): + self['platform']['keymap'] = XendOptions.instance().get_keymap() + + if self.is_hvm() or self.has_rfb(): + if 'device_model' not in self['platform']: + self['platform']['device_model'] = xen.util.auxbin.pathTo("qemu-dm") + if self.is_hvm(): - if 'keymap' not in self['platform'] and XendOptions.instance().get_keymap(): - self['platform']['keymap'] = XendOptions.instance().get_keymap() - - if 'device_model' not in self['platform']: - self['platform']['device_model'] = DEFAULT_DM - # Compatibility hack, can go away soon. if 'soundhw' not in self['platform'] and \ self['platform'].get('enable_audio'): @@ -744,16 +744,7 @@ class XendConfig(dict): # coalesce hvm vnc frame buffer with vfb config if self.is_hvm() and int(self['platform'].get('vnc', 0)) != 0: # add vfb device if it isn't there already - has_rfb = False - for console_uuid in self['console_refs']: - if self['devices'][console_uuid][1].get('protocol') == 'rfb': - has_rfb = True - break - if self['devices'][console_uuid][0] == 'vfb': - has_rfb = True - break - - if not has_rfb: + if not self.has_rfb(): dev_config = ['vfb'] dev_config.append(['type', 'vnc']) # copy VNC related params from platform config to vfb dev conf @@ -764,6 +755,14 @@ class XendConfig(dict): self.device_add('vfb', cfg_sxp = dev_config) + + def has_rfb(self): + for console_uuid in self['console_refs']: + if self['devices'][console_uuid][1].get('protocol') == 'rfb': + return True + if self['devices'][console_uuid][0] == 'vfb': + return True + return False def _sxp_to_xapi_unsupported(self, sxp_cfg): """Read in an SXP configuration object and populate diff -r f0a3bb81fbe3 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Wed Oct 24 15:31:33 2007 -0400 +++ b/tools/python/xen/xend/XendDomainInfo.py Wed Oct 24 15:58:37 2007 -0400 @@ -1455,10 +1455,16 @@ class XendDomainInfo: def _releaseDevices(self, suspend = False): """Release all domain's devices. Nothrow guarantee.""" - if suspend and self.image: - self.image.destroy(suspend) - return - + 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) for devclass in XendDevices.valid_devices(): for dev in t.list(devclass): @@ -1709,11 +1715,6 @@ class XendDomainInfo: bootloader_tidy(self) if self.image: - try: - self.image.destroy() - except: - log.exception( - "XendDomainInfo.cleanup: image.destroy() failed.") self.image = None try: @@ -1881,8 +1882,8 @@ class XendDomainInfo: ResumeDomain(self.domid) except: log.exception("XendDomainInfo.resume: xc.domain_resume failed on domain %s." % (str(self.domid))) - if self.is_hvm(): - self.image.resumeDeviceModel() + self.image.resumeDeviceModel() + log.debug("XendDomainInfo.resumeDomain: completed") # diff -r f0a3bb81fbe3 tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Wed Oct 24 15:31:33 2007 -0400 +++ b/tools/python/xen/xend/image.py Wed Oct 24 15:54:42 2007 -0400 @@ -56,10 +56,9 @@ class ImageHandler: defining in a subclass. The method createDeviceModel() is called to create the domain device - model if it needs one. The default is to do nothing. - - The method destroy() is called when the domain is destroyed. - The default is to do nothing. + model. + + The method destroyDeviceModel() is called to reap the device model """ ostype = None @@ -91,6 +90,15 @@ class ImageHandler: ("image/cmdline", self.cmdline), ("image/ramdisk", self.ramdisk)) + self.dmargs = self.parseDeviceModelArgs(vmConfig) + 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.pid = None + + def cleanupBootloading(self): if self.bootloader: @@ -173,25 +181,145 @@ class ImageHandler: """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': + 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] + + vnclisten = vnc_config.get('vnclisten', + xenopts().get_vnclisten_address()) + vncdisplay = vnc_config.get('vncdisplay', 0) + ret.append('-vnc') + ret.append("%s:%d" % (vnclisten, vncdisplay)) + + if vnc_config.get('vncunused', 0): + ret.append('-vncunused') + + # Store vncpassword in xenstore + vncpasswd = vnc_config.get('vncpasswd') + if not vncpasswd: + vncpasswd = xenopts().get_vncpasswd_default() + + if vncpasswd is None: + raise VmError('vncpasswd is not setup in vmconfig or ' + 'xend-config.sxp') + + if vncpasswd != '': + self.vm.storeVm('vncpasswd', vncpasswd) + 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): - """Create device model for the domain (define in subclass if needed).""" - pass - + 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): - """Save device model for the domain (define in subclass if needed).""" - pass + 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): - """Unpause device model for the domain (define in subclass if needed).""" - pass - - def destroy(self): - """Extra cleanup on domain destroy (define in subclass if needed).""" - pass - + 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): - pass + 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: + return + if self.pid: + try: + os.kill(self.pid, signal.SIGKILL) + except OSError, exn: + log.exception(exn) + try: + os.waitpid(self.pid, 0) + except OSError, exn: + # This is expected if Xend has been restarted within the + # life of this domain. In this case, we can kill the process, + # but we can't wait for it because it's not our child. + pass + self.pid = None + state = xstransact.Remove("/local/domain/0/device-model/%i" + % self.vm.getDomid()) class LinuxImageHandler(ImageHandler): @@ -229,6 +357,19 @@ class LinuxImageHandler(ImageHandler): flags = self.flags, vhpt = self.vhpt) + def parseDeviceModelArgs(self, vmConfig): + ret = ImageHandler.parseDeviceModelArgs(self, vmConfig) + # Equivalent to old xenconsoled behaviour. Should make + # it configurable in future + ret = ret + ["-serial", "pty"] + return ret + + def getDeviceModelArgs(self, restore = False): + args = ImageHandler.getDeviceModelArgs(self, restore) + args = args + ([ "-M", "xenpv"]) + return args + + class PPC_LinuxImageHandler(LinuxImageHandler): ostype = "linux" @@ -262,15 +403,6 @@ class HVMImageHandler(ImageHandler): if 'hvm' not in info['xen_caps']: raise HVMRequired() - self.dmargs = self.parseDeviceModelArgs(vmConfig) - self.device_model = vmConfig['platform'].get('device_model') - if not self.device_model: - raise VmError("hvm: missing device model") - - self.display = vmConfig['platform'].get('display') - self.xauthority = vmConfig['platform'].get('xauthority') - self.vncconsole = vmConfig['platform'].get('vncconsole') - rtc_timeoffset = vmConfig['platform'].get('rtc_timeoffset') self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)), @@ -278,49 +410,18 @@ class HVMImageHandler(ImageHandler): ("image/display", self.display)) self.vm.storeVm(("rtc/timeoffset", rtc_timeoffset)) - self.pid = None - self.apic = int(vmConfig['platform'].get('apic', 0)) self.acpi = int(vmConfig['platform'].get('acpi', 0)) - - - def buildDomain(self): - store_evtchn = self.vm.getStorePort() - - mem_mb = self.getRequiredInitialReservation() / 1024 - - log.debug("domid = %d", self.vm.getDomid()) - log.debug("image = %s", self.kernel) - log.debug("store_evtchn = %d", store_evtchn) - log.debug("memsize = %d", mem_mb) - log.debug("vcpus = %d", self.vm.getVCpuCount()) - log.debug("acpi = %d", self.acpi) - log.debug("apic = %d", self.apic) - - rc = xc.hvm_build(domid = self.vm.getDomid(), - image = self.kernel, - memsize = mem_mb, - vcpus = self.vm.getVCpuCount(), - acpi = self.acpi, - apic = self.apic) - - rc['notes'] = { 'SUSPEND_CANCEL': 1 } - - rc['store_mfn'] = xc.hvm_get_param(self.vm.getDomid(), - HVM_PARAM_STORE_PFN) - xc.hvm_set_param(self.vm.getDomid(), HVM_PARAM_STORE_EVTCHN, - store_evtchn) - - return rc # Return a list of cmd line args to the device models based on the # xm config file def parseDeviceModelArgs(self, vmConfig): + ret = ImageHandler.parseDeviceModelArgs(self, vmConfig) + ret = ret + ['-vcpus', str(self.vm.getVCpuCount())] + dmargs = [ 'boot', 'fda', 'fdb', 'soundhw', 'localtime', 'serial', 'stdvga', 'isa', - 'acpi', 'usb', 'usbdevice', 'keymap', 'pci' ] - - ret = ['-vcpus', str(self.vm.getVCpuCount())] + 'acpi', 'usb', 'usbdevice', 'pci' ] for a in dmargs: v = vmConfig['platform'].get(a) @@ -349,7 +450,6 @@ class HVMImageHandler(ImageHandler): # Handle disk/network related options mac = None - ret = ret + ["-domain-name", str(self.vm.info['name_label'])] nics = 0 for devuuid in vmConfig['vbd_refs']: @@ -378,130 +478,43 @@ class HVMImageHandler(ImageHandler): ret.append("-net") ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge)) - - # - # 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': - vnc_config = dev_info.get('other_config', {}) - has_vnc = True - break - - 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] - - vnclisten = vnc_config.get('vnclisten', - xenopts().get_vnclisten_address()) - vncdisplay = vnc_config.get('vncdisplay', 0) - ret.append('-vnc') - ret.append("%s:%d" % (vnclisten, vncdisplay)) - - if vnc_config.get('vncunused', 0): - ret.append('-vncunused') - - # Store vncpassword in xenstore - vncpasswd = vnc_config.get('vncpasswd') - if not vncpasswd: - vncpasswd = xenopts().get_vncpasswd_default() - - if vncpasswd is None: - raise VmError('vncpasswd is not setup in vmconfig or ' - 'xend-config.sxp') - - if vncpasswd != '': - self.vm.storeVm('vncpasswd', vncpasswd) - 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 createDeviceModel(self, restore = False): - if self.pid: - return - # Execute device model. - #todo: Error handling - args = [self.device_model] - args = args + ([ "-d", "%d" % self.vm.getDomid() ]) - if arch.type == "ia64": - args = args + ([ "-m", "%s" % - (self.getRequiredInitialReservation() / 1024) ]) - args = args + self.dmargs + def getDeviceModelArgs(self, restore = False): + args = ImageHandler.getDeviceModelArgs(self, restore) + args = args + ([ "-M", "xenfv"]) if restore: args = args + ([ "-loadvm", "/var/lib/xen/qemu-save.%d" % self.vm.getDomid() ]) - 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): - # 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): - # 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): - self.pid = self.vm.gatherDom(('image/device-model-pid', int)) - - def destroy(self, suspend = False): - if self.pid and not suspend: - try: - os.kill(self.pid, signal.SIGKILL) - except OSError, exn: - log.exception(exn) - try: - os.waitpid(self.pid, 0) - except OSError, exn: - # This is expected if Xend has been restarted within the - # life of this domain. In this case, we can kill the process, - # but we can't wait for it because it's not our child. - pass - self.pid = None - state = xstransact.Remove("/local/domain/0/device-model/%i" - % self.vm.getDomid()) + return args + + def buildDomain(self): + store_evtchn = self.vm.getStorePort() + + mem_mb = self.getRequiredInitialReservation() / 1024 + + log.debug("domid = %d", self.vm.getDomid()) + log.debug("image = %s", self.kernel) + log.debug("store_evtchn = %d", store_evtchn) + log.debug("memsize = %d", mem_mb) + log.debug("vcpus = %d", self.vm.getVCpuCount()) + log.debug("acpi = %d", self.acpi) + log.debug("apic = %d", self.apic) + + rc = xc.hvm_build(domid = self.vm.getDomid(), + image = self.kernel, + memsize = mem_mb, + vcpus = self.vm.getVCpuCount(), + acpi = self.acpi, + apic = self.apic) + rc['notes'] = { 'SUSPEND_CANCEL': 1 } + + rc['store_mfn'] = xc.hvm_get_param(self.vm.getDomid(), + HVM_PARAM_STORE_PFN) + xc.hvm_set_param(self.vm.getDomid(), HVM_PARAM_STORE_EVTCHN, + store_evtchn) + + return rc class IA64_HVM_ImageHandler(HVMImageHandler): @@ -528,6 +541,13 @@ class IA64_HVM_ImageHandler(HVMImageHand def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb): # Explicit shadow memory is not a concept return 0 + + def getDeviceModelArgs(self, restore = False): + args = HVMImageHandler.getDeviceModelArgs(self, restore) + args = args + ([ "-m", "%s" % + (self.getRequiredInitialReservation() / 1024) ]) + return args + class IA64_Linux_ImageHandler(LinuxImageHandler): diff -r f0a3bb81fbe3 tools/python/xen/xend/server/vfbif.py --- a/tools/python/xen/xend/server/vfbif.py Wed Oct 24 15:31:33 2007 -0400 +++ b/tools/python/xen/xend/server/vfbif.py Wed Oct 24 15:56:36 2007 -0400 @@ -5,14 +5,6 @@ import xen.xend import xen.xend import os -def spawn_detached(path, args, env): - p = os.fork() - if p == 0: - os.spawnve(os.P_NOWAIT, path, args, env) - os._exit(0) - else: - os.waitpid(p, 0) - CONFIG_ENTRIES = ['type', 'vncdisplay', 'vnclisten', 'vncpasswd', 'vncunused', 'display', 'xauthority', 'keymap', 'uuid', 'location', 'protocol'] @@ -43,65 +35,9 @@ class VfbifController(DevController): for i in range(len(CONFIG_ENTRIES)) if devinfo[i] is not None]) - - def createDevice(self, config): - DevController.createDevice(self, config) - if self.vm.info.is_hvm(): - # is HVM, so qemu-dm will handle the vfb. - return - - args = [ xen.util.auxbin.pathTo("qemu-dm"), - "-M", "xenpv", - "-d", "%d" % self.vm.getDomid(), - "-domain-name", self.vm.getName() ] - t = config.get("type", None) - if t == "vnc": - passwd = None - if config.has_key("vncpasswd"): - passwd = config["vncpasswd"] - else: - passwd = xen.xend.XendOptions.instance().get_vncpasswd_default() - if passwd: - self.vm.storeVm("vncpasswd", passwd) - log.debug("Stored a VNC password for vfb access") - else: - log.debug("No VNC passwd configured for vfb access") - - vnclisten = config.get('vnclisten', - xen.xend.XendOptions.instance().get_vnclisten_address()) - vncdisplay = config.get('vncdisplay', 0) - args += ['-vnc', "%s:%d" % (vnclisten, vncdisplay)] - - if config.get('vncunused', 0): - args += ['-vncunused'] - - if config.has_key("keymap"): - args += ["-k", "%s" % config["keymap"]] - else: - xoptions = xen.xend.XendOptions.instance() - if xoptions.get_keymap(): - args += ["-k", "%s" % xoptions.get_keymap()] - - spawn_detached(args[0], args, os.environ) - elif t == "sdl": - env = dict(os.environ) - if config.has_key("display"): - env['DISPLAY'] = config["display"] - if config.has_key("xauthority"): - env['XAUTHORITY'] = config["xauthority"] - spawn_detached(args[0], args, env) - else: - raise VmError('Unknown vfb type %s (%s)' % (t, repr(config))) - - def waitForDevice(self, devid): - if self.vm.info.get('HVM_boot_policy'): - log.debug('skip waiting for HVM vfb') - # is a qemu-dm managed device, don't wait for hotplug for these. - return - - DevController.waitForDevice(self, devid) - + # is a qemu-dm managed device, don't wait for hotplug for these. + return def reconfigureDevice(self, _, config): """ Only allow appending location information of vnc port into @@ -115,19 +51,16 @@ class VfbifController(DevController): raise VmError('Refusing to reconfigure device vfb:%d' % devid) def destroyDevice(self, devid, force): - if self.vm.info.get('HVM_boot_policy'): - # remove the backend xenstore entries for HVM guests no matter - # what - DevController.destroyDevice(self, devid, True) - else: - DevController.destroyDevice(self, devid, force) + # remove the backend xenstore entries no matter what + # because we kill qemu-dm with extreme prejudice + # not giving it a chance to remove them itself + DevController.destroyDevice(self, devid, True) def migrate(self, deviceConfig, network, dst, step, domName): - if self.vm.info.get('HVM_boot_policy'): - return 0 - return DevController.migrate(self, deviceConfig, network, dst, step, - domName) + # Handled by qemu-dm so no action needed + return 0 + class VkbdifController(DevController): """Virtual keyboard controller. Handles all vkbd devices for a domain. @@ -141,22 +74,15 @@ class VkbdifController(DevController): return (devid, back, front) def waitForDevice(self, config): - if self.vm.info.get('HVM_boot_policy'): - # is a qemu-dm managed device, don't wait for hotplug for these. - return - - DevController.waitForDevice(self, config) + # is a qemu-dm managed device, don't wait for hotplug for these. + return def destroyDevice(self, devid, force): - if self.vm.info.get('HVM_boot_policy'): - # remove the backend xenstore entries for HVM guests no matter - # what - DevController.destroyDevice(self, devid, True) - else: - DevController.destroyDevice(self, devid, force) + # remove the backend xenstore entries no matter what + # because we kill qemu-dm with extreme prejudice + # not giving it a chance to remove them itself + DevController.destroyDevice(self, devid, True) def migrate(self, deviceConfig, network, dst, step, domName): - if self.vm.info.get('HVM_boot_policy'): - return 0 - return DevController.migrate(self, deviceConfig, network, dst, step, - domName) + # Handled by qemu-dm so no action needed + return 0 -- |=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=| |=- Perl modules: http://search.cpan.org/~danberr/ -=| |=- Projects: http://freshmeat.net/~danielpb/ -=| |=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=| _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |