load_lib site.exp proc installtest_p {} { global TOOL_OPTIONS if {[info exists TOOL_OPTIONS] && [string match "*install*" $TOOL_OPTIONS]} { return 1 } else { return 0 } } proc use_server_p {} { global TOOL_OPTIONS if {[info exists TOOL_OPTIONS] && [string match "*server*" $TOOL_OPTIONS]} { return 1 } else { return 0 } } proc utrace_p {} { set path "/proc/kallsyms" if {! [catch {exec grep -q utrace_attach $path} dummy]} { return 1 } else { return 0 } } proc print_systemtap_version {} { set version [exec /bin/uname -r] set location "/boot/vmlinux-$version" if {! [file exists $location]} { # try the debuginfo location set location "/usr/lib/debug/lib/modules/$version/vmlinux" if {! [file exists $location]} { set location "" } } print "kernel location: $location" print "kernel version: $version" set location [exec /usr/bin/which stap] regexp {version [^)]*} [exec stap -V 2>@ stdout] version print "systemtap location: $location" print "systemtap version: $version" } proc setup_systemtap_environment {} { global srcdir env # need an absolute SRCDIR for the top-level src/ tree # XXX: or, we could change nearby uses of ${SRCDIR}/testsuite to ${SRCDIR} if {[string index $srcdir 0] != "/"} then { set env(SRCDIR) [exec pwd]/$srcdir/.. } else { set env(SRCDIR) $srcdir/.. } # Use a local systemtap directory and cache. Add user name so # make check and sudo make check don't clobber each other. set env(SYSTEMTAP_DIR) [exec pwd]/.systemtap-[exec whoami] # Find or start a systemtap server, if requested. if {[use_server_p]} then { if {! [setup_server]} then { return 0 } } # PATH, SYSTEMTAP_TAPSET, SYSTEMTAP_RUNTIME, LD_LIBRARY_PATH are already set. foreach var {PATH STAP SRCDIR SYSTEMTAP_TAPSET SYSTEMTAP_RUNTIME SYSTEMTAP_DIR LD_LIBRARY_PATH} { if [info exists env($var)] { verbose -log "env $var = $env($var)" } } return 1 } # Set up the environment so that tests will be performed using the systemtap # client and server. proc setup_server {} { global srcdir env server_pid net_path # Make sure that the necessary resources are available to run the client/server. if {[installtest_p]} then { if {[catch {exec /usr/bin/which stap-client-connect} dummy]} then { print "Unable to start a server: stap-client-connect is not found in PATH" return 0 } } elseif {! [file exists [exec pwd]/../stap-client-connect]} then { print "Unable to start a server: [exec pwd]/../stap-client-connect is not found" return 0 } if {[catch {exec /usr/bin/which avahi-publish-service} dummy]} then { print "Unable to start a server: avahi-publish-service is not found in PATH" return 0 } print "Testing using a systemtap server" # A place for some temporary files and scripts. set net_path [exec pwd]/net exec /bin/mkdir -p $net_path # Server management scripts and data are installed if this is an # install test, otherwise there is some setup to do. if {! [installtest_p]} then { # Make sure the server management scripts and tools are on the $PATH. set env(PATH) "$srcdir/..:[exec pwd]/..:$env(PATH)" set env(SYSTEMTAP_SERVER_SCRIPTS) "$srcdir/.." } # Try to find or start the server. set server_pid [exec stap-find-or-start-server] if { "$server_pid" == "-1" } then { print "Cannot find or start a systemtap server" set server_pid 0 return 0 } elseif { "$server_pid" == "0" } then { print "A compatible systemtap server is already available" } else { print "Started a systemtap server as PID==$server_pid" } # Make a copy of 'stap-client' as 'stap' and make sure it's at the # beginning of the $PATH. Do this after starting the server so that # The server does not call this instance of 'stap' if {[installtest_p]} then { exec /bin/cp -p [exec which stap-client] $net_path/stap exec /bin/cp -p [exec which stap-env] $net_path/stap-env } else { exec /bin/cp -p $srcdir/../stap-client $net_path/stap exec /bin/cp -p $srcdir/../stap-env $net_path/stap-env } set env(PATH) "$net_path:$env(PATH)" return 1 } proc shutdown_server {} { global server_pid net_path if { $server_pid != 0 } then { print "Stopping the systemtap server with PID==$server_pid" exec stap-stop-server $server_pid } # Remove the temporary stap script exec /bin/rm -fr $net_path } proc get_system_info {} { global Host Snapshot Distro env set Host [exec /bin/uname -a] if [file exists ../SNAPSHOT] { set Snapshot [exec /bin/cat ../SNAPSHOT] } elseif [file exists $env(SRCDIR)/../SNAPSHOT] { set Snapshot [exec /bin/cat $env(SRCDIR)/../SNAPSHOT] } else { regexp {version [^)]*} [exec stap -V 2>@ stdout] version set Snapshot $version } set Distro "Linux" if [file exists /usr/bin/lsb_release] { # this produces one line of this format: # Distribution:\tSTRING set Distro [lrange [exec /usr/bin/lsb_release -d] 1 end] } else { foreach f {/etc/fedora-release /etc/enterprise-release /etc/redhat-release /etc/suse-release /etc/debian_version} { if [file exists $f] then {set Distro [exec /bin/cat $f]; break } } } } if {! [setup_systemtap_environment]} then { return 0 } print_systemtap_version get_system_info proc systemtap_init {args} {} proc systemtap_version {} {} proc systemtap_exit {} { # Stop the stap server, if we started it. if {[use_server_p]} then { shutdown_server } } proc stap_run_batch {args} { verbose -log "starting $args" # Many of our test cases use "#! stap ...". Since these lack # /full/paths, they are not really executable. (We can't have # /full/paths because the choice of systemtap interpreter is set # at "make check" time.) # So we cheat. If the file begins with "#! stap", we will spawn # stap manually here (relying on $PATH). Otherwise, we presume # the file properly executable. set file [open [lindex $args 0] r] set firstbits [gets $file] close $file if [regexp -line {\#! stap (.*)} $firstbits -> stap_args] { verbose -log "spawn1 stap $stap_args [lindex $args 0]" spawn stap $stap_args [lindex $args 0] } else { verbose -log "spawn2 $args" spawn $args } expect { -timeout -1 -re {[^\r]*\r} { verbose -log $expect_out(0,string); exp_continue } eof { } } set results [wait] verbose -log "wait results: $results" if {[llength $results] >= 5} { # Unexpected output. stap must have crashed return -1 } else { return [lindex $results 3] } } proc as_root { command } { set effective_pid [exec /usr/bin/id -u] if {$effective_pid != 0} { set command "sudo $command" } verbose -log "as_root $command" set res [catch {eval exec $command} value] verbose -log "OUT $value" verbose -log "RC $res" return $res }