Sun Cluster 3.0 12/01 データサービス開発ガイド

付録 B データサービスのコード例

この付録では、データサービスの各メソッドの完全なコード例を示します。また、リソースタイプ登録 (RTR) ファイルの内容も示します。

この付録に含まれるコードリストは、次のとおりです。.

リソースタイプ登録ファイルのリスト

リソースタイプ登録 (RTR) ファイルには、クラスタ管理者がデータサービスを登録するとき、データサービスの初期構成を定義するリソースとリソースタイプのプロパティ宣言が含まれています。


例 B-1 SUNW.Sample RTR ファイル

#
# Copyright (c) 1998-2000 by Sun Microsystems, Inc.
# All rights reserved.
#
#  ドメインネームサービス (DNS) の登録情報
#
 
 
#pragma ident	"@(#)SUNW.sample	1.1	00/05/24 SMI"
 
RESOURCE_TYPE = "sample";
VENDOR_ID = SUNW;
RT_DESCRIPTION = "Domain Name Service on Sun Cluster";
 
RT_VERSION ="1.0"; 
API_VERSION = 2;	 
FAILOVER = TRUE;
 
RT_BASEDIR=/opt/SUNWsample/bin;
PKGLIST = SUNWsample;
 
START						=	 dns_svc_start;
STOP						=	 dns_svc_stop;
 
VALIDATE 							= dns_validate;
UPDATE 							= dns_update;
 
MONITOR_START 			 = dns_monitor_start;
MONITOR_STOP 						= dns_monitor_stop;
MONITOR_CHECK 						= dns_monitor_check;
 
# リソースタイプ宣言の後に、中括弧に囲まれたリソースプロパティ宣言のリスト
# が続く。プロパティ名宣言は、各エントリの左中括弧の直後にある最初
# の属性である必要がある。
#
 
# <method>_timeout プロパティは、RGM がメソッドの呼び出しが失敗
# したという結論を下すまでの時間 (秒) を設定する。
 
# すべてのメソッドタイムアウトの MIN 値は 60 秒に設定されている。こ
# れは、管理者が短すぎる時間を設定することを防ぐためである。短すぎ
# る時間を設定すると、スイッチオーバーやフェイルオーバーの性能が上
# がらず、さらには、予期せぬ RGM アクションが発生する可能性がある
# (間違ったフェイルオーバー、ノードの再起動、リソースグループの 
# ERROR_STOP_FAILED 状態への移行、オペレータの介入の必要性など)。
# メソッドタイムアウトに短すぎる時間を設定すると、データサービス全
# 体の可用性を下げることになる。
{  
	PROPERTY = Start_timeout; 
	MIN=60; 
	DEFAULT=300;
}
 
{
 	 	 	 PROPERTY = Stop_timeout; 
	 	 	 MIN=60; 
		 	 DEFAULT=300;
}
{
        PROPERTY = Validate_timeout;
        MIN=60;
        DEFAULT=300;
}
{
        PROPERTY = Update_timeout;
        MIN=60;
        DEFAULT=300;
}
{
        PROPERTY = Monitor_Start_timeout;
        MIN=60;
        DEFAULT=300;
}
{
        PROPERTY = Monitor_Stop_timeout;
        MIN=60;
        DEFAULT=300;
}
{
        PROPERTY = Thorough_Probe_Interval;
        MIN=1;
        MAX=3600;
        DEFAULT=60;
        TUNABLE = ANYTIME;
}
 
# 当該ノード上でアプリケーションを正常に起動できないと結論を下すま
# でに、ある期間 (Retry_Interval) に行う再試行の回数
{
        PROPERTY = Retry_Count;
        MIN=0;
        MAX=10;
        DEFAULT=2;
        TUNABLE = ANYTIME; 
}
# Retry_Interval には 60 の倍数を設定する。これは、秒から分に変換さ
# れ、端数が切り上げられるためである。たとえば、50 (秒) という値を指
# 定すると、1 分に変換される。
# このプロパティは再試行数 (Retry_Count) のタイミングを決定する。
{
        PROPERTY = Retry_Interval;
        MIN=60;
        MAX=3600;
        DEFAULT=300;
        TUNABLE = ANYTIME;
}
 
