mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
This is Anthony Liguori's virtual framebuffer forward ported and
extensively hacked based on feedback from xen-devel. Its architecture is comparable to the common split device driver architecture: xenfb and xenkbd modules serve as frontend in domU, and the user space vncfb or sdlfb process serves as backend in dom0. Signed-off-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
1 parent
b4f5b27478
commit
a5ae44fcdf
24 files changed
+2895
-3277
No files matched your search
@@ -19,7 +19,7 @@
|
||||
# A collection of DevControllers
|
||||
#
|
||||
|
||||
from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, usbif
|
||||
from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, usbif, vfbif
|
||||
from xen.xend.server.BlktapController import BlktapController
|
||||
|
||||
class XendDevices:
|
||||
@@ -41,6 +41,8 @@ class XendDevices:
|
||||
'irq': irqif.IRQController,
|
||||
'usb': usbif.UsbifController,
|
||||
'tap': BlktapController,
|
||||
'vfb': vfbif.VfbifController,
|
||||
'vkbd': vfbif.VkbdifController,
|
||||
}
|
||||
|
||||
#@classmethod
|
||||
|
||||
@@ -458,7 +458,7 @@ class XendDomainInfo:
|
||||
try:
|
||||
self._constructDomain()
|
||||
self._storeVmDetails()
|
||||
self._createDevices()
|
||||
self._restoreDomain()
|
||||
self._createChannels()
|
||||
self._storeDomDetails()
|
||||
self._endRestore()
|
||||
@@ -1387,6 +1387,23 @@ class XendDomainInfo:
|
||||
raise VmError(str(exn))
|
||||
|
||||
|
||||
def _restoreDomain(self):
|
||||
log.debug('XendDomainInfo.restoreDomain: %s %s',
|
||||
self.domid,
|
||||
self.info['cpu_weight'])
|
||||
|
||||
if not self.infoIsSet('image'):
|
||||
raise VmError('Missing image in configuration')
|
||||
|
||||
try:
|
||||
self.image = image.create(self,
|
||||
self.info['image'],
|
||||
self.info['device'])
|
||||
|
||||
self._createDevices()
|
||||
except RuntimeError, exn:
|
||||
raise VmError(str(exn))
|
||||
|
||||
def cleanupDomain(self):
|
||||
"""Cleanup domain resources; release devices. Idempotent. Nothrow
|
||||
guarantee."""
|
||||
|
||||
@@ -23,6 +23,7 @@ import math
|
||||
import signal
|
||||
|
||||
import xen.lowlevel.xc
|
||||
import xen.util.auxbin
|
||||
from xen.xend.XendConstants import REVERSE_DOMAIN_SHUTDOWN_REASONS
|
||||
from xen.xend.XendError import VmError, XendError
|
||||
from xen.xend.XendLogging import log
|
||||
@@ -199,6 +200,79 @@ class LinuxImageHandler(ImageHandler):
|
||||
ramdisk = self.ramdisk,
|
||||
features = self.vm.getFeatures())
|
||||
|
||||
def configure(self, imageConfig, deviceConfig):
|
||||
ImageHandler.configure(self, imageConfig, deviceConfig)
|
||||
|
||||
self.pid = 0
|
||||
log.info("configuring linux guest")
|
||||
|
||||
# set up the graphics bits.
|
||||
# FIXME: this is much like what we do for HVM, should it be
|
||||
# for all image types now?
|
||||
self.display = sxp.child_value(imageConfig, 'display')
|
||||
self.xauthority = sxp.child_value(imageConfig, 'xauthority')
|
||||
self.vncconsole = sxp.child_value(imageConfig, 'vncconsole')
|
||||
vncpasswd = sxp.child_value(imageConfig, 'vncpasswd')
|
||||
self.vncpasswd = vncpasswd
|
||||
|
||||
self.vnc = sxp.child_value(imageConfig, 'vnc')
|
||||
self.sdl = sxp.child_value(imageConfig, 'sdl')
|
||||
if self.vnc:
|
||||
self.vncdisplay = int(sxp.child_value(imageConfig, 'vncdisplay',
|
||||
self.vm.getDomid()))
|
||||
self.vncunused = sxp.child_value(imageConfig, 'vncunused')
|
||||
self.vnclisten = sxp.child_value(imageConfig, 'vnclisten')
|
||||
if not(self.vnclisten):
|
||||
self.vnclisten = xen.xend.XendRoot.instance().get_vnclisten_address()
|
||||
|
||||
def createDeviceModel(self):
|
||||
if self.pid:
|
||||
return
|
||||
# Execute device model (for us, it's just the fb frontend)
|
||||
if not self.vnc and not self.sdl:
|
||||
return
|
||||
|
||||
if self.vnc:
|
||||
args = [xen.util.auxbin.pathTo("xen-vncfb")]
|
||||
if self.vncunused:
|
||||
args += ['--unused']
|
||||
elif self.vncdisplay:
|
||||
args += [ "--vncport", "%d" %(5900 + self.vncdisplay,) ]
|
||||
if self.vnclisten:
|
||||
args += [ "--listen", self.vnclisten ]
|
||||
|
||||
# password check
|
||||
if self.vncpasswd is None:
|
||||
# get password from xend-config(if password omitted, None)
|
||||
self.vncpasswd = xen.xend.XendRoot.instance().get_vncpasswd_default()
|
||||
|
||||
if self.vncpasswd is None:
|
||||
raise VmError('vncpasswd is not setup in the guest config or xend-config.')
|
||||
if self.vncpasswd != '':
|
||||
self.vm.storeVm("vncpasswd", self.vncpasswd)
|
||||
log.info("vncpassword set to '%s'", self.vncpasswd)
|
||||
|
||||
elif self.sdl:
|
||||
args = [xen.util.auxbin.pathTo("xen-sdlfb")]
|
||||
args = args + [ "--domid", "%d" % self.vm.getDomid(),
|
||||
"--title", self.vm.info['name'] ]
|
||||
|
||||
env = dict(os.environ)
|
||||
if self.display:
|
||||
env['DISPLAY'] = self.display
|
||||
if self.xauthority:
|
||||
env['XAUTHORITY'] = self.xauthority
|
||||
log.info("spawning video: %s", args)
|
||||
self.pid = os.spawnve(os.P_NOWAIT, args[0], args, env)
|
||||
log.info("device model pid: %d", self.pid)
|
||||
|
||||
def destroy(self):
|
||||
if not self.pid:
|
||||
return
|
||||
os.kill(self.pid, signal.SIGKILL)
|
||||
os.waitpid(self.pid, 0)
|
||||
self.pid = 0
|
||||
|
||||
class PPC_LinuxImageHandler(LinuxImageHandler):
|
||||
|
||||
ostype = "linux"
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
from xen.xend.server.DevController import DevController
|
||||
|
||||
class VfbifController(DevController):
|
||||
"""Virtual frame buffer controller. Handles all vfb devices for a domain.
|
||||
"""
|
||||
|
||||
def __init__(self, vm):
|
||||
DevController.__init__(self, vm)
|
||||
|
||||
def getDeviceDetails(self, config):
|
||||
"""@see DevController.getDeviceDetails"""
|
||||
devid = 0
|
||||
back = {}
|
||||
front = {}
|
||||
return (devid, back, front)
|
||||
|
||||
class VkbdifController(DevController):
|
||||
"""Virtual keyboard controller. Handles all vkbd devices for a domain.
|
||||
"""
|
||||
|
||||
def __init__(self, vm):
|
||||
DevController.__init__(self, vm)
|
||||
|
||||
def getDeviceDetails(self, config):
|
||||
"""@see DevController.getDeviceDetails"""
|
||||
devid = 0
|
||||
back = {}
|
||||
front = {}
|
||||
return (devid, back, front)
|
||||
@@ -284,6 +284,14 @@ gopts.var('usbport', val='PATH',
|
||||
use="""Add a physical USB port to a domain, as specified by the path
|
||||
to that port. This option may be repeated to add more than one port.""")
|
||||
|
||||
gopts.var('vfb', val="no|yes'",
|
||||
fn=set_bool, default=0,
|
||||
use="Make the domain a framebuffer backend.")
|
||||
|
||||
gopts.var('vkbd', val="no|yes'",
|
||||
fn=set_bool, default=0,
|
||||
use="Make the domain a keyboard backend.")
|
||||
|
||||
gopts.var('vif', val="type=TYPE,mac=MAC,bridge=BRIDGE,ip=IPADDR,script=SCRIPT,backend=DOM,vifname=NAME",
|
||||
fn=append_value, default=[],
|
||||
use="""Add a network interface with the given MAC address and bridge.
|
||||
@@ -512,8 +520,10 @@ def configure_image(vals):
|
||||
config_image.append(['args', vals.extra])
|
||||
|
||||
if vals.builder == 'hvm':
|
||||
configure_hvm(config_image, vals)
|
||||
|
||||
configure_hvm(config_image, vals)
|
||||
|
||||
configure_graphics(config_image, vals)
|
||||
|
||||
return config_image
|
||||
|
||||
def configure_disks(config_devs, vals):
|
||||
@@ -564,6 +574,13 @@ def configure_usb(config_devs, vals):
|
||||
config_usb = ['usbport', ['path', path]]
|
||||
config_devs.append(['device', config_usb])
|
||||
|
||||
def configure_vfbs(config_devs, vals):
|
||||
if vals.vfb:
|
||||
config_devs.append(['device', ['vfb', []]])
|
||||
|
||||
def configure_vkbds(config_devs, vals):
|
||||
if vals.vkbd:
|
||||
config_devs.append(['device', ['vkbd', []]])
|
||||
|
||||
def configure_security(config, vals):
|
||||
"""Create the config for ACM security labels.
|
||||
@@ -661,13 +678,20 @@ def configure_vifs(config_devs, vals):
|
||||
config_devs.append(['device', config_vif])
|
||||
|
||||
|
||||
def configure_graphics(config_image, vals):
|
||||
"""Create the config for graphic consoles.
|
||||
"""
|
||||
args = [ 'vnc', 'vncdisplay', 'vncconsole', 'vncunused',
|
||||
'sdl', 'display', 'xauthority', 'vnclisten', 'vncpasswd']
|
||||
for a in args:
|
||||
if (vals.__dict__[a]):
|
||||
config_image.append([a, vals.__dict__[a]])
|
||||
|
||||
def configure_hvm(config_image, vals):
|
||||
"""Create the config for HVM devices.
|
||||
"""
|
||||
args = [ 'device_model', 'pae', 'vcpus', 'boot', 'fda', 'fdb',
|
||||
'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw',
|
||||
'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten',
|
||||
'sdl', 'display', 'xauthority',
|
||||
'acpi', 'apic', 'usb', 'usbdevice', 'keymap' ]
|
||||
for a in args:
|
||||
if a in vals.__dict__ and vals.__dict__[a] is not None:
|
||||
@@ -742,6 +766,8 @@ def make_config(vals):
|
||||
configure_vifs(config_devs, vals)
|
||||
configure_usb(config_devs, vals)
|
||||
configure_vtpm(config_devs, vals)
|
||||
configure_vfbs(config_devs, vals)
|
||||
configure_vkbds(config_devs, vals)
|
||||
configure_security(config, vals)
|
||||
config += config_devs
|
||||
|
||||
|
||||