Sun Cluster データサービス開発ガイド (Solaris OS 版)

障害モニターの定義

サンプルのアプリケーションは、DNS リソース (in.named) の信頼性を監視する基本的な障害モニターを実装します。

障害モニターは、次の要素から構成されます。

検証プログラムの仕組み

dns_probe プログラムは、サンプルのデータサービスの管理下にある DNS リソースが動作しているかどうかを確認する、連続して動作するプロセスを実行します。dns_probe は、サンプルのデータサービスがオンラインになったあと、RGM によって自動的に実行される dns_monitor_start メソッドによって起動されます。データサービスは、サンプルのデータサービスがオフラインになる前、RGM によって実行される dns_monitor_stop メソッドによって停止されます。

この節では、サンプルのアプリケーションの PROBE メソッドの重要な部分だけを説明します。parse_args() 関数など、すべてのコールバックメソッドに共通な機能については説明しません。また、syslog() 関数の使用法についても説明しません。共通の機能については、「すべてのメソッドに共通な機能の提供」を参照してください。

PROBE メソッドの完全なリストについては、PROBE プログラムのコードリスト」を参照してください。

検証プログラムの動作

検証プログラムは無限ループで動作します。検証プログラムは、nslookup を使用し、適切な DNS リソースが動作しているかどうかを確認します。DNS が動作している場合、検証プログラムは一定の期間 (Thorough_probe_interval システム定義プロパティーに設定されている期間) だけ休眠し、再び検証を行います。DNS が動作していない場合、検証プログラムは DNS をローカルで再起動しようとするか、再起動の再試行回数によっては、RGM がデータサービスを別のノードまたはゾーンに再配置することを要求します。

プロパティー値の取得

このプログラムには、次のプロパティーの値が必要です。

scha_resource_get() 関数は、次に示すように、上記プロパティーの値を取得し、シェル変数に格納します。

PROBE_INTERVAL=`scha_resource_get -O Thorough_probe_interval \
-R $RESOURCE_NAME -G $RESOURCEGROUP_NAME`

PROBE_TIMEOUT_INFO=`scha_resource_get -O Extension -R $RESOURCE_NAME \
-G $RESOURCEGROUP_NAME Probe_timeout` 
Probe_timeout=`echo $probe_timeout_info | awk '{print $2}'`

DNS_HOST=`scha_resource_get -O Network_resources_used -R $RESOURCE_NAME \
-G $RESOURCEGROUP_NAME`

RETRY_COUNT=`scha_resource_get -O Retry_count -R $RESOURCE_NAME -G \
$RESOURCEGROUP_NAME`

RETRY_INTERVAL=`scha_resource_get -O Retry_interval -R $RESOURCE_NAME -G \
$RESOURCEGROUP_NAME`

RT_BASEDIR=`scha_resource_get -O RT_basedir -R $RESOURCE_NAME -G \
 $RESOURCEGROUP_NAME`

注 –

システム定義プロパティー (Thorough_probe_intervalなど) の場合、scha_resource_get() 関数は値だけを戻します。拡張プロパティー (Probe_timeout など) の場合、scha_resource_get() 関数はタイプと値を戻します。値だけを取得するには awk コマンドを使用します。


サービスの信頼性の検査

検証プログラム自身は、nslookup コマンドの while による無限ループです。while ループの前に、nslookup の応答を保管する一時ファイルを設定します。probefail 変数と retries 変数は 0 に初期化されます。

# Set up a temporary file for the nslookup replies.
DNSPROBEFILE=/tmp/.$RESOURCE_NAME.probe
probefail=0
retries=0

while ループは、次の作業を行います。

次に、while ループコードを示します。

while :
do
   # 検証が実行される時間は THOROUGH_PROBE_INTERVAL プロパティー
   # に指定されている。したがって、THOROUGH_PROBE_INTERVAL の間
   # 検証が Sleep するように設定する。
   sleep $PROBE_INTERVAL

   # DNS がサービスを提供している IP アドレス上で nslookup コマンドを実行する。
   hatimerun -t $PROBE_TIMEOUT /usr/sbin/nslookup $DNS_HOST $DNS_HOST \
   > $DNSPROBEFILE 2>&1

      retcode=$?
      if [ $retcode -ne 0 ]; then
            probefail=1
      fi

   # nslookup への応答が /etc/resolv.conf ファイルに指定されている
   # そのほかのネームサーバーではなく HA-DNS サーバーから返されて 
   # いることを確認する。
   if [ $probefail -eq 0 ]; then
