#!/bin/bash # Find compile servers for systemtap # # Copyright (C) 2008, 2009 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 uses avahi to find systemtap compile servers on the local # network. Information about each server found is printed to stdout. # Initialize the environment . ${PKGLIBEXECDIR}stap-env #----------------------------------------------------------------------------- # Helper functions. #----------------------------------------------------------------------------- # function: initialization function initialization { rc=1 # not found yet if test "X$1" = "X--all"; then find_all=1 else find_all=0 fi timeout=20 # seconds } # function: find_servers # # Find and establish connection with a compatible stap server. function find_servers { # Create a temp file for the list of servers. We do this instead # of using a pipe so that we can kill avahi-browse if it # takes too long. tmpfile=`mktemp -t stap-serversXXXXXX` || \ fatal "Cannot create temporary file " $tmpfile # Find servers avahi-browse $stap_avahi_service_tag --terminate -r > $tmpfile & for ((attempt=0; $attempt < $timeout; ++attempt)) do if ! jobs '%avahi-browse' >/dev/null 2>&1; then break fi sleep 1 done # Kill avahi-browse, if it's still running test $attempt = $timeout && kill -s SIGTERM '%avahi-browse' 2>/dev/null match_server < $tmpfile rm -fr $tmpfile } # function: match_server # # Find a suitable server using the avahi-browse output provided on stdin. function match_server { local server_ip local server_name local server_sysinfo local server_port rc=1 # not found yet # Loop over the avahi service descriptors. read -t $timeout || return while test "X$REPLY" != "X" do server_name= server_ip= server_port= server_sysinfo= # Examine the next service descriptor # Is it a stap server? if ! echo $REPLY | grep -q "=.* .* IPv4 .*_stap"; then read -t $timeout || return continue fi REPLY= # Get the details of the service local service_tag equal service_data while read -t $timeout service_tag equal service_data do case $service_tag in hostname ) server_name=`expr "$service_data" : '\[\([^]]*\)\]'` ;; address ) # Sometimes (seems random), avahi-resolve-host-name resolves a local server to its # hardware address rather than its ip address. Keep trying until we get # an ip address. server_ip=`expr "$service_data" : '\[\([^]]*\)\]'` local attempt for ((attempt=0; $attempt < 5; ++attempt)) do server_ip=`expr "$server_ip" : '\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\)$'` if test "X$server_ip" != "X"; then break fi # Resolve the server.domain to an ip address. server_ip=`avahi-resolve-host-name $server_name` server_ip=`expr "$server_ip" : '.* \(.*\)$'` done ;; port ) server_port=`expr "$service_data" : '\[\([^]]*\)\]'` ;; txt ) server_sysinfo=`expr "$service_data" : '\[.*\"\(sysinfo=[^]]*\)\"\]'` ;; * ) REPLY="$service_tag $equal $service_data" break ;; esac done # It's an stap server, but is it compatible? if test $find_all = 0 -a "$server_sysinfo" != "`client_sysinfo`"; then continue fi # It's compatible, or we're finding all servers. Print a summary line echo "$server_name $server_ip $server_port '$server_sysinfo'" rc=0 done } # function client_sysinfo # # Generate the client's sysinfo and echo it to stdout function client_sysinfo { if test "X$sysinfo_client" = "X"; then # Add some info from uname sysinfo_client="`uname -r` `stap_get_arch`" fi echo sysinfo=$sysinfo_client } # function: fatal [ MESSAGE ] # # Fatal error # Prints its arguments to stderr and exits function fatal { echo "$0: ERROR:" "$@" >&2 exit 1 } #----------------------------------------------------------------------------- # Beginning of main line execution. #----------------------------------------------------------------------------- initialization "$@" find_servers exit $rc