summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog30
-rwxr-xr-xstap-client146
-rwxr-xr-xstap-server113
-rwxr-xr-xstap-serverd93
4 files changed, 256 insertions, 126 deletions
diff --git a/ChangeLog b/ChangeLog
index 7c34f223..697f4e0d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2008-07-03 <brolley@redhat.com>
+
+ * stap-serverd: New script.
+ * stap-client (client_sysinfo): Client sysinfo is stripped down to
+ the output of `uname -r` for now.
+ (package_request): Don't create temporary server tar file here.
+ (send_request): Communication protocol simplified. Use nc to send
+ the tar file.
+ (receive_response): Communication protocol eliminated. Simply wait
+ for the file from the server using nc.
+ (unpack_response): Create temporary server tar file here. Verify the
+ contents of the server's response.
+ (find_and_connect_to_server): Obtain server address and port from
+ avahi-browse.
+ (server_fatal): New function.
+ (check_server_error): Call server_fatal.
+ * stap-server (configuration): port is now provided as an argument.
+ Default to port 65001.
+ (initialization): Don't create temp work directory here.
+ (receive_request): Communication protocol simplified. Receive the
+ request file using nc.
+ (unpack_request): Make temp work directory here. Verify the contents
+ of the request.
+ (server_sysinfo): New function.
+ (check_compatibility): Exact match required.
+ (package_response): Don't use -p on tar command.
+ (send_response): Communication protocol eliminated. Simply send the
+ file using nc.
+ (main line): Pass "$@" to configuration.
+
2008-07-01 Frank Ch. Eigler <fche@elastic.org>
* main.cxx (main): In -vv mode, also dump out session arch/release
diff --git a/stap-client b/stap-client
index 42402a27..515cab92 100755
--- a/stap-client
+++ b/stap-client
@@ -314,12 +314,8 @@ function create_request {
# Generate the client's sysinfo and echo it to stdout
function client_sysinfo {
if test "X$sysinfo_client" = "X"; then
- # Get the stap version
- stap_version=`stap -V 2>&1 | grep version`
- # Remove the number before the first slash
- stap_version=`expr "$stap_version" : '.*version [^/]*/\([0-9./]*\).*'`
# Add some info from uname
- sysinfo_client="stap $stap_version `uname -sr`"
+ sysinfo_client="`uname -r`"
fi
echo $sysinfo_client
}
@@ -338,67 +334,50 @@ function package_request {
tar -czhf $tar_client $tmpdir_client_base || \
fatal "ERROR: tar of request tree, $tmpdir_client, failed"
-
- tar_server=$tmpdir_env/`mktemp $tmpdir_prefix_server.tgz.XXXXXX` || \
- fatal "ERROR: cannot create temporary file " $tar_server
}
# function: send_request
#
-# Notify the server and then send $tar_client to the server as $tar_server
+# Notify the server and then send $tar_client to the server
# The protocol is:
-# client -> "request: $tmpdir_client"
-# server -> "send: $tar_server"
-# client: rsync local:$tar_client server:$tar_server
-# client -> "waiting:"
+# client -> "request:"
+# server -> "ready:"
+# client -> $tar_client
#
# $tmpdir_client is provided on the request so that the server knows what
# the tar file will expand to.
function send_request {
- echo "request: `basename $tmpdir_client`" >&3
+ echo "request:" >&3
+ # Get the server's response.
read <&3
local line=$REPLY
check_server_error $line
- local tar_dest=`expr "$line" : 'send: \([^ ]*\)$'`
- test "X$tar_dest" == "X" && \
- fatal "ERROR: destination tar file not provided"
-
- rsync -essh -a --delete $tar_client root@$server:$tar_dest || \
- fatal "ERROR: rsync of client request, $tar_client to $server:$tar_dest, failed"
+ # Check for the proper response.
+ test "$line" = "ready:" || \
+ fatal "ERROR: server response, '$line', is incorrect"
- echo "waiting:" >&3
+ # Send the request file.
+ until nc $server $(($port + 1)) < $tar_client
+ do
+ sleep 1
+ done
}
# function: receive_response
#
# Wait for a response from the server indicating the results of our request.
-# The protocol is:
-# server -> "sending: remote-tar-name server-tempdir-name stap-tempdir-name"
-# client -> "OK"
function receive_response {
- read <&3
- local line=$REPLY
- check_server_error $line
-
- tar_dest=`expr "$line" : 'sending: \([^ ]*\) [^ ]* [^ ]*$'`
- test "X$tar_dest" == "X" && \
- fatal "ERROR: server response remote file is missing"
-
- tmpdir_server=`expr "$line" : 'sending: [^ ]* \([^ ]*\) [^ ]*$'`
- test "X$tmpdir_server" == "X" && \
- fatal "ERROR: server response temp dir is missing"
-
- tmpdir_stap=`expr "$line" : 'sending: [^ ]* [^ ]* \([^ ]*\)$'`
- test "X$tmpdir_stap" == "X" && \
- fatal "ERROR: server response stap temp dir is missing"
-
+ # Make a place to receive the response file.
+ tar_server=`mktemp -t $tmpdir_prefix_client.server.tgz.XXXXXX` || \
+ fatal "ERROR: cannot create temporary file " $tar_server
# Retrieve the file
- rsync -essh -a --delete root@$server:$tar_dest $tar_server || \
- fatal "ERROR: rsync of server response, $server:$tar_dest to $tar_server, failed"
- echo "OK" >&3
+ until nc $server $(($port + 1)) > $tar_server
+ do
+ sleep 1
+ done
}
# function: unpack_response
@@ -406,17 +385,45 @@ function receive_response {
# Unpack the tar file received from the server and make the contents available
# for printing the results and/or running 'staprun'.
function unpack_response {
+ tmpdir_server=`mktemp -dt $tmpdir_prefix_client.server.XXXXXX` || \
+ fatal "ERROR: cannot create temporary file " $tmpdir_server
+
# Unpack the server output directory
- cd $tmpdir_client
+ cd $tmpdir_server
tar -xzf $tar_server || \
fatal "ERROR: Unpacking of server response, $tar_server, failed"
- # Create a local location for the server response.
- local local_tmpdir_server_base=`basename $tar_server | sed 's,\.tgz,,'`
- local local_tmpdir_server=`mktemp -dt $local_tmpdir_server_base.XXXXXX` || \
- fatal "ERROR: cannot create temporary directory " $local_tmpdir_server
-
- # Move the systemtap temp directory to our a local temp location, if -k
+ # Identify the server's request tree. The tar file should have expanded
+ # into a single directory named to match $tmpdir_prefix_server.??????
+ # which should now be the only item in the current directory.
+ test "`ls | wc -l`" = 1 || \
+ fatal "ERROR: Wrong number of files after expansion of server's tar file"
+
+ tmpdir_server=`ls`
+ tmpdir_server=`expr "$tmpdir_server" : "\\\($tmpdir_prefix_server\\\\.......\\\)"`
+
+ test "X$tmpdir_server" != "X" || \
+ fatal "ERROR: server tar file did not expand as expected"
+
+ # Check the contents of the expanded directory. It should contain:
+ # 1) a file called stdout
+ # 2) a file called stderr
+ # 3) a directory named to match stap??????
+ test "`ls $tmpdir_server | wc -l`" = 3 || \
+ fatal "ERROR: Wrong number of files after expansion of server's tar file"
+ test -f $tmpdir_server/stdout || \
+ fatal "ERROR: `pwd`/$tmpdir_server/stdout does not exist or is not a regular file"
+ test -f $tmpdir_server/stderr || \
+ fatal "ERROR: `pwd`/$tmpdir_server/stderr does not exist or is not a regular file"
+
+ tmpdir_stap=`ls $tmpdir_server | grep stap`
+ tmpdir_stap=`expr "$tmpdir_stap" : "\\\(stap......\\\)"`
+ test "X$tmpdir_stap" = "X" && \
+ fatal "ERROR: `pwd`/$tmpdir_server/stap?????? does not exist"
+ test -d $tmpdir_server/$tmpdir_stap || \
+ fatal "ERROR: `pwd`/$tmpdir_server/$tmpdir_stap is not a directory"
+
+ # Move the systemtap temp directory to a local temp location, if -k
# was specified.
if test $keep_temps = 1; then
local local_tmpdir_stap=`mktemp -dt stapXXXXXX` || \
@@ -428,13 +435,17 @@ function unpack_response {
sed -i "s,^Keeping temporary directory.*,Keeping temporary directory \"$local_tmpdir_stap\"," $tmpdir_server/stderr
tmpdir_stap=$local_tmpdir_stap
else
- tmpdir_stap=$local_tmpdir_server/$tmpdir_stap
+ tmpdir_stap=`pwd`/$tmpdir_stap
fi
- # Move the extracted tree to our local location
- mv $tmpdir_server/* $local_tmpdir_server
+ # Move the contents of the server's tmpdir down one level to the
+ # current directory (our local server tmpdir)
+ mv $tmpdir_server/* . 2>/dev/null
rm -fr $tmpdir_server
- tmpdir_server=$local_tmpdir_server
+ tmpdir_server=`pwd`
+
+ # Make sure we own the systemtap temp directory if we are root.
+ test $EUID = 0 && chown $EUID:$EUID $tmpdir_stap
}
# function: find_and_connect_to_server
@@ -443,11 +454,14 @@ function unpack_response {
function find_and_connect_to_server {
# Find a server
server=`avahi-browse $avahi_service_tag --terminate -r 2>/dev/null | match_server`
+ port=`expr "$server" : '[^/]*/\(.*\)'`
+ server=`expr "$server" : '\([^/]*\)/.*'`
+
test "X$server" != "X" || \
fatal "ERROR: cannot find a server"
- port=`expr "$server" : '[^/]*/\(.*\)'`
- server=`expr "$server" : '\([^/]*\)/.*'`
+ test "X$port" != "X" || \
+ fatal "ERROR: server port not provided"
# Open a connection to the server
if ! exec 3<> /dev/tcp/$server/$port; then
@@ -500,7 +514,6 @@ function match_server {
;;
txt )
sysinfo_server=`expr "$service_data" : '\[\"\([^]]*\)\"\]'`
- sysinfo_server=`expr "$sysinfo_server" : '[^/]*/\(.*\)'`
;;
* )
break ;;
@@ -508,7 +521,6 @@ function match_server {
done
# It is a stap server, but is it compatible?
- sysinfo_server="stap $sysinfo_server"
if test "$sysinfo_server" != "`client_sysinfo`"; then
continue
fi
@@ -534,9 +546,9 @@ function disconnect_from_server {
# Write the stdout and stderr from the server to stdout and stderr respectively.
function stream_output {
# Output stdout and stderr as directed
- cd $local_tmpdir_server
- cat ${tmpdir_server}/stderr >&2
- eval cat ${tmpdir_server}/stdout $stdout_redirection
+ cd $tmpdir_server
+ cat stderr >&2
+ eval cat stdout $stdout_redirection
}
# function: maybe_call_staprun
@@ -558,7 +570,7 @@ function maybe_call_staprun {
# Check the given server response for an error message.
function check_server_error {
echo $1 | grep -q "^ERROR:" && \
- fatal "Server:" "$@"
+ server_fatal "Server:" "$@"
}
# function: fatal [ MESSAGE ]
@@ -567,6 +579,16 @@ function check_server_error {
# Prints its arguments to stderr and exits
function fatal {
echo $0: "$@" >&2
+ cleanup
+ exit 1
+}
+
+# function: server_fatal [ MESSAGE ]
+#
+# Fatal error
+# Prints its arguments to stderr and exits
+function server_fatal {
+ echo $0: "$@" >&2
cat <&3 >&2
cleanup
exit 1
diff --git a/stap-server b/stap-server
index 1a2e7918..11d6d81d 100755
--- a/stap-server
+++ b/stap-server
@@ -21,6 +21,8 @@ function configuration {
# Configuration
tmpdir_prefix_client=stap.client
tmpdir_prefix_server=stap.server
+ port=$1
+ test "X$port" = "X" && port=65001
}
# function: initialization
@@ -31,54 +33,33 @@ function initialization {
# Default options settings
p_phase=5
keep_temps=0
-
- # Make a temp directory to work in.
- tmpdir_server=`mktemp -dt $tmpdir_prefix_server.XXXXXX` || \
- fatal "ERROR: cannot create temporary directory " $tmpdir_server
- tmpdir_env=`dirname $tmpdir_server`
}
# function: receive_request
#
# Receive a tar file representing the request from the client:
# The protocol is:
-# client -> "request: $tmpdir_client"
-# server -> "send: $tar_client"
-# client: copies file to server:$tar_client
-# client -> "waiting:"
-#
-# $tmpdir_client is provided on the request so that we know what
-# the tar file will expand to.
+# client -> "request:"
+# server -> "ready:"
+# client -> $tar_client
function receive_request {
- cd $tmpdir_server
-
# Request from the client is on stdin
read
line=$REPLY
- # Extract the name of the client's temp directory.
- tmpdir_client=`expr "$line" : 'request: \([^ ]*\)$'`
- test "X$tmpdir_client" == "X" && \
- fatal "ERROR: client request temp dir name is missing" $tmpdir_server
- tmpdir_client=$tmpdir_server/$tmpdir_client
-
- # Create the client's temp dir now to guarantee that it won't clash with
- # any files we need to create later.
- mkdir $tmpdir_client || \
- fatal "ERROR: cannot create client temp dir" $tmpdir_client
+ # Check to see that it is a client request
+ test "$line" = "request:" || \
+ fatal "ERROR: client request, '$line' is incorrect"
# Create a place to receive the client's tar file
- tar_client=`mktemp -t $tmpdir_prefix_client.tgz.XXXXXX` || \
+ tar_client=`mktemp -t $tmpdir_prefix_server.client.tgz.XXXXXX` || \
fatal "ERROR: cannot create temporary tar file " $tar_client
# Request that the file be sent.
- echo "send: $tar_client"
+ echo "ready:"
- # Wait for confirmation that the tar file has arrived via rysnc
- read
- line=$REPLY
- test "X$line" = "Xwaiting:" || \
- fatal "ERROR: client send confirmation, '$line', is incorrect"
+ # Receive the file.
+ nc -l $port < /dev/null > $tar_client
}
# function: unpack_request
@@ -86,15 +67,31 @@ function receive_request {
# Unpack the tar file received from the client and make the contents
# available for use when running 'stap'
function unpack_request {
+ # Make a temp directory to work in.
+ tmpdir_server=`mktemp -dt $tmpdir_prefix_server.XXXXXX` || \
+ fatal "ERROR: cannot create temporary directory " $tmpdir_server
+ tmpdir_env=`dirname $tmpdir_server`
+
cd $tmpdir_server
# Unpack the tar file.
tar -xzf $tar_client || \
fatal "ERROR: cannot unpack tar archive $tar_client"
+ # Identify the client's request tree. The tar file should have expanded
+ # into a single directory named to match $tmpdir_prefix_client.??????
+ # which should now be the only item in the current directory.
+ test "`ls | wc -l`" = 1 || \
+ fatal "ERROR: Wrong number of files after expansion of client's tar file"
+
+ tmpdir_client=`ls`
+ tmpdir_client=`expr "$tmpdir_client" : "\\\($tmpdir_prefix_client\\\\.......\\\)"`
+
+ test "X$tmpdir_client" != "X" || \
+ fatal "ERROR: client tar file did not expand as expected"
+
# Move the client's temp directory to a local temp location
- local tmpdir_client_base=`basename $tar_client | sed 's,\.tgz,,'`
- local local_tmpdir_client=`mktemp -dt $tmpdir_client_base.XXXXXX` || \
+ local local_tmpdir_client=`mktemp -dt $tmpdir_prefix_server.client.XXXXXX` || \
fatal "ERROR: cannot create temporary tar file " $local_tmpdir_client
mv $tmpdir_client/* $local_tmpdir_client
rm -fr $tmpdir_client
@@ -114,19 +111,18 @@ function check_request {
client_sysinfo=`read_data_file sysinfo`
test "X$client_sysinfo" != "X" || exit 1
- # Extract the client's config info.
- client_name=`expr "$client_sysinfo" : 'stap [^ ]* [^ ]* \([^ ]*\).*'`
- client_sysinfo=`echo $client_sysinfo | sed s,$client_name,,`
-
- # Extract the server's config info.
- server_sysinfo=`uname -sr`
- server_name=`expr "$server_sysinfo" : '[^ ]* \([^ ]*\).*'`
- server_sysinfo=`echo $server_sysinfo | sed s,$server_name,,`
- local stap_version=`stap -V 2>&1 | grep version`
- stap_version=`expr "$stap_version" : '.*version \([0-9./]*\).*'`
- server_sysinfo="stap $stap_version $server_sysinfo"
+ check_compatibility "$client_sysinfo" `server_sysinfo`
+}
- check_compatibility "$client_sysinfo" "$server_sysinfo"
+# function server_sysinfo
+#
+# Generate the server's sysinfo and echo it to stdout
+function server_sysinfo {
+ if test "X$sysinfo_server" = "X"; then
+ # Add some info from uname
+ sysinfo_server="`uname -r`"
+ fi
+ echo $sysinfo_server
}
# function check_compaibility SYSINFO1 SYSINFO2
@@ -134,10 +130,9 @@ function check_request {
# Make sure that systemtap as described by SYSINFO1 and SYSINFO2 are compaible
function check_compatibility {
# TODO: This needs work
- # - In stap version x/y, require that the y matches
# - Make sure the linux kernel matches exactly
- local sysinfo1=`echo $1 | sed 's,stap [^/]*/,stap ,'`
- local sysinfo2=`echo $2 | sed 's,stap [^/]*/,stap ,'`
+ local sysinfo1=$1
+ local sysinfo2=$2
if test "$sysinfo1" != "$sysinfo2"; then
error "ERROR: system configuration mismatch"
@@ -361,7 +356,7 @@ function package_response {
chmod +r $tar_server
# Generate the tar file
- tar -czphf $tar_server `basename $tmpdir_server` || \
+ tar -czhf $tar_server `basename $tmpdir_server` || \
fatal "ERROR: tar of $tmpdir_server failed"
}
@@ -370,21 +365,11 @@ function package_response {
# Notify the client that $tar_server is ready and wait for the client to take
# it.
# The protocol is:
-# server -> "sending: $tar_server $tmpdir_server $tmpdir_stap"
-# client: copies file from server:$tar_server
-# client -> "OK"
+# server -> "sending: $tmpdir_server $tmpdir_stap"
+# server -> $tar_server
function send_response {
- # TODO needed for rsync from client to work
- chmod +r $tmpdir_server
-
- # Tell the client where to get it.
- echo "sending: $tar_server `basename $tmpdir_server` `basename $tmpdir_stap`"
-
- # Wait for the confirmation
- read
- line=$REPLY
- test $line = "OK" || \
- fatal "ERROR: client final confirmation, '$line' is incorrect"
+ # Now send it
+ nc -l $port < $tar_server > /dev/null
}
# function: fatal [ MESSAGE ]
@@ -421,7 +406,7 @@ function cleanup {
#-----------------------------------------------------------------------------
# Beginning of main line execution.
#-----------------------------------------------------------------------------
-configuration
+configuration "$@"
initialization
receive_request
unpack_request
diff --git a/stap-serverd b/stap-serverd
new file mode 100755
index 00000000..2c0743c0
--- /dev/null
+++ b/stap-serverd
@@ -0,0 +1,93 @@
+#!/bin/bash
+
+# Compile server manager for systemtap
+#
+# Copyright (C) 2008 Red Hat Inc.
+#
+# This file is part of systemtap, and is free software. You can
+# redistribute it and/or modify it under the terms of the GNU General
+# Public License (GPL); either version 2, or (at your option) any
+# later version.
+
+# This script publishes its presence on the network and then listens for
+# incoming connections. When a connection is detected, the stap-server script
+# is run to handle the request.
+
+# Catch ctrl-c
+trap 'handle_sigint' SIGINT
+
+#-----------------------------------------------------------------------------
+# Helper functions.
+#-----------------------------------------------------------------------------
+# function: initialization PORT
+function initialization {
+ # Default settings.
+ tmpdir_prefix_serverd=stap.serverd
+ avahi_type=_stap._tcp
+ port=$1
+ test "X$port" = "X" && port=65000
+}
+
+# function: advertise_presence
+#
+# Advertise the availability of the server on the network.
+function advertise_presence {
+ # Build up a string representing our server's properties.
+ # TODO: this needs fleshing out.
+
+ local sysinfo=`uname -r`
+ local txt="$sysinfo"
+
+ # Call avahi-publish-service to advertise our presence.
+ avahi-publish-service "Systemtap Compile Server on `uname -n`" \
+ $avahi_type $port $txt > /dev/null 2>&1 &
+
+ echo "Systemtap Compile Server on `uname -n` listening on port $port"
+}
+
+# function: listen
+#
+# Listen for and handle requests to the server.
+function listen {
+ # Work in a temporary directory
+ tmpdir=`mktemp -dt $tmpdir_prefix_serverd.XXXXXX` || \
+ fatal "ERROR: cannot create temporary directory " $tmpdir
+ cd $tmpdir
+
+ # Create a fifo for communicating with the server
+ local fifo_name=$tmpdir_prefix_serverd.fifo
+ mknod $fifo_name p || \
+ fatal "ERROR: cannot create temporary fifo " $tmpdir/$fifo_name
+
+ # Loop forever accepting requests
+ while true
+ do
+ nc -l $port < $fifo_name | stap-server $((port + 1)) > $fifo_name 2>&1
+ done
+}
+
+# function: fatal [ MESSAGE ]
+#
+# Fatal error
+# Prints its arguments to stderr and exits
+function fatal {
+ echo "$@" >&2
+ exit 1
+}
+
+# function: handle_sigint
+#
+# Terminate gracefully when SIGINT is received.
+function handle_sigint {
+ echo "$0: received SIGINT. Exiting."
+ cd `dirname $tmpdir`
+ rm -fr $tmpdir
+ exit
+}
+
+#-----------------------------------------------------------------------------
+# Beginning of main line execution.
+#-----------------------------------------------------------------------------
+initialization "$@"
+advertise_presence
+listen