pv-qemu 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 unnecessary 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).

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Keir Fraser committed 2007-10-25 14:45:07 +01:00
1 parent 36a48e9d87
commit f8ffd3b21f
5 files changed
+285 -336

No files matched your search

+4 -1
View File
@@ -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, checkpoint=False):
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, paused = False):
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")
+15 -16
View File
@@ -32,6 +32,7 @@ from xen.xend.server.BlktapController import blktap_disk_types
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)
@@ -234,8 +235,6 @@ LEGACY_XENSTORE_VM_PARAMS = [
'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 self.is_hvm():
if 'keymap' not in self['platform'] and XendOptions.instance().get_keymap():
self['platform']['keymap'] = XendOptions.instance().get_keymap()
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'] = DEFAULT_DM
self['platform']['device_model'] = xen.util.auxbin.pathTo("qemu-dm")
if self.is_hvm():
# 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
@@ -765,6 +756,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
values are that not related directly supported in
+11 -10
View File
@@ -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")
#
+238 -218
View File
@@ -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.
model.
The method destroy() is called when the domain is destroyed.
The default is to do nothing.
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,216 +181,13 @@ class ImageHandler:
"""Build the domain. Define in subclass."""
raise NotImplementedError()
def createDeviceModel(self, restore = False):
"""Create device model for the domain (define in subclass if needed)."""
pass
def saveDeviceModel(self):
"""Save device model for the domain (define in subclass if needed)."""
pass
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
def recreate(self):
pass
class LinuxImageHandler(ImageHandler):
ostype = "linux"
flags = 0
vhpt = 0
def buildDomain(self):
store_evtchn = self.vm.getStorePort()
console_evtchn = self.vm.getConsolePort()
mem_mb = self.getRequiredInitialReservation() / 1024
log.debug("domid = %d", self.vm.getDomid())
log.debug("memsize = %d", mem_mb)
log.debug("image = %s", self.kernel)
log.debug("store_evtchn = %d", store_evtchn)
log.debug("console_evtchn = %d", console_evtchn)
log.debug("cmdline = %s", self.cmdline)
log.debug("ramdisk = %s", self.ramdisk)
log.debug("vcpus = %d", self.vm.getVCpuCount())
log.debug("features = %s", self.vm.getFeatures())
if arch.type == "ia64":
log.debug("vhpt = %d", self.flags)
return xc.linux_build(domid = self.vm.getDomid(),
memsize = mem_mb,
image = self.kernel,
store_evtchn = store_evtchn,
console_evtchn = console_evtchn,
cmdline = self.cmdline,
ramdisk = self.ramdisk,
features = self.vm.getFeatures(),
flags = self.flags,
vhpt = self.vhpt)
class PPC_LinuxImageHandler(LinuxImageHandler):
ostype = "linux"
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.
PowerPC currently uses "shadow memory" to refer to the hash table."""
return max(maxmem_kb / 64, shadow_mem_kb)
class HVMImageHandler(ImageHandler):
ostype = "hvm"
def __init__(self, vm, vmConfig):
ImageHandler.__init__(self, vm, vmConfig)
self.shutdownWatch = None
self.rebootFeatureWatch = None
def configure(self, vmConfig):
ImageHandler.configure(self, vmConfig)
if not self.kernel:
self.kernel = '/usr/lib/xen/boot/hvmloader'
info = xc.xeninfo()
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)),
("image/device-model", self.device_model),
("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):
dmargs = [ 'boot', 'fda', 'fdb', 'soundhw',
'localtime', 'serial', 'stdvga', 'isa',
'acpi', 'usb', 'usbdevice', 'keymap', 'pci' ]
ret = ['-vcpus', str(self.vm.getVCpuCount())]
ret = ["-domain-name", str(self.vm.info['name_label'])]
for a in dmargs:
v = vmConfig['platform'].get(a)
# python doesn't allow '-' in variable names
if a == 'stdvga': a = 'std-vga'
if a == 'keymap': a = 'k'
# Handle booleans gracefully
if a in ['localtime', 'std-vga', 'isa', 'usb', 'acpi']:
try:
if v != None: v = int(v)
if v: ret.append("-%s" % a)
except (ValueError, TypeError):
pass # if we can't convert it to a sane type, ignore it
else:
if v:
ret.append("-%s" % a)
ret.append("%s" % v)
if a in ['fda', 'fdb']:
if v:
if not os.path.isabs(v):
raise VmError("Floppy file %s does not exist." % v)
log.debug("args: %s, val: %s" % (a,v))
# 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']:
devinfo = vmConfig['devices'][devuuid][1]
uname = devinfo.get('uname')
if uname is not None and 'file:' in uname:
(_, vbdparam) = string.split(uname, ':', 1)
if not os.path.isfile(vbdparam):
raise VmError('Disk image does not exist: %s' %
vbdparam)
for devuuid in vmConfig['vif_refs']:
devinfo = vmConfig['devices'][devuuid][1]
dtype = devinfo.get('type', 'ioemu')
if dtype != 'ioemu':
continue
nics += 1
mac = devinfo.get('mac')
if mac is None:
raise VmError("MAC address not specified or generated.")
bridge = devinfo.get('bridge', 'xenbr0')
model = devinfo.get('model', 'rtl8139')
ret.append("-net")
ret.append("nic,vlan=%d,macaddr=%s,model=%s" %
(nics, mac, model))
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')
@@ -398,6 +203,11 @@ class HVMImageHandler(ImageHandler):
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',
@@ -435,20 +245,20 @@ class HVMImageHandler(ImageHandler):
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.device_model]
args = args + ([ "-d", "%d" % self.vm.getDomid() ])
if arch.type == "ia64":
args = args + ([ "-m", "%s" %
(self.getRequiredInitialReservation() / 1024) ])
args = args + self.dmargs
if restore:
args = args + ([ "-loadvm", "/var/lib/xen/qemu-save.%d" %
self.vm.getDomid() ])
args = self.getDeviceModelArgs(restore)
env = dict(os.environ)
if self.display:
env['DISPLAY'] = self.display
@@ -463,6 +273,8 @@ class HVMImageHandler(ImageHandler):
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'))
@@ -479,15 +291,21 @@ class HVMImageHandler(ImageHandler):
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 destroy(self, suspend = False):
if self.pid and not suspend:
def destroyDeviceModel(self):
if self.device_model is None:
return
if self.pid:
try:
os.kill(self.pid, signal.SIGKILL)
except OSError, exn:
@@ -504,6 +322,201 @@ class HVMImageHandler(ImageHandler):
% self.vm.getDomid())
class LinuxImageHandler(ImageHandler):
ostype = "linux"
flags = 0
vhpt = 0
def buildDomain(self):
store_evtchn = self.vm.getStorePort()
console_evtchn = self.vm.getConsolePort()
mem_mb = self.getRequiredInitialReservation() / 1024
log.debug("domid = %d", self.vm.getDomid())
log.debug("memsize = %d", mem_mb)
log.debug("image = %s", self.kernel)
log.debug("store_evtchn = %d", store_evtchn)
log.debug("console_evtchn = %d", console_evtchn)
log.debug("cmdline = %s", self.cmdline)
log.debug("ramdisk = %s", self.ramdisk)
log.debug("vcpus = %d", self.vm.getVCpuCount())
log.debug("features = %s", self.vm.getFeatures())
if arch.type == "ia64":
log.debug("vhpt = %d", self.flags)
return xc.linux_build(domid = self.vm.getDomid(),
memsize = mem_mb,
image = self.kernel,
store_evtchn = store_evtchn,
console_evtchn = console_evtchn,
cmdline = self.cmdline,
ramdisk = self.ramdisk,
features = self.vm.getFeatures(),
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"
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.
PowerPC currently uses "shadow memory" to refer to the hash table."""
return max(maxmem_kb / 64, shadow_mem_kb)
class HVMImageHandler(ImageHandler):
ostype = "hvm"
def __init__(self, vm, vmConfig):
ImageHandler.__init__(self, vm, vmConfig)
self.shutdownWatch = None
self.rebootFeatureWatch = None
def configure(self, vmConfig):
ImageHandler.configure(self, vmConfig)
if not self.kernel:
self.kernel = '/usr/lib/xen/boot/hvmloader'
info = xc.xeninfo()
if 'hvm' not in info['xen_caps']:
raise HVMRequired()
rtc_timeoffset = vmConfig['platform'].get('rtc_timeoffset')
self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)),
("image/device-model", self.device_model),
("image/display", self.display))
self.vm.storeVm(("rtc/timeoffset", rtc_timeoffset))
self.apic = int(vmConfig['platform'].get('apic', 0))
self.acpi = int(vmConfig['platform'].get('acpi', 0))
# 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', 'pci' ]
for a in dmargs:
v = vmConfig['platform'].get(a)
# python doesn't allow '-' in variable names
if a == 'stdvga': a = 'std-vga'
if a == 'keymap': a = 'k'
# Handle booleans gracefully
if a in ['localtime', 'std-vga', 'isa', 'usb', 'acpi']:
try:
if v != None: v = int(v)
if v: ret.append("-%s" % a)
except (ValueError, TypeError):
pass # if we can't convert it to a sane type, ignore it
else:
if v:
ret.append("-%s" % a)
ret.append("%s" % v)
if a in ['fda', 'fdb']:
if v:
if not os.path.isabs(v):
raise VmError("Floppy file %s does not exist." % v)
log.debug("args: %s, val: %s" % (a,v))
# Handle disk/network related options
mac = None
nics = 0
for devuuid in vmConfig['vbd_refs']:
devinfo = vmConfig['devices'][devuuid][1]
uname = devinfo.get('uname')
if uname is not None and 'file:' in uname:
(_, vbdparam) = string.split(uname, ':', 1)
if not os.path.isfile(vbdparam):
raise VmError('Disk image does not exist: %s' %
vbdparam)
for devuuid in vmConfig['vif_refs']:
devinfo = vmConfig['devices'][devuuid][1]
dtype = devinfo.get('type', 'ioemu')
if dtype != 'ioemu':
continue
nics += 1
mac = devinfo.get('mac')
if mac is None:
raise VmError("MAC address not specified or generated.")
bridge = devinfo.get('bridge', 'xenbr0')
model = devinfo.get('model', 'rtl8139')
ret.append("-net")
ret.append("nic,vlan=%d,macaddr=%s,model=%s" %
(nics, mac, model))
ret.append("-net")
ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge))
return ret
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() ])
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):
def configure(self, vmConfig):
@@ -529,6 +542,13 @@ class IA64_HVM_ImageHandler(HVMImageHandler):
# 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):
def configure(self, vmConfig):
+17 -91
View File
@@ -5,14 +5,6 @@ from xen.xend.XendError import VmError
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
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.