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