1#!/usr/bin/env bash 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4# 5testdir=$(readlink -f "$(dirname "$0")") 6rootdir=$(readlink -f "$testdir/../..") 7source "$rootdir/test/common/autotest_common.sh" 8source "$rootdir/test/lvol/common.sh" 9source "$rootdir/test/bdev/nbd_common.sh" 10 11set -u 12 13g_nbd_dev=INVALID 14g_cluster_size=INVALID 15g_block_size=INVALID 16 17function test_esnap_reload() { 18 local bs_dev esnap_dev 19 local block_size=512 20 local esnap_size_mb=1 21 local lvs_cluster_size=$((16 * 1024)) 22 local lvs_uuid esnap_uuid eclone_uuid snap_uuid clone_uuid uuid 23 local aio_bdev=test_esnap_reload_aio0 24 25 # Create the lvstore on an aio device. Can't use malloc because we need to remove 26 # the device and re-add it to trigger an lvstore unload and then load. 27 rm -f $testdir/aio_bdev_0 28 truncate -s "${AIO_SIZE_MB}M" $testdir/aio_bdev_0 29 bs_dev=$(rpc_cmd bdev_aio_create "$testdir/aio_bdev_0" "$aio_bdev" "$block_size") 30 lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore -c "$lvs_cluster_size" "$bs_dev" lvs_test) 31 32 # Create a bdev that will be the external snapshot 33 esnap_uuid=e4b40d8b-f623-416d-8234-baf5a4c83cbd 34 esnap_dev=$(rpc_cmd bdev_malloc_create -u "$esnap_uuid" "$esnap_size_mb" "$block_size") 35 eclone_uuid=$(rpc_cmd bdev_lvol_clone_bdev "$esnap_uuid" lvs_test "eclone1") 36 37 # Unload the lvstore 38 rpc_cmd bdev_aio_delete "$aio_bdev" 39 NOT rpc_cmd bdev_lvol_get_lvstores -l lvs_test 40 41 # Load the lvstore, expect to see eclone1 again 42 bs_dev=$(rpc_cmd bdev_aio_create "$testdir/aio_bdev_0" "$aio_bdev" "$block_size") 43 lvs_uuid=$(rpc_cmd bdev_lvol_get_lvstores -l lvs_test) 44 uuid=$(rpc_cmd bdev_get_bdevs -b lvs_test/eclone1 | jq -r '.[].name') 45 [[ "$uuid" == "$eclone_uuid" ]] 46 47 # Create a snapshot of the eclone, reload, and verify all is there. 48 snap_uuid=$(rpc_cmd bdev_lvol_snapshot "$eclone_uuid" snap1) 49 rpc_cmd bdev_aio_delete "$aio_bdev" 50 NOT rpc_cmd bdev_lvol_get_lvstores -l lvs_test 51 bs_dev=$(rpc_cmd bdev_aio_create "$testdir/aio_bdev_0" "$aio_bdev" "$block_size") 52 lvs_uuid=$(rpc_cmd bdev_lvol_get_lvstores -l lvs_test) 53 uuid=$(rpc_cmd bdev_get_bdevs -b lvs_test/eclone1 | jq -r '.[].name') 54 [[ "$uuid" == "$eclone_uuid" ]] 55 uuid=$(rpc_cmd bdev_get_bdevs -b lvs_test/snap1 | jq -r '.[].name') 56 [[ "$uuid" == "$snap_uuid" ]] 57 58 # Create a clone of the snapshot, reload, and verify all is there. 59 clone_uuid=$(rpc_cmd bdev_lvol_clone "$snap_uuid" clone1) 60 rpc_cmd bdev_aio_delete "$aio_bdev" 61 NOT rpc_cmd bdev_lvol_get_lvstores -l lvs_test 62 bs_dev=$(rpc_cmd bdev_aio_create "$testdir/aio_bdev_0" "$aio_bdev" "$block_size") 63 lvs_uuid=$(rpc_cmd bdev_lvol_get_lvstores -l lvs_test) 64 uuid=$(rpc_cmd bdev_get_bdevs -b lvs_test/eclone1 | jq -r '.[].name') 65 [[ "$uuid" == "$eclone_uuid" ]] 66 uuid=$(rpc_cmd bdev_get_bdevs -b lvs_test/snap1 | jq -r '.[].name') 67 [[ "$uuid" == "$snap_uuid" ]] 68 uuid=$(rpc_cmd bdev_get_bdevs -b lvs_test/clone1 | jq -r '.[].name') 69 [[ "$uuid" == "$clone_uuid" ]] 70 71 rpc_cmd bdev_lvol_delete "$clone_uuid" 72 rpc_cmd bdev_lvol_delete "$snap_uuid" 73 rpc_cmd bdev_lvol_delete "$eclone_uuid" 74 rpc_cmd bdev_aio_delete "$aio_bdev" 75 rpc_cmd bdev_malloc_delete "$esnap_dev" 76} 77 78function test_esnap_reload_missing() { 79 local bs_dev esnap_dev 80 local block_size=512 81 local esnap_size_mb=1 82 local lvs_cluster_size=$((16 * 1024)) 83 local lvs_uuid esnap_uuid eclone_uuid snap_uuid clone_uuid uuid 84 local aio_bdev=test_esnap_reload_aio0 85 local lvols 86 87 # Create the lvstore on an aio device. Can't use malloc because we need to remove 88 # the device and re-add it to trigger an lvstore unload and then load. 89 rm -f $testdir/aio_bdev_0 90 truncate -s "${AIO_SIZE_MB}M" $testdir/aio_bdev_0 91 bs_dev=$(rpc_cmd bdev_aio_create "$testdir/aio_bdev_0" "$aio_bdev" "$block_size") 92 lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore -c "$lvs_cluster_size" "$bs_dev" lvs_test) 93 94 # Create a bdev that will be the external snapshot 95 # State: 96 # esnap(present) <-- eclone(not degraded) 97 esnap_uuid=e4b40d8b-f623-416d-8234-baf5a4c83cbd 98 esnap_dev=$(rpc_cmd bdev_malloc_create -u "$esnap_uuid" "$esnap_size_mb" "$block_size") 99 eclone_uuid=$(rpc_cmd bdev_lvol_clone_bdev "$esnap_uuid" lvs_test "eclone") 100 lvols=$(rpc_cmd bdev_lvol_get_lvols) 101 [[ "$(jq -r '. | length' <<< "$lvols")" == "1" ]] 102 [[ "$(jq -r '.[] | select(.name == "eclone").is_esnap_clone' <<< "$lvols")" == "true" ]] 103 [[ "$(jq -r '.[] | select(.name == "eclone").is_degraded' <<< "$lvols")" == "false" ]] 104 105 # Unload the lvstore and delete the external snapshot 106 rpc_cmd bdev_aio_delete "$aio_bdev" 107 NOT rpc_cmd bdev_lvol_get_lvstores -l lvs_test 108 rpc_cmd bdev_malloc_delete "$esnap_uuid" 109 110 # Load the lvstore, eclone bdev should not exist but the lvol should exist. 111 # State: 112 # esnap(missing) <-- eclone(degraded) 113 bs_dev=$(rpc_cmd bdev_aio_create "$testdir/aio_bdev_0" "$aio_bdev" "$block_size") 114 NOT rpc_cmd bdev_get_bdevs -b lvs_test/eclone 115 NOT rpc_cmd bdev_get_bdevs -b "$eclone_uuid" 116 lvols=$(rpc_cmd bdev_lvol_get_lvols) 117 [[ "$(jq -r '. | length' <<< "$lvols")" == "1" ]] 118 [[ "$(jq -r '.[] | select(.name == "eclone").is_degraded' <<< "$lvols")" == "true" ]] 119 120 # Reload the lvstore with esnap present during load. This should make the lvol not degraded. 121 # State: 122 # esnap(present) <-- eclone(not degraded) 123 rpc_cmd bdev_aio_delete "$aio_bdev" 124 NOT rpc_cmd bdev_lvol_get_lvstores -l lvs_test 125 esnap_dev=$(rpc_cmd bdev_malloc_create -u "$esnap_uuid" "$esnap_size_mb" "$block_size") 126 bs_dev=$(rpc_cmd bdev_aio_create "$testdir/aio_bdev_0" "$aio_bdev" "$block_size") 127 rpc_cmd bdev_lvol_get_lvstores -l lvs_test 128 rpc_cmd bdev_get_bdevs -b lvs_test/eclone 129 rpc_cmd bdev_get_bdevs -b "$eclone_uuid" 130 lvols=$(rpc_cmd bdev_lvol_get_lvols) 131 [[ "$(jq -r '. | length' <<< "$lvols")" == "1" ]] 132 [[ "$(jq -r '.[] | select(.name == "eclone").is_esnap_clone' <<< "$lvols")" == "true" ]] 133 [[ "$(jq -r '.[] | select(.name == "eclone").is_degraded' <<< "$lvols")" == "false" ]] 134 135 # Create a clone of eclone, then reload without the esnap present. 136 # State: 137 # esnap(missing) <-- eclone(degraded) <-- clone(degraded) 138 rpc_cmd bdev_lvol_set_read_only "$eclone_uuid" 139 clone_uuid=$(rpc_cmd bdev_lvol_clone "$eclone_uuid" clone) 140 rpc_cmd bdev_get_bdevs -b lvs_test/clone 141 rpc_cmd bdev_get_bdevs -b "$clone_uuid" 142 rpc_cmd bdev_aio_delete "$aio_bdev" 143 NOT rpc_cmd bdev_lvol_get_lvstores -l lvs_test 144 rpc_cmd bdev_malloc_delete "$esnap_uuid" 145 bs_dev=$(rpc_cmd bdev_aio_create "$testdir/aio_bdev_0" "$aio_bdev" "$block_size") 146 lvols=$(rpc_cmd bdev_lvol_get_lvols) 147 [[ "$(jq -r '.[] | select(.name == "eclone").is_esnap_clone' <<< "$lvols")" == "true" ]] 148 [[ "$(jq -r '.[] | select(.name == "eclone").is_degraded' <<< "$lvols")" == "true" ]] 149 [[ "$(jq -r '.[] | select(.name == "clone").is_clone' <<< "$lvols")" == "true" ]] 150 [[ "$(jq -r '.[] | select(.name == "eclone").is_degraded' <<< "$lvols")" == "true" ]] 151 NOT rpc_cmd bdev_get_bdevs -b lvs_test/eclone 152 NOT rpc_cmd bdev_get_bdevs -b "$eclone_uuid" 153 NOT rpc_cmd bdev_get_bdevs -b lvs_test/clone 154 NOT rpc_cmd bdev_get_bdevs -b "$clone_uuid" 155 156 # Reload the lvstore with esnap present during load. This should make the lvols not 157 # degraded. 158 # State: 159 # esnap(present) <-- eclone(not degraded) <-- clone(not degraded) 160 rpc_cmd bdev_aio_delete "$aio_bdev" 161 NOT rpc_cmd bdev_lvol_get_lvstores -l lvs_test 162 esnap_dev=$(rpc_cmd bdev_malloc_create -u "$esnap_uuid" "$esnap_size_mb" "$block_size") 163 bs_dev=$(rpc_cmd bdev_aio_create "$testdir/aio_bdev_0" "$aio_bdev" "$block_size") 164 lvols=$(rpc_cmd bdev_lvol_get_lvols) 165 [[ "$(jq -r '.[] | select(.name == "eclone").is_esnap_clone' <<< "$lvols")" == "true" ]] 166 [[ "$(jq -r '.[] | select(.name == "eclone").is_degraded' <<< "$lvols")" == "false" ]] 167 [[ "$(jq -r '.[] | select(.name == "clone").is_clone' <<< "$lvols")" == "true" ]] 168 [[ "$(jq -r '.[] | select(.name == "clone").is_degraded' <<< "$lvols")" == "false" ]] 169 rpc_cmd bdev_get_bdevs -b lvs_test/eclone 170 rpc_cmd bdev_get_bdevs -b "$eclone_uuid" 171 rpc_cmd bdev_get_bdevs -b lvs_test/clone 172 rpc_cmd bdev_get_bdevs -b "$clone_uuid" 173 174 # Create a snapshot of clone, then reload without the esnap present. 175 # State: 176 # esnap(missing) <-- eclone(degraded) <-- snap(degraded) <-- clone(degraded) 177 snap_uuid=$(rpc_cmd bdev_lvol_snapshot "$clone_uuid" snap) 178 rpc_cmd bdev_get_bdevs -b lvs_test/snap 179 rpc_cmd bdev_get_bdevs -b "$snap_uuid" 180 rpc_cmd bdev_aio_delete "$aio_bdev" 181 NOT rpc_cmd bdev_lvol_get_lvstores -l lvs_test 182 rpc_cmd bdev_malloc_delete "$esnap_uuid" 183 bs_dev=$(rpc_cmd bdev_aio_create "$testdir/aio_bdev_0" "$aio_bdev" "$block_size") 184 lvols=$(rpc_cmd bdev_lvol_get_lvols) 185 [[ "$(jq -r '.[] | select(.name == "eclone").is_esnap_clone' <<< "$lvols")" == "true" ]] 186 [[ "$(jq -r '.[] | select(.name == "eclone").is_degraded' <<< "$lvols")" == "true" ]] 187 [[ "$(jq -r '.[] | select(.name == "clone").is_clone' <<< "$lvols")" == "true" ]] 188 [[ "$(jq -r '.[] | select(.name == "clone").is_degraded' <<< "$lvols")" == "true" ]] 189 [[ "$(jq -r '.[] | select(.name == "snap").is_clone' <<< "$lvols")" == "true" ]] 190 [[ "$(jq -r '.[] | select(.name == "snap").is_snapshot' <<< "$lvols")" == "true" ]] 191 [[ "$(jq -r '.[] | select(.name == "snap").is_degraded' <<< "$lvols")" == "true" ]] 192 NOT rpc_cmd bdev_get_bdevs -b lvs_test/eclone 193 NOT rpc_cmd bdev_get_bdevs -b "$eclone_uuid" 194 NOT rpc_cmd bdev_get_bdevs -b lvs_test/clone 195 NOT rpc_cmd bdev_get_bdevs -b "$clone_uuid" 196 NOT rpc_cmd bdev_get_bdevs -b lvs_test/snap 197 NOT rpc_cmd bdev_get_bdevs -b "$snap_uuid" 198 199 # Create the esnap bdev and verify the degraded bdevs become not degraded. 200 esnap_dev=$(rpc_cmd bdev_malloc_create -u "$esnap_uuid" "$esnap_size_mb" "$block_size") 201 rpc_cmd bdev_wait_for_examine 202 lvols=$(rpc_cmd bdev_lvol_get_lvols) 203 [[ "$(jq -r '.[] | select(.name == "eclone").is_esnap_clone' <<< "$lvols")" == "true" ]] 204 [[ "$(jq -r '.[] | select(.name == "eclone").is_degraded' <<< "$lvols")" == "false" ]] 205 [[ "$(jq -r '.[] | select(.name == "clone").is_clone' <<< "$lvols")" == "true" ]] 206 [[ "$(jq -r '.[] | select(.name == "clone").is_degraded' <<< "$lvols")" == "false" ]] 207 [[ "$(jq -r '.[] | select(.name == "snap").is_clone' <<< "$lvols")" == "true" ]] 208 [[ "$(jq -r '.[] | select(.name == "snap").is_snapshot' <<< "$lvols")" == "true" ]] 209 [[ "$(jq -r '.[] | select(.name == "snap").is_degraded' <<< "$lvols")" == "false" ]] 210 rpc_cmd bdev_get_bdevs -b lvs_test/eclone 211 rpc_cmd bdev_get_bdevs -b "$eclone_uuid" 212 rpc_cmd bdev_get_bdevs -b lvs_test/clone 213 rpc_cmd bdev_get_bdevs -b "$clone_uuid" 214 rpc_cmd bdev_get_bdevs -b lvs_test/snap 215 rpc_cmd bdev_get_bdevs -b "$snap_uuid" 216 217 rpc_cmd bdev_aio_delete "$aio_bdev" 218 rpc_cmd bdev_malloc_delete "$esnap_uuid" 219} 220 221function log_jq_out() { 222 local key 223 224 xtrace_disable 225 226 while read -r key; do 227 printf '%50s = %s\n' "$key" "${jq_out[$key]}" 228 done < <(printf '%s\n' "${!jq_out[@]}" | sort) 229 230 xtrace_restore 231} 232 233function verify_clone() { 234 local bdev=$1 235 local parent=$2 236 237 rpc_cmd_simple_data_json bdev bdev_get_bdevs -b "$bdev" 238 log_jq_out 239 240 [[ "${jq_out["supported_io_types.read"]}" == true ]] 241 [[ "${jq_out["supported_io_types.write"]}" == true ]] 242 [[ "${jq_out["driver_specific.lvol.clone"]}" == true ]] 243 [[ "${jq_out["driver_specific.lvol.base_snapshot"]}" == "$parent" ]] 244 [[ "${jq_out["driver_specific.lvol.esnap_clone"]}" == false ]] 245 [[ "${jq_out["driver_specific.lvol.external_snapshot_name"]}" == null ]] 246} 247 248function verify_esnap_clone() { 249 local bdev=$1 250 local parent=$2 251 local writable=${3:-true} 252 253 rpc_cmd_simple_data_json bdev bdev_get_bdevs -b "$bdev" 254 log_jq_out 255 256 [[ "${jq_out["supported_io_types.read"]}" == true ]] 257 [[ "${jq_out["supported_io_types.write"]}" == "$writable" ]] 258 [[ "${jq_out["driver_specific.lvol.esnap_clone"]}" == true ]] 259 [[ "${jq_out["driver_specific.lvol.external_snapshot_name"]}" == "$parent" ]] 260} 261 262function test_esnap_clones() { 263 local bs_dev esnap_dev 264 local block_size=512 265 local lvs_size_mb=100 266 local esnap_size_mb=1 267 local lvs_cluster_size=$((16 * 1024)) 268 local lvs_uuid esnap_uuid 269 local vol1_uuid vol2_uuid vol3_uuid vol3_uuid vol4_uuid vol5_uuid 270 271 # Create the lvstore on a malloc device. 272 bs_dev=$(rpc_cmd bdev_malloc_create $lvs_size_mb $block_size) 273 lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore -c "$lvs_cluster_size" "$bs_dev" lvs_test) 274 275 # Create a bdev that will be the external snapshot 276 # State: 277 # esnap1 278 esnap_uuid=2abddd12-c08d-40ad-bccf-ab131586ee4c 279 esnap_dev=$(rpc_cmd bdev_malloc_create -b esnap1 -u "$esnap_uuid" "$esnap_size_mb" \ 280 "$block_size") 281 282 # Create an esnap clone: vol1 283 # New state: 284 # esnap1 <-- vol1(rw) 285 vol1_uuid=$(rpc_cmd bdev_lvol_clone_bdev "$esnap_uuid" lvs_test vol1) 286 verify_esnap_clone "$vol1_uuid" "$esnap_uuid" 287 288 # Create a snapshot of the esnap clone: vol2 289 # New state: 290 # esnap1 <-- vol2(ro) <-- vol1(rw) 291 vol2_uuid=$(rpc_cmd bdev_lvol_snapshot "$vol1_uuid" vol2) 292 verify_esnap_clone "$vol2_uuid" "$esnap_uuid" false 293 verify_clone "$vol1_uuid" vol2 294 295 # Delete vol2. 296 # New state: 297 # esnap1 <-- vol1(rw) 298 rpc_cmd bdev_lvol_delete "$vol2_uuid" 299 NOT rpc_cmd bdev_get_bdevs -b "$vol2_uuid" 300 verify_esnap_clone "$vol1_uuid" "$esnap_uuid" 301 vol2_uuid= 302 303 # Snapshot vol1: vol3 304 # New state: 305 # ensap1 <-- vol3(ro) <-- vol1(rw) 306 vol3_uuid=$(rpc_cmd bdev_lvol_snapshot "$vol1_uuid" vol3) 307 verify_esnap_clone "$vol3_uuid" "$esnap_uuid" false 308 verify_clone "$vol1_uuid" vol3 309 310 # Delete vol1 311 # New state: 312 # esnap1 <-- vol3(ro) 313 rpc_cmd bdev_lvol_delete $vol1_uuid 314 NOT rpc_cmd bdev_get_bdevs -b $vol1_uuid 315 verify_esnap_clone "$vol3_uuid" "$esnap_uuid" false 316 vol1_uuid= 317 318 # Create clone of vol3: vol4 319 # Verify vol3 is still a read-only esnap clone and vol4 is a normal clone. 320 # New state: 321 # ensap1 <-- vol3(ro) <-- vol4(rw) 322 vol4_uuid=$(rpc_cmd bdev_lvol_clone "$vol3_uuid" vol4) 323 rpc_cmd bdev_get_bdevs -b "$vol4_uuid" 324 verify_esnap_clone "$vol3_uuid" "$esnap_uuid" false 325 verify_clone "$vol4_uuid" vol3 326 327 # Create clone of vol3 (vol5). 328 # New state: 329 # ensap1 <-- vol3(ro) <-- vol4(rw) 330 # `<-- vol5(rw) 331 vol5_uuid=$(rpc_cmd bdev_lvol_clone "$vol3_uuid" vol5) 332 verify_esnap_clone "$vol3_uuid" "$esnap_uuid" false 333 verify_clone "$vol4_uuid" vol3 334 verify_clone "$vol5_uuid" vol3 335 336 # Cannot delete vol3 because it has multiple clones 337 NOT rpc_cmd bdev_lvol_delete "$vol3_uuid" 338 339 # Delete vol4 340 # New state: 341 # ensap1 <-- vol3(ro) <-- vol5(rw) 342 rpc_cmd bdev_lvol_delete "$vol4_uuid" 343 NOT rpc_cmd bdev_get_bdevs -b "$vol4_uuid" 344 verify_esnap_clone "$vol3_uuid" "$esnap_uuid" false 345 verify_clone "$vol5_uuid" vol3 346 347 # Delete vol3. 348 # New state: 349 # ensap1 <-- vol5(rw) 350 rpc_cmd bdev_lvol_delete "$vol3_uuid" 351 NOT rpc_cmd bdev_get_bdevs -b "$vol3_uuid" 352 verify_esnap_clone "$vol5_uuid" "$esnap_uuid" 353 354 # Delete vol5. 355 # New state: 356 # esnap1 357 rpc_cmd bdev_lvol_delete "$vol5_uuid" 358 NOT rpc_cmd bdev_get_bdevs -b "$vol5_uuid" 359 360 rpc_cmd bdev_malloc_delete "$bs_dev" 361 rpc_cmd bdev_malloc_delete "$esnap_dev" 362} 363 364function test_esnap_late_arrival() { 365 local bs_dev esnap_dev 366 local block_size=512 367 local esnap_size_mb=1 368 local lvs_cluster_size=$((16 * 1024)) 369 local lvs_uuid esnap_uuid eclone_uuid snap_uuid clone_uuid uuid 370 local aio_bdev=test_esnap_reload_aio0 371 local lvols 372 373 # Create the lvstore on an aio device. Can't use malloc because we need to remove 374 # the device and re-add it to trigger an lvstore unload and then load. 375 rm -f $testdir/aio_bdev_0 376 truncate -s "${AIO_SIZE_MB}M" $testdir/aio_bdev_0 377 bs_dev=$(rpc_cmd bdev_aio_create "$testdir/aio_bdev_0" "$aio_bdev" "$block_size") 378 lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore -c "$lvs_cluster_size" "$bs_dev" lvs_test) 379 380 # Create a bdev that will be the external snapshot 381 esnap_uuid=e4b40d8b-f623-416d-8234-baf5a4c83cbd 382 esnap_dev=$(rpc_cmd bdev_malloc_create -u "$esnap_uuid" "$esnap_size_mb" "$block_size") 383 eclone_uuid=$(rpc_cmd bdev_lvol_clone_bdev "$esnap_uuid" lvs_test "eclone1") 384 385 # Unload the lvstore 386 rpc_cmd bdev_aio_delete "$aio_bdev" 387 NOT rpc_cmd bdev_lvol_get_lvstores -l lvs_test 388 389 # Delete the external snapshot device then reload the lvstore. 390 rpc_cmd bdev_malloc_delete "$esnap_dev" 391 bs_dev=$(rpc_cmd bdev_aio_create "$testdir/aio_bdev_0" "$aio_bdev" "$block_size") 392 lvs_uuid=$(rpc_cmd bdev_lvol_get_lvstores -l lvs_test) 393 394 # Verify that the esnap clone exists but does not have the esnap loaded. 395 NOT rpc_cmd bdev_get_bdevs -b "$esnap_uuid" 396 NOT rpc_cmd bdev_get_bdevs -b "$eclone_uuid" 397 lvols=$(rpc_cmd bdev_lvol_get_lvols) 398 [[ "$(jq -r '.[] | select(.uuid == "'$eclone_uuid'").is_esnap_clone' <<< "$lvols")" == "true" ]] 399 [[ "$(jq -r '.[] | select(.uuid == "'$eclone_uuid'").is_degraded' <<< "$lvols")" == "true" ]] 400 401 # Create the esnap device and verify that the esnap clone finds it. 402 esnap_dev=$(rpc_cmd bdev_malloc_create -u "$esnap_uuid" "$esnap_size_mb" "$block_size") 403 rpc_cmd bdev_wait_for_examine 404 verify_esnap_clone "$eclone_uuid" "$esnap_uuid" 405 406 rpc_cmd bdev_aio_delete "$aio_bdev" 407 rpc_cmd bdev_malloc_delete "$esnap_dev" 408} 409 410function test_esnap_remove_degraded() { 411 local bs_dev esnap_dev 412 local block_size=512 413 local esnap_size_mb=1 414 local lvs_cluster_size=$((16 * 1024)) 415 local lvs_uuid esnap_uuid eclone_uuid snap_uuid clone_uuid uuid 416 local aio_bdev=test_esnap_reload_aio0 417 local lvols 418 419 # Create the lvstore on an aio device. Can't use malloc because we need to remove 420 # the device and re-add it to trigger an lvstore unload and then load. 421 rm -f $testdir/aio_bdev_0 422 truncate -s "${AIO_SIZE_MB}M" $testdir/aio_bdev_0 423 bs_dev=$(rpc_cmd bdev_aio_create "$testdir/aio_bdev_0" "$aio_bdev" "$block_size") 424 lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore -c "$lvs_cluster_size" "$bs_dev" lvs_test) 425 426 # Create a bdev that will be the external snapshot 427 esnap_uuid=e4b40d8b-f623-416d-8234-baf5a4c83cbd 428 esnap_dev=$(rpc_cmd bdev_malloc_create -u "$esnap_uuid" "$esnap_size_mb" "$block_size") 429 eclone_uuid=$(rpc_cmd bdev_lvol_clone_bdev "$esnap_uuid" lvs_test "eclone") 430 rpc_cmd bdev_get_bdevs -b "$eclone_uuid" 431 432 # Create a clone of eclone 433 rpc_cmd bdev_lvol_set_read_only "$eclone_uuid" 434 clone_uuid=$(rpc_cmd bdev_lvol_clone "$eclone_uuid" clone) 435 rpc_cmd bdev_get_bdevs -b "$clone_uuid" 436 437 # Reload the lvolstore without the external snapshot 438 rpc_cmd bdev_aio_delete "$aio_bdev" 439 NOT rpc_cmd bdev_lvol_get_lvstores -l lvs_test 440 rpc_cmd bdev_malloc_delete "$esnap_dev" 441 bs_dev=$(rpc_cmd bdev_aio_create "$testdir/aio_bdev_0" "$aio_bdev" "$block_size") 442 lvs_uuid=$(rpc_cmd bdev_lvol_get_lvstores -l lvs_test) 443 444 # Verify clone and eclone are degraded 445 lvols=$(rpc_cmd bdev_lvol_get_lvols) 446 [[ "$(jq -r '.[] | select(.uuid == "'$eclone_uuid'").is_degraded' <<< "$lvols")" == "true" ]] 447 [[ "$(jq -r '.[] | select(.uuid == "'$clone_uuid'").is_degraded' <<< "$lvols")" == "true" ]] 448 NOT rpc_cmd bdev_get_bdevs -b "$clone_uuid" 449 NOT rpc_cmd bdev_get_bdevs -b "$eclone_uuid" 450 451 # Delete the lvols and verify they are gone. 452 rpc_cmd bdev_lvol_delete "$clone_uuid" 453 lvols=$(rpc_cmd bdev_lvol_get_lvols) 454 [[ "$(jq -r '. | length' <<< "$lvols")" == "1" ]] 455 rpc_cmd bdev_lvol_delete "$eclone_uuid" 456 lvols=$(rpc_cmd bdev_lvol_get_lvols) 457 [[ "$(jq -r '. | length' <<< "$lvols")" == "0" ]] 458 459 rpc_cmd bdev_aio_delete "$aio_bdev" 460} 461 462function test_lvol_set_parent_bdev_from_esnap() { 463 local vol_size_mb=20 464 local vol_size=$((vol_size_mb * 1024 * 1024)) 465 local vol_blocks_count=$((vol_size / MALLOC_BS)) 466 local three_clusters_size=$((LVS_DEFAULT_CLUSTER_SIZE * 3)) 467 local three_clusters_block_count=$((LVS_DEFAULT_CLUSTER_SIZE * 3 / MALLOC_BS)) 468 local two_clusters_block_count=$((LVS_DEFAULT_CLUSTER_SIZE * 2 / MALLOC_BS)) 469 470 # Create the lvstore on a malloc device. 471 malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS) 472 lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test) 473 474 # Create a bdev that will be the old external snapshot 475 # State: 476 # esnap1 477 rpc_cmd bdev_malloc_create -b esnap1 "$vol_size_mb" $MALLOC_BS 478 479 # Perform write operation over esnap1 480 nbd_start_disks "$DEFAULT_RPC_ADDR" esnap1 /dev/nbd0 481 run_fio_test /dev/nbd0 0 $vol_size "write" "0xaa" "" 482 nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0 483 sleep 1 484 485 # Create a bdev that will be the new external snapshot 486 # New state: 487 # esnap1 488 # esnap2 489 esnap2_uuid=037128af-3662-4137-9e24-e74e44310ad3 490 rpc_cmd bdev_malloc_create -b esnap2 -u "$esnap2_uuid" "$vol_size_mb" $MALLOC_BS 491 492 # Perform write operation over esnap2 493 # Calculate md5 of the last part of esnap2 corresponding to 2 clusters size 494 nbd_start_disks "$DEFAULT_RPC_ADDR" esnap2 /dev/nbd2 495 run_fio_test /dev/nbd2 0 $vol_size "write" "0xbb" "" 496 md5_2=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$two_clusters_block_count skip=$three_clusters_block_count | md5sum) 497 nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2 498 sleep 1 499 500 # Create an esnap1 clone: lvol 501 # New state: 502 # esnap1 <-- lvol 503 # esnap2 504 lvol_uuid=$(rpc_cmd bdev_lvol_clone_bdev esnap1 lvs_test lvol) 505 506 # Perform write operation over the first 3 clusters of lvol 507 # Calculate md5sum of the first 3 clusters and of last 2 clusters of lvol 508 nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd2 509 run_fio_test /dev/nbd2 0 $three_clusters_size "write" "0xcc" "" 510 md5_lvol_1=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$three_clusters_block_count | md5sum) 511 md5_lvol_2=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$two_clusters_block_count skip=$three_clusters_block_count | md5sum) 512 nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2 513 514 # Change parent of lvol 515 # New state: 516 # esnap1 517 # esnap2 <-- lvol 518 rpc_cmd bdev_lvol_set_parent_bdev "$lvol_uuid" "$esnap2_uuid" 519 520 # Check lvol consistency 521 verify_esnap_clone "$lvol_uuid" "$esnap2_uuid" 522 523 # Try again with aliases instead uuid 524 NOT rpc_cmd bdev_lvol_set_parent_bdev lvs_test/lvol esnap2 525 526 # Calculate again md5 of the first 3 clusters and of last 2 clusters of lvol 527 nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd2 528 md5_lvol_1_new=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$three_clusters_block_count | md5sum) 529 md5_lvol_2_new=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$two_clusters_block_count skip=$three_clusters_block_count | md5sum) 530 nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2 531 532 # Check that first three clusters of lvol didn't change anche that the last 2 clusters changed 533 [[ $md5_lvol_1 == "$md5_lvol_1_new" ]] 534 [[ $md5_lvol_2 != "$md5_lvol_2_new" ]] 535 [[ $md5_lvol_2_new == "$md5_2" ]] 536 537 # Clean up 538 rpc_cmd bdev_lvol_delete "$lvol_uuid" 539 rpc_cmd bdev_malloc_delete esnap1 540 rpc_cmd bdev_malloc_delete esnap2 541 rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid" 542 rpc_cmd bdev_malloc_delete "$malloc_name" 543 check_leftover_devices 544} 545 546function test_lvol_set_parent_bdev_from_snapshot() { 547 local vol_size_mb=20 548 local vol_size=$((vol_size_mb * 1024 * 1024)) 549 local vol_blocks_count=$((vol_size / MALLOC_BS)) 550 local three_clusters_size=$((LVS_DEFAULT_CLUSTER_SIZE * 3)) 551 local three_clusters_block_count=$((LVS_DEFAULT_CLUSTER_SIZE * 3 / MALLOC_BS)) 552 local two_clusters_block_count=$((LVS_DEFAULT_CLUSTER_SIZE * 2 / MALLOC_BS)) 553 554 # Create the lvstore on a malloc device. 555 malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS) 556 lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test) 557 558 # Create a bdev that will be the external snapshot 559 # State: 560 # esnap1 561 esnap1_uuid=533c2e20-3e74-47a1-9c4f-0ffe4922ffed 562 rpc_cmd bdev_malloc_create -b esnap1 -u "$esnap1_uuid" "$vol_size_mb" $MALLOC_BS 563 564 # Perform write operation over the external snapshot 565 # Calculate md5 of the last part of esnap1 corresponding to 2 clusters size 566 nbd_start_disks "$DEFAULT_RPC_ADDR" "$esnap1_uuid" /dev/nbd1 567 run_fio_test /dev/nbd1 0 $vol_size "write" "0xaa" "" 568 md5_1=$(dd if=/dev/nbd1 bs=$MALLOC_BS count=$two_clusters_block_count skip=$three_clusters_block_count | md5sum) 569 nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd1 570 sleep 1 571 572 # Create a volume: lvol 573 # New state: 574 # esnap1 575 # lvol 576 lvol_uuid=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol "$vol_size_mb") 577 578 # Perform write operation over lvol 579 nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd2 580 run_fio_test /dev/nbd2 0 $vol_size "write" "0xbb" "" 581 nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2 582 583 # Make a snapshot of lvol: snap2 584 # New state: 585 # esnap1 586 # snap2 <-- lvol 587 snap2_uuid=$(rpc_cmd bdev_lvol_snapshot "$lvol_uuid" snap2) 588 589 # Perform write operation over the first 3 clusters of lvol 590 # Calculate md5sum of the first 3 clusters and of last 2 clusters of lvol 591 nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd2 592 run_fio_test /dev/nbd2 0 $three_clusters_size "write" "0xcc" "" 593 md5_lvol_1=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$three_clusters_block_count | md5sum) 594 md5_lvol_2=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$two_clusters_block_count skip=$three_clusters_block_count | md5sum) 595 nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2 596 597 # Change parent of lvol 598 # New state: 599 # esnap1 <-- lvol 600 # snap2 601 rpc_cmd bdev_lvol_set_parent_bdev "$lvol_uuid" "$esnap1_uuid" 602 603 # Check lvol consistency 604 verify_esnap_clone "$lvol_uuid" "$esnap1_uuid" 605 606 # Try again with aliases instead uuid 607 NOT rpc_cmd bdev_lvol_set_parent_bdev lvs_test/lvol esnap1 608 609 # Calculate again md5 of the first 3 clusters and of last 2 clusters of lvol 610 nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd2 611 md5_lvol_1_new=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$three_clusters_block_count | md5sum) 612 md5_lvol_2_new=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$two_clusters_block_count skip=$three_clusters_block_count | md5sum) 613 nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2 614 615 # Check that first three clusters of lvol didn't change anche that the last 2 clusters changed 616 [[ $md5_lvol_1 == "$md5_lvol_1_new" ]] 617 [[ $md5_lvol_2 != "$md5_lvol_2_new" ]] 618 [[ $md5_lvol_2_new == "$md5_1" ]] 619 620 # Clean up 621 rpc_cmd bdev_lvol_delete "$lvol_uuid" 622 rpc_cmd bdev_lvol_delete "$snap2_uuid" 623 rpc_cmd bdev_malloc_delete esnap1 624 rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid" 625 rpc_cmd bdev_malloc_delete "$malloc_name" 626 check_leftover_devices 627} 628 629function test_lvol_set_parent_bdev_from_none() { 630 local vol_size_mb=20 631 local vol_size=$((vol_size_mb * 1024 * 1024)) 632 local three_clusters_size=$((LVS_DEFAULT_CLUSTER_SIZE * 3)) 633 local three_clusters_block_count=$((LVS_DEFAULT_CLUSTER_SIZE * 3 / MALLOC_BS)) 634 local two_clusters_block_count=$((LVS_DEFAULT_CLUSTER_SIZE * 2 / MALLOC_BS)) 635 636 # Create the lvstore on a malloc device. 637 malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS) 638 lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test) 639 640 # Create a thin provisioned volume: lvol 641 # New state: 642 # lvol 643 lvol_uuid=$(rpc_cmd bdev_lvol_create -t -u "$lvs_uuid" lvol "$vol_size_mb") 644 645 # Perform write operation over the first 3 clusters of lvol 646 # Calculate md5sum of the first 3 clusters and of last 2 clusters of lvol 647 nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd2 648 run_fio_test /dev/nbd2 0 $three_clusters_size "write" "0xaa" "" 649 md5_lvol_1=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$three_clusters_block_count | md5sum) 650 md5_lvol_2=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$two_clusters_block_count skip=$three_clusters_block_count | md5sum) 651 nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2 652 653 # Create a bdev that will be the external snapshot 654 # New State: 655 # esnap 656 # lvol 657 esnap_uuid=61571088-ffcf-48d9-af1f-259eb853f7b4 658 rpc_cmd bdev_malloc_create -b esnap -u "$esnap_uuid" "$vol_size_mb" $MALLOC_BS 659 660 # Perform write operation over the external snapshot 661 # Calculate md5 of the last part of esnap corresponding to 2 clusters size 662 nbd_start_disks "$DEFAULT_RPC_ADDR" "$esnap_uuid" /dev/nbd2 663 run_fio_test /dev/nbd2 0 $vol_size "write" "0xbb" "" 664 md5_2=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$two_clusters_block_count skip=$three_clusters_block_count | md5sum) 665 nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2 666 sleep 1 667 668 # Change parent of lvol 669 # New state: 670 # esnap <-- lvol 671 rpc_cmd bdev_lvol_set_parent_bdev "$lvol_uuid" "$esnap_uuid" 672 673 # Check lvol consistency 674 verify_esnap_clone "$lvol_uuid" "$esnap_uuid" 675 676 # Try again with aliases instead uuid 677 NOT rpc_cmd bdev_lvol_set_parent_bdev lvs_test/lvol esnap 678 679 # Calculate again md5 of the first 3 clusters and of last 2 clusters of lvol 680 nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd2 681 md5_lvol_1_new=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$three_clusters_block_count | md5sum) 682 md5_lvol_2_new=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$two_clusters_block_count skip=$three_clusters_block_count | md5sum) 683 nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2 684 685 # Check that first three clusters of lvol didn't change anche that the last 2 clusters changed 686 [[ $md5_lvol_1 == "$md5_lvol_1_new" ]] 687 [[ $md5_lvol_2 != "$md5_lvol_2_new" ]] 688 [[ $md5_lvol_2_new == "$md5_2" ]] 689 690 # Clean up 691 rpc_cmd bdev_lvol_delete "$lvol_uuid" 692 rpc_cmd bdev_malloc_delete esnap 693 rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid" 694 rpc_cmd bdev_malloc_delete "$malloc_name" 695 check_leftover_devices 696} 697 698$SPDK_BIN_DIR/spdk_tgt & 699spdk_pid=$! 700trap 'killprocess "$spdk_pid"; rm -f "$testdir/aio_bdev_0"; exit 1' SIGINT SIGTERM SIGPIPE EXIT 701waitforlisten $spdk_pid 702modprobe nbd 703 704run_test "test_esnap_reload" test_esnap_reload 705run_test "test_esnap_reload" test_esnap_reload_missing 706run_test "test_esnap_clones" test_esnap_clones 707run_test "test_esnap_late_arrival" test_esnap_late_arrival 708run_test "test_esnap_remove_degraded" test_esnap_remove_degraded 709run_test "test_lvol_set_parent_bdev_from_esnap" test_lvol_set_parent_bdev_from_esnap 710run_test "test_lvol_set_parent_bdev_from_snapshot" test_lvol_set_parent_bdev_from_snapshot 711run_test "test_lvol_set_parent_bdev_from_none" test_lvol_set_parent_bdev_from_none 712 713trap - SIGINT SIGTERM SIGPIPE EXIT 714killprocess $spdk_pid 715rm -f "$testdir/aio_bdev_0" 716