xref: /spdk/test/setup/devices.sh (revision f6866117acb32c78d5ea7bd76ba330284655af35)
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