1testdir=$(readlink -f $(dirname $0)) 2rootdir=$(readlink -f $testdir/../../..) 3source $rootdir/test/common/autotest_common.sh 4source $rootdir/test/vhost/common.sh 5 6dry_run=false 7no_shutdown=false 8fio_bin="fio" 9fio_jobs="$testdir/fio_jobs/" 10test_type=spdk_vhost_scsi 11reuse_vms=false 12vms=() 13used_vms="" 14disk_split="" 15x="" 16scsi_hot_remove_test=0 17blk_hot_remove_test=0 18readonly="" 19 20function usage() { 21 [[ -n $2 ]] && ( 22 echo "$2" 23 echo "" 24 ) 25 echo "Shortcut script for doing automated hotattach/hotdetach test" 26 echo "Usage: $(basename $1) [OPTIONS]" 27 echo 28 echo "-h, --help print help and exit" 29 echo " --test-type=TYPE Perform specified test:" 30 echo " virtio - test host virtio-scsi-pci using file as disk image" 31 echo " kernel_vhost - use kernel driver vhost-scsi" 32 echo " spdk_vhost_scsi - use spdk vhost scsi" 33 echo " spdk_vhost_blk - use spdk vhost block" 34 echo "-x set -x for script debug" 35 echo " --fio-bin=FIO Use specific fio binary (will be uploaded to VM)" 36 echo " --fio-jobs= Fio configs to use for tests. Can point to a directory or" 37 echo " --vm=NUM[,OS][,DISKS] VM configuration. This parameter might be used more than once:" 38 echo " NUM - VM number (mandatory)" 39 echo " OS - VM os disk path (optional)" 40 echo " DISKS - VM os test disks/devices path (virtio - optional, kernel_vhost - mandatory)" 41 echo " --scsi-hotremove-test Run scsi hotremove tests" 42 echo " --readonly Use readonly for fio" 43 exit 0 44} 45 46while getopts 'xh-:' optchar; do 47 case "$optchar" in 48 -) 49 case "$OPTARG" in 50 help) usage $0 ;; 51 fio-bin=*) fio_bin="${OPTARG#*=}" ;; 52 fio-jobs=*) fio_jobs="${OPTARG#*=}" ;; 53 test-type=*) test_type="${OPTARG#*=}" ;; 54 vm=*) vms+=("${OPTARG#*=}") ;; 55 scsi-hotremove-test) scsi_hot_remove_test=1 ;; 56 blk-hotremove-test) blk_hot_remove_test=1 ;; 57 readonly) readonly="--readonly" ;; 58 *) usage $0 "Invalid argument '$OPTARG'" ;; 59 esac 60 ;; 61 h) usage $0 ;; 62 x) 63 set -x 64 x="-x" 65 ;; 66 *) usage $0 "Invalid argument '$OPTARG'" ;; 67 esac 68done 69shift $((OPTIND - 1)) 70 71fio_job=$testdir/fio_jobs/default_integrity.job 72tmp_attach_job=$testdir/fio_jobs/fio_attach.job.tmp 73tmp_detach_job=$testdir/fio_jobs/fio_detach.job.tmp 74 75rpc_py="$rootdir/scripts/rpc.py -s $(get_vhost_dir 0)/rpc.sock" 76 77function print_test_fio_header() { 78 notice "===============" 79 notice "" 80 notice "Testing..." 81 82 notice "Running fio jobs ..." 83 if [ $# -gt 0 ]; then 84 echo $1 85 fi 86} 87 88function vms_setup() { 89 for vm_conf in "${vms[@]}"; do 90 IFS=',' read -ra conf <<< "$vm_conf" 91 if [[ -z ${conf[0]} ]] || ! assert_number ${conf[0]}; then 92 fail "invalid VM configuration syntax $vm_conf" 93 fi 94 95 # Sanity check if VM is not defined twice 96 for vm_num in $used_vms; do 97 if [[ $vm_num -eq ${conf[0]} ]]; then 98 fail "VM$vm_num defined more than twice ( $(printf "'%s' " "${vms[@]}"))!" 99 fi 100 done 101 102 used_vms+=" ${conf[0]}" 103 104 setup_cmd="vm_setup --disk-type=$test_type --force=${conf[0]}" 105 [[ x"${conf[1]}" != x"" ]] && setup_cmd+=" --os=${conf[1]}" 106 [[ x"${conf[2]}" != x"" ]] && setup_cmd+=" --disks=${conf[2]}" 107 $setup_cmd 108 done 109} 110 111function vm_run_with_arg() { 112 local vms_to_run="$*" 113 vm_run $vms_to_run 114 vm_wait_for_boot 300 $vms_to_run 115} 116 117function vms_setup_and_run() { 118 local vms_to_run="$*" 119 vms_setup 120 vm_run_with_arg $vms_to_run 121} 122 123function vms_prepare() { 124 for vm_num in $1; do 125 qemu_mask_param="VM_${vm_num}_qemu_mask" 126 127 host_name="VM-${vm_num}-${!qemu_mask_param}" 128 notice "Setting up hostname: $host_name" 129 vm_exec $vm_num "hostname $host_name" 130 vm_start_fio_server --fio-bin=$fio_bin $readonly $vm_num 131 done 132} 133 134function vms_reboot_all() { 135 notice "Rebooting all vms " 136 for vm_num in $1; do 137 vm_exec $vm_num "reboot" || true 138 while vm_os_booted $vm_num; do 139 sleep 0.5 140 done 141 done 142 143 vm_wait_for_boot 300 $1 144} 145 146function check_fio_retcode() { 147 local fio_retcode=$3 148 echo $1 149 local retcode_expected=$2 150 if [ $retcode_expected == 0 ]; then 151 if [ $fio_retcode != 0 ]; then 152 error " Fio test ended with error." 153 else 154 notice " Fio test ended with success." 155 fi 156 else 157 if [ $fio_retcode != 0 ]; then 158 notice " Fio test ended with expected error." 159 else 160 error " Fio test ended with unexpected success." 161 fi 162 fi 163} 164 165function wait_for_finish() { 166 local wait_for_pid=$1 167 local sequence=${2:-30} 168 for i in $(seq 1 $sequence); do 169 if kill -0 $wait_for_pid; then 170 sleep 0.5 171 continue 172 else 173 break 174 fi 175 done 176 if kill -0 $wait_for_pid; then 177 error "Timeout for fio command" 178 fi 179 180 wait $wait_for_pid 181} 182 183function reboot_all_and_prepare() { 184 vms_reboot_all "$1" 185 vms_prepare "$1" 186} 187 188function post_test_case() { 189 vm_shutdown_all 190 vhost_kill 0 191} 192 193function on_error_exit() { 194 set +e 195 echo "Error on $1 - $2" 196 post_test_case 197 print_backtrace 198 exit 1 199} 200 201function check_disks() { 202 if [ "$1" == "$2" ]; then 203 echo "Disk has not been deleted" 204 exit 1 205 fi 206} 207 208function get_traddr() { 209 local nvme_name=$1 210 local nvme 211 212 nvme="$($rootdir/scripts/gen_nvme.sh)" 213 traddr=$(jq -r ".config[] | select(.params.name == \"$nvme_name\") | .params.trtype" <<< "$nvme") 214 [[ -n $traddr ]] || return 1 215} 216 217function delete_nvme() { 218 $rpc_py bdev_nvme_detach_controller $1 219} 220 221function add_nvme() { 222 $rpc_py bdev_nvme_attach_controller -b $1 -t PCIe -a $2 223} 224