blob: d4d6a77309e0a1a3a818dbb6fe9f8160bc04a42b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
#!/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 and other termination signals
trap 'terminate' SIGTERM SIGINT
#-----------------------------------------------------------------------------
# Helper functions.
#-----------------------------------------------------------------------------
# function: initialization PORT
function initialization {
# Default settings.
avahi_type=_stap._tcp
# We need either netcat or nc.
netcat=`which netcat 2>/dev/null`
test "X$netcat" = "X" && netcat=`which nc 2>/dev/null`
test "X$netcat" = "X" && fatal "ERROR: cannot find required program 'netcat' or 'nc' on PATH"
# See if the given port, or the default port is busy. If so, select another.
port=$1
test "X$port" = "X" && port=65000
port2=$(($port + 1))
while netstat -atn | awk '{print $4}' | cut -f2 -d: | egrep -q "^($port|$port2)\$"; do
# Whoops, the port is busy; try another one.
port=$((1024+($port + $RANDOM)%64000))
port2=$(($port + 1))
done
}
# 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 -rvm`
local txt="sysinfo=$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 {
# Loop forever accepting requests
while true
do
for ((attempt=0; $attempt < 5; ++attempt))
do
$netcat -l $port < /dev/null 2>/dev/null | process_request &
wait '%$netcat -l'
rc=$?
if test $rc = 0 -o $rc = 127; then
break; # port was read ok
fi
done
if test $attempt = 5; then
fatal "ERROR: cannot listen on port $port. rc==$rc"
fi
done
}
# function: process_request
#
# Process an incoming request on stdin
function process_request {
read
case $REPLY in
request:)
stap-server $port2 >/dev/null 2>&1 &
wait '%stap-server'
rc=$?
test $rc = 127 && rc=0
;;
*)
rc=1
esac
exit $rc
}
# function: fatal [ MESSAGE ]
#
# Fatal error
# Prints its arguments to stderr and exits
function fatal {
echo "$@" >&2
terminate
exit 1
}
# function: terminate
#
# Terminate gracefully.
function terminate {
echo "$0: Exiting"
# Kill the running 'avahi-publish-service' job
kill -s SIGTERM %avahi-publish-service 2> /dev/null
wait '%avahi-publish-service' >/dev/null 2>&1
# Kill any running 'stap-server' job.
kill -s SIGTERM "%stap-server" 2> /dev/null
wait '%stap-server' >/dev/null 2>&1
# Kill any running '$netcat -l' job.
kill -s SIGTERM '%$netcat -l' 2>/dev/null
wait '%$netcat -l' >/dev/null 2>&1
exit
}
#-----------------------------------------------------------------------------
# Beginning of main line execution.
#-----------------------------------------------------------------------------
initialization "$@"
advertise_presence
listen
|