blob: cb7bfcb01be3ee539880e3c80e8157706f55d6e4 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
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
|