085 (7696B)
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 28 owner=codyprime@gmail.com 29 30 seq=`basename $0` 31 echo "QA output created by $seq" 32 33 status=1 # failure is the default! 34 35 snapshot_virt0="snapshot-v0.qcow2" 36 snapshot_virt1="snapshot-v1.qcow2" 37 38 SNAPSHOTS=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 } 55 trap "_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 67 create_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 77 create_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 95 do_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 106 create_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 114 add_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' 123 blockdev_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 131 size=128M 132 133 TEST_IMG="$TEST_IMG.1" _make_test_img $size 134 TEST_IMG="$TEST_IMG.2" _make_test_img $size 135 136 echo 137 echo === Running QEMU === 138 echo 139 140 qemu_comm_method="qmp" 141 _launch_qemu -drive file="${TEST_IMG}.1",if=virtio -drive file="${TEST_IMG}.2",if=virtio 142 h=$QEMU_HANDLE 143 144 echo 145 echo === Sending capabilities === 146 echo 147 148 _send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" "return" 149 150 # Tests for the blockdev-snapshot-sync command 151 152 echo 153 echo === Create a single snapshot on virtio0 === 154 echo 155 156 create_single_snapshot 1 157 158 159 echo 160 echo === Invalid command - missing device and nodename === 161 echo 162 163 _send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync', 164 'arguments': { 'snapshot-file':'${TEST_DIR}/1-${snapshot_virt0}', 165 'format': 'qcow2' } }" "error" 166 167 echo 168 echo === Invalid command - missing snapshot-file === 169 echo 170 171 _send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync', 172 'arguments': { 'device': 'virtio0', 173 'format': 'qcow2' } }" "error" 174 echo 175 echo 176 echo === Create several transactional group snapshots === 177 echo 178 179 for i in $(seq 2 ${SNAPSHOTS}) 180 do 181 create_group_snapshot ${i} 182 done 183 184 # Tests for the blockdev-snapshot command 185 186 echo 187 echo === Create a couple of snapshots using blockdev-snapshot === 188 echo 189 190 SNAPSHOTS=$((${SNAPSHOTS}+1)) 191 add_snapshot_image ${SNAPSHOTS} 192 blockdev_snapshot ${SNAPSHOTS} 193 194 SNAPSHOTS=$((${SNAPSHOTS}+1)) 195 add_snapshot_image ${SNAPSHOTS} 196 blockdev_snapshot ${SNAPSHOTS} 197 198 echo 199 echo === Invalid command - cannot create a snapshot using a file BDS === 200 echo 201 202 _send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot', 203 'arguments': { 'node':'virtio0', 204 'overlay':'file_${SNAPSHOTS}' } 205 }" "error" 206 207 echo 208 echo === Invalid command - snapshot node used as active layer === 209 echo 210 211 blockdev_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 223 echo 224 echo === Invalid command - snapshot node used as backing hd === 225 echo 226 227 blockdev_snapshot $((${SNAPSHOTS}-1)) error 228 229 echo 230 echo === Invalid command - snapshot node has a backing image === 231 echo 232 233 SNAPSHOTS=$((${SNAPSHOTS}+1)) 234 235 TEST_IMG="$TEST_IMG.base" _make_test_img "$size" 236 _make_test_img -b "${TEST_IMG}.base" -F $IMGFMT "$size" 237 do_blockdev_add ${SNAPSHOTS} "" "${TEST_IMG}" 238 blockdev_snapshot ${SNAPSHOTS} error 239 240 echo 241 echo === Invalid command - creating loops === 242 echo 243 244 SNAPSHOTS=$((${SNAPSHOTS}+1)) 245 add_snapshot_image ${SNAPSHOTS} 246 247 _send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot', 248 'arguments': { 'node':'snap_${SNAPSHOTS}', 249 'overlay':'snap_${SNAPSHOTS}' } 250 }" "error" 251 252 SNAPSHOTS=$((${SNAPSHOTS}+1)) 253 create_snapshot_image ${SNAPSHOTS} 254 do_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 262 echo 263 echo === Invalid command - The node does not exist === 264 echo 265 266 blockdev_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 274 echo "*** done" 275 rm -f $seq.full 276 status=0