知ってる人には当たり前なのでしょうが、
無知な自分は小一時間ハマりました。
最近はsystemdがデフォルトになってきているので、古いバージョンでの話です。
各種サービスの起動/停止にはrcスクリプトではなく、
serviceコマンドを使いましょう。
常日頃serviceコマンドで起動/停止しているならば発生しない問題でもあります。
癖でrcスクリプトで実行しがちな自分用備忘録です。
- 誤:/etc/init.d/service_name start
- 正:service service_name start
以上です。
- 参考
経緯
赤い帽子(とせんとくん)歴はそれなりにありましたが、 ほぼ初Ubuntuで /etc/init.d/* スクリプトを使用したサービス起動/停止が行えませんでした。
検証
実際にどうして動作しないのかを確認しました。
環境
$ cat /etc/*release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=14.04 DISTRIB_CODENAME=trusty DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS" NAME="Ubuntu" VERSION="14.04.3 LTS, Trusty Tahr" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 14.04.3 LTS" VERSION_ID="14.04" HOME_URL="http://www.ubuntu.com/" SUPPORT_URL="http://help.ubuntu.com/" BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
serviceコマンドでの起動/停止
sshの起動/停止を実行します。 正常に動作(起動/停止)します。
起動
# 停止していることを確認 $ ps -ef | grep '[/]usr/sbin/sshd' $ sudo service ssh status ssh stop/waiting # 起動 $ sudo service ssh start ssh start/running, process 2462 # 起動される $ ps -ef | grep '[/]usr/sbin/sshd' root 2462 1 0 18:06 ? 00:00:00 /usr/sbin/sshd -D $ sudo service ssh status ssh start/running, process 2462
停止
# 起動していることを確認 $ ps -ef | grep '[/]usr/sbin/sshd' root 1786 1 0 17:39 ? 00:00:00 /usr/sbin/sshd -D # 起動していることを確認 $ sudo service ssh status ssh start/running, process 1786 # 停止 $ sudo service ssh stop ssh stop/waiting # 停止される $ ps -ef | grep '[/]usr/sbin/sshd' $ sudo service ssh status ssh stop/waiting
rcコマンドでの起動/停止
sshの起動/停止を実行します。
正常に動作(起動/停止) しません。
出力はスクリプトによりまちまちで、失敗(fail)を返してくれる物もありますが、sshは何も出力されません。
起動
# 停止していることを確認 $ ps -ef | grep '[/]usr/sbin/sshd' # ステータスが取得できない $ sudo /etc/init.d/ssh status # 起動 $ sudo /etc/init.d/ssh start # 起動されない $ ps -ef | grep '[/]usr/sbin/sshd' # ステータスが取得できない $ sudo /etc/init.d/ssh status
停止
# 起動していることを確認 $ ps -ef | grep '[/]usr/sbin/sshd' root 1786 1 0 17:39 ? 00:00:00 /usr/sbin/sshd -D # ステータスが取得できない $ sudo /etc/init.d/ssh status # 停止 $ sudo /etc/init.d/ssh stop # 停止されない $ ps -ef | grep '[/]usr/sbin/sshd' root 1786 1 0 17:39 ? 00:00:00 /usr/sbin/sshd -D # ステータスが取得できない $ sudo /etc/init.d/ssh status
調査
rcスクリプトのデバッグ実行
init_is_upstart関数で終了しています。
$ sudo sh -x /etc/init.d/ssh status ・・・略・・・ + check_for_upstart 1 + init_is_upstart + [ -x /sbin/initctl ] + /bin/grep -q upstart + /sbin/initctl version + return 0 + exit 1
init_is_upstart関数を実行している箇所がcheck_for_upstart関数となっています。
36 check_for_upstart() { 37 if init_is_upstart; then 38 exit $1 39 fi 40 }
呼び出し元を検索すると実行時の引数に関わらず、check_for_upstart関数を実行しています。
$ grep -n -B 1 "check_for_upstart" /etc/init.d/ssh 35- 36:check_for_upstart() { -- 84- start) 85: check_for_upstart 1 -- 96- stop) 97: check_for_upstart 0 -- 106- reload|force-reload) 107: check_for_upstart 1 -- 118- restart) 119: check_for_upstart 1 -- 133- try-restart) 134: check_for_upstart 1 -- 164- status) 165: check_for_upstart 1
init_is_upstart関数
/lib/lsb/init-functions
に定義されています。
# If the currently running init daemon is upstart, return zero; if the # calling init script belongs to a package which also provides a native # upstart job, it should generally exit non-zero in this case. init_is_upstart() { if [ -x /sbin/initctl ] && /sbin/initctl version 2>/dev/null | /bin/grep -q upstart; then return 0 fi return 1 }
upstartを使用している場合は "0" を返すため、 check_for_upstartで必ずexitとなり、スクリプト内後続コマンドが実行されません。
$ /sbin/initctl version init (upstart 1.12.1)
/etc/init.d/ で init_is_upstart を検索
init_is_upstartが含まれているスクリプトは同じような動作でした。
$ grep -c "init_is_upstart" /etc/init.d/* | grep -v -e ':0$' /etc/init.d/networking:4 /etc/init.d/rpcbind:3 /etc/init.d/rsyslog:3 /etc/init.d/ssh:1 /etc/init.d/udev:2
思い込みは敵であるということを再認識しました。