From 8cfcf6a49cbc2933c4434e55ddd7f66840f2581e Mon Sep 17 00:00:00 2001 From: joshuaboud Date: Fri, 8 Dec 2023 18:00:43 -0400 Subject: [PATCH] add slot_num_to_block_dev, slot_name_to_block_dev, check_ubm_func_support --- Makefile | 10 ++- ubm/id_disk | 2 + ubm/on_enclosure_add | 2 + ubm/patch_vdev_id_conf | 1 + ubm/ubm_func_wrapper.sh | 4 ++ ubm/ubm_funcs.sh | 136 ++++++++++++++++++++++++++++++++-------- 6 files changed, 127 insertions(+), 28 deletions(-) diff --git a/Makefile b/Makefile index 47f1f05..da521a1 100644 --- a/Makefile +++ b/Makefile @@ -34,12 +34,15 @@ endif ln -sf /opt/45drives/ubm/slot_led_ctrl "$(DESTDIR)/usr/bin/slot_led_ctrl" ln -sf /opt/45drives/tools/slot_speeds "$(DESTDIR)/usr/bin/slot_speeds" for i in \ - block_dev_to_slot_num \ slot_num_to_slot_name \ slot_name_to_slot_num \ + block_dev_to_slot_num \ block_dev_to_slot_name \ + slot_num_to_block_dev \ + slot_name_to_block_dev \ all_slot_nums \ all_slot_names \ + check_ubm_func_support \ ; do ln -sf /opt/45drives/tools/ubm_func_wrapper.sh "$(DESTDIR)/usr/bin/$i"; done uninstall: @@ -58,10 +61,13 @@ uninstall: rm -f "$(DESTDIR)/usr/bin/slot_led_ctrl" rm -f "$(DESTDIR)/usr/bin/slot_speeds" for i in \ - block_dev_to_slot_num \ slot_num_to_slot_name \ slot_name_to_slot_num \ + block_dev_to_slot_num \ block_dev_to_slot_name \ + slot_num_to_block_dev \ + slot_name_to_block_dev \ all_slot_nums \ all_slot_names \ + check_ubm_func_support \ ; do rm -f "$(DESTDIR)/usr/bin/$i"; done diff --git a/ubm/id_disk b/ubm/id_disk index 1d7708a..8a0e380 100755 --- a/ubm/id_disk +++ b/ubm/id_disk @@ -17,6 +17,8 @@ # shellcheck source=./ubm_funcs.sh source "$(dirname -- "$(readlink -f -- "${BASH_SOURCE[0]}")")/ubm_funcs.sh" +check_ubm_func_support || exit 0 + BLOCK_DEV_KERNEL_NAME=$1 BLOCK_DEV_KERNEL_NAME=$(normalize_block_dev_name "$1") || exit 0 diff --git a/ubm/on_enclosure_add b/ubm/on_enclosure_add index f86f479..7627c0b 100755 --- a/ubm/on_enclosure_add +++ b/ubm/on_enclosure_add @@ -16,6 +16,8 @@ # shellcheck source=./ubm_funcs.sh source "$(dirname -- "$(readlink -f -- "${BASH_SOURCE[0]}")")/ubm_funcs.sh" +check_ubm_func_support || exit 0 + SLOT_LINK_DIR=/var/run/45drives/slots CACHE_DIR='/var/cache/45drives/ubm' diff --git a/ubm/patch_vdev_id_conf b/ubm/patch_vdev_id_conf index 1e57a63..7fb0edb 100755 --- a/ubm/patch_vdev_id_conf +++ b/ubm/patch_vdev_id_conf @@ -25,6 +25,7 @@ generate_vdev_id_conf() { local TMPFILE # shellcheck source=./ubm_funcs.sh source "$(dirname -- "$(readlink -f -- "${BASH_SOURCE[0]}")")/ubm_funcs.sh" + check_ubm_func_support || exit 0 TMPFILE=$(mktemp) echo "# Generated by $(realpath "$0") via /usr/lib/udev/rules.d/67-ubm.rules" > "$TMPFILE" ALL_SLOT_NAMES=$(all_slot_names) || perror "all_slot_names failed" || exit 0 diff --git a/ubm/ubm_func_wrapper.sh b/ubm/ubm_func_wrapper.sh index e8396ac..e5a852b 100755 --- a/ubm/ubm_func_wrapper.sh +++ b/ubm/ubm_func_wrapper.sh @@ -5,6 +5,10 @@ source "$(dirname -- "$(readlink -f -- "${BASH_SOURCE[0]}")")/ubm_funcs.sh" UBM_FUNC_NAME=$(basename "$0") +if [ "$UBM_FUNC_NAME" != "check_ubm_func_support" ]; then + check_ubm_func_support || exit $? +fi + [ "$UBM_FUNC_NAME" == "ubm_func_wrapper.sh" ] && perror "Intended to be executed via symlink" && exit 2 "$UBM_FUNC_NAME" "$@" diff --git a/ubm/ubm_funcs.sh b/ubm/ubm_funcs.sh index 8e03294..b1220a6 100644 --- a/ubm/ubm_funcs.sh +++ b/ubm/ubm_funcs.sh @@ -55,6 +55,35 @@ die() { exit $? } +_get_map_key() { + if [[ -r "$CACHE_DIR/map_key" ]]; then + cat "$CACHE_DIR/map_key" + return 0 + fi + ( + set -o pipefail + ipmitool fru | awk -F: ' + BEGIN { + found_key = 0 + } + $1 ~ "Product Name" { + found_key=1 + key=toupper($2); + sub(/-(TURBO|BASE|ENHANCED).*$/, "", key); + sub(/\s+/, "", key); + print key; + exit + } + END { + if (!found_key) { + print "map key lookup failed" > "/dev/stderr" + exit 1 + } + } + ' + ) +} + # get_map_key # print map key for table lookups # @@ -65,33 +94,11 @@ get_map_key() { if [[ -r "$CACHE_DIR/map_key" ]]; then UBM_MAP_KEY="$(<"$CACHE_DIR/map_key")" else - UBM_MAP_KEY=$( - ( - set -o pipefail - ipmitool fru | awk -F: ' - BEGIN { - found_key = 0 - } - $1 ~ "Product Name" { - found_key=1 - key=toupper($2); - sub(/-(TURBO|BASE|ENHANCED).*$/, "", key); - sub(/\s+/, "", key); - print key; - exit - } - END { - if (!found_key) { - print "map key lookup failed" > "/dev/stderr" - exit 1 - } - } - ' - ) - ) || perror "Failed to get Product Name from FRU" || return $? + UBM_MAP_KEY=$(_get_map_key) || perror "Failed to get Product Name from FRU" || return $? [ -d "$CACHE_DIR" ] || mkdir -p "$CACHE_DIR" >/dev/null TMPFILE=$(mktemp -p "$CACHE_DIR") || return $? echo "$UBM_MAP_KEY" >"$TMPFILE" + chmod 644 "$TMPFILE" mv "$TMPFILE" "$CACHE_DIR/map_key" || return $? fi fi @@ -230,7 +237,7 @@ table_lookup_val() { [[ ! "$ROW_SEARCH_COL" =~ ^[0-9]+$ ]] && perror "Invalid row search column: $ROW_SEARCH_COL" && return 2 [[ -z "$ROW_SEARCH_VAL" ]] && perror "Row search value is empty" && return 2 [[ ! "$OUTPUT_COL" =~ ^[0-9]+$ ]] && perror "Invalid output column: $OUTPUT_COL" && return 2 - awk -v ROW_SEARCH_COL=$((ROW_SEARCH_COL+1)) -v ROW_SEARCH_VAL="$ROW_SEARCH_VAL" -v OUTPUT_COL=$((OUTPUT_COL+1)) ' + awk -v ROW_SEARCH_COL=$((ROW_SEARCH_COL + 1)) -v ROW_SEARCH_VAL="$ROW_SEARCH_VAL" -v OUTPUT_COL=$((OUTPUT_COL + 1)) ' BEGIN { found_row = 0 } @@ -265,7 +272,7 @@ table_lookup_col() { [[ ! "$ROW_SEARCH_COL" =~ ^[0-9]+$ ]] && perror "Invalid row search column: $ROW_SEARCH_COL" && return 2 [[ -z "$ROW_SEARCH_VAL" ]] && perror "Row search value is empty" && return 2 [[ -z "$COL_SEARCH_VAL" ]] && perror "Column search value is empty" && return 2 - awk -v ROW_SEARCH_COL=$((ROW_SEARCH_COL+1)) -v ROW_SEARCH_VAL="$ROW_SEARCH_VAL" -v COL_SEARCH_VAL="$COL_SEARCH_VAL" ' + awk -v ROW_SEARCH_COL=$((ROW_SEARCH_COL + 1)) -v ROW_SEARCH_VAL="$ROW_SEARCH_VAL" -v COL_SEARCH_VAL="$COL_SEARCH_VAL" ' BEGIN { found_row = 0 found_col = 0 @@ -332,6 +339,56 @@ block_dev_to_slot_name() { slot_num_to_slot_name "$SLOT_NUM" || perror "slot_num_to_slot_name failed" } +# slot_num_to_block_dev SLOT_NUM +# +# Get block device OS name from slot number +# +# e.g. +# slot_num_to_block_dev 5 -> "sdj" +slot_num_to_block_dev() { + local SLOT_NUM=$1 + [[ ! "$SLOT_NUM" =~ ^[0-9]+$ ]] && perror "Invalid slot number: $SLOT_NUM" && return 2 + for slot_attr in /sys/block/*/device/slot; do + if [[ $(cat "$slot_attr") == "$SLOT_NUM" ]]; then + cut -d'/' -f 4 <<<"$slot_attr" + return 0 + fi + done + perror "Warning: getting slot number from storcli2 output (slow)" + ( + set -o pipefail + storcli2 "/call/eall/sall" show all J | jq -re ' + [ + .Controllers[] | + select(."Command Status"."Status" == "Success" and ."Response Data"."Drives List") | + ."Response Data"."Drives List"[] | + select(."Drive Information"."EID:Slt" | split(":")[1] == "'"$SLOT_NUM"'") + ] | + if length == 1 then + .[0] + elif length == 0 then + error("slot '"$SLOT_NUM"' not found in storcli2 output") + else + error("more than one match for slot '"$SLOT_NUM"'") + end | + ."Drive Detailed Information"."OS Drive Name" // error("OS Drive Name not given for slot '"$SLOT_NUM"'") | split("/")[-1] + ' + ) +} + +# slot_name_to_block_dev SLOT_NUM +# +# Get block device OS name from slot number +# +# e.g. +# slot_num_to_block_dev 3-4 -> "sdj" +slot_name_to_block_dev() { + local SLOT_NUM + SLOT_NUM=$(slot_name_to_slot_num "$@") || return $? + slot_num_to_block_dev "$SLOT_NUM" +} + +# Get all slot names, space delimited all_slot_names() { UBM_MAP_KEY=$(get_map_key) || return $? ( @@ -340,6 +397,7 @@ all_slot_names() { ) || perror $? "Failed to lookup all slot names" } +# Get all slot numbers, space delimited all_slot_nums() { UBM_MAP_KEY=$(get_map_key) || return $? awk -v MAP_KEY="$UBM_MAP_KEY" ' @@ -365,3 +423,29 @@ all_slot_nums() { } ' "$SCRIPT_DIR/slot_name_map.txt" || perror $? "Failed to lookup all slot numbers" } + +# check_ubm_func_support [ -q ] +# +# Check for server compatibility with ubm_funcs +# +# Options: +# -q - silence error message +# +# e.g. +# check_ubm_func_support || exit $? +check_ubm_func_support() { + local ubm_map_key + local PERROR=perror + _silent_perror() { + # shellcheck disable=SC2317 + return $? + } + if [[ "$1" == "-q" ]]; then + PERROR=_silent_perror + fi + ubm_map_key=$(_get_map_key 2>/dev/null) || $PERROR "Failed to determine ubm_map_key" || return $? + if ! grep -q "^$ubm_map_key" "$SCRIPT_DIR/slot_name_map.txt"; then + $PERROR "ERROR: It seems like this server is not supported for UBM functions: '$ubm_map_key' not in $SCRIPT_DIR/slot_name_map.txt" + return 1 + fi +}