PROBE プログラムは、nslookup コマンドを使用して、データサービスの可用性を検査します (nslookup(1M) のマニュアルページを参照)。このプログラムは Monitor_start コールバックメソッドによって起動され、Monitor_stop コールバックメソッドによって停止されます。
#!/bin/ksh #pragma ident “@(#)dns_probe 1.1 00/04/19 SMI” # # HA-DNS の Probe メソッド # # このプログラムは、nslookup を使用して、データサービスの可用性を検査 # する。nslookup は DNS サーバーに照会することによって、DNS # サーバー自身を探す。サーバーが応答しない場合、あるいは、別のサー # バーが照会に応答した場合、probe メソッドはデータサービスまたはク # ラスタ内の別のノードになんらかの問題が発生したという結論を下す。 # 検証は、RTR ファイルの THOROUGH_PROBE_INTERVAL で設定さ # れた間隔で行われる。 #pragma ident “@(#)dns_probe 1.1 00/05/24 SMI” ############################################################################### # プログラム引数を構文解析する。 function parse_args # [args ...] { typeset opt while getopts `R:G:T:' opt do case “$opt” in R) # DNS リソースの名前。 RESOURCE_NAME=$OPTARG ;; G) # リソースが構成されているリソース # グループの名前。 RESOURCEGROUP_NAME=$OPTARG ;; T) # リソースタイプの名前。 RESOURCETYPE_NAME=$OPTARG ;; *) logger -p ${SYSLOG_FACILITY}.err \ -t [$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME] \ “ERROR: Option $OPTARG unknown” exit 1 ;; esac done } ############################################################################### # restart_service () # # この関数は、まずデータサービスの Stop メソッドを呼び出し、 # 次に Start メソッドを呼び出すことによって、データサービスを再起動 # しようとする。データサービスがすでに起動しておらず、 # データサービスのタグが PMF に登録されていない場合、 # この関数はデータサービスをクラスタ内の # 別のノードにフェイルオーバーする。 # 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 } ############################################################################### # decide_restart_or_failover () # # この関数は、検証が失敗したときに行うべきアクション、つまり、デー # タサービスをローカルで再起動するか、クラスタ内の別のノードに # フェイルオーバーするかを決定する。 # function decide_restart_or_failover { # 最初の再起動の試行であるかどうかを検査する。 if [ $retries -eq 0 ]; then # 最初の失敗である。 # 最初の試行の時刻を記録する。 start_time=`$RT_BASEDIR/gettimè retries=`expr $retries + 1` # 最初の失敗であるので、データサービスを # 再起動しようと試行する。 restart_service if [ $? -ne 0 ]; then logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \ “${ARGV0} Failed to restart data service.” exit 1 fi else # 最初の失敗ではない。 current_time=`$RT_BASEDIR/gettimè time_diff=`expr $current_time - $start_timè if [ $time_diff -ge $RETRY_INTERVAL ]; then # この失敗は再試行最大期間後に発生した。 # したがって、再試行カウンタをリセットし、 # 再試行時間をリセットし、さらに再試行する。 retries=1 start_time=$current_time # 前回の失敗が Retry_interval よりも以前に発生しているので、 # データサービスを再起動しようと試行する。 restart_service if [ $? -ne 0 ]; then logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG \ “${ARGV0} Failed to restart HA-DNS.” exit 1 fi elif [ $retries -ge $RETRY_COUNT ]; then # 再試行最大期間内であり、再試行カウンタは満了 # している。したがって、フェイルオーバーする。 retries=0 scha_control -O GIVEOVER -G $RESOURCEGROUP_NAME \ -R $RESOURCE_NAME if [ $? -ne 0 ]; then logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \ “${ARGV0} Failover attempt failed.” exit 1 fi else # 再試行最大期間内であり、再試行カウンタは満了 # していない。したがって、さらに再試行する。 retries=`expr $retries + 1` restart_service if [ $? -ne 0 ]; then logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \ “${ARGV0} Failed to restart HA-DNS.” exit 1 fi fi fi } ############################################################################### # MAIN ############################################################################### export PATH=/bin:/usr/bin:/usr/cluster/bin:/usr/sbin:/usr/proc/bin:$PATH # メッセージの記録に使用する syslog 機能番号を取得する。 SYSLOG_FACILITY=`scha_cluster_get -O SYSLOG_FACILITY` # このメソッドに渡された引数を構文解析する。 parse_args “$@” PMF_TAG=$RESOURCE_NAME.named SYSLOG_TAG=$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME # 証が行われる間隔はシステム定義プロパティー THOROUGH_PROBE_INTERVAL # に設定されている。scha_resource_get でこのプロパティーの値を取得する。 PROBE_INTERVAL=scha_resource_get -O THOROUGH_PROBE_INTERVAL \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ # 検証用のタイムアウト値を取得する。この値は RTR ファイルの # PROBE_TIMEOUT 拡張プロパティーに設定されている。nslookup のデフォル # トのタイムアウトは 1.5 分。 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}'` # リソースの NETWORK_RESOURCES_USED プロパティーの値を取得して、 # DNS がサービスを提供するサーバーを見つける。 DNS_HOST=`scha_resource_get -O NETWORK_RESOURCES_USED -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAMÈ # システム定義プロパティー Retry_count から再試行最大回数を取得する。 RETRY_COUNT =`scha_resource_get -O RETRY_COUNT -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAMÈ # システム定義プロパティー Retry_interval から再試行最大期間を取得する。 Retry_interval RETRY_INTERVAL=scha_resource_get -O RETRY_INTERVAL -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAMÈ # リソースタイプの RT_basedir プロパティーから gettime ユーティリティーの # 完全パスを取得する。 RT_BASEDIR=scha_resource_get -O RT_basedir -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAMÈ # 検証は無限ループで動作し、nslookup コマンドを実行し続ける。 # nslookup 応答用の一時ファイルを設定する。 DNSPROBEFILE=/tmp/.$RESOURCE_NAME.probe probefail=0 retries=0 while : do # 検証が動作すべき期間は <THOROUGH_PROBE_INTERVAL> プロパティーに指 # 定されている。したがって、THOROUGH_PROBE_INTERVAL の間、検証 # プログラムが休眠するように設定する。 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 への応答が HA-DNS サーバーから来ており、 # /etc/resolv.conf ファイル内に指定されているほかのネームサーバー # から来ていないことを確認する。 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 コマンドがタイム # アウトしたか、あるいは、別のサーバー (/etc/resolv.conf ファイ # ルに指定されている) から照会への応答が来ていることを示す。 # どちらの場合でも、DNS サーバーは応答していないので、 # このメソッドは decide_restart_or_failover を呼び出して、 # データサービスをローカルで起動するか、あるいは、別のノードに # フェイルオーバーするかを評価する。 if [ $probefail -ne 0 ]; then decide_restart_or_failover else logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG] \ “${ARGV0} Probe for resource HA-DNS successful” fi done |