xref: /openbmc/qemu/tests/qemu-iotests/237 (revision 520e210c)
1#!/usr/bin/env python
2#
3# Test vmdk and file image creation
4#
5# Copyright (C) 2018 Red Hat, Inc.
6#
7# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; either version 2 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program.  If not, see <http://www.gnu.org/licenses/>.
21#
22
23import math
24import iotests
25from iotests import imgfmt
26
27iotests.verify_image_format(supported_fmts=['vmdk'])
28
29def blockdev_create(vm, options):
30    result = vm.qmp_log('blockdev-create', job_id='job0', options=options)
31
32    if 'return' in result:
33        assert result['return'] == {}
34        vm.run_job('job0')
35    iotests.log("")
36
37with iotests.FilePath('t.vmdk') as disk_path, \
38     iotests.FilePath('t.vmdk.1') as extent1_path, \
39     iotests.FilePath('t.vmdk.2') as extent2_path, \
40     iotests.FilePath('t.vmdk.3') as extent3_path, \
41     iotests.VM() as vm:
42
43    #
44    # Successful image creation (defaults)
45    #
46    iotests.log("=== Successful image creation (defaults) ===")
47    iotests.log("")
48
49    size = 5 * 1024 * 1024 * 1024
50
51    vm.launch()
52    blockdev_create(vm, { 'driver': 'file',
53                          'filename': disk_path,
54                          'size': 0 })
55
56    vm.qmp_log('blockdev-add', driver='file', filename=disk_path,
57               node_name='imgfile')
58
59    blockdev_create(vm, { 'driver': imgfmt,
60                          'file': 'imgfile',
61                          'size': size })
62    vm.shutdown()
63
64    iotests.img_info_log(disk_path)
65
66    #
67    # Successful image creation (inline blockdev-add, explicit defaults)
68    #
69    iotests.log("=== Successful image creation (inline blockdev-add, explicit defaults) ===")
70    iotests.log("")
71
72    # Choose a different size to show that we got a new image
73    size = 64 * 1024 * 1024
74
75    vm.launch()
76    blockdev_create(vm, { 'driver': 'file',
77                          'filename': disk_path,
78                          'size': 0 })
79
80    blockdev_create(vm, { 'driver': imgfmt,
81                          'file': {
82                              'driver': 'file',
83                              'filename': disk_path,
84                          },
85                          'size': size,
86                          'extents': [],
87                          'subformat': 'monolithicSparse',
88                          'adapter-type': 'ide',
89                          'hwversion': '4',
90                          'zeroed-grain': False })
91    vm.shutdown()
92
93    iotests.img_info_log(disk_path)
94
95    #
96    # Successful image creation (non-default options)
97    #
98    iotests.log("=== Successful image creation (with non-default options) ===")
99    iotests.log("")
100
101    # Choose a different size to show that we got a new image
102    size = 32 * 1024 * 1024
103
104    vm.launch()
105    blockdev_create(vm, { 'driver': 'file',
106                          'filename': disk_path,
107                          'size': 0 })
108
109    blockdev_create(vm, { 'driver': imgfmt,
110                          'file': {
111                              'driver': 'file',
112                              'filename': disk_path,
113                          },
114                          'size': size,
115                          'extents': [],
116                          'subformat': 'monolithicSparse',
117                          'adapter-type': 'buslogic',
118                          'zeroed-grain': True })
119    vm.shutdown()
120
121    iotests.img_info_log(disk_path)
122
123    #
124    # Invalid BlockdevRef
125    #
126    iotests.log("=== Invalid BlockdevRef ===")
127    iotests.log("")
128
129    vm.launch()
130    blockdev_create(vm, { 'driver': imgfmt,
131                          'file': "this doesn't exist",
132                          'size': size })
133    vm.shutdown()
134
135    #
136    # Adapter types
137    #
138
139    iotests.log("=== Adapter types ===")
140    iotests.log("")
141
142    vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path))
143
144    # Valid
145    iotests.log("== Valid adapter types ==")
146    iotests.log("")
147
148    vm.launch()
149    for adapter_type in [ 'ide', 'buslogic', 'lsilogic', 'legacyESX' ]:
150        blockdev_create(vm, { 'driver': imgfmt,
151                              'file': 'node0',
152                              'size': size,
153                              'adapter-type': adapter_type })
154    vm.shutdown()
155
156    # Invalid
157    iotests.log("== Invalid adapter types ==")
158    iotests.log("")
159
160    vm.launch()
161    for adapter_type in [ 'foo', 'IDE', 'legacyesx', 1 ]:
162        blockdev_create(vm, { 'driver': imgfmt,
163                              'file': 'node0',
164                              'size': size,
165                              'adapter-type': adapter_type })
166    vm.shutdown()
167
168    #
169    # Other subformats
170    #
171    iotests.log("=== Other subformats ===")
172    iotests.log("")
173
174    for path in [ extent1_path, extent2_path, extent3_path ]:
175        msg = iotests.qemu_img_pipe('create', '-f', imgfmt, path, '0')
176        iotests.log(msg, [iotests.filter_testfiles])
177
178    vm.add_blockdev('driver=file,filename=%s,node-name=ext1' % (extent1_path))
179    vm.add_blockdev('driver=file,filename=%s,node-name=ext2' % (extent2_path))
180    vm.add_blockdev('driver=file,filename=%s,node-name=ext3' % (extent3_path))
181
182    # Missing extent
183    iotests.log("== Missing extent ==")
184    iotests.log("")
185
186    vm.launch()
187    blockdev_create(vm, { 'driver': imgfmt,
188                          'file': 'node0',
189                          'size': size,
190                          'subformat': 'monolithicFlat' })
191    vm.shutdown()
192
193    # Correct extent
194    iotests.log("== Correct extent ==")
195    iotests.log("")
196
197    vm.launch()
198    blockdev_create(vm, { 'driver': imgfmt,
199                          'file': 'node0',
200                          'size': size,
201                          'subformat': 'monolithicFlat',
202                          'extents': ['ext1'] })
203    vm.shutdown()
204
205    # Extra extent
206    iotests.log("== Extra extent ==")
207    iotests.log("")
208
209    vm.launch()
210    blockdev_create(vm, { 'driver': imgfmt,
211                          'file': 'node0',
212                          'size': 512,
213                          'subformat': 'monolithicFlat',
214                          'extents': ['ext1', 'ext2', 'ext3'] })
215    vm.shutdown()
216
217    # Split formats
218    iotests.log("== Split formats ==")
219    iotests.log("")
220
221    for size in [ 512, 1073741824, 2147483648, 5368709120 ]:
222        for subfmt in [ 'twoGbMaxExtentFlat', 'twoGbMaxExtentSparse' ]:
223            iotests.log("= %s %d =" % (subfmt, size))
224            iotests.log("")
225
226            num_extents = math.ceil(size / 2.0**31)
227            extents = [ "ext%d" % (i) for i in range(1, num_extents + 1) ]
228
229            vm.launch()
230            blockdev_create(vm, { 'driver': imgfmt,
231                                  'file': 'node0',
232                                  'size': size,
233                                  'subformat': subfmt,
234                                  'extents': extents })
235            vm.shutdown()
236
237            iotests.img_info_log(disk_path)
238