この記事は…

集え、初老丸達よ。初老丸達による世界に向けた技術的(又はそれに関連する)な物語を綴るカレンダーです。我こそ初老丸という方、初老丸予備軍の方も奮ってご参加下さい。ジーク・初老丸!

qiita.com

参加者の少ない, 初老丸 Advent Calendar 2017 12 日目の記事です.

何をしたかったのか

  • OS をシャットダウン、又は再起動した際に何らかの処理をさせたい

どこで(何で)やりたかったのか

  • SysVInit 系の OS (CentOS 6.x)でやりたい

やったこと

init スクリプト

以下のような init スクリプトを書いた. 尚, スクリプト名は /etc/init.d/execute-some-command とする.

#!/bin/sh

# chkconfig:         2345 99 01
# description:       execute-some-command

lock_file="/var/lock/subsys/execute-some-command"

start()
{
  touch ${lock_file}
}

#
# 何らかの処理を実行
#
stop()
{
  rm -r ${lock_file}
  # 何らかの処理
}

case "$1" in
  start)
    start
  ;;
  stop)
    stop
  ;;
  *)
    echo "Usage: $0 {start|stop}"
  ;;
esac

exit 0

スクリプトの肝は冒頭の…

...                  起動するランレベル 起動時の優先度 停止時の優先度
# chkconfig:         2345 99 01
# description:       execute-some-command
...

で, chkconfig の定義は以下のような意味を持つ. (こちらの記事がとても参考になりました. 有難うございました.)

定義 詳細
起動するランレベル ランレベルを数字で入力, 複数の場合は 2345 と連続で書く 2345
起動時の優先度 数値(1 〜 99 で入力), 数字が大きくなる程, 後から起動する 99
停止時の優先度 数値(1 〜 99 で入力), 数字が大きくなる程, 後から停止する 01

もう一つは, 以下の lock_file のパス指定.

lock_file="/var/lock/subsys/execute-some-command"

このファイルが存在しないと OS 停止時にコマンドが実行されないとのこと.(こちらのの記事を参考にさせて頂きました. 有難うございました.)

確かに, /etc/rc の以下の部分で /var/lock/subsys/ 以下のファイルをチェックしているようです.

...
# First, run the KILL scripts.
for i in /etc/rc$runlevel.d/K* ; do

        # Check if the subsystem is already up.
        subsys=${i#/etc/rc$runlevel.d/K??}
        [ -f /var/lock/subsys/$subsys -o -f /var/lock/subsys/$subsys.init ] || continue
        check_runlevel "$i" || continue

        # Bring the subsystem down.
        [ -n "$UPSTART" ] && initctl emit --quiet stopping JOB=$subsys
        $i stop
        [ -n "$UPSTART" ] && initctl emit --quiet stopped JOB=$subsys
done
...

ふむ, ふむ.

chkconfig で追加

sudo /etc/init.d/execute-some-command
sudo chkconfig --add execute-some-command

上記を実行すると, 以下のようにシンボリックリンクが生成される.

$ find /etc/rc.d/rc*.d/ -name *execute-some-command | xargs ls -l
lrwxrwxrwx 1 root root 30 12月 16 06:11 /etc/rc.d/rc0.d/K01execute-some-command -> ../init.d/execute-some-command
lrwxrwxrwx 1 root root 30 12月 16 06:11 /etc/rc.d/rc1.d/K01execute-some-command -> ../init.d/execute-some-command
lrwxrwxrwx 1 root root 30 12月 16 06:11 /etc/rc.d/rc2.d/S99execute-some-command -> ../init.d/execute-some-command
lrwxrwxrwx 1 root root 30 12月 16 06:11 /etc/rc.d/rc3.d/S99execute-some-command -> ../init.d/execute-some-command
lrwxrwxrwx 1 root root 30 12月 16 06:11 /etc/rc.d/rc4.d/S99execute-some-command -> ../init.d/execute-some-command
1rwxrwxrwx 1 root root 30 12月 16 06:11 /etc/rc.d/rc5.d/S99execute-some-command -> ../init.d/execute-some-command
lrwxrwxrwx 1 root root 30 12月 16 06:11 /etc/rc.d/rc6.d/K01execute-some-command -> ../init.d/execute-some-command

上記の場合…

  • ランレベル 2 〜 ランレベル 5 までの場合, 99 番目に execute-some-command の start() が実行される
  • ランレベル 0 〜 ランレベル 1 及び, ランレベル 6 の場合, 最初に execute-some-command の stop() が実行される

ということで, OS のシャットダウン時と再起動に execute-some-command の stop() が実行されることになる.

おさらいになるが, レッドハット系のディストリビューションでのランレベルは以下のような種類がある.(こちらより抜粋)

ランレベル 詳細
0 休止
1 シングルユーザー, テキストモード
2 未使用(ユーザー定義可能)
3 フルマルチユーザー, テキストモード
4 未使用(ユーザー定義可能)
5 フルマルチユーザー, グラフィカルモード(X ベースのログイン画面)
6 再起動

以上

Linux とはなんぞや的な基礎的な内容だったけど, とても参考になったし, このような知識は改めて勉強する必要があるなと思った次第.

元記事はこちら

CentOS で OS のシャットダウンや再起動時に何らかの処理をさせたい