diff options
-rw-r--r-- | initscript/stap-server.in | 289 | ||||
-rwxr-xr-x | stap-client | 2 | ||||
-rwxr-xr-x | stap-env | 4 | ||||
-rwxr-xr-x | stap-find-servers | 2 | ||||
-rwxr-xr-x | stap-server | 2 | ||||
-rwxr-xr-x | stap-serverd | 23 | ||||
-rwxr-xr-x | stap-start-server | 34 | ||||
-rwxr-xr-x | stap-stop-server | 2 |
8 files changed, 302 insertions, 56 deletions
diff --git a/initscript/stap-server.in b/initscript/stap-server.in index aad6b064..9f2b1369 100644 --- a/initscript/stap-server.in +++ b/initscript/stap-server.in @@ -3,7 +3,8 @@ # stap-server init.d script for the systemtap compile server # # chkconfig: - 00 99 -# description: The systemtap compile server provides a centralized and secure environment for compiling systemtap scripts. +# description: The systemtap compile server provides a centralized and secure \ +# environment for compiling systemtap scripts. # config: /etc/stap-server/config # config: /etc/stap-server/conf.d ### BEGIN INIT INFO @@ -14,30 +15,64 @@ # Description: The systemtap compile server provides a centralized and secure environment for compiling systemtap scripts. ### END INIT INFO +# TEMPORARY SEARCH DIRECTORY WHILE TESTING. SHOULD BE CHANGED TO @bindir@ +BINDIR=/usr/local/bin + # Source function library. . /etc/rc.d/init.d/functions +# Systemtap function library +. $BINDIR/stap-env + prog=stap-server # Commands -STAP_START_SERVER=@bindir@/stap-start-server -STAP_STOP_SERVER=@bindir@/stap-stop-server +STAP_START_SERVER=$BINDIR/stap-start-server +STAP_STOP_SERVER=$BINDIR/stap-stop-server UNAME=/bin/uname # Path setup CONFIG_PATH=/etc/stap-server/conf.d -STAT_PATH=/var/run/stap-server +STAT_PATH=/tmp/var/run/stap-server # for now, should be /var/run/stap-server TEMP_PATH=/tmp -LOG_FILE=/var/log/stap-server.log +LOG_FILE=$stap_server_logfile # /var/log/stap-server.log # Default option settings +# Target architecture +OPT_KERNEL_ARCH=`stap_get_arch` +# A list of release_arch pairs +OPT_SERVER_LIST= CONFIG=/etc/stap-server/config echo_usage () { - echo $"Usage: $prog {start|stop|restart|status|cleanup} [option]" + echo $"Usage: $prog {start|stop|restart|status} [option]" echo $"Options:" + echo $" -a arch : change the target architecture" echo $" -c configfile : specify config file" + echo $" -i : specify all installed kernel releases" + echo $" -r release : specify a kernel release" + echo $"" + echo $"All options, except -c may be specified more than once." + echo $"" + echo $"Each -a option changes the target architecture for subsequent -r" + echo $"options. The default is the architecture of the host platform." + echo $"" + echo $"Each -r option specifies a server for the given kernel release and the" + echo $"current architecture (either the default or set by the previous -a" + echo $"option)." + echo $"" + echo $"the -i option is a shortcut which specifies one server for each kernel" + echo $"release installed in /lib/modules/. The default architecture is used" + echo $"for these servers." + echo $"" + echo $"If no kernel release is specified, the defaults are as follows:" + echo $"" + echo $" start: start a server for the kernel release of the host platform." + echo $" stop: stop all servers." + echo $" restart: restart all servers." + echo $" status: report the status of all servers." + echo $"" } #----------------------------------------------------------------- @@ -84,7 +119,6 @@ check_bool () { # value } ask_yesno () { # message local yn ret=2 - [ "$OPT_ASSUMEYES" ] && return 1 while [ $ret -eq 2 ]; do echo -n "$1 [y/N]: " read yn @@ -102,10 +136,22 @@ parse_args () { # arguments local error=0 while [ -n "$1" ]; do case "$1" in + -a) + process_a $2 + shift 1 + ;; -c) CONFIG=$2 shift 1 ;; + -i) + process_i + ;; + -r) + process_r $2 + test $? = 0 || error=1 + shift 1 + ;; --) ;; *) @@ -114,19 +160,64 @@ parse_args () { # arguments esac shift 1 done - test error = 1 && echo_usage + test error = 1 && echo_usage && return 1 + + return 0 +} + +# Process the -a flag. +process_a () { + OPT_KERNEL_ARCH=$1 +} + +# Process the -i flag. +process_i () { + local save_arch=$OPT_KERNEL_ARCH + OPT_KERNEL_ARCH=`stap_get_arch` + + cd /lib/modules + local release + for release in `ls`; do + process_r $release + done + + OPT_KERNEL_ARCH=$save_arch + return 0 +} + +# Process the -r flag. +process_r () { + local first_char=`expr "$1" : '\(.\).*'` + + if test "$first_char" = "/"; then # fully specified path + local kernel_build_tree=$1 + local version_file_name="$kernel_build_tree/include/config/kernel.release" + # The file include/config/kernel.release within the kernel + # build tree is used to pull out the version information + local kernel_release=`cat $version_file_name 2>/dev/null` + if test "X$kernel_release" = "X"; then + echo "Missing $version_file_name" + return 1 + fi + OPT_SERVER_LIST="$OPT_SERVER_LIST ${kernel_release}_${OPT_KERNEL_ARCH}" + return 0 + fi + + # kernel release specified directly + OPT_SERVER_LIST="$OPT_SERVER_LIST ${1}_${OPT_KERNEL_ARCH}" + return 0 } CMD=$1 shift 1 -OPTS=`getopt -s bash -u -o 'c:Ry' $@` +OPTS=`getopt -s bash -u -o 'a:c:ir:' -- $@` if [ $? -ne 0 ]; then slog "Error: Argument parse error: $@" failure $"parse error" echo_usage exit 3 fi -parse_args $OPTS +parse_args $OPTS || exit 3 # Include configs if [ -f "$CONFIG" ]; then @@ -147,56 +238,186 @@ prepare_stat_dir () { return 0 } -start () { - clog $"Starting $prog: " -n +# Default to the currently running kernel release +get_release () { # server-spec + if [ -z "$1" ]; then + uname -r + else + expr "$1" : '\(.*\)_.*' + fi +} + +# Default to the currently running kernel release +get_arch () { # server-spec + if [ -z "$1" ]; then + stap_get_arch + else + expr "$spec" : '.*_\(.*\)' + fi +} + +stat_file () { # server-spec + echo $STAT_PATH/$1 +} + +get_server_list () { + if [ -z "$OPT_SERVER_LIST" ]; then + echo "`get_release`_`get_arch`" + return 0 + fi + echo "$OPT_SERVER_LIST" +} + +check_server_running () { # server-spec + local server_status=`stat_file $1` + test ! -f $server_status && return 1 + (ps -e | grep stap-serverd | grep -q `cat $server_status`) || return 1 + # Server is already running + return 0 +} + +managed_servers () { + if [ ! -d $STAT_PATH ]; then + echo "" + return 1 + fi + cd $STAT_PATH + local list=`ls` + if [ -z "$list" ]; then + echo "" + return 1 + fi + + echo "$list" +} +start () { # release arch prepare_stat_dir if [ $? -ne 0 ]; then do_failure $"Failed to make stat directory ($STAT_PATH)" return 1 fi - # Start the server here - do_failure $"$prog start not implemented" + # Start each requested server in turn + local server_list=`get_server_list` + local spec + local first=1 + for spec in $server_list; do + local release=`get_release $spec` + local arch=`get_arch $spec` + + test $first = 0 && echo + first=0 + clog $"Starting $prog for $release $arch: " -n + + # Is there already a server running for the requested kernel release + # and arch? + if check_server_running $spec; then + do_success $"$prog start for $release $arch" + continue + fi + + # Start the server here. Use sudo for now to start it as root. + local server_status=`stat_file $spec` + sudo $STAP_START_SERVER -r $release -a $arch > $server_status + if [ $? != 0 ]; then + rm -f $server_status + do_failure $"$prog start: unable to start stap-server for $release $arch" + return 1 + fi + + do_success $"$prog start for $release $arch" + done - do_success $"$prog start" return 0 } stop () { - clog $"Stopping $prog: " -n + local server_status + local server_list + local first=1 - # Stop the server here - do_failure $"$prog stop not implemented" + # Stop the specified servers or all servers, if none specified. + if [ -n "$OPT_SERVER_LIST" ]; then + server_list="$OPT_SERVER_LIST" + else + server_list=`managed_servers` + fi - do_success $"$prog stop" - return 0 -} + for server_status in $server_list; do + release_arch=`echo $server_status | sed 's/_/ /'` -status () { - local ret=0 + test $first = 0 && echo + first=0 + clog $"Stopping $prog for $release_arch: " -n - # Print the status here - echo $"$prog status not implemented" + if check_server_running $server_status; then + local server_status_file=`stat_file $server_status` + local pid=`cat $server_status_file` + sudo $STAP_STOP_SERVER $pid + fi + rm -f $server_status_file - return $ret + do_success $"$prog stop for $release_arch" + done + + return 0 } -# Cleanup caches -cleanup () { - clog $"Stopping systemtap compile servers: " -n +status () { + local server_list - # Clean up the server(s) here - do_failure $"$prog cleanup not implemented" + # Report status for the specified servers or all servers, if none specified. + if [ -n "$OPT_SERVER_LIST" ]; then + server_list="$OPT_SERVER_LIST" + else + server_list=`managed_servers` + fi - do_success "done" + if [ -z "$server_list" ]; then + echo "No managed stap-server is running" + return 0 + fi + + local server_status + for server_status in $server_list; do + local release_arch=`echo $server_status | sed 's/_/ /'` + local server_status_file=`stat_file $server_status` + if [ ! -f $server_status_file ]; then + echo "stap-server for $release_arch is not running" + else + local pid=`cat $server_status_file` + if check_server_running $server_status; then + echo "stap-server for $release_arch running as PID $pid" + else + echo "stap-server for $release_arch started as PID $pid is no longer running" + rm -f $server_status_file + fi + fi + done return 0 } # Restart scripts function restart () { + local server_list + + # Restart the specified servers or all servers, if none specified. + if [ -n "$OPT_SERVER_LIST" ]; then + server_list="$OPT_SERVER_LIST" + else + server_list=`managed_servers` + fi + + if [ -z "$server_list" ]; then + clog "No managed stap-server is running" -n + do_success "No managed stap-server is running" + return 0 + fi + stop echo + OPT_SERVER_LIST=$server_list start return $? } @@ -220,10 +441,6 @@ case $CMD in status exit $? ;; - cleanup) - cleanup - RETVAL=$? - ;; *) echo_usage RETVAL=3 diff --git a/stap-client b/stap-client index 18e24ca9..68584e1b 100755 --- a/stap-client +++ b/stap-client @@ -61,7 +61,7 @@ function initialization { m_name= module_name=stap_$$ uname_r="`uname -r`" - arch=`get_arch` + arch=`stap_get_arch` # Default variable settings find_all= @@ -41,7 +41,9 @@ stap_signing_db=$stap_sysconfdir/systemtap/staprun stap_certfile=stap.cert stap_old_certfile=stap-server.cert -function get_arch { +stap_server_logfile=/tmp/stap-server.log # for now + +function stap_get_arch { # PR4186: Copy logic from coreutils uname (uname -i) to squash # i?86->i386. Actually, copy logic from linux top-level Makefile # to squash uname -m -> $(SUBARCH). diff --git a/stap-find-servers b/stap-find-servers index 789f508b..91bb0ea8 100755 --- a/stap-find-servers +++ b/stap-find-servers @@ -140,7 +140,7 @@ function match_server { function client_sysinfo { if test "X$sysinfo_client" = "X"; then # Add some info from uname - sysinfo_client="`uname -r` `get_arch`" + sysinfo_client="`uname -r` `stap_get_arch`" fi echo sysinfo=$sysinfo_client } diff --git a/stap-server b/stap-server index d99eec2d..d69119db 100755 --- a/stap-server +++ b/stap-server @@ -125,7 +125,7 @@ function check_request { function server_sysinfo { if test "X$sysinfo_server" = "X"; then # Add some info from uname - sysinfo_server="`uname -r` `get_arch`" + sysinfo_server="`uname -r` `stap_get_arch`" fi echo "$sysinfo_server" } diff --git a/stap-serverd b/stap-serverd index 431d03e9..f89a5f02 100755 --- a/stap-serverd +++ b/stap-serverd @@ -29,7 +29,7 @@ function initialization { ssl_db= stap_options= uname_r="`uname -r`" - arch="`get_arch`" + arch="`stap_get_arch`" # Parse the arguments parse_options "$@" @@ -39,7 +39,7 @@ function initialization { while netstat -atn | awk '{print $4}' | cut -f2 -d: | egrep -q "^$port\$"; do # Whoops, the port is busy; try another one. - echo "$0: Port $port is busy" + echo "$0: Port $port is busy" >> $stap_server_logfile port=$((1024+($port + $RANDOM)%64000)) done @@ -57,7 +57,7 @@ function initialization { # If no certificate/key database has been specified, then find/create # a local one. if ! test -f $ssl_db/$stap_certfile; then - ${stap_exec_prefix}stap-gen-cert $ssl_db || exit 1 + ${stap_exec_prefix}stap-gen-cert $ssl_db >> $stap_server_logfile 2>&1 || exit 1 # Now add the server's certificate to the client's database, # making it a trusted peer. Do this only if the client has been installed. if test -f `which ${stap_exec_prefix}stap-client` -a \ @@ -282,7 +282,7 @@ function process_r { if test "$first_char" = "/"; then # fully specified path kernel_build_tree=$1 version_file_name="$kernel_build_tree/include/config/kernel.release" - # The file include/config/kernel.release within the + # The file include/config/kernel.release within the kernel # build tree is used to pull out the version information release=`cat $version_file_name 2>/dev/null` if test "X$release" = "X"; then @@ -305,13 +305,14 @@ function process_r { # Advertise the availability of the server on the network. function advertise_presence { # Build up a string representing our server's properties. + local service_name="Systemtap Compile Server for $uname_r $arch" local txt="sysinfo=$uname_r $arch" # Call avahi-publish-service to advertise our presence. - avahi-publish-service "Systemtap Compile Server on `uname -n`" \ - $stap_avahi_service_tag $port "$txt" > /dev/null & + avahi-publish-service "$service_name" \ + $stap_avahi_service_tag $port "$txt" >> $stap_server_logfile 2>&1 & - echo "Systemtap Compile Server on `uname -n` listening on port $port" + echo "$service_name listening on port $port" >> $stap_server_logfile } # function: listen @@ -323,7 +324,7 @@ function listen { ${stap_exec_prefix}stap-server-connect \ -p $port -n $nss_cert -d $ssl_db -w $nss_pw \ -s "$stap_options" \ - 2>&1 & + >> $stap_server_logfile 2>&1 & wait '%${stap_exec_prefix}stap-server-connect' >/dev/null 2>&1 } @@ -538,7 +539,7 @@ function check_cert_file { # Warning error # Prints its arguments to stderr function warning { - echo "$0: WARNING:" "$@" >&2 + echo "$0: WARNING:" "$@" >> $stap_server_logfile } # function: fatal [ MESSAGE ] @@ -546,7 +547,7 @@ function warning { # Fatal error # Prints its arguments to stderr and exits function fatal { - echo "$0: ERROR:" "$@" >&2 + echo "$0: ERROR:" "$@" >> $stap_server_logfile terminate exit 1 } @@ -555,7 +556,7 @@ function fatal { # # Terminate gracefully. function terminate { - echo "$0: Exiting" + echo "$0: Exiting" >> $stap_server_logfile # Kill the running 'avahi-publish-service' job kill -s SIGTERM '%avahi-publish-service' 2> /dev/null diff --git a/stap-start-server b/stap-start-server index ac31d3bd..e43a4cdf 100755 --- a/stap-start-server +++ b/stap-start-server @@ -17,27 +17,53 @@ startup_timeout=20 # start the server -${stap_exec_prefix}stap-serverd "$@" </dev/null >/dev/null 2>&1 & +${stap_exec_prefix}stap-serverd "$@" </dev/null & server_pid=$! # Make sure the server is started for ((attempt=0; $attempt < $startup_timeout; ++attempt)) do + server_started=0 + avahi_advertising=0 + server_listening=0 + # Has the server started? - if ! (ps -e | grep $server_pid) >/dev/null 2>&1; then - sleep 1 - continue + if ! (ps -e | grep stap-serverd | grep $server_pid) >/dev/null 2>&1; then + sleep 1 + continue fi + server_started=1 # Is avahi advertizing the server? if ! (ps -fe | grep avahi-publish-service | grep $server_pid) > /dev/null 2>&1; then sleep 1 continue fi + avahi_advertising=1 + + # Is the server listening? + if ! (ps -fe | grep stap-server-connect | grep $server_pid) > /dev/null 2>&1; then + sleep 1 + continue + fi + server_listening=1 # The server is ready echo $server_pid exit 0 done +echo -n "Unable to start a systemtap server: " >&2 + +if test $server_started = 0; then + echo "${stap_exec_prefix}stap-serverd did not start" >&2 +elif test $avahi_advertising = 0; then + echo "avahi is not advertising the server" >&2 +elif test $server_listening = 0; then + echo "The server could not open a connection to listen on" >&2 +fi + +# If the server partially started, then kill it. +test $server_started = 1 && ${stap_exec_prefix}stap-stop-server $server_pid + exit 1 # server did not start diff --git a/stap-stop-server b/stap-stop-server index 48c8a450..8b92f4a7 100755 --- a/stap-stop-server +++ b/stap-stop-server @@ -22,7 +22,7 @@ fi # Verify that it is a systemtap server (ps -e | grep stap-serverd | grep -q $pid) if test $? != 0; then - echo "$pid is not a systemtap server" + echo "$pid is not a systemtap server" >&2 exit 1 fi |