#! /bin/sh ### BEGIN INIT INFO # Provides: @DAEMON@ # Default-Start: 2 # Default-Stop: 1 # Short-Description: Yandex daemon ### END INIT INFO USER=metrika GROUP=metrika SHELL=/bin/sh PROGRAM=@DAEMON@ SYSCONFDIR=/etc/$PROGRAM LOGDIR=/var/log/$PROGRAM LOCALSTATEDIR=/var/lock BINDIR=/usr/bin CRONFILE=/etc/cron.d/@CRONFILE@ CNFFILE=$SYSCONFDIR/config.xml LOCKFILE=$LOCALSTATEDIR/$PROGRAM RETVAL=0 DEFAULT_NUMBER_OF_PROCESSES=1 NUMBER_OF_PROCESSES=$(xmlstarlet sel -t -v "/yandex/number_of_processes" $CNFFILE || echo $DEFAULT_NUMBER_OF_PROCESSES) PIDDIR=/var/run/$PROGRAM PIDFILE_PREFIX=$PIDDIR/$PROGRAM PIDFILE_RE="$PIDFILE_PREFIX[0-9]*.pid" generate_pid_name() { echo $PIDFILE_PREFIX$1.pid } generate_log_filename() { log_file=$(xmlstarlet sel -t -v "/yandex/logger/log" $CNFFILE) # Не будем менять имя лог файла, при одном процессе if [ $NUMBER_OF_PROCESSES -gt 1 ]; then log_file=$(echo $log_file | sed "s/\.log/$1.log/") fi echo $log_file } find_pid_files() { find $PIDDIR -regex $PIDFILE_RE } is_running() { pidfile=$1 [ -r "$pidfile" ] && pgrep -s $(cat "$pidfile") 1> /dev/null 2> /dev/null } running_processes() { pidfiles=$(find_pid_files) running=0 for pidfile in $pidfiles; do if is_running $pidfile; then running=$(($running + 1)) fi done echo $running } any_runs() { if [[ $(running_processes) -gt 0 ]]; then return 0; else return 1; fi } wait4done() { while any_runs; do sleep 1 done } start() { [ -x $BINDIR/$PROGRAM ] || exit 0 local EXIT_STATUS EXIT_STATUS=0 echo -n "Start $PROGRAM service: " [ -f "$LOCKFILE" ] && sleep 1 if [[ $(running_processes) -eq $NUMBER_OF_PROCESSES ]]; then echo -n "already running " EXIT_STATUS=1 else # Clean stale lock files rm -f "$LOCKFILE" mkdir -p $LOGDIR mkdir -p $PIDDIR chown -R $USER:$GROUP $LOGDIR chown -R $USER:$GROUP $PIDDIR chown -R $USER:$GROUP $SYSCONFDIR for i in $(seq 1 $NUMBER_OF_PROCESSES); do if ! is_running $(generate_pid_name $i); then rm -f $(generate_pid_name $i) # TODO может лучше передавать демону номер процесса, а демон сам будет делать все необходимые подстановки su -l $USER -s $SHELL -c "\"$BINDIR/$PROGRAM\" --daemon --pid-file=\"$(generate_pid_name $i)\" --config-file=\"$CNFFILE\" --log-file=\"$(generate_log_filename $i)\"" EXIT_STATUS=$? if [[ $EXIT_STATUS -ne 0 ]]; then break fi fi done fi if [[ $EXIT_STATUS -eq 0 ]]; then touch "$LOCKFILE" echo "DONE" else echo "FAILED" fi return $EXIT_STATUS } stop() { local EXIT_STATUS EXIT_STATUS=0 echo -n "Stop $PROGRAM service: " if any_runs; then if [ -f "$LOCKFILE" ]; then for pid_file in $(find_pid_files); do kill -TERM `cat "$pid_file"` done wait4done rm -f "$LOCKFILE" else echo "has been stopping already" return 1 fi else rm -f "$LOCKFILE" fi echo "DONE" return $EXIT_STATUS } restart() { stop start } forcestop() { local EXIT_STATUS EXIT_STATUS=0 echo -n "Stop $PROGRAM service: " if any_runs; then if [ -f "$LOCKFILE" ]; then for pid_file in $(find_pid_files); do kill -9 `cat "$pid_file"` done wait4done rm -f "$LOCKFILE" else echo "has been stopping already" return 1 fi fi echo "DONE" return $EXIT_STATUS } forcerestart() { forcestop start } enable_cron() { sed -i 's/^#*//' "$CRONFILE" } disable_cron() { sed -i 's/^#*/#/' "$CRONFILE" } # See how we were called. EXIT_STATUS=0 case "$1" in start) start && enable_cron ;; stop) disable_cron && stop ;; status) if [[ $(running_processes) -eq $NUMBER_OF_PROCESSES ]]; then echo "$PROGRAM service is running" else if [ ! -e $LOCKFILE ]; then echo "$PROGRAM service is stopped"; else echo "$PROGRAM: $(($NUMBER_OF_PROCESSES - $(running_processes))) of $NUMBER_OF_PROCESSES processes unexpectedly terminated" fi fi ;; restart) restart && enable_cron ;; forcestop) disable_cron && forcestop ;; forcerestart) forcerestart && enable_cron ;; reload) restart ;; condstart) any_runs || start ;; condstop) any_runs && stop ;; condrestart) any_runs && restart ;; condreload) any_runs && restart ;; *) echo "Usage: ${0##*/} {start|stop|status|restart|forcestop|forcerestart|reload|condstart|condstop|condrestart|condreload}" EXIT_STATUS=2 esac exit $EXIT_STATUS