summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--initscript/README.stap-server120
-rw-r--r--initscript/stap-server.in709
-rw-r--r--modsign.cxx10
-rw-r--r--runtime/staprun/modverify.c3
-rwxr-xr-xstap-client3
-rwxr-xr-xstap-serverd26
-rw-r--r--systemtap.spec7
7 files changed, 654 insertions, 224 deletions
diff --git a/initscript/README.stap-server b/initscript/README.stap-server
index 1e1d1bf5..8d18a9f9 100644
--- a/initscript/README.stap-server
+++ b/initscript/README.stap-server
@@ -1,5 +1,5 @@
stap-server initscript
-Version 0.1.0
+Version 0.1.1
INDEX
=====
@@ -27,15 +27,15 @@ One of the actions below must be specified.
2.2.1 start
Start server(s). If a specified server is already started, this action will
- be ignored for that server. If any server fails to start this action fails.
+ be ignored for that server. If any server fails to start, this action fails.
If no server is specified, the configured servers are started. If no servers
are configured, a server for the kernel release and architecture of the host
is started.
2.2.2 stop
Stop server(s). If a specified server is already stopped, this action
- will be ignored for that server. If a server fails to stop, this action fails.
- If no server is specified, all currently running servers are stopped.
+ will be successful for that server. If a server fails to stop, this action
+ fails. If no server is specified, all currently running servers are stopped.
2.2.3 restart
Stop and start servers again. The specified servers are stopped and restarted.
@@ -72,21 +72,62 @@ to specify servers to be managed.
configuration file specified will be used.
2.3.2 -a architecture
- Each stap-server instance targets a specific kernel release and target
- architecture. This option specifies the target architecture to be associated
- with subsequent -r options. The default architecture is the architecture of
- the host.
+ This option specifies the target architecture of the server and is
+ analogous to the -a option of 'stap'. See stap(1) for more details.
+ The default architecture is the architecture of the host.
2.3.3 -r kernel-release
- This option specifies a server for the given kernel release and the current
- target architecture (specified by a previous -a option, or the default). The
- arguments accepted by this option are the same as for stap itself. See stap(1)
- for more details.
-
-2.3.4 -i
+ This option specifies the target kernel release of the server an is
+ analogous to the -r option of 'stap'. See stap(1) for more details.
+ The default release is that of the currently running kernel.
+
+2.3.4 -u user-name
+ Each stap-server instance is normally run by the user name 'stap-server',
+ unless otherwise configured (see 3.2 Configuation Files). This option
+ specifies the user name used to run the server(s). The user name specified
+ must be a member of the group 'stap-server'.
+
+2.3.5 -I path
+ This option specifies an additional path to be searched by thes server for
+ tapsets and is analogous to the -I option of 'stap'. See stap(1) for more
+ details.
+
+2.3.6 -R path
+ This option specifies the location of the systemtap runtime to be user by the
+ server and is analogous to the -R option of 'stap'. See stap(1) for more
+ details.
+
+2.3.7 -B options
+ This option specifies options to be passed to 'make' when building systemtap
+ modules and is analogous to the -B option of 'stap'. See stap(1) for more
+ details.
+
+2.3.8 -i
This option is a shortcut which specifies one server for each kernel
- release installed in /lib/modules/. The default architecture is associated
- with these servers (i.e. previous -a has no effect).
+ release installed in /lib/modules/. Previous -I, -R, -B and -u options will be
+ applied to each server, however previous -a options are ignored and the default
+ architecture is used.
+
+2.3.9 -n nickname
+ This option allows the specification of a server configuration by nickname.
+ When -n is specified, a currently running server with the given nickname will
+ be searched for. If no currently running server with the given nickname is
+ found, a server configuration with the given nickname will be searched for in
+ /etc/stap-server/conf.d/*.conf. If a server configuration for the given
+ nickname is found, the -a, -r, -I, -R, -B and -u options for that server will
+ be used as if they were specified on the command line. If no configuration with
+ the given nickname is found, and the action is 'start' (or an action behaving
+ like 'start' (see below), the server will be started with the given nickname.
+ If no configuration with the given nickname is found, and the action is not
+ 'start' (or an action behaving" "like 'start', it is an error. If a nickname is
+ not specified for a server, its nickname will be its process id.
+
+2.3.10 -p pid
+ This option allows the specification of a server configuration by process id.
+ When -p is specified, a currently running server with the given process id will
+ be searched for. If no such server is found, it is an error. If a server with
+ the given procss id is found, the -a, -r, -I, -R, -B and -u options for that
+ server will be used as if they were specified on the command line.
3. Files
========
@@ -122,7 +163,7 @@ output is optional, because this service may start before syslog).
3.4 Status files
----------------
-/var/run/stap-server/<server_spec>
+/var/run/stap-server/<server_pid>
4. Configuration Format
=======================
@@ -156,7 +197,8 @@ variables.
4.2 Individual server configuration (/etc/stap-server/conf.d/*.conf)
--------------------------------------------------------------------
Each server configuration file configures a server to be started when no
-server is specified for the 'start' action.
+server is specified for the 'start' action. The configuration file is a
+bash script fragment. The following variables may be set.
4.2.1 ARCH
Specify the target architecture for this server. If ARCH is not set, the
@@ -166,6 +208,24 @@ server is specified for the 'start' action.
Specify the kernel release for this server. If RELEASE is not set, the release
of the kernel running on the host will be used.
+4.2.3 BUILD
+ Specify options to be passed to the 'make' process used to build kernel
+ modules.
+
+4.2.4 INCLUDE
+ Specify a list of directories to be searched by the server for tapsets.
+
+4.2.5 RUNTIME
+ Specify the directory which contains the systemtap runtime code to be used
+ by this server.
+
+4.2.6 USER
+ Specify the user name to be used to run this server. The specified user must
+ be a member of the group 'stap-server'.
+
+4.2.6 NICKNAME
+ Specify the nickname to be used to refer to this server.
+
4.3 Configuration Example
-------------------------
@@ -179,9 +239,15 @@ server is specified for the 'start' action.
--- file1.conf
ARCH=i386
RELEASE=2.6.18-128.el5
+ ---
+
--- file2.conf
- ARCH=powerpc
+ USER=serveruser
RELEASE=/kernels/2.6.18-92.1.18.el5/build
+ INCLUDE="/mytapsets /yourtapsets"
+ BUILD='VARIABLE1=VALUE1 VARIABLE2=VALUE2'
+ RUNTIME=/myruntime
+ NICKNAME=my-server
---
5. Usage Eamples
@@ -191,8 +257,7 @@ server is specified for the 'start' action.
------------------------
After installing the systemtap package, install the systemtap-server package.
# yum install systemtap-server
-This package will include the initscript, default configuration files and
-other files.
+This package will include the initscript and default configuration files.
5.2 Testing
-----------
@@ -238,7 +303,7 @@ After all test have passed, enable the stap-server initscript.
5.5 Managing Specific Servers
-----------------------------
-Specifying an architecture and/or release for all other actions will act on
+For all other actions, specifying a server configuration will act on
that server alone (if it is running). For example
# service stap-server status -r 2.6.18-128.el5
@@ -250,20 +315,25 @@ that server alone (if it is running). For example
5.6.1 Create Server Config Files
Each file in /etc/stap-server/conf.d/*.conf represents a server to be started
by default if no servers are specified on the 'start' action. Each such
- config file may set the ARCH and/or RELEASE variables which correspond to the
- -a and -r command line options respectively.
+ config file may set variables which correspond to the command line options.
# vi /etc/stap-server/conf.d/2.6.18-128.el5.conf
ARCH= # default arch
+ USER=serveruser
RELEASE=2.6.18-128.el5
+ NICKNAME=2.6.18-128.el5
# vi /etc/stap-server/conf.d/powerpc.conf
ARCH=powerpc
+ USER= # default user
RELEASE= #default release
+ NICKNAME=powerpc
# vi /etc/stap-server/conf.d/native.conf
ARCH= #default arch
+ USER= # default user
RELEASE= #default release
+ NICKNAME=native
5.6.2 Starting Default Servers
@@ -272,7 +342,7 @@ that server alone (if it is running). For example
5.6.2 Restarting After Changing the Configuration
To restart the service after global configuration changes and/or when default
- servers have been added to removed:
+ servers have been added, changed or removed:
# service stap-server force-reload
diff --git a/initscript/stap-server.in b/initscript/stap-server.in
index 48808eb4..07595ec6 100644
--- a/initscript/stap-server.in
+++ b/initscript/stap-server.in
@@ -23,46 +23,75 @@ STAP_START_SERVER=$BINDIR/stap-start-server
STAP_STOP_SERVER=$BINDIR/stap-stop-server
UNAME=/bin/uname
-# Path setup
+# Default Global Configuration
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
-# Target architecture
-OPT_KERNEL_ARCH=`stap_get_arch`
-# A list of release_arch pairs
-OPT_SERVER_LIST=
# 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 $" -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 $"All options, except -c, may be specified more than once."
+ echo $"If -a is not specified, the default architecture is that of the host"
+ echo $"platform."
echo $""
- echo $"Each -a option changes the target architecture for subsequent -r"
- echo $"options. The default is the architecture of the host platform."
+ echo $"If -r is not specified, the default kernel release is that currently"
+ echo $"running on 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 $"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/. The default architecture is used"
- echo $"for these servers."
+ 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 /etc/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 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 $"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 /etc/stap-server/conf.d/*.conf."
echo $" If none are configured, start a server for the kernel release"
@@ -121,7 +150,11 @@ parse_args () { # arguments
while [ -n "$1" ]; do
case "$1" in
-a)
- OPT_KERNEL_ARCH=$2
+ OPT_SERVER_CMDS="$OPT_SERVER_CMDS ARCH='$2'"
+ shift 1
+ ;;
+ -B)
+ OPT_SERVER_CMDS="$OPT_SERVER_CMDS BUILD='$2'"
shift 1
;;
-c)
@@ -131,11 +164,32 @@ parse_args () { # arguments
-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
+ ;;
--)
;;
*)
@@ -145,22 +199,65 @@ parse_args () { # arguments
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
}
# 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
+ test -n "$OPT_SERVER_CMDS" && OPT_SERVER_CMDS="$OPT_SERVER_CMDS EXEC"
+ process_r $release
+ done
+
+ return 0
+}
+
+# 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
- OPT_KERNEL_ARCH=$save_arch
+ # 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"
+
+ # Are we managing a server with the given pid?
+ test ! -f $STAT_PATH/$pid && echo "No stap-server running as pid $pid" && \
+ 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`"
+
return 0
}
@@ -178,33 +275,15 @@ process_r () {
echo "Missing $version_file_name"
return 1
fi
- OPT_SERVER_LIST="$OPT_SERVER_LIST ${kernel_release}_${OPT_KERNEL_ARCH}"
+ OPT_SERVER_CMDS="$OPT_SERVER_CMDS RELEASE='$kernel_release'"
return 0
fi
# kernel release specified directly
- OPT_SERVER_LIST="$OPT_SERVER_LIST ${1}_${OPT_KERNEL_ARCH}"
+ OPT_SERVER_CMDS="$OPT_SERVER_CMDS RELEASE='$1'"
return 0
}
-# 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 "$1" : '.*_\(.*\)'
- fi
-}
-
load_config () {
# Include configs
if [ -f "$CONFIG_FILE" ]; then
@@ -215,19 +294,67 @@ load_config () {
fi
}
+# Default to the currently running kernel release
+get_release () {
+ $UNAME -r
+}
+
+# Default to the currently running kernel release
+get_arch () {
+ stap_get_arch
+}
+
+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'"
+ # The NICKNAME= command must be last. See start ().
+ echo -n " NICKNAME='$NICKNAME'"
+ echo
+}
+
+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
+}
+
load_server_config () {
- CONFIG_OPTS=
+ 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.
+ # 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"
- [ -z "$ARCH" ] && ARCH=`get_arch`
- [ -z "$RELEASE" ] && RELEASE=`get_release`
- CONFIG_OPTS="$CONFIG_OPTS -a $ARCH -r $RELEASE"
+ # 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
done
}
@@ -244,16 +371,78 @@ stat_file () { # server-spec
echo $STAT_PATH/$1
}
-default_server_list () {
- echo "`get_release`_`get_arch`"
+default_server_cmds () {
+ echo "EXEC"
}
-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
+init_server_opts () {
+ ARCH=`get_arch`
+ RELEASE=`get_release`
+ BUILD=
+ INCLUDE=
+ NICKNAME=
+ NICKNAME_NOT_FOUND=
+ RUNTIME=
+ USER=$STAP_USER
+}
+
+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 () {
@@ -271,7 +460,76 @@ managed_servers () {
echo "$list"
}
-start () { # server-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
+}
+
+start_server () {
+ 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_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
+
+ # 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=`runuser -s /bin/bash - $USER -c "$server_cmd"`
+ 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
+
+ # Nickname defaults to the pid.
+ test -z "$NICKNAME" && NICKNAME="$pid"
+
+ # 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
+
+ do_success $"$prog start `echo_server_options`"
+}
+
+start () { # server-cmds
prepare_stat_dir
if [ $? -ne 0 ]; then
do_failure $"Failed to make stat directory ($STAT_PATH)"
@@ -279,91 +537,127 @@ start () { # server-list
fi
# Start the specified servers
- local server_list="$1"
+ server_cmds="$1"
# If none specified, start the configured servers
- if [ -z "$server_list" ]; then
+ if [ -z "$server_cmds" ]; then
load_server_config
- parse_args $CONFIG_OPTS || exit 2
- server_list="$OPT_SERVER_LIST"
+ server_cmds="$CONFIG_SERVER_CMDS"
# If none configured, start the default servers
- [ -z "$server_list" ] && server_list=`default_server_list`
+ [ -z "$server_cmds" ] && server_cmds=`default_server_cmds`
fi
# Start each requested server in turn
local rc=0
- 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"
+ 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
-
- # Start the server here.
- local server_status=`stat_file $spec`
- runuser -s /bin/bash - $STAP_USER -c "$STAP_START_SERVER -r $release -a $arch --log=$LOG_FILE" > $server_status
- if [ $? != 0 ]; then
- rm -f $server_status
- do_failure $"$prog start: unable to start stap-server for $release $arch"
- rc=1
- continue
+ # 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
- do_success $"$prog start for $release $arch"
+ # 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
}
-stop () { # server-list
- local server_status
- local server_list
+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
- # Stop the specified servers or all servers, if none specified.
- server_list="$1"
- [ -z "$server_list" ] && server_list=`managed_servers`
+ # 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
- # No server specified or running?
- if [ -z "$server_list" ]; then
- clog $"Stopping $prog: " -n
- do_success $"$prog: No managed servers to stop"
- return 0
+ # 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
- for server_status in $server_list; do
- release_arch=`echo $server_status | sed 's/_/ /'`
+ local pid
+ for pid in $server_list; do
+ . $STAT_PATH/$pid
test $first = 0 && echo
first=0
- clog $"Stopping $prog for $release_arch: " -n
+ clog $"Stopping $prog for $RELEASE $ARCH: " -n
local this_rc=0
- local server_status_file=`stat_file $server_status`
- if check_server_running $server_status; then
- local pid=`cat $server_status_file`
- runuser -s /bin/bash - $STAP_USER -c "$STAP_STOP_SERVER $pid"
+ if server_still_running $pid; then
+ runuser -s /bin/bash - $USER -c "$STAP_STOP_SERVER $pid"
if [ $? != 0 ]; then
- do_failure $"$prog start: unable to start stap-server for $release $arch"
+ do_failure $"$prog stop `echo_server_options`"
this_rc=1
rc=1
fi
fi
if [ $this_rc = 0 ]; then
- rm -f $server_status_file
- do_success $"$prog stop for $release_arch"
+ rm -f $STAT_PATH/$pid
+ do_success $"$prog stop `echo_server_options`"
fi
done
@@ -371,58 +665,91 @@ stop () { # server-list
}
status () { # server-list
- local server_list
local rc=0
- # Report status for the specified servers or all servers, if none specified.
- server_list="$1"
- [ -z "$server_list" ] && server_list=`managed_servers`
+ # 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
- # No server specified or running?
- if [ -z "$server_list" ]; then
- echo "No managed stap-server is running"
- return 3
+ # 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 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"
- rc=3
- 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
- rc=1
- fi
+ 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
}
# Restart or start if not running
-function restart () { # server-list
- local server_list
-
+function restart () { # server-cmds
# Restart the specified servers or all servers, if none specified.
- server_list="$1"
- [ -z "$server_list" ] && server_list=`managed_servers`
+ 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_list"
+ stop "$server_cmds"
local rc=$?
echo
# Restart the same servers. If none were specified then
# start the configured or default server(s)).
- start "$server_list"
+ start "$server_cmds"
local this_rc=$?
[ $this_rc != 0 ] && rc=$this_rc
@@ -431,52 +758,64 @@ function restart () { # server-list
# Restart only if running
function condrestart () { # server-list
- local server_list
-
# Restart the specified servers or all servers, if none specified,
# but only if they are already running.
- server_list="$1"
- [ -z "$server_list" ] && server_list=`managed_servers`
-
- # No server specified or running?
- if [ -z "$server_list" ]; then
- clog "No managed stap-server is running" -n
- do_success "No managed stap-server is running"
- return 0
+ 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 rc=0
- local this_rc
- local start_list=
- local server_spec
+ local start_cmds=
local first=1
- for server_spec in $server_list; do
- test $first = 0 && echo
- first=0
-
- if ! status $server_spec >/dev/null 2>&1; then
- local release=`get_release $server_spec`
- local arch=`get_arch $server_spec`
- clog $"$prog for $release $arch is not running" -n
- do_success "$prog for $release $arch is not running"
+ 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
+ fi
+
+ start_cmds="$start_cmds $server_cmd"
- start_list="$start_list $server_spec"
+ stop "$server_cmd"
+ this_rc=$?
+ [ $this_rc != 0 ] && rc=$this_rc
- stop "$server_spec"
- this_rc=$?
- [ $this_rc != 0 ] && rc=$this_rc
+ server_cmd=
done
# Now restart the servers that were running
- for server_spec in $start_list; do
- echo
- start "$server_spec"
- local this_rc=$?
- [ $this_rc != 0 ] && rc=$this_rc
- done
+ if [ "X$start_cmds" != "X" ]; then
+ echo
+ start "$start_cmds"
+ local this_rc=$?
+ [ $this_rc != 0 ] && rc=$this_rc
+ fi
return $rc
}
@@ -486,7 +825,7 @@ function condrestart () { # server-list
#------------------------------------------------------------------
CMD=$1
shift 1
-OPTS=`getopt -s bash -u -o 'a:c:ir:' -- $@`
+OPTS=`getopt -s bash -u -o 'a:B:c:iI:n:p:r:R:u:' -- $@`
if [ $? -ne 0 ]; then
slog "Error: Argument parse error: $@"
failure $"parse error"
@@ -494,6 +833,8 @@ if [ $? -ne 0 ]; then
exit 2
fi
+# Initialize server specs
+OPT_SERVER_CMDS=
parse_args $OPTS || exit 2
load_config
@@ -502,27 +843,27 @@ RETVAL=0
case $CMD in
start)
# Start specified servers. If none specified, start configured servers
- start "$OPT_SERVER_LIST"
+ start "$OPT_SERVER_CMDS"
RETVAL=$?
;;
stop)
# Stop specified servers
- stop "$OPT_SERVER_LIST"
+ stop "$OPT_SERVER_CMDS"
RETVAL=$?
;;
# Restart specified servers
restart)
- restart "$OPT_SERVER_LIST"
+ restart "$OPT_SERVER_CMDS"
RETVAL=$?
;;
# Restart specified servers if they are running
condrestart|try-restart)
- condrestart "$OPT_SERVER_LIST"
+ condrestart "$OPT_SERVER_CMDS"
RETVAL=$?
;;
# Give status on specified servers
status)
- status "$OPT_SERVER_LIST"
+ status "$OPT_SERVER_CMDS"
exit $?
;;
# Reloading config without stop/restart is not supported
@@ -536,7 +877,7 @@ case $CMD in
echo
# Restart specified servers
# If none specified, restart configured servers
- start "$OPT_SERVER_LIST"
+ start "$OPT_SERVER_CMDS"
RETVAL=$?
;;
usage|*)
diff --git a/modsign.cxx b/modsign.cxx
index 0965b923..326534ce 100644
--- a/modsign.cxx
+++ b/modsign.cxx
@@ -49,20 +49,12 @@ using namespace std;
*/
static int
init_cert_db_path (const string &cert_db_path) {
- int rc, rc1;
+ int rc;
// Generate the certificate and database.
string cmd = BINDIR "/stap-gen-cert " + cert_db_path;
rc = system (cmd.c_str ()) == 0;
- // If we are root, authorize the new certificate as a trusted
- // signer. It is not an error if this fails.
- if (geteuid () == 0)
- {
- cmd = BINDIR "/stap-authorize-signing-cert " + cert_db_path + "/stap.cert";
- rc1 = system (cmd.c_str ());
- }
-
return rc;
}
diff --git a/runtime/staprun/modverify.c b/runtime/staprun/modverify.c
index 4ed5eb74..a17bb2ec 100644
--- a/runtime/staprun/modverify.c
+++ b/runtime/staprun/modverify.c
@@ -330,6 +330,7 @@ int verify_module (const char *signatureName, const char* module_name,
fprintf (stderr, "Unable to initialize nss library using the database in %s.\n",
dbdir);
nssError ();
+ nssCleanup ();
return MODULE_CHECK_ERROR;
}
@@ -339,6 +340,7 @@ int verify_module (const char *signatureName, const char* module_name,
fprintf (stderr, "Unable to find certificates in the certificate database in %s.\n",
dbdir);
nssError ();
+ nssCleanup ();
return MODULE_UNTRUSTED;
}
@@ -355,6 +357,7 @@ int verify_module (const char *signatureName, const char* module_name,
fprintf (stderr, "Unable to extract public key from the certificate with nickname %s from the certificate database in %s.\n",
cert->nickname, dbdir);
nssError ();
+ nssCleanup ();
return MODULE_CHECK_ERROR;
}
diff --git a/stap-client b/stap-client
index 68584e1b..e5f2d941 100755
--- a/stap-client
+++ b/stap-client
@@ -331,7 +331,6 @@ function process_server {
# Process the -c flag.
function process_c {
c_cmd="$1"
- cmdline2="${cmdline2} -c '$1'"
}
# function: process_e ARGUMENT
@@ -838,7 +837,7 @@ function maybe_call_staprun {
# Run it in the background and wait for it. This
# way any signals sent to us can be caught.
if test $v_level -ge 2; then
- echo "running `which staprun` $staprun_opts $module_name.ko" >&2
+ echo "running `staprun_PATH` $staprun_opts $module_name.ko" >&2
fi
eval `staprun_PATH` "$staprun_opts" $module_name.ko
rc=$?
diff --git a/stap-serverd b/stap-serverd
index d2f99cdb..d8eb1962 100755
--- a/stap-serverd
+++ b/stap-serverd
@@ -31,6 +31,9 @@ function initialization {
uname_r="`uname -r`"
arch="`stap_get_arch`"
logfile=/dev/null
+ B_options=
+ I_options=
+ R_option=
# Parse the arguments
parse_options "$@"
@@ -147,6 +150,7 @@ function parse_options {
;;
B)
get_arg $first_token $2
+ B_options="$B_options $stap_arg"
stap_options="$stap_options -$first_char $stap_arg"
;;
c)
@@ -167,6 +171,7 @@ function parse_options {
;;
I)
get_arg $first_token $2
+ I_options="$I_options $stap_arg"
stap_options="$stap_options -$first_char $stap_arg"
;;
l)
@@ -195,6 +200,7 @@ function parse_options {
;;
R)
get_arg $first_token $2
+ R_option="$stap_arg"
stap_options="$stap_options -$first_char $stap_arg"
;;
s)
@@ -306,13 +312,25 @@ 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"
+ # Build up a strings representing our server's properties.
+ # The service name must differ for each server, so put the port number
+ # in it.
+ local service_name="Systemtap Compile Server on port $port"
+
+ local sysinfo="sysinfo=$uname_r $arch"
+ local optinfo="optinfo="
+ test -n "$R_option" && optinfo="${optinfo}-R '$R_option'"
+ for opt in $B_options; do
+ optinfo="$optinfo -B '$opt'"
+ done
+ for opt in $I_options; do
+ optinfo="$optinfo -I '$opt'"
+ done
+ optinfo=`echo $optinfo | sed 's/optinfo= /optinfo=/'`
# Call avahi-publish-service to advertise our presence.
avahi-publish-service "$service_name" \
- $stap_avahi_service_tag $port "$txt" >> $logfile 2>&1 &
+ $stap_avahi_service_tag $port "$sysinfo" "$optinfo" >> $logfile 2>&1 &
echo "$service_name listening on port $port" >> $logfile
}
diff --git a/systemtap.spec b/systemtap.spec
index 508f03ba..c0cddbb5 100644
--- a/systemtap.spec
+++ b/systemtap.spec
@@ -315,6 +315,13 @@ chgrp stap-server %{_localstatedir}/log/stap-server.log
test -e /usr/share/systemtap/runtime/uprobes || mkdir -p /usr/share/systemtap/runtime/uprobes
chgrp stap-server /usr/share/systemtap/runtime/uprobes
chmod 775 /usr/share/systemtap/runtime/uprobes
+# As stap-server, generate the certificate used for signing and for ssl.
+runuser -s /bin/sh - stap-server -c %{_bindir}/stap-gen-cert >/dev/null
+# Authorize the certificate as a trusted ssl peer and as a trusted signer
+# local host.
+%{_bindir}/stap-authorize-server-cert %{_localstatedir}/lib/stap-server/.systemtap/ssl/server/stap.cert
+%{_bindir}/stap-authorize-signing-cert %{_localstatedir}/lib/stap-server/.systemtap/ssl/server/stap.cert
+
# Activate the service
/sbin/chkconfig --add stap-server
exit 0