#!/bin/bash ### BEGIN INIT INFO # Provides: engine # Required-Start: $local_fs $syslog # Required-Stop: $local_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: KittenDB Meta Engine ### END INIT INFO # # run script for KittenDB Engine # author: kot # author: burunduk # author: burunduk # # Version: 2013-06-06 # # Features added: # -- flock to avoid parallel execution # -- checks to avoid creating empty engine configuration files # a bit changed it for telegram-daemon to use different folders # and to have posiiblilities to have fake root # Vitaly Valtman ROOT="" PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DAEMONDIR=$ROOT/usr/share/telegram-daemon/bin DAEMONBOOTSTRAP=$ROOT/usr/share/telegram-daemon/bin/start-telegram-daemon NAME=telegram-daemon DESC="KOT's meta engine" PIDFILE=$ROOT/var/run/$NAME LOCKFILE=$ROOT/var/lock/$NAME CONFFILE=$ROOT/etc/telegram-daemon/$NAME LOCK_WAIT=5 STOP_TIMEOUT=5 KILL_TIMEOUT=5 test -x $DAEMONDIR || exit 0 test -x $DAEMONBOOTSTRAP || exit 0 set -e ## Utilitary functions # Send information to stderr function echo_stderr() { echo "$*" 1>&2 } # Get engine status. Returns 0 on running engine, 1 otherwise. function engine_status() { local id="$1" local pif="$PIDFILE.$id.pid" if ! [ -f "$pif" ] ; then echo "stopped" return 1 fi local pid="$(<$pif)" if [ -z "$pid" ]; then echo "corrupt pid file" return 1 fi if [ -d "/proc/$pid/" ]; then echo "$pid" return 0 else echo "failed (pid $pid)" return 1 fi } # Start engine. Usage: engine_start function engine_start() { local eid="$1" local r='' local pid='' pid="$(engine_status "$eid")" && r='ok' || r='fail' if [ "$r" == 'ok' ] ; then echo_stderr "telegram-daemon-$eid: already running ($pid)" else start-stop-daemon --start --quiet --exec $DAEMONBOOTSTRAP -- .$eid 100> /dev/null fi return 0 } # Stop engine. Usage: engine_stop function engine_stop() { local eid="$1" local r='' local status="$(engine_status "$eid")" && r='ok' || r='fail' local pif="$PIDFILE.$eid.pid" if [ "$r" == 'ok' ] ; then start-stop-daemon --stop --quiet --oknodo --pidfile "$pif" local ti=0 while [ $ti -lt $((10 * $STOP_TIMEOUT)) ] ; do status="$(engine_status "$eid")" && r='ok' || r='fail' if [ "$r" == 'fail' ]; then break fi sleep 0.1 ti=$(($ti + 1)) done if [ "$r" == 'ok' ] ; then echo_stderr "telegram-daemon-$eid: not stopped, sending SIGKILL..." start-stop-daemon --stop --quiet --oknodo --pidfile "$pif" --signal KILL ti=0 while [ $ti -lt $((10 * $KILL_TIMEOUT)) ] ; do status="$(engine_status "$eid")" && r='ok' || r='fail' if [ "$r" == 'fail' ]; then break fi sleep 0.1 ti=$(($ti + 1)) done fi if [ "$r" == 'ok' ] ; then echo_stderr "telegram-daemon-$eid: not stopped with SIGKILL, giving up" return 1 else if [ -f "$pif" ] ; then rm "$pif" fi echo "telegram-daemon-$eid: stopped" fi else echo_stderr "telegram-daemon-$eid: not running: $status" fi return 0 } # usage: engine_disable function engine_disable() { local eid="$1" local conf="$CONFFILE.$eid.conf" [ -e "$conf" ] || return 1 # work only with existing engines if grep -E '^quit 1$' "$conf" > /dev/null ; then echo_stderr "telegram-daemon-$eid: already disabled" else echo 'quit 1' >> "$conf" fi return 0 } # usage: engine_enable function engine_enable() { local eid="$1" local conf="$CONFFILE.$eid.conf" [ -e "$conf" ] || return 1 # work only with existing engines if ! grep -E '^quit' "$conf" > /dev/null ; then echo_stderr "telegram-daemon-$eid: already enabled" else sed -i~ -e '/^quit/d' -- "$conf" fi return 0 } # Wait for engine's command to be completed function engine_wait() { local eid="$1" ( flock -x -w $(($LOCK_WAIT + $STOP_TIMEOUT + $KILL_TIMEOUT)) 100 || exit 1 ) 100> $LOCKFILE.$eid.lock || echo "Unable to wait for $eid" return 0 } # Run a single command # Only one instance of this command per engine is supposed to work function run_one() { local eid="$1" shift local command="$*" [ "${#eid}" -gt 5 ] && return 0 # avoid long engine ids ( flock -x -w $LOCK_WAIT 100 || exit 1 $command "$eid" ) 100> $LOCKFILE.$eid.lock return 0 } # Run commands function run() { local mode="$1" shift local command="$*" local eid='' if [ "$mode" == 'parallel' ] ; then for eid in $arguments ; do run_one "$eid" "$command" & done sleep 0.1 for eid in $arguments ; do engine_wait "$eid" done else for eid in $arguments ; do run_one "$eid" "$command" done fi return 0 } # Get all actual engine ids function arguments_all() { local file='' local id='' local list='' for file in $(ls $CONFFILE.?*.conf 2> /dev/null) ; do id=${file#$CONFFILE.} id=${id%.conf} list="$list $id" done for file in $(ls $PIDFILE.?*.pid 2> /dev/null) ; do id=${file#$PIDFILE.} id=${id%.pid} list="$list $id" done local f='' for f in $list ; do echo "$f" ; done | sort -u return 0 } ## Commands # Start engine. function engine_command_start() { local eid="$1" engine_start "$eid" } # Stop engine. function engine_command_stop() { local eid="$1" engine_stop "$eid" } # Enable engine. function engine_command_enable() { local eid="$1" engine_enable "$eid" engine_start "$eid" } # Disable engine. function engine_command_disable() { local eid="$1" engine_disable "$eid" engine_stop "$eid" } # Restart engine. function engine_command_restart() { local eid="$1" engine_stop "$eid" echo "restarting telegram-daemon-$eid..." engine_start "$eid" } # Send signal to engine. Usage: engine_command_signal function engine_command_signal() { local id="$2" local signal="$1" local r='' local comment="$(engine_status "$id")" && r='ok' || r='fail' local res='' if [ "$r" == 'ok' ]; then start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE.$id.pid --signal "$signal" else echo_stderr "telegram-daemon-$id: not running: $comment" fi return 0 } # Get engine status function engine_command_status() { local id="$1" local res="telegram-daemon-$id: " local r='' local pid='' pid="$(engine_status "$id")" && r='ok' || r='fail' if [ "$r" == 'ok' ]; then res="$res $(COLUMNS=10000 ps -o pid,c,stime,time,cmd --no-header --pid $pid | sed -e 's/\/usr\/share\/telegram-daemon\/bin\///')" else res="$res $pid" fi echo "$res" return 0 } ## Entry point command="$1" shift arguments="$*" if [ -z "$arguments" ] ; then if [ "$command" == "status" -o "$command" == "start" -o "$command" == "rotate-logs" -o "$command" == "stop" ] ; then arguments="$(arguments_all)" fi elif [ "$arguments" == "all" ] ; then arguments="$(arguments_all)" fi if [ -z "$arguments" ] ; then echo "nothing to do" exit 0 fi case "$command" in ('disable') run parallel engine_command_disable ;; ('enable') run parallel engine_command_enable ;; # ('start') run parallel engine_command_start ;; ('status') run normal engine_command_status ;; ('stop') run parallel engine_command_stop ;; # ('rotate-logs') run parallel engine_command_signal USR1 ;; # ('restart'|'force-reload') run parallel engine_command_restart ;; (*) N=/etc/init.d/$NAME echo "Usage: $N {start|stop|restart|rotate-logs|status} [|all]" >&2 echo " additional commands: disable , enable , reindex (use with caution)" >&2 exit 1 ;; esac exit 0