]> git.proxmox.com Git - mirror_qemu.git/blob - tests/qemu-iotests/tests/image-fleecing
tcg/s390x: Implement TCG_TARGET_HAS_cmpsel_vec
[mirror_qemu.git] / tests / qemu-iotests / tests / image-fleecing
1 #!/usr/bin/env python3
2 # group: rw quick
3 #
4 # This test covers the basic fleecing workflow, which provides a
5 # point-in-time snapshot of a node that can be queried over NBD.
6 #
7 # Copyright (C) 2018 Red Hat, Inc.
8 # John helped, too.
9 #
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
14 #
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
19 #
20 # You should have received a copy of the GNU General Public License
21 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #
23 # Creator/Owner: John Snow <jsnow@redhat.com>
24
25 import iotests
26 from iotests import log, qemu_img, qemu_io, qemu_io_silent
27
28 iotests.script_initialize(
29 supported_fmts=['qcow2', 'qcow', 'qed', 'vmdk', 'vhdx', 'raw'],
30 supported_platforms=['linux'],
31 )
32
33 patterns = [('0x5d', '0', '64k'),
34 ('0xd5', '1M', '64k'),
35 ('0xdc', '32M', '64k'),
36 ('0xcd', '0x3ff0000', '64k')] # 64M - 64K
37
38 overwrite = [('0xab', '0', '64k'), # Full overwrite
39 ('0xad', '0x00f8000', '64k'), # Partial-left (1M-32K)
40 ('0x1d', '0x2008000', '64k'), # Partial-right (32M+32K)
41 ('0xea', '0x3fe0000', '64k')] # Adjacent-left (64M - 128K)
42
43 zeroes = [('0', '0x00f8000', '32k'), # Left-end of partial-left (1M-32K)
44 ('0', '0x2010000', '32k'), # Right-end of partial-right (32M+64K)
45 ('0', '0x3fe0000', '64k')] # overwrite[3]
46
47 remainder = [('0xd5', '0x108000', '32k'), # Right-end of partial-left [1]
48 ('0xdc', '32M', '32k'), # Left-end of partial-right [2]
49 ('0xcd', '0x3ff0000', '64k')] # patterns[3]
50
51 def do_test(use_cbw, base_img_path, fleece_img_path, nbd_sock_path, vm):
52 log('--- Setting up images ---')
53 log('')
54
55 assert qemu_img('create', '-f', iotests.imgfmt, base_img_path, '64M') == 0
56 assert qemu_img('create', '-f', 'qcow2', fleece_img_path, '64M') == 0
57
58 for p in patterns:
59 qemu_io('-f', iotests.imgfmt,
60 '-c', 'write -P%s %s %s' % p, base_img_path)
61
62 log('Done')
63
64 log('')
65 log('--- Launching VM ---')
66 log('')
67
68 src_node = 'source'
69 tmp_node = 'temp'
70 qom_path = '/machine/peripheral/sda'
71 vm.add_blockdev(f'driver={iotests.imgfmt},file.driver=file,'
72 f'file.filename={base_img_path},node-name={src_node}')
73 vm.add_device('virtio-scsi')
74 vm.add_device(f'scsi-hd,id=sda,drive={src_node}')
75 vm.launch()
76 log('Done')
77
78 log('')
79 log('--- Setting up Fleecing Graph ---')
80 log('')
81
82
83 # create tmp_node backed by src_node
84 log(vm.qmp('blockdev-add', {
85 'driver': 'qcow2',
86 'node-name': tmp_node,
87 'file': {
88 'driver': 'file',
89 'filename': fleece_img_path,
90 },
91 'backing': src_node,
92 }))
93
94 # Establish CBW from source to fleecing node
95 if use_cbw:
96 log(vm.qmp('blockdev-add', {
97 'driver': 'copy-before-write',
98 'node-name': 'fl-cbw',
99 'file': src_node,
100 'target': tmp_node
101 }))
102
103 log(vm.qmp('qom-set', path=qom_path, property='drive', value='fl-cbw'))
104 else:
105 log(vm.qmp('blockdev-backup',
106 job_id='fleecing',
107 device=src_node,
108 target=tmp_node,
109 sync='none'))
110
111 log('')
112 log('--- Setting up NBD Export ---')
113 log('')
114
115 nbd_uri = 'nbd+unix:///%s?socket=%s' % (tmp_node, nbd_sock_path)
116 log(vm.qmp('nbd-server-start',
117 {'addr': { 'type': 'unix',
118 'data': { 'path': nbd_sock_path } } }))
119
120 log(vm.qmp('nbd-server-add', device=tmp_node))
121
122 log('')
123 log('--- Sanity Check ---')
124 log('')
125
126 for p in patterns + zeroes:
127 cmd = 'read -P%s %s %s' % p
128 log(cmd)
129 assert qemu_io_silent('-r', '-f', 'raw', '-c', cmd, nbd_uri) == 0
130
131 log('')
132 log('--- Testing COW ---')
133 log('')
134
135 for p in overwrite:
136 cmd = 'write -P%s %s %s' % p
137 log(cmd)
138 log(vm.hmp_qemu_io(qom_path, cmd, qdev=True))
139
140 log('')
141 log('--- Verifying Data ---')
142 log('')
143
144 for p in patterns + zeroes:
145 cmd = 'read -P%s %s %s' % p
146 log(cmd)
147 assert qemu_io_silent('-r', '-f', 'raw', '-c', cmd, nbd_uri) == 0
148
149 log('')
150 log('--- Cleanup ---')
151 log('')
152
153 if use_cbw:
154 log(vm.qmp('qom-set', path=qom_path, property='drive', value=src_node))
155 log(vm.qmp('blockdev-del', node_name='fl-cbw'))
156 else:
157 log(vm.qmp('block-job-cancel', device='fleecing'))
158 e = vm.event_wait('BLOCK_JOB_CANCELLED')
159 assert e is not None
160 log(e, filters=[iotests.filter_qmp_event])
161
162 log(vm.qmp('nbd-server-stop'))
163 log(vm.qmp('blockdev-del', node_name=tmp_node))
164 vm.shutdown()
165
166 log('')
167 log('--- Confirming writes ---')
168 log('')
169
170 for p in overwrite + remainder:
171 cmd = 'read -P%s %s %s' % p
172 log(cmd)
173 assert qemu_io_silent(base_img_path, '-c', cmd) == 0
174
175 log('')
176 log('Done')
177
178
179 def test(use_cbw):
180 with iotests.FilePath('base.img') as base_img_path, \
181 iotests.FilePath('fleece.img') as fleece_img_path, \
182 iotests.FilePath('nbd.sock',
183 base_dir=iotests.sock_dir) as nbd_sock_path, \
184 iotests.VM() as vm:
185 do_test(use_cbw, base_img_path, fleece_img_path, nbd_sock_path, vm)
186
187
188 log('=== Test backup(sync=none) based fleecing ===\n')
189 test(False)
190
191 log('=== Test filter based fleecing ===\n')
192 test(True)