ia64/xen-unstable

changeset 12686:5bed7bc05c8a

[XEND] Remove SXP from most parts of Xend.

Attempt to get rid of most SXP dependency in Xend except in
configuration parsing and certain places where it is
required.

XendConfig now stores configuration options similar to Xen API VM
and devices attributes but exports an SXP version to certain things
like xm and XendCheckpoint. All access to VM and device attributes
should now use Python dictionaries rather than the SXP parser.

Signed-off-by: Alastair Tse <atse@xensource.com>
author Alastair Tse <atse@xensource.com>
date Thu Nov 30 14:44:58 2006 +0000 (2006-11-30)
parents e7cb5813e2a7
children a3b8c9e773e1
files tools/python/xen/xend/XendAPI.py tools/python/xen/xend/XendCheckpoint.py tools/python/xen/xend/XendConfig.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/image.py tools/python/xen/xend/server/DevController.py tools/python/xen/xend/server/blkif.py tools/python/xen/xend/server/iopif.py tools/python/xen/xend/server/irqif.py tools/python/xen/xend/server/netif.py tools/python/xen/xend/server/pciif.py tools/python/xen/xend/server/pciquirk.py tools/python/xen/xend/server/tests/test_controllers.py tools/python/xen/xend/server/tpmif.py tools/python/xen/xm/main.py
line diff
     1.1 --- a/tools/python/xen/xend/XendAPI.py	Thu Nov 30 14:05:27 2006 +0000
     1.2 +++ b/tools/python/xen/xend/XendAPI.py	Thu Nov 30 14:44:58 2006 +0000
     1.3 @@ -730,11 +730,11 @@ class XendAPI:
     1.4      
     1.5      def vm_get_memory_dynamic_max(self, session, vm_ref):
     1.6          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
     1.7 -        return xen_api_todo()
     1.8 +        return xen_api_success(dom.get_memory_dynamic_max())
     1.9  
    1.10      def vm_get_memory_dynamic_min(self, session, vm_ref):
    1.11          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.12 -        return xen_api_todo()    
    1.13 +        return xen_api_success(dom.get_memory_dynamic_min())        
    1.14      
    1.15      def vm_get_VCPUs_policy(self, session, vm_ref):
    1.16          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.17 @@ -798,11 +798,11 @@ class XendAPI:
    1.18      
    1.19      def vm_get_builder(self, session, vm_ref):
    1.20          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.21 -        return xen_api_todo()
    1.22 +        return xen_api_success(dom.get_builder())
    1.23      
    1.24      def vm_get_boot_method(self, session, vm_ref):
    1.25          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.26 -        return xen_api_success('')
    1.27 +        return xen_api_success(dom.get_boot_method())
    1.28      
    1.29      def vm_get_kernel_kernel(self, session, vm_ref):
    1.30          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.31 @@ -969,8 +969,8 @@ class XendAPI:
    1.32              'resident_on': XendNode.instance().uuid,
    1.33              'memory_static_min': xeninfo.get_memory_static_min(),
    1.34              'memory_static_max': xeninfo.get_memory_static_max(),
    1.35 -            'memory_dynamic_min': xeninfo.get_memory_static_min(),
    1.36 -            'memory_dynamic_max': xeninfo.get_memory_static_max(),
    1.37 +            'memory_dynamic_min': xeninfo.get_memory_dynamic_min(),
    1.38 +            'memory_dynamic_max': xeninfo.get_memory_dynamic_max(),
    1.39              'memory_actual': xeninfo.get_memory_static_min(),
    1.40              'vcpus_policy': xeninfo.get_vcpus_policy(),
    1.41              'vcpus_params': xeninfo.get_vcpus_params(),
     2.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Thu Nov 30 14:05:27 2006 +0000
     2.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Thu Nov 30 14:44:58 2006 +0000
     2.3 @@ -18,8 +18,8 @@ import xen.lowlevel.xc
     2.4  from xen.xend import balloon, sxp
     2.5  from xen.xend.XendError import XendError, VmError
     2.6  from xen.xend.XendLogging import log
     2.7 +from xen.xend.XendConfig import XendConfig
     2.8  from xen.xend.XendConstants import *
     2.9 -from xen.xend.XendConfig import XendConfig
    2.10  
    2.11  SIGNATURE = "LinuxGuestRecord"
    2.12  XC_SAVE = "xc_save"
    2.13 @@ -137,7 +137,7 @@ def restore(xd, fd, dominfo = None, paus
    2.14      vmconfig = p.get_val()
    2.15  
    2.16      if dominfo:
    2.17 -        dominfo.update(XendConfig(sxp = vmconfig), refresh = False)
    2.18 +        dominfo.update(XendConfig(sxp_obj = vmconfig), refresh = False)
    2.19          dominfo.resume()
    2.20      else:
    2.21          dominfo = xd.restore_(vmconfig)
     3.1 --- a/tools/python/xen/xend/XendConfig.py	Thu Nov 30 14:05:27 2006 +0000
     3.2 +++ b/tools/python/xen/xend/XendConfig.py	Thu Nov 30 14:44:58 2006 +0000
     3.3 @@ -31,31 +31,34 @@ from xen.xend.XendConstants import DOM_S
     3.4  XendConfig API
     3.5  
     3.6    XendConfig will try to mirror as closely the Xen API VM Struct
     3.7 -  providing a backwards compatibility mode for SXP dumping, loading.
     3.8 +  with extra parameters for those options that are not supported.
     3.9  
    3.10  """
    3.11  
    3.12 +def reverse_dict(adict):
    3.13 +    """Return the reverse mapping of a dictionary."""
    3.14 +    return dict([(v, k) for k, v in adict.items()])
    3.15  
    3.16 -LEGACY_CFG_TO_XENAPI_CFG = {
    3.17 +# Mapping from XendConfig configuration keys to the old
    3.18 +# legacy configuration keys that map directly.
    3.19 +
    3.20 +XENAPI_CFG_TO_LEGACY_CFG = {
    3.21      'uuid': 'uuid',
    3.22 -    'vcpus': 'vcpus_number',
    3.23 -    'maxmem': 'memory_static_max',
    3.24 -    'memory': 'memory_static_min',
    3.25 -    'name': 'name_label',
    3.26 -    'on_poweroff': 'actions_after_shutdown',            
    3.27 -    'on_reboot': 'actions_after_reboot',
    3.28 -    'on_crash': 'actions_after_crash',
    3.29 -    'bootloader': 'boot_method',
    3.30 -    'kernel_kernel': 'kernel_kernel',
    3.31 -    'kernel_initrd': 'kernel_initrd',
    3.32 -    'kernel_args': 'kernel_args',
    3.33 -    }
    3.34 +    'vcpus_number': 'vcpus',
    3.35 +    'memory_static_min': 'memory',
    3.36 +    'memory_static_max': 'maxmem',
    3.37 +    'name_label': 'name',
    3.38 +    'actions_after_shutdown': 'on_poweroff',
    3.39 +    'actions_after_reboot': 'on_reboot',
    3.40 +    'actions_after_crash': 'on_crash', 
    3.41 +    'platform_localtime': 'localtime',
    3.42 +}
    3.43  
    3.44 -XENAPI_CFG_CUSTOM_TRANSLATE = [
    3.45 -    'vifs',
    3.46 -    'vbds',
    3.47 -    ]
    3.48 +LEGACY_CFG_TO_XENAPI_CFG = reverse_dict(XENAPI_CFG_TO_LEGACY_CFG)
    3.49  
    3.50 +# Mapping from XendConfig configuration keys to the old
    3.51 +# legacy configuration keys that are found in the 'image'
    3.52 +# SXP object.
    3.53  XENAPI_HVM_CFG = {
    3.54      'platform_std_vga': 'std-vga',
    3.55      'platform_serial' : 'serial',
    3.56 @@ -64,7 +67,10 @@ XENAPI_HVM_CFG = {
    3.57      'platform_keymap' : 'keymap',
    3.58  }    
    3.59  
    3.60 -XENAPI_UNSUPPORTED_IN_LEGACY_CFG = [
    3.61 +# List of XendConfig configuration keys that have no equivalent
    3.62 +# in the old world.
    3.63 +
    3.64 +XENAPI_UNSUPPORTED_BY_LEGACY_CFG = [
    3.65      'name_description',
    3.66      'user_version',
    3.67      'is_a_template',
    3.68 @@ -85,11 +91,116 @@ XENAPI_UNSUPPORTED_IN_LEGACY_CFG = [
    3.69      'platform_clock_offset',
    3.70      'platform_enable_audio',
    3.71      'platform_keymap',
    3.72 +    'boot_method',
    3.73      'builder',
    3.74      'grub_cmdline',
    3.75      'pci_bus',
    3.76      'otherconfig'
    3.77 -    ]
    3.78 +]
    3.79 +
    3.80 +# List of legacy configuration keys that have no equivalent in the
    3.81 +# Xen API, but are still stored in XendConfig.
    3.82 +
    3.83 +LEGACY_UNSUPPORTED_BY_XENAPI_CFG = [
    3.84 +    # roundtripped (dynamic, unmodified)
    3.85 +    'shadow_memory',
    3.86 +    'security',
    3.87 +    'vcpu_avail',
    3.88 +    'cpu_weight',
    3.89 +    'cpu_cap',
    3.90 +    'bootloader',
    3.91 +    'bootloader_args',
    3.92 +    'features',
    3.93 +    # read/write
    3.94 +    'on_xend_start',
    3.95 +    'on_xend_stop',
    3.96 +    # read-only
    3.97 +    'domid',
    3.98 +    'start_time',
    3.99 +    'cpu_time',
   3.100 +    'online_vcpus',
   3.101 +    # write-once
   3.102 +    'cpu',
   3.103 +    'cpus',
   3.104 +]
   3.105 +
   3.106 +LEGACY_CFG_TYPES = {
   3.107 +    'uuid':          str,
   3.108 +    'name':          str,
   3.109 +    'vcpus':         int,
   3.110 +    'vcpu_avail':    int,
   3.111 +    'memory':        int,
   3.112 +    'shadow_memory': int,
   3.113 +    'maxmem':        int,
   3.114 +    'start_time':    float,
   3.115 +    'cpu_cap':         int,
   3.116 +    'cpu_weight':      int,
   3.117 +    'cpu_time':      float,
   3.118 +    'bootloader':      str,
   3.119 +    'bootloader_args': str,
   3.120 +    'features':        str,
   3.121 +    'localtime':       int,
   3.122 +    'name':        str,
   3.123 +    'on_poweroff': str,
   3.124 +    'on_reboot':   str,
   3.125 +    'on_crash':    str,
   3.126 +    'on_xend_stop': str,
   3.127 +    'on_xend_start': str,
   3.128 +}
   3.129 +
   3.130 +# Values that should be stored in xenstore's /vm/<uuid> that is used
   3.131 +# by Xend. Used in XendDomainInfo to restore running VM state from
   3.132 +# xenstore.
   3.133 +LEGACY_XENSTORE_VM_PARAMS = [
   3.134 +    'uuid',
   3.135 +    'name',
   3.136 +    'vcpus',
   3.137 +    'vcpu_avail',
   3.138 +    'memory',
   3.139 +    'shadow_memory',
   3.140 +    'maxmem',
   3.141 +    'start_time',
   3.142 +    'name',
   3.143 +    'on_poweroff',
   3.144 +    'on_crash',
   3.145 +    'on_reboot',
   3.146 +    'on_xend_start',
   3.147 +    'on_xend_stop',
   3.148 +]
   3.149 +
   3.150 +LEGACY_IMAGE_CFG = [
   3.151 +    ('root', str),
   3.152 +    ('ip', str),
   3.153 +    ('nographic', int),
   3.154 +    ('vnc', int),
   3.155 +    ('sdl', int),
   3.156 +    ('vncdisplay', int),
   3.157 +    ('vncunused', int),
   3.158 +]
   3.159 +
   3.160 +LEGACY_IMAGE_HVM_CFG = [
   3.161 +    ('device_model', str),
   3.162 +    ('display', str),
   3.163 +    ('xauthority', str),
   3.164 +    ('vncconsole', int),
   3.165 +    ('pae', int),
   3.166 +    ('apic', int),
   3.167 +    ('acpi', int),
   3.168 +    ('serial', str),
   3.169 +]
   3.170 +
   3.171 +LEGACY_IMAGE_HVM_DEVICES_CFG = [
   3.172 +    ('boot', str),
   3.173 +    ('fda', str),
   3.174 +    ('fdb', str),
   3.175 +    ('soundhw', str),
   3.176 +    ('isa', str),
   3.177 +    ('vcpus', int),
   3.178 +    ('acpi', int),
   3.179 +    ('usb', str),
   3.180 +    ('usbdevice', str),
   3.181 +]
   3.182 +
   3.183  
   3.184  
   3.185  # configuration params that need to be converted to ints
   3.186 @@ -102,75 +213,12 @@ XENAPI_INT_CFG = [
   3.187      'memory_static_max',
   3.188      'memory_dynamic_min',
   3.189      'memory_dynamic_max',
   3.190 +    'memory_actual',
   3.191      'tpm_instance',
   3.192      'tpm_backend',
   3.193  ]    
   3.194  
   3.195  ##
   3.196 -## Xend Configuration Parameters
   3.197 -##
   3.198 -
   3.199 -
   3.200 -# All parameters of VMs that may be configured on-the-fly, or at start-up.
   3.201 -VM_CONFIG_ENTRIES = [
   3.202 -    ('name',        str),
   3.203 -    ('on_crash',    str),
   3.204 -    ('on_poweroff', str),
   3.205 -    ('on_reboot',   str),
   3.206 -    ('on_xend_start', str),
   3.207 -    ('on_xend_stop', str),        
   3.208 -]
   3.209 -
   3.210 -# All entries written to the store.  This is VM_CONFIG_ENTRIES, plus those
   3.211 -# entries written to the store that cannot be reconfigured on-the-fly.
   3.212 -VM_STORE_ENTRIES = [
   3.213 -    ('uuid',       str),
   3.214 -    ('vcpus',      int),
   3.215 -    ('vcpu_avail', int),
   3.216 -    ('memory',     int),
   3.217 -    ('maxmem',     int),
   3.218 -    ('start_time', float),
   3.219 -]
   3.220 -
   3.221 -VM_STORED_ENTRIES = VM_CONFIG_ENTRIES + VM_STORE_ENTRIES
   3.222 -
   3.223 -# Configuration entries that we expect to round-trip -- be read from the
   3.224 -# config file or xc, written to save-files (i.e. through sxpr), and reused as
   3.225 -# config on restart or restore, all without munging.  Some configuration
   3.226 -# entries are munged for backwards compatibility reasons, or because they
   3.227 -# don't come out of xc in the same form as they are specified in the config
   3.228 -# file, so those are handled separately.
   3.229 -
   3.230 -ROUNDTRIPPING_CONFIG_ENTRIES = [
   3.231 -    ('uuid',       str),
   3.232 -    ('vcpus',      int),
   3.233 -    ('vcpu_avail', int),
   3.234 -    ('cpu_cap',    int),
   3.235 -    ('cpu_weight', int),
   3.236 -    ('memory',     int),
   3.237 -    ('shadow_memory', int),
   3.238 -    ('maxmem',     int),
   3.239 -    ('bootloader', str),
   3.240 -    ('bootloader_args', str),
   3.241 -    ('features', str),
   3.242 -    ('localtime', int),
   3.243 -]
   3.244 -ROUNDTRIPPING_CONFIG_ENTRIES += VM_CONFIG_ENTRIES
   3.245 -
   3.246 -## Static Configuration
   3.247 -
   3.248 -STATIC_CONFIG_ENTRIES = [
   3.249 -    ('cpu',      int),
   3.250 -    ('cpus',     str),
   3.251 -    ('image',    list),
   3.252 -    ('security', list), # TODO: what if null?
   3.253 -]
   3.254 -
   3.255 -DEPRECATED_ENTRIES = [
   3.256 -    ('restart', str),
   3.257 -]
   3.258 -
   3.259 -##
   3.260  ## Config Choices
   3.261  ##
   3.262  
   3.263 @@ -178,245 +226,152 @@ CONFIG_RESTART_MODES = ('restart', 'dest
   3.264  CONFIG_OLD_DOM_STATES = ('running', 'blocked', 'paused', 'shutdown',
   3.265                           'crashed', 'dying')
   3.266  
   3.267 -##
   3.268 -## Defaults
   3.269 -##
   3.270 -
   3.271 -def DEFAULT_VCPUS(info):
   3.272 -    if 'max_vcpu_id' in info: return int(info['max_vcpu_id']) + 1
   3.273 -    else: return 1
   3.274 -
   3.275 -DEFAULT_CONFIGURATION = (
   3.276 -    ('uuid',         lambda info: uuid.createString()),
   3.277 -    ('name',         lambda info: 'Domain-' + info['uuid']),
   3.278 -
   3.279 -    ('on_poweroff',  lambda info: 'destroy'),
   3.280 -    ('on_reboot',    lambda info: 'restart'),
   3.281 -    ('on_crash',     lambda info: 'restart'),
   3.282 -    ('features',     lambda info: ''),
   3.283 -
   3.284 -    
   3.285 -    ('memory',       lambda info: 0),
   3.286 -    ('shadow_memory',lambda info: 0),
   3.287 -    ('maxmem',       lambda info: 0),
   3.288 -    ('bootloader',   lambda info: None),
   3.289 -    ('bootloader_args', lambda info: None),            
   3.290 -    ('backend',      lambda info: []),
   3.291 -    ('device',       lambda info: {}),
   3.292 -    ('image',        lambda info: None),
   3.293 -    ('security',     lambda info: []),
   3.294 -    ('on_xend_start', lambda info: 'ignore'),    
   3.295 -    ('on_xend_stop', lambda info: 'ignore'),
   3.296 -
   3.297 -    ('cpus',         lambda info: []),
   3.298 -    ('cpu_cap',      lambda info: 0),
   3.299 -    ('cpu_weight',   lambda info: 256),
   3.300 -    ('vcpus',        lambda info: DEFAULT_VCPUS(info)),
   3.301 -    ('online_vcpus', lambda info: info['vcpus']),
   3.302 -    ('max_vcpu_id',  lambda info: info['vcpus']-1),
   3.303 -    ('vcpu_avail',   lambda info: (1<<info['vcpus'])-1),
   3.304 -
   3.305 -    # New for Xen API
   3.306 -    ('kernel_kernel', lambda info: ''),
   3.307 -    ('kernel_initrd', lambda info: ''),
   3.308 -    ('kernel_args',   lambda info: ''),
   3.309 -    
   3.310 -)
   3.311 -    
   3.312  class XendConfigError(VmError):
   3.313      def __str__(self):
   3.314          return 'Invalid Configuration: %s' % str(self.value)
   3.315  
   3.316  ##
   3.317 -## XendConfig SXP Config Compat
   3.318 -##
   3.319 -
   3.320 -class XendSXPConfig:
   3.321 -    def get_domid(self):
   3.322 -        pass
   3.323 -    def get_handle(self):
   3.324 -        return self['uuid']
   3.325 -        
   3.326 -
   3.327 -##
   3.328  ## XendConfig Class (an extended dictionary)
   3.329  ##
   3.330  
   3.331  class XendConfig(dict):
   3.332 -    """ Generic Configuration Parser accepting SXP, Python or XML.
   3.333 -    This is a dictionary-like object that is populated.
   3.334 -
   3.335 -    @ivar legacy: dictionary holding legacy xen domain info
   3.336 -    @ivar xenapi: dictionary holding xen api config info
   3.337 -    """
   3.338 -
   3.339 -    def __init__(self, filename = None, fd = None,
   3.340 -                 sxp = None, xml = None, pycfg = None, xenapi_vm = None,
   3.341 -                 cfg = {}):
   3.342 -        """Constructor. Provide either the filename, fd or sxp.
   3.343 +    """ The new Xend VM Configuration.
   3.344  
   3.345 -        @keyword filename: filename of an SXP file
   3.346 -        @keyword fd: file descriptor of an SXP file
   3.347 -        @keyword sxp: a list of list of a parsed SXP
   3.348 -        @keyword xml: an XML tree object
   3.349 -        @keyword xenapi_vm: a struct passed from an XMLRPC call (Xen API)
   3.350 -        @keyword cfg: a dictionary of configuration (eg. from xc)
   3.351 -        """
   3.352 -        format = 'unknown'
   3.353 -
   3.354 -        self.xenapi = {}
   3.355 -
   3.356 -        if filename and not fd:
   3.357 -            fd = open(filename, 'r')
   3.358 -
   3.359 -        if fd:
   3.360 -            format = self._detect_format(fd)
   3.361 +    Stores the configuration in xenapi compatible format but retains
   3.362 +    import and export functions for SXP.
   3.363 +    """
   3.364 +    def __init__(self, filename = None, sxp_obj = None,
   3.365 +                 xapi = None, dominfo = None):
   3.366          
   3.367 -        if fd:
   3.368 -            if format == 'sxp':
   3.369 -                sxp = self._read_sxp(fd)
   3.370 -            elif format == 'python' and filename != None:
   3.371 -                pycfg = self._read_python(filename)
   3.372 -            elif format == 'python' and filename == None:
   3.373 -                raise XendConfigError("Python files must be passed as a "
   3.374 -                                      "filename rather than file descriptor.")
   3.375 -            elif format == 'xml':
   3.376 -                xml = self._read_xml(fd)
   3.377 -            else:
   3.378 -                raise XendConfigError("Unable to determine format of file")
   3.379 -                
   3.380 -        if sxp:
   3.381 -            cfg = self._populate_from_sxp(sxp)
   3.382 -        if xml:
   3.383 -            cfg = self._populate_from_xml(xml)
   3.384 -        if pycfg:
   3.385 -            cfg = self._populate_from_python_config(pycfg)
   3.386 -        if xenapi_vm:
   3.387 -            cfg = self._populate_from_xenapi_vm(xenapi_vm)
   3.388 -            
   3.389 -        if cfg:
   3.390 -            self.update(cfg)
   3.391 -            
   3.392 -        if xenapi_vm:
   3.393 -            self.xenapi.update(xenapi_vm)
   3.394 +        dict.__init__(self)
   3.395 +        self.update(self._defaults())
   3.396  
   3.397 -        log.debug('XendConfig: %s' % str(self))
   3.398 +        if filename:
   3.399 +            try:
   3.400 +                sxp_obj = sxp.parse(open(filename,'r'))
   3.401 +                sxp_obj = sxp_obj[0]
   3.402 +            except IOError, e:
   3.403 +                raise XendConfigError("Unable to read file: %s" % filename)
   3.404 +        
   3.405 +        if sxp_obj:
   3.406 +            self._sxp_to_xapi(sxp_obj)
   3.407 +            self._sxp_to_xapi_unsupported(sxp_obj)
   3.408 +        elif xapi:
   3.409 +            self.update(xapi)
   3.410 +            self._add_xapi_unsupported()
   3.411 +        elif dominfo:
   3.412 +            # output from xc.domain_getinfo
   3.413 +            self._dominfo_to_xapi(dominfo)
   3.414 +
   3.415 +        log.debug('XendConfig.init: %s' % self)
   3.416 +
   3.417 +        # validators go here
   3.418          self.validate()
   3.419  
   3.420 -    #
   3.421 -    # Xen API Attribute Access
   3.422 -    #
   3.423 -
   3.424 -    def __getattr__(self, name):
   3.425 -        try:
   3.426 -            return dict.__getattr__(self, name)
   3.427 -        except AttributeError:
   3.428 -            try:
   3.429 -                return  self.__dict__['xenapi'][name]
   3.430 -            except KeyError:
   3.431 -                raise AttributeError("XendConfig Xen API has no attribute "
   3.432 -                                     "'%s'" % name)
   3.433 -            
   3.434 -
   3.435 -    def __setattr__(self, name, value):
   3.436 -        try:
   3.437 -            return dict.__setattr__(self, name, value)
   3.438 -        except AttributeError:
   3.439 -            self.xenapi[name] = value
   3.440 -            #self.set_legacy_api_with_xen_api_value(name, value)
   3.441 +    def _defaults(self):
   3.442 +        defaults = {
   3.443 +            'uuid': uuid.createString(),
   3.444 +            'name_label': 'Domain-Unnamed',
   3.445 +            'actions_after_shutdown': 'destroy',
   3.446 +            'actions_after_reboot': 'restart',
   3.447 +            'actions_after_crash': 'restart',
   3.448 +            'actions_after_suspend': '',
   3.449 +            'features': '',
   3.450 +            'builder': 'linux',
   3.451 +            'memory_static_min': 0,
   3.452 +            'memory_dynamic_min': 0,
   3.453 +            'shadow_memory': 0,
   3.454 +            'memory_static_max': 0,
   3.455 +            'memory_dynamic_max': 0,
   3.456 +            'memory_actual': 0,
   3.457 +            'boot_method': None,
   3.458 +            'bootloader': None,
   3.459 +            'bootloader_args': None,
   3.460 +            'devices': {},
   3.461 +            'image': {},
   3.462 +            'security': None,
   3.463 +            'on_xend_start': 'ignore',
   3.464 +            'on_xend_stop': 'ignore',
   3.465 +            'cpus': [],
   3.466 +            'cpu_weight': 256,
   3.467 +            'cpu_cap': 0,
   3.468 +            'vcpus_number': 1,
   3.469 +            'online_vcpus': 1,
   3.470 +            'max_vcpu_id': 0,
   3.471 +            'vcpu_avail': 1,
   3.472 +            'vif_refs': [],
   3.473 +            'vbd_refs': [],
   3.474 +            'vtpm_refs': [],
   3.475 +        }
   3.476 +        
   3.477 +        defaults['name_label'] = 'Domain-' + defaults['uuid']
   3.478 +        return defaults
   3.479  
   3.480 -    def __delattr__(self, name):
   3.481 -        try:
   3.482 -            dict.__delattr__(self, name)
   3.483 -        except AttributeError:
   3.484 -            del self.xenapi[name]
   3.485 -        #self.del_legacy_api_with_xen_api_key(name)
   3.486 -
   3.487 -
   3.488 -    """
   3.489 -    #
   3.490 -    # Legacy API Attribute Access
   3.491 -    #
   3.492 -
   3.493 -    def __getitem__(self, key):
   3.494 -        try:
   3.495 -            return self.legacy[key]
   3.496 -        except KeyError:
   3.497 -            raise AttributeError, "XendConfig Legacy has no attribute '%s'"\
   3.498 -                  % key
   3.499 -
   3.500 -    def __setitem__(self, key, value):
   3.501 -        self.legacy[key] = value
   3.502 -        self.set_xen_api_with_legacy_api_value(key, value)
   3.503 -
   3.504 -    def __delitem__(self, key):
   3.505 -        del self.legacy[key]
   3.506 -        self.del_xen_api_with_legacy_api_key(key)
   3.507 -    """
   3.508 -    
   3.509 +    def _memory_sanity_check(self):
   3.510 +        if self['memory_static_min'] == 0:
   3.511 +            self['memory_static_min'] = self['memory_dynamic_min']
   3.512  
   3.513 -    def _detect_format(self, fd):
   3.514 -        """Detect the format of the configuration passed.
   3.515 +        # If the static max is not set, let's set it to dynamic max.
   3.516 +        # If the static max is smaller than static min, then fix it!
   3.517 +        self['memory_static_max'] = max(self['memory_static_max'],
   3.518 +                                        self['memory_dynamic_max'],
   3.519 +                                        self['memory_static_min'])
   3.520  
   3.521 -        @param fd: file descriptor of contents to detect
   3.522 -        @rtype: string, 'sxp', 'xml', 'python' or 'unknown'
   3.523 -        """
   3.524 -        format = 'unknown'
   3.525 -        
   3.526 -        fd.seek(0)
   3.527 -        for line in fd:
   3.528 -            stripped = line.strip()
   3.529 -            if stripped:
   3.530 -                if re.search(r'^\(', stripped): 
   3.531 -                    format = 'sxp'
   3.532 -                elif re.search(r'^\<?xml', stripped):
   3.533 -                    format = 'xml'
   3.534 -                else:
   3.535 -                    format = 'python'
   3.536 -                break
   3.537 +        for mem_type in ('memory_static_min', 'memory_static_max'):
   3.538 +            if self[mem_type] <= 0:
   3.539 +                raise XendConfigError('Memory value too low for %s: %d' %
   3.540 +                                      (mem_type, self[mem_type]))
   3.541  
   3.542 -        fd.seek(0)
   3.543 -        return format
   3.544 +    def _actions_sanity_check(self):
   3.545 +        for event in ['shutdown', 'reboot', 'crash']:
   3.546 +            if self['actions_after_' + event] not in CONFIG_RESTART_MODES:
   3.547 +                raise XendConfigError('Invalid event handling mode: ' +
   3.548 +                                      event)
   3.549  
   3.550 -    def _read_sxp(self, fd):
   3.551 -        """ Read and parse SXP (from SXP to list of lists)
   3.552 +    def validate(self):
   3.553 +        self._memory_sanity_check()
   3.554 +        self._actions_sanity_check()
   3.555  
   3.556 -        @rtype: list of lists.
   3.557 -        """
   3.558 -        try:
   3.559 -            parsed = sxp.parse(fd)[0]
   3.560 -            return parsed
   3.561 -        except:
   3.562 -            raise
   3.563 -            return None
   3.564 -
   3.565 -    def _read_xml(self, fd):
   3.566 -        """TODO: Read and parse XML (from XML to dict)
   3.567 +    def _dominfo_to_xapi(self, dominfo):
   3.568 +        self['domid'] = dominfo['domid']
   3.569 +        self['online_vcpus'] = dominfo['online_vcpus']
   3.570 +        self['max_vcpu_id'] = dominfo['max_vcpu_id']
   3.571 +        self['memory_dynamic_min'] = (dominfo['mem_kb'] + 1023)/1024
   3.572 +        self['memory_dynamic_max'] = (dominfo['maxmem_kb'] + 1023)/1024
   3.573 +        self['cpu_time'] = dominfo['cpu_time']/1e9
   3.574 +        # TODO: i don't know what the security stuff expects here
   3.575 +        if dominfo.get('ssidref'):
   3.576 +            self['security'] = [['ssidref', dominfo['ssidref']]]
   3.577 +        self['shutdown_reason'] = dominfo['shutdown_reason']
   3.578  
   3.579 -        @rtype: dict
   3.580 -        """
   3.581 -        raise NotImplementedError
   3.582 -
   3.583 -    def _read_python(self, filename):
   3.584 -        """Read and parse python module that represents the config.
   3.585 +        # parse state into Xen API states
   3.586 +        self['running'] = dominfo['running']
   3.587 +        self['crashed'] = dominfo['crashed']
   3.588 +        self['dying'] = dominfo['dying']
   3.589 +        self['shutdown'] = dominfo['shutdown']
   3.590 +        self['paused'] = dominfo['paused']
   3.591 +        self['blocked'] = dominfo['blocked']
   3.592  
   3.593 -        @rtype: dict
   3.594 -        """
   3.595 -        cfg_globals = {}
   3.596 -        execfile(filename, cfg_globals, {})
   3.597 -        return cfg_globals
   3.598 +        if 'name' in dominfo:
   3.599 +            self['name_label'] = dominfo['name']
   3.600  
   3.601 -    def _populate_from_sxp(self, parsed):
   3.602 +        if 'handle' in dominfo:
   3.603 +            self['uuid'] = uuid.toString(dominfo['handle'])
   3.604 +            
   3.605 +    def _parse_sxp(self, sxp_cfg):
   3.606          """ Populate this XendConfig using the parsed SXP.
   3.607  
   3.608 +        @param sxp_cfg: Parsed SXP Configuration
   3.609 +        @type sxp_cfg: list of lists
   3.610          @rtype: dictionary
   3.611 +        @return: A dictionary containing the parsed options of the SXP.
   3.612          """
   3.613          cfg = {}
   3.614  
   3.615          # First step is to convert deprecated options to
   3.616          # current equivalents.
   3.617          
   3.618 -        restart = sxp.child_value(parsed, 'restart')
   3.619 +        restart = sxp.child_value(sxp_cfg, 'restart')
   3.620          if restart:
   3.621              if restart == 'onreboot':
   3.622                  cfg['on_poweroff'] = 'destroy'
   3.623 @@ -433,24 +388,20 @@ class XendConfig(dict):
   3.624                           'restart = \'%s\'', restart)
   3.625  
   3.626          # Only extract options we know about.
   3.627 -        all_params = VM_CONFIG_ENTRIES + ROUNDTRIPPING_CONFIG_ENTRIES + \
   3.628 -                     STATIC_CONFIG_ENTRIES
   3.629 -                     
   3.630 -        for key, typeconv in all_params:
   3.631 -            val = sxp.child_value(parsed, key)
   3.632 +        extract_keys = LEGACY_UNSUPPORTED_BY_XENAPI_CFG
   3.633 +        extract_keys += XENAPI_CFG_TO_LEGACY_CFG.values()
   3.634 +        
   3.635 +        for key in extract_keys:
   3.636 +            val = sxp.child_value(sxp_cfg, key)
   3.637              if val:
   3.638                  try:
   3.639 -                    cfg[key] = typeconv(val)
   3.640 +                    try:
   3.641 +                        cfg[key] = LEGACY_CFG_TYPES[key](val)
   3.642 +                    except KeyError:
   3.643 +                        cfg[key] = val
   3.644                  except ValueError:
   3.645                      pass
   3.646  
   3.647 -        # Manually extract other complex configuration
   3.648 -        # options.
   3.649 -
   3.650 -        cfg['backend'] = []
   3.651 -        for c in sxp.children(parsed, 'backend'):
   3.652 -            cfg['backend'].append(sxp.name(sxp.child0(c)))
   3.653 -
   3.654          # Parsing the device SXP's. In most cases, the SXP looks
   3.655          # like this:
   3.656          #
   3.657 @@ -472,65 +423,52 @@ class XendConfig(dict):
   3.658          # Hence we deal with pci device configurations outside of
   3.659          # the regular device parsing.
   3.660          
   3.661 -        cfg['device'] = {}
   3.662 -        for dev in sxp.children(parsed, 'device'):
   3.663 +        cfg['devices'] = {}
   3.664 +        for dev in sxp.children(sxp_cfg, 'device'):
   3.665              config = sxp.child0(dev)
   3.666              dev_type = sxp.name(config)
   3.667              dev_info = {}
   3.668              
   3.669              if dev_type == 'pci':
   3.670 -                continue 
   3.671 -            
   3.672 -            for opt, val in config[1:]:
   3.673 -                dev_info[opt] = val
   3.674 -            log.debug("XendConfig: reading device: %s" % dev_info)
   3.675 -            # create uuid if it doesn't
   3.676 -            dev_uuid = dev_info.get('uuid', uuid.createString())
   3.677 -            dev_info['uuid'] = dev_uuid
   3.678 -            cfg['device'][dev_uuid] = (dev_type, dev_info)
   3.679 -
   3.680 -        # deal with PCI device configurations if they exist
   3.681 -        for dev in sxp.children(parsed, 'device'):
   3.682 -            config = sxp.child0(dev)
   3.683 -            dev_type = sxp.name(config)
   3.684 -
   3.685 -            if dev_type != 'pci':
   3.686 -                continue
   3.687 -            
   3.688 -            dev_attr = sxp.child_value(config, 'dev')
   3.689 -            if isinstance(dev_attr, (types.ListType, types.TupleType)):
   3.690 +                pci_devs_uuid = sxp.child_value(config, 'uuid',
   3.691 +                                                uuid.createString())
   3.692 +                pci_devs = []
   3.693                  for pci_dev in sxp.children(config, 'dev'):
   3.694 -                    dev_info = {}
   3.695 +                    pci_dev_info = {}
   3.696                      for opt, val in pci_dev[1:]:
   3.697 -                        dev_info[opt] = val
   3.698 -                    log.debug("XendConfig: reading device: %s" % dev_info)
   3.699 -                    dev_uuid = dev_info.get('uuid', uuid.createString())
   3.700 -                    dev_info['uuid'] = dev_uuid
   3.701 -                    cfg['device'][dev_uuid] = (dev_type, dev_info)
   3.702 -                    
   3.703 -            else: # Xen 2.0 PCI device configuration
   3.704 +                        pci_dev_info[opt] = val
   3.705 +                    pci_devs.append(pci_dev_info)
   3.706 +                
   3.707 +                cfg['devices'][pci_devs_uuid] = (dev_type,
   3.708 +                                                 {'devs': pci_devs,
   3.709 +                                                  'uuid': pci_devs_uuid})
   3.710 +                
   3.711 +                log.debug("XendConfig: reading device: %s" % pci_devs)
   3.712 +            else:
   3.713                  for opt, val in config[1:]:
   3.714                      dev_info[opt] = val
   3.715                  log.debug("XendConfig: reading device: %s" % dev_info)
   3.716                  # create uuid if it doesn't
   3.717                  dev_uuid = dev_info.get('uuid', uuid.createString())
   3.718                  dev_info['uuid'] = dev_uuid
   3.719 -                cfg['device'][dev_uuid] = (dev_type, dev_info)
   3.720 +                cfg['devices'][dev_uuid] = (dev_type, dev_info)
   3.721 +
   3.722  
   3.723          # Extract missing data from configuration entries
   3.724 -        if 'image' in cfg:
   3.725 -            image_vcpus = sxp.child_value(cfg['image'], 'vcpus')
   3.726 +        image_sxp = sxp.child_value(sxp_cfg, 'image', [])
   3.727 +        if image_sxp:
   3.728 +            image_vcpus = sxp.child_value(image_sxp, 'vcpus')
   3.729              if image_vcpus is not None:
   3.730                  try:
   3.731 -                    if 'vcpus' not in cfg:
   3.732 -                        cfg['vcpus'] = int(image_vcpus)
   3.733 -                    elif cfg['vcpus'] != int(image_vcpus):
   3.734 -                        cfg['vcpus'] = int(image_vcpus)
   3.735 +                    if 'vcpus_number' not in cfg:
   3.736 +                        cfg['vcpus_number'] = int(image_vcpus)
   3.737 +                    elif cfg['vcpus_number'] != int(image_vcpus):
   3.738 +                        cfg['vcpus_number'] = int(image_vcpus)
   3.739                          log.warn('Overriding vcpus from %d to %d using image'
   3.740 -                                 'vcpus value.', cfg['vcpus'])
   3.741 +                                 'vcpus value.', cfg['vcpus_number'])
   3.742                  except ValueError, e:
   3.743                      raise XendConfigError('integer expeceted: %s: %s' %
   3.744 -                                        str(cfg['image']), e)
   3.745 +                                          image_sxp, e)
   3.746  
   3.747          # Deprecated cpu configuration
   3.748          if 'cpu' in cfg:
   3.749 @@ -564,101 +502,176 @@ class XendConfig(dict):
   3.750          except ValueError, e:
   3.751              raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e))
   3.752  
   3.753 -        # Parse image SXP outside of image.py
   3.754 -        # - used to be only done in image.py
   3.755 -        if 'image' in cfg:
   3.756 -            cfg['kernel_kernel'] = sxp.child_value(cfg['image'], 'kernel','')
   3.757 -            cfg['kernel_initrd'] = sxp.child_value(cfg['image'], 'ramdisk','')
   3.758 -            kernel_args = sxp.child_value(cfg['image'], 'args', '')
   3.759 -
   3.760 -            # attempt to extract extra arguments from SXP config
   3.761 -            arg_ip = sxp.child_value(cfg['image'], 'ip')
   3.762 -            if arg_ip: kernel_args += ' ip=%s' % arg_ip
   3.763 -            arg_root = sxp.child_value(cfg['image'], 'root')
   3.764 -            if arg_root: kernel_args += ' root=%s' % arg_root
   3.765 -            
   3.766 -            cfg['kernel_args'] = kernel_args
   3.767 +        if 'security' in cfg and isinstance(cfg['security'], str):
   3.768 +            cfg['security'] = sxp.from_string(cfg['security'])
   3.769  
   3.770          # TODO: get states
   3.771 -        old_state = sxp.child_value(parsed, 'state')
   3.772 +        old_state = sxp.child_value(sxp_cfg, 'state')
   3.773          if old_state:
   3.774              for i in range(len(CONFIG_OLD_DOM_STATES)):
   3.775                  cfg[CONFIG_OLD_DOM_STATES[i]] = int(old_state[i] != '-')
   3.776  
   3.777 -        # Xen API extra cfgs
   3.778 -        # ------------------
   3.779 -        cfg['vif_refs'] = []
   3.780 -        cfg['vbd_refs'] = []
   3.781 -        cfg['vtpm_refs'] = []
   3.782 -        for dev_uuid, (dev_type, dev_info) in cfg['device'].items():
   3.783 -            if dev_type == 'vif':
   3.784 -                cfg['vif_refs'].append(dev_uuid)
   3.785 -            elif dev_type in ('vbd','tap'):
   3.786 -                cfg['vbd_refs'].append(dev_uuid)
   3.787 -            elif dev_type == 'vtpm':
   3.788 -                cfg['vtpm_refs'].append(dev_uuid)
   3.789 -                
   3.790          return cfg
   3.791 -
   3.792 -
   3.793 -    def _populate_from_xenapi_vm(self, xenapi_vm):
   3.794 -        cfg = {}
   3.795 +    
   3.796  
   3.797 -        for cfgkey, apikey in LEGACY_CFG_TO_XENAPI_CFG.items():
   3.798 +    def _sxp_to_xapi(self, sxp_cfg):
   3.799 +        """Read in an SXP Configuration object and
   3.800 +        populate at much of the Xen API with valid values.
   3.801 +        """
   3.802 +        cfg = self._parse_sxp(sxp_cfg)
   3.803 +
   3.804 +        # Convert parameters that can be directly mapped from
   3.805 +        # the Legacy Config to Xen API Config
   3.806 +        
   3.807 +        for apikey, cfgkey in XENAPI_CFG_TO_LEGACY_CFG.items():
   3.808              try:
   3.809 -                if apikey in XENAPI_INT_CFG:
   3.810 -                    cfg[cfgkey] = int(xenapi_vm[apikey])
   3.811 -                else:
   3.812 -                    cfg[cfgkey] = xenapi_vm[apikey]                    
   3.813 +                self[apikey] = LEGACY_CFG_TYPES[cfgkey](cfg[cfgkey])
   3.814              except KeyError:
   3.815                  pass
   3.816  
   3.817 -        # Reconstruct image SXP 
   3.818 -        # TODO: get rid of SXP altogether from here
   3.819 -        sxp_image = ['linux']
   3.820 -        if xenapi_vm['kernel_kernel']:
   3.821 -            sxp_image.append(['kernel', xenapi_vm['kernel_kernel']])
   3.822 -        if xenapi_vm['kernel_initrd']:
   3.823 -            sxp_image.append(['ramdisk', xenapi_vm['kernel_initrd']])
   3.824 -        if xenapi_vm['kernel_args']:
   3.825 -            sxp_image.append(['args', xenapi_vm['kernel_args']])
   3.826 +        # Convert Legacy "image" config to Xen API kernel_*
   3.827 +        # configuration
   3.828 +        image_sxp = sxp.child_value(sxp_cfg, 'image', [])
   3.829 +        if image_sxp:
   3.830 +            self['kernel_kernel'] = sxp.child_value(image_sxp, 'kernel','')
   3.831 +            self['kernel_initrd'] = sxp.child_value(image_sxp, 'ramdisk','')
   3.832 +            kernel_args = sxp.child_value(image_sxp, 'args', '')
   3.833 +
   3.834 +            # attempt to extract extra arguments from SXP config
   3.835 +            arg_ip = sxp.child_value(image_sxp, 'ip')
   3.836 +            if arg_ip and not re.search(r'ip=[0-9\.]+', kernel_args):
   3.837 +                kernel_args += ' ip=%s' % arg_ip
   3.838 +            arg_root = sxp.child_value(image_sxp, 'root')
   3.839 +            if arg_root and not re.search(r'root=[^ ]+', kernel_args):
   3.840 +                kernel_args += ' root=%s' % arg_root
   3.841 +            
   3.842 +            self['kernel_args'] = kernel_args
   3.843 +
   3.844 +        # Convert Legacy HVM parameters to Xen API configuration
   3.845 +        self['platform_std_vga'] = cfg.get('std-vga', 0)
   3.846 +        self['platform_serial'] = cfg.get('serial', '')
   3.847 +        self['platform_localtime'] = cfg.get('localtime', 0)
   3.848 +        self['platform_enable_audio'] = cfg.get('soundhw', 0)
   3.849  
   3.850 -        cfg['image'] = prettyprintstring(sxp_image)
   3.851 +        # Convert path to bootloader to boot_method
   3.852 +        if not cfg.get('bootloader'):
   3.853 +            if self.get('kernel_kernel','').endswith('hvmloader'):
   3.854 +                self['boot_method'] = 'bios'
   3.855 +            else:
   3.856 +                self['boot_method'] = 'kernel_external'
   3.857 +        else:
   3.858 +            self['boot_method'] = 'grub'
   3.859 +
   3.860 +        # make sure a sane maximum is set
   3.861 +        if self['memory_static_max'] <= 0:
   3.862 +            self['memory_static_max'] = self['memory_static_min']
   3.863 +            
   3.864 +        self['memory_dynamic_max'] = self['memory_static_max']
   3.865 +        self['memory_dynamic_min'] = self['memory_static_min']
   3.866  
   3.867 -        # make sure device structures are there.
   3.868 -        if 'device' not in cfg:
   3.869 -            cfg['device'] = {}
   3.870 -        if 'vif_refs' not in cfg:
   3.871 -            cfg['vif_refs'] = []
   3.872 -        if 'vbd_refs' not in cfg:
   3.873 -            cfg['vbd_refs'] = []
   3.874 -        if 'vtpm_refs' not in cfg:
   3.875 -            cfg['vtpm_refs'] = []
   3.876 +        # set device references in the configuration
   3.877 +        self['devices'] = cfg.get('devices', {})
   3.878 +        
   3.879 +        self['vif_refs'] = []
   3.880 +        self['vbd_refs'] = []
   3.881 +        self['vtpm_refs'] = []
   3.882 +        for dev_uuid, (dev_type, dev_info) in self['devices'].items():
   3.883 +            if dev_type == 'vif':
   3.884 +                self['vif_refs'].append(dev_uuid)
   3.885 +            elif dev_type in ('vbd','tap'):
   3.886 +                self['vbd_refs'].append(dev_uuid)
   3.887 +            elif dev_type in ('vtpm',):
   3.888 +                self['vtpm_refs'].append(dev_uuid)
   3.889 +        
   3.890 +
   3.891 +    def _sxp_to_xapi_unsupported(self, sxp_cfg):
   3.892 +        """Read in an SXP configuration object and populate
   3.893 +        values are that not related directly supported in
   3.894 +        the Xen API.
   3.895 +        """
   3.896  
   3.897 -        return cfg
   3.898 -
   3.899 +        # Parse and convert parameters used to configure
   3.900 +        # the image (as well as HVM images)
   3.901 +        image_sxp = sxp.child_value(sxp_cfg, 'image', [])
   3.902 +        if image_sxp:
   3.903 +            image = {}
   3.904 +            image['type'] = sxp.name(image_sxp)
   3.905 +            for arg, conv in LEGACY_IMAGE_CFG:
   3.906 +                val = sxp.child_value(image_sxp, arg, None)
   3.907 +                if val != None:
   3.908 +                    image[arg] = conv(val)
   3.909  
   3.910 -    def _sync_xen_api_from_legacy_api(self):
   3.911 -        """ Sync all the attributes that is supported by the Xen API
   3.912 -        from the legacy API configuration.
   3.913 -        """
   3.914 -        for cfgkey, apikey in LEGACY_CFG_TO_XENAPI_CFG.items():        
   3.915 -            if cfgkey in self:
   3.916 -                self.xenapi[apikey] = self[cfgkey]
   3.917 +            image_hvm = {}
   3.918 +            for arg, conv in LEGACY_IMAGE_HVM_CFG:
   3.919 +                val = sxp.child_value(image_sxp, arg, None)
   3.920 +                if val != None:
   3.921 +                    image_hvm[arg] = conv(val)
   3.922 +                    
   3.923 +            image_hvm_devices = {}
   3.924 +            for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
   3.925 +                val = sxp.child_value(image_sxp, arg, None)
   3.926 +                if val != None:
   3.927 +                    image_hvm_devices[arg] = conv(val)
   3.928 +
   3.929 +            if image_hvm or image_hvm_devices:
   3.930 +                image['hvm'] = image_hvm
   3.931 +                image['hvm']['devices'] = image_hvm_devices
   3.932 +
   3.933 +            self['image'] = image
   3.934 +
   3.935 +            for apikey, imgkey in XENAPI_HVM_CFG.items():
   3.936 +                val = sxp.child(image_sxp, imgkey, None)
   3.937 +                if val != None:
   3.938 +                    self[apikey] = val
   3.939  
   3.940 -    def _sync_legacy_api_from_xen_api(self):
   3.941 -        for cfgkey, apikey in LEGACY_CFG_TO_XENAPI_CFG.items():
   3.942 -            if apikey in self.xenapi:
   3.943 -                self[cfgkey] = self.xenapi[apikey]
   3.944 +        # extract backend value
   3.945 +                    
   3.946 +        backend = []
   3.947 +        for c in sxp.children(sxp_cfg, 'backend'):
   3.948 +            backend.append(sxp.name(sxp.child0(c)))
   3.949 +        if backend:
   3.950 +            self['backend'] = backend
   3.951  
   3.952 +        if self['image'].has_key('hvm'):
   3.953 +            self['builder'] = 'hvm'
   3.954 +            
   3.955 +        # Parse and convert other Non Xen API parameters.
   3.956 +        def _set_cfg_if_exists(sxp_arg):
   3.957 +            val = sxp.child_value(sxp_cfg, sxp_arg)
   3.958 +            if val != None:
   3.959 +                if LEGACY_CFG_TYPES.get(sxp_arg):
   3.960 +                    self[sxp_arg] = LEGACY_CFG_TYPES[sxp_arg](val)
   3.961 +                else:
   3.962 +                    self[sxp_arg] = val
   3.963  
   3.964 -    def _populate_from_xml(self, parsed_xml):
   3.965 -        raise NotImplementedError
   3.966 +        _set_cfg_if_exists('shadow_memory')
   3.967 +        _set_cfg_if_exists('security')
   3.968 +        _set_cfg_if_exists('features')
   3.969 +        _set_cfg_if_exists('on_xend_stop')
   3.970 +        _set_cfg_if_exists('on_xend_start')
   3.971 +        _set_cfg_if_exists('vcpu_avail')
   3.972 +        _set_cfg_if_exists('max_vcpu_id') # TODO, deprecated?
   3.973 +        
   3.974 +        # Parse and store runtime configuration 
   3.975 +        _set_cfg_if_exists('start_time')
   3.976 +        _set_cfg_if_exists('online_vcpus')
   3.977 +        _set_cfg_if_exists('cpu_time')
   3.978 +        _set_cfg_if_exists('shutdown_reason')
   3.979 +        _set_cfg_if_exists('up_time')
   3.980 +        _set_cfg_if_exists('status') # TODO, deprecated  
   3.981  
   3.982 -    def _populate_from_python_config(self, parsed_py):
   3.983 -        raise NotImplementedError
   3.984 +    def _add_xapi_unsupported(self):
   3.985 +        """Updates the configuration object with entries that are not
   3.986 +        officially supported by the Xen API but is required for
   3.987 +        the rest of Xend to function.
   3.988 +        """
   3.989 +        pass
   3.990  
   3.991      def _get_old_state_string(self):
   3.992 +        """Returns the old xm state string.
   3.993 +        @rtype: string
   3.994 +        @return: old state string
   3.995 +        """
   3.996          state_string = ''
   3.997          for state_name in CONFIG_OLD_DOM_STATES:
   3.998              on_off = self.get(state_name, 0)
   3.999 @@ -669,9 +682,25 @@ class XendConfig(dict):
  3.1000  
  3.1001          return state_string
  3.1002  
  3.1003 -    def get_sxp(self, domain = None, ignore_devices = False, ignore = []):
  3.1004 +
  3.1005 +    def update_config(self, dominfo):
  3.1006 +        """Update configuration with the output from xc.domain_getinfo().
  3.1007 +
  3.1008 +        @param dominfo: Domain information via xc.domain_getinfo()
  3.1009 +        @type dominfo: dict
  3.1010 +        """
  3.1011 +        self._dominfo_to_xapi(dominfo)
  3.1012 +        self.validate()
  3.1013 +
  3.1014 +    def to_xml(self):
  3.1015 +        """Return an XML string representing the configuration."""
  3.1016 +        pass
  3.1017 +
  3.1018 +    def to_sxp(self, domain = None, ignore_devices = False, ignore = []):
  3.1019          """ Get SXP representation of this config object.
  3.1020  
  3.1021 +        Incompat: removed store_mfn, console_mfn
  3.1022 +
  3.1023          @keyword domain: (optional) XendDomainInfo to get extra information
  3.1024                           from such as domid and running devices.
  3.1025          @type    domain: XendDomainInfo
  3.1026 @@ -688,45 +717,33 @@ class XendConfig(dict):
  3.1027          if domain.getDomid() is not None:
  3.1028              sxpr.append(['domid', domain.getDomid()])
  3.1029  
  3.1030 -        for cfg, typefunc in ROUNDTRIPPING_CONFIG_ENTRIES:
  3.1031 -            if cfg in self:
  3.1032 -                if self[cfg] is not None:
  3.1033 -                    sxpr.append([cfg, self[cfg]])
  3.1034 +        for xenapi, legacy in XENAPI_CFG_TO_LEGACY_CFG.items():
  3.1035 +            if self.has_key(xenapi) and self[xenapi] not in (None, []):
  3.1036 +                sxpr.append([legacy, self[xenapi]])
  3.1037  
  3.1038 -        if 'image' in self and self['image'] is not None:
  3.1039 -            sxpr.append(['image', self['image']])
  3.1040 -        if 'security' in self and self['security']:
  3.1041 -            sxpr.append(['security', self['security']])
  3.1042 -        if 'shutdown_reason' in self:
  3.1043 -            sxpr.append(['shutdown_reason', self['shutdown_reason']])
  3.1044 -        if 'cpu_time' in self:
  3.1045 -            sxpr.append(['cpu_time', self['cpu_time']/1e9])
  3.1046 +        for legacy in LEGACY_UNSUPPORTED_BY_XENAPI_CFG:
  3.1047 +            if legacy in ('domid', 'uuid'): # skip these
  3.1048 +                continue
  3.1049 +            if self.has_key(legacy) and self[legacy] not in (None, []):
  3.1050 +                sxpr.append([legacy, self[legacy]])
  3.1051  
  3.1052 -        sxpr.append(['online_vcpus', self['online_vcpus']])
  3.1053 +        if 'image' in self and self['image']:
  3.1054 +            sxpr.append(['image', self.image_sxpr()])
  3.1055  
  3.1056 -        if 'start_time' in self:
  3.1057 -            uptime = time.time() - self['start_time']
  3.1058 -            sxpr.append(['up_time', str(uptime)])
  3.1059 -            sxpr.append(['start_time', str(self['start_time'])])
  3.1060 -
  3.1061 -        if domain:
  3.1062 -            sxpr.append(['status', str(domain.state)])
  3.1063 -        else:
  3.1064 -            sxpr.append(['status', str(DOM_STATE_HALTED)])
  3.1065 +        sxpr.append(['status', domain.state])
  3.1066 +        sxpr.append(['memory_dynamic_min',  self.get('memory_dynamic_min')])
  3.1067 +        sxpr.append(['memory_dynamic_max',  self.get('memory_dynamic_max')])
  3.1068  
  3.1069          if domain.getDomid() is not None:
  3.1070              sxpr.append(['state', self._get_old_state_string()])
  3.1071  
  3.1072 -        sxpr.append(['memory_dynamic_max', self.get('memory_dynamic_max',
  3.1073 -                                                    self['memory'])])
  3.1074 -
  3.1075 -        # For save/restore migration
  3.1076          if domain:
  3.1077              if domain.store_mfn:
  3.1078                  sxpr.append(['store_mfn', domain.store_mfn])
  3.1079              if domain.console_mfn:
  3.1080                  sxpr.append(['console_mfn', domain.console_mfn])
  3.1081  
  3.1082 +
  3.1083          # Marshall devices (running or from configuration)
  3.1084          if not ignore_devices:
  3.1085              for cls in XendDevices.valid_devices():
  3.1086 @@ -743,7 +760,7 @@ class XendConfig(dict):
  3.1087                      except:
  3.1088                          log.exception("dumping sxp from device controllers")
  3.1089                          pass
  3.1090 -                        
  3.1091 +                    
  3.1092                  # if we didn't find that device, check the existing config
  3.1093                  # for a device in the same class
  3.1094                  if not found:
  3.1095 @@ -751,58 +768,28 @@ class XendConfig(dict):
  3.1096                          if dev_type == cls:
  3.1097                              sxpr.append(['device', dev_info])
  3.1098  
  3.1099 -        return sxpr
  3.1100 -
  3.1101 -    def validate(self):
  3.1102 -        """ Validate the configuration and fill in missing configuration
  3.1103 -        with defaults.
  3.1104 -        """
  3.1105 -
  3.1106 -        # Fill in default values
  3.1107 -        for key, default_func in DEFAULT_CONFIGURATION:
  3.1108 -            if key not in self or self[key] == None:
  3.1109 -                self[key] = default_func(self)
  3.1110 +        return sxpr    
  3.1111 +    
  3.1112 +    def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None):
  3.1113 +        """Add a device configuration in SXP format or XenAPI struct format.
  3.1114  
  3.1115 -        # Basic sanity checks
  3.1116 -        if 'image' in self and isinstance(self['image'], str):
  3.1117 -            self['image'] = sxp.from_string(self['image'])
  3.1118 -        if 'security' in self and isinstance(self['security'], str):
  3.1119 -            self['security'] = sxp.from_string(self['security'])
  3.1120 -        if self['memory'] == 0 and 'mem_kb' in self:
  3.1121 -            self['memory'] = (self['mem_kb'] + 1023)/1024
  3.1122 -        if self['memory'] <= 0:
  3.1123 -            raise XendConfigError('Invalid memory size: %s' %
  3.1124 -                                  str(self['memory']))
  3.1125 +        For SXP, it could be either:
  3.1126  
  3.1127 -        self['maxmem'] = max(self['memory'], self['maxmem'])
  3.1128 +        [device, [vbd, [uname ...]]
  3.1129 +
  3.1130 +        or:
  3.1131  
  3.1132 -        # convert mem_kb from domain_getinfo to something more descriptive
  3.1133 -        if 'mem_kb' in self:
  3.1134 -            self['memory_dynamic_max'] = (self['mem_kb'] + 1023)/1024
  3.1135 -
  3.1136 -        # Verify devices
  3.1137 -        for d_uuid, (d_type, d_info) in self['device'].items():
  3.1138 -            if d_type not in XendDevices.valid_devices() and \
  3.1139 -               d_type not in XendDevices.pseudo_devices():
  3.1140 -                raise XendConfigError('Invalid device (%s)' % d_type)
  3.1141 +        [vbd, [uname ..]]
  3.1142  
  3.1143 -        # Verify restart modes
  3.1144 -        for event in ('on_poweroff', 'on_reboot', 'on_crash'):
  3.1145 -            if self[event] not in CONFIG_RESTART_MODES:
  3.1146 -                raise XendConfigError('Invalid restart event: %s = %s' % \
  3.1147 -                                      (event, str(self[event])))
  3.1148 -
  3.1149 -        # Verify that {vif,vbd}_refs are here too
  3.1150 -        if 'vif_refs' not in self:
  3.1151 -            self['vif_refs'] = []
  3.1152 -        if 'vbd_refs' not in self:
  3.1153 -            self['vbd_refs'] = []
  3.1154 -        if 'vtpm_refs' not in self:
  3.1155 -            self['vtpm_refs'] = []
  3.1156 -
  3.1157 -    def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None):
  3.1158 +        @type cfg_sxp: list of lists (parsed sxp object)
  3.1159 +        @param cfg_sxp: SXP configuration object
  3.1160 +        @type cfg_xenapi: dict
  3.1161 +        @param cfg_xenapi: A device configuration from Xen API (eg. vbd,vif)
  3.1162 +        @rtype: string
  3.1163 +        @return: Assigned UUID of the device.
  3.1164 +        """
  3.1165          if dev_type not in XendDevices.valid_devices() and \
  3.1166 -           dev_type not in XendDevices.pseudo_devices():
  3.1167 +           dev_type not in XendDevices.pseudo_devices():        
  3.1168              raise XendConfigError("XendConfig: %s not a valid device type" %
  3.1169                              dev_type)
  3.1170  
  3.1171 @@ -816,22 +803,48 @@ class XendConfig(dict):
  3.1172              log.debug("XendConfig.device_add: %s" % str(cfg_xenapi))
  3.1173  
  3.1174          if cfg_sxp:
  3.1175 +            if sxp.child0(cfg_sxp) == 'device':
  3.1176 +                config = sxp.child0(cfg_sxp)
  3.1177 +            else:
  3.1178 +                config = cfg_sxp
  3.1179 +
  3.1180 +            dev_type = sxp.name(config)
  3.1181              dev_info = {}
  3.1182  
  3.1183              try:
  3.1184 -                for opt, val in cfg_sxp[1:]:
  3.1185 +                for opt, val in config[1:]:
  3.1186                      dev_info[opt] = val
  3.1187              except ValueError:
  3.1188                  pass # SXP has no options for this device
  3.1189  
  3.1190 +            
  3.1191 +            def _get_config_ipaddr(config):
  3.1192 +                val = []
  3.1193 +                for ipaddr in sxp.children(config, elt='ip'):
  3.1194 +                    val.append(sxp.child0(ipaddr))
  3.1195 +                return val
  3.1196 +
  3.1197 +            if dev_type == 'vif' and 'ip' in dev_info:
  3.1198 +                dev_info['ip'] = _get_config_ipaddr(config)
  3.1199 +
  3.1200 +            if dev_type == 'vbd':
  3.1201 +                if dev_info.get('dev', '').startswith('ioemu:'):
  3.1202 +                    dev_info['driver'] = 'ioemu'
  3.1203 +                else:
  3.1204 +                    dev_info['driver'] = 'paravirtualised'
  3.1205 +                    
  3.1206 +
  3.1207              # create uuid if it doesn't exist
  3.1208              dev_uuid = dev_info.get('uuid', uuid.createString())
  3.1209              dev_info['uuid'] = dev_uuid
  3.1210 -            self['device'][dev_uuid] = (dev_type, dev_info)
  3.1211 -            if dev_type in ('vif', 'vbd'):
  3.1212 +
  3.1213 +            # store dev references by uuid for certain device types
  3.1214 +            self['devices'][dev_uuid] = (dev_type, dev_info)
  3.1215 +            if dev_type in ('vif', 'vbd', 'vtpm'):
  3.1216                  self['%s_refs' % dev_type].append(dev_uuid)
  3.1217              elif dev_type in ('tap',):
  3.1218                  self['vbd_refs'].append(dev_uuid)
  3.1219 +
  3.1220              return dev_uuid
  3.1221  
  3.1222          if cfg_xenapi:
  3.1223 @@ -849,13 +862,20 @@ class XendConfig(dict):
  3.1224                  
  3.1225                  dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
  3.1226                  dev_info['uuid'] = dev_uuid
  3.1227 -                self['device'][dev_uuid] = (dev_type, dev_info)
  3.1228 +                self['devices'][dev_uuid] = (dev_type, dev_info)
  3.1229                  self['vif_refs'].append(dev_uuid)
  3.1230                  return dev_uuid
  3.1231              
  3.1232 -            elif dev_type == 'vbd':
  3.1233 -                dev_info['uname'] = cfg_xenapi.get('image', None)
  3.1234 -                dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
  3.1235 +            elif dev_type in ('vbd', 'tap'):
  3.1236 +                if dev_type == 'vbd':
  3.1237 +                    dev_info['uname'] = cfg_xenapi.get('image', None)
  3.1238 +                    dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
  3.1239 +                elif dev_type == 'tap':
  3.1240 +                    dev_info['uname'] = 'tap:qcow:%s' % cfg_xenapi.get('image')
  3.1241 +                    dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
  3.1242 +                    
  3.1243 +                dev_info['driver'] = cfg_xenapi.get('driver')
  3.1244 +                    
  3.1245                  if cfg_xenapi.get('mode') == 'RW':
  3.1246                      dev_info['mode'] = 'w'
  3.1247                  else:
  3.1248 @@ -863,35 +883,33 @@ class XendConfig(dict):
  3.1249  
  3.1250                  dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
  3.1251                  dev_info['uuid'] = dev_uuid
  3.1252 -                self['device'][dev_uuid] = (dev_type, dev_info)
  3.1253 +                self['devices'][dev_uuid] = (dev_type, dev_info)
  3.1254                  self['vbd_refs'].append(dev_uuid)                
  3.1255                  return dev_uuid
  3.1256 +            
  3.1257 +        return ''
  3.1258  
  3.1259 -            elif dev_type == 'vtpm':
  3.1260 -                if cfg_xenapi.get('type'):
  3.1261 -                    dev_info['type'] = cfg_xenapi.get('type')
  3.1262 -                dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
  3.1263 -                dev_info['uuid'] = dev_uuid
  3.1264 -                self['device'][dev_uuid] = (dev_type, dev_info)
  3.1265 -                self['vtpm_refs'].append(dev_uuid)
  3.1266 -                return dev_uuid
  3.1267 +    def device_update(self, dev_uuid, cfg_sxp):
  3.1268 +        """Update an existing device with the new configuration.
  3.1269  
  3.1270 -            elif dev_type == 'tap':
  3.1271 -                dev_info['uname'] = 'tap:qcow:%s' % cfg_xenapi.get('image')
  3.1272 -                dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
  3.1273 -                
  3.1274 -                if cfg_xenapi.get('mode') == 'RW':
  3.1275 -                    dev_info['mode'] = 'w'
  3.1276 -                else:
  3.1277 -                    dev_info['mode'] = 'r'
  3.1278 +        @rtype: boolean
  3.1279 +        @return: Returns True if succesfully found and updated a device conf
  3.1280 +        """
  3.1281 +        if dev_uuid in self['devices']:
  3.1282 +            config = sxp.child0(cfg_sxp)
  3.1283 +            dev_type = sxp.name(config)
  3.1284 +            dev_info = {}
  3.1285  
  3.1286 -                dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
  3.1287 -                dev_info['uuid'] = dev_uuid
  3.1288 -                self['device'][dev_uuid] = (dev_type, dev_info)
  3.1289 -                self['vbd_refs'].append(dev_uuid)                
  3.1290 -                return dev_uuid                
  3.1291 -                
  3.1292 -        return ''
  3.1293 +            try:
  3.1294 +                for opt, val in config[1:]:
  3.1295 +                    self['devices'][opt] = val
  3.1296 +            except ValueError:
  3.1297 +                pass # SXP has no options for this device
  3.1298 +            
  3.1299 +            return True
  3.1300 +
  3.1301 +        return False
  3.1302 +
  3.1303  
  3.1304      def device_sxpr(self, dev_uuid = None, dev_type = None, dev_info = None):
  3.1305          """Get Device SXPR by either giving the device UUID or (type, config).
  3.1306 @@ -900,8 +918,8 @@ class XendConfig(dict):
  3.1307          @return: device config sxpr
  3.1308          """
  3.1309          sxpr = []
  3.1310 -        if dev_uuid != None and dev_uuid in self['device']:
  3.1311 -            dev_type, dev_info = self['device'][dev_uuid]
  3.1312 +        if dev_uuid != None and dev_uuid in self['devices']:
  3.1313 +            dev_type, dev_info = self['devices'][dev_uuid]
  3.1314  
  3.1315          if dev_type == None or dev_info == None:
  3.1316              raise XendConfigError("Required either UUID or device type and "
  3.1317 @@ -917,27 +935,102 @@ class XendConfig(dict):
  3.1318          """Returns the SXPR for all devices in the current configuration."""
  3.1319          sxprs = []
  3.1320          pci_devs = []
  3.1321 -        for dev_type, dev_info in self['device'].values():
  3.1322 +
  3.1323 +        if 'devices' in self:
  3.1324 +            return sxprs
  3.1325 +        
  3.1326 +        for dev_type, dev_info in self['devices'].values():
  3.1327              if dev_type == 'pci': # special case for pci devices
  3.1328 -                pci_devs.append(dev_info)
  3.1329 +                sxpr = [['uuid', dev_info['uuid']]]
  3.1330 +                for pci_dev_info in dev_info['devs']:
  3.1331 +                    pci_dev_sxpr = ['dev']
  3.1332 +                    for opt, val in pci_dev_info.items():
  3.1333 +                        pci_dev_sxpr.append([opt, val])
  3.1334 +                    sxpr.append(pci_dev_sxpr)
  3.1335 +                sxprs.append((dev_type, sxpr))
  3.1336              else:
  3.1337                  sxpr = self.device_sxpr(dev_type = dev_type,
  3.1338                                          dev_info = dev_info)
  3.1339                  sxprs.append((dev_type, sxpr))
  3.1340  
  3.1341 -        # if we have any pci_devs, we parse them differently into
  3.1342 -        # one single pci SXP entry.
  3.1343 -        if pci_devs:
  3.1344 -            sxpr = ['pci',]
  3.1345 -            for dev_info in pci_devs:
  3.1346 -                dev_sxpr = self.device_sxpr(dev_type = 'dev',
  3.1347 -                                            dev_info = dev_info)
  3.1348 -                sxpr.append(dev_sxpr)
  3.1349 -            sxprs.append(('pci', sxpr))
  3.1350 -            
  3.1351          return sxprs
  3.1352  
  3.1353 -                     
  3.1354 +    def image_sxpr(self):
  3.1355 +        """Returns a backwards compatible image SXP expression that is
  3.1356 +        used in xenstore's /vm/<uuid>/image value and xm list."""
  3.1357 +        image = [self['image'].get('type', 'linux')]
  3.1358 +        if self.has_key('kernel_kernel'):
  3.1359 +            image.append(['kernel', self['kernel_kernel']])
  3.1360 +        if self.has_key('kernel_initrd') and self['kernel_initrd']:
  3.1361 +            image.append(['ramdisk', self['kernel_initrd']])
  3.1362 +        if self.has_key('kernel_args') and self['kernel_args']:
  3.1363 +            image.append(['args', self['kernel_args']])
  3.1364 +
  3.1365 +        for arg, conv in LEGACY_IMAGE_CFG:
  3.1366 +            if self['image'].has_key(arg):
  3.1367 +                image.append([arg, self['image'][arg]])
  3.1368 +
  3.1369 +        if 'hvm' in self['image']:
  3.1370 +            for arg, conv in LEGACY_IMAGE_HVM_CFG:
  3.1371 +                if self['image']['hvm'].has_key(arg):
  3.1372 +                    image.append([arg, self['image']['hvm'][arg]])
  3.1373 +
  3.1374 +        if 'hvm' in self['image'] and 'devices' in self['image']['hvm']:
  3.1375 +            for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
  3.1376 +                if self['image']['hvm']['devices'].has_key(arg):
  3.1377 +                    image.append([arg,
  3.1378 +                                  self['image']['hvm']['devices'][arg]])
  3.1379 +
  3.1380 +        return image
  3.1381 +
  3.1382 +    def update_with_image_sxp(self, image_sxp):
  3.1383 +        # Convert Legacy "image" config to Xen API kernel_*
  3.1384 +        # configuration
  3.1385 +        self['kernel_kernel'] = sxp.child_value(image_sxp, 'kernel','')
  3.1386 +        self['kernel_initrd'] = sxp.child_value(image_sxp, 'ramdisk','')
  3.1387 +        kernel_args = sxp.child_value(image_sxp, 'args', '')
  3.1388 +        
  3.1389 +        # attempt to extract extra arguments from SXP config
  3.1390 +        arg_ip = sxp.child_value(image_sxp, 'ip')
  3.1391 +        if arg_ip and not re.search(r'ip=[0-9\.]', kernel_args):
  3.1392 +            kernel_args += ' ip=%s' % arg_ip
  3.1393 +        arg_root = sxp.child_value(image_sxp, 'root')
  3.1394 +        if arg_root and not re.search(r'root=', kernel_args):
  3.1395 +            kernel_args += ' root=%s' % arg_root
  3.1396 +        self['kernel_args'] = kernel_args
  3.1397 +
  3.1398 +        # Store image SXP in python dictionary format
  3.1399 +        image = {}
  3.1400 +        image['type'] = sxp.name(image_sxp)
  3.1401 +        for arg, conv in LEGACY_IMAGE_CFG:
  3.1402 +            val = sxp.child_value(image_sxp, arg, None)
  3.1403 +            if val != None:
  3.1404 +                image[arg] = conv(val)
  3.1405 +
  3.1406 +        image_hvm = {}
  3.1407 +        for arg, conv in LEGACY_IMAGE_HVM_CFG:
  3.1408 +            val = sxp.child_value(image_sxp, arg, None)
  3.1409 +            if val != None:
  3.1410 +                image_hvm[arg] = conv(val)
  3.1411 +                    
  3.1412 +        image_hvm_devices = {}
  3.1413 +        for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
  3.1414 +            val = sxp.child_value(image_sxp, arg, None)
  3.1415 +            if val != None:
  3.1416 +                image_hvm_devices[arg] = conv(val)
  3.1417 +
  3.1418 +        if image_hvm or image_hvm_devices:
  3.1419 +            image['hvm'] = image_hvm
  3.1420 +            image['hvm']['devices'] = image_hvm_devices
  3.1421 +
  3.1422 +        self['image'] = image
  3.1423 +
  3.1424 +        for apikey, imgkey in XENAPI_HVM_CFG.items():
  3.1425 +            val = sxp.child(image_sxp, imgkey, None)
  3.1426 +            if val != None:
  3.1427 +                self[apikey] = val        
  3.1428 +
  3.1429 +        
  3.1430  #
  3.1431  # debugging 
  3.1432  #
     4.1 --- a/tools/python/xen/xend/XendDomain.py	Thu Nov 30 14:05:27 2006 +0000
     4.2 +++ b/tools/python/xen/xend/XendDomain.py	Thu Nov 30 14:44:58 2006 +0000
     4.3 @@ -433,6 +433,11 @@ class XendDomain:
     4.4          """
     4.5          log.debug("Adding Domain: %s" % info.getDomid())
     4.6          self.domains[info.getDomid()] = info
     4.7 +        
     4.8 +        # update the managed domains with a new XendDomainInfo object
     4.9 +        # if we are keeping track of it.
    4.10 +        if info.get_uuid() in self.managed_domains:
    4.11 +            self._managed_domain_register(info)
    4.12  
    4.13      def _remove_domain(self, info, domid = None):
    4.14          """Remove the domain from the list of running domains
    4.15 @@ -669,7 +674,7 @@ class XendDomain:
    4.16          self.domains_lock.acquire()
    4.17          try:
    4.18              try:
    4.19 -                xeninfo = XendConfig(xenapi_vm = xenapi_vm)
    4.20 +                xeninfo = XendConfig(xapi = xenapi_vm)
    4.21                  dominfo = XendDomainInfo.createDormant(xeninfo)
    4.22                  log.debug("Creating new managed domain: %s: %s" %
    4.23                            (dominfo.getName(), dominfo.get_uuid()))
    4.24 @@ -873,8 +878,8 @@ class XendDomain:
    4.25          self.domains_lock.acquire()
    4.26          try:
    4.27              try:
    4.28 -                xeninfo = XendConfig(sxp = config)
    4.29 -                dominfo = XendDomainInfo.createDormant(xeninfo)
    4.30 +                domconfig = XendConfig(sxp_obj = config)
    4.31 +                dominfo = XendDomainInfo.createDormant(domconfig)
    4.32                  log.debug("Creating new managed domain: %s" %
    4.33                            dominfo.getName())
    4.34                  self._managed_domain_register(dominfo)
     5.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu Nov 30 14:05:27 2006 +0000
     5.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu Nov 30 14:44:58 2006 +0000
     5.3 @@ -38,10 +38,9 @@ from xen.util.blkif import blkdev_uname_
     5.4  from xen.util import security
     5.5  
     5.6  from xen.xend import balloon, sxp, uuid, image, arch
     5.7 -from xen.xend import XendRoot, XendNode
     5.8 +from xen.xend import XendRoot, XendNode, XendConfig
     5.9  
    5.10  from xen.xend.XendBootloader import bootloader
    5.11 -from xen.xend.XendConfig import XendConfig
    5.12  from xen.xend.XendError import XendError, VmError
    5.13  from xen.xend.XendDevices import XendDevices
    5.14  from xen.xend.xenstore.xstransact import xstransact, complete
    5.15 @@ -145,7 +144,7 @@ def create(config):
    5.16      """
    5.17  
    5.18      log.debug("XendDomainInfo.create(%s)", config)
    5.19 -    vm = XendDomainInfo(XendConfig(sxp = config))
    5.20 +    vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config))
    5.21      try:
    5.22          vm.start()
    5.23      except:
    5.24 @@ -175,10 +174,9 @@ def recreate(info, priv):
    5.25  
    5.26      assert not info['dying']
    5.27  
    5.28 -    xeninfo = XendConfig(cfg = info)
    5.29 +    xeninfo = XendConfig.XendConfig(dominfo = info)
    5.30      domid = xeninfo['domid']
    5.31 -    uuid1 = xeninfo['handle']
    5.32 -    xeninfo['uuid'] = uuid.toString(uuid1)
    5.33 +    uuid1 = uuid.fromString(xeninfo['uuid'])
    5.34      needs_reinitialising = False
    5.35      
    5.36      dompath = GetDomainPath(domid)
    5.37 @@ -236,7 +234,7 @@ def recreate(info, priv):
    5.38  def restore(config):
    5.39      """Create a domain and a VM object to do a restore.
    5.40  
    5.41 -    @param config: Domain configuration object
    5.42 +    @param config: Domain SXP configuration
    5.43      @type  config: list of lists. (see C{create})
    5.44  
    5.45      @rtype:  XendDomainInfo
    5.46 @@ -246,7 +244,8 @@ def restore(config):
    5.47      """
    5.48  
    5.49      log.debug("XendDomainInfo.restore(%s)", config)
    5.50 -    vm = XendDomainInfo(XendConfig(sxp = config), resume = True)
    5.51 +    vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config),
    5.52 +                        resume = True)
    5.53      try:
    5.54          vm.resume()
    5.55          return vm
    5.56 @@ -254,24 +253,24 @@ def restore(config):
    5.57          vm.destroy()
    5.58          raise
    5.59  
    5.60 -def createDormant(xeninfo):
    5.61 +def createDormant(domconfig):
    5.62      """Create a dormant/inactive XenDomainInfo without creating VM.
    5.63      This is for creating instances of persistent domains that are not
    5.64      yet start.
    5.65  
    5.66 -    @param xeninfo: Parsed configuration
    5.67 -    @type  xeninfo: dictionary
    5.68 +    @param domconfig: Parsed configuration
    5.69 +    @type  domconfig: XendConfig object
    5.70      
    5.71      @rtype:  XendDomainInfo
    5.72      @return: A up and running XendDomainInfo instance
    5.73      @raise XendError: Errors with configuration.    
    5.74      """
    5.75      
    5.76 -    log.debug("XendDomainInfo.createDormant(%s)", xeninfo)
    5.77 +    log.debug("XendDomainInfo.createDormant(%s)", domconfig)
    5.78      
    5.79      # domid does not make sense for non-running domains.
    5.80 -    xeninfo.pop('domid', None)
    5.81 -    vm = XendDomainInfo(XendConfig(cfg = xeninfo))
    5.82 +    domconfig.pop('domid', None)
    5.83 +    vm = XendDomainInfo(domconfig)
    5.84      return vm    
    5.85  
    5.86  def domain_by_name(name):
    5.87 @@ -383,14 +382,6 @@ class XendDomainInfo:
    5.88          #if not self._infoIsSet('uuid'):
    5.89          #    self.info['uuid'] = uuid.toString(uuid.create())
    5.90  
    5.91 -        #REMOVE: domid logic can be shortened 
    5.92 -        #if domid is not None:
    5.93 -        #    self.domid = domid
    5.94 -        #elif info.has_key('dom'):
    5.95 -        #    self.domid = int(info['dom'])
    5.96 -        #else:
    5.97 -        #    self.domid = None
    5.98 -
    5.99          self.vmpath  = XS_VMROOT + self.info['uuid']
   5.100          self.dompath = dompath
   5.101  
   5.102 @@ -403,6 +394,7 @@ class XendDomainInfo:
   5.103          self.vmWatch = None
   5.104          self.shutdownWatch = None
   5.105          self.shutdownStartTime = None
   5.106 +        self._resume = resume
   5.107  
   5.108          self.state = DOM_STATE_HALTED
   5.109          self.state_updated = threading.Condition()
   5.110 @@ -416,8 +408,7 @@ class XendDomainInfo:
   5.111          if augment:
   5.112              self._augmentInfo(priv)
   5.113  
   5.114 -        self._checkName(self.info['name'])
   5.115 -        self.setResume(resume)
   5.116 +        self._checkName(self.info['name_label'])
   5.117              
   5.118  
   5.119      #
   5.120 @@ -477,7 +468,7 @@ class XendDomainInfo:
   5.121          if self.domid == 0:
   5.122              raise XendError('Domain 0 cannot be shutdown')
   5.123          
   5.124 -        if not reason in DOMAIN_SHUTDOWN_REASONS.values():
   5.125 +        if reason not in DOMAIN_SHUTDOWN_REASONS.values():
   5.126              raise XendError('Invalid reason: %s' % reason)
   5.127          self._storeDom("control/shutdown", reason)
   5.128                  
   5.129 @@ -512,12 +503,14 @@ class XendDomainInfo:
   5.130          """Create a new device.
   5.131  
   5.132          @param dev_config: device configuration
   5.133 -        @type  dev_config: dictionary (parsed config)
   5.134 +        @type  dev_config: SXP object (parsed config)
   5.135          """
   5.136          log.debug("XendDomainInfo.device_create: %s" % dev_config)
   5.137          dev_type = sxp.name(dev_config)
   5.138 -        devid = self._createDevice(dev_type, dev_config)
   5.139 -        self.info.device_add(dev_type, cfg_sxp = dev_config)        
   5.140 +        dev_uuid = self.info.device_add(dev_type, cfg_sxp = dev_config)
   5.141 +        dev_config_dict = self.info['devices'][dev_uuid][1]
   5.142 +        log.debug("XendDomainInfo.device_create: %s" % dev_config_dict)
   5.143 +        devid = self._createDevice(dev_type, dev_config_dict)
   5.144          self._waitForDevice(dev_type, devid)
   5.145          return self.getDeviceController(dev_type).sxpr(devid)
   5.146  
   5.147 @@ -525,12 +518,26 @@ class XendDomainInfo:
   5.148          """Configure an existing device.
   5.149          
   5.150          @param dev_config: device configuration
   5.151 -        @type  dev_config: dictionary (parsed config)
   5.152 +        @type  dev_config: SXP object (parsed config)
   5.153          @param devid:      device id
   5.154          @type  devid:      int
   5.155 +        @return: Returns True if successfully updated device
   5.156 +        @rtype: boolean
   5.157          """
   5.158          deviceClass = sxp.name(dev_config)
   5.159 -        self._reconfigureDevice(deviceClass, devid, dev_config)
   5.160 +        
   5.161 +        # look up uuid of the device
   5.162 +        dev_control =  self.getDeviceController(deviceClass)
   5.163 +        dev_sxpr = dev_control.sxpr(devid)
   5.164 +        dev_uuid = sxp.child_value(sxpr, 'uuid')
   5.165 +        if not dev_uuid:
   5.166 +            return False
   5.167 +
   5.168 +        self.info.device_update(dev_uuid, dev_config)
   5.169 +        dev_config_dict = self.info['devices'].get(dev_uuid)
   5.170 +        if dev_config_dict:
   5.171 +            dev_control.reconfigureDevice(devid, dev_config_dict[1])
   5.172 +        return True
   5.173  
   5.174      def waitForDevices(self):
   5.175          """Wait for this domain's configured devices to connect.
   5.176 @@ -567,12 +574,12 @@ class XendDomainInfo:
   5.177          @param target: In MiB.
   5.178          """
   5.179          log.debug("Setting memory target of domain %s (%d) to %d MiB.",
   5.180 -                  self.info['name'], self.domid, target)
   5.181 +                  self.info['name_label'], self.domid, target)
   5.182          
   5.183          if target <= 0:
   5.184              raise XendError('Invalid memory size')
   5.185          
   5.186 -        self.info['memory'] = target
   5.187 +        self.info['memory_static_min'] = target
   5.188          self.storeVm("memory", target)
   5.189          self._storeDom("memory/target", target << 10)
   5.190  
   5.191 @@ -581,8 +588,8 @@ class XendDomainInfo:
   5.192              # We include the domain name and ID, to help xm.
   5.193              sxpr = ['domain',
   5.194                      ['domid',      self.domid],
   5.195 -                    ['name',       self.info['name']],
   5.196 -                    ['vcpu_count', self.info['online_vcpus']]]
   5.197 +                    ['name',       self.info['name_label']],
   5.198 +                    ['vcpu_count', self.info['vcpus_number']]]
   5.199  
   5.200              for i in range(0, self.info['max_vcpu_id']+1):
   5.201                  info = xc.vcpu_getinfo(self.domid, i)
   5.202 @@ -610,30 +617,40 @@ class XendDomainInfo:
   5.203          values taken from the store.  This recovers those values known
   5.204          to xend but not to the hypervisor.
   5.205          """
   5.206 -        def useIfNeeded(name, val):
   5.207 -            if not self._infoIsSet(name) and val is not None:
   5.208 -                self.info[name] = val
   5.209 -
   5.210 +        augment_entries = XendConfig.LEGACY_XENSTORE_VM_PARAMS[:]
   5.211          if priv:
   5.212 -            entries = VM_STORE_ENTRIES[:]
   5.213 -            entries.remove(('memory', int))
   5.214 -            entries.remove(('maxmem', int))
   5.215 -        else:
   5.216 -            entries = VM_STORE_ENTRIES
   5.217 -        entries.append(('image', str))
   5.218 -        entries.append(('security', str))
   5.219 +            augment_entries.remove('memory')
   5.220 +            augment_entries.remove('maxmem')
   5.221  
   5.222 -        map(lambda x, y: useIfNeeded(x[0], y), entries,
   5.223 -            self._readVMDetails(entries))
   5.224 +        vm_config = self._readVMDetails([(k, XendConfig.LEGACY_CFG_TYPES[k])
   5.225 +                                         for k in augment_entries])
   5.226 +        
   5.227 +        # make returned lists into a dictionary
   5.228 +        vm_config = dict(zip(augment_entries, vm_config))
   5.229 +        
   5.230 +        for arg in augment_entries:
   5.231 +            xapicfg = arg
   5.232 +            val = vm_config[arg]
   5.233 +            if val != None:
   5.234 +                if arg in XendConfig.LEGACY_CFG_TO_XENAPI_CFG:
   5.235 +                    xapiarg = XendConfig.LEGACY_CFG_TO_XENAPI_CFG[arg]
   5.236 +                    self.info[xapiarg] = val
   5.237 +                else:
   5.238 +                    self.info[arg] = val
   5.239  
   5.240 +        # read image value
   5.241 +        image_sxp = self._readVm('image')
   5.242 +        if image_sxp:
   5.243 +            self.info.update_with_image_sxp(sxp.from_string(image_sxp))
   5.244 +
   5.245 +        # read devices
   5.246          devices = []
   5.247 -
   5.248          for devclass in XendDevices.valid_devices():
   5.249              devconfig = self.getDeviceController(devclass).configurations()
   5.250              if devconfig:
   5.251                  devices.extend(map(lambda conf: (devclass, conf), devconfig))
   5.252  
   5.253 -        if not self.info['device'] and devices is not None:
   5.254 +        if not self.info['devices'] and devices is not None:
   5.255              for device in devices:
   5.256                  self.info.device_add(device[0], cfg_sxp = device)
   5.257  
   5.258 @@ -678,16 +695,16 @@ class XendDomainInfo:
   5.259      def _recreateDomFunc(self, t):
   5.260          t.remove()
   5.261          t.mkdir()
   5.262 -        t.set_permissions({ 'dom' : self.domid })
   5.263 +        t.set_permissions({'dom' : self.domid})
   5.264          t.write('vm', self.vmpath)
   5.265  
   5.266      def _storeDomDetails(self):
   5.267          to_store = {
   5.268              'domid':              str(self.domid),
   5.269              'vm':                 self.vmpath,
   5.270 -            'name':               self.info['name'],
   5.271 +            'name':               self.info['name_label'],
   5.272              'console/limit':      str(xroot.get_console_limit() * 1024),
   5.273 -            'memory/target':      str(self.info['memory'] * 1024)
   5.274 +            'memory/target':      str(self.info['memory_static_min'] * 1024)
   5.275              }
   5.276  
   5.277          def f(n, v):
   5.278 @@ -713,7 +730,7 @@ class XendDomainInfo:
   5.279                  return 'offline'
   5.280  
   5.281          result = {}
   5.282 -        for v in range(0, self.info['vcpus']):
   5.283 +        for v in range(0, self.info['vcpus_number']):
   5.284              result["cpu/%d/availability" % v] = availability(v)
   5.285          return result
   5.286  
   5.287 @@ -735,19 +752,29 @@ class XendDomainInfo:
   5.288          log.trace("XendDomainInfo.storeChanged");
   5.289  
   5.290          changed = False
   5.291 +
   5.292 +        # Check whether values in the configuration have
   5.293 +        # changed in Xenstore.
   5.294          
   5.295 -        def f(x, y):
   5.296 -            if y is not None and self.info[x[0]] != y:
   5.297 -                self.info[x[0]] = y
   5.298 -                changed = True
   5.299 +        cfg_vm = ['name', 'on_poweroff', 'on_reboot', 'on_crash']
   5.300 +        
   5.301 +        vm_details = self._readVMDetails([(k,XendConfig.LEGACY_CFG_TYPES[k])
   5.302 +                                           for k in cfg_vm])
   5.303  
   5.304 -        map(f, VM_CONFIG_PARAMS, self._readVMDetails(VM_CONFIG_PARAMS))
   5.305 +        # convert two lists into a python dictionary
   5.306 +        vm_details = dict(zip(cfg_vm, vm_details))
   5.307 +        
   5.308 +        for arg, val in vm_details.items():
   5.309 +            if arg in XendConfig.LEGACY_CFG_TO_XENAPI_CFG:
   5.310 +                xapiarg = XendConfig.LEGACY_CFG_TO_XENAPI_CFG[arg]
   5.311 +                if val != None and val != self.info[xapiarg]:
   5.312 +                    self.info[xapiarg] = val
   5.313 +                    changed= True
   5.314  
   5.315 -        im = self._readVm('image')
   5.316 -        current_im = self.info['image']
   5.317 -        if (im is not None and
   5.318 -            (current_im is None or sxp.to_string(current_im) != im)):
   5.319 -            self.info['image'] = sxp.from_string(im)
   5.320 +        # Check whether image definition has been updated
   5.321 +        image_sxp = self._readVm('image')
   5.322 +        if image_sxp and image_sxp != self.info.image_sxpr():
   5.323 +            self.info.update_with_image_sxp(sxp.from_string(image_sxp))
   5.324              changed = True
   5.325  
   5.326          if changed:
   5.327 @@ -791,11 +818,11 @@ class XendDomainInfo:
   5.328  
   5.329      def setName(self, name):
   5.330          self._checkName(name)
   5.331 -        self.info['name'] = name
   5.332 +        self.info['name_label'] = name
   5.333          self.storeVm("name", name)
   5.334  
   5.335      def getName(self):
   5.336 -        return self.info['name']
   5.337 +        return self.info['name_label']
   5.338  
   5.339      def getDomainPath(self):
   5.340          return self.dompath
   5.341 @@ -816,7 +843,7 @@ class XendDomainInfo:
   5.342          return self.info['features']
   5.343  
   5.344      def getVCpuCount(self):
   5.345 -        return self.info['vcpus']
   5.346 +        return self.info['vcpus_number']
   5.347  
   5.348      def setVCpuCount(self, vcpus):
   5.349          self.info['vcpu_avail'] = (1 << vcpus) - 1
   5.350 @@ -828,19 +855,19 @@ class XendDomainInfo:
   5.351  
   5.352      def getMemoryTarget(self):
   5.353          """Get this domain's target memory size, in KB."""
   5.354 -        return self.info['memory'] * 1024
   5.355 +        return self.info['memory_static_min'] * 1024
   5.356  
   5.357      def getResume(self):
   5.358 -        return "%s" % self.info['resume']
   5.359 +        return str(self._resume)
   5.360  
   5.361      def getCap(self):
   5.362 -        return self.info['cpu_cap']
   5.363 +        return self.info.get('cpu_cap', 0)
   5.364  
   5.365      def getWeight(self):
   5.366          return self.info['cpu_weight']
   5.367  
   5.368      def setResume(self, state):
   5.369 -        self.info['resume'] = state
   5.370 +        self._resume = state
   5.371  
   5.372      def getRestartCount(self):
   5.373          return self._readVm('xend/restart_count')
   5.374 @@ -891,7 +918,7 @@ class XendDomainInfo:
   5.375                      return
   5.376  
   5.377                  log.warn('Domain has crashed: name=%s id=%d.',
   5.378 -                         self.info['name'], self.domid)
   5.379 +                         self.info['name_label'], self.domid)
   5.380  
   5.381                  if xroot.get_enable_dump():
   5.382                      self.dumpCore()
   5.383 @@ -910,7 +937,7 @@ class XendDomainInfo:
   5.384                      reason = shutdown_reason(xeninfo['shutdown_reason'])
   5.385  
   5.386                      log.info('Domain has shutdown: name=%s id=%d reason=%s.',
   5.387 -                             self.info['name'], self.domid, reason)
   5.388 +                             self.info['name_label'], self.domid, reason)
   5.389  
   5.390                      self._clearRestart()
   5.391  
   5.392 @@ -945,7 +972,7 @@ class XendDomainInfo:
   5.393                      if timeout < 0:
   5.394                          log.info(
   5.395                              "Domain shutdown timeout expired: name=%s id=%s",
   5.396 -                            self.info['name'], self.domid)
   5.397 +                            self.info['name_label'], self.domid)
   5.398                          self.destroy()
   5.399          finally:
   5.400              self.refresh_shutdown_lock.release()
   5.401 @@ -965,11 +992,23 @@ class XendDomainInfo:
   5.402      def _maybeRestart(self, reason):
   5.403          # Dispatch to the correct method based upon the configured on_{reason}
   5.404          # behaviour.
   5.405 -        {"destroy"        : self.destroy,
   5.406 -         "restart"        : self._restart,
   5.407 -         "preserve"       : self._preserve,
   5.408 -         "rename-restart" : self._renameRestart}[self.info['on_' + reason]]()
   5.409 +        actions =  {"destroy"        : self.destroy,
   5.410 +                    "restart"        : self._restart,
   5.411 +                    "preserve"       : self._preserve,
   5.412 +                    "rename-restart" : self._renameRestart}
   5.413  
   5.414 +        action_conf = {
   5.415 +            'poweroff': 'actions_after_shutdown',
   5.416 +            'reboot': 'actions_after_reboot',
   5.417 +            'crash': 'actions_after_crash',
   5.418 +        }
   5.419 +
   5.420 +        action_target = self.info.get(action_conf.get(reason))
   5.421 +        func = actions.get(action_target, None)
   5.422 +        if func and callable(func):
   5.423 +            func()
   5.424 +        else:
   5.425 +            self.destroy() # default to destroy
   5.426  
   5.427      def _renameRestart(self):
   5.428          self._restart(True)
   5.429 @@ -1008,7 +1047,7 @@ class XendDomainInfo:
   5.430                  log.error(
   5.431                      'VM %s restarting too fast (%f seconds since the last '
   5.432                      'restart).  Refusing to restart to avoid loops.',
   5.433 -                    self.info['name'], timeout)
   5.434 +                    self.info['name_label'], timeout)
   5.435                  self.destroy()
   5.436                  return
   5.437  
   5.438 @@ -1055,11 +1094,11 @@ class XendDomainInfo:
   5.439          new_uuid = uuid.createString()
   5.440          new_name = 'Domain-%s' % new_uuid
   5.441          log.info("Renaming dead domain %s (%d, %s) to %s (%s).",
   5.442 -                 self.info['name'], self.domid, self.info['uuid'],
   5.443 +                 self.info['name_label'], self.domid, self.info['uuid'],
   5.444                   new_name, new_uuid)
   5.445          self._unwatchVm()
   5.446          self._releaseDevices()
   5.447 -        self.info['name'] = new_name
   5.448 +        self.info['name_label'] = new_name
   5.449          self.info['uuid'] = new_uuid
   5.450          self.vmpath = XS_VMROOT + new_uuid
   5.451          self._storeVmDetails()
   5.452 @@ -1067,7 +1106,7 @@ class XendDomainInfo:
   5.453  
   5.454  
   5.455      def _preserve(self):
   5.456 -        log.info("Preserving dead domain %s (%d).", self.info['name'],
   5.457 +        log.info("Preserving dead domain %s (%d).", self.info['name_label'],
   5.458                   self.domid)
   5.459          self._unwatchVm()
   5.460          self._storeDom('xend/shutdown_completed', 'True')
   5.461 @@ -1084,7 +1123,7 @@ class XendDomainInfo:
   5.462              if not corefile:
   5.463                  this_time = time.strftime("%Y-%m%d-%H%M.%S", time.localtime())
   5.464                  corefile = "/var/xen/dump/%s-%s.%s.core" % (this_time,
   5.465 -                                  self.info['name'], self.domid)
   5.466 +                                  self.info['name_label'], self.domid)
   5.467                  
   5.468              if os.path.isdir(corefile):
   5.469                  raise XendError("Cannot dump core in a directory: %s" %
   5.470 @@ -1095,7 +1134,7 @@ class XendDomainInfo:
   5.471              corefile_incomp = corefile+'-incomplete'
   5.472              os.rename(corefile, corefile_incomp)
   5.473              log.exception("XendDomainInfo.dumpCore failed: id = %s name = %s",
   5.474 -                          self.domid, self.info['name'])
   5.475 +                          self.domid, self.info['name_label'])
   5.476              raise XendError("Failed to dump core: %s" %  str(ex))
   5.477  
   5.478      #
   5.479 @@ -1117,8 +1156,8 @@ class XendDomainInfo:
   5.480  
   5.481          @raise: VmError for invalid devices
   5.482          """
   5.483 -        for (devclass, config) in self.info.all_devices_sxpr():
   5.484 -            if devclass in XendDevices.valid_devices():
   5.485 +        for (devclass, config) in self.info.get('devices', {}).values():
   5.486 +            if devclass in XendDevices.valid_devices():            
   5.487                  log.info("createDevice: %s : %s" % (devclass, config))
   5.488                  self._createDevice(devclass, config)
   5.489  
   5.490 @@ -1139,7 +1178,7 @@ class XendDomainInfo:
   5.491                          # there's nothing more we can do.
   5.492                          log.exception(
   5.493                             "Device release failed: %s; %s; %s",
   5.494 -                           self.info['name'], devclass, dev)
   5.495 +                           self.info['name_label'], devclass, dev)
   5.496              if t.commit():
   5.497                  break
   5.498  
   5.499 @@ -1211,11 +1250,12 @@ class XendDomainInfo:
   5.500  
   5.501          log.debug('XendDomainInfo.constructDomain')
   5.502  
   5.503 -        hvm = (self._infoIsSet('image') and
   5.504 -               sxp.name(self.info['image']) == "hvm")
   5.505 +        image_cfg = self.info.get('image', {})
   5.506 +        hvm = image_cfg.has_key('hvm')
   5.507 +
   5.508          if hvm:
   5.509              info = xc.xeninfo()
   5.510 -            if not 'hvm' in info['xen_caps']:
   5.511 +            if 'hvm' not in info['xen_caps']:
   5.512                  raise VmError("HVM guest support is unavailable: is VT/AMD-V "
   5.513                                "supported by your CPU and enabled in your "
   5.514                                "BIOS?")
   5.515 @@ -1228,14 +1268,14 @@ class XendDomainInfo:
   5.516  
   5.517          if self.domid < 0:
   5.518              raise VmError('Creating domain failed: name=%s' %
   5.519 -                          self.info['name'])
   5.520 +                          self.info['name_label'])
   5.521  
   5.522          self.dompath = GetDomainPath(self.domid)
   5.523  
   5.524          self._recreateDom()
   5.525  
   5.526          # Set maximum number of vcpus in domain
   5.527 -        xc.domain_max_vcpus(self.domid, int(self.info['vcpus']))
   5.528 +        xc.domain_max_vcpus(self.domid, int(self.info['vcpus_number']))
   5.529  
   5.530  
   5.531      def _introduceDomain(self):
   5.532 @@ -1256,7 +1296,7 @@ class XendDomainInfo:
   5.533  
   5.534          # if we have a boot loader but no image, then we need to set things
   5.535          # up by running the boot loader non-interactively
   5.536 -        if self._infoIsSet('bootloader') and not self._infoIsSet('image'):
   5.537 +        if self.info.get('bootloader') and self.info.get('image'):
   5.538              self._configureBootloader()
   5.539  
   5.540          if not self._infoIsSet('image'):
   5.541 @@ -1264,8 +1304,9 @@ class XendDomainInfo:
   5.542  
   5.543          try:
   5.544              self.image = image.create(self,
   5.545 +                                      self.info,
   5.546                                        self.info['image'],
   5.547 -                                      self.info.all_devices_sxpr())
   5.548 +                                      self.info['devices'])
   5.549  
   5.550              localtime = self.info.get('localtime', 0)
   5.551              if localtime is not None and localtime == 1:
   5.552 @@ -1284,12 +1325,12 @@ class XendDomainInfo:
   5.553              # the various headrooms necessary, given the raw configured
   5.554              # values. maxmem, memory, and shadow are all in KiB.
   5.555              maxmem = self.image.getRequiredAvailableMemory(
   5.556 -                self.info['maxmem'] * 1024)
   5.557 +                self.info['memory_static_min'] * 1024)
   5.558              memory = self.image.getRequiredAvailableMemory(
   5.559 -                self.info['memory'] * 1024)
   5.560 +                self.info['memory_static_max'] * 1024)
   5.561              shadow = self.image.getRequiredShadowMemory(
   5.562                  self.info['shadow_memory'] * 1024,
   5.563 -                self.info['maxmem'] * 1024)
   5.564 +                self.info['memory_static_max'] * 1024)
   5.565  
   5.566              # Round shadow up to a multiple of a MiB, as shadow_mem_control
   5.567              # takes MiB and we must not round down and end up under-providing.
   5.568 @@ -1317,7 +1358,7 @@ class XendDomainInfo:
   5.569  
   5.570              self._createDevices()
   5.571  
   5.572 -            if self.info['bootloader'] not in [None, 'kernel_external']:
   5.573 +            if self.info['bootloader']:
   5.574                  self.image.cleanupBootloading()
   5.575  
   5.576              self.info['start_time'] = time.time()
   5.577 @@ -1325,7 +1366,7 @@ class XendDomainInfo:
   5.578              self._stateSet(DOM_STATE_RUNNING)
   5.579          except RuntimeError, exn:
   5.580              log.exception("XendDomainInfo.initDomain: exception occurred")
   5.581 -            if self.info['bootloader'] not in [None, 'kernel_external'] \
   5.582 +            if self.info['bootloader'] not in (None, 'kernel_external') \
   5.583                     and self.image is not None:
   5.584                  self.image.cleanupBootloading()
   5.585              raise VmError(str(exn))
   5.586 @@ -1338,7 +1379,6 @@ class XendDomainInfo:
   5.587          self.refresh_shutdown_lock.acquire()
   5.588          try:
   5.589              self.unwatchShutdown()
   5.590 -
   5.591              self._releaseDevices()
   5.592  
   5.593              if self.image:
   5.594 @@ -1459,14 +1499,14 @@ class XendDomainInfo:
   5.595  
   5.596      def _configureBootloader(self):
   5.597          """Run the bootloader if we're configured to do so."""
   5.598 -        if not self.info['bootloader']:
   5.599 +        if not self.info.get('bootloader'):
   5.600              return
   5.601          blcfg = None
   5.602          # FIXME: this assumes that we want to use the first disk device
   5.603 -        for (n, c) in self.info.all_devices_sxpr():
   5.604 -            if not n or not c or not(n in ["vbd", "tap"]):
   5.605 +        for devuuid, (devtype, devinfo) in self.info.all_devices_sxpr():
   5.606 +            if not devtype or not devinfo or devtype not in ('vbd', 'tap'):
   5.607                  continue
   5.608 -            disk = sxp.child_value(c, "uname")
   5.609 +            disk = devinfo.get('uname')
   5.610              if disk is None:
   5.611                  continue
   5.612              fn = blkdev_uname_to_file(disk)
   5.613 @@ -1478,7 +1518,8 @@ class XendDomainInfo:
   5.614              msg = "Had a bootloader specified, but can't find disk"
   5.615              log.error(msg)
   5.616              raise VmError(msg)
   5.617 -        self.info['image'] = blcfg
   5.618 +        
   5.619 +        self.info.update_with_image_sxp(blcfg)
   5.620  
   5.621      # 
   5.622      # VM Functions
   5.623 @@ -1516,7 +1557,8 @@ class XendDomainInfo:
   5.624          if arch.type == "x86":
   5.625              # 1MB per vcpu plus 4Kib/Mib of RAM.  This is higher than 
   5.626              # the minimum that Xen would allocate if no value were given.
   5.627 -            overhead_kb = self.info['vcpus'] * 1024 + self.info['maxmem'] * 4
   5.628 +            overhead_kb = self.info['vcpus_number'] * 1024 + \
   5.629 +                          self.info['memory_static_max'] * 4
   5.630              overhead_kb = ((overhead_kb + 1023) / 1024) * 1024
   5.631              # The domain might already have some shadow memory
   5.632              overhead_kb -= xc.shadow_mem_control(self.domid) * 1024
   5.633 @@ -1558,12 +1600,15 @@ class XendDomainInfo:
   5.634      def _storeVmDetails(self):
   5.635          to_store = {}
   5.636  
   5.637 -        for k in VM_STORE_ENTRIES:
   5.638 -            if self._infoIsSet(k[0]):
   5.639 -                to_store[k[0]] = str(self.info[k[0]])
   5.640 +        for key in XendConfig.LEGACY_XENSTORE_VM_PARAMS:
   5.641 +            info_key = XendConfig.LEGACY_CFG_TO_XENAPI_CFG.get(key, key)
   5.642 +            if self._infoIsSet(info_key):
   5.643 +                to_store[key] = str(self.info[info_key])
   5.644  
   5.645 -        if self._infoIsSet('image'):
   5.646 -            to_store['image'] = sxp.to_string(self.info['image'])
   5.647 +        if self.info.get('image'):
   5.648 +            image_sxpr = self.info.image_sxpr()
   5.649 +            if image_sxpr:
   5.650 +                to_store['image'] = sxp.to_string(image_sxpr)
   5.651  
   5.652          if self._infoIsSet('security'):
   5.653              secinfo = self.info['security']
   5.654 @@ -1656,6 +1701,7 @@ class XendDomainInfo:
   5.655                      #create new security element
   5.656                      self.info.update({'security':
   5.657                                        [['ssidref', str(info['ssidref'])]]})
   5.658 +                    
   5.659          #ssidref field not used any longer
   5.660          if 'ssidref' in info:
   5.661              info.pop('ssidref')
   5.662 @@ -1663,8 +1709,7 @@ class XendDomainInfo:
   5.663          # make sure state is reset for info
   5.664          # TODO: we should eventually get rid of old_dom_states
   5.665  
   5.666 -        self.info.update(info)
   5.667 -        self.info.validate()
   5.668 +        self.info.update_config(info)
   5.669  
   5.670          if refresh:
   5.671              self.refreshShutdown(info)
   5.672 @@ -1673,7 +1718,7 @@ class XendDomainInfo:
   5.673                    str(self.domid), self.info)
   5.674  
   5.675      def sxpr(self, ignore_store = False):
   5.676 -        result = self.info.get_sxp(domain = self,
   5.677 +        result = self.info.to_sxp(domain = self,
   5.678                                     ignore_devices = ignore_store)
   5.679  
   5.680          if not ignore_store and self.dompath:
   5.681 @@ -1695,9 +1740,15 @@ class XendDomainInfo:
   5.682          return dom_uuid
   5.683      
   5.684      def get_memory_static_max(self):
   5.685 -        return self.info['maxmem']
   5.686 +        return self.info['memory_static_max']
   5.687      def get_memory_static_min(self):
   5.688 -        return self.info['memory']
   5.689 +        return self.info['memory_static_min']
   5.690 +    def get_memory_dynamic_max(self):
   5.691 +        return self.info['memory_dynamic_min']
   5.692 +    def get_memory_dynamic_min(self):
   5.693 +        return self.info['memory_static_min']
   5.694 +    
   5.695 +    
   5.696      def get_vcpus_policy(self):
   5.697          sched_id = xc.sched_id_get()
   5.698          if sched_id == xen.lowlevel.xc.XEN_SCHEDULER_SEDF:
   5.699 @@ -1717,21 +1768,17 @@ class XendDomainInfo:
   5.700      def get_platform_keymap(self):
   5.701          return ''
   5.702      def get_platform_serial(self):
   5.703 -        return '' # TODO
   5.704 +        return self.info['platform_serial']
   5.705      def get_platform_localtime(self):
   5.706 -        return False # TODO
   5.707 +        return self.info['platform_localtime']
   5.708      def get_platform_clock_offset(self):
   5.709 -        return False # TODO
   5.710 +        return self.info['platform_clock_offset']
   5.711      def get_platform_enable_audio(self):
   5.712 -        return False # TODO
   5.713 +        return self.info['platform_enable_audio']
   5.714      def get_builder(self):
   5.715 -        return 'Linux' # TODO
   5.716 +        return self.info['builder']
   5.717      def get_boot_method(self):
   5.718 -        bootloader = self.info['bootloader']
   5.719 -        if not bootloader or bootloader not in XEN_API_BOOT_TYPE:
   5.720 -            return 'kernel_external'
   5.721 -        return bootloader
   5.722 -    
   5.723 +        return self.info['boot_method']
   5.724      def get_kernel_image(self):
   5.725          return self.info['kernel_kernel']
   5.726      def get_kernel_initrd(self):
   5.727 @@ -1748,25 +1795,26 @@ class XendDomainInfo:
   5.728          return {} # TODO
   5.729      
   5.730      def get_on_shutdown(self):
   5.731 -        after_shutdown = self.info.get('on_poweroff')
   5.732 +        after_shutdown = self.info.get('action_after_shutdown')
   5.733          if not after_shutdown or after_shutdown not in XEN_API_ON_NORMAL_EXIT:
   5.734              return XEN_API_ON_NORMAL_EXIT[-1]
   5.735          return after_shutdown
   5.736  
   5.737      def get_on_reboot(self):
   5.738 -        after_reboot = self.info.get('on_reboot')
   5.739 +        after_reboot = self.info.get('action_after_reboot')
   5.740          if not after_reboot or after_reboot not in XEN_API_ON_NORMAL_EXIT:
   5.741              return XEN_API_ON_NORMAL_EXIT[-1]
   5.742          return after_reboot
   5.743  
   5.744      def get_on_suspend(self):
   5.745 -        after_suspend = self.info.get('on_suspend') # TODO: not supported
   5.746 +        # TODO: not supported        
   5.747 +        after_suspend = self.info.get('action_after_suspend') 
   5.748          if not after_suspend or after_suspend not in XEN_API_ON_NORMAL_EXIT:
   5.749              return XEN_API_ON_NORMAL_EXIT[-1]
   5.750          return after_suspend        
   5.751  
   5.752      def get_on_crash(self):
   5.753 -        after_crash = self.info.get('on_crash')
   5.754 +        after_crash = self.info.get('action_after_crash')
   5.755          if not after_crash or after_crash not in XEN_API_ON_CRASH_BEHAVIOUR:
   5.756              return XEN_API_ON_CRASH_BEHAVIOUR[0]
   5.757          return after_crash
   5.758 @@ -1780,7 +1828,7 @@ class XendDomainInfo:
   5.759  
   5.760          @rtype: dictionary
   5.761          """
   5.762 -        dev_type_config = self.info['device'].get(dev_uuid)
   5.763 +        dev_type_config = self.info['devices'].get(dev_uuid)
   5.764  
   5.765          # shortcut if the domain isn't started because
   5.766          # the devcontrollers will have no better information
   5.767 @@ -1840,7 +1888,7 @@ class XendDomainInfo:
   5.768              config['IO_bandwidth_incoming_kbs'] = 0.0
   5.769              config['IO_bandwidth_outgoing_kbs'] = 0.0
   5.770  
   5.771 -        if dev_class =='vbd':
   5.772 +        if dev_class == 'vbd':
   5.773              config['VDI'] = '' # TODO
   5.774              config['device'] = config.get('dev', '')
   5.775              config['driver'] = 'paravirtualised' # TODO
   5.776 @@ -1984,8 +2032,8 @@ class XendDomainInfo:
   5.777  
   5.778      def __str__(self):
   5.779          return '<domain id=%s name=%s memory=%s state=%s>' % \
   5.780 -               (str(self.domid), self.info['name'],
   5.781 -                str(self.info['memory']), DOM_STATES[self.state])
   5.782 +               (str(self.domid), self.info['name_label'],
   5.783 +                str(self.info['memory_static_min']), DOM_STATES[self.state])
   5.784  
   5.785      __repr__ = __str__
   5.786  
     6.1 --- a/tools/python/xen/xend/image.py	Thu Nov 30 14:05:27 2006 +0000
     6.2 +++ b/tools/python/xen/xend/image.py	Thu Nov 30 14:44:58 2006 +0000
     6.3 @@ -23,7 +23,6 @@ import math
     6.4  import signal
     6.5  
     6.6  import xen.lowlevel.xc
     6.7 -from xen.xend import sxp
     6.8  from xen.xend.XendError import VmError, XendError
     6.9  from xen.xend.XendLogging import log
    6.10  from xen.xend.server.netif import randomMAC
    6.11 @@ -31,19 +30,18 @@ from xen.xend.xenstore.xswatch import xs
    6.12  from xen.xend import arch
    6.13  from xen.xend import FlatDeviceTree
    6.14  
    6.15 -
    6.16  xc = xen.lowlevel.xc.xc()
    6.17  
    6.18 -
    6.19  MAX_GUEST_CMDLINE = 1024
    6.20  
    6.21  
    6.22 -def create(vm, imageConfig, deviceConfig):
    6.23 +def create(vm, vmConfig, imageConfig, deviceConfig):
    6.24      """Create an image handler for a vm.
    6.25  
    6.26      @return ImageHandler instance
    6.27      """
    6.28 -    return findImageHandlerClass(imageConfig)(vm, imageConfig, deviceConfig)
    6.29 +    return findImageHandlerClass(imageConfig)(vm, vmConfig, imageConfig,
    6.30 +                                              deviceConfig)
    6.31  
    6.32  
    6.33  class ImageHandler:
    6.34 @@ -66,34 +64,20 @@ class ImageHandler:
    6.35      ostype = None
    6.36  
    6.37  
    6.38 -    def __init__(self, vm, imageConfig, deviceConfig):
    6.39 +    def __init__(self, vm, vmConfig, imageConfig, deviceConfig):
    6.40          self.vm = vm
    6.41  
    6.42          self.kernel = None
    6.43          self.ramdisk = None
    6.44          self.cmdline = None
    6.45  
    6.46 -        self.configure(imageConfig, deviceConfig)
    6.47 -
    6.48 -    def configure(self, imageConfig, _):
    6.49 -        """Config actions common to all unix-like domains."""
    6.50 -
    6.51 -        def get_cfg(name, default = None):
    6.52 -            return sxp.child_value(imageConfig, name, default)
    6.53 +        self.configure(vmConfig, imageConfig, deviceConfig)
    6.54  
    6.55 -        self.kernel = get_cfg("kernel")
    6.56 -        self.cmdline = ""
    6.57 -        ip = get_cfg("ip")
    6.58 -        if ip:
    6.59 -            self.cmdline += " ip=" + ip
    6.60 -        root = get_cfg("root")
    6.61 -        if root:
    6.62 -            self.cmdline += " root=" + root
    6.63 -        args = get_cfg("args")
    6.64 -        if args:
    6.65 -            self.cmdline += " " + args
    6.66 -        self.ramdisk = get_cfg("ramdisk", '')
    6.67 -        
    6.68 +    def configure(self, vmConfig, imageConfig, _):
    6.69 +        """Config actions common to all unix-like domains."""
    6.70 +        self.kernel = vmConfig['kernel_kernel']
    6.71 +        self.cmdline = vmConfig['kernel_args']
    6.72 +        self.ramdisk = vmConfig['kernel_initrd']
    6.73          self.vm.storeVm(("image/ostype", self.ostype),
    6.74                          ("image/kernel", self.kernel),
    6.75                          ("image/cmdline", self.cmdline),
    6.76 @@ -214,8 +198,8 @@ class PPC_LinuxImageHandler(LinuxImageHa
    6.77  
    6.78      ostype = "linux"
    6.79  
    6.80 -    def configure(self, imageConfig, deviceConfig):
    6.81 -        LinuxImageHandler.configure(self, imageConfig, deviceConfig)
    6.82 +    def configure(self, vmConfig, imageConfig, deviceConfig):
    6.83 +        LinuxImageHandler.configure(self, vmConfig, imageConfig, deviceConfig)
    6.84          self.imageConfig = imageConfig
    6.85  
    6.86      def buildDomain(self):
    6.87 @@ -248,25 +232,26 @@ class PPC_LinuxImageHandler(LinuxImageHa
    6.88  
    6.89  class HVMImageHandler(ImageHandler):
    6.90  
    6.91 -    def __init__(self, vm, imageConfig, deviceConfig):
    6.92 -        ImageHandler.__init__(self, vm, imageConfig, deviceConfig)
    6.93 +    def __init__(self, vm, vmConfig, imageConfig, deviceConfig):
    6.94 +        ImageHandler.__init__(self, vm, vmConfig, imageConfig, deviceConfig)
    6.95          self.shutdownWatch = None
    6.96  
    6.97 -    def configure(self, imageConfig, deviceConfig):
    6.98 -        ImageHandler.configure(self, imageConfig, deviceConfig)
    6.99 +    def configure(self, vmConfig, imageConfig, deviceConfig):
   6.100 +        ImageHandler.configure(self, vmConfig, imageConfig, deviceConfig)
   6.101  
   6.102          info = xc.xeninfo()
   6.103 -        if not 'hvm' in info['xen_caps']:
   6.104 +        if 'hvm' not in info['xen_caps']:
   6.105              raise VmError("HVM guest support is unavailable: is VT/AMD-V "
   6.106                            "supported by your CPU and enabled in your BIOS?")
   6.107  
   6.108          self.dmargs = self.parseDeviceModelArgs(imageConfig, deviceConfig)
   6.109 -        self.device_model = sxp.child_value(imageConfig, 'device_model')
   6.110 +        self.device_model = imageConfig['hvm'].get('device_model')
   6.111          if not self.device_model:
   6.112              raise VmError("hvm: missing device model")
   6.113 -        self.display = sxp.child_value(imageConfig, 'display')
   6.114 -        self.xauthority = sxp.child_value(imageConfig, 'xauthority')
   6.115 -        self.vncconsole = sxp.child_value(imageConfig, 'vncconsole')
   6.116 +        
   6.117 +        self.display = imageConfig['hvm'].get('display')
   6.118 +        self.xauthority = imageConfig['hvm'].get('xauthority')
   6.119 +        self.vncconsole = imageConfig['hvm'].get('vncconsole')
   6.120  
   6.121          self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)),
   6.122                          ("image/device-model", self.device_model),
   6.123 @@ -276,9 +261,9 @@ class HVMImageHandler(ImageHandler):
   6.124  
   6.125          self.dmargs += self.configVNC(imageConfig)
   6.126  
   6.127 -        self.pae  = int(sxp.child_value(imageConfig, 'pae',  1))
   6.128 -        self.acpi = int(sxp.child_value(imageConfig, 'acpi', 1))
   6.129 -        self.apic = int(sxp.child_value(imageConfig, 'apic', 1))
   6.130 +        self.pae  = imageConfig['hvm'].get('pae', 0)
   6.131 +        self.acpi  = imageConfig['hvm'].get('acpi', 0)
   6.132 +        self.apic  = imageConfig['hvm'].get('apic', 0)
   6.133  
   6.134      def buildDomain(self):
   6.135          store_evtchn = self.vm.getStorePort()
   6.136 @@ -312,8 +297,12 @@ class HVMImageHandler(ImageHandler):
   6.137                     'localtime', 'serial', 'stdvga', 'isa', 'vcpus',
   6.138                     'acpi', 'usb', 'usbdevice', 'keymap' ]
   6.139          ret = []
   6.140 +        hvmDeviceConfig = imageConfig['hvm']['devices']
   6.141 +        
   6.142          for a in dmargs:
   6.143 -            v = sxp.child_value(imageConfig, a)
   6.144 +            v = hvmDeviceConfig.get(a)
   6.145 +            if a == 'vcpus':
   6.146 +                v = hvmDeviceConfig.get('vcpus_number')
   6.147  
   6.148              # python doesn't allow '-' in variable names
   6.149              if a == 'stdvga': a = 'std-vga'
   6.150 @@ -328,7 +317,7 @@ class HVMImageHandler(ImageHandler):
   6.151                      ret.append("-%s" % a)
   6.152                      ret.append("%s" % v)
   6.153  
   6.154 -            if a in ['fda', 'fdb' ]:
   6.155 +            if a in ['fda', 'fdb']:
   6.156                  if v:
   6.157                      if not os.path.isabs(v):
   6.158                          raise VmError("Floppy file %s does not exist." % v)
   6.159 @@ -336,26 +325,27 @@ class HVMImageHandler(ImageHandler):
   6.160  
   6.161          # Handle disk/network related options
   6.162          mac = None
   6.163 -        ret = ret + ["-domain-name", "%s" % self.vm.info['name']]
   6.164 +        ret = ret + ["-domain-name", str(self.vm.info['name_label'])]
   6.165          nics = 0
   6.166 -        for (name, info) in deviceConfig:
   6.167 -            if name == 'vbd':
   6.168 -                uname = sxp.child_value(info, 'uname')
   6.169 +        
   6.170 +        for devuuid, (devtype, devinfo) in deviceConfig.items():
   6.171 +            if devtype == 'vbd':
   6.172 +                uname = devinfo['uname']
   6.173                  if uname is not None and 'file:' in uname:
   6.174                      (_, vbdparam) = string.split(uname, ':', 1)
   6.175                      if not os.path.isfile(vbdparam):
   6.176                          raise VmError('Disk image does not exist: %s' %
   6.177                                        vbdparam)
   6.178 -            if name == 'vif':
   6.179 -                type = sxp.child_value(info, 'type')
   6.180 -                if type != 'ioemu':
   6.181 +            if devtype == 'vif':
   6.182 +                dtype = devinfo.get('type', 'ioemu')
   6.183 +                if dtype != 'ioemu':
   6.184                      continue
   6.185                  nics += 1
   6.186 -                mac = sxp.child_value(info, 'mac')
   6.187 +                mac = devinfo.get('mac')
   6.188                  if mac == None:
   6.189                      mac = randomMAC()
   6.190 -                bridge = sxp.child_value(info, 'bridge', 'xenbr0')
   6.191 -                model = sxp.child_value(info, 'model', 'rtl8139')
   6.192 +                bridge = devinfo.get('bridge', 'xenbr0')
   6.193 +                model = devinfo.get('model', 'rtl8139')
   6.194                  ret.append("-net")
   6.195                  ret.append("nic,vlan=%d,macaddr=%s,model=%s" %
   6.196                             (nics, mac, model))
   6.197 @@ -363,31 +353,32 @@ class HVMImageHandler(ImageHandler):
   6.198                  ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge))
   6.199          return ret
   6.200  
   6.201 -    def configVNC(self, config):
   6.202 +    def configVNC(self, imageConfig):
   6.203          # Handle graphics library related options
   6.204 -        vnc = sxp.child_value(config, 'vnc')
   6.205 -        sdl = sxp.child_value(config, 'sdl')
   6.206 +        vnc = imageConfig.get('vnc')
   6.207 +        sdl = imageConfig.get('sdl')
   6.208          ret = []
   6.209 -        nographic = sxp.child_value(config, 'nographic')
   6.210 +        nographic = imageConfig.get('nographic')
   6.211  
   6.212          # get password from VM config (if password omitted, None)
   6.213 -        vncpasswd_vmconfig = sxp.child_value(config, 'vncpasswd')
   6.214 +        vncpasswd_vmconfig = imageConfig.get('vncpasswd')
   6.215  
   6.216          if nographic:
   6.217              ret.append('-nographic')
   6.218              return ret
   6.219  
   6.220          if vnc:
   6.221 -            vncdisplay = int(sxp.child_value(config, 'vncdisplay',
   6.222 -                                             self.vm.getDomid()))
   6.223 +            vncdisplay = imageConfig.get('vncdisplay',
   6.224 +                                         int(self.vm.getDomid()))
   6.225 +            vncunused = imageConfig.get('vncunused')
   6.226  
   6.227 -            vncunused = sxp.child_value(config, 'vncunused')
   6.228              if vncunused:
   6.229                  ret += ['-vncunused']
   6.230              else:
   6.231                  ret += ['-vnc', '%d' % vncdisplay]
   6.232  
   6.233 -            vnclisten = sxp.child_value(config, 'vnclisten')
   6.234 +            vnclisten = imageConfig.get('vnclisten')
   6.235 +
   6.236              if not(vnclisten):
   6.237                  vnclisten = (xen.xend.XendRoot.instance().
   6.238                               get_vnclisten_address())
   6.239 @@ -423,21 +414,26 @@ class HVMImageHandler(ImageHandler):
   6.240          if self.vncconsole:
   6.241              args = args + ([ "-vncviewer" ])
   6.242          log.info("spawning device models: %s %s", self.device_model, args)
   6.243 +        # keep track of pid and spawned options to kill it later
   6.244          self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env)
   6.245          log.info("device model pid: %d", self.pid)
   6.246  
   6.247      def destroy(self):
   6.248 -        self.unregister_shutdown_watch();
   6.249 +        self.unregister_shutdown_watch()
   6.250          if not self.pid:
   6.251              return
   6.252 -        os.kill(self.pid, signal.SIGKILL)
   6.253 -        os.waitpid(self.pid, 0)
   6.254 +        try:
   6.255 +            os.kill(self.pid, signal.SIGKILL)
   6.256 +            os.waitpid(self.pid, 0)
   6.257 +        except OSError, e:
   6.258 +            log.warning("Unable to kill device model (pid: %d)" % self.pid)
   6.259 +            
   6.260          self.pid = 0
   6.261  
   6.262      def register_shutdown_watch(self):
   6.263          """ add xen store watch on control/shutdown """
   6.264 -        self.shutdownWatch = xswatch(self.vm.dompath + "/control/shutdown", \
   6.265 -                                    self.hvm_shutdown)
   6.266 +        self.shutdownWatch = xswatch(self.vm.dompath + "/control/shutdown",
   6.267 +                                     self.hvm_shutdown)
   6.268          log.debug("hvm shutdown watch registered")
   6.269  
   6.270      def unregister_shutdown_watch(self):
   6.271 @@ -529,10 +525,10 @@ def findImageHandlerClass(image):
   6.272      @param image config
   6.273      @return ImageHandler subclass or None
   6.274      """
   6.275 -    type = sxp.name(image)
   6.276 -    if type is None:
   6.277 +    image_type = image['type']
   6.278 +    if image_type is None:
   6.279          raise VmError('missing image type')
   6.280      try:
   6.281 -        return _handlers[arch.type][type]
   6.282 +        return _handlers[arch.type][image_type]
   6.283      except KeyError:
   6.284 -        raise VmError('unknown image type: ' + type)
   6.285 +        raise VmError('unknown image type: ' + image_type)
     7.1 --- a/tools/python/xen/xend/server/DevController.py	Thu Nov 30 14:05:27 2006 +0000
     7.2 +++ b/tools/python/xen/xend/server/DevController.py	Thu Nov 30 14:44:58 2006 +0000
     7.3 @@ -17,6 +17,7 @@
     7.4  #============================================================================
     7.5  
     7.6  from threading import Event
     7.7 +import types
     7.8  
     7.9  from xen.xend import sxp
    7.10  from xen.xend.XendError import VmError
    7.11 @@ -86,7 +87,7 @@ class DevController:
    7.12  
    7.13          import xen.xend.XendDomain
    7.14          xd = xen.xend.XendDomain.instance()
    7.15 -        backdom_name = sxp.child_value(config, 'backend')
    7.16 +        backdom_name = config.get('backend')
    7.17          if backdom_name is None:
    7.18              backdom = xen.xend.XendDomain.DOM0_ID
    7.19          else:
    7.20 @@ -223,7 +224,7 @@ class DevController:
    7.21          configDict = self.getDeviceConfiguration(devid)
    7.22          sxpr = [self.deviceClass]
    7.23          for key, val in configDict.items():
    7.24 -            if type(val) == type(list()):
    7.25 +            if isinstance(val, (types.ListType, types.TupleType)):
    7.26                  for v in val:
    7.27                      sxpr.append([key, v])
    7.28              else:
    7.29 @@ -405,7 +406,7 @@ class DevController:
    7.30          import xen.xend.XendDomain
    7.31          xd = xen.xend.XendDomain.instance()
    7.32  
    7.33 -        backdom_name = sxp.child_value(config, 'backend')
    7.34 +        backdom_name = config.get('backend')
    7.35          if backdom_name:
    7.36              backdom = xd.domain_lookup_nr(backdom_name)
    7.37          else:
     8.1 --- a/tools/python/xen/xend/server/blkif.py	Thu Nov 30 14:05:27 2006 +0000
     8.2 +++ b/tools/python/xen/xend/server/blkif.py	Thu Nov 30 14:44:58 2006 +0000
     8.3 @@ -21,7 +21,6 @@ import string
     8.4  
     8.5  from xen.util import blkif
     8.6  from xen.util import security
     8.7 -from xen.xend import sxp
     8.8  from xen.xend.XendError import VmError
     8.9  from xen.xend.server.DevController import DevController
    8.10  
    8.11 @@ -37,9 +36,9 @@ class BlkifController(DevController):
    8.12  
    8.13      def getDeviceDetails(self, config):
    8.14          """@see DevController.getDeviceDetails"""
    8.15 -        uname = sxp.child_value(config, 'uname', '')
    8.16 -        dev = sxp.child_value(config, 'dev', '')
    8.17 -
    8.18 +        uname = config.get('uname', '')
    8.19 +        dev = config.get('dev', '')
    8.20 +        
    8.21          if 'ioemu:' in dev:
    8.22              (_, dev) = string.split(dev, ':', 1)
    8.23          try:
    8.24 @@ -59,17 +58,17 @@ class BlkifController(DevController):
    8.25              except ValueError:
    8.26                  (typ, params) = ("", "")
    8.27  
    8.28 -        mode = sxp.child_value(config, 'mode', 'r')
    8.29 +        mode = config.get('mode', 'r')
    8.30          if mode not in ('r', 'w', 'w!'):
    8.31              raise VmError('Invalid mode')
    8.32  
    8.33 -        back = { 'dev'    : dev,
    8.34 -                 'type'   : typ,
    8.35 -                 'params' : params,
    8.36 -                 'mode'   : mode
    8.37 -               }
    8.38 +        back = {'dev'    : dev,
    8.39 +                'type'   : typ,
    8.40 +                'params' : params,
    8.41 +                'mode'   : mode,
    8.42 +                }
    8.43  
    8.44 -        uuid = sxp.child_value(config, 'uuid')
    8.45 +        uuid = config.get('uuid')
    8.46          if uuid:
    8.47              back['uuid'] = uuid
    8.48  
     9.1 --- a/tools/python/xen/xend/server/iopif.py	Thu Nov 30 14:05:27 2006 +0000
     9.2 +++ b/tools/python/xen/xend/server/iopif.py	Thu Nov 30 14:44:58 2006 +0000
     9.3 @@ -22,7 +22,6 @@ import types
     9.4  
     9.5  import xen.lowlevel.xc
     9.6  
     9.7 -from xen.xend import sxp
     9.8  from xen.xend.XendError import VmError
     9.9  
    9.10  from xen.xend.server.DevController import DevController
    9.11 @@ -49,13 +48,12 @@ class IOPortsController(DevController):
    9.12      def __init__(self, vm):
    9.13          DevController.__init__(self, vm)
    9.14  
    9.15 -
    9.16      def getDeviceDetails(self, config):
    9.17          """@see DevController.getDeviceDetails"""
    9.18  
    9.19          def get_param(field):
    9.20              try:
    9.21 -                val = sxp.child_value(config, field)
    9.22 +                val = config.get(field)
    9.23  
    9.24                  if not val:
    9.25                      raise VmError('ioports: Missing %s config setting' % field)
    10.1 --- a/tools/python/xen/xend/server/irqif.py	Thu Nov 30 14:05:27 2006 +0000
    10.2 +++ b/tools/python/xen/xend/server/irqif.py	Thu Nov 30 14:44:58 2006 +0000
    10.3 @@ -45,7 +45,7 @@ class IRQController(DevController):
    10.4  
    10.5          def get_param(field):
    10.6              try:
    10.7 -                val = sxp.child_value(config, field)
    10.8 +                val = config.get(field)
    10.9  
   10.10                  if not val:
   10.11                      raise VmError('irq: Missing %s config setting' % field)
    11.1 --- a/tools/python/xen/xend/server/netif.py	Thu Nov 30 14:05:27 2006 +0000
    11.2 +++ b/tools/python/xen/xend/server/netif.py	Thu Nov 30 14:44:58 2006 +0000
    11.3 @@ -24,7 +24,6 @@ import os
    11.4  import random
    11.5  import re
    11.6  
    11.7 -from xen.xend import sxp
    11.8  from xen.xend import XendRoot
    11.9  from xen.xend.server.DevController import DevController
   11.10  
   11.11 @@ -139,22 +138,15 @@ class NetifController(DevController):
   11.12      def getDeviceDetails(self, config):
   11.13          """@see DevController.getDeviceDetails"""
   11.14  
   11.15 -        def _get_config_ipaddr(config):
   11.16 -            val = []
   11.17 -            for ipaddr in sxp.children(config, elt='ip'):
   11.18 -                val.append(sxp.child0(ipaddr))
   11.19 -            return val
   11.20 -
   11.21          script = os.path.join(xroot.network_script_dir,
   11.22 -                              sxp.child_value(config, 'script',
   11.23 -                                              xroot.get_vif_script()))
   11.24 -        typ = sxp.child_value(config, 'type')
   11.25 -        bridge  = sxp.child_value(config, 'bridge')
   11.26 -        mac     = sxp.child_value(config, 'mac')
   11.27 -        vifname = sxp.child_value(config, 'vifname')
   11.28 -        rate    = sxp.child_value(config, 'rate')
   11.29 -        uuid    = sxp.child_value(config, 'uuid')
   11.30 -        ipaddr  = _get_config_ipaddr(config)
   11.31 +                              config.get('script', xroot.get_vif_script()))
   11.32 +        typ = config.get('type')
   11.33 +        bridge  = config.get('bridge')
   11.34 +        mac     = config.get('mac')
   11.35 +        vifname = config.get('vifname')
   11.36 +        rate    = config.get('rate')
   11.37 +        uuid    = config.get('uuid')
   11.38 +        ipaddr  = config.get('ip')
   11.39  
   11.40          devid = self.allocateDeviceID()
   11.41  
    12.1 --- a/tools/python/xen/xend/server/pciif.py	Thu Nov 30 14:05:27 2006 +0000
    12.2 +++ b/tools/python/xen/xend/server/pciif.py	Thu Nov 30 14:44:58 2006 +0000
    12.3 @@ -53,60 +53,29 @@ class PciController(DevController):
    12.4  
    12.5      def getDeviceDetails(self, config):
    12.6          """@see DevController.getDeviceDetails"""
    12.7 -        #log.debug('pci config='+sxp.to_string(config))
    12.8 -
    12.9 -        def get_param(config, field, default=None):
   12.10 +        def parse_hex(val):
   12.11              try:
   12.12 -                val = sxp.child_value(config, field)
   12.13 -
   12.14 -                if not val:
   12.15 -                    if default==None:
   12.16 -                        raise VmError('pci: Missing %s config setting' % field)
   12.17 -                    else:
   12.18 -                        return default
   12.19 -
   12.20                  if isinstance(val, types.StringTypes):
   12.21                      return int(val, 16)
   12.22                  else:
   12.23                      return val
   12.24 -            except:
   12.25 -                if default==None:
   12.26 -                    raise VmError('pci: Invalid config setting %s: %s' %
   12.27 -                              (field, val))
   12.28 -                else:
   12.29 -                    return default
   12.30 -        
   12.31 +            except ValueError:
   12.32 +                return None
   12.33 +            
   12.34          back = {}
   12.35 -
   12.36 -        val = sxp.child_value(config, 'dev')
   12.37 -        if isinstance(val, (types.ListType, types.TupleType)):
   12.38 -            pcidevid = 0
   12.39 -            for dev_config in sxp.children(config, 'dev'):
   12.40 -                domain = get_param(dev_config, 'domain', 0)
   12.41 -                bus = get_param(dev_config,'bus')
   12.42 -                slot = get_param(dev_config,'slot')
   12.43 -                func = get_param(dev_config,'func')
   12.44 +        pcidevid = 0
   12.45 +        for pci_config in config.get('devs', []):
   12.46 +            domain = parse_hex(pci_config.get('domain', 0))
   12.47 +            bus = parse_hex(pci_config.get('bus', 0))
   12.48 +            slot = parse_hex(pci_config.get('slot', 0))
   12.49 +            func = parse_hex(pci_config.get('func', 0))            
   12.50 +            self.setupDevice(domain, bus, slot, func)
   12.51 +            back['dev-%i' % pcidevid] = "%04x:%02x:%02x.%02x" % \
   12.52 +                                        (domain, bus, slot, func)
   12.53 +            pcidevid += 1
   12.54  
   12.55 -                self.setupDevice(domain, bus, slot, func)
   12.56 -
   12.57 -                back['dev-%i' % pcidevid]="%04x:%02x:%02x.%02x"% \
   12.58 -                        (domain, bus, slot, func)
   12.59 -                pcidevid+=1
   12.60 -            
   12.61 -            back['num_devs']=str(pcidevid)
   12.62 -
   12.63 -        else:
   12.64 -            # Xen 2.0 configuration compatibility
   12.65 -            domain = get_param(config, 'domain', 0)
   12.66 -            bus  = get_param(config, 'bus')
   12.67 -            slot = get_param(config, 'dev')
   12.68 -            func = get_param(config, 'func')
   12.69 -
   12.70 -            self.setupDevice(domain, bus, slot, func)
   12.71 -
   12.72 -            back['dev-0']="%04x:%02x:%02x.%02x"%(domain, bus, slot, func)
   12.73 -            back['num_devs']=str(1)
   12.74 -
   12.75 +        back['num_devs']=str(pcidevid)
   12.76 +        back['uuid'] = config.get('uuid','')
   12.77          return (0, back, {})
   12.78  
   12.79      def getDeviceConfiguration(self, devid):
   12.80 @@ -129,7 +98,8 @@ class PciController(DevController):
   12.81                                   'slot': '0x%(slot)s' % pci_dev_info,
   12.82                                   'func': '0x%(func)s' % pci_dev_info})
   12.83  
   12.84 -        result['dev'] = pci_devs
   12.85 +        result['devs'] = pci_devs
   12.86 +        result['uuid'] = self.readBackend(devid, 'uuid')
   12.87          return result
   12.88  
   12.89      def configuration(self, devid):
   12.90 @@ -142,7 +112,8 @@ class PciController(DevController):
   12.91          sxpr = [self.deviceClass]
   12.92  
   12.93          # remove devs
   12.94 -        devs = configDict.pop('dev', [])
   12.95 +        devs = configDict.pop('devs', [])
   12.96 +        
   12.97          for dev in devs:
   12.98              dev_sxpr = ['dev']
   12.99              for dev_item in dev.items():
    13.1 --- a/tools/python/xen/xend/server/pciquirk.py	Thu Nov 30 14:05:27 2006 +0000
    13.2 +++ b/tools/python/xen/xend/server/pciquirk.py	Thu Nov 30 14:44:58 2006 +0000
    13.3 @@ -15,25 +15,24 @@ class PCIQuirk:
    13.4          self.device = device
    13.5          self.subvendor = subvendor
    13.6          self.subdevice = subdevice
    13.7 -	self.domain = domain
    13.8 -	self.bus = bus
    13.9 -	self.slot = slot
   13.10 -	self.func = func
   13.11 +        self.domain = domain
   13.12 +        self.bus = bus
   13.13 +        self.slot = slot
   13.14 +        self.func = func
   13.15  
   13.16          self.devid = "%04x:%04x:%04x:%04x" % (vendor, device, subvendor, subdevice)
   13.17 -	self.pciid = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
   13.18 +        self.pciid = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
   13.19 +        self.quirks = self.__getQuirksByID()
   13.20  
   13.21 -        self.quirks = self.__getQuirksByID( )
   13.22 -
   13.23 -	self.__sendQuirks( )
   13.24 -	self.__sendPermDevs( )
   13.25 +        self.__sendQuirks()
   13.26 +        self.__sendPermDevs()
   13.27  
   13.28      def __matchPCIdev( self, list ):
   13.29          ret = False
   13.30          if list == None:
   13.31              return False
   13.32          for id in list:
   13.33 -            if id.startswith( self.devid[:9] ): # id's vendor and device ID match
   13.34 +            if id.startswith(self.devid[:9]): # id's vendor and device ID match
   13.35                  skey = id.split(':')
   13.36                  size = len(skey)
   13.37                  if (size == 2):		# subvendor/subdevice not suplied
   13.38 @@ -41,13 +40,13 @@ class PCIQuirk:
   13.39                      break
   13.40                  elif (size == 4):	# check subvendor/subdevice
   13.41                      # check subvendor
   13.42 -		    subven = '%04x' % self.subvendor
   13.43 +                    subven = '%04x' % self.subvendor
   13.44                      if ((skey[2] != 'FFFF') and 
   13.45                          (skey[2] != 'ffff') and 
   13.46                          (skey[2] != subven)):
   13.47                              continue
   13.48                      # check subdevice
   13.49 -		    subdev = '%04x' % self.subdevice
   13.50 +                    subdev = '%04x' % self.subdevice
   13.51                      if ((skey[3] != 'FFFF') and 
   13.52                          (skey[3] != 'ffff') and 
   13.53                          (skey[3] != subdev)):
   13.54 @@ -101,8 +100,8 @@ class PCIQuirk:
   13.55  			self.slot, self.func, quirk) )
   13.56                  f.close()
   13.57              except Exception, e:
   13.58 -                raise VmError("pci: failed to open/write/close quirks sysfs " + \
   13.59 -			"node - " + str(e))
   13.60 +                raise VmError("pci: failed to open/write/close quirks " +
   13.61 +                              "sysfs node - " + str(e))
   13.62  
   13.63      def __devIsUnconstrained( self ):
   13.64          if os.path.exists(PERMISSIVE_CONFIG_FILE):
   13.65 @@ -126,20 +125,22 @@ class PCIQuirk:
   13.66  
   13.67          devices = child_at(child(pci_perm_dev_config, 'unconstrained_dev_ids'),0)
   13.68  	if self.__matchPCIdev( devices ):
   13.69 -            log.debug("Permissive mode enabled for PCI device [%s]" % self.devid)
   13.70 +            log.debug("Permissive mode enabled for PCI device [%s]" %
   13.71 +                      self.devid)
   13.72              return True
   13.73 -        log.debug("Permissive mode NOT enabled for PCI device [%s]" % self.devid)
   13.74 +        log.debug("Permissive mode NOT enabled for PCI device [%s]" %
   13.75 +                  self.devid)
   13.76          return False
   13.77  
   13.78      def __sendPermDevs(self):
   13.79  	if self.__devIsUnconstrained( ):
   13.80 -            log.debug("Unconstrained device: %04x:%02x:%02x.%1x" % (self.domain,
   13.81 -		    self.bus, self.slot, self.func))
   13.82 +            log.debug("Unconstrained device: %04x:%02x:%02x.%1x" %
   13.83 +                      (self.domain, self.bus, self.slot, self.func))
   13.84              try:
   13.85                  f = file(PERMISSIVE_SYSFS_NODE ,"w")
   13.86                  f.write( "%04x:%02x:%02x.%1x" % (self.domain, self.bus,
   13.87 -			self.slot, self.func) )
   13.88 +                                                 self.slot, self.func))
   13.89                  f.close()
   13.90              except Exception, e:
   13.91 -                raise VmError("pci: failed to open/write/close permissive " + \
   13.92 -		"sysfs node: " + str(e))
   13.93 +                raise VmError("pci: failed to open/write/close permissive " +
   13.94 +                              "sysfs node: " + str(e))
    14.1 --- a/tools/python/xen/xend/server/tests/test_controllers.py	Thu Nov 30 14:05:27 2006 +0000
    14.2 +++ b/tools/python/xen/xend/server/tests/test_controllers.py	Thu Nov 30 14:44:58 2006 +0000
    14.3 @@ -21,13 +21,13 @@ class test_controllers(unittest.TestCase
    14.4      def testNetif(self):
    14.5          controller = self.controllerInstance(netif.NetifController)
    14.6  
    14.7 -        self.assertNetif(controller.getDeviceDetails(['vif']), None)
    14.8 +        self.assertNetif(controller.getDeviceDetails({}), None)
    14.9          self.assertNetif(
   14.10 -            controller.getDeviceDetails(
   14.11 -            ['vif', ['mac', 'aa:bb:cc:dd:ee:ff']]),
   14.12 +            controller.getDeviceDetails({'mac': 'aa:bb:cc:dd:ee:ff'}),
   14.13              'aa:bb:cc:dd:ee:ff')
   14.14  
   14.15  
   14.16 +
   14.17      def assertNetif(self, results, expectedMac):
   14.18  
   14.19          (devid, backdets, frontdets) = results
    15.1 --- a/tools/python/xen/xend/server/tpmif.py	Thu Nov 30 14:05:27 2006 +0000
    15.2 +++ b/tools/python/xen/xend/server/tpmif.py	Thu Nov 30 14:44:58 2006 +0000
    15.3 @@ -18,10 +18,8 @@
    15.4  # Copyright (C) 2005 XenSource Ltd
    15.5  #============================================================================
    15.6  
    15.7 -"""Support for virtual TPM interfaces.
    15.8 -"""
    15.9 +"""Support for virtual TPM interfaces."""
   15.10  
   15.11 -from xen.xend import sxp
   15.12  from xen.xend import XendRoot
   15.13  from xen.xend.XendLogging import log
   15.14  from xen.xend.XendError import XendError
   15.15 @@ -49,12 +47,12 @@ class TPMifController(DevController):
   15.16          """@see DevController.getDeviceDetails"""
   15.17  
   15.18          devid = self.allocateDeviceID()
   15.19 -        inst = int(sxp.child_value(config, 'pref_instance', '-1'))
   15.20 +        inst = int(config.get('pref_instance', -1))
   15.21          if inst == -1:
   15.22 -            inst = int(sxp.child_value(config, 'instance' , '0'))
   15.23 +            inst = int(config.get('instance', 0))
   15.24  
   15.25 -        typ    = sxp.child_value(config, 'type')
   15.26 -        uuid   = sxp.child_value(config, 'uuid')
   15.27 +        typ    = config.get('type')
   15.28 +        uuid   = config.get('uuid')
   15.29  
   15.30          log.info("The domain has a TPM with pref. instance %d and devid %d.",
   15.31                   inst, devid)
    16.1 --- a/tools/python/xen/xm/main.py	Thu Nov 30 14:05:27 2006 +0000
    16.2 +++ b/tools/python/xen/xm/main.py	Thu Nov 30 14:44:58 2006 +0000
    16.3 @@ -581,8 +581,8 @@ def parse_doms_info(info):
    16.4      return {
    16.5          'domid'    : get_info('domid',        str,   ''),
    16.6          'name'     : get_info('name',         str,   '??'),
    16.7 -        'mem'      : get_info('memory_dynamic_max', int,   0),
    16.8 -        'vcpus'    : get_info('online_vcpus', int,   0),
    16.9 +        'mem'      : get_info('memory_dynamic_min', int,   0),
   16.10 +        'vcpus'    : get_info('vcpus',        int,   0),
   16.11          'state'    : get_info('state',        str,    ''),
   16.12          'cpu_time' : get_info('cpu_time',     float, 0),
   16.13          'up_time'  : get_info('up_time',      float, -1),