mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
Provide xend support for setting up TPM front- and back-end interfaces.
Signed-off-by: Steven Hand <steven@xensource.com> Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
This commit is contained in:
1 parent
142a767280
commit
d22746ede9
7 files changed
+229
No files matched your search
@@ -269,6 +269,7 @@ class XendDomainInfo:
|
||||
self.blkif_backend = False
|
||||
self.netif_backend = False
|
||||
self.netif_idx = 0
|
||||
self.tpmif_backend = False
|
||||
|
||||
#todo: state: running, suspended
|
||||
self.state = STATE_VM_OK
|
||||
@@ -458,6 +459,31 @@ class XendDomainInfo:
|
||||
|
||||
return
|
||||
|
||||
if type == 'vtpm':
|
||||
backdom = domain_exists(sxp.child_value(devconfig, 'backend', '0'))
|
||||
|
||||
devnum = int(sxp.child_value(devconfig, 'instance', '0'))
|
||||
log.error("The domain has a TPM with instance %d." % devnum)
|
||||
|
||||
# create backend db
|
||||
backdb = backdom.db.addChild("/backend/%s/%s/%d" %
|
||||
(type, self.uuid, devnum))
|
||||
# create frontend db
|
||||
db = self.db.addChild("/device/%s/%d" % (type, devnum))
|
||||
|
||||
backdb['frontend'] = db.getPath()
|
||||
backdb['frontend-id'] = "%i" % self.id
|
||||
backdb['instance'] = sxp.child_value(devconfig, 'instance', '0')
|
||||
backdb.saveDB(save=True)
|
||||
|
||||
db['handle'] = "%i" % devnum
|
||||
db['backend'] = backdb.getPath()
|
||||
db['backend-id'] = "%i" % int(sxp.child_value(devconfig,
|
||||
'backend', '0'))
|
||||
db.saveDB(save=True)
|
||||
|
||||
return
|
||||
|
||||
ctrl = self.findDeviceController(type)
|
||||
return ctrl.createDevice(devconfig, recreate=self.recreate,
|
||||
change=change)
|
||||
@@ -779,6 +805,11 @@ class XendDomainInfo:
|
||||
for dev in typedb.keys():
|
||||
typedb[dev].delete()
|
||||
typedb.saveDB(save=True)
|
||||
if type == 'vtpm':
|
||||
typedb = ddb.addChild(type)
|
||||
for dev in typedb.keys():
|
||||
typedb[dev].delete()
|
||||
typedb.saveDB(save=True)
|
||||
|
||||
def show(self):
|
||||
"""Print virtual machine info.
|
||||
@@ -1018,6 +1049,8 @@ class XendDomainInfo:
|
||||
self.netif_backend = True
|
||||
elif name == 'usbif':
|
||||
self.usbif_backend = True
|
||||
elif name == 'tpmif':
|
||||
self.tpmif_backend = True
|
||||
else:
|
||||
raise VmError('invalid backend type:' + str(name))
|
||||
|
||||
@@ -1190,6 +1223,10 @@ from server import netif
|
||||
controller.addDevControllerClass("vif", netif.NetifController)
|
||||
add_device_handler("vif", "vif")
|
||||
|
||||
from server import tpmif
|
||||
controller.addDevControllerClass("vtpm", tpmif.TPMifController)
|
||||
add_device_handler("vtpm", "vtpm")
|
||||
|
||||
from server import pciif
|
||||
controller.addDevControllerClass("pci", pciif.PciController)
|
||||
add_device_handler("pci", "pci")
|
||||
|
||||
@@ -32,6 +32,9 @@ SIF_BLK_BE_DOMAIN = (1<<4)
|
||||
"""Flag for a net device backend domain."""
|
||||
SIF_NET_BE_DOMAIN = (1<<5)
|
||||
|
||||
"""Flag for a TPM device backend domain."""
|
||||
SIF_TPM_BE_DOMAIN = (1<<7)
|
||||
|
||||
class ImageHandler:
|
||||
"""Abstract base class for image handlers.
|
||||
|
||||
@@ -194,6 +197,7 @@ class ImageHandler:
|
||||
self.flags = 0
|
||||
if self.vm.netif_backend: self.flags |= SIF_NET_BE_DOMAIN
|
||||
if self.vm.blkif_backend: self.flags |= SIF_BLK_BE_DOMAIN
|
||||
if self.vm.tpmif_backend: self.flags |= SIF_TPM_BE_DOMAIN
|
||||
|
||||
if self.vm.recreate or self.vm.restore:
|
||||
return
|
||||
@@ -366,6 +370,11 @@ class VmxImageHandler(ImageHandler):
|
||||
mac = sxp.child_value(vifinfo, 'mac')
|
||||
ret.append("-macaddr")
|
||||
ret.append("%s" % mac)
|
||||
if name == 'vtpm':
|
||||
vtpminfo = sxp.child(device, 'vtpm')
|
||||
instance = sxp.child_value(vtpminfo, 'instance')
|
||||
ret.append("-instance")
|
||||
ret.append("%s" % instance)
|
||||
|
||||
# Handle graphics library related options
|
||||
vnc = sxp.child_value(self.vm.config, 'vnc')
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
# Copyright (C) 2005 IBM Corporation
|
||||
# Authort: Stefan Berger, stefanb@us.ibm.com
|
||||
# Derived from netif.py:
|
||||
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
|
||||
"""Support for virtual TPM interfaces.
|
||||
"""
|
||||
|
||||
import random
|
||||
|
||||
from xen.xend import sxp
|
||||
from xen.xend.XendError import XendError, VmError
|
||||
from xen.xend.XendLogging import log
|
||||
from xen.xend.XendRoot import get_component
|
||||
from xen.xend.xenstore import DBVar
|
||||
|
||||
from xen.xend.server import channel
|
||||
from xen.xend.server.controller import CtrlMsgRcvr, Dev, DevController
|
||||
from xen.xend.server.messages import *
|
||||
|
||||
class TPMifController(DevController):
|
||||
"""TPM interface controller. Handles all TPM devices for a domain.
|
||||
"""
|
||||
|
||||
def __init__(self, vm, recreate=False):
|
||||
DevController.__init__(self, vm, recreate=recreate)
|
||||
self.rcvr = None
|
||||
self.channel = None
|
||||
|
||||
def initController(self, recreate=False, reboot=False):
|
||||
self.destroyed = False
|
||||
self.channel = self.getChannel()
|
||||
|
||||
def destroyController(self, reboot=False):
|
||||
"""Destroy the controller and all devices.
|
||||
"""
|
||||
self.destroyed = True
|
||||
self.destroyDevices(reboot=reboot)
|
||||
if self.rcvr:
|
||||
self.rcvr.deregisterChannel()
|
||||
|
||||
def sxpr(self):
|
||||
val = ['tpmif', ['dom', self.getDomain()]]
|
||||
return val
|
||||
|
||||
def newDevice(self, id, config, recreate=False):
|
||||
"""Create a TPM device.
|
||||
|
||||
@param id: interface id
|
||||
@param config: device configuration
|
||||
@param recreate: recreate flag (true after xend restart)
|
||||
"""
|
||||
return None
|
||||
@@ -175,6 +175,12 @@ gopts.var('netif', val='no|yes',
|
||||
fn=set_bool, default=0,
|
||||
use="Make the domain a network interface backend.")
|
||||
|
||||
gopts.var('tpmif', val='frontend=DOM',
|
||||
fn=append_value, default=[],
|
||||
use="""Make the domain a TPM interface backend. If frontend is given,
|
||||
the frontend in that domain is connected to this backend (not
|
||||
completely implemented, yet)""")
|
||||
|
||||
gopts.var('disk', val='phy:DEV,VDEV,MODE[,DOM]',
|
||||
fn=append_value, default=[],
|
||||
use="""Add a disk device to a domain. The physical device is DEV,
|
||||
@@ -213,6 +219,12 @@ gopts.var('vif', val="mac=MAC,be_mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM
|
||||
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",
|
||||
fn=append_value, default=[],
|
||||
use="""Add a tpm interface. On the backend side us the the given
|
||||
instance as virtual TPM instance. Use the backend in the given
|
||||
domain.""")
|
||||
|
||||
gopts.var('nics', val="NUM",
|
||||
fn=set_int, default=1,
|
||||
use="""Set the number of network interfaces.
|
||||
@@ -369,6 +381,46 @@ def configure_usb(opts, config_devs, vals):
|
||||
config_usb = ['usb', ['path', path]]
|
||||
config_devs.append(['device', config_usb])
|
||||
|
||||
def configure_vtpm(opts, 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:
|
||||
try:
|
||||
if int(instance) == 0:
|
||||
opts.err('VM config error: vTPM instance must not be 0.')
|
||||
except ValueError:
|
||||
opts.err('Vm config error: could not parse instance number.')
|
||||
backend = d.get('backend')
|
||||
config_vtpm = ['vtpm']
|
||||
if instance:
|
||||
config_vtpm.append(['instance', instance])
|
||||
if backend:
|
||||
config_vtpm.append(['backend', backend])
|
||||
config_devs.append(['device', config_vtpm])
|
||||
|
||||
def configure_tpmif(opts, config_devs, vals):
|
||||
"""Create the config for virtual TPM interfaces.
|
||||
"""
|
||||
tpmif = vals.tpmif
|
||||
tpmif_n = 1
|
||||
for idx in range(0, tpmif_n):
|
||||
if idx < len(tpmif):
|
||||
d = tpmif[idx]
|
||||
frontend = d.get('frontend')
|
||||
config_tpmif = ['tpmif']
|
||||
if frontend:
|
||||
config_tpmif.append(['frontend', frontend])
|
||||
config_devs.append(['device', config_tpmif])
|
||||
|
||||
|
||||
def randomMAC():
|
||||
"""Generate a random MAC address.
|
||||
|
||||
@@ -479,6 +531,8 @@ def make_config(opts, vals):
|
||||
config.append(['backend', ['blkif']])
|
||||
if vals.netif:
|
||||
config.append(['backend', ['netif']])
|
||||
if vals.tpmif:
|
||||
config.append(['backend', ['tpmif']])
|
||||
if vals.restart:
|
||||
config.append(['restart', vals.restart])
|
||||
|
||||
@@ -491,6 +545,7 @@ def make_config(opts, vals):
|
||||
configure_pci(opts, config_devs, vals)
|
||||
configure_vifs(opts, config_devs, vals)
|
||||
configure_usb(opts, config_devs, vals)
|
||||
configure_vtpm(opts, config_devs, vals)
|
||||
configure_vmx(opts, config_devs, vals)
|
||||
config += config_devs
|
||||
|
||||
@@ -539,6 +594,38 @@ def preprocess_vifs(opts, vals):
|
||||
vifs.append(d)
|
||||
vals.vif = vifs
|
||||
|
||||
def preprocess_vtpm(opts, vals):
|
||||
if not vals.vtpm: return
|
||||
vtpms = []
|
||||
for vtpm in vals.vtpm:
|
||||
d = {}
|
||||
a = vtpm.split(',')
|
||||
for b in a:
|
||||
(k, v) = b.strip().split('=', 1)
|
||||
k = k.strip()
|
||||
v = v.strip()
|
||||
if k not in ['backend', 'instance']:
|
||||
opts.err('Invalid vtpm specifier: ' + vtpm)
|
||||
d[k] = v
|
||||
vtpms.append(d)
|
||||
vals.vtpm = vtpms
|
||||
|
||||
def preprocess_tpmif(opts, vals):
|
||||
if not vals.tpmif: return
|
||||
tpmifs = []
|
||||
for tpmif in vals.tpmif:
|
||||
d = {}
|
||||
a = tpmif.split(',')
|
||||
for b in a:
|
||||
(k, v) = b.strip().split('=', 1)
|
||||
k = k.strip()
|
||||
v = v.strip()
|
||||
if k not in ['frontend']:
|
||||
opts.err('Invalid tpmif specifier: ' + vtpm)
|
||||
d[k] = v
|
||||
tpmifs.append(d)
|
||||
vals.tpmif = tpmifs
|
||||
|
||||
def preprocess_ip(opts, vals):
|
||||
if vals.ip or vals.dhcp != 'off':
|
||||
dummy_nfs_server = '1.2.3.4'
|
||||
@@ -627,6 +714,8 @@ def preprocess(opts, vals):
|
||||
preprocess_ip(opts, vals)
|
||||
preprocess_nfs(opts, vals)
|
||||
preprocess_vnc(opts, vals)
|
||||
preprocess_vtpm(opts, vals)
|
||||
preprocess_tpmif(opts, vals)
|
||||
|
||||
def make_domain(opts, config):
|
||||
"""Create, build and start a domain.
|
||||
|
||||