direct-io.hg

view tools/examples/vtpm-common.sh @ 11416:536c25a9654d

The attached patch prevents a domain with an attached vTPM from doing
local migration since this does not seem to work correctly (see tests in
xm test suite). If no vTPM has been attached, the local migration
proceeds as usual.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
author Ewan Mellor <ewan@xensource.com>
date Tue Sep 05 14:17:49 2006 +0100 (2006-09-05)
parents 28b766e3bcca
children f247e0b52dda
line source
1 #
2 # Copyright (c) 2005 IBM Corporation
3 # Copyright (c) 2005 XenSource Ltd.
4 #
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.
8 #
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.
13 #
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
17 #
19 dir=$(dirname "$0")
20 . "$dir/logging.sh"
21 . "$dir/locking.sh"
23 VTPMDB="/etc/xen/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" ]; then
28 . "$dir/vtpm-impl"
29 else
30 function vtpm_create () {
31 true
32 }
33 function vtpm_setup() {
34 true
35 }
36 function vtpm_start() {
37 true
38 }
39 function vtpm_suspend() {
40 true
41 }
42 function vtpm_resume() {
43 true
44 }
45 function vtpm_delete() {
46 true
47 }
48 function vtpm_migrate() {
49 echo "Error: vTPM migration accross machines not implemented."
50 }
51 function vtpm_migrate_local() {
52 echo "Error: local vTPM migration not supported"
53 }
54 function vtpm_migrate_recover() {
55 true
56 }
57 fi
60 #Find the instance number for the vtpm given the name of the domain
61 # Parameters
62 # - vmname : the name of the vm
63 # Return value
64 # Returns '0' if instance number could not be found, otherwise
65 # it returns the instance number in the variable 'instance'
66 function vtpmdb_find_instance () {
67 local vmname ret instance
68 vmname=$1
69 ret=0
71 instance=$(cat $VTPMDB | \
72 awk -vvmname=$vmname \
73 '{ \
74 if ( 1 != index($1,"#")) { \
75 if ( $1 == vmname ) { \
76 print $2; \
77 exit; \
78 } \
79 } \
80 }')
81 if [ "$instance" != "" ]; then
82 ret=$instance
83 fi
84 echo "$ret"
85 }
88 # Check whether a particular instance number is still available
89 # returns "0" if it is not available, "1" otherwise.
90 function vtpmdb_is_free_instancenum () {
91 local instance instances avail i
92 instance=$1
93 avail=1
94 #Allowed instance number range: 1-255
95 if [ $instance -eq 0 -o $instance -gt 255 ]; then
96 avail=0
97 else
98 instances=$(cat $VTPMDB | \
99 gawk \
100 '{ \
101 if (1 != index($1,"#")) { \
102 printf("%s ",$2); \
103 } \
104 }')
105 for i in $instances; do
106 if [ $i -eq $instance ]; then
107 avail=0
108 break
109 fi
110 done
111 fi
112 echo "$avail"
113 }
116 # Get an available instance number given the database
117 # Returns an unused instance number
118 function vtpmdb_get_free_instancenum () {
119 local ctr instances don found
120 instances=$(cat $VTPMDB | \
121 gawk \
122 '{ \
123 if (1 != index($1,"#")) { \
124 printf("%s ",$2); \
125 } \
126 }')
127 ctr=1
128 don=0
129 while [ $don -eq 0 ]; do
130 found=0
131 for i in $instances; do
132 if [ $i -eq $ctr ]; then
133 found=1;
134 break;
135 fi
136 done
138 if [ $found -eq 0 ]; then
139 don=1
140 break
141 fi
142 let ctr=ctr+1
143 done
144 echo "$ctr"
145 }
148 # Add a domain name and instance number to the DB file
149 function vtpmdb_add_instance () {
150 local res vmname inst
151 vmname=$1
152 inst=$2
154 if [ ! -f $VTPMDB ]; then
155 echo "#Database for VM to vTPM association" > $VTPMDB
156 echo "#1st column: domain name" >> $VTPMDB
157 echo "#2nd column: TPM instance number" >> $VTPMDB
158 fi
159 res=$(vtpmdb_validate_entry $vmname $inst)
160 if [ $res -eq 0 ]; then
161 echo "$vmname $inst" >> $VTPMDB
162 fi
163 }
166 #Validate whether an entry is the same as passed to this
167 #function
168 function vtpmdb_validate_entry () {
169 local res rc vmname inst
170 rc=0
171 vmname=$1
172 inst=$2
174 res=$(cat $VTPMDB | \
175 gawk -vvmname=$vmname \
176 -vinst=$inst \
177 '{ \
178 if ( 1 == index($1,"#")) {\
179 } else \
180 if ( $1 == vmname && \
181 $2 == inst) { \
182 printf("1"); \
183 exit; \
184 } else \
185 if ( $1 == vmname || \
186 $2 == inst) { \
187 printf("2"); \
188 exit; \
189 } \
190 }')
192 if [ "$res" == "1" ]; then
193 rc=1
194 elif [ "$res" == "2" ]; then
195 rc=2
196 fi
197 echo "$rc"
198 }
201 #Remove an entry from the vTPM database given its domain name
202 #and instance number
203 function vtpmdb_remove_entry () {
204 local vmname instance VTPMDB_TMP
205 vmname=$1
206 instance=$2
207 VTPMDB_TMP="$VTPMDB".tmp
209 $(cat $VTPMDB | \
210 gawk -vvmname=$vmname \
211 '{ \
212 if ( $1 != vmname ) { \
213 print $0; \
214 } \
215 '} > $VTPMDB_TMP)
216 if [ -e $VTPMDB_TMP ]; then
217 mv -f $VTPMDB_TMP $VTPMDB
218 vtpm_delete $instance
219 else
220 log err "Error creating temporary file '$VTPMDB_TMP'."
221 fi
222 }
225 # Find the reason for the creation of this device:
226 # Returns 'resume' or 'create'
227 function vtpm_get_create_reason () {
228 local resume
229 resume=$(xenstore-read $XENBUS_PATH/resume)
230 if [ "$resume" == "True" ]; then
231 echo "resume"
232 else
233 echo "create"
234 fi
235 }
238 #Create a vTPM instance
239 # If no entry in the TPM database is found, the instance is
240 # created and an entry added to the database.
241 function vtpm_create_instance () {
242 local res instance domname reason
243 domname=$(xenstore_read "$XENBUS_PATH"/domain)
244 reason=$(vtpm_get_create_reason)
246 claim_lock vtpmdb
247 instance=$(vtpmdb_find_instance $domname)
249 if [ "$instance" == "0" -a "$reason" != "create" ]; then
250 release_lock vtpmdb
251 return
252 fi
254 if [ "$instance" == "0" ]; then
255 #Try to give the preferred instance to the domain
256 instance=$(xenstore_read "$XENBUS_PATH"/pref_instance)
257 if [ "$instance" != "" ]; then
258 res=$(vtpmdb_is_free_instancenum $instance)
259 if [ $res -eq 0 ]; then
260 instance=$(vtpmdb_get_free_instancenum)
261 fi
262 else
263 instance=$(vtpmdb_get_free_instancenum)
264 fi
266 vtpm_create $instance
268 if [ $vtpm_fatal_error -eq 0 ]; then
269 vtpmdb_add_instance $domname $instance
270 fi
271 else
272 if [ "$reason" == "resume" ]; then
273 vtpm_resume $instance
274 else
275 vtpm_start $instance
276 fi
277 fi
279 release_lock vtpmdb
281 xenstore_write $XENBUS_PATH/instance $instance
282 }
285 #Remove an instance when a VM is terminating or suspending.
286 #Since it is assumed that the VM will appear again, the
287 #entry is kept in the VTPMDB file.
288 function vtpm_remove_instance () {
289 local instance reason domname
290 domname=$(xenstore_read "$XENBUS_PATH"/domain)
292 if [ "$domname" != "" ]; then
293 claim_lock vtpmdb
295 instance=$(vtpmdb_find_instance $domname)
297 if [ "$instance" != "0" ]; then
298 vtpm_suspend $instance
299 fi
301 release_lock vtpmdb
302 fi
303 }
306 #Remove an entry in the VTPMDB file given the domain's name
307 #1st parameter: The name of the domain
308 function vtpm_delete_instance () {
309 local instance
311 claim_lock vtpmdb
313 instance=$(vtpmdb_find_instance $1)
314 if [ "$instance" != "0" ]; then
315 vtpmdb_remove_entry $1 $instance
316 fi
318 release_lock vtpmdb
319 }
321 # Determine whether the given address is local to this machine
322 # Return values:
323 # "-1" : the given machine name is invalid
324 # "0" : this is not an address of this machine
325 # "1" : this is an address local to this machine
326 function vtpm_isLocalAddress() {
327 local addr res
328 addr=$(ping $1 -c 1 | \
329 gawk '{ print substr($3,2,length($3)-2); exit }')
330 if [ "$addr" == "" ]; then
331 echo "-1"
332 return
333 fi
334 res=$(ifconfig | grep "inet addr" | \
335 gawk -vaddr=$addr \
336 '{ \
337 if ( addr == substr($2, 6)) {\
338 print "1"; \
339 } \
340 }' \
341 )
342 if [ "$res" == "" ]; then
343 echo "0"
344 return
345 fi
346 echo "1"
347 }
349 # Perform a migration step. This function differentiates between migration
350 # to the local host or to a remote machine.
351 # Parameters:
352 # 1st: destination host to migrate to
353 # 2nd: name of the domain to migrate
354 # 3rd: the migration step to perform
355 function vtpm_migration_step() {
356 local res=$(vtpm_isLocalAddress $1)
357 if [ "$res" == "0" ]; then
358 vtpm_migrate $1 $2 $3
359 else
360 vtpm_migrate_local
361 fi
362 }
364 # Recover from migration due to an error. This function differentiates
365 # between migration to the local host or to a remote machine.
366 # Parameters:
367 # 1st: destination host the migration was going to
368 # 2nd: name of the domain that was to be migrated
369 # 3rd: the last successful migration step that was done
370 function vtpm_recover() {
371 local res
372 res=$(vtpm_isLocalAddress $1)
373 if [ "$res" == "0" ]; then
374 vtpm_migrate_recover $1 $2 $3
375 fi
376 }
379 #Determine the domain id given a domain's name.
380 #1st parameter: name of the domain
381 #return value: domain id or -1 if domain id could not be determined
382 function vtpm_domid_from_name () {
383 local id name ids
384 ids=$(xenstore-list /local/domain)
385 for id in $ids; do
386 name=$(xenstore-read /local/domain/$id/name)
387 if [ "$name" == "$1" ]; then
388 echo "$id"
389 return
390 fi
391 done
392 echo "-1"
393 }
396 #Add a virtual TPM instance number and its associated domain name
397 #to the VTPMDB file and activate usage of this virtual TPM instance
398 #by writing the instance number into the xenstore
399 #1st parm: name of virtual machine
400 #2nd parm: instance of assoicate virtual TPM
401 function vtpm_add_and_activate() {
402 local domid=$(vtpm_domid_from_name $1)
403 if [ "$domid" != "-1" ]; then
404 vtpmdb_add_instance $1 $2
405 xenstore-write backend/vtpm/$domid/0/instance $2
406 fi
407 }