xref: /spdk/test/lvol/snapshot_clone.sh (revision 9b107f7e08a474f8bd5dafc95a8a84cdad3f27a5)
1#!/usr/bin/env bash
2#  SPDX-License-Identifier: BSD-3-Clause
3#  Copyright (C) 2019 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/lvol/common.sh
10source $rootdir/test/bdev/nbd_common.sh
11
12function test_snapshot_compare_with_lvol_bdev() {
13	malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
14	lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test)
15
16	# Create two lvol bdevs
17	lvol_size_mb=$(round_down $((LVS_DEFAULT_CAPACITY_MB / 6)))
18	lvol_size=$((lvol_size_mb * 1024 * 1024))
19
20	lvol_uuid1=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol_test1 "$lvol_size_mb" -t)
21	lvol_uuid2=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol_test2 "$lvol_size_mb")
22
23	# Fill thin provisioned lvol bdev with 50% of its space
24	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid1" /dev/nbd0
25	count=$((lvol_size / LVS_DEFAULT_CLUSTER_SIZE / 2))
26	dd if=/dev/urandom of=/dev/nbd0 oflag=direct bs="$LVS_DEFAULT_CLUSTER_SIZE" count=$count
27	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
28	# Fill whole thick provisioned lvol bdev
29	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid2" /dev/nbd0
30	count=$((lvol_size / LVS_DEFAULT_CLUSTER_SIZE))
31	dd if=/dev/urandom of=/dev/nbd0 oflag=direct bs="$LVS_DEFAULT_CLUSTER_SIZE" count=$count
32	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
33
34	# Create snapshots of lvol bdevs
35	snapshot_uuid1=$(rpc_cmd bdev_lvol_snapshot lvs_test/lvol_test1 lvol_snapshot1)
36	snapshot_uuid2=$(rpc_cmd bdev_lvol_snapshot lvs_test/lvol_test2 lvol_snapshot2)
37
38	nbd_start_disks "$DEFAULT_RPC_ADDR" "$snapshot_uuid1" /dev/nbd0
39	# Try to perform write operation on created snapshot
40	# Check if filling snapshot of lvol bdev fails
41	count=$((lvol_size / LVS_DEFAULT_CLUSTER_SIZE))
42	dd if=/dev/urandom of=/dev/nbd0 oflag=direct bs="$LVS_DEFAULT_CLUSTER_SIZE" count=$count && false
43	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
44
45	# Declare nbd devices as vars for an easy cross-reference
46	local lvol_nbd1=/dev/nbd0 lvol_nbd2=/dev/nbd1
47	local snapshot_nbd1=/dev/nbd2 snapshot_nbd2=/dev/nbd3
48
49	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid1" "$lvol_nbd1"
50	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid2" "$lvol_nbd2"
51	nbd_start_disks "$DEFAULT_RPC_ADDR" "$snapshot_uuid1" "$snapshot_nbd1"
52	nbd_start_disks "$DEFAULT_RPC_ADDR" "$snapshot_uuid2" "$snapshot_nbd2"
53	# Compare every lvol bdev with corresponding snapshot and check that data are the same
54	cmp "$lvol_nbd1" "$snapshot_nbd1"
55	cmp "$lvol_nbd2" "$snapshot_nbd2"
56
57	# Fill second half of thin provisioned lvol bdev
58	count=$((lvol_size / LVS_DEFAULT_CLUSTER_SIZE / 2))
59	dd if=/dev/urandom of="$lvol_nbd1" oflag=direct seek=$count bs="$LVS_DEFAULT_CLUSTER_SIZE" count=$count
60
61	# Compare thin provisioned lvol bdev with its snapshot and check if it fails
62	cmp "$lvol_nbd1" "$snapshot_nbd1" && false
63
64	# clean up
65	for bdev in "${!lvol_nbd@}" "${!snapshot_nbd@}"; do
66		nbd_stop_disks "$DEFAULT_RPC_ADDR" "${!bdev}"
67	done
68
69	rpc_cmd bdev_lvol_delete "$lvol_uuid1"
70	rpc_cmd bdev_get_bdevs -b "$lvol_uuid1" && false
71	rpc_cmd bdev_lvol_delete "$snapshot_uuid1"
72	rpc_cmd bdev_get_bdevs -b "$snapshot_uuid1" && false
73	rpc_cmd bdev_lvol_delete "$lvol_uuid2"
74	rpc_cmd bdev_get_bdevs -b "$lvol_uuid2" && false
75	rpc_cmd bdev_lvol_delete "$snapshot_uuid2"
76	rpc_cmd bdev_get_bdevs -b "$snapshot_uuid2" && false
77	rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid"
78	rpc_cmd bdev_lvol_get_lvstores -u "$lvs_uuid" && false
79	rpc_cmd bdev_malloc_delete "$malloc_name"
80	check_leftover_devices
81}
82
83# Check that when writing to lvol bdev
84# creating snapshot ends with success
85function test_create_snapshot_with_io() {
86	malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
87	lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test)
88
89	# Create lvol bdev
90	lvol_size_mb=$(round_down $((LVS_DEFAULT_CAPACITY_MB / 2)))
91	lvol_size=$((lvol_size_mb * 1024 * 1024))
92
93	lvol_uuid=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol_test "$lvol_size_mb" -t)
94
95	# Run fio in background that writes to lvol bdev
96	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd0
97	run_fio_test /dev/nbd0 0 $lvol_size "write" "0xcc" "--time_based --runtime=16" &
98	fio_proc=$!
99	sleep 4
100	# Create snapshot of lvol bdev
101	snapshot_uuid=$(rpc_cmd bdev_lvol_snapshot lvs_test/lvol_test lvol_snapshot)
102	wait $fio_proc
103
104	# Clean up
105	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
106	rpc_cmd bdev_lvol_delete "$lvol_uuid"
107	rpc_cmd bdev_get_bdevs -b "$lvol_uuid" && false
108	rpc_cmd bdev_lvol_delete "$snapshot_uuid"
109	rpc_cmd bdev_get_bdevs -b "$snapshot_uuid" && false
110	rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid"
111	rpc_cmd bdev_lvol_get_lvstores -u "$lvs_uuid" && false
112	rpc_cmd bdev_malloc_delete "$malloc_name"
113	check_leftover_devices
114}
115
116# Check that creating snapshot of snapshot will fail
117function test_create_snapshot_of_snapshot() {
118	malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
119	lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test)
120
121	# Create lvol bdev
122	lvol_size_mb=$(round_down $((LVS_DEFAULT_CAPACITY_MB / 3)))
123
124	lvol_uuid=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol_test "$lvol_size_mb")
125	lvol=$(rpc_cmd bdev_get_bdevs -b "$lvol_uuid")
126
127	# Create snapshots of lvol bdev
128	snapshot_uuid=$(rpc_cmd bdev_lvol_snapshot lvs_test/lvol_test lvol_snapshot)
129
130	# Create snapshot of previously created snapshot
131	# and check if operation will fail
132	rpc_cmd bdev_lvol_snapshot lvs_test/lvol_snapshot lvol_snapshot2 && false
133
134	# Clean up
135	rpc_cmd bdev_lvol_delete "$lvol_uuid"
136	rpc_cmd bdev_get_bdevs -b "$lvol_uuid" && false
137	rpc_cmd bdev_lvol_delete "$snapshot_uuid"
138	rpc_cmd bdev_get_bdevs -b "$snapshot_uuid" && false
139	rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid"
140	rpc_cmd bdev_lvol_get_lvstores -u "$lvs_uuid" && false
141	rpc_cmd bdev_malloc_delete "$malloc_name"
142	check_leftover_devices
143}
144
145# Check if only clone of snapshot can be created.
146# Check if writing to one clone doesn't affect other clone
147# Check if relations between clones and snapshots are properly set in configuration
148function test_clone_snapshot_relations() {
149	malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
150	lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test)
151
152	# Calculate size and create lvol bdev
153	lvol_size_mb=$(round_down $((LVS_DEFAULT_CAPACITY_MB / 6)))
154	lvol_size=$((lvol_size_mb * 1024 * 1024))
155
156	lvol_uuid=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol_test "$lvol_size_mb")
157	lvol=$(rpc_cmd bdev_get_bdevs -b "$lvol_uuid")
158
159	# Fill lvol bdev with 100% of its space
160	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd0
161	run_fio_test /dev/nbd0 0 $lvol_size "write" "0xcc"
162	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
163
164	# An attempt to create a clone from lvol that is rw capable should fail
165	rpc_cmd bdev_lvol_clone lvs_test/lvol_test clone_test && false
166
167	# Create snapshots of lvol bdev
168	snapshot_uuid=$(rpc_cmd bdev_lvol_snapshot lvs_test/lvol_test lvol_snapshot)
169
170	# Create again clone of lvol bdev and check if it fails
171	rpc_cmd bdev_lvol_clone lvs_test/lvol_test clone_test && false
172
173	# Create two clones of snapshot and check if it ends with success
174	clone_uuid1=$(rpc_cmd bdev_lvol_clone lvs_test/lvol_snapshot clone_test1)
175	clone_uuid2=$(rpc_cmd bdev_lvol_clone lvs_test/lvol_snapshot clone_test2)
176
177	# Perform write operation to first clone
178	# Change first half of its space
179	nbd_start_disks "$DEFAULT_RPC_ADDR" "$clone_uuid1" /dev/nbd0
180	fill_size=$((lvol_size / 2))
181	run_fio_test /dev/nbd0 0 $fill_size "write" "0xaa"
182
183	# Compare snapshot with second clone. Data on both bdevs should be the same
184	nbd_start_disks "$DEFAULT_RPC_ADDR" "$snapshot_uuid" /dev/nbd1
185	nbd_start_disks "$DEFAULT_RPC_ADDR" "$clone_uuid2" /dev/nbd2
186	sleep 1
187	cmp /dev/nbd1 /dev/nbd2
188	# Compare snapshot with first clone
189	cmp /dev/nbd0 /dev/nbd1 && false
190
191	snapshot_bdev=$(rpc_cmd bdev_get_bdevs -b "lvs_test/lvol_snapshot")
192	clone_bdev1=$(rpc_cmd bdev_get_bdevs -b "lvs_test/clone_test1")
193	clone_bdev2=$(rpc_cmd bdev_get_bdevs -b "lvs_test/lvol_test")
194
195	# Check snapshot consistency
196	[ "$(jq '.[].driver_specific.lvol.snapshot' <<< "$snapshot_bdev")" = "true" ]
197	[ "$(jq '.[].driver_specific.lvol.clone' <<< "$snapshot_bdev")" = "false" ]
198	[ "$(jq '.[].driver_specific.lvol.clones|sort' <<< "$snapshot_bdev")" = "$(jq '.|sort' <<< '["lvol_test", "clone_test1", "clone_test2"]')" ]
199
200	# Check first clone consistency
201	[ "$(jq '.[].driver_specific.lvol.snapshot' <<< "$clone_bdev1")" = "false" ]
202	[ "$(jq '.[].driver_specific.lvol.clone' <<< "$clone_bdev1")" = "true" ]
203	[ "$(jq '.[].driver_specific.lvol.base_snapshot' <<< "$clone_bdev1")" = '"lvol_snapshot"' ]
204
205	# Check second clone consistency
206	[ "$(jq '.[].driver_specific.lvol.snapshot' <<< "$clone_bdev2")" = "false" ]
207	[ "$(jq '.[].driver_specific.lvol.clone' <<< "$clone_bdev2")" = "true" ]
208	[ "$(jq '.[].driver_specific.lvol.base_snapshot' <<< "$clone_bdev2")" = '"lvol_snapshot"' ]
209
210	# Destroy first clone and check if it is deleted from snapshot
211	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
212	rpc_cmd bdev_lvol_delete "$clone_uuid1"
213	snapshot_bdev=$(rpc_cmd bdev_get_bdevs -b "lvs_test/lvol_snapshot")
214	[ "$(jq '.[].driver_specific.lvol.clones|sort' <<< "$snapshot_bdev")" = "$(jq '.|sort' <<< '["lvol_test", "clone_test2"]')" ]
215
216	# Clean up
217	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd1
218	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2
219	rpc_cmd bdev_lvol_delete "$lvol_uuid"
220	rpc_cmd bdev_lvol_delete "$clone_uuid2"
221	rpc_cmd bdev_lvol_delete "$snapshot_uuid"
222	rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid"
223	rpc_cmd bdev_malloc_delete "$malloc_name"
224	check_leftover_devices
225}
226
227# Testing usage of bdev_lvol_inflate
228function test_clone_inflate() {
229	malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
230	lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test)
231
232	# Calculate size and create lvol bdev
233	lvol_size_mb=$(round_down $((LVS_DEFAULT_CAPACITY_MB / 4)))
234
235	lvol_uuid=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol_test "$lvol_size_mb")
236	lvol=$(rpc_cmd bdev_get_bdevs -b "$lvol_uuid")
237
238	# Fill lvol bdev with 100% of its space
239	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd0
240	run_fio_test /dev/nbd0 0 $((lvol_size_mb * 1024 * 1024)) "write" "0xcc"
241	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
242
243	# Create snapshots of lvol bdev
244	snapshot_uuid=$(rpc_cmd bdev_lvol_snapshot lvs_test/lvol_test lvol_snapshot)
245
246	# Create clone of snapshot
247	lvol=$(rpc_cmd bdev_get_bdevs -b "$lvol_uuid")
248	[ "$(jq '.[].driver_specific.lvol.thin_provision' <<< "$lvol")" = "true" ]
249
250	# Fill part of clone with data of known pattern
251	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd0
252	first_fill=0
253	second_fill=$((lvol_size_mb * 1024 * 1024 * 3 / 4))
254	run_fio_test /dev/nbd0 $first_fill $((1024 * 1024)) "write" "0xdd"
255	run_fio_test /dev/nbd0 $second_fill $((1024 * 1024)) "write" "0xdd"
256	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
257
258	# Do inflate
259	rpc_cmd bdev_lvol_inflate lvs_test/lvol_test
260	lvol=$(rpc_cmd bdev_get_bdevs -b "$lvol_uuid")
261	[ "$(jq '.[].driver_specific.lvol.thin_provision' <<< "$lvol")" = "false" ]
262
263	# Delete snapshot
264	rpc_cmd bdev_lvol_delete "$snapshot_uuid"
265
266	# Check data consistency
267	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd0
268	run_fio_test /dev/nbd0 $first_fill $((1024 * 1024)) "read" "0xdd"
269	run_fio_test /dev/nbd0 $(((first_fill + 1) * 1024 * 1024)) $((second_fill - 1024 * 1024)) "read" "0xcc"
270	run_fio_test /dev/nbd0 $second_fill $((1024 * 1024)) "read" "0xdd"
271	run_fio_test /dev/nbd0 $((second_fill + 1024 * 1024)) $((lvol_size_mb * 1024 * 1024 - (second_fill + 1024 * 1024))) "read" "0xcc"
272	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
273
274	# Clean up
275	rpc_cmd bdev_lvol_delete "$lvol_uuid"
276	rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid"
277	rpc_cmd bdev_malloc_delete "$malloc_name"
278	check_leftover_devices
279}
280
281# Create chain of snapshot<-snapshot2<-lvol_test lvol bdevs.
282# Decouple lvol_test twice and delete the remaining snapshot lvol.
283# Each time check consistency of snapshot-clone relations and written data.
284function test_clone_decouple_parent() {
285	malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
286	lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test)
287
288	# Calculate size and create lvol bdev
289	lvol_size_mb=$((5 * LVS_DEFAULT_CLUSTER_SIZE_MB))
290	lvol_uuid=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol_test "$lvol_size_mb" -t)
291	lvol=$(rpc_cmd bdev_get_bdevs -b "$lvol_uuid")
292
293	# Decouple_parent should fail on lvol bdev without a parent
294	rpc_cmd bdev_lvol_decouple_parent lvs_test/lvol_test && false
295
296	# Fill first four out of 5 clusters of clone with data of known pattern
297	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd0
298	begin_fill=0
299	end_fill=$((lvol_size_mb * 4 * 1024 * 1024 / 5))
300	run_fio_test /dev/nbd0 $begin_fill $end_fill "write" "0xdd"
301
302	# Create snapshot (snapshot<-lvol_bdev)
303	snapshot_uuid=$(rpc_cmd bdev_lvol_snapshot lvs_test/lvol_test lvol_snapshot)
304
305	# Fill second and fourth cluster of clone with data of known pattern
306	start_fill=$((lvol_size_mb * 1024 * 1024 / 5))
307	fill_range=$start_fill
308	run_fio_test /dev/nbd0 $start_fill $fill_range "write" "0xcc"
309	start_fill=$((lvol_size_mb * 3 * 1024 * 1024 / 5))
310	run_fio_test /dev/nbd0 $start_fill $fill_range "write" "0xcc"
311
312	# Create snapshot (snapshot<-snapshot2<-lvol_bdev)
313	snapshot_uuid2=$(rpc_cmd bdev_lvol_snapshot lvs_test/lvol_test lvol_snapshot2)
314
315	# Fill second cluster of clone with data of known pattern
316	start_fill=$fill_range
317	run_fio_test /dev/nbd0 $start_fill $fill_range "write" "0xee"
318
319	# Check data consistency
320	pattern=("0xdd" "0xee" "0xdd" "0xcc" "0x00")
321	for i in "${!pattern[@]}"; do
322		start_fill=$((lvol_size_mb * i * 1024 * 1024 / 5))
323		run_fio_test /dev/nbd0 $start_fill $fill_range "read" "${pattern[i]}"
324	done
325
326	# Decouple_parent of lvol bdev resulting in two relation chains:
327	#  - snapshot<-lvol_bdev
328	#  - snapshot<-snapshot2
329	rpc_cmd bdev_lvol_decouple_parent lvs_test/lvol_test
330	lvol=$(rpc_cmd bdev_get_bdevs -b "$lvol_uuid")
331	snapshot=$(rpc_cmd bdev_get_bdevs -b "$snapshot_uuid")
332	snapshot2=$(rpc_cmd bdev_get_bdevs -b "$snapshot_uuid2")
333	[ "$(jq '.[].driver_specific.lvol.thin_provision' <<< "$lvol")" = "true" ]
334	[ "$(jq '.[].driver_specific.lvol.clone' <<< "$lvol")" = "true" ]
335	[ "$(jq '.[].driver_specific.lvol.snapshot' <<< "$lvol")" = "false" ]
336	[ "$(jq '.[].driver_specific.lvol.clone' <<< "$snapshot")" = "false" ]
337	[ "$(jq '.[].driver_specific.lvol.clone' <<< "$snapshot2")" = "true" ]
338	[ "$(jq '.[].driver_specific.lvol.snapshot' <<< "$snapshot2")" = "true" ]
339
340	# Delete second snapshot
341	rpc_cmd bdev_lvol_delete "$snapshot_uuid2"
342
343	# Check data consistency
344	for i in "${!pattern[@]}"; do
345		start_fill=$((lvol_size_mb * i * 1024 * 1024 / 5))
346		run_fio_test /dev/nbd0 $start_fill $fill_range "read" "${pattern[i]}"
347	done
348
349	# Decouple_parent of lvol bdev again resulting in two relation chains:
350	#  - lvol_bdev
351	#  - snapshot<-snapshot2
352	rpc_cmd bdev_lvol_decouple_parent lvs_test/lvol_test
353	lvol=$(rpc_cmd bdev_get_bdevs -b "$lvol_uuid")
354	snapshot=$(rpc_cmd bdev_get_bdevs -b "$snapshot_uuid")
355	[ "$(jq '.[].driver_specific.lvol.thin_provision' <<< "$lvol")" = "true" ]
356	[ "$(jq '.[].driver_specific.lvol.clone' <<< "$lvol")" = "false" ]
357	[ "$(jq '.[].driver_specific.lvol.snapshot' <<< "$lvol")" = "false" ]
358	[ "$(jq '.[].driver_specific.lvol.clone' <<< "$snapshot")" = "false" ]
359
360	# Delete first snapshot
361	rpc_cmd bdev_lvol_delete "$snapshot_uuid"
362
363	# Check data consistency
364	for i in "${!pattern[@]}"; do
365		start_fill=$((lvol_size_mb * i * 1024 * 1024 / 5))
366		run_fio_test /dev/nbd0 $start_fill $fill_range "read" "${pattern[i]}"
367	done
368
369	# Clean up
370	rpc_cmd bdev_lvol_delete "$lvol_uuid"
371	rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid"
372	rpc_cmd bdev_malloc_delete "$malloc_name"
373	check_leftover_devices
374}
375
376# Set lvol bdev as read only and perform clone on it.
377function test_lvol_bdev_readonly() {
378	malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
379	lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test)
380
381	# Calculate size and create lvol bdev
382	lvol_size_mb=$(round_down $((LVS_DEFAULT_CAPACITY_MB / 2)))
383
384	lvol_uuid=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol_test "$lvol_size_mb")
385	lvol=$(rpc_cmd bdev_get_bdevs -b "$lvol_uuid")
386
387	# Set lvol bdev as read only
388	rpc_cmd bdev_lvol_set_read_only lvs_test/lvol_test
389
390	# Try to perform write operation on lvol marked as read only
391	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd0
392	run_fio_test /dev/nbd0 0 $lvol_size "write" "0xcc" && false
393	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
394
395	# Create clone of lvol set to read only
396	clone_uuid=$(rpc_cmd bdev_lvol_clone lvs_test/lvol_test clone_test)
397
398	# Try to perform write operation on lvol clone
399	nbd_start_disks "$DEFAULT_RPC_ADDR" "$clone_uuid" /dev/nbd0
400	run_fio_test /dev/nbd0 0 $lvol_size "write" "0xcc"
401	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
402
403	# Clean up
404	rpc_cmd bdev_lvol_delete "$clone_uuid"
405	rpc_cmd bdev_lvol_delete "$lvol_uuid"
406	rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid"
407	rpc_cmd bdev_malloc_delete "$malloc_name"
408	check_leftover_devices
409}
410
411# Check if it is possible to delete snapshot with clone
412function test_delete_snapshot_with_clone() {
413	malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
414	lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test)
415
416	# Calculate size and create lvol bdev
417	lvol_size_mb=$(round_down $((LVS_DEFAULT_CAPACITY_MB / 2)))
418	lvol_size=$((lvol_size_mb * 1024 * 1024))
419
420	lvol_uuid=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol_test "$lvol_size_mb")
421	lvol=$(rpc_cmd bdev_get_bdevs -b "$lvol_uuid")
422
423	# Perform write operation on lvol
424	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd0
425	run_fio_test /dev/nbd0 0 $lvol_size "write" "0xcc"
426
427	# Create snapshots of lvol bdev
428	snapshot_uuid=$(rpc_cmd bdev_lvol_snapshot lvs_test/lvol_test lvol_snapshot)
429
430	# Fill first half of lvol bdev
431	half_size=$((lvol_size / 2 - 1))
432	run_fio_test /dev/nbd0 0 $half_size "write" "0xee"
433
434	# Check if snapshot was unchanged
435	nbd_start_disks "$DEFAULT_RPC_ADDR" "$snapshot_uuid" /dev/nbd1
436	run_fio_test /dev/nbd1 0 $half_size "read" "0xcc"
437
438	# Verify lvol bdev
439	run_fio_test /dev/nbd0 0 $half_size "read" "0xee"
440	lvol=$(rpc_cmd bdev_get_bdevs -b "$lvol_uuid")
441	[ "$(jq '.[].driver_specific.lvol.clone' <<< "$lvol")" = "true" ]
442
443	# Delete snapshot - should succeed
444	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd1
445	rpc_cmd bdev_lvol_delete "$snapshot_uuid"
446
447	# Check data consistency
448	lvol=$(rpc_cmd bdev_get_bdevs -b "$lvol_uuid")
449	[ "$(jq '.[].driver_specific.lvol.clone' <<< "$lvol")" = "false" ]
450	run_fio_test /dev/nbd0 0 $half_size "read" "0xee"
451	run_fio_test /dev/nbd0 $((half_size + 1)) $half_size "read" "0xcc"
452
453	# Clean up
454	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
455	rpc_cmd bdev_lvol_delete "$lvol_uuid"
456	rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid"
457	rpc_cmd bdev_malloc_delete "$malloc_name"
458	check_leftover_devices
459}
460
461# Check if it is possible to delete snapshot with one snapshot on it
462function test_delete_snapshot_with_snapshot() {
463	malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
464	lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test)
465
466	# Calculate size and create lvol bdev
467	lvol_size_mb=$(round_down $((LVS_DEFAULT_CAPACITY_MB / 5)))
468	lvol_size=$((lvol_size_mb * 1024 * 1024))
469
470	lvol_uuid=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol_test "$lvol_size_mb")
471	lvol=$(rpc_cmd bdev_get_bdevs -b "$lvol_uuid")
472
473	# Perform write operation on lvol
474	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol_uuid" /dev/nbd0
475	run_fio_test /dev/nbd0 0 $lvol_size "write" "0xcc"
476
477	# Create snapshot of lvol bdev
478	snapshot_uuid=$(rpc_cmd bdev_lvol_snapshot lvs_test/lvol_test lvol_snapshot)
479	lvol=$(rpc_cmd bdev_get_bdevs -b "$lvol_uuid")
480	[ "$(jq '.[].driver_specific.lvol.base_snapshot' <<< "$lvol")" = '"lvol_snapshot"' ]
481
482	# Fill second 1/3 of lvol bdev
483	first_part=$((lvol_size / 3))
484	second_part=$((lvol_size * 2 / 3))
485	run_fio_test /dev/nbd0 $first_part $((second_part - first_part)) "write" "0xee"
486
487	# Check if snapshot was unchanged
488	nbd_start_disks "$DEFAULT_RPC_ADDR" "$snapshot_uuid" /dev/nbd1
489	run_fio_test /dev/nbd1 0 $lvol_size "read" "0xcc"
490
491	# Create second snapshot of lvol_bdev
492	# First snapshot becomes snapshot of second snapshot
493	snapshot_uuid2=$(rpc_cmd bdev_lvol_snapshot lvs_test/lvol_test lvol_snapshot2)
494	lvol=$(rpc_cmd bdev_get_bdevs -b "$lvol_uuid")
495	snapshot=$(rpc_cmd bdev_get_bdevs -b "$snapshot_uuid")
496	snapshot2=$(rpc_cmd bdev_get_bdevs -b "$snapshot_uuid2")
497	[ "$(jq '.[].driver_specific.lvol.base_snapshot' <<< "$snapshot2")" = '"lvol_snapshot"' ]
498	[ "$(jq '.[].driver_specific.lvol.clones|sort' <<< "$snapshot2")" = "$(jq '.|sort' <<< '["lvol_test"]')" ]
499	[ "$(jq '.[].driver_specific.lvol.clone' <<< "$snapshot2")" = "true" ]
500	[ "$(jq '.[].driver_specific.lvol.snapshot' <<< "$snapshot2")" = "true" ]
501	[ "$(jq '.[].driver_specific.lvol.clones|sort' <<< "$snapshot")" = "$(jq '.|sort' <<< '["lvol_snapshot2"]')" ]
502
503	# Verify snapshots
504	run_fio_test /dev/nbd1 0 $size "read" "0xcc"
505	nbd_start_disks "$DEFAULT_RPC_ADDR" "$snapshot_uuid2" /dev/nbd2
506	run_fio_test /dev/nbd2 0 $((first_part - 1)) "read" "0xcc"
507	run_fio_test /dev/nbd2 $first_part $((second_part - first_part)) "read" "0xee"
508	run_fio_test /dev/nbd2 $second_part $((lvol_size - second_part)) "read" "0xcc"
509
510	# Verify lvol bdev
511	run_fio_test /dev/nbd0 $first_part $((second_part - first_part)) "read" "0xee"
512	run_fio_test /dev/nbd0 $second_part $((lvol_size - second_part)) "read" "0xcc"
513	[ "$(jq '.[].driver_specific.lvol.clone' <<< "$lvol")" = "true" ]
514	[ "$(jq '.[].driver_specific.lvol.base_snapshot' <<< "$lvol")" = '"lvol_snapshot2"' ]
515
516	# Fill third part of lvol bdev
517	run_fio_test /dev/nbd0 $second_part $((lvol_size - second_part)) "write" "0xdd"
518
519	# Verify snapshots
520	run_fio_test /dev/nbd1 0 $size "read" "0xcc"
521	run_fio_test /dev/nbd0 $second_part $((lvol_size - second_part)) "read" "0xdd"
522	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2
523	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd1
524
525	# Delete snapshot - should succeed
526	rpc_cmd bdev_lvol_delete "$snapshot_uuid2"
527
528	# Check data consistency
529	lvol=$(rpc_cmd bdev_get_bdevs -b "$lvol_uuid")
530	snapshot=$(rpc_cmd bdev_get_bdevs -b "$snapshot_uuid")
531	[ "$(jq '.[].driver_specific.lvol.clone' <<< "$lvol")" = "true" ]
532	[ "$(jq '.[].driver_specific.lvol.base_snapshot' <<< "$lvol")" = '"lvol_snapshot"' ]
533	[ "$(jq '.[].driver_specific.lvol.clones|sort' <<< "$snapshot")" = "$(jq '.|sort' <<< '["lvol_test"]')" ]
534	run_fio_test /dev/nbd0 $first_part $((second_part - first_part)) "read" "0xee"
535	run_fio_test /dev/nbd0 $second_part $((lvol_size - second_part)) "read" "0xdd"
536
537	# Clean up
538	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd0
539	rpc_cmd bdev_lvol_delete "$snapshot_uuid"
540	rpc_cmd bdev_lvol_delete "$lvol_uuid"
541	rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid"
542	rpc_cmd bdev_malloc_delete "$malloc_name"
543	check_leftover_devices
544}
545
546# Test for destroying lvol bdevs in particular order.
547function test_bdev_lvol_delete_ordering() {
548	local snapshot_name=snapshot snapshot_uuid
549	local clone_name=clone clone_uuid
550
551	local bdev_uuid
552	local lbd_name=lbd_test
553	local lvstore_uuid lvstore_name=lvs_name
554	local malloc_dev
555	local size
556
557	malloc_dev=$(rpc_cmd bdev_malloc_create 256 "$MALLOC_BS")
558	lvstore_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_dev" "$lvstore_name")
559
560	get_lvs_jq bdev_lvol_get_lvstores -u "$lvstore_uuid"
561	[[ ${jq_out["uuid"]} == "$lvstore_uuid" ]]
562	[[ ${jq_out["name"]} == "$lvstore_name" ]]
563	[[ ${jq_out["base_bdev"]} == "$malloc_dev" ]]
564
565	size=$((jq_out["free_clusters"] * jq_out["cluster_size"] / 4 / 1024 ** 2))
566
567	bdev_uuid=$(rpc_cmd bdev_lvol_create -t -u "$lvstore_uuid" "$lbd_name" "$size")
568
569	get_bdev_jq bdev_get_bdevs -b "$bdev_uuid"
570
571	snapshot_uuid=$(rpc_cmd bdev_lvol_snapshot "${jq_out["name"]}" "$snapshot_name")
572
573	get_bdev_jq bdev_get_bdevs -b "$lvstore_name/$snapshot_name"
574	[[ ${jq_out["name"]} == "$snapshot_uuid" ]]
575	[[ ${jq_out["product_name"]} == "Logical Volume" ]]
576	[[ ${jq_out["aliases[0]"]} == "$lvstore_name/$snapshot_name" ]]
577
578	clone_uuid=$(rpc_cmd bdev_lvol_clone "$lvstore_name/$snapshot_name" "$clone_name")
579
580	get_bdev_jq bdev_get_bdevs -b "$lvstore_name/$clone_name"
581	[[ ${jq_out["name"]} == "$clone_uuid" ]]
582	[[ ${jq_out["product_name"]} == "Logical Volume" ]]
583	[[ ${jq_out["aliases[0]"]} == "$lvstore_name/$clone_name" ]]
584
585	# Try to destroy snapshot with clones and check if it fails
586	rpc_cmd bdev_lvol_delete "$snapshot_uuid" && false
587
588	# cleanup logical volumes
589	rpc_cmd bdev_lvol_delete "$bdev_uuid"
590	rpc_cmd bdev_lvol_delete "$clone_uuid"
591	rpc_cmd bdev_lvol_delete "$snapshot_uuid"
592
593	# cleanup lvstore
594	rpc_cmd bdev_lvol_delete_lvstore -u "$lvstore_uuid"
595
596	# cleanup malloc dev
597	rpc_cmd bdev_malloc_delete "$malloc_dev"
598
599	check_leftover_devices
600}
601
602function test_lvol_set_parent_from_snapshot() {
603	local vol_size_mb=20
604	local vol_size=$((vol_size_mb * 1024 * 1024))
605	local vol_blocks_count=$((vol_size / MALLOC_BS))
606	local three_clusters_size=$((LVS_DEFAULT_CLUSTER_SIZE * 3))
607	local three_clusters_block_count=$((LVS_DEFAULT_CLUSTER_SIZE * 3 / MALLOC_BS))
608	local two_clusters_block_count=$((LVS_DEFAULT_CLUSTER_SIZE * 2 / MALLOC_BS))
609
610	# Create the lvstore on a malloc device.
611	malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
612	lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test)
613
614	# Create volume: lvol1
615	# New state:
616	#    lvol1
617	lvol1_uuid=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol1 "$vol_size_mb")
618
619	# Perform write operation over lvol1
620	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol1_uuid" /dev/nbd1
621	run_fio_test /dev/nbd1 0 $vol_size "write" "0xaa"
622	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd1
623	sleep 1
624
625	# Create a temp volume: lvol2_temp
626	# New state:
627	#    lvol1
628	#    lvol2_temp
629	lvol2_temp_uuid=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol2_temp "$vol_size_mb")
630
631	# Perform write operation over lvol2_temp
632	# Calculate md5 of last 2 clusters of lvol2_temp
633	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol2_temp_uuid" /dev/nbd2
634	run_fio_test /dev/nbd2 0 $vol_size "write" "0xbb"
635	md5_2=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$two_clusters_block_count skip=$three_clusters_block_count | md5sum)
636	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2
637
638	# Make a snapshot of lvol2_temp: snap2
639	# New state:
640	#    lvol1
641	#    snap2  <-- lvol2_temp
642	snap2_uuid=$(rpc_cmd bdev_lvol_snapshot "$lvol2_temp_uuid" snap2)
643
644	# Make a snapshot of lvol1: snap1
645	# New state:
646	#    snap1  <-- lvol1
647	#    snap2  <-- lvol2_temp
648	snap1_uuid=$(rpc_cmd bdev_lvol_snapshot "$lvol1_uuid" snap1)
649
650	# Create another clone of snap1: lvol2
651	# New state:
652	#    snap1  <-- lvol1
653	#          `<-- lvol2
654	#    snap2  <-- lvol2_temp
655	lvol2_uuid=$(rpc_cmd bdev_lvol_clone "$snap1_uuid" lvol2)
656
657	# Perform write operation over the first 3 clusters of lvol2
658	# Calculate md5sum of the first 3 clusters and of last 2 clusters of lvol2
659	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol2_uuid" /dev/nbd2
660	run_fio_test /dev/nbd2 0 $three_clusters_size "write" "0xcc"
661	md5_lvol2_1=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$three_clusters_block_count | md5sum)
662	md5_lvol2_2=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$two_clusters_block_count skip=$three_clusters_block_count | md5sum)
663	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2
664
665	# Change parent of lvol2
666	# New state:
667	#    snap1  <-- lvol1
668	#    snap2  <-- lvol2_temp
669	#          `<-- lvol2
670	rpc_cmd bdev_lvol_set_parent "$lvol2_uuid" "$snap2_uuid"
671
672	# Check lvol2 consistency
673	clone_bdev=$(rpc_cmd bdev_get_bdevs -b "$lvol2_uuid")
674	[ "$(jq '.[].driver_specific.lvol.snapshot' <<< "$clone_bdev")" = "false" ]
675	[ "$(jq '.[].driver_specific.lvol.clone' <<< "$clone_bdev")" = "true" ]
676	[ "$(jq '.[].driver_specific.lvol.base_snapshot' <<< "$clone_bdev")" = '"snap2"' ]
677	[ "$(jq '.[].driver_specific.lvol.esnap_clone' <<< "$clone_bdev")" = "false" ]
678
679	# Try again with aliases instead uuid
680	NOT rpc_cmd bdev_lvol_set_parent lvs_test/lvol2 lvs_test/snap2
681
682	# Delete lvol2_temp
683	# New state:
684	#    snap1  <-- lvol1
685	#    snap2  <-- lvol2
686	rpc_cmd bdev_lvol_delete "$lvol2_temp_uuid"
687
688	# Calculate again md5 of the first 3 clusters and of last 2 clusters of lvol2
689	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol2_uuid" /dev/nbd2
690	md5_lvol2_1_new=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$three_clusters_block_count | md5sum)
691	md5_lvol2_2_new=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$two_clusters_block_count skip=$three_clusters_block_count | md5sum)
692	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2
693
694	# Check that first three clusters of lvol2 didn't change anche that the last 2 clusters changed
695	[[ $md5_lvol2_1 == "$md5_lvol2_1_new" ]]
696	[[ $md5_lvol2_2 != "$md5_lvol2_2_new" ]]
697	[[ $md5_lvol2_2_new == "$md5_2" ]]
698
699	# Clean up
700	rpc_cmd bdev_lvol_delete "$lvol1_uuid"
701	rpc_cmd bdev_lvol_delete "$snap1_uuid"
702	rpc_cmd bdev_lvol_delete "$lvol2_uuid"
703	rpc_cmd bdev_lvol_delete "$snap2_uuid"
704	rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid"
705	rpc_cmd bdev_malloc_delete "$malloc_name"
706	check_leftover_devices
707}
708
709function test_lvol_set_parent_from_esnap() {
710	local vol_size_mb=20
711	local vol_size=$((vol_size_mb * 1024 * 1024))
712	local vol_blocks_count=$((vol_size / MALLOC_BS))
713	local three_clusters_size=$((LVS_DEFAULT_CLUSTER_SIZE * 3))
714	local three_clusters_block_count=$((LVS_DEFAULT_CLUSTER_SIZE * 3 / MALLOC_BS))
715	local two_clusters_block_count=$((LVS_DEFAULT_CLUSTER_SIZE * 2 / MALLOC_BS))
716
717	# Create the lvstore on a malloc device.
718	malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
719	lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test)
720
721	# Create a bdev that will be the external snapshot
722	# State:
723	#    esnap1
724	rpc_cmd bdev_malloc_create -b esnap1 "$vol_size_mb" $MALLOC_BS
725
726	# Perform write operation over the external snapshot
727	nbd_start_disks "$DEFAULT_RPC_ADDR" esnap1 /dev/nbd1
728	run_fio_test /dev/nbd1 0 $vol_size "write" "0xaa"
729	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd1
730	sleep 1
731
732	# Create a temp volume: lvol2_temp
733	# New state:
734	#    esnap1
735	#    lvol2_temp
736	lvol2_temp_uuid=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol2_temp "$vol_size_mb")
737
738	# Perform write operation over lvol2_temp
739	# Calculate md5 of last 2 clusters of lvol2_temp
740	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol2_temp_uuid" /dev/nbd2
741	run_fio_test /dev/nbd2 0 $vol_size "write" "0xbb"
742	md5_2=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$two_clusters_block_count skip=$three_clusters_block_count | md5sum)
743	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2
744
745	# Make a snapshot of lvol2_temp: snap2
746	# New state:
747	#    esnap1
748	#    snap2  <-- lvol2_temp
749	snap2_uuid=$(rpc_cmd bdev_lvol_snapshot "$lvol2_temp_uuid" snap2)
750
751	# Create an esnap clone: lvol2
752	# New state:
753	#    esnap1 <-- lvol2
754	#    snap2  <-- lvol2_temp
755	lvol2_uuid=$(rpc_cmd bdev_lvol_clone_bdev esnap1 lvs_test lvol2)
756
757	# Perform write operation over the first 3 clusters of lvol2
758	# Calculate md5sum of the first 3 clusters and of last 2 clusters of lvol2
759	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol2_uuid" /dev/nbd2
760	run_fio_test /dev/nbd2 0 $three_clusters_size "write" "0xcc"
761	md5_lvol2_1=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$three_clusters_block_count | md5sum)
762	md5_lvol2_2=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$two_clusters_block_count skip=$three_clusters_block_count | md5sum)
763	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2
764
765	# Change parent of lvol2
766	# New state:
767	#    esnap1
768	#    snap2  <-- lvol2
769	#          `<-- lvol2_temp
770	rpc_cmd bdev_lvol_set_parent "$lvol2_uuid" "$snap2_uuid"
771
772	# Check lvol2 consistency
773	clone_bdev=$(rpc_cmd bdev_get_bdevs -b "$lvol2_uuid")
774	[ "$(jq '.[].driver_specific.lvol.snapshot' <<< "$clone_bdev")" = "false" ]
775	[ "$(jq '.[].driver_specific.lvol.clone' <<< "$clone_bdev")" = "true" ]
776	[ "$(jq '.[].driver_specific.lvol.base_snapshot' <<< "$clone_bdev")" = '"snap2"' ]
777	[ "$(jq '.[].driver_specific.lvol.esnap_clone' <<< "$clone_bdev")" = "false" ]
778
779	# Try again with aliases instead uuid
780	NOT rpc_cmd bdev_lvol_set_parent lvs_test/lvol2 lvs_test/snap2
781
782	# Delete lvol2_temp
783	# New state:
784	#    esnap1
785	#    snap2  <-- lvol2
786	rpc_cmd bdev_lvol_delete "$lvol2_temp_uuid"
787
788	# Calculate again md5 of the first 3 clusters and of last 2 clusters of lvol2
789	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol2_uuid" /dev/nbd2
790	md5_lvol2_1_new=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$three_clusters_block_count | md5sum)
791	md5_lvol2_2_new=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$two_clusters_block_count skip=$three_clusters_block_count | md5sum)
792	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2
793
794	# Check that first three clusters of lvol2 didn't change anche that the last 2 clusters changed
795	[[ $md5_lvol2_1 == "$md5_lvol2_1_new" ]]
796	[[ $md5_lvol2_2 != "$md5_lvol2_2_new" ]]
797	[[ $md5_lvol2_2_new == "$md5_2" ]]
798
799	# Clean up
800	rpc_cmd bdev_lvol_delete "$lvol2_uuid"
801	rpc_cmd bdev_lvol_delete "$snap2_uuid"
802	rpc_cmd bdev_malloc_delete esnap1
803	rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid"
804	rpc_cmd bdev_malloc_delete "$malloc_name"
805	check_leftover_devices
806}
807
808function test_lvol_set_parent_from_none() {
809	local vol_size_mb=20
810	local vol_size=$((vol_size_mb * 1024 * 1024))
811	local three_clusters_size=$((LVS_DEFAULT_CLUSTER_SIZE * 3))
812	local three_clusters_block_count=$((LVS_DEFAULT_CLUSTER_SIZE * 3 / MALLOC_BS))
813	local two_clusters_block_count=$((LVS_DEFAULT_CLUSTER_SIZE * 2 / MALLOC_BS))
814
815	# Create the lvstore on a malloc device.
816	malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
817	lvs_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc_name" lvs_test)
818
819	# Create a temp volume: lvol2_temp
820	# New state:
821	#    lvol2_temp
822	lvol2_temp_uuid=$(rpc_cmd bdev_lvol_create -u "$lvs_uuid" lvol2_temp "$vol_size_mb")
823
824	# Perform write operation over lvol2_temp
825	# Calculate md5 of last 2 clusters of lvol2_temp
826	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol2_temp_uuid" /dev/nbd2
827	run_fio_test /dev/nbd2 0 $vol_size "write" "0xbb"
828	md5_2=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$two_clusters_block_count skip=$three_clusters_block_count | md5sum)
829	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2
830
831	# Make a snapshot of lvol2_temp: snap2
832	# New state:
833	#    snap2  <-- lvol2_temp
834	snap2_uuid=$(rpc_cmd bdev_lvol_snapshot "$lvol2_temp_uuid" snap2)
835
836	# Create another volume: lvol2
837	# New state:
838	#               lvol2
839	#    snap2  <-- lvol2_temp
840	lvol2_uuid=$(rpc_cmd bdev_lvol_create -t -u "$lvs_uuid" lvol2 "$vol_size_mb")
841
842	# Perform write operation over the first 3 clusters of lvol2
843	# Calculate md5sum of the first 3 clusters and of last 2 clusters of lvol2
844	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol2_uuid" /dev/nbd2
845	run_fio_test /dev/nbd2 0 $three_clusters_size "write" "0xcc"
846	md5_lvol2_1=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$three_clusters_block_count | md5sum)
847	md5_lvol2_2=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$two_clusters_block_count skip=$three_clusters_block_count | md5sum)
848	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2
849
850	# Change parent of lvol2
851	# New state:
852	#    snap2  <-- lvol2_temp
853	#          `<-- lvol2
854	rpc_cmd bdev_lvol_set_parent "$lvol2_uuid" "$snap2_uuid"
855
856	# Check lvol2 consistency
857	clone_bdev=$(rpc_cmd bdev_get_bdevs -b "$lvol2_uuid")
858	[ "$(jq '.[].driver_specific.lvol.snapshot' <<< "$clone_bdev")" = "false" ]
859	[ "$(jq '.[].driver_specific.lvol.clone' <<< "$clone_bdev")" = "true" ]
860	[ "$(jq '.[].driver_specific.lvol.base_snapshot' <<< "$clone_bdev")" = '"snap2"' ]
861	[ "$(jq '.[].driver_specific.lvol.esnap_clone' <<< "$clone_bdev")" = "false" ]
862
863	# Try again with aliases instead uuid
864	NOT rpc_cmd bdev_lvol_set_parent lvs_test/lvol2 lvs_test/snap2
865
866	# Delete lvol2_temp
867	# New state:
868	#    snap2  <-- lvol2
869	rpc_cmd bdev_lvol_delete "$lvol2_temp_uuid"
870
871	# Calculate again md5 of the first 3 clusters and of last 2 clusters of lvol2
872	nbd_start_disks "$DEFAULT_RPC_ADDR" "$lvol2_uuid" /dev/nbd2
873	md5_lvol2_1_new=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$three_clusters_block_count | md5sum)
874	md5_lvol2_2_new=$(dd if=/dev/nbd2 bs=$MALLOC_BS count=$two_clusters_block_count skip=$three_clusters_block_count | md5sum)
875	nbd_stop_disks "$DEFAULT_RPC_ADDR" /dev/nbd2
876
877	# Check that first three clusters of lvol2 didn't change anche that the last 2 clusters changed
878	[[ $md5_lvol2_1 == "$md5_lvol2_1_new" ]]
879	[[ $md5_lvol2_2 != "$md5_lvol2_2_new" ]]
880	[[ $md5_lvol2_2_new == "$md5_2" ]]
881
882	# Clean up
883	rpc_cmd bdev_lvol_delete "$lvol2_uuid"
884	rpc_cmd bdev_lvol_delete "$snap2_uuid"
885	rpc_cmd bdev_lvol_delete_lvstore -u "$lvs_uuid"
886	rpc_cmd bdev_malloc_delete "$malloc_name"
887	check_leftover_devices
888}
889
890function test_lvol_set_parent_failed() {
891	local vol_size_mb=20
892
893	# Create a lvstore on a malloc device.
894	malloc1_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
895	lvs1_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc1_name" lvs1_test)
896
897	# Create another lvstore on another malloc device.
898	malloc2_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
899	lvs2_uuid=$(rpc_cmd bdev_lvol_create_lvstore "$malloc2_name" lvs2_test)
900
901	# Create a volume on lvol store 1: lvol1
902	lvol1_uuid=$(rpc_cmd bdev_lvol_create -t -u "$lvs1_uuid" lvol1 "$vol_size_mb")
903
904	# Create a volume on lvol store 2: lvol2
905	lvol2_uuid=$(rpc_cmd bdev_lvol_create -t -u "$lvs2_uuid" lvol2 "$vol_size_mb")
906
907	# Make a snapshot of lvol2: snap2
908	snap2_uuid=$(rpc_cmd bdev_lvol_snapshot "$lvol2_uuid" snap2)
909
910	# The setting of snap2 as the parent of lvol2 must fail because they belong to different lvol stores
911	NOT rpc_cmd bdev_lvol_set_parent "$lvol1_uuid" "$snap2_uuid"
912
913	# Try to set parent with a parent that is not a lvol
914	NOT rpc_cmd bdev_lvol_set_parent "$lvol1_uuid" "$malloc2_name"
915
916	# Clean up
917	rpc_cmd bdev_lvol_delete "$lvol1_uuid"
918	rpc_cmd bdev_lvol_delete "$lvol2_uuid"
919	rpc_cmd bdev_lvol_delete "$snap2_uuid"
920	rpc_cmd bdev_lvol_delete_lvstore -u "$lvs1_uuid"
921	rpc_cmd bdev_lvol_delete_lvstore -u "$lvs2_uuid"
922	rpc_cmd bdev_malloc_delete "$malloc1_name"
923	rpc_cmd bdev_malloc_delete "$malloc2_name"
924	check_leftover_devices
925}
926
927$SPDK_BIN_DIR/spdk_tgt &
928spdk_pid=$!
929trap 'killprocess "$spdk_pid"; exit 1' SIGINT SIGTERM EXIT
930waitforlisten $spdk_pid
931modprobe nbd
932
933run_test "test_snapshot_compare_with_lvol_bdev" test_snapshot_compare_with_lvol_bdev
934run_test "test_create_snapshot_with_io" test_create_snapshot_with_io
935run_test "test_create_snapshot_of_snapshot" test_create_snapshot_of_snapshot
936run_test "test_clone_snapshot_relations" test_clone_snapshot_relations
937run_test "test_clone_inflate" test_clone_inflate
938run_test "test_clone_decouple_parent" test_clone_decouple_parent
939run_test "test_lvol_bdev_readonly" test_lvol_bdev_readonly
940run_test "test_delete_snapshot_with_clone" test_delete_snapshot_with_clone
941run_test "test_delete_snapshot_with_snapshot" test_delete_snapshot_with_snapshot
942run_test "test_bdev_lvol_delete_ordering" test_bdev_lvol_delete_ordering
943run_test "test_lvol_set_parent_from_snapshot" test_lvol_set_parent_from_snapshot
944run_test "test_lvol_set_parent_from_esnap" test_lvol_set_parent_from_esnap
945run_test "test_lvol_set_parent_from_none" test_lvol_set_parent_from_none
946run_test "test_lvol_set_parent_failed" test_lvol_set_parent_failed
947
948trap - SIGINT SIGTERM EXIT
949killprocess $spdk_pid
950