]> sourceware.org Git - systemtap.git/commitdiff
client/server take 2. See bz6565.
authorDave Brolley <brolley@redhat.com>
Thu, 3 Jul 2008 17:10:44 +0000 (13:10 -0400)
committerDave Brolley <brolley@redhat.com>
Thu, 3 Jul 2008 17:10:44 +0000 (13:10 -0400)
ChangeLog
stap-client
stap-server
stap-serverd [new file with mode: 0755]

index 7c34f2238c09fb85fe1a976359f996298d14baf3..697f4e0d80428c1f5ae4f624b147580500d55710 100644 (file)
--- 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
index 42402a27a1b3b91318cf4a4298497d87fdf90e08..515cab92b74540c032e0a7d60be78b20c2ab12d0 100755 (executable)
@@ -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 ]
@@ -566,6 +578,16 @@ function check_server_error {
 # Fatal 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
index 1a2e7918fc7a98a74d6274e9b32e5c00f566bfcb..11d6d81d9d57f99f2b5d322399d7e2e2419c81c7 100755 (executable)
@@ -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 (executable)
index 0000000..2c0743c
--- /dev/null
@@ -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
This page took 0.04736 seconds and 5 git commands to generate.