1#!/usr/bin/env bash 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright (C) 2020 Intel Corporation 4# All rights reserved. 5# 6testdir=$(readlink -f "$(dirname "$0")") 7rootdir=$(readlink -f "$testdir/../../") 8source "$testdir/common.sh" 9 10shopt -s nullglob 11 12cleanup() { 13 cleanup_nvme 14 cleanup_dm 15 16 if [[ -b /dev/$test_disk ]]; then 17 wipefs --all "/dev/$test_disk" 18 fi 19} 20 21cleanup_nvme() { 22 if mountpoint -q "$nvme_mount"; then 23 umount "$nvme_mount" 24 fi 25 26 if [[ -b /dev/$nvme_disk_p ]]; then 27 wipefs --all "/dev/$nvme_disk_p" 28 fi 29 if [[ -b /dev/$nvme_disk ]]; then 30 wipefs --all "/dev/$nvme_disk" 31 fi 32} 33 34cleanup_dm() { 35 if mountpoint -q "$dm_mount"; then 36 umount "$dm_mount" 37 fi 38 if [[ -L /dev/mapper/$dm_name ]]; then 39 dmsetup remove --force "$dm_name" 40 fi 41 if [[ -b /dev/$pv0 ]]; then 42 wipefs --all "/dev/$pv0" 43 fi 44 if [[ -b /dev/$pv1 ]]; then 45 wipefs --all "/dev/$pv1" 46 fi 47} 48 49verify() { 50 local dev=$1 51 local mounts=$2 52 local mount_point=$3 53 local test_file=$4 54 55 local found=0 56 57 if [[ -n $test_file ]]; then 58 : > "$test_file" 59 fi 60 61 local pci status 62 while read -r pci _ _ status; do 63 if [[ $pci == "$dev" && \ 64 $status == *"Active devices: "*"$mounts"* ]]; then 65 found=1 66 fi 67 done < <(PCI_ALLOWED="$dev" setup output config) 68 ((found == 1)) 69 70 [[ -n $mount_point ]] || return 0 71 72 # Does the mount still exist? 73 mountpoint -q "$mount_point" 74 # Does the test file still exist? 75 [[ -e $test_file ]] 76 rm "$test_file" 77} 78 79nvme_mount() { 80 # Agenda 1: 81 # - Create single partition on the nvme drive 82 # - Install ext4 fs on the first partition 83 # - Mount the partition 84 # - Run tests and check if setup.sh skipped 85 # nvme controller given block device is 86 # bound to. 87 88 # Agenda 2: 89 # - Install ext4 on the entire nvme drive 90 # - Mount the drive 91 # Run tests and check if setup.sh skipped 92 # nvme controller given block device is 93 # bound to. 94 95 # Keep scope of all the variables global to make the cleanup process easier. 96 97 nvme_disk=$test_disk 98 nvme_disk_p=${nvme_disk}p1 99 nvme_mount=$SPDK_TEST_STORAGE/nvme_mount 100 nvme_dummy_test_file=$nvme_mount/test_nvme 101 102 # Agenda 1 103 partition_drive "$nvme_disk" 1 104 mkfs "/dev/$nvme_disk_p" "$nvme_mount" 105 106 verify \ 107 "${blocks_to_pci["$nvme_disk"]}" \ 108 "$nvme_disk:$nvme_disk_p" \ 109 "$nvme_mount" \ 110 "$nvme_dummy_test_file" 111 112 cleanup_nvme 113 114 # Agenda 2 115 mkfs "/dev/$nvme_disk" "$nvme_mount" 1024M 116 117 verify \ 118 "${blocks_to_pci["$nvme_disk"]}" \ 119 "$nvme_disk:$nvme_disk" \ 120 "$nvme_mount" \ 121 "$nvme_dummy_test_file" 122 123 # umount the nvme device and verify again - device should not be touched 124 # when a valid fs is still present. 125 umount "$nvme_mount" 126 127 verify "${blocks_to_pci["$nvme_disk"]}" "data@$nvme_disk" "" "" 128 129 # All done, final cleanup 130 cleanup_nvme 131} 132 133dm_mount() { 134 # Agenda: 135 # - Create two partitions on the nvme drive 136 # - Create dm device consisting of half of 137 # the size of each partition. 138 # - Install ext4 fs on the dm device 139 # - Mount dm device 140 # - Run tests and check if setup.sh skipped 141 # nvme controller given block devices are 142 # bound to. 143 144 # Keep scope of all the variables global to make the cleanup process easier. 145 146 pv=$test_disk 147 pv0=${pv}p1 148 pv1=${pv}p2 149 150 partition_drive "$pv" 151 152 dm_name=nvme_dm_test 153 dm_mount=$SPDK_TEST_STORAGE/dm_mount 154 dm_dummy_test_file=$dm_mount/test_dm 155 156 # Each partition is 1G in size, join their halves 157 dmsetup create "$dm_name" <<- DM_TABLE 158 0 1048576 linear /dev/$pv0 0 159 1048576 1048576 linear /dev/$pv1 0 160 DM_TABLE 161 162 [[ -e /dev/mapper/$dm_name ]] 163 dm=$(readlink -f "/dev/mapper/$dm_name") 164 dm=${dm##*/} 165 166 [[ -e /sys/class/block/$pv0/holders/$dm ]] 167 [[ -e /sys/class/block/$pv1/holders/$dm ]] 168 169 mkfs "/dev/mapper/$dm_name" "$dm_mount" 170 171 verify \ 172 "${blocks_to_pci["$pv"]}" \ 173 "$pv:$dm_name" \ 174 "$dm_mount" \ 175 "$dm_dummy_test_file" 176 177 # umount the dm device and verify again - device should not be 178 # touched when it's actively being hold, regardless if it's mounted 179 # or not. 180 umount "$dm_mount" 181 182 verify "${blocks_to_pci["$pv"]}" "holder@$pv0:$dm,holder@$pv1:$dm" "" "" 183 184 # All done, start tiding up 185 cleanup_dm 186} 187 188trap "cleanup" EXIT 189 190setup reset 191 192get_zoned_devs 193 194declare -a blocks=() 195declare -A blocks_to_pci=() 196min_disk_size=$((1024 ** 3 * 3)) # 3GB 197 198for block in "/sys/block/nvme"*; do 199 pci=$(readlink -f "$block/device/device") 200 pci=${pci##*/} 201 [[ ${zoned_devs[*]} == *"$pci"* ]] && continue 202 if ! block_in_use "${block##*/}" && (($(sec_size_to_bytes "${block##*/}") >= min_disk_size)); then 203 blocks+=("${block##*/}") 204 blocks_to_pci["${block##*/}"]=$pci 205 fi 206done 207((${#blocks[@]} > 0)) 208 209declare -r test_disk=${blocks[0]} 210 211run_test "nvme_mount" nvme_mount 212run_test "dm_mount" dm_mount 213