3 # lc_cluman - script for generating the Red Hat Cluster Manager
4 # HA software's configuration files
6 ################################################################################
12 Usage: `basename $0` <-n hostnames> [-s service addresses]
13 [-c heartbeat channel] [-o heartbeat options] [-v]
14 <-d target device> [-d target device...]
16 -n hostnames the nodenames of the primary node and its fail-
18 Multiple nodenames are separated by colon (:)
19 delimeter. The first one is the nodename of the
20 primary node, the others are failover nodenames.
21 -s service addresses the IP addresses to failover
22 Multiple addresses are separated by colon (:)
24 -c heartbeat channel the method to send/rcv heartbeats on
25 The default method is multicast, and multicast_
26 ipaddress is "225.0.0.11".
27 -o heartbeat options a "catchall" for other heartbeat configuration
29 Multiple options are separated by colon (:)
32 -d target device the target device name and mount point
33 The device name and mount point are separated by
40 # Get the library of functions
41 . @scriptlibdir@/lc_common
43 #****************************** Global variables ******************************#
44 TMP_DIR=${CLUMGR_TMP_DIR} # Temporary directory
46 declare -a NODE_NAMES # Node names in the failover group
47 declare -a SRV_IPADDRS # Service IP addresses
49 # Lustre target device names, service names and mount points
50 declare -a TARGET_DEVNAMES TARGET_SRVNAMES TARGET_MNTPNTS
51 declare -i TARGET_NUM=0 # Number of targets
53 # Get and check the positional parameters
55 while getopts "n:s:c:o:vd:" OPTION; do
59 PRIM_NODENAME=`echo ${HOSTNAME_OPT} | awk -F":" '{print $1}'`
60 if [ -z "${PRIM_NODENAME}" ]; then
61 echo >&2 $"`basename $0`: Missing primary nodename!"
64 HOSTNAME_NUM=`echo ${HOSTNAME_OPT} | awk -F":" '{print NF}'`
65 if [ ${HOSTNAME_NUM} -lt 2 ]; then
66 echo >&2 $"`basename $0`: Missing failover nodenames!"
75 HBCHANNEL_OPT=`echo "${HBCHANNEL_OPT}" | sed 's/^"//' \
77 if [ -n "${HBCHANNEL_OPT}" ] \
78 && [ "${HBCHANNEL_OPT}" = "${HBCHANNEL_OPT#*broadcast*}" ] \
79 && [ "${HBCHANNEL_OPT}" = "${HBCHANNEL_OPT#*multicast*}" ]; then
80 echo >&2 $"`basename $0`: Invalid Heartbeat channel" \
87 HBOPT_OPT=`echo "${HBOPT_OPT}" | sed 's/^"//' | sed 's/"$//'`
94 TARGET_DEVNAMES[TARGET_NUM]=`echo ${DEVICE_OPT}|awk -F: '{print $1}'`
95 TARGET_MNTPNTS[TARGET_NUM]=`echo ${DEVICE_OPT}|awk -F: '{print $2}'`
96 if [ -z "${TARGET_DEVNAMES[TARGET_NUM]}" ]; then
97 echo >&2 $"`basename $0`: Missing target device name!"
100 if [ -z "${TARGET_MNTPNTS[TARGET_NUM]}" ]; then
101 echo >&2 $"`basename $0`: Missing mount point for target"\
102 "${TARGET_DEVNAMES[TARGET_NUM]}!"
105 TARGET_NUM=$(( TARGET_NUM + 1 ))
113 # Check the required parameters
114 if [ -z "${HOSTNAME_OPT}" ]; then
115 echo >&2 $"`basename $0`: Missing -n option!"
119 if [ -z "${DEVICE_OPT}" ]; then
120 echo >&2 $"`basename $0`: Missing -d option!"
126 # Get all the node names in this failover group
129 local nodename_str nodename
131 nodename_str=`echo ${HOSTNAME_OPT}|awk '{split($HOSTNAME_OPT, a, ":")}\
132 END {for (i in a) print a[i]}'`
134 for nodename in ${nodename_str}
136 NODE_NAMES[idx]=${nodename}
143 # get_check_srvIPaddrs
145 # Get and check all the service IP addresses in this failover group
146 get_check_srvIPaddrs() {
149 local srvIPaddr_str srvIPaddr
151 srvIPaddr_str=`echo ${SRVADDR_OPT}|awk '{split($SRVADDR_OPT, a, ":")}\
152 END {for (i in a) print a[i]}'`
154 for srvIPaddr in ${srvIPaddr_str}
156 SRV_IPADDRS[idx]=${srvIPaddr}
160 for ((idx = 0; idx < ${#SRV_IPADDRS[@]}; idx++)); do
161 for ((i = 0; i < ${#NODE_NAMES[@]}; i++)); do
162 # Check service IP address
163 verbose_output "Verifying service IP ${SRV_IPADDRS[idx]} and" \
164 "real IP of host ${NODE_NAMES[i]} are in the" \
166 if ! ${SCRIPT_VERIFY_SRVIP} ${SRV_IPADDRS[idx]} ${NODE_NAMES[i]}
177 # cluman_running host_name
179 # Run remote command to check whether clumanager service is running in @host_name
184 ret_str=`${REMOTE} ${host_name} "/sbin/service clumanager status" 2>&1`
185 if [ $? -ne 0 ]; then
186 if [ "${ret_str}" != "${ret_str#*unrecognized*}" ]; then
187 echo >&2 "`basename $0`: cluman_running() error:"\
188 "remote command to ${host_name} error: ${ret_str}!"
198 # stop_cluman host_name
200 # Run remote command to stop clumanager service running in @host_name
205 ret_str=`${REMOTE} ${host_name} "/sbin/service clumanager stop" 2>&1`
206 if [ $? -ne 0 ]; then
207 echo >&2 "`basename $0`: stop_cluman() error:"\
208 "remote command to ${host_name} error: ${ret_str}!"
212 echo "`basename $0`: Clumanager service is stopped on node ${host_name}."
218 # Run remote command to check each node's clumanager service
223 # Get and check all the service IP addresses
224 if [ -n "${SRVADDR_OPT}" ] && ! get_check_srvIPaddrs; then
228 for ((idx = 0; idx < ${#NODE_NAMES[@]}; idx++)); do
229 # Check clumanager service status
230 cluman_running ${NODE_NAMES[idx]}
232 if [ "$rc" -eq "2" ]; then
234 elif [ "$rc" -eq "1" ]; then
235 verbose_output "Clumanager service is stopped on"\
236 "node ${NODE_NAMES[idx]}."
237 elif [ "$rc" -eq "0" ]; then
239 echo -n "`basename $0`: Clumanager service is running on"\
240 "${NODE_NAMES[idx]}, go ahead to stop the service and"\
241 "generate new configurations? [y/n]:"
243 if [ "${OK}" = "n" ]; then
244 echo "`basename $0`: New Clumanager configurations"\
249 # Stop clumanager service
250 stop_cluman ${NODE_NAMES[idx]}
257 # get_srvname hostname target_devname
259 # Get the lustre target server name from the node @hostname
262 local target_devname=$2
263 local target_srvname=
266 # Execute remote command to get the target server name
267 ret_str=`${REMOTE} ${host_name} \
268 "${TUNEFS} --print --verbose ${target_devname} | grep Target:" 2>&1`
269 if [ $? -ne 0 ]; then
270 echo "`basename $0`: get_srvname() error:" \
271 "from host ${host_name} - ${ret_str}"
275 if [ "${ret_str}" != "${ret_str#*Target: }" ]; then
276 ret_str=${ret_str#*Target: }
277 target_srvname=`echo ${ret_str} | awk '{print $1}'`
280 if [ -z "${target_srvname}" ]; then
281 echo "`basename $0`: get_srvname() error: Cannot get the"\
282 "server name of target ${target_devname} in ${host_name}!"
286 echo ${target_srvname}
292 # Get server names of all the Lustre targets in this failover group
296 # Initialize the TARGET_SRVNAMES array
297 unset TARGET_SRVNAMES
299 # Get Lustre target service names
300 for ((i = 0; i < ${#TARGET_DEVNAMES[@]}; i++)); do
301 TARGET_SRVNAMES[i]=$(get_srvname ${PRIM_NODENAME} \
302 ${TARGET_DEVNAMES[i]})
303 if [ $? -ne 0 ]; then
304 echo >&2 "${TARGET_SRVNAMES[i]}"
312 # check_retval retval
314 # Check the return value of redhat-config-cluster-cmd
316 if [ $1 -ne 0 ]; then
317 echo >&2 "`basename $0`: Failed to run ${CONFIG_CMD}!"
326 # Add service tags into the cluster.xml file
332 for ((i = 0; i < ${#TARGET_SRVNAMES[@]}; i++)); do
333 ${CONFIG_CMD} --add_service --name=${TARGET_SRVNAMES[i]}
334 if ! check_retval $?; then
338 for ((idx = 0; idx < ${#SRV_IPADDRS[@]}; idx++)); do
339 ${CONFIG_CMD} --service=${TARGET_SRVNAMES[i]} \
340 --add_service_ipaddress --ipaddress=${SRV_IPADDRS[idx]}
341 if ! check_retval $?; then
346 ${CONFIG_CMD} --service=${TARGET_SRVNAMES[i]} \
348 --name=${TARGET_DEVNAMES[i]}
349 if ! check_retval $?; then
353 ${CONFIG_CMD} --service=${TARGET_SRVNAMES[i]} \
354 --device=${TARGET_DEVNAMES[i]} \
356 --mountpoint=${TARGET_MNTPNTS[i]} \
358 if ! check_retval $?; then
368 # Run redhat-config-cluster-cmd to create the cluster.xml file
376 [ -e "${CLUMAN_DIR}/cluster.xml" ] && \
377 /bin/mv ${CLUMAN_DIR}/cluster.xml ${CLUMAN_DIR}/cluster.xml.old
379 # Run redhat-config-cluster-cmd to generate cluster.xml
381 if [ "${HBCHANNEL_OPT}" != "${HBCHANNEL_OPT#*broadcast*}" ]; then
382 ${CONFIG_CMD} --clumembd --broadcast=yes
383 ${CONFIG_CMD} --clumembd --multicast=no
384 if ! check_retval $?; then
387 elif [ "${HBCHANNEL_OPT}" != "${HBCHANNEL_OPT#*multicast*}" ]; then
388 mcast_IPaddr=`echo ${HBCHANNEL_OPT} | awk '{print $2}'`
389 if [ -n "${mcast_IPaddr}" ]; then
390 ${CONFIG_CMD} --clumembd --multicast=yes\
391 --multicast_ipaddress=${mcast_IPaddr}
392 if ! check_retval $?; then
400 for ((idx = 0; idx < ${#NODE_NAMES[@]}; idx++)); do
401 node_names=${node_names}"${NODE_NAMES[idx]} "
404 ${CONFIG_CMD} --cluster --name="${node_names}failover group"
405 if ! check_retval $?; then
410 for ((idx = 0; idx < ${#NODE_NAMES[@]}; idx++)); do
411 ${CONFIG_CMD} --add_member --name=${NODE_NAMES[idx]}
412 if ! check_retval $?; then
418 if ! add_services; then
423 if [ -n "${HBOPT_OPT}" ]; then
426 ${CONFIG_CMD} ${hbopt}
427 if ! check_retval $?; then
430 done < <(echo ${HBOPT_OPT}|awk '{split($HBOPT_OPT, a, ":")}\
431 END {for (i in a) print a[i]}')
439 # Create the cluster.xml file and scp it to the each node's /etc/
443 /bin/mkdir -p ${TMP_DIR}
444 CONFIG_PRIMNODE=${TMP_DIR}$"/cluster.xml."${PRIM_NODENAME}
445 CONFIG_LUSTRE=${TMP_DIR}$"/cluster.xml"${FILE_SUFFIX}
447 # Get server names of Lustre targets
448 if ! get_srvnames; then
452 if [ -s ${CONFIG_PRIMNODE} ]; then
453 if [ -n "`/bin/grep ${TARGET_SRVNAMES[0]} ${CONFIG_PRIMNODE}`" ]
455 verbose_output "${CONFIG_PRIMNODE} already exists."
458 [ -e "${CLUMAN_DIR}/cluster.xml" ] && \
459 /bin/mv ${CLUMAN_DIR}/cluster.xml ${CLUMAN_DIR}/cluster.xml.old
461 /bin/cp -f ${CONFIG_PRIMNODE} ${CLUMAN_DIR}/cluster.xml
463 # Add services into the cluster.xml file
464 if ! add_services; then
469 # Run redhat-config-cluster-cmd to generate cluster.xml
470 verbose_output "Creating cluster.xml file for" \
471 "${PRIM_NODENAME} failover group hosts..."
472 if ! gen_cluster_xml; then
478 /bin/mv ${CLUMAN_DIR}/cluster.xml ${CONFIG_LUSTRE}
479 [ -e "${CLUMAN_DIR}/cluster.xml.old" ] && \
480 /bin/mv ${CLUMAN_DIR}/cluster.xml.old ${CLUMAN_DIR}/cluster.xml
482 # scp the cluster.xml file to all the nodes
483 verbose_output "Remote copying cluster.xml${FILE_SUFFIX} file to" \
484 "${PRIM_NODENAME} failover group hosts..."
485 for ((idx = 0; idx < ${#NODE_NAMES[@]}; idx++)); do
486 /bin/cp -f ${CONFIG_LUSTRE} ${TMP_DIR}$"/cluster.xml."${NODE_NAMES[idx]}
488 scp ${CONFIG_LUSTRE} ${NODE_NAMES[idx]}:${CLUMAN_DIR}/
489 if [ $? -ne 0 ]; then
490 echo >&2 "`basename $0`: Failed to scp cluster.xml file"\
491 "to node ${NODE_NAMES[idx]}!"
501 # Get all the node names
502 if ! get_nodenames; then
506 # Check clumanager services
507 verbose_output "Checking clumanager service in the ${PRIM_NODENAME}"\
508 "failover group hosts..."
511 if [ "$rc" -eq "2" ]; then
514 elif [ "$rc" -eq "1" ]; then
519 # Generate configuration files
520 if ! create_config; then