This file is indexed.

/usr/sbin/lustre_start is in lustre-utils 1.8.5+dfsg-3ubuntu1.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
#!/bin/bash

# vim:expandtab:shiftwidth=4:softtabstop=4:tabstop=4:

#
# lustre_start - start or stop multiple Lustre servers from a CSV file
#
# This script is used to parse each line of a CSV (Comma-Separated Value) file
# and execute remote command to start/stop the service on every Lustre server
# target that will be part of the Lustre cluster.
#
################################################################################

# Usage
usage() {
    cat <<EOF

Usage: $(basename $0) [options] <-a|-w|-x> <CSV file>

    This script is used to start or stop multiple Lustre servers 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) to
                operate on rather than all the nodes in the CSV file
    -x hostname,hostname,...
                exclude the specified list of nodes (separated by commas)
    -n          no net - don't verify network connectivity and hostnames
                in the cluster
    -m          pass "mount options" item in the CSV file to mount command line
    -k          stop the services on Lustre server targets
    -v          verbose mode
    -h          help
    CSV file    a comma-separated value file that contains configuration
                parameters for each target in a Lustre cluster

    Please refer to "lustre_config -h" for the description of CSV file formats.

EOF
}

# Get the library of functions
. /usr/libexec/lustre/lc_common

SPECIFY_MNTOPTS=false
STOP_SERVICE=false
# Get and check the positional parameters
while getopts "aw:x:nmkhv" 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"
        ;;
    n)
        VERIFY_CONNECT=false
        ;;
    m)
        SPECIFY_MNTOPTS=true
        ;;
    k)
        STOP_SERVICE=true 
        ;;
    h)
        usage
        exit 0
        ;;
    v)
        VERBOSE_OPT="-v"
        VERBOSE_OUTPUT=true
        ;;
    ?)
        usage 1>&2
        exit 1
        ;;
    esac
done

# Toss out the parameters we've already processed
shift $((OPTIND - 1))