# nslookup 照会に応答したサーバーの名前を取得する。
   SERVER=` awk ' $1=="Server:" { print $2 }' \
   $DNSPROBEFILE | awk -F. ' { print $1 } ' `
   if [ -z "$SERVER" ]; then
      probefail=1
      else
         if [ $SERVER != $DNS_HOST ]; then
            probefail=1
         fi
   fi
fi

再起動とフェイルオーバーの評価

probefail 変数が 0 (成功) 以外である場合、nslookup コマンドがタイムアウトしたか、あるいは、サンプルのサービスの DNS 以外のサーバーから応答が来ていることを示します。どちらの場合でも、DNS サーバーは期待どおりに機能していないので、障害モニターは decide_restart_or_failover() 関数を呼び出し、データサービスをローカルで起動するか、RGM がデータサービスを別のノードまたはゾーンに再配置することを要求するかを決定します。probefail 変数が 0 の場合、検証が成功したことを示すメッセージが生成されます。

   if [ $probefail -ne 0 ]; then
         decide_restart_or_failover
   else
         logger -p ${SYSLOG_FACILITY}.err\
         -t [$SYSLOG_TAG]\
         "${ARGV0} Probe for resource HA-DNS successful"
   fi

decide_restart_or_failover() 関数は、再試行最大期間 (Retry_interval) と再試行最大回数 (Retry_count) を使用し、DNS をローカルで再起動するか、RGM がデータサービスを別のノードまたはゾーンに再配置することを要求するかを決定します。この関数は、次のような条件付きコードを実装します。コードリストについては、PROBE プログラムのコードリスト」にある decide_restart_or_failover() を参照してください。

期限 (再試行最大期間) 内に再起動の回数 (再試行カウンタ) が制限 (再試行最大回数) に到達した場合、この関数は、RGM がデータサービスを別のノードまたはゾーンに再配置することを要求します。再起動の回数が制限に到達していない場合、あるいは、再試行最大期間を過ぎていて、再試行カウンタをリセットする場合、この関数は DNS を同じノードまたはゾーン上で再起動しようとします。

この関数については、次の点に注意してください。

データサービスの再起動

restart_service() 関数は、decide_restart_or_failover() によって呼び出され、同じノードまたはゾーン上でデータサービスの再起動を試行します。

この関数は次の作業を行います。

function restart_service
{

        # データサービスを再起動するには、まずデータサービス自体が PMF に 
        # 登録されているかどうかを確認する。
        pmfadm -q $PMF_TAG
        if [[ $? -eq 0 ]]; then
                # データサービスの TAG が PMF に登録されている場合、データ
                # サービスを停止し、再起動する。

                # 当該リソースの Stop メソッド名と
                # STOP_TIMEOUT 値を取得する。
                STOP_TIMEOUT=`scha_resource_get -O STOP_TIMEOUT \
                        -R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ
                STOP_METHOD=`scha_resource_get -O STOP \
                        -R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ
                hatimerun -t $STOP_TIMEOUT $RT_BASEDIR/$STOP_METHOD \
                        -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \
                        -T $RESOURCETYPE_NAME

                if [[ $? -ne 0 ]]; then
                        logger-p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \
                                “${ARGV0} Stop method failed.”
                        return 1
                fi

                # 当該リソースの START メソッド名と START_TIMEOUT 値
                # を取得する。
                START_TIMEOUT=`scha_resource_get -O START_TIMEOUT \
                        -R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ
                START_METHOD=`scha_resource_get -O START \
                        -R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ
                hatimerun -t $START_TIMEOUT $RT_BASEDIR/$START_METHOD \
                        -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \
                        -T $RESOURCETYPE_NAME

                if [[ $? -ne 0 ]]; then
                        logger-p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \
                                “${ARGV0} Start method failed.”
                        return 1
                fi


        else
                # データサービスの TAG が PMF に登録されていない場合、 
                # データサービスが PMF で許可されている最大再試行回数
                # を超過している。したがって、データサービスを再起動しては
                # ならない。代わりに、同じクラスタ内の別のノードへの
                # フェイルオーバーを試みる。
                scha_control -O GIVEOVER -G $RESOURCEGROUP_NAME \
                        -R $RESOURCE_NAME
        fi

        return 0
}

