Index: root/xen-api.hg/tools/python/xen/xend/XendAPI.py =================================================================== --- root.orig/xen-api.hg/tools/python/xen/xend/XendAPI.py +++ root/xen-api.hg/tools/python/xen/xend/XendAPI.py @@ -171,6 +171,28 @@ def valid_vif(func): return check_vif_ref +def valid_vtpm(func): + """Decorator to verify if vtpm_ref is valid before calling + method. + + @param func: function with params: (self, session, vtpm_ref) + @rtype: callable object + """ + def check_vtpm_ref(self, session, vtpm_ref, *args, **kwargs): + xendom = XendDomain.instance() + if type(vtpm_ref) == type(str()) and \ + xendom.is_valid_dev('vtpm', vtpm_ref): + return func(self, session, vtpm_ref, *args, **kwargs) + else: + return {'Status': 'Failure', + 'ErrorDescription': XEND_ERROR_VTPM_INVALID} + + # make sure we keep the 'api' attribute + if hasattr(func, 'api'): + check_vtpm_ref.api = func.api + + return check_vtpm_ref + def do_vm_func(fn_name, vm_ref, *args): """Helper wrapper func to abstract away from repeative code. @@ -212,7 +234,8 @@ class XendAPI: 'Host_CPU': (valid_host_cpu, session_required), 'VM': (valid_vm, session_required), 'VBD': (valid_vbd, session_required), - 'VIF': (valid_vif, session_required)} + 'VIF': (valid_vif, session_required), + 'VTPM' : (valid_vtpm, session_required)} # Cheat methods # ------------- @@ -480,8 +503,6 @@ class XendAPI: 'VCPUs_can_use', 'VIFs', 'VBDs', - 'TPM_instance', - 'TPM_backend', 'PCI_bus', 'tools_version', ] @@ -547,8 +568,6 @@ class XendAPI: 'actions_after_reboot', 'actions_after_suspend', 'actions_after_crash', - 'TPM_instance', - 'TPM_backend', 'bios_boot', 'platform_std_VGA', 'platform_serial', @@ -608,14 +627,6 @@ class XendAPI: dom = XendDomain.instance().get_vm_by_uuid(vm_ref) return xen_api_success(dom.get_vbds()) - def vm_get_tpm_instance(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_todo() # unsupported by xc - - def vm_get_tpm_backend(self, session, vm_ref): - dom = XendDomain.instance().get_vm_by_uuid(vm_ref) - return xen_api_todo() # unsupported by xc - def vm_get_pci_bus(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) return xen_api_todo() # unsupported by xc @@ -893,8 +904,6 @@ class XendAPI: 'actions_after_crash': xeninfo.get_on_crash(), 'vifs': xeninfo.get_vifs(), 'vbds': xeninfo.get_vbds(), - 'tpm_instance': xeninfo.get_tpm_instance(), - 'tpm_backend': xeninfo.get_tpm_backend(), 'bios_boot': xeninfo.get_bios_boot(), 'platform_std_vga': xeninfo.get_platform_std_vga(), 'platform_serial': xeninfo.get_platform_serial(), @@ -1053,6 +1062,49 @@ class XendAPI: return xen_api_error(XEND_ERROR_DOMAIN_INVALID) + # Xen API: Class VTPM + # ---------------------------------------------------------------- + + VTPM_attr_ro = [ ] + VTPM_attr_rw = ['type', + 'VM', + 'backend', + 'instance'] + + VTPM_attr_inst = VTPM_attr_rw + + # object methods + def vtpm_get_record(self, session, vtpm_ref): + xendom = XendDomain.instance() + vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref) + if not vm: + return xen_api_error(XEND_ERROR_VTPM_INVALID) + cfg = vm.get_dev_xenapi_config('vtpm', vtpm_ref) + if not cfg: + return xen_api_error(XEND_ERROR_VTPM_INVALID) + valid_vtpm_keys = self.VTPM_attr_ro + self.VTPM_attr_rw + \ + self.Base_attr_ro + self.Base_attr_rw + for k in cfg.keys(): + if k not in valid_vtpm_keys: + del cfg[k] + + return xen_api_success(cfg) + + # class methods + def vtpm_create(self, session, vtpm_struct): + xendom = XendDomain.instance() + if xendom.is_valid_vm(vtpm_struct['VM']): + dom = xendom.get_vm_by_uuid(vtpm_struct['VM']) + try: + vtpm_ref = dom.create_vtpm(vtpm_struct) + xendom.managed_config_save(dom) + return xen_api_success(vtpm_ref) + except XendError: + return xen_api_error(XEND_ERROR_TODO) + else: + return xen_api_error(XEND_ERROR_DOMAIN_INVALID) + + # Xen API: Class SR # ---------------------------------------------------------------- # NOT IMPLEMENTED Index: root/xen-api.hg/tools/python/xen/xend/XendError.py =================================================================== --- root.orig/xen-api.hg/tools/python/xen/xend/XendError.py +++ root/xen-api.hg/tools/python/xen/xend/XendError.py @@ -47,4 +47,5 @@ XEND_ERROR_UNSUPPORTED = ('EUN XEND_ERROR_VM_INVALID = ('EVMINVALID', 'VM Invalid') XEND_ERROR_VBD_INVALID = ('EVBDINVALID', 'VBD Invalid') XEND_ERROR_VIF_INVALID = ('EVIFINVALID', 'VIF Invalid') +XEND_ERROR_VTPM_INVALID = ('EVTPMINVALID', 'VTPM Invalid') XEND_ERROR_TODO = ('ETODO', 'Lazy Programmer Error') Index: root/xen-api.hg/tools/python/xen/xend/server/tpmif.py =================================================================== --- root.orig/xen-api.hg/tools/python/xen/xend/server/tpmif.py +++ root/xen-api.hg/tools/python/xen/xend/server/tpmif.py @@ -49,22 +49,37 @@ class TPMifController(DevController): if inst == -1: inst = int(sxp.child_value(config, 'instance' , '0')) + typ = sxp.child_value(config, 'type') + uuid = sxp.child_value(config, 'uuid') + log.info("The domain has a TPM with pref. instance %d and devid %d.", inst, devid) back = { 'pref_instance' : "%i" % inst, 'resume' : "%s" % (self.vm.getResume()) } + if typ: + back['type'] = typ + if uuid: + back['uuid'] = uuid + front = { 'handle' : "%i" % devid } return (devid, back, front) - def configuration(self, devid): - - result = DevController.configuration(self, devid) - - instance = self.readBackend(devid, 'instance') + def getDeviceConfiguration(self, devid): + """Returns the configuration of a device""" + result = DevController.getDeviceConfiguration(self, devid) + + (instance, uuid, type) = \ + self.readBackend(devid, 'instance', + 'uuid', + 'type') if instance: - result.append(['instance', instance]) + result['instance'] = instance + if uuid: + result['uuid'] = uuid + if type: + result['type'] == type return result Index: root/xen-api.hg/tools/python/xen/xend/XendConfig.py =================================================================== --- root.orig/xen-api.hg/tools/python/xen/xend/XendConfig.py +++ root/xen-api.hg/tools/python/xen/xend/XendConfig.py @@ -103,8 +103,6 @@ XENAPI_UNSUPPORTED_IN_LEGACY_CFG = [ 'vcpus_features_force_on', 'vcpus_features_force_off', 'actions_after_suspend', - 'tpm_instance', - 'tpm_backends', 'bios_boot', 'platform_std_vga', 'platform_serial', @@ -549,11 +547,14 @@ class XendConfig(dict): # ------------------ cfg['vif_refs'] = [] cfg['vbd_refs'] = [] + cfg['vtpm_refs'] = [] for dev_uuid, (dev_type, dev_info) in cfg['device'].items(): if dev_type == 'vif': cfg['vif_refs'].append(dev_uuid) elif dev_type == 'vbd': cfg['vbd_refs'].append(dev_uuid) + elif dev_type == 'vtpm': + cfg['vtpm_refs'].append(dev_uuid) return cfg @@ -585,6 +586,8 @@ class XendConfig(dict): cfg['vif_refs'] = [] if 'vbd_refs' not in cfg: cfg['vbd_refs'] = [] + if 'vtpm_refs' not in cfg: + cfg['vtpm_refs'] = [] return cfg @@ -722,6 +725,8 @@ class XendConfig(dict): self['vif_refs'] = [] if 'vbd_refs' not in self: self['vbd_refs'] = [] + if 'vtpm_refs' not in self: + self['vtpm_refs'] = [] def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None): if dev_type not in XendDevices.valid_devices(): @@ -788,7 +793,14 @@ class XendConfig(dict): self['device'][dev_uuid] = (dev_type, dev_info) self['vbd_refs'].append(dev_uuid) return dev_uuid - + + elif dev_type == 'vtpm': + if cfg_xenapi.get('type'): + dev_info['type'] = cfg_xenapi.get('type') + dev_uuid = cfg_xenapi.get('uuid', uuid.createString()) + dev_info['uuid'] = dev_uuid + self['device'][dev_uuid] = (dev_type, dev_info) + self['vtpm_refs'].append(dev_uuid) return '' Index: root/xen-api.hg/tools/python/xen/xend/XendDomainInfo.py =================================================================== --- root.orig/xen-api.hg/tools/python/xen/xend/XendDomainInfo.py +++ root/xen-api.hg/tools/python/xen/xend/XendDomainInfo.py @@ -1808,6 +1808,9 @@ class XendDomainInfo: def get_vbds(self): return self.info.get('vbd_refs', []) + def get_vtpms(self): + return self.info.get('vtpm_refs', []) + def create_vbd(self, xenapi_vbd): """Create a VBD device from the passed struct in Xen API format. @@ -1839,6 +1842,24 @@ class XendDomainInfo: return dev_uuid + def create_vtpm(self, xenapi_vtpm): + """Create a VTPM device from the passed struct in Xen API format. + + @return: uuid of the device + @rtype: string + """ + + dev_uuid = self.info.device_add('vtpm', cfg_xenapi = xenapi_vtpm) + if not dev_uuid: + raise XendError('Failed to create device') + + if self.state in (DOM_STATE_HALTED,): + sxpr = self.info.device_sxpr(dev_uuid) + devid = self.getDeviceController('vtpm').createDevice(sxpr) + raise XendError("Device creation failed") + + return dev_uuid + def has_device(self, dev_class, dev_uuid): return (dev_uuid in self.info['%s_refs' % dev_class]) Index: root/xen-api.hg/tools/python/xen/xm/create.py =================================================================== --- root.orig/xen-api.hg/tools/python/xen/xm/create.py +++ root/xen-api.hg/tools/python/xen/xm/create.py @@ -291,7 +291,7 @@ gopts.var('vif', val="type=TYPE,mac=MAC, This option may be repeated to add more than one vif. Specifying vifs will increase the number of interfaces as needed.""") -gopts.var('vtpm', val="instance=INSTANCE,backend=DOM", +gopts.var('vtpm', val="instance=INSTANCE,backend=DOM,type=TYPE", fn=append_value, default=[], use="""Add a TPM interface. On the backend side use the given instance as virtual TPM instance. The given number is merely the @@ -299,7 +299,11 @@ gopts.var('vtpm', val="instance=INSTANCE which instance number will actually be assigned to the domain. The associtation between virtual machine and the TPM instance number can be found in /etc/xen/vtpm.db. Use the backend in the - given domain.""") + given domain. + The type parameter can be used to select a specific driver type + that the VM can use. To prevent a fully virtualized domain (HVM) + from being able to access an emulated device model, you may specify + 'paravirtualized' here.""") gopts.var('access_control', val="policy=POLICY,label=LABEL", fn=append_value, default=[], @@ -585,27 +589,28 @@ def configure_vtpm(config_devs, vals): """Create the config for virtual TPM interfaces. """ vtpm = vals.vtpm - vtpm_n = 1 - for idx in range(0, vtpm_n): - if idx < len(vtpm): - d = vtpm[idx] - instance = d.get('instance') - if instance == "VTPMD": - instance = "0" - else: - if instance != None: - try: - if int(instance) == 0: - err('VM config error: vTPM instance must not be 0.') - except ValueError: - err('Vm config error: could not parse instance number.') - backend = d.get('backend') - config_vtpm = ['vtpm'] - if instance: - config_vtpm.append(['pref_instance', instance]) - if backend: - config_vtpm.append(['backend', backend]) - config_devs.append(['device', config_vtpm]) + if len(vtpm) > 0: + d = vtpm[0] + instance = d.get('instance') + if instance == "VTPMD": + instance = "0" + else: + if instance != None: + try: + if int(instance) == 0: + err('VM config error: vTPM instance must not be 0.') + except ValueError: + err('Vm config error: could not parse instance number.') + backend = d.get('backend') + typ = d.get('type') + config_vtpm = ['vtpm'] + if instance: + config_vtpm.append(['pref_instance', instance]) + if backend: + config_vtpm.append(['backend', backend]) + if typ: + config_vtpm.append(['type', type]) + config_devs.append(['device', config_vtpm]) def configure_vifs(config_devs, vals):