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 がデータサービスを別のノードまたはゾーンに再配置することを要求します。
このプログラムには、次のプロパティーの値が必要です。
Thorough_probe_interval – 検証プログラムが休眠する期間を設定します。
Probe_timeout – nslookup コマンドが検証を行う期間 (タイムアウト値) を設定します。
Network_resources_used – DNS が動作するサーバーを設定します。
Retry_count と Retry_interval – 再起動を行う回数と期間を設定します。
RT_basedir – PROBE プログラムと gettime ユーティリティーが格納されているディレクトリを設定します。
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 ループは、次の作業を行います。
検証プログラム用の休眠期間を設定します。
hatimerun を使用して nslookup を起動し、Probe_timeout の値を渡し、ターゲットホストを指定します。
nslookup の戻りコード (成功または失敗) に基づいて、probefail 変数を設定します。
probefail が 1 (失敗) に設定された場合、nslookup への応答がサンプルのデータサービスから来ており、ほかの DNS サーバーから来ているのではないことを確認します。
次に、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() を参照してください。
最初の障害である場合、データサービスをローカルで再起動します。エラーメッセージを記録し、retries 変数の再試行カウンタをインクリメントします。
最初の障害ではなく、再試行時間が再試行最大期間を過ぎている場合、データサービスをローカルで再起動します。エラーメッセージを記録し、再試行カウンタをリセットし、再試行時間をリセットします。
再試行時間が再試行最大期間を過ぎておらず、再試行カウンタが再試行最大回数を超えている場合、別のノードまたはゾーンにフェイルオーバーします。フェイルオーバーが失敗すると、エラーメッセージを記録し、検証プログラムを状態 1 (失敗) で終了します。
再試行時間が再試行最大期間を過ぎておらず、再試行カウンタが再試行最大回数を超えていない場合、データサービスをローカルで再起動します。エラーメッセージを記録し、retries 変数の再試行カウンタをインクリメントします。
期限 (再試行最大期間) 内に再起動の回数 (再試行カウンタ) が制限 (再試行最大回数) に到達した場合、この関数は、RGM がデータサービスを別のノードまたはゾーンに再配置することを要求します。再起動の回数が制限に到達していない場合、あるいは、再試行最大期間を過ぎていて、再試行カウンタをリセットする場合、この関数は DNS を同じノードまたはゾーン上で再起動しようとします。
この関数については、次の点に注意してください。
gettime ユーティリティーを使用すると、再起動間の時間を追跡できます。これは C プログラムで、(RT_basedir ) ディレクトリ内にあります。
Retry_count と Retry_interval のシステム定義リソースプロパティーは、再起動を行う回数と期間を決定します。RTR ファイルでは、これらのプロパティーのデフォルト値は、再試行が 2 回、期間が 5 分 (300 秒) ですが、クラスタ管理者はこれらの値を変更できます。
restart_service() 関数は、同じノードまたはゾーン上でデータサービスの再起動を試行する場合に呼び出されます。この関数の詳細については、次の節である「データサービスの再起動」を参照してください。
scha_control() API 関数を SCHA_GIVEOVER 引数付きで実行すると、サンプルデータサービスのあるリソースグループがオフラインになり、別ノードまたはゾーン上でオンラインに戻ります。
restart_service() 関数は、decide_restart_or_failover() によって呼び出され、同じノードまたはゾーン上でデータサービスの再起動を試行します。
この関数は次の作業を行います。
データサービスがまだ PMF 下に登録されているかどうかを判別します。
サービスがまだ登録されている場合、この関数は次の作業を行います。
データサービスの Stop メソッド名と Stop_timeout 値を取得します。
hatimerun を使用してデータサービスの Stop メソッドを起動し、Stop_timeout 値を渡します。
データサービスが正常に停止した場合は、データサービスの Start メソッド名と Start_timeout 値を取得します。
hatimerun を使用してデータサービスの Start メソッドを起動し、Start_timeout 値を渡します。
データサービスが PMF 下に登録されていない場合は、データサービスが PMF 下で許可されている再試行最大回数を超えていることを示しています。scha_control コマンドが GIVEOVER 引数付きで実行され、それによってデータサービスが別のノードまたはゾーンにフェイルオーバーします。
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」(フェイルオーバーは失敗しました) というメッセージを記録します。