Spdk/test/sma/crypto.sh
Krzysztof Karas 0af934b38c event: add CPU lock files
When running SPDK application on a given set of
CPU cores, create lock files for each of them.
This wil prevent user misconfiguration and
assigning a core to more than one SPDK instance.

The introduced mechanism is based on device locks
implemented in spdk_pci_device_claim() function.

Add a command line option to disable lock files.
This feature will be useful in cases where differing
CPU cores is impossible (eg. setup with only one core
available).

The patch also fixes all existing cases of overlapping
core masks.

Change-Id: Ie9aacb7523a3597b9aa20f2c3fa9efe4db92c44c
Signed-off-by: Krzysztof Karas <krzysztof.karas@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14919
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
2022-11-09 08:18:32 +00:00

271 lines
7.3 KiB
Bash
Executable File

#!/usr/bin/env bash
testdir=$(readlink -f "$(dirname "$0")")
rootdir=$(readlink -f "$testdir/../..")
source "$rootdir/test/common/autotest_common.sh"
source "$testdir/common.sh"
rpc_py="$rootdir/scripts/rpc.py"
localnqn=nqn.2016-06.io.spdk:cnode0
tgtnqn=nqn.2016-06.io.spdk:tgt0
key0=1234567890abcdef1234567890abcdef
key1=deadbeefcafebabefeedbeefbabecafe
tgtsock=/var/tmp/spdk.sock2
discovery_port=8009
cleanup() {
killprocess $smapid
killprocess $hostpid
killprocess $tgtpid
}
gen_volume_params() {
local volume_id=$1 cipher=$2 key=$3 key2=$4 config
local -a params crypto
config=$(
cat <<- PARAMS
"volume_id": "$(uuid2base64 $volume_id)",
"nvmf": {
"hostnqn": "nqn.2016-06.io.spdk:host0",
"discovery": {
"discovery_endpoints": [
{
"trtype": "tcp",
"traddr": "127.0.0.1",
"trsvcid": "$discovery_port"
}
]
}
}
PARAMS
)
params+=("$config")
local IFS=","
if [[ -n "$cipher" ]]; then
crypto+=("\"cipher\": $(get_cipher $cipher)")
crypto+=("\"key\": \"$(format_key $key)\"")
if [[ -n "$key2" ]]; then
crypto+=("\"key2\": \"$(format_key $key2)\"")
fi
crypto_config=$(
cat <<- PARAMS
"crypto": {
${crypto[*]}
}
PARAMS
)
params+=("$crypto_config")
fi
cat <<- PARAMS
"volume": {
${params[*]}
}
PARAMS
}
create_device() {
"$rootdir/scripts/sma-client.py" <<- CREATE
{
"method": "CreateDevice",
"params": {
"nvmf_tcp": {
"subnqn": "$localnqn",
"adrfam": "ipv4",
"traddr": "127.0.0.1",
"trsvcid": "4420"
}
${1:+, $(gen_volume_params "$@")}
}
}
CREATE
}
delete_device() {
"$rootdir/scripts/sma-client.py" <<- DELETE
{
"method": "DeleteDevice",
"params": {
"handle": "$1"
}
}
DELETE
}
attach_volume() {
local device=$1
shift
"$rootdir/scripts/sma-client.py" <<- ATTACH
{
"method": "AttachVolume",
"params": {
"device_handle": "$device",
$(gen_volume_params "$@")
}
}
ATTACH
}
detach_volume() {
"$rootdir/scripts/sma-client.py" <<- DETACH
{
"method": "DetachVolume",
"params": {
"device_handle": "$1",
"volume_id": "$(uuid2base64 $2)"
}
}
DETACH
}
verify_crypto_volume() {
local nqn=$1 uuid=$2 ns ns_bdev
ns=$(rpc_cmd nvmf_get_subsystems $nqn | jq -r '.[0].namespaces[0]')
ns_bdev=$(jq -r '.name' <<< "$ns")
# Make sure that the namespace is a crypto bdev and that there's only a single crypto bdev
[[ $(rpc_cmd bdev_get_bdevs -b "$ns_bdev" | jq -r '.[0].product_name') == crypto ]]
[[ $(rpc_cmd bdev_get_bdevs | jq -r '[.[] | select(.product_name == "crypto")] | length') -eq 1 ]]
# Check that the namespace's UUID/NGUID matches the one requested by the user
[[ $(jq -r '.uuid' <<< "$ns") == "$uuid" ]]
[[ $(jq -r '.nguid' <<< "$ns") == "$(uuid2nguid $uuid)" ]]
}
trap "cleanup; exit 1" SIGINT SIGTERM EXIT
"$rootdir/build/bin/spdk_tgt" -m 0x1 &
hostpid=$!
"$rootdir/build/bin/spdk_tgt" -r "$tgtsock" -m 0x2 &
tgtpid=$!
$rootdir/scripts/sma.py -c <(
cat <<- CONFIG
address: 127.0.0.1
port: 8080
devices:
- name: 'nvmf_tcp'
crypto:
name: 'bdev_crypto'
params:
driver: 'crypto_aesni_mb'
CONFIG
) &
smapid=$!
# Wait until the SMA starts listening
sma_waitforlisten
# Prepare the target
uuid=$(uuidgen)
waitforlisten "$tgtpid" "$tgtsock"
$rpc_py -s "$tgtsock" << CONFIG
bdev_malloc_create -b malloc0 32 4096 -u $uuid
nvmf_create_transport -t tcp
nvmf_create_subsystem $tgtnqn -a
nvmf_subsystem_add_listener discovery -t tcp -a 127.0.0.1 -s $discovery_port
nvmf_subsystem_add_listener -t tcp -a 127.0.0.1 -s 4421 -f ipv4 $tgtnqn
nvmf_subsystem_add_ns $tgtnqn malloc0
CONFIG
# Create an empty device first
device=$(create_device | jq -r '.handle')
# First attach a volume without crypto
attach_volume $device $uuid
ns_bdev=$(rpc_cmd nvmf_get_subsystems $localnqn | jq -r '.[0].namespaces[0].name')
[[ $(rpc_cmd bdev_get_bdevs -b "$ns_bdev" | jq -r '.[0].product_name') == 'NVMe disk' ]]
[[ $(rpc_cmd bdev_get_bdevs | jq -r '[.[] | select(.product_name == "crypto")] | length') -eq 0 ]]
[[ $(rpc_cmd nvmf_get_subsystems $localnqn | jq -r '.[0].namespaces[0].uuid') == "$uuid" ]]
[[ $(rpc_cmd nvmf_get_subsystems $localnqn | jq -r '.[0].namespaces[0].nguid') == "$(uuid2nguid $uuid)" ]]
detach_volume $device $uuid
# Now attach a volume with crypto enabled
attach_volume $device $uuid AES_CBC $key0
[[ $(rpc_cmd bdev_nvme_get_discovery_info | jq -r '. | length') -eq 1 ]]
[[ $(rpc_cmd nvmf_get_subsystems $localnqn | jq -r '.[0].namespaces | length') -eq 1 ]]
# Make sure that the namespace exposed in the subsystem is a crypto bdev and is using malloc bdev's UUID
verify_crypto_volume $localnqn $uuid
# Check that it's using correct key
crypto_bdev=$(rpc_cmd bdev_get_bdevs | jq -r '.[] | select(.product_name == "crypto")')
[[ $(jq -r '.driver_specific.crypto.key' <<< "$crypto_bdev") == "$key0" ]]
# Attach the same volume again
attach_volume $device $uuid AES_CBC $key0
# Nothing should change
[[ $(rpc_cmd bdev_nvme_get_discovery_info | jq -r '. | length') -eq 1 ]]
[[ $(rpc_cmd nvmf_get_subsystems $localnqn | jq -r '.[0].namespaces | length') -eq 1 ]]
verify_crypto_volume $localnqn $uuid
crypto_bdev2=$(rpc_cmd bdev_get_bdevs | jq -r '.[] | select(.product_name == "crypto")')
[[ $(jq -r '.name' <<< "$crypto_bdev") == $(jq -r '.name' <<< "$crypto_bdev2") ]]
[[ $(jq -r '.driver_specific.crypto.key' <<< "$crypto_bdev2") == "$key0" ]]
# Try to do attach it again, but this time use a different crypto algorithm
NOT attach_volume $device $uuid AES_XTS $key0
# Check the same, this time changing the key
NOT attach_volume $device $uuid AES_CBC $key1
# Check the same, this time adding second key
NOT attach_volume $device $uuid AES_CBC $key0 $key1
# Check out-of-range cipher value
NOT attach_volume $device $uuid 8 $key0
# Make sure these failures haven't affected anything
verify_crypto_volume $localnqn $uuid
detach_volume $device $uuid
# Check that if there's something wrong with crypto params, the volume won't get attached and
# everything is cleaned up afterwards
NOT attach_volume $device $uuid 8 $key0
[[ $(rpc_cmd nvmf_get_subsystems $localnqn | jq -r '.[0].namespaces | length') -eq 0 ]]
[[ $(rpc_cmd bdev_nvme_get_discovery_info | jq -r '. | length') -eq 0 ]]
[[ $(rpc_cmd bdev_get_bdevs | jq -r length) -eq 0 ]]
delete_device $device
# Check that it's possible to create a device immediately specyfing a volume with crypto
device=$(create_device $uuid AES_CBC $key0 | jq -r '.handle')
verify_crypto_volume $localnqn $uuid
delete_device $device
# Try to create a device with incorrect volume crypto params, check that it fails and everything
# is cleaned up afterwards
NOT create_device $uuid 8 $key0
[[ $(rpc_cmd bdev_nvme_get_discovery_info | jq -r '. | length') -eq 0 ]]
[[ $(rpc_cmd bdev_get_bdevs | jq -r length) -eq 0 ]]
[[ $(rpc_cmd nvmf_get_subsystems | jq -r "[.[] | select(.nqn == \"$localnqn\")] | length") -eq 0 ]]
# Check that if crypto is disabled, it's not possible to attach a volume with crypto
killprocess $smapid
$rootdir/scripts/sma.py -c <(
cat <<- CONFIG
address: 127.0.0.1
port: 8080
devices:
- name: 'nvmf_tcp'
CONFIG
) &
smapid=$!
sma_waitforlisten
device=$(create_device | jq -r '.handle')
NOT attach_volume $device $uuid AES_CBC $key0
[[ $(rpc_cmd bdev_nvme_get_discovery_info | jq -r '. | length') -eq 0 ]]
[[ $(rpc_cmd bdev_get_bdevs | jq -r length) -eq 0 ]]
cleanup
trap - SIGINT SIGTERM EXIT