検証プログラムの終了状態

ローカルでの再起動が失敗したり、別のノードまたはゾーンへのフェイルオーバーが失敗したりすると、サンプルのデータサービスの PROBE プログラムは失敗で終了します。このプログラムは「Failover attempt failed」(フェイルオーバーは失敗しました) というメッセージを記録します。

Monitor_start メソッドの仕組み

RGM は、サンプルデータサービスがオンラインになったあとに、Monitor_start メソッドを呼び出して dns_probe メソッドを起動します。

この節では、サンプルアプリケーションの Monitor_start メソッドの重要な部分だけを説明します。parse_args() 関数など、すべてのコールバックメソッドに共通な機能については説明しません。また、syslog() 関数の使用法についても説明しません。共通の機能については、「すべてのメソッドに共通な機能の提供」を参照してください。

Monitor_start メソッドの完全なリストについては、Monitor_start メソッドのコードリスト」を参照してください。

Monitor_start メソッドの動作

このメソッドは PMF (pmfadm) を使って検証プログラムを起動します。

検証プログラムの起動

Monitor_start メソッドは、RT_basedir プロパティーの値を取得し、PROBE プログラムの完全パス名を構築します。このメソッドは、pmfadm の無限再試行オプション (-n -1-t -1) を使用して検証プログラムを起動します。つまり、検証プログラムの起動に失敗しても、PMF は検証プログラムを無限に起動しようとします。

# リソースの RT_BASEDIR プロパティーを取得し、検証プログラムが存在する
# 場所を確認する。
RT_BASEDIR=`scha_resource_get -O RT_basedir -R $RESOURCE_NAME -G \
$RESOURCEGROUP_NAME`

# PMF の制御下でデータサービスの検証を開始する。無限再試行オプションを使って
# 検証プログラムを起動する。リソースの名前、タイプ、グループを検証
# プログラムに渡す。 
pmfadm -c $RESOURCE_NAME.monitor -n -1 -t -1 \
   $RT_BASEDIR/dns_probe -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \
   -T $RESOURCETYPE_NAME

Monitor_stop メソッドの仕組み

RGM は、サンプルデータサービスがオフラインになるときに、Monitor_stop メソッドを呼び出して dns_probe の実行を停止します。

この節では、サンプルアプリケーションの Monitor_stop メソッドの重要な部分だけを説明します。parse_args() 関数など、すべてのコールバックメソッドに共通な機能については説明しません。また、syslog() 関数の使用法についても説明しません。共通の機能については、「すべてのメソッドに共通な機能の提供」を参照してください。

Monitor_stop メソッドの完全なリストについては、Monitor_stop メソッドのコードリスト」を参照してください。

Monitor_stop メソッドの動作

このメソッドは、PMF (pmfadm) を使用して検証プログラムが動作しているかどうかを判断し、動作している場合は検証プログラムを停止します。

検証プログラムの停止

Monitor_stop メソッドは、pmfadm -q を使用して検証プログラムが動作しているかどうかを判断し、動作している場合は pmfadm -s を使用して検証プログラムを停止します。検証プログラムがすでに停止している場合でも、このメソッドは成功状態でします。これによって、メソッドが呼び出し回数に依存しないことが保証されます。


注意 – 注意 –

