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