1#!/usr/bin/env bash 2# 3# Tests oVirt-like storage migration: 4# - Create snapshot 5# - Create target image with (not yet existing) target backing chain 6# (i.e. just write the name of a soon-to-be-copied-over backing file into it) 7# - drive-mirror the snapshot to the target with mode=existing and sync=top 8# - In the meantime, copy the original source files to the destination via 9# conventional means (i.e. outside of qemu) 10# - Complete the drive-mirror job 11# - Delete all source images 12# 13# Copyright (C) 2016 Red Hat, Inc. 14# 15# This program is free software; you can redistribute it and/or modify 16# it under the terms of the GNU General Public License as published by 17# the Free Software Foundation; either version 2 of the License, or 18# (at your option) any later version. 19# 20# This program is distributed in the hope that it will be useful, 21# but WITHOUT ANY WARRANTY; without even the implied warranty of 22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23# GNU General Public License for more details. 24# 25# You should have received a copy of the GNU General Public License 26# along with this program. If not, see <http://www.gnu.org/licenses/>. 27# 28 29# creator 30owner=mreitz@redhat.com 31 32seq="$(basename $0)" 33echo "QA output created by $seq" 34 35status=1 # failure is the default! 36 37_cleanup() 38{ 39 _cleanup_qemu 40 for img in "$TEST_IMG"{,.target}{,.backing,.overlay}; do 41 _rm_test_img "$img" 42 done 43} 44trap "_cleanup; exit \$status" 0 1 2 3 15 45 46# get standard environment, filters and checks 47. ./common.rc 48. ./common.filter 49. ./common.qemu 50 51_supported_fmt qcow2 qed 52_supported_proto generic 53# Copying files around with cp does not work with external data files 54_unsupported_imgopts data_file 55 56# Create source disk 57TEST_IMG="$TEST_IMG.backing" _make_test_img 1M 58_make_test_img -b "$TEST_IMG.backing" -F $IMGFMT 1M 59 60$QEMU_IO -c 'write -P 1 0 256k' "$TEST_IMG.backing" | _filter_qemu_io 61$QEMU_IO -c 'write -P 2 64k 192k' "$TEST_IMG" | _filter_qemu_io 62 63_launch_qemu -drive if=none,id=source,file="$TEST_IMG" 64 65_send_qemu_cmd $QEMU_HANDLE \ 66 "{ 'execute': 'qmp_capabilities' }" \ 67 'return' 68 69# Create snapshot 70TEST_IMG="$TEST_IMG.overlay" _make_test_img -u -b "$TEST_IMG" -F $IMGFMT 1M 71_send_qemu_cmd $QEMU_HANDLE \ 72 "{ 'execute': 'blockdev-snapshot-sync', 73 'arguments': { 'device': 'source', 74 'snapshot-file': '$TEST_IMG.overlay', 75 'format': '$IMGFMT', 76 'mode': 'existing' } }" \ 77 'return' 78 79# Write something to the snapshot 80_send_qemu_cmd $QEMU_HANDLE \ 81 "{ 'execute': 'human-monitor-command', 82 'arguments': { 'command-line': 83 'qemu-io source \"write -P 3 128k 128k\"' } }" \ 84 'return' 85 86# Create target image 87TEST_IMG="$TEST_IMG.target.overlay" _make_test_img -u -b "$TEST_IMG.target" \ 88 -F $IMGFMT 1M 89 90# Mirror snapshot 91_send_qemu_cmd $QEMU_HANDLE \ 92 "{ 'execute': 'drive-mirror', 93 'arguments': { 'device': 'source', 94 'target': '$TEST_IMG.target.overlay', 95 'mode': 'existing', 96 'sync': 'top' } }" \ 97 'return' 98 99# Wait for convergence 100_send_qemu_cmd $QEMU_HANDLE \ 101 '' \ 102 'BLOCK_JOB_READY' 103 104# Write some more 105_send_qemu_cmd $QEMU_HANDLE \ 106 "{ 'execute': 'human-monitor-command', 107 'arguments': { 'command-line': 108 'qemu-io source \"write -P 4 192k 64k\"' } }" \ 109 'return' 110 111# Copy source backing chain to the target before completing the job 112cp "$TEST_IMG.backing" "$TEST_IMG.target.backing" 113cp "$TEST_IMG" "$TEST_IMG.target" 114$QEMU_IMG rebase -u -b "$TEST_IMG.target.backing" -F $IMGFMT "$TEST_IMG.target" 115 116# Complete block job 117_send_qemu_cmd $QEMU_HANDLE \ 118 "{ 'execute': 'block-job-complete', 119 'arguments': { 'device': 'source' } }" \ 120 '' 121 122_send_qemu_cmd $QEMU_HANDLE \ 123 '' \ 124 '"status": "null"' 125 126# Remove the source images 127for img in "$TEST_IMG{,.backing,.overlay}"; do 128 _rm_test_img "$img" 129done 130 131echo 132 133# Check online disk contents 134_send_qemu_cmd $QEMU_HANDLE \ 135 "{ 'execute': 'human-monitor-command', 136 'arguments': { 'command-line': 137 'qemu-io source \"read -P 1 0k 64k\"' } }" \ 138 'return' 139 140_send_qemu_cmd $QEMU_HANDLE \ 141 "{ 'execute': 'human-monitor-command', 142 'arguments': { 'command-line': 143 'qemu-io source \"read -P 2 64k 64k\"' } }" \ 144 'return' 145 146_send_qemu_cmd $QEMU_HANDLE \ 147 "{ 'execute': 'human-monitor-command', 148 'arguments': { 'command-line': 149 'qemu-io source \"read -P 3 128k 64k\"' } }" \ 150 'return' 151 152_send_qemu_cmd $QEMU_HANDLE \ 153 "{ 'execute': 'human-monitor-command', 154 'arguments': { 'command-line': 155 'qemu-io source \"read -P 4 192k 64k\"' } }" \ 156 'return' 157 158echo 159 160_send_qemu_cmd $QEMU_HANDLE \ 161 "{ 'execute': 'quit' }" \ 162 'return' 163 164wait=1 _cleanup_qemu 165 166echo 167 168# Check offline disk contents 169$QEMU_IO -c 'read -P 1 0k 64k' \ 170 -c 'read -P 2 64k 64k' \ 171 -c 'read -P 3 128k 64k' \ 172 -c 'read -P 4 192k 64k' \ 173 "$TEST_IMG.target.overlay" | _filter_qemu_io 174 175echo 176 177# success, all done 178echo '*** done' 179rm -f $seq.full 180status=0 181