本章介绍 in.named 应用程序的一个 Sun Cluster 数据服务样例 HA-DNS。in.named 守护进程是域名服务 (DNS) 的 Solaris 实现。数据服务样例说明了如何使用资源管理 API 使应用程序具有高可用性。
资源管理 API 支持 shell 脚本接口和 C 程序接口。本章中的应用程序样例是使用 shell 脚本接口编写的。
本章包括以下主题:
数据服务样例在群集节点之间启动、停止、重新启动和切换 DNS 应用程序以便对群集事件(例如管理操作、应用程序故障或节点故障)做出响应。
应用程序的重启操作由进程监视工具 (PMF) 管理。如果失败的应用程序数超过了故障次数窗口中的故障计数,故障监视器会将包含应用程序资源的资源组故障转移到另一个节点上。
数据服务样例以 PROBE 方法的形式提供故障监视,该方法使用 nslookup 命令来确保应用程序正常运行。如果探测检测到挂起的 DNS 服务,它将通过在本地重新启动 DNS 应用程序来尝试改正这种情形。如果本地重新启动 DNS 应用程序没有改进该情况,并且探测重复检测到服务所出现的问题,则探测将尝试把服务故障转移到群集中的另一个节点上。
特别指出,数据服务样例包括以下元素:
用于定义数据服务的静态属性的资源类型注册文件。
通过 RGM 运行的 Start 回调方法,用来在包含 HA-DAS 数据服务的资源组联机时启动 in.named 守护进程。
通过 RGM 运行的 Stop 回调方法,用来在包含 HA-DNS 的资源组脱机时停止 in.named 守护进程。
用于通过检验 DNS 服务器是否正在运行来检查服务的可用性的故障监视器。故障监视器通过用户定义的 PROBE 方法实现,并通过 Monitor_start 和 Monitor_stop 回调方法启动和停止。
通过 RGM 运行的 Validate 回调方法,用于验证服务的配置目录是否可访问。
通过 RGM 运行的 Update 回调方法,用来在群集管理员更改资源属性值时重新启动故障监视器。
本实例中的资源类型注册 (RTR) 文件中定义了 DNS 资源类型的静态配置。该类型的资源继承 RTR 文件中定义的属性。
资源组管理器 (RGM) 在群集管理员注册 HA-DNS 数据服务时读取 RTR 文件中的信息。
RTR 文件采用定义好的格式。在文件中将依次定义资源类型属性、系统定义的资源属性和扩展属性。有关更多信息,请参见 rt_reg(4) 手册页和设置资源和资源类型属性。
以下各节介绍了样例 RTR 文件中的特定属性。其中列出了该文件的不同部分。有关样例 RTR 文件内容的完整列表,请参见资源类型注册文件列表。
RTR 文件样例的开头部分是注释,其后跟有用来定义 HA-DNS 配置的资源类型属性,如下所示。
资源组、资源和资源类型的属性名称不区分大小写。在指定属性名称时,您可以使用大小写字母的任意组合。
# # Copyright (c) 1998-2005 by Sun Microsystems, Inc. # All rights reserved. # # Registration information for Domain Name Service (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;
您必须将 Resource_type 属性声明为 RTR 文件中的第一项。否则,资源类型注册将失败。
以下信息介绍了这些属性:
可以只通过 Resource_type 属性来指定资源类型名称 (sample),或通过使用 vendor-id 作为前缀,后跟一个句点 (.),后面加上资源类型属性来指定资源类型名称 (SUNW.sample)。
指定 vendor-id 时,使用用于定义资源类型的公司证券交易符号。在群集中资源类型的名称必须唯一。
RT_version 属性用于将数据服务样例的版本标识为供应商指定的版本。
API_version 属性用于标识 Sun Cluster 的版本。例如,API_version = 2 表明数据服务可以在从 Sun Cluster 3.0 开始的 Sun Cluster 的所有版本上运行;API_version = 5 表明数据服务可以安装在从 Sun Cluster 3.1 9/04 开始的 Sun Cluster 的所有版本上。但是,API_version = 5 还表明数据服务无法安装在 Sun Cluster 3.1 9/04 发行之前的 Sun Cluster 的所有版本上。有关该属性的详细信息,请参见资源类型属性中有关 API_version 条目下的内容。
Failover = TRUE 表示数据服务无法在可以在多个节点上同时联机的资源组中运行。
RT_basedir 指向 /opt/SUNWsample/bin,将其作为完善相关路径(例如回调方法路径)的目录路径。
Start、Stop 和 Validate 提供了通过 RGM 运行的回调方法程序的相应路径。这些路径是 RT_basedir 所指定的目录的相对路径。
Pkglist 将 SUNWsample 标识为包含数据服务样例安装的软件包。
在此 RTR 文件中没有指定的资源类型属性(例如 Single_instance、Init_nodes 和 Installed_nodes 被设置为其默认值。资源类型属性包含资源类型属性(包括其默认值)的完整列表。
群集管理员不能更改 RTR 文件中资源类型属性的值。
根据约定,在 RTR 文件中的资源类型属性之后声明资源属性。资源属性包括由 Sun Cluster 软件提供的系统定义的属性以及您定义的扩展属性。您可以为每一种类型指定许多属性的属性,它们由 Sun Cluster 软件提供,例如最小值、最大值和默认值。
以下列表显示了某个样例 RTR 文件中系统定义的属性。
# A list of bracketed resource property declarations follows the # resource type declarations. The property-name declaration must be # the first attribute after the open curly bracket of each entry. # The <method>_timeout properties set the value in seconds after which # the RGM concludes invocation of the method has failed. # The MIN value for all method timeouts is set to 60 seconds. This # prevents administrators from setting shorter timeouts, which do not # improve switchover/failover performance, and can lead to undesired # RGM actions (false failovers, node reboot, or moving the resource group # to ERROR_STOP_FAILED state, requiring operator intervention). Setting # too-short method timeouts leads to a *decrease* in overall availability # of the data service. { 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; } # The number of retries to be done within a certain period before concluding # that the application cannot be successfully started on this node. { PROPERTY = Retry_count; MIN=0; MAX=10; DEFAULT=2; TUNABLE = ANYTIME; } # Set Retry_interval as a multiple of 60 since it is converted from seconds # to minutes, rounding up. For example, a value of 50 (seconds) # is converted to 1 minute. Use this property to time the number of # retries (Retry_count). { PROPERTY = Retry_interval; MIN=60; MAX=3600; DEFAULT=300; TUNABLE = ANYTIME; } { PROPERTY = Network_resources_used; TUNABLE = AT_CREATION; DEFAULT = ““; }
尽管 Sun Cluster 软件提供了系统定义的属性,您也可以使用资源属性的属性设置不同的默认值。有关您可用来应用到资源属性中的属性的完整列表,请参见资源特性属性。
有关样例 RTR 文件中系统定义的资源属性,请注意以下几点:
对于所有超时,Sun Cluster 给出了最小值(1 秒钟)和默认值(3600 秒,或 1 小时)。样例 RTR 文件将最小超时值更改为 60 秒,将默认值更改为 300 秒。群集管理员可以接受此默认值,或将超时值更改为其他值,60 秒或更大值。Sun Cluster 没有最大值上限。
属性 Thorough_probe_interval、Retry_count 和 Retry_interval 的 TUNABLE 属性被设置为 ANYTIME。这些设置表示群集管理员可以更改这些属性的值,即使数据服务正在运行。这些属性由通过数据服务样例实现的故障监视器使用。数据服务样例将实现 Update 方法,以在通过管理操作更改这些或其它资源属性后停止和重启故障监视器。请参见Update 方法的工作方式。
资源属性按以下分类:
必需。创建资源时,群集管理员必须指定一个值。
可选。如果群集管理员没有指定值,系统将提供默认值。
条件。只有在 RTR 文件中声明后,RGM 才能创建属性。
数据服务样例的故障监视器使用 Thorough_probe_interval、Retry_count、Retry_interval 和 Network_resources_used 条件属性,因此需要在 RTR 文件中对它们进行声明。有关如何给属性分类的信息,请参见 r_properties(5) 手册页或资源属性。
# Extension Properties # The cluster administrator must set the value of this property to point to the # directory that contains the configuration files used by the application. # For this application, DNS, specify the path of the DNS configuration file on # PXFS (typically named.conf). { PROPERTY = Confdir; EXTENSION; STRING; TUNABLE = AT_CREATION; DESCRIPTION = “The Configuration Directory Path”; } # Time out value in seconds before declaring the probe as failed. { PROPERTY = Probe_timeout; EXTENSION; INT; DEFAULT = 120; TUNABLE = ANYTIME; DESCRIPTION = “Time out value for the probe (seconds)”; }
样例 RTR 文件定义两种扩展属性,Confdir 和 Probe_timeout。Confdir 属性指定 DNS 配置目录的路径。该目录包含 DNS 正常操作所需的 in.named 文件。数据服务样例的 Start 和 Validate 方法使用该属性验证启动 DNS 之前配置目录和 in.named 文件是否可访问。
配置数据服务之后,Validate 方法将检验新目录是否可以访问。
数据服务样例的 PROBE 方法不是 Sun Cluster 回调方法,而是用户定义的方法。因此,Sun Cluster 没有为其提供 Probe_timeout 属性。要使群集管理员可以配置 Probe_timeout 值,需要在 RTR 文件中定义扩展属性。
shell 脚本中的第一行必须用来标识命令解释程序。数据服务样例中的每个方法脚本都可以标识命令解释程序,如下所示:
#!/bin/ksh
应用程序样例中的所有方法脚本都将导出 Sun Cluster 二进制数据和库的路径,而不依赖用户的 PATH 设置。
####################################################################### # MAIN ####################################################################### export PATH=/bin:/usr/bin:/usr/cluster/bin:/usr/sbin:/usr/proc/bin:$PATH
所有方法脚本(除了 Validate)都使用 pmfadm来启动或停止数据服务或监视器,并传递资源名称。每个脚本都定义一个 PMF_TAG 变量,该变量可以传递至 pmfadm 以标识数据服务或监视器。
同样地,每个方法脚本都使用 logger 命令将消息记录到系统日志中。每个脚本都定义一个 SYSLOG_TAG 变量,该变量可以和 -t 选项一起传递至 logger,以标识正在为其记录消息的资源的资源类型、资源名称和资源组。
所有方法都以同一种方式定义 SYSLOG_TAG,如以下样例代码所示。dns_probe、dns_svc_start、dns_svc_stop 和 dns_monitor_check 方法按如下所示定义 PMF_TAG(pmfadm 和 logger 的用法来自 dns_svc_stop 方法)。
######################################################################### # MAIN ######################################################################### PMF_TAG=$RESOURCE_NAME.named SYSLOG_TAG=$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME # Send a SIGTERM signal to the data service and wait for 80% of the # total timeout value. 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”
dns_monitor_start、dns_monitor_stop 和 dns_update 方法按以下方式定义 PMF_TAG(pmfadm 的用法来自 dns_monitor_stop 方法):
##################################################################### # MAIN ##################################################################### PMF_TAG=$RESOURCE_NAME.monitor SYSLOG_TAG=$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME ... # See if the monitor is running, and if so, kill it. if pmfadm -q $PMF_TAG.monitor; then pmfadm -s $PMF_TAG.monitor KILL
RGM 运行所有的回调方法(除了 Validate),如下所示:
method-name -R resource-name -T resource-type-name -G resource-group-name
方法名是实现回调方法的程序的路径名。数据服务指定 RTR 文件中各个方法的路径名。这些路径名与 RT_basedir 属性(也在 RTR 文件中)指定的目录有关。例如,在数据服务样例的 RTR 文件中,基目录和方法名按以下方式指定:
RT_basedir=/opt/SUNWsample/bin; Start = dns_svc_start; Stop = dns_svc_stop; ...
所有回调方法参数都将作为带标志的值传递。参数 -R 表示资源实例的名称。参数 -T 表示资源的类型。参数 -G 表示资源配置到的组。有关回调方法的更多信息,请参见 rt_callbacks(1HA) 手册页。
Validate 方法与其他参数(即,在其上调用该方法的资源和资源组的属性值)一起调用。有关更多信息,请参见处理属性更新。
每个回调方法都需要一个函数来解析传递该函数的参数。因为所有回调方法都传送相同的参数,所以数据服务提供了一个用于应用程序中所有回调方法的分析函数。
以下样例显示了样例应用程序中的回调方法所使用的 parse_args() 函数。
######################################################################### # Parse program arguments. # function parse_args # [args ...] { typeset opt while getopts 'R:G:T:' opt do case "$opt" in R) # Name of the DNS resource. RESOURCE_NAME=$OPTARG ;; G) # Name of the resource group in which the resource is # configured. RESOURCEGROUP_NAME=$OPTARG ;; T) # Name of the resource type. RESOURCETYPE_NAME=$OPTARG ;; *) logger -p ${SYSLOG_FACILITY}.err \ -t [$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME] \ "ERROR: Option $OPTARG unknown" exit 1 ;; esac done }
虽然应用程序样例中的 PROBE 方法是用户定义的(不是 Sun Cluster 回调方法),但是也使用与调用回调方法相同的变量来调用该方法。因此,该方法包含一个与另一个回调方法使用的解析函数相同的解析函数。
分析函数在 MAIN 中调用,如下所示:
parse_args “$@”
回调方法应使用 syslog() 函数将错误消息输出到最终用户。数据服务样例中的所有回调方法都使用 scha_cluster_get 命令检索用于群集日志的 syslog() 函数的数目,如下所示:
SYSLOG_FACILITY=`scha_cluster_get -O SYSLOG_FACILITY`
该值存储在 shell 变量 SYSLOG_FACILITY 中,可以用作 logger 命令在群集日志中记录消息的工具。例如,数据服务样例中的 Start 方法检索 syslog() 函数并记录已启动数据服务的消息,如下所示:
SYSLOG_FACILITY=`scha_cluster_get -O SYSLOG_FACILITY` ... if [ $? -eq 0 ]; then logger -p ${SYSLOG_FACILITY}.err \ -t [$SYSLOG_TAG] \ "${ARGV0} HA-DNS successfully started" fi
有关更多信息,请参见 scha_cluster_get(1HA) 手册页。
大多数回调方法需要获取有关数据服务的资源和资源类型属性的信息。为实现此操作,API 提供了 scha_resource_get() 函数。
系统定义的属性和扩展属性都可用。系统定义的属性是预定义的。由您在 RTR 文件中定义扩展属性。
当使用 scha_resource_get() 获取系统定义的属性的值时,使用 -O 选项指定属性的名称。命令仅返回该属性的值。例如,在数据服务样例中,Monitor_start 方法需要找到探测程序,这样才能启动该程序。该探测程序位于数据服务的基目录中,由 RT_basedir 属性指向该基目录。Monitor_start 方法检索 RT_basedir 的值并将其放到 RT_BASEDIR 变量中,如下所示:
RT_BASEDIR=`scha_resource_get -O RT_basedir -R $RESOURCE_NAME -G \ $RESOURCEGROUP_NAME`
对于扩展属性,必须使用 -O 选项指定某属性为扩展属性。您还必须提供属性的名称,将其作为最后一个参数。对于扩展属性,命令将同时返回属性的类型和值。例如,在数据服务样例中,探测程序检索 Probe_timeout 扩展属性的类型和值并使用 awk 命令将值仅放于 PROBE_TIMEOUT shell 变量中,如下所示:
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}'`
数据服务必须提供 Start 或 Prenet_start 方法以在群集中激活应用程序守护进程,还必须提供 Stop 或 Postnet_stop 方法以在群集中停止应用程序守护进程。数据服务样例中实现了 Start 和 Stop 方法。有关何时改为使用 Prenet_start 和 Postnet_stop 的信息,请参见确定使用哪种 Start 或 Stop 方法。
当包含数据服务资源的资源组在某节点上进入联机状态或该资源组已联机并启用了该资源时,RGM 将在该群集节点上运行 Start 方法。在样例应用程序中,Start 方法在该节点上激活 in.named DNS 守护进程。
本小节介绍了应用程序样例中的 Start 方法的重要方面,本节没有介绍所有回调方法通用的功能,例如 parse_args() 函数。本节也没有介绍 syslog() 函数的使用。通用功能在为所有方法提供通用功能中进行介绍。
有关 Start 方法的完整列表,请参见Start 方法代码列表。
在尝试启动 DNS 之前,数据服务样例中的 Start 方法将验证是否可以访问配置目录和配置文件 (named.conf) 以及该目录和文件是否可用。named.conf 中的信息对 DNS 的成功操作是必需的。
该回调方法使用 PMF (pmfadm) 启动 DNS 守护进程 (in.named)。如果 DNS 崩溃或无法启动,则 PMF 将在指定的时间间隔内尝试按指定的次数启动 DNS 守护进程。重试的次数和时间间隔都是由数据服务的 RTR 文件中的属性指定的。
要进行操作,DNS 需要位于配置目录下的 named.conf 文件中的信息。因此,Start 方法在尝试启动 DNS 之前,将执行一些完整性检查,以验证目录和文件是否可访问。
Confdir 扩展属性提供了指向配置目录的路径。属性本身是在 RTR 文件中定义的,但是,群集管理员在配置数据服务时需指定实际位置。
在数据服务样例中,Start 方法通过使用 scha_resource_get() 函数检索配置目录的位置。
因为 Confdir 是扩展属性,所以 scha_resource_get() 将同时返回类型和值。awk 命令仅检索值并将该值放入 shell 变量 CONFIG_DIR 中。
# find the value of Confdir set by the cluster administrator at the time of # adding the resource. config_info=`scha_resource_get -O Extension -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAME Confdir` # scha_resource_get returns the "type" as well as the "value" for the # extension properties. Get only the value of the extension property CONFIG_DIR=`echo $config_info | awk '{print $2}'`
Start 方法使用 CONFIG_DIR 的值来验证目录是否可访问。如果该目录不可访问,则 Start 将记录一条错误消息,并在出错状态下退出。请参见Start 退出状态。
# Check if $CONFIG_DIR is accessible. if [ ! -d $CONFIG_DIR ]; then logger -p ${SYSLOG_FACILITY}.err \ -t [$SYSLOG_TAG] \ "${ARGV0} Directory $CONFIG_DIR is missing or not mounted" exit 1 fi
在启动应用程序守护进程之前,此方法将执行 final 检查,以检验 named.conf 文件是否存在。如果该文件不存在,则 Start 将记录一条错误消息,并在出错状态下退出。
# Change to the $CONFIG_DIR directory in case there are relative # pathnames in the data files. cd $CONFIG_DIR # Check that the named.conf file is present in the $CONFIG_DIR directory 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
该方法使用进程管理器工具 (pmfadm) 来启动应用程序。使用 pmfadm 命令,可以设置在指定时间范围内尝试重新启动应用程序的次数。RTR 文件包含两种属性:Retry_count 指定尝试重新启动应用程序的次数,Retry_interval 指定执行此操作的时间间隔。
Start 方法使用 scha_resource_get() 函数检索 Retry_count 和 Retry_interval 的值,并将其值存储于 shell 变量中。Start 方法使用 -n 和 -t 选项将这些值传递给 pmfadm。
# Get the value for retry count from the RTR file. RETRY_CNT=`scha_resource_get -O Retry_count -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAME` # Get the value for retry interval from the RTR file. This value is in seconds # and must be converted to minutes for passing to pmfadm. Note that the # conversion rounds up; for example, 50 seconds rounds up to 1 minute. ((RETRY_INTRVAL=`scha_resource_get -O Retry_interval -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAME` / 60)) # Start the in.named daemon under the control of PMF. Let it crash and restart # up to $RETRY_COUNT times in a period of $RETRY_INTERVAL; if it crashes # more often than that, PMF will cease trying to restart it. # If there is a process already registered under the tag # <$PMF_TAG>, then PMF sends out an alert message that the # process is already running. pmfadm -c $PMF_TAAG -n $RETRY_CNT -t $RETRY_INTRVAL \ /usr/sbin/in.named -c named.conf # Log a message indicating that HA-DNS has been started. if [ $? -eq 0 ]; then logger -p ${SYSLOG_FACILITY}.err \ -t [$SYSLOG_TAG] \ "${ARGV0} HA-DNS successfully started" fi exit 0
Start 方法在基本应用程序实际运行且可用之前不应该成功退出,特别是在其他数据服务依赖于它的情况下。一种验证成功的方法是探测应用程序,以确保在 Start 方法退出之前它已运行。对于复杂的应用程序,例如数据库,请确保将 RTR 文件中的 Start_timeout 属性值设置得足够高,以允许应用程序有初始化和从崩溃中恢复的时间。
由于数据服务样例中的应用程序资源 (DNS) 快速启动,因此数据服务样例不会进行轮询以验证在成功退出之前该资源是否已运行。
如果此方法无法启动 DNS 并在失败状态下退出,RGM 将检查用来确定如何作出反应的 Failover_mode 属性。数据服务样例不会明确设置 Failover_mode 属性,因此该属性的默认值为 NONE(除非群集管理员覆盖了默认值并指定了其他值)。在这种情况下,RGM 仅执行设置数据服务状态的操作。群集管理员需要在同一节点上执行重新启动,或故障转移到其他节点。
当使包含有 HA-DNS 资源的资源组在群集节点上脱机时,或当该资源组处于联机状态但资源已被禁用时,RGM 将在该群集节点上运行 Stop 方法。该方法将停止该节点上的 in.named (DNS) 守护进程。
本小节介绍了应用程序样例中的 Stop 方法的重要方面,本节没有介绍所有回调方法通用的功能,例如 parse_args() 函数。本节也没有介绍 syslog() 函数的使用。通用功能在为所有方法提供通用功能中进行介绍。
有关 Stop 方法的完整列表,请参见Stop 方法代码列表。
当尝试停止数据服务时,需要考虑以下两个主要方面。第一方面是进行顺序停机。通过 pmfadm 发送 SIGTERM 信号是完成顺序停机的最佳方法。
第二方面是要确保数据服务确实已停止,以避免使其处于 Stop_failed 状态。达到将数据服务置于该状态的最佳方法是通过 pmfadm 发送一个 SIGKILL 信号。
数据服务样例中的 Stop 方法将同时考虑这两个方面。它先发送一个 SIGTERM 信号。如果该信号不能停止数据服务,该方法将发送 SIGKILL 信号。
在尝试停止 DNS 之前,此 Stop 方法将检验该进程是否确实正在运行。如果进程正在运行,则 Stop 将使用 PMF (pmfadm) 来停止进程。
确保此 Stop 方法具有幂等性。尽管 RGM 不应在没有首先调用其 Start 方法来启动数据服务的情况下两次调用 Stop 方法,RGM 也可以在资源上调用 Stop 方法,即使该资源从未启动或已自动关闭。因此,即使 DNS 未运行,此 Stop 方法也可以在成功状态下退出。
Stop 方法提供了用来停止数据服务的双重方法:顺序或平稳方法通过 pmfadm 使用 SIGTERM 信号,突然或强硬方法使用 SIGKILL 信号。Stop 方法获取 Stop_timeout 值(时间量,Stop 方法必须在该期间返回)。Stop 将此时间的 80% 分配给平稳停止,15% 分配给突然停止(5% 保留),如以下样例代码所示。
STOP_TIMEOUT='scha_resource_get -O STOP_TIMEOUT -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAME' ((SMOOTH_TIMEOUT=$STOP_TIMEOUT * 80/100)) ((HARD_TIMEOUT=$STOP_TIMEOUT * 15/100))
Stop 方法将使用 pmfadm -q 检验 DNS 守护进程是否正在运行。如果 DNS 守护进程正在运行,Stop 首先使用 pmfadm -s 发送 TERM 信号终止 DNS 进程。如果经过超时值的 80% 后该信号还无法终止进程,Stop 将发送 SIGKILL 信号。如果该信号在超时值的 15% 范围内仍无法终止进程,方法将记录一条错误消息并以出错状态退出。
如果 pmfadm 终止了该进程,该方法将记录一条说明该进程已停止并在成功状态下退出的消息。
如果 DNS 进程未运行,该方法将记录一条说明该进程未运行并仍在成功状态下退出的消息。以下样例代码说明了 Stop 如何使用 pmfadm 停止 DNS 进程。
# See if in.named is running, and if so, kill it. if pmfadm -q $PMF_TAG; then # Send a SIGTERM signal to the data service and wait for 80% of the # total timeout value. pmfadm -s $RESOURCE_NAME.named -w $SMOOTH_TIMEOUT TERM if [ $? -ne 0 ]; then logger -p ${SYSLOG_FACILITY}.err \ -t [$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME] \ “${ARGV0} Failed to stop HA-DNS with SIGTERM; Retry with \ SIGKILL” # Since the data service did not stop with a SIGTERM signal, use # SIGKILL now and wait for another 15% of the total timeout value. pmfadm -s $PMF_TAG -w $HARD_TIMEOUT KILL if [ $? -ne 0 ]; then logger -p ${SYSLOG_FACILITY}.err \ -t [$SYSLOG_TAG] \ “${ARGV0} Failed to stop HA-DNS; Exiting UNSUCCESSFUL” exit 1 fi fi else # The data service is not running as of now. Log a message and # exit success. logger -p ${SYSLOG_FACILITY}.err \ -t [$SYSLOG_TAG] \ “HA-DNS is not started” # Even if HA-DNS is not running, exit success to avoid putting # the data service resource in STOP_FAILED State. exit 0 fi # Could successfully stop DNS. Log a message and exit success. logger -p ${SYSLOG_FACILITY}.err \ -t [$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME] \ “HA-DNS successfully stopped” exit 0 |
Stop 方法在基本应用程序实际停止之前不应该成功退出,特别是在其他数据服务依赖于它的情况下。如果未做到这一点,可能会导致数据毁坏。
对于复杂的应用程序(例如数据库),请确保在 RTR 文件中设置了足够大的 Start_timeout 属性值,使应用程序有足够长的时间在停止时进行清除。
如果此方法无法停止 DNS 并在失败状态下退出,RGM 将检查用来确定如何作出反应的 Failover_mode 属性。数据服务样例不会明确设置 Failover_mode 属性,因此该属性的默认值为 NONE(除非群集管理员覆盖了默认值并指定了其他值)。这种情况下,RGM 仅将数据服务的状态设置为 Stop_failed,而不会采取其他操作。群集管理员需要强制停止应用程序并清除 Stop_failed 状态。
样例应用程序执行基本的故障监视,以监视 DNS 资源 (in.named) 的可靠性。故障监视器由以下元素组成:
dns_probe,用户定义的程序,使用 nslookup 验证由数据服务样例控制的 DNS 资源是否正在运行。如果 DNS 未运行,此方法将尝试在本地重启该 DNS,或按照重启尝试的次数请求 RGM 将数据服务重定位到其它节点。
dns_monitor_start,启动 dns_probe 的回调方法。如果启用了监视,RGM 将在数据服务样例联机之后自动调用 dns_monitor_start。
dns_monitor_stop,停止 dns_probe 的回调方法。使数据服务样例脱机之前,RGM 自动调用 dns_monitor_stop。
dns_monitor_check,一种回调方法,当 PROBE 程序将数据服务故障转移到新节点时该方法调用 Validate 方法,以验证配置目录是否可用。
dns_probe 程序执行连续运行过程,验证由数据服务样例控制的 DNS 资源是否正在运行。dns_probe 由 dns_monitor_start 方法启动,该方法在数据服务样例联机之后由 RGM 自动运行。数据服务由 dns_monitor_stop 方法停止,RGM 在使数据服务样例脱机之前运行该方法。
本小节介绍了应用程序样例中的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 服务器的 IP 地址
Retry_count 和 Retry_interval??确定尝试重新启动的次数以及计算这些次数的时间段
RT_basedir??获取包含 PROBE 程序和 gettime 实用程序的目录
scha_resource_get() 函数获取这些属性的值并将其存储于 shell 变量中,如下所示:
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 # The interval at which the probe needs to run is specified in the # property THOROUGH_PROBE_INTERVAL. Therefore, set the probe to sleep # for a duration of THOROUGH_PROBE_INTERVAL. sleep $PROBE_INTERVAL # Run an nslookup command of the IP address on which DNS is serving. hatimerun -t $PROBE_TIMEOUT /usr/sbin/nslookup $DNS_HOST $DNS_HOST \ > $DNSPROBEFILE 2>&1 retcode=$? if [ $retcode -ne 0 ]; then probefail=1 fi # Make sure that the reply to nslookup comes from the HA-DNS # server and not from another nameserver mentioned in the # /etc/resolv.conf file. if [ $probefail -eq 0 ]; then # Get the name of the server that replied to the nslookup query. 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 文件中,这些属性的默认值为在时间段 5 分钟(300 秒)内进行两次尝试,尽管群集管理员可以更改这些值。
系统将调用 restart_service() 函数尝试在同一节点上重新启动数据服务。有关该函数的信息,请参见下一节,重启数据服务。
scha_control() API 函数带有 GIVEOVER 选项使包含数据服务样例的资源组脱机并在其他节点上使其重新联机。
decide_restart_or_failover() 调用 restart_service() 函数,以尝试在同一节点上重新启动数据服务。 该函数执行以下逻辑:
确定数据服务是否仍在 PMF 之下注册。如果服务仍处于注册状态,函数将执行以下操作:
为数据服务获取 Stop 方法名称和 Stop_timeout 值
使用 hatimerun 为数据服务启动 Stop 方法,传递 Stop_timeout 值
如果数据服务成功停止,则为数据服务获取 Start 方法名称和 Start_timeout 值
使用 hatimerun 为数据服务启动 Start 方法,传递 Start_timeout 值
如果数据服务已不在 PMF 之下注册,则表示数据服务已超过了 PMF 下允许的最大重试次数。系统将使用 GIVEOVER 选项调用 scha_control() 函数,以将数据服务故障转移到其他节点。
function restart_service { # To restart the data service, first verify that the # data service itself is still registered under PMF. pmfadm -q $PMF_TAG if [[ $? -eq 0 ]]; then # Since the TAG for the data service is still registered under # PMF, first stop the data service and start it back up again. # Obtain the Stop method name and the STOP_TIMEOUT value for # this resource. 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 # Obtain the START method name and the START_TIMEOUT value for # this resource. 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 # The absence of the TAG for the dataservice # implies that the data service has already # exceeded the maximum retries allowed under PMF. # Therefore, do not attempt to restart the # data service again, but try to failover # to another node in the cluster. scha_control -O GIVEOVER -G $RESOURCEGROUP_NAME \ -R $RESOURCE_NAME fi return 0 }
如果尝试在本地重新启动失败,并且尝试故障转移到其他节点也失败,则数据服务样例的 PROBE 程序将以失败退出。此程序将记录消息 Failover attempt failed。
RGM 调用 Monitor_start 方法,以在使数据服务样例联机之后启动 dns_probe 方法。
本节介绍样例应用程序的 Monitor_start 方法的主要方面。本节没有介绍所有回调方法通用的功能,例如 parse_args() 函数。本节也没有介绍 syslog() 函数的使用。通用功能在为所有方法提供通用功能中进行介绍。
有关 Monitor_start 方法的完整列表,请参见Monitor_start 方法代码列表。
该方法使用 PMF (pmfadm) 来启动探测。
Monitor_start 方法获取 RT_basedir 属性的值,用来为 PROBE 程序构造完整的路径名。该方法通过使用 pmfadm 的无限重试选项(-n -1、-t -1)启动探测,意味着如果探测无法启动,PMF 将在无限时间期限内无限次地启动探测。
# Find where the probe program resides by obtaining the value of the # RT_basedir property of the resource. RT_BASEDIR=`scha_resource_get -O RT_basedir -R $RESOURCE_NAME -G \ $RESOURCEGROUP_NAME` # Start the probe for the data service under PMF. Use the infinite retries # option to start the probe. Pass the resource name, type, and group to the # probe program. pmfadm -c $RESOURCE_NAME.monitor -n -1 -t -1 \ $RT_BASEDIR/dns_probe -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \ -T $RESOURCETYPE_NAME
数据服务样例脱机时,RGM 调用 Monitor_stop 方法以停止 dns_probe 的执行。
本节介绍样例应用程序的 Monitor_stop 方法的主要方面。本节没有介绍所有回调方法通用的功能,例如 parse_args() 函数。本节也没有介绍 syslog() 函数的使用。通用功能在为所有方法提供通用功能中进行介绍。
有关 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_stop 将挂起,等待 scha_control() 完成,并且 scha_control() 将挂起等待 Monitor_stop 完成。
# See if the monitor is running, and if so, kill it. 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 # could successfully stop the monitor. Log a message. logger -p ${SYSLOG_FACILITY}.err \ -t [$SYSLOG_TAG] \ "${ARGV0} Monitor for resource " $RESOURCE_NAME \ " successfully stopped" fi fi exit 0
如果 Monitor_stop 方法无法停止 PROBE 方法,它将记录一条错误消息。RGM 使数据服务样例在主节点上进入 MONITOR_FAILED 状态,这样可以应急该节点。
在探测程序停止之前,Monitor_stop 不应退出。
无论 PROBE 方法何时尝试将包含数据服务的资源组故障转移到新节点上,RGM 都将调用 Monitor_check 方法。
本节介绍样例应用程序的 Monitor_check 方法的主要方面。本节没有介绍所有回调方法通用的功能,例如 parse_args() 函数。本节也没有介绍 syslog() 函数的使用。通用功能在为所有方法提供通用功能中进行介绍。
有关 Monitor_check 方法的完整列表,请参见Monitor_check 方法代码列表。
Monitor_check 方法必须执行,因此它不会与并发运行的其他方法发生冲突。
Monitor_check 方法调用 Validate 方法以验证 DNS 配置目录在新节点上是否可用。Confdir 扩展属性指向 DNS 配置目录。因此,Monitor_check 获取 Validate 方法的路径和名称以及 Confdir 的值。它将把此值传送到 Validate,如下所示。
# Obtain the full path for the Validate method from # the RT_basedir property of the resource type. RT_BASEDIR=`scha_resource_get -O RT_basedir -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAM? # Obtain the name of the Validate method for this resource. VALIDATE_METHOD=`scha_resource_get -O Validate \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAM? # Obtain the value of the Confdir property in order to start the # data service. Use the resource name and the resource group entered to # obtain the Confdir value set at the time of adding the resource. config_info=`scha_resource_get -O Extension -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAME Confdir` # scha_resource_get returns the type as well as the value for extension # properties. Use awk to get only the value of the extension property. CONFIG_DIR=`echo $config_info | awk `{print $2}'` # Call the validate method so that the dataservice can be failed over # successfully to the new node. $RT_BASEDIR/$VALIDATE_METHOD -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \ -T $RESOURCETYPE_NAME -x Confdir=$CONFIG_DIR
请参见Validate 方法的工作方式,以查看样例应用程序如何验证某节点主管数据服务的适当性。
数据服务样例执行 Validate 和 Update 方法,以处理群集管理员对属性的更新。
创建资源时以及通过管理操作更新资源或其资源组的属性时,RGM 将调用 Validate 方法。在进行创建或更新之前,RGM 将调用 Validate,如果从任何节点上的方法返回失败出口代码都将导致创建或更新操作取消。
仅当群集管理员更改资源或资源组属性时 RGM 才调用 Validate,RGM 设置属性或监视器设置资源属性 Status 和 Status_msg 时 RGM 不执行该调用。
只要 PROBE 方法尝试将数据服务故障转移到新节点,Monitor_check 方法也会明确调用 Validate 方法。
RGM 使用传递给其他方法的其他参数调用 Validate,包括要更新的属性和值。因此,数据服务样例中的此方法必须执行不同的 parse_args() 函数以处理其他参数。
数据服务样例中的 Validate 方法用来检验单个属性 Confdir 扩展属性。此属性指向 DNS 配置目录,这对于能否成功地进行 DNS 操作来说至关重要。
由于在 DNS 运行时不能更改配置目录,所以 Confdir 属性在 RTR 文件中被声明为 TUNABLE = AT_CREATION。因此,更新后系统从不调用 Validate 方法来验证 Confdir 属性,仅在创建数据服务资源时执行该操作。
如果 Confdir 是 RGM 传递给 Validate 的属性之一,parse_args() 函数将检索并保存其值。Validate 验证 Confdir 的新值所指向的目录是否可访问,以及该目录中是否存在 named.conf 文件并且该文件是否包含数据。
如果 parse_args() 函数无法从由 RGM 传递的命令行参数中检索 Confdir 的值,Validate 仍会尝试验证 Confdir 属性。Validate 使用 scha_resource_get() 从静态配置中获取 Confdir 的值。Validate 执行同样的检查,验证配置目录是否可访问并且是否包含非空文件 named.conf。
如果 Validate 在失败状态下退出,所有属性(而不仅仅是 Confdir)的更新或创建操作都将失败。
由于 RGM 向 Validate 方法传递了一组与其他回调方法不同的参数,因此 Validate 需要与其他方法不同的函数来解析这些参数。有关传递给 Validate 和其他回调方法的参数的更多信息,请参见 rt_callbacks(1HA) 手册页。以下样例代码显示了 Validate 的 parse_args() 函数。
######################################################################### # Parse Validate arguments. # function parse_args # [args...] { typeset opt while getopts 'cur:x:g:R:T:G:' opt do case "$opt" in R) # Name of the DNS resource. RESOURCE_NAME=$OPTARG ;; G) # Name of the resource group in which the resource is # configured. RESOURCEGROUP_NAME=$OPTARG ;; T) # Name of the resource type. RESOURCETYPE_NAME=$OPTARG ;; r) # The method is not accessing any system defined # properties so this is a no-op ;; g) # The method is not accessing any resource group # properties, so this is a no-op ;; c) # Indicates the Validate method is being called while # creating the resource, so this flag is a no-op. ;; u) # Indicates the updating of a property when the # resource already exists. If the update is to the # Confdir property then Confdir should appear in the # command-line arguments. If it does not, the method must # look for it specifically using scha_resource_get. UPDATE_PROPERTY=1 ;; x) # Extension property list. Separate the property and # value pairs using "=" as the separator. PROPERTY=`echo $OPTARG | awk -F= '{print $1}'` VAL=`echo $OPTARG | awk -F= '{print $2}'` # If the Confdir extension property is found on the # command line, note its value. 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 }
相对其他方法的 parse_args() 函数,该函数提供了标志 (R) 以捕获资源名称,(G) 以捕获资源组名称,(T) 以捕获 RGM 传递的资源类型。
忽略 r 标志(表示系统定义的属性)g 标志(表示资源组属性)和 c 标志(表示资源创建期间进行了验证)。忽略它们,是因为更新资源时,系统调用该方法验证扩展属性。
u 标记将 UPDATE_PROPERTY shell 变量的值设置为 1 (TRUE)。x 标志捕获要更新的属性名称和值。如果 Confdir 是要更新的属性之一,其值将被放于 shell 变量 CONFDIR 中,并且变量 CONFDIR_FOUND 将被设置为 1 (TRUE)。
在其 MAIN 函数中,Validate 首先将 CONFDIR 变量设置为空字符串,并将 UPDATE_PROPERTY 和 CONFDIR_FOUND 设置为 0。
CONFDIR="" UPDATE_PROPERTY=0 CONFDIR_FOUND=0
Validate 调用 parse_args() 解析由 RGM 传递的参数。
parse_args “$@”
Validate 检查 Validate 是否因属性更新而被调用。Validate 还会检查 Confdir 扩展属性是否在命令行中。Validate 验证 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 # Verify that the Confdir property has a value. If not there is a failure # and exit with status 1 if [[ -z $CONFDIR ]]; then logger -p ${SYSLOG_FACILITY}.err \ "${ARGV0} Validate method for resource "$RESOURCE_NAME " failed" exit 1 fi
特别地,上述代码检查是否因更新而调用 Validate ($UPDATE_PROPERTY == 1) 以及是否未在命令行中找到该属性 (CONFDIR_FOUND == 0)。在这种情况下,代码将使用 scha_resource_get() 检索 Confdir 的现有值。如果在命令行中找到了 Confdir (CONFDIR_FOUND == 1),则 CONFDIR 的值来自于 parse_args() 函数,而不是来自于 scha_resource_get()。
Validate 方法使用 CONFDIR 的值来验证目录是否可访问。如果目录不可访问,Validate 将记录一条错误消息并以出错状态退出。
# Check if $CONFDIR is accessible. if [ ! -d $CONFDIR ]; then logger -p ${SYSLOG_FACILITY}.err \ -t [$SYSLOG_TAG] \ "${ARGV0} Directory $CONFDIR missing or not mounted" exit 1 fi
在验证 Confdir 属性的更新之前,Validate 将执行 final 检查来检验 named.conf 文件是否存在。如果文件不存在,该方法将记录一条错误消息并以出错状态退出。
# Check that the named.conf file is present in the Confdir directory 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 将记录表示成功的消息并以成功状态退出。
# Log a message indicating that the Validate method was successful. logger -p ${SYSLOG_FACILITY}.err \ -t [$SYSLOG_TAG] \ "${ARGV0} Validate method for resource "$RESOURCE_NAME \ " completed successfully" exit 0
如果 Validate 以成功状态退出 (0),系统将用新值创建 Confdir。如果 Validate 以失败状态退出 (1),则不会创建 Confdir 和其他任何属性,并生成指出原因的消息。
RGM 通过运行 Update 方法来通知正在运行的资源其属性已更改。群集管理员成功设置了资源或其组的属性后,RGM 将运行 Update。在资源联机所在的节点上调用该方法。
Update 方法不更新属性。RGM 更新属性。Update 方法通知正在运行的进程已执行了更新。在数据服务样例中,受属性更新影响的唯一进程是故障监视器。因而,故障监视器进程是 Update 方法停止并重新启动的进程。
Update 方法必须验证故障监视器是否正在运行,然后使用 pmfadm 命令中止它。该方法获取执行故障监视的探测程序的位置,并使用 pmfadm 命令将其重新启动。
Update 方法使用 pmfadm -q 验证监视器是否正在运行,如果是,则使用 pmfadm -s TERM 中止它。如果监视器成功终止,将会向群集管理员发送一条描述该结果的消息。如果无法停止监视器,Update 将以失败状态退出并向群集管理员发送一条错误消息。
if pmfadm -q $RESOURCE_NAME.monitor; then # Kill the monitor that is running already pmfadm -s $PMF_TAG TERM if [ $? -ne 0 ]; then logger -p ${SYSLOG_FACILITY}.err \ -t [$SYSLOG_TAG] \ "${ARGV0} Could not stop the monitor" exit 1 else # could successfully stop DNS. Log a message. logger -p ${SYSLOG_FACILITY}.err \ -t [$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME] \ "Monitor for HA-DNS successfully stopped" fi
要重新启动监视器,Update 方法必须定位实现探测程序的脚本。探测程序位于数据服务的基目录中,RT_basedir 属性指向该基目录。Update 检索 RT_basedir 的值并将其存储于 RT_BASEDIR 变量中,如下所示。
RT_BASEDIR=`scha_resource_get -O RT_basedir -R $RESOURCE_NAME -G \ $RESOURCEGROUP_NAME`
Update 使用 RT_BASEDIR 的值和 pmfadm 重新启动 dns_probe 程序。如果成功,Update 将以成功状态退出并向群集管理员发送一条描述该结果的消息。如果 pmfadm 无法启动探测程序,Update 将以失败状态退出并记录一条错误消息。
Update 方法的失败将导致资源处于“更新失败”状态。该状态对资源的 RGM 管理没有影响,但是会通过 syslog() 函数将更新操作的失败告知管理工具。