#!/bin/bash # # 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. # config: /etc/sysconfig/stap-server # config: /etc/stap-server/conf.d BINDIR=@bindir@ # 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 UNAME=/bin/uname # Path setup CONFIG_FILE=/etc/sysconfig/stap-server CONFIG_PATH=/etc/stap-server/conf.d STAT_PATH=/var/run/stap-server LOG_FILE=/var/log/stap-server.log # Default Settings STAP_USER=stap-server # 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 config file" echo $" -a arch : change the target architecture" echo $" -r release : specify a kernel release" echo $" -i : specify all installed kernel releases" 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 $"The specified action is performed on each server specified on the command line." echo $"If no servers are specified on the command line, the behavior is as follows:" echo $"" echo $" start: Start the servers configured in /etc/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 $"" } #----------------------------------------------------------------- # 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" } #------------------------------------------------------------------ # 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 ;; -c) OPT_CONFIG_FILE=$2 shift 1 ;; -i) process_i ;; -r) process_r $2 test $? = 0 || rc=1 shift 1 ;; --) ;; *) rc=1 ;; esac shift 1 done test $rc != 0 && echo_usage return $rc } # Process the -i flag. process_i () { cd /lib/modules local release for release in `ls`; do process_r $release done 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_CMDS="$OPT_SERVER_CMDS RELEASE='$kernel_release'" return 0 fi # kernel release specified directly OPT_SERVER_CMDS="$OPT_SERVER_CMDS RELEASE='$1'" return 0 } load_config () { # Include configs if [ -f "$CONFIG_FILE" ]; then . "$CONFIG_FILE" fi if [ -f "$OPT_CONFIG_FILE" ]; then . "$OPT_CONFIG_FILE" fi } # Default to the currently running kernel release get_release () { $UNAME -r } # Default to the currently running kernel release get_arch () { stap_get_arch } load_server_config () { CONFIG_SERVER_CMDS= for f in "$CONFIG_PATH"/*.conf; do if [ -f "$f" ]; then # Obtain an architecture and release from each config file. # Ensure that we get the default architecture and release if they # are not specified. local ARCH= local RELEASE= . "$f" [ -z "$ARCH" ] && ARCH=`get_arch` [ -z "$RELEASE" ] && RELEASE=`get_release` CONFIG_SERVER_CMDS="$CONFIG_SERVER_CMDS ARCH='$ARCH' RELEASE='$RELEASE'" fi done } prepare_stat_dir () { if [ ! -d "$STAT_PATH" ]; then logex mkdir -p "$STAT_PATH" [ $? -ne 0 ] && return 1 fi return 0 } stat_file () { # server-spec echo $STAT_PATH/$1 } default_server_cmds () { echo "RELEASE='`get_release`'" } init_server_opts () { ARCH=`get_arch` } 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 () { local target_release="$RELEASE" local target_arch="$ARCH" # Check the status file for each running server to see if it matches # the one currently configured. for f in $STAT_PATH/*; do test ! -e $f && continue . $f test "$RELEASE" = "$target_release" || continue test "$ARCH" = "$target_arch" || continue echo `basename $f` # Server has a pid return done RELEASE="$target_release" ARCH="$target_arch" } 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 () { # 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 for cmd in $server_cmds; do # Evaluate commands until the RELEASE= command is found. eval $cmd echo $cmd | grep -q ^RELEASE || continue 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? local server_pid=`get_server_pid` if test -n "$server_pid"; then if server_still_running $server_pid; then do_success $"$prog start for $RELEASE $ARCH" continue fi fi # Start the server here. local server_status_file=$STAT_PATH/`runuser -s /bin/bash - $STAP_USER \ -c "$STAP_START_SERVER -r $RELEASE -a $ARCH --log=$LOG_FILE"` if [ $? != 0 ]; then rm -f $server_status_file do_failure $"$prog start: unable to start stap-server for $RELEASE $ARCH" rc=1 continue fi echo "ARCH=$ARCH" > $server_status_file echo "RELEASE=$RELEASE" >> $server_status_file do_success $"$prog start for $RELEASE $ARCH" done return $rc } 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 for cmd in $server_cmds; do # Evaluate commands until the RELEASE= command is found. eval $cmd echo $cmd | grep -q ^RELEASE || continue # Get the pid for this server, if it's running local server_pid=`get_server_pid` 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 for $release_arch" done fi if [ -z "$server_list" ]; then # If there was a non-existent server specified, then we're done test $first = 0 && return 0 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 runuser -s /bin/bash - $STAP_USER -c "$STAP_STOP_SERVER $pid" if [ $? != 0 ]; then do_failure $"$prog stop: unable to stop stap-server for $RELEASE $ARCH" this_rc=1 rc=1 fi fi if [ $this_rc = 0 ]; then rm -f $STAT_PATH/$pid do_success $"$prog stop for $RELEASE $ARCH" fi done return $rc } 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 for cmd in $server_cmds; do # Evaluate commands until the RELEASE= command is found. eval $cmd echo $cmd | grep -q ^RELEASE || continue # Get the pid for this server, if it's running local server_pid=`get_server_pid` if test -n "$server_pid"; then server_list="$server_list $server_pid" continue fi # This server is not running echo "stap-server for $RELEASE $ARCH is not running" rc=3 done fi if [ -z "$server_list" ]; then 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 for $RELEASE $ARCH started as PID $pid is no longer running" rc=1 continue fi echo "stap-server for $RELEASE $ARCH running as PID $pid" done return $rc } # 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 ARCH='$ARCH' RELEASE='$RELEASE'" 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 } # 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 ARCH='$ARCH' RELEASE='$RELEASE'" 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 # Collect commands until the RELEASE= command is found. server_cmd="$server_cmd $cmd" eval $cmd echo $cmd | grep -q ^RELEASE || continue 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 for $RELEASE $ARCH 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 } #------------------------------------------------------------------ # Mainline script #------------------------------------------------------------------ CMD=$1 shift 1 OPTS=`getopt -s bash -u -o 'a:c:ir:' -- $@` if [ $? -ne 0 ]; then slog "Error: Argument parse error: $@" failure $"parse error" 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