This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[Example] Yet another remote systemtap compiler over ssh
- From: Masami Hiramatsu <mhiramat at redhat dot com>
- To: systemtap-ml <systemtap at sources dot redhat dot com>
- Date: Mon, 16 Jun 2008 16:14:51 -0400
- Subject: [Example] Yet another remote systemtap compiler over ssh
Hi,
Here is a shell script which executes stap on remote machine to compile
scripts. This script uses ssh to execute stap and to get a binary
module. So, you don't need to setup server program; just install
systemtap and kernel-debuginfo(, gcc, kernel-devel, etc.) packages on
the remote machine.
Usage is also simple.
stap-remote <[user@]host> [options] <file|-|-e 'script'|-l 'tracepoint'>
options: same as stap.
ex.)
[root@local]# stap-remote mhiramat@remote -e 'probe syscall.read{println("hello");exit()}'
this means, what you just need to do is s/stap/stap-remote <host>/g :-).
Actually, this script doesn't care security so much (just use ssh),
because this script can not ensure whether remote stap is genuine or not,
neither check client program. So, before using this, please check
security of both remote server and local machine carefully:-).
In other words, this just automates
'scp -r ... host: ; ssh host stap ...; scp host:XXX.ko ./; staprun ... XXX.ko'
Thank you,
--
Masami Hiramatsu
Software Engineer
Hitachi Computer Products (America) Inc.
Software Solutions Division
e-mail: mhiramat@redhat.com
#!/bin/bash
#
# Serverless remote systemtap compiler
#
# This file 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.
#
# path configurations
STAP=/usr/bin/stap
STAPRUN=/usr/bin/staprun
SSH=/usr/bin/ssh
function usage () {
echo "Usage: stap-remote <hostname> [options] FILE"
echo " or: stap-remote <hostname> [options] -"
echo " or: stap-remote <hostname> [options] -e"
exit 0;
}
function eexit () {
echo "Error: "$*
exit 1;
}
function debug () {
echo "Debug:$*"
}
function abspath() {
(cd `dirname $1`;echo `pwd`/`basename $1`)
}
# check options
[ $# -lt 2 ] && usage;
SSH=ssh
HOST=$1
shift 1
case "$HOST" in
-*)
usage
;;
esac
# escaping options
__OPTS=
while [ "$1" ]; do
__OPTS="$__OPTS '$1'"
shift 1
done
# option parsing
_OPTS=`eval getopt -s bash -l 'kelf,kmap::,ignore-vmlinux,ignore-dwarf' 'hVMvtp:I:e:o:R:r:m:kgPc:x:D:bs:uqwl:' $__OPTS`
if [ $! ]; then
eexit "option parse error."
fi
KREL=`uname -r`
MACH=`uname -m`
VERB=0
OPTS=
FILE=
ROPT=
PHASE=5
KMOD=
KEEP=no
KMAP=
RSRC=
TAPS=
# get arguments
function get_args() {
while [ "$1" != '--' ]; do
case $1 in
-I|-R)
[ ! -d $2 ] && eexit "$2 is not a directory"
[ x$1 = "x-I" ] && TAPS="$TAPS $2"
[ x$1 = "x-R" ] && RSRC=$2
shift 2
;;
-k)
KEEP=yes
shift 1
;;
-o|-c|-x)
ROPT="$ROPT $1 '$2'"
shift 2
;;
-s)
ROPT="$ROPT -b $2"
shift 2
;;
-r)
KREL=$2
shift 2
;;
-m)
OPTS="$OPTS $1 '$2'"
KMOD=$2
shift 2
;;
-p)
if [ `eval echo $2` -le 4 ]; then
eval PHASE=$2
fi
shift 2
;;
-l)
PHASE=3
OPTS="$OPTS $1 '$2'"
shift 2
;;
-e|-D)
OPTS="$OPTS $1 '$2'"
shift 2
;;
-v)
VERB=$((VERB + 1))
OPTS="$OPTS $1"
shift 1
;;
--kmap)
KMAP=$2
[ ! -f $KMAP ] && OPTS="$OPTS $1"
shift 2
;;
-*)
OPTS="$OPTS $1"
shift 1
;;
*)
eexit "parse error at $1"
esac
done
if [ "$2" ]; then # file or stdin
FILE=`eval echo $2`
if [ $FILE != '-' -a ! -f $FILE ]; then
eexit "file not found: $FILE "
fi
fi
OPTS="-r $KREL $OPTS"
while [ $VERB -ge 2 ]; do
ROPT="-v $ROPT"
VERB=$((VERB - 1))
done
}
eval get_args $_OPTS
# checking phase and build stap command
_PH=$PHASE;
[ $_PH -ge 5 ] && _PH=4
CMD="$STAP -p $_PH $OPTS"
CHKMACH='[ `uname -m` != "'$MACH'" ] && echo "Error: different arch" && exit 0;'
CURD=$PWD
TARF="echo -n "
TARX="cat"
TMPD=
PRE=
POST=
# cleanup
function cleanup() {
if [ "$TMPD" ]; then
if [ $KEEP = no ] ; then
[ $VERB -ge 1 ] && echo "Running rm -rf $TMPD"
rm -rf $TMPD
else
echo "Keeping temporary directory $TMPD"
fi
fi
}
trap "cleanup" SIGINT SIGTERM SIGCHLD SIGPIPE
if [ x"$FILE$KMAP$RSRC$TAPS" != x -o $_PH -eq 4 ]; then
TMPD=`mktemp -d /tmp/stap-guest.XXXXXX`
if [ x$FILE != x ]; then
if [ -f "$FILE" ];then
cp $FILE $TMPD/script
else
cat > $TMPD/script
fi
CMD="$CMD ./script"
fi
if [ -f "$KMAP" ]; then
cp $KMAP $TMPD/kmap
CMD="$CMD --kmap=./kmap"
fi
if [ "$RSRC" ]; then
cp -r $RSRC $TMPD/runtime
CMD="$CMD -R ./runtime"
fi
mkdir $TMPD/tapset/
[ "$TAPS" ] && for t in $TAPS; do
cp -r $t $TMPD/tapset/
CMD="$CMD -I ./tapset/`basename $t`"
done
cd $TMPD
TARF="tar -Oc ./* "
PRE='H=`mktemp -d /tmp/stap-remote.XXXXXX`; cd $H; tar -x;'
if [ $_PH -eq 4 ]; then
if [ -z "$KMOD" ]; then
POST='| tee $H/stdout; F=`tail -n 1 $H/stdout`; [ -f "$F" ] && (cd `dirname $F`; echo "Begin"; tar -Oc `basename $F`); rm -rf $H'
else
POST=' && (echo "Begin"; tar -Oc *.ko) ; rm -rf $H'
fi
function tarxout() {
while read LN; do
if [ "$LN" = "Begin" ] ; then
tar -x
break
fi
echo "$LN"
done
}
TARX="tarxout"
else
POST='; rm -rf $H'
fi
fi
# execute remote command
$TARF | $SSH $HOST "$CHKMACH$PRE$CMD$POST" | $TARX
cd $CURD
KOFILE=
[ "$TMPD" ] && KOFILE=$TMPD/*.ko
if [ ! -z "$KMOD" -a -f "$KOFILE" ]; then
cp $KOFILE ./
fi
# execute local staprun
if [ $PHASE -ge 5 -a -f "$KOFILE" ] ;then
if [ $VERB -ge 1 ]; then
echo "Pass 5: starting run."
export TIMEFORMAT="Pass 5: run completed in %Uusr/%Ssys/%Rreal sec."
time eval $STAPRUN $ROPT $KOFILE
else
eval $STAPRUN $ROPT $KOFILE
fi
fi
#cleanup
cleanup