2022-08-04 02:28:15 +00:00
|
|
|
#!/usr/bin/env bash
|
2022-11-02 15:49:40 +00:00
|
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
# Copyright (C) 2022 Intel Corporation
|
|
|
|
# All rights reserved.
|
|
|
|
#
|
2022-08-04 02:28:15 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2022-10-20 13:21:23 +00:00
|
|
|
"$rootdir/build/bin/spdk_tgt" -m 0x1 &
|
2022-08-04 02:28:15 +00:00
|
|
|
hostpid=$!
|
|
|
|
|
2022-10-20 13:21:23 +00:00
|
|
|
"$rootdir/build/bin/spdk_tgt" -r "$tgtsock" -m 0x2 &
|
2022-08-04 02:28:15 +00:00
|
|
|
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
|