17c477526SPhilippe Mathieu-Daudé#!/usr/bin/env python3 20f62cd82SMax Reitz# 30f62cd82SMax Reitz# Test for when a backing file is considered overridden (thus, a 40f62cd82SMax Reitz# json:{} filename is generated for the overlay) and when it is not 50f62cd82SMax Reitz# 60f62cd82SMax Reitz# Copyright (C) 2018 Red Hat, Inc. 70f62cd82SMax Reitz# 80f62cd82SMax Reitz# This program is free software; you can redistribute it and/or modify 90f62cd82SMax Reitz# it under the terms of the GNU General Public License as published by 100f62cd82SMax Reitz# the Free Software Foundation; either version 2 of the License, or 110f62cd82SMax Reitz# (at your option) any later version. 120f62cd82SMax Reitz# 130f62cd82SMax Reitz# This program is distributed in the hope that it will be useful, 140f62cd82SMax Reitz# but WITHOUT ANY WARRANTY; without even the implied warranty of 150f62cd82SMax Reitz# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 160f62cd82SMax Reitz# GNU General Public License for more details. 170f62cd82SMax Reitz# 180f62cd82SMax Reitz# You should have received a copy of the GNU General Public License 190f62cd82SMax Reitz# along with this program. If not, see <http://www.gnu.org/licenses/>. 200f62cd82SMax Reitz# 210f62cd82SMax Reitz# Creator/Owner: Max Reitz <mreitz@redhat.com> 220f62cd82SMax Reitz 230f62cd82SMax Reitzimport iotests 240f62cd82SMax Reitzfrom iotests import log, qemu_img, filter_testfiles, filter_imgfmt, \ 250f62cd82SMax Reitz filter_qmp_testfiles, filter_qmp_imgfmt 260f62cd82SMax Reitz 270f62cd82SMax Reitz# Need backing file and change-backing-file support 28*7d814059SJohn Snowiotests.script_initialize( 29*7d814059SJohn Snow supported_fmts=['qcow2', 'qed'], 30*7d814059SJohn Snow supported_platforms=['linux'], 31*7d814059SJohn Snow) 320f62cd82SMax Reitz 330f62cd82SMax Reitz 340f62cd82SMax Reitzdef log_node_info(node): 350f62cd82SMax Reitz log('') 360f62cd82SMax Reitz 370f62cd82SMax Reitz log('bs->filename: ' + node['image']['filename'], 380f62cd82SMax Reitz filters=[filter_testfiles, filter_imgfmt]) 390f62cd82SMax Reitz log('bs->backing_file: ' + node['backing_file'], 400f62cd82SMax Reitz filters=[filter_testfiles, filter_imgfmt]) 410f62cd82SMax Reitz 420f62cd82SMax Reitz if 'backing-image' in node['image']: 430f62cd82SMax Reitz log('bs->backing->bs->filename: ' + 440f62cd82SMax Reitz node['image']['backing-image']['filename'], 450f62cd82SMax Reitz filters=[filter_testfiles, filter_imgfmt]) 460f62cd82SMax Reitz else: 470f62cd82SMax Reitz log('bs->backing: (none)') 480f62cd82SMax Reitz 490f62cd82SMax Reitz log('') 500f62cd82SMax Reitz 510f62cd82SMax Reitz 520f62cd82SMax Reitzwith iotests.FilePath('base.img') as base_img_path, \ 530f62cd82SMax Reitz iotests.FilePath('top.img') as top_img_path, \ 540f62cd82SMax Reitz iotests.VM() as vm: 550f62cd82SMax Reitz 560f62cd82SMax Reitz assert qemu_img('create', '-f', iotests.imgfmt, base_img_path, '64M') == 0 570f62cd82SMax Reitz # Choose a funny way to describe the backing filename 580f62cd82SMax Reitz assert qemu_img('create', '-f', iotests.imgfmt, '-b', 590f62cd82SMax Reitz 'file:' + base_img_path, top_img_path) == 0 600f62cd82SMax Reitz 610f62cd82SMax Reitz vm.launch() 620f62cd82SMax Reitz 630f62cd82SMax Reitz log('--- Implicit backing file ---') 640f62cd82SMax Reitz log('') 650f62cd82SMax Reitz 660f62cd82SMax Reitz vm.qmp_log('blockdev-add', 670f62cd82SMax Reitz node_name='node0', 680f62cd82SMax Reitz driver=iotests.imgfmt, 690f62cd82SMax Reitz file={ 700f62cd82SMax Reitz 'driver': 'file', 710f62cd82SMax Reitz 'filename': top_img_path 720f62cd82SMax Reitz }, 730f62cd82SMax Reitz filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) 740f62cd82SMax Reitz 750f62cd82SMax Reitz # Filename should be plain, and the backing filename should not 760f62cd82SMax Reitz # contain the "file:" prefix 770f62cd82SMax Reitz log_node_info(vm.node_info('node0')) 780f62cd82SMax Reitz 790f62cd82SMax Reitz vm.qmp_log('blockdev-del', node_name='node0') 800f62cd82SMax Reitz 810f62cd82SMax Reitz log('') 820f62cd82SMax Reitz log('--- change-backing-file ---') 830f62cd82SMax Reitz log('') 840f62cd82SMax Reitz 850f62cd82SMax Reitz vm.qmp_log('blockdev-add', 860f62cd82SMax Reitz node_name='node0', 870f62cd82SMax Reitz driver=iotests.imgfmt, 880f62cd82SMax Reitz file={ 890f62cd82SMax Reitz 'driver': 'file', 900f62cd82SMax Reitz 'filename': top_img_path 910f62cd82SMax Reitz }, 920f62cd82SMax Reitz filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) 930f62cd82SMax Reitz 940f62cd82SMax Reitz # Changing the backing file to a qemu-reported filename should 950f62cd82SMax Reitz # result in qemu accepting the corresponding BDS as the implicit 960f62cd82SMax Reitz # backing BDS (and thus not generate a json:{} filename). 970f62cd82SMax Reitz # So, first, query the backing filename. 980f62cd82SMax Reitz 990f62cd82SMax Reitz backing_filename = \ 1000f62cd82SMax Reitz vm.node_info('node0')['image']['backing-image']['filename'] 1010f62cd82SMax Reitz 1020f62cd82SMax Reitz # Next, change the backing file to something different 1030f62cd82SMax Reitz 1040f62cd82SMax Reitz vm.qmp_log('change-backing-file', 1050f62cd82SMax Reitz image_node_name='node0', 1060f62cd82SMax Reitz device='node0', 1070f62cd82SMax Reitz backing_file='null-co://', 1080f62cd82SMax Reitz filters=[filter_qmp_testfiles]) 1090f62cd82SMax Reitz 1100f62cd82SMax Reitz # Now, verify that we get a json:{} filename 1110f62cd82SMax Reitz # (Image header says "null-co://", actual backing file still is 1120f62cd82SMax Reitz # base_img_path) 1130f62cd82SMax Reitz 1140f62cd82SMax Reitz log_node_info(vm.node_info('node0')) 1150f62cd82SMax Reitz 1160f62cd82SMax Reitz # Change it back 1170f62cd82SMax Reitz # (To get header and backing file in sync) 1180f62cd82SMax Reitz 1190f62cd82SMax Reitz vm.qmp_log('change-backing-file', 1200f62cd82SMax Reitz image_node_name='node0', 1210f62cd82SMax Reitz device='node0', 1220f62cd82SMax Reitz backing_file=backing_filename, 1230f62cd82SMax Reitz filters=[filter_qmp_testfiles]) 1240f62cd82SMax Reitz 1250f62cd82SMax Reitz # And verify that we get our original results 1260f62cd82SMax Reitz 1270f62cd82SMax Reitz log_node_info(vm.node_info('node0')) 1280f62cd82SMax Reitz 1290f62cd82SMax Reitz # Finally, try a "file:" prefix. While this is actually what we 1300f62cd82SMax Reitz # originally had in the image header, qemu will not reopen the 1310f62cd82SMax Reitz # backing file here, so it cannot verify that this filename 1320f62cd82SMax Reitz # "resolves" to the actual backing BDS's filename and will thus 1330f62cd82SMax Reitz # consider both to be different. 1340f62cd82SMax Reitz # (This may be fixed in the future.) 1350f62cd82SMax Reitz 1360f62cd82SMax Reitz vm.qmp_log('change-backing-file', 1370f62cd82SMax Reitz image_node_name='node0', 1380f62cd82SMax Reitz device='node0', 1390f62cd82SMax Reitz backing_file=('file:' + backing_filename), 1400f62cd82SMax Reitz filters=[filter_qmp_testfiles]) 1410f62cd82SMax Reitz 1420f62cd82SMax Reitz # So now we should get a json:{} filename 1430f62cd82SMax Reitz 1440f62cd82SMax Reitz log_node_info(vm.node_info('node0')) 1450f62cd82SMax Reitz 1460f62cd82SMax Reitz # Remove and re-attach so we can see that (as in our first try), 1470f62cd82SMax Reitz # opening the image anew helps qemu resolve the header backing 1480f62cd82SMax Reitz # filename. 1490f62cd82SMax Reitz 1500f62cd82SMax Reitz vm.qmp_log('blockdev-del', node_name='node0') 1510f62cd82SMax Reitz 1520f62cd82SMax Reitz vm.qmp_log('blockdev-add', 1530f62cd82SMax Reitz node_name='node0', 1540f62cd82SMax Reitz driver=iotests.imgfmt, 1550f62cd82SMax Reitz file={ 1560f62cd82SMax Reitz 'driver': 'file', 1570f62cd82SMax Reitz 'filename': top_img_path 1580f62cd82SMax Reitz }, 1590f62cd82SMax Reitz filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) 1600f62cd82SMax Reitz 1610f62cd82SMax Reitz log_node_info(vm.node_info('node0')) 1620f62cd82SMax Reitz 1630f62cd82SMax Reitz vm.qmp_log('blockdev-del', node_name='node0') 1640f62cd82SMax Reitz 1650f62cd82SMax Reitz log('') 1660f62cd82SMax Reitz log('--- Override backing file ---') 1670f62cd82SMax Reitz log('') 1680f62cd82SMax Reitz 1690f62cd82SMax Reitz # For this test, we need the plain filename in the image header 1700f62cd82SMax Reitz # (because qemu cannot "canonicalize"/"resolve" the backing 1710f62cd82SMax Reitz # filename unless the backing file is opened implicitly with the 1720f62cd82SMax Reitz # overlay) 1730f62cd82SMax Reitz assert qemu_img('create', '-f', iotests.imgfmt, '-b', base_img_path, 1740f62cd82SMax Reitz top_img_path) == 0 1750f62cd82SMax Reitz 1760f62cd82SMax Reitz # You can only reliably override backing options by using a node 1770f62cd82SMax Reitz # reference (or by specifying file.filename, but, well...) 1780f62cd82SMax Reitz vm.qmp_log('blockdev-add', node_name='null', driver='null-co') 1790f62cd82SMax Reitz 1800f62cd82SMax Reitz vm.qmp_log('blockdev-add', 1810f62cd82SMax Reitz node_name='node0', 1820f62cd82SMax Reitz driver=iotests.imgfmt, 1830f62cd82SMax Reitz file={ 1840f62cd82SMax Reitz 'driver': 'file', 1850f62cd82SMax Reitz 'filename': top_img_path 1860f62cd82SMax Reitz }, 1870f62cd82SMax Reitz backing='null', 1880f62cd82SMax Reitz filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) 1890f62cd82SMax Reitz 1900f62cd82SMax Reitz # Should get a json:{} filename (and bs->backing_file is 1910f62cd82SMax Reitz # null-co://, because that field actually has not much to do 1920f62cd82SMax Reitz # with the header backing filename (except that it is changed by 1930f62cd82SMax Reitz # change-backing-file)) 1940f62cd82SMax Reitz 1950f62cd82SMax Reitz log_node_info(vm.node_info('node0')) 1960f62cd82SMax Reitz 1970f62cd82SMax Reitz # Detach the backing file by reopening the whole thing 1980f62cd82SMax Reitz 1990f62cd82SMax Reitz vm.qmp_log('blockdev-del', node_name='node0') 2000f62cd82SMax Reitz vm.qmp_log('blockdev-del', node_name='null') 2010f62cd82SMax Reitz 2020f62cd82SMax Reitz vm.qmp_log('blockdev-add', 2030f62cd82SMax Reitz node_name='node0', 2040f62cd82SMax Reitz driver=iotests.imgfmt, 2050f62cd82SMax Reitz file={ 2060f62cd82SMax Reitz 'driver': 'file', 2070f62cd82SMax Reitz 'filename': top_img_path 2080f62cd82SMax Reitz }, 2090f62cd82SMax Reitz backing=None, 2100f62cd82SMax Reitz filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) 2110f62cd82SMax Reitz 2120f62cd82SMax Reitz # Should get a json:{} filename (because we overrode the backing 2130f62cd82SMax Reitz # file to not be there) 2140f62cd82SMax Reitz 2150f62cd82SMax Reitz log_node_info(vm.node_info('node0')) 2160f62cd82SMax Reitz 2170f62cd82SMax Reitz # Open the original backing file 2180f62cd82SMax Reitz 2190f62cd82SMax Reitz vm.qmp_log('blockdev-add', 2200f62cd82SMax Reitz node_name='original-backing', 2210f62cd82SMax Reitz driver=iotests.imgfmt, 2220f62cd82SMax Reitz file={ 2230f62cd82SMax Reitz 'driver': 'file', 2240f62cd82SMax Reitz 'filename': base_img_path 2250f62cd82SMax Reitz }, 2260f62cd82SMax Reitz filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) 2270f62cd82SMax Reitz 2280f62cd82SMax Reitz # Attach the original backing file to its overlay 2290f62cd82SMax Reitz 2300f62cd82SMax Reitz vm.qmp_log('blockdev-snapshot', 2310f62cd82SMax Reitz node='original-backing', 2320f62cd82SMax Reitz overlay='node0') 2330f62cd82SMax Reitz 2340f62cd82SMax Reitz # This should give us the original plain result 2350f62cd82SMax Reitz 2360f62cd82SMax Reitz log_node_info(vm.node_info('node0')) 2370f62cd82SMax Reitz 2380f62cd82SMax Reitz vm.qmp_log('blockdev-del', node_name='node0') 2390f62cd82SMax Reitz vm.qmp_log('blockdev-del', node_name='original-backing') 2400f62cd82SMax Reitz 2410f62cd82SMax Reitz vm.shutdown() 242