summaryrefslogtreecommitdiffstats
path: root/stap-server
diff options
context:
space:
mode:
authorDave Brolley <brolley@redhat.com>2009-12-21 19:26:16 -0500
committerDave Brolley <brolley@redhat.com>2009-12-21 19:26:16 -0500
commit600450900a5e98404c91104d2cb20cddce42838e (patch)
treee0a54b23be5755ec80c72f8b16a6281b5540c661 /stap-server
parentd12a5be645d7036e7834308e714496f57adda852 (diff)
downloadsystemtap-steved-600450900a5e98404c91104d2cb20cddce42838e.tar.gz
systemtap-steved-600450900a5e98404c91104d2cb20cddce42838e.tar.xz
systemtap-steved-600450900a5e98404c91104d2cb20cddce42838e.zip
PR 10905: initscript improvements.
Make the stap-server initscript available as $bindir/stap-server Reimplement the stap-server initscript as a thin wrapper around $bindir/stap-server.
Diffstat (limited to 'stap-server')
-rw-r--r--[-rwxr-xr-x]stap-server1291
1 files changed, 846 insertions, 445 deletions
diff --git a/stap-server b/stap-server
index d1731895..85e5bf19 100755..100644
--- a/stap-server
+++ b/stap-server
@@ -1,6 +1,6 @@
#!/bin/bash
-
-# Compile server for systemtap
+#
+# stap-server script for managing the systemtap compile server
#
# Copyright (C) 2008, 2009 Red Hat Inc.
#
@@ -8,505 +8,906 @@
# redistribute it and/or modify it under the terms of the GNU General
# Public License (GPL); either version 2, or (at your option) any
# later version.
+#
+# This script provides management of systemtap compile servers as a service.
+# See stap-server(8) for more information.
-# This script unpacks the tar file provided on stdin and uses the information
-# contained in the unpacked tree to build the requested systemtap kernel module.
-# This module is then written to stdout.
-
-# Catch ctrl-c and other termination signals
-trap 'terminate' SIGTERM SIGINT
+. /etc/rc.d/init.d/functions
-# Initialize the environment
+# Systemtap function library
. ${PKGLIBEXECDIR}stap-env
-#-----------------------------------------------------------------------------
-# Helper functions.
-#-----------------------------------------------------------------------------
-# function: initialization
-function initialization {
- # Initialization
- stap_rc=0
- wd=`pwd`
-
- # Default options settings
- p_phase=5
- keep_temps=0
- unprivileged=0
- stap_options=
-
- zip_client=$1
- tmpdir_server=$2
- zip_server=$3
- ssl_db=$4
- server_options="$5"
-
- # This script is not intended to be called directly, so if the arguments
- # aren't specified correctly, just exit with non-zero
- test "X$tmpdir_server" != "X" || exit 2
- test -d $tmpdir_server || exit 3
- tmpdir_env=`dirname $tmpdir_server`
-
- # Response file name.
- test "X$zip_server" != "X" || exit 4
- # Make sure the specified .zip file exists.
- test -f $zip_server || exit 5
-
- # Request file name.
- test "X$zip_client" != "X" || exit 6
- test -f $zip_client || exit 7
-
- # Where is the ssl certificate/key database?
- test "X$ssl_db" != "X" || exit 8
- test -d $ssl_db || exit 9
- nss_pw=$ssl_db/pw
- test -f $nss_pw || exit 10
-
- # What are the options that the server was started with?
- eval parse_options "$server_options"
-
- nss_cert=stap-server
-
- touch $tmpdir_server/stdout
- touch $tmpdir_server/stderr
-}
-
-# function: unpack_request
-#
-# Unpack the zip file received from the client and make the contents
-# available for use when running 'stap'
-function unpack_request {
- cd $tmpdir_server
-
- # Unpack the zip file.
- unzip $zip_client > /dev/null || \
- fatal "Cannot unpack zip archive $zip_client"
+prog=stap-server
+
+# Commands
+STAP_START_SERVER=${stap_pkglibexecdir}stap-start-server
+STAP_STOP_SERVER=${stap_pkglibexecdir}stap-stop-server
+UNAME=/bin/uname
+
+# Default Global Configuration
+CONFIG_FILE=$stap_sysconfdir/sysconfig/stap-server
+CONFIG_PATH=$stap_sysconfdir/stap-server/conf.d
+STAT_PATH=$stap_localstatedir/run/stap-server
+LOG_FILE=$stap_localstatedir/log/stap-server.log
+
+# Default option settings
+# Optional global config file
+OPT_CONFIG_FILE=
+
+echo_usage () {
+ echo $"Usage: $prog {start|stop|restart|condrestart|try-restart|force-reload|status} [options]"
+ echo $"Options:"
+ echo $" -c configfile : specify additional global configuration file."
+ echo $" -a arch : specify the target architecture."
+ echo $" -r release : specify the kernel release."
+ echo $" -I path : augment the search path for tapsets."
+ echo $" -R path : specify the location of the systemtap runtime."
+ echo $" -B options : specify 'make' options for building systemtap modules."
+ echo $" -u username : specify the user who will run the server(s)."
+ echo $" -i : specify a server for each installed kernel release."
+ echo $" -n nickname : specify a server configuration by nickname."
+ echo $" -p pid : specify a server or server configuration by process id."
+ echo $""
+ echo $"All options, may be specified more than once."
+ echo $""
+ echo $"If -a is not specified, the default architecture is that of the host"
+ echo $"platform."
+ echo $""
+ echo $"If -r is not specified, the default kernel release is that currently"
+ echo $"running on the host platform."
+ echo $""
+ echo $"If -u is not specified, the default user is 'stap-server'"
+ echo $""
+ echo $"Each -I and -B option specifies an additional path or option"
+ echo $"respectively. For other options, each new instance overrides the"
+ echo $"previous setting."
+ echo $""
+ echo $"The -i option is a shortcut which specifies one server for each kernel"
+ echo $"release installed in /lib/modules/. Previous -I, -R, -B and -u"
+ echo $"options will be applied to each server, however previous -a options"
+ echo $"are ignored and the default architecture is used."
+ echo $""
+ echo $"The -n option allows the specification of a server configuration by"
+ echo $"nickname. When -n is specified, a currently running server with the"
+ echo $"given nickname will be searched for. If no currently running server"
+ echo $"with the given nickname is found, a server configuration with the"
+ echo $"given nickname will be searched for in $stap_sysconfdir/stap-server/conf.d/*.conf."
+ echo $"If a server configuration for the given nickname is found, the -a, -r,"
+ echo $"-I, -R, -B and -u options for that server will be used as if they were"
+ echo $"specified on the command line. If no configuration with the given"
+ echo $"nickname is found, and the action is 'start' (or an action behaving"
+ echo $"like 'start' (see below), the server will be started with the given"
+ echo $"nickname. If no configuration with the given nickname is found, and"
+ echo $"the action is not 'start' (or an action behaving" "like 'start',"
+ echo $"it is an error. If a nickname is not specified for a server, its"
+ echo $"nickname will be its process id."
+ echo $""
+ echo $"The -p option allows the specification of a server configuration by"
+ echo $"process id. When -p is specified, a currently running server with the"
+ echo $"given process id will be searched for. If no such server is found,"
+ echo $"it is an error. If a server with the given pid is found, the -a, -r,"
+ echo $"-I, -R, -B and -u options for that server will be used as if they were"
+ echo $"specified on the command line."
+ echo $""
+ echo $"The specified action is performed for the server(s) specified on the"
+ echo $"command line. If no servers are specified on the command line, the"
+ echo $"behavior is as follows:"
+ echo $""
+ echo $" start: Start the servers configured in $stap_sysconfdir/stap-server/conf.d/*.conf."
+ echo $" If none are configured, start a server for the kernel release"
+ echo $" and architecture of the host platform."
+ echo $""
+ echo $" stop: Stop all currently running servers."
+ echo $""
+ echo $" restart: Restart all currently running servers. If no servers are running,"
+ echo $" behave as if 'start' was specified."
+ echo $""
+ echo $" condrestart: Restart all currently running servers. If no servers are running,"
+ echo $" do nothing."
+ echo $""
+ echo $" try-restart: Same as condrestart."
+ echo $""
+ echo $" force-reload: Stop all currently running servers and behave as if 'start'"
+ echo $" was specified."
+ echo $""
+ echo $" status: Report the status of all current running servers."
+ echo $""
+}
- # Identify the client's request tree. The zip file should have expanded
- # into a single directory named to match $stap_tmpdir_prefix_client.??????
- # which should now be the only item in the current directory.
- test "`ls | wc -l`" = 3 || \
- fatal "Wrong number of files after expansion of client's zip file"
+#-----------------------------------------------------------------
+# Helper functions
+#-----------------------------------------------------------------
+log () { # message
+ echo `LC_ALL=en date +"%b %e %T"`": $1" >> "$LOG_FILE"
+}
+clog () { # message [-n]
+ echo $2 "$1"
+ log "$1"
+}
+slog () { # message
+ logger "$1" # if syslogd is running, this message will be sent to syslog.
+ log "$1"
+}
+logex () { # command
+ eval log \"Exec: $@\"
+ "$@" >> "$LOG_FILE" 2>&1
+ return $?
+}
+do_failure () { # message
+ slog "Error: $1"
+ failure "$1"
+}
+do_success () { # message
+ log "Pass: $1"
+ success "$1"
+}
- tmpdir_client=`ls | grep $stap_tmpdir_prefix_client.......\$`
+#------------------------------------------------------------------
+# Parameter parsing and setup options
+#------------------------------------------------------------------
+parse_args () { # arguments
+ local rc=0
+ while [ -n "$1" ]; do
+ case "$1" in
+ -a)
+ OPT_SERVER_CMDS="$OPT_SERVER_CMDS ARCH='$2'"
+ shift 1
+ ;;
+ -B)
+ OPT_SERVER_CMDS="$OPT_SERVER_CMDS BUILD='$2'"
+ shift 1
+ ;;
+ -c)
+ OPT_CONFIG_FILE=$2
+ shift 1
+ ;;
+ -i)
+ process_i
+ ;;
+ -I)
+ OPT_SERVER_CMDS="$OPT_SERVER_CMDS INCLUDE='$2'"
+ shift 1
+ ;;
+ -n)
+ process_n $2
+ shift 1
+ ;;
+ -p)
+ process_p $2
+ test $? = 0 || rc=1
+ shift 1
+ ;;
+ -r)
+ process_r $2
+ test $? = 0 || rc=1
+ shift 1
+ ;;
+ -R)
+ OPT_SERVER_CMDS="$OPT_SERVER_CMDS RUNTIME='$2'"
+ shift 1
+ ;;
+ -u)
+ OPT_SERVER_CMDS="$OPT_SERVER_CMDS USER='$2'"
+ shift 1
+ ;;
+ --)
+ ;;
+ *)
+ rc=1
+ ;;
+ esac
+ shift 1
+ done
+
+ # Add an EXEC command to the end if any server options were specified
+ test -n "$OPT_SERVER_CMDS" && OPT_SERVER_CMDS="$OPT_SERVER_CMDS EXEC"
+
+ test $rc != 0 && echo_usage
+ return $rc
+}
- test "X$tmpdir_client" != "X" || \
- fatal "Client zip file did not expand as expected"
+# Process the -i flag.
+process_i () {
+ cd /lib/modules
+ local release
+ for release in `ls`; do
+ test -n "$OPT_SERVER_CMDS" && OPT_SERVER_CMDS="$OPT_SERVER_CMDS EXEC"
+ process_r $release
+ done
- # Move the client's temp directory to a local temp location
- local local_tmpdir_client=`mktemp -dt $stap_tmpdir_prefix_server.client.XXXXXX` || \
- fatal "Cannot create temporary client request directory " $local_tmpdir_client
- mv $tmpdir_client/* $local_tmpdir_client
- rm -fr $tmpdir_client
- tmpdir_client=$local_tmpdir_client
+ return 0
}
-# function: check_request
-#
-# Examine the contents of the request to make sure that they are valid.
-function check_request {
- # Work in the temporary directory provided by the client
- cd $tmpdir_client
+# Process the -n flag.
+process_n () {
+ local target_NICKNAME="$1"
+
+ # Is there a running server with this nickname?
+ local pid=`get_server_pid_by_nickname "$target_NICKNAME"`
+ if [ -n "$pid" ]; then
+ # Read the configuration and add it to the configuration commands.
+ . $STAT_PATH/$pid
+ OPT_SERVER_CMDS="$OPT_SERVER_CMDS `echo_server_commands`"
+ return
+ fi
+
+ # Is there a server configuration with this nickname?
+ for f in "$CONFIG_PATH"/*.conf; do
+ if [ -f "$f" ]; then
+ . "$f"
+ test "X$NICKNAME" = "X$target_NICKNAME" || continue
+ OPT_SERVER_CMDS="$OPT_SERVER_CMDS `echo_server_commands`"
+ return
+ fi
+ done
- # Add the necessary info from files in our temporary directory.
- cmdline=`read_data_file cmdline`
- test "X$cmdline" != "X" || exit 1
+ # No server configuration could be found for this nickname. Add a
+ # NICKNAME_NOT_FOUND=... command to the configuration commands.
+ OPT_SERVER_CMDS="$OPT_SERVER_CMDS NICKNAME_NOT_FOUND='$target_NICKNAME'"
+}
+
+# Process the -p flag.
+process_p () {
+ local pid="$1"
- eval parse_options "$cmdline"
+ # Are we managing a server with the given pid?
+ test ! -f $STAT_PATH/$pid && echo "No stap-server running as pid $pid" && \
+ exit 1
- client_sysinfo=`read_data_file sysinfo`
- test "X$client_sysinfo" != "X" || exit 1
+ # Add the configuration of the server running as $pid to OPT_SERVER_CMDS
+ . $STAT_PATH/$pid
+ OPT_SERVER_CMDS="$CONFIG_SERVER_CMDS `echo_server_commands`"
- check_compatibility "$client_sysinfo" "`server_sysinfo`"
+ return 0
}
-# function server_sysinfo
-#
-# Generate the server's sysinfo and echo it to stdout
-function server_sysinfo {
- if test "X$sysinfo_server" = "X"; then
- # Add some info from uname
- sysinfo_server="`uname -r` `stap_get_arch`"
+# 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_CMDS="$OPT_SERVER_CMDS RELEASE='$kernel_release'"
+ return 0
fi
- echo "$sysinfo_server"
-}
-# function check_compaibility SYSINFO1 SYSINFO2
-#
-# Make sure that systemtap as described by SYSINFO1 and SYSINFO2 are compaible
-function check_compatibility {
- # Compatibility is irrelevant. The client can choose any server
- # it sees fit
- return
+ # kernel release specified directly
+ OPT_SERVER_CMDS="$OPT_SERVER_CMDS RELEASE='$1'"
+ return 0
}
-# function: read_data_file PREFIX
-#
-# Find a file whose name is '$1' and whose first line
-# contents are '$1: .*'. Read and echo the data.
-function read_data_file {
- test -f $1 || \
- fatal "Data file $1 not found"
-
- # Open the file
- exec 3< $1
-
- # Verify the first line of the file.
- read <&3
- line="$REPLY"
- data=`expr "$line" : "$1: \\\(.*\\\)"`
- if test "X$data" = "X"; then
- fatal "Data in file $1 is incorrect"
- return
- fi
+load_config () {
+ # Include configs
+ if [ -f "$CONFIG_FILE" ]; then
+ . "$CONFIG_FILE"
+ fi
+ if [ -f "$OPT_CONFIG_FILE" ]; then
+ . "$OPT_CONFIG_FILE"
+ fi
+}
- # Close the file
- exec 3<&-
+# Default to the currently running kernel release
+get_release () {
+ $UNAME -r
+}
- # Now read the entire file.
- cat $1 | sed "s/$1: //"
+# Default to the currently running kernel release
+get_arch () {
+ stap_get_arch
}
-# function: parse_options [ STAP-OPTIONS ]
-#
-# Examine the command line. We need not do much checking, but we do need to
-# parse all options in order to discover the ones we're interested in.
-function parse_options {
- # We need to know in advance if --unprivileged was specified.
- all_options=" ""$@"" "
- token=`expr "$all_options" : '.* \(--unprivileged\) .*'`
- if test "X$token" = "X--unprivileged"; then
- unprivileged=1
- fi
+echo_server_commands () {
+ # Echo the configuration command string.
+ echo -n "ARCH='$ARCH'"
+ echo -n " RELEASE='$RELEASE'"
+ echo -n " RUNTIME='$RUNTIME'"
+ for i in $INCLUDE; do
+ echo -n " INCLUDE='$i'"
+ done
+ for b in $BUILD; do
+ echo -n " BUILD='$b'"
+ done
+ echo -n " USER='$USER'"
+ echo -n " NICKNAME='$NICKNAME'"
+ echo
+}
- while test $# != 0
- do
- advance_p=0
- dash_seen=0
-
- # Start of a new token.
- first_token=$1
-
- # Process the option.
- until test $advance_p != 0
- do
- # Identify the next option
- first_char=`expr "$first_token" : '\(.\).*'`
- if test $dash_seen = 0; then
- if test "$first_char" = "-"; then
- if test "$first_token" != "-"; then
- # It's not a lone dash, so it's an option.
- # Is it a long option (i.e. --option)?
- second_char=`expr "$first_token" : '.\(.\).*'`
- if test "X$second_char" = "X-"; then
- advance_p=$(($advance_p + 1))
- stap_options="$stap_options $first_token"
- break
- fi
- # It's not a lone dash, or a long option, so it's a short option string.
- # Remove the dash.
- first_token=`expr "$first_token" : '-\(.*\)'`
- dash_seen=1
- first_char=`expr "$first_token" : '\(.\).*'`
- fi
- fi
- if test $dash_seen = 0; then
- # The dash has not been seen. This is either the script file
- # name or an arument to be passed to the probe module.
- # If this is the first time, and -e has not been specified,
- # then it could be the name of the script file.
- if test "X$e_script" = "X" -a "X$script_file" = "X"; then
- script_file="$first_token"
- fi
- if test "$first_char" != "'"; then
- stap_options="$stap_options '$first_token'"
- else
- stap_options="$stap_options $first_token"
- fi
- advance_p=$(($advance_p + 1))
- break
- fi
- fi
-
- # We are at the start of an option. Look at the first character.
- case $first_char in
- a)
- get_arg $first_token $2
- if test $unprivileged = 1; then
- fatal "You can't specify -$first_char and --unprivileged together."
- else
- stap_options="$stap_options -$first_char $stap_arg"
- fi
- ;;
- B)
- get_arg $first_token $2
- if test $unprivileged = 1; then
- fatal "You can't specify -$first_char and --unprivileged together."
- else
- stap_options="$stap_options -$first_char $stap_arg"
- fi
- ;;
- d)
- get_arg $first_token $2
- stap_options="$stap_options -$first_char $stap_arg"
- ;;
- D)
- get_arg $first_token $2
- if test $unprivileged = 1; then
- fatal "You can't specify -$first_char and --unprivileged together."
- else
- stap_options="$stap_options -$first_char $stap_arg"
- fi
- ;;
- e)
- get_arg $first_token "$2"
- stap_options="$stap_options -$first_char '$stap_arg'"
- process_e "$stap_arg"
- ;;
- I)
- get_arg $first_token $2
- if test $unprivileged = 1; then
- fatal "You can't specify -$first_char and --unprivileged together."
- else
- stap_options="$stap_options -$first_char $stap_arg"
- fi
- ;;
- k)
- keep_temps=1
- ;;
- l)
- get_arg $first_token $2
- stap_options="$stap_options -$first_char $stap_arg"
- process_p 2
- ;;
- L)
- get_arg $first_token $2
- stap_options="$stap_options -$first_char $stap_arg"
- process_p 2
- ;;
- m)
- get_arg $first_token $2
- if test $unprivileged = 1; then
- fatal "You can't specify -$first_char and --unprivileged together."
- else
- stap_options="$stap_options -$first_char $stap_arg"
- fi
- ;;
- o)
- get_arg $first_token $2
- stap_options="$stap_options -$first_char $stap_arg"
- ;;
- p)
- get_arg $first_token $2
- process_p $stap_arg
- ;;
- r)
- get_arg $first_token $2
- if test $unprivileged = 1; then
- fatal "You can't specify -$first_char and --unprivileged together."
- else
- stap_options="$stap_options -$first_char $stap_arg"
- fi
- ;;
- R)
- get_arg $first_token $2
- if test $unprivileged = 1; then
- fatal "You can't specify -$first_char and --unprivileged together."
- else
- stap_options="$stap_options -$first_char $stap_arg"
- fi
- ;;
- s)
- get_arg $first_token $2
- stap_options="$stap_options -$first_char $stap_arg"
- ;;
- S)
- get_arg $first_token $2
- stap_options="$stap_options -$first_char $stap_arg"
- ;;
- x)
- get_arg $first_token $2
- stap_options="$stap_options -$first_char $stap_arg"
- ;;
- *)
- # An unknown flag. Ignore it.
- ;;
- esac
-
- if test $advance_p = 0; then
- # Just another flag character. Consume it.
- stap_options="$stap_options -$first_char"
- first_token=`expr "$first_token" : '.\(.*\)'`
- if test "X$first_token" = "X"; then
- advance_p=$(($advance_p + 1))
- fi
- fi
- done
-
- # Consume the arguments we just processed.
- while test $advance_p != 0
- do
- shift
- advance_p=$(($advance_p - 1))
- done
+echo_server_options () {
+ # Echo the configuration options.
+ echo -n "-a '$ARCH'"
+ echo -n " -r '$RELEASE'"
+ test -n "$RUNTIME" && echo -n " -R '$RUNTIME'"
+ for i in $INCLUDE; do
+ echo -n " -I '$i'"
+ done
+ for b in $BUILD; do
+ echo -n " -B '$b'"
done
+ test -n "$USER" && echo -n " -u '$USER'"
+ echo -n " -n '$NICKNAME'"
+ echo
}
-# function: get_arg FIRSTWORD SECONDWORD
-#
-# Collect an argument to the given option
-function get_arg {
- # Remove first character. Advance to the next token, if the first one
- # is exhausted.
- local first=`expr "$1" : '.\(.*\)'`
- if test "X$first" = "X"; then
- shift
- advance_p=$(($advance_p + 1))
- first=$1
+load_server_config () {
+ CONFIG_SERVER_CMDS=
+ for f in "$CONFIG_PATH"/*.conf; do
+ if [ -f "$f" ]; then
+ # Obtain a configuration from each config file.
+ # Ensure that we get the correct defaults for items not specified.
+ local ARCH=
+ local BUILD=
+ local INCLUDE=
+ local RUNTIME=
+ local USER=
+ local RELEASE=
+ . "$f"
+ # Other options default to empty. These ones don't.
+ [ -z "$ARCH" ] && ARCH=`get_arch`
+ [ -z "$RELEASE" ] && RELEASE=`get_release`
+ [ -z "$USER" ] && USER=$STAP_USER
+ CONFIG_SERVER_CMDS="$CONFIG_SERVER_CMDS `echo_server_commands` EXEC"
fi
- stap_arg="$first"
- advance_p=$(($advance_p + 1))
+ done
}
-# function: process_e ARGUMENT
-#
-# Process the -e flag.
-function process_e {
- if test "X$e_script" = "X"; then
- e_script="$1"
- script_file=
- fi
+prepare_stat_dir () {
+ if [ ! -d "$STAT_PATH" ]; then
+ logex mkdir -p "$STAT_PATH"
+ [ $? -ne 0 ] && return 1
+ fi
+ return 0
}
-# function: process_p ARGUMENT
-#
-# Process the -p flag.
-function process_p {
- if test $1 -ge 1 -a $1 -le 5; then
- p_phase=$1
- fi
+prepare_log_dir () {
+ local log_path=`dirname "$LOG_FILE"`
+ if [ ! -d "$log_path" ]; then
+ mkdir -p "$log_path"
+ [ $? -ne 0 ] && return 1
+ fi
+ return 0
}
-# function: call_stap
-#
-# Call 'stap' with the options provided. Don't run past phase 4.
-function call_stap {
- # Invoke systemtap.
- # Use -k so we can return results to the client
- # Limit to -p4. i.e. don't run the module
- cd $tmpdir_client
- if test $p_phase -gt 4; then
- server_p_phase=4
- else
- server_p_phase=$p_phase
- fi
+stat_file () { # server-spec
+ echo $STAT_PATH/$1
+}
- eval ${stap_exec_prefix}stap "$stap_options" -k -p $server_p_phase \
- >> $tmpdir_server/stdout \
- 2>> $tmpdir_server/stderr
+default_server_cmds () {
+ echo "EXEC"
+}
- stap_rc=$?
+init_server_opts () {
+ ARCH=`get_arch`
+ RELEASE=`get_release`
+ BUILD=
+ INCLUDE=
+ NICKNAME=
+ NICKNAME_NOT_FOUND=
+ RUNTIME=
+ USER=$STAP_USER
}
-# function: create_response
-#
-# Add information to the server's temp directory representing the response
-# to the client.
-function create_response {
- cd $tmpdir_server
-
- # Get the name of the stap temp directory, which was kept, from stderr.
- tmpdir_line=`cat stderr | grep "Keeping temp"`
- tmpdir_stap=`expr "$tmpdir_line" : '.*"\(.*\)".*'`
-
- # Remove the message about keeping the stap temp directory from stderr, unless
- # the user did request to keep it.
- if test "X$tmpdir_stap" != "X"; then
- if test $keep_temps != 1; then
- sed -i "/^Keeping temp/d" stderr
- fi
+server_still_running () { # PID
+ (ps -e | grep stap-serverd | grep -q $1) && return 0 # Still running
+
+ rm -f $STAT_PATH/$1
+ return 1 # Not running
+}
+
+get_server_pid_by_config () {
+ # Need to save the config, since the process of checking the running
+ # servers alters it.
+ local target_ARCH="$ARCH"
+ local target_RELEASE="$RELEASE"
+ local target_INCLUDE="$INCLUDE"
+ local target_RUNTIME="$RUNTIME"
+ local target_BUILD="$BUILD"
+ local target_USER="$USER"
+ local target_NICKNAME="$NICKNAME"
+
+ # Check the status file for each running server to see if it matches
+ # the one currently configured. We're checking for a given configuration,
+ # so don't compare the nickname.
+ for f in $STAT_PATH/*; do
+ test ! -e $f && continue
+ . $f
+ test "X$ARCH" = "X$target_ARCH" || continue
+ test "X$RELEASE" = "X$target_RELEASE" || continue
+ test "X$INCLUDE" = "X$target_INCLUDE" || continue
+ test "X$RUNTIME" = "X$target_RUNTIME" || continue
+ test "X$BUILD" = "X$target_BUILD" || continue
+ test "X$USER" = "X$target_USER" || continue
+ echo `basename $f` # Server has a pid
+ return
+ done
+
+ ARCH="$target_ARCH"
+ RELEASE="$target_RELEASE"
+ INCLUDE="$target_INCLUDE"
+ RUNTIME="$target_RUNTIME"
+ BUILD="$target_BUILD"
+ USER="$target_USER"
+ NICKNAME="$target_NICKNAME"
+}
+
+get_server_pid_by_nickname () {
+ # No need to save the current configuration. This function is not called
+ # in a context requiring it.
+ local target_NICKNAME="$1"
+
+ # Check the status file for each running server to see if the nickname
+ # matches the one we want.
+ for f in $STAT_PATH/*; do
+ test ! -e $f && continue
+ . $f
+ test "X$NICKNAME" = "X$target_NICKNAME" || continue
+ echo `basename $f` # Server with nickname was found
+ return
+ done
+}
+
+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"
+}
+
+eval_server_command () {
+ local cmd="$1"
+
+ # Accumulate the results of BUILD and INCLUDE commands.
+ if echo $cmd | grep -q ^BUILD; then
+ local prevBUILD="$BUILD"
+ eval $cmd
+ BUILD="$prevBUILD $BUILD"
+ BUILD=`echo $BUILD | sed 's/^ //'`
+ elif echo $cmd | grep -q ^INCLUDE; then
+ local prevINCLUDE="$INCLUDE"
+ eval $cmd
+ INCLUDE="$prevINCLUDE $INCLUDE"
+ INCLUDE=`echo $INCLUDE | sed 's/^ //'`
+ else
+ eval $cmd
+ fi
+}
- # Add the contents of the stap temp directory to the server output directory
- ln -s $tmpdir_stap `basename $tmpdir_stap`
+start_server () {
+ clog $"Starting $prog for $RELEASE $ARCH: " -n
- # Sign the resulting module if --unprivileged was specified.
- if test $unprivileged = 1 -a $p_phase -ge 4 -a $stap_rc = 0; then
- modname=$tmpdir_stap/`grep -m1 '^.*\.ko$' stdout`
- if test "X$modname" != "X"; then
- ${stap_pkglibexecdir}stap-sign-module $modname $ssl_db
- fi
+ # Is there already a server running for the requested kernel release
+ # and arch?
+ local server_pid=`get_server_pid_by_config`
+ if test -n "$server_pid"; then
+ if server_still_running $server_pid; then
+ do_success $"$prog start `echo_server_options`"
+ return 0 # Success
fi
fi
- # If the user specified -p5, remove the name of the kernel module from stdout.
- if test $p_phase = 5; then
- sed -i '/\.ko$/d' stdout
+ # Construct the server start command.
+ local server_cmd="$STAP_START_SERVER -r '$RELEASE' -a '$ARCH'"
+ for b in $BUILD; do
+ server_cmd="$server_cmd -B '$b'"
+ done
+ for i in $INCLUDE; do
+ server_cmd="$server_cmd -I '$i'"
+ done
+ test -n "$RUNTIME" && server_cmd="$server_cmd -R '$RUNTIME'"
+ server_cmd="$server_cmd --log=$LOG_FILE"
+
+ # Start the server here.
+ local pid
+ if [ -n "$USER" ]; then
+ pid=`runuser -s /bin/bash - $USER -c "$server_cmd"`
+ else
+ pid=`eval $server_cmd`
+ fi
+ if [ $? != 0 -o -z "$pid" ]; then
+ if [ -n "$pid" ]; then
+ rm -f $STAT_PATH/$pid
+ fi
+ do_failure $"$prog start `echo_server_options`"
+ return 1 # Failure
fi
- # The return status of the stap command.
- echo -n $stap_rc > rc
-}
+ # Nickname defaults to the pid.
+ test -z "$NICKNAME" && NICKNAME="$pid"
-# function: package_response
-#
-# Package the server's temp directory into a form suitable for sending to the
-# client.
-function package_response {
- cd $tmpdir_env
+ # Write the configuration to the status file.
+ local server_status_file=$STAT_PATH/$pid
+ echo "ARCH='$ARCH'" > $server_status_file
+ echo "USER='$USER'" >> $server_status_file
+ echo "BUILD='$BUILD'" >> $server_status_file
+ echo "INCLUDE='$INCLUDE'" >> $server_status_file
+ echo "NICKNAME='$NICKNAME'" >> $server_status_file
+ echo "RUNTIME='$RUNTIME'" >> $server_status_file
+ echo "RELEASE='$RELEASE'" >> $server_status_file
- # Compress the server's temporary directory into a .zip archive.
- (rm $zip_server && zip -r $zip_server `basename $tmpdir_server` > /dev/null)
- return $?
+ do_success $"$prog start `echo_server_options`"
}
-# function: fatal [ MESSAGE ]
-#
-# Fatal error
-# Prints its arguments to stderr and exits
-function fatal {
- echo "$0: ERROR:" "$@" >> $tmpdir_server/stderr
- echo -n 1 > $tmpdir_server/rc
- package_response
- cleanup
- exit 1
+start () { # server-cmds
+ prepare_stat_dir
+ if [ $? -ne 0 ]; then
+ do_failure $"Failed to make stat directory ($STAT_PATH)"
+ return 1
+ fi
+
+ # Start the specified servers
+ server_cmds="$1"
+ # If none specified, start the configured servers
+ if [ -z "$server_cmds" ]; then
+ load_server_config
+ server_cmds="$CONFIG_SERVER_CMDS"
+
+ # If none configured, start the default servers
+ [ -z "$server_cmds" ] && server_cmds=`default_server_cmds`
+ fi
+
+ # Start each requested server in turn
+ local rc=0
+ local first=1
+ init_server_opts
+ local cmd
+ local prevCmd
+ for cmd in $server_cmds; do
+ prevCmd=$cmd
+ # Evaluate commands until the EXEC command is found.
+ if test "$cmd" != "EXEC"; then
+ eval_server_command $cmd
+ # A specified nickname only sticks if it is the final command.
+ # Otherwise, we have a configuration based on a nicknamed
+ # configuration.
+ echo "$cmd" | grep -q "^NICKNAME=" || NICKNAME=""
+ continue
+ fi
+ # If a nickname was specified, but the corresponding config was not found,
+ # then it is the nickname for this new configuration.
+ if test -n "$NICKNAME_NOT_FOUND"; then
+ NICKNAME="$NICKNAME_NOT_FOUND"
+ NICKNAME_NOT_FOUND=
+ fi
+
+ # Start the configured server
+ test $first = 0 && echo
+ first=0
+ start_server || rc=1
+
+ # Don't use the same nickname for the next server.
+ NICKNAME=
+ done
+
+ return $rc
}
-# Non fatal error
-# Prints its arguments to stderr but does not exit
-function error {
- echo "$0: ERROR:" "$@" >> $tmpdir_server/stderr
+stop () { # server-cmds
+ local first=1
+ local server_list=
+ server_cmds="$1"
+ if [ -n "$server_cmds" ]; then
+ # Get the pids of all the requested servers.
+ init_server_opts
+ local cmd
+ local prevCmd
+ for cmd in $server_cmds; do
+ prevCmd=$cmd
+ # Evaluate commands until the EXEC command is found.
+ if test "$cmd" != "EXEC"; then
+ eval_server_command $cmd
+ # A specified nickname only sticks if it is the final command.
+ # Otherwise, we have a configuration based on a nicknamed
+ # configuration.
+ echo "$cmd" | grep -q "^NICKNAME=" || NICKNAME=""
+ continue
+ fi
+ # If a nickname was specified, but the corresponding config was not
+ # found, it is an error.
+ if test -n "$NICKNAME_NOT_FOUND"; then
+ clog "No configuration found for the nickname '$NICKNAME_NOT_FOUND'" -n
+ NICKNAME="$NICKNAME_NOT_FOUND"
+ do_failure $"$prog stop `echo_server_options`"
+ NICKNAME_NOT_FOUND=
+ rc=1
+ continue
+ fi
+
+ # Get the pid for this server, if it's running
+ local server_pid=`get_server_pid_by_config`
+ if test -n "$server_pid"; then
+ server_list="$server_list $server_pid"
+ continue
+ fi
+
+ # This server is not running, but give a success stop status anyway.
+ test $first = 0 && echo
+ first=0
+ clog $"Stopping $prog for $RELEASE $ARCH: " -n
+ do_success $"$prog stop `echo_server_options`"
+ done
+ else
+ server_list=`managed_servers`
+ if [ -z "$server_list" ]; then
+ clog $"Stopping $prog: " -n
+ do_success $"$prog: No managed servers to stop"
+ return 0
+ fi
+ fi
+
+ # Stop each server in turn
+ local rc=0
+ local pid
+ for pid in $server_list; do
+ . $STAT_PATH/$pid
+
+ test $first = 0 && echo
+ first=0
+ clog $"Stopping $prog for $RELEASE $ARCH: " -n
+
+ local this_rc=0
+ if server_still_running $pid; then
+ if [ -n "$USER" ]; then
+ runuser -s /bin/bash - $USER -c "$STAP_STOP_SERVER $pid"
+ else
+ eval $STAP_STOP_SERVER $pid
+ fi
+ if [ $? != 0 ]; then
+ do_failure $"$prog stop `echo_server_options`"
+ this_rc=1
+ rc=1
+ fi
+ fi
+ if [ $this_rc = 0 ]; then
+ rm -f $STAT_PATH/$pid
+ do_success $"$prog stop `echo_server_options`"
+ fi
+ done
+
+ return $rc
}
-# function cleanup
-#
-# Cleanup work files unless asked to keep them.
-function cleanup {
- # Clean up.
- cd $tmpdir_env
- if test $keep_temps != 1; then
- rm -fr $tmpdir_server
- rm -fr $tmpdir_client
- rm -fr $tmpdir_stap
- fi
+status () { # server-list
+ local rc=0
+
+ # Report status for the specified servers or all running servers, if none
+ # specified.
+ local server_list=
+ server_cmds="$1"
+ if [ -n "$server_cmds" ]; then
+ # Get the pids of all the requested servers.
+ init_server_opts
+ local cmd
+ local prevCmd
+ for cmd in $server_cmds; do
+ prevCmd=$cmd
+ # Evaluate commands until the EXEC command is found.
+ if test "$cmd" != "EXEC"; then
+ eval_server_command $cmd
+ # A specified nickname only sticks if it is the final command.
+ # Otherwise, we have a configuration based on a nicknamed
+ # configuration.
+ echo "$cmd" | grep -q "^NICKNAME=" || NICKNAME=""
+ continue
+ fi
+ # If a nickname was specified, but the corresponding config was not
+ # found, say so.
+ if test -n "$NICKNAME_NOT_FOUND"; then
+ echo "No configuration found for the nickname '$NICKNAME_NOT_FOUND'"
+ NICKNAME_NOT_FOUND=
+ rc=3
+ continue
+ fi
+
+ # Get the pid for this server, if it's running
+ local server_pid=`get_server_pid_by_config`
+ if test -n "$server_pid"; then
+ server_list="$server_list $server_pid"
+ continue
+ fi
+ # This server is not running
+ echo "stap-server `echo_server_options`"
+ rc=3
+ done
+ else
+ server_list=`managed_servers`
+ if [ -z "$server_list" ]; then
+ echo "No managed stap-server is running"
+ return 3
+ fi
+ fi
+
+ # Get status of each server in turn
+ local pid
+ for pid in $server_list; do
+ . $STAT_PATH/$pid
+ if ! server_still_running $pid; then
+ echo "stap-server `echo_server_options` started as PID $pid is no longer running"
+ rc=1
+ continue
+ fi
+ echo "stap-server `echo_server_options` running as PID $pid"
+ done
+
+ return $rc
}
-# function: terminate
-#
-# Terminate gracefully.
-function terminate {
- # Clean up
- cleanup
- exit 1
+# Restart or start if not running
+function restart () { # server-cmds
+ # Restart the specified servers or all servers, if none specified.
+ local server_cmds="$1"
+ if [ -z "$server_cmds" ]; then
+ local server_list=`managed_servers`
+ local pid
+ for pid in $server_list; do
+ . $STAT_PATH/$pid
+ server_cmds="$server_cmds `echo_server_commands` EXEC"
+ done
+ fi
+
+ # Stop the specified servers, or all if none specified
+ stop "$server_cmds"
+ local rc=$?
+ echo
+
+ # Restart the same servers. If none were specified then
+ # start the configured or default server(s)).
+ start "$server_cmds"
+ local this_rc=$?
+ [ $this_rc != 0 ] && rc=$this_rc
+
+ return $rc
}
-#-----------------------------------------------------------------------------
-# Beginning of main line execution.
-#-----------------------------------------------------------------------------
-initialization "$@"
-unpack_request
-check_request
-call_stap
-create_response
-package_response
-cleanup
+# Restart only if running
+function condrestart () { # server-list
+ # Restart the specified servers or all servers, if none specified,
+ # but only if they are already running.
+ local server_cmds="$1"
+ if [ -z "$server_cmds" ]; then
+ local server_list=`managed_servers`
+ local pid
+ for pid in $server_list; do
+ . $STAT_PATH/$pid
+ server_cmds="$server_cmds `echo_server_commands` EXEC"
+ done
+ # No server specified or running?
+ if [ -z "$server_cmds" ]; then
+ clog "No managed stap-server is running" -n
+ do_success "No managed stap-server is running"
+ return 0
+ fi
+ fi
+
+ # For each server in the list, stop it if it is running
+ local start_cmds=
+ local first=1
+ local server_cmd=
+ local cmd
+ for cmd in $server_cmds; do
+ # Execute and collect commands until the EXEC command is found.
+ server_cmd="$server_cmd $cmd"
+ if test "$cmd" != "EXEC"; then
+ eval_server_command $cmd
+ continue
+ fi
+
+ test $first = 0 && echo
+ first=0
+
+ # Now see if this server is running
+ if ! status "$server_cmd" >/dev/null 2>&1; then
+ clog $"$prog for $RELEASE $ARCH is not running" -n
+ do_success "$prog `echo_server_options` is not running"
+ server_cmd=
+ continue
+ fi
+
+ start_cmds="$start_cmds $server_cmd"
+
+ stop "$server_cmd"
+ this_rc=$?
+ [ $this_rc != 0 ] && rc=$this_rc
+
+ server_cmd=
+ done
+
+ # Now restart the servers that were running
+ if [ "X$start_cmds" != "X" ]; then
+ echo
+ start "$start_cmds"
+ local this_rc=$?
+ [ $this_rc != 0 ] && rc=$this_rc
+ fi
+
+ return $rc
+}
-exit 0
+#------------------------------------------------------------------
+# Mainline script
+#------------------------------------------------------------------
+CMD=$1
+shift 1
+
+prepare_log_dir
+if [ $? -ne 0 ]; then
+ echo $"Failed to make log directory (`dirname $LOG_FILE`)" >&2
+ exit 1
+fi
+
+OPTS=`getopt -s bash -u -o 'a:B:c:iI:n:p:r:R:u:' -- $@`
+if [ $? -ne 0 ]; then
+ echo "Error: Argument parse error: $@" >&2
+ echo_usage
+ exit 2
+fi
+
+# Initialize server specs
+OPT_SERVER_CMDS=
+parse_args $OPTS || exit 2
+load_config
+
+RETVAL=0
+
+case $CMD in
+ start)
+ # Start specified servers. If none specified, start configured servers
+ start "$OPT_SERVER_CMDS"
+ RETVAL=$?
+ ;;
+ stop)
+ # Stop specified servers
+ stop "$OPT_SERVER_CMDS"
+ RETVAL=$?
+ ;;
+ # Restart specified servers
+ restart)
+ restart "$OPT_SERVER_CMDS"
+ RETVAL=$?
+ ;;
+ # Restart specified servers if they are running
+ condrestart|try-restart)
+ condrestart "$OPT_SERVER_CMDS"
+ RETVAL=$?
+ ;;
+ # Give status on specified servers
+ status)
+ status "$OPT_SERVER_CMDS"
+ exit $?
+ ;;
+ # Reloading config without stop/restart is not supported
+ reload)
+ RETVAL=3
+ ;;
+ # Reload config with stop/start
+ force-reload)
+ # stop all running servers
+ stop
+ echo
+ # Restart specified servers
+ # If none specified, restart configured servers
+ start "$OPT_SERVER_CMDS"
+ RETVAL=$?
+ ;;
+ usage|*)
+ echo_usage
+ RETVAL=0
+ ;;
+esac
+
+echo
+exit $RETVAL