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
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
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
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
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
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
+}
usage() {
cat >&2 <<EOF
-Usage: `basename $0` [-h] [-v] <csv file>
+Usage: `basename $0` [options] <csv file>
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
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
;;
CSV_FILE=$1
local LINE line_marker
+ local hostname
declare -i line_num=0
declare -i idx=0
[ -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
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
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
usage() {
cat >&2 <<EOF
-Usage: `basename $0` [-h] [-v] <csv file>
+Usage: `basename $0` [options] <csv file>
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
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
;;
CSV_FILE=$1
local LINE
+ local hostname
declare -i line_num=0
declare -i idx=0
[ -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
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}!"
"" | 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
# 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
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
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
usage() {
cat >&2 <<EOF
-Usage: `basename $0` [-v] <csv file>
-
+Usage: `basename $0` [options] <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)
-v verbose mode
csv file a spreadsheet that contains configuration parameters
(separated by commas) for each target in a Lustre cl-
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
;;
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
}
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
# 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
# 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
# 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
usage() {
cat >&2 <<EOF
-Usage: `basename $0` [-t HAtype] [-n] [-d] [-f] [-m] [-h] [-v] <csv file>
+Usage: `basename $0` [options] <csv file>
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
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
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}" ] \
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
"${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"\
return 0
}
-
# Get all the items in the csv file and do some checks.
get_items() {
# Check argument
CSV_FILE=$1
local LINE
local marker
+ local hostname
declare -i line_num=0
declare -i idx=0
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"\
# 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
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
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" \
# 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}"
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
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]}!"\
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]}!"
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]}!"
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
# 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
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
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]}!"
# 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"\
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!"