{
        PROPERTY = Network_resources_used;
        TUNABLE = AT_CREATION;
        DEFAULT = "";
}
 
#
# 拡張プロパティ
#
# クラスタ管理者はこのプロパティの値を設定して、アプリケーションが使用
# する構成ファイルが入っているディレクトリを示す必要がある。このアプリ
# ケーションの場合、DNS は PXFS (通常は named.conf) 上の DNS 構成ファイ
# ルのパスを指定する。
{
	PROPERTY = Confdir;
	EXTENSION;
	STRING;
	TUNABLE = AT_CREATION;
	DESCRIPTION = "The Configuration Directory Path";
}
 
# 検証が失敗したと宣言するまでのタイムアウト値 (秒) 
{
        PROPERTY = Probe_timeout;
        EXTENSION;
        INT;
        DEFAULT = 30;
        TUNABLE = ANYTIME;
        DESCRIPTION = "Time out value for the probe (seconds)";
}

START メソッドのコードリスト

データサービスリソースを含むリソースグループがクラスタのノード上でオンラインになったとき、あるいは、リソースが有効になったとき、RGM はそのクラスタノード上で START メソッドを呼び出します。サンプルのアプリケーションでは、START メソッドはそのノード上で in.named (DNS) デーモンを起動します。


例 B-2 dns_svc_start メソッド

#!/bin/ksh
#
# HA-DNS の START メソッド
#
# このメソッドは PMF の制御下でデータサービスを起動する。DNS の 
# in.named プロセスを起動する前に、いくつかの妥当性検査を実行する。
#
# データサービスの PMF タグは $RESOURCE_NAME.named である。PMF は、
# 指定された回数 (Retry_count) だけ、サービスを起動しようとする。そ
# して、指定された期間 (Retry_interval) 内で試行回数がこの値を超えた
# 場合、PMF はサービスの起動に失敗したことを報告する。
# Retry_count と Retry_interval は両方とも RTR ファイルに設定されて
# いるリソースプロパティである。
#pragma ident	"@(#)dns_svc_start	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

}




###############################################################################
# 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

# DNS を起動するため、リソースの Confdir プロパティの値を取得する。入
# 力されたリソース名とリソースグループを使用して、リソースを追加するときにクラ
# スタ管理者が設定した Confdir の値を見つける。


config_info=`scha_resource_get -O Extension -R $RESOURCE_NAME
-G $RESOURCEGROUP_NAME Confdir`
# scha_resource_get は拡張プロパティの「タイプ」と「値」を戻す。拡
# 張プロパティの値だけを取得する。
CONFIG_DIR=`echo $config_info | awk `{print $2}'`

# $CONFIG_DIR がアクセス可能であるかどうかを検査する。
if [ ! -d $CONFIG_DIR ]; then
	logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] ¥
	    "${ARGV0} Directory $CONFIG_DIR missing or not mounted"
	exit 1
fi

# データファイルへの相対パス名が存在する場合、$CONFIG_DIR ディレク
# トリに移動する。
cd $CONFIG_DIR

# named.conf ファイルが $CONFIG_DIR ディレクトリ内に存在するかどうか
# を検査する。
if [ ! -s named.conf ]; then
	logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] ¥
	    "${ARGV0} File $CONFIG_DIR/named.conf is missing or
empty"
	exit 1
fi

# RTR ファイルから Retry_count の値を取得する。
RETRY_CNT=`scha_resource_get -O Retry_Count -R $RESOURCE_NAME
-G ¥ $RESOURCEGROUP_NAM�

# RTR ファイルから Retry_interval の値を取得する。この値の単位は秒
# であり、pmfadm に渡すときは分に変換する必要がある。変換時、端数は
# 切り上げられるので注意すること。たとえば、50 秒は 1 分に切り上げられる。

((RETRY_INTRVAL = `scha_resource_get -O Retry_Interval
-R $RESOURCE_NAME -G $RESOURCEGROUP_NAM� / 60))

