3 # vim:expandtab:shiftwidth=4:softtabstop=4:tabstop=4:
6 # lustre_config - format and set up multiple lustre servers from a csv file
8 # This script is used to parse each line of a spreadsheet (csv file) and
9 # execute remote commands to format (mkfs.lustre) every Lustre target
10 # that will be part of the Lustre cluster.
12 # In addition, it can also verify the network connectivity and hostnames in
13 # the cluster, configure Linux MD/LVM devices and produce High-Availability
14 # software configurations for Heartbeat or CluManager.
16 ################################################################################
22 Usage: $(basename $0) [options] <-a|-w|-x> <csv file>
24 This script is used to format and set up multiple lustre servers from a
29 -a select all the nodes from the csv file to operate on
30 -w hostname,hostname,...
31 select the specified list of nodes (separated by commas) to
32 operate on rather than all the nodes in the csv file
33 -x hostname,hostname,...
34 exclude the specified list of nodes (separated by commas)
35 -t HAtype produce High-Availability software configurations
36 The argument following -t is used to indicate the High-
37 Availability software type. The HA software types which
38 are currently supported are: hbv1 (Heartbeat version 1)
39 and hbv2 (Heartbeat version 2).
40 -n no net - don't verify network connectivity and hostnames
42 -d configure Linux MD/LVM devices before formatting the
44 -f force-format the Lustre targets using --reformat option
45 -m no fstab change - don't modify /etc/fstab to add the new
47 If using this option, then the value of "mount options"
48 item in the csv file will be passed to mkfs.lustre, else
49 the value will be added into the /etc/fstab.
50 -u upgrade Lustre targets from 1.4 to 1.6
52 csv file a spreadsheet that contains configuration parameters
53 (separated by commas) for each target in a Lustre cluster
62 This script is used to parse each line of a spreadsheet (csv file) and
63 execute remote commands to format (mkfs.lustre) every Lustre target
64 that will be part of the Lustre cluster.
66 It can also optionally:
67 * upgrade Lustre targets from 1.4 to 1.6
68 It does not support "rolling upgrade". Before upgrading, the entire Lustre
69 filesystem (all servers and clients) need be shut down. After upgrading, old
70 configuration logs for the filesystem would be erased and new configuration
71 logs would be regenerated as Lustre servers restart.
72 * verify the network connectivity and hostnames in the cluster
73 * configure Linux MD/LVM devices
74 * modify /etc/modprobe.conf to add Lustre networking info
75 * add the Lustre server info to /etc/fstab
76 * produce configurations for Heartbeat or CluManager.
78 There are 5 kinds of line formats in the csv file. They represent the following
82 hostname,MD,md name,operation mode,options,raid level,component devices
84 hostname hostname of the node in the cluster
85 MD marker of MD device line
86 md name MD device name, e.g. /dev/md0
87 operation mode create or remove, default is create
88 options a "catchall" for other mdadm options, e.g. "-c 128"
89 raid level raid level: 0,1,4,5,6,10,linear and multipath
90 component devices block devices to be combined into the MD device
91 Multiple devices are separated by space or by using
92 shell expansions, e.g. "/dev/sd{a,b,c}"
94 2) Linux LVM PV (Physical Volume)
96 hostname,PV,pv names,operation mode,options
98 hostname hostname of the node in the cluster
100 pv names devices or loopback files to be initialized for later
101 use by LVM or to be wiped the label, e.g. /dev/sda
102 Multiple devices or files are separated by space or by
103 using shell expansions, e.g. "/dev/sd{a,b,c}"
104 operation mode create or remove, default is create
105 options a "catchall" for other pvcreate/pvremove options
108 3) Linux LVM VG (Volume Group)
110 hostname,VG,vg name,operation mode,options,pv paths
112 hostname hostname of the node in the cluster
114 vg name name of the volume group, e.g. ost_vg
115 operation mode create or remove, default is create
116 options a "catchall" for other vgcreate/vgremove options
118 pv paths physical volumes to construct this VG, required by
120 Multiple PVs are separated by space or by using
121 shell expansions, e.g. "/dev/sd[k-m]1"
123 4) Linux LVM LV (Logical Volume)
125 hostname,LV,lv name,operation mode,options,lv size,vg name
127 hostname hostname of the node in the cluster
129 lv name name of the logical volume to be created (optional)
130 or path of the logical volume to be removed (required
132 operation mode create or remove, default is create
133 options a "catchall" for other lvcreate/lvremove options
135 lv size size [kKmMgGtT] to be allocated for the new LV
136 Default unit is megabytes.
137 vg name name of the VG in which the new LV will be created
141 hostname,module_opts,device name,mount point,device type,fsname,mgs nids,index,
142 format options,mkfs options,mount options,failover nids
144 hostname hostname of the node in the cluster, must match "uname -n"
145 module_opts Lustre networking module options
146 device name Lustre target (block device or loopback file)
147 mount point Lustre target mount point
148 device type Lustre target type (mgs, mdt, ost, mgs|mdt, mdt|mgs)
149 fsname Lustre filesystem name, should be limited to 8 characters
151 mgs nids NID(s) of remote mgs node, required for mdt and ost targets
152 If this item is not given for an mdt, it is assumed that
153 the mdt will also be an mgs, according to mkfs.lustre.
154 index Lustre target index
155 format options a "catchall" contains options to be passed to mkfs.lustre
156 "--device-size", "--param", etc. all goes into this item.
157 mkfs options format options to be wrapped with --mkfsoptions="" and
158 passed to mkfs.lustre
159 mount options If this script is invoked with "-m" option, then the value of
160 this item will be wrapped with --mountfsoptions="" and passed
161 to mkfs.lustre, else the value will be added into /etc/fstab.
162 failover nids NID(s) of failover partner node
164 All the NIDs in one node are delimited by commas (','). When multiple nodes are
165 specified, they are delimited by a colon (':').
167 Items left blank will be set to defaults.
169 Example 1 - Simple, with combo MGS/MDT:
170 -------------------------------------------------------------------------------
172 lustre-mgs,options lnet networks=tcp,/tmp/mgs,/mnt/mgs,mgs|mdt,,,,--device-size=10240
175 lustre-ost,options lnet networks=tcp,/tmp/ost0,/mnt/ost0,ost,,lustre-mgs@tcp0,,--device-size=10240
178 lustre-ost,options lnet networks=tcp,/tmp/ost1,/mnt/ost1,ost,,lustre-mgs@tcp0,,--device-size=10240
179 -------------------------------------------------------------------------------
181 Example 2 - Separate MGS/MDT, two networks interfaces:
182 -------------------------------------------------------------------------------
184 lustre-mgs1,options lnet 'networks="tcp,elan"',/dev/sda,/mnt/mgs,mgs,,,,--quiet --param="sys.timeout=50",,"defaults,noauto","lustre-mgs2,2@elan"
187 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
190 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
191 -------------------------------------------------------------------------------
193 Example 3 - with combo MGS/MDT failover pair and OST failover pair:
194 -------------------------------------------------------------------------------
196 lustre-mgs1,options lnet networks=tcp,/tmp/mgs,/mnt/mgs,mgs|mdt,,,,--quiet --device-size=10240,,,lustre-mgs2@tcp0
198 # combo mgs/mdt backup (--noformat)
199 lustre-mgs2,options lnet networks=tcp,/tmp/mgs,/mnt/mgs,mgs|mdt,,,,--quiet --device-size=10240 --noformat,,,lustre-mgs1@tcp0
202 lustre-ost1,options lnet networks=tcp,/tmp/ost1,/mnt/ost1,ost,,"lustre-mgs1@tcp0:lustre-mgs2@tcp0",,--quiet --device-size=10240,,,lustre-ost2@tcp0
204 # ost backup (--noformat) (note different device name)
205 lustre-ost2,options lnet networks=tcp,/tmp/ost2,/mnt/ost2,ost,,"lustre-mgs1@tcp0:lustre-mgs2@tcp0",,--quiet --device-size=10240 --noformat,,,lustre-ost1@tcp0
206 -------------------------------------------------------------------------------
208 Example 4 - Configure Linux MD/LVM devices before formatting Lustre targets:
209 -------------------------------------------------------------------------------
210 # MD device on mgsnode
211 mgsnode,MD,/dev/md0,,-q,1,/dev/sda1 /dev/sdb1
213 # MD/LVM devices on ostnode
214 ostnode,MD,/dev/md0,,-q -c 128,5,"/dev/sd{a,b,c}"
215 ostnode,MD,/dev/md1,,-q -c 128,5,"/dev/sd{d,e,f}"
216 ostnode,PV,/dev/md0 /dev/md1
217 ostnode,VG,ost_vg,,-s 32M,/dev/md0 /dev/md1
218 ostnode,LV,ost0,,-i 2 -I 128,300G,ost_vg
219 ostnode,LV,ost1,,-i 2 -I 128,300G,ost_vg
222 mgsnode,options lnet networks=tcp,/dev/md0,/mnt/mgs,mgs|mdt,,,,--quiet
225 ostnode,options lnet networks=tcp,/dev/ost_vg/ost0,/mnt/ost0,ost,,mgsnode,,--quiet
228 ostnode,options lnet networks=tcp,/dev/ost_vg/ost1,/mnt/ost1,ost,,mgsnode,,--quiet
229 -------------------------------------------------------------------------------
235 # Get the library of functions
236 . @scriptlibdir@/lc_common
238 #***************************** Global variables *****************************#
239 declare -a NODE_NAMES # node names in the failover group
240 declare -a TARGET_OPTS # target services in one failover group
245 # Get and check the positional parameters
246 while getopts "aw:x:t:ndfmuhv" OPTION; do
249 [ -z "${SPECIFIED_NODELIST}" ] && [ -z "${EXCLUDED_NODELIST}" ] \
251 NODELIST_OPT="${NODELIST_OPT} -a"
255 SPECIFIED_NODELIST=$OPTARG
256 NODELIST_OPT="${NODELIST_OPT} -w ${SPECIFIED_NODELIST}"
260 EXCLUDED_NODELIST=$OPTARG
261 NODELIST_OPT="${NODELIST_OPT} -x ${EXCLUDED_NODELIST}"
265 if [ "${HATYPE_OPT}" != "${HBVER_HBV1}" ] \
266 && [ "${HATYPE_OPT}" != "${HBVER_HBV2}" ] \
267 && [ "${HATYPE_OPT}" != "${HATYPE_CLUMGR}" ]; then
268 error_output "Invalid HA software type" \
281 REFORMAT_OPTION=$"--reformat "
304 # Toss out the parameters we've already processed
305 shift `expr $OPTIND - 1`
307 # Here we expect the csv file
308 if [ $# -eq 0 ]; then
309 error_output "Missing csv file!"
316 # Construct the command line of mkfs.lustre
317 construct_mkfs_cmdline() {
319 if [ $# -eq 0 ]; then
320 error_output "construct_mkfs_cmdline():"\
321 "Missing argument for function construct_mkfs_cmdline()!"
326 local mgsnids mgsnids_str
327 local failnids failnids_str
329 if $UPGRADE_TARGET; then
330 MKFS_CMD="$TUNEFS --writeconf"
332 MKFS_CMD="$MKFS $REFORMAT_OPTION"
335 case "${DEVICE_TYPE[i]}" in
337 MKFS_CMD="$MKFS_CMD --ost"
340 MKFS_CMD="$MKFS_CMD --mdt"
341 $UPGRADE_TARGET && [ -n "${MGS_NIDS[i]}" ] && \
342 MKFS_CMD="$MKFS_CMD --nomgs"
345 MKFS_CMD="$MKFS_CMD --mgs"
347 "mdt|mgs" | "mgs|mdt")
348 MKFS_CMD="$MKFS_CMD --mgs --mdt"
351 error_output "construct_mkfs_cmdline():"\
352 "Invalid device type - \"${DEVICE_TYPE[i]}\"!"
357 if [ -n "${FS_NAME[i]}" ]; then
358 MKFS_CMD="$MKFS_CMD --fsname=${FS_NAME[i]}"
361 if [ -n "${MGS_NIDS[i]}" ]; then
362 mgsnids_str=${MGS_NIDS[i]}
363 for mgsnids in ${mgsnids_str//:/ }; do
364 MKFS_CMD="$MKFS_CMD --mgsnode=$mgsnids"
368 if [ -n "${INDEX[i]}" ]; then
369 MKFS_CMD="$MKFS_CMD --index=${INDEX[i]}"
372 if [ -n "${FORMAT_OPTIONS[i]}" ]; then
373 MKFS_CMD="$MKFS_CMD ${FORMAT_OPTIONS[i]}"
376 if ! $UPGRADE_TARGET && [ -n "${MKFS_OPTIONS[i]}" ]; then
377 MKFS_CMD="$MKFS_CMD --mkfsoptions=\"${MKFS_OPTIONS[i]}\""
380 if [ -n "${MOUNT_OPTIONS[i]}" ] && ! $MODIFY_FSTAB; then
381 MKFS_CMD="$MKFS_CMD --mountfsoptions=\"${MOUNT_OPTIONS[i]}\""
384 if [ -n "${FAILOVERS[i]}" ]; then
385 failnids_str=${FAILOVERS[i]}
386 for failnids in ${failnids_str//:/ }; do
387 MKFS_CMD="$MKFS_CMD --failnode=$failnids"
391 MKFS_CMD="$MKFS_CMD ${DEVICE_NAME[i]}"
395 # Get all the node names in this failover group
398 if [ $# -eq 0 ]; then
399 error_output "get_nodenames(): Missing"\
400 "argument for function get_nodenames()!"
408 # Initialize the NODE_NAMES array
411 NODE_NAMES[0]=${HOST_NAME[i]}
414 for nids in ${FAILOVERS_NAMES[i]//:/ }
416 NODE_NAMES[idx]=$(nids2hostname ${nids})
417 if [ ${PIPESTATUS[0]} -ne 0 ]; then
418 error_output "${NODE_NAMES[idx]}"
428 # Verify whether the format line has HA items
432 [ -n "${FAILOVERS[i]}" ] && return 0
437 # Produce HA software's configuration files
445 HOSTNAME_OPT=${HOST_NAME[i]}
447 if ! get_nodenames $i; then
448 error_output "gen_ha_config(): Can not get the"\
449 "failover nodenames from failover nids - \"${FAILOVERS[i]}\" in"\
450 "the \"${HOST_NAME[i]}\" failover group!"
454 for ((idx = 1; idx < ${#NODE_NAMES[@]}; idx++)); do
455 HOSTNAME_OPT=${HOSTNAME_OPT}$":"${NODE_NAMES[idx]}
458 # Target devices option
459 DEVICE_OPT=" -d "${TARGET_OPTS[0]}
460 for ((idx = 1; idx < ${#TARGET_OPTS[@]}; idx++)); do
461 DEVICE_OPT=${DEVICE_OPT}" -d "${TARGET_OPTS[idx]}
464 # Construct the generation script command line
465 case "${HATYPE_OPT}" in
466 "${HBVER_HBV1}"|"${HBVER_HBV2}") # Heartbeat
467 cmd_line=${GEN_HB_CONFIG}$" -r ${HATYPE_OPT} -n ${HOSTNAME_OPT}"
468 cmd_line=${cmd_line}${DEVICE_OPT}${VERBOSE_OPT}
470 "${HATYPE_CLUMGR}") # CluManager
471 cmd_line=${GEN_CLUMGR_CONFIG}$" -n ${HOSTNAME_OPT}"
472 cmd_line=${cmd_line}${DEVICE_OPT}${VERBOSE_OPT}
476 # Execute script to generate HA software's configuration files
477 verbose_output "Generating HA software's configurations in"\
478 "${HOST_NAME[i]} failover group..."
479 verbose_output "${cmd_line}"
480 eval $(echo "${cmd_line}")
481 if [ ${PIPESTATUS[0]} -ne 0 ]; then
484 verbose_output "Generate HA software's configurations in"\
485 "${HOST_NAME[i]} failover group OK"
490 # Configure HA software
492 if $UPGRADE_TARGET || [ -z "${HATYPE_OPT}" ]; then
497 declare -i prim_idx # Index for PRIM_HOSTNAMES array
498 declare -i target_idx # Index for TARGET_OPTS and HOST_INDEX arrays
500 declare -a PRIM_HOSTNAMES # Primary hostnames in all the failover
501 # groups in the lustre cluster
502 declare -a HOST_INDEX # Indices for the same node in all the
503 # format lines in the csv file
506 # Initialize the PRIM_HOSTNAMES array
510 # Get failover groups and generate HA configuration files
511 for ((i = 0; i < ${#HOST_NAME[@]}; i++)); do
512 prim_host=${HOST_NAME[i]}
514 for ((j = 0; j < ${#PRIM_HOSTNAMES[@]}; j++)); do
515 [ "${prim_host}" = "${PRIM_HOSTNAMES[j]}" ] && continue 2
521 for ((k = 0; k < ${#HOST_NAME[@]}; k++)); do
522 if [ "${prim_host}" = "${HOST_NAME[k]}" ] && is_ha_line "${k}"
524 HOST_INDEX[target_idx]=$k
525 TARGET_OPTS[target_idx]=${DEVICE_NAME[k]}:${MOUNT_POINT[k]}
526 target_idx=$(( target_idx + 1 ))
530 if [ ${#TARGET_OPTS[@]} -ne 0 ]; then
531 PRIM_HOSTNAMES[prim_idx]=${prim_host}
532 prim_idx=$(( prim_idx + 1 ))
534 if ! gen_ha_config ${HOST_INDEX[0]}; then
540 if [ ${#PRIM_HOSTNAMES[@]} -eq 0 ]; then
541 verbose_output "There are no \"failover nids\" items in the"\
542 "csv file. No HA configuration files are generated!"
549 # Execute remote command to add lnet options lines to remote nodes'
550 # modprobe.conf/modules.conf and format(mkfs.lustre) Lustre targets
553 declare -a REMOTE_PID
554 declare -a REMOTE_CMD
557 local checked_hosts=""
559 if [ ${#HOST_NAME[@]} -eq 0 ]; then
560 verbose_output "There are no Lustre targets specified."
564 if ! $UPGRADE_TARGET; then
565 # Start lnet network in the MGS node
566 start_mgs_lnet || return 1
569 for ((i = 0; i < ${#HOST_NAME[@]}; i++)); do
570 # Construct the command line of mkfs.lustre
571 if ! construct_mkfs_cmdline $i; then
575 # create the mount point on the node
576 COMMAND="mkdir -p ${MOUNT_POINT[i]}"
577 verbose_output "Creating the mount point ${MOUNT_POINT[i]} on" \
579 ${REMOTE} ${HOST_NAME[i]} "${COMMAND}" >&2
580 if [ ${PIPESTATUS[0]} -ne 0 ]; then
581 error_output "mass_config():"\
582 "Failed to execute remote command to"\
583 "create the mountpoint on ${HOST_NAME[i]}!"
587 if ! $UPGRADE_TARGET && ! is_mgs_node ${HOST_NAME[i]} && \
588 ! host_in_hostlist ${HOST_NAME[i]} $checked_hosts; then
589 # Execute remote command to add lnet options lines to
590 # modprobe.conf/modules.conf
591 add_module_options $i ${HOST_NAME[i]} || return ${PIPESTATUS[0]}
593 # Check lnet networks
594 check_lnet $i || return ${PIPESTATUS[0]}
596 checked_hosts="$checked_hosts,${HOST_NAME[i]}"
599 # Execute remote command to format or upgrade Lustre target
601 $UPGRADE_TARGET && OP="Upgrading" || OP="Formatting"
602 verbose_output "$OP Lustre target ${DEVICE_NAME[i]} on ${HOST_NAME[i]}..."
604 COMMAND="export PATH=\$PATH:/sbin:/usr/sbin; $MKFS_CMD"
605 REMOTE_CMD[$pid_num]="$REMOTE ${HOST_NAME[i]} \"$COMMAND\""
606 verbose_output "$OP command line is: ${REMOTE_CMD[$pid_num]}"
608 $REMOTE ${HOST_NAME[i]} "$COMMAND" &
609 REMOTE_PID[$pid_num]=$!
610 let pid_num=$pid_num+1
614 # Wait for the exit status of the background remote command
615 verbose_output "Waiting for the return of the remote command..."
616 fail_exit_status=false
617 for ((pid_num = 0; pid_num < ${#REMOTE_PID[@]}; pid_num++)); do
618 wait ${REMOTE_PID[${pid_num}]}
619 if [ ${PIPESTATUS[0]} -ne 0 ]; then
620 error_output "mass_config(): Failed"\
621 "to execute \"${REMOTE_CMD[${pid_num}]}\"!"
622 fail_exit_status=true
626 if ${fail_exit_status}; then
630 verbose_output "Success on all Lustre targets!"
634 # get_mntopts hostname device_name failovers
635 # Construct the mount options of Lustre target @device_name in host @hostname
643 [ -n "${failovers}" ] && mnt_opts=defaults,noauto || mnt_opts=defaults
645 # Execute remote command to check whether the device
646 # is a block device or not
647 ret_str=$(${REMOTE} ${host_name} \
648 "[ -b ${device_name} ] && echo block || echo loop" 2>&1)
649 if [ ${PIPESTATUS[0]} -ne 0 -a -n "${ret_str}" ]; then
650 echo "`basename $0`: get_mntopts() error:" \
651 "remote command to ${host_name} error: ${ret_str}"
655 if [ -z "${ret_str}" ]; then
656 echo "`basename $0`: get_mntopts() error: remote error:" \
657 "No results from remote!" \
658 "Check network connectivity between the local host and ${host_name}!"
662 [ "${ret_str}" != "${ret_str#*loop}" ] && mnt_opts=${mnt_opts},loop
668 # Execute remote command to modify /etc/fstab to add the new Lustre targets
671 local mntent mntopts device_name
674 if ! ${MODIFY_FSTAB}; then
678 for ((i = 0; i < ${#HOST_NAME[@]}; i++)); do
679 verbose_output "Modify /etc/fstab of host ${HOST_NAME[i]}"\
680 "to add Lustre target ${DEVICE_NAME[i]}"
681 mntent=${DEVICE_NAME[i]}"\t\t"${MOUNT_POINT[i]}"\t\t"${FS_TYPE}
684 if [ -n "${MOUNT_OPTIONS[i]}" ]; then
685 # The mount options already specified in the csv file.
686 mntopts="${MOUNT_OPTIONS[i]}"
688 mntopts=$(get_mntopts ${HOST_NAME[i]} ${DEVICE_NAME[i]}\
690 if [ ${PIPESTATUS[0]} -ne 0 ]; then
691 error_output "${mntopts}"
696 mntent=${mntent}"\t"${mntopts}"\t"0" "0
697 verbose_output "`echo -e ${mntent}`"
699 # Execute remote command to modify /etc/fstab
700 device_name=${DEVICE_NAME[i]//\//\\/}
701 COMMAND=". @scriptlibdir@/lc_common; \
702 sed -i \"/^${device_name}\t/d\" \$(fcanon /etc/fstab); \
703 echo -e \"${mntent}\" >> \$(fcanon /etc/fstab)"
704 ${REMOTE} ${HOST_NAME[i]} "${COMMAND}" >&2
705 if [ ${PIPESTATUS[0]} -ne 0 ]; then
706 error_output "modify_fstab():"\
707 "Failed to modify /etc/fstab of host ${HOST_NAME[i]}"\
708 "to add Lustre target ${DEVICE_NAME[i]}!"
716 #********************************* Main Flow **********************************#
719 check_file $CSV_FILE || exit ${PIPESTATUS[0]}
721 # Get the list of nodes to be operated on
722 NODES_TO_USE=$(get_nodelist) || error_exit ${PIPESTATUS[0]} "$NODES_TO_USE"
724 # Check the node list
725 check_nodelist $NODES_TO_USE || exit ${PIPESTATUS[0]}
727 if ${VERIFY_CONNECT}; then
728 # Check the network connectivity and hostnames
729 echo "`basename $0`: Checking the cluster network connectivity"\
731 if ! ${VERIFY_CLUSTER_NET} ${NODELIST_OPT} ${VERBOSE_OPT} ${CSV_FILE}; then
734 echo "`basename $0`: Check the cluster network connectivity"\
739 if $CONFIG_MD_LVM && ! $UPGRADE_TARGET; then
740 # Configure Linux MD/LVM devices
741 echo "`basename $0`: Configuring Linux MD/LVM devices..."
742 if ! ${SCRIPT_CONFIG_MD} ${NODELIST_OPT} ${VERBOSE_OPT} ${CSV_FILE}; then
746 if ! ${SCRIPT_CONFIG_LVM} ${NODELIST_OPT} ${VERBOSE_OPT} ${CSV_FILE}; then
749 echo "`basename $0`: Configure Linux MD/LVM devices OK!"
753 # Configure the Lustre cluster
754 echo "`basename $0`: ******** Lustre cluster configuration BEGIN ********"
756 get_lustre_items $CSV_FILE || exit ${PIPESTATUS[0]}
758 check_mgs || exit ${PIPESTATUS[0]}
760 # Format or upgrade Lustre server targets
761 mass_config || exit ${PIPESTATUS[0]}
763 # Modify /etc/fstab to add the new Lustre server targets
764 modify_fstab || exit ${PIPESTATUS[0]}
766 # Produce HA software's configuration files
772 echo "`basename $0`: ******** Lustre cluster configuration END **********"