4 # Copyright (C) 2021 Red Hat, Inc.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 from subprocess import CalledProcessError
24 from iotests import imgfmt, qemu_img_create, qemu_io
27 test_img = os.path.join(iotests.test_dir, 'test.img')
28 mig_sock = os.path.join(iotests.sock_dir, 'mig.sock')
31 class TestMigrationPermissions(iotests.QMPTestCase):
33 qemu_img_create('-f', imgfmt, test_img, '1M')
35 # Set up two VMs (source and destination) accessing the same raw
36 # image file with a virtio-blk device; prepare the destination for
37 # migration with .add_incoming() and enable migration events
40 vms[i] = iotests.VM(path_suffix=f'{i}')
41 vms[i].add_blockdev(f'file,node-name=prot,filename={test_img}')
42 vms[i].add_blockdev(f'{imgfmt},node-name=fmt,file=prot')
43 vms[i].add_device('virtio-blk,drive=fmt')
46 vms[i].add_incoming(f'unix:{mig_sock}')
50 vms[i].cmd('migrate-set-capabilities',
52 {'capability': 'events', 'state': True}
63 except FileNotFoundError:
67 # Migrate an image in use by a virtio-blk device to another VM and
68 # verify that the WRITE permission is unshared both before and after
70 def test_post_migration_permissions(self):
71 # Try to access the image R/W, which should fail because virtio-blk
72 # has not been configured with share-rw=on
73 emsg = ('ERROR (pre-migration): qemu-io should not be able to '
74 'access this image, but it reported no error')
75 with self.assertRaises(CalledProcessError, msg=emsg) as ctx:
76 qemu_io('-f', imgfmt, '-c', 'quit', test_img)
77 if 'Is another process using the image' not in ctx.exception.stdout:
81 self.vm_s.qmp('migrate', uri=f'unix:{mig_sock}')
82 assert self.vm_s.wait_migration(None)
83 assert self.vm_d.wait_migration(None)
85 # Try the same qemu-io access again, verifying that the WRITE
86 # permission remains unshared
87 emsg = ('ERROR (post-migration): qemu-io should not be able to '
88 'access this image, but it reported no error')
89 with self.assertRaises(CalledProcessError, msg=emsg) as ctx:
90 qemu_io('-f', imgfmt, '-c', 'quit', test_img)
91 if 'Is another process using the image' not in ctx.exception.stdout:
95 if __name__ == '__main__':
96 # Only works with raw images because we are testing the
97 # BlockBackend permissions; image format drivers may additionally
98 # unshare permissions and thus tamper with the result
99 iotests.main(supported_fmts=['raw'],
100 supported_protocols=['file'])