# PMF の制御下で in.named デーモンを起動する。$RETRY_INTERVAL の期
# 間、$RETRY_COUNT の回数だけ、クラッシュおよび再起動できる。どちら
# かの値以上クラッシュした場合、PMF は再起動をやめる。
# <$PMF_TAG> というタグですでにプロセスが登録されて
# いる場合、PMF はすでにプロセスが動作していることを示す警告メッセ
# ージを送信する。
#
echo "Retry interval is "$RETRY_INTRVAL
pmfadm -c $PMF_TAG.named -n $RETRY_CNT -t $RETRY_INTRVAL ¥
    /usr/sbin/in.named -c named.conf

# HA-DNS が起動していることを示すメッセージを記録する。
if [ $? -eq 0 ]; then
	logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG]¥
    	    "${ARGV0} HA-DNS successfully started"
fi
exit 0
 

STOP メソッドのコードリスト

HA-DNS リソースを含むリソースグループがクラスタノード上でオフラインになるとき、あるいは、HA-DNS リソースが無効になるとき、RGM は STOP メソッドを呼び出します。このメソッドは、そのノード上で in.named (DNS) デーモンを停止します。


例 B-3 dns_svc_stop メソッド

#
# HA-DNS の STOP メソッド
#
# このメソッドは、PMF を使用するデータサービスを停止する。サービス
# が動作していない場合、このメソッドは状態 0 で終了する。その他の値
# は戻さない。リソースは STOP_FAILED 状態になる。
#pragma ident	"@(#)dns_svc_stop	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

}


###############################################################################
# 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

# RTR ファイルから Stop_timeout 値を取得する。
STOP_TIMEOUT=`scha_resource_get -O STOP_TIMEOUT -R $RESOURCE_NAME
-G ¥ $RESOURCEGROUP_NAM�

# PMF 経由で SIGTERM シグナルを使用する規則正しい方法でデータサービ
# スを停止しようとする。SIGTERM がデータサービスを停止できるまで、
# Stop_timeout 値の 80% だけ待つ。停止できない場合、SIGKILL を送信
# して、データサービスを停止しようとする。SIGKILL がデータサービス
# を停止できるまで、Stop_timeout 値の 15% だけ待つ。停止できない場
# 合、メソッドは何か異常があったと判断し、0 以外の状態で終了する。
# Stop_timeout の残りの 5% は他の目的のために予約されている。((SMOOTH_TIMEOUT=$STOP_TIMEOUT * 80/100))

((HARD_TIMEOUT=$STOP_TIMEOUT * 15/100))

# in.named が動作しているかどうかを調べて、動作していれば停止する。
if pmfadm -q $PMF_TAG.named; then 
	# SIGTERM シグナルをデータサービスに送信して、合計タイムアウト値
	# の 80% だけ待つ。
	pmfadm -s $PMF_TAG.named -w $SMOOTH_TIMEOUT TERM
	if [ $? -ne 0 ]; then 
		logger -p ${SYSLOG_FACILITY}.info -t [SYSLOG_TAG] ¥
		    "${ARGV0} Failed to stop HA-DNS with SIGTERM; Retry
with ¥
		     SIGKILL"
		
		# SIGTERM シグナルでデータサービスが停止しないので、今度は
		# SIGKILL を使用して、合計タイムアウト値の 15% だけ待つ。
		pmfadm -s $PMF_TAG.named -w $HARD_TIMEOUT KILL
		if [ $? -ne 0 ]; then
		    logger -p ${SYSLOG_FACILITY}.err -t [SYSLOG_TAG]
¥
		    "${ARGV0} Failed to stop HA-DNS; Exiting UNSUCCESFUL"
		    
		    exit 1
		fi	
fi
else 
	# この時点でデータサービスは動作していない。メッセージを記録して、
	# 成功で終了する。
	logger -p ${SYSLOG_FACILITY}.info -t [SYSLOG_TAG] ¥
    	    "HA-DNS is not started"

	# HA-DNS が動作していない場合でも、成功で終了し、データサービス
	# リソースが STOP_FAILED 状態にならないようにする。

	exit 0

fi

# DNS の停止に成功。メッセージを記録して、成功で終了する。
logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG] ¥
    "HA-DNS successfully stopped"
exit 0

gettime ユーティリティーのコードリスト

gettime ユーティリティーは、検証の再起動間の経過時間を PROBE プログラムが追跡するための C プログラムです。このプログラムは、コンパイル後、コールバックメソッドと同じディレクトリ (RT_basedir プロパティが指すディレクトリ) に格納する必要があります。


例 B-4 gettime.c ユーティリティープログラム

# このユーティリティープログラムは、データサービスの検証メソッドによ
# って使用され、既知の参照ポイント (基準点) からの経過時間 (秒) を
# 追跡する。このプログラムは、コンパイル後、データサービスのコール
# バックメソッドと同じディレクトリ (RT_basedir) に格納しておくこと。
#pragma ident	"@(#)gettime.c	1.1	00/05/24 SMI"

#include <stdio.h>
#include <sys/types.h>
#include <time.h>

main()
{
    printf("%d¥n", time(0));
    exit(0);
}

PROBE プログラムのコードリスト

PROBE プログラムは、nslookup(1M) コマンドを使用して、データサービスの可用性を検査します。このプログラムは、MONITOR_START コールバックメソッドによって起動され、MONITOR_STOP コールバックメソッドによって停止されます。


例 B-5 dns_probe プログラム

#!/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

MONITOR_START メソッドのコードリスト

このメソッドは、データサービスの PROBE プログラムを起動します。


例 B-6 dns_monitor_start メソッド

#!/bin/ksh
#
# HA-DNS の Monitor_Start メソッド
#
# このメソッドは、PMF の制御下でデータサービスのモニター (検証) を
# 起動する。モニターは一定の間隔でデータサービスを検証するプロセス
# で、問題が発生すると、データサービスを同じノード上で再起動するか、
# クラスタ内の別のノードにフェイルオーバーする。モニター用の PMF 
# タグは $RESOURCE_NAME.monitor。

#pragma ident	"@(#)dns_monitor_start	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

}



###############################################################################
# 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.monitor
SYSLOG_TAG=$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME

# データサービスの RT_BASEDIR プロパティを取得することによって、検
# 証メソッドが存在する場所を見つける。
RT_BASEDIR=`scha_resource_get -O RT_BASEDIR -R $RESOURCE_NAME
-G ¥$RESOURCEGROUP_NAM�

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

