ライン

ポイント:自サーバを監視し、インターネットに疎通できなければ再起動

ライン

 はじめに

tasksとshutdown

 何故、このようなページがあるかを先に記述した方がいいのかも知れません。ある会社のWindows Server 2003 SP2マシンが、某社のコロケーションエリアに設置してあります。マシンは、どういったタイミングはわかりませんが、OSは動作しているのですが、マシン内部からも外部からもNIC経由の疎通が取れなくなり、現地センターの担当者様にご依頼して電源のon/offをするしかない状態になることがありました。

 NICは2つあるマシンなので、チーミングさせるなど方法はあるかも知れませんが、現象としては単純なので内部から、すぐ外にあるルータへのpingによる死活監視を行い、応答がない場合には再起動するように設定を加えました。
 本来的な使い方ではありませんでしたが、この方法の実装でどうにか自立? で動作しているのでそのまま動作させているのです。

 このページでは、その設定方法の備忘録を公開しています。現在までに参照に来られた方が同様の使い方をしているとは思いませんが、何かしらの実装のために参考にされているのだと思います。

 Windows Server 2003

shutdown

 マシンを再起動(リブート)させるためのコマンドは、shutdown。これは、PC UNIXと同様です。
まず、この利用方法を確認しておきましょう。

> shutdown -?
使用法: shutdown [/i | /l | /s | /r | /a | /p | /h | /e] [/f]
    [/m \\コンピュータ][/t xxx][/d [p:]xx:yy [/c "コメント"]]
 
    引数なし   ヘルプを表示します。/? と入力するのと同じです
    /?         ヘルプを表示します。何もオプションを入力しないのと同じです
    /i         グラフィック ユーザー インターフェース (GUI) を表示します
               このオプションは最初に指定する必要があります
    /l         ログオフします。/m または /d オプションとは併用できません
    /s         コンピュータをシャットダウンします
    /r         コンピュータをシャットダウンして再起動します
    /a         システム シャットダウンを中止します
               これはタイムアウトの期間中のみ使用できます
    /p         タイムアウトまたは警告なしでローカル コンピュータの電源を切り
               ます。
               このオプションは /d オプションとのみ併用できます
    /h         ローカル コンピュータを休止状態にします
               このオプションは /f オプションとのみ併用できます
    /e         コンピュータの予期しないシャットダウンの理由を記録します
    /m \\コンピュータ
               対象となるコンピュータを指定します
    /t xxx     シャットダウン前のタイムアウト期間を xxx 秒に設定します
               有効な範囲は 0 から 600 で、既定値は 30 です
    /c "コメント"
               再起動またはシャットダウンの理由にコメントを付けます
                最高 127 文字まで入力できます
    /f         ユーザーに警告せずに実行中のアプリケーションを強制終了します
    /d [p:]xx:yy
               再起動またはシャットダウンの理由を指定します
               p は再起動またはシャットダウンが計画されていたことを示します
               xx は主因の番号です (255 以下の正の整数)
               yy は副因の番号です (65535 以下の正の整数)-

 おおよそ、PC UNIXに近いことが指定できることがわかります。
syslogにログとして、Windowsにはイベントログがあります。イベントログに再起動理由の指定が必要そうです。

 その理由に関する内容を少し確認しておきます。

理由:
(E = 予期していた理由 U = 予期していない理由 P = 計画済み, C = ユーザー定義)
種類    主因    副因    タイトル
 
 U      0       0       その他 (計画外)
E       0       0       その他 (計画外)
E P     0       0       その他 (計画済)
 U      0       5       その他の障害: システム応答なし
E       1       1       ハードウェア: メンテナンス (計画外)
E P     1       1       ハードウェア: メンテナンス (計画済)
E       1       2       ハードウェア: インストール (計画外)
E P     1       2       ハードウェア: インストール (計画済)
  P     2       3       オペレーティング システム: アップグレード (計画済)
E       2       4       オペレーティング システム: 再構成 (計画外)
E P     2       4       オペレーティング システム: 再構成 (計画済)
  P     2       16      オペレーティング システム: Service pack (計画済)
        2       17      オペレーティング システム: ホットフィックス (計画外)
  P     2       17      オペレーティング システム: ホットフィックス (計画済)
        2       18      オペレーティング システム: セキュリティ フィックス (計画外)
  P     2       18      オペレーティング システム: セキュリティ フィックス (計画済)
