c09b139e61
Signed-off-by: Michal Berger <michalx.berger@intel.com> Change-Id: Iafc067f880525f25363db1adf9a94a9fc9215455 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6994 Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Karol Latecki <karol.latecki@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
318 lines
5.8 KiB
Bash
Executable File
318 lines
5.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
[[ $(uname -s) == Linux ]] || exit 0
|
|
|
|
shopt -s extglob nullglob
|
|
|
|
declare -r rdma_rxe=/sys/module/rdma_rxe
|
|
declare -r rdma_rxe_add=$rdma_rxe/parameters/add
|
|
declare -r rdma_rxe_rm=$rdma_rxe/parameters/remove
|
|
|
|
declare -r infiniband=/sys/class/infiniband
|
|
declare -r infiniband_verbs=/sys/class/infiniband_verbs
|
|
declare -r net=/sys/class/net
|
|
|
|
declare -A net_devices
|
|
declare -A net_to_rxe
|
|
declare -A rxe_to_net
|
|
|
|
uevent() (
|
|
[[ -e $1/uevent ]] || return 0
|
|
|
|
source "$1/uevent"
|
|
|
|
if [[ -v $2 ]]; then
|
|
echo "${!2}"
|
|
elif [[ -n $3 ]]; then
|
|
echo "$3"
|
|
fi
|
|
)
|
|
|
|
modprobeq() {
|
|
modprobe -q "$@"
|
|
}
|
|
|
|
get_ipv4() {
|
|
local ip
|
|
|
|
# Get only the first ip
|
|
read -r _ _ _ ip _ < <(ip -o -4 addr show dev "$1")
|
|
if [[ -n $ip ]]; then
|
|
echo "${ip%/*}"
|
|
else
|
|
echo " "
|
|
fi
|
|
}
|
|
|
|
get_rxe_mtu() {
|
|
local rxe=$1
|
|
local mtu
|
|
local uverb
|
|
|
|
for uverb in "$infiniband_verbs/uverbs"*; do
|
|
if [[ $(< "$uverb/ibdev") == "$rxe" ]] \
|
|
&& [[ -c /dev/infiniband/${uverb##*/} ]]; then
|
|
[[ $(ibv_devinfo -d "$rxe") =~ active_mtu:(.*\ \(.*\)) ]]
|
|
echo "${BASH_REMATCH[1]:-(?)}"
|
|
return 0
|
|
fi
|
|
done
|
|
}
|
|
|
|
start() {
|
|
local modules module
|
|
|
|
modules=(
|
|
"ib_core"
|
|
"ib_uverbs"
|
|
"rdma_ucm"
|
|
"rdma_rxe"
|
|
)
|
|
|
|
for module in "${modules[@]}"; do
|
|
[[ -e /sys/module/$module ]] && continue
|
|
if [[ ! -e $(modinfo -F filename "$module") ]]; then
|
|
return 0
|
|
fi
|
|
done 2> /dev/null
|
|
|
|
modprobeq -a "${modules[@]}" || return 1
|
|
add_rxe all
|
|
}
|
|
|
|
stop() {
|
|
remove_rxe
|
|
|
|
if ! modprobeq -r rdma_rxe \
|
|
|| [[ -e $rdma_rxe ]]; then
|
|
printf 'unable to unload drivers, reboot required\n'
|
|
fi
|
|
}
|
|
|
|
status_header() {
|
|
local header=("Name" "Link" "Driver" "Speed" "NMTU" "IPv4_addr" "RDEV" "RMTU")
|
|
|
|
size_print_fields "${header[@]}"
|
|
}
|
|
|
|
status() {
|
|
if [[ ! -e $rdma_rxe ]]; then
|
|
printf 'rdma_rxe module not loaded\n' >&2
|
|
fi
|
|
|
|
local dev
|
|
local link_map
|
|
|
|
link_map[0]=no
|
|
link_map[1]=yes
|
|
|
|
status_header
|
|
|
|
local name link driver speed mtu ip rxe rxe_dev active_mtu
|
|
for dev in "${net_devices[@]}"; do
|
|
name="" link="" driver=""
|
|
speed="" mtu="" ip=""
|
|
rxe_dev="" active_mtu=""
|
|
|
|
name=${dev##*/}
|
|
rxe_dev=${net_to_rxe["$name"]}
|
|
active_mtu=$(get_rxe_mtu "$rxe_dev")
|
|
|
|
link=${link_map[$(< "$dev/carrier")]}
|
|
|
|
if [[ -e $dev/device/driver ]]; then
|
|
driver=$(readlink -f "$dev/device/driver")
|
|
driver=${driver##*/}
|
|
elif [[ -e /sys/devices/virtual/net/${dev##*/} ]]; then
|
|
# Try to be smart and get the type of the device instead
|
|
driver=$(uevent "$dev" "DEVTYPE" "virtual")
|
|
fi
|
|
|
|
if [[ $link == yes ]]; then
|
|
speed=$(< "$dev/speed")
|
|
if ((speed >= 1000)); then
|
|
speed=$((speed / 1000))GigE
|
|
elif ((speed > 0)); then
|
|
speed=${speed}Mb/s
|
|
else
|
|
speed=""
|
|
fi
|
|
fi
|
|
|
|
mtu=$(< "$dev/mtu")
|
|
ip=$(get_ipv4 "$name")
|
|
|
|
size_print_fields \
|
|
"$name" \
|
|
"$link" \
|
|
"$driver" \
|
|
"$speed" \
|
|
"$mtu" \
|
|
"$ip" \
|
|
"$rxe_dev" \
|
|
"$active_mtu"
|
|
done 2> /dev/null
|
|
print_status
|
|
}
|
|
|
|
size_print_fields() {
|
|
local fields=("$@") field
|
|
local -g lengths lines lineno
|
|
|
|
for field in "${!fields[@]}"; do
|
|
if [[ -z ${fields[field]} ]]; then
|
|
fields[field]="###"
|
|
fi
|
|
if [[ -z ${lengths[field]} ]]; then
|
|
lengths[field]=${#fields[field]}
|
|
else
|
|
lengths[field]=$((lengths[field] > ${#fields[field]} ? lengths[field] : ${#fields[field]}))
|
|
fi
|
|
done
|
|
|
|
eval "local -g _line_$lineno=(\"\${fields[@]}\")"
|
|
lines+=("_line_${lineno}[@]")
|
|
((++lineno))
|
|
}
|
|
|
|
print_status() {
|
|
local field field_ref fieldidx
|
|
local pad
|
|
|
|
if [[ -n $NO_HEADER ]]; then
|
|
unset -v "lines[0]"
|
|
fi
|
|
|
|
for field_ref in "${lines[@]}"; do
|
|
printf ' '
|
|
fieldidx=0
|
|
for field in "${!field_ref}"; do
|
|
if [[ -n $field ]]; then
|
|
pad=$((lengths[fieldidx] - ${#field} + 2))
|
|
else
|
|
pad=$((lengths[fieldidx] + 2))
|
|
fi
|
|
if [[ -n $field && $field != "###" ]]; then
|
|
printf '%s' "$field"
|
|
else
|
|
printf ' '
|
|
fi
|
|
printf '%*s' "$pad" ""
|
|
((++fieldidx))
|
|
done
|
|
printf '\n'
|
|
done
|
|
}
|
|
|
|
add_rxe() {
|
|
local dev net_devs
|
|
|
|
[[ -e $rdma_rxe_add ]] || return 0
|
|
|
|
if [[ -z $1 || $1 == all ]]; then
|
|
net_devs=("${!net_devices[@]}")
|
|
elif [[ -n ${net_to_rxe["$1"]} ]]; then
|
|
printf '%s interface already in use (%s)\n' \
|
|
"$1" "${net_to_rxe["$1"]}"
|
|
return 0
|
|
elif [[ -n ${net_devices["$1"]} ]]; then
|
|
net_devs=("$1")
|
|
else
|
|
printf '%s interface does not exist\n' "$1"
|
|
return 1
|
|
fi
|
|
|
|
for dev in "${net_devs[@]}"; do
|
|
if [[ -z ${net_to_rxe["$dev"]} ]]; then
|
|
echo "${dev##*/}" > "$rdma_rxe_add"
|
|
fi
|
|
link_up "${dev##*/}"
|
|
done 2> /dev/null
|
|
}
|
|
|
|
remove_rxe() {
|
|
local rxes rxe
|
|
|
|
[[ -e $rdma_rxe_rm ]] || return 0
|
|
|
|
rxes=("${!rxe_to_net[@]}")
|
|
if [[ -z $1 || $1 == all ]]; then
|
|
rxes=("${!rxe_to_net[@]}")
|
|
elif [[ -z ${rxe_to_net["$1"]} ]]; then
|
|
printf '%s rxe interface does not exist\n' "$1"
|
|
return 0
|
|
elif [[ -n ${rxe_to_net["$1"]} ]]; then
|
|
rxes=("$1")
|
|
fi
|
|
|
|
for rxe in "${rxes[@]}"; do
|
|
echo "$rxe" > "$rdma_rxe_rm"
|
|
done 2> /dev/null
|
|
}
|
|
|
|
link_up() {
|
|
[[ -e $net/$1 ]] || return 0
|
|
|
|
echo $(($(< "$net/$1/flags") | 0x1)) > "$net/$1/flags"
|
|
}
|
|
|
|
collect_net_devices() {
|
|
local net_dev
|
|
|
|
for net_dev in "$net/"!(bonding_masters); do
|
|
(($(< "$net_dev/type") != 1)) && continue
|
|
net_devices["${net_dev##*/}"]=$net_dev
|
|
done
|
|
}
|
|
|
|
collect_rxe_devices() {
|
|
local rxe_dev net_dev
|
|
|
|
for rxe_dev in "$infiniband/"*; do
|
|
if [[ -e $rxe_dev/parent ]]; then
|
|
# Soft
|
|
net_dev=$(< "$rxe_dev/parent")
|
|
elif [[ -e $rxe_dev/device/net ]]; then
|
|
# HW
|
|
net_dev=$(readlink -f "$rxe_dev/device/net/"*)
|
|
net_dev=${net_dev##*/}
|
|
else
|
|
continue
|
|
fi 2> /dev/null
|
|
|
|
[[ -n ${net_devices["$net_dev"]} ]] || continue
|
|
net_to_rxe["$net_dev"]=${rxe_dev##*/}
|
|
rxe_to_net["${rxe_dev##*/}"]=$net_dev
|
|
done
|
|
}
|
|
|
|
collect_net_devices
|
|
collect_rxe_devices
|
|
|
|
case "${1:-status}" in
|
|
start)
|
|
start
|
|
;;
|
|
stop)
|
|
stop
|
|
;;
|
|
add)
|
|
add_rxe "${2:-all}"
|
|
;;
|
|
remove)
|
|
remove_rxe "${2:-all}"
|
|
;;
|
|
status)
|
|
IFS= read -r match < <(
|
|
IFS="|"
|
|
printf '%s\n' "${*:2}"
|
|
)
|
|
status | grep -E "${match:-.}"
|
|
;;
|
|
rxe-net)
|
|
printf '%s\n' "${rxe_to_net[@]}"
|
|
;;
|
|
*)
|
|
printf 'Invalid argument (%s)\n' "$1"
|
|
;;
|
|
esac
|