ia64/xen-unstable

view tools/examples/vtpm-common.sh @ 11100:905ff6e616cc

[HVM] Add stubs to Linux for the new hvm_op hypercall.
Signed-off-by: Steven Smith <ssmith@xensource.com>
author kfraser@localhost.localdomain
date Mon Aug 14 11:33:50 2006 +0100 (2006-08-14)
parents 28b766e3bcca
children 536c25a9654d
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_recover() {
52 true
53 }
54 fi
57 #Find the instance number for the vtpm given the name of the domain
58 # Parameters
59 # - vmname : the name of the vm
60 # Return value
61 # Returns '0' if instance number could not be found, otherwise
62 # it returns the instance number in the variable 'instance'
63 function vtpmdb_find_instance () {
64 local vmname ret instance
65 vmname=$1
66 ret=0
68 instance=$(cat $VTPMDB | \
69 awk -vvmname=$vmname \
70 '{ \
71 if ( 1 != index($1,"#")) { \
72 if ( $1 == vmname ) { \
73 print $2; \
74 exit; \
75 } \
76 } \
77 }')
78 if [ "$instance" != "" ]; then
79 ret=$instance
80 fi
81 echo "$ret"
82 }
85 # Check whether a particular instance number is still available
86 # returns "0" if it is not available, "1" otherwise.
87 function vtpmdb_is_free_instancenum () {
88 local instance instances avail i
89 instance=$1
90 avail=1
91 #Allowed instance number range: 1-255
92 if [ $instance -eq 0 -o $instance -gt 255 ]; then
93 avail=0
94 else
95 instances=$(cat $VTPMDB | \
96 gawk \
97 '{ \
98 if (1 != index($1,"#")) { \
99 printf("%s ",$2); \
100 } \
101 }')
102 for i in $instances; do
103 if [ $i -eq $instance ]; then
104 avail=0
105 break
106 fi
107 done
108 fi
109 echo "$avail"
110 }
113 # Get an available instance number given the database
114 # Returns an unused instance number
115 function vtpmdb_get_free_instancenum () {
116 local ctr instances don found
117 instances=$(cat $VTPMDB | \
118 gawk \
119 '{ \
120 if (1 != index($1,"#")) { \
121 printf("%s ",$2); \
122 } \
123 }')
124 ctr=1
125 don=0
126 while [ $don -eq 0 ]; do
127 found=0
128 for i in $instances; do
129 if [ $i -eq $ctr ]; then
130 found=1;
131 break;
132 fi
133 done
135 if [ $found -eq 0 ]; then
136 don=1
137 break
138 fi
139 let ctr=ctr+1
140 done
141 echo "$ctr"
142 }
145 # Add a domain name and instance number to the DB file
146 function vtpmdb_add_instance () {
147 local res vmname inst
148 vmname=$1
149 inst=$2
151 if [ ! -f $VTPMDB ]; then
152 echo "#Database for VM to vTPM association" > $VTPMDB
153 echo "#1st column: domain name" >> $VTPMDB
154 echo "#2nd column: TPM instance number" >> $VTPMDB
155 fi
156 res=$(vtpmdb_validate_entry $vmname $inst)
157 if [ $res -eq 0 ]; then
158 echo "$vmname $inst" >> $VTPMDB
159 fi
160 }
163 #Validate whether an entry is the same as passed to this
164 #function
165 function vtpmdb_validate_entry () {
166 local res rc vmname inst
167 rc=0
168 vmname=$1
169 inst=$2
171 res=$(cat $VTPMDB | \
172 gawk -vvmname=$vmname \
173 -vinst=$inst \
174 '{ \
175 if ( 1 == index($1,"#")) {\
176 } else \
177 if ( $1 == vmname && \
178 $2 == inst) { \
179 printf("1"); \
180 exit; \
181 } else \
182 if ( $1 == vmname || \
183 $2 == inst) { \
184 printf("2"); \
185 exit; \
186 } \
187 }')
189 if [ "$res" == "1" ]; then
190 rc=1
191 elif [ "$res" == "2" ]; then
192 rc=2
193 fi
194 echo "$rc"
195 }
198 #Remove an entry from the vTPM database given its domain name
199 #and instance number
200 function vtpmdb_remove_entry () {
201 local vmname instance VTPMDB_TMP
202 vmname=$1
203 instance=$2
204 VTPMDB_TMP="$VTPMDB".tmp
206 $(cat $VTPMDB | \
207 gawk -vvmname=$vmname \
208 '{ \
209 if ( $1 != vmname ) { \
210 print $0; \
211 } \
212 '} > $VTPMDB_TMP)
213 if [ -e $VTPMDB_TMP ]; then
214 mv -f $VTPMDB_TMP $VTPMDB
215 vtpm_delete $instance
216 else
217 log err "Error creating temporary file '$VTPMDB_TMP'."
218 fi
219 }
222 # Find the reason for the creation of this device:
223 # Returns 'resume' or 'create'
224 function vtpm_get_create_reason () {
225 local resume
226 resume=$(xenstore-read $XENBUS_PATH/resume)
227 if [ "$resume" == "True" ]; then
228 echo "resume"
229 else
230 echo "create"
231 fi
232 }
235 #Create a vTPM instance
236 # If no entry in the TPM database is found, the instance is
237 # created and an entry added to the database.
238 function vtpm_create_instance () {
239 local res instance domname reason
240 domname=$(xenstore_read "$XENBUS_PATH"/domain)
241 reason=$(vtpm_get_create_reason)
243 claim_lock vtpmdb
244 instance=$(vtpmdb_find_instance $domname)
246 if [ "$instance" == "0" -a "$reason" != "create" ]; then
247 release_lock vtpmdb
248 return
249 fi
251 if [ "$instance" == "0" ]; then
252 #Try to give the preferred instance to the domain
253 instance=$(xenstore_read "$XENBUS_PATH"/pref_instance)
254 if [ "$instance" != "" ]; then
255 res=$(vtpmdb_is_free_instancenum $instance)
256 if [ $res -eq 0 ]; then
257 instance=$(vtpmdb_get_free_instancenum)
258 fi
259 else
260 instance=$(vtpmdb_get_free_instancenum)
261 fi
263 vtpm_create $instance
265 if [ $vtpm_fatal_error -eq 0 ]; then
266 vtpmdb_add_instance $domname $instance
267 fi
268 else
269 if [ "$reason" == "resume" ]; then
270 vtpm_resume $instance
271 else
272 vtpm_start $instance
273 fi
274 fi
276 release_lock vtpmdb
278 xenstore_write $XENBUS_PATH/instance $instance
279 }
282 #Remove an instance when a VM is terminating or suspending.
283 #Since it is assumed that the VM will appear again, the
284 #entry is kept in the VTPMDB file.
285 function vtpm_remove_instance () {
286 local instance reason domname
287 domname=$(xenstore_read "$XENBUS_PATH"/domain)
289 if [ "$domname" != "" ]; then
290 claim_lock vtpmdb
292 instance=$(vtpmdb_find_instance $domname)
294 if [ "$instance" != "0" ]; then
295 vtpm_suspend $instance
296 fi
298 release_lock vtpmdb
299 fi
300 }
303 #Remove an entry in the VTPMDB file given the domain's name
304 #1st parameter: The name of the domain
305 function vtpm_delete_instance () {
306 local instance
308 claim_lock vtpmdb
310 instance=$(vtpmdb_find_instance $1)
311 if [ "$instance" != "0" ]; then
312 vtpmdb_remove_entry $1 $instance
313 fi
315 release_lock vtpmdb
316 }
318 # Determine whether the given address is local to this machine
319 # Return values:
320 # "-1" : the given machine name is invalid
321 # "0" : this is not an address of this machine
322 # "1" : this is an address local to this machine
323 function vtpm_isLocalAddress() {
324 local addr res
325 addr=$(ping $1 -c 1 | \
326 gawk '{ print substr($3,2,length($3)-2); exit }')
327 if [ "$addr" == "" ]; then
328 echo "-1"
329 return
330 fi
331 res=$(ifconfig | grep "inet addr" | \
332 gawk -vaddr=$addr \
333 '{ \
334 if ( addr == substr($2, 6)) {\
335 print "1"; \
336 } \
337 }' \
338 )
339 if [ "$res" == "" ]; then
340 echo "0"
341 return
342 fi
343 echo "1"
344 }
346 # Perform a migration step. This function differentiates between migration
347 # to the local host or to a remote machine.
348 # Parameters:
349 # 1st: destination host to migrate to
350 # 2nd: name of the domain to migrate
351 # 3rd: the migration step to perform
352 function vtpm_migration_step() {
353 local res=$(vtpm_isLocalAddress $1)
354 if [ "$res" == "0" ]; then
355 vtpm_migrate $1 $2 $3
356 fi
357 }
359 # Recover from migration due to an error. This function differentiates
360 # between migration to the local host or to a remote machine.
361 # Parameters:
362 # 1st: destination host the migration was going to
363 # 2nd: name of the domain that was to be migrated
364 # 3rd: the last successful migration step that was done
365 function vtpm_recover() {
366 local res
367 res=$(vtpm_isLocalAddress $1)
368 if [ "$res" == "0" ]; then
369 vtpm_migrate_recover $1 $2 $3
370 fi
371 }
374 #Determine the domain id given a domain's name.
375 #1st parameter: name of the domain
376 #return value: domain id or -1 if domain id could not be determined
377 function vtpm_domid_from_name () {
378 local id name ids
379 ids=$(xenstore-list /local/domain)
380 for id in $ids; do
381 name=$(xenstore-read /local/domain/$id/name)
382 if [ "$name" == "$1" ]; then
383 echo "$id"
384 return
385 fi
386 done
387 echo "-1"
388 }
391 #Add a virtual TPM instance number and its associated domain name
392 #to the VTPMDB file and activate usage of this virtual TPM instance
393 #by writing the instance number into the xenstore
394 #1st parm: name of virtual machine
395 #2nd parm: instance of assoicate virtual TPM
396 function vtpm_add_and_activate() {
397 local domid=$(vtpm_domid_from_name $1)
398 if [ "$domid" != "-1" ]; then
399 vtpmdb_add_instance $1 $2
400 xenstore-write backend/vtpm/$domid/0/instance $2
401 fi
402 }