mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
The attached patch does the following:
- introduces two basic tests for the virtual TPM (skipped on hardware where a TPM is not available or vtpm manager has not been started manually before) - adapts the Makefiles to make the test cases available - splits up the hotplug files into two files where the vtpm-common.sh can be sourced by 'other' scripts as well - uses echo "$var" to return variables from functions - gets rid of the 'set +e" work-around - introduces a script (vtpm-delete) to delete entries from the virtual TPM directory in /etc/xen/vtpm.db The xm-tests will skip over the 2nd test on most systems and the patch has otherwise no effect on existing tests. Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
This commit is contained in:
1 parent
46ede6808b
commit
d8a4248e02
11 files changed
+256
-56
No files matched your search
@@ -26,10 +26,10 @@ XEN_SCRIPTS += network-route vif-route
|
||||
XEN_SCRIPTS += network-nat vif-nat
|
||||
XEN_SCRIPTS += block
|
||||
XEN_SCRIPTS += block-enbd block-nbd
|
||||
XEN_SCRIPTS += vtpm
|
||||
XEN_SCRIPTS += vtpm vtpm-delete
|
||||
XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh
|
||||
XEN_SCRIPT_DATA += xen-hotplug-common.sh xen-network-common.sh vif-common.sh
|
||||
XEN_SCRIPT_DATA += block-common.sh vtpm-common.sh
|
||||
XEN_SCRIPT_DATA += block-common.sh vtpm-common.sh vtpm-hotplug-common.sh
|
||||
|
||||
XEN_HOTPLUG_DIR = /etc/hotplug
|
||||
XEN_HOTPLUG_SCRIPTS = xen-backend.agent
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
dir=$(dirname "$0")
|
||||
. "$dir/vtpm-common.sh"
|
||||
. "$dir/vtpm-hotplug-common.sh"
|
||||
|
||||
vtpm_fatal_error=0
|
||||
|
||||
|
||||
@@ -17,21 +17,8 @@
|
||||
#
|
||||
|
||||
dir=$(dirname "$0")
|
||||
. "$dir/xen-hotplug-common.sh"
|
||||
|
||||
findCommand "$@"
|
||||
if [ "$command" != "online" ] &&
|
||||
[ "$command" != "offline" ] &&
|
||||
[ "$command" != "add" ] &&
|
||||
[ "$command" != "remove" ]
|
||||
then
|
||||
log err "Invalid command: $command"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
XENBUS_PATH="${XENBUS_PATH:?}"
|
||||
|
||||
. "$dir/logging.sh"
|
||||
. "$dir/locking.sh"
|
||||
|
||||
VTPMDB="/etc/xen/vtpm.db"
|
||||
|
||||
@@ -58,15 +45,19 @@ if [ -z "$VTPM_IMPL_DEFINED" ]; then
|
||||
function vtpm_resume() {
|
||||
true
|
||||
}
|
||||
function vtpm_delete() {
|
||||
true
|
||||
}
|
||||
fi
|
||||
|
||||
|
||||
#Find the instance number for the vtpm given the name of the domain
|
||||
# Parameters
|
||||
# - vmname : the name of the vm
|
||||
# Return value
|
||||
# Returns '0' if instance number could not be found, otherwise
|
||||
# it returns the instance number in the variable 'instance'
|
||||
function find_instance () {
|
||||
function vtpmdb_find_instance () {
|
||||
local vmname=$1
|
||||
local ret=0
|
||||
instance=`cat $VTPMDB | \
|
||||
@@ -80,18 +71,17 @@ function find_instance () {
|
||||
} \
|
||||
}'`
|
||||
if [ "$instance" != "" ]; then
|
||||
ret=1
|
||||
ret=$instance
|
||||
fi
|
||||
return $ret
|
||||
echo "$ret"
|
||||
}
|
||||
|
||||
|
||||
# Check whether a particular instance number is still available
|
||||
# returns '1' if it is available
|
||||
function is_free_instancenum () {
|
||||
# returns "0" if it is not available, "1" otherwise.
|
||||
function vtpmdb_is_free_instancenum () {
|
||||
local instance=$1
|
||||
local avail=1
|
||||
|
||||
#Allowed instance number range: 1-255
|
||||
if [ $instance -eq 0 -o $instance -gt 255 ]; then
|
||||
avail=0
|
||||
@@ -110,13 +100,13 @@ function is_free_instancenum () {
|
||||
fi
|
||||
done
|
||||
fi
|
||||
return $avail
|
||||
echo "$avail"
|
||||
}
|
||||
|
||||
|
||||
# Get an available instance number given the database
|
||||
# Returns an unused instance number
|
||||
function get_free_instancenum () {
|
||||
function vtpmdb_get_free_instancenum () {
|
||||
local ctr
|
||||
local instances
|
||||
local don
|
||||
@@ -145,12 +135,12 @@ function get_free_instancenum () {
|
||||
fi
|
||||
let ctr=ctr+1
|
||||
done
|
||||
let instance=$ctr
|
||||
echo "$ctr"
|
||||
}
|
||||
|
||||
|
||||
# Add a domain name and instance number to the DB file
|
||||
function add_instance () {
|
||||
function vtpmdb_add_instance () {
|
||||
local vmname=$1
|
||||
local inst=$2
|
||||
|
||||
@@ -159,8 +149,8 @@ function add_instance () {
|
||||
echo "#1st column: domain name" >> $VTPMDB
|
||||
echo "#2nd column: TPM instance number" >> $VTPMDB
|
||||
fi
|
||||
validate_entry $vmname $inst
|
||||
if [ $? -eq 0 ]; then
|
||||
res=$(vtpmdb_validate_entry $vmname $inst)
|
||||
if [ $res -eq 0 ]; then
|
||||
echo "$vmname $inst" >> $VTPMDB
|
||||
fi
|
||||
}
|
||||
@@ -168,11 +158,10 @@ function add_instance () {
|
||||
|
||||
#Validate whether an entry is the same as passed to this
|
||||
#function
|
||||
function validate_entry () {
|
||||
function vtpmdb_validate_entry () {
|
||||
local rc=0
|
||||
local vmname=$1
|
||||
local inst=$2
|
||||
local res
|
||||
|
||||
res=`cat $VTPMDB | \
|
||||
gawk -vvmname=$vmname \
|
||||
@@ -197,13 +186,15 @@ function validate_entry () {
|
||||
elif [ "$res" == "2" ]; then
|
||||
let rc=2
|
||||
fi
|
||||
return $rc
|
||||
echo "$rc"
|
||||
}
|
||||
|
||||
|
||||
#Remove an entry from the vTPM database given its domain name
|
||||
function remove_entry () {
|
||||
#and instance number
|
||||
function vtpmdb_remove_entry () {
|
||||
local vmname=$1
|
||||
local instance=$2
|
||||
local VTPMDB_TMP="$VTPMDB".tmp
|
||||
`cat $VTPMDB | \
|
||||
gawk -vvmname=$vmname \
|
||||
@@ -214,6 +205,7 @@ function remove_entry () {
|
||||
'} > $VTPMDB_TMP`
|
||||
if [ -e $VTPMDB_TMP ]; then
|
||||
mv -f $VTPMDB_TMP $VTPMDB
|
||||
vtpm_delete $instance
|
||||
else
|
||||
log err "Error creating temporary file '$VTPMDB_TMP'."
|
||||
fi
|
||||
@@ -222,7 +214,7 @@ function remove_entry () {
|
||||
|
||||
# Find the reason for the creation of this device:
|
||||
# Set global REASON variable to 'resume' or 'create'
|
||||
function get_create_reason () {
|
||||
function vtpm_get_create_reason () {
|
||||
local resume=$(xenstore-read $XENBUS_PATH/resume)
|
||||
if [ "$resume" == "True" ]; then
|
||||
REASON="resume"
|
||||
@@ -231,32 +223,30 @@ function get_create_reason () {
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
#Create a vTPM instance
|
||||
# If no entry in the TPM database is found, the instance is
|
||||
# created and an entry added to the database.
|
||||
function vtpm_create_instance () {
|
||||
local domname=$(xenstore_read "$XENBUS_PATH"/domain)
|
||||
local res
|
||||
set +e
|
||||
get_create_reason
|
||||
local instance
|
||||
vtpm_get_create_reason
|
||||
|
||||
claim_lock vtpmdb
|
||||
|
||||
find_instance $domname
|
||||
res=$?
|
||||
if [ $res -eq 0 ]; then
|
||||
instance=$(vtpmdb_find_instance $domname)
|
||||
if [ "$instance" == "0" ]; then
|
||||
#Try to give the preferred instance to the domain
|
||||
instance=$(xenstore_read "$XENBUS_PATH"/pref_instance)
|
||||
if [ "$instance" != "" ]; then
|
||||
is_free_instancenum $instance
|
||||
res=$?
|
||||
res=$(vtpmdb_is_free_instancenum $instance)
|
||||
if [ $res -eq 0 ]; then
|
||||
get_free_instancenum
|
||||
instance=$(vtpmdb_get_free_instancenum)
|
||||
fi
|
||||
else
|
||||
get_free_instancenum
|
||||
instance=$(vtpmdb_get_free_instancenum)
|
||||
fi
|
||||
add_instance $domname $instance
|
||||
vtpmdb_add_instance $domname $instance
|
||||
if [ "$REASON" == "create" ]; then
|
||||
vtpm_create $instance
|
||||
elif [ "$REASON" == "resume" ]; then
|
||||
@@ -279,25 +269,40 @@ function vtpm_create_instance () {
|
||||
true
|
||||
fi
|
||||
xenstore_write $XENBUS_PATH/instance $instance
|
||||
set -e
|
||||
}
|
||||
|
||||
|
||||
#Remove an instance
|
||||
#Remove an instance when a VM is terminating or suspending.
|
||||
#Since it is assumed that the VM will appear again, the
|
||||
#entry is kept in the VTPMDB file.
|
||||
function vtpm_remove_instance () {
|
||||
local domname=$(xenstore_read "$XENBUS_PATH"/domain)
|
||||
set +e
|
||||
find_instance $domname
|
||||
res=$?
|
||||
if [ $res -eq 0 ]; then
|
||||
#Something is really wrong with the DB
|
||||
log err "vTPM DB file $VTPMDB has no entry for '$domname'"
|
||||
else
|
||||
|
||||
claim_lock vtpmdb
|
||||
|
||||
instance=$(vtpmdb_find_instance $domname)
|
||||
|
||||
if [ "$instance" != "0" ]; then
|
||||
if [ "$REASON" == "suspend" ]; then
|
||||
vtpm_suspend $instance
|
||||
fi
|
||||
fi
|
||||
set -e
|
||||
|
||||
release_lock vtpmdb
|
||||
}
|
||||
|
||||
|
||||
#Remove an entry in the VTPMDB file given the domain's name
|
||||
#1st parameter: The name of the domain
|
||||
function vtpm_delete_instance () {
|
||||
local rc
|
||||
|
||||
claim_lock vtpmdb
|
||||
|
||||
instance=$(vtpmdb_find_instance $1)
|
||||
if [ "$instance" != "0" ]; then
|
||||
vtpmdb_remove_entry $1 $instance
|
||||
fi
|
||||
|
||||
release_lock vtpmdb
|
||||
}
|
||||
@@ -93,6 +93,7 @@ AC_CONFIG_FILES([
|
||||
tests/unpause/Makefile
|
||||
tests/vcpu-pin/Makefile
|
||||
tests/vcpu-disable/Makefile
|
||||
tests/vtpm/Makefile
|
||||
tests/enforce_dom0_cpus/Makefile
|
||||
lib/XmTestReport/xmtest.py
|
||||
lib/XmTestLib/config.py
|
||||
|
||||
@@ -99,6 +99,7 @@ class XenConfig:
|
||||
# These options need to be lists
|
||||
self.defaultOpts["disk"] = []
|
||||
self.defaultOpts["vif"] = []
|
||||
self.defaultOpts["vtpm"] = []
|
||||
|
||||
self.opts = self.defaultOpts
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ SUBDIRS = \
|
||||
unpause \
|
||||
vcpu-disable \
|
||||
vcpu-pin \
|
||||
vtpm \
|
||||
enforce_dom0_cpus \
|
||||
save restore migrate
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This scripts must be called the following way:
|
||||
# vtpm-delete <domain name>
|
||||
|
||||
dir=$(dirname "$0")
|
||||
. "$dir/vtpm-common.sh"
|
||||
|
||||
vtpm_delete_instance $1
|
||||
@@ -0,0 +1,35 @@
|
||||
#
|
||||
# Copyright (c) 2005 IBM Corporation
|
||||
# Copyright (c) 2005 XenSource Ltd.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2.1 of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
dir=$(dirname "$0")
|
||||
. "$dir/xen-hotplug-common.sh"
|
||||
|
||||
findCommand "$@"
|
||||
if [ "$command" != "online" ] &&
|
||||
[ "$command" != "offline" ] &&
|
||||
[ "$command" != "add" ] &&
|
||||
[ "$command" != "remove" ]
|
||||
then
|
||||
log err "Invalid command: $command"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
XENBUS_PATH="${XENBUS_PATH:?}"
|
||||
|
||||
. "$dir/vtpm-common.sh"
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# Copyright (C) International Business Machines Corp., 2006
|
||||
# Author: Stefan Berger <stefanb@us.ibm.com)
|
||||
|
||||
# Positive Test: create domain with virtual TPM attached at build time,
|
||||
# verify list
|
||||
|
||||
|
||||
from XmTestLib import *
|
||||
|
||||
def vtpm_cleanup(domName):
|
||||
# Since this is only a temporary domain I clean up the domain from the
|
||||
# virtual TPM directory
|
||||
traceCommand("/etc/xen/scripts/vtpm-delete %s" % domName)
|
||||
|
||||
if ENABLE_HVM_SUPPORT:
|
||||
SKIP("vtpm-list not supported for HVM domains")
|
||||
|
||||
config = {"vtpm":"instance=1,backend=0"}
|
||||
domain = XmTestDomain(extraConfig=config)
|
||||
|
||||
try:
|
||||
domain.start()
|
||||
except DomainError, e:
|
||||
if verbose:
|
||||
print e.extra
|
||||
vtpm_cleanup(domain.getName())
|
||||
FAIL("Unable to create domain")
|
||||
|
||||
domName = domain.getName()
|
||||
|
||||
status, output = traceCommand("xm vtpm-list %s" % domain.getId())
|
||||
eyecatcher = "/local/domain/0/backend/vtpm"
|
||||
where = output.find(eyecatcher)
|
||||
if status != 0:
|
||||
vtpm_cleanup(domName)
|
||||
FAIL("xm vtpm-list returned bad status, expected 0, status is %i" % status)
|
||||
elif where < 0:
|
||||
vtpm_cleanup(domName)
|
||||
FAIL("Fail to list virtual TPM device")
|
||||
|
||||
domain.stop()
|
||||
|
||||
vtpm_cleanup(domName)
|
||||
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# Copyright (C) International Business Machines Corp., 2006
|
||||
# Author: Stefan Berger <stefanb@us.ibm.com)
|
||||
|
||||
# Positive Test: create domain with virtual TPM attached at build time,
|
||||
# check list of pcrs
|
||||
|
||||
from XmTestLib import *
|
||||
|
||||
def vtpm_cleanup(domName):
|
||||
# Since this is only a temporary domain I clean up the domain from the
|
||||
# virtual TPM directory
|
||||
traceCommand("/etc/xen/scripts/vtpm-delete %s" % domName)
|
||||
|
||||
if ENABLE_HVM_SUPPORT:
|
||||
SKIP("vtpm-list not supported for HVM domains")
|
||||
|
||||
status, output = traceCommand("ls /dev/tpm0")
|
||||
if re.search("No such file or directory",output):
|
||||
SKIP("This machine has no hardware TPM; cannot run this test")
|
||||
|
||||
status, output = traceCommand("ps aux | grep vtpm_manager | grep -v grep")
|
||||
if output == "":
|
||||
FAIL("virtual TPM manager must be started to run this test")
|
||||
|
||||
# vtpm manager has been detected
|
||||
config = {"vtpm":"instance=1,backend=0"}
|
||||
domain = XmTestDomain(extraConfig=config)
|
||||
|
||||
try:
|
||||
domain.start()
|
||||
except DomainError, e:
|
||||
if verbose:
|
||||
print e.extra
|
||||
vtpm_cleanup(domain.getName())
|
||||
FAIL("Unable to create domain")
|
||||
|
||||
domName = domain.getName()
|
||||
|
||||
try:
|
||||
console = XmConsole(domain.getName())
|
||||
except ConsoleError, e:
|
||||
vtpm_cleanup(domName)
|
||||
FAIL(str(e))
|
||||
|
||||
try:
|
||||
console.sendInput("input")
|
||||
run = console.runCmd("ls /sys")
|
||||
except ConsoleError, e:
|
||||
saveLog(console.getHistory())
|
||||
vtpm_cleanup(domName)
|
||||
FAIL(str(e))
|
||||
|
||||
if re.search("No such file",run["output"]):
|
||||
try:
|
||||
run = console.runCmd("mkdir /sys")
|
||||
run = console.runCmd("mount -t sysfs /sys /sys")
|
||||
except ConsoleError, e:
|
||||
saveLog(console.getHistory())
|
||||
vtpm_cleanup(domName)
|
||||
FAIL(str(e))
|
||||
|
||||
try:
|
||||
run = console.runCmd("cat /sys/devices/platform/tpm_vtpm/pcrs")
|
||||
except ConsoleError, e:
|
||||
saveLog(console.getHistory())
|
||||
vtpm_cleanup(domName)
|
||||
FAIL(str(e))
|
||||
|
||||
if re.search("No such file",run["output"]):
|
||||
FAIL("TPM frontend support not compiled into (domU?) kernel")
|
||||
|
||||
console.closeConsole()
|
||||
|
||||
domain.stop()
|
||||
|
||||
vtpm_cleanup(domName)
|
||||
|
||||
if not re.search("PCR-00:",run["output"]):
|
||||
FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
TESTS = 01_vtpm-list_pos.test \
|
||||
02_vtpm-cat_pcrs.test
|
||||
|
||||
XFAIL_TESTS =
|
||||
|
||||
EXTRA_DIST = $(TESTS) $(XFAIL_TESTS)
|
||||
|
||||
TESTS_ENVIRONMENT=@TENV@
|
||||
|
||||
%.test: %.py
|
||||
cp $< $@
|
||||
chmod +x $@
|
||||
|
||||
clean-local: am_config_clean-local
|
||||
|
||||
am_config_clean-local:
|
||||
rm -f *test
|
||||
rm -f *log
|
||||
rm -f *~
|
||||