This file is indexed.

/usr/sbin/lc_net 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
#!/bin/bash

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

#
# lc_net - script for Lustre cluster network verification
#
###############################################################################

# Usage
usage() {
	cat >&2 <<EOF

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-
			uster, the first field of each line is the host name 
			of the cluster node

EOF
	exit 1
}

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

VERBOSE_OUTPUT=false
# Get and check the positional parameters
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
		;;
        ?) 
		usage 
	esac
done

# Toss out the parameters we've already processed
shift  `expr $OPTIND - 1`

# Here we expect the csv file
if [ $# -eq 0 ]; then
	error_output "Missing csv file!"
	usage
fi

# Global variables
CSV_FILE=$1
declare -a HOST_NAMES
declare -a HOST_IPADDRS

# Get the hosts to be operated on
get_hostnames() {
	local NODES_TO_USE

	# Initialize the HOST_NAMES array
	unset HOST_NAMES

	# Get the list of nodes to be operated on
	NODES_TO_USE=$(get_nodelist)
	[ ${PIPESTATUS[0]} -ne 0 ] && error_output "${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

	# Load the hostnames in the nodelist into the array
	HOST_NAMES=( $(echo ${NODES_TO_USE//,/ }) )

	return 0
}

# ping_host host_name
# Check whether host $host_name is reachable. 
# If it is, then return the IP address of this host.
ping_host() {
	local host_name=$1
	local ip_addr=
	local ret_str

	if [ -z "${host_name}" ]; then
		echo "`basename $0`: ping_host() error: Missing hostname!"
		return 1
	fi

	# Run ping command
	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
			echo "`basename $0`: ping_host() error:"\
			"Host ${host_name} does not respond to ping!"
		fi
		return 1
	fi

	# Get the IP address
	ip_addr=`echo "${ret_str}" | head -1 | awk '{print $3}' | \
		sed -e 's/^(//' -e 's/)$//'`

	echo "${ip_addr}"
	return 0
}

# local_check index
# Check the network connectivity between local host and ${HOST_NAMES[index]}.
local_check() {
	declare -i i=$1

	# 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 [ ${PIPESTATUS[0]} -ne 0 ]; then
		error_output "${HOST_IPADDRS[i]}"
		return 1
	fi

	return 0
}

# remote_check index
# Check whether ${HOST_NAMES[index]} can resolve its own name and whether
# this host agrees with the local host about what its name is resolved to.
remote_check() {
	declare -i i=$1
	local cmd ret_str
	local ip_addr=		# the IP address got from remote ping

	# 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]} "${cmd}" 2>&1)
	if [ ${PIPESTATUS[0]} -ne 0 -a -n "${ret_str}" ]; then
		error_output "remote_check():"\
		"remote to ${HOST_NAMES[i]} error: ${ret_str}!"
		return 1
	fi

	if [ -z "${ret_str}" ]; then
		error_output "remote_check():"\
		"No results from ${HOST_NAMES[i]}! Check the network"\
		"connectivity between local host and ${HOST_NAMES[i]}!"
		return 1
	fi

	# Get the IP address of ${HOST_NAMES[i]} from its own ping
       ip_pattern="[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
       ip_addr=`echo "${ret_str}" | egrep -o "${ip_pattern}"`
	ip_addr=`echo "${ip_addr}" | sed -e 's/^(//' -e 's/)$//'`

	# Compare IP addresses
	# Check whether ${HOST_NAMES[i]} agrees with the local host
	# about what its name is resolved to.
	if [ "${ip_addr}" != "${HOST_IPADDRS[i]}" ]; then
		error_output "remote_check():"\
		"Local host resolves ${HOST_NAMES[i]} to IP address"\
		"\"${HOST_IPADDRS[i]}\", while its own resolution is"\
		"\"${ip_addr}\". They are not the same!"
		return 1
	fi
	
	return 0
}

# network_verify
# Verify name resolution and network connectivity of the Lustre cluster
network_verify() {
	declare -i i

	# Initialize the HOST_IPADDRS array
	unset HOST_IPADDRS

	# Get all the host names to be operated on 
	! get_hostnames && return 1

	# Check the network connectivity between local host 
	# and other cluster nodes
	for ((i = 0; i < ${#HOST_NAMES[@]}; i++)); do
		[ "${HOST_NAMES[i]}" = "`hostname`" ] && continue

		verbose_output "Verifying network connectivity between"\
			       "\"`hostname`\" and \"${HOST_NAMES[i]}\"..."
		! local_check $i && return 1
		! remote_check $i && return 1
		verbose_output "OK"
	done

	return 0
}

# Main flow
if ! check_file ${CSV_FILE}; then
	exit 1	
fi

# Cluster network verification
if ! network_verify; then
	exit 1	
fi

exit 0