# HA-DNS のモニターが起動されたことを示すメッセージを記録する。
started.
if [ $? -eq 0 ]; then
	logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG] ¥
    	    "${ARGV0} Monitor for HA-DNS successfully started"
fi
exit 0
 

MONITOR_STOP メソッドのコードリスト

このメソッドは、データサービスの PROBE プログラムを停止します。


例 B-7 dns_monitor_stop メソッド

#!/bin/ksh
#
# HA-DNS の Monitor_Stop メソッド
#
# PMF を使用して動作しているモニターを停止する。

#pragma ident	"@(#)dns_monitor_stop	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

}


###############################################################################
# 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.monitor
SYSLOG_TAG=$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME

# モニターが動作しているかどうかを調べて、動作していれば停止する。
if pmfadm -q $PMF_TAG.monitor; then 
	pmfadm -s $PMF_TAG.monitor 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}.info -t [$SYSLOG_TAG]¥
		    "${ARGV0} Monitor for resource " $RESOURCE_NAME
¥
		    " successfully stopped"
	fi
fi

exit 0

MONITOR_CHECK メソッドのコードリスト

このメソッドは、Confdir プロパティが示すディレクトリの存在を確認します。PROBE メソッドがデータサービスを新しいノードにフェイルオーバーするとき、RGM は MONITOR_CHECK を呼び出し、また、潜在マスターであるノードを検査します。


例 B-8 dns_monitor_check メソッド

#!/bin/ksh
#
# DNS の Monitor_check メソッド
#
# 障害モニターがデータサービスを新しいノードにフェイルオーバーするとき、RGM はこのメソッドを
# 呼び出す。Monitor_check は VALIDATE メソッドを呼び出して、新しいノード上で構成ディレク
# トリおよびファイルが利用できるかどうかを確認する。

#pragma ident	"@(#)dns_monitor_check 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

}

###############################################################################
# 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

# リソースタイプの 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 は、拡張プロパティの値とともにタイプも戻す。awk を使用して、
# 拡張プロパティの値だけを取得する。
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

# モニター検査が成功したことを示すメッセージを記録する。
if [ $? -eq 0 ]; then
	logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG] ¥
		"${ARGV0} Monitor check for DNS successful."
	exit 0
