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