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 | 34 ++--
image.py | 379 ++++++++++++++++++++++++++++--------------------------
server/vfbif.py | 110 ++-------------
5 files changed, 254 insertions(+), 309 deletions(-)
Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx>
Dan.
diff -r 912986c9283d tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py Wed Aug 22 16:17:45 2007 -0400
+++ b/tools/python/xen/xend/XendCheckpoint.py Wed Aug 22 16:17:49 2007 -0400
@@ -6,6 +6,7 @@
# this archive for more details.
import os
+import os.path
import re
import string
import threading
@@ -105,7 +106,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)
@@ -231,6 +232,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 912986c9283d tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py Wed Aug 22 16:17:45 2007 -0400
+++ b/tools/python/xen/xend/XendConfig.py Wed Aug 22 16:17:49 2007 -0400
@@ -32,6 +32,7 @@ from xen.util.blkif import blkdev_name_t
from xen.util.blkif import blkdev_name_to_number
from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
from xen.util import xsconstants
+import xen.util.auxbin
log = logging.getLogger("xend.XendConfig")
log.setLevel(logging.WARN)
@@ -236,8 +237,6 @@ LEGACY_XENSTORE_VM_PARAMS = [
'on_xend_start',
'on_xend_stop',
]
-
-DEFAULT_DM = '/usr/lib/xen/bin/qemu-dm'
##
## Config Choices
@@ -398,13 +397,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'):
@@ -740,16 +740,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']
# copy VNC related params from platform config to vfb dev conf
for key in ['vncpasswd', 'vncunused', 'vncdisplay',
@@ -759,6 +750,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 912986c9283d tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Wed Aug 22 16:17:45 2007 -0400
+++ b/tools/python/xen/xend/XendDomainInfo.py Wed Aug 22 16:20:05 2007 -0400
@@ -1347,10 +1347,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):
@@ -1360,8 +1366,8 @@ class XendDomainInfo:
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)
+ log.exception("Device release failed: %s; %s; %s",
+ self.info['name_label'], devclass, dev)
@@ -1586,11 +1592,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:
@@ -1638,10 +1639,9 @@ class XendDomainInfo:
self.console_mfn = console_mfn
self._introduceDomain()
- if self.info.is_hvm():
- self.image = image.create(self, self.info)
- if self.image:
- self.image.createDeviceModel(True)
+ self.image = image.create(self, self.info)
+ if self.image:
+ self.image.createDeviceModel(True)
self._storeDomDetails()
self._registerWatches()
self.refreshShutdown()
@@ -1758,8 +1758,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 912986c9283d tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Wed Aug 22 16:17:45 2007 -0400
+++ b/tools/python/xen/xend/image.py Wed Aug 22 16:17:49 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):
@@ -223,6 +351,19 @@ class LinuxImageHandler(ImageHandler):
ramdisk = self.ramdisk,
features = self.vm.getFeatures())
+ 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"
@@ -256,15 +397,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)),
@@ -272,46 +404,17 @@ class HVMImageHandler(ImageHandler):
("image/display", self.display))
self.vm.storeVm(("rtc/timeoffset", rtc_timeoffset))
- self.pid = None
-
self.pae = int(vmConfig['platform'].get('pae', 0))
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("pae = %d", self.pae)
- log.debug("acpi = %d", self.acpi)
- log.debug("apic = %d", self.apic)
-
- rc = xc.hvm_build(domid = self.vm.getDomid(),
- image = self.kernel,
- store_evtchn = store_evtchn,
- memsize = mem_mb,
- vcpus = self.vm.getVCpuCount(),
- pae = self.pae,
- acpi = self.acpi,
- apic = self.apic)
- rc['notes'] = { 'SUSPEND_CANCEL': 1 }
- 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' ]
-
- ret = ['-vcpus', str(self.vm.getVCpuCount())]
+ 'acpi', 'usb', 'usbdevice' ]
for a in dmargs:
v = vmConfig['platform'].get(a)
@@ -340,7 +443,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']:
@@ -369,130 +471,40 @@ 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("pae = %d", self.pae)
+ log.debug("acpi = %d", self.acpi)
+ log.debug("apic = %d", self.apic)
+
+ rc = xc.hvm_build(domid = self.vm.getDomid(),
+ image = self.kernel,
+ store_evtchn = store_evtchn,
+ memsize = mem_mb,
+ vcpus = self.vm.getVCpuCount(),
+ pae = self.pae,
+ acpi = self.acpi,
+ apic = self.apic)
+ rc['notes'] = { 'SUSPEND_CANCEL': 1 }
+ return rc
class IA64_HVM_ImageHandler(HVMImageHandler):
@@ -514,6 +526,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 X86_HVM_ImageHandler(HVMImageHandler):
diff -r 912986c9283d tools/python/xen/xend/server/vfbif.py
--- a/tools/python/xen/xend/server/vfbif.py Wed Aug 22 16:17:45 2007 -0400
+++ b/tools/python/xen/xend/server/vfbif.py Wed Aug 22 16:17:49 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,20 +51,15 @@ 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 +72,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
|