diff options
-rw-r--r-- | initscript/README.stap-server | 120 | ||||
-rw-r--r-- | initscript/stap-server.in | 709 | ||||
-rw-r--r-- | modsign.cxx | 10 | ||||
-rw-r--r-- | runtime/staprun/modverify.c | 3 | ||||
-rwxr-xr-x | stap-client | 3 | ||||
-rwxr-xr-x | stap-serverd | 26 | ||||
-rw-r--r-- | systemtap.spec | 7 |
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 |