# HG changeset patch
# User Ewan Mellor <ewan@xxxxxxxxxxxxx>
# Node ID faaa8256558bd6a884264e57c64fa93387797797
# Parent 5bef3f695b552e15a121d717611241d41d179bfa
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@xxxxxxxxxx>
---
tools/python/xen/xend/XendAPI.py | 76 +++++++++++++++++++++++++++-----
tools/python/xen/xend/XendConfig.py | 20 +++++++-
tools/python/xen/xend/XendDomainInfo.py | 18 +++++++
tools/python/xen/xend/XendError.py | 1
tools/python/xen/xend/server/tpmif.py | 25 ++++++++--
tools/python/xen/xm/create.py | 51 +++++++++++----------
6 files changed, 150 insertions(+), 41 deletions(-)
diff -r 5bef3f695b55 -r faaa8256558b tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py Sat Oct 28 13:30:21 2006 +0100
+++ b/tools/python/xen/xend/XendAPI.py Sat Oct 28 17:12:04 2006 +0100
@@ -181,6 +181,28 @@ def valid_vdi(func):
return check_vdi_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 valid_sr(func):
"""Decorator to verify if sr_ref is valid before calling
method.
@@ -246,6 +268,7 @@ class XendAPI:
'VBD': (valid_vbd, session_required),
'VIF': (valid_vif, session_required),
'VDI': (valid_vdi, session_required),
+ 'VTPM':(valid_vtpm, session_required),
'SR': (valid_sr, session_required)}
# Cheat methods
@@ -580,8 +603,6 @@ class XendAPI:
'actions_after_reboot',
'actions_after_suspend',
'actions_after_crash',
- 'TPM_instance',
- 'TPM_backend',
'bios_boot',
'platform_std_VGA',
'platform_serial',
@@ -644,14 +665,6 @@ class XendAPI:
def vm_get_vtpms(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_vtpms())
-
- 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)
@@ -1262,6 +1275,49 @@ class XendAPI:
return xen_api_error(XEND_ERROR_VDI_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
# ----------------------------------------------------------------
SR_attr_ro = ['VDIs',
diff -r 5bef3f695b55 -r faaa8256558b tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py Sat Oct 28 13:30:21 2006 +0100
+++ b/tools/python/xen/xend/XendConfig.py Sat Oct 28 17:12:04 2006 +0100
@@ -110,8 +110,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',
@@ -570,11 +568,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 in ('vbd','tap'):
cfg['vbd_refs'].append(dev_uuid)
+ elif dev_type == 'vtpm':
+ cfg['vtpm_refs'].append(dev_uuid)
return cfg
@@ -610,6 +611,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
@@ -747,6 +750,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():
@@ -815,7 +820,16 @@ 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 dev_uuid
+
elif dev_type == 'tap':
dev_info['uname'] = 'tap:qcow:%s' % cfg_xenapi.get('image')
dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
diff -r 5bef3f695b55 -r faaa8256558b tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Sat Oct 28 13:30:21 2006 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py Sat Oct 28 17:12:04 2006 +0100
@@ -1897,6 +1897,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])
diff -r 5bef3f695b55 -r faaa8256558b tools/python/xen/xend/XendError.py
--- a/tools/python/xen/xend/XendError.py Sat Oct 28 13:30:21 2006 +0100
+++ b/tools/python/xen/xend/XendError.py Sat Oct 28 17:12:04 2006 +0100
@@ -47,6 +47,7 @@ XEND_ERROR_VM_INVALID = ('EVM
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_VDI_INVALID = ('EVDIINVALID', 'VDI Invalid')
XEND_ERROR_SR_INVALID = ('ESRINVALID', 'SR Invalid')
XEND_ERROR_TODO = ('ETODO', 'Lazy Programmer Error')
diff -r 5bef3f695b55 -r faaa8256558b tools/python/xen/xend/server/tpmif.py
--- a/tools/python/xen/xend/server/tpmif.py Sat Oct 28 13:30:21 2006 +0100
+++ b/tools/python/xen/xend/server/tpmif.py Sat Oct 28 17:12:04 2006 +0100
@@ -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):
+ def getDeviceConfiguration(self, devid):
+ """Returns the configuration of a device"""
+ result = DevController.getDeviceConfiguration(self, devid)
- result = DevController.configuration(self, devid)
-
- instance = self.readBackend(devid, 'instance')
+ (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
diff -r 5bef3f695b55 -r faaa8256558b tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Sat Oct 28 13:30:21 2006 +0100
+++ b/tools/python/xen/xm/create.py Sat Oct 28 17:12:04 2006 +0100
@@ -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):
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|