# Here we expect the CSV file
if [ $# -eq 0 ]; then
    error_output "Missing CSV file!"
    usage 1>&2
    exit 1
fi

CSV_FILE=$1

# get_fstab_mntopts host_name device_name mount_point
# Get the mount options from the /etc/fstab file
get_fstab_mntopts() {
    local host_name=$1
    local dev_name=$2
    local mnt_pnt=$3

    local mnt_opts=""

    if [ -z "$host_name" -o -z "$dev_name" -o -z "$mnt_pnt" ]; then
        echo "get_fstab_mntopts(): Missing argument!"
        return 1
    fi

    # Execute remote command to get the mount options from /etc/fstab file
    mnt_opts=$($REMOTE $host_name "grep -w ^$dev_name /etc/fstab | \
grep -w $mnt_pnt | awk '{print \$4}'" 2>/dev/null)

    mnt_opts=${mnt_opts//$host_name: /}

    echo $mnt_opts
    return 0
}

# Start the service on one Lustre server target
start_service() {
    declare -i i=$1
    shift
    local extra_mntopts="$*"
    local mntopts=""

    # Get mount options
    if $SPECIFY_MNTOPTS; then
        # Use the "mount options" item from the CSV file
        [ -n "${MOUNT_OPTIONS[i]}" ] && mntopts=${MOUNT_OPTIONS[i]}
    else
        # Do not use the "mount options" item from the CSV file
        mntopts=$(get_fstab_mntopts ${HOST_NAME[i]} ${DEVICE_NAME[i]} \
                ${MOUNT_POINT[i]})
        [ ${PIPESTATUS[0]} -ne 0 ] && error_output "$mntopts" && return 1
    fi

    [ -n "$mntopts" ] && mntopts="-o $mntopts"
    [ -n "$extra_mntopts" ] && mntopts="$mntopts $extra_mntopts"
    # Strip of any leading space
    mntopts=${mntopts# }

    # Execute remote command to start the service
    verbose_output "Mounting Lustre ${DEVICE_TYPE[i]} target"\
    "${DEVICE_NAME[i]} (opts: $mntopts) on ${HOST_NAME[i]}:${MOUNT_POINT[i]}..."
    $REMOTE ${HOST_NAME[i]} "PATH=\$PATH:/sbin:/usr/sbin
error() { set +x; echo \"ERROR: \$2: \$1\"; echo \"XXRETCODE:\$1\"; exit \$1; }
mkdir -p ${MOUNT_POINT[i]} || \\
    error \${PIPESTATUS[0]} \"failed to mkdir ${MOUNT_POINT[i]}\"
mount -t $FS_TYPE $mntopts ${DEVICE_NAME[i]} ${MOUNT_POINT[i]} || \\
    error \${PIPESTATUS[0]} \\
        \"failed to mount ${DEVICE_NAME[i]} on host ${HOST_NAME[i]}\""
    return ${PIPESTATUS[0]}
}

# Stop the service on one Lustre server target
stop_service() {
    declare -i i=$1

    # Execute remote command to stop the service
    verbose_output "Unmounting Lustre ${DEVICE_TYPE[i]} target"\
    "${DEVICE_NAME[i]} on ${HOST_NAME[i]}:${MOUNT_POINT[i]}..."
    $REMOTE ${HOST_NAME[i]} "PATH=\$PATH:/sbin:/usr/sbin
error() { set +x; echo \"ERROR: \$2: \$1\"; echo \"XXRETCODE:\$1\"; exit \$1; }
if grep -q \" ${MOUNT_POINT[i]} \" /proc/mounts; then
    umount -d -f ${MOUNT_POINT[i]} || \\
        error \${PIPESTATUS[0]} \\
            \"failed to unmount ${DEVICE_NAME[i]} on host ${HOST_NAME[i]}\"
else
    echo \"${DEVICE_NAME[i]} was not mounted on\"\\
    \"${HOST_NAME[i]}:${MOUNT_POINT[i]}\"
fi"
    return ${PIPESTATUS[0]}
}

# mass_op op_type target_type
# Start/stop the services on Lustre server targets in parallel
mass_op() {
    local op_type=$1
    local target_type=$2

    local op_func
    declare -i i
    declare -i pid_num=0
    declare -a REMOTE_PID
    local RC=0

    if [ -z "$op_type" -o -z "$target_type" ]; then
        error_output "mass_op(): Missing argument!"
        return 1
    fi

    case "$op_type" in
    "start")  op_func=start_service;;
    "stop")   op_func=stop_service;;
    *)  error_output "mass_op(): Invalid op type \"$op_type\"!" && return 1;;
    esac

    for ((i = 0; i < ${#HOST_NAME[@]}; i++)); do
        if [ "${DEVICE_TYPE[i]}" = "$target_type" ] \
        && [[ "${FORMAT_OPTIONS[i]}" != *noformat* ]]; then
            eval "$op_func $i &"
            REMOTE_PID[$pid_num]=$!
            let pid_num=$pid_num+1
        fi
    done

    for ((pid_num = 0; pid_num < ${#REMOTE_PID[@]}; pid_num++)); do
        wait ${REMOTE_PID[${pid_num}]}
        local RC1=${PIPESTATUS[0]}
        [ $RC1 -ne 0 ] && RC=$RC1
    done

    [ $RC -ne 0 ] && return $RC

    return 0
}

# Unload the modules to make cleanup
unload_modules() {
    local command
    local host
    local host_list

    host_list=$(comma_list "${HOST_NAME[@]}")
    [ -z "$host_list" ] && return 0

    command="PATH=\$PATH:/sbin:/usr/sbin
if grep -q libcfs /proc/modules; then
    lctl net down 1>/dev/null 2>&1
    lustre_rmmod
fi"

    if is_pdsh; then
        $REMOTE $host_list "$command"
    else
        for host in ${host_list//,/ }; do
            $REMOTE $host "$command"
        done
    fi
}

# Start the services on Lustre server targets
mass_start() {
    declare -i i
    local combo_mgs_mdt=false

    if [ ${#HOST_NAME[@]} -eq 0 ]; then
        verbose_output "There are no Lustre targets specified."
        return 0
    fi

    # Start lnet network on the MGS node
    start_mgs_lnet || return ${PIPESTATUS[0]}

    local checked_hosts=""
    for ((i = 0; i < ${#HOST_NAME[@]}; i++)); do
        host_in_hostlist ${HOST_NAME[i]} $checked_hosts && continue
        if ! is_mgs_node ${HOST_NAME[i]}; then
            # Add module options to the module configuration file
            add_module_options $i ${HOST_NAME[i]} || return ${PIPESTATUS[0]}

            # Check lnet networks
            check_lnet $i || return ${PIPESTATUS[0]}

            checked_hosts="$checked_hosts,${HOST_NAME[i]}"
        fi
    done

    # Start MGS or the MGS service on combo MGS/MDT (with "-o nosvc -n" options)
    if [ -n "${MGS_NODENAME[0]}" ]; then
        local idx=${MGS_IDX[0]}
        if [ "${DEVICE_TYPE[idx]#*mdt*}" != "${DEVICE_TYPE[idx]}" ]; then
            # Combo MGS/MDT
            combo_mgs_mdt=true
            start_service ${MGS_IDX[0]} "-o nosvc -n" || return ${PIPESTATUS[0]}
        else
            start_service ${MGS_IDX[0]} || return ${PIPESTATUS[0]}
        fi
    fi

    # Start OST(s)
    mass_op "start" "ost" || return ${PIPESTATUS[0]}

    # Start the MDT service on combo MGS/MDT (with "-o nomgs" option)
    if $combo_mgs_mdt; then
        start_service ${MGS_IDX[0]} "-o nomgs" || return ${PIPESTATUS[0]}
    fi

    # Start MDT(s)
    mass_op "start" "mdt" || return ${PIPESTATUS[0]}

    verbose_output "Success on all Lustre targets!"
    return 0
}

# Stop the services on Lustre server targets
mass_stop() {
    declare -i i

    if [ ${#HOST_NAME[@]} -eq 0 ]; then
        verbose_output "There are no Lustre targets specified."
        return 0
    fi

    # Stop MDT(s)
    mass_op "stop" "mdt" || return ${PIPESTATUS[0]}

    # Stop the MDT service on combo MGS/MDT
    if [ -n "${MGS_NODENAME[0]}" ]; then
        local idx=${MGS_IDX[0]}
        if [ "${DEVICE_TYPE[idx]#*mdt*}" != "${DEVICE_TYPE[idx]}" ]; then
            # Combo MGS/MDT
            stop_service ${MGS_IDX[0]} || return ${PIPESTATUS[0]}
        fi
    fi

    # Stop OST(s)
    mass_op "stop" "ost" || return ${PIPESTATUS[0]}
    
    # Stop MGS or the MGS service on combo MGS/MDT
    if [ -n "${MGS_NODENAME[0]}" ]; then
        stop_service ${MGS_IDX[0]} || return ${PIPESTATUS[0]}
    fi

    unload_modules

    return 0
}

#********************************* Main Flow **********************************#

# Check the CSV file
check_file $CSV_FILE || exit ${PIPESTATUS[0]}

# Get the list of nodes to be operated on
NODES_TO_USE=$(get_nodelist) || error_exit ${PIPESTATUS[0]} "$NODES_TO_USE"

# Check the node list
check_nodelist $NODES_TO_USE || exit ${PIPESTATUS[0]}

# Check the network connectivity and hostnames
if $VERIFY_CONNECT; then
    verbose_output "Checking the cluster network connectivity and hostnames..."
    $VERIFY_CLUSTER_NET $NODELIST_OPT $VERBOSE_OPT $CSV_FILE || \
        exit ${PIPESTATUS[0]}
    verbose_output "Check the cluster network connectivity and hostnames OK!"
fi

# Configure the Lustre cluster
echo "$(basename $0): ******** Lustre cluster configuration BEGIN ********"

get_lustre_items $CSV_FILE || exit ${PIPESTATUS[0]}

check_mgs || exit ${PIPESTATUS[0]}

if ! $STOP_SERVICE; then
    mass_start || exit ${PIPESTATUS[0]}
else
    mass_stop || exit ${PIPESTATUS[0]}
fi

echo "$(basename $0): ******** Lustre cluster configuration END **********"

exit 0