PROBE プログラムは、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
|