|
From: <smi...@us...> - 2004-03-01 00:48:53
|
Update of /cvsroot/devil-linux/build/scripts/scripts In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1601/scripts/scripts Added Files: enbd Log Message: initial checkin of enbd --- NEW FILE: enbd --- #!/bin/bash # # $Source: /cvsroot/devil-linux/build/scripts/scripts/enbd,v $ # $Revision: 1.1 $ # $Date: 2004/03/01 00:30:25 $ # # http://www.devil-linux.org # ### BEGIN INIT INFO # Provides: enbd # Required-Start: $network $syslog # Required-Stop: $network $syslog # Default-Start: 3 5 # Default-Stop: 0 6 # Description: starts ENBD Daemons ### END INIT INFO # settings source /etc/sysconfig/config # parameters CONFIGNAME=ENBD # source function library source /etc/init.d/functions eval START=\$START_$CONFIGNAME # Determine the base and follow a runlevel link name. base=${0##*/} link=${base#*[SK][0-9][0-9]} # Force execution if not called by a runlevel directory. test $link = $base && START=yes test "$START" = "yes" || exit 0 #set -x CONFIG=${NBD_CONFIG-/etc/enbd.conf} [ ! -r $CONFIG ] && exit 0 export PATH=/sbin:/usr/sbin:/usr/local/sbin:/usr/bin:/bin:/usr/local/bin SERVERNAME=enbd-server CLIENTNAME=enbd-client SSTATDNAME=enbd-sstatd CSTATDNAME=enbd-cstatd MODULENAME=enbd PROCFLNAME=nbdinfo cmd=eval if [ "$DEBUG" != "" ] && [ "$DEBUG" -gt 0 ] ; then cmd=echo fi ######################################################################### # look in path for a particular executable and return its full path # find_foo() { local foo="$1" IFS=':' ; set -- $PATH ; IFS=' ' for i; do if [ -x "$i/$foo" ] ; then echo "$i/$foo" return 0 fi done return 1 } ######################################################################### # look for enbd-server in path # find_server() { find_foo $SERVERNAME } ######################################################################### # look for enbd-client in path # find_client() { find_foo $CLIENTNAME } ######################################################################### # see if a given host responds to pings. # can_contact() { ping -c 1 $1 | grep -vqs "100% packet loss" && return 0 return 1 } ######################################################################### # replace a couple of minor funcs not in /bin. # mydirname() { echo $1 | sed -e 's,/[^/]*$,,' } mybasename() { echo $1 | sed -e 's,^.*/,,' } ######################################################################### # look at a given pidfile. Return OK if nonexistent or stale and # put our pid in the pidfile. # Return BAD if it contains a pid of a running process, # try_lock() { local pidfile="$1" if [ -s "$pidfile" ] ; then local pid="`head -1 $pidfile`" # grrr ... tr is not always available at boot, so can't trim easily for p in $pid ""; do pid=$p ; break done case $pid in *[^0-9]*) echo bad pid $pid read from $pidfile && return 1 ;; esac if [ -n "$pid" ] && [ "$pid" -gt 0 ] ; then kill -0 "$pid" 2>&1 >/dev/null && return 1 fi fi rm -f $1 local mytmp="`mydirname $pidfile`/.try_lock_`mybasename $pidfile`.$$" touch $mytmp || return 1 if ! echo $$ >> $mytmp ; then rm -f $mytmp return 1 fi if ! ln $mytmp $pidfile; then rm -f $mytmp return 1 fi rm -f $mytmp return 0 } ######################################################################### # test that a given server is ready to receive our client # Be quiet if all OK, otherwise make noise # client_ready() { if [ ! -e /proc/$PROCFLNAME ] ; then echo "module not loaded" return 1 fi local client eval client="`find_client | head -1`" if [ -z "$client" ] ; then echo "$CLIENTNAME cannot be found locally" return 2 fi local server="$1" if ! can_contact $server ; then echo "$server cannot be contacted" return 3 fi return 0 } ######################################################################### # separate process to launch a given enbd-client id # start_client() { local id=$1 echo -n starting $CLIENTNAME $id shift try_lock /var/run/${CLIENTNAME}-$id.pid || return #IFS=':' ; set -- $2 ; IFS=' ' local server="$1" local port="$2" shift 2 local args="$*" local message="`client_ready $server $port`" if [ -n "$message" ]; then echo "$CLIENTNAME $id to server $server : start delayed because $message" sleep 30 local oldmessage="$message" message="`client_ready $server $port`" while [ -n "$message" ]; do if [ "$oldmessage" != "$message" ]; then echo "$CLIENTNAME $id to server $server : start delayed because $message" fi sleep 30 local oldmessage="$message" message="`client_ready $server $port`" done fi $cmd $CLIENTNAME ${server}:$port $args & # the executable will write this itself in >= 2.4.24 #local pid=$! #$cmd "echo $pid > /var/run/${CLIENTNAME}-$id.pid" ## tell the server to restart its ${SERVERNAME} #$cmd telnet $server nbd echo done } ######################################################################### # how to do lookup and murder via a pidfile # stop_foo() { local pidfile=$1 [ ! -s $pidfile ] && return 1 pid="`head -1 $pidfile`" for sig in USR1 TERM 9; do $cmd "kill -$sig $pid >/dev/null 2>&1" sleep 1 $cmd "fuser -k -$sig $pidfile >/dev/null 2>&1" sleep 1 if ! kill -0 $pid >/dev/null 2>&1 ; then #echo removing $pidfile because process $pid is dead #$cmd rm -f $pidfile return 0 fi done return 1 } ################################################################# # list our interface IP addresses # my_interface_ips() { /sbin/ifconfig \ | grep 'inet addr:' \ | sed -e 's/.*inet addr:\([0-9.][0-9.]*\).*/\1/' } ######################################################################### # separate process to stop a given enbd-client id # stop_client() { local id=$1 local server=$2 local port=$3 local ipaddrs="`my_interface_ips`" echo -n stopping $CLIENTNAME $id if stop_foo /var/run/${CLIENTNAME}-$id.pid; then ( echo notice client-stop $port $ipaddrs; echo quit ) | socket $server $SSTATDNAME echo done return fi echo failed } ######################################################################### # stop all known enbd-clients # stop_all_clients() { for pidfile in /var/run/${CLIENTNAME}-*.pid; do local id id=${pidfile#/var/run/${CLIENTNAME}-} id=${id%.pid} [ -e /var/run/${CLIENTNAME}-$id.pid ] || continue cat $CONFIG | grep -v '^[ ]*$' | while read line; do LINE="" for word in $line "#"; do case $word in [#]*) break;; esac LINE="$LINE $word" done line=$LINE echo "$line" | while read target client_id rest; do [ client = "$target" ] || continue [ "$client_id" = "$id" ] || continue echo "$rest" | while read device server port options; do stop_client $id $server $port done done done done } ######################################################################### # try and see if the partition or file we want exists yet # resource_available() { for i; do [ ! -e $i ] && return 1 head -1c $i >/dev/null 2>&1 || return 2 done return 0 } ######################################################################### # test that a given client is ready to talk to our server # Be quiet if all OK, otherwise make noise # server_ready() { local server eval server="`find_server | head -1`" if [ -z "$server" ] ; then echo "$SERVERNAME cannot be found locally" return 2 fi for resource; do if ! resource_available $resource ; then echo "$resource is not available" return 3 fi done return 0 } ######################################################################### # separate process to start a given enbd-server id # start_server() { local id=$1 local port=$2 try_lock /var/run/${SERVERNAME}-$id.pid || return echo -n starting $SERVERNAME $id local resources="`IFS=','; set -- $3; IFS=' '; echo $*`" shift 3 options="$*" local message="`server_ready $resources`" if [ -n "$message" ]; then echo "$SERVERNAME $id : start delayed because $message" sleep 30 local oldmessage="$message" message="`server_ready $resources`" while [ -n "$message" ]; do if [ "$oldmessage" != "$message" ]; then echo "$SERVERNAME $id : start delayed because $message" fi sleep 30 local oldmessage="$message" message="`server_ready $resources`" done fi $cmd $SERVERNAME $port $resources $options & # the executable will write this itself in >= 2.4.24 #local pid=$! #$cmd "echo $pid > /var/run/${SERVERNAME}-$id.pid" # the executable will do this itself in >= 2.4.24 ## revise our connections and signal them #[ -r /var/state/enbd/server-$id.ipaddr ] && \ #myipaddr="`hostname -i`" && \ #grep -qws enbd-cstatd /etc/services 2>/dev/null && \ #cat /var/state/enbd/server-$id.ipaddr | while read ipaddr whatever ; do # case "$ipaddr" in # ""|"#"*) continue ;; # esac # echo $myipaddr | socket $ipaddr $CSTATDNAME #done echo done } ######################################################################### # separate process to stop a given enbd-server id # stop_server() { local id=$1 echo -n stopping $SERVERNAME $id stop_foo /var/run/${SERVERNAME}-$id.pid && echo done && return echo failed } ######################################################################### # stop all known enbd-servers # stop_all_servers() { for pidfile in /var/run/${SERVERNAME}-*.pid; do local id id=${pidfile#/var/run/${SERVERNAME}-} id=${id%.pid} [ -e /var/run/${SERVERNAME}-$id.pid ] && stop_server $id done } ######################################################################### # remove the enbd module # stop_module() { echo -n removing nbd module for i in 1 2 3; do sleep 1; echo -n . ; done; $cmd modprobe -r $MODULENAME >/dev/null 2>&1 echo done } ######################################################################### # insert the enbd module # start_module() { local id=$1 shift options="$*" $cmd modprobe $MODULENAME $options } ######################################################################### # remove all enbd modules # stop_all_modules() { stop_module } ######################################################################### # usage message # usage() { echo usage $0 '{ start | stop | restart | force-reload } [ { module | server | client | all } [ id | -a ] ]' } ######################################################################### # main business. no args # main() { do_what="$1" to_what="$2" to_which="$3" [ "$to_what" = all ] && to_what="" [ "$to_which" = "-a" ] && to_which="" case $do_what in start|stop) cat $CONFIG | grep -v '^[ ]*$' | while read line; do # grrr ... tr/sed is not always available at boot, so can't trim easily # so do it primitively LINE="" for word in $line "#"; do case $word in [#]*) break;; esac LINE="$LINE $word" done line=$LINE COMMANDS=`echo "$line" | while read target id rest; do [ -z "$target" ] && continue [ -z "$id" ] && continue if [ -z "$to_what" -o "$to_what" = "$target" ] \ && [ -z "$to_which" -o "$to_which" = "$id" ] ; then case $target in module) echo "$COMMANDS\n${do_what}_module $id $rest" ;; client) echo "$rest" | while read device server port options; do echo "${do_what}_client $id $server $port -i $id $options $device" done ;; server) echo "$rest" | while read port resource options; do echo "${do_what}_server $id $port $resource -i $id $options" done ;; *) usage exit 1 ;; esac fi done` $cmd $COMMANDS done ;; restart) shift main stop $* sleep 4 main start $* ;; reload|force-reload) main restart ;; *) usage exit 1 ;; esac } main $* |