]> sourceware.org Git - systemtap.git/blob - stap-client
Touch up warning message from stap-client
[systemtap.git] / stap-client
1 #!/bin/bash
2
3 # Compile server client for systemtap
4 #
5 # Copyright (C) 2008, 2009 Red Hat Inc.
6 #
7 # This file is part of systemtap, and is free software. You can
8 # redistribute it and/or modify it under the terms of the GNU General
9 # Public License (GPL); either version 2, or (at your option) any
10 # later version.
11
12 # This script examines the systemtap command line and packages the files and
13 # information needed to execute the command. This is then sent to a trusted
14 # systemtap server which will process the request and return the resulting
15 # kernel module (if requested) and any other information generated by the
16 # request. If a kernel module is generated, this script will load the module
17 # and execute it using 'staprun', if requested.
18
19 # Catch ctrl-c and other termination signals
20 trap 'terminate' SIGTERM
21 trap 'interrupt' SIGINT
22 trap 'ignore_signal' SIGHUP SIGPIPE
23
24 #-----------------------------------------------------------------------------
25 # Helper functions.
26 #-----------------------------------------------------------------------------
27 # function: configuration
28 function configuration {
29 # INSTALL-HOOK These settings work for running the client from the source tree
30 # INSTALL-HOOK using the dejagnu test harness and will be overridden at install
31 # INSTALL-HOOK time.
32 exec_prefix=
33 sysconfdir=`pwd`/net
34
35 # General configuration
36 tmpdir_prefix_client=stap.client
37 tmpdir_prefix_server=stap.server
38 avahi_service_tag=_stap._tcp
39 }
40
41 # function: initialization
42 function initialization {
43 our_host_name=`expr "$HOSTNAME" : "\\\([a-zA-Z0-9-]*\\\).*"`
44 our_domain_name=`expr "$HOSTNAME" : "$our_host_name\\\(.*\\\)"`
45
46 rc=0
47 wd=`pwd`
48 umask 0
49 staprun_running=0
50
51 # Default location for server certificates if we're not root
52 # Must be owned by us.
53 local uid uname
54 if test $EUID != 0; then
55 if test -e $HOME/.systemtap/ssl/client; then
56 if check_db $HOME/.systemtap/ssl/client $EUID $USER; then
57 local_ssl_dbs=$HOME/.systemtap/ssl/client
58 fi
59 fi
60 fi
61 # Additional location for all users. Must be owned by root.
62 if test "X$sysconfdir" != "X"; then
63 if test -e $sysconfdir/systemtap/ssl/client; then
64 if check_db $sysconfdir/systemtap/ssl/client 0 root; then
65 public_ssl_dbs=$sysconfdir/systemtap/ssl/client
66 fi
67 fi
68 fi
69
70 # Default options settings
71 p_phase=5
72 v_level=0
73 keep_temps=0
74 b_specified=0
75
76 # Default variable settings
77 find_all=
78
79 # Create a temporary directory to package things in
80 # Do this before parsing the command line so that there is a place
81 # to put -I and -R directories.
82 tmpdir_client=`mktemp -dt $tmpdir_prefix_client.XXXXXX` || \
83 fatal "Cannot create temporary directory " $tmpdir_client
84 tmpdir_env=`dirname $tmpdir_client`
85 }
86
87 # function: parse_options [ STAP-OPTIONS ]
88 #
89 # Examine the command line. We need not do much checking, but we do need to
90 # parse all options in order to discover the ones we're interested in.
91 # The server will take care of most situations and return the appropriate
92 # output.
93 #
94 function parse_options {
95 cmdline=
96 cmdline1=
97 cmdline2=
98 while test $# != 0
99 do
100 advance_p=0
101 dash_seen=0
102
103 # Start of a new token.
104 first_token=$1
105 until test $advance_p != 0
106 do
107 # Identify the next option
108 first_char=`expr "$first_token" : '\(.\).*'`
109 second_char=
110 if test $dash_seen = 0; then
111 if test "$first_char" = "-"; then
112 if test "$first_token" != "-"; then
113 # It's not a lone dash, so it's an option.
114 # Is it a long option (i.e. --option)?
115 second_char=`expr "$first_token" : '.\(.\).*'`
116 if test "X$second_char" = "X-"; then
117 long_option=`expr "$first_token" : '--\(.*\)=.*'`
118 test "X$long_option" != "X" || long_option=`expr "$first_token" : '--\(.*\)'`
119 case $long_option in
120 ssl)
121 process_ssl $first_token
122 ;;
123 server)
124 process_server $first_token
125 ;;
126 *)
127 # An unknown or unimportant option.
128 # Ignore it, but pass it on to the server.
129 cmdline2="$cmdline2 $first_token"
130 ;;
131 esac
132 advance_p=$(($advance_p + 1))
133 break
134 fi
135 # It's not a lone dash, or a long option, so it's a short option string.
136 # Remove the dash.
137 first_token=`expr "$first_token" : '-\(.*\)'`
138 dash_seen=1
139 first_char=`expr "$first_token" : '\(.\).*'`
140 cmdline2="$cmdline2 -"
141 fi
142 fi
143 if test $dash_seen = 0; then
144 # The dash has not been seen. This is either the script file
145 # name, a long argument or an argument to be passed to the probe module.
146 # If this is the first time, and -e has not been specified,
147 # then it could be the name of the script file.
148 if test "X$second_char" = "X-"; then
149 cmdline2="$cmdline2 $first_token"
150 elif test "X$e_script" = "X" -a "X$script_file" = "X"; then
151 script_file=$first_token
152 cmdline1="$cmdline2"
153 cmdline2=
154 elif test "$first_char" != "'"; then
155 cmdline2="$cmdline2 '$first_token'"
156 else
157 cmdline2="$cmdline2 $first_token"
158 fi
159 advance_p=$(($advance_p + 1))
160 break
161 fi
162 fi
163
164 # We are at the start of an option. Look at the first character.
165 case $first_char in
166 b)
167 b_specified=1
168 ;;
169 c)
170 get_arg $first_token "$2"
171 process_c "$stap_arg"
172 ;;
173 D)
174 get_arg $first_token $2
175 cmdline2="${cmdline2}D '$stap_arg'"
176 ;;
177 e)
178 get_arg $first_token "$2"
179 process_e "$stap_arg"
180 ;;
181 I)
182 get_arg $first_token $2
183 process_I $stap_arg
184 ;;
185 k)
186 keep_temps=1
187 ;;
188 l)
189 get_arg $first_token $2
190 cmdline2="${cmdline2}l '$stap_arg'"
191 ;;
192 m)
193 get_arg $first_token $2
194 process_m $stap_arg
195 ;;
196 o)
197 get_arg $first_token $2
198 process_o $stap_arg
199 ;;
200 p)
201 get_arg $first_token $2
202 process_p $stap_arg
203 ;;
204 r)
205 get_arg $first_token $2
206 cmdline2="${cmdline2}r '$stap_arg'"
207 ;;
208 R)
209 get_arg $first_token $2
210 process_R $stap_arg
211 ;;
212 s)
213 get_arg $first_token $2
214 cmdline2="${cmdline2}s '$stap_arg'"
215 ;;
216 v)
217 v_level=$(($v_level + 1))
218 ;;
219 x)
220 get_arg $first_token $2
221 cmdline2="${cmdline2}x '$stap_arg'"
222 ;;
223 *)
224 # An unknown or unimportant flag. Ignore it, but pass it on to the server.
225 ;;
226 esac
227
228 if test $advance_p = 0; then
229 # Just another flag character. Consume it.
230 cmdline2="$cmdline2$first_char"
231 first_token=`expr "$first_token" : '.\(.*\)'`
232 if test "X$first_token" = "X"; then
233 advance_p=$(($advance_p + 1))
234 fi
235 fi
236 done
237
238 # Consume the arguments we just processed.
239 while test $advance_p != 0
240 do
241 shift
242 advance_p=$(($advance_p - 1))
243 done
244 done
245
246 # If the script file was given and it's not '-', then replace it with its
247 # client-temp-name in the command string.
248 if test "X$script_file" != "X"; then
249 local local_name
250 if test "$script_file" != "-"; then
251 local_name=`generate_client_temp_name $script_file`
252 else
253 local_name=$script_file
254 fi
255 cmdline="$cmdline1 script/$local_name $cmdline2"
256 else
257 cmdline="$cmdline1 $cmdline2"
258 fi
259
260 # Processing based on final options settings
261 # Complete the list of local certificate databases
262 local_ssl_dbs="$additional_local_ssl_dbs $local_ssl_dbs"
263
264 # We must have at least one usable certificate database.
265 test "X$local_ssl_dbs" != "X " -o "X$public_ssl_dbs" != "X" || \
266 fatal "No usable certificate databases found"
267
268 # We can use any server if the phase is less than 5
269 if test $p_phase -lt 5; then
270 find_all="--all"
271 fi
272 }
273
274 # function: get_arg FIRSTWORD SECONDWORD
275 #
276 # Collect an argument to the given option
277 function get_arg {
278 # Remove first character.
279 local opt=`expr "$1" : '\(.\).*'`
280 local first=`expr "$1" : '.\(.*\)'`
281
282 # Advance to the next token, if the first one is exhausted.
283 if test "X$first" = "X"; then
284 shift
285 advance_p=$(($advance_p + 1))
286 first=$1
287 fi
288
289 test "X$first" != "X" || \
290 fatal "Missing argument to -$opt"
291
292 stap_arg="$first"
293 advance_p=$(($advance_p + 1))
294 }
295
296 # function: process_ssl ARGUMENT
297 #
298 # Process the --ssl option.
299 function process_ssl {
300 local db=`expr "$1" : '--ssl=\(.*\)'`
301
302 test "X$db" != "X" || \
303 fatal "Missing argument to --ssl"
304
305 check_db $db || return
306
307 additional_local_ssl_dbs="$additional_local_ssl_dbs $db"
308 }
309
310 # function: process_server ARGUMENT
311 #
312 # Process the --server option.
313 function process_server {
314 local spec=`expr "$1" : '--server=\(.*\)'`
315
316 test "X$spec" != "X" || \
317 fatal "Missing argument to --server"
318
319 specified_servers="$specified_servers $spec"
320 }
321
322 # function: process_c ARGUMENT
323 #
324 # Process the -c flag.
325 function process_c {
326 c_cmd="$1"
327 cmdline2="${cmdline2}c '$1'"
328 }
329
330 # function: process_e ARGUMENT
331 #
332 # Process the -e flag.
333 function process_e {
334 # Only the first -e option is recognized and it overrides any script file name
335 # which may have already been identified.
336 if test "X$e_script" = "X"; then
337 e_script="$1"
338 if test "X$script_file" != "X"; then
339 cmdline1="$cmdline1 $script_file $cmdline2"
340 cmdline2=
341 script_file=
342 fi
343 fi
344 cmdline2="${cmdline2}e '$1'"
345 }
346
347 # function: process_I ARGUMENT
348 #
349 # Process the -I flag.
350 function process_I {
351 local local_name=`include_file_or_directory tapsets $1`
352 test "X$local_name" != "X" || return
353 cmdline2="${cmdline2}I 'tapsets/$local_name'"
354 }
355
356 # function: process_m ARGUMENT
357 #
358 # Process the -m flag.
359 function process_m {
360 m_name="$1"
361 cmdline2="${cmdline2}m '$1'"
362 }
363
364 # function: process_o ARGUMENT
365 #
366 # Process the -o flag.
367 function process_o {
368 stdout_redirection="$1"
369 cmdline2="${cmdline2}o '$1'"
370 }
371
372 # function: process_p ARGUMENT
373 #
374 # Process the -p flag.
375 function process_p {
376 p_phase=$1
377 cmdline2="${cmdline2}p '$1'"
378 }
379
380 # function: process_R ARGUMENT
381 #
382 # Process the -R flag.
383 function process_R {
384 local local_name=`include_file_or_directory runtime $1`
385 test "X$local_name" != "X" || return
386 cmdline2="${cmdline2}R 'runtime/$local_name'"
387 }
388
389 # function: include_file_or_directory PREFIX NAME
390 #
391 # Include the given file or directory in the client's temporary
392 # tree to be sent to the server.
393 function include_file_or_directory {
394 # Add a symbolic link of the named file or directory to our temporary directory
395 local local_name=`generate_client_temp_name $2`
396 mkdir -p $tmpdir_client/$1/`dirname $local_name` || \
397 fatal "Could not create $tmpdir_client/$1/`dirname $local_name`"
398 ln -s /$local_name $tmpdir_client/$1/$local_name || \
399 fatal "Could not link $tmpdir_client/$1/$local_name to /$local_name"
400 echo "$local_name"
401 }
402
403 # function: generate_client_temp_name NAME
404 #
405 # Generate the name to be used for the given file/directory relative to the
406 # client's temporary directory.
407 function generate_client_temp_name {
408 # Transform the name into a fully qualified path name
409 local full_name=`echo "$1" | sed "s,^\\\([^/]\\\),$wd/\\\\1,"`
410
411 # The same name without the initial / or trailing /
412 local local_name=`echo "$full_name" | sed 's,^/\(.*\),\1,'`
413 local_name=`echo "$local_name" | sed 's,\(.*\)/$,\1,'`
414 echo "$local_name"
415 }
416
417 # function: create_request
418 #
419 # Add information to the client's temp directory representing the request
420 # to the server.
421 function create_request {
422 # Work in our temporary directory
423 cd $tmpdir_client
424
425 if test "X$script_file" != "X"; then
426 if test "$script_file" = "-"; then
427 mkdir -p $tmpdir_client/script || \
428 fatal "Cannot create temporary directory " $tmpdir_client/script
429 cat > $tmpdir_client/script/$script_file
430 else
431 include_file_or_directory script $script_file > /dev/null
432 fi
433 fi
434
435 # Add the necessary info to special files in our temporary directory.
436 echo "cmdline: $cmdline" > cmdline
437 echo "sysinfo: `client_sysinfo`" > sysinfo
438 }
439
440 # function client_sysinfo
441 #
442 # Generate the client's sysinfo and echo it to stdout
443 function client_sysinfo {
444 if test "X$sysinfo_client" = "X"; then
445 # Add some info from uname
446 sysinfo_client="`uname -rvm`"
447 fi
448 echo "$sysinfo_client"
449 }
450
451 # function: package_request
452 #
453 # Package the client's temp directory into a form suitable for sending to the
454 # server.
455 function package_request {
456 # Package up the temporary directory into a zip file
457 cd $tmpdir_env
458
459 local tmpdir_client_base=`basename $tmpdir_client`
460 zip_client=$tmpdir_env/`mktemp $tmpdir_client_base.zip.XXXXXX` || \
461 fatal "Cannot create temporary file " $zip_client
462
463 (rm $zip_client && zip -r $zip_client $tmpdir_client_base > /dev/null) || \
464 fatal "zip of request tree, $tmpdir_client, failed"
465 }
466
467 # function: unpack_response
468 #
469 # Unpack the jar file received from the server and make the contents available
470 # for printing the results and/or running 'staprun'.
471 function unpack_response {
472 tmpdir_server=`mktemp -dt $tmpdir_prefix_client.server.XXXXXX` || \
473 fatal "Cannot create temporary file " $tmpdir_server
474
475 # Unpack and verify the digitally signed server output directory
476 if ! signtool -d $ssl_db -v $jar_server > /dev/null 2>&1; then
477 # Run the verification again to get the reason
478 fatal "Verification of server response, $jar_server, failed.
479 "`signtool -d $ssl_db -v $jar_server | grep "reported reason"`
480 fi
481
482 # Unpack the server output directory
483 unzip -d $tmpdir_server $jar_server > /dev/null || \
484 fatal "Cannot unpack server response, $jar_server"
485
486 # Check the contents of the expanded directory. It should contain:
487 # 1) a file called stdout
488 # 2) a file called stderr
489 # 3) a file called rc
490 # 4) a directory called META-INF
491 # 5) optionally a directory named to match stap??????
492 local num_files=`ls $tmpdir_server | wc -l`
493 test $num_files = 5 -o $num_files = 4 || \
494 fatal "Wrong number of files in server's temp directory"
495 test -f $tmpdir_server/stdout || \
496 fatal "`pwd`/$tmpdir_server/stdout does not exist or is not a regular file"
497 test -f $tmpdir_server/stderr || \
498 fatal "`pwd`/$tmpdir_server/stderr does not exist or is not a regular file"
499 test -f $tmpdir_server/rc || \
500 fatal "`pwd`/$tmpdir_server/rc does not exist or is not a regular file"
501 test -d $tmpdir_server/META-INF || \
502 fatal "`pwd`/$tmpdir_server/META-INF does not exist or is not a directory"
503
504 # See if there is a systemtap temp directory
505 tmpdir_stap=`cd $tmpdir_server && ls | grep stap......\$ 2>/dev/null`
506 if test "X$tmpdir_stap" != "X"; then
507 test -d $tmpdir_server/$tmpdir_stap || \
508 fatal "$tmpdir_server/$tmpdir_stap is not a directory"
509
510 # Move the systemtap temp directory to a local temp location, if -k
511 # was specified.
512 if test $keep_temps = 1; then
513 local local_tmpdir_stap=`mktemp -dt stapXXXXXX` || \
514 fatal "Cannot create temporary directory " $local_tmpdir_stap
515 mv $tmpdir_server/$tmpdir_stap/* $local_tmpdir_stap 2>/dev/null
516 rm -fr $tmpdir_server/$tmpdir_stap
517
518 # Correct the name of the temp directory in the server's stderr output
519 sed -i "s,^Keeping temporary directory.*,Keeping temporary directory \"$local_tmpdir_stap\"," $tmpdir_server/stderr
520 tmpdir_stap=$local_tmpdir_stap
521 else
522 # Make sure we own the systemtap temp directory if we are root.
523 test $EUID = 0 && chown $EUID:$EUID $tmpdir_server/$tmpdir_stap
524 fi
525 fi
526 }
527
528 # function: find_and_connect_to_server
529 #
530 # Find and establish connection with a compatible stap server.
531 function find_and_connect_to_server {
532 local num_servers=0
533
534 # Make a place to receive the response file.
535 jar_server=`mktemp -t $tmpdir_prefix_client.server.jar.XXXXXX` || \
536 fatal "Cannot create temporary file " $jar_server
537
538 # Make a place to record connection errors
539 touch $tmpdir_client/connect
540
541 # If servers were specified on the command line, then try them
542 # in sequence. Don't try any other servers.
543 if test "X$specified_servers" != "X"; then
544 for server in $specified_servers; do
545 num_servers=$(($num_servers + 1))
546
547 # If the server is completely specified, (i.e. server:port),
548 # then try it directly.
549 port=`expr "$server" : '.\+:\([0-9]\+\)'`
550 if test "X$port" != "X"; then
551 name=`expr "$server" : '\(.\+\):[0-9]\+'`
552
553 # If we have been given an ip address, then try to resolve it to a name.
554 # If we have been given a name, try to resolve the full name.
555 # The full name is needed in order to validate the server's certificate.
556 address=`expr "$name" : '\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\)'`
557 if test "X$address" = "X"; then
558 # We've been given a host name
559 full_name=`nslookup $name | awk '/^Name\:/ {print $2}'`
560 if test "X$full_name" != "X"; then
561 name=$full_name
562 fi
563 else
564 # We've been given an ip address.
565 name=`nslookup $address | awk '/in-addr\.arpa/ {print $4}'`
566 name=`expr "$name" : '\(.*\)\.'`
567 if test "X$name" = "X"; then
568 echo "Cannot resolve ip address $address" >> $tmpdir_client/connect
569 continue
570 fi
571 fi
572
573 # Now try to contact the given server.
574 ssl_db=`send_receive $name $port`
575 test "X$ssl_db" != "X" && return
576 continue
577 fi
578
579 # Otherwise select the matching server from the available servers
580 # and use the port it is advertizing.
581 #
582 # Have we been given an ip address? If so, just use it.
583 address=`expr "$server" : '\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\)'`
584 if test "X$address" = "X"; then
585 # We have not been given an ip address. Try to resolve it as a host name.
586 if test "X$server" = "Xlocalhost"; then
587 # We don't want the address of the loopback interface here. Avahi will present
588 # the actual ip address.
589 server=$our_host_name$our_domain_name
590 fi
591 address=`nslookup $server | awk '/^Address\:[ \t][0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/ {print $2}'`
592 if test "X$address" = "X"; then
593 echo "Cannot resolve server $server" >> $tmpdir_client/connect
594 continue
595 fi
596 fi
597
598 if test `${exec_prefix}stap-find-servers $find_all | grep $address | wc -l` = "0"; then
599 warning "No server is available on $server" 2>> $tmpdir_client/connect
600 continue
601 fi
602
603 ssl_db=`${exec_prefix}stap-find-servers $find_all | grep $address | choose_server`
604 test "X$ssl_db" != "X" && return
605 done
606 else
607 # No servers specified. Find available servers and choose one of them.
608 # Remember which ssl certificate database was used to authenticate the chosen
609 # server.
610 ssl_db=`${exec_prefix}stap-find-servers $find_all | choose_server`
611 test "X$ssl_db" != "X" && return
612
613 num_servers=`${exec_prefix}stap-find-servers $find_all | wc -l`
614 fi
615
616 if test $num_servers = 0; then
617 fatal "Unable to find a server"
618 fi
619
620 cat $tmpdir_client/connect >&2
621 fatal "Unable to connect to a server"
622 }
623
624 # function: choose_server
625 #
626 # Examine each line from stdin and attempt to connect to each server
627 # specified until successful.
628 # echo the name of the ssl certificate database used to successfully authenticate
629 # the server.
630 function choose_server {
631 local name ip port remain
632
633 while read name ip port remain
634 do
635 if test "X$name" = "X"; then
636 fatal "Server name not provided by avahi"
637 fi
638
639 # if test "X$ip" = "X"; then
640 # fatal "Server ip address not provided by avahi"
641 # fi
642
643 if test "X$port" = "X"; then
644 fatal "Server port not provided by avahi"
645 fi
646
647 ssl_db=`send_receive $name $port`
648 test "X$ssl_db" != "X" && echo $ssl_db && return
649 done
650 }
651
652 # function: send_receive SERVER PORT
653 #
654 # Connect to the server, send the request and receive the response
655 # echo the name of the ssl certificate database used to successfully authenticate
656 # the server.
657 function send_receive {
658 local server=$1
659 local port=$2
660
661 # The server must match the dns name on the certificate
662 # and must be 'localhost' if the server is on the local host.
663 local server_host_name=`expr "$server" : "\\\([a-zA-Z0-9-]*\\\).*"`
664 local server_domain_name=`expr "$server" : "$server_host_name\\\(.*\\\)"`
665
666 if test "X$server_domain_name" = "X.local"; then
667 server_domain_name=$our_domain_name
668 fi
669 if test "X$server_host_name$server_domain_name" = "Xlocalhost$our_domain_name"; then
670 server=localhost
671 elif test "X$server_host_name$server_domain_name" = "X$our_host_name$our_domain_name"; then
672 server=localhost
673 else
674 server=$server_host_name$server_domain_name
675 fi
676
677 # Try to connect using each of the given local certificate databases in turn
678 # for verification.
679 for db in $local_ssl_dbs
680 do
681 # Send the request and receive the response using stap-client-connect
682 echo "Attempting connection with $server:$port using certificate database in '$db'" >> $tmpdir_client/connect
683 ${exec_prefix}stap-client-connect -i $zip_client -o $jar_server -d $db -p $port -h $server >> $tmpdir_client/connect 2>&1 &
684 wait '%${exec_prefix}stap-client-connect'
685 test $? = 0 && echo $db && return
686 sleep 1
687 done
688
689 # Next, try the public certificate databases.
690 for db in $public_ssl_dbs
691 do
692 # Send the request and receive the response using stap-client-connect
693 echo "Attempting connection with $server:$port using certificate database in '$db'" >> $tmpdir_client/connect
694 ${exec_prefix}stap-client-connect -i $zip_client -o $jar_server -d $db -p $port -h $server >> $tmpdir_client/connect 2>&1 &
695 wait '%${exec_prefix}stap-client-connect'
696 test $? = 0 && echo $db && return
697 sleep 1
698 done
699
700 # Could not connect using any of the certificate databases
701 }
702
703 # function: process_response
704 #
705 # Write the stdout and stderr from the server to stdout and stderr respectively.
706 function process_response {
707 # Pick up the results of running stap on the server.
708 cd $tmpdir_server
709 rc=`cat rc`
710
711 # Copy the module to the current directory, if -m was specified
712 if test "X$m_name" != "X"; then
713 if test -f $tmpdir_stap/$m_name.ko; then
714 cp $tmpdir_stap/$m_name.ko $wd
715 else
716 stream_output
717 fatal "module $tmpdir_stap/$m_name.ko does not exist"
718 fi
719 fi
720
721 # Output stdout and stderr as directed
722 stream_output
723 }
724
725 # function: stream_output
726 #
727 # Output stdout and stderr as directed
728 function stream_output {
729 cd $tmpdir_server
730 cat stderr >&2
731 cat stdout
732 }
733
734 # function: maybe_call_staprun
735 #
736 # Call staprun using the module returned from the server, if requested.
737 function maybe_call_staprun {
738 if test $rc != 0; then
739 # stap run on the server failed, so don't bother
740 return
741 fi
742
743 if test $p_phase -ge 4; then
744 # There should be a systemtap temporary directory.
745 if test "X$tmpdir_stap" = "X"; then
746 # OK if no script specified
747 if test "X$e_script" != "X" -o "X$script_file" != "X"; then
748 fatal "systemtap temporary directory is missing in server response"
749 fi
750 return
751 fi
752
753 # There should be a module.
754 local mod_name=`ls $tmpdir_stap | grep '.ko$'`
755 if test "X$mod_name" = "X"; then
756 fatal "No module was found in $tmpdir_stap"
757 fi
758
759 if test $p_phase = 5; then
760 test $v_level -gt 0 && echo "Pass 5: starting run." >&2
761
762 # We have a module. Try to run it
763 # If a -c command was specified, pass it along.
764 if test "X$c_cmd" != "X"; then
765 staprun_opts="-c '$c_cmd'"
766 fi
767
768 # The -v level will be one less than what was specified
769 # for us.
770 for ((vl=$((v_level - 1)); $vl > 0; --vl))
771 do
772 staprun_opts="$staprun_opts -v"
773 done
774
775 # if -o was specified, pass it along
776 if test "X$stdout_redirection" != "X"; then
777 staprun_opts="$staprun_opts -o $stdout_redirection"
778 fi
779
780 # Run it in the background and wait for it. This
781 # way any signals send to us can be caught.
782 if test $v_level -ge 2; then
783 echo "running `which staprun` $staprun_opts $tmpdir_stap/`ls $tmpdir_stap | grep '.ko$'`" >&2
784 fi
785 eval `staprun_PATH` "$staprun_opts" \
786 $tmpdir_stap/`ls $tmpdir_stap | grep '.ko$'`
787 staprun_running=1
788 wait '%?staprun' > /dev/null 2>&1
789 rc=$?
790 staprun_running=0
791 # 127 from wait means that the job was already finished.
792 test $rc=127 && rc=0
793
794 # Wait until the job actually disappears so that its output is complete.
795 while jobs '%?staprun' >/dev/null 2>&1
796 do
797 sleep 1
798 done
799
800 test $v_level -gt 0 && echo "Pass 5: run completed in 0usr/0sys/0real ms." >&2
801 fi
802 fi
803 }
804
805 # function: staprun_PATH
806 #
807 # Compute a PATH suitable for running staprun.
808 function staprun_PATH {
809 # If $SYSTEMTAP_STAPRUN is set, then use that
810 if test "X$SYSTEMTAP_STAPRUN" != "X"; then
811 echo $SYSTEMTAP_STAPRUN
812 return
813 fi
814
815 # Otherwise, if there is an exec_prefix, then use it.
816 if test "X$exec_prefix" != "X"; then
817 echo ${exec_prefix}staprun
818 return
819 fi
820
821 # Otherwise, we have been called by the dejagnu test harness as 'stap'
822 # and we are the first 'stap' on the path. Since staprun may call
823 # 'stap', remove the PATH component where we live from the PATH in order to
824 # avoid recursion.
825 local first_stap=`which stap`
826 local PATH_component=`dirname $first_stap`
827 echo "PATH=$PATH staprun" | sed "s,$PATH_component,,g"
828 }
829
830 # function: check_db DBNAME [ EUID USER ]
831 #
832 # Check the security of the given database directory.
833 function check_db {
834 local dir=$1
835 local euid=$2
836 local user=$3
837 local rc=0
838
839 # Check that we have been given a directory
840 if ! test -e $dir; then
841 warning "Certificate database '$dir' does not exist"
842 return 1
843 fi
844 if ! test -d $dir; then
845 warning "Certificate database '$dir' is not a directory"
846 return 1
847 fi
848
849 # If euid has been specified, then this directory must be owned by that
850 # user.
851 if test "X$euid" != "X"; then
852 local ownerid=`stat -c "%u" $dir`
853 if test "X$ownerid" != "X$euid"; then
854 warning "Certificate database '$dir' must be owned by $user"
855 rc=1
856 fi
857 fi
858
859 # Check that we can read the directory
860 if ! test -r $dir; then
861 warning "Certificate database '$dir' is not readble"
862 rc=1
863 fi
864
865 # Check the access permissions of the directory
866 local perm=0`stat -c "%a" $dir`
867 if test $((($perm & 0400) == 0400)) = 0; then
868 warning "Certificate database '$dir' should be readable by the owner"
869 fi
870 if test $((($perm & 0200) == 0200)) = 0; then
871 warning "Certificate database '$dir' should be writeable by the owner"
872 fi
873 if test $((($perm & 0100) == 0100)) = 0; then
874 warning "Certificate database '$dir' should be searchable by the owner"
875 fi
876 if test $((($perm & 0040) == 0040)) = 0; then
877 warning "Certificate database '$dir' should be readable by the group"
878 fi
879 if test $((($perm & 0020) == 0020)) = 1; then
880 warning "Certificate database '$dir' must not be writable by the group"
881 rc=1
882 fi
883 if test $((($perm & 0010) == 0010)) = 0; then
884 warning "Certificate database '$dir' should be searchable by the group"
885 fi
886 if test $((($perm & 0004) == 0004)) = 0; then
887 warning "Certificate database '$dir' should be readable by others"
888 fi
889 if test $((($perm & 0002) == 0002)) = 1; then
890 warning "Certificate database '$dir' must not be writable by others"
891 rc=1
892 fi
893 if test $((($perm & 0001) == 0001)) = 0; then
894 warning "Certificate database '$dir' should be searchable by others"
895 fi
896
897 # Now check the permissions of the critical files.
898 check_db_file $dir/cert8.db $euid $user || rc=1
899 check_db_file $dir/key3.db $euid $user || rc=1
900 check_db_file $dir/secmod.db $euid $user || rc=1
901
902 test $rc = 1 && warning "Unable to use certificate database '$dir' due to errors"
903
904 return $rc
905 }
906
907 # function: check_db_file FILENAME [ EUID USER ]
908 #
909 # Check the security of the given database file.
910 function check_db_file {
911 local file=$1
912 local rc=0
913
914 # Check that we have been given a file
915 if ! test -e $file; then
916 warning "Certificate database file '$file' does not exist"
917 return 1
918 fi
919 if ! test -f $file; then
920 warning "Certificate database file '$file' is not a regular file"
921 return 1
922 fi
923
924 # If euid has been specified, then this directory must be owned by that
925 # user.
926 if test "X$euid" != "X"; then
927 local ownerid=`stat -c "%u" $file`
928 if test "X$ownerid" != "X$euid"; then
929 warning "Certificate database file '$file' must be owned by $user"
930 rc=1
931 fi
932 fi
933
934 # Check that we can read the file
935 if ! test -r $file; then
936 warning "Certificate database file '$file' is not readble"
937 rc=1
938 fi
939
940 # Check the access permissions of the file
941 local perm=0`stat -c "%a" $file`
942 if test $((($perm & 0400) == 0400)) = 0; then
943 warning "Certificate database file '$file' should be readable by the owner"
944 fi
945 if test $((($perm & 0200) == 0200)) = 0; then
946 warning "Certificate database file '$file' should be writeable by the owner"
947 fi
948 if test $((($perm & 0100) == 0100)) = 1; then
949 warning "Certificate database file '$file' must not be executable by the owner"
950 rc=1
951 fi
952 if test $((($perm & 0040) == 0040)) = 0; then
953 warning "Certificate database file '$file' should be readable by the group"
954 fi
955 if test $((($perm & 0020) == 0020)) = 1; then
956 warning "Certificate database file '$file' must not be writable by the group"
957 rc=1
958 fi
959 if test $((($perm & 0010) == 0010)) = 1; then
960 warning "Certificate database file '$file' must not be executable by the group"
961 rc=1
962 fi
963 if test $((($perm & 0004) == 0004)) = 0; then
964 warning "Certificate database file '$file' should be readable by others"
965 fi
966 if test $((($perm & 0002) == 0002)) = 1; then
967 warning "Certificate database file '$file' must not be writable by others"
968 rc=1
969 fi
970 if test $((($perm & 0001) == 0001)) = 1; then
971 warning "Certificate database file '$file' must not be executable by others"
972 rc=1
973 fi
974
975 return $rc
976 }
977
978 # function: warning [ MESSAGE ]
979 #
980 # Warning error
981 # Prints its arguments to stderr
982 function warning {
983 echo "$0: WARNING:" "$@" >&2
984 }
985
986 # function: fatal [ MESSAGE ]
987 #
988 # Fatal error
989 # Prints its arguments to stderr and exits
990 function fatal {
991 echo "$0: ERROR:" "$@" >&2
992 cleanup
993 exit 1
994 }
995
996 # function cleanup
997 #
998 # Cleanup work files unless asked to keep them.
999 function cleanup {
1000 # Clean up.
1001 cd $tmpdir_env
1002 if test $keep_temps != 1; then
1003 rm -fr $tmpdir_client
1004 rm -f $zip_client
1005 rm -f $jar_server
1006 rm -fr $tmpdir_server
1007 fi
1008 }
1009
1010 # function: terminate
1011 #
1012 # Terminate gracefully.
1013 function terminate {
1014 # Clean up
1015 echo "$0: terminated by signal" >&2
1016 cleanup
1017
1018 # Kill any running staprun job
1019 kill -s SIGTERM '%?staprun' 2>/dev/null
1020
1021 # Kill any stap-client-connect job
1022 kill -s SIGTERM '%${exec_prefix}stap-client-connect'
1023
1024 exit 1
1025 }
1026
1027 # function: interrupt
1028 #
1029 # Pass an interrupt (ctrl-C) to staprun
1030 function interrupt {
1031 # Pass the signal on to any running staprun job
1032 if test $staprun_running = 1; then
1033 kill -s SIGINT '%?staprun' 2>/dev/null
1034 return
1035 fi
1036
1037 # Kill any stap-client-connect job
1038 # SIGINT won't do it.
1039 kill -s SIGTERM '%${exec_prefix}stap-client-connect'
1040
1041 # If staprun was not running, then exit.
1042 cleanup
1043 exit 1
1044 }
1045
1046 # function: ignore_signal
1047 #
1048 # Called in order to ignore a signal
1049 function ignore_signal {
1050 :
1051 }
1052
1053 #-----------------------------------------------------------------------------
1054 # Beginning of main line execution.
1055 #-----------------------------------------------------------------------------
1056 configuration
1057 initialization
1058 parse_options "$@"
1059 create_request
1060 package_request
1061 find_and_connect_to_server
1062 unpack_response
1063 process_response
1064 maybe_call_staprun
1065 cleanup
1066
1067 exit $rc
This page took 0.091965 seconds and 6 git commands to generate.