qemu/tests/qemu-iotests/085
<<
>>
Prefs
   1#!/usr/bin/env bash
   2# group: rw
   3#
   4# Live snapshot tests
   5#
   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.
   9#
  10# Copyright (C) 2014 Red Hat, Inc.
  11# Copyright (C) 2015 Igalia, S.L.
  12#
  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.
  17#
  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.
  22#
  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/>.
  25#
  26
  27# creator
  28owner=codyprime@gmail.com
  29
  30seq=`basename $0`
  31echo "QA output created by $seq"
  32
  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    _cleanup_test_img
  44    for i in $(seq 1 ${SNAPSHOTS})
  45    do
  46        _rm_test_img "${TEST_DIR}/${i}-${snapshot_virt0}"
  47        _rm_test_img "${TEST_DIR}/${i}-${snapshot_virt1}"
  48    done
  49    for img in "${TEST_IMG}".{1,2,base}
  50    do
  51        _rm_test_img "$img"
  52    done
  53
  54}
  55trap "_cleanup; exit \$status" 0 1 2 3 15
  56
  57# get standard environment, filters and checks
  58. ./common.rc
  59. ./common.filter
  60. ./common.qemu
  61
  62_supported_fmt qcow2
  63_supported_proto file
  64
  65
  66# ${1}: unique identifier for the snapshot filename
  67create_single_snapshot()
  68{
  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"
  74}
  75
  76# ${1}: unique identifier for the snapshot filename
  77create_group_snapshot()
  78{
  79    cmd="{ 'execute': 'transaction', 'arguments':
  80           {'actions': [
  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}' } } ]
  87             } }"
  88
  89    _send_qemu_cmd $h "${cmd}" "return"
  90}
  91
  92# ${1}: unique identifier for the snapshot filename
  93# ${2}: extra_params to the blockdev-add command
  94# ${3}: filename
  95do_blockdev_add()
  96{
  97    cmd="{ 'execute': 'blockdev-add', 'arguments':
  98           { 'driver': 'qcow2', 'node-name': 'snap_${1}', ${2}
  99             'file':
 100             { 'driver': 'file', 'filename': '${3}',
 101               'node-name': 'file_${1}' } } }"
 102    _send_qemu_cmd $h "${cmd}" "return"
 103}
 104
 105# ${1}: unique identifier for the snapshot filename
 106create_snapshot_image()
 107{
 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"
 111}
 112
 113# ${1}: unique identifier for the snapshot filename
 114add_snapshot_image()
 115{
 116    snapshot_file="${TEST_DIR}/${1}-${snapshot_virt0}"
 117    create_snapshot_image "$1"
 118    do_blockdev_add "$1" "'backing': null, " "${snapshot_file}"
 119}
 120
 121# ${1}: unique identifier for the snapshot filename
 122# ${2}: expected response, defaults to 'return'
 123blockdev_snapshot()
 124{
 125    cmd="{ 'execute': 'blockdev-snapshot',
 126                      'arguments': { 'node': 'virtio0',
 127                                     'overlay':'snap_${1}' } }"
 128    _send_qemu_cmd $h "${cmd}" "${2:-return}"
 129}
 130
 131size=128M
 132
 133TEST_IMG="$TEST_IMG.1" _make_test_img $size
 134TEST_IMG="$TEST_IMG.2" _make_test_img $size
 135
 136echo
 137echo === Running QEMU ===
 138echo
 139
 140qemu_comm_method="qmp"
 141_launch_qemu -drive file="${TEST_IMG}.1",if=virtio -drive file="${TEST_IMG}.2",if=virtio
 142h=$QEMU_HANDLE
 143
 144echo
 145echo === Sending capabilities ===
 146echo
 147
 148_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" "return"
 149
 150# Tests for the blockdev-snapshot-sync command
 151
 152echo
 153echo === Create a single snapshot on virtio0 ===
 154echo
 155
 156create_single_snapshot 1
 157
 158
 159echo
 160echo === Invalid command - missing device and nodename ===
 161echo
 162
 163_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync',
 164                         'arguments': { 'snapshot-file':'${TEST_DIR}/1-${snapshot_virt0}',
 165                                     'format': 'qcow2' } }" "error"
 166
 167echo
 168echo === Invalid command - missing snapshot-file ===
 169echo
 170
 171_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync',
 172                         'arguments': { 'device': 'virtio0',
 173                                     'format': 'qcow2' } }" "error"
 174echo
 175echo
 176echo === Create several transactional group snapshots ===
 177echo
 178
 179for i in $(seq 2 ${SNAPSHOTS})
 180do
 181    create_group_snapshot ${i}
 182done
 183
 184# Tests for the blockdev-snapshot command
 185
 186echo
 187echo === Create a couple of snapshots using blockdev-snapshot ===
 188echo
 189
 190SNAPSHOTS=$((${SNAPSHOTS}+1))
 191add_snapshot_image ${SNAPSHOTS}
 192blockdev_snapshot ${SNAPSHOTS}
 193
 194SNAPSHOTS=$((${SNAPSHOTS}+1))
 195add_snapshot_image ${SNAPSHOTS}
 196blockdev_snapshot ${SNAPSHOTS}
 197
 198echo
 199echo === Invalid command - cannot create a snapshot using a file BDS ===
 200echo
 201
 202_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot',
 203                     'arguments': { 'node':'virtio0',
 204                                    'overlay':'file_${SNAPSHOTS}' }
 205                   }" "error"
 206
 207echo
 208echo === Invalid command - snapshot node used as active layer ===
 209echo
 210
 211blockdev_snapshot ${SNAPSHOTS} error
 212
 213_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot',
 214                     'arguments': { 'node':'virtio0',
 215                                    'overlay':'virtio0' }
 216                   }" "error"
 217
 218_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot',
 219                     'arguments': { 'node':'virtio0',
 220                                    'overlay':'virtio1' }
 221                   }" "error"
 222
 223echo
 224echo === Invalid command - snapshot node used as backing hd ===
 225echo
 226
 227blockdev_snapshot $((${SNAPSHOTS}-1)) error
 228
 229echo
 230echo === Invalid command - snapshot node has a backing image ===
 231echo
 232
 233SNAPSHOTS=$((${SNAPSHOTS}+1))
 234
 235TEST_IMG="$TEST_IMG.base" _make_test_img "$size"
 236_make_test_img -b "${TEST_IMG}.base" -F $IMGFMT "$size"
 237do_blockdev_add ${SNAPSHOTS} "" "${TEST_IMG}"
 238blockdev_snapshot ${SNAPSHOTS} error
 239
 240echo
 241echo === Invalid command - creating loops ===
 242echo
 243
 244SNAPSHOTS=$((${SNAPSHOTS}+1))
 245add_snapshot_image ${SNAPSHOTS}
 246
 247_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot',
 248                     'arguments': { 'node':'snap_${SNAPSHOTS}',
 249                                    'overlay':'snap_${SNAPSHOTS}' }
 250                   }" "error"
 251
 252SNAPSHOTS=$((${SNAPSHOTS}+1))
 253create_snapshot_image ${SNAPSHOTS}
 254do_blockdev_add ${SNAPSHOTS} "'backing': 'snap_$((${SNAPSHOTS}-1))', " \
 255    "${TEST_DIR}/${SNAPSHOTS}-${snapshot_virt0}"
 256
 257_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot',
 258                     'arguments': { 'node':'snap_${SNAPSHOTS}',
 259                                    'overlay':'snap_$((${SNAPSHOTS}-1))' }
 260                   }" "error"
 261
 262echo
 263echo === Invalid command - The node does not exist ===
 264echo
 265
 266blockdev_snapshot $((${SNAPSHOTS}+1)) error
 267
 268_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot',
 269                     'arguments': { 'node':'nodevice',
 270                                    'overlay':'snap_${SNAPSHOTS}' }
 271                   }" "error"
 272
 273# success, all done
 274echo "*** done"
 275rm -f $seq.full
 276status=0
 277