CentOS: порядок выполнения init.d скриптов и приоритеты chkconfig

На сервере использовался запуск TeamCity одной строкой в файле /etc/rc.local:

su -c teamcity '/home/teamcity/TeamCity/bin/runAll.sh start'

Но после перезагрузки – в логе TeamCity появились сообщения:

[2014-08-05 13:17:23,402] ERROR – jetbrains.buildServer.SERVER – Unable to change status of build 23908
jetbrains.buildServer.serverSide.db.UnexpectedDBException: Attempting to determine database type
SQL exception: Communications link failure

Т.е. – MySQL запустился после того, как запустился TeamCity.

Что бы это исправить – создадим отдельный скрипт для управления TeamCity в каталоге /etc/init.d/.

Для корректного запуска (т.е. – после MySQL) – рассмотрим “приоритеты” init:

01 # ls -1 /etc/rc3.d/
02 K01smartd
03 K10psacct
04 K10saslauthd
05 K15htcacheclean
06 K15svnserve
07 K20tomcat6
08 K50netconsole
09 K50snmpd
10 K50snmptrapd
11 K60nfs
12 K69rpcsvcgssd
13 K73slapd
14 K75quota_nld
15 K80tomcat55
16 K87cntlmd
17 K87restorecond
18 K88auditd
19 K89rdisc
20 K92ip6tables
21 K92iptables
22 S01sysstat
23 S10network
24 S11portreserve
25 S12rsyslog
26 S13irqbalance
27 S13rpcbind
28 S14nfslock
29 S18rpcidmapd
30 S19rpcgssd
31 S22messagebus
32 S25netfs
33 S26udev-post
34 S55sshd
35 S57ntpdate
36 S58ntpd
37 S64mysqld

Скрипты в каталоге rc3.d начинают выполняться на уровне init 3 в том порядке, в котором они расположены в каталоге (т.е. – чем выше “приоритет” – тем позже будет запущен скрипт).

При этом скрипты K (kill) – выполняются при остановке системы, а S (start) – при её запуске.

Очередь init runlevel выглядит так:

Runlevel 0 – уровень выключения системы;
Runlevel 1 – запуск системы в single user mode;
Runlevel 2 – загрузка системы в  multi-user mode, но без поддержки сети;
Runlevel 3 – аналогичен 2 уровню, но с загрузкой сети, без X-сервера;
Runlevel 4 – неопределённый уровень, который можно использовать на своё усмотрение;
Runlevel 5 – запуск системы  в multi-user mode, с поддержкой сети, X-сервером;
Runlevel 6reboot системы.

Находим приоритет MySQL:

1 # ls -l /etc/rc3.d/ | grep mysql
2 lrwxrwxrwx 1 root root 16 Sep 24 2013 S64mysqld -> ../init.d/mysqld

Имя S64 говорит о том, что это файл, выполянемый при старте MySQL, с приоритетом 64.

Что бы задать запуск нашего TeamCity позже, чем MySQL – нам нужно устновить приоритет выше – например, 70.

Сделать это можно с помощью инструкции chkconfig в файле скрипта.

Например, строка:

1 # chkconfig 345 70 40

означает запуск на уровнях 3, 4 или 5 с приоритетом 70, и остановка с приоритетом 40.

Создаём скрипт /etc/init.d/teamcity на основе шаблона /usr/share/doc/initscripts-9.03.38/sysvinitfiles с таким содержимым:

01 #!/usr/bin/env bash
02
03 # description: TeamCity build-server
04 # processname: teamcity
05 # chkconfig: - 70 30
06
07 # Source function library.
08 . /etc/init.d/functions
09
10 RETVAL=0
11 prog="teamcity"
12 LOCKFILE=/var/lock/subsys/$prog
13
14 USER="teamcity"
15 INSTALL="/home/teamcity/TeamCity"
16 SCRIPT="$INSTALL/bin/runAll.sh"
17
18 start() {
19  printf "Starting $prog: n"
20  su -l "$USER" -c "$SCRIPT start"
21  RETVAL=$?
22  [ $RETVAL -eq 0 ] && touch $LOCKFILE
23  echo
24  return $RETVAL
25 }
26
27 stop() {
28  printf "Shutting down $prog: n"
29  su -l "$USER" -c "$SCRIPT stop"
30  RETVAL=$?
31  [ $RETVAL -eq 0 ] && rm -f $LOCKFILE
32  echo
33  return $RETVAL
34 }
35
36 status() {
37  printf "Checking $prog status: n"
38  ps aux | grep "$INSTALL" | grep -v grep
39 }
40
41 case "$1" in
42  start)
43    start
44    ;;
45  stop)
46    stop
47    ;;
48  status)
49    status
50    ;;
51  restart)
52    stop
53    start
54    ;;
55  *)
56    echo "Usage: $prog {start|stop|status|restart}"
57    exit 1
58    ;;
59 esac
60 exit $RETVAL
1 # chmod +x /etc/init.d/teamcity

Проверяем сам скрипт:

1 # service teamcity status
2 Checking teamcity status:
3 teamcity 2422 56.3 9.9 3344728 799008 pts/3 Sl 13:26 95:25 /home/teamcity/opt/jre1.7.0_51/bin/java -Djava.util.logging.config.file=./../conf/logging.properties -Xmx1536m -XX:MaxPermSize=768m -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -server -Xmx512m -XX:MaxPermSize=270m -Dlog4j.configuration=file:/home/teamcity/TeamCity/bin/../conf/teamcity-server-log4j.xml -Dteamcity_logs=../logs/ -Djava.awt.headless=true -Djava.endorsed.dirs=./../endorsed -classpath ./../bin/bootstrap.jar:./../bin/tomcat-juli.jar -Dcatalina.base=./.. -Dcatalina.home=./.. -Djava.io.tmpdir=./../temp org.apache.catalina.startup.Bootstrap start

Добавляем в автозапуск:

1 # chkconfig --add teamcity
1 # chkconfig --level 35 teamcity on
1 # chkconfig --list | grep teamcity
2 teamcity 0:off 1:off 2:off 3:on 4:off 5:on 6:off

И посмотрим – какие файлы создал chkconfig в каталоге /etc/rc.d:

1 # find /etc/rc* -name "*teamcity" | xargs ls -l
2 -rwxr-xr-x 1 root root 1033 Aug 5 17:03 /etc/rc.d/init.d/teamcity
3 lrwxrwxrwx 1 root root 18 Aug 5 17:03 /etc/rc.d/rc0.d/K30teamcity -> ../init.d/teamcity
4 lrwxrwxrwx 1 root root 18 Aug 5 17:03 /etc/rc.d/rc1.d/K30teamcity -> ../init.d/teamcity
5 lrwxrwxrwx 1 root root 18 Aug 5 17:03 /etc/rc.d/rc2.d/K30teamcity -> ../init.d/teamcity
6 lrwxrwxrwx 1 root root 18 Aug 5 17:05 /etc/rc.d/rc3.d/S70teamcity -> ../init.d/teamcity
7 lrwxrwxrwx 1 root root 18 Aug 5 17:03 /etc/rc.d/rc4.d/K30teamcity -> ../init.d/teamcity
8 lrwxrwxrwx 1 root root 18 Aug 5 17:05 /etc/rc.d/rc5.d/S70teamcity -> ../init.d/teamcity
9 lrwxrwxrwx 1 root root 18 Aug 5 17:03 /etc/rc.d/rc6.d/K30teamcity -> ../init.d/teamcity

Готово.