#!/bin/bash ### BEGIN INIT INFO # Provides: @DAEMON@ # Default-Start: 2 # Default-Stop: 1 # Short-Description: Yandex daemon ### END INIT INFO USER=metrika GROUP=metrika SHELL=/bin/bash 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=$DEFAULT_NUMBER_OF_PROCESSES LOG_FILE="" # С помощью xmlstarlet пытаемся взять некоторые параметры из конфига if command -v xmlstarlet >/dev/null 2>&1; then NUMBER_OF_PROCESSES=$(xmlstarlet sel -t -v "/yandex/number_of_processes" $CNFFILE || echo $DEFAULT_NUMBER_OF_PROCESSES) LOG_FILE=$(xmlstarlet sel -t -v "/yandex/logger/log" $CNFFILE || echo $LOG_FILE) fi PIDDIR=/var/run/$PROGRAM PIDFILE_PREFIX=$PIDDIR/$PROGRAM PIDFILE_RE="$PIDFILE_PREFIX[0-9]*.pid" generate_program_name() { if [ $NUMBER_OF_PROCESSES -eq 1 ]; then echo $PROGRAM else echo $PROGRAM$1 fi } generate_pid_name() { if [ $NUMBER_OF_PROCESSES -gt 1 ]; then echo $PIDFILE_PREFIX$1.pid else echo $PIDFILE_PREFIX.pid fi } specific_log_file_for_each_process() { # Не будем менять имя лог файла, при одном процессе # Не выставляем, если имя лог файла пустое if [ $NUMBER_OF_PROCESSES -gt 1 ] && [ "$LOG_FILE" != "" ]; then log_file=$(echo $LOG_FILE | sed "s/\.log/$1.log/") echo "--log-file=\"$log_file\"" fi echo "" } 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: " if [[ $(running_processes) -eq $NUMBER_OF_PROCESSES ]]; then echo -n "already running " EXIT_STATUS=1 else 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) # чтобы лок не удерживался в течении времени жизни дочернего процесса, освободим лок su -l $USER -s $SHELL -c "flock -u 9; exec -a $(generate_program_name $i) \"$BINDIR/$PROGRAM\" --daemon --pid-file=\"$(generate_pid_name $i)\" --config-file=\"$CNFFILE\" $(specific_log_file_for_each_process $i)" EXIT_STATUS=$? if [[ $EXIT_STATUS -ne 0 ]]; then break fi fi done fi if [[ $EXIT_STATUS -eq 0 ]]; then echo "DONE" else echo "FAILED" fi return $EXIT_STATUS } stop() { local EXIT_STATUS EXIT_STATUS=0 echo -n "Stop $PROGRAM service: " for pid_file in $(find_pid_files); do kill -TERM `cat "$pid_file"` done wait4done echo "DONE" return $EXIT_STATUS } restart() { stop start } forcestop() { local EXIT_STATUS EXIT_STATUS=0 echo -n "Stop $PROGRAM service: " for pid_file in $(find_pid_files); do kill -9 `cat "$pid_file"` done wait4done echo "DONE" return $EXIT_STATUS } forcerestart() { forcestop start } enable_cron() { sed -i 's/^#*//' "$CRONFILE" } disable_cron() { sed -i 's/^#*/#/' "$CRONFILE" } is_cron_disabled() { [[ `grep -E "^#.*" $CRONFILE` == `cat $CRONFILE` ]]; } main() { # 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 is_cron_disabled; 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 } ( if flock -n 9; then main "$@" else echo "Init script is already running" && exit 1 fi ) 9> $LOCKFILE