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.
9 # Copyright (C) 2014 Red Hat, Inc.
11 # This program is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; either version 2 of the License, or
14 # (at your option) any later version.
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details.
21 # You should have received a copy of the GNU General Public License
22 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 owner
=jcody@redhat.com
29 echo "QA output created by $seq"
32 status
=1 # failure is the default!
35 QMP_IN
="${TEST_DIR}/qmp-in-$$"
36 QMP_OUT
="${TEST_DIR}/qmp-out-$$"
38 snapshot_virt0
="snapshot-v0.qcow2"
39 snapshot_virt1
="snapshot-v1.qcow2"
45 kill -KILL ${qemu_pid}
46 wait ${qemu_pid} 2>/dev
/null
# silent kill
48 rm -f "${QMP_IN}" "${QMP_OUT}"
49 for i
in $
(seq 1 ${MAX_SNAPSHOTS})
51 rm -f "${TEST_DIR}/${i}-${snapshot_virt0}"
52 rm -f "${TEST_DIR}/${i}-${snapshot_virt1}"
57 trap "_cleanup; exit \$status" 0 1 2 3 15
59 # get standard environment, filters and checks
67 # Wait for expected QMP response from QEMU. Will time out
68 # after 10 seconds, which counts as failure.
70 # $1 is the string to expect
72 # If $silent is set to anything but an empty string, then
73 # response is not echoed out.
74 function timed_wait_for
()
76 while read -t 10 resp
<&5
78 if [ "${silent}" == "" ]; then
79 echo "${resp}" | _filter_testdir | _filter_qemu
81 grep -q "${1}" < <(echo ${resp})
86 echo "Timeout waiting for ${1}"
87 exit 1 # Timeout means the test failed
90 # Sends QMP command to QEMU, and waits for the expected response
92 # ${1}: String of the QMP command to send
93 # ${2}: String that the QEMU response should contain
94 function send_qmp_cmd
()
100 # ${1}: unique identifier for the snapshot filename
101 function create_single_snapshot
()
103 cmd
="{ 'execute': 'blockdev-snapshot-sync',
104 'arguments': { 'device': 'virtio0',
105 'snapshot-file':'"${TEST_DIR}/${1}-${snapshot_virt0}"',
106 'format': 'qcow2' } }"
107 send_qmp_cmd
"${cmd}" "return"
110 # ${1}: unique identifier for the snapshot filename
111 function create_group_snapshot
()
113 cmd
="{ 'execute': 'transaction', 'arguments':
115 { 'type': 'blockdev-snapshot-sync', 'data' :
116 { 'device': 'virtio0',
117 'snapshot-file': '"${TEST_DIR}/${1}-${snapshot_virt0}"' } },
118 { 'type': 'blockdev-snapshot-sync', 'data' :
119 { 'device': 'virtio1',
120 'snapshot-file': '"${TEST_DIR}/${1}-${snapshot_virt1}"' } } ]
123 send_qmp_cmd "${cmd}" "return"
132 mv "${TEST_IMG}" "${TEST_IMG}.orig"
136 echo === Running QEMU ===
139 "${QEMU}" -nographic -monitor none -serial none -qmp stdio\
140 -drive file="${TEST_IMG}.orig",if=virtio\
141 -drive file="${TEST_IMG}",if=virtio 2>&1 >"${QMP_OUT}" <"${QMP_IN}"&
144 # redirect fifos to file descriptors, to keep from blocking
148 # Don't print response
, since it has version information
in it
149 silent
=yes timed_wait_for
"capabilities"
152 echo === Sending capabilities
===
155 send_qmp_cmd
"{ 'execute': 'qmp_capabilities' }" "return"
158 echo === Create a single snapshot on virtio0
===
161 create_single_snapshot
1
165 echo === Invalid
command - missing device and nodename
===
168 send_qmp_cmd
"{ 'execute': 'blockdev-snapshot-sync',
169 'arguments': { 'snapshot-file':'"${TEST_DIR}"/1-${snapshot_virt0}',
170 'format': 'qcow2' } }" "error"
173 echo === Invalid
command - missing snapshot-file
===
176 send_qmp_cmd
"{ 'execute': 'blockdev-snapshot-sync',
177 'arguments': { 'device': 'virtio0',
178 'format': 'qcow2' } }" "error"
181 echo === Create several transactional group snapshots
===
184 for i
in $
(seq 2 ${MAX_SNAPSHOTS})
186 create_group_snapshot
${i}