diff --git a/autotest.sh b/autotest.sh index e3298a430..f835cdaa4 100755 --- a/autotest.sh +++ b/autotest.sh @@ -109,12 +109,6 @@ timing_enter lib if [ $SPDK_TEST_BLOCKDEV -eq 1 ]; then run_test suite test/bdev/blockdev.sh - if [ $(uname -s) = Linux ]; then - run_test suite test/bdev/bdevjson/json_config.sh - if modprobe -n nbd; then - run_test suite test/bdev/nbdjson/json_config.sh - fi - fi fi if [ $SPDK_TEST_JSON -eq 1 ]; then @@ -150,7 +144,6 @@ timing_exit lib if [ $SPDK_TEST_ISCSI -eq 1 ]; then run_test suite ./test/iscsi_tgt/iscsi_tgt.sh posix - run_test suite ./test/iscsi_tgt/iscsijson/json_config.sh run_test suite ./test/spdkcli/iscsi.sh fi @@ -161,7 +154,6 @@ fi if [ $SPDK_TEST_NVMF -eq 1 ]; then run_test suite ./test/nvmf/nvmf.sh - run_test suite ./test/nvmf/nvmfjson/json_config.sh run_test suite ./test/spdkcli/nvmf.sh fi @@ -186,7 +178,6 @@ fi if [ $SPDK_TEST_VHOST_INIT -eq 1 ]; then timing_enter vhost_initiator run_test suite ./test/vhost/initiator/blockdev.sh - run_test suite ./test/vhost/initiator/json_config.sh run_test suite ./test/spdkcli/virtio.sh report_test_completion "vhost_initiator" timing_exit vhost_initiator @@ -194,15 +185,15 @@ fi if [ $SPDK_TEST_PMDK -eq 1 ]; then run_test suite ./test/pmem/pmem.sh -x - run_test suite ./test/pmem/json_config/json_config.sh run_test suite ./test/spdkcli/pmem.sh fi if [ $SPDK_TEST_RBD -eq 1 ]; then - run_test suite ./test/bdev/bdevjson/rbd_json_config.sh run_test suite ./test/spdkcli/rbd.sh fi +run_test suite ./test/json_config/json_config.sh + timing_enter cleanup autotest_cleanup timing_exit cleanup diff --git a/test/bdev/bdevjson/json_config.sh b/test/bdev/bdevjson/json_config.sh deleted file mode 100755 index 3e5d276ef..000000000 --- a/test/bdev/bdevjson/json_config.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash -set -ex -BDEV_JSON_DIR=$(readlink -f $(dirname $0)) -. $BDEV_JSON_DIR/../../json_config/common.sh - -function test_subsystems() { - run_spdk_tgt - rootdir=$(readlink -f $BDEV_JSON_DIR/../../..) - - rpc_py="$spdk_rpc_py" - clear_config_py="$spdk_clear_config_py" - load_nvme - create_bdev_subsystem_config - test_json_config - - clear_bdev_subsystem_config - test_global_params "spdk_tgt" - kill_targets -} - -timing_enter json_config -trap 'on_error_exit "${FUNCNAME}" "${LINENO}"' ERR - -test_subsystems - -timing_exit json_config -report_test_completion json_config diff --git a/test/bdev/bdevjson/rbd_json_config.sh b/test/bdev/bdevjson/rbd_json_config.sh deleted file mode 100755 index 458ecb740..000000000 --- a/test/bdev/bdevjson/rbd_json_config.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash -set -ex -VHOST_JSON_DIR=$(readlink -f $(dirname $0)) -. $VHOST_JSON_DIR/../../json_config/common.sh - -function test_subsystems() { - run_spdk_tgt - rootdir=$(readlink -f $VHOST_JSON_DIR/../../..) - - rpc_py="$spdk_rpc_py" - clear_config_py="$spdk_clear_config_py" - $rpc_py start_subsystem_init - - create_rbd_bdev_subsystem_config - test_json_config - clear_rbd_bdev_subsystem_config - - kill_targets -} - -trap 'rbd_cleanup; on_error_exit "${FUNCNAME}" "${LINENO}"' ERR -timing_enter rbd_json_config - -test_subsystems -timing_exit rbd_json_config -report_test_completion rbd_json_config diff --git a/test/bdev/nbdjson/json_config.sh b/test/bdev/nbdjson/json_config.sh deleted file mode 100755 index 062d12038..000000000 --- a/test/bdev/nbdjson/json_config.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash -set -xe -NBD_JSON_DIR=$(readlink -f $(dirname $0)) -. $NBD_JSON_DIR/../../json_config/common.sh -rpc_py="$spdk_rpc_py" -clear_config_py="$spdk_clear_config_py" -trap 'on_error_exit "${FUNCNAME}" "${LINENO}"' ERR - -timing_enter nbd_json_config -run_spdk_tgt -load_nvme -modprobe nbd - -timing_enter nbd_json_config_create_setup -$rpc_py construct_malloc_bdev 128 512 --name Malloc0 -$rpc_py start_nbd_disk Malloc0 /dev/nbd0 -waitfornbd nbd0 -$rpc_py start_nbd_disk Nvme0n1 /dev/nbd1 -waitfornbd nbd1 -timing_exit nbd_json_config_create_setup - -timing_enter nbd_json_config_test -test_json_config -timing_exit nbd_json_config_test - -$clear_config_py clear_config -kill_targets -timing_exit nbd_json_config -report_test_completion nbd_json_config diff --git a/test/iscsi_tgt/iscsijson/json_config.sh b/test/iscsi_tgt/iscsijson/json_config.sh deleted file mode 100755 index cec662b7e..000000000 --- a/test/iscsi_tgt/iscsijson/json_config.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env bash -set -xe -ISCSI_JSON_DIR=$(readlink -f $(dirname $0)) -. $ISCSI_JSON_DIR/../../json_config/common.sh -. $JSON_DIR/../iscsi_tgt/common.sh -base_iscsi_config=$JSON_DIR/base_iscsi_config.json -last_iscsi_config=$JSON_DIR/last_iscsi_config.json -rpc_py="$spdk_rpc_py" -clear_config_py="$spdk_clear_config_py" -trap 'on_error_exit "${FUNCNAME}" "${LINENO}"; rm -f $base_iscsi_config $last_iscsi_config' ERR - -timing_enter iscsi_json_config -run_spdk_tgt -$rpc_py start_subsystem_init - -timing_enter iscsi_json_config_create_setup -$rpc_py add_portal_group $PORTAL_TAG 127.0.0.1:$ISCSI_PORT -$rpc_py add_initiator_group $INITIATOR_TAG $INITIATOR_NAME $NETMASK -$rpc_py construct_malloc_bdev 64 4096 --name Malloc0 -$rpc_py construct_target_node Target3 Target3_alias 'Malloc0:0' $PORTAL_TAG:$INITIATOR_TAG 64 -d -$rpc_py save_config > $base_iscsi_config -timing_exit iscsi_json_config_create_setup - -timing_enter iscsi_json_config_test -test_json_config -timing_exit iscsi_json_config_test - -timing_enter iscsi_json_config_restart_spdk -$clear_config_py clear_config -kill_targets -run_spdk_tgt -$rpc_py load_config < $base_iscsi_config -$rpc_py save_config > $last_iscsi_config -timing_exit iscsi_json_config_restart_spdk - -json_diff $base_iscsi_config $last_iscsi_config - -$clear_config_py clear_config -kill_targets -rm -f $base_iscsi_config $last_iscsi_config - -timing_exit iscsi_json_config -report_test_completion iscsi_json_config diff --git a/test/json_config/common.sh b/test/json_config/common.sh deleted file mode 100644 index 79a9aed6d..000000000 --- a/test/json_config/common.sh +++ /dev/null @@ -1,281 +0,0 @@ -JSON_DIR=$(readlink -f $(dirname ${BASH_SOURCE[0]})) -SPDK_BUILD_DIR=$JSON_DIR/../../ -source $JSON_DIR/../common/autotest_common.sh -source $JSON_DIR/../nvmf/common.sh - -spdk_rpc_py="$SPDK_BUILD_DIR/scripts/rpc.py -s /var/tmp/spdk.sock" -spdk_clear_config_py="$JSON_DIR/clear_config.py -s /var/tmp/spdk.sock" -initiator_rpc_py="$SPDK_BUILD_DIR/scripts/rpc.py -s /var/tmp/virtio.sock" -initiator_clear_config_py="$JSON_DIR/clear_config.py -s /var/tmp/virtio.sock" -base_json_config=$JSON_DIR/base_config.json -last_json_config=$JSON_DIR/last_config.json -full_config=$JSON_DIR/full_config.json -base_bdevs=$JSON_DIR/bdevs_base.txt -last_bdevs=$JSON_DIR/bdevs_last.txt -null_json_config=$JSON_DIR/null_json_config.json - -function run_spdk_tgt() { - echo "Running spdk target" - local wait_for_rpc='' - - if [[ $# -eq 0 ]]; then - wait_for_rpc='--wait-for-rpc' - fi - - $SPDK_BUILD_DIR/app/spdk_tgt/spdk_tgt -m 0x1 -p 0 -s 4096 $wait_for_rpc "$@" & - spdk_tgt_pid=$! - - echo "Waiting for app to run..." - waitforlisten $spdk_tgt_pid - echo "spdk_tgt started - pid=$spdk_tgt_pid but waits for subsystem initialization" - - echo "" -} - -function load_nvme() { - echo '{"subsystems": [' > nvme_config.json - $SPDK_BUILD_DIR/scripts/gen_nvme.sh --json >> nvme_config.json - echo ']}' >> nvme_config.json - $rpc_py load_config < nvme_config.json - rm nvme_config.json -} - -function run_initiator() { - local wait_for_rpc='' - - if [[ $# -eq 0 ]]; then - wait_for_rpc='--wait-for-rpc' - fi - - $SPDK_BUILD_DIR/app/spdk_tgt/spdk_tgt -m 0x2 -p 0 -g -u -s 1024 -r /var/tmp/virtio.sock $wait_for_rpc "$@" & - virtio_pid=$! - waitforlisten $virtio_pid /var/tmp/virtio.sock -} - -function upload_vhost() { - $rpc_py construct_split_vbdev Nvme0n1 8 - $rpc_py construct_vhost_scsi_controller sample1 - $rpc_py add_vhost_scsi_lun sample1 0 Nvme0n1p3 - $rpc_py add_vhost_scsi_lun sample1 1 Nvme0n1p4 - $rpc_py set_vhost_controller_coalescing sample1 1 100 - $rpc_py construct_vhost_blk_controller sample2 Nvme0n1p5 - $rpc_py construct_vhost_nvme_controller sample3 16 - $rpc_py add_vhost_nvme_ns sample3 Nvme0n1p6 -} - -function kill_targets() { - if [ ! -z $virtio_pid ]; then - killprocess $virtio_pid - fi - if [ ! -z $spdk_tgt_pid ]; then - killprocess $spdk_tgt_pid - fi -} - -# Compare two JSON files. -# -# NOTE: Order of objects in JSON can change by just doing loads -> dumps so all JSON objects (not arrays) are sorted by -# config_filter.py script. Sorted output is used to compare JSON output. -# -function json_diff() -{ - local tmp_file_1=$(mktemp ${1}.XXX) - local tmp_file_2=$(mktemp ${2}.XXX) - local ret=0 - - cat $1 | $JSON_DIR/config_filter.py -method "sort" > $tmp_file_1 - cat $2 | $JSON_DIR/config_filter.py -method "sort" > $tmp_file_2 - - if ! diff -u $tmp_file_1 $tmp_file_2; then - ret=1 - fi - - rm $tmp_file_1 $tmp_file_2 - return $ret -} - -# This function test if json config was properly saved and loaded. -# 1. Get a list of bdevs and save it to the file "base_bdevs". -# 2. Save only configuration of the running spdk_tgt to the file "base_json_config" -# (global parameters are not saved). -# 3. Clear configuration of the running spdk_tgt. -# 4. Save only configuration of the running spdk_tgt to the file "null_json_config" -# (global parameters are not saved). -# 5. Check if configuration of the running spdk_tgt is cleared by checking -# if the file "null_json_config" doesn't have any configuration. -# 6. Load the file "base_json_config" to the running spdk_tgt. -# 7. Get a list of bdevs and save it to the file "last_bdevs". -# 8. Save only configuration of the running spdk_tgt to the file "last_json_config". -# 9. Check if the file "base_json_config" matches the file "last_json_config". -# 10. Check if the file "base_bdevs" matches the file "last_bdevs". -# 11. Remove all files. -function test_json_config() { - $rpc_py get_bdevs | jq '.|sort_by(.name)' > $base_bdevs - $rpc_py save_config > $full_config - $JSON_DIR/config_filter.py -method "delete_global_parameters" < $full_config > $base_json_config - $clear_config_py clear_config - $rpc_py save_config | $JSON_DIR/config_filter.py -method "delete_global_parameters" > $null_json_config - if [ "[]" != "$(jq '.subsystems | map(select(.config != null)) | map(select(.config != []))' $null_json_config)" ]; then - echo "Config has not been cleared" - return 1 - fi - $rpc_py load_config < $base_json_config - $rpc_py get_bdevs | jq '.|sort_by(.name)' > $last_bdevs - $rpc_py save_config | $JSON_DIR/config_filter.py -method "delete_global_parameters" > $last_json_config - - json_diff $base_json_config $last_json_config - json_diff $base_bdevs $last_bdevs - remove_config_files_after_test_json_config -} - -function remove_config_files_after_test_json_config() { - rm -f $last_bdevs $base_bdevs - rm -f $last_json_config $base_json_config - rm -f $full_config $null_json_config -} - -function create_pmem_bdev_subsytem_config() { - $rpc_py create_pmem_pool /tmp/pool_file1 128 512 - $rpc_py construct_pmem_bdev -n pmem1 /tmp/pool_file1 -} - -function clear_pmem_bdev_subsystem_config() { - $clear_config_py clear_config - $rpc_py delete_pmem_pool /tmp/pool_file1 -} - -function create_rbd_bdev_subsystem_config() { - rbd_setup 127.0.0.1 - $rpc_py construct_rbd_bdev $RBD_POOL $RBD_NAME 4096 -} - -function clear_rbd_bdev_subsystem_config() { - $clear_config_py clear_config - rbd_cleanup -} - -function create_bdev_subsystem_config() { - $rpc_py construct_split_vbdev Nvme0n1 2 - $rpc_py construct_null_bdev Null0 32 512 - $rpc_py construct_malloc_bdev 128 512 --name Malloc0 - $rpc_py construct_malloc_bdev 64 4096 --name Malloc1 - $rpc_py construct_malloc_bdev 8 1024 --name Malloc2 - if [ $SPDK_TEST_CRYPTO -eq 1 ]; then - $rpc_py construct_malloc_bdev 8 1024 --name Malloc3 - if [ $(lspci -d:37c8 | wc -l) -eq 0 ]; then - $rpc_py construct_crypto_bdev -b Malloc3 -c CryMalloc3 -d crypto_aesni_mb -k 0123456789123456 - else - $rpc_py construct_crypto_bdev -b Malloc3 -c CryMalloc3 -d crypto_qat -k 0123456789123456 - fi - fi - $rpc_py construct_malloc_bdev 8 1024 --name Malloc4 - $rpc_py construct_passthru_bdev -b Malloc4 -p PTMalloc4 - $rpc_py construct_error_bdev Malloc2 - if [ $(uname -s) = Linux ]; then - dd if=/dev/zero of=/tmp/sample_aio bs=2048 count=5000 - $rpc_py construct_aio_bdev /tmp/sample_aio aio_disk 1024 - fi - $rpc_py construct_lvol_store -c 1048576 Nvme0n1p0 lvs_test - $rpc_py construct_lvol_bdev -l lvs_test lvol0 32 - $rpc_py construct_lvol_bdev -l lvs_test -t lvol1 32 - $rpc_py snapshot_lvol_bdev lvs_test/lvol0 snapshot0 - $rpc_py clone_lvol_bdev lvs_test/snapshot0 clone0 -} - -function create_nvmf_subsystem_config() { - rdma_device_init - RDMA_IP_LIST=$(get_available_rdma_ips) - NVMF_FIRST_TARGET_IP=$(echo "$RDMA_IP_LIST" | head -n 1) - if [ -z $NVMF_FIRST_TARGET_IP ]; then - echo "Error: no NIC for nvmf test" - return 1 - fi - - bdevs="$($rpc_py construct_malloc_bdev 64 512) " - bdevs+="$($rpc_py construct_malloc_bdev 64 512)" - - $rpc_py nvmf_create_transport -t RDMA -u 8192 -p 4 -c 0 - $rpc_py nvmf_subsystem_create nqn.2016-06.io.spdk:cnode1 -a -s SPDK00000000000001 - for bdev in $bdevs; do - $rpc_py nvmf_subsystem_add_ns nqn.2016-06.io.spdk:cnode1 $bdev - done - $rpc_py nvmf_subsystem_add_listener nqn.2016-06.io.spdk:cnode1 -t RDMA -a $NVMF_FIRST_TARGET_IP -s "$NVMF_PORT" -} - -function clear_nvmf_subsystem_config() { - $clear_config_py clear_config -} - -function clear_bdev_subsystem_config() { - $rpc_py destroy_lvol_bdev lvs_test/clone0 - $rpc_py destroy_lvol_bdev lvs_test/lvol0 - $rpc_py destroy_lvol_bdev lvs_test/snapshot0 - $rpc_py destroy_lvol_store -l lvs_test - $clear_config_py clear_config - if [ $(uname -s) = Linux ]; then - rm -f /tmp/sample_aio - fi -} - -# In this test, target is spdk_tgt or virtio_initiator. -# 1. Save current spdk config to full_config -# and save only global parameters to the file "base_json_config". -# 2. Exit the running spdk target. -# 3. Start the spdk target or initiator. -# 4. Load global parameters and configuration to the spdk target or initiator from the file full_config. -# 5. Save only global parameters to the file "last_json_config". -# 7. Check if the file "base_json_config" matches the file "last_json_config". -# 8. Start the spdk target or initiator with JSON file as it's configuration. -# 9. Save only global parameters to the file "last_json_config". -# 10. Check if the file "base_json_config" matches the file "last_json_config". -# 11. Delete all files. -function test_global_params() { - target=$1 - $rpc_py save_config > $full_config - - $JSON_DIR/config_filter.py -method "delete_configs" < $full_config > $base_json_config - if [ $target == "spdk_tgt" ]; then - killprocess $spdk_tgt_pid - run_spdk_tgt - elif [ $target == "virtio_initiator" ]; then - killprocess $virtio_pid - run_initiator - else - echo "Target is not specified for test_global_params" - return 1 - fi - $rpc_py load_config < $full_config - $rpc_py save_config | $JSON_DIR/config_filter.py -method "delete_configs" > $last_json_config - json_diff $base_json_config $last_json_config - - if [ $target == "spdk_tgt" ]; then - killprocess $spdk_tgt_pid - run_spdk_tgt --json $full_config - elif [ $target == "virtio_initiator" ]; then - killprocess $virtio_pid - run_initiator --json $full_config - else - echo "Target is not specified for test_global_params" - return 1 - fi - - $rpc_py save_config | $JSON_DIR/config_filter.py -method "delete_configs" > $last_json_config - json_diff $base_json_config $last_json_config - - rm $base_json_config $last_json_config - rm $full_config -} - -function on_error_exit() { - set +e - echo "Error on $1 - $2" - remove_config_files_after_test_json_config - rpc_py="$spdk_rpc_py" - clear_config_py="$spdk_clear_config_py" - clear_bdev_subsystem_config - - kill_targets - - print_backtrace - exit 1 -} diff --git a/test/json_config/json_config.sh b/test/json_config/json_config.sh new file mode 100755 index 000000000..c3da1f754 --- /dev/null +++ b/test/json_config/json_config.sh @@ -0,0 +1,384 @@ +#!/usr/bin/env bash + +set -e + +rootdir=$(readlink -f $(dirname $0)/../..) +SPDK_AUTOTEST_X=false +source "$rootdir/test/common/autotest_common.sh" +source "$rootdir/test/nvmf/common.sh" + +set -x + +if [[ $SPDK_TEST_ISCSI -eq 1 ]]; then + source "$rootdir/test/iscsi_tgt/common.sh" +fi + +if [[ $SPDK_TEST_VHOST -ne 1 && $SPDK_TEST_VHOST_INIT -eq 1 ]]; then + SPDK_TEST_VHOST=1 + echo "WARNING: Virtio initiator JSON_config test requires vhost target." + echo " Setting SPDK_TEST_VHOST=1 for duration of current script." +fi + +set -x + +if (( SPDK_TEST_BLOCKDEV + \ + SPDK_TEST_ISCSI + + SPDK_TEST_NVMF + + SPDK_TEST_VHOST + + SPDK_TEST_VHOST_INIT + + SPDK_TEST_PMDK + + SPDK_TEST_RBD == 0 )); then + echo "WARNING: No tests are enabled so not running JSON configuration tests" + exit 0 +fi + +declare -A app_pid=([target]= [initiator]=) +declare -A app_socket=([target]='/var/tmp/spdk_tgt.sock' [initiator]='/var/tmp/spdk_initiator.sock') +declare -A app_params=([target]='-m 0x1 -s 1024' [initiator]='-m 0x2 -g -u -s 1024') +declare -A configs_path=([target]="$rootdir/spdk_tgt_config.json" [initiator]="$rootdir/spdk_initiator_config.json") + +function tgt_rpc() { + $rootdir/scripts/rpc.py -s "${app_socket[target]}" "$@" +} + +function initiator_rpc() { + $rootdir/scripts/rpc.py -s "${app_socket[initiator]}" "$@" +} + +# $1 - target / initiator +# $2..$n app parameters +function json_config_test_start_app() { + local app=$1 + shift + + [[ ! -z "${#app_socket[$app]}" ]] # Check app type + [[ -z "${app_pid[$app]}" ]] # Assert if app is not running + set -x + + local app_extra_params="" + if [[ $SPDK_TEST_VHOST -eq 1 || $SPDK_TEST_VHOST_INIT -eq 1 ]]; then + # If PWD is nfs/sshfs we can't create UNIX sockets there. Always use safe location instead. + app_extra_params='-S /var/tmp' + fi + + $rootdir/app/spdk_tgt/spdk_tgt ${app_params[$app]} ${app_extra_params} -r ${app_socket[$app]} "$@" & + app_pid[$app]=$! + + echo "Waiting for $app to run..." + waitforlisten ${app_pid[$app]} ${app_socket[$app]} + echo "" +} + +# $1 - target / initiator +function json_config_test_shutdown_app() { + local app=$1 + + # Check app type && assert app was started + [[ ! -z "${#app_socket[$app]}" ]] + [[ ! -z "${app_pid[$app]}" ]] + + # kill_instance RPC will trigger ASAN + kill -SIGINT ${app_pid[$app]} + + for (( i=0; i<10; i++ )); do + if ! kill -0 ${app_pid[$app]} 2>/dev/null; then + app_pid[$app]= + break + fi + sleep 0.5 + done + + if [[ ! -z "${app_pid[$app]}" ]]; then + echo "SPDK $app shutdown timeout" + return 1 + fi + + echo "SPDK $app shutdown done" +} + +function create_bdev_subsystem_config() { + timing_enter $FUNCNAME + + if [[ $SPDK_TEST_BLOCKDEV -eq 1 ]]; then + local lvol_store_base_bdev=Nvme0n1 + if ! tgt_rpc get_bdevs --name ${lvol_store_base_bdev} >/dev/null; then + if [[ $(uname -s) = Linux ]]; then + lvol_store_base_bdev=aio_disk + echo "WARNING: No NVMe drive found. Using '$lvol_store_base_bdev' instead." + else + echo "ERROR: No NVMe drive found and bdev_aio is not supported on $(uname -s)." + timing_exit $FUNCNAME + return 1 + fi + fi + + tgt_rpc construct_split_vbdev $lvol_store_base_bdev 2 + tgt_rpc construct_split_vbdev Malloc0 3 + tgt_rpc construct_passthru_bdev -b Malloc3 -p PTBdevFromMalloc3 + + tgt_rpc construct_null_bdev Null0 32 512 + + tgt_rpc construct_malloc_bdev 32 512 --name Malloc0 + tgt_rpc construct_malloc_bdev 16 4096 --name Malloc1 + + if [[ $(uname -s) = Linux ]]; then + # This AIO bdev must be large enough to be used as LVOL store + dd if=/dev/zero of=/tmp/sample_aio bs=1024 count=102400 + tgt_rpc construct_aio_bdev /tmp/sample_aio aio_disk 1024 + fi + + # For LVOLs use split to check for proper order of initialization. + # If LVOLs cofniguration will be reordered (eg moved before splits or AIO/NVMe) + # it should fail loading JSON config from file. + tgt_rpc construct_lvol_store -c 1048576 ${lvol_store_base_bdev}p0 lvs_test + tgt_rpc construct_lvol_bdev -l lvs_test lvol0 32 + tgt_rpc construct_lvol_bdev -l lvs_test -t lvol1 32 + tgt_rpc snapshot_lvol_bdev lvs_test/lvol0 snapshot0 + tgt_rpc clone_lvol_bdev lvs_test/snapshot0 clone0 + fi + + if [[ $SPDK_TEST_CRYPTO -eq 1 ]]; then + tgt_rpc construct_malloc_bdev 8 1024 --name MallocForCryptoBdev + if [[ $(lspci -d:37c8 | wc -l) -eq 0 ]]; then + local crypto_dirver=crypto_aesni_mb + else + local crypto_dirver=crypto_qat + fi + + tgt_rpc construct_crypto_bdev -b MallocForCryptoBdev -c CryptoMallocBdev -d $crypto_dirver -k 0123456789123456 + fi + + if [[ $SPDK_TEST_PMDK -eq 1 ]]; then + pmem_pool_file=$(mktemp /tmp/pool_file1.XXXXX) + rm -f $pmem_pool_file + tgt_rpc create_pmem_pool $pmem_pool_file 128 4096 + tgt_rpc construct_pmem_bdev -n pmem1 $pmem_pool_file + fi + + if [[ $SPDK_TEST_RBD -eq 1 ]]; then + rbd_setup 127.0.0.1 + tgt_rpc construct_rbd_bdev $RBD_POOL $RBD_NAME 4096 + fi + + timing_exit $FUNCNAME +} + +function cleanup_bdev_subsystem_config() { + timing_enter $FUNCNAME + + if [[ $SPDK_TEST_BLOCKDEV -eq 1 ]]; then + tgt_rpc destroy_lvol_bdev lvs_test/clone0 + tgt_rpc destroy_lvol_bdev lvs_test/lvol0 + tgt_rpc destroy_lvol_bdev lvs_test/snapshot0 + tgt_rpc destroy_lvol_store -l lvs_test + fi + + if [[ $(uname -s) = Linux ]]; then + rm -f /tmp/sample_aio + fi + + if [[ $SPDK_TEST_PMDK -eq 1 && ! -z "$pmem_pool_file" && -f "$pmem_pool_file" ]]; then + tgt_rpc delete_pmem_bdev pmem1 + tgt_rpc delete_pmem_pool $pmem_pool_file + rm -f $pmem_pool_file + fi + + if [[ $SPDK_TEST_RBD -eq 1 ]]; then + rbd_cleanup + fi + + timing_exit $FUNCNAME +} + +function create_vhost_subsystem_config() { + timing_enter $FUNCNAME + + tgt_rpc construct_malloc_bdev 64 1024 --name MallocForVhost0 + tgt_rpc construct_split_vbdev MallocForVhost0 8 + + tgt_rpc construct_vhost_scsi_controller VhostScsiCtrlr0 + tgt_rpc add_vhost_scsi_lun VhostScsiCtrlr0 0 MallocForVhost0p3 + tgt_rpc add_vhost_scsi_lun VhostScsiCtrlr0 1 MallocForVhost0p4 + tgt_rpc set_vhost_controller_coalescing VhostScsiCtrlr0 1 100 + + tgt_rpc construct_vhost_blk_controller VhostBlkCtrlr0 MallocForVhost0p5 + + tgt_rpc construct_vhost_nvme_controller VhostNvmeCtrlr0 16 + tgt_rpc add_vhost_nvme_ns VhostNvmeCtrlr0 MallocForVhost0p6 + + timing_exit $FUNCNAME +} + +function create_iscsi_subsystem_config() { + timing_enter $FUNCNAME + tgt_rpc construct_malloc_bdev 64 1024 --name MallocForIscsi0 + tgt_rpc add_portal_group $PORTAL_TAG 127.0.0.1:$ISCSI_PORT + tgt_rpc add_initiator_group $INITIATOR_TAG $INITIATOR_NAME $NETMASK + tgt_rpc construct_target_node Target3 Target3_alias 'MallocForIscsi0:0' $PORTAL_TAG:$INITIATOR_TAG 64 -d + timing_exit $FUNCNAME +} + +function create_nvmf_subsystem_config() { + timing_enter $FUNCNAME + + RDMA_IP_LIST=$(get_available_rdma_ips) + NVMF_FIRST_TARGET_IP=$(echo "$RDMA_IP_LIST" | head -n 1) + if [[ -z $NVMF_FIRST_TARGET_IP ]]; then + echo "Error: no NIC for nvmf test" + return 1 + fi + + tgt_rpc construct_malloc_bdev 8 512 --name MallocForNvmf0 + tgt_rpc construct_malloc_bdev 4 1024 --name MallocForNvmf1 + + tgt_rpc nvmf_create_transport -t RDMA -u 8192 -p 4 -c 0 + tgt_rpc nvmf_subsystem_create nqn.2016-06.io.spdk:cnode1 -a -s SPDK00000000000001 + tgt_rpc nvmf_subsystem_add_ns nqn.2016-06.io.spdk:cnode1 MallocForNvmf0 + tgt_rpc nvmf_subsystem_add_ns nqn.2016-06.io.spdk:cnode1 MallocForNvmf1 + tgt_rpc nvmf_subsystem_add_listener nqn.2016-06.io.spdk:cnode1 -t RDMA -a $NVMF_FIRST_TARGET_IP -s "$NVMF_PORT" + + timing_exit $FUNCNAME +} + +function create_virtio_initiator_config() { + timing_enter $FUNCNAME + initiator_rpc construct_virtio_dev -t user -a /var/tmp/VhostScsiCtrlr0 -d scsi VirtioScsiCtrlr0 + initiator_rpc construct_virtio_dev -t user -a /var/tmp/VhostBlkCtrlr0 -d blk VirtioBlk0 + # TODO: initiator_rpc construct_virtio_dev -t user -a /var/tmp/VhostNvmeCtrlr0 -d nvme VirtioNvme0 + timing_exit $FUNCNAME +} + + +function json_config_test_init() +{ + timing_enter $FUNCNAME + timing_enter json_config_setup_target + + json_config_test_start_app target --wait-for-rpc + + #TODO: global subsystem params + + # Load nvme configuration. The load_config will issue start_subsystem_init automatically + ( + echo '{"subsystems": ['; + $rootdir/scripts/gen_nvme.sh --json + echo ']}' + ) | tgt_rpc load_config + + if [[ $SPDK_TEST_BLOCKDEV -eq 1 ]]; then + create_bdev_subsystem_config + fi + + if [[ $SPDK_TEST_VHOST -eq 1 ]]; then + create_vhost_subsystem_config + fi + + if [[ $SPDK_TEST_ISCSI -eq 1 ]]; then + create_iscsi_subsystem_config + fi + + if [[ $SPDK_TEST_NVMF -eq 1 ]]; then + create_nvmf_subsystem_config + fi + timing_exit json_config_setup_target + + if [[ $SPDK_TEST_VHOST_INIT -eq 1 ]]; then + json_config_test_start_app initiator + create_virtio_initiator_config + fi + + tgt_rpc construct_malloc_bdev 8 512 --name MallocBdevForConfigChangeCheck + + timing_exit $FUNCNAME +} + +function json_config_test_fini() { + timing_enter $FUNCNAME + local ret=0 + + if [[ ! -z "${app_pid[initiator]}" ]]; then + if ! json_config_test_shutdown_app initiator; then + kill -9 ${app_pid[initiator]} + app_pid[initiator]= + ret=1 + fi + fi + + if [[ ! -z "${app_pid[target]}" ]]; then + + # Remove any artifacts we created (files, lvol etc) + cleanup_bdev_subsystem_config + + # SPDK_TEST_NVMF: Should we clear something? + + if ! json_config_test_shutdown_app target; then + kill -9 ${app_pid[target]} + app_pid[target]= + ret=1 + fi + fi + + rm -f "${configs_path[@]}" + timing_exit $FUNCNAME + return $ret +} + +function json_config_clear() { + [[ ! -z "${#app_socket[$1]}" ]] # Check app type + $rootdir/test/json_config/clear_config.py -s ${app_socket[$1]} clear_config + + #TODO check if config is cleared +} + +on_error_exit() { + set -x + set +e + print_backtrace + trap - ERR + echo "Error on $1 - $2" + json_config_test_fini + exit 1 +} + +trap 'on_error_exit "${FUNCNAME}" "${LINENO}"' ERR +echo "INFO: JSON configuration test init" +json_config_test_init + +tgt_rpc save_config > ${configs_path[target]} + +echo "INFO: shutting down applications..." +if [[ $SPDK_TEST_VHOST_INIT -eq 1 ]]; then + initiator_rpc save_config > ${configs_path[initiator]} + json_config_clear initiator + json_config_test_shutdown_app initiator +fi + +json_config_clear target +json_config_test_shutdown_app target + +echo "INFO: relaunching applications..." +json_config_test_start_app target --json ${configs_path[target]} +if [[ $SPDK_TEST_VHOST_INIT -eq 1 ]]; then + json_config_test_start_app initiator --json ${configs_path[initiator]} +fi + +echo "INFO: Checking if target configuration is the same..." +$rootdir/test/json_config/json_diff.sh <(tgt_rpc save_config) "${configs_path[target]}" +if [[ $SPDK_TEST_VHOST_INIT -eq 1 ]]; then + echo "INFO: Checking if virtio initiator configuration is the same..." + $rootdir/test/json_config/json_diff.sh <(initiator_rpc save_config) "${configs_path[initiator]}" +fi + +echo "INFO: changing configuration and checking if this can be detected..." +# Self test to check if configuration diff can be detected. +tgt_rpc delete_malloc_bdev MallocBdevForConfigChangeCheck +if $rootdir/test/json_config/json_diff.sh <(tgt_rpc save_config) "${configs_path[target]}" >/dev/null; then + echo "ERROR: intentional configuration difference not detected!" + false +else + echo "INFO: configuration change detected." +fi + +json_config_test_fini + +echo "INFO: Success" diff --git a/test/json_config/json_diff.sh b/test/json_config/json_diff.sh new file mode 100755 index 000000000..8b4bd6cbe --- /dev/null +++ b/test/json_config/json_diff.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +set -x + +if [ $# -ne 2 ]; then + echo "This script need exactly two arguments" + exit 1 +fi + +rootdir=$(readlink -f $(dirname $0)/../..) +# FIXME: Remove this when python3 will be on FeeBSD machines +if [ $(uname -s) = "FreeBSD" ]; then + python_cmd=python +else + python_cmd="" +fi + +# Compare two JSON files. +# +# NOTE: Order of objects in JSON can change by just doing loads -> dumps so all JSON objects (not arrays) are sorted by +# config_filter.py script. Sorted output is used to compare JSON output. +# + +tmp_file_1=$(mktemp /tmp/$(basename ${1}).XXX) +tmp_file_2=$(mktemp /tmp/$(basename ${2}).XXX) +ret=0 + +cat $1 | $python_cmd $rootdir/test/json_config/config_filter.py -method "sort" > $tmp_file_1 +cat $2 | $python_cmd $rootdir/test/json_config/config_filter.py -method "sort" > $tmp_file_2 + +if ! diff -u $tmp_file_1 $tmp_file_2; then + ret=1 + + echo "=== Start of file: $tmp_file_1 ===" + cat $tmp_file_1 + echo "=== End of file: $tmp_file_1 ===" + echo "" + echo "=== Start of file: $tmp_file_2 ===" + cat $tmp_file_2 + echo "=== End of file: $tmp_file_2 ===" + echo "" +else + echo "INFO: JSON config files are the same" +fi + +rm $tmp_file_1 $tmp_file_2 +exit $ret diff --git a/test/nvmf/nvmfjson/json_config.sh b/test/nvmf/nvmfjson/json_config.sh deleted file mode 100755 index bc624d21f..000000000 --- a/test/nvmf/nvmfjson/json_config.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env bash -set -xe -NVMF_JSON_DIR=$(readlink -f $(dirname $0)) -. $NVMF_JSON_DIR/../../json_config/common.sh -base_nvmf_config=$JSON_DIR/base_nvmf_config.json -last_nvmf_config=$JSON_DIR/last_nvmf_config.json - -function test_subsystems() { - run_spdk_tgt - - rpc_py="$spdk_rpc_py" - clear_config_py="$spdk_clear_config_py" - - $rpc_py start_subsystem_init - create_nvmf_subsystem_config - $rpc_py save_config > $base_nvmf_config - test_json_config - - clear_nvmf_subsystem_config - kill_targets - - run_spdk_tgt - $rpc_py load_config < $base_nvmf_config - $rpc_py save_config > $last_nvmf_config - - json_diff $base_nvmf_config $last_nvmf_config - - clear_nvmf_subsystem_config - kill_targets - rm -f $base_nvmf_config $last_nvmf_config -} - -trap 'on_error_exit "${FUNCNAME}" "${LINENO}"; rm -f $base_nvmf_config $last_nvmf_config' ERR - -timing_enter nvmf_json_config -test_subsystems -timing_exit nvmf_json_config -revert_soft_roce - -report_test_completion nvmf_json_config diff --git a/test/pmem/json_config/json_config.sh b/test/pmem/json_config/json_config.sh deleted file mode 100755 index bd232b8f3..000000000 --- a/test/pmem/json_config/json_config.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash -set -ex -VHOST_JSON_DIR=$(readlink -f $(dirname $0)) -. $VHOST_JSON_DIR/../../json_config/common.sh - -function test_subsystems() { - run_spdk_tgt - - rpc_py="$spdk_rpc_py" - clear_config_py="$spdk_clear_config_py" - $rpc_py start_subsystem_init - - create_pmem_bdev_subsytem_config - test_json_config - clear_pmem_bdev_subsystem_config - - kill_targets -} - -trap 'on_error_exit "${FUNCNAME}" "${LINENO}"' ERR -timing_enter json_config_pmem - -test_subsystems -timing_exit json_config_pmem -report_test_completion json_config_pmem diff --git a/test/spdkcli/common.sh b/test/spdkcli/common.sh index 61557bd3b..e1f7e2aa7 100644 --- a/test/spdkcli/common.sh +++ b/test/spdkcli/common.sh @@ -3,6 +3,7 @@ set -xe testdir=$(readlink -f $(dirname $0)) SPDKCLI_BUILD_DIR=$(readlink -f $testdir/../..) spdkcli_job="$SPDKCLI_BUILD_DIR/test/spdkcli/spdkcli_job.py" +spdk_clear_config_py="$SPDKCLI_BUILD_DIR/test/json_config/clear_config.py" . $SPDKCLI_BUILD_DIR/test/common/autotest_common.sh function on_error_exit() { diff --git a/test/spdkcli/vhost.sh b/test/spdkcli/vhost.sh index 7f5b542b1..8809f3804 100755 --- a/test/spdkcli/vhost.sh +++ b/test/spdkcli/vhost.sh @@ -4,7 +4,6 @@ set -xe MATCH_FILE="spdkcli_vhost.test" SPDKCLI_BRANCH="/" testdir=$(readlink -f $(dirname $0)) -. $testdir/../json_config/common.sh . $testdir/common.sh timing_enter spdk_cli_vhost diff --git a/test/vhost/initiator/json_config.sh b/test/vhost/initiator/json_config.sh deleted file mode 100755 index 86078c9a2..000000000 --- a/test/vhost/initiator/json_config.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env bash -set -ex -INITIATOR_JSON_DIR=$(readlink -f $(dirname $0)) -. $INITIATOR_JSON_DIR/../../json_config/common.sh - -# Load spdk_tgt with controllers used by virtio initiator -# Test also virtio_pci bdevs -function construct_vhost_devices() { - $rpc_py construct_split_vbdev Nvme0n1 4 - $rpc_py construct_vhost_scsi_controller naa.Nvme0n1p0.0 - $rpc_py construct_vhost_scsi_controller naa.Nvme0n1p1.1 - $rpc_py add_vhost_scsi_lun naa.Nvme0n1p0.0 0 Nvme0n1p0 - $rpc_py add_vhost_scsi_lun naa.Nvme0n1p1.1 0 Nvme0n1p1 - $rpc_py construct_vhost_blk_controller naa.Nvme0n1p2.0 Nvme0n1p2 - $rpc_py construct_vhost_blk_controller naa.Nvme0n1p3.1 Nvme0n1p3 - pci_scsi=$(lspci -nn -D | grep '1af4:1004' | head -1 | awk '{print $1;}') - pci_blk=$(lspci -nn -D | grep '1af4:1001' | head -1 | awk '{print $1;}') - if [ ! -z $pci_scsi ]; then - $rpc_py construct_virtio_dev -t pci -a $pci_scsi -d scsi Virtio0 - fi - if [ ! -z $pci_blk ]; then - $rpc_py construct_virtio_dev -t pci -a $pci_blk -d blk Virtio1 - fi -} - -# Load virtio initiator with bdevs -function connect_to_vhost_devices_from_initiator() { - $rpc_py construct_virtio_dev -t user -a naa.Nvme0n1p0.0 -d scsi Nvme0n1p0 - $rpc_py construct_virtio_dev -t user -a naa.Nvme0n1p2.0 -d blk Nvme0n1p2 -} - -function disconnect_and_clear_vhost_devices() { - $clear_config_py clear_config -} - -function test_subsystems() { - run_spdk_tgt - rootdir=$(readlink -f $INITIATOR_JSON_DIR/../../..) - - rpc_py="$spdk_rpc_py" - clear_config_py="$spdk_clear_config_py" - load_nvme - - construct_vhost_devices - test_json_config - run_initiator - rpc_py="$initiator_rpc_py" - clear_config_py="$initiator_clear_config_py" - $rpc_py start_subsystem_init - connect_to_vhost_devices_from_initiator - test_json_config - disconnect_and_clear_vhost_devices - test_global_params "virtio_initiator" - clear_config_py="$spdk_clear_config_py" - $clear_config_py clear_config - kill_targets -} - -trap 'on_error_exit "${FUNCNAME}" "${LINENO}"' ERR -timing_enter json_config_virtio_initiator - -test_subsystems -timing_exit json_config_virtio_initiator -report_test_completion json_config_virtio_initiator diff --git a/test/vhost/json_config/json_config.sh b/test/vhost/json_config/json_config.sh deleted file mode 100755 index d5683f1d5..000000000 --- a/test/vhost/json_config/json_config.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash -set -ex -VHOST_JSON_DIR=$(readlink -f $(dirname $0)) -. $VHOST_JSON_DIR/../../json_config/common.sh - -function test_subsystems() { - run_spdk_tgt - - rpc_py="$spdk_rpc_py" - clear_config_py="$spdk_clear_config_py" - load_nvme - - upload_vhost - test_json_config - $clear_config_py clear_config - - kill_targets -} - -trap 'on_error_exit "${FUNCNAME}" "${LINENO}"' ERR -timing_enter json_config_vhost - -test_subsystems -timing_exit json_config_vhost -report_test_completion json_config_vhost diff --git a/test/vhost/vhost.sh b/test/vhost/vhost.sh index 1ebea1806..64a4e435a 100755 --- a/test/vhost/vhost.sh +++ b/test/vhost/vhost.sh @@ -8,10 +8,6 @@ timing_enter negative run_test suite ./test/vhost/spdk_vhost.sh --negative timing_exit negative -timing_enter vhost_json_config -run_test suite ./test/vhost/json_config/json_config.sh -timing_exit vhost_json_config - timing_enter vhost_boot run_test suite ./test/vhost/spdk_vhost.sh --boot timing_exit vhost_boot