xref: /spdk/test/nvmf/target/nvmf_lvs_grow.sh (revision c6c1234de9e0015e670dd0b51bf6ce39ee0e07bd)
1#!/usr/bin/env bash
2#  SPDX-License-Identifier: BSD-3-Clause
3#  Copyright (C) 2023 Intel Corporation
4#  All rights reserved.
5#
6testdir=$(readlink -f "$(dirname "$0")")
7rootdir=$(readlink -f "$testdir/../../..")
8source "$rootdir/test/common/autotest_common.sh"
9source "$rootdir/test/nvmf/common.sh"
10
11rpc_py="$rootdir/scripts/rpc.py"
12bdevperf_rpc_sock="/var/tmp/bdevperf.sock"
13
14lvs_grow() {
15	local aio_bdev lvs lvol
16	local data_clusters free_clusters
17	local bdevperf_pid run_test_pid
18	local aio_init_size_mb=200
19	local aio_final_size_mb=400
20	local lvol_bdev_size_mb=150
21
22	# Create an AIO bdev for the logical volume store
23	rm -f "$testdir/aio_bdev"
24	truncate -s "${aio_init_size_mb}M" "$testdir/aio_bdev"
25	aio_bdev=$($rpc_py bdev_aio_create "$testdir/aio_bdev" aio_bdev 4096)
26
27	# Create the logical volume store on the AIO bdev, with predictable cluster size and remaining md pages for grow
28	lvs=$($rpc_py bdev_lvol_create_lvstore --cluster-sz 4194304 --md-pages-per-cluster-ratio 300 $aio_bdev lvs)
29	data_clusters=$($rpc_py bdev_lvol_get_lvstores -u $lvs | jq -r '.[0].total_data_clusters')
30	((data_clusters == 49))
31
32	# Create a thin provisioned logical volume on the logical volume store
33	lvol=$($rpc_py bdev_lvol_create -u $lvs lvol $lvol_bdev_size_mb)
34
35	# Increase the AIO file size, without yet increasing the logical volume store size
36	truncate -s "${aio_final_size_mb}M" "$testdir/aio_bdev"
37	$rpc_py bdev_aio_rescan $aio_bdev
38	((data_clusters == $($rpc_py bdev_lvol_get_lvstores -u $lvs | jq -r '.[0].total_data_clusters')))
39
40	# Create an NVMe-oF subsystem and add the logical volume as a namespace
41	$rpc_py nvmf_create_subsystem nqn.2016-06.io.spdk:cnode0 -a -s SPDK0
42	$rpc_py nvmf_subsystem_add_ns nqn.2016-06.io.spdk:cnode0 $lvol
43	$rpc_py nvmf_subsystem_add_listener nqn.2016-06.io.spdk:cnode0 -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP -s $NVMF_PORT
44	$rpc_py nvmf_subsystem_add_listener discovery -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP -s $NVMF_PORT
45
46	# Start random writes in the background
47	$SPDK_EXAMPLE_DIR/bdevperf -r $bdevperf_rpc_sock -m 0x2 -o 4096 -q 128 -w randwrite -t 10 -S 1 -z &
48	bdevperf_pid=$!
49	trap 'killprocess $bdevperf_pid; nvmftestfini; exit 1' SIGINT SIGTERM EXIT
50	waitforlisten $bdevperf_pid $bdevperf_rpc_sock
51
52	$rpc_py -s $bdevperf_rpc_sock bdev_nvme_attach_controller -b Nvme0 -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP -s $NVMF_PORT -f ipv4 -n nqn.2016-06.io.spdk:cnode0
53	$rpc_py -s $bdevperf_rpc_sock bdev_get_bdevs -b Nvme0n1 -t 3000
54
55	$rootdir/examples/bdev/bdevperf/bdevperf.py -s $bdevperf_rpc_sock perform_tests &
56	run_test_pid=$!
57	sleep 2
58
59	# Perform grow operation on the logical volume store
60	$rpc_py bdev_lvol_grow_lvstore -u $lvs
61	data_clusters=$($rpc_py bdev_lvol_get_lvstores -u $lvs | jq -r '.[0].total_data_clusters')
62	((data_clusters == 99))
63
64	# Wait for I/O to complete
65	wait $run_test_pid
66	killprocess $bdevperf_pid
67
68	$rpc_py nvmf_subsystem_remove_listener discovery -t $TEST_TRANSPORT -a $NVMF_FIRST_TARGET_IP -s $NVMF_PORT
69	$rpc_py nvmf_delete_subsystem nqn.2016-06.io.spdk:cnode0
70	free_clusters=$($rpc_py bdev_lvol_get_lvstores -u $lvs | jq -r '.[0].free_clusters')
71
72	if [[ "$1" == "dirty" ]]; then
73		# Immediately shutdown nvmf_tgt without a chance to persist metadata after grow
74		kill -9 $nvmfpid
75		wait $nvmfpid || true
76		nvmfappstart -m 0x1
77		aio_bdev=$($rpc_py bdev_aio_create "$testdir/aio_bdev" aio_bdev 4096)
78		waitforbdev $lvol
79		((free_clusters == $($rpc_py bdev_lvol_get_lvstores -u $lvs | jq -r '.[0].free_clusters')))
80		((data_clusters == $($rpc_py bdev_lvol_get_lvstores -u $lvs | jq -r '.[0].total_data_clusters')))
81	fi
82
83	# Reload the logical volume store, making sure that number of clusters remain unchanged
84	$rpc_py bdev_aio_delete $aio_bdev
85	NOT $rpc_py bdev_lvol_get_lvstores -u $lvs
86	$rpc_py bdev_aio_create "$testdir/aio_bdev" $aio_bdev 4096
87	waitforbdev $lvol
88	((free_clusters == $($rpc_py bdev_lvol_get_lvstores -u $lvs | jq -r '.[0].free_clusters')))
89	((data_clusters == $($rpc_py bdev_lvol_get_lvstores -u $lvs | jq -r '.[0].total_data_clusters')))
90
91	# Clean up
92	$rpc_py bdev_lvol_delete $lvol
93	$rpc_py bdev_lvol_delete_lvstore -u $lvs
94	$rpc_py bdev_aio_delete $aio_bdev
95	rm -f "$testdir/aio_bdev"
96}
97
98nvmftestinit
99nvmfappstart -m 0x1
100$rpc_py nvmf_create_transport $NVMF_TRANSPORT_OPTS -u 8192
101
102run_test "lvs_grow_clean" lvs_grow
103run_test "lvs_grow_dirty" lvs_grow dirty
104