xref: /qemu/tests/qemu-iotests/085 (revision 814bb12a)
1#!/bin/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
32here=`pwd`
33status=1	# failure is the default!
34
35snapshot_virt0="snapshot-v0.qcow2"
36snapshot_virt1="snapshot-v1.qcow2"
37
38SNAPSHOTS=10
39
40_cleanup()
41{
42    _cleanup_qemu
43    for i in $(seq 1 ${SNAPSHOTS})
44    do
45        rm -f "${TEST_DIR}/${i}-${snapshot_virt0}"
46        rm -f "${TEST_DIR}/${i}-${snapshot_virt1}"
47    done
48    rm -f "${TEST_IMG}.1" "${TEST_IMG}.2"
49
50}
51trap "_cleanup; exit \$status" 0 1 2 3 15
52
53# get standard environment, filters and checks
54. ./common.rc
55. ./common.filter
56. ./common.qemu
57
58_supported_fmt qcow2
59_supported_proto file
60_supported_os Linux
61
62
63# ${1}: unique identifier for the snapshot filename
64function create_single_snapshot()
65{
66    cmd="{ 'execute': 'blockdev-snapshot-sync',
67                      'arguments': { 'device': 'virtio0',
68                                     'snapshot-file':'${TEST_DIR}/${1}-${snapshot_virt0}',
69                                     'format': 'qcow2' } }"
70    _send_qemu_cmd $h "${cmd}" "return"
71}
72
73# ${1}: unique identifier for the snapshot filename
74function create_group_snapshot()
75{
76    cmd="{ 'execute': 'transaction', 'arguments':
77           {'actions': [
78               { 'type': 'blockdev-snapshot-sync', 'data' :
79                   { 'device': 'virtio0',
80                      'snapshot-file': '${TEST_DIR}/${1}-${snapshot_virt0}' } },
81               { 'type': 'blockdev-snapshot-sync', 'data' :
82                   { 'device': 'virtio1',
83                       'snapshot-file': '${TEST_DIR}/${1}-${snapshot_virt1}' } } ]
84             } }"
85
86    _send_qemu_cmd $h "${cmd}" "return"
87}
88
89# ${1}: unique identifier for the snapshot filename
90# ${2}: true: open backing images; false: don't open them (default)
91function add_snapshot_image()
92{
93    if [ "${2}" = "true" ]; then
94        extra_params=""
95    else
96        extra_params="'backing': '', "
97    fi
98    base_image="${TEST_DIR}/$((${1}-1))-${snapshot_virt0}"
99    snapshot_file="${TEST_DIR}/${1}-${snapshot_virt0}"
100    _make_test_img -b "${base_image}" "$size"
101    mv "${TEST_IMG}" "${snapshot_file}"
102    cmd="{ 'execute': 'blockdev-add', 'arguments':
103           { 'driver': 'qcow2', 'node-name': 'snap_${1}', ${extra_params}
104             'file':
105             { 'driver': 'file', 'filename': '${snapshot_file}',
106               'node-name': 'file_${1}' } } }"
107    _send_qemu_cmd $h "${cmd}" "return"
108}
109
110# ${1}: unique identifier for the snapshot filename
111# ${2}: expected response, defaults to 'return'
112function blockdev_snapshot()
113{
114    cmd="{ 'execute': 'blockdev-snapshot',
115                      'arguments': { 'node': 'virtio0',
116                                     'overlay':'snap_${1}' } }"
117    _send_qemu_cmd $h "${cmd}" "${2:-return}"
118}
119
120size=128M
121
122_make_test_img $size
123mv "${TEST_IMG}" "${TEST_IMG}.1"
124_make_test_img $size
125mv "${TEST_IMG}" "${TEST_IMG}.2"
126
127echo
128echo === Running QEMU ===
129echo
130
131qemu_comm_method="qmp"
132_launch_qemu -drive file="${TEST_IMG}.1",if=virtio -drive file="${TEST_IMG}.2",if=virtio
133h=$QEMU_HANDLE
134
135echo
136echo === Sending capabilities ===
137echo
138
139_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" "return"
140
141# Tests for the blockdev-snapshot-sync command
142
143echo
144echo === Create a single snapshot on virtio0 ===
145echo
146
147create_single_snapshot 1
148
149
150echo
151echo === Invalid command - missing device and nodename ===
152echo
153
154_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync',
155                         'arguments': { 'snapshot-file':'${TEST_DIR}/1-${snapshot_virt0}',
156                                     'format': 'qcow2' } }" "error"
157
158echo
159echo === Invalid command - missing snapshot-file ===
160echo
161
162_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync',
163                         'arguments': { 'device': 'virtio0',
164                                     'format': 'qcow2' } }" "error"
165echo
166echo
167echo === Create several transactional group snapshots ===
168echo
169
170for i in $(seq 2 ${SNAPSHOTS})
171do
172    create_group_snapshot ${i}
173done
174
175# Tests for the blockdev-snapshot command
176
177echo
178echo === Create a couple of snapshots using blockdev-snapshot ===
179echo
180
181SNAPSHOTS=$((${SNAPSHOTS}+1))
182add_snapshot_image ${SNAPSHOTS}
183blockdev_snapshot ${SNAPSHOTS}
184
185SNAPSHOTS=$((${SNAPSHOTS}+1))
186add_snapshot_image ${SNAPSHOTS}
187blockdev_snapshot ${SNAPSHOTS}
188
189echo
190echo === Invalid command - cannot create a snapshot using a file BDS ===
191echo
192
193_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot',
194                     'arguments': { 'node':'virtio0',
195                                    'overlay':'file_${SNAPSHOTS}' }
196                   }" "error"
197
198echo
199echo === Invalid command - snapshot node used as active layer ===
200echo
201
202blockdev_snapshot ${SNAPSHOTS} error
203
204_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot',
205                     'arguments': { 'node':'virtio0',
206                                    'overlay':'virtio0' }
207                   }" "error"
208
209_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot',
210                     'arguments': { 'node':'virtio0',
211                                    'overlay':'virtio1' }
212                   }" "error"
213
214echo
215echo === Invalid command - snapshot node used as backing hd ===
216echo
217
218blockdev_snapshot $((${SNAPSHOTS}-1)) error
219
220echo
221echo === Invalid command - snapshot node has a backing image ===
222echo
223
224SNAPSHOTS=$((${SNAPSHOTS}+1))
225add_snapshot_image ${SNAPSHOTS} true
226blockdev_snapshot ${SNAPSHOTS} error
227
228echo
229echo === Invalid command - The node does not exist ===
230echo
231
232blockdev_snapshot $((${SNAPSHOTS}+1)) error
233
234_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot',
235                     'arguments': { 'node':'nodevice',
236                                    'overlay':'snap_${SNAPSHOTS}' }
237                   }" "error"
238
239# success, all done
240echo "*** done"
241rm -f $seq.full
242status=0
243