E       4       1       アプリケーション: メンテナンス (計画外)
E P     4       1       アプリケーション: メンテナンス (計画済)
E P     4       2       アプリケーション: インストール (計画済)
E       4       5       アプリケーション: 応答なし
E       4       6       アプリケーション: 不安定
 U      5       15      システム障害: STOP エラー
E       5       19      セキュリティの問題
 U      5       19      セキュリティの問題
E P     5       19      セキュリティの問題
E       5       20      ネットワーク接続の損失 (計画外)
 U      6       11      電源障害: コードが抜けました
 U      6       12      電源障害: 環境
  P     7       0       レガシ API シャットダウン

 上記を前提に、手動で同コマンドを使ってみることにしました。

> shutdown /r /f /t 600 /c "再起動をすることを準備しています。
拒否するにはコマンドラインから `shutdown /a` を投入してください" /d p:4:1

p:4:1 の指定は、上記の通り アプリケーション:メンテナンス(計画済) となるわけです。
とかにして、10分間(600秒)で、 shutdown /a をコマンドで入れなければ、正常にリブートできることを確認しました。

shutdown実施開始後に表示される画面

 上記のように、メッセージを出しているのは、NICを外してメンテナンスしている時などに勝手に再起動が開始しても困るので、
10分間の猶予を指定することにしました。必要がなければ /t 10 などにして10秒後に実施されるようにしました。

> shutdown /a

と DOS窓などで実行することにより、シャットダウン(再起動)は中断(キャンセル)されます。
動きとしては理解することができました。

crontabとschtasks (tasks)

 Windows では、tasksというスケジュールをGUIで指定することができます。この機能が便利そうでかなり不便。未だになじめません。
ただ、そうもいってられないのでわかる範囲で使っていこうと思います。

 shutdownと同様に schtasksの使い方を確認しておきます。

> schtasks /?

SCHTASKS /パラメータ [引数]

説明:
    管理者がローカルまたはリモートのシステム上のスケジュール タスクの作成、
    削除、クエリ実行、変更、実行および終了を行います。AT.exe の代用です。
 
パラメータの一覧:
    /Create         スケジュール タスクを新しく作成します。
 
    /Delete         スケジュール タスクを削除します。
 
    /Query          スケジュール タスクをすべて表示します。
 
    /Change         スケジュール タスクのプロパティを変更します。
 
    /Run            今すぐスケジュール タスクを実行します。
 
    /End            現在実行中のスケジュール タスクを停止します。
 
    /?              このヘルプを表示します。

例:
    SCHTASKS
    SCHTASKS /?
    SCHTASKS /Run /?
    SCHTASKS /End /?
    SCHTASKS /Create /?
    SCHTASKS /Delete /?
    SCHTASKS /Query  /?
    SCHTASKS /Change /?

> schtasks /create /?

SCHTASKS /Create [/S システム [/U ユーザー名 [/P [パスワード]]]]
    [/RU ユーザー名 [/RP パスワード]] /SC スケジュール [/MO 修飾子] [/D 日]
    [/M 月] [/I アイドル時間] /TN タスク名 /TR 実行タスク [/ST 開始時刻]
    [/RI 間隔] [ {/ET 終了時刻 | /DU 継続時間} [/K] ]
    [/SD 開始日] [/ED 終了日] [/IT] [/Z] [/F]

説明:
    管理者がローカルまたはリモートのシステム上にスケジュール タスク
    を作成します。
.
.
.

 上記を前提に、試してみます。

> schtasks /create /sc MINUTE /MO 15 /TN PING_CHECK /TR c:\reboot_check.bat
タスクは現在ログオンしているユーザー名 ("HOST\Administrator") の名前の下で作成されます。
HOST\Administrator の実行者パスワードを入力してください: ***********
 
成功: スケジュール タスク "PING_CHECK" は正しく作成されました。                 

のようにうまく投じることができました。

 意味を解説する必要はなさそうですが、/createで追加。/sc で単位指定。ここでは分を指定。/MO は分ごとの単位。ここでは15分。/TN は ネーミング。 /TRは 実際に起動する実行ファイルの指定を実施します。
 例にある通り、これらの詳細については /? をつけて眺めると書いてあります。
気が向けば更に詳細にヘルプの内容を書きますが、今回はそのままで先に進みます。

 注意すべきなのは、Administrator のパスワードを変更した際には、再度登録し直さなければ実施されなくなります。
この部分ははまってしまったので注意が必要です。登録されている内容の確認は queryで実施します。

