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