xref: /qemu/tests/qemu-iotests/085 (revision 4089f7c6a0d91020ca60ce8300784c93dd9ddcbe)
1*4089f7c6SJeff Cody#!/bin/bash
2*4089f7c6SJeff Cody#
3*4089f7c6SJeff Cody# Live snapshot tests
4*4089f7c6SJeff Cody#
5*4089f7c6SJeff Cody# This tests live snapshots of images on a running QEMU instance, using
6*4089f7c6SJeff Cody# QMP commands.  Both single disk snapshots, and transactional group
7*4089f7c6SJeff Cody# snapshots are performed.
8*4089f7c6SJeff Cody#
9*4089f7c6SJeff Cody# Copyright (C) 2014 Red Hat, Inc.
10*4089f7c6SJeff Cody#
11*4089f7c6SJeff Cody# This program is free software; you can redistribute it and/or modify
12*4089f7c6SJeff Cody# it under the terms of the GNU General Public License as published by
13*4089f7c6SJeff Cody# the Free Software Foundation; either version 2 of the License, or
14*4089f7c6SJeff Cody# (at your option) any later version.
15*4089f7c6SJeff Cody#
16*4089f7c6SJeff Cody# This program is distributed in the hope that it will be useful,
17*4089f7c6SJeff Cody# but WITHOUT ANY WARRANTY; without even the implied warranty of
18*4089f7c6SJeff Cody# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19*4089f7c6SJeff Cody# GNU General Public License for more details.
20*4089f7c6SJeff Cody#
21*4089f7c6SJeff Cody# You should have received a copy of the GNU General Public License
22*4089f7c6SJeff Cody# along with this program.  If not, see <http://www.gnu.org/licenses/>.
23*4089f7c6SJeff Cody#
24*4089f7c6SJeff Cody
25*4089f7c6SJeff Cody# creator
26*4089f7c6SJeff Codyowner=jcody@redhat.com
27*4089f7c6SJeff Cody
28*4089f7c6SJeff Codyseq=`basename $0`
29*4089f7c6SJeff Codyecho "QA output created by $seq"
30*4089f7c6SJeff Cody
31*4089f7c6SJeff Codyhere=`pwd`
32*4089f7c6SJeff Codystatus=1	# failure is the default!
33*4089f7c6SJeff Codyqemu_pid=
34*4089f7c6SJeff Cody
35*4089f7c6SJeff CodyQMP_IN="${TEST_DIR}/qmp-in-$$"
36*4089f7c6SJeff CodyQMP_OUT="${TEST_DIR}/qmp-out-$$"
37*4089f7c6SJeff Cody
38*4089f7c6SJeff Codysnapshot_virt0="snapshot-v0.qcow2"
39*4089f7c6SJeff Codysnapshot_virt1="snapshot-v1.qcow2"
40*4089f7c6SJeff Cody
41*4089f7c6SJeff CodyMAX_SNAPSHOTS=10
42*4089f7c6SJeff Cody
43*4089f7c6SJeff Cody_cleanup()
44*4089f7c6SJeff Cody{
45*4089f7c6SJeff Cody    kill -KILL ${qemu_pid}
46*4089f7c6SJeff Cody    wait ${qemu_pid} 2>/dev/null  # silent kill
47*4089f7c6SJeff Cody
48*4089f7c6SJeff Cody    rm -f "${QMP_IN}" "${QMP_OUT}"
49*4089f7c6SJeff Cody    for i in $(seq 1 ${MAX_SNAPSHOTS})
50*4089f7c6SJeff Cody    do
51*4089f7c6SJeff Cody        rm -f "${TEST_DIR}/${i}-${snapshot_virt0}"
52*4089f7c6SJeff Cody        rm -f "${TEST_DIR}/${i}-${snapshot_virt1}"
53*4089f7c6SJeff Cody    done
54*4089f7c6SJeff Cody	_cleanup_test_img
55*4089f7c6SJeff Cody
56*4089f7c6SJeff Cody}
57*4089f7c6SJeff Codytrap "_cleanup; exit \$status" 0 1 2 3 15
58*4089f7c6SJeff Cody
59*4089f7c6SJeff Cody# get standard environment, filters and checks
60*4089f7c6SJeff Cody. ./common.rc
61*4089f7c6SJeff Cody. ./common.filter
62*4089f7c6SJeff Cody
63*4089f7c6SJeff Cody_supported_fmt qcow2
64*4089f7c6SJeff Cody_supported_proto file
65*4089f7c6SJeff Cody_supported_os Linux
66*4089f7c6SJeff Cody
67*4089f7c6SJeff Cody# Wait for expected QMP response from QEMU.  Will time out
68*4089f7c6SJeff Cody# after 10 seconds, which counts as failure.
69*4089f7c6SJeff Cody#
70*4089f7c6SJeff Cody# $1 is the string to expect
71*4089f7c6SJeff Cody#
72*4089f7c6SJeff Cody# If $silent is set to anything but an empty string, then
73*4089f7c6SJeff Cody# response is not echoed out.
74*4089f7c6SJeff Codyfunction timed_wait_for()
75*4089f7c6SJeff Cody{
76*4089f7c6SJeff Cody    while read -t 10 resp <&5
77*4089f7c6SJeff Cody    do
78*4089f7c6SJeff Cody        if [ "${silent}" == "" ]; then
79*4089f7c6SJeff Cody            echo "${resp}" | _filter_testdir | _filter_qemu
80*4089f7c6SJeff Cody        fi
81*4089f7c6SJeff Cody        grep -q "${1}" < <(echo ${resp})
82*4089f7c6SJeff Cody        if [ $? -eq 0 ]; then
83*4089f7c6SJeff Cody            return
84*4089f7c6SJeff Cody        fi
85*4089f7c6SJeff Cody    done
86*4089f7c6SJeff Cody    echo "Timeout waiting for ${1}"
87*4089f7c6SJeff Cody    exit 1  # Timeout means the test failed
88*4089f7c6SJeff Cody}
89*4089f7c6SJeff Cody
90*4089f7c6SJeff Cody# Sends QMP command to QEMU, and waits for the expected response
91*4089f7c6SJeff Cody#
92*4089f7c6SJeff Cody# ${1}:  String of the QMP command to send
93*4089f7c6SJeff Cody# ${2}:  String that the QEMU response should contain
94*4089f7c6SJeff Codyfunction send_qmp_cmd()
95*4089f7c6SJeff Cody{
96*4089f7c6SJeff Cody    echo "${1}" >&6
97*4089f7c6SJeff Cody    timed_wait_for "${2}"
98*4089f7c6SJeff Cody}
99*4089f7c6SJeff Cody
100*4089f7c6SJeff Cody# ${1}: unique identifier for the snapshot filename
101*4089f7c6SJeff Codyfunction create_single_snapshot()
102*4089f7c6SJeff Cody{
103*4089f7c6SJeff Cody    cmd="{ 'execute': 'blockdev-snapshot-sync',
104*4089f7c6SJeff Cody                      'arguments': { 'device': 'virtio0',
105*4089f7c6SJeff Cody                                     'snapshot-file':'"${TEST_DIR}/${1}-${snapshot_virt0}"',
106*4089f7c6SJeff Cody                                     'format': 'qcow2' } }"
107*4089f7c6SJeff Cody    send_qmp_cmd "${cmd}" "return"
108*4089f7c6SJeff Cody}
109*4089f7c6SJeff Cody
110*4089f7c6SJeff Cody# ${1}: unique identifier for the snapshot filename
111*4089f7c6SJeff Codyfunction create_group_snapshot()
112*4089f7c6SJeff Cody{
113*4089f7c6SJeff Cody    cmd="{ 'execute': 'transaction', 'arguments':
114*4089f7c6SJeff Cody           {'actions': [
115*4089f7c6SJeff Cody               { 'type': 'blockdev-snapshot-sync', 'data' :
116*4089f7c6SJeff Cody                   { 'device': 'virtio0',
117*4089f7c6SJeff Cody                      'snapshot-file': '"${TEST_DIR}/${1}-${snapshot_virt0}"' } },
118*4089f7c6SJeff Cody               { 'type': 'blockdev-snapshot-sync', 'data' :
119*4089f7c6SJeff Cody                   { 'device': 'virtio1',
120*4089f7c6SJeff Cody                       'snapshot-file': '"${TEST_DIR}/${1}-${snapshot_virt1}"' } } ]
121*4089f7c6SJeff Cody             } }"
122*4089f7c6SJeff Cody
123*4089f7c6SJeff Cody    send_qmp_cmd "${cmd}" "return"
124*4089f7c6SJeff Cody}
125*4089f7c6SJeff Cody
126*4089f7c6SJeff Codysize=128M
127*4089f7c6SJeff Cody
128*4089f7c6SJeff Codymkfifo "${QMP_IN}"
129*4089f7c6SJeff Codymkfifo "${QMP_OUT}"
130*4089f7c6SJeff Cody
131*4089f7c6SJeff Cody_make_test_img $size
132*4089f7c6SJeff Codymv "${TEST_IMG}" "${TEST_IMG}.orig"
133*4089f7c6SJeff Cody_make_test_img $size
134*4089f7c6SJeff Cody
135*4089f7c6SJeff Codyecho
136*4089f7c6SJeff Codyecho === Running QEMU ===
137*4089f7c6SJeff Codyecho
138*4089f7c6SJeff Cody
139*4089f7c6SJeff Cody"${QEMU}" -nographic -monitor none -serial none -qmp stdio\
140*4089f7c6SJeff Cody          -drive file="${TEST_IMG}.orig",if=virtio\
141*4089f7c6SJeff Cody          -drive file="${TEST_IMG}",if=virtio 2>&1 >"${QMP_OUT}" <"${QMP_IN}"&
142*4089f7c6SJeff Codyqemu_pid=$!
143*4089f7c6SJeff Cody
144*4089f7c6SJeff Cody# redirect fifos to file descriptors, to keep from blocking
145*4089f7c6SJeff Codyexec 5<"${QMP_OUT}"
146*4089f7c6SJeff Codyexec 6>"${QMP_IN}"
147*4089f7c6SJeff Cody
148*4089f7c6SJeff Cody# Don't print response, since it has version information in it
149*4089f7c6SJeff Codysilent=yes timed_wait_for "capabilities"
150*4089f7c6SJeff Cody
151*4089f7c6SJeff Codyecho
152*4089f7c6SJeff Codyecho === Sending capabilities ===
153*4089f7c6SJeff Codyecho
154*4089f7c6SJeff Cody
155*4089f7c6SJeff Codysend_qmp_cmd "{ 'execute': 'qmp_capabilities' }" "return"
156*4089f7c6SJeff Cody
157*4089f7c6SJeff Codyecho
158*4089f7c6SJeff Codyecho === Create a single snapshot on virtio0 ===
159*4089f7c6SJeff Codyecho
160*4089f7c6SJeff Cody
161*4089f7c6SJeff Codycreate_single_snapshot 1
162*4089f7c6SJeff Cody
163*4089f7c6SJeff Cody
164*4089f7c6SJeff Codyecho
165*4089f7c6SJeff Codyecho === Invalid command - missing device and nodename ===
166*4089f7c6SJeff Codyecho
167*4089f7c6SJeff Cody
168*4089f7c6SJeff Codysend_qmp_cmd "{ 'execute': 'blockdev-snapshot-sync',
169*4089f7c6SJeff Cody                      'arguments': { 'snapshot-file':'"${TEST_DIR}"/1-${snapshot_virt0}',
170*4089f7c6SJeff Cody                                     'format': 'qcow2' } }" "error"
171*4089f7c6SJeff Cody
172*4089f7c6SJeff Codyecho
173*4089f7c6SJeff Codyecho === Invalid command - missing snapshot-file ===
174*4089f7c6SJeff Codyecho
175*4089f7c6SJeff Cody
176*4089f7c6SJeff Codysend_qmp_cmd "{ 'execute': 'blockdev-snapshot-sync',
177*4089f7c6SJeff Cody                      'arguments': { 'device': 'virtio0',
178*4089f7c6SJeff Cody                                     'format': 'qcow2' } }" "error"
179*4089f7c6SJeff Codyecho
180*4089f7c6SJeff Codyecho
181*4089f7c6SJeff Codyecho === Create several transactional group snapshots ===
182*4089f7c6SJeff Codyecho
183*4089f7c6SJeff Cody
184*4089f7c6SJeff Codyfor i in $(seq 2 ${MAX_SNAPSHOTS})
185*4089f7c6SJeff Codydo
186*4089f7c6SJeff Cody    create_group_snapshot ${i}
187*4089f7c6SJeff Codydone
188*4089f7c6SJeff Cody
189*4089f7c6SJeff Cody# success, all done
190*4089f7c6SJeff Codyecho "*** done"
191*4089f7c6SJeff Codyrm -f $seq.full
192*4089f7c6SJeff Codystatus=0
193