share facebook facebook2 twitter menu hatena pocket slack

2016.04.12 TUE

Ubuntu 旧バージョンでのサービス起動/停止はserviceコマンドで。

WRITTEN BY大住 孝之

知ってる人には当たり前なのでしょうが、 無知な自分は小一時間ハマりました。
最近はsystemdがデフォルトになってきているので、古いバージョンでの話です。

20160216050523

各種サービスの起動/停止にはrcスクリプトではなく、 serviceコマンドを使いましょう。
常日頃serviceコマンドで起動/停止しているならば発生しない問題でもあります。
癖でrcスクリプトで実行しがちな自分用備忘録です。

  • 誤:/etc/init.d/service_name start
  • 正:service service_name start

以上です。

経緯

赤い帽子(とせんとくん)歴はそれなりにありましたが、 ほぼ初Ubuntuで /etc/init.d/* スクリプトを使用したサービス起動/停止が行えませんでした。

検証

実際にどうして動作しないのかを確認しました。

環境

  • Ubuntu 14.04
    • Vagrant: Official Ubuntu 14.04 daily Cloud Image amd64
$ 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

思い込みは敵であるということを再認識しました。

元記事はこちら

Ubuntu 旧バージョンでのサービス起動/停止はserviceコマンドで。

大住 孝之

構築運用担当。 個性的な面々の中で無個性という個性を打ち出していこうと画策中。