[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [XEND] Merge VFB support for PV and HVM guests.



# HG changeset patch
# User Alastair Tse <atse@xxxxxxxxxxxxx>
# Date 1170249636 0
# Node ID 3cccf8e6429666be58408972570dbd063a2bae1e
# Parent  7c992fd3b19ba3f7094e0c01205a481dc74661f8
[XEND] Merge VFB support for PV and HVM guests.

This patch merges the way VFB are represented inside Xend by making
HVM VNC consoles use the VFB as its configuration object.

It preserves the way options are specified through xm but will create
a new VFB device that is used by image.py to put vnc config into
qemu-dm's command line. The parsing is moved into image.py's
parseDeviceModel() rather than in configVNC().

Through the Xen API, you can create a 'console' of protocol 'rfb' and
end up with a VNC console, on both HVM and PV guests. The location of
the connecting port is stored in the location attribute of the console
object. This is updated on each XendDomainInfo.update() if it
changes.

Also fixes missing read of the vnclisten and HVM_boot from the
config when initialised via xm. Makes sure bootable attribute for VBD
is store as an int when making SXP config.

Signed-off-by: Alastair Tse <atse@xxxxxxxxxxxxx>
---
 tools/python/scripts/test_hvm_create.py           |   12 +
 tools/python/scripts/test_vm_create.py            |   13 +
 tools/python/scripts/xapi.py                      |    4 
 tools/python/xen/xend/XendAPI.py                  |   25 ++-
 tools/python/xen/xend/XendConfig.py               |  160 ++++++++++++++++++----
 tools/python/xen/xend/XendDomainInfo.py           |   65 ++++++--
 tools/python/xen/xend/image.py                    |   95 +++++++------
 tools/python/xen/xend/server/ConsoleController.py |    6 
 tools/python/xen/xend/server/vfbif.py             |   69 +++++++++
 9 files changed, 351 insertions(+), 98 deletions(-)

diff -r 7c992fd3b19b -r 3cccf8e64296 tools/python/scripts/test_hvm_create.py
--- a/tools/python/scripts/test_hvm_create.py   Wed Jan 31 12:58:41 2007 +0000
+++ b/tools/python/scripts/test_hvm_create.py   Wed Jan 31 13:20:36 2007 +0000
@@ -72,6 +72,12 @@ vif_cfg = {
     'MTU': 1500,
 }    
 
+console_cfg = {
+    'protocol': 'rfb',
+    'other_config': {'vncunused': 1, 'vncpasswd': 'testing'},
+}
+
+
 import sys
 import time
 sys.path.append('/usr/lib/python')
@@ -125,6 +131,12 @@ def test_vm_create():
         vif_cfg['VM'] = vm_uuid
         vif_uuid = execute(server, 'VIF.create', (session, vif_cfg))
 
+        # Create a console
+        console_cfg['VM'] = vm_uuid
+        console_uuid = execute(server, 'console.create',
+                               (session, console_cfg))
+        print console_uuid
+
         # Start the VM
         execute(server, 'VM.start', (session, vm_uuid, False))
 
diff -r 7c992fd3b19b -r 3cccf8e64296 tools/python/scripts/test_vm_create.py
--- a/tools/python/scripts/test_vm_create.py    Wed Jan 31 12:58:41 2007 +0000
+++ b/tools/python/scripts/test_vm_create.py    Wed Jan 31 13:20:36 2007 +0000
@@ -91,6 +91,11 @@ vif_cfg = {
     'network': '',
     'MAC': '',
     'MTU': 1500,
+}
+
+console_cfg = {
+    'protocol': 'rfb',
+    'other_config': {'vncunused': 1, 'vncpasswd': 'testing'},
 }    
 
 import sys
@@ -157,12 +162,18 @@ def test_vm_create():
         vif_cfg['VM'] = vm_uuid
         vif_uuid = execute(server, 'VIF.create', (session, vif_cfg))
 
+        # Create a console
+        console_cfg['VM'] = vm_uuid
+        console_uuid = execute(server, 'console.create',
+                               (session, console_cfg))
+        print console_uuid
+
         # Start the VM
         execute(server, 'VM.start', (session, vm_uuid, False))
 
         time.sleep(30)
 
-        test_suspend = True
+        test_suspend = False
         if test_suspend:
             print 'Suspending VM..'
             execute(server, 'VM.suspend', (session, vm_uuid))
diff -r 7c992fd3b19b -r 3cccf8e64296 tools/python/scripts/xapi.py
--- a/tools/python/scripts/xapi.py      Wed Jan 31 12:58:41 2007 +0000
+++ b/tools/python/scripts/xapi.py      Wed Jan 31 13:20:36 2007 +0000
@@ -45,7 +45,7 @@ VBD_LIST_FORMAT = '%(device)-6s %(uuid)-
 VBD_LIST_FORMAT = '%(device)-6s %(uuid)-36s %(VDI)-8s'
 TASK_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(status)-8s %(progress)-4s'
 VIF_LIST_FORMAT = '%(name)-8s %(device)-7s %(uuid)-36s %(MAC)-10s'
-CONSOLE_LIST_FORMAT = '%(uuid)-36s %(protocol)-8s %(uri)-32s'
+CONSOLE_LIST_FORMAT = '%(uuid)-36s %(protocol)-8s %(location)-32s'
 
 COMMANDS = {
     'host-info': ('', 'Get Xen Host Info'),
@@ -545,7 +545,7 @@ def xapi_console_list(args, async = Fals
 
     if not is_long:
         print CONSOLE_LIST_FORMAT % {'protocol': 'Protocol',
-                                     'uri': 'URI',
+                                     'location': 'Location',
                                      'uuid': 'UUID'}
 
         for console in consoles:
diff -r 7c992fd3b19b -r 3cccf8e64296 tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Wed Jan 31 12:58:41 2007 +0000
+++ b/tools/python/xen/xend/XendAPI.py  Wed Jan 31 13:20:36 2007 +0000
@@ -1835,8 +1835,9 @@ class XendAPI(object):
     # ----------------------------------------------------------------
 
 
-    console_attr_ro = ['uri', 'protocol', 'VM']
-    console_attr_rw = []
+    console_attr_ro = ['location', 'protocol', 'VM']
+    console_attr_rw = ['other_config']
+    console_funcs = [('create', 'console')]
     
     def console_get_all(self, session):
         xendom = XendDomain.instance()
@@ -1844,10 +1845,10 @@ class XendAPI(object):
         cons = reduce(lambda x, y: x + y, cons)
         return xen_api_success(cons)
 
-    def console_get_uri(self, session, console_ref):
+    def console_get_location(self, session, console_ref):
         return xen_api_success(xendom.get_dev_property_by_uuid('console',
                                                                console_ref,
-                                                               'uri'))
+                                                               'location'))
 
     def console_get_protocol(self, session, console_ref):
         return xen_api_success(xendom.get_dev_property_by_uuid('console',
@@ -1879,6 +1880,22 @@ class XendAPI(object):
             
         return xen_api_success(return_cfg)
 
+    def console_create(self, session, console_struct):
+        xendom = XendDomain.instance()
+        if not xendom.is_valid_vm(console_struct['VM']):
+            return xen_api_error(['VM_HANDLE_INVALID', console_struct['VM']])
+        
+        dom = xendom.get_vm_by_uuid(console_struct['VM'])
+        try:
+            if 'protocol' not in console_struct:
+                return xen_api_error(['CONSOLE_PROTOCOL_INVALID',
+                                      'No protocol specified'])
+            
+            console_ref = dom.create_console(console_struct)
+            xendom.managed_config_save(dom)
+            return xen_api_success(console_ref)
+        except XendError, e:
+            return xen_api_error([XEND_ERROR_TODO, str(e)])
 
     # Xen API: Class SR
     # ----------------------------------------------------------------
diff -r 7c992fd3b19b -r 3cccf8e64296 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Wed Jan 31 12:58:41 2007 +0000
+++ b/tools/python/xen/xend/XendConfig.py       Wed Jan 31 13:20:36 2007 +0000
@@ -126,6 +126,7 @@ XENAPI_HVM_CFG = {
     'platform_serial' : 'serial',
     'platform_localtime': 'localtime',
     'platform_keymap' : 'keymap',
+    'HVM_boot': 'boot',
 }    
 
 # List of XendConfig configuration keys that have no direct equivalent
@@ -250,7 +251,8 @@ LEGACY_IMAGE_CFG = [
     ('sdl', int),
     ('vncdisplay', int),
     ('vncunused', int),
-    ('vncpasswd', str),    
+    ('vncpasswd', str),
+    ('vnclisten', str),
 ]
 
 LEGACY_IMAGE_HVM_CFG = [
@@ -379,6 +381,7 @@ class XendConfig(dict):
             'vif_refs': [],
             'vbd_refs': [],
             'vtpm_refs': [],
+            'other_config': {},
         }
         
         defaults['name_label'] = 'Domain-' + defaults['uuid']
@@ -660,6 +663,25 @@ class XendConfig(dict):
         self['vbd_refs'] = cfg.get('vbd_refs', [])
         self['vtpm_refs'] = cfg.get('vtpm_refs', [])
 
+        # coalesce hvm vnc frame buffer with vfb config
+        if self['image']['type'] == 'hvm' and self['image'].get('vnc', 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 not has_rfb:
+                dev_config = ['vfb']
+                # copy VNC related params from image config to vfb dev conf
+                for key in ['vncpasswd', 'vncunused', 'vncdisplay',
+                            'vnclisten']:
+                    if key in self['image']:
+                        dev_config.append([key, self['image'][key]])
+
+                self.device_add('vfb', cfg_sxp = dev_config)
+
 
     def _sxp_to_xapi_unsupported(self, sxp_cfg):
         """Read in an SXP configuration object and populate
@@ -756,7 +778,7 @@ class XendConfig(dict):
 
                 # currently unsupported options
                 self['image']['hvm']['device_model'] = LEGACY_DM
-                self['image']['vnc'] = 1
+                self['image']['vnc'] = 0
                 self['image']['hvm']['pae'] = 1
 
                 if self['platform_enable_audio']:
@@ -883,8 +905,9 @@ class XendConfig(dict):
                                 # store as part of the device config.
                                 dev_uuid = sxp.child_value(config, 'uuid')
                                 dev_type, dev_cfg = self['devices'][dev_uuid]
-                                config.append(['bootable',
-                                               int(dev_cfg['bootable'])])
+                                is_bootable = dev_cfg.get('bootable', False)
+                                config.append(['bootable', int(is_bootable)])
+
                             sxpr.append(['device', config])
 
                         found = True
@@ -986,6 +1009,28 @@ class XendConfig(dict):
                         # bootable.
                         dev_info['bootable'] = True
                     target['vbd_refs'].append(dev_uuid)
+                    
+            elif dev_type == 'vfb':
+                # Populate other config with aux data that is associated
+                # with vfb
+
+                other_config = {}
+                for key in ['vncunused', 'vncdisplay', 'vnclisten',
+                            'vncpasswd', 'type', 'display', 'xauthority',
+                            'keymap']:
+                    if key in dev_info:
+                        other_config[key] = dev_info[key]
+                target['devices'][dev_uuid][1]['other_config'] =  other_config
+                
+                
+                if 'console_refs' not in target:
+                    target['console_refs'] = []
+
+                # Treat VFB devices as console devices so they are found
+                # through Xen API
+                if dev_uuid not in target['console_refs']:
+                    target['console_refs'].append(dev_uuid)
+
             elif dev_type == 'console':
                 if 'console_refs' not in target:
                     target['console_refs'] = []
@@ -1048,50 +1093,117 @@ class XendConfig(dict):
                 target['devices'][dev_uuid] = (dev_type, dev_info)
                 target['vtpm_refs'].append(dev_uuid)
 
+            elif dev_type == 'console':
+                dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
+                dev_info['uuid'] = dev_uuid
+                dev_info['protocol'] = cfg_xenapi.get('protocol', 'rfb')
+                dev_info['other_config'] = cfg_xenapi.get('other_config', {})
+                if dev_info['protocol'] == 'rfb':
+                    # collapse other config into devinfo for things
+                    # such as vncpasswd, vncunused, etc.                    
+                    dev_info.update(cfg_xenapi.get('other_config', {}))
+                    dev_info['type'] = 'vnc'                        
+                    target['devices'][dev_uuid] = ('vfb', dev_info)
+                    target['console_refs'].append(dev_uuid)
+
+                    # Finally, if we are a pvfb, we need to make a vkbd
+                    # as well that is not really exposed to Xen API
+                    vkbd_uuid = uuid.createString()
+                    target['devices'][vkbd_uuid] = ('vkbd', {})
+                    
+                elif dev_info['protocol'] == 'vt100':
+                    # if someone tries to create a VT100 console
+                    # via the Xen API, we'll have to ignore it
+                    # because we create one automatically in
+                    # XendDomainInfo._update_consoles
+                    raise XendConfigError('Creating vt100 consoles via '
+                                          'Xen API is unsupported')
+
             return dev_uuid
 
         # no valid device to add
         return ''
 
-    def console_add(self, protocol, uri):
+    def console_add(self, protocol, location, other_config = {}):
         dev_uuid = uuid.createString()
-        dev_info = {
-            'uuid': dev_uuid,
-            'protocol': protocol,
-            'uri': uri
-        }
-        if 'devices' not in self:
-            self['devices'] = {}
+        if protocol == 'vt100':
+            dev_info = {
+                'uuid': dev_uuid,
+                'protocol': protocol,
+                'location': location,
+                'other_config': other_config,
+            }
+
+            if 'devices' not in self:
+                self['devices'] = {}
             
-        self['devices'][dev_uuid] = ('console', dev_info)
-        self['console_refs'].append(dev_uuid)
-        return dev_info
+            self['devices'][dev_uuid] = ('console', dev_info)
+            self['console_refs'].append(dev_uuid)
+            return dev_info
+
+        return {}
+
+    def console_update(self, console_uuid, key, value):
+        for dev_uuid, (dev_type, dev_info) in self['devices'].items():
+            if dev_uuid == console_uuid:
+                dev_info[key] = value
+                break
 
     def console_get_all(self, protocol):
-        consoles = [dinfo for dtype, dinfo in self['devices'].values()
-                    if dtype == 'console']
-        return [c for c in consoles if c.get('protocol') == protocol]
-
-    def device_update(self, dev_uuid, cfg_sxp):
+        if protocol == 'vt100':
+            consoles = [dinfo for dtype, dinfo in self['devices'].values()
+                        if dtype == 'console']
+            return [c for c in consoles if c.get('protocol') == protocol]
+
+        elif protocol == 'rfb':
+            vfbs = [dinfo for dtype, dinfo in self['devices'].values()
+                   if dtype == 'vfb']
+
+            # move all non-console key values to other_config before
+            # returning console config
+            valid_keys = ['uuid', 'location']
+            for vfb in vfbs:
+                other_config = {}
+                for key, val in vfb.items():
+                    if key not in valid_keys:
+                        other_config[key] = vfb[key]
+                    del vfb[key]
+                vfb['other_config'] = other_config
+                vfb['protocol'] = 'rfb'
+                        
+            return vfbs
+
+        else:
+            return []
+
+    def device_update(self, dev_uuid, cfg_sxp = [], cfg_xenapi = {}):
         """Update an existing device with the new configuration.
 
         @rtype: boolean
         @return: Returns True if succesfully found and updated a device conf
         """
-        if dev_uuid in self['devices']:
+        if dev_uuid in self['devices'] and cfg_sxp:
             if sxp.child0(cfg_sxp) == 'device':            
                 config = sxp.child0(cfg_sxp)
             else:
                 config = cfg_sxp
-                
+
+            dev_type, dev_info = self['devices'][dev_uuid]
             for opt_val in config[1:]:
                 try:
                     opt, val = opt_val
-                    self['devices'][dev_uuid][opt] = val
+                    dev_info[opt] = val
                 except (TypeError, ValueError):
                     pass # no value for this config option
-            
+
+            self['devices'][dev_uuid] = (dev_type, dev_info)
             return True
+        
+        elif dev_uuid in self['devices'] and cfg_xenapi:
+            dev_type, dev_info = self['devices'][dev_uuid]
+            for key, val in cfg_xenapi.items():
+                dev_info[key] = val
+            self['devices'][dev_uuid] = (dev_type, dev_info)
 
         return False
 
diff -r 7c992fd3b19b -r 3cccf8e64296 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Wed Jan 31 12:58:41 2007 +0000
+++ b/tools/python/xen/xend/XendDomainInfo.py   Wed Jan 31 13:20:36 2007 +0000
@@ -695,16 +695,29 @@ class XendDomainInfo:
             if not serial_consoles:
                 cfg = self.info.console_add('vt100', self.console_port)
                 self._createDevice('console', cfg)
-
-        # Update VNC port if it exists
+            else:
+                console_uuid = serial_consoles[0].get('uuid')
+                self.info.console_update(console_uuid, 'location',
+                                         self.console_port)
+                
+
+        # Update VNC port if it exists and write to xenstore
         vnc_port = self.readDom('console/vnc-port')
         if vnc_port is not None:
-            vnc_consoles = self.info.console_get_all('rfb')
-            if not vnc_consoles:
-                cfg = self.info.console_add('rfb', 'localhost:%s' %
-                                           str(vnc_port))
-                self._createDevice('console', cfg)                
-
+            for dev_uuid, (dev_type, dev_info) in self.info['devices'].items():
+                if dev_type == 'vfb':
+                    old_location = dev_info.get('location')
+                    listen_host = dev_info.get('vnclisten', 'localhost')
+                    new_location = '%s:%s' % (listen_host, str(vnc_port))
+                    if old_location == new_location:
+                        break
+
+                    dev_info['location'] = new_location
+                    self.info.device_update(dev_uuid, cfg_xenapi = dev_info)
+                    vfb_ctrl = self.getDeviceController('vfb')
+                    vfb_ctrl.reconfigureDevice(0, dev_info)
+                    break
+                
     #
     # Function to update xenstore /vm/*
     #
@@ -2017,21 +2030,18 @@ class XendDomainInfo:
 
         @rtype: dictionary
         """
-        dev_type_config = self.info['devices'].get(dev_uuid)
+        dev_type, dev_config = self.info['devices'].get(dev_uuid, (None, None))
 
         # shortcut if the domain isn't started because
         # the devcontrollers will have no better information
         # than XendConfig.
         if self.state in (XEN_API_VM_POWER_STATE_HALTED,):
-            if dev_type_config:
-                return copy.deepcopy(dev_type_config[1])
+            if dev_config:
+                return copy.deepcopy(dev_config)
             return None
 
         # instead of using dev_class, we use the dev_type
         # that is from XendConfig.
-        # This will accomdate 'tap' as well as 'vbd'
-        dev_type = dev_type_config[0]
-        
         controller = self.getDeviceController(dev_type)
         if not controller:
             return None
@@ -2040,14 +2050,14 @@ class XendDomainInfo:
         if not all_configs:
             return None
 
-        dev_config = copy.deepcopy(dev_type_config[1])
+        updated_dev_config = copy.deepcopy(dev_config)
         for _devid, _devcfg in all_configs.items():
             if _devcfg.get('uuid') == dev_uuid:
-                dev_config.update(_devcfg)
-                dev_config['id'] = _devid
-                return dev_config
-
-        return dev_config
+                updated_dev_config.update(_devcfg)
+                updated_dev_config['id'] = _devid
+                return updated_dev_config
+
+        return updated_dev_config
                     
     def get_dev_xenapi_config(self, dev_class, dev_uuid):
         config = self.get_dev_config_by_uuid(dev_class, dev_uuid)
@@ -2230,6 +2240,21 @@ class XendDomainInfo:
 
         return dev_uuid
 
+    def create_console(self, xenapi_console):
+        """ Create a console device from a Xen API struct.
+
+        @return: uuid of device
+        @rtype: string
+        """
+        if self.state not in (DOM_STATE_HALTED,):
+            raise VmError("Can only add console to a halted domain.")
+
+        dev_uuid = self.info.device_add('console', cfg_xenapi = xenapi_console)
+        if not dev_uuid:
+            raise XendError('Failed to create device')
+
+        return dev_uuid
+
     def destroy_device_by_uuid(self, dev_type, dev_uuid):
         if dev_uuid not in self.info['devices']:
             raise XendError('Device does not exist')
diff -r 7c992fd3b19b -r 3cccf8e64296 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Wed Jan 31 12:58:41 2007 +0000
+++ b/tools/python/xen/xend/image.py    Wed Jan 31 13:20:36 2007 +0000
@@ -26,6 +26,7 @@ from xen.xend.XendConstants import REVER
 from xen.xend.XendConstants import REVERSE_DOMAIN_SHUTDOWN_REASONS
 from xen.xend.XendError import VmError, XendError
 from xen.xend.XendLogging import log
+from xen.xend.XendOptions import instance as xenopts
 from xen.xend.server.netif import randomMAC
 from xen.xend.xenstore.xswatch import xswatch
 from xen.xend import arch
@@ -340,8 +341,6 @@ class HVMImageHandler(ImageHandler):
 
         self.pid = None
 
-        self.dmargs += self.configVNC(imageConfig)
-
         self.pae  = imageConfig['hvm'].get('pae', 0)
         self.apic  = imageConfig['hvm'].get('apic', 0)
         self.acpi  = imageConfig['hvm']['devices'].get('acpi', 0)
@@ -379,8 +378,8 @@ class HVMImageHandler(ImageHandler):
         dmargs = [ 'boot', 'fda', 'fdb', 'soundhw',
                    'localtime', 'serial', 'stdvga', 'isa',
                    'acpi', 'usb', 'usbdevice', 'keymap' ]
+        
         hvmDeviceConfig = vmConfig['image']['hvm']['devices']
-
         ret = ['-vcpus', str(self.vm.getVCpuCount())]
 
         for a in dmargs:
@@ -439,49 +438,59 @@ class HVMImageHandler(ImageHandler):
             ret.append("-net")
             ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge))
 
-        return ret
-
-    def configVNC(self, imageConfig):
-        # Handle graphics library related options
-        vnc = imageConfig.get('vnc')
-        sdl = imageConfig.get('sdl')
-        ret = []
-        nographic = imageConfig.get('nographic')
-
-        # get password from VM config (if password omitted, None)
-        vncpasswd_vmconfig = imageConfig.get('vncpasswd')
-
-        if nographic:
+
+        #
+        # Find RFB console device, and if it exists, make QEMU enable
+        # the VNC console.
+        #
+        if vmConfig['image'].get('nographic'):
+            # skip vnc init if nographic is set
             ret.append('-nographic')
             return ret
 
-        if vnc:
-            vncdisplay = imageConfig.get('vncdisplay',
-                                         int(self.vm.getDomid()))
-            vncunused = imageConfig.get('vncunused')
-
-            if vncunused:
-                ret += ['-vncunused']
-            else:
-                ret += ['-vnc', '%d' % vncdisplay]
-
-            vnclisten = imageConfig.get('vnclisten')
-
-            if not(vnclisten):
-                vnclisten = (xen.xend.XendOptions.instance().
-                             get_vnclisten_address())
-            if vnclisten:
-                ret += ['-vnclisten', vnclisten]
-
-            vncpasswd = vncpasswd_vmconfig
-            if vncpasswd is None:
-                vncpasswd = (xen.xend.XendOptions.instance().
-                             get_vncpasswd_default())
-                if vncpasswd is None:
-                    raise VmError('vncpasswd is not set up in ' +
-                                  'VMconfig and xend-config.')
-            if vncpasswd != '':
-                self.vm.storeVm("vncpasswd", vncpasswd)
+        vnc_config = {}
+        has_vfb = False
+        has_vnc = int(vmConfig['image'].get('vnc')) != 0
+        for dev_uuid in vmConfig['console_refs']:
+            dev_type, dev_info = vmConfig['devices'][devuuid]
+            if dev_type == 'rfb':
+                vnc_config = dev_info.get('other_config', {})
+                has_vfb = True
+                break
+
+        if not vnc_config:
+            for key in ('vncunused', 'vnclisten', 'vncdisplay', 'vncpasswd'):
+                if key in vmConfig['image']:
+                    vnc_config[key] = vmConfig['image'][key]
+
+        if not has_vfb and not has_vnc:
+            ret.append('-nographic')
+            return ret
+
+                    
+        if not vnc_config.get('vncunused', 0) and \
+               vnc_config.get('vncdisplay', 0):
+            ret.append('-vnc')
+            ret.append(str(vncdisplay))
+        else:
+            ret.append('-vncunused')
+
+        vnclisten = vnc_config.get('vnclisten',
+                                   xenopts().get_vnclisten_address())
+        ret.append('-vnclisten')
+        ret.append(str(vnclisten))
+        
+        # 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)
 
         return ret
 
diff -r 7c992fd3b19b -r 3cccf8e64296 
tools/python/xen/xend/server/ConsoleController.py
--- a/tools/python/xen/xend/server/ConsoleController.py Wed Jan 31 12:58:41 
2007 +0000
+++ b/tools/python/xen/xend/server/ConsoleController.py Wed Jan 31 13:20:36 
2007 +0000
@@ -8,7 +8,7 @@ class ConsoleController(DevController):
     console devices with persistent UUIDs.
     """
 
-    valid_cfg = ['uri', 'uuid', 'protocol']
+    valid_cfg = ['location', 'uuid', 'protocol']
 
     def __init__(self, vm):
         DevController.__init__(self, vm)
@@ -29,3 +29,7 @@ class ConsoleController(DevController):
 
     def migrate(self, deviceConfig, network, dst, step, domName):
         return 0
+
+    def destroyDevice(self, devid, force):
+        DevController.destroyDevice(self, devid, True)
+        
diff -r 7c992fd3b19b -r 3cccf8e64296 tools/python/xen/xend/server/vfbif.py
--- a/tools/python/xen/xend/server/vfbif.py     Wed Jan 31 12:58:41 2007 +0000
+++ b/tools/python/xen/xend/server/vfbif.py     Wed Jan 31 13:20:36 2007 +0000
@@ -14,7 +14,8 @@ def spawn_detached(path, args, env):
         os.waitpid(p, 0)
         
 CONFIG_ENTRIES = ['type', 'vncdisplay', 'vnclisten', 'vncpasswd', 'vncunused',
-                  'display', 'xauthority', 'keymap' ]
+                  'display', 'xauthority', 'keymap',
+                  'uuid', 'location', 'protocol']
 
 class VfbifController(DevController):
     """Virtual frame buffer controller. Handles all vfb devices for a domain.
@@ -27,10 +28,11 @@ class VfbifController(DevController):
     def getDeviceDetails(self, config):
         """@see DevController.getDeviceDetails"""
 
-        back = dict([(k, config[k]) for k in CONFIG_ENTRIES
+        back = dict([(k, str(config[k])) for k in CONFIG_ENTRIES
                      if config.has_key(k)])
 
-        return (0, back, {})
+        devid = 0
+        return (devid, back, {})
 
 
     def getDeviceConfiguration(self, devid):
@@ -44,6 +46,10 @@ class VfbifController(DevController):
 
     def createDevice(self, config):
         DevController.createDevice(self, config)
+        if self.vm.info.get('HVM_boot'):
+            # is HVM, so qemu-dm will handle the vfb.
+            return
+        
         std_args = [ "--domid", "%d" % self.vm.getDomid(),
                      "--title", self.vm.getName() ]
         t = config.get("type", None)
@@ -82,6 +88,42 @@ class VfbifController(DevController):
         else:
             raise VmError('Unknown vfb type %s (%s)' % (t, repr(config)))
 
+
+    def waitForDevice(self, devid):
+        if self.vm.info.get('HVM_boot'):
+            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)
+
+
+    def reconfigureDevice(self, _, config):
+        """ Only allow appending location information of vnc port into
+        xenstore."""
+
+        if 'location' in config:
+            (devid, back, front) = self.getDeviceDetails(config)
+            self.writeBackend(devid, 'location', config['location'])
+            return back.get('uuid')
+
+        raise VmError('Refusing to reconfigure device vfb:%d' % devid)
+
+    def destroyDevice(self, devid, force):
+        if self.vm.info.get('HVM_boot'):
+            # remove the backend xenstore entries for HVM guests no matter
+            # what
+            DevController.destroyDevice(self, devid, True)
+        else:
+            DevController.destroyDevice(self, devid, force)
+
+
+    def migrate(self, deviceConfig, network, dst, step, domName):
+        if self.vm.info.get('HVM_boot'):        
+            return 0
+        return DevController.migrate(self, deviceConfig, network, dst, step,
+                                     domName)
+    
 class VkbdifController(DevController):
     """Virtual keyboard controller. Handles all vkbd devices for a domain.
     """
@@ -92,3 +134,24 @@ class VkbdifController(DevController):
         back = {}
         front = {}
         return (devid, back, front)
+
+    def waitForDevice(self, config):
+        if self.vm.info.get('HVM_boot'):
+            # is a qemu-dm managed device, don't wait for hotplug for these.
+            return
+
+        DevController.waitForDevice(self, config)
+
+    def destroyDevice(self, devid, force):
+        if self.vm.info.get('HVM_boot'):
+            # remove the backend xenstore entries for HVM guests no matter
+            # what
+            DevController.destroyDevice(self, devid, True)
+        else:
+            DevController.destroyDevice(self, devid, force)
+
+    def migrate(self, deviceConfig, network, dst, step, domName):
+        if self.vm.info.get('HVM_boot'):        
+            return 0
+        return DevController.migrate(self, deviceConfig, network, dst, step,
+                                     domName)        

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.