else
	logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] ¥
		"${ARGV0} Monitor check for DNS not successful."
	exit 1
fi

VALIDATE メソッドのコードリスト

このメソッドは、Confdir プロパティが示すディレクトリの存在を確認します。RGM がこのメソッドを呼び出すのは、クラスタ管理者がデータサービスを作成したときと、データサービスのプロパティを更新したときです。障害モニターがデータサービスを新しいノードにフェイルオーバーしたときは、MONITOR_CHECK メソッドは常にこのメソッドを呼び出します。


例 B-9 dns_validate メソッド

#!/bin/ksh
#
# HA-DNS の Validate メソッド
#
# このメソッドは、リソースの Confdir プロパティを妥当性検査する。
# Validate メソッドが呼び出されるのは、リソースが作成されたときと、リソース
# プロパティが更新されたときの 2 つである。リソースが作成されたとき、
# Validate メソッドは -c フラグで呼び出され、すべてのシステム定義プ
# ロパティと拡張プロパティがコマンド行引数として渡される。リソースプロ
# パティが更新されたとき、Validate メソッドは -u フラグで呼び出され、
# 更新されるプロパティのプロパティ/値のペアだけがコマンド行引数とし
# て渡される。
#
# 例: リソースが作成されたとき、コマンド行引数は次のようになる。
#   
# dns_validate -c -R <..> -G <...> -T <..>
-r <sysdef-prop=value>... 
#       -x <extension-prop=value>.... -g <resourcegroup-prop=value>....
#
# 例: リソースプロパティが更新されたとき、コマンド行引数は次のようになる。
#
# dns_validate -u -R <..> -G <...> -T <..>
-r <sys-prop_being_updated=value>
#   または
# dns_validate -u -R <..> -G <...> -T <..>
-x <extn-prop_being_updated=value>
#

#pragma ident	"@(#)dns_validate	1.1	00/05/24 SMI"

###############################################################################
# プログラム引数を構文解析する。
#
function parse_args # [args ...]
{
	typeset opt

	while getopts `cur:x:g:R:T:G:' opt
	do
                case "$opt" in
                R)
                        # DNS リソースの名前
                        RESOURCE_NAME=$OPTARG
                        ;;
                G)
                        # リソースが構成されているリソース
                        # グループの名前
                        RESOURCEGROUP_NAME=$OPTARG
                        ;;
                T)
                        # リソースタイプの名前
                        RESOURCETYPE_NAME=$OPTARG
                        ;;

                r)      
			# メソッドはシステム定義プロパティにアクセスして
			# いない。したがって、このフラグは動作なし。
                        ;;

                g)
			# メソッドはリソースグループプロパティにアクセスして
			# いない。したがって、このフラグは動作なし。
                        ;;

                c)
			# Validate メソッドがリソースの作成中に呼び出されてい
			# ることを示す。したがって、このフラグは動作なし。
                        ;;

                u)
			# リソースがすでに存在しているときは、プロパティの更新
			# を示す。Confdir プロパティを更新する場合、Confdir 
			# がコマンド行引数に現れるはずである。現れない場合、
			# メソッドは scha_resource_get を使用して Confdir 
			# を探す必要がある。
			UPDATE_PROPERTY=1
                        ;;

                x)
			# 拡張プロパティのリスト。プロパティと値のペア。区
			# 切り文字は「=」
			PROPERTY=`echo $OPTARG | awk -F= `{print $1}'`
			VAL=`echo $OPTARG | awk -F= `{print $2}'`

			# Confdir 拡張プロパティがコマンド行上に存在する場
			# 合、その値を記録する。
			if [ $PROPERTY == "Confdir" ]; then
				CONFDIR=$VAL
				CONFDIR_FOUND=1
			fi
                        ;;

                *)
                    logger -p ${SYSLOG_FACILITY}.err ¥
                    -t [$SYSLOG_TAG] ¥
                    "ERROR: Option $OPTARG unknown"
                     exit 1
                     ;;

                esac
	done
}

###############################################################################
# MAIN
#
##############################################################################

export PATH=/bin:/usr/bin:/usr/cluster/bin:/usr/sbin:/usr/proc/bin:$PATH