必ず KILL シグナルと pmfadm を使用して検証プログラムを停止してください。TERM などのマスク可能なシグナルは使用しないでください。そうしないと、Monitor_stop メソッドが無限にハングし、結果としてタイムアウトする可能性があります。これは、データサービスを再起動またはフェイルオーバーする必要がある場合に PROBE メソッドは scha_control() を呼び出すためです。データサービスをオフラインにするプロセスの一部として scha_control()Monitor_stop を呼び出す場合、Monitor_stop がマスク可能なシグナルを使用すると、Monitor_stopscha_control() の完了を待機してハングし、scha_control()Monitor_stop の完了を待機してハングします。


# 検証プログラムが動作しているかどうかを判断し、動作している場合は停止する。
if pmfadm -q $PMF_TAG; then
   pmfadm -s $PMF_TAG KILL
   if [ $? -ne 0 ]; then
         logger -p ${SYSLOG_FACILITY}.err \
            -t [$SYSLOG_TAG] \
            "${ARGV0} Could not stop monitor for resource " \
            $RESOURCE_NAME
           exit 1
   else
         # 検証プログラムの停止に成功。メッセージを記録する。
         logger -p ${SYSLOG_FACILITY}.err \
            -t [$SYSLOG_TAG] \
            "${ARGV0} Monitor for resource " $RESOURCE_NAME \
            " successfully stopped"
   fi
fi
exit 0

Monitor_stop の終了状態

PROBE メソッドを停止できない場合、Monitor_stop メソッドはエラーメッセージを記録します。RGM は、主ノードまたはゾーン上でサンプルのデータサービスを MONITOR_FAILED 状態にするため、そのノードに障害が発生することがあります。

Monitor_stop メソッドは、検証プログラムが停止するまで終了してはなりません。

Monitor_check メソッドの仕組み

PROBE メソッドが、データサービスのあるリソースグループを新しいノードまたはゾーンにフェイルオーバーしようとするときに、RGM は必ず Monitor_check メソッドを呼び出します。

この節では、サンプルアプリケーションの Monitor_check メソッドの重要な部分だけを説明します。parse_args() 関数など、すべてのコールバックメソッドに共通な機能については説明しません。また、syslog() 関数の使用法についても説明しません。共通の機能については、「すべてのメソッドに共通な機能の提供」を参照してください。

Monitor_check メソッドの完全なリストについては、Monitor_check メソッドのコードリスト」を参照してください。

Monitor_check メソッドは、並行して実行中のそのほかのメソッドと競合しない方法で実装する必要があります。

Monitor_check メソッドは Validate メソッドを呼び出し、新しいノードまたはゾーン上で DNS 構成ディレクトリが利用可能かどうかを確認します。Confdir 拡張プロパティーが DNS 構成ディレクトリを指します。したがって、Monitor_checkValidate メソッドのパスと名前、および Confdir の値を取得します。Monitor_check は、次のように、この値を Validate に渡します。

# リソースタイプの RT_BASEDIR プロパティーから Validate メソッドの
# 完全パスを取得する。
RT_BASEDIR=`scha_resource_get -O RT_basedir -R $RESOURCE_NAME \
   -G $RESOURCEGROUP_NAMÈ

# 当該リソースの Validate メソッド名を取得する。
VALIDATE_METHOD=`scha_resource_get -O Validate \
   -R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ

# データサービスを起動するための Confdir プロパティーの値を取得する。
# 入力されたリソース名とリソースグループを使用し、リソースを追加
# するときに設定した Confdir の値を取得する。
config_info=`scha_resource_get -O Extension -R $RESOURCE_NAME \
 -G $RESOURCEGROUP_NAME Confdir`

# scha_resource_get は、Confdir 拡張プロパティーの値とともにタイプも戻す。
# awk を使用し、Confdir 拡張プロパティーの値だけを取得する。
CONFIG_DIR=`echo $config_info | awk `{print $2}'`

# Validate メソッドを呼び出し、データサービスを新しいノードに
# フェイルオーバーできるかどうかを確認する。
$RT_BASEDIR/$VALIDATE_METHOD -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \
   -T $RESOURCETYPE_NAME -x Confdir=$CONFIG_DIR

ノードまたはゾーンがデータサービスのホストとして最適であるかどうかをサンプルアプリケーションが確認する方法については、Validate メソッドの仕組み」を参照してください。