test/sma: crypto test
The test uses bdev_crypto and NVMe/TCP devices to verify that volumes with crypto parameters are correctly attached and any errors are handled as intended. It starts up two spdk_tgt processes, one is being orchestrated by SMA and the other one acts as an NVMe-oF target. This ensures that we can verify that SMA terminates discovery service connections whenever a failure occurs during crypto setup. Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com> Change-Id: I74001c256d4a05d2d8d295fb6fd8375d30ab66a1 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13873 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
a9d10dade8
commit
30ff5c6f14
@ -100,3 +100,4 @@ sma_plugins
|
||||
sma_discovery
|
||||
sma_vhost
|
||||
sma_vfiouser_qemu
|
||||
sma_crypto
|
||||
|
288
test/sma/crypto.sh
Executable file
288
test/sma/crypto.sh
Executable file
@ -0,0 +1,288 @@
|
||||
#!/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
|
||||
}
|
||||
|
||||
get_cipher() {
|
||||
case "$1" in
|
||||
AES_CBC) echo 0 ;;
|
||||
AES_XTS) echo 1 ;;
|
||||
*) echo "$1" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
format_key() {
|
||||
base64 <(echo -n "$1")
|
||||
}
|
||||
|
||||
uuid2nguid() {
|
||||
# The NGUID returned by the RPC is UPPERCASE
|
||||
local uuid=${1^^}
|
||||
echo ${uuid//-/}
|
||||
}
|
||||
|
||||
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" &
|
||||
hostpid=$!
|
||||
|
||||
"$rootdir/build/bin/spdk_tgt" -r "$tgtsock" &
|
||||
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
|
@ -10,3 +10,4 @@ run_test "sma_vfiouser_qemu" $testdir/vfiouser_qemu.sh
|
||||
run_test "sma_plugins" $testdir/plugins.sh
|
||||
run_test "sma_discovery" $testdir/discovery.sh
|
||||
run_test "sma_vhost" $testdir/vhost_blk.sh
|
||||
run_test "sma_crypto" $testdir/crypto.sh
|
||||
|
Loading…
Reference in New Issue
Block a user