14089f7c6SJeff Cody#!/bin/bash 24089f7c6SJeff Cody# 34089f7c6SJeff Cody# Live snapshot tests 44089f7c6SJeff Cody# 54089f7c6SJeff Cody# This tests live snapshots of images on a running QEMU instance, using 64089f7c6SJeff Cody# QMP commands. Both single disk snapshots, and transactional group 74089f7c6SJeff Cody# snapshots are performed. 84089f7c6SJeff Cody# 94089f7c6SJeff Cody# Copyright (C) 2014 Red Hat, Inc. 10*89e3a2d8SAlberto Garcia# Copyright (C) 2015 Igalia, S.L. 114089f7c6SJeff Cody# 124089f7c6SJeff Cody# This program is free software; you can redistribute it and/or modify 134089f7c6SJeff Cody# it under the terms of the GNU General Public License as published by 144089f7c6SJeff Cody# the Free Software Foundation; either version 2 of the License, or 154089f7c6SJeff Cody# (at your option) any later version. 164089f7c6SJeff Cody# 174089f7c6SJeff Cody# This program is distributed in the hope that it will be useful, 184089f7c6SJeff Cody# but WITHOUT ANY WARRANTY; without even the implied warranty of 194089f7c6SJeff Cody# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 204089f7c6SJeff Cody# GNU General Public License for more details. 214089f7c6SJeff Cody# 224089f7c6SJeff Cody# You should have received a copy of the GNU General Public License 234089f7c6SJeff Cody# along with this program. If not, see <http://www.gnu.org/licenses/>. 244089f7c6SJeff Cody# 254089f7c6SJeff Cody 264089f7c6SJeff Cody# creator 274089f7c6SJeff Codyowner=jcody@redhat.com 284089f7c6SJeff Cody 294089f7c6SJeff Codyseq=`basename $0` 304089f7c6SJeff Codyecho "QA output created by $seq" 314089f7c6SJeff Cody 324089f7c6SJeff Codyhere=`pwd` 334089f7c6SJeff Codystatus=1 # failure is the default! 344089f7c6SJeff Cody 354089f7c6SJeff Codysnapshot_virt0="snapshot-v0.qcow2" 364089f7c6SJeff Codysnapshot_virt1="snapshot-v1.qcow2" 374089f7c6SJeff Cody 38*89e3a2d8SAlberto GarciaSNAPSHOTS=10 394089f7c6SJeff Cody 404089f7c6SJeff Cody_cleanup() 414089f7c6SJeff Cody{ 42e86e8697SJeff Cody _cleanup_qemu 43*89e3a2d8SAlberto Garcia for i in $(seq 1 ${SNAPSHOTS}) 444089f7c6SJeff Cody do 454089f7c6SJeff Cody rm -f "${TEST_DIR}/${i}-${snapshot_virt0}" 464089f7c6SJeff Cody rm -f "${TEST_DIR}/${i}-${snapshot_virt1}" 474089f7c6SJeff Cody done 48*89e3a2d8SAlberto Garcia rm -f "${TEST_IMG}.1" "${TEST_IMG}.2" 494089f7c6SJeff Cody 504089f7c6SJeff Cody} 514089f7c6SJeff Codytrap "_cleanup; exit \$status" 0 1 2 3 15 524089f7c6SJeff Cody 534089f7c6SJeff Cody# get standard environment, filters and checks 544089f7c6SJeff Cody. ./common.rc 554089f7c6SJeff Cody. ./common.filter 56e86e8697SJeff Cody. ./common.qemu 574089f7c6SJeff Cody 584089f7c6SJeff Cody_supported_fmt qcow2 594089f7c6SJeff Cody_supported_proto file 604089f7c6SJeff Cody_supported_os Linux 614089f7c6SJeff Cody 624089f7c6SJeff Cody 634089f7c6SJeff Cody# ${1}: unique identifier for the snapshot filename 644089f7c6SJeff Codyfunction create_single_snapshot() 654089f7c6SJeff Cody{ 664089f7c6SJeff Cody cmd="{ 'execute': 'blockdev-snapshot-sync', 674089f7c6SJeff Cody 'arguments': { 'device': 'virtio0', 684089f7c6SJeff Cody 'snapshot-file':'"${TEST_DIR}/${1}-${snapshot_virt0}"', 694089f7c6SJeff Cody 'format': 'qcow2' } }" 70e86e8697SJeff Cody _send_qemu_cmd $h "${cmd}" "return" 714089f7c6SJeff Cody} 724089f7c6SJeff Cody 734089f7c6SJeff Cody# ${1}: unique identifier for the snapshot filename 744089f7c6SJeff Codyfunction create_group_snapshot() 754089f7c6SJeff Cody{ 764089f7c6SJeff Cody cmd="{ 'execute': 'transaction', 'arguments': 774089f7c6SJeff Cody {'actions': [ 784089f7c6SJeff Cody { 'type': 'blockdev-snapshot-sync', 'data' : 794089f7c6SJeff Cody { 'device': 'virtio0', 804089f7c6SJeff Cody 'snapshot-file': '"${TEST_DIR}/${1}-${snapshot_virt0}"' } }, 814089f7c6SJeff Cody { 'type': 'blockdev-snapshot-sync', 'data' : 824089f7c6SJeff Cody { 'device': 'virtio1', 834089f7c6SJeff Cody 'snapshot-file': '"${TEST_DIR}/${1}-${snapshot_virt1}"' } } ] 844089f7c6SJeff Cody } }" 854089f7c6SJeff Cody 86e86e8697SJeff Cody _send_qemu_cmd $h "${cmd}" "return" 874089f7c6SJeff Cody} 884089f7c6SJeff Cody 89*89e3a2d8SAlberto Garcia# ${1}: unique identifier for the snapshot filename 90*89e3a2d8SAlberto Garcia# ${2}: true: open backing images; false: don't open them (default) 91*89e3a2d8SAlberto Garciafunction add_snapshot_image() 92*89e3a2d8SAlberto Garcia{ 93*89e3a2d8SAlberto Garcia if [ "${2}" = "true" ]; then 94*89e3a2d8SAlberto Garcia extra_params="" 95*89e3a2d8SAlberto Garcia else 96*89e3a2d8SAlberto Garcia extra_params="'backing': '', " 97*89e3a2d8SAlberto Garcia fi 98*89e3a2d8SAlberto Garcia base_image="${TEST_DIR}/$((${1}-1))-${snapshot_virt0}" 99*89e3a2d8SAlberto Garcia snapshot_file="${TEST_DIR}/${1}-${snapshot_virt0}" 100*89e3a2d8SAlberto Garcia _make_test_img -b "${base_image}" "$size" 101*89e3a2d8SAlberto Garcia mv "${TEST_IMG}" "${snapshot_file}" 102*89e3a2d8SAlberto Garcia cmd="{ 'execute': 'blockdev-add', 'arguments': 103*89e3a2d8SAlberto Garcia { 'options': 104*89e3a2d8SAlberto Garcia { 'driver': 'qcow2', 'node-name': 'snap_"${1}"', "${extra_params}" 105*89e3a2d8SAlberto Garcia 'file': 106*89e3a2d8SAlberto Garcia { 'driver': 'file', 'filename': '"${snapshot_file}"' } } } }" 107*89e3a2d8SAlberto Garcia _send_qemu_cmd $h "${cmd}" "return" 108*89e3a2d8SAlberto Garcia} 109*89e3a2d8SAlberto Garcia 110*89e3a2d8SAlberto Garcia# ${1}: unique identifier for the snapshot filename 111*89e3a2d8SAlberto Garcia# ${2}: expected response, defaults to 'return' 112*89e3a2d8SAlberto Garciafunction blockdev_snapshot() 113*89e3a2d8SAlberto Garcia{ 114*89e3a2d8SAlberto Garcia cmd="{ 'execute': 'blockdev-snapshot', 115*89e3a2d8SAlberto Garcia 'arguments': { 'node': 'virtio0', 116*89e3a2d8SAlberto Garcia 'overlay':'snap_"${1}"' } }" 117*89e3a2d8SAlberto Garcia _send_qemu_cmd $h "${cmd}" "${2:-return}" 118*89e3a2d8SAlberto Garcia} 119*89e3a2d8SAlberto Garcia 1204089f7c6SJeff Codysize=128M 1214089f7c6SJeff Cody 1224089f7c6SJeff Cody_make_test_img $size 123*89e3a2d8SAlberto Garciamv "${TEST_IMG}" "${TEST_IMG}.1" 1244089f7c6SJeff Cody_make_test_img $size 125*89e3a2d8SAlberto Garciamv "${TEST_IMG}" "${TEST_IMG}.2" 1264089f7c6SJeff Cody 1274089f7c6SJeff Codyecho 1284089f7c6SJeff Codyecho === Running QEMU === 1294089f7c6SJeff Codyecho 1304089f7c6SJeff Cody 131e86e8697SJeff Codyqemu_comm_method="qmp" 132*89e3a2d8SAlberto Garcia_launch_qemu -drive file="${TEST_IMG}.1",if=virtio -drive file="${TEST_IMG}.2",if=virtio 133e86e8697SJeff Codyh=$QEMU_HANDLE 1344089f7c6SJeff Cody 1354089f7c6SJeff Codyecho 1364089f7c6SJeff Codyecho === Sending capabilities === 1374089f7c6SJeff Codyecho 1384089f7c6SJeff Cody 139e86e8697SJeff Cody_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" "return" 1404089f7c6SJeff Cody 141*89e3a2d8SAlberto Garcia# Tests for the blockdev-snapshot-sync command 142*89e3a2d8SAlberto Garcia 1434089f7c6SJeff Codyecho 1444089f7c6SJeff Codyecho === Create a single snapshot on virtio0 === 1454089f7c6SJeff Codyecho 1464089f7c6SJeff Cody 1474089f7c6SJeff Codycreate_single_snapshot 1 1484089f7c6SJeff Cody 1494089f7c6SJeff Cody 1504089f7c6SJeff Codyecho 1514089f7c6SJeff Codyecho === Invalid command - missing device and nodename === 1524089f7c6SJeff Codyecho 1534089f7c6SJeff Cody 154e86e8697SJeff Cody_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync', 155e86e8697SJeff Cody 'arguments': { 'snapshot-file':'"${TEST_DIR}/1-${snapshot_virt0}"', 1564089f7c6SJeff Cody 'format': 'qcow2' } }" "error" 1574089f7c6SJeff Cody 1584089f7c6SJeff Codyecho 1594089f7c6SJeff Codyecho === Invalid command - missing snapshot-file === 1604089f7c6SJeff Codyecho 1614089f7c6SJeff Cody 162e86e8697SJeff Cody_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync', 1634089f7c6SJeff Cody 'arguments': { 'device': 'virtio0', 1644089f7c6SJeff Cody 'format': 'qcow2' } }" "error" 1654089f7c6SJeff Codyecho 1664089f7c6SJeff Codyecho 1674089f7c6SJeff Codyecho === Create several transactional group snapshots === 1684089f7c6SJeff Codyecho 1694089f7c6SJeff Cody 170*89e3a2d8SAlberto Garciafor i in $(seq 2 ${SNAPSHOTS}) 1714089f7c6SJeff Codydo 1724089f7c6SJeff Cody create_group_snapshot ${i} 1734089f7c6SJeff Codydone 1744089f7c6SJeff Cody 175*89e3a2d8SAlberto Garcia# Tests for the blockdev-snapshot command 176*89e3a2d8SAlberto Garcia 177*89e3a2d8SAlberto Garciaecho 178*89e3a2d8SAlberto Garciaecho === Create a couple of snapshots using blockdev-snapshot === 179*89e3a2d8SAlberto Garciaecho 180*89e3a2d8SAlberto Garcia 181*89e3a2d8SAlberto GarciaSNAPSHOTS=$((${SNAPSHOTS}+1)) 182*89e3a2d8SAlberto Garciaadd_snapshot_image ${SNAPSHOTS} 183*89e3a2d8SAlberto Garciablockdev_snapshot ${SNAPSHOTS} 184*89e3a2d8SAlberto Garcia 185*89e3a2d8SAlberto GarciaSNAPSHOTS=$((${SNAPSHOTS}+1)) 186*89e3a2d8SAlberto Garciaadd_snapshot_image ${SNAPSHOTS} 187*89e3a2d8SAlberto Garciablockdev_snapshot ${SNAPSHOTS} 188*89e3a2d8SAlberto Garcia 189*89e3a2d8SAlberto Garciaecho 190*89e3a2d8SAlberto Garciaecho === Invalid command - snapshot node used as active layer === 191*89e3a2d8SAlberto Garciaecho 192*89e3a2d8SAlberto Garcia 193*89e3a2d8SAlberto Garciablockdev_snapshot ${SNAPSHOTS} error 194*89e3a2d8SAlberto Garcia 195*89e3a2d8SAlberto Garcia_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot', 196*89e3a2d8SAlberto Garcia 'arguments': { 'node':'virtio0', 197*89e3a2d8SAlberto Garcia 'overlay':'virtio0' } 198*89e3a2d8SAlberto Garcia }" "error" 199*89e3a2d8SAlberto Garcia 200*89e3a2d8SAlberto Garcia_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot', 201*89e3a2d8SAlberto Garcia 'arguments': { 'node':'virtio0', 202*89e3a2d8SAlberto Garcia 'overlay':'virtio1' } 203*89e3a2d8SAlberto Garcia }" "error" 204*89e3a2d8SAlberto Garcia 205*89e3a2d8SAlberto Garciaecho 206*89e3a2d8SAlberto Garciaecho === Invalid command - snapshot node used as backing hd === 207*89e3a2d8SAlberto Garciaecho 208*89e3a2d8SAlberto Garcia 209*89e3a2d8SAlberto Garciablockdev_snapshot $((${SNAPSHOTS}-1)) error 210*89e3a2d8SAlberto Garcia 211*89e3a2d8SAlberto Garciaecho 212*89e3a2d8SAlberto Garciaecho === Invalid command - snapshot node has a backing image === 213*89e3a2d8SAlberto Garciaecho 214*89e3a2d8SAlberto Garcia 215*89e3a2d8SAlberto GarciaSNAPSHOTS=$((${SNAPSHOTS}+1)) 216*89e3a2d8SAlberto Garciaadd_snapshot_image ${SNAPSHOTS} true 217*89e3a2d8SAlberto Garciablockdev_snapshot ${SNAPSHOTS} error 218*89e3a2d8SAlberto Garcia 219*89e3a2d8SAlberto Garciaecho 220*89e3a2d8SAlberto Garciaecho === Invalid command - The node does not exist === 221*89e3a2d8SAlberto Garciaecho 222*89e3a2d8SAlberto Garcia 223*89e3a2d8SAlberto Garciablockdev_snapshot $((${SNAPSHOTS}+1)) error 224*89e3a2d8SAlberto Garcia 225*89e3a2d8SAlberto Garcia_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot', 226*89e3a2d8SAlberto Garcia 'arguments': { 'node':'nodevice', 227*89e3a2d8SAlberto Garcia 'overlay':'snap_"${SNAPSHOTS}"' } 228*89e3a2d8SAlberto Garcia }" "error" 229*89e3a2d8SAlberto Garcia 2304089f7c6SJeff Cody# success, all done 2314089f7c6SJeff Codyecho "*** done" 2324089f7c6SJeff Codyrm -f $seq.full 2334089f7c6SJeff Codystatus=0 234