From 2168332ab6f259a9dff7caaa5bc6b66f669f79bd Mon Sep 17 00:00:00 2001 From: yujian Date: Thu, 28 Sep 2006 03:43:30 +0000 Subject: [PATCH] 1) add nodelist options "-a", "-w" and "-x" to lustre config scripts 2) replace $? with ${PIPESTATUS[0]} and `` with $() --- lustre/scripts/lc_common.sh | 141 +++++++++++++++++++++++++++++++++++-- lustre/scripts/lc_lvm.sh.in | 40 +++++++++-- lustre/scripts/lc_md.sh.in | 48 ++++++++++--- lustre/scripts/lc_net.sh.in | 68 ++++++++++-------- lustre/scripts/lustre_config.sh.in | 101 ++++++++++++++++++-------- 5 files changed, 321 insertions(+), 77 deletions(-) diff --git a/lustre/scripts/lc_common.sh b/lustre/scripts/lc_common.sh index ef62b9a..8fb00d65 100644 --- a/lustre/scripts/lc_common.sh +++ b/lustre/scripts/lc_common.sh @@ -72,6 +72,13 @@ LV_MARKER=${LV_MARKER:-"LV"} declare -a CONFIG_ITEM # Items in each line of the csv file declare -a NODE_NAME # Hostnames of nodes have been configured +# Nodelist variables +USE_ALLNODES=false # default is not to operate on all the nodes +SPECIFIED_NODELIST="" # specified list of nodes to be operated on +EXCLUDED_NODELIST="" # list of nodes to be excluded + +export PATH=$PATH:$CMD_PATH:$SCRIPTS_PATH:$CLUMAN_TOOLS_PATH:$RAID_CMD_PATH:/sbin:/usr/sbin + # verbose_output string # Output verbose information $string @@ -285,8 +292,8 @@ nid2hostname() { fi # Execute remote command to get the host name - ret_str=`${REMOTE} ${ip_addr} "hostname" 2>&1` - if [ $? -ne 0 -a -n "${ret_str}" ]; then + ret_str=$(${REMOTE} ${ip_addr} "hostname" 2>&1) + if [ ${PIPESTATUS[0]} -ne 0 -a -n "${ret_str}" ]; then echo "`basename $0`: nid2hostname() error:" \ "remote command to ${ip_addr} error: ${ret_str}" return 1 @@ -320,7 +327,7 @@ nids2hostname() { lo* | elan* | gm* | ptl*) ;; *) # tcp, o2ib, cib, openib, iib, vib, ra host_name=$(nid2hostname ${nid}) - if [ $? -ne 0 ]; then + if [ ${PIPESTATUS[0]} -ne 0 ]; then echo "${host_name}" return 1 fi @@ -354,7 +361,7 @@ ip2hostname_single_node() { lo* | elan* | gm* | ptl*) ;; *) # tcp, o2ib, cib, openib, iib, vib, ra host_name=$(nid2hostname ${nid}) - if [ $? -ne 0 ]; then + if [ ${PIPESTATUS[0]} -ne 0 ]; then echo "${host_name}" return 1 fi @@ -380,7 +387,7 @@ ip2hostname_multi_node() { for nid in ${orig_nids//:/ }; do nid=$(ip2hostname_single_node ${nid}) - if [ $? -ne 0 ]; then + if [ ${PIPESTATUS[0]} -ne 0 ]; then echo "${nid}" return 1 fi @@ -391,3 +398,127 @@ ip2hostname_multi_node() { echo ${nids} return 0 } + +# comma_list space-delimited-list +# Convert a space-delimited list to a sorted list of unique values +# separated by commas. +comma_list() { + # the sed converts spaces to commas, but leaves the last space + # alone, so the line doesn't end with a comma. + echo "$*" | tr -s " " "\n" | sort -b -u | tr "\n" " " | sed 's/ \([^$]\)/,\1/g' +} + +# host_in_hostlist hostname hostlist +# Given a hostname, and a list of hostnames, return true if the hostname +# appears in the list of hostnames, or false otherwise. +host_in_hostlist() { + local HOST=$1 + local HOSTLIST=$2 + + [ -z "$HOST" -o -z "$HOSTLIST" ] && false && return + + # Hostnames in the list are separated by commas. + [[ ,$HOSTLIST, == *,$HOST,* ]] && true && return + + false && return +} + +# exclude_items_from_list list_of_items list_of_items_to_exclude +# Given a list of items, and a second list of items to exclude from +# the first list, return the contents of the first list minus the contents +# of the second. +exclude_items_from_list() { + local INLIST=$1 + local EXCLUDELIST=$2 + local ITEM OUTLIST + + # Handle an empty inlist by throwing back an empty string. + if [ -z "$INLIST" ]; then + echo "" + return 0 + fi + + # Handle an empty excludelist by throwing back the inlist unmodified. + if [ -z "$EXCLUDELIST" ]; then + echo $INLIST + return 0 + fi + + for ITEM in ${INLIST//,/ }; do + if ! host_in_hostlist $ITEM $EXCLUDELIST; then + OUTLIST="$OUTLIST,$ITEM" + fi + done + + # strip leading comma + echo ${OUTLIST#,} +} + +# get_csv_nodelist csv_file +# Get the comma-separated list of all the nodes from the csv file +get_csv_nodelist() { + local csv_file=$1 + local all_nodelist + + # Check the csv file + ! check_file ${csv_file} 2>&1 && return 1 + + all_nodelist=$(egrep -v "([[:space:]]|^)#" ${csv_file} | cut -d, -f 1) + all_nodelist=$(comma_list ${all_nodelist}) + + echo ${all_nodelist} + return 0 +} + +# get_nodelist +# Get the comma-separated list of nodes to be operated on +# Note: CSV_FILE, USE_ALLNODES, SPECIFIED_NODELIST and EXCLUDED_NODELIST +# are global variables +get_nodelist() { + local ALL_NODELIST + + # Get the list of all the nodes in the csv file + ALL_NODELIST=$(get_csv_nodelist ${CSV_FILE}) + [ ${PIPESTATUS[0]} -ne 0 ] && echo "${ALL_NODELIST}" && return 1 + + if [ -z "${ALL_NODELIST}" ]; then + echo "`basename $0`: get_nodelist() error:"\ + "There are no hosts in the ${CSV_FILE} file!" + return 1 + fi + + if ${USE_ALLNODES}; then + echo ${ALL_NODELIST} && return 0 + fi + + if [ -n "${SPECIFIED_NODELIST}" ]; then + echo $(exclude_items_from_list ${SPECIFIED_NODELIST} ${EXCLUDED_NODELIST}) + return 0 + fi + + if [ -n "${EXCLUDED_NODELIST}" ]; then + echo $(exclude_items_from_list ${ALL_NODELIST} ${EXCLUDED_NODELIST}) + return 0 + fi + + # No hosts to be operated on + echo "" + return 0 +} + +# check_nodelist nodelist +# Given a list of nodes to be operated on, check whether the nodelist is +# empty or not and output prompt message. +check_nodelist() { + local nodes_to_use=$1 + + if [ -z "${nodes_to_use}" ]; then + echo "`basename $0`: There are no hosts to be operated on."\ + "Check the node selection options (-a, -w or -x)." + usage + else + verbose_output "Operating on the following nodes: ${nodes_to_use}" + fi + + return 0 +} diff --git a/lustre/scripts/lc_lvm.sh.in b/lustre/scripts/lc_lvm.sh.in index 64018d2..6d9f7e5 100644 --- a/lustre/scripts/lc_lvm.sh.in +++ b/lustre/scripts/lc_lvm.sh.in @@ -10,11 +10,17 @@ usage() { cat >&2 < +Usage: `basename $0` [options] This script is used to configure Linux LVM devices in a Lustre cluster from a csv file. + Options: + -a select all the nodes from the csv file to operate on + -w hostname,hostname,... + select the specified list of nodes (separated by commas) + -x hostname,hostname,... + exclude the specified list of nodes (separated by commas) -h help and examples -v verbose mode csv file a spreadsheet that contains configuration parameters @@ -126,8 +132,20 @@ declare -i pid_num=0 VERBOSE_OUTPUT=false # Get and check the positional parameters -while getopts "hv" OPTION; do +while getopts "aw:x:hv" OPTION; do case $OPTION in + a) + [ -z "${SPECIFIED_NODELIST}" ] && [ -z "${EXCLUDED_NODELIST}" ] \ + && USE_ALLNODES=true + ;; + w) + USE_ALLNODES=false + SPECIFIED_NODELIST=$OPTARG + ;; + x) + USE_ALLNODES=false + EXCLUDED_NODELIST=$OPTARG + ;; h) sample ;; @@ -225,6 +243,7 @@ get_lvm_items() { CSV_FILE=$1 local LINE line_marker + local hostname declare -i line_num=0 declare -i idx=0 @@ -235,11 +254,17 @@ get_lvm_items() { [ -z "`echo \"${LINE}\" | egrep -v \"([[:space:]]|^)#\"`" ] && continue # Skip the non-LVM line - line_marker=`echo ${LINE} | awk -F, '{print $2}'` + line_marker=$(echo ${LINE} | cut -d, -f 2) [ "${line_marker}" != "${PV_MARKER}" ] \ && [ "${line_marker}" != "${VG_MARKER}" ] \ && [ "${line_marker}" != "${LV_MARKER}" ] && continue + # Skip the host which is not specified in the host list + if ! ${USE_ALLNODES}; then + hostname=$(echo ${LINE} | cut -d, -f 1) + ! host_in_hostlist ${hostname} ${NODES_TO_USE} && continue + fi + # Parse the config line into CONFIG_ITEM if ! parse_line "$LINE"; then return 1 @@ -527,7 +552,7 @@ config_lvm() { failed_status=false for ((pid_num = 0; pid_num < ${#REMOTE_PID[@]}; pid_num++)); do wait ${REMOTE_PID[${pid_num}]} - if [ $? -ne 0 ]; then + if [ ${PIPESTATUS[0]} -ne 0 ]; then echo >&2 "`basename $0`: config_lvm() error: Failed"\ "to execute \"${REMOTE_CMD[${pid_num}]}\"!" failed_status=true @@ -548,6 +573,13 @@ if ! check_file $1; then exit 1 fi +# Get the list of nodes to be operated on +NODES_TO_USE=$(get_nodelist) +[ ${PIPESTATUS[0]} -ne 0 ] && echo >&2 "${NODES_TO_USE}" && exit 1 + +# Check the node list +check_nodelist ${NODES_TO_USE} || exit 1 + # Get all the LVM device items from the csv file if ! get_lvm_items ${CSV_FILE}; then exit 1 diff --git a/lustre/scripts/lc_md.sh.in b/lustre/scripts/lc_md.sh.in index 77a508f..48109d0 100644 --- a/lustre/scripts/lc_md.sh.in +++ b/lustre/scripts/lc_md.sh.in @@ -10,11 +10,17 @@ usage() { cat >&2 < +Usage: `basename $0` [options] This script is used to configure Linux MD devices in a Lustre cluster from a csv file. + Options: + -a select all the nodes from the csv file to operate on + -w hostname,hostname,... + select the specified list of nodes (separated by commas) + -x hostname,hostname,... + exclude the specified list of nodes (separated by commas) -h help and examples -v verbose mode csv file a spreadsheet that contains configuration parameters @@ -78,8 +84,20 @@ declare -i pid_num=0 VERBOSE_OUTPUT=false # Get and check the positional parameters -while getopts "hv" OPTION; do +while getopts "aw:x:hv" OPTION; do case $OPTION in + a) + [ -z "${SPECIFIED_NODELIST}" ] && [ -z "${EXCLUDED_NODELIST}" ] \ + && USE_ALLNODES=true + ;; + w) + USE_ALLNODES=false + SPECIFIED_NODELIST=$OPTARG + ;; + x) + USE_ALLNODES=false + EXCLUDED_NODELIST=$OPTARG + ;; h) sample ;; @@ -157,6 +175,7 @@ get_md_items() { CSV_FILE=$1 local LINE + local hostname declare -i line_num=0 declare -i idx=0 @@ -167,7 +186,13 @@ get_md_items() { [ -z "`echo \"${LINE}\" | egrep -v \"([[:space:]]|^)#\"`" ] && continue # Skip the non-MD line - [ "`echo ${LINE}|awk -F, '{print $2}'`" != "${MD_MARKER}" ] && continue + [ "$(echo ${LINE} | cut -d, -f 2)" != "${MD_MARKER}" ] && continue + + # Skip the host which is not specified in the host list + if ! ${USE_ALLNODES}; then + hostname=$(echo ${LINE} | cut -d, -f 1) + ! host_in_hostlist ${hostname} ${NODES_TO_USE} && continue + fi # Parse the config line into CONFIG_ITEM if ! parse_line "$LINE"; then @@ -203,8 +228,8 @@ md_is_active() { local cmd ret_str cmd="grep -q ${md_name##*/} /proc/mdstat 2>&1" - ret_str=`${REMOTE} ${host_name} "${cmd}" 2>&1` - if [ $? -ne 0 ]; then + ret_str=$(${REMOTE} ${host_name} "${cmd}" 2>&1) + if [ ${PIPESTATUS[0]} -ne 0 ]; then if [ -n "${ret_str}" ]; then echo >&2 "`basename $0`: md_is_active() error:"\ "remote command to ${host_name} error: ${ret_str}!" @@ -318,7 +343,7 @@ construct_mdadm_cmdline() { "" | create) # Check the status of the MD array md_is_active ${host_name} ${MD_NAME[i]} - rc=$? + rc=${PIPESTATUS[0]} if [ "$rc" -eq "2" ]; then return 1 elif [ "$rc" -eq "0" ]; then @@ -339,7 +364,7 @@ construct_mdadm_cmdline() { # Construct the create command line mdadm_cmd=$(construct_mdadm_create_cmdline ${i}) - if [ $? -ne 0 ]; then + if [ ${PIPESTATUS[0]} -ne 0 ]; then echo >&2 "${mdadm_cmd}" return 1 fi @@ -445,7 +470,7 @@ config_md() { failed_status=false for ((pid_num = 0; pid_num < ${#REMOTE_PID[@]}; pid_num++)); do wait ${REMOTE_PID[${pid_num}]} - if [ $? -ne 0 ]; then + if [ ${PIPESTATUS[0]} -ne 0 ]; then echo >&2 "`basename $0`: config_md() error: Failed"\ "to execute \"${REMOTE_CMD[${pid_num}]}\"!" failed_status=true @@ -466,6 +491,13 @@ if ! check_file $1; then exit 1 fi +# Get the list of nodes to be operated on +NODES_TO_USE=$(get_nodelist) +[ ${PIPESTATUS[0]} -ne 0 ] && echo >&2 "${NODES_TO_USE}" && exit 1 + +# Check the node list +check_nodelist ${NODES_TO_USE} || exit 1 + # Get all the MD device items from the csv file if ! get_md_items ${CSV_FILE}; then exit 1 diff --git a/lustre/scripts/lc_net.sh.in b/lustre/scripts/lc_net.sh.in index 26fe899..4bc889f 100644 --- a/lustre/scripts/lc_net.sh.in +++ b/lustre/scripts/lc_net.sh.in @@ -8,8 +8,14 @@ usage() { cat >&2 < - +Usage: `basename $0` [options] + + Options: + -a select all the nodes from the csv file to operate on + -w hostname,hostname,... + select the specified list of nodes (separated by commas) + -x hostname,hostname,... + exclude the specified list of nodes (separated by commas) -v verbose mode csv file a spreadsheet that contains configuration parameters (separated by commas) for each target in a Lustre cl- @@ -25,8 +31,20 @@ EOF VERBOSE_OUTPUT=false # Get and check the positional parameters -while getopts "v" OPTION; do +while getopts "aw:x:v" OPTION; do case $OPTION in + a) + [ -z "${SPECIFIED_NODELIST}" ] && [ -z "${EXCLUDED_NODELIST}" ]\ + && USE_ALLNODES=true + ;; + w) + USE_ALLNODES=false + SPECIFIED_NODELIST=$OPTARG + ;; + x) + USE_ALLNODES=false + EXCLUDED_NODELIST=$OPTARG + ;; v) VERBOSE_OUTPUT=true ;; @@ -49,34 +67,26 @@ CSV_FILE=$1 declare -a HOST_NAMES declare -a HOST_IPADDRS -# Get the host names from the csv file +# Get the hosts to be operated on get_hostnames() { - local NAME CHECK_STR - declare -i i - declare -i j + local NODES_TO_USE # Initialize the HOST_NAMES array unset HOST_NAMES - CHECK_STR=`egrep -v "([[:space:]]|^)#" ${CSV_FILE} | awk -F, \ - '/[[:alnum:]]/{if ($1 !~/[[:alnum:]]/) print $0}'` - if [ -n "${CHECK_STR}" ]; then - echo >&2 $"`basename $0`: get_hostnames() error: Missing"\ - "hostname field in the line - ${CHECK_STR}" + # Get the list of nodes to be operated on + NODES_TO_USE=$(get_nodelist) + [ ${PIPESTATUS[0]} -ne 0 ] && echo >&2 "${NODES_TO_USE}" && return 1 + + # Check the node list + if [ -z "${NODES_TO_USE}" ]; then + echo "`basename $0`: There are no hosts to be operated on."\ + "Check the node selection options (-a, -w or -x)." return 1 fi - i=0 - for NAME in `egrep -v "([[:space:]]|^)#" ${CSV_FILE}\ - | awk -F, '/[[:alnum:]]/{print $1}'` - do - for ((j = 0; j < ${#HOST_NAMES[@]}; j++)); do - [ "${NAME}" = "${HOST_NAMES[j]}" ] && continue 2 - done - - HOST_NAMES[i]=${NAME} - i=$i+1 - done + # Load the hostnames in the nodelist into the array + HOST_NAMES=( $(echo ${NODES_TO_USE//,/ }) ) return 0 } @@ -95,8 +105,8 @@ ping_host() { fi # Run ping command - ret_str=`ping -c1 ${host_name} 2>&1` - if [ $? -ne 0 ]; then + ret_str=$(ping -c1 ${host_name} 2>&1) + if [ ${PIPESTATUS[0]} -ne 0 ]; then if [ -n "${ret_str}" ]; then echo "`basename $0`: ping_host() error: ${ret_str}!" else @@ -122,7 +132,7 @@ local_check() { # Check whether ${HOST_NAMES[i]} is reachable # and get the IP address of this host from ping HOST_IPADDRS[i]=$(ping_host ${HOST_NAMES[i]}) - if [ $? -ne 0 ]; then + if [ ${PIPESTATUS[0]} -ne 0 ]; then echo >&2 "${HOST_IPADDRS[i]}" return 1 fi @@ -141,8 +151,8 @@ remote_check() { # Execute remote command to check whether ${HOST_NAMES[i]} # can resolve its own name cmd="ping -c1 ${HOST_NAMES[i]} 2>&1" - ret_str=`${REMOTE} ${HOST_NAMES[i]} "(${EXPORT_PATH} ${cmd})" 2>&1` - if [ $? -ne 0 -a -n "${ret_str}" ]; then + ret_str=$(${REMOTE} ${HOST_NAMES[i]} "${cmd}" 2>&1) + if [ ${PIPESTATUS[0]} -ne 0 -a -n "${ret_str}" ]; then echo >&2 "`basename $0`: remote_check() error:"\ "remote to ${HOST_NAMES[i]} error: ${ret_str}!" return 1 @@ -185,7 +195,7 @@ network_verify() { # Initialize the HOST_IPADDRS array unset HOST_IPADDRS - # Get all the host names from the csv file + # Get all the host names to be operated on ! get_hostnames && return 1 # Check the network connectivity between local host diff --git a/lustre/scripts/lustre_config.sh.in b/lustre/scripts/lustre_config.sh.in index 5ee082f..cde6aee 100644 --- a/lustre/scripts/lustre_config.sh.in +++ b/lustre/scripts/lustre_config.sh.in @@ -19,12 +19,19 @@ usage() { cat >&2 < +Usage: `basename $0` [options] This script is used to format and set up multiple lustre servers from a csv file. + Options: -h help and examples + -a select all the nodes from the csv file to operate on + -w hostname,hostname,... + select the specified list of nodes (separated by commas) to + operate on rather than all the nodes in the csv file + -x hostname,hostname,... + exclude the specified list of nodes (separated by commas) -t HAtype produce High-Availability software configurations The argument following -t is used to indicate the High- Availability software type. The HA software types which @@ -172,7 +179,7 @@ Example 2 - Separate MGS/MDT, two networks interfaces: lustre-mgs1,options lnet 'networks="tcp,elan"',/dev/sda,/mnt/mgs,mgs,,,,--quiet --param="sys.timeout=50",,"defaults,noauto","lustre-mgs2,2@elan" # mdt -lustre-mdt1,options lnet 'networks="tcp,elan"',/dev/sdb,/mnt/mdt,mdt,lustre2,"lustre-mgs1,1@elan:lustre-mgs2,2@elan",,--quiet --param="lov.stripe.size=4194304",-J size=16,"defaults,noauto",lustre-mdt2 +lustre-mdt1,options lnet 'networks="tcp,elan"',/dev/sdb,/mnt/mdt,mdt,lustre2,"lustre-mgs1,1@elan:lustre-mgs2,2@elan",,--quiet --param="lov.stripesize=4194304",-J size=16,"defaults,noauto",lustre-mdt2 # ost lustre-ost1,options lnet 'networks="tcp,elan"',/dev/sdc,/mnt/ost,ost,lustre2,"lustre-mgs1,1@elan:lustre-mgs2,2@elan",,--quiet,-I 512,"defaults,noauto",lustre-ost2 @@ -245,8 +252,23 @@ CONFIG_MD_LVM=false MODIFY_FSTAB=true VERBOSE_OUTPUT=false # Get and check the positional parameters -while getopts "t:ndfmhv" OPTION; do +while getopts "aw:x:t:ndfmhv" OPTION; do case $OPTION in + a) + [ -z "${SPECIFIED_NODELIST}" ] && [ -z "${EXCLUDED_NODELIST}" ] \ + && USE_ALLNODES=true + NODELIST_OPT="${NODELIST_OPT} -a" + ;; + w) + USE_ALLNODES=false + SPECIFIED_NODELIST=$OPTARG + NODELIST_OPT="${NODELIST_OPT} -w ${SPECIFIED_NODELIST}" + ;; + x) + USE_ALLNODES=false + EXCLUDED_NODELIST=$OPTARG + NODELIST_OPT="${NODELIST_OPT} -x ${EXCLUDED_NODELIST}" + ;; t) HATYPE_OPT=$OPTARG if [ "${HATYPE_OPT}" != "${HBVER_HBV1}" ] \ @@ -583,7 +605,7 @@ get_nodenames() { for nids in ${FAILOVERS_NAMES[i]//:/ } do NODE_NAMES[idx]=$(nids2hostname ${nids}) - if [ $? -ne 0 ]; then + if [ ${PIPESTATUS[0]} -ne 0 ]; then echo >&2 "${NODE_NAMES[idx]}" return 1 fi @@ -647,7 +669,7 @@ gen_ha_config() { "${HOST_NAME[i]} failover group..." verbose_output "${cmd_line}" eval $(echo "${cmd_line}") - if [ $? -ne 0 ]; then + if [ ${PIPESTATUS[0]} -ne 0 ]; then return 1 fi verbose_output "Generate HA software's configurations in"\ @@ -715,7 +737,6 @@ config_ha() { return 0 } - # Get all the items in the csv file and do some checks. get_items() { # Check argument @@ -728,6 +749,7 @@ get_items() { CSV_FILE=$1 local LINE local marker + local hostname declare -i line_num=0 declare -i idx=0 @@ -747,12 +769,18 @@ get_items() { fi # Skip the Linux MD/LVM line - marker=`echo ${LINE} | awk -F, '{print $2}'` + marker=$(echo ${LINE} | cut -d, -f 2) if [ "${marker}" = "${MD_MARKER}" -o "${marker}" = "${PV_MARKER}" ] \ || [ "${marker}" = "${VG_MARKER}" -o "${marker}" = "${LV_MARKER}" ]; then continue fi + # Skip the host which is not specified in the host list + if ! ${USE_ALLNODES}; then + hostname=$(echo ${LINE} | cut -d, -f 1) + ! host_in_hostlist ${hostname} ${NODES_TO_USE} && continue + fi + # Parse the config line into CONFIG_ITEM if ! parse_line "$LINE"; then echo >&2 $"`basename $0`: parse_line() error: Occurred"\ @@ -777,13 +805,13 @@ get_items() { # Convert IP addresses in NIDs to hostnames MGS_NIDS_NAMES[idx]=$(ip2hostname_multi_node ${MGS_NIDS[idx]}) - if [ $? -ne 0 ]; then + if [ ${PIPESTATUS[0]} -ne 0 ]; then echo >&2 "${MGS_NIDS_NAMES[idx]}" return 1 fi FAILOVERS_NAMES[idx]=$(ip2hostname_multi_node ${FAILOVERS[idx]}) - if [ $? -ne 0 ]; then + if [ ${PIPESTATUS[0]} -ne 0 ]; then echo >&2 "${FAILOVERS_NAMES[idx]}" return 1 fi @@ -832,7 +860,7 @@ check_lnet_connect() { else for nids in ${MGS_NIDS[i]//:/ }; do nids_names=$(ip2hostname_single_node ${nids}) - if [ $? -ne 0 ]; then + if [ ${PIPESTATUS[0]} -ne 0 ]; then echo >&2 "${nids_names}" return 1 fi @@ -853,8 +881,8 @@ check_lnet_connect() { for mgs_nid in ${nids_str//,/ } do COMMAND=$"${LCTL} ping ${mgs_nid} 5 || echo failed 2>&1" - RET_STR=`${REMOTE} ${HOST_NAME[i]} "${COMMAND}" 2>&1` - if [ $? -eq 0 -a "${RET_STR}" = "${RET_STR#*failed*}" ] + RET_STR=$(${REMOTE} ${HOST_NAME[i]} "${COMMAND}" 2>&1) + if [ ${PIPESTATUS[0]} -eq 0 -a "${RET_STR}" = "${RET_STR#*failed*}" ] then # This node can contact the MGS node verbose_output "${HOST_NAME[i]} can contact the MGS" \ @@ -894,9 +922,9 @@ check_lnet() { # Execute remote command to start lnet network verbose_output "Starting lnet network in ${HOST_NAME[i]}" - COMMAND=$"modprobe lnet; ${LCTL} network up 2>&1" - RET_STR=`${REMOTE} ${HOST_NAME[i]} "(${EXPORT_PATH} ${COMMAND})" 2>&1` - if [ $? -ne 0 -o "${RET_STR}" = "${RET_STR#*LNET configured*}" ] + COMMAND="PATH=\$PATH:/sbin:/usr/sbin modprobe lnet; ${LCTL} network up 2>&1" + RET_STR=$(${REMOTE} ${HOST_NAME[i]} "${COMMAND}" 2>&1) + if [ ${PIPESTATUS[0]} -ne 0 -o "${RET_STR}" = "${RET_STR#*LNET configured*}" ] then echo >&2 "`basename $0`: check_lnet() error: remote" \ "${HOST_NAME[i]} error: ${RET_STR}" @@ -925,7 +953,11 @@ start_mgs_lnet() { local COMMAND if [ -z "${MGS_NODENAME[0]}" -a -z "${MGS_NODENAME[1]}" ]; then - verbose_output "There is no MGS target in the ${CSV_FILE} file." + if ${USE_ALLNODES}; then + verbose_output "There is no MGS target in the ${CSV_FILE} file." + else + verbose_output "There is no MGS target in the node list \"${NODES_TO_USE}\"." + fi return 0 fi @@ -936,7 +968,7 @@ start_mgs_lnet() { COMMAND=$"echo \"${MODULE_OPTS[${idx}]}\"|${MODULE_CONFIG}" verbose_output "Adding lnet module options to ${MGS_NODENAME[i]}" ${REMOTE} ${MGS_NODENAME[i]} "${COMMAND}" >&2 - if [ $? -ne 0 ]; then + if [ ${PIPESTATUS[0]} -ne 0 ]; then echo >&2 "`basename $0`: start_mgs_lnet() error:"\ "Failed to execute remote command to" \ "add module options to ${MGS_NODENAME[i]}!"\ @@ -982,8 +1014,8 @@ mass_config() { COMMAND="mkdir -p ${MOUNT_POINT[i]}" verbose_output "Creating the mount point ${MOUNT_POINT[i]} on" \ "${HOST_NAME[i]}" - ${REMOTE} ${HOST_NAME[i]} "(${EXPORT_PATH} ${COMMAND})" >&2 - if [ $? -ne 0 ]; then + ${REMOTE} ${HOST_NAME[i]} "${COMMAND}" >&2 + if [ ${PIPESTATUS[0]} -ne 0 ]; then echo >&2 "`basename $0`: mass_config() error:"\ "Failed to execute remote command to"\ "create the mountpoint on ${HOST_NAME[i]}!" @@ -997,7 +1029,7 @@ mass_config() { verbose_output "Adding lnet module options to" \ "${HOST_NAME[i]}" ${REMOTE} ${HOST_NAME[i]} "${COMMAND}" >&2 - if [ $? -ne 0 ]; then + if [ ${PIPESTATUS[0]} -ne 0 ]; then echo >&2 "`basename $0`: mass_config() error:"\ "Failed to execute remote command to"\ "add module options to ${HOST_NAME[i]}!" @@ -1025,7 +1057,7 @@ mass_config() { fail_exit_status=false for ((pid_num = 0; pid_num < ${#REMOTE_PID[@]}; pid_num++)); do wait ${REMOTE_PID[${pid_num}]} - if [ $? -ne 0 ]; then + if [ ${PIPESTATUS[0]} -ne 0 ]; then echo >&2 "`basename $0`: mass_config() error: Failed"\ "to execute \"${REMOTE_CMD[${pid_num}]}\"!" fail_exit_status=true @@ -1053,9 +1085,9 @@ get_mntopts() { # Execute remote command to check whether the device # is a block device or not - ret_str=`${REMOTE} ${host_name} \ - "[ -b ${device_name} ] && echo block || echo loop" 2>&1` - if [ $? -ne 0 -a -n "${ret_str}" ]; then + ret_str=$(${REMOTE} ${host_name} \ + "[ -b ${device_name} ] && echo block || echo loop" 2>&1) + if [ ${PIPESTATUS[0]} -ne 0 -a -n "${ret_str}" ]; then echo "`basename $0`: get_mntopts() error:" \ "remote command to ${host_name} error: ${ret_str}" return 1 @@ -1096,7 +1128,7 @@ modify_fstab() { else mntopts=$(get_mntopts ${HOST_NAME[i]} ${DEVICE_NAME[i]}\ ${FAILOVERS[i]}) - if [ $? -ne 0 ]; then + if [ ${PIPESTATUS[0]} -ne 0 ]; then echo >&2 "${mntopts}" return 1 fi @@ -1110,8 +1142,8 @@ modify_fstab() { COMMAND=". @scriptlibdir@/lc_common.sh; \ sed -i \"/^${device_name}\t/d\" \$(fcanon /etc/fstab); \ echo -e \"${mntent}\" >> \$(fcanon /etc/fstab)" - ${REMOTE} ${HOST_NAME[i]} "(${EXPORT_PATH} ${COMMAND})" >&2 - if [ $? -ne 0 ]; then + ${REMOTE} ${HOST_NAME[i]} "${COMMAND}" >&2 + if [ ${PIPESTATUS[0]} -ne 0 ]; then echo >&2 "`basename $0`: modify_fstab() error:"\ "Failed to modify /etc/fstab of host ${HOST_NAME[i]}"\ "to add Lustre target ${DEVICE_NAME[i]}!" @@ -1125,14 +1157,21 @@ modify_fstab() { # Main flow # Check the csv file if ! check_file $1; then - exit 1 + exit 1 fi +# Get the list of nodes to be operated on +NODES_TO_USE=$(get_nodelist) +[ ${PIPESTATUS[0]} -ne 0 ] && echo >&2 "${NODES_TO_USE}" && exit 1 + +# Check the node list +check_nodelist ${NODES_TO_USE} || exit 1 + if ${VERIFY_CONNECT}; then # Check the network connectivity and hostnames echo "`basename $0`: Checking the cluster network connectivity"\ "and hostnames..." - if ! ${VERIFY_CLUSTER_NET} ${VERBOSE_OPT} ${CSV_FILE}; then + if ! ${VERIFY_CLUSTER_NET} ${NODELIST_OPT} ${VERBOSE_OPT} ${CSV_FILE}; then exit 1 fi echo "`basename $0`: Check the cluster network connectivity"\ @@ -1143,11 +1182,11 @@ fi if ${CONFIG_MD_LVM}; then # Configure Linux MD/LVM devices echo "`basename $0`: Configuring Linux MD/LVM devices..." - if ! ${SCRIPT_CONFIG_MD} ${VERBOSE_OPT} ${CSV_FILE}; then + if ! ${SCRIPT_CONFIG_MD} ${NODELIST_OPT} ${VERBOSE_OPT} ${CSV_FILE}; then exit 1 fi - if ! ${SCRIPT_CONFIG_LVM} ${VERBOSE_OPT} ${CSV_FILE}; then + if ! ${SCRIPT_CONFIG_LVM} ${NODELIST_OPT} ${VERBOSE_OPT} ${CSV_FILE}; then exit 1 fi echo "`basename $0`: Configure Linux MD/LVM devices OK!" -- 1.8.3.1