xref: /qemu/tests/qemu-iotests/085 (revision dd154c4d)
1#!/usr/bin/env bash
2#
3# Live snapshot tests
4#
5# This tests live snapshots of images on a running QEMU instance, using
6# QMP commands.  Both single disk snapshots, and transactional group
7# snapshots are performed.
8#
9# Copyright (C) 2014 Red Hat, Inc.
10# Copyright (C) 2015 Igalia, S.L.
11#
12# This program is free software; you can redistribute it and/or modify
13# it under the terms of the GNU General Public License as published by
14# the Free Software Foundation; either version 2 of the License, or
15# (at your option) any later version.
16#
17# This program is distributed in the hope that it will be useful,
18# but WITHOUT ANY WARRANTY; without even the implied warranty of
19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20# GNU General Public License for more details.
21#
22# You should have received a copy of the GNU General Public License
23# along with this program.  If not, see <http://www.gnu.org/licenses/>.
24#
25
26# creator
27owner=jcody@redhat.com
28
29seq=`basename $0`
30echo "QA output created by $seq"
31
32status=1	# failure is the default!
33
34snapshot_virt0="snapshot-v0.qcow2"
35snapshot_virt1="snapshot-v1.qcow2"
36
37SNAPSHOTS=10
38
39_cleanup()
40{
41    _cleanup_qemu
42    for i in $(seq 1 ${SNAPSHOTS})
43    do
44        rm -f "${TEST_DIR}/${i}-${snapshot_virt0}"
45        rm -f "${TEST_DIR}/${i}-${snapshot_virt1}"
46    done
47    rm -f "${TEST_IMG}" "${TEST_IMG}.1" "${TEST_IMG}.2" "${TEST_IMG}.base"
48
49}
50trap "_cleanup; exit \$status" 0 1 2 3 15
51
52# get standard environment, filters and checks
53. ./common.rc
54. ./common.filter
55. ./common.qemu
56
57_supported_fmt qcow2
58_supported_proto file
59_supported_os Linux
60
61
62# ${1}: unique identifier for the snapshot filename
63create_single_snapshot()
64{
65    cmd="{ 'execute': 'blockdev-snapshot-sync',
66                      'arguments': { 'device': 'virtio0',
67                                     'snapshot-file':'${TEST_DIR}/${1}-${snapshot_virt0}',
68                                     'format': 'qcow2' } }"
69    _send_qemu_cmd $h "${cmd}" "return"
70}
71
72# ${1}: unique identifier for the snapshot filename
73create_group_snapshot()
74{
75    cmd="{ 'execute': 'transaction', 'arguments':
76           {'actions': [
77               { 'type': 'blockdev-snapshot-sync', 'data' :
78                   { 'device': 'virtio0',
79                      'snapshot-file': '${TEST_DIR}/${1}-${snapshot_virt0}' } },
80               { 'type': 'blockdev-snapshot-sync', 'data' :
81                   { 'device': 'virtio1',
82                       'snapshot-file': '${TEST_DIR}/${1}-${snapshot_virt1}' } } ]
83             } }"
84
85    _send_qemu_cmd $h "${cmd}" "return"
86}
87
88# ${1}: unique identifier for the snapshot filename
89# ${2}: extra_params to the blockdev-add command
90# ${3}: filename
91do_blockdev_add()
92{
93    cmd="{ 'execute': 'blockdev-add', 'arguments':
94           { 'driver': 'qcow2', 'node-name': 'snap_${1}', ${2}
95             'file':
96             { 'driver': 'file', 'filename': '${3}',
97               'node-name': 'file_${1}' } } }"
98    _send_qemu_cmd $h "${cmd}" "return"
99}
100
101# ${1}: unique identifier for the snapshot filename
102add_snapshot_image()
103{
104    base_image="${TEST_DIR}/$((${1}-1))-${snapshot_virt0}"
105    snapshot_file="${TEST_DIR}/${1}-${snapshot_virt0}"
106    _make_test_img -u -b "${base_image}" "$size"
107    mv "${TEST_IMG}" "${snapshot_file}"
108    do_blockdev_add "$1" "'backing': null, " "${snapshot_file}"
109}
110
111# ${1}: unique identifier for the snapshot filename
112# ${2}: expected response, defaults to 'return'
113blockdev_snapshot()
114{
115    cmd="{ 'execute': 'blockdev-snapshot',
116                      'arguments': { 'node': 'virtio0',
117                                     'overlay':'snap_${1}' } }"
118    _send_qemu_cmd $h "${cmd}" "${2:-return}"
119}
120
121size=128M
122
123_make_test_img $size
124mv "${TEST_IMG}" "${TEST_IMG}.1"
125_make_test_img $size
126mv "${TEST_IMG}" "${TEST_IMG}.2"
127
128echo
129echo === Running QEMU ===
130echo
131
132qemu_comm_method="qmp"
133_launch_qemu -drive file="${TEST_IMG}.1",if=virtio -drive file="${TEST_IMG}.2",if=virtio
134h=$QEMU_HANDLE
135
136echo
137echo === Sending capabilities ===
138echo
139
140_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" "return"
141
142# Tests for the blockdev-snapshot-sync command
143
144echo
145echo === Create a single snapshot on virtio0 ===
146echo
147
148create_single_snapshot 1
149
150
151echo
152echo === Invalid command - missing device and nodename ===
153echo
154
155_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync',
156                         'arguments': { 'snapshot-file':'${TEST_DIR}/1-${snapshot_virt0}',
157                                     'format': 'qcow2' } }" "error"
158
159echo
160echo === Invalid command - missing snapshot-file ===
161echo
162
163_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync',
164                         'arguments': { 'device': 'virtio0',
165                                     'format': 'qcow2' } }" "error"
166echo
167echo
168echo === Create several transactional group snapshots ===
169echo
170
171for i in $(seq 2 ${SNAPSHOTS})
172do
173    create_group_snapshot ${i}
174done
175
176# Tests for the blockdev-snapshot command
177
178echo
179echo === Create a couple of snapshots using blockdev-snapshot ===
180echo
181
182SNAPSHOTS=$((${SNAPSHOTS}+1))
183add_snapshot_image ${SNAPSHOTS}
184blockdev_snapshot ${SNAPSHOTS}
185
186SNAPSHOTS=$((${SNAPSHOTS}+1))
187add_snapshot_image ${SNAPSHOTS}
188blockdev_snapshot ${SNAPSHOTS}
189
190echo
191echo === Invalid command - cannot create a snapshot using a file BDS ===
192echo
193
194_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot',
195                     'arguments': { 'node':'virtio0',
196                                    'overlay':'file_${SNAPSHOTS}' }
197                   }" "error"
198
199echo
200echo === Invalid command - snapshot node used as active layer ===
201echo
202
203blockdev_snapshot ${SNAPSHOTS} error
204
205_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot',
206                     'arguments': { 'node':'virtio0',
207                                    'overlay':'virtio0' }
208                   }" "error"
209
210_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot',
211                     'arguments': { 'node':'virtio0',
212                                    'overlay':'virtio1' }
213                   }" "error"
214
215echo
216echo === Invalid command - snapshot node used as backing hd ===
217echo
218
219blockdev_snapshot $((${SNAPSHOTS}-1)) error
220
221echo
222echo === Invalid command - snapshot node has a backing image ===
223echo
224
225SNAPSHOTS=$((${SNAPSHOTS}+1))
226
227TEST_IMG="$TEST_IMG.base" _make_test_img "$size"
228_make_test_img -b "${TEST_IMG}.base" "$size"
229do_blockdev_add ${SNAPSHOTS} "" "${TEST_IMG}"
230blockdev_snapshot ${SNAPSHOTS} error
231
232echo
233echo === Invalid command - The node does not exist ===
234echo
235
236blockdev_snapshot $((${SNAPSHOTS}+1)) error
237
238_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot',
239                     'arguments': { 'node':'nodevice',
240                                    'overlay':'snap_${SNAPSHOTS}' }
241                   }" "error"
242
243# success, all done
244echo "*** done"
245rm -f $seq.full
246status=0
247