direct-io.hg

view tools/examples/vtpm-common.sh @ 13337:7ce714d3a9ac

Source a file called 'vtpm-impl.alt' if it exists.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
author Ewan Mellor <ewan@xensource.com>
date Thu Jan 11 18:55:18 2007 +0000 (2007-01-11)
parents f247e0b52dda
children
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.alt" ]; then
28 . "$dir/vtpm-impl.alt"
29 elif [ -r "$dir/vtpm-impl" ]; then
30 . "$dir/vtpm-impl"
31 else
32 function vtpm_create () {
33 true
34 }
35 function vtpm_setup() {
36 true
37 }
38 function vtpm_start() {
39 true
40 }
41 function vtpm_suspend() {
42 true
43 }
44 function vtpm_resume() {
45 true
46 }
47 function vtpm_delete() {
48 true
49 }
50 function vtpm_migrate() {
51 echo "Error: vTPM migration accross machines not implemented."
52 }
53 function vtpm_migrate_local() {
54 echo "Error: local vTPM migration not supported"
55 }
56 function vtpm_migrate_recover() {
57 true
58 }
59 fi
62 #Find the instance number for the vtpm given the name of the domain
63 # Parameters
64 # - vmname : the name of the vm
65 # Return value
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
70 vmname=$1
71 ret=0
73 instance=$(cat $VTPMDB | \
74 awk -vvmname=$vmname \
75 '{ \
76 if ( 1 != index($1,"#")) { \
77 if ( $1 == vmname ) { \
78 print $2; \
79 exit; \
80 } \
81 } \
82 }')
83 if [ "$instance" != "" ]; then
84 ret=$instance
85 fi
86 echo "$ret"
87 }
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
94 instance=$1
95 avail=1
96 #Allowed instance number range: 1-255
97 if [ $instance -eq 0 -o $instance -gt 255 ]; then
98 avail=0
99 else
100 instances=$(cat $VTPMDB | \
101 gawk \
102 '{ \
103 if (1 != index($1,"#")) { \
104 printf("%s ",$2); \
105 } \
106 }')
107 for i in $instances; do
108 if [ $i -eq $instance ]; then
109 avail=0
110 break
111 fi
112 done
113 fi
114 echo "$avail"
115 }
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 | \
123 gawk \
124 '{ \
125 if (1 != index($1,"#")) { \
126 printf("%s ",$2); \
127 } \
128 }')
129 ctr=1
130 don=0
131 while [ $don -eq 0 ]; do
132 found=0
133 for i in $instances; do
134 if [ $i -eq $ctr ]; then
135 found=1;
136 break;
137 fi
138 done
140 if [ $found -eq 0 ]; then
141 don=1
142 break
143 fi
144 let ctr=ctr+1
145 done
146 echo "$ctr"
147 }
150 # Add a domain name and instance number to the DB file
151 function vtpmdb_add_instance () {
152 local res vmname inst
153 vmname=$1
154 inst=$2
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
160 fi
161 res=$(vtpmdb_validate_entry $vmname $inst)
162 if [ $res -eq 0 ]; then
163 echo "$vmname $inst" >> $VTPMDB
164 fi
165 }
168 #Validate whether an entry is the same as passed to this
169 #function
170 function vtpmdb_validate_entry () {
171 local res rc vmname inst
172 rc=0
173 vmname=$1
174 inst=$2
176 res=$(cat $VTPMDB | \
177 gawk -vvmname=$vmname \
178 -vinst=$inst \
179 '{ \
180 if ( 1 == index($1,"#")) {\
181 } else \
182 if ( $1 == vmname && \
183 $2 == inst) { \
184 printf("1"); \
185 exit; \
186 } else \
187 if ( $1 == vmname || \
188 $2 == inst) { \
189 printf("2"); \
190 exit; \
191 } \
192 }')
194 if [ "$res" == "1" ]; then
195 rc=1
196 elif [ "$res" == "2" ]; then
197 rc=2
198 fi
199 echo "$rc"
200 }
203 #Remove an entry from the vTPM database given its domain name
204 #and instance number
205 function vtpmdb_remove_entry () {
206 local vmname instance VTPMDB_TMP
207 vmname=$1
208 instance=$2
209 VTPMDB_TMP="$VTPMDB".tmp
211 $(cat $VTPMDB | \
212 gawk -vvmname=$vmname \
213 '{ \
214 if ( $1 != vmname ) { \
215 print $0; \
216 } \
217 '} > $VTPMDB_TMP)
218 if [ -e $VTPMDB_TMP ]; then
219 mv -f $VTPMDB_TMP $VTPMDB
220 vtpm_delete $instance
221 else
222 log err "Error creating temporary file '$VTPMDB_TMP'."
223 fi
224 }
227 # Find the reason for the creation of this device:
228 # Returns 'resume' or 'create'
229 function vtpm_get_create_reason () {
230 local resume
231 resume=$(xenstore_read $XENBUS_PATH/resume)
232 if [ "$resume" == "True" ]; then
233 echo "resume"
234 else
235 echo "create"
236 fi
237 }
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
245 domname=$(xenstore_read "$XENBUS_PATH"/domain)
246 reason=$(vtpm_get_create_reason)
248 claim_lock vtpmdb
249 instance=$(vtpmdb_find_instance $domname)
251 if [ "$instance" == "0" -a "$reason" != "create" ]; then
252 release_lock vtpmdb
253 return
254 fi
256 if [ "$instance" == "0" ]; then
257 #Try to give the preferred instance to the domain
258 instance=$(xenstore_read "$XENBUS_PATH"/pref_instance)
259 if [ "$instance" != "" ]; then
260 res=$(vtpmdb_is_free_instancenum $instance)
261 if [ $res -eq 0 ]; then
262 instance=$(vtpmdb_get_free_instancenum)
263 fi
264 else
265 instance=$(vtpmdb_get_free_instancenum)
266 fi
268 vtpm_create $instance
270 if [ $vtpm_fatal_error -eq 0 ]; then
271 vtpmdb_add_instance $domname $instance
272 fi
273 else
274 if [ "$reason" == "resume" ]; then
275 vtpm_resume $instance
276 else
277 vtpm_start $instance
278 fi
279 fi
281 release_lock vtpmdb
283 xenstore_write $XENBUS_PATH/instance $instance
284 }
287 #Remove an instance when a VM is terminating or suspending.
288 #Since it is assumed that the VM will appear again, the
289 #entry is kept in the VTPMDB file.
290 function vtpm_remove_instance () {
291 local instance reason domname
292 #Stop script execution quietly if path does not exist (anymore)
293 xenstore-exists "$XENBUS_PATH"/domain
294 domname=$(xenstore_read "$XENBUS_PATH"/domain)
296 if [ "$domname" != "" ]; then
297 claim_lock vtpmdb
299 instance=$(vtpmdb_find_instance $domname)
301 if [ "$instance" != "0" ]; then
302 vtpm_suspend $instance
303 fi
305 release_lock vtpmdb
306 fi
307 }
310 #Remove an entry in the VTPMDB file given the domain's name
311 #1st parameter: The name of the domain
312 function vtpm_delete_instance () {
313 local instance
315 claim_lock vtpmdb
317 instance=$(vtpmdb_find_instance $1)
318 if [ "$instance" != "0" ]; then
319 vtpmdb_remove_entry $1 $instance
320 fi
322 release_lock vtpmdb
323 }
325 # Determine whether the given address is local to this machine
326 # Return values:
327 # "-1" : the given machine name is invalid
328 # "0" : this is not an address of this machine
329 # "1" : this is an address local to this machine
330 function vtpm_isLocalAddress() {
331 local addr res
332 addr=$(ping $1 -c 1 | \
333 gawk '{ print substr($3,2,length($3)-2); exit }')
334 if [ "$addr" == "" ]; then
335 echo "-1"
336 return
337 fi
338 res=$(ifconfig | grep "inet addr" | \
339 gawk -vaddr=$addr \
340 '{ \
341 if ( addr == substr($2, 6)) {\
342 print "1"; \
343 } \
344 }' \
345 )
346 if [ "$res" == "" ]; then
347 echo "0"
348 return
349 fi
350 echo "1"
351 }
353 # Perform a migration step. This function differentiates between migration
354 # to the local host or to a remote machine.
355 # Parameters:
356 # 1st: destination host to migrate to
357 # 2nd: name of the domain to migrate
358 # 3rd: the migration step to perform
359 function vtpm_migration_step() {
360 local res=$(vtpm_isLocalAddress $1)
361 if [ "$res" == "0" ]; then
362 vtpm_migrate $1 $2 $3
363 else
364 vtpm_migrate_local
365 fi
366 }
368 # Recover from migration due to an error. This function differentiates
369 # between migration to the local host or to a remote machine.
370 # Parameters:
371 # 1st: destination host the migration was going to
372 # 2nd: name of the domain that was to be migrated
373 # 3rd: the last successful migration step that was done
374 function vtpm_recover() {
375 local res
376 res=$(vtpm_isLocalAddress $1)
377 if [ "$res" == "0" ]; then
378 vtpm_migrate_recover $1 $2 $3
379 fi
380 }
383 #Determine the domain id given a domain's name.
384 #1st parameter: name of the domain
385 #return value: domain id or -1 if domain id could not be determined
386 function vtpm_domid_from_name () {
387 local id name ids
388 ids=$(xenstore-list /local/domain)
389 for id in $ids; do
390 name=$(xenstore_read /local/domain/$id/name)
391 if [ "$name" == "$1" ]; then
392 echo "$id"
393 return
394 fi
395 done
396 echo "-1"
397 }
400 #Add a virtual TPM instance number and its associated domain name
401 #to the VTPMDB file and activate usage of this virtual TPM instance
402 #by writing the instance number into the xenstore
403 #1st parm: name of virtual machine
404 #2nd parm: instance of assoicate virtual TPM
405 function vtpm_add_and_activate() {
406 local domid=$(vtpm_domid_from_name $1)
407 if [ "$domid" != "-1" ]; then
408 vtpmdb_add_instance $1 $2
409 xenstore-write backend/vtpm/$domid/0/instance $2
410 fi
411 }