6 # This tests live snapshots of images on a running QEMU instance, using
7 # QMP commands. Both single disk snapshots, and transactional group
8 # snapshots are performed.
10 # Copyright (C) 2014 Red Hat, Inc.
11 # Copyright (C) 2015 Igalia, S.L.
13 # This program is free software; you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation; either version 2 of the License, or
16 # (at your option) any later version.
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
28 owner
=codyprime@gmail.com
31 echo "QA output created by $seq"
33 status
=1 # failure is the default!
35 snapshot_virt0
="snapshot-v0.qcow2"
36 snapshot_virt1
="snapshot-v1.qcow2"
44 for i
in $
(seq 1 ${SNAPSHOTS})
46 _rm_test_img
"${TEST_DIR}/${i}-${snapshot_virt0}"
47 _rm_test_img
"${TEST_DIR}/${i}-${snapshot_virt1}"
49 for img
in "${TEST_IMG}".
{1,2,base
}
55 trap "_cleanup; exit \$status" 0 1 2 3 15
57 # get standard environment, filters and checks
66 # ${1}: unique identifier for the snapshot filename
67 create_single_snapshot
()
69 cmd
="{ 'execute': 'blockdev-snapshot-sync',
70 'arguments': { 'device': 'virtio0',
71 'snapshot-file':'${TEST_DIR}/${1}-${snapshot_virt0}',
72 'format': 'qcow2' } }"
73 _send_qemu_cmd
$h "${cmd}" "return"
76 # ${1}: unique identifier for the snapshot filename
77 create_group_snapshot
()
79 cmd
="{ 'execute': 'transaction', 'arguments':
81 { 'type': 'blockdev-snapshot-sync', 'data' :
82 { 'device': 'virtio0',
83 'snapshot-file': '${TEST_DIR}/${1}-${snapshot_virt0}' } },
84 { 'type': 'blockdev-snapshot-sync', 'data' :
85 { 'device': 'virtio1',
86 'snapshot-file': '${TEST_DIR}/${1}-${snapshot_virt1}' } } ]
89 _send_qemu_cmd
$h "${cmd}" "return"
92 # ${1}: unique identifier for the snapshot filename
93 # ${2}: extra_params to the blockdev-add command
97 cmd
="{ 'execute': 'blockdev-add', 'arguments':
98 { 'driver': 'qcow2', 'node-name': 'snap_${1}', ${2}
100 { 'driver': 'file', 'filename': '${3}',
101 'node-name': 'file_${1}' } } }"
102 _send_qemu_cmd
$h "${cmd}" "return"
105 # ${1}: unique identifier for the snapshot filename
106 create_snapshot_image
()
108 base_image
="${TEST_DIR}/$((${1}-1))-${snapshot_virt0}"
109 snapshot_file
="${TEST_DIR}/${1}-${snapshot_virt0}"
110 TEST_IMG
=$snapshot_file _make_test_img
-u -b "${base_image}" -F $IMGFMT "$size"
113 # ${1}: unique identifier for the snapshot filename
116 snapshot_file
="${TEST_DIR}/${1}-${snapshot_virt0}"
117 create_snapshot_image
"$1"
118 do_blockdev_add
"$1" "'backing': null, " "${snapshot_file}"
121 # ${1}: unique identifier for the snapshot filename
122 # ${2}: expected response, defaults to 'return'
125 cmd
="{ 'execute': 'blockdev-snapshot',
126 'arguments': { 'node': 'virtio0',
127 'overlay':'snap_${1}' } }"
128 _send_qemu_cmd
$h "${cmd}" "${2:-return}"
133 TEST_IMG
="$TEST_IMG.1" _make_test_img
$size
134 TEST_IMG
="$TEST_IMG.2" _make_test_img
$size
137 echo === Running QEMU
===
140 qemu_comm_method
="qmp"
141 _launch_qemu
-drive file="${TEST_IMG}.1",if=virtio
-drive file="${TEST_IMG}.2",if=virtio
145 echo === Sending capabilities
===
148 _send_qemu_cmd
$h "{ 'execute': 'qmp_capabilities' }" "return"
150 # Tests for the blockdev-snapshot-sync command
153 echo === Create a single snapshot on virtio0
===
156 create_single_snapshot
1
160 echo === Invalid
command - missing device and nodename
===
163 _send_qemu_cmd
$h "{ 'execute': 'blockdev-snapshot-sync',
164 'arguments': { 'snapshot-file':'${TEST_DIR}/1-${snapshot_virt0}',
165 'format': 'qcow2' } }" "error"
168 echo === Invalid
command - missing snapshot-file
===
171 _send_qemu_cmd
$h "{ 'execute': 'blockdev-snapshot-sync',
172 'arguments': { 'device': 'virtio0',
173 'format': 'qcow2' } }" "error"
176 echo === Create several transactional group snapshots
===
179 for i
in $
(seq 2 ${SNAPSHOTS})
181 create_group_snapshot
${i}
184 # Tests for the blockdev-snapshot command
187 echo === Create a couple of snapshots using blockdev-snapshot
===
190 SNAPSHOTS
=$
((${SNAPSHOTS}+1))
191 add_snapshot_image
${SNAPSHOTS}
192 blockdev_snapshot
${SNAPSHOTS}
194 SNAPSHOTS
=$
((${SNAPSHOTS}+1))
195 add_snapshot_image
${SNAPSHOTS}
196 blockdev_snapshot
${SNAPSHOTS}
199 echo === Invalid
command - cannot create a snapshot using a
file BDS
===
202 _send_qemu_cmd
$h "{ 'execute': 'blockdev-snapshot',
203 'arguments': { 'node':'virtio0',
204 'overlay':'file_${SNAPSHOTS}' }
208 echo === Invalid
command - snapshot node used as active layer
===
211 blockdev_snapshot
${SNAPSHOTS} error
213 _send_qemu_cmd
$h "{ 'execute': 'blockdev-snapshot',
214 'arguments': { 'node':'virtio0',
215 'overlay':'virtio0' }
218 _send_qemu_cmd
$h "{ 'execute': 'blockdev-snapshot',
219 'arguments': { 'node':'virtio0',
220 'overlay':'virtio1' }
224 echo === Invalid
command - snapshot node used as backing hd
===
227 blockdev_snapshot $
((${SNAPSHOTS}-1)) error
230 echo === Invalid
command - snapshot node has a backing image
===
233 SNAPSHOTS
=$
((${SNAPSHOTS}+1))
235 TEST_IMG
="$TEST_IMG.base" _make_test_img
"$size"
236 _make_test_img
-b "${TEST_IMG}.base" -F $IMGFMT "$size"
237 do_blockdev_add
${SNAPSHOTS} "" "${TEST_IMG}"
238 blockdev_snapshot
${SNAPSHOTS} error
241 echo === Invalid
command - creating loops
===
244 SNAPSHOTS
=$
((${SNAPSHOTS}+1))
245 add_snapshot_image
${SNAPSHOTS}
247 _send_qemu_cmd
$h "{ 'execute': 'blockdev-snapshot',
248 'arguments': { 'node':'snap_${SNAPSHOTS}',
249 'overlay':'snap_${SNAPSHOTS}' }
252 SNAPSHOTS
=$
((${SNAPSHOTS}+1))
253 create_snapshot_image
${SNAPSHOTS}
254 do_blockdev_add
${SNAPSHOTS} "'backing': 'snap_$((${SNAPSHOTS}-1))', " \
255 "${TEST_DIR}/${SNAPSHOTS}-${snapshot_virt0}"
257 _send_qemu_cmd
$h "{ 'execute': 'blockdev-snapshot',
258 'arguments': { 'node':'snap_${SNAPSHOTS}',
259 'overlay':'snap_$((${SNAPSHOTS}-1))' }
263 echo === Invalid
command - The node does not exist
===
266 blockdev_snapshot $
((${SNAPSHOTS}+1)) error
268 _send_qemu_cmd
$h "{ 'execute': 'blockdev-snapshot',
269 'arguments': { 'node':'nodevice',
270 'overlay':'snap_${SNAPSHOTS}' }