> schtasks /query
 
タスク名                             次回の実行時刻           状態
==================================== ======================== ===============
PING_CHECK                           15:16:00, 2006/07/17

 登録されていることを確認できました。

 スケジュールも削除は以下の通り。

> schtasks  /delete /tn PING_CHECK
警告: タスク "PING_CHECK" を削除しますか (Y/N) ? y
成功: スケジュール タスク "PING_CHECK" は正しく削除されました。

そこそこわかりやすいです

 死活監視を自サーバで…

ping

 これも、PC UNIXに同様に pingコマンドで疎通確認をすることができます。当然、この使い方を確認する必要があります。

> ping /?

Usage: ping [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS]
            [-r count] [-s count] [[-j host-list] | [-k host-list]]
            [-w timeout] [-R] [-S srcaddr] [-4] [-6] target_name

Options:
    -t             Ping the specified host until stopped.
                   To see statistics and continue - type Control-Break;
                   To stop - type Control-C.
    -a             Resolve addresses to hostnames.
    -n count       Number of echo requests to send.
    -l size        Send buffer size.
    -f             Set Don't Fragment flag in packet (IPv4-only).
    -i TTL         Time To Live.
    -v TOS         Type Of Service (IPv4-only).
    -r count       Record route for count hops (IPv4-only).
    -s count       Timestamp for count hops (IPv4-only).
    -j host-list   Loose source route along host-list (IPv4-only).
    -k host-list   Strict source route along host-list (IPv4-only).
    -w timeout     Timeout in milliseconds to wait for each reply.
    -R             Trace round-trip path (IPv6-only).
    -S srcaddr     Source address to use (IPv6-only).
    -4             Force using IPv4.
    -6             Force using IPv6.

Windows XPでも同様ですが、日本語では説明が表示されませんでした。

  • -l 1…バッファーサイズ 1にしてみた。本当はデフォルトでいい。
  • -n 10…回数10回を指定。1回でも正常な応答が来ればステータスは正常。
  • -a
  • -4…IPv4

という感じにしました。

これを反映した形で作成したバッチファイルが以下のものです。
c:\>notepad reboot_check.bat

@echo off
ping -l 1 -n 10 -4 -a 192.168.0.1 1>nul
if %errorlevel% EQU 1 (
echo  オフラインにより再起動を準備します
C:\WINDOWS\system32\shutdown.exe /r /f /t 180 /c 
"再起動をすることを準備しています。拒否するにはコマンドラインから `shutdown /a` を投入してください" /d p:2:4
)

のようにしました。
ここで書いてある 192.168.0.1 はそれぞれの環境近くにある返事が来る機器のIPアドレスにすればいいでしょう。

 最近は、ちょっと試しに以下のように変更しています。
もうちょい、setでIPアドレス等を変数化したり、イベントログにも出力するなどをしたりを加えたいと思っていますが、試している最中なので。

@echo off
set /a COUNT=0
ping -w 5000 -n 2 -a 192.168.0.1 | find /i "bytes=32" 1>nul
if %errorlevel%==0 (
        goto end
) else (
        goto step1
)

:step1
        set /A count=count+1
        echo *** step1:1分の待機時間 %count% 回目です
        ping localhost -n 5 >NUL
        ping -w 5000 -n 2 -a 192.168.0.1 | find /i "bytes=32" 1>nul
        if %errorlevel%==0 (goto end)
        if %count%==3 (
        echo  オフラインにより再起動を準備します
        C:\WINDOWS\system32\shutdown.exe /r /f /t 600 /c
"再起動をすることを準備しています。拒否するにはコマンドラインから shutdown /a を投入してください" /d p:0:0
        goto end
        )
        goto step1

:end
        exit 0

 このような感じです。
goto ばかりで気持ちが悪いのですけど、動けばいいのでそのまま試している段階にあります。

 スケジューラでこれを5分に一回程度で監視するようにしました。
本来的には、この状態でのエラーが数回出たタイミングで初めて再起動を実施で十分だと思います。
 また、外部監視でこのマシンを見張る場合には、リブートをみて通知するような同様を作成しておけばいいでしょう。

【改訂履歴】作成:2009/01/10
2009/06/14 … Namazu検索の窓を追加、複数タイミングによる死活監視いとしたバッチファイルに更新したものを追加。

【参考リンク】

デル株式会社

Copyright © 1996,1997-2006,2007- by F.Kimura,