summaryrefslogtreecommitdiffstats
path: root/src/spdk/test/lvol/thin_provisioning.sh
diff options
context:
space:
mode:
Diffstat (limited to 'src/spdk/test/lvol/thin_provisioning.sh')
-rwxr-xr-xsrc/spdk/test/lvol/thin_provisioning.sh236
1 files changed, 236 insertions, 0 deletions
diff --git a/src/spdk/test/lvol/thin_provisioning.sh b/src/spdk/test/lvol/thin_provisioning.sh
new file mode 100755
index 000000000..cb7bfcb01
--- /dev/null
+++ b/src/spdk/test/lvol/thin_provisioning.sh
@@ -0,0 +1,236 @@
+#!/usr/bin/env bash
+
+testdir=$(readlink -f $(dirname $0))
+rootdir=$(readlink -f $testdir/../..)
+source $rootdir/test/common/autotest_common.sh
+source $rootdir/test/lvol/common.sh
+source $rootdir/test/bdev/nbd_common.sh
+
+# Check if number of free clusters on lvol store decreases
+# if we write to created thin provisioned lvol bdev
+function test_thin_lvol_check_space() {
+ malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
+ lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test)
+ lvs=$(rpc_cmd bdev_lvol_get_lvstores -u "$lvs_uuid")
+ free_clusters_start="$(jq -r '.[0].free_clusters' <<< "$lvs")"
+
+ # Create thin provision lvol bdev with size equals to lvol store space
+ lvol_size_mb=$(round_down $((LVS_DEFAULT_CAPACITY_MB)))
+ lvol_uuid=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol_test "$lvol_size_mb" -t)
+
+ lvs=$(rpc_cmd bdev_lvol_get_lvstores -u "$lvs_uuid")
+ free_clusters_create_lvol="$(jq -r '.[0].free_clusters' <<< "$lvs")"
+ [ $free_clusters_start == $free_clusters_create_lvol ]
+
+ # Write data (lvs cluster size) to created lvol bdev starting from offset 0.
+ size=$LVS_DEFAULT_CLUSTER_SIZE
+ nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd0
+ run_fio_test /dev/nbd0 0 $size "write" "0xcc"
+ lvs=$(rpc_cmd bdev_lvol_get_lvstores -u "$lvs_uuid")
+ free_clusters_first_fio="$(jq -r '.[0].free_clusters' <<< "$lvs")"
+ [ $((free_clusters_first_fio + 1)) == $free_clusters_start ]
+
+ # Write data (lvs cluster size) to lvol bdev with offset set to one and half of cluster size
+ offset=$((LVS_DEFAULT_CLUSTER_SIZE * 3 / 2))
+ size=$LVS_DEFAULT_CLUSTER_SIZE
+ run_fio_test /dev/nbd0 $offset $size "write" "0xcc"
+ lvs=$(rpc_cmd bdev_lvol_get_lvstores -u "$lvs_uuid")
+ free_clusters_second_fio="$(jq -r '.[0].free_clusters' <<< "$lvs")"
+ [ $((free_clusters_second_fio + 3)) == $free_clusters_start ]
+
+ # write data to lvol bdev to the end of its size
+ size=$((LVS_DEFAULT_CLUSTER_SIZE * free_clusters_first_fio))
+ offset=$((3 * LVS_DEFAULT_CLUSTER_SIZE))
+ run_fio_test /dev/nbd0 $offset $size "write" "0xcc"
+ lvs=$(rpc_cmd bdev_lvol_get_lvstores -u "$lvs_uuid")
+ # Check that lvol store free clusters number equals to 0
+ free_clusters_third_fio="$(jq -r '.[0].free_clusters' <<< "$lvs")"
+ [ $((free_clusters_third_fio)) == 0 ]
+
+ nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
+ rpc_cmd bdev_lvol_delete "$lvol_uuid"
+ rpc_cmd bdev_get_bdevs -b "$lvol_uuid" && false
+ lvs=$(rpc_cmd bdev_lvol_get_lvstores -u "$lvs_uuid")
+ free_clusters_end="$(jq -r '.[0].free_clusters' <<< "$lvs")"
+ [ $((free_clusters_end)) == $free_clusters_start ]
+
+ # Clean up
+ rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid"
+ rpc_cmd bdev_lvol_get_lvstores -u "$lvs_uuid" && false
+ rpc_cmd bdev_malloc_delete "$malloc_name"
+}
+
+# Check if we can create thin provisioned bdev on empty lvol store
+# and check if we can read from this device and it returns zeroes.
+function test_thin_lvol_check_zeroes() {
+ malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
+ lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test)
+ lvs=$(rpc_cmd bdev_lvol_get_lvstores -u "$lvs_uuid")
+ free_clusters_start="$(jq -r '.[0].free_clusters' <<< "$lvs")"
+
+ # Create thick and thin provisioned lvol bdevs with size equals to lvol store space
+ lbd_name0=lvol_test0
+ lbd_name1=lvol_test1
+ lvol_size_mb=$((LVS_DEFAULT_CAPACITY_MB))
+ # Round down lvol size to the nearest cluster size boundary
+ lvol_size_mb=$((lvol_size_mb / LVS_DEFAULT_CLUSTER_SIZE_MB * LVS_DEFAULT_CLUSTER_SIZE_MB))
+ lvol_size=$((lvol_size_mb * 1024 * 1024))
+ lvol_uuid0=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" $lbd_name0 "$lvol_size_mb")
+ lvol_uuid1=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" $lbd_name1 "$lvol_size_mb" -t)
+
+ nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid0" /dev/nbd0
+ nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid1" /dev/nbd1
+
+ # Fill the whole thick provisioned lvol bdev
+ run_fio_test /dev/nbd0 0 $lvol_size "write" "0xcc"
+
+ # Perform read operations on thin provisioned lvol bdev
+ # and check if they return zeroes
+ run_fio_test /dev/nbd1 0 $lvol_size "read" "0x00"
+
+ # Clean up
+ nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd1
+ nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
+ rpc_cmd bdev_lvol_delete "$lvol_uuid1"
+ rpc_cmd bdev_lvol_delete "$lvol_uuid0"
+ rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid"
+ rpc_cmd bdev_malloc_delete "$malloc_name"
+}
+
+# Check if data written to thin provisioned lvol bdev
+# were properly written (fio test with verification)
+function test_thin_lvol_check_integrity() {
+ malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
+ lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test)
+
+ # Create thin provisioned lvol bdev with size equals to lvol store space
+ lvol_size_mb=$((LVS_DEFAULT_CAPACITY_MB))
+ # Round down lvol size to the nearest cluster size boundary
+ lvol_size_mb=$((lvol_size_mb / LVS_DEFAULT_CLUSTER_SIZE_MB * LVS_DEFAULT_CLUSTER_SIZE_MB))
+ lvol_size=$((lvol_size_mb * 1024 * 1024))
+ lvol_uuid=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol_test "$lvol_size_mb" -t)
+
+ nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd0
+ run_fio_test /dev/nbd0 0 $lvol_size "write" "0xcc"
+
+ # Clean up
+ nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
+ rpc_cmd bdev_lvol_delete "$lvol_uuid"
+ rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid"
+ rpc_cmd bdev_malloc_delete "$malloc_name"
+}
+
+# Check thin provisioned bdev resize
+function test_thin_lvol_resize() {
+ malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
+ lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test)
+
+ # Construct thin provisioned lvol bdevs on created lvol store
+ # with size equal to 50% of lvol store
+ lvol_size_mb=$(round_down $((LVS_DEFAULT_CAPACITY_MB / 2)))
+ lvol_size=$((lvol_size_mb * 1024 * 1024))
+ lvol_uuid=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol_test "$lvol_size_mb" -t)
+
+ # Fill all free space of lvol bdev with data
+ nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd0
+ run_fio_test /dev/nbd0 0 $lvol_size "write" "0xcc"
+ nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
+
+ # Save number of free clusters for lvs
+ lvs=$(rpc_cmd bdev_lvol_get_lvstores -u "$lvs_uuid")
+ free_clusters_start="$(jq -r '.[0].free_clusters' <<< "$lvs")"
+ # Resize bdev to full size of lvs
+ lvol_size_full_mb=$(round_down $((LVS_DEFAULT_CAPACITY_MB)))
+ lvol_size_full=$((lvol_size_full_mb * 1024 * 1024))
+ rpc_cmd bdev_lvol_resize $lvol_uuid $lvol_size_full_mb
+
+ # Check if bdev size changed (total_data_clusters*cluster_size
+ # equals to num_blocks*block_size)
+ lvol=$(rpc_cmd bdev_get_bdevs -b "$lvol_uuid")
+ [ "$(jq -r '.[0].block_size' <<< "$lvol")" = "$MALLOC_BS" ]
+ [ "$(jq -r '.[0].num_blocks' <<< "$lvol")" = $((lvol_size_full / MALLOC_BS)) ]
+
+ # Check if free_clusters on lvs remain unaffected
+ lvs=$(rpc_cmd bdev_lvol_get_lvstores -u "$lvs_uuid")
+ free_clusters_resize="$(jq -r '.[0].free_clusters' <<< "$lvs")"
+ [ $free_clusters_start == $free_clusters_resize ]
+
+ # Perform write operation with verification
+ # to newly created free space of lvol bdev
+ nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd0
+ run_fio_test /dev/nbd0 0 $lvol_size_full "write" "0xcc"
+ nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
+
+ # Check if free clusters on lvs equals to zero
+ lvs=$(rpc_cmd bdev_lvol_get_lvstores -u "$lvs_uuid")
+ free_clusters_start="$(jq -r '.[0].free_clusters' <<< "$lvs")"
+ [ $free_clusters_start == 0 ]
+
+ # Resize bdev to 25% of lvs and check if it ended with success
+ lvol_size_quarter_mb=$(round_down $((LVS_DEFAULT_CAPACITY_MB / 4)))
+ rpc_cmd bdev_lvol_resize $lvol_uuid $lvol_size_quarter_mb
+
+ # Check free clusters on lvs
+ lvs=$(rpc_cmd bdev_lvol_get_lvstores -u "$lvs_uuid")
+ free_clusters_resize_quarter="$(jq -r '.[0].free_clusters' <<< "$lvs")"
+ free_clusters_expected=$(((lvol_size_full_mb - lvol_size_quarter_mb) / LVS_DEFAULT_CLUSTER_SIZE_MB))
+ [ $free_clusters_resize_quarter == $free_clusters_expected ]
+
+ rpc_cmd bdev_lvol_delete "$lvol_uuid"
+ rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid"
+ rpc_cmd bdev_malloc_delete "$malloc_name"
+}
+
+function test_thin_overprovisioning() {
+ malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
+ lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test)
+
+ # Construct two thin provisioned lvol bdevs on created lvol store
+ # with size equal to free lvol store size
+ lvol_size_mb=$(round_down $((LVS_DEFAULT_CAPACITY_MB)))
+ lvol_size=$((lvol_size_mb * 1024 * 1024))
+ lvol_uuid1=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol_test1 "$lvol_size_mb" -t)
+ lvol_uuid2=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol_test2 "$lvol_size_mb" -t)
+
+ nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid1" /dev/nbd0
+ nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid2" /dev/nbd1
+ # Fill first bdev to 50% of its space with specific pattern
+ fill_size=$((lvol_size_mb * 5 / 10 / LVS_DEFAULT_CLUSTER_SIZE_MB * LVS_DEFAULT_CLUSTER_SIZE_MB))
+ fill_size=$((fill_size * 1024 * 1024))
+ run_fio_test /dev/nbd0 0 $fill_size "write" "0xcc"
+
+ # Fill second bdev up to 50% of its space
+ run_fio_test /dev/nbd1 0 $fill_size "write" "0xcc"
+
+ # Fill rest of second bdev
+ # Check that error message occured while filling second bdev with data
+ offset=$fill_size
+ fill_size_rest=$((lvol_size - fill_size))
+ run_fio_test /dev/nbd1 "$offset" "$fill_size_rest" "write" "0xcc" && false
+
+ # Check if data on first disk stayed unchanged
+ run_fio_test /dev/nbd0 0 $fill_size "read" "0xcc"
+ run_fio_test /dev/nbd0 $offset $fill_size_rest "read" "0x00"
+
+ nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
+ nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd1
+
+ rpc_cmd bdev_lvol_delete "$lvol_uuid2"
+ rpc_cmd bdev_lvol_delete "$lvol_uuid1"
+ rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid"
+ rpc_cmd bdev_malloc_delete "$malloc_name"
+}
+
+$SPDK_BIN_DIR/spdk_tgt &
+spdk_pid=$!
+trap 'killprocess "$spdk_pid"; exit 1' SIGINT SIGTERM EXIT
+waitforlisten $spdk_pid
+
+run_test "test_thin_lvol_check_space" test_thin_lvol_check_space
+run_test "test_thin_lvol_check_zeroes" test_thin_lvol_check_zeroes
+run_test "test_thin_lvol_check_integrity" test_thin_lvol_check_integrity
+run_test "test_thin_lvol_resize" test_thin_lvol_resize
+run_test "test_thin_overprovisioning" test_thin_overprovisioning
+
+trap - SIGINT SIGTERM EXIT
+killprocess $spdk_pid