diff --git a/test/nvme/cuse/common.sh b/test/nvme/cuse/common.sh new file mode 100755 index 000000000..adf90c19a --- /dev/null +++ b/test/nvme/cuse/common.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (C) 2023 Intel Corporation +# All rights reserved. +# + +testdir=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")") +rootdir=$(readlink -f "$testdir/../../../") +source "$rootdir/test/common/autotest_common.sh" + +shopt -s extglob + +NVME_CMD="/usr/local/src/nvme-cli/nvme" + +rpc_py=$rootdir/scripts/rpc.py + +declare -A ctrls=() +declare -A nvmes=() +declare -A bdfs=() +nvme_name="" + +nvme_get() { + local ref=$1 reg val + shift + + local -gA "$ref=()" + while IFS=":" read -r reg val; do + [[ -n $val ]] \ + && eval "${ref}[${reg//[[:space:]]/}]=\"${val##+([[:space:]])}\"" + done < <($NVME_CMD "$@") +} + +scan_nvme_ctrls() { + # Create set of references and bundle them together in global assoc arrays. + # Each controller's regs are mapped onto a separate array named as the target + # ctrl. Each ctrl also gets a dedicated array which holds references to each + # namespace device. E.g.: + # + # ctrls["nvme0"]=nvme0 + # nvme0["mn"] nvme0["vid"] + # nvmes["nvme0"]=nvme0_ns + # nvme0_ns[1]=nvme0n1 nvme0_ns[2]=nvme0n2 + # nvme0n1["lbaf0"] nvme0n1["ncap"] + # bdf["nvme0"]=0000:00:42.0 + # + # Each of these can be accessed via get*() helpers defined below. E.g.: + # get_nvme_ctrl_feature nvme0 vid -> 0x8086 + # get_nvme_ns_feature nvme0 1 ncap -> 0x2e9390b0 + # get_nvme_nss nvme0 -> 1 2 + + local ctrl ctrl_dev reg val ns pci + + for ctrl in /sys/class/nvme/nvme*; do + [[ -e $ctrl ]] || continue + pci=$(< "$ctrl/address") + pci_can_use "$pci" || continue + ctrl_dev=${ctrl##*/} + nvme_get "$ctrl_dev" id-ctrl "/dev/$ctrl_dev" + local -n _ctrl_ns=${ctrl_dev}_ns + for ns in "$ctrl/${ctrl##*/}n"*; do + [[ -e $ns ]] || continue + ns_dev=${ns##*/} + nvme_get "$ns_dev" id-ns "/dev/$ns_dev" + _ctrl_ns[${ns##*n}]=$ns_dev + done + ctrls["$ctrl_dev"]=$ctrl_dev + nvmes["$ctrl_dev"]=${ctrl_dev}_ns + bdfs["$ctrl_dev"]=$pci + done +} + +get_nvme_ctrl_feature() { + local ctrl=$1 reg=${2:-cntlid} + + [[ -n ${ctrls["$ctrl"]} ]] || return 1 + + local -n _ctrl=${ctrls["$ctrl"]} + + [[ -n ${_ctrl["$reg"]} ]] || return 1 + echo "${_ctrl["$reg"]}" +} + +get_nvme_ns_feature() { + local ctrl=$1 ns=$2 reg=${3:-nsze} + + [[ -n ${nvmes["$ctrl"]} ]] || return 1 + + local -n _nss=${nvmes["$ctrl"]} + [[ -n ${_nss[ns]} ]] || return 1 + + local -n _ns=${_nss[ns]} + + [[ -n ${_ns["$reg"]} ]] || return 1 + echo "${_ns["$reg"]}" +} + +get_nvme_nss() { + local ctrl=$1 + + [[ -n ${nvmes["$ctrl"]} ]] || return 1 + local -n _nss=${nvmes["$ctrl"]} + + echo "${!_nss[@]}" +} + +get_active_lbaf() { + local ctrl=$1 ns=$2 reg lbaf + + [[ -n ${nvmes["$ctrl"]} ]] || return 1 + + local -n _nss=${nvmes["$ctrl"]} + [[ -n ${_nss[ns]} ]] || return 1 + + local -n _ns=${_nss[ns]} + + for reg in "${!_ns[@]}"; do + [[ $reg == lbaf* ]] || continue + [[ ${_ns["$reg"]} == *"in use"* ]] || continue + echo "${reg/lbaf/}" && return 0 + done + return 1 +}