2
# Copyright (c) 2005 IBM Corporation
3
# Copyright (c) 2005 XenSource Ltd.
5
# This library is free software; you can redistribute it and/or
6
# modify it under the terms of version 2.1 of the GNU Lesser General Public
7
# License as published by the Free Software Foundation.
9
# This library is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
# Lesser General Public License for more details.
14
# You should have received a copy of the GNU Lesser General Public
15
# License along with this library; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
VTPMDB="/var/vtpm/vtpm.db"
25
#In the vtpm-impl file some commands should be defined:
26
# vtpm_create, vtpm_setup, vtpm_start, etc. (see below)
27
if [ -r "$dir/vtpm-impl.alt" ]; then
28
. "$dir/vtpm-impl.alt"
29
elif [ -r "$dir/vtpm-impl" ]; then
32
function vtpm_create () {
35
function vtpm_setup() {
38
function vtpm_start() {
41
function vtpm_suspend() {
44
function vtpm_resume() {
47
function vtpm_delete() {
50
function vtpm_migrate() {
51
echo "Error: vTPM migration accross machines not implemented."
53
function vtpm_migrate_local() {
54
echo "Error: local vTPM migration not supported"
56
function vtpm_migrate_recover() {
62
#Find the instance number for the vtpm given the name of the domain
64
# - vmname : the name of the vm
66
# Returns '0' if instance number could not be found, otherwise
67
# it returns the instance number in the variable 'instance'
68
function vtpmdb_find_instance () {
69
local vmname ret instance
73
instance=$(cat $VTPMDB | \
74
awk -vvmname=$vmname \
76
if ( 1 != index($1,"#")) { \
77
if ( $1 == vmname ) { \
83
if [ "$instance" != "" ]; then
90
# Check whether a particular instance number is still available
91
# returns "0" if it is not available, "1" otherwise.
92
function vtpmdb_is_free_instancenum () {
93
local instance instances avail i
96
#Allowed instance number range: 1-255
97
if [ $instance -eq 0 -o $instance -gt 255 ]; then
100
instances=$(cat $VTPMDB | \
103
if (1 != index($1,"#")) { \
107
for i in $instances; do
108
if [ $i -eq $instance ]; then
118
# Get an available instance number given the database
119
# Returns an unused instance number
120
function vtpmdb_get_free_instancenum () {
121
local ctr instances don found
122
instances=$(cat $VTPMDB | \
125
if (1 != index($1,"#")) { \
131
while [ $don -eq 0 ]; do
133
for i in $instances; do
134
if [ $i -eq $ctr ]; then
140
if [ $found -eq 0 ]; then
150
# Add a domain name and instance number to the DB file
151
function vtpmdb_add_instance () {
152
local res vmname inst
156
if [ ! -f $VTPMDB ]; then
157
echo "#Database for VM to vTPM association" > $VTPMDB
158
echo "#1st column: domain name" >> $VTPMDB
159
echo "#2nd column: TPM instance number" >> $VTPMDB
161
res=$(vtpmdb_validate_entry $vmname $inst)
162
if [ $res -eq 0 ]; then
163
echo "$vmname $inst" >> $VTPMDB
168
#Validate whether an entry is the same as passed to this
170
function vtpmdb_validate_entry () {
171
local res rc vmname inst
176
res=$(cat $VTPMDB | \
177
gawk -vvmname=$vmname \
180
if ( 1 == index($1,"#")) {\
182
if ( $1 == vmname && \
187
if ( $1 == vmname || \
194
if [ "$res" == "1" ]; then
196
elif [ "$res" == "2" ]; then
203
#Remove an entry from the vTPM database given its domain name
205
function vtpmdb_remove_entry () {
206
local vmname instance VTPMDB_TMP
209
VTPMDB_TMP="$VTPMDB".tmp
212
gawk -vvmname=$vmname \
214
if ( $1 != vmname ) { \
218
if [ -e $VTPMDB_TMP ]; then
219
mv -f $VTPMDB_TMP $VTPMDB
220
vtpm_delete $instance
222
log err "Error creating temporary file '$VTPMDB_TMP'."
227
# Find the reason for the creation of this device:
228
# Returns 'resume' or 'create'
229
function vtpm_get_create_reason () {
231
resume=$(xenstore_read $XENBUS_PATH/resume)
232
if [ "$resume" == "True" ]; then
240
#Create a vTPM instance
241
# If no entry in the TPM database is found, the instance is
242
# created and an entry added to the database.
243
function vtpm_create_instance () {
244
local res instance domname reason uuid
245
uuid=$(xenstore_read "$XENBUS_PATH"/uuid)
246
reason=$(vtpm_get_create_reason)
252
if [ "$uuid" != "" ]; then
253
instance=$(vtpmdb_find_instance $uuid)
255
if [ "$instance" == "0" ]; then
256
domname=$(xenstore_read "$XENBUS_PATH"/domain)
257
instance=$(vtpmdb_find_instance $domname)
260
if [ "$instance" == "0" -a "$reason" != "create" ]; then
265
if [ "$instance" == "0" ]; then
266
#Try to give the preferred instance to the domain
267
instance=$(xenstore_read "$XENBUS_PATH"/pref_instance)
268
if [ "$instance" != "" ]; then
269
res=$(vtpmdb_is_free_instancenum $instance)
270
if [ $res -eq 0 ]; then
271
instance=$(vtpmdb_get_free_instancenum)
274
instance=$(vtpmdb_get_free_instancenum)
277
vtpm_create $instance
279
if [ $vtpm_fatal_error -eq 0 ]; then
280
if [ "$uuid" != "" ]; then
281
vtpmdb_add_instance $uuid $instance
283
vtpmdb_add_instance $domname $instance
287
if [ "$reason" == "resume" ]; then
288
vtpm_resume $instance
296
xenstore_write $XENBUS_PATH/instance $instance
300
#Remove an instance when a VM is terminating or suspending.
301
#Since it is assumed that the VM will appear again, the
302
#entry is kept in the VTPMDB file.
303
function vtpm_remove_instance () {
304
local instance reason domname uuid
305
#Stop script execution quietly if path does not exist (anymore)
306
xenstore-exists "$XENBUS_PATH"/domain
307
uuid=$(xenstore_read "$XENBUS_PATH"/uuid)
313
if [ "$uuid" != "" ]; then
314
instance=$(vtpmdb_find_instance $uuid)
317
if [ "$instance" == "0" ]; then
318
domname=$(xenstore_read "$XENBUS_PATH"/domain)
319
instance=$(vtpmdb_find_instance $domname)
322
if [ "$instance" != "0" ]; then
323
vtpm_suspend $instance
330
#Remove an entry in the VTPMDB file given the domain's name
331
#1st parameter: The name of the domain
332
function vtpm_delete_instance () {
337
instance=$(vtpmdb_find_instance $1)
338
if [ "$instance" != "0" ]; then
339
vtpmdb_remove_entry $1 $instance
345
# Determine whether the given address is local to this machine
347
# "-1" : the given machine name is invalid
348
# "0" : this is not an address of this machine
349
# "1" : this is an address local to this machine
350
function vtpm_isLocalAddress() {
352
addr=$(ping $1 -c 1 | \
353
gawk '{ print substr($3,2,length($3)-2); exit }')
354
if [ "$addr" == "" ]; then
358
res=$(ifconfig | grep "inet addr" | \
361
if ( addr == substr($2, 6)) {\
366
if [ "$res" == "" ]; then
373
# Perform a migration step. This function differentiates between migration
374
# to the local host or to a remote machine.
376
# 1st: destination host to migrate to
377
# 2nd: name of the domain to migrate
378
# 3rd: the migration step to perform
379
function vtpm_migration_step() {
380
local res=$(vtpm_isLocalAddress $1)
381
if [ "$res" == "0" ]; then
382
vtpm_migrate $1 $2 $3
388
# Recover from migration due to an error. This function differentiates
389
# between migration to the local host or to a remote machine.
391
# 1st: destination host the migration was going to
392
# 2nd: name of the domain that was to be migrated
393
# 3rd: the last successful migration step that was done
394
function vtpm_recover() {
396
res=$(vtpm_isLocalAddress $1)
397
if [ "$res" == "0" ]; then
398
vtpm_migrate_recover $1 $2 $3
403
#Determine the domain id given a domain's name.
404
#1st parameter: name of the domain
405
#return value: domain id or -1 if domain id could not be determined
406
function vtpm_domid_from_name () {
408
ids=$(xenstore-list /local/domain)
410
name=$(xenstore-read /local/domain/$id/name)
411
if [ "$name" == "$1" ]; then
419
#Determine the virtual TPM's instance number using the domain ID.
421
function vtpm_uuid_by_domid() {
422
echo $(xenstore-read /local/domain/0/backend/vtpm/$1/0/uuid)
426
# Determine the vTPM's UUID by the name of the VM
427
function vtpm_uuid_from_vmname() {
428
local domid=$(vtpm_domid_from_name $1)
429
if [ "$domid" != "-1" ]; then
430
echo $(vtpm_uuid_by_domid $domid)
436
#Add a virtual TPM instance number and its associated domain name
437
#to the VTPMDB file and activate usage of this virtual TPM instance
438
#by writing the instance number into the xenstore
439
#1st parm: name of virtual machine
440
#2nd parm: instance of associated virtual TPM
441
function vtpm_add_and_activate() {
442
local domid=$(vtpm_domid_from_name $1)
443
local vtpm_uuid=$(vtpm_uuid_from_vmname $1)
444
if [ "$vtpm_uuid" != "" -a "$domid" != "-1" ]; then
445
vtpmdb_add_instance $vtpm_uuid $2
446
xenstore-write backend/vtpm/$domid/0/instance $2