direct-io.hg

changeset 12168:faaa8256558b

These are the proposed changes to XenD that adapt vTPM handling to the
document and the implementation in the library. It's implementation is
now similar to VIF and VBD. The implementation passes the first 2 tests
in the vTPM- related tests in the xm-test suite.

Minor conflict resolution by Ewan Mellor.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
author Ewan Mellor <ewan@xensource.com>
date Sat Oct 28 17:12:04 2006 +0100 (2006-10-28)
parents 5bef3f695b55
children 3cccc8697a13
files tools/python/xen/xend/XendAPI.py tools/python/xen/xend/XendConfig.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/XendError.py tools/python/xen/xend/server/tpmif.py tools/python/xen/xm/create.py
line diff
     1.1 --- a/tools/python/xen/xend/XendAPI.py	Sat Oct 28 13:30:21 2006 +0100
     1.2 +++ b/tools/python/xen/xend/XendAPI.py	Sat Oct 28 17:12:04 2006 +0100
     1.3 @@ -181,6 +181,28 @@ def valid_vdi(func):
     1.4          
     1.5      return check_vdi_ref
     1.6  
     1.7 +def valid_vtpm(func):
     1.8 +    """Decorator to verify if vtpm_ref is valid before calling
     1.9 +    method.
    1.10 +
    1.11 +    @param func: function with params: (self, session, vtpm_ref)
    1.12 +    @rtype: callable object
    1.13 +    """
    1.14 +    def check_vtpm_ref(self, session, vtpm_ref, *args, **kwargs):
    1.15 +        xendom = XendDomain.instance()
    1.16 +        if type(vtpm_ref) == type(str()) and \
    1.17 +               xendom.is_valid_dev('vtpm', vtpm_ref):
    1.18 +            return func(self, session, vtpm_ref, *args, **kwargs)
    1.19 +        else:
    1.20 +            return {'Status': 'Failure',
    1.21 +                    'ErrorDescription': XEND_ERROR_VTPM_INVALID}
    1.22 +
    1.23 +    # make sure we keep the 'api' attribute
    1.24 +    if hasattr(func, 'api'):
    1.25 +        check_vtpm_ref.api = func.api
    1.26 +
    1.27 +    return check_vtpm_ref
    1.28 +
    1.29  def valid_sr(func):
    1.30      """Decorator to verify if sr_ref is valid before calling
    1.31      method.
    1.32 @@ -246,6 +268,7 @@ class XendAPI:
    1.33              'VBD': (valid_vbd, session_required),
    1.34              'VIF': (valid_vif, session_required),
    1.35              'VDI': (valid_vdi, session_required),
    1.36 +            'VTPM':(valid_vtpm, session_required),
    1.37              'SR':  (valid_sr, session_required)}
    1.38          
    1.39          # Cheat methods
    1.40 @@ -580,8 +603,6 @@ class XendAPI:
    1.41          'actions_after_reboot',
    1.42          'actions_after_suspend',
    1.43          'actions_after_crash',
    1.44 -        'TPM_instance',
    1.45 -        'TPM_backend',
    1.46          'bios_boot',
    1.47          'platform_std_VGA',
    1.48          'platform_serial',
    1.49 @@ -645,14 +666,6 @@ class XendAPI:
    1.50          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.51          return xen_api_success(dom.get_vtpms())
    1.52      
    1.53 -    def vm_get_tpm_instance(self, session, vm_ref):
    1.54 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.55 -        return xen_api_todo() # unsupported by xc
    1.56 -    
    1.57 -    def vm_get_tpm_backend(self, session, vm_ref):
    1.58 -        dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.59 -        return xen_api_todo() # unsupported by xc
    1.60 -    
    1.61      def vm_get_pci_bus(self, session, vm_ref):
    1.62          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    1.63          return xen_api_todo() # unsupported by xc
    1.64 @@ -1262,6 +1275,49 @@ class XendAPI:
    1.65          return xen_api_error(XEND_ERROR_VDI_INVALID)
    1.66  
    1.67  
    1.68 +    # Xen API: Class VTPM
    1.69 +    # ----------------------------------------------------------------
    1.70 +
    1.71 +    VTPM_attr_ro = [ ]
    1.72 +    VTPM_attr_rw = ['type',
    1.73 +                    'VM',
    1.74 +                    'backend',
    1.75 +                    'instance']
    1.76 +
    1.77 +    VTPM_attr_inst = VTPM_attr_rw
    1.78 +
    1.79 +    # object methods
    1.80 +    def vtpm_get_record(self, session, vtpm_ref):
    1.81 +        xendom = XendDomain.instance()
    1.82 +        vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
    1.83 +        if not vm:
    1.84 +            return xen_api_error(XEND_ERROR_VTPM_INVALID)
    1.85 +        cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref)
    1.86 +        if not cfg:
    1.87 +            return xen_api_error(XEND_ERROR_VTPM_INVALID)
    1.88 +        valid_vtpm_keys = self.VTPM_attr_ro + self.VTPM_attr_rw + \
    1.89 +                          self.Base_attr_ro + self.Base_attr_rw
    1.90 +        for k in cfg.keys():
    1.91 +            if k not in valid_vtpm_keys:
    1.92 +                del cfg[k]
    1.93 +
    1.94 +        return xen_api_success(cfg)
    1.95 +
    1.96 +    # class methods
    1.97 +    def vtpm_create(self, session, vtpm_struct):
    1.98 +        xendom = XendDomain.instance()
    1.99 +        if xendom.is_valid_vm(vtpm_struct['VM']):
   1.100 +            dom = xendom.get_vm_by_uuid(vtpm_struct['VM'])
   1.101 +            try:
   1.102 +                vtpm_ref = dom.create_vtpm(vtpm_struct)
   1.103 +                xendom.managed_config_save(dom)
   1.104 +                return xen_api_success(vtpm_ref)
   1.105 +            except XendError:
   1.106 +                return xen_api_error(XEND_ERROR_TODO)
   1.107 +        else:
   1.108 +            return xen_api_error(XEND_ERROR_DOMAIN_INVALID)
   1.109 +
   1.110 +
   1.111      # Xen API: Class SR
   1.112      # ----------------------------------------------------------------
   1.113      SR_attr_ro = ['VDIs',
     2.1 --- a/tools/python/xen/xend/XendConfig.py	Sat Oct 28 13:30:21 2006 +0100
     2.2 +++ b/tools/python/xen/xend/XendConfig.py	Sat Oct 28 17:12:04 2006 +0100
     2.3 @@ -110,8 +110,6 @@ XENAPI_UNSUPPORTED_IN_LEGACY_CFG = [
     2.4      'vcpus_features_force_on',
     2.5      'vcpus_features_force_off',
     2.6      'actions_after_suspend',
     2.7 -    'tpm_instance',
     2.8 -    'tpm_backends',
     2.9      'bios_boot',
    2.10      'platform_std_vga',
    2.11      'platform_serial',
    2.12 @@ -570,11 +568,14 @@ class XendConfig(dict):
    2.13          # ------------------
    2.14          cfg['vif_refs'] = []
    2.15          cfg['vbd_refs'] = []
    2.16 +        cfg['vtpm_refs'] = []
    2.17          for dev_uuid, (dev_type, dev_info) in cfg['device'].items():
    2.18              if dev_type == 'vif':
    2.19                  cfg['vif_refs'].append(dev_uuid)
    2.20              elif dev_type in ('vbd','tap'):
    2.21                  cfg['vbd_refs'].append(dev_uuid)
    2.22 +            elif dev_type == 'vtpm':
    2.23 +                cfg['vtpm_refs'].append(dev_uuid)
    2.24                  
    2.25          return cfg
    2.26  
    2.27 @@ -610,6 +611,8 @@ class XendConfig(dict):
    2.28              cfg['vif_refs'] = []
    2.29          if 'vbd_refs' not in cfg:
    2.30              cfg['vbd_refs'] = []
    2.31 +        if 'vtpm_refs' not in cfg:
    2.32 +            cfg['vtpm_refs'] = []
    2.33  
    2.34          return cfg
    2.35  
    2.36 @@ -747,6 +750,8 @@ class XendConfig(dict):
    2.37              self['vif_refs'] = []
    2.38          if 'vbd_refs' not in self:
    2.39              self['vbd_refs'] = []
    2.40 +        if 'vtpm_refs' not in self:
    2.41 +            self['vtpm_refs'] = []
    2.42  
    2.43      def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None):
    2.44          if dev_type not in XendDevices.valid_devices():
    2.45 @@ -815,7 +820,16 @@ class XendConfig(dict):
    2.46                  self['device'][dev_uuid] = (dev_type, dev_info)
    2.47                  self['vbd_refs'].append(dev_uuid)                
    2.48                  return dev_uuid
    2.49 -            
    2.50 +
    2.51 +            elif dev_type == 'vtpm':
    2.52 +                if cfg_xenapi.get('type'):
    2.53 +                    dev_info['type'] = cfg_xenapi.get('type')
    2.54 +                dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
    2.55 +                dev_info['uuid'] = dev_uuid
    2.56 +                self['device'][dev_uuid] = (dev_type, dev_info)
    2.57 +                self['vtpm_refs'].append(dev_uuid)
    2.58 +                return dev_uuid
    2.59 +
    2.60              elif dev_type == 'tap':
    2.61                  dev_info['uname'] = 'tap:qcow:%s' % cfg_xenapi.get('image')
    2.62                  dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
     3.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Sat Oct 28 13:30:21 2006 +0100
     3.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Sat Oct 28 17:12:04 2006 +0100
     3.3 @@ -1897,6 +1897,24 @@ class XendDomainInfo:
     3.4  
     3.5          return dev_uuid
     3.6  
     3.7 +    def create_vtpm(self, xenapi_vtpm):
     3.8 +        """Create a VTPM device from the passed struct in Xen API format.
     3.9 +
    3.10 +        @return: uuid of the device
    3.11 +        @rtype: string
    3.12 +        """
    3.13 +
    3.14 +        dev_uuid = self.info.device_add('vtpm', cfg_xenapi = xenapi_vtpm)
    3.15 +        if not dev_uuid:
    3.16 +            raise XendError('Failed to create device')
    3.17 +
    3.18 +        if self.state in (DOM_STATE_HALTED,):
    3.19 +            sxpr = self.info.device_sxpr(dev_uuid)
    3.20 +            devid = self.getDeviceController('vtpm').createDevice(sxpr)
    3.21 +            raise XendError("Device creation failed")
    3.22 +
    3.23 +        return dev_uuid
    3.24 +
    3.25      def has_device(self, dev_class, dev_uuid):
    3.26          return (dev_uuid in self.info['%s_refs' % dev_class])
    3.27  
     4.1 --- a/tools/python/xen/xend/XendError.py	Sat Oct 28 13:30:21 2006 +0100
     4.2 +++ b/tools/python/xen/xend/XendError.py	Sat Oct 28 17:12:04 2006 +0100
     4.3 @@ -47,6 +47,7 @@ XEND_ERROR_UNSUPPORTED           = ('EUN
     4.4  XEND_ERROR_VM_INVALID            = ('EVMINVALID', 'VM Invalid')
     4.5  XEND_ERROR_VBD_INVALID           = ('EVBDINVALID', 'VBD Invalid')
     4.6  XEND_ERROR_VIF_INVALID           = ('EVIFINVALID', 'VIF Invalid')
     4.7 +XEND_ERROR_VTPM_INVALID          = ('EVTPMINVALID', 'VTPM Invalid')
     4.8  XEND_ERROR_VDI_INVALID           = ('EVDIINVALID', 'VDI Invalid')
     4.9  XEND_ERROR_SR_INVALID           = ('ESRINVALID', 'SR Invalid')
    4.10  XEND_ERROR_TODO                  = ('ETODO', 'Lazy Programmer Error')
     5.1 --- a/tools/python/xen/xend/server/tpmif.py	Sat Oct 28 13:30:21 2006 +0100
     5.2 +++ b/tools/python/xen/xend/server/tpmif.py	Sat Oct 28 17:12:04 2006 +0100
     5.3 @@ -49,22 +49,37 @@ class TPMifController(DevController):
     5.4          if inst == -1:
     5.5              inst = int(sxp.child_value(config, 'instance' , '0'))
     5.6  
     5.7 +        typ    = sxp.child_value(config, 'type')
     5.8 +        uuid   = sxp.child_value(config, 'uuid')
     5.9 +
    5.10          log.info("The domain has a TPM with pref. instance %d and devid %d.",
    5.11                   inst, devid)
    5.12          back  = { 'pref_instance' : "%i" % inst,
    5.13                    'resume'        : "%s" % (self.vm.getResume()) }
    5.14 +        if typ:
    5.15 +            back['type'] = typ
    5.16 +        if uuid:
    5.17 +            back['uuid'] = uuid
    5.18 +
    5.19          front = { 'handle' : "%i" % devid }
    5.20  
    5.21          return (devid, back, front)
    5.22  
    5.23 -    def configuration(self, devid):
    5.24 +    def getDeviceConfiguration(self, devid):
    5.25 +        """Returns the configuration of a device"""
    5.26 +        result = DevController.getDeviceConfiguration(self, devid)
    5.27  
    5.28 -        result = DevController.configuration(self, devid)
    5.29 -
    5.30 -        instance = self.readBackend(devid, 'instance')
    5.31 +        (instance, uuid, type) = \
    5.32 +                           self.readBackend(devid, 'instance',
    5.33 +                                                   'uuid',
    5.34 +                                                   'type')
    5.35  
    5.36          if instance:
    5.37 -            result.append(['instance', instance])
    5.38 +            result['instance'] = instance
    5.39 +        if uuid:
    5.40 +            result['uuid'] = uuid
    5.41 +        if type:
    5.42 +            result['type'] == type
    5.43  
    5.44          return result
    5.45  
     6.1 --- a/tools/python/xen/xm/create.py	Sat Oct 28 13:30:21 2006 +0100
     6.2 +++ b/tools/python/xen/xm/create.py	Sat Oct 28 17:12:04 2006 +0100
     6.3 @@ -291,7 +291,7 @@ gopts.var('vif', val="type=TYPE,mac=MAC,
     6.4            This option may be repeated to add more than one vif.
     6.5            Specifying vifs will increase the number of interfaces as needed.""")
     6.6  
     6.7 -gopts.var('vtpm', val="instance=INSTANCE,backend=DOM",
     6.8 +gopts.var('vtpm', val="instance=INSTANCE,backend=DOM,type=TYPE",
     6.9            fn=append_value, default=[],
    6.10            use="""Add a TPM interface. On the backend side use the given
    6.11            instance as virtual TPM instance. The given number is merely the
    6.12 @@ -299,7 +299,11 @@ gopts.var('vtpm', val="instance=INSTANCE
    6.13            which instance number will actually be assigned to the domain.
    6.14            The associtation between virtual machine and the TPM instance
    6.15            number can be found in /etc/xen/vtpm.db. Use the backend in the
    6.16 -          given domain.""")
    6.17 +          given domain.
    6.18 +          The type parameter can be used to select a specific driver type
    6.19 +          that the VM can use. To prevent a fully virtualized domain (HVM)
    6.20 +          from being able to access an emulated device model, you may specify
    6.21 +          'paravirtualized' here.""")
    6.22  
    6.23  gopts.var('access_control', val="policy=POLICY,label=LABEL",
    6.24            fn=append_value, default=[],
    6.25 @@ -585,27 +589,28 @@ def configure_vtpm(config_devs, vals):
    6.26      """Create the config for virtual TPM interfaces.
    6.27      """
    6.28      vtpm = vals.vtpm
    6.29 -    vtpm_n = 1
    6.30 -    for idx in range(0, vtpm_n):
    6.31 -        if idx < len(vtpm):
    6.32 -            d = vtpm[idx]
    6.33 -            instance = d.get('instance')
    6.34 -            if instance == "VTPMD":
    6.35 -                instance = "0"
    6.36 -            else:
    6.37 -                if instance != None:
    6.38 -                    try:
    6.39 -                        if int(instance) == 0:
    6.40 -                            err('VM config error: vTPM instance must not be 0.')
    6.41 -                    except ValueError:
    6.42 -                        err('Vm config error: could not parse instance number.')
    6.43 -            backend = d.get('backend')
    6.44 -            config_vtpm = ['vtpm']
    6.45 -            if instance:
    6.46 -                config_vtpm.append(['pref_instance', instance])
    6.47 -            if backend:
    6.48 -                config_vtpm.append(['backend', backend])
    6.49 -            config_devs.append(['device', config_vtpm])
    6.50 +    if len(vtpm) > 0:
    6.51 +        d = vtpm[0]
    6.52 +        instance = d.get('instance')
    6.53 +        if instance == "VTPMD":
    6.54 +            instance = "0"
    6.55 +        else:
    6.56 +            if instance != None:
    6.57 +                try:
    6.58 +                    if int(instance) == 0:
    6.59 +                        err('VM config error: vTPM instance must not be 0.')
    6.60 +                except ValueError:
    6.61 +                    err('Vm config error: could not parse instance number.')
    6.62 +        backend = d.get('backend')
    6.63 +        typ = d.get('type')
    6.64 +        config_vtpm = ['vtpm']
    6.65 +        if instance:
    6.66 +            config_vtpm.append(['pref_instance', instance])
    6.67 +        if backend:
    6.68 +            config_vtpm.append(['backend', backend])
    6.69 +        if typ:
    6.70 +            config_vtpm.append(['type', type])
    6.71 +        config_devs.append(['device', config_vtpm])
    6.72  
    6.73  
    6.74  def configure_vifs(config_devs, vals):