ClickHouse/tools/init.d/template
2016-06-26 08:17:26 +03:00

312 lines
6.4 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
### BEGIN INIT INFO
# Provides: @DAEMON@
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Required-Start:
# Required-Stop:
# 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=""
# On x86_64, check for required instruction set.
if uname -mpi | grep -q 'x86_64'; then
if ! grep -q 'sse4_2' /proc/cpuinfo; then
# On KVM, cpuinfo could falsely not report SSE 4.2 support, so skip the check.
if ! grep -q 'Common KVM processor' /proc/cpuinfo; then
# Some other VMs also report wrong flags in cpuinfo.
# Tricky way to test for instruction set:
# create temporary binary and run it;
# if it get caught illegal instruction signal,
# then required instruction set is not supported really.
#
# Generated this way:
# gcc -xc -Os -static -nostdlib - <<< 'void _start() { __asm__("pcmpgtq %%xmm0, %%xmm1; mov $0x3c, %%rax; xor %%rdi, %%rdi; syscall":::"memory"); }' && strip -R .note.gnu.build-id -R .comment -R .eh_frame -s ./a.out && gzip -c -9 ./a.out | base64 -w0; echo
if ! (echo -n 'H4sICAwAW1cCA2Eub3V0AKt39XFjYmRkgAEmBjsGEI+H0QHMd4CKGyCUAMUsGJiBJDNQNUiYlQEZOKDQclB9cnD9CmCSBYqJBRxQOvBpSQobGfqIAWn8FuYnPI4fsAGyPQz/87MeZtArziguKSpJTGLQK0mtKGGgGHADMSgoYH6AhTMPNHyE0NQzYuEzYzEXFr6CBPQDANAsXKTwAQAA' | base64 -d | gzip -d > /tmp/clickhouse_test_sse42 && chmod a+x /tmp/clickhouse_test_sse42 && /tmp/clickhouse_test_sse42); then
echo 'SSE 4.2 instruction set is not supported'
exit 3
fi
fi
fi
fi
# С помощью 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"
SUPPORTED_COMMANDS="{start|stop|status|restart|forcestop|forcerestart|reload|condstart|condstop|condrestart|condreload}"
is_supported_command()
{
echo $SUPPORTED_COMMANDS | grep -E "(\{|\|)$1(\||})" &> /dev/null
}
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()
{
[[ -e $PIDDIR ]] && 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
}
all_runs()
{
[[ $(running_processes) -eq $NUMBER_OF_PROCESSES ]]
}
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: "
ulimit -n 262144
if all_runs; 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
;;
restart)
restart && enable_cron
;;
forcestop)
disable_cron && forcestop
;;
forcerestart)
forcerestart && enable_cron
;;
reload)
restart
;;
condstart)
all_runs || start
;;
condstop)
any_runs && stop
;;
condrestart)
any_runs && restart
;;
condreload)
any_runs && restart
;;
esac
exit $EXIT_STATUS
}
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
}
# выполняем команды, не нуждающиеся в блокировке
if ! is_supported_command "$1"; then
echo "Usage: ${0##*/} $SUPPORTED_COMMANDS"
exit 2
fi
if [[ "$1" == "status" ]]; then
status
exit 0
fi
(
if flock -n 9; then
main "$@"
else
echo "Init script is already running" && exit 1
fi
) 9> $LOCKFILE