# メッセージの記録に使用する syslog 機能番号を取得する。
SYSLOG_FACILITY=`scha_cluster_get -O SYSLOG_FACILITY`

# CONFDIR の値を NULL に設定する。この後、このメソッドは Confdir プロパ
# ティの値を、コマンド行から取得するか、scha_resource_get を使
# 用して取得する。
CONFDIR=""
UPDATE_PROPERTY=0
CONFDIR_FOUND=0

# このメソッドに渡された引数を構文解析する。
parse_args "$@"

# プロパティの更新の結果として呼び出されている場合、Validate メソッ
# ドはコマンド行から Confdir 拡張プロパティの値を取得する。そうでな
# い場合、scha_resource_get を使用して Confdir の値を取得する。

if ( (( $UPDATE_PROPERTY == 1 )) &&  (( CONFDIR_FOUND
== 0 )) ); then
	config_info=`scha_resource_get -O Extension -R $RESOURCE_NAME
¥
	    -G $RESOURCEGROUP_NAME Confdir`
	CONFDIR=`echo $config_info | awk `{print $2}'`
fi

# Confdir プロパティが値を持っているかどうかを確認する。持っていな
# い場合、状態 1 (失敗) で終了する。
if [[ -z $CONFDIR ]]; then
	logger -p ${SYSLOG_FACILITY}.err ¥
	    "${ARGV0} Validate method for resource "$RESOURCE_NAME " failed"
	exit 1
fi

# 実際の Confdir プロパティ値の妥当性検査はここから始まる。

# $CONFDIR がアクセス可能であるかどうかを検査する。
if [ ! -d $CONFDIR ]; then
        logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG]¥
            "${ARGV0} Directory $CONFDIR missing or not
mounted"
        exit 1
fi

# named.conf ファイルが Confdir ディレクトリ内に存在するかどうかを
# 検査する。
if [ ! -s $CONFDIR/named.conf ]; then
        logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG]
¥
            "${ARGV0} File $CONFDIR/named.conf is missing
or empty"
        exit 1
fi

# Validate メソッドが成功したことを示すメッセージを記録する。
logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG] ¥
   "${ARGV0} Validate method for resource "$RESOURCE_NAME
¥
   " completed successfully"

exit 0

UPDATE メソッドのコードリスト

RGM は、UPDATE メソッドを呼び出して、プロパティが変更されたことを実行中のリソースに通知します。


例 B-10 dns_update メソッド

#!/bin/ksh
#
# HA-DNS の Update メソッド
#
# 実際のプロパティの更新は RGM が行う。更新の影響を受けるのは障害モ
# ニターだけである。したがって、このメソッドは障害モニターを再起動
# する必要がある。

#pragma ident	"@(#)dns_update	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

}




###############################################################################
# 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.monitor
SYSLOG_TAG=$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME

# リソースの RT_BASEDIR プロパティを取得することによって、検証メソッド
# が存在する場所を見つける。
RT_BASEDIR=`scha_resource_get -O RT_BASEDIR -R $RESOURCE_NAME
-G $RESOURCEGROUP_NAM�

# Update メソッドが呼び出されると、RGM は更新されるプロパティの値を
# 更新する。このメソッドは、障害モニター (検証メソッド) が動作し
# ているかどうかを検査し、動作している場合は強制終了し、再起動
# する必要がある。
if pmfadm -q $PMF_TAG.monitor; then

	# すでに動作している障害モニターを強制終了する。
        pmfadm -s $PMF_TAG.monitor TERM
        if [ $? -ne 0 ]; then
                logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG]
¥
                    "${ARGV0} Could not stop the monitor"
                exit 1
        else
                # DNS の停止に成功。メッセージを記録する。
                logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG]
¥
                    "Monitor for HA-DNS successfully stopped"
        fi

	# モニターを再起動する。
	pmfadm -c $PMF_TAG.monitor -n -1 -t -1 $RT_BASEDIR/dns_probe ¥
	   -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME -T $RESOURCETYPE_NAME
	if [ $? -ne 0 ]; then
	    	logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG]¥
    	    	    "${ARGV0} Could not restart monitor for HA-DNS "
		exit 1
	else
		logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG]¥
                    "Monitor for HA-DNS successfully restarted"

	fi
fi
exit 0