1
Merge remote-tracking branch 'remotes/edgar/tags/edgar/xilinx-next-2018-05-29-v1.for-upstream' into staging (2018-05-29 13:01:11 +0100)
1
The following changes since commit 16aaacb307ed607b9780c12702c44f0fe52edc7e:
2
2
3
are available in the git repository at:
3
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20200430' into staging (2020-04-30 14:00:36 +0100)
4
5
are available in the Git repository at:
4
6
5
git://repo.or.cz/qemu/kevin.git tags/for-upstream
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
6
8
7
for you to fetch changes up to 3fb588a0f2c006122c34e1960a15c87ae2b927eb:
9
for you to fetch changes up to eaae29ef89d498d0eac553c77b554f310a47f809:
8
10
9
block/create: Mark blockdev-create stable (2018-05-30 13:31:18 +0200)
11
qemu-storage-daemon: Fix non-string --object properties (2020-04-30 17:51:07 +0200)
10
12
11
----------------------------------------------------------------
13
----------------------------------------------------------------
12
Block layer patches:
14
Block layer patches:
13
15
14
- Add blockdev-create job
16
- Fix resize (extending) of short overlays
15
- qcow2: Silence Coverity false positive
17
- nvme: introduce PMR support from NVMe 1.4 spec
18
- qemu-storage-daemon: Fix non-string --object properties
16
19
17
----------------------------------------------------------------
20
----------------------------------------------------------------
18
Alberto Garcia (1):
21
Alberto Garcia (1):
19
qcow2: Fix Coverity warning when calculating the refcount cache size
22
qcow2: Add incompatibility note between backing files and raw external data files
20
23
21
Kevin Wolf (16):
24
Andrzej Jakowski (1):
22
vdi: Fix vdi_co_do_create() return value
25
nvme: introduce PMR support from NVMe 1.4 spec
23
vhdx: Fix vhdx_co_create() return value
24
job: Add error message for failing jobs
25
block/create: Make x-blockdev-create a job
26
qemu-iotests: Add VM.get_qmp_events_filtered()
27
qemu-iotests: Add VM.qmp_log()
28
qemu-iotests: Add iotests.img_info_log()
29
qemu-iotests: Add VM.run_job()
30
qemu-iotests: iotests.py helper for non-file protocols
31
qemu-iotests: Rewrite 206 for blockdev-create job
32
qemu-iotests: Rewrite 207 for blockdev-create job
33
qemu-iotests: Rewrite 210 for blockdev-create job
34
qemu-iotests: Rewrite 211 for blockdev-create job
35
qemu-iotests: Rewrite 212 for blockdev-create job
36
qemu-iotests: Rewrite 213 for blockdev-create job
37
block/create: Mark blockdev-create stable
38
26
39
qapi/block-core.json | 18 +-
27
Kevin Wolf (12):
40
qapi/job.json | 4 +-
28
block: Add flags to BlockDriver.bdrv_co_truncate()
41
include/qemu/job.h | 7 +-
29
block: Add flags to bdrv(_co)_truncate()
42
block/backup.c | 2 +-
30
block-backend: Add flags to blk_truncate()
43
block/commit.c | 2 +-
31
qcow2: Support BDRV_REQ_ZERO_WRITE for truncate
44
block/create.c | 67 +++--
32
raw-format: Support BDRV_REQ_ZERO_WRITE for truncate
45
block/mirror.c | 2 +-
33
file-posix: Support BDRV_REQ_ZERO_WRITE for truncate
46
block/qcow2.c | 5 +-
34
block: truncate: Don't make backing file data visible
47
block/stream.c | 2 +-
35
iotests: Filter testfiles out in filter_img_info()
48
block/vdi.c | 1 +
36
iotests: Test committing to short backing file
49
block/vhdx.c | 2 +-
37
qcow2: Forward ZERO_WRITE flag for full preallocation
50
job-qmp.c | 9 +-
38
qom: Factor out user_creatable_add_dict()
51
job.c | 16 +-
39
qemu-storage-daemon: Fix non-string --object properties
52
tests/test-bdrv-drain.c | 2 +-
53
tests/test-blockjob-txn.c | 2 +-
54
tests/test-blockjob.c | 2 +-
55
tests/qemu-iotests/206 | 680 ++++++++++++++++--------------------------
56
tests/qemu-iotests/206.out | 253 +++++++++-------
57
tests/qemu-iotests/207 | 440 ++++++++++++---------------
58
tests/qemu-iotests/207.out | 107 +++----
59
tests/qemu-iotests/210 | 393 ++++++++++--------------
60
tests/qemu-iotests/210.out | 197 ++++++++----
61
tests/qemu-iotests/211 | 381 ++++++++++-------------
62
tests/qemu-iotests/211.out | 133 +++++----
63
tests/qemu-iotests/212 | 483 +++++++++++-------------------
64
tests/qemu-iotests/212.out | 191 +++++++-----
65
tests/qemu-iotests/213 | 520 ++++++++++++--------------------
66
tests/qemu-iotests/213.out | 208 ++++++++-----
67
tests/qemu-iotests/iotests.py | 78 +++++
68
29 files changed, 1981 insertions(+), 2226 deletions(-)
69
40
41
Paolo Bonzini (1):
42
qemu-iotests: allow qcow2 external discarded clusters to contain stale data
43
44
docs/interop/qcow2.txt | 3 +
45
hw/block/nvme.h | 2 +
46
include/block/block.h | 5 +-
47
include/block/block_int.h | 10 +-
48
include/block/nvme.h | 172 ++++++++++++++++++++++++++
49
include/qom/object_interfaces.h | 16 +++
50
include/sysemu/block-backend.h | 2 +-
51
block.c | 3 +-
52
block/block-backend.c | 4 +-
53
block/commit.c | 4 +-
54
block/crypto.c | 7 +-
55
block/file-posix.c | 6 +-
56
block/file-win32.c | 2 +-
57
block/gluster.c | 1 +
58
block/io.c | 43 ++++++-
59
block/iscsi.c | 2 +-
60
block/mirror.c | 2 +-
61
block/nfs.c | 3 +-
62
block/parallels.c | 6 +-
63
block/qcow.c | 4 +-
64
block/qcow2-cluster.c | 2 +-
65
block/qcow2-refcount.c | 2 +-
66
block/qcow2.c | 73 +++++++++--
67
block/qed.c | 3 +-
68
block/raw-format.c | 6 +-
69
block/rbd.c | 1 +
70
block/sheepdog.c | 4 +-
71
block/ssh.c | 2 +-
72
block/vdi.c | 2 +-
73
block/vhdx-log.c | 2 +-
74
block/vhdx.c | 6 +-
75
block/vmdk.c | 8 +-
76
block/vpc.c | 2 +-
77
blockdev.c | 2 +-
78
hw/block/nvme.c | 109 ++++++++++++++++
79
qemu-img.c | 2 +-
80
qemu-io-cmds.c | 2 +-
81
qemu-storage-daemon.c | 4 +-
82
qom/object_interfaces.c | 31 +++++
83
qom/qom-qmp-cmds.c | 24 +---
84
tests/test-block-iothread.c | 9 +-
85
tests/qemu-iotests/iotests.py | 5 +-
86
hw/block/Makefile.objs | 2 +-
87
hw/block/trace-events | 4 +
88
tests/qemu-iotests/244 | 10 +-
89
tests/qemu-iotests/244.out | 9 +-
90
tests/qemu-iotests/274 | 155 +++++++++++++++++++++++
91
tests/qemu-iotests/274.out | 268 ++++++++++++++++++++++++++++++++++++++++
92
tests/qemu-iotests/group | 1 +
93
49 files changed, 951 insertions(+), 96 deletions(-)
94
create mode 100755 tests/qemu-iotests/274
95
create mode 100644 tests/qemu-iotests/274.out
96
97
diff view generated by jsdifflib
1
This rewrites the test case 213 to work with the new x-blockdev-create
1
From: Alberto Garcia <berto@igalia.com>
2
job rather than the old synchronous version of the command.
3
2
4
All of the test cases stay the same as before, but in order to be able
3
Backing files and raw external data files are mutually exclusive.
5
to implement proper job handling, the test case is rewritten in Python.
4
The documentation of the raw external data bit (in autoclear_features)
5
already indicates that, but we should also mention it on the other
6
side.
6
7
8
Suggested-by: Eric Blake <eblake@redhat.com>
9
Signed-off-by: Alberto Garcia <berto@igalia.com>
10
Message-Id: <20200410121816.8334-1-berto@igalia.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
---
13
---
10
tests/qemu-iotests/213 | 520 +++++++++++++++++----------------------------
14
docs/interop/qcow2.txt | 3 +++
11
tests/qemu-iotests/213.out | 208 +++++++++++-------
15
1 file changed, 3 insertions(+)
12
tests/qemu-iotests/group | 4 +-
13
3 files changed, 319 insertions(+), 413 deletions(-)
14
16
15
diff --git a/tests/qemu-iotests/213 b/tests/qemu-iotests/213
17
diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
16
index XXXXXXX..XXXXXXX 100755
18
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/qemu-iotests/213
19
--- a/docs/interop/qcow2.txt
18
+++ b/tests/qemu-iotests/213
20
+++ b/docs/interop/qcow2.txt
19
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ The first cluster of a qcow2 image contains the file header:
20
-#!/bin/bash
22
is stored (NB: The string is not null terminated). 0 if the
21
+#!/usr/bin/env python
23
image doesn't have a backing file.
22
#
24
23
# Test vhdx and file image creation
25
+ Note: backing files are incompatible with raw external data
24
#
26
+ files (auto-clear feature bit 1).
25
# Copyright (C) 2018 Red Hat, Inc.
26
#
27
+# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
28
+#
29
# This program is free software; you can redistribute it and/or modify
30
# it under the terms of the GNU General Public License as published by
31
# the Free Software Foundation; either version 2 of the License, or
32
@@ -XXX,XX +XXX,XX @@
33
# along with this program. If not, see <http://www.gnu.org/licenses/>.
34
#
35
36
-# creator
37
-owner=kwolf@redhat.com
38
-
39
-seq=`basename $0`
40
-echo "QA output created by $seq"
41
-
42
-here=`pwd`
43
-status=1    # failure is the default!
44
-
45
-# get standard environment, filters and checks
46
-. ./common.rc
47
-. ./common.filter
48
-
49
-_supported_fmt vhdx
50
-_supported_proto file
51
-_supported_os Linux
52
-
53
-function do_run_qemu()
54
-{
55
- echo Testing: "$@"
56
- $QEMU -nographic -qmp stdio -serial none "$@"
57
- echo
58
-}
59
-
60
-function run_qemu()
61
-{
62
- do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp \
63
- | _filter_qemu | _filter_imgfmt \
64
- | _filter_actual_image_size
65
-}
66
-
67
-echo
68
-echo "=== Successful image creation (defaults) ==="
69
-echo
70
-
71
-size=$((128 * 1024 * 1024))
72
-
73
-run_qemu <<EOF
74
-{ "execute": "qmp_capabilities" }
75
-{ "execute": "x-blockdev-create",
76
- "arguments": {
77
- "driver": "file",
78
- "filename": "$TEST_IMG",
79
- "size": 0
80
- }
81
-}
82
-{ "execute": "blockdev-add",
83
- "arguments": {
84
- "driver": "file",
85
- "node-name": "imgfile",
86
- "filename": "$TEST_IMG"
87
- }
88
-}
89
-{ "execute": "x-blockdev-create",
90
- "arguments": {
91
- "driver": "$IMGFMT",
92
- "file": "imgfile",
93
- "size": $size
94
- }
95
-}
96
-{ "execute": "quit" }
97
-EOF
98
-
99
-_img_info --format-specific | _filter_img_info --format-specific
100
-
101
-echo
102
-echo "=== Successful image creation (explicit defaults) ==="
103
-echo
104
-
105
-# Choose a different size to show that we got a new image
106
-size=$((64 * 1024 * 1024))
107
-
108
-run_qemu <<EOF
109
-{ "execute": "qmp_capabilities" }
110
-{ "execute": "x-blockdev-create",
111
- "arguments": {
112
- "driver": "file",
113
- "filename": "$TEST_IMG",
114
- "size": 0
115
- }
116
-}
117
-{ "execute": "x-blockdev-create",
118
- "arguments": {
119
- "driver": "$IMGFMT",
120
- "file": {
121
- "driver": "file",
122
- "filename": "$TEST_IMG"
123
- },
124
- "size": $size,
125
- "log-size": 1048576,
126
- "block-size": 8388608,
127
- "subformat": "dynamic",
128
- "block-state-zero": true
129
- }
130
-}
131
-{ "execute": "quit" }
132
-EOF
133
-
134
-_img_info --format-specific | _filter_img_info --format-specific
135
-
136
-echo
137
-echo "=== Successful image creation (with non-default options) ==="
138
-echo
139
-
140
-# Choose a different size to show that we got a new image
141
-size=$((32 * 1024 * 1024))
142
-
143
-run_qemu <<EOF
144
-{ "execute": "qmp_capabilities" }
145
-{ "execute": "x-blockdev-create",
146
- "arguments": {
147
- "driver": "file",
148
- "filename": "$TEST_IMG",
149
- "size": 0
150
- }
151
-}
152
-{ "execute": "x-blockdev-create",
153
- "arguments": {
154
- "driver": "$IMGFMT",
155
- "file": {
156
- "driver": "file",
157
- "filename": "$TEST_IMG"
158
- },
159
- "size": $size,
160
- "log-size": 8388608,
161
- "block-size": 268435456,
162
- "subformat": "fixed",
163
- "block-state-zero": false
164
- }
165
-}
166
-{ "execute": "quit" }
167
-EOF
168
-
169
-_img_info --format-specific | _filter_img_info --format-specific
170
-
171
-echo
172
-echo "=== Invalid BlockdevRef ==="
173
-echo
174
-
175
-run_qemu <<EOF
176
-{ "execute": "qmp_capabilities" }
177
-{ "execute": "x-blockdev-create",
178
- "arguments": {
179
- "driver": "$IMGFMT",
180
- "file": "this doesn't exist",
181
- "size": $size
182
- }
183
-}
184
-{ "execute": "quit" }
185
-EOF
186
-
187
-echo
188
-echo "=== Zero size ==="
189
-echo
190
-
191
-run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF
192
-{ "execute": "qmp_capabilities" }
193
-{ "execute": "x-blockdev-create",
194
- "arguments": {
195
- "driver": "$IMGFMT",
196
- "file": "node0",
197
- "size": 0
198
- }
199
-}
200
-{ "execute": "quit" }
201
-EOF
202
-
203
-_img_info | _filter_img_info
204
-
205
-echo
206
-echo "=== Maximum size ==="
207
-echo
208
-
209
-run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF
210
-{ "execute": "qmp_capabilities" }
211
-{ "execute": "x-blockdev-create",
212
- "arguments": {
213
- "driver": "$IMGFMT",
214
- "file": "node0",
215
- "size": 70368744177664
216
- }
217
-}
218
-{ "execute": "quit" }
219
-EOF
220
-
221
-_img_info | _filter_img_info
222
-
223
-echo
224
-echo "=== Invalid sizes ==="
225
-echo
226
-
227
-# TODO Negative image sizes aren't handled correctly, but this is a problem
228
-# with QAPI's implementation of the 'size' type and affects other commands as
229
-# well. Once this is fixed, we may want to add a test case here.
230
-
231
-# 1. 2^64 - 512
232
-# 2. 2^63 = 8 EB (qemu-img enforces image sizes less than this)
233
-# 3. 2^63 - 512 (generally valid, but with the image header the file will
234
-# exceed 63 bits)
235
-# 4. 2^46 + 1 (one byte more than maximum image size)
236
-
237
-run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF
238
-{ "execute": "qmp_capabilities" }
239
-{ "execute": "x-blockdev-create",
240
- "arguments": {
241
- "driver": "$IMGFMT",
242
- "file": "node0",
243
- "size": 18446744073709551104
244
- }
245
-}
246
-{ "execute": "x-blockdev-create",
247
- "arguments": {
248
- "driver": "$IMGFMT",
249
- "file": "node0",
250
- "size": 9223372036854775808
251
- }
252
-}
253
-{ "execute": "x-blockdev-create",
254
- "arguments": {
255
- "driver": "$IMGFMT",
256
- "file": "node0",
257
- "size": 9223372036854775296
258
- }
259
-}
260
-{ "execute": "x-blockdev-create",
261
- "arguments": {
262
- "driver": "$IMGFMT",
263
- "file": "node0",
264
- "size": 70368744177665
265
- }
266
-}
267
-{ "execute": "quit" }
268
-EOF
269
-
270
-echo
271
-echo "=== Invalid block size ==="
272
-echo
273
-
274
-run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF
275
-{ "execute": "qmp_capabilities" }
276
-{ "execute": "x-blockdev-create",
277
- "arguments": {
278
- "driver": "$IMGFMT",
279
- "file": "node0",
280
- "size": 67108864,
281
- "block-size": 1234567
282
- }
283
-}
284
-{ "execute": "x-blockdev-create",
285
- "arguments": {
286
- "driver": "$IMGFMT",
287
- "file": "node0",
288
- "size": 67108864,
289
- "block-size": 128
290
- }
291
-}
292
-{ "execute": "x-blockdev-create",
293
- "arguments": {
294
- "driver": "$IMGFMT",
295
- "file": "node0",
296
- "size": 67108864,
297
- "block-size": 3145728
298
- }
299
-}
300
-{ "execute": "x-blockdev-create",
301
- "arguments": {
302
- "driver": "$IMGFMT",
303
- "file": "node0",
304
- "size": 67108864,
305
- "block-size": 536870912
306
- }
307
-}
308
-{ "execute": "x-blockdev-create",
309
- "arguments": {
310
- "driver": "$IMGFMT",
311
- "file": "node0",
312
- "size": 67108864,
313
- "block-size": 0
314
- }
315
-}
316
-{ "execute": "quit" }
317
-EOF
318
-
319
-echo
320
-echo "=== Invalid log size ==="
321
-echo
322
-
323
-run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF
324
-{ "execute": "qmp_capabilities" }
325
-{ "execute": "x-blockdev-create",
326
- "arguments": {
327
- "driver": "$IMGFMT",
328
- "file": "node0",
329
- "size": 67108864,
330
- "log-size": 1234567
331
- }
332
-}
333
-{ "execute": "x-blockdev-create",
334
- "arguments": {
335
- "driver": "$IMGFMT",
336
- "file": "node0",
337
- "size": 67108864,
338
- "log-size": 128
339
- }
340
-}
341
-{ "execute": "x-blockdev-create",
342
- "arguments": {
343
- "driver": "$IMGFMT",
344
- "file": "node0",
345
- "size": 67108864,
346
- "log-size": 4294967296
347
- }
348
-}
349
-{ "execute": "x-blockdev-create",
350
- "arguments": {
351
- "driver": "$IMGFMT",
352
- "file": "node0",
353
- "size": 67108864,
354
- "log-size": 0
355
- }
356
-}
357
-{ "execute": "quit" }
358
-EOF
359
-
360
-
361
-# success, all done
362
-echo "*** done"
363
-rm -f $seq.full
364
-status=0
365
+import iotests
366
+from iotests import imgfmt
367
+
27
+
368
+iotests.verify_image_format(supported_fmts=['vhdx'])
28
16 - 19: backing_file_size
369
+iotests.verify_protocol(supported=['file'])
29
Length of the backing file name in bytes. Must not be
370
+
30
longer than 1023 bytes. Undefined if the image doesn't have
371
+def blockdev_create(vm, options):
372
+ result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options)
373
+
374
+ if 'return' in result:
375
+ assert result['return'] == {}
376
+ vm.run_job('job0')
377
+ iotests.log("")
378
+
379
+with iotests.FilePath('t.vhdx') as disk_path, \
380
+ iotests.VM() as vm:
381
+
382
+ #
383
+ # Successful image creation (defaults)
384
+ #
385
+ iotests.log("=== Successful image creation (defaults) ===")
386
+ iotests.log("")
387
+
388
+ size = 128 * 1024 * 1024
389
+
390
+ vm.launch()
391
+ blockdev_create(vm, { 'driver': 'file',
392
+ 'filename': disk_path,
393
+ 'size': 0 })
394
+
395
+ vm.qmp_log('blockdev-add', driver='file', filename=disk_path,
396
+ node_name='imgfile')
397
+
398
+ blockdev_create(vm, { 'driver': imgfmt,
399
+ 'file': 'imgfile',
400
+ 'size': size })
401
+ vm.shutdown()
402
+
403
+ iotests.img_info_log(disk_path)
404
+
405
+ #
406
+ # Successful image creation (explicit defaults)
407
+ #
408
+ iotests.log("=== Successful image creation (explicit defaults) ===")
409
+ iotests.log("")
410
+
411
+ # Choose a different size to show that we got a new image
412
+ size = 64 * 1024 * 1024
413
+
414
+ vm.launch()
415
+ blockdev_create(vm, { 'driver': 'file',
416
+ 'filename': disk_path,
417
+ 'size': 0 })
418
+ blockdev_create(vm, { 'driver': imgfmt,
419
+ 'file': {
420
+ 'driver': 'file',
421
+ 'filename': disk_path,
422
+ },
423
+ 'size': size,
424
+ 'log-size': 1048576,
425
+ 'block-size': 8388608,
426
+ 'subformat': 'dynamic',
427
+ 'block-state-zero': True })
428
+ vm.shutdown()
429
+
430
+ iotests.img_info_log(disk_path)
431
+
432
+ #
433
+ # Successful image creation (with non-default options)
434
+ #
435
+ iotests.log("=== Successful image creation (with non-default options) ===")
436
+ iotests.log("")
437
+
438
+ # Choose a different size to show that we got a new image
439
+ size = 32 * 1024 * 1024
440
+
441
+ vm.launch()
442
+ blockdev_create(vm, { 'driver': 'file',
443
+ 'filename': disk_path,
444
+ 'size': 0 })
445
+ blockdev_create(vm, { 'driver': imgfmt,
446
+ 'file': {
447
+ 'driver': 'file',
448
+ 'filename': disk_path,
449
+ },
450
+ 'size': size,
451
+ 'log-size': 8388608,
452
+ 'block-size': 268435456,
453
+ 'subformat': 'fixed',
454
+ 'block-state-zero': False })
455
+ vm.shutdown()
456
+
457
+ iotests.img_info_log(disk_path)
458
+
459
+ #
460
+ # Invalid BlockdevRef
461
+ #
462
+ iotests.log("=== Invalid BlockdevRef ===")
463
+ iotests.log("")
464
+
465
+ vm.launch()
466
+ blockdev_create(vm, { 'driver': imgfmt,
467
+ 'file': "this doesn't exist",
468
+ 'size': size })
469
+ vm.shutdown()
470
+
471
+ #
472
+ # Zero size
473
+ #
474
+ iotests.log("=== Zero size ===")
475
+ iotests.log("")
476
+
477
+ vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path))
478
+ vm.launch()
479
+ blockdev_create(vm, { 'driver': imgfmt,
480
+ 'file': 'node0',
481
+ 'size': 0 })
482
+ vm.shutdown()
483
+
484
+ iotests.img_info_log(disk_path)
485
+
486
+ #
487
+ # Maximum size
488
+ #
489
+ iotests.log("=== Maximum size ===")
490
+ iotests.log("")
491
+
492
+ vm.launch()
493
+ blockdev_create(vm, { 'driver': imgfmt,
494
+ 'file': 'node0',
495
+ 'size': 70368744177664 })
496
+ vm.shutdown()
497
+
498
+ iotests.img_info_log(disk_path)
499
+
500
+ #
501
+ # Invalid sizes
502
+ #
503
+
504
+ # TODO Negative image sizes aren't handled correctly, but this is a problem
505
+ # with QAPI's implementation of the 'size' type and affects other commands
506
+ # as well. Once this is fixed, we may want to add a test case here.
507
+
508
+ # 1. 2^64 - 512
509
+ # 2. 2^63 = 8 EB (qemu-img enforces image sizes less than this)
510
+ # 3. 2^63 - 512 (generally valid, but with the image header the file will
511
+ # exceed 63 bits)
512
+ # 4. 2^46 + 1 (one byte more than maximum image size)
513
+
514
+ iotests.log("=== Invalid sizes ===")
515
+ iotests.log("")
516
+
517
+ vm.launch()
518
+ for size in [ 18446744073709551104, 9223372036854775808,
519
+ 9223372036854775296, 70368744177665 ]:
520
+ blockdev_create(vm, { 'driver': imgfmt,
521
+ 'file': 'node0',
522
+ 'size': size })
523
+ vm.shutdown()
524
+
525
+ #
526
+ # Invalid block size
527
+ #
528
+ iotests.log("=== Invalid block size ===")
529
+ iotests.log("")
530
+
531
+ vm.launch()
532
+ for bsize in [ 1234567, 128, 3145728, 536870912, 0 ]:
533
+ blockdev_create(vm, { 'driver': imgfmt,
534
+ 'file': 'node0',
535
+ 'size': 67108864,
536
+ 'block-size': bsize })
537
+ vm.shutdown()
538
+
539
+ #
540
+ # Invalid log size
541
+ #
542
+ iotests.log("=== Invalid log size ===")
543
+ iotests.log("")
544
+
545
+ vm.launch()
546
+ for lsize in [ 1234567, 128, 4294967296, 0 ]:
547
+ blockdev_create(vm, { 'driver': imgfmt,
548
+ 'file': 'node0',
549
+ 'size': 67108864,
550
+ 'log-size': lsize })
551
+ vm.shutdown()
552
diff --git a/tests/qemu-iotests/213.out b/tests/qemu-iotests/213.out
553
index XXXXXXX..XXXXXXX 100644
554
--- a/tests/qemu-iotests/213.out
555
+++ b/tests/qemu-iotests/213.out
556
@@ -XXX,XX +XXX,XX @@
557
-QA output created by 213
558
-
559
=== Successful image creation (defaults) ===
560
561
-Testing:
562
-QMP_VERSION
563
-{"return": {}}
564
-{"return": {}}
565
-{"return": {}}
566
-{"return": {}}
567
-{"return": {}}
568
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
569
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}}
570
+{u'return': {}}
571
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
572
+{u'return': {}}
573
+
574
+{'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}
575
+{u'return': {}}
576
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'imgfile', 'size': 134217728}}}
577
+{u'return': {}}
578
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
579
+{u'return': {}}
580
581
-image: TEST_DIR/t.IMGFMT
582
+image: TEST_IMG
583
file format: IMGFMT
584
virtual size: 128M (134217728 bytes)
585
+cluster_size: 8388608
586
587
=== Successful image creation (explicit defaults) ===
588
589
-Testing:
590
-QMP_VERSION
591
-{"return": {}}
592
-{"return": {}}
593
-{"return": {}}
594
-{"return": {}}
595
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
596
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}}
597
+{u'return': {}}
598
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
599
+{u'return': {}}
600
601
-image: TEST_DIR/t.IMGFMT
602
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'block-size': 8388608, 'driver': 'vhdx', 'subformat': 'dynamic', 'log-size': 1048576, 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}, 'block-state-zero': True, 'size': 67108864}}}
603
+{u'return': {}}
604
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
605
+{u'return': {}}
606
+
607
+image: TEST_IMG
608
file format: IMGFMT
609
virtual size: 64M (67108864 bytes)
610
+cluster_size: 8388608
611
612
=== Successful image creation (with non-default options) ===
613
614
-Testing:
615
-QMP_VERSION
616
-{"return": {}}
617
-{"return": {}}
618
-{"return": {}}
619
-{"return": {}}
620
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
621
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}}
622
+{u'return': {}}
623
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
624
+{u'return': {}}
625
+
626
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'block-size': 268435456, 'driver': 'vhdx', 'subformat': 'fixed', 'log-size': 8388608, 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}, 'block-state-zero': False, 'size': 33554432}}}
627
+{u'return': {}}
628
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
629
+{u'return': {}}
630
631
-image: TEST_DIR/t.IMGFMT
632
+image: TEST_IMG
633
file format: IMGFMT
634
virtual size: 32M (33554432 bytes)
635
+cluster_size: 268435456
636
637
=== Invalid BlockdevRef ===
638
639
-Testing:
640
-QMP_VERSION
641
-{"return": {}}
642
-{"error": {"class": "GenericError", "desc": "Cannot find device=this doesn't exist nor node_name=this doesn't exist"}}
643
-{"return": {}}
644
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
645
-
646
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': "this doesn't exist", 'size': 33554432}}}
647
+{u'return': {}}
648
+Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist
649
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
650
+{u'return': {}}
651
652
=== Zero size ===
653
654
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0
655
-QMP_VERSION
656
-{"return": {}}
657
-{"return": {}}
658
-{"return": {}}
659
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
660
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 0}}}
661
+{u'return': {}}
662
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
663
+{u'return': {}}
664
665
-image: TEST_DIR/t.IMGFMT
666
+image: TEST_IMG
667
file format: IMGFMT
668
virtual size: 0 (0 bytes)
669
+cluster_size: 8388608
670
671
=== Maximum size ===
672
673
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0
674
-QMP_VERSION
675
-{"return": {}}
676
-{"return": {}}
677
-{"return": {}}
678
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
679
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 70368744177664}}}
680
+{u'return': {}}
681
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
682
+{u'return': {}}
683
684
-image: TEST_DIR/t.IMGFMT
685
+image: TEST_IMG
686
file format: IMGFMT
687
virtual size: 64T (70368744177664 bytes)
688
+cluster_size: 67108864
689
690
=== Invalid sizes ===
691
692
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0
693
-QMP_VERSION
694
-{"return": {}}
695
-{"error": {"class": "GenericError", "desc": "Image size too large; max of 64TB"}}
696
-{"error": {"class": "GenericError", "desc": "Image size too large; max of 64TB"}}
697
-{"error": {"class": "GenericError", "desc": "Image size too large; max of 64TB"}}
698
-{"error": {"class": "GenericError", "desc": "Image size too large; max of 64TB"}}
699
-{"return": {}}
700
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
701
-
702
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 18446744073709551104L}}}
703
+{u'return': {}}
704
+Job failed: Image size too large; max of 64TB
705
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
706
+{u'return': {}}
707
+
708
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 9223372036854775808L}}}
709
+{u'return': {}}
710
+Job failed: Image size too large; max of 64TB
711
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
712
+{u'return': {}}
713
+
714
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 9223372036854775296}}}
715
+{u'return': {}}
716
+Job failed: Image size too large; max of 64TB
717
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
718
+{u'return': {}}
719
+
720
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 70368744177665}}}
721
+{u'return': {}}
722
+Job failed: Image size too large; max of 64TB
723
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
724
+{u'return': {}}
725
726
=== Invalid block size ===
727
728
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0
729
-QMP_VERSION
730
-{"return": {}}
731
-{"error": {"class": "GenericError", "desc": "Block size must be a multiple of 1 MB"}}
732
-{"error": {"class": "GenericError", "desc": "Block size must be a multiple of 1 MB"}}
733
-{"error": {"class": "GenericError", "desc": "Block size must be a power of two"}}
734
-{"error": {"class": "GenericError", "desc": "Block size must not exceed 268435456"}}
735
-{"error": {"class": "GenericError", "desc": "Block size must be a multiple of 1 MB"}}
736
-{"return": {}}
737
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
738
-
739
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 1234567, 'file': 'node0', 'size': 67108864}}}
740
+{u'return': {}}
741
+Job failed: Block size must be a multiple of 1 MB
742
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
743
+{u'return': {}}
744
+
745
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 128, 'file': 'node0', 'size': 67108864}}}
746
+{u'return': {}}
747
+Job failed: Block size must be a multiple of 1 MB
748
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
749
+{u'return': {}}
750
+
751
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 3145728, 'file': 'node0', 'size': 67108864}}}
752
+{u'return': {}}
753
+Job failed: Block size must be a power of two
754
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
755
+{u'return': {}}
756
+
757
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 536870912, 'file': 'node0', 'size': 67108864}}}
758
+{u'return': {}}
759
+Job failed: Block size must not exceed 268435456
760
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
761
+{u'return': {}}
762
+
763
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 0, 'file': 'node0', 'size': 67108864}}}
764
+{u'return': {}}
765
+Job failed: Block size must be a multiple of 1 MB
766
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
767
+{u'return': {}}
768
769
=== Invalid log size ===
770
771
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0
772
-QMP_VERSION
773
-{"return": {}}
774
-{"error": {"class": "GenericError", "desc": "Log size must be a multiple of 1 MB"}}
775
-{"error": {"class": "GenericError", "desc": "Log size must be a multiple of 1 MB"}}
776
-{"error": {"class": "GenericError", "desc": "Log size must be smaller than 4 GB"}}
777
-{"error": {"class": "GenericError", "desc": "Log size must be a multiple of 1 MB"}}
778
-{"return": {}}
779
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
780
-
781
-*** done
782
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 1234567, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}}
783
+{u'return': {}}
784
+Job failed: Log size must be a multiple of 1 MB
785
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
786
+{u'return': {}}
787
+
788
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 128, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}}
789
+{u'return': {}}
790
+Job failed: Log size must be a multiple of 1 MB
791
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
792
+{u'return': {}}
793
+
794
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 4294967296, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}}
795
+{u'return': {}}
796
+Job failed: Log size must be smaller than 4 GB
797
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
798
+{u'return': {}}
799
+
800
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 0, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}}
801
+{u'return': {}}
802
+Job failed: Log size must be a multiple of 1 MB
803
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
804
+{u'return': {}}
805
+
806
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
807
index XXXXXXX..XXXXXXX 100644
808
--- a/tests/qemu-iotests/group
809
+++ b/tests/qemu-iotests/group
810
@@ -XXX,XX +XXX,XX @@
811
210 rw auto
812
211 rw auto quick
813
212 rw auto quick
814
-# TODO The following commented out tests need to be reworked to work
815
-# with the x-blockdev-create job
816
-#213 rw auto quick
817
+213 rw auto quick
818
214 rw auto
819
215 rw auto quick
820
216 rw auto quick
821
--
31
--
822
2.13.6
32
2.25.3
823
33
824
34
diff view generated by jsdifflib
1
This rewrites the test case 212 to work with the new x-blockdev-create
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
job rather than the old synchronous version of the command.
3
2
4
All of the test cases stay the same as before, but in order to be able
3
Test 244 checks the expected behavior of qcow2 external data files
5
to implement proper job handling, the test case is rewritten in Python.
4
with respect to zero and discarded clusters. Filesystems however
5
are free to ignore discard requests, and this seems to be the
6
case for overlayfs. Relax the tests to skip checks on the
7
external data file for discarded areas, which implies not using
8
qemu-img compare in the data_file_raw=on case.
6
9
10
This fixes docker tests on RHEL8.
11
12
Cc: Kevin Wolf <kwolf@redhat.com>
13
Cc: qemu-block@nongnu.org
14
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
15
Message-Id: <20200409191006.24429-1-pbonzini@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
---
17
---
10
tests/qemu-iotests/212 | 483 +++++++++++++++++----------------------------
18
tests/qemu-iotests/244 | 10 ++++++++--
11
tests/qemu-iotests/212.out | 191 +++++++++++-------
19
tests/qemu-iotests/244.out | 9 ++++++---
12
tests/qemu-iotests/group | 2 +-
20
2 files changed, 14 insertions(+), 5 deletions(-)
13
3 files changed, 295 insertions(+), 381 deletions(-)
14
21
15
diff --git a/tests/qemu-iotests/212 b/tests/qemu-iotests/212
22
diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244
16
index XXXXXXX..XXXXXXX 100755
23
index XXXXXXX..XXXXXXX 100755
17
--- a/tests/qemu-iotests/212
24
--- a/tests/qemu-iotests/244
18
+++ b/tests/qemu-iotests/212
25
+++ b/tests/qemu-iotests/244
19
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'read -P 0 0 1M' \
20
-#!/bin/bash
27
echo
21
+#!/usr/bin/env python
28
$QEMU_IO -c 'read -P 0 0 1M' \
22
#
29
-c 'read -P 0x11 1M 1M' \
23
# Test parallels and file image creation
30
- -c 'read -P 0 2M 2M' \
24
#
31
-c 'read -P 0x11 4M 1M' \
25
# Copyright (C) 2018 Red Hat, Inc.
32
-c 'read -P 0 5M 1M' \
26
#
33
-f raw "$TEST_IMG.data" |
27
+# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
34
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'read -P 0 0 1M' \
28
+#
35
-f $IMGFMT "$TEST_IMG" |
29
# This program is free software; you can redistribute it and/or modify
36
_filter_qemu_io
30
# it under the terms of the GNU General Public License as published by
37
31
# the Free Software Foundation; either version 2 of the License, or
38
+# Discarded clusters are only marked as such in the qcow2 metadata, but
32
@@ -XXX,XX +XXX,XX @@
39
+# they can contain stale data in the external data file. Instead, zero
33
# along with this program. If not, see <http://www.gnu.org/licenses/>.
40
+# clusters must be zeroed in the external data file too.
34
#
41
echo
35
42
-$QEMU_IMG compare "$TEST_IMG" "$TEST_IMG.data"
36
-# creator
43
+$QEMU_IO -c 'read -P 0 0 1M' \
37
-owner=kwolf@redhat.com
44
+ -c 'read -P 0x11 1M 1M' \
38
-
45
+ -c 'read -P 0 3M 3M' \
39
-seq=`basename $0`
46
+ -f raw "$TEST_IMG".data |
40
-echo "QA output created by $seq"
47
+ _filter_qemu_io
41
-
48
42
-here=`pwd`
49
echo -n "qcow2 file size after I/O: "
43
-status=1    # failure is the default!
50
du -b $TEST_IMG | cut -f1
44
-
51
diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
45
-# get standard environment, filters and checks
46
-. ./common.rc
47
-. ./common.filter
48
-
49
-_supported_fmt parallels
50
-_supported_proto file
51
-_supported_os Linux
52
-
53
-function do_run_qemu()
54
-{
55
- echo Testing: "$@"
56
- $QEMU -nographic -qmp stdio -serial none "$@"
57
- echo
58
-}
59
-
60
-function run_qemu()
61
-{
62
- do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp \
63
- | _filter_qemu | _filter_imgfmt \
64
- | _filter_actual_image_size
65
-}
66
-
67
-echo
68
-echo "=== Successful image creation (defaults) ==="
69
-echo
70
-
71
-size=$((128 * 1024 * 1024))
72
-
73
-run_qemu <<EOF
74
-{ "execute": "qmp_capabilities" }
75
-{ "execute": "x-blockdev-create",
76
- "arguments": {
77
- "driver": "file",
78
- "filename": "$TEST_IMG",
79
- "size": 0
80
- }
81
-}
82
-{ "execute": "blockdev-add",
83
- "arguments": {
84
- "driver": "file",
85
- "node-name": "imgfile",
86
- "filename": "$TEST_IMG"
87
- }
88
-}
89
-{ "execute": "x-blockdev-create",
90
- "arguments": {
91
- "driver": "$IMGFMT",
92
- "file": "imgfile",
93
- "size": $size
94
- }
95
-}
96
-{ "execute": "quit" }
97
-EOF
98
-
99
-_img_info --format-specific | _filter_img_info --format-specific
100
-
101
-echo
102
-echo "=== Successful image creation (explicit defaults) ==="
103
-echo
104
-
105
-# Choose a different size to show that we got a new image
106
-size=$((64 * 1024 * 1024))
107
-
108
-run_qemu <<EOF
109
-{ "execute": "qmp_capabilities" }
110
-{ "execute": "x-blockdev-create",
111
- "arguments": {
112
- "driver": "file",
113
- "filename": "$TEST_IMG",
114
- "size": 0
115
- }
116
-}
117
-{ "execute": "x-blockdev-create",
118
- "arguments": {
119
- "driver": "$IMGFMT",
120
- "file": {
121
- "driver": "file",
122
- "filename": "$TEST_IMG"
123
- },
124
- "size": $size,
125
- "cluster-size": 1048576
126
- }
127
-}
128
-{ "execute": "quit" }
129
-EOF
130
-
131
-_img_info --format-specific | _filter_img_info --format-specific
132
-
133
-echo
134
-echo "=== Successful image creation (with non-default options) ==="
135
-echo
136
-
137
-# Choose a different size to show that we got a new image
138
-size=$((32 * 1024 * 1024))
139
-
140
-run_qemu <<EOF
141
-{ "execute": "qmp_capabilities" }
142
-{ "execute": "x-blockdev-create",
143
- "arguments": {
144
- "driver": "file",
145
- "filename": "$TEST_IMG",
146
- "size": 0
147
- }
148
-}
149
-{ "execute": "x-blockdev-create",
150
- "arguments": {
151
- "driver": "$IMGFMT",
152
- "file": {
153
- "driver": "file",
154
- "filename": "$TEST_IMG"
155
- },
156
- "size": $size,
157
- "cluster-size": 65536
158
- }
159
-}
160
-{ "execute": "quit" }
161
-EOF
162
-
163
-_img_info --format-specific | _filter_img_info --format-specific
164
-
165
-echo
166
-echo "=== Invalid BlockdevRef ==="
167
-echo
168
-
169
-run_qemu <<EOF
170
-{ "execute": "qmp_capabilities" }
171
-{ "execute": "x-blockdev-create",
172
- "arguments": {
173
- "driver": "$IMGFMT",
174
- "file": "this doesn't exist",
175
- "size": $size
176
- }
177
-}
178
-{ "execute": "quit" }
179
-EOF
180
-
181
-echo
182
-echo "=== Zero size ==="
183
-echo
184
-
185
-run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF
186
-{ "execute": "qmp_capabilities" }
187
-{ "execute": "x-blockdev-create",
188
- "arguments": {
189
- "driver": "$IMGFMT",
190
- "file": "node0",
191
- "size": 0
192
- }
193
-}
194
-{ "execute": "quit" }
195
-EOF
196
-
197
-_img_info | _filter_img_info
198
-
199
-echo
200
-echo "=== Maximum size ==="
201
-echo
202
-
203
-run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF
204
-{ "execute": "qmp_capabilities" }
205
-{ "execute": "x-blockdev-create",
206
- "arguments": {
207
- "driver": "$IMGFMT",
208
- "file": "node0",
209
- "size": 4503599627369984
210
- }
211
-}
212
-{ "execute": "quit" }
213
-EOF
214
-
215
-_img_info | _filter_img_info
216
-
217
-echo
218
-echo "=== Invalid sizes ==="
219
-echo
220
-
221
-# TODO Negative image sizes aren't handled correctly, but this is a problem
222
-# with QAPI's implementation of the 'size' type and affects other commands as
223
-# well. Once this is fixed, we may want to add a test case here.
224
-
225
-# 1. Misaligned image size
226
-# 2. 2^64 - 512
227
-# 3. 2^63 = 8 EB (qemu-img enforces image sizes less than this)
228
-# 4. 2^63 - 512 (generally valid, but with the image header the file will
229
-# exceed 63 bits)
230
-# 5. 2^52 (512 bytes more than maximum image size)
231
-
232
-run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF
233
-{ "execute": "qmp_capabilities" }
234
-{ "execute": "x-blockdev-create",
235
- "arguments": {
236
- "driver": "$IMGFMT",
237
- "file": "node0",
238
- "size": 1234
239
- }
240
-}
241
-{ "execute": "x-blockdev-create",
242
- "arguments": {
243
- "driver": "$IMGFMT",
244
- "file": "node0",
245
- "size": 18446744073709551104
246
- }
247
-}
248
-{ "execute": "x-blockdev-create",
249
- "arguments": {
250
- "driver": "$IMGFMT",
251
- "file": "node0",
252
- "size": 9223372036854775808
253
- }
254
-}
255
-{ "execute": "x-blockdev-create",
256
- "arguments": {
257
- "driver": "$IMGFMT",
258
- "file": "node0",
259
- "size": 9223372036854775296
260
- }
261
-}
262
-{ "execute": "x-blockdev-create",
263
- "arguments": {
264
- "driver": "$IMGFMT",
265
- "file": "node0",
266
- "size": 4503599627370497
267
- }
268
-}
269
-{ "execute": "quit" }
270
-EOF
271
-
272
-echo
273
-echo "=== Invalid cluster size ==="
274
-echo
275
-
276
-run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF
277
-{ "execute": "qmp_capabilities" }
278
-{ "execute": "x-blockdev-create",
279
- "arguments": {
280
- "driver": "$IMGFMT",
281
- "file": "node0",
282
- "size": 67108864,
283
- "cluster-size": 1234
284
- }
285
-}
286
-{ "execute": "x-blockdev-create",
287
- "arguments": {
288
- "driver": "$IMGFMT",
289
- "file": "node0",
290
- "size": 67108864,
291
- "cluster-size": 128
292
- }
293
-}
294
-{ "execute": "x-blockdev-create",
295
- "arguments": {
296
- "driver": "$IMGFMT",
297
- "file": "node0",
298
- "size": 67108864,
299
- "cluster-size": 4294967296
300
- }
301
-}
302
-{ "execute": "x-blockdev-create",
303
- "arguments": {
304
- "driver": "$IMGFMT",
305
- "file": "node0",
306
- "size": 67108864,
307
- "cluster-size": 9223372036854775808
308
- }
309
-}
310
-{ "execute": "x-blockdev-create",
311
- "arguments": {
312
- "driver": "$IMGFMT",
313
- "file": "node0",
314
- "size": 67108864,
315
- "cluster-size": 18446744073709551104
316
- }
317
-}
318
-{ "execute": "x-blockdev-create",
319
- "arguments": {
320
- "driver": "$IMGFMT",
321
- "file": "node0",
322
- "size": 67108864,
323
- "cluster-size": 0
324
- }
325
-}
326
-{ "execute": "x-blockdev-create",
327
- "arguments": {
328
- "driver": "$IMGFMT",
329
- "file": "node0",
330
- "size": 281474976710656,
331
- "cluster-size": 512
332
- }
333
-}
334
-{ "execute": "quit" }
335
-EOF
336
-
337
-
338
-# success, all done
339
-echo "*** done"
340
-rm -f $seq.full
341
-status=0
342
+import iotests
343
+from iotests import imgfmt
344
+
345
+iotests.verify_image_format(supported_fmts=['parallels'])
346
+iotests.verify_protocol(supported=['file'])
347
+
348
+def blockdev_create(vm, options):
349
+ result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options)
350
+
351
+ if 'return' in result:
352
+ assert result['return'] == {}
353
+ vm.run_job('job0')
354
+ iotests.log("")
355
+
356
+with iotests.FilePath('t.parallels') as disk_path, \
357
+ iotests.VM() as vm:
358
+
359
+ #
360
+ # Successful image creation (defaults)
361
+ #
362
+ iotests.log("=== Successful image creation (defaults) ===")
363
+ iotests.log("")
364
+
365
+ size = 128 * 1024 * 1024
366
+
367
+ vm.launch()
368
+ blockdev_create(vm, { 'driver': 'file',
369
+ 'filename': disk_path,
370
+ 'size': 0 })
371
+
372
+ vm.qmp_log('blockdev-add', driver='file', filename=disk_path,
373
+ node_name='imgfile')
374
+
375
+ blockdev_create(vm, { 'driver': imgfmt,
376
+ 'file': 'imgfile',
377
+ 'size': size })
378
+ vm.shutdown()
379
+
380
+ iotests.img_info_log(disk_path)
381
+
382
+ #
383
+ # Successful image creation (explicit defaults)
384
+ #
385
+ iotests.log("=== Successful image creation (explicit defaults) ===")
386
+ iotests.log("")
387
+
388
+ # Choose a different size to show that we got a new image
389
+ size = 64 * 1024 * 1024
390
+
391
+ vm.launch()
392
+ blockdev_create(vm, { 'driver': 'file',
393
+ 'filename': disk_path,
394
+ 'size': 0 })
395
+ blockdev_create(vm, { 'driver': imgfmt,
396
+ 'file': {
397
+ 'driver': 'file',
398
+ 'filename': disk_path,
399
+ },
400
+ 'size': size,
401
+ 'cluster-size': 1048576 })
402
+ vm.shutdown()
403
+
404
+ iotests.img_info_log(disk_path)
405
+
406
+ #
407
+ # Successful image creation (with non-default options)
408
+ #
409
+ iotests.log("=== Successful image creation (with non-default options) ===")
410
+ iotests.log("")
411
+
412
+ # Choose a different size to show that we got a new image
413
+ size = 32 * 1024 * 1024
414
+
415
+ vm.launch()
416
+ blockdev_create(vm, { 'driver': 'file',
417
+ 'filename': disk_path,
418
+ 'size': 0 })
419
+ blockdev_create(vm, { 'driver': imgfmt,
420
+ 'file': {
421
+ 'driver': 'file',
422
+ 'filename': disk_path,
423
+ },
424
+ 'size': size,
425
+ 'cluster-size': 65536 })
426
+ vm.shutdown()
427
+
428
+ iotests.img_info_log(disk_path)
429
+
430
+ #
431
+ # Invalid BlockdevRef
432
+ #
433
+ iotests.log("=== Invalid BlockdevRef ===")
434
+ iotests.log("")
435
+
436
+ vm.launch()
437
+ blockdev_create(vm, { 'driver': imgfmt,
438
+ 'file': "this doesn't exist",
439
+ 'size': size })
440
+ vm.shutdown()
441
+
442
+ #
443
+ # Zero size
444
+ #
445
+ iotests.log("=== Zero size ===")
446
+ iotests.log("")
447
+
448
+ vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path))
449
+ vm.launch()
450
+ blockdev_create(vm, { 'driver': imgfmt,
451
+ 'file': 'node0',
452
+ 'size': 0 })
453
+ vm.shutdown()
454
+
455
+ iotests.img_info_log(disk_path)
456
+
457
+ #
458
+ # Maximum size
459
+ #
460
+ iotests.log("=== Maximum size ===")
461
+ iotests.log("")
462
+
463
+ vm.launch()
464
+ blockdev_create(vm, { 'driver': imgfmt,
465
+ 'file': 'node0',
466
+ 'size': 4503599627369984})
467
+ vm.shutdown()
468
+
469
+ iotests.img_info_log(disk_path)
470
+
471
+ #
472
+ # Invalid sizes
473
+ #
474
+
475
+ # TODO Negative image sizes aren't handled correctly, but this is a problem
476
+ # with QAPI's implementation of the 'size' type and affects other commands
477
+ # as well. Once this is fixed, we may want to add a test case here.
478
+
479
+ # 1. Misaligned image size
480
+ # 2. 2^64 - 512
481
+ # 3. 2^63 = 8 EB (qemu-img enforces image sizes less than this)
482
+ # 4. 2^63 - 512 (generally valid, but with the image header the file will
483
+ # exceed 63 bits)
484
+ # 5. 2^52 (512 bytes more than maximum image size)
485
+
486
+ iotests.log("=== Invalid sizes ===")
487
+ iotests.log("")
488
+
489
+ vm.launch()
490
+ for size in [ 1234, 18446744073709551104, 9223372036854775808,
491
+ 9223372036854775296, 4503599627370497 ]:
492
+ blockdev_create(vm, { 'driver': imgfmt,
493
+ 'file': 'node0',
494
+ 'size': size })
495
+ vm.shutdown()
496
+
497
+ #
498
+ # Invalid cluster size
499
+ #
500
+ iotests.log("=== Invalid cluster size ===")
501
+ iotests.log("")
502
+
503
+ vm.launch()
504
+ for csize in [ 1234, 128, 4294967296, 9223372036854775808,
505
+ 18446744073709551104, 0 ]:
506
+ blockdev_create(vm, { 'driver': imgfmt,
507
+ 'file': 'node0',
508
+ 'size': 67108864,
509
+ 'cluster-size': csize })
510
+ blockdev_create(vm, { 'driver': imgfmt,
511
+ 'file': 'node0',
512
+ 'size': 281474976710656,
513
+ 'cluster-size': 512 })
514
+ vm.shutdown()
515
diff --git a/tests/qemu-iotests/212.out b/tests/qemu-iotests/212.out
516
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
517
--- a/tests/qemu-iotests/212.out
53
--- a/tests/qemu-iotests/244.out
518
+++ b/tests/qemu-iotests/212.out
54
+++ b/tests/qemu-iotests/244.out
519
@@ -XXX,XX +XXX,XX @@
55
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 0
520
-QA output created by 212
56
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
521
-
57
read 1048576/1048576 bytes at offset 1048576
522
=== Successful image creation (defaults) ===
58
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
523
59
-read 2097152/2097152 bytes at offset 2097152
524
-Testing:
60
-2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
525
-QMP_VERSION
61
read 1048576/1048576 bytes at offset 4194304
526
-{"return": {}}
62
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
527
-{"return": {}}
63
read 1048576/1048576 bytes at offset 5242880
528
-{"return": {}}
64
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 1048576
529
-{"return": {}}
65
read 4194304/4194304 bytes at offset 2097152
530
-{"return": {}}
66
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
531
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
67
532
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}}
68
-Images are identical.
533
+{u'return': {}}
69
+read 1048576/1048576 bytes at offset 0
534
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
70
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
535
+{u'return': {}}
71
+read 1048576/1048576 bytes at offset 1048576
536
+
72
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
537
+{'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}
73
+read 3145728/3145728 bytes at offset 3145728
538
+{u'return': {}}
74
+3 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
539
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'imgfile', 'size': 134217728}}}
75
qcow2 file size after I/O: 327680
540
+{u'return': {}}
76
541
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
77
=== bdrv_co_block_status test for file and offset=0 ===
542
+{u'return': {}}
543
544
-image: TEST_DIR/t.IMGFMT
545
+image: TEST_IMG
546
file format: IMGFMT
547
virtual size: 128M (134217728 bytes)
548
549
=== Successful image creation (explicit defaults) ===
550
551
-Testing:
552
-QMP_VERSION
553
-{"return": {}}
554
-{"return": {}}
555
-{"return": {}}
556
-{"return": {}}
557
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
558
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}}
559
+{u'return': {}}
560
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
561
+{u'return': {}}
562
563
-image: TEST_DIR/t.IMGFMT
564
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 1048576, 'driver': 'parallels', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}, 'size': 67108864}}}
565
+{u'return': {}}
566
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
567
+{u'return': {}}
568
+
569
+image: TEST_IMG
570
file format: IMGFMT
571
virtual size: 64M (67108864 bytes)
572
573
=== Successful image creation (with non-default options) ===
574
575
-Testing:
576
-QMP_VERSION
577
-{"return": {}}
578
-{"return": {}}
579
-{"return": {}}
580
-{"return": {}}
581
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
582
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}}
583
+{u'return': {}}
584
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
585
+{u'return': {}}
586
+
587
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 65536, 'driver': 'parallels', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}, 'size': 33554432}}}
588
+{u'return': {}}
589
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
590
+{u'return': {}}
591
592
-image: TEST_DIR/t.IMGFMT
593
+image: TEST_IMG
594
file format: IMGFMT
595
virtual size: 32M (33554432 bytes)
596
597
=== Invalid BlockdevRef ===
598
599
-Testing:
600
-QMP_VERSION
601
-{"return": {}}
602
-{"error": {"class": "GenericError", "desc": "Cannot find device=this doesn't exist nor node_name=this doesn't exist"}}
603
-{"return": {}}
604
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
605
-
606
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': "this doesn't exist", 'size': 33554432}}}
607
+{u'return': {}}
608
+Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist
609
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
610
+{u'return': {}}
611
612
=== Zero size ===
613
614
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0
615
-QMP_VERSION
616
-{"return": {}}
617
-{"return": {}}
618
-{"return": {}}
619
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
620
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 0}}}
621
+{u'return': {}}
622
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
623
+{u'return': {}}
624
625
-image: TEST_DIR/t.IMGFMT
626
+image: TEST_IMG
627
file format: IMGFMT
628
virtual size: 0 (0 bytes)
629
630
=== Maximum size ===
631
632
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0
633
-QMP_VERSION
634
-{"return": {}}
635
-{"return": {}}
636
-{"return": {}}
637
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
638
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 4503599627369984}}}
639
+{u'return': {}}
640
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
641
+{u'return': {}}
642
643
-image: TEST_DIR/t.IMGFMT
644
+image: TEST_IMG
645
file format: IMGFMT
646
virtual size: 4096T (4503599627369984 bytes)
647
648
=== Invalid sizes ===
649
650
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0
651
-QMP_VERSION
652
-{"return": {}}
653
-{"error": {"class": "GenericError", "desc": "Image size must be a multiple of 512 bytes"}}
654
-{"error": {"class": "GenericError", "desc": "Image size is too large for this cluster size"}}
655
-{"error": {"class": "GenericError", "desc": "Image size is too large for this cluster size"}}
656
-{"error": {"class": "GenericError", "desc": "Image size is too large for this cluster size"}}
657
-{"error": {"class": "GenericError", "desc": "Image size is too large for this cluster size"}}
658
-{"return": {}}
659
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
660
-
661
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 1234}}}
662
+{u'return': {}}
663
+Job failed: Image size must be a multiple of 512 bytes
664
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
665
+{u'return': {}}
666
+
667
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 18446744073709551104L}}}
668
+{u'return': {}}
669
+Job failed: Image size is too large for this cluster size
670
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
671
+{u'return': {}}
672
+
673
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 9223372036854775808L}}}
674
+{u'return': {}}
675
+Job failed: Image size is too large for this cluster size
676
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
677
+{u'return': {}}
678
+
679
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 9223372036854775296}}}
680
+{u'return': {}}
681
+Job failed: Image size is too large for this cluster size
682
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
683
+{u'return': {}}
684
+
685
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 4503599627370497}}}
686
+{u'return': {}}
687
+Job failed: Image size is too large for this cluster size
688
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
689
+{u'return': {}}
690
691
=== Invalid cluster size ===
692
693
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0
694
-QMP_VERSION
695
-{"return": {}}
696
-{"error": {"class": "GenericError", "desc": "Cluster size must be a multiple of 512 bytes"}}
697
-{"error": {"class": "GenericError", "desc": "Cluster size must be a multiple of 512 bytes"}}
698
-{"error": {"class": "GenericError", "desc": "Cluster size is too large"}}
699
-{"error": {"class": "GenericError", "desc": "Cluster size is too large"}}
700
-{"error": {"class": "GenericError", "desc": "Cluster size is too large"}}
701
-{"error": {"class": "GenericError", "desc": "Image size is too large for this cluster size"}}
702
-{"error": {"class": "GenericError", "desc": "Image size is too large for this cluster size"}}
703
-{"return": {}}
704
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
705
-
706
-*** done
707
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 1234, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}}
708
+{u'return': {}}
709
+Job failed: Cluster size must be a multiple of 512 bytes
710
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
711
+{u'return': {}}
712
+
713
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 128, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}}
714
+{u'return': {}}
715
+Job failed: Cluster size must be a multiple of 512 bytes
716
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
717
+{u'return': {}}
718
+
719
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 4294967296, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}}
720
+{u'return': {}}
721
+Job failed: Cluster size is too large
722
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
723
+{u'return': {}}
724
+
725
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 9223372036854775808L, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}}
726
+{u'return': {}}
727
+Job failed: Cluster size is too large
728
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
729
+{u'return': {}}
730
+
731
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 18446744073709551104L, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}}
732
+{u'return': {}}
733
+Job failed: Cluster size is too large
734
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
735
+{u'return': {}}
736
+
737
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 0, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}}
738
+{u'return': {}}
739
+Job failed: Image size is too large for this cluster size
740
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
741
+{u'return': {}}
742
+
743
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 512, 'driver': 'parallels', 'file': 'node0', 'size': 281474976710656}}}
744
+{u'return': {}}
745
+Job failed: Image size is too large for this cluster size
746
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
747
+{u'return': {}}
748
+
749
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
750
index XXXXXXX..XXXXXXX 100644
751
--- a/tests/qemu-iotests/group
752
+++ b/tests/qemu-iotests/group
753
@@ -XXX,XX +XXX,XX @@
754
209 rw auto quick
755
210 rw auto
756
211 rw auto quick
757
+212 rw auto quick
758
# TODO The following commented out tests need to be reworked to work
759
# with the x-blockdev-create job
760
-#212 rw auto quick
761
#213 rw auto quick
762
214 rw auto
763
215 rw auto quick
764
--
78
--
765
2.13.6
79
2.25.3
766
80
767
81
diff view generated by jsdifflib
1
We're ready to declare the blockdev-create job stable. This renames the
1
This adds a new BdrvRequestFlags parameter to the .bdrv_co_truncate()
2
corresponding QMP command from x-blockdev-create to blockdev-create.
2
driver callbacks, and a supported_truncate_flags field in
3
BlockDriverState that allows drivers to advertise support for request
4
flags in the context of truncate.
5
6
For now, we always pass 0 and no drivers declare support for any flag.
3
7
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Reviewed-by: Alberto Garcia <berto@igalia.com>
5
Reviewed-by: Max Reitz <mreitz@redhat.com>
11
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
Reviewed-by: Jeff Cody <jcody@redhat.com>
12
Message-Id: <20200424125448.63318-2-kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
14
---
8
qapi/block-core.json | 4 ++--
15
include/block/block_int.h | 10 +++++++++-
9
qapi/job.json | 2 +-
16
block/crypto.c | 3 ++-
10
block/create.c | 4 ++--
17
block/file-posix.c | 2 +-
11
tests/qemu-iotests/206 | 2 +-
18
block/file-win32.c | 2 +-
12
tests/qemu-iotests/206.out | 54 +++++++++++++++++++++++-----------------------
19
block/gluster.c | 1 +
13
tests/qemu-iotests/207 | 2 +-
20
block/io.c | 8 +++++++-
14
tests/qemu-iotests/207.out | 18 ++++++++--------
21
block/iscsi.c | 2 +-
15
tests/qemu-iotests/210 | 2 +-
22
block/nfs.c | 3 ++-
16
tests/qemu-iotests/210.out | 18 ++++++++--------
23
block/qcow2.c | 2 +-
17
tests/qemu-iotests/211 | 2 +-
24
block/qed.c | 1 +
18
tests/qemu-iotests/211.out | 24 ++++++++++-----------
25
block/raw-format.c | 2 +-
19
tests/qemu-iotests/212 | 2 +-
26
block/rbd.c | 1 +
20
tests/qemu-iotests/212.out | 42 ++++++++++++++++++------------------
27
block/sheepdog.c | 4 ++--
21
tests/qemu-iotests/213 | 2 +-
28
block/ssh.c | 2 +-
22
tests/qemu-iotests/213.out | 44 ++++++++++++++++++-------------------
29
tests/test-block-iothread.c | 3 ++-
23
15 files changed, 111 insertions(+), 111 deletions(-)
30
15 files changed, 33 insertions(+), 13 deletions(-)
24
31
25
diff --git a/qapi/block-core.json b/qapi/block-core.json
32
diff --git a/include/block/block_int.h b/include/block/block_int.h
26
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
27
--- a/qapi/block-core.json
34
--- a/include/block/block_int.h
28
+++ b/qapi/block-core.json
35
+++ b/include/block/block_int.h
29
@@ -XXX,XX +XXX,XX @@
36
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
30
} }
37
*/
31
38
int coroutine_fn (*bdrv_co_truncate)(BlockDriverState *bs, int64_t offset,
32
##
39
bool exact, PreallocMode prealloc,
33
-# @x-blockdev-create:
40
- Error **errp);
34
+# @blockdev-create:
41
+ BdrvRequestFlags flags, Error **errp);
35
#
42
36
# Starts a job to create an image format on a given node. The job is
43
int64_t (*bdrv_getlength)(BlockDriverState *bs);
37
# automatically finalized, but a manual job-dismiss is required.
44
bool has_variable_length;
38
@@ -XXX,XX +XXX,XX @@
45
@@ -XXX,XX +XXX,XX @@ struct BlockDriverState {
39
#
46
/* Flags honored during pwrite_zeroes (so far: BDRV_REQ_FUA,
40
# Since: 3.0
47
* BDRV_REQ_MAY_UNMAP, BDRV_REQ_WRITE_UNCHANGED) */
41
##
48
unsigned int supported_zero_flags;
42
-{ 'command': 'x-blockdev-create',
49
+ /*
43
+{ 'command': 'blockdev-create',
50
+ * Flags honoured during truncate (so far: BDRV_REQ_ZERO_WRITE).
44
'data': { 'job-id': 'str',
51
+ *
45
'options': 'BlockdevCreateOptions' } }
52
+ * If BDRV_REQ_ZERO_WRITE is given, the truncate operation must make sure
46
53
+ * that any added space reads as all zeros. If this can't be guaranteed,
47
diff --git a/qapi/job.json b/qapi/job.json
54
+ * the operation must fail.
48
index XXXXXXX..XXXXXXX 100644
55
+ */
49
--- a/qapi/job.json
56
+ unsigned int supported_truncate_flags;
50
+++ b/qapi/job.json
57
51
@@ -XXX,XX +XXX,XX @@
58
/* the following member gives a name to every node on the bs graph. */
52
#
59
char node_name[32];
53
# @backup: drive backup job type, see "drive-backup"
60
diff --git a/block/crypto.c b/block/crypto.c
54
#
61
index XXXXXXX..XXXXXXX 100644
55
-# @create: image creation job type, see "x-blockdev-create" (since 3.0)
62
--- a/block/crypto.c
56
+# @create: image creation job type, see "blockdev-create" (since 3.0)
63
+++ b/block/crypto.c
57
#
64
@@ -XXX,XX +XXX,XX @@ static int block_crypto_co_create_generic(BlockDriverState *bs,
58
# Since: 1.7
65
59
##
66
static int coroutine_fn
60
diff --git a/block/create.c b/block/create.c
67
block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
61
index XXXXXXX..XXXXXXX 100644
68
- PreallocMode prealloc, Error **errp)
62
--- a/block/create.c
69
+ PreallocMode prealloc, BdrvRequestFlags flags,
63
+++ b/block/create.c
64
@@ -XXX,XX +XXX,XX @@ static const JobDriver blockdev_create_job_driver = {
65
.start = blockdev_create_run,
66
};
67
68
-void qmp_x_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
69
- Error **errp)
70
+void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
71
+ Error **errp)
70
+ Error **errp)
72
{
71
{
73
BlockdevCreateJob *s;
72
BlockCrypto *crypto = bs->opaque;
74
const char *fmt = BlockdevDriver_str(options->driver);
73
uint64_t payload_offset =
75
diff --git a/tests/qemu-iotests/206 b/tests/qemu-iotests/206
74
diff --git a/block/file-posix.c b/block/file-posix.c
76
index XXXXXXX..XXXXXXX 100755
75
index XXXXXXX..XXXXXXX 100644
77
--- a/tests/qemu-iotests/206
76
--- a/block/file-posix.c
78
+++ b/tests/qemu-iotests/206
77
+++ b/block/file-posix.c
79
@@ -XXX,XX +XXX,XX @@ from iotests import imgfmt
78
@@ -XXX,XX +XXX,XX @@ raw_regular_truncate(BlockDriverState *bs, int fd, int64_t offset,
80
iotests.verify_image_format(supported_fmts=['qcow2'])
79
81
80
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
82
def blockdev_create(vm, options):
81
bool exact, PreallocMode prealloc,
83
- result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options)
82
- Error **errp)
84
+ result = vm.qmp_log('blockdev-create', job_id='job0', options=options)
83
+ BdrvRequestFlags flags, Error **errp)
85
84
{
86
if 'return' in result:
85
BDRVRawState *s = bs->opaque;
87
assert result['return'] == {}
86
struct stat st;
88
diff --git a/tests/qemu-iotests/206.out b/tests/qemu-iotests/206.out
87
diff --git a/block/file-win32.c b/block/file-win32.c
89
index XXXXXXX..XXXXXXX 100644
88
index XXXXXXX..XXXXXXX 100644
90
--- a/tests/qemu-iotests/206.out
89
--- a/block/file-win32.c
91
+++ b/tests/qemu-iotests/206.out
90
+++ b/block/file-win32.c
92
@@ -XXX,XX +XXX,XX @@
91
@@ -XXX,XX +XXX,XX @@ static void raw_close(BlockDriverState *bs)
93
=== Successful image creation (defaults) ===
92
94
93
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
95
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}}
94
bool exact, PreallocMode prealloc,
96
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}}
95
- Error **errp)
97
{u'return': {}}
96
+ BdrvRequestFlags flags, Error **errp)
98
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
97
{
99
{u'return': {}}
98
BDRVRawState *s = bs->opaque;
100
99
LONG low, high;
101
{'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}
100
diff --git a/block/gluster.c b/block/gluster.c
102
{u'return': {}}
101
index XXXXXXX..XXXXXXX 100644
103
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'imgfile', 'size': 134217728}}}
102
--- a/block/gluster.c
104
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'imgfile', 'size': 134217728}}}
103
+++ b/block/gluster.c
105
{u'return': {}}
104
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qemu_gluster_co_truncate(BlockDriverState *bs,
106
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
105
int64_t offset,
107
{u'return': {}}
106
bool exact,
108
@@ -XXX,XX +XXX,XX @@ Format specific information:
107
PreallocMode prealloc,
109
108
+ BdrvRequestFlags flags,
110
=== Successful image creation (inline blockdev-add, explicit defaults) ===
109
Error **errp)
111
110
{
112
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'nocow': False, 'preallocation': 'off', 'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}}
111
BDRVGlusterState *s = bs->opaque;
113
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'nocow': False, 'preallocation': 'off', 'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}}
112
diff --git a/block/io.c b/block/io.c
114
{u'return': {}}
113
index XXXXXXX..XXXXXXX 100644
115
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
114
--- a/block/io.c
116
{u'return': {}}
115
+++ b/block/io.c
117
116
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
118
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 65536, 'refcount-bits': 16, 'version': 'v3', 'preallocation': 'off', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'lazy-refcounts': False, 'driver': 'qcow2', 'size': 67108864}}}
117
BlockDriverState *bs = child->bs;
119
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 65536, 'refcount-bits': 16, 'version': 'v3', 'preallocation': 'off', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'lazy-refcounts': False, 'driver': 'qcow2', 'size': 67108864}}}
118
BlockDriver *drv = bs->drv;
120
{u'return': {}}
119
BdrvTrackedRequest req;
121
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
120
+ BdrvRequestFlags flags = 0;
122
{u'return': {}}
121
int64_t old_size, new_bytes;
123
@@ -XXX,XX +XXX,XX @@ Format specific information:
122
int ret;
124
123
125
=== Successful image creation (v3 non-default options) ===
124
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
126
125
}
127
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'nocow': True, 'preallocation': 'falloc', 'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}}
126
128
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'nocow': True, 'preallocation': 'falloc', 'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}}
127
if (drv->bdrv_co_truncate) {
129
{u'return': {}}
128
- ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, errp);
130
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
129
+ if (flags & ~bs->supported_truncate_flags) {
131
{u'return': {}}
130
+ error_setg(errp, "Block driver does not support requested flags");
132
131
+ ret = -ENOTSUP;
133
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 2097152, 'refcount-bits': 1, 'version': 'v3', 'preallocation': 'metadata', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'lazy-refcounts': True, 'driver': 'qcow2', 'size': 33554432}}}
132
+ goto out;
134
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 2097152, 'refcount-bits': 1, 'version': 'v3', 'preallocation': 'metadata', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'lazy-refcounts': True, 'driver': 'qcow2', 'size': 33554432}}}
133
+ }
135
{u'return': {}}
134
+ ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, flags, errp);
136
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
135
} else if (bs->file && drv->is_filter) {
137
{u'return': {}}
136
ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
138
@@ -XXX,XX +XXX,XX @@ Format specific information:
137
} else {
139
138
diff --git a/block/iscsi.c b/block/iscsi.c
140
=== Successful image creation (v2 non-default options) ===
139
index XXXXXXX..XXXXXXX 100644
141
140
--- a/block/iscsi.c
142
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}}
141
+++ b/block/iscsi.c
143
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}}
142
@@ -XXX,XX +XXX,XX @@ static void iscsi_reopen_commit(BDRVReopenState *reopen_state)
144
{u'return': {}}
143
145
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
144
static int coroutine_fn iscsi_co_truncate(BlockDriverState *bs, int64_t offset,
146
{u'return': {}}
145
bool exact, PreallocMode prealloc,
147
146
- Error **errp)
148
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 512, 'backing-fmt': 'qcow2', 'driver': 'qcow2', 'version': 'v2', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'backing-file': 'TEST_DIR/PID-t.qcow2.base', 'size': 33554432}}}
147
+ BdrvRequestFlags flags, Error **errp)
149
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 512, 'backing-fmt': 'qcow2', 'driver': 'qcow2', 'version': 'v2', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'backing-file': 'TEST_DIR/PID-t.qcow2.base', 'size': 33554432}}}
148
{
150
{u'return': {}}
149
IscsiLun *iscsilun = bs->opaque;
151
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
150
int64_t cur_length;
152
{u'return': {}}
151
diff --git a/block/nfs.c b/block/nfs.c
153
@@ -XXX,XX +XXX,XX @@ Format specific information:
152
index XXXXXXX..XXXXXXX 100644
154
153
--- a/block/nfs.c
155
=== Successful image creation (encrypted) ===
154
+++ b/block/nfs.c
156
155
@@ -XXX,XX +XXX,XX @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
157
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'encrypt': {'key-secret': 'keysec0', 'iter-time': 10, 'cipher-mode': 'ctr', 'ivgen-hash-alg': 'md5', 'cipher-alg': 'twofish-128', 'format': 'luks', 'ivgen-alg': 'plain64', 'hash-alg': 'sha1'}, 'driver': 'qcow2', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'size': 33554432}}}
156
158
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'encrypt': {'key-secret': 'keysec0', 'iter-time': 10, 'cipher-mode': 'ctr', 'ivgen-hash-alg': 'md5', 'cipher-alg': 'twofish-128', 'format': 'luks', 'ivgen-alg': 'plain64', 'hash-alg': 'sha1'}, 'driver': 'qcow2', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'size': 33554432}}}
157
static int coroutine_fn
159
{u'return': {}}
158
nfs_file_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
160
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
159
- PreallocMode prealloc, Error **errp)
161
{u'return': {}}
160
+ PreallocMode prealloc, BdrvRequestFlags flags,
162
@@ -XXX,XX +XXX,XX @@ Format specific information:
161
+ Error **errp)
163
162
{
164
=== Invalid BlockdevRef ===
163
NFSClient *client = bs->opaque;
165
164
int ret;
166
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': "this doesn't exist", 'size': 33554432}}}
165
diff --git a/block/qcow2.c b/block/qcow2.c
167
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': "this doesn't exist", 'size': 33554432}}}
166
index XXXXXXX..XXXXXXX 100644
168
{u'return': {}}
167
--- a/block/qcow2.c
169
Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist
168
+++ b/block/qcow2.c
170
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
169
@@ -XXX,XX +XXX,XX @@ fail:
171
{u'return': {}}
170
172
171
static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
173
=== Invalid sizes ===
172
bool exact, PreallocMode prealloc,
174
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 1234}}}
173
- Error **errp)
175
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 1234}}}
174
+ BdrvRequestFlags flags, Error **errp)
176
{u'return': {}}
175
{
177
Job failed: Image size must be a multiple of 512 bytes
176
BDRVQcow2State *s = bs->opaque;
178
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
177
uint64_t old_length;
179
{u'return': {}}
178
diff --git a/block/qed.c b/block/qed.c
180
179
index XXXXXXX..XXXXXXX 100644
181
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 18446744073709551104L}}}
180
--- a/block/qed.c
182
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 18446744073709551104L}}}
181
+++ b/block/qed.c
183
{u'return': {}}
182
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_truncate(BlockDriverState *bs,
184
Job failed: Could not resize image: Image size cannot be negative
183
int64_t offset,
185
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
184
bool exact,
186
{u'return': {}}
185
PreallocMode prealloc,
187
186
+ BdrvRequestFlags flags,
188
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 9223372036854775808L}}}
187
Error **errp)
189
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 9223372036854775808L}}}
188
{
190
{u'return': {}}
189
BDRVQEDState *s = bs->opaque;
191
Job failed: Could not resize image: Image size cannot be negative
190
diff --git a/block/raw-format.c b/block/raw-format.c
192
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
191
index XXXXXXX..XXXXXXX 100644
193
{u'return': {}}
192
--- a/block/raw-format.c
194
193
+++ b/block/raw-format.c
195
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 9223372036854775296}}}
194
@@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
196
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 9223372036854775296}}}
195
197
{u'return': {}}
196
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
198
Job failed: Could not resize image: Failed to grow the L1 table: File too large
197
bool exact, PreallocMode prealloc,
199
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
198
- Error **errp)
200
{u'return': {}}
199
+ BdrvRequestFlags flags, Error **errp)
201
200
{
202
=== Invalid version ===
201
BDRVRawState *s = bs->opaque;
203
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'version': 'v1', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
202
204
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'version': 'v1', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
203
diff --git a/block/rbd.c b/block/rbd.c
205
{u'error': {u'class': u'GenericError', u'desc': u"Invalid parameter 'v1'"}}
204
index XXXXXXX..XXXXXXX 100644
206
205
--- a/block/rbd.c
207
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'lazy-refcounts': True, 'version': 'v2', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
206
+++ b/block/rbd.c
208
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'lazy-refcounts': True, 'version': 'v2', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
207
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qemu_rbd_co_truncate(BlockDriverState *bs,
209
{u'return': {}}
208
int64_t offset,
210
Job failed: Lazy refcounts only supported with compatibility level 1.1 and above (use version=v3 or greater)
209
bool exact,
211
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
210
PreallocMode prealloc,
212
{u'return': {}}
211
+ BdrvRequestFlags flags,
213
212
Error **errp)
214
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 8, 'version': 'v2', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
213
{
215
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 8, 'version': 'v2', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
214
int r;
216
{u'return': {}}
215
diff --git a/block/sheepdog.c b/block/sheepdog.c
217
Job failed: Different refcount widths than 16 bits require compatibility level 1.1 or above (use version=v3 or greater)
216
index XXXXXXX..XXXXXXX 100644
218
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
217
--- a/block/sheepdog.c
219
{u'return': {}}
218
+++ b/block/sheepdog.c
220
219
@@ -XXX,XX +XXX,XX @@ static int64_t sd_getlength(BlockDriverState *bs)
221
=== Invalid backing file options ===
220
222
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'preallocation': 'full', 'driver': 'qcow2', 'backing-file': '/dev/null', 'file': 'node0', 'size': 67108864}}}
221
static int coroutine_fn sd_co_truncate(BlockDriverState *bs, int64_t offset,
223
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'preallocation': 'full', 'driver': 'qcow2', 'backing-file': '/dev/null', 'file': 'node0', 'size': 67108864}}}
222
bool exact, PreallocMode prealloc,
224
{u'return': {}}
223
- Error **errp)
225
Job failed: Backing file and preallocation cannot be used at the same time
224
+ BdrvRequestFlags flags, Error **errp)
226
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
225
{
227
{u'return': {}}
226
BDRVSheepdogState *s = bs->opaque;
228
227
int ret, fd;
229
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'backing-fmt': 'qcow2', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
228
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
230
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'backing-fmt': 'qcow2', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
229
231
{u'return': {}}
230
assert(!flags);
232
Job failed: Backing format cannot be used without backing file
231
if (offset > s->inode.vdi_size) {
233
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
232
- ret = sd_co_truncate(bs, offset, false, PREALLOC_MODE_OFF, NULL);
234
{u'return': {}}
233
+ ret = sd_co_truncate(bs, offset, false, PREALLOC_MODE_OFF, 0, NULL);
235
234
if (ret < 0) {
236
=== Invalid cluster size ===
235
return ret;
237
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 1234, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
236
}
238
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 1234, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
237
diff --git a/block/ssh.c b/block/ssh.c
239
{u'return': {}}
238
index XXXXXXX..XXXXXXX 100644
240
Job failed: Cluster size must be a power of two between 512 and 2048k
239
--- a/block/ssh.c
241
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
240
+++ b/block/ssh.c
242
{u'return': {}}
241
@@ -XXX,XX +XXX,XX @@ static int64_t ssh_getlength(BlockDriverState *bs)
243
242
244
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 128, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
243
static int coroutine_fn ssh_co_truncate(BlockDriverState *bs, int64_t offset,
245
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 128, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
244
bool exact, PreallocMode prealloc,
246
{u'return': {}}
245
- Error **errp)
247
Job failed: Cluster size must be a power of two between 512 and 2048k
246
+ BdrvRequestFlags flags, Error **errp)
248
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
247
{
249
{u'return': {}}
248
BDRVSSHState *s = bs->opaque;
250
249
251
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 4194304, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
250
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
252
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 4194304, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
251
index XXXXXXX..XXXXXXX 100644
253
{u'return': {}}
252
--- a/tests/test-block-iothread.c
254
Job failed: Cluster size must be a power of two between 512 and 2048k
253
+++ b/tests/test-block-iothread.c
255
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
254
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_test_co_pdiscard(BlockDriverState *bs,
256
{u'return': {}}
255
257
256
static int coroutine_fn
258
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 0, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
257
bdrv_test_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
259
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 0, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
258
- PreallocMode prealloc, Error **errp)
260
{u'return': {}}
259
+ PreallocMode prealloc, BdrvRequestFlags flags,
261
Job failed: Cluster size must be a power of two between 512 and 2048k
260
+ Error **errp)
262
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
261
{
263
{u'return': {}}
262
return 0;
264
263
}
265
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 512, 'driver': 'qcow2', 'file': 'node0', 'size': 281474976710656}}}
266
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 512, 'driver': 'qcow2', 'file': 'node0', 'size': 281474976710656}}}
267
{u'return': {}}
268
Job failed: Could not resize image: Failed to grow the L1 table: File too large
269
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
270
{u'return': {}}
271
272
=== Invalid refcount width ===
273
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 128, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
274
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 128, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
275
{u'return': {}}
276
Job failed: Refcount width must be a power of two and may not exceed 64 bits
277
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
278
{u'return': {}}
279
280
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 0, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
281
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 0, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
282
{u'return': {}}
283
Job failed: Refcount width must be a power of two and may not exceed 64 bits
284
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
285
{u'return': {}}
286
287
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 7, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
288
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 7, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
289
{u'return': {}}
290
Job failed: Refcount width must be a power of two and may not exceed 64 bits
291
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
292
diff --git a/tests/qemu-iotests/207 b/tests/qemu-iotests/207
293
index XXXXXXX..XXXXXXX 100755
294
--- a/tests/qemu-iotests/207
295
+++ b/tests/qemu-iotests/207
296
@@ -XXX,XX +XXX,XX @@ def filter_hash(msg):
297
return re.sub("'hash': '[0-9a-f]+'", "'hash': HASH", msg)
298
299
def blockdev_create(vm, options):
300
- result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options,
301
+ result = vm.qmp_log('blockdev-create', job_id='job0', options=options,
302
filters=[iotests.filter_testfiles, filter_hash])
303
304
if 'return' in result:
305
diff --git a/tests/qemu-iotests/207.out b/tests/qemu-iotests/207.out
306
index XXXXXXX..XXXXXXX 100644
307
--- a/tests/qemu-iotests/207.out
308
+++ b/tests/qemu-iotests/207.out
309
@@ -XXX,XX +XXX,XX @@
310
=== Successful image creation (defaults) ===
311
312
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}}
313
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}}
314
{u'return': {}}
315
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
316
{u'return': {}}
317
@@ -XXX,XX +XXX,XX @@ virtual size: 4.0M (4194304 bytes)
318
319
=== Test host-key-check options ===
320
321
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'mode': 'none'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 8388608}}}
322
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'mode': 'none'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 8388608}}}
323
{u'return': {}}
324
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
325
{u'return': {}}
326
@@ -XXX,XX +XXX,XX @@ image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.po
327
file format: IMGFMT
328
virtual size: 8.0M (8388608 bytes)
329
330
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'mode': 'known_hosts'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}}
331
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'mode': 'known_hosts'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}}
332
{u'return': {}}
333
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
334
{u'return': {}}
335
@@ -XXX,XX +XXX,XX @@ image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.po
336
file format: IMGFMT
337
virtual size: 4.0M (4194304 bytes)
338
339
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': 'wrong', 'type': 'md5', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 2097152}}}
340
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': 'wrong', 'type': 'md5', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 2097152}}}
341
{u'return': {}}
342
Job failed: remote host key does not match host_key_check 'wrong'
343
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
344
{u'return': {}}
345
346
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': HASH, 'type': 'md5', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 8388608}}}
347
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': HASH, 'type': 'md5', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 8388608}}}
348
{u'return': {}}
349
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
350
{u'return': {}}
351
@@ -XXX,XX +XXX,XX @@ image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.po
352
file format: IMGFMT
353
virtual size: 8.0M (8388608 bytes)
354
355
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': 'wrong', 'type': 'sha1', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 2097152}}}
356
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': 'wrong', 'type': 'sha1', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 2097152}}}
357
{u'return': {}}
358
Job failed: remote host key does not match host_key_check 'wrong'
359
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
360
{u'return': {}}
361
362
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': HASH, 'type': 'sha1', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}}
363
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': HASH, 'type': 'sha1', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}}
364
{u'return': {}}
365
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
366
{u'return': {}}
367
@@ -XXX,XX +XXX,XX @@ virtual size: 4.0M (4194304 bytes)
368
369
=== Invalid path and user ===
370
371
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': '/this/is/not/an/existing/path', 'host-key-check': {'mode': 'none'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}}
372
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': '/this/is/not/an/existing/path', 'host-key-check': {'mode': 'none'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}}
373
{u'return': {}}
374
Job failed: failed to open remote file '/this/is/not/an/existing/path': Failed opening remote file (libssh2 error code: -31)
375
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
376
{u'return': {}}
377
378
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'mode': 'none'}, 'user': 'invalid user', 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}}
379
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'mode': 'none'}, 'user': 'invalid user', 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}}
380
{u'return': {}}
381
Job failed: failed to authenticate using publickey authentication and the identities held by your ssh-agent
382
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
383
diff --git a/tests/qemu-iotests/210 b/tests/qemu-iotests/210
384
index XXXXXXX..XXXXXXX 100755
385
--- a/tests/qemu-iotests/210
386
+++ b/tests/qemu-iotests/210
387
@@ -XXX,XX +XXX,XX @@ iotests.verify_image_format(supported_fmts=['luks'])
388
iotests.verify_protocol(supported=['file'])
389
390
def blockdev_create(vm, options):
391
- result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options)
392
+ result = vm.qmp_log('blockdev-create', job_id='job0', options=options)
393
394
if 'return' in result:
395
assert result['return'] == {}
396
diff --git a/tests/qemu-iotests/210.out b/tests/qemu-iotests/210.out
397
index XXXXXXX..XXXXXXX 100644
398
--- a/tests/qemu-iotests/210.out
399
+++ b/tests/qemu-iotests/210.out
400
@@ -XXX,XX +XXX,XX @@
401
=== Successful image creation (defaults) ===
402
403
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}}}
404
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}}}
405
{u'return': {}}
406
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
407
{u'return': {}}
408
409
{'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}}
410
{u'return': {}}
411
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'iter-time': 10, 'driver': 'luks', 'file': 'imgfile', 'size': 134217728}}}
412
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'iter-time': 10, 'driver': 'luks', 'file': 'imgfile', 'size': 134217728}}}
413
{u'return': {}}
414
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
415
{u'return': {}}
416
@@ -XXX,XX +XXX,XX @@ Format specific information:
417
418
=== Successful image creation (with non-default options) ===
419
420
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}}}
421
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}}}
422
{u'return': {}}
423
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
424
{u'return': {}}
425
426
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'hash-alg': 'sha1', 'cipher-mode': 'ctr', 'cipher-alg': 'twofish-128', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}, 'iter-time': 10, 'ivgen-alg': 'plain64', 'ivgen-hash-alg': 'md5', 'driver': 'luks', 'size': 67108864}}}
427
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'hash-alg': 'sha1', 'cipher-mode': 'ctr', 'cipher-alg': 'twofish-128', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}, 'iter-time': 10, 'ivgen-alg': 'plain64', 'ivgen-hash-alg': 'md5', 'driver': 'luks', 'size': 67108864}}}
428
{u'return': {}}
429
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
430
{u'return': {}}
431
@@ -XXX,XX +XXX,XX @@ Format specific information:
432
433
=== Invalid BlockdevRef ===
434
435
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'luks', 'file': "this doesn't exist", 'size': 67108864}}}
436
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'luks', 'file': "this doesn't exist", 'size': 67108864}}}
437
{u'return': {}}
438
Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist
439
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
440
@@ -XXX,XX +XXX,XX @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi
441
442
=== Zero size ===
443
444
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'iter-time': 10, 'driver': 'luks', 'file': 'node0', 'size': 0}}}
445
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'iter-time': 10, 'driver': 'luks', 'file': 'node0', 'size': 0}}}
446
{u'return': {}}
447
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
448
{u'return': {}}
449
@@ -XXX,XX +XXX,XX @@ Format specific information:
450
451
=== Invalid sizes ===
452
453
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 18446744073709551104L}}}
454
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 18446744073709551104L}}}
455
{u'return': {}}
456
Job failed: The requested file size is too large
457
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
458
{u'return': {}}
459
460
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 9223372036854775808L}}}
461
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 9223372036854775808L}}}
462
{u'return': {}}
463
Job failed: The requested file size is too large
464
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
465
{u'return': {}}
466
467
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 9223372036854775296}}}
468
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 9223372036854775296}}}
469
{u'return': {}}
470
Job failed: The requested file size is too large
471
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
472
diff --git a/tests/qemu-iotests/211 b/tests/qemu-iotests/211
473
index XXXXXXX..XXXXXXX 100755
474
--- a/tests/qemu-iotests/211
475
+++ b/tests/qemu-iotests/211
476
@@ -XXX,XX +XXX,XX @@ iotests.verify_image_format(supported_fmts=['vdi'])
477
iotests.verify_protocol(supported=['file'])
478
479
def blockdev_create(vm, options):
480
- result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options)
481
+ result = vm.qmp_log('blockdev-create', job_id='job0', options=options)
482
483
if 'return' in result:
484
assert result['return'] == {}
485
diff --git a/tests/qemu-iotests/211.out b/tests/qemu-iotests/211.out
486
index XXXXXXX..XXXXXXX 100644
487
--- a/tests/qemu-iotests/211.out
488
+++ b/tests/qemu-iotests/211.out
489
@@ -XXX,XX +XXX,XX @@
490
=== Successful image creation (defaults) ===
491
492
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}}
493
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}}
494
{u'return': {}}
495
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
496
{u'return': {}}
497
498
{'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}
499
{u'return': {}}
500
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'imgfile', 'size': 134217728}}}
501
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'imgfile', 'size': 134217728}}}
502
{u'return': {}}
503
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
504
{u'return': {}}
505
@@ -XXX,XX +XXX,XX @@ cluster_size: 1048576
506
507
=== Successful image creation (explicit defaults) ===
508
509
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}}
510
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}}
511
{u'return': {}}
512
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
513
{u'return': {}}
514
515
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'preallocation': 'off', 'driver': 'vdi', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}, 'size': 67108864}}}
516
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'preallocation': 'off', 'driver': 'vdi', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}, 'size': 67108864}}}
517
{u'return': {}}
518
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
519
{u'return': {}}
520
@@ -XXX,XX +XXX,XX @@ cluster_size: 1048576
521
522
=== Successful image creation (with non-default options) ===
523
524
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}}
525
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}}
526
{u'return': {}}
527
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
528
{u'return': {}}
529
530
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'preallocation': 'metadata', 'driver': 'vdi', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}, 'size': 33554432}}}
531
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'preallocation': 'metadata', 'driver': 'vdi', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}, 'size': 33554432}}}
532
{u'return': {}}
533
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
534
{u'return': {}}
535
@@ -XXX,XX +XXX,XX @@ cluster_size: 1048576
536
537
=== Invalid BlockdevRef ===
538
539
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': "this doesn't exist", 'size': 33554432}}}
540
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': "this doesn't exist", 'size': 33554432}}}
541
{u'return': {}}
542
Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist
543
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
544
@@ -XXX,XX +XXX,XX @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi
545
546
=== Zero size ===
547
548
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 0}}}
549
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 0}}}
550
{u'return': {}}
551
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
552
{u'return': {}}
553
@@ -XXX,XX +XXX,XX @@ cluster_size: 1048576
554
555
=== Maximum size ===
556
557
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 562949819203584}}}
558
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 562949819203584}}}
559
{u'return': {}}
560
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
561
{u'return': {}}
562
@@ -XXX,XX +XXX,XX @@ cluster_size: 1048576
563
564
=== Invalid sizes ===
565
566
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 18446744073709551104L}}}
567
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 18446744073709551104L}}}
568
{u'return': {}}
569
Job failed: Unsupported VDI image size (size is 0xfffffffffffffe00, max supported is 0x1fffff8000000)
570
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
571
{u'return': {}}
572
573
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 9223372036854775808L}}}
574
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 9223372036854775808L}}}
575
{u'return': {}}
576
Job failed: Unsupported VDI image size (size is 0x8000000000000000, max supported is 0x1fffff8000000)
577
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
578
{u'return': {}}
579
580
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 562949819203585}}}
581
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 562949819203585}}}
582
{u'return': {}}
583
Job failed: Unsupported VDI image size (size is 0x1fffff8000001, max supported is 0x1fffff8000000)
584
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
585
diff --git a/tests/qemu-iotests/212 b/tests/qemu-iotests/212
586
index XXXXXXX..XXXXXXX 100755
587
--- a/tests/qemu-iotests/212
588
+++ b/tests/qemu-iotests/212
589
@@ -XXX,XX +XXX,XX @@ iotests.verify_image_format(supported_fmts=['parallels'])
590
iotests.verify_protocol(supported=['file'])
591
592
def blockdev_create(vm, options):
593
- result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options)
594
+ result = vm.qmp_log('blockdev-create', job_id='job0', options=options)
595
596
if 'return' in result:
597
assert result['return'] == {}
598
diff --git a/tests/qemu-iotests/212.out b/tests/qemu-iotests/212.out
599
index XXXXXXX..XXXXXXX 100644
600
--- a/tests/qemu-iotests/212.out
601
+++ b/tests/qemu-iotests/212.out
602
@@ -XXX,XX +XXX,XX @@
603
=== Successful image creation (defaults) ===
604
605
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}}
606
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}}
607
{u'return': {}}
608
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
609
{u'return': {}}
610
611
{'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}
612
{u'return': {}}
613
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'imgfile', 'size': 134217728}}}
614
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'imgfile', 'size': 134217728}}}
615
{u'return': {}}
616
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
617
{u'return': {}}
618
@@ -XXX,XX +XXX,XX @@ virtual size: 128M (134217728 bytes)
619
620
=== Successful image creation (explicit defaults) ===
621
622
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}}
623
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}}
624
{u'return': {}}
625
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
626
{u'return': {}}
627
628
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 1048576, 'driver': 'parallels', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}, 'size': 67108864}}}
629
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 1048576, 'driver': 'parallels', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}, 'size': 67108864}}}
630
{u'return': {}}
631
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
632
{u'return': {}}
633
@@ -XXX,XX +XXX,XX @@ virtual size: 64M (67108864 bytes)
634
635
=== Successful image creation (with non-default options) ===
636
637
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}}
638
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}}}
639
{u'return': {}}
640
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
641
{u'return': {}}
642
643
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 65536, 'driver': 'parallels', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}, 'size': 33554432}}}
644
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 65536, 'driver': 'parallels', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.parallels'}, 'size': 33554432}}}
645
{u'return': {}}
646
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
647
{u'return': {}}
648
@@ -XXX,XX +XXX,XX @@ virtual size: 32M (33554432 bytes)
649
650
=== Invalid BlockdevRef ===
651
652
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': "this doesn't exist", 'size': 33554432}}}
653
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': "this doesn't exist", 'size': 33554432}}}
654
{u'return': {}}
655
Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist
656
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
657
@@ -XXX,XX +XXX,XX @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi
658
659
=== Zero size ===
660
661
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 0}}}
662
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 0}}}
663
{u'return': {}}
664
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
665
{u'return': {}}
666
@@ -XXX,XX +XXX,XX @@ virtual size: 0 (0 bytes)
667
668
=== Maximum size ===
669
670
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 4503599627369984}}}
671
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 4503599627369984}}}
672
{u'return': {}}
673
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
674
{u'return': {}}
675
@@ -XXX,XX +XXX,XX @@ virtual size: 4096T (4503599627369984 bytes)
676
677
=== Invalid sizes ===
678
679
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 1234}}}
680
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 1234}}}
681
{u'return': {}}
682
Job failed: Image size must be a multiple of 512 bytes
683
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
684
{u'return': {}}
685
686
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 18446744073709551104L}}}
687
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 18446744073709551104L}}}
688
{u'return': {}}
689
Job failed: Image size is too large for this cluster size
690
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
691
{u'return': {}}
692
693
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 9223372036854775808L}}}
694
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 9223372036854775808L}}}
695
{u'return': {}}
696
Job failed: Image size is too large for this cluster size
697
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
698
{u'return': {}}
699
700
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 9223372036854775296}}}
701
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 9223372036854775296}}}
702
{u'return': {}}
703
Job failed: Image size is too large for this cluster size
704
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
705
{u'return': {}}
706
707
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 4503599627370497}}}
708
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'parallels', 'file': 'node0', 'size': 4503599627370497}}}
709
{u'return': {}}
710
Job failed: Image size is too large for this cluster size
711
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
712
@@ -XXX,XX +XXX,XX @@ Job failed: Image size is too large for this cluster size
713
714
=== Invalid cluster size ===
715
716
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 1234, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}}
717
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 1234, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}}
718
{u'return': {}}
719
Job failed: Cluster size must be a multiple of 512 bytes
720
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
721
{u'return': {}}
722
723
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 128, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}}
724
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 128, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}}
725
{u'return': {}}
726
Job failed: Cluster size must be a multiple of 512 bytes
727
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
728
{u'return': {}}
729
730
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 4294967296, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}}
731
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 4294967296, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}}
732
{u'return': {}}
733
Job failed: Cluster size is too large
734
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
735
{u'return': {}}
736
737
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 9223372036854775808L, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}}
738
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 9223372036854775808L, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}}
739
{u'return': {}}
740
Job failed: Cluster size is too large
741
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
742
{u'return': {}}
743
744
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 18446744073709551104L, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}}
745
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 18446744073709551104L, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}}
746
{u'return': {}}
747
Job failed: Cluster size is too large
748
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
749
{u'return': {}}
750
751
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 0, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}}
752
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 0, 'driver': 'parallels', 'file': 'node0', 'size': 67108864}}}
753
{u'return': {}}
754
Job failed: Image size is too large for this cluster size
755
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
756
{u'return': {}}
757
758
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 512, 'driver': 'parallels', 'file': 'node0', 'size': 281474976710656}}}
759
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 512, 'driver': 'parallels', 'file': 'node0', 'size': 281474976710656}}}
760
{u'return': {}}
761
Job failed: Image size is too large for this cluster size
762
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
763
diff --git a/tests/qemu-iotests/213 b/tests/qemu-iotests/213
764
index XXXXXXX..XXXXXXX 100755
765
--- a/tests/qemu-iotests/213
766
+++ b/tests/qemu-iotests/213
767
@@ -XXX,XX +XXX,XX @@ iotests.verify_image_format(supported_fmts=['vhdx'])
768
iotests.verify_protocol(supported=['file'])
769
770
def blockdev_create(vm, options):
771
- result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options)
772
+ result = vm.qmp_log('blockdev-create', job_id='job0', options=options)
773
774
if 'return' in result:
775
assert result['return'] == {}
776
diff --git a/tests/qemu-iotests/213.out b/tests/qemu-iotests/213.out
777
index XXXXXXX..XXXXXXX 100644
778
--- a/tests/qemu-iotests/213.out
779
+++ b/tests/qemu-iotests/213.out
780
@@ -XXX,XX +XXX,XX @@
781
=== Successful image creation (defaults) ===
782
783
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}}
784
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}}
785
{u'return': {}}
786
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
787
{u'return': {}}
788
789
{'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}
790
{u'return': {}}
791
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'imgfile', 'size': 134217728}}}
792
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'imgfile', 'size': 134217728}}}
793
{u'return': {}}
794
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
795
{u'return': {}}
796
@@ -XXX,XX +XXX,XX @@ cluster_size: 8388608
797
798
=== Successful image creation (explicit defaults) ===
799
800
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}}
801
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}}
802
{u'return': {}}
803
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
804
{u'return': {}}
805
806
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'block-size': 8388608, 'driver': 'vhdx', 'subformat': 'dynamic', 'log-size': 1048576, 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}, 'block-state-zero': True, 'size': 67108864}}}
807
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'block-size': 8388608, 'driver': 'vhdx', 'subformat': 'dynamic', 'log-size': 1048576, 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}, 'block-state-zero': True, 'size': 67108864}}}
808
{u'return': {}}
809
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
810
{u'return': {}}
811
@@ -XXX,XX +XXX,XX @@ cluster_size: 8388608
812
813
=== Successful image creation (with non-default options) ===
814
815
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}}
816
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}}}
817
{u'return': {}}
818
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
819
{u'return': {}}
820
821
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'block-size': 268435456, 'driver': 'vhdx', 'subformat': 'fixed', 'log-size': 8388608, 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}, 'block-state-zero': False, 'size': 33554432}}}
822
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'block-size': 268435456, 'driver': 'vhdx', 'subformat': 'fixed', 'log-size': 8388608, 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vhdx'}, 'block-state-zero': False, 'size': 33554432}}}
823
{u'return': {}}
824
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
825
{u'return': {}}
826
@@ -XXX,XX +XXX,XX @@ cluster_size: 268435456
827
828
=== Invalid BlockdevRef ===
829
830
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': "this doesn't exist", 'size': 33554432}}}
831
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': "this doesn't exist", 'size': 33554432}}}
832
{u'return': {}}
833
Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist
834
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
835
@@ -XXX,XX +XXX,XX @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi
836
837
=== Zero size ===
838
839
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 0}}}
840
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 0}}}
841
{u'return': {}}
842
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
843
{u'return': {}}
844
@@ -XXX,XX +XXX,XX @@ cluster_size: 8388608
845
846
=== Maximum size ===
847
848
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 70368744177664}}}
849
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 70368744177664}}}
850
{u'return': {}}
851
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
852
{u'return': {}}
853
@@ -XXX,XX +XXX,XX @@ cluster_size: 67108864
854
855
=== Invalid sizes ===
856
857
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 18446744073709551104L}}}
858
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 18446744073709551104L}}}
859
{u'return': {}}
860
Job failed: Image size too large; max of 64TB
861
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
862
{u'return': {}}
863
864
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 9223372036854775808L}}}
865
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 9223372036854775808L}}}
866
{u'return': {}}
867
Job failed: Image size too large; max of 64TB
868
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
869
{u'return': {}}
870
871
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 9223372036854775296}}}
872
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 9223372036854775296}}}
873
{u'return': {}}
874
Job failed: Image size too large; max of 64TB
875
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
876
{u'return': {}}
877
878
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 70368744177665}}}
879
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'file': 'node0', 'size': 70368744177665}}}
880
{u'return': {}}
881
Job failed: Image size too large; max of 64TB
882
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
883
@@ -XXX,XX +XXX,XX @@ Job failed: Image size too large; max of 64TB
884
885
=== Invalid block size ===
886
887
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 1234567, 'file': 'node0', 'size': 67108864}}}
888
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 1234567, 'file': 'node0', 'size': 67108864}}}
889
{u'return': {}}
890
Job failed: Block size must be a multiple of 1 MB
891
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
892
{u'return': {}}
893
894
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 128, 'file': 'node0', 'size': 67108864}}}
895
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 128, 'file': 'node0', 'size': 67108864}}}
896
{u'return': {}}
897
Job failed: Block size must be a multiple of 1 MB
898
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
899
{u'return': {}}
900
901
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 3145728, 'file': 'node0', 'size': 67108864}}}
902
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 3145728, 'file': 'node0', 'size': 67108864}}}
903
{u'return': {}}
904
Job failed: Block size must be a power of two
905
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
906
{u'return': {}}
907
908
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 536870912, 'file': 'node0', 'size': 67108864}}}
909
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 536870912, 'file': 'node0', 'size': 67108864}}}
910
{u'return': {}}
911
Job failed: Block size must not exceed 268435456
912
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
913
{u'return': {}}
914
915
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 0, 'file': 'node0', 'size': 67108864}}}
916
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vhdx', 'block-size': 0, 'file': 'node0', 'size': 67108864}}}
917
{u'return': {}}
918
Job failed: Block size must be a multiple of 1 MB
919
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
920
@@ -XXX,XX +XXX,XX @@ Job failed: Block size must be a multiple of 1 MB
921
922
=== Invalid log size ===
923
924
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 1234567, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}}
925
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 1234567, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}}
926
{u'return': {}}
927
Job failed: Log size must be a multiple of 1 MB
928
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
929
{u'return': {}}
930
931
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 128, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}}
932
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 128, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}}
933
{u'return': {}}
934
Job failed: Log size must be a multiple of 1 MB
935
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
936
{u'return': {}}
937
938
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 4294967296, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}}
939
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 4294967296, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}}
940
{u'return': {}}
941
Job failed: Log size must be smaller than 4 GB
942
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
943
{u'return': {}}
944
945
-{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 0, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}}
946
+{'execute': 'blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'log-size': 0, 'driver': 'vhdx', 'file': 'node0', 'size': 67108864}}}
947
{u'return': {}}
948
Job failed: Log size must be a multiple of 1 MB
949
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
950
--
264
--
951
2.13.6
265
2.25.3
952
266
953
267
diff view generated by jsdifflib
1
.bdrv_co_create() is supposed to return 0 on success, but vhdx could
1
Now that block drivers can support flags for .bdrv_co_truncate, expose
2
return a positive value instead. Fix this.
2
the parameter in the node level interfaces bdrv_co_truncate() and
3
bdrv_truncate().
3
4
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
5
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
Reviewed-by: Jeff Cody <jcody@redhat.com>
9
Message-Id: <20200424125448.63318-3-kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
11
---
8
block/vhdx.c | 2 +-
12
include/block/block.h | 5 +++--
9
1 file changed, 1 insertion(+), 1 deletion(-)
13
block/block-backend.c | 2 +-
14
block/crypto.c | 2 +-
15
block/io.c | 12 +++++++-----
16
block/parallels.c | 6 +++---
17
block/qcow.c | 4 ++--
18
block/qcow2-refcount.c | 2 +-
19
block/qcow2.c | 15 +++++++++------
20
block/raw-format.c | 2 +-
21
block/vhdx-log.c | 2 +-
22
block/vhdx.c | 2 +-
23
block/vmdk.c | 2 +-
24
tests/test-block-iothread.c | 6 +++---
25
13 files changed, 34 insertions(+), 28 deletions(-)
10
26
27
diff --git a/include/block/block.h b/include/block/block.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/include/block/block.h
30
+++ b/include/block/block.h
31
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
32
void bdrv_refresh_filename(BlockDriverState *bs);
33
34
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
35
- PreallocMode prealloc, Error **errp);
36
+ PreallocMode prealloc, BdrvRequestFlags flags,
37
+ Error **errp);
38
int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
39
- PreallocMode prealloc, Error **errp);
40
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
41
42
int64_t bdrv_nb_sectors(BlockDriverState *bs);
43
int64_t bdrv_getlength(BlockDriverState *bs);
44
diff --git a/block/block-backend.c b/block/block-backend.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/block/block-backend.c
47
+++ b/block/block-backend.c
48
@@ -XXX,XX +XXX,XX @@ int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
49
return -ENOMEDIUM;
50
}
51
52
- return bdrv_truncate(blk->root, offset, exact, prealloc, errp);
53
+ return bdrv_truncate(blk->root, offset, exact, prealloc, 0, errp);
54
}
55
56
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
57
diff --git a/block/crypto.c b/block/crypto.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/block/crypto.c
60
+++ b/block/crypto.c
61
@@ -XXX,XX +XXX,XX @@ block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
62
63
offset += payload_offset;
64
65
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
66
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
67
}
68
69
static void block_crypto_close(BlockDriverState *bs)
70
diff --git a/block/io.c b/block/io.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/block/io.c
73
+++ b/block/io.c
74
@@ -XXX,XX +XXX,XX @@ static void bdrv_parent_cb_resize(BlockDriverState *bs)
75
* 'offset' bytes in length.
76
*/
77
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
78
- PreallocMode prealloc, Error **errp)
79
+ PreallocMode prealloc, BdrvRequestFlags flags,
80
+ Error **errp)
81
{
82
BlockDriverState *bs = child->bs;
83
BlockDriver *drv = bs->drv;
84
BdrvTrackedRequest req;
85
- BdrvRequestFlags flags = 0;
86
int64_t old_size, new_bytes;
87
int ret;
88
89
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
90
}
91
ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, flags, errp);
92
} else if (bs->file && drv->is_filter) {
93
- ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
94
+ ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
95
} else {
96
error_setg(errp, "Image format driver does not support resize");
97
ret = -ENOTSUP;
98
@@ -XXX,XX +XXX,XX @@ typedef struct TruncateCo {
99
int64_t offset;
100
bool exact;
101
PreallocMode prealloc;
102
+ BdrvRequestFlags flags;
103
Error **errp;
104
int ret;
105
} TruncateCo;
106
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_truncate_co_entry(void *opaque)
107
{
108
TruncateCo *tco = opaque;
109
tco->ret = bdrv_co_truncate(tco->child, tco->offset, tco->exact,
110
- tco->prealloc, tco->errp);
111
+ tco->prealloc, tco->flags, tco->errp);
112
aio_wait_kick();
113
}
114
115
int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
116
- PreallocMode prealloc, Error **errp)
117
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
118
{
119
Coroutine *co;
120
TruncateCo tco = {
121
@@ -XXX,XX +XXX,XX @@ int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
122
.offset = offset,
123
.exact = exact,
124
.prealloc = prealloc,
125
+ .flags = flags,
126
.errp = errp,
127
.ret = NOT_DONE,
128
};
129
diff --git a/block/parallels.c b/block/parallels.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/block/parallels.c
132
+++ b/block/parallels.c
133
@@ -XXX,XX +XXX,XX @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
134
} else {
135
ret = bdrv_truncate(bs->file,
136
(s->data_end + space) << BDRV_SECTOR_BITS,
137
- false, PREALLOC_MODE_OFF, NULL);
138
+ false, PREALLOC_MODE_OFF, 0, NULL);
139
}
140
if (ret < 0) {
141
return ret;
142
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs,
143
* That means we have to pass exact=true.
144
*/
145
ret = bdrv_truncate(bs->file, res->image_end_offset, true,
146
- PREALLOC_MODE_OFF, &local_err);
147
+ PREALLOC_MODE_OFF, 0, &local_err);
148
if (ret < 0) {
149
error_report_err(local_err);
150
res->check_errors++;
151
@@ -XXX,XX +XXX,XX @@ static void parallels_close(BlockDriverState *bs)
152
153
/* errors are ignored, so we might as well pass exact=true */
154
bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS, true,
155
- PREALLOC_MODE_OFF, NULL);
156
+ PREALLOC_MODE_OFF, 0, NULL);
157
}
158
159
g_free(s->bat_dirty_bmap);
160
diff --git a/block/qcow.c b/block/qcow.c
161
index XXXXXXX..XXXXXXX 100644
162
--- a/block/qcow.c
163
+++ b/block/qcow.c
164
@@ -XXX,XX +XXX,XX @@ static int get_cluster_offset(BlockDriverState *bs,
165
return -E2BIG;
166
}
167
ret = bdrv_truncate(bs->file, cluster_offset + s->cluster_size,
168
- false, PREALLOC_MODE_OFF, NULL);
169
+ false, PREALLOC_MODE_OFF, 0, NULL);
170
if (ret < 0) {
171
return ret;
172
}
173
@@ -XXX,XX +XXX,XX @@ static int qcow_make_empty(BlockDriverState *bs)
174
l1_length) < 0)
175
return -1;
176
ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length, false,
177
- PREALLOC_MODE_OFF, NULL);
178
+ PREALLOC_MODE_OFF, 0, NULL);
179
if (ret < 0)
180
return ret;
181
182
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
183
index XXXXXXX..XXXXXXX 100644
184
--- a/block/qcow2-refcount.c
185
+++ b/block/qcow2-refcount.c
186
@@ -XXX,XX +XXX,XX @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
187
}
188
189
ret = bdrv_truncate(bs->file, offset + s->cluster_size, false,
190
- PREALLOC_MODE_OFF, &local_err);
191
+ PREALLOC_MODE_OFF, 0, &local_err);
192
if (ret < 0) {
193
error_report_err(local_err);
194
goto resize_fail;
195
diff --git a/block/qcow2.c b/block/qcow2.c
196
index XXXXXXX..XXXXXXX 100644
197
--- a/block/qcow2.c
198
+++ b/block/qcow2.c
199
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
200
mode = PREALLOC_MODE_OFF;
201
}
202
ret = bdrv_co_truncate(s->data_file, host_offset + cur_bytes, false,
203
- mode, errp);
204
+ mode, 0, errp);
205
if (ret < 0) {
206
return ret;
207
}
208
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
209
* always fulfilled, so there is no need to pass it on.)
210
*/
211
bdrv_co_truncate(bs->file, (last_cluster + 1) * s->cluster_size,
212
- false, PREALLOC_MODE_OFF, &local_err);
213
+ false, PREALLOC_MODE_OFF, 0, &local_err);
214
if (local_err) {
215
warn_reportf_err(local_err,
216
"Failed to truncate the tail of the image: ");
217
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
218
* file should be resized to the exact target size, too,
219
* so we pass @exact here.
220
*/
221
- ret = bdrv_co_truncate(s->data_file, offset, exact, prealloc, errp);
222
+ ret = bdrv_co_truncate(s->data_file, offset, exact, prealloc, 0,
223
+ errp);
224
if (ret < 0) {
225
goto fail;
226
}
227
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
228
new_file_size = allocation_start +
229
nb_new_data_clusters * s->cluster_size;
230
/* Image file grows, so @exact does not matter */
231
- ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, errp);
232
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
233
+ errp);
234
if (ret < 0) {
235
error_prepend(errp, "Failed to resize underlying file: ");
236
qcow2_free_clusters(bs, allocation_start,
237
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
238
if (len < 0) {
239
return len;
240
}
241
- return bdrv_co_truncate(bs->file, len, false, PREALLOC_MODE_OFF, NULL);
242
+ return bdrv_co_truncate(bs->file, len, false, PREALLOC_MODE_OFF, 0,
243
+ NULL);
244
}
245
246
if (offset_into_cluster(s, offset)) {
247
@@ -XXX,XX +XXX,XX @@ static int make_completely_empty(BlockDriverState *bs)
248
}
249
250
ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size, false,
251
- PREALLOC_MODE_OFF, &local_err);
252
+ PREALLOC_MODE_OFF, 0, &local_err);
253
if (ret < 0) {
254
error_report_err(local_err);
255
goto fail;
256
diff --git a/block/raw-format.c b/block/raw-format.c
257
index XXXXXXX..XXXXXXX 100644
258
--- a/block/raw-format.c
259
+++ b/block/raw-format.c
260
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
261
262
s->size = offset;
263
offset += s->offset;
264
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
265
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
266
}
267
268
static void raw_eject(BlockDriverState *bs, bool eject_flag)
269
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
270
index XXXXXXX..XXXXXXX 100644
271
--- a/block/vhdx-log.c
272
+++ b/block/vhdx-log.c
273
@@ -XXX,XX +XXX,XX @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
274
goto exit;
275
}
276
ret = bdrv_truncate(bs->file, new_file_size, false,
277
- PREALLOC_MODE_OFF, NULL);
278
+ PREALLOC_MODE_OFF, 0, NULL);
279
if (ret < 0) {
280
goto exit;
281
}
11
diff --git a/block/vhdx.c b/block/vhdx.c
282
diff --git a/block/vhdx.c b/block/vhdx.c
12
index XXXXXXX..XXXXXXX 100644
283
index XXXXXXX..XXXXXXX 100644
13
--- a/block/vhdx.c
284
--- a/block/vhdx.c
14
+++ b/block/vhdx.c
285
+++ b/block/vhdx.c
15
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vhdx_co_create(BlockdevCreateOptions *opts,
286
@@ -XXX,XX +XXX,XX @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
16
goto delete_and_exit;
287
}
17
}
288
18
289
return bdrv_truncate(bs->file, *new_offset + s->block_size, false,
19
-
290
- PREALLOC_MODE_OFF, NULL);
20
+ ret = 0;
291
+ PREALLOC_MODE_OFF, 0, NULL);
21
delete_and_exit:
292
}
22
blk_unref(blk);
293
23
bdrv_unref(bs);
294
/*
295
diff --git a/block/vmdk.c b/block/vmdk.c
296
index XXXXXXX..XXXXXXX 100644
297
--- a/block/vmdk.c
298
+++ b/block/vmdk.c
299
@@ -XXX,XX +XXX,XX @@ vmdk_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
300
}
301
length = QEMU_ALIGN_UP(length, BDRV_SECTOR_SIZE);
302
ret = bdrv_truncate(s->extents[i].file, length, false,
303
- PREALLOC_MODE_OFF, NULL);
304
+ PREALLOC_MODE_OFF, 0, NULL);
305
if (ret < 0) {
306
return ret;
307
}
308
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
309
index XXXXXXX..XXXXXXX 100644
310
--- a/tests/test-block-iothread.c
311
+++ b/tests/test-block-iothread.c
312
@@ -XXX,XX +XXX,XX @@ static void test_sync_op_truncate(BdrvChild *c)
313
int ret;
314
315
/* Normal success path */
316
- ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
317
+ ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, 0, NULL);
318
g_assert_cmpint(ret, ==, 0);
319
320
/* Early error: Negative offset */
321
- ret = bdrv_truncate(c, -2, false, PREALLOC_MODE_OFF, NULL);
322
+ ret = bdrv_truncate(c, -2, false, PREALLOC_MODE_OFF, 0, NULL);
323
g_assert_cmpint(ret, ==, -EINVAL);
324
325
/* Error: Read-only image */
326
c->bs->read_only = true;
327
c->bs->open_flags &= ~BDRV_O_RDWR;
328
329
- ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
330
+ ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, 0, NULL);
331
g_assert_cmpint(ret, ==, -EACCES);
332
333
c->bs->read_only = false;
24
--
334
--
25
2.13.6
335
2.25.3
26
336
27
337
diff view generated by jsdifflib
1
So far we relied on job->ret and strerror() to produce an error message
1
Now that node level interface bdrv_truncate() supports passing request
2
for failed jobs. Not surprisingly, this tends to result in completely
2
flags to the block driver, expose this on the BlockBackend level, too.
3
useless messages.
4
5
This adds a Job.error field that can contain an error string for a
6
failing job, and a parameter to job_completed() that sets the field. As
7
a default, if NULL is passed, we continue to use strerror(job->ret).
8
9
All existing callers are changed to pass NULL. They can be improved in
10
separate patches.
11
3
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
13
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
14
Reviewed-by: Jeff Cody <jcody@redhat.com>
8
Message-Id: <20200424125448.63318-4-kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
10
---
16
include/qemu/job.h | 7 ++++++-
11
include/sysemu/block-backend.h | 2 +-
17
block/backup.c | 2 +-
12
block.c | 3 ++-
18
block/commit.c | 2 +-
13
block/block-backend.c | 4 ++--
19
block/mirror.c | 2 +-
14
block/commit.c | 4 ++--
20
block/stream.c | 2 +-
15
block/crypto.c | 2 +-
21
job-qmp.c | 9 ++-------
16
block/mirror.c | 2 +-
22
job.c | 16 ++++++++++++++--
17
block/qcow2.c | 4 ++--
23
tests/test-bdrv-drain.c | 2 +-
18
block/qed.c | 2 +-
24
tests/test-blockjob-txn.c | 2 +-
19
block/vdi.c | 2 +-
25
tests/test-blockjob.c | 2 +-
20
block/vhdx.c | 4 ++--
26
10 files changed, 29 insertions(+), 17 deletions(-)
21
block/vmdk.c | 6 +++---
27
22
block/vpc.c | 2 +-
28
diff --git a/include/qemu/job.h b/include/qemu/job.h
23
blockdev.c | 2 +-
29
index XXXXXXX..XXXXXXX 100644
24
qemu-img.c | 2 +-
30
--- a/include/qemu/job.h
25
qemu-io-cmds.c | 2 +-
31
+++ b/include/qemu/job.h
26
15 files changed, 22 insertions(+), 21 deletions(-)
32
@@ -XXX,XX +XXX,XX @@ typedef struct Job {
27
33
/** Estimated progress_current value at the completion of the job */
28
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
34
int64_t progress_total;
29
index XXXXXXX..XXXXXXX 100644
35
30
--- a/include/sysemu/block-backend.h
36
+ /** Error string for a failed job (NULL if, and only if, job->ret == 0) */
31
+++ b/include/sysemu/block-backend.h
37
+ char *error;
32
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
38
+
33
int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
39
/** ret code passed to job_completed. */
34
int bytes);
35
int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
36
- PreallocMode prealloc, Error **errp);
37
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
38
int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes);
39
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
40
int64_t pos, int size);
41
diff --git a/block.c b/block.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/block.c
44
+++ b/block.c
45
@@ -XXX,XX +XXX,XX @@ static int64_t create_file_fallback_truncate(BlockBackend *blk,
46
int64_t size;
40
int ret;
47
int ret;
41
48
42
@@ -XXX,XX +XXX,XX @@ void job_transition_to_ready(Job *job);
49
- ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, &local_err);
43
/**
50
+ ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, 0,
44
* @job: The job being completed.
51
+ &local_err);
45
* @ret: The status code.
52
if (ret < 0 && ret != -ENOTSUP) {
46
+ * @error: The error message for a failing job (only with @ret < 0). If @ret is
53
error_propagate(errp, local_err);
47
+ * negative, but NULL is given for @error, strerror() is used.
54
return ret;
48
*
55
diff --git a/block/block-backend.c b/block/block-backend.c
49
* Marks @job as completed. If @ret is non-zero, the job transaction it is part
56
index XXXXXXX..XXXXXXX 100644
50
* of is aborted. If @ret is zero, the job moves into the WAITING state. If it
57
--- a/block/block-backend.c
51
* is the last job to complete in its transaction, all jobs in the transaction
58
+++ b/block/block-backend.c
52
* move from WAITING to PENDING.
59
@@ -XXX,XX +XXX,XX @@ int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
53
*/
60
}
54
-void job_completed(Job *job, int ret);
61
55
+void job_completed(Job *job, int ret, Error *error);
62
int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
56
63
- PreallocMode prealloc, Error **errp)
57
/** Asynchronously complete the specified @job. */
64
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
58
void job_complete(Job *job, Error **errp);
59
diff --git a/block/backup.c b/block/backup.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/block/backup.c
62
+++ b/block/backup.c
63
@@ -XXX,XX +XXX,XX @@ static void backup_complete(Job *job, void *opaque)
64
{
65
{
65
BackupCompleteData *data = opaque;
66
if (!blk_is_available(blk)) {
66
67
error_setg(errp, "No medium inserted");
67
- job_completed(job, data->ret);
68
return -ENOMEDIUM;
68
+ job_completed(job, data->ret, NULL);
69
}
69
g_free(data);
70
71
- return bdrv_truncate(blk->root, offset, exact, prealloc, 0, errp);
72
+ return bdrv_truncate(blk->root, offset, exact, prealloc, flags, errp);
70
}
73
}
71
74
75
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
72
diff --git a/block/commit.c b/block/commit.c
76
diff --git a/block/commit.c b/block/commit.c
73
index XXXXXXX..XXXXXXX 100644
77
index XXXXXXX..XXXXXXX 100644
74
--- a/block/commit.c
78
--- a/block/commit.c
75
+++ b/block/commit.c
79
+++ b/block/commit.c
76
@@ -XXX,XX +XXX,XX @@ static void commit_complete(Job *job, void *opaque)
80
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn commit_run(Job *job, Error **errp)
77
* bdrv_set_backing_hd() to fail. */
81
}
78
block_job_remove_all_bdrv(bjob);
82
79
83
if (base_len < len) {
80
- job_completed(job, ret);
84
- ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, NULL);
81
+ job_completed(job, ret, NULL);
85
+ ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, 0, NULL);
82
g_free(data);
86
if (ret) {
83
87
goto out;
84
/* If bdrv_drop_intermediate() didn't already do that, remove the commit
88
}
89
@@ -XXX,XX +XXX,XX @@ int bdrv_commit(BlockDriverState *bs)
90
* grow the backing file image if possible. If not possible,
91
* we must return an error */
92
if (length > backing_length) {
93
- ret = blk_truncate(backing, length, false, PREALLOC_MODE_OFF,
94
+ ret = blk_truncate(backing, length, false, PREALLOC_MODE_OFF, 0,
95
&local_err);
96
if (ret < 0) {
97
error_report_err(local_err);
98
diff --git a/block/crypto.c b/block/crypto.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/block/crypto.c
101
+++ b/block/crypto.c
102
@@ -XXX,XX +XXX,XX @@ static ssize_t block_crypto_init_func(QCryptoBlock *block,
103
* which will be used by the crypto header
104
*/
105
return blk_truncate(data->blk, data->size + headerlen, false,
106
- data->prealloc, errp);
107
+ data->prealloc, 0, errp);
108
}
109
110
85
diff --git a/block/mirror.c b/block/mirror.c
111
diff --git a/block/mirror.c b/block/mirror.c
86
index XXXXXXX..XXXXXXX 100644
112
index XXXXXXX..XXXXXXX 100644
87
--- a/block/mirror.c
113
--- a/block/mirror.c
88
+++ b/block/mirror.c
114
+++ b/block/mirror.c
89
@@ -XXX,XX +XXX,XX @@ static void mirror_exit(Job *job, void *opaque)
115
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
90
blk_set_perm(bjob->blk, 0, BLK_PERM_ALL, &error_abort);
116
91
blk_insert_bs(bjob->blk, mirror_top_bs, &error_abort);
117
if (s->bdev_length > base_length) {
92
118
ret = blk_truncate(s->target, s->bdev_length, false,
93
- job_completed(job, data->ret);
119
- PREALLOC_MODE_OFF, NULL);
94
+ job_completed(job, data->ret, NULL);
120
+ PREALLOC_MODE_OFF, 0, NULL);
95
121
if (ret < 0) {
96
g_free(data);
122
goto immediate_exit;
97
bdrv_drained_end(src);
123
}
98
diff --git a/block/stream.c b/block/stream.c
124
diff --git a/block/qcow2.c b/block/qcow2.c
99
index XXXXXXX..XXXXXXX 100644
125
index XXXXXXX..XXXXXXX 100644
100
--- a/block/stream.c
126
--- a/block/qcow2.c
101
+++ b/block/stream.c
127
+++ b/block/qcow2.c
102
@@ -XXX,XX +XXX,XX @@ out:
128
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
103
}
129
104
130
/* Okay, now that we have a valid image, let's give it the right size */
105
g_free(s->backing_file_str);
131
ret = blk_truncate(blk, qcow2_opts->size, false, qcow2_opts->preallocation,
106
- job_completed(job, data->ret);
132
- errp);
107
+ job_completed(job, data->ret, NULL);
133
+ 0, errp);
108
g_free(data);
134
if (ret < 0) {
109
}
135
error_prepend(errp, "Could not resize image: ");
110
136
goto out;
111
diff --git a/job-qmp.c b/job-qmp.c
137
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
112
index XXXXXXX..XXXXXXX 100644
138
* Amending image options should ensure that the image has
113
--- a/job-qmp.c
139
* exactly the given new values, so pass exact=true here.
114
+++ b/job-qmp.c
140
*/
115
@@ -XXX,XX +XXX,XX @@ void qmp_job_dismiss(const char *id, Error **errp)
141
- ret = blk_truncate(blk, new_size, true, PREALLOC_MODE_OFF, errp);
116
static JobInfo *job_query_single(Job *job, Error **errp)
142
+ ret = blk_truncate(blk, new_size, true, PREALLOC_MODE_OFF, 0, errp);
117
{
143
blk_unref(blk);
118
JobInfo *info;
144
if (ret < 0) {
119
- const char *errmsg = NULL;
145
return ret;
120
146
diff --git a/block/qed.c b/block/qed.c
121
assert(!job_is_internal(job));
147
index XXXXXXX..XXXXXXX 100644
122
148
--- a/block/qed.c
123
- if (job->ret < 0) {
149
+++ b/block/qed.c
124
- errmsg = strerror(-job->ret);
150
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
125
- }
151
* The QED format associates file length with allocation status,
126
-
152
* so a new file (which is empty) must have a length of 0.
127
info = g_new(JobInfo, 1);
153
*/
128
*info = (JobInfo) {
154
- ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, errp);
129
.id = g_strdup(job->id),
155
+ ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, 0, errp);
130
@@ -XXX,XX +XXX,XX @@ static JobInfo *job_query_single(Job *job, Error **errp)
156
if (ret < 0) {
131
.status = job->status,
157
goto out;
132
.current_progress = job->progress_current,
158
}
133
.total_progress = job->progress_total,
159
diff --git a/block/vdi.c b/block/vdi.c
134
- .has_error = !!errmsg,
160
index XXXXXXX..XXXXXXX 100644
135
- .error = g_strdup(errmsg),
161
--- a/block/vdi.c
136
+ .has_error = !!job->error,
162
+++ b/block/vdi.c
137
+ .error = g_strdup(job->error),
163
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
138
};
164
139
165
if (image_type == VDI_TYPE_STATIC) {
140
return info;
166
ret = blk_truncate(blk, offset + blocks * block_size, false,
141
diff --git a/job.c b/job.c
167
- PREALLOC_MODE_OFF, errp);
142
index XXXXXXX..XXXXXXX 100644
168
+ PREALLOC_MODE_OFF, 0, errp);
143
--- a/job.c
169
if (ret < 0) {
144
+++ b/job.c
170
error_prepend(errp, "Failed to statically allocate file");
145
@@ -XXX,XX +XXX,XX @@ void job_unref(Job *job)
171
goto exit;
146
172
diff --git a/block/vhdx.c b/block/vhdx.c
147
QLIST_REMOVE(job, job_list);
173
index XXXXXXX..XXXXXXX 100644
148
174
--- a/block/vhdx.c
149
+ g_free(job->error);
175
+++ b/block/vhdx.c
150
g_free(job->id);
176
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
151
g_free(job);
177
/* All zeroes, so we can just extend the file - the end of the BAT
152
}
178
* is the furthest thing we have written yet */
153
@@ -XXX,XX +XXX,XX @@ static void job_update_rc(Job *job)
179
ret = blk_truncate(blk, data_file_offset, false, PREALLOC_MODE_OFF,
154
job->ret = -ECANCELED;
180
- errp);
155
}
181
+ 0, errp);
156
if (job->ret) {
182
if (ret < 0) {
157
+ if (!job->error) {
183
goto exit;
158
+ job->error = g_strdup(strerror(-job->ret));
184
}
159
+ }
185
} else if (type == VHDX_TYPE_FIXED) {
160
job_state_transition(job, JOB_STATUS_ABORTING);
186
ret = blk_truncate(blk, data_file_offset + image_size, false,
161
}
187
- PREALLOC_MODE_OFF, errp);
162
}
188
+ PREALLOC_MODE_OFF, 0, errp);
163
@@ -XXX,XX +XXX,XX @@ static int job_prepare(Job *job)
189
if (ret < 0) {
164
{
190
goto exit;
165
if (job->ret == 0 && job->driver->prepare) {
191
}
166
job->ret = job->driver->prepare(job);
192
diff --git a/block/vmdk.c b/block/vmdk.c
167
+ job_update_rc(job);
193
index XXXXXXX..XXXXXXX 100644
168
}
194
--- a/block/vmdk.c
169
return job->ret;
195
+++ b/block/vmdk.c
170
}
196
@@ -XXX,XX +XXX,XX @@ static int vmdk_init_extent(BlockBackend *blk,
171
@@ -XXX,XX +XXX,XX @@ static void job_completed_txn_success(Job *job)
197
int gd_buf_size;
172
}
198
173
}
199
if (flat) {
174
200
- ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, errp);
175
-void job_completed(Job *job, int ret)
201
+ ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, 0, errp);
176
+void job_completed(Job *job, int ret, Error *error)
202
goto exit;
177
{
203
}
178
assert(job && job->txn && !job_is_completed(job));
204
magic = cpu_to_be32(VMDK4_MAGIC);
179
+
205
@@ -XXX,XX +XXX,XX @@ static int vmdk_init_extent(BlockBackend *blk,
180
job->ret = ret;
206
}
181
+ if (error) {
207
182
+ assert(job->ret < 0);
208
ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9, false,
183
+ job->error = g_strdup(error_get_pretty(error));
209
- PREALLOC_MODE_OFF, errp);
184
+ error_free(error);
210
+ PREALLOC_MODE_OFF, 0, errp);
185
+ }
211
if (ret < 0) {
186
+
212
goto exit;
187
job_update_rc(job);
213
}
188
trace_job_completed(job, ret, job->ret);
214
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
189
if (job->ret) {
215
/* bdrv_pwrite write padding zeros to align to sector, we don't need that
190
@@ -XXX,XX +XXX,XX @@ void job_cancel(Job *job, bool force)
216
* for description file */
191
}
217
if (desc_offset == 0) {
192
job_cancel_async(job, force);
218
- ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, errp);
193
if (!job_started(job)) {
219
+ ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, 0, errp);
194
- job_completed(job, -ECANCELED);
220
if (ret < 0) {
195
+ job_completed(job, -ECANCELED, NULL);
221
goto exit;
196
} else if (job->deferred_to_main_loop) {
222
}
197
job_completed_txn_abort(job);
223
diff --git a/block/vpc.c b/block/vpc.c
224
index XXXXXXX..XXXXXXX 100644
225
--- a/block/vpc.c
226
+++ b/block/vpc.c
227
@@ -XXX,XX +XXX,XX @@ static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
228
/* Add footer to total size */
229
total_size += HEADER_SIZE;
230
231
- ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, errp);
232
+ ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, 0, errp);
233
if (ret < 0) {
234
return ret;
235
}
236
diff --git a/blockdev.c b/blockdev.c
237
index XXXXXXX..XXXXXXX 100644
238
--- a/blockdev.c
239
+++ b/blockdev.c
240
@@ -XXX,XX +XXX,XX @@ void qmp_block_resize(bool has_device, const char *device,
241
}
242
243
bdrv_drained_begin(bs);
244
- ret = blk_truncate(blk, size, false, PREALLOC_MODE_OFF, errp);
245
+ ret = blk_truncate(blk, size, false, PREALLOC_MODE_OFF, 0, errp);
246
bdrv_drained_end(bs);
247
248
out:
249
diff --git a/qemu-img.c b/qemu-img.c
250
index XXXXXXX..XXXXXXX 100644
251
--- a/qemu-img.c
252
+++ b/qemu-img.c
253
@@ -XXX,XX +XXX,XX @@ static int img_resize(int argc, char **argv)
254
* resizing, so pass @exact=true. It is of no use to report
255
* success when the image has not actually been resized.
256
*/
257
- ret = blk_truncate(blk, total_size, true, prealloc, &err);
258
+ ret = blk_truncate(blk, total_size, true, prealloc, 0, &err);
259
if (!ret) {
260
qprintf(quiet, "Image resized.\n");
198
} else {
261
} else {
199
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
262
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
200
index XXXXXXX..XXXXXXX 100644
263
index XXXXXXX..XXXXXXX 100644
201
--- a/tests/test-bdrv-drain.c
264
--- a/qemu-io-cmds.c
202
+++ b/tests/test-bdrv-drain.c
265
+++ b/qemu-io-cmds.c
203
@@ -XXX,XX +XXX,XX @@ typedef struct TestBlockJob {
266
@@ -XXX,XX +XXX,XX @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
204
267
* exact=true. It is better to err on the "emit more errors" side
205
static void test_job_completed(Job *job, void *opaque)
268
* than to be overly permissive.
206
{
269
*/
207
- job_completed(job, 0);
270
- ret = blk_truncate(blk, offset, true, PREALLOC_MODE_OFF, &local_err);
208
+ job_completed(job, 0, NULL);
271
+ ret = blk_truncate(blk, offset, true, PREALLOC_MODE_OFF, 0, &local_err);
209
}
272
if (ret < 0) {
210
273
error_report_err(local_err);
211
static void coroutine_fn test_job_start(void *opaque)
274
return ret;
212
diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c
213
index XXXXXXX..XXXXXXX 100644
214
--- a/tests/test-blockjob-txn.c
215
+++ b/tests/test-blockjob-txn.c
216
@@ -XXX,XX +XXX,XX @@ static void test_block_job_complete(Job *job, void *opaque)
217
rc = -ECANCELED;
218
}
219
220
- job_completed(job, rc);
221
+ job_completed(job, rc, NULL);
222
bdrv_unref(bs);
223
}
224
225
diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c
226
index XXXXXXX..XXXXXXX 100644
227
--- a/tests/test-blockjob.c
228
+++ b/tests/test-blockjob.c
229
@@ -XXX,XX +XXX,XX @@ static void cancel_job_completed(Job *job, void *opaque)
230
{
231
CancelJob *s = opaque;
232
s->completed = true;
233
- job_completed(job, 0);
234
+ job_completed(job, 0, NULL);
235
}
236
237
static void cancel_job_complete(Job *job, Error **errp)
238
--
275
--
239
2.13.6
276
2.25.3
240
277
241
278
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
If BDRV_REQ_ZERO_WRITE is set and we're extending the image, calling
2
qcow2_cluster_zeroize() with flags=0 does the right thing: It doesn't
3
undo any previous preallocation, but just adds the zero flag to all
4
relevant L2 entries. If an external data file is in use, a write_zeroes
5
request to the data file is made instead.
2
6
3
MIN_REFCOUNT_CACHE_SIZE is 4 and the cluster size is guaranteed to be
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
at most 2MB, so the minimum refcount cache size (in bytes) is always
8
Message-Id: <20200424125448.63318-5-kwolf@redhat.com>
5
going to fit in a 32-bit integer.
6
7
Coverity doesn't know that, and since we're storing the result in a
8
uint64_t (*refcount_cache_size) it thinks that we need the 64 bits and
9
that we probably want to do a 64-bit multiplication to prevent the
10
result from being truncated.
11
12
This is a false positive in this case, but it's a fair warning.
13
We could do a 64-bit multiplication to get rid of it, but since we
14
know that a 32-bit variable is enough to store this value let's simply
15
reuse min_refcount_cache, make it a normal int and stop doing casts.
16
17
Reported-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Alberto Garcia <berto@igalia.com>
19
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Reviewed-by: Max Reitz <mreitz@redhat.com>
20
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
21
---
12
---
22
block/qcow2.c | 5 ++---
13
block/qcow2-cluster.c | 2 +-
23
1 file changed, 2 insertions(+), 3 deletions(-)
14
block/qcow2.c | 34 ++++++++++++++++++++++++++++++++++
15
2 files changed, 35 insertions(+), 1 deletion(-)
24
16
17
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qcow2-cluster.c
20
+++ b/block/qcow2-cluster.c
21
@@ -XXX,XX +XXX,XX @@ int qcow2_cluster_zeroize(BlockDriverState *bs, uint64_t offset,
22
/* Caller must pass aligned values, except at image end */
23
assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
24
assert(QEMU_IS_ALIGNED(end_offset, s->cluster_size) ||
25
- end_offset == bs->total_sectors << BDRV_SECTOR_BITS);
26
+ end_offset >= bs->total_sectors << BDRV_SECTOR_BITS);
27
28
/* The zero flag is only supported by version 3 and newer */
29
if (s->qcow_version < 3) {
25
diff --git a/block/qcow2.c b/block/qcow2.c
30
diff --git a/block/qcow2.c b/block/qcow2.c
26
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
27
--- a/block/qcow2.c
32
--- a/block/qcow2.c
28
+++ b/block/qcow2.c
33
+++ b/block/qcow2.c
29
@@ -XXX,XX +XXX,XX @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
34
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
30
BDRVQcow2State *s = bs->opaque;
35
31
uint64_t combined_cache_size;
36
bs->supported_zero_flags = header.version >= 3 ?
32
bool l2_cache_size_set, refcount_cache_size_set, combined_cache_size_set;
37
BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK : 0;
33
+ int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size;
38
+ bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
34
39
35
combined_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_CACHE_SIZE);
40
/* Repair image if dirty */
36
l2_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_SIZE);
41
if (!(flags & (BDRV_O_CHECK | BDRV_O_INACTIVE)) && !bs->read_only &&
37
@@ -XXX,XX +XXX,XX @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
42
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
38
} else {
43
g_assert_not_reached();
39
uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
40
uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8);
41
- uint64_t min_refcount_cache =
42
- (uint64_t) MIN_REFCOUNT_CACHE_SIZE * s->cluster_size;
43
44
/* Assign as much memory as possible to the L2 cache, and
45
* use the remainder for the refcount cache */
46
@@ -XXX,XX +XXX,XX @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
47
* s->cluster_size);
48
}
49
if (!refcount_cache_size_set) {
50
- *refcount_cache_size = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size;
51
+ *refcount_cache_size = min_refcount_cache;
52
}
53
}
44
}
54
45
46
+ if ((flags & BDRV_REQ_ZERO_WRITE) && offset > old_length) {
47
+ uint64_t zero_start = QEMU_ALIGN_UP(old_length, s->cluster_size);
48
+
49
+ /*
50
+ * Use zero clusters as much as we can. qcow2_cluster_zeroize()
51
+ * requires a cluster-aligned start. The end may be unaligned if it is
52
+ * at the end of the image (which it is here).
53
+ */
54
+ ret = qcow2_cluster_zeroize(bs, zero_start, offset - zero_start, 0);
55
+ if (ret < 0) {
56
+ error_setg_errno(errp, -ret, "Failed to zero out new clusters");
57
+ goto fail;
58
+ }
59
+
60
+ /* Write explicit zeros for the unaligned head */
61
+ if (zero_start > old_length) {
62
+ uint64_t len = zero_start - old_length;
63
+ uint8_t *buf = qemu_blockalign0(bs, len);
64
+ QEMUIOVector qiov;
65
+ qemu_iovec_init_buf(&qiov, buf, len);
66
+
67
+ qemu_co_mutex_unlock(&s->lock);
68
+ ret = qcow2_co_pwritev_part(bs, old_length, len, &qiov, 0, 0);
69
+ qemu_co_mutex_lock(&s->lock);
70
+
71
+ qemu_vfree(buf);
72
+ if (ret < 0) {
73
+ error_setg_errno(errp, -ret, "Failed to zero out the new area");
74
+ goto fail;
75
+ }
76
+ }
77
+ }
78
+
79
if (prealloc != PREALLOC_MODE_OFF) {
80
/* Flush metadata before actually changing the image size */
81
ret = qcow2_write_caches(bs);
55
--
82
--
56
2.13.6
83
2.25.3
57
84
58
85
diff view generated by jsdifflib
1
This rewrites the test case 211 to work with the new x-blockdev-create
1
The raw format driver can simply forward the flag and let its bs->file
2
job rather than the old synchronous version of the command.
2
child take care of actually providing the zeros.
3
4
All of the test cases stay the same as before, but in order to be able
5
to implement proper job handling, the test case is rewritten in Python.
6
3
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
5
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Message-Id: <20200424125448.63318-6-kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
---
10
tests/qemu-iotests/211 | 381 ++++++++++++++++++---------------------------
11
block/raw-format.c | 4 +++-
11
tests/qemu-iotests/211.out | 133 +++++++++-------
12
1 file changed, 3 insertions(+), 1 deletion(-)
12
tests/qemu-iotests/group | 2 +-
13
3 files changed, 229 insertions(+), 287 deletions(-)
14
13
15
diff --git a/tests/qemu-iotests/211 b/tests/qemu-iotests/211
14
diff --git a/block/raw-format.c b/block/raw-format.c
16
index XXXXXXX..XXXXXXX 100755
17
--- a/tests/qemu-iotests/211
18
+++ b/tests/qemu-iotests/211
19
@@ -XXX,XX +XXX,XX @@
20
-#!/bin/bash
21
+#!/usr/bin/env python
22
#
23
# Test VDI and file image creation
24
#
25
# Copyright (C) 2018 Red Hat, Inc.
26
#
27
+# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
28
+#
29
# This program is free software; you can redistribute it and/or modify
30
# it under the terms of the GNU General Public License as published by
31
# the Free Software Foundation; either version 2 of the License, or
32
@@ -XXX,XX +XXX,XX @@
33
# along with this program. If not, see <http://www.gnu.org/licenses/>.
34
#
35
36
-# creator
37
-owner=kwolf@redhat.com
38
-
39
-seq=`basename $0`
40
-echo "QA output created by $seq"
41
-
42
-here=`pwd`
43
-status=1    # failure is the default!
44
-
45
-# get standard environment, filters and checks
46
-. ./common.rc
47
-. ./common.filter
48
-
49
-_supported_fmt vdi
50
-_supported_proto file
51
-_supported_os Linux
52
-
53
-function do_run_qemu()
54
-{
55
- echo Testing: "$@"
56
- $QEMU -nographic -qmp stdio -serial none "$@"
57
- echo
58
-}
59
-
60
-function run_qemu()
61
-{
62
- do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp \
63
- | _filter_qemu | _filter_imgfmt \
64
- | _filter_actual_image_size
65
-}
66
-
67
-echo
68
-echo "=== Successful image creation (defaults) ==="
69
-echo
70
-
71
-size=$((128 * 1024 * 1024))
72
-
73
-run_qemu <<EOF
74
-{ "execute": "qmp_capabilities" }
75
-{ "execute": "x-blockdev-create",
76
- "arguments": {
77
- "driver": "file",
78
- "filename": "$TEST_IMG",
79
- "size": 0
80
- }
81
-}
82
-{ "execute": "blockdev-add",
83
- "arguments": {
84
- "driver": "file",
85
- "node-name": "imgfile",
86
- "filename": "$TEST_IMG"
87
- }
88
-}
89
-{ "execute": "x-blockdev-create",
90
- "arguments": {
91
- "driver": "$IMGFMT",
92
- "file": "imgfile",
93
- "size": $size
94
- }
95
-}
96
-{ "execute": "quit" }
97
-EOF
98
-
99
-_img_info --format-specific | _filter_img_info --format-specific
100
-$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
101
-
102
-echo
103
-echo "=== Successful image creation (explicit defaults) ==="
104
-echo
105
-
106
-# Choose a different size to show that we got a new image
107
-size=$((64 * 1024 * 1024))
108
-
109
-run_qemu <<EOF
110
-{ "execute": "qmp_capabilities" }
111
-{ "execute": "x-blockdev-create",
112
- "arguments": {
113
- "driver": "file",
114
- "filename": "$TEST_IMG",
115
- "size": 0
116
- }
117
-}
118
-{ "execute": "x-blockdev-create",
119
- "arguments": {
120
- "driver": "$IMGFMT",
121
- "file": {
122
- "driver": "file",
123
- "filename": "$TEST_IMG"
124
- },
125
- "size": $size,
126
- "preallocation": "off"
127
- }
128
-}
129
-{ "execute": "quit" }
130
-EOF
131
-
132
-_img_info --format-specific | _filter_img_info --format-specific
133
-$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
134
-
135
-echo
136
-echo "=== Successful image creation (with non-default options) ==="
137
-echo
138
-
139
-# Choose a different size to show that we got a new image
140
-size=$((32 * 1024 * 1024))
141
-
142
-run_qemu <<EOF
143
-{ "execute": "qmp_capabilities" }
144
-{ "execute": "x-blockdev-create",
145
- "arguments": {
146
- "driver": "file",
147
- "filename": "$TEST_IMG",
148
- "size": 0
149
- }
150
-}
151
-{ "execute": "x-blockdev-create",
152
- "arguments": {
153
- "driver": "$IMGFMT",
154
- "file": {
155
- "driver": "file",
156
- "filename": "$TEST_IMG"
157
- },
158
- "size": $size,
159
- "preallocation": "metadata"
160
- }
161
-}
162
-{ "execute": "quit" }
163
-EOF
164
-
165
-_img_info --format-specific | _filter_img_info --format-specific
166
-$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
167
-
168
-echo
169
-echo "=== Invalid BlockdevRef ==="
170
-echo
171
-
172
-run_qemu <<EOF
173
-{ "execute": "qmp_capabilities" }
174
-{ "execute": "x-blockdev-create",
175
- "arguments": {
176
- "driver": "$IMGFMT",
177
- "file": "this doesn't exist",
178
- "size": $size
179
- }
180
-}
181
-{ "execute": "quit" }
182
-EOF
183
-
184
-echo
185
-echo "=== Zero size ==="
186
-echo
187
-
188
-run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF
189
-{ "execute": "qmp_capabilities" }
190
-{ "execute": "x-blockdev-create",
191
- "arguments": {
192
- "driver": "$IMGFMT",
193
- "file": "node0",
194
- "size": 0
195
- }
196
-}
197
-{ "execute": "quit" }
198
-EOF
199
-
200
-_img_info | _filter_img_info
201
-
202
-echo
203
-echo "=== Maximum size ==="
204
-echo
205
-
206
-run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF
207
-{ "execute": "qmp_capabilities" }
208
-{ "execute": "x-blockdev-create",
209
- "arguments": {
210
- "driver": "$IMGFMT",
211
- "file": "node0",
212
- "size": 562949819203584
213
- }
214
-}
215
-{ "execute": "quit" }
216
-EOF
217
-
218
-_img_info | _filter_img_info
219
-
220
-echo
221
-echo "=== Invalid sizes ==="
222
-echo
223
-
224
-# TODO Negative image sizes aren't handled correctly, but this is a problem
225
-# with QAPI's implementation of the 'size' type and affects other commands as
226
-# well. Once this is fixed, we may want to add a test case here.
227
-
228
-# 1. 2^64 - 512
229
-# 2. 2^63 = 8 EB (qemu-img enforces image sizes less than this)
230
-# 3. 0x1fffff8000001 (one byte more than maximum image size for VDI)
231
-
232
-run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF
233
-{ "execute": "qmp_capabilities" }
234
-{ "execute": "x-blockdev-create",
235
- "arguments": {
236
- "driver": "$IMGFMT",
237
- "file": "node0",
238
- "size": 18446744073709551104
239
- }
240
-}
241
-{ "execute": "x-blockdev-create",
242
- "arguments": {
243
- "driver": "$IMGFMT",
244
- "file": "node0",
245
- "size": 9223372036854775808
246
- }
247
-}
248
-{ "execute": "x-blockdev-create",
249
- "arguments": {
250
- "driver": "$IMGFMT",
251
- "file": "node0",
252
- "size": 562949819203585
253
- }
254
-}
255
-{ "execute": "quit" }
256
-EOF
257
-
258
-# success, all done
259
-echo "*** done"
260
-rm -f $seq.full
261
-status=0
262
+import iotests
263
+from iotests import imgfmt
264
+
265
+iotests.verify_image_format(supported_fmts=['vdi'])
266
+iotests.verify_protocol(supported=['file'])
267
+
268
+def blockdev_create(vm, options):
269
+ result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options)
270
+
271
+ if 'return' in result:
272
+ assert result['return'] == {}
273
+ vm.run_job('job0')
274
+ iotests.log("")
275
+
276
+with iotests.FilePath('t.vdi') as disk_path, \
277
+ iotests.VM() as vm:
278
+
279
+ #
280
+ # Successful image creation (defaults)
281
+ #
282
+ iotests.log("=== Successful image creation (defaults) ===")
283
+ iotests.log("")
284
+
285
+ size = 128 * 1024 * 1024
286
+
287
+ vm.launch()
288
+ blockdev_create(vm, { 'driver': 'file',
289
+ 'filename': disk_path,
290
+ 'size': 0 })
291
+
292
+ vm.qmp_log('blockdev-add', driver='file', filename=disk_path,
293
+ node_name='imgfile')
294
+
295
+ blockdev_create(vm, { 'driver': imgfmt,
296
+ 'file': 'imgfile',
297
+ 'size': size })
298
+ vm.shutdown()
299
+
300
+ iotests.img_info_log(disk_path)
301
+ iotests.log(iotests.qemu_img_pipe('map', '--output=json', disk_path))
302
+
303
+ #
304
+ # Successful image creation (explicit defaults)
305
+ #
306
+ iotests.log("=== Successful image creation (explicit defaults) ===")
307
+ iotests.log("")
308
+
309
+ size = 64 * 1024 * 1024
310
+
311
+ vm.launch()
312
+ blockdev_create(vm, { 'driver': 'file',
313
+ 'filename': disk_path,
314
+ 'size': 0 })
315
+ blockdev_create(vm, { 'driver': imgfmt,
316
+ 'file': {
317
+ 'driver': 'file',
318
+ 'filename': disk_path,
319
+ },
320
+ 'size': size,
321
+ 'preallocation': 'off' })
322
+ vm.shutdown()
323
+
324
+ iotests.img_info_log(disk_path)
325
+ iotests.log(iotests.qemu_img_pipe('map', '--output=json', disk_path))
326
+
327
+ #
328
+ # Successful image creation (with non-default options)
329
+ #
330
+ iotests.log("=== Successful image creation (with non-default options) ===")
331
+ iotests.log("")
332
+
333
+ size = 32 * 1024 * 1024
334
+
335
+ vm.launch()
336
+ blockdev_create(vm, { 'driver': 'file',
337
+ 'filename': disk_path,
338
+ 'size': 0 })
339
+ blockdev_create(vm, { 'driver': imgfmt,
340
+ 'file': {
341
+ 'driver': 'file',
342
+ 'filename': disk_path,
343
+ },
344
+ 'size': size,
345
+ 'preallocation': 'metadata' })
346
+ vm.shutdown()
347
+
348
+ iotests.img_info_log(disk_path)
349
+ iotests.log(iotests.qemu_img_pipe('map', '--output=json', disk_path))
350
+
351
+ #
352
+ # Invalid BlockdevRef
353
+ #
354
+ iotests.log("=== Invalid BlockdevRef ===")
355
+ iotests.log("")
356
+
357
+ vm.launch()
358
+ blockdev_create(vm, { 'driver': imgfmt,
359
+ 'file': "this doesn't exist",
360
+ 'size': size })
361
+ vm.shutdown()
362
+
363
+ #
364
+ # Zero size
365
+ #
366
+ iotests.log("=== Zero size ===")
367
+ iotests.log("")
368
+
369
+ vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path))
370
+ vm.launch()
371
+ blockdev_create(vm, { 'driver': imgfmt,
372
+ 'file': 'node0',
373
+ 'size': 0 })
374
+ vm.shutdown()
375
+
376
+ iotests.img_info_log(disk_path)
377
+
378
+ #
379
+ # Maximum size
380
+ #
381
+ iotests.log("=== Maximum size ===")
382
+ iotests.log("")
383
+
384
+ vm.launch()
385
+ blockdev_create(vm, { 'driver': imgfmt,
386
+ 'file': 'node0',
387
+ 'size': 562949819203584 })
388
+ vm.shutdown()
389
+
390
+ iotests.img_info_log(disk_path)
391
+
392
+ #
393
+ # Invalid sizes
394
+ #
395
+
396
+ # TODO Negative image sizes aren't handled correctly, but this is a problem
397
+ # with QAPI's implementation of the 'size' type and affects other commands
398
+ # as well. Once this is fixed, we may want to add a test case here.
399
+
400
+ # 1. 2^64 - 512
401
+ # 2. 2^63 = 8 EB (qemu-img enforces image sizes less than this)
402
+ # 3. 0x1fffff8000001 (one byte more than maximum image size for VDI)
403
+
404
+ iotests.log("=== Invalid sizes ===")
405
+ iotests.log("")
406
+
407
+ vm.launch()
408
+ for size in [ 18446744073709551104, 9223372036854775808, 562949819203585 ]:
409
+ blockdev_create(vm, { 'driver': imgfmt,
410
+ 'file': 'node0',
411
+ 'size': size })
412
+ vm.shutdown()
413
diff --git a/tests/qemu-iotests/211.out b/tests/qemu-iotests/211.out
414
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
415
--- a/tests/qemu-iotests/211.out
16
--- a/block/raw-format.c
416
+++ b/tests/qemu-iotests/211.out
17
+++ b/block/raw-format.c
417
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
418
-QA output created by 211
19
419
-
20
s->size = offset;
420
=== Successful image creation (defaults) ===
21
offset += s->offset;
421
22
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
422
-Testing:
23
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
423
-QMP_VERSION
24
}
424
-{"return": {}}
25
425
-{"return": {}}
26
static void raw_eject(BlockDriverState *bs, bool eject_flag)
426
-{"return": {}}
27
@@ -XXX,XX +XXX,XX @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
427
-{"return": {}}
28
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
428
-{"return": {}}
29
((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
429
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
30
bs->file->bs->supported_zero_flags);
430
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}}
31
+ bs->supported_truncate_flags = bs->file->bs->supported_truncate_flags &
431
+{u'return': {}}
32
+ BDRV_REQ_ZERO_WRITE;
432
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
33
433
+{u'return': {}}
34
if (bs->probed && !bdrv_is_read_only(bs)) {
434
+
35
bdrv_refresh_filename(bs->file->bs);
435
+{'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}
436
+{u'return': {}}
437
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'imgfile', 'size': 134217728}}}
438
+{u'return': {}}
439
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
440
+{u'return': {}}
441
442
-image: TEST_DIR/t.IMGFMT
443
+image: TEST_IMG
444
file format: IMGFMT
445
virtual size: 128M (134217728 bytes)
446
+cluster_size: 1048576
447
+
448
[{ "start": 0, "length": 134217728, "depth": 0, "zero": true, "data": false}]
449
450
=== Successful image creation (explicit defaults) ===
451
452
-Testing:
453
-QMP_VERSION
454
-{"return": {}}
455
-{"return": {}}
456
-{"return": {}}
457
-{"return": {}}
458
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
459
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}}
460
+{u'return': {}}
461
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
462
+{u'return': {}}
463
464
-image: TEST_DIR/t.IMGFMT
465
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'preallocation': 'off', 'driver': 'vdi', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}, 'size': 67108864}}}
466
+{u'return': {}}
467
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
468
+{u'return': {}}
469
+
470
+image: TEST_IMG
471
file format: IMGFMT
472
virtual size: 64M (67108864 bytes)
473
+cluster_size: 1048576
474
+
475
[{ "start": 0, "length": 67108864, "depth": 0, "zero": true, "data": false}]
476
477
=== Successful image creation (with non-default options) ===
478
479
-Testing:
480
-QMP_VERSION
481
-{"return": {}}
482
-{"return": {}}
483
-{"return": {}}
484
-{"return": {}}
485
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
486
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}}}
487
+{u'return': {}}
488
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
489
+{u'return': {}}
490
491
-image: TEST_DIR/t.IMGFMT
492
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'preallocation': 'metadata', 'driver': 'vdi', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.vdi'}, 'size': 33554432}}}
493
+{u'return': {}}
494
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
495
+{u'return': {}}
496
+
497
+image: TEST_IMG
498
file format: IMGFMT
499
virtual size: 32M (33554432 bytes)
500
-[{ "start": 0, "length": 3072, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
501
-{ "start": 3072, "length": 33551360, "depth": 0, "zero": true, "data": true, "offset": OFFSET}]
502
+cluster_size: 1048576
503
504
-=== Invalid BlockdevRef ===
505
+[{ "start": 0, "length": 3072, "depth": 0, "zero": false, "data": true, "offset": 1024},
506
+{ "start": 3072, "length": 33551360, "depth": 0, "zero": true, "data": true, "offset": 4096}]
507
508
-Testing:
509
-QMP_VERSION
510
-{"return": {}}
511
-{"error": {"class": "GenericError", "desc": "Cannot find device=this doesn't exist nor node_name=this doesn't exist"}}
512
-{"return": {}}
513
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
514
+=== Invalid BlockdevRef ===
515
516
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': "this doesn't exist", 'size': 33554432}}}
517
+{u'return': {}}
518
+Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist
519
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
520
+{u'return': {}}
521
522
=== Zero size ===
523
524
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0
525
-QMP_VERSION
526
-{"return": {}}
527
-{"return": {}}
528
-{"return": {}}
529
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
530
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 0}}}
531
+{u'return': {}}
532
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
533
+{u'return': {}}
534
535
-image: TEST_DIR/t.IMGFMT
536
+image: TEST_IMG
537
file format: IMGFMT
538
virtual size: 0 (0 bytes)
539
+cluster_size: 1048576
540
541
=== Maximum size ===
542
543
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0
544
-QMP_VERSION
545
-{"return": {}}
546
-{"return": {}}
547
-{"return": {}}
548
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
549
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 562949819203584}}}
550
+{u'return': {}}
551
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
552
+{u'return': {}}
553
554
-image: TEST_DIR/t.IMGFMT
555
+image: TEST_IMG
556
file format: IMGFMT
557
virtual size: 512T (562949819203584 bytes)
558
+cluster_size: 1048576
559
560
=== Invalid sizes ===
561
562
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0
563
-QMP_VERSION
564
-{"return": {}}
565
-{"error": {"class": "GenericError", "desc": "Unsupported VDI image size (size is 0xfffffffffffffe00, max supported is 0x1fffff8000000)"}}
566
-{"error": {"class": "GenericError", "desc": "Unsupported VDI image size (size is 0x8000000000000000, max supported is 0x1fffff8000000)"}}
567
-{"error": {"class": "GenericError", "desc": "Unsupported VDI image size (size is 0x1fffff8000001, max supported is 0x1fffff8000000)"}}
568
-{"return": {}}
569
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
570
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 18446744073709551104L}}}
571
+{u'return': {}}
572
+Job failed: Unsupported VDI image size (size is 0xfffffffffffffe00, max supported is 0x1fffff8000000)
573
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
574
+{u'return': {}}
575
+
576
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 9223372036854775808L}}}
577
+{u'return': {}}
578
+Job failed: Unsupported VDI image size (size is 0x8000000000000000, max supported is 0x1fffff8000000)
579
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
580
+{u'return': {}}
581
+
582
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'vdi', 'file': 'node0', 'size': 562949819203585}}}
583
+{u'return': {}}
584
+Job failed: Unsupported VDI image size (size is 0x1fffff8000001, max supported is 0x1fffff8000000)
585
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
586
+{u'return': {}}
587
588
-*** done
589
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
590
index XXXXXXX..XXXXXXX 100644
591
--- a/tests/qemu-iotests/group
592
+++ b/tests/qemu-iotests/group
593
@@ -XXX,XX +XXX,XX @@
594
208 rw auto quick
595
209 rw auto quick
596
210 rw auto
597
+211 rw auto quick
598
# TODO The following commented out tests need to be reworked to work
599
# with the x-blockdev-create job
600
-#211 rw auto quick
601
#212 rw auto quick
602
#213 rw auto quick
603
214 rw auto
604
--
36
--
605
2.13.6
37
2.25.3
606
38
607
39
diff view generated by jsdifflib
1
This rewrites the test case 210 to work with the new x-blockdev-create
1
For regular files, we always get BDRV_REQ_ZERO_WRITE behaviour from the
2
job rather than the old synchronous version of the command.
2
OS, so we can advertise the flag and just ignore it.
3
4
All of the test cases stay the same as before, but in order to be able
5
to implement proper job handling, the test case is rewritten in Python.
6
3
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Reviewed-by: Jeff Cody <jcody@redhat.com>
8
Message-Id: <20200424125448.63318-7-kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
10
---
11
tests/qemu-iotests/210 | 393 ++++++++++++++++++------------------------
11
block/file-posix.c | 4 ++++
12
tests/qemu-iotests/210.out | 197 ++++++++++++++-------
12
1 file changed, 4 insertions(+)
13
tests/qemu-iotests/group | 2 +-
14
tests/qemu-iotests/iotests.py | 12 +-
15
4 files changed, 314 insertions(+), 290 deletions(-)
16
13
17
diff --git a/tests/qemu-iotests/210 b/tests/qemu-iotests/210
14
diff --git a/block/file-posix.c b/block/file-posix.c
18
index XXXXXXX..XXXXXXX 100755
19
--- a/tests/qemu-iotests/210
20
+++ b/tests/qemu-iotests/210
21
@@ -XXX,XX +XXX,XX @@
22
-#!/bin/bash
23
+#!/usr/bin/env python
24
#
25
# Test luks and file image creation
26
#
27
# Copyright (C) 2018 Red Hat, Inc.
28
#
29
+# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
30
+#
31
# This program is free software; you can redistribute it and/or modify
32
# it under the terms of the GNU General Public License as published by
33
# the Free Software Foundation; either version 2 of the License, or
34
@@ -XXX,XX +XXX,XX @@
35
# along with this program. If not, see <http://www.gnu.org/licenses/>.
36
#
37
38
-# creator
39
-owner=kwolf@redhat.com
40
-
41
-seq=`basename $0`
42
-echo "QA output created by $seq"
43
-
44
-here=`pwd`
45
-status=1    # failure is the default!
46
-
47
-# get standard environment, filters and checks
48
-. ./common.rc
49
-. ./common.filter
50
-
51
-_supported_fmt luks
52
-_supported_proto file
53
-_supported_os Linux
54
-
55
-function do_run_qemu()
56
-{
57
- echo Testing: "$@"
58
- $QEMU -nographic -qmp stdio -serial none "$@"
59
- echo
60
-}
61
-
62
-function run_qemu()
63
-{
64
- do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp \
65
- | _filter_qemu | _filter_imgfmt \
66
- | _filter_actual_image_size
67
-}
68
-
69
-echo
70
-echo "=== Successful image creation (defaults) ==="
71
-echo
72
-
73
-size=$((128 * 1024 * 1024))
74
-
75
-run_qemu -object secret,id=keysec0,data="foo" <<EOF
76
-{ "execute": "qmp_capabilities" }
77
-{ "execute": "x-blockdev-create",
78
- "arguments": {
79
- "driver": "file",
80
- "filename": "$TEST_IMG_FILE",
81
- "size": 0
82
- }
83
-}
84
-{ "execute": "blockdev-add",
85
- "arguments": {
86
- "driver": "file",
87
- "node-name": "imgfile",
88
- "filename": "$TEST_IMG_FILE"
89
- }
90
-}
91
-{ "execute": "x-blockdev-create",
92
- "arguments": {
93
- "driver": "$IMGFMT",
94
- "file": "imgfile",
95
- "key-secret": "keysec0",
96
- "size": $size,
97
- "iter-time": 10
98
- }
99
-}
100
-{ "execute": "quit" }
101
-EOF
102
-
103
-_img_info --format-specific | _filter_img_info --format-specific
104
-
105
-echo
106
-echo "=== Successful image creation (with non-default options) ==="
107
-echo
108
-
109
-# Choose a different size to show that we got a new image
110
-size=$((64 * 1024 * 1024))
111
-
112
-run_qemu -object secret,id=keysec0,data="foo" <<EOF
113
-{ "execute": "qmp_capabilities" }
114
-{ "execute": "x-blockdev-create",
115
- "arguments": {
116
- "driver": "file",
117
- "filename": "$TEST_IMG_FILE",
118
- "size": 0
119
- }
120
-}
121
-{ "execute": "x-blockdev-create",
122
- "arguments": {
123
- "driver": "$IMGFMT",
124
- "file": {
125
- "driver": "file",
126
- "filename": "$TEST_IMG_FILE"
127
- },
128
- "size": $size,
129
- "key-secret": "keysec0",
130
- "cipher-alg": "twofish-128",
131
- "cipher-mode": "ctr",
132
- "ivgen-alg": "plain64",
133
- "ivgen-hash-alg": "md5",
134
- "hash-alg": "sha1",
135
- "iter-time": 10
136
- }
137
-}
138
-{ "execute": "quit" }
139
-EOF
140
-
141
-_img_info --format-specific | _filter_img_info --format-specific
142
-
143
-echo
144
-echo "=== Invalid BlockdevRef ==="
145
-echo
146
-
147
-run_qemu <<EOF
148
-{ "execute": "qmp_capabilities" }
149
-{ "execute": "x-blockdev-create",
150
- "arguments": {
151
- "driver": "$IMGFMT",
152
- "file": "this doesn't exist",
153
- "size": $size
154
- }
155
-}
156
-{ "execute": "quit" }
157
-EOF
158
-
159
-echo
160
-echo "=== Zero size ==="
161
-echo
162
-
163
-run_qemu -blockdev driver=file,filename="$TEST_IMG_FILE",node-name=node0 \
164
- -object secret,id=keysec0,data="foo" <<EOF
165
-{ "execute": "qmp_capabilities" }
166
-{ "execute": "x-blockdev-create",
167
- "arguments": {
168
- "driver": "$IMGFMT",
169
- "file": "node0",
170
- "key-secret": "keysec0",
171
- "size": 0,
172
- "iter-time": 10
173
- }
174
-}
175
-{ "execute": "quit" }
176
-EOF
177
-
178
-_img_info | _filter_img_info
179
-
180
-
181
-echo
182
-echo "=== Invalid sizes ==="
183
-echo
184
-
185
-# TODO Negative image sizes aren't handled correctly, but this is a problem
186
-# with QAPI's implementation of the 'size' type and affects other commands as
187
-# well. Once this is fixed, we may want to add a test case here.
188
-
189
-# 1. 2^64 - 512
190
-# 2. 2^63 = 8 EB (qemu-img enforces image sizes less than this)
191
-# 3. 2^63 - 512 (generally valid, but with the crypto header the file will
192
-# exceed 63 bits)
193
-
194
-run_qemu -blockdev driver=file,filename="$TEST_IMG_FILE",node-name=node0 \
195
- -object secret,id=keysec0,data="foo" <<EOF
196
-{ "execute": "qmp_capabilities" }
197
-{ "execute": "x-blockdev-create",
198
- "arguments": {
199
- "driver": "$IMGFMT",
200
- "file": "node0",
201
- "key-secret": "keysec0",
202
- "size": 18446744073709551104
203
- }
204
-}
205
-{ "execute": "x-blockdev-create",
206
- "arguments": {
207
- "driver": "$IMGFMT",
208
- "file": "node0",
209
- "key-secret": "keysec0",
210
- "size": 9223372036854775808
211
- }
212
-}
213
-{ "execute": "x-blockdev-create",
214
- "arguments": {
215
- "driver": "$IMGFMT",
216
- "file": "node0",
217
- "key-secret": "keysec0",
218
- "size": 9223372036854775296
219
- }
220
-}
221
-{ "execute": "quit" }
222
-EOF
223
-
224
-echo
225
-echo "=== Resize image with invalid sizes ==="
226
-echo
227
-
228
-run_qemu -blockdev driver=file,filename="$TEST_IMG_FILE",node-name=node0 \
229
- -blockdev driver=luks,file=node0,key-secret=keysec0,node-name=node1 \
230
- -object secret,id=keysec0,data="foo" <<EOF
231
-{ "execute": "qmp_capabilities" }
232
-{ "execute": "block_resize",
233
- "arguments": {
234
- "node-name": "node1",
235
- "size": 9223372036854775296
236
- }
237
-}
238
-{ "execute": "block_resize",
239
- "arguments": {
240
- "node-name": "node1",
241
- "size": 9223372036854775808
242
- }
243
-}
244
-{ "execute": "block_resize",
245
- "arguments": {
246
- "node-name": "node1",
247
- "size": 18446744073709551104
248
- }
249
-}
250
-{ "execute": "block_resize",
251
- "arguments": {
252
- "node-name": "node1",
253
- "size": -9223372036854775808
254
- }
255
-}
256
-{ "execute": "quit" }
257
-EOF
258
-
259
-_img_info | _filter_img_info
260
-
261
-# success, all done
262
-echo "*** done"
263
-rm -f $seq.full
264
-status=0
265
+import iotests
266
+from iotests import imgfmt
267
+
268
+iotests.verify_image_format(supported_fmts=['luks'])
269
+iotests.verify_protocol(supported=['file'])
270
+
271
+def blockdev_create(vm, options):
272
+ result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options)
273
+
274
+ if 'return' in result:
275
+ assert result['return'] == {}
276
+ vm.run_job('job0')
277
+ iotests.log("")
278
+
279
+with iotests.FilePath('t.luks') as disk_path, \
280
+ iotests.VM() as vm:
281
+
282
+ vm.add_object('secret,id=keysec0,data=foo')
283
+
284
+ #
285
+ # Successful image creation (defaults)
286
+ #
287
+ iotests.log("=== Successful image creation (defaults) ===")
288
+ iotests.log("")
289
+
290
+ size = 128 * 1024 * 1024
291
+
292
+ vm.launch()
293
+ blockdev_create(vm, { 'driver': 'file',
294
+ 'filename': disk_path,
295
+ 'size': 0 })
296
+
297
+ vm.qmp_log('blockdev-add', driver='file', filename=disk_path,
298
+ node_name='imgfile')
299
+
300
+ blockdev_create(vm, { 'driver': imgfmt,
301
+ 'file': 'imgfile',
302
+ 'key-secret': 'keysec0',
303
+ 'size': size,
304
+ 'iter-time': 10 })
305
+ vm.shutdown()
306
+
307
+ # TODO Proper support for images to be used with imgopts and/or protocols
308
+ iotests.img_info_log(
309
+ 'driver=luks,file.driver=file,file.filename=%s,key-secret=keysec0' % (disk_path),
310
+ filter_path=disk_path,
311
+ extra_args=['--object', 'secret,id=keysec0,data=foo'],
312
+ imgopts=True)
313
+
314
+ #
315
+ # Successful image creation (with non-default options)
316
+ #
317
+ iotests.log("=== Successful image creation (with non-default options) ===")
318
+ iotests.log("")
319
+
320
+ size = 64 * 1024 * 1024
321
+
322
+ vm.launch()
323
+ blockdev_create(vm, { 'driver': 'file',
324
+ 'filename': disk_path,
325
+ 'size': 0 })
326
+ blockdev_create(vm, { 'driver': imgfmt,
327
+ 'file': {
328
+ 'driver': 'file',
329
+ 'filename': disk_path,
330
+ },
331
+ 'size': size,
332
+ 'key-secret': 'keysec0',
333
+ 'cipher-alg': 'twofish-128',
334
+ 'cipher-mode': 'ctr',
335
+ 'ivgen-alg': 'plain64',
336
+ 'ivgen-hash-alg': 'md5',
337
+ 'hash-alg': 'sha1',
338
+ 'iter-time': 10 })
339
+ vm.shutdown()
340
+
341
+ # TODO Proper support for images to be used with imgopts and/or protocols
342
+ iotests.img_info_log(
343
+ 'driver=luks,file.driver=file,file.filename=%s,key-secret=keysec0' % (disk_path),
344
+ filter_path=disk_path,
345
+ extra_args=['--object', 'secret,id=keysec0,data=foo'],
346
+ imgopts=True)
347
+
348
+ #
349
+ # Invalid BlockdevRef
350
+ #
351
+ iotests.log("=== Invalid BlockdevRef ===")
352
+ iotests.log("")
353
+
354
+ size = 64 * 1024 * 1024
355
+
356
+ vm.launch()
357
+ blockdev_create(vm, { 'driver': imgfmt,
358
+ 'file': "this doesn't exist",
359
+ 'size': size })
360
+ vm.shutdown()
361
+
362
+ #
363
+ # Zero size
364
+ #
365
+ iotests.log("=== Zero size ===")
366
+ iotests.log("")
367
+
368
+ vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path))
369
+ vm.launch()
370
+ blockdev_create(vm, { 'driver': imgfmt,
371
+ 'file': 'node0',
372
+ 'key-secret': 'keysec0',
373
+ 'size': 0,
374
+ 'iter-time': 10 })
375
+ vm.shutdown()
376
+
377
+ # TODO Proper support for images to be used with imgopts and/or protocols
378
+ iotests.img_info_log(
379
+ 'driver=luks,file.driver=file,file.filename=%s,key-secret=keysec0' % (disk_path),
380
+ filter_path=disk_path,
381
+ extra_args=['--object', 'secret,id=keysec0,data=foo'],
382
+ imgopts=True)
383
+
384
+ #
385
+ # Invalid sizes
386
+ #
387
+
388
+ # TODO Negative image sizes aren't handled correctly, but this is a problem
389
+ # with QAPI's implementation of the 'size' type and affects other commands as
390
+ # well. Once this is fixed, we may want to add a test case here.
391
+
392
+ # 1. 2^64 - 512
393
+ # 2. 2^63 = 8 EB (qemu-img enforces image sizes less than this)
394
+ # 3. 2^63 - 512 (generally valid, but with the crypto header the file will
395
+ # exceed 63 bits)
396
+ iotests.log("=== Invalid sizes ===")
397
+ iotests.log("")
398
+
399
+ vm.launch()
400
+ for size in [ 18446744073709551104, 9223372036854775808, 9223372036854775296 ]:
401
+ blockdev_create(vm, { 'driver': imgfmt,
402
+ 'file': 'node0',
403
+ 'key-secret': 'keysec0',
404
+ 'size': size })
405
+ vm.shutdown()
406
+
407
+ #
408
+ # Resize image with invalid sizes
409
+ #
410
+ iotests.log("=== Resize image with invalid sizes ===")
411
+ iotests.log("")
412
+
413
+ vm.add_blockdev('driver=luks,file=node0,key-secret=keysec0,node-name=node1')
414
+ vm.launch()
415
+ vm.qmp_log('block_resize', node_name='node1', size=9223372036854775296)
416
+ vm.qmp_log('block_resize', node_name='node1', size=9223372036854775808)
417
+ vm.qmp_log('block_resize', node_name='node1', size=18446744073709551104)
418
+ vm.qmp_log('block_resize', node_name='node1', size=-9223372036854775808)
419
+ vm.shutdown()
420
+
421
+ # TODO Proper support for images to be used with imgopts and/or protocols
422
+ iotests.img_info_log(
423
+ 'driver=luks,file.driver=file,file.filename=%s,key-secret=keysec0' % (disk_path),
424
+ filter_path=disk_path,
425
+ extra_args=['--object', 'secret,id=keysec0,data=foo'],
426
+ imgopts=True)
427
diff --git a/tests/qemu-iotests/210.out b/tests/qemu-iotests/210.out
428
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
429
--- a/tests/qemu-iotests/210.out
16
--- a/block/file-posix.c
430
+++ b/tests/qemu-iotests/210.out
17
+++ b/block/file-posix.c
431
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
432
-QA output created by 210
19
#endif
433
-
20
434
=== Successful image creation (defaults) ===
21
bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK;
435
22
+ if (S_ISREG(st.st_mode)) {
436
-Testing: -object secret,id=keysec0,data=foo
23
+ /* When extending regular files, we get zeros from the OS */
437
-QMP_VERSION
24
+ bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
438
-{"return": {}}
25
+ }
439
-{"return": {}}
26
ret = 0;
440
-{"return": {}}
27
fail:
441
-{"return": {}}
28
if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
442
-{"return": {}}
443
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
444
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}}}
445
+{u'return': {}}
446
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
447
+{u'return': {}}
448
+
449
+{'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}}
450
+{u'return': {}}
451
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'iter-time': 10, 'driver': 'luks', 'file': 'imgfile', 'size': 134217728}}}
452
+{u'return': {}}
453
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
454
+{u'return': {}}
455
456
-image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "key-secret": "keysec0"}
457
+image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"}
458
file format: IMGFMT
459
virtual size: 128M (134217728 bytes)
460
+encrypted: yes
461
Format specific information:
462
ivgen alg: plain64
463
hash alg: sha256
464
cipher alg: aes-256
465
- uuid: 00000000-0000-0000-0000-000000000000
466
+ uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
467
cipher mode: xts
468
slots:
469
[0]:
470
active: true
471
- iters: 1024
472
+ iters: XXX
473
key offset: 4096
474
stripes: 4000
475
[1]:
476
@@ -XXX,XX +XXX,XX @@ Format specific information:
477
active: false
478
key offset: 1810432
479
payload offset: 2068480
480
- master key iters: 1024
481
+ master key iters: XXX
482
483
=== Successful image creation (with non-default options) ===
484
485
-Testing: -object secret,id=keysec0,data=foo
486
-QMP_VERSION
487
-{"return": {}}
488
-{"return": {}}
489
-{"return": {}}
490
-{"return": {}}
491
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
492
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}}}
493
+{u'return': {}}
494
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
495
+{u'return': {}}
496
+
497
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'hash-alg': 'sha1', 'cipher-mode': 'ctr', 'cipher-alg': 'twofish-128', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}, 'iter-time': 10, 'ivgen-alg': 'plain64', 'ivgen-hash-alg': 'md5', 'driver': 'luks', 'size': 67108864}}}
498
+{u'return': {}}
499
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
500
+{u'return': {}}
501
502
-image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "key-secret": "keysec0"}
503
+image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"}
504
file format: IMGFMT
505
virtual size: 64M (67108864 bytes)
506
+encrypted: yes
507
Format specific information:
508
ivgen alg: plain64
509
hash alg: sha1
510
cipher alg: twofish-128
511
- uuid: 00000000-0000-0000-0000-000000000000
512
+ uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
513
cipher mode: ctr
514
slots:
515
[0]:
516
active: true
517
- iters: 1024
518
+ iters: XXX
519
key offset: 4096
520
stripes: 4000
521
[1]:
522
@@ -XXX,XX +XXX,XX @@ Format specific information:
523
active: false
524
key offset: 462848
525
payload offset: 528384
526
- master key iters: 1024
527
+ master key iters: XXX
528
529
=== Invalid BlockdevRef ===
530
531
-Testing:
532
-QMP_VERSION
533
-{"return": {}}
534
-{"error": {"class": "GenericError", "desc": "Cannot find device=this doesn't exist nor node_name=this doesn't exist"}}
535
-{"return": {}}
536
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
537
-
538
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'luks', 'file': "this doesn't exist", 'size': 67108864}}}
539
+{u'return': {}}
540
+Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist
541
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
542
+{u'return': {}}
543
544
=== Zero size ===
545
546
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -object secret,id=keysec0,data=foo
547
-QMP_VERSION
548
-{"return": {}}
549
-{"return": {}}
550
-{"return": {}}
551
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
552
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'iter-time': 10, 'driver': 'luks', 'file': 'node0', 'size': 0}}}
553
+{u'return': {}}
554
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
555
+{u'return': {}}
556
557
-image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "key-secret": "keysec0"}
558
+image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"}
559
file format: IMGFMT
560
virtual size: 0 (0 bytes)
561
+encrypted: yes
562
+Format specific information:
563
+ ivgen alg: plain64
564
+ hash alg: sha256
565
+ cipher alg: aes-256
566
+ uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
567
+ cipher mode: xts
568
+ slots:
569
+ [0]:
570
+ active: true
571
+ iters: XXX
572
+ key offset: 4096
573
+ stripes: 4000
574
+ [1]:
575
+ active: false
576
+ key offset: 262144
577
+ [2]:
578
+ active: false
579
+ key offset: 520192
580
+ [3]:
581
+ active: false
582
+ key offset: 778240
583
+ [4]:
584
+ active: false
585
+ key offset: 1036288
586
+ [5]:
587
+ active: false
588
+ key offset: 1294336
589
+ [6]:
590
+ active: false
591
+ key offset: 1552384
592
+ [7]:
593
+ active: false
594
+ key offset: 1810432
595
+ payload offset: 2068480
596
+ master key iters: XXX
597
598
=== Invalid sizes ===
599
600
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -object secret,id=keysec0,data=foo
601
-QMP_VERSION
602
-{"return": {}}
603
-{"error": {"class": "GenericError", "desc": "The requested file size is too large"}}
604
-{"error": {"class": "GenericError", "desc": "The requested file size is too large"}}
605
-{"error": {"class": "GenericError", "desc": "The requested file size is too large"}}
606
-{"return": {}}
607
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
608
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 18446744073709551104L}}}
609
+{u'return': {}}
610
+Job failed: The requested file size is too large
611
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
612
+{u'return': {}}
613
+
614
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 9223372036854775808L}}}
615
+{u'return': {}}
616
+Job failed: The requested file size is too large
617
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
618
+{u'return': {}}
619
620
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 9223372036854775296}}}
621
+{u'return': {}}
622
+Job failed: The requested file size is too large
623
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
624
+{u'return': {}}
625
626
=== Resize image with invalid sizes ===
627
628
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -blockdev driver=IMGFMT,file=node0,key-secret=keysec0,node-name=node1 -object secret,id=keysec0,data=foo
629
-QMP_VERSION
630
-{"return": {}}
631
-{"error": {"class": "GenericError", "desc": "The requested file size is too large"}}
632
-{"error": {"class": "GenericError", "desc": "Invalid parameter type for 'size', expected: integer"}}
633
-{"error": {"class": "GenericError", "desc": "Invalid parameter type for 'size', expected: integer"}}
634
-{"error": {"class": "GenericError", "desc": "Parameter 'size' expects a >0 size"}}
635
-{"return": {}}
636
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
637
-
638
-image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "key-secret": "keysec0"}
639
+{'execute': 'block_resize', 'arguments': {'size': 9223372036854775296, 'node_name': 'node1'}}
640
+{u'error': {u'class': u'GenericError', u'desc': u'The requested file size is too large'}}
641
+{'execute': 'block_resize', 'arguments': {'size': 9223372036854775808L, 'node_name': 'node1'}}
642
+{u'error': {u'class': u'GenericError', u'desc': u"Invalid parameter type for 'size', expected: integer"}}
643
+{'execute': 'block_resize', 'arguments': {'size': 18446744073709551104L, 'node_name': 'node1'}}
644
+{u'error': {u'class': u'GenericError', u'desc': u"Invalid parameter type for 'size', expected: integer"}}
645
+{'execute': 'block_resize', 'arguments': {'size': -9223372036854775808, 'node_name': 'node1'}}
646
+{u'error': {u'class': u'GenericError', u'desc': u"Parameter 'size' expects a >0 size"}}
647
+image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"}
648
file format: IMGFMT
649
virtual size: 0 (0 bytes)
650
-*** done
651
+encrypted: yes
652
+Format specific information:
653
+ ivgen alg: plain64
654
+ hash alg: sha256
655
+ cipher alg: aes-256
656
+ uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
657
+ cipher mode: xts
658
+ slots:
659
+ [0]:
660
+ active: true
661
+ iters: XXX
662
+ key offset: 4096
663
+ stripes: 4000
664
+ [1]:
665
+ active: false
666
+ key offset: 262144
667
+ [2]:
668
+ active: false
669
+ key offset: 520192
670
+ [3]:
671
+ active: false
672
+ key offset: 778240
673
+ [4]:
674
+ active: false
675
+ key offset: 1036288
676
+ [5]:
677
+ active: false
678
+ key offset: 1294336
679
+ [6]:
680
+ active: false
681
+ key offset: 1552384
682
+ [7]:
683
+ active: false
684
+ key offset: 1810432
685
+ payload offset: 2068480
686
+ master key iters: XXX
687
+
688
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
689
index XXXXXXX..XXXXXXX 100644
690
--- a/tests/qemu-iotests/group
691
+++ b/tests/qemu-iotests/group
692
@@ -XXX,XX +XXX,XX @@
693
207 rw auto
694
208 rw auto quick
695
209 rw auto quick
696
+210 rw auto
697
# TODO The following commented out tests need to be reworked to work
698
# with the x-blockdev-create job
699
-#210 rw auto
700
#211 rw auto quick
701
#212 rw auto quick
702
#213 rw auto quick
703
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
704
index XXXXXXX..XXXXXXX 100644
705
--- a/tests/qemu-iotests/iotests.py
706
+++ b/tests/qemu-iotests/iotests.py
707
@@ -XXX,XX +XXX,XX @@ def qemu_img_pipe(*args):
708
sys.stderr.write('qemu-img received signal %i: %s\n' % (-exitcode, ' '.join(qemu_img_args + list(args))))
709
return subp.communicate()[0]
710
711
-def img_info_log(filename, filter_path=None):
712
- output = qemu_img_pipe('info', '-f', imgfmt, filename)
713
+def img_info_log(filename, filter_path=None, imgopts=False, extra_args=[]):
714
+ args = [ 'info' ]
715
+ if imgopts:
716
+ args.append('--image-opts')
717
+ else:
718
+ args += [ '-f', imgfmt ]
719
+ args += extra_args
720
+ args.append(filename)
721
+
722
+ output = qemu_img_pipe(*args)
723
if not filter_path:
724
filter_path = filename
725
log(filter_img_info(output, filter_path))
726
--
29
--
727
2.13.6
30
2.25.3
728
31
729
32
diff view generated by jsdifflib
1
This rewrites the test case 206 to work with the new x-blockdev-create
1
When extending the size of an image that has a backing file larger than
2
job rather than the old synchronous version of the command.
2
its old size, make sure that the backing file data doesn't become
3
visible in the guest, but the added area is properly zeroed out.
3
4
4
All of the test cases stay the same as before, but in order to be able
5
Consider the following scenario where the overlay is shorter than its
5
to implement proper job handling, the test case is rewritten in Python.
6
backing file:
7
8
base.qcow2: AAAAAAAA
9
overlay.qcow2: BBBB
10
11
When resizing (extending) overlay.qcow2, the new blocks should not stay
12
unallocated and make the additional As from base.qcow2 visible like
13
before this patch, but zeros should be read.
14
15
A similar case happens with the various variants of a commit job when an
16
intermediate file is short (- for unallocated):
17
18
base.qcow2: A-A-AAAA
19
mid.qcow2: BB-B
20
top.qcow2: C--C--C-
21
22
After commit top.qcow2 to mid.qcow2, the following happens:
23
24
mid.qcow2: CB-C00C0 (correct result)
25
mid.qcow2: CB-C--C- (before this fix)
26
27
Without the fix, blocks that previously read as zeros on top.qcow2
28
suddenly turn into A.
6
29
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
30
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
31
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
32
Message-Id: <20200424125448.63318-8-kwolf@redhat.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
33
Reviewed-by: Max Reitz <mreitz@redhat.com>
34
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
35
---
10
tests/qemu-iotests/206 | 680 ++++++++++++++++++---------------------------
36
block/io.c | 25 +++++++++++++++++++++++++
11
tests/qemu-iotests/206.out | 253 ++++++++++-------
37
1 file changed, 25 insertions(+)
12
tests/qemu-iotests/group | 2 +-
13
3 files changed, 414 insertions(+), 521 deletions(-)
14
38
15
diff --git a/tests/qemu-iotests/206 b/tests/qemu-iotests/206
39
diff --git a/block/io.c b/block/io.c
16
index XXXXXXX..XXXXXXX 100755
40
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/qemu-iotests/206
41
--- a/block/io.c
18
+++ b/tests/qemu-iotests/206
42
+++ b/block/io.c
19
@@ -XXX,XX +XXX,XX @@
43
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
20
-#!/bin/bash
44
goto out;
21
+#!/usr/bin/env python
45
}
22
#
46
23
# Test qcow2 and file image creation
47
+ /*
24
#
48
+ * If the image has a backing file that is large enough that it would
25
# Copyright (C) 2018 Red Hat, Inc.
49
+ * provide data for the new area, we cannot leave it unallocated because
26
#
50
+ * then the backing file content would become visible. Instead, zero-fill
27
+# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
51
+ * the new area.
28
+#
52
+ *
29
# This program is free software; you can redistribute it and/or modify
53
+ * Note that if the image has a backing file, but was opened without the
30
# it under the terms of the GNU General Public License as published by
54
+ * backing file, taking care of keeping things consistent with that backing
31
# the Free Software Foundation; either version 2 of the License, or
55
+ * file is the user's responsibility.
32
@@ -XXX,XX +XXX,XX @@
56
+ */
33
# along with this program. If not, see <http://www.gnu.org/licenses/>.
57
+ if (new_bytes && bs->backing) {
34
#
58
+ int64_t backing_len;
35
36
-# creator
37
-owner=kwolf@redhat.com
38
-
39
-seq=`basename $0`
40
-echo "QA output created by $seq"
41
-
42
-here=`pwd`
43
-status=1    # failure is the default!
44
-
45
-# get standard environment, filters and checks
46
-. ./common.rc
47
-. ./common.filter
48
-
49
-_supported_fmt qcow2
50
-_supported_proto file
51
-_supported_os Linux
52
-
53
-function do_run_qemu()
54
-{
55
- echo Testing: "$@"
56
- $QEMU -nographic -qmp stdio -serial none "$@"
57
- echo
58
-}
59
-
60
-function run_qemu()
61
-{
62
- do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp \
63
- | _filter_qemu | _filter_imgfmt \
64
- | _filter_actual_image_size
65
-}
66
-
67
-echo
68
-echo "=== Successful image creation (defaults) ==="
69
-echo
70
-
71
-size=$((128 * 1024 * 1024))
72
-
73
-run_qemu <<EOF
74
-{ "execute": "qmp_capabilities" }
75
-{ "execute": "x-blockdev-create",
76
- "arguments": {
77
- "driver": "file",
78
- "filename": "$TEST_IMG",
79
- "size": 0
80
- }
81
-}
82
-{ "execute": "blockdev-add",
83
- "arguments": {
84
- "driver": "file",
85
- "node-name": "imgfile",
86
- "filename": "$TEST_IMG"
87
- }
88
-}
89
-{ "execute": "x-blockdev-create",
90
- "arguments": {
91
- "driver": "$IMGFMT",
92
- "file": "imgfile",
93
- "size": $size
94
- }
95
-}
96
-{ "execute": "quit" }
97
-EOF
98
-
99
-_img_info --format-specific
100
-
101
-echo
102
-echo "=== Successful image creation (inline blockdev-add, explicit defaults) ==="
103
-echo
104
-
105
-# Choose a different size to show that we got a new image
106
-size=$((64 * 1024 * 1024))
107
-
108
-run_qemu <<EOF
109
-{ "execute": "qmp_capabilities" }
110
-{ "execute": "x-blockdev-create",
111
- "arguments": {
112
- "driver": "file",
113
- "filename": "$TEST_IMG",
114
- "size": 0,
115
- "preallocation": "off",
116
- "nocow": false
117
- }
118
-}
119
-{ "execute": "x-blockdev-create",
120
- "arguments": {
121
- "driver": "$IMGFMT",
122
- "file": {
123
- "driver": "file",
124
- "filename": "$TEST_IMG"
125
- },
126
- "size": $size,
127
- "version": "v3",
128
- "cluster-size": 65536,
129
- "preallocation": "off",
130
- "lazy-refcounts": false,
131
- "refcount-bits": 16
132
- }
133
-}
134
-{ "execute": "quit" }
135
-EOF
136
-
137
-_img_info --format-specific
138
-
139
-echo
140
-echo "=== Successful image creation (v3 non-default options) ==="
141
-echo
142
-
143
-# Choose a different size to show that we got a new image
144
-size=$((32 * 1024 * 1024))
145
-
146
-run_qemu <<EOF
147
-{ "execute": "qmp_capabilities" }
148
-{ "execute": "x-blockdev-create",
149
- "arguments": {
150
- "driver": "file",
151
- "filename": "$TEST_IMG",
152
- "size": 0,
153
- "preallocation": "falloc",
154
- "nocow": true
155
- }
156
-}
157
-{ "execute": "x-blockdev-create",
158
- "arguments": {
159
- "driver": "$IMGFMT",
160
- "file": {
161
- "driver": "file",
162
- "filename": "$TEST_IMG"
163
- },
164
- "size": $size,
165
- "version": "v3",
166
- "cluster-size": 2097152,
167
- "preallocation": "metadata",
168
- "lazy-refcounts": true,
169
- "refcount-bits": 1
170
- }
171
-}
172
-{ "execute": "quit" }
173
-EOF
174
-
175
-_img_info --format-specific
176
-
177
-echo
178
-echo "=== Successful image creation (v2 non-default options) ==="
179
-echo
180
-
181
-mv $TEST_IMG $TEST_IMG.base
182
-
183
-run_qemu <<EOF
184
-{ "execute": "qmp_capabilities" }
185
-{ "execute": "x-blockdev-create",
186
- "arguments": {
187
- "driver": "file",
188
- "filename": "$TEST_IMG",
189
- "size": 0
190
- }
191
-}
192
-{ "execute": "x-blockdev-create",
193
- "arguments": {
194
- "driver": "$IMGFMT",
195
- "file": {
196
- "driver": "file",
197
- "filename": "$TEST_IMG"
198
- },
199
- "size": $size,
200
- "backing-file": "$TEST_IMG.base",
201
- "backing-fmt": "qcow2",
202
- "version": "v2",
203
- "cluster-size": 512
204
- }
205
-}
206
-{ "execute": "quit" }
207
-EOF
208
-
209
-_img_info --format-specific
210
-
211
-echo
212
-echo "=== Successful image creation (encrypted) ==="
213
-echo
214
-
215
-run_qemu -object secret,id=keysec0,data="foo" <<EOF
216
-{ "execute": "qmp_capabilities" }
217
-{ "execute": "x-blockdev-create",
218
- "arguments": {
219
- "driver": "$IMGFMT",
220
- "file": {
221
- "driver": "file",
222
- "filename": "$TEST_IMG"
223
- },
224
- "size": $size,
225
- "encrypt": {
226
- "format": "luks",
227
- "key-secret": "keysec0",
228
- "cipher-alg": "twofish-128",
229
- "cipher-mode": "ctr",
230
- "ivgen-alg": "plain64",
231
- "ivgen-hash-alg": "md5",
232
- "hash-alg": "sha1",
233
- "iter-time": 10
234
- }
235
- }
236
-}
237
-{ "execute": "quit" }
238
-EOF
239
-
240
-_img_info --format-specific | _filter_img_info --format-specific
241
-
242
-echo
243
-echo "=== Invalid BlockdevRef ==="
244
-echo
245
-
246
-run_qemu <<EOF
247
-{ "execute": "qmp_capabilities" }
248
-{ "execute": "x-blockdev-create",
249
- "arguments": {
250
- "driver": "$IMGFMT",
251
- "file": "this doesn't exist",
252
- "size": $size
253
- }
254
-}
255
-{ "execute": "quit" }
256
-EOF
257
-
258
-
259
-echo
260
-echo "=== Invalid sizes ==="
261
-echo
262
-
263
-# TODO Negative image sizes aren't handled correctly, but this is a problem
264
-# with QAPI's implementation of the 'size' type and affects other commands as
265
-# well. Once this is fixed, we may want to add a test case here.
266
-
267
-# 1. Misaligned image size
268
-# 2. 2^64 - 512
269
-# 3. 2^63 = 8 EB (qemu-img enforces image sizes less than this)
270
-# 4. 2^63 - 512 (generally valid, but qcow2 can't handle images this size)
271
-
272
-run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF
273
-{ "execute": "qmp_capabilities" }
274
-{ "execute": "x-blockdev-create",
275
- "arguments": {
276
- "driver": "$IMGFMT",
277
- "file": "node0",
278
- "size": 1234
279
- }
280
-}
281
-{ "execute": "x-blockdev-create",
282
- "arguments": {
283
- "driver": "$IMGFMT",
284
- "file": "node0",
285
- "size": 18446744073709551104
286
- }
287
-}
288
-{ "execute": "x-blockdev-create",
289
- "arguments": {
290
- "driver": "$IMGFMT",
291
- "file": "node0",
292
- "size": 9223372036854775808
293
- }
294
-}
295
-{ "execute": "x-blockdev-create",
296
- "arguments": {
297
- "driver": "$IMGFMT",
298
- "file": "node0",
299
- "size": 9223372036854775296
300
- }
301
-}
302
-{ "execute": "quit" }
303
-EOF
304
-
305
-echo
306
-echo "=== Invalid version ==="
307
-echo
308
-
309
-run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF
310
-{ "execute": "qmp_capabilities" }
311
-{ "execute": "x-blockdev-create",
312
- "arguments": {
313
- "driver": "$IMGFMT",
314
- "file": "node0",
315
- "size": 67108864,
316
- "version": "v1"
317
- }
318
-}
319
-{ "execute": "x-blockdev-create",
320
- "arguments": {
321
- "driver": "$IMGFMT",
322
- "file": "node0",
323
- "size": 67108864,
324
- "version": "v2",
325
- "lazy-refcounts": true
326
- }
327
-}
328
-{ "execute": "x-blockdev-create",
329
- "arguments": {
330
- "driver": "$IMGFMT",
331
- "file": "node0",
332
- "size": 67108864,
333
- "version": "v2",
334
- "refcount-bits": 8
335
- }
336
-}
337
-{ "execute": "quit" }
338
-EOF
339
-
340
-echo
341
-echo "=== Invalid backing file options ==="
342
-echo
343
-
344
-run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF
345
-{ "execute": "qmp_capabilities" }
346
-{ "execute": "x-blockdev-create",
347
- "arguments": {
348
- "driver": "$IMGFMT",
349
- "file": "node0",
350
- "size": 67108864,
351
- "backing-file": "/dev/null",
352
- "preallocation": "full"
353
- }
354
-}
355
-{ "execute": "x-blockdev-create",
356
- "arguments": {
357
- "driver": "$IMGFMT",
358
- "file": "node0",
359
- "size": 67108864,
360
- "backing-fmt": "$IMGFMT"
361
- }
362
-}
363
-{ "execute": "quit" }
364
-EOF
365
-
366
-echo
367
-echo "=== Invalid cluster size ==="
368
-echo
369
-
370
-run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF
371
-{ "execute": "qmp_capabilities" }
372
-{ "execute": "x-blockdev-create",
373
- "arguments": {
374
- "driver": "$IMGFMT",
375
- "file": "node0",
376
- "size": 67108864,
377
- "cluster-size": 1234
378
- }
379
-}
380
-{ "execute": "x-blockdev-create",
381
- "arguments": {
382
- "driver": "$IMGFMT",
383
- "file": "node0",
384
- "size": 67108864,
385
- "cluster-size": 128
386
- }
387
-}
388
-{ "execute": "x-blockdev-create",
389
- "arguments": {
390
- "driver": "$IMGFMT",
391
- "file": "node0",
392
- "size": 67108864,
393
- "cluster-size": 4194304
394
- }
395
-}
396
-{ "execute": "x-blockdev-create",
397
- "arguments": {
398
- "driver": "$IMGFMT",
399
- "file": "node0",
400
- "size": 67108864,
401
- "cluster-size": 0
402
- }
403
-}
404
-{ "execute": "x-blockdev-create",
405
- "arguments": {
406
- "driver": "$IMGFMT",
407
- "file": "node0",
408
- "size": 281474976710656,
409
- "cluster-size": 512
410
- }
411
-}
412
-{ "execute": "quit" }
413
-EOF
414
-
415
-echo
416
-echo "=== Invalid refcount width ==="
417
-echo
418
-
419
-run_qemu -blockdev driver=file,filename="$TEST_IMG",node-name=node0 <<EOF
420
-{ "execute": "qmp_capabilities" }
421
-{ "execute": "x-blockdev-create",
422
- "arguments": {
423
- "driver": "$IMGFMT",
424
- "file": "node0",
425
- "size": 67108864,
426
- "refcount-bits": 128
427
- }
428
-}
429
-{ "execute": "x-blockdev-create",
430
- "arguments": {
431
- "driver": "$IMGFMT",
432
- "file": "node0",
433
- "size": 67108864,
434
- "refcount-bits": 0
435
- }
436
-}
437
-{ "execute": "x-blockdev-create",
438
- "arguments": {
439
- "driver": "$IMGFMT",
440
- "file": "node0",
441
- "size": 67108864,
442
- "refcount-bits": 7
443
- }
444
-}
445
-{ "execute": "quit" }
446
-EOF
447
-
448
-# success, all done
449
-echo "*** done"
450
-rm -f $seq.full
451
-status=0
452
+import iotests
453
+from iotests import imgfmt
454
+
59
+
455
+iotests.verify_image_format(supported_fmts=['qcow2'])
60
+ backing_len = bdrv_getlength(backing_bs(bs));
61
+ if (backing_len < 0) {
62
+ ret = backing_len;
63
+ error_setg_errno(errp, -ret, "Could not get backing file size");
64
+ goto out;
65
+ }
456
+
66
+
457
+def blockdev_create(vm, options):
67
+ if (backing_len > old_size) {
458
+ result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options)
68
+ flags |= BDRV_REQ_ZERO_WRITE;
69
+ }
70
+ }
459
+
71
+
460
+ if 'return' in result:
72
if (drv->bdrv_co_truncate) {
461
+ assert result['return'] == {}
73
if (flags & ~bs->supported_truncate_flags) {
462
+ vm.run_job('job0')
74
error_setg(errp, "Block driver does not support requested flags");
463
+ iotests.log("")
464
+
465
+with iotests.FilePath('t.qcow2') as disk_path, \
466
+ iotests.FilePath('t.qcow2.base') as backing_path, \
467
+ iotests.VM() as vm:
468
+
469
+ vm.add_object('secret,id=keysec0,data=foo')
470
+
471
+ #
472
+ # Successful image creation (defaults)
473
+ #
474
+ iotests.log("=== Successful image creation (defaults) ===")
475
+ iotests.log("")
476
+
477
+ size = 128 * 1024 * 1024
478
+
479
+ vm.launch()
480
+ blockdev_create(vm, { 'driver': 'file',
481
+ 'filename': disk_path,
482
+ 'size': 0 })
483
+
484
+ vm.qmp_log('blockdev-add', driver='file', filename=disk_path,
485
+ node_name='imgfile')
486
+
487
+ blockdev_create(vm, { 'driver': imgfmt,
488
+ 'file': 'imgfile',
489
+ 'size': size })
490
+ vm.shutdown()
491
+
492
+ iotests.img_info_log(disk_path)
493
+
494
+ #
495
+ # Successful image creation (inline blockdev-add, explicit defaults)
496
+ #
497
+ iotests.log("=== Successful image creation (inline blockdev-add, explicit defaults) ===")
498
+ iotests.log("")
499
+
500
+ # Choose a different size to show that we got a new image
501
+ size = 64 * 1024 * 1024
502
+
503
+ vm.launch()
504
+ blockdev_create(vm, { 'driver': 'file',
505
+ 'filename': disk_path,
506
+ 'size': 0,
507
+ 'preallocation': 'off',
508
+ 'nocow': False })
509
+
510
+ blockdev_create(vm, { 'driver': imgfmt,
511
+ 'file': {
512
+ 'driver': 'file',
513
+ 'filename': disk_path,
514
+ },
515
+ 'size': size,
516
+ 'version': 'v3',
517
+ 'cluster-size': 65536,
518
+ 'preallocation': 'off',
519
+ 'lazy-refcounts': False,
520
+ 'refcount-bits': 16 })
521
+ vm.shutdown()
522
+
523
+ iotests.img_info_log(disk_path)
524
+
525
+ #
526
+ # Successful image creation (v3 non-default options)
527
+ #
528
+ iotests.log("=== Successful image creation (v3 non-default options) ===")
529
+ iotests.log("")
530
+
531
+ # Choose a different size to show that we got a new image
532
+ size = 32 * 1024 * 1024
533
+
534
+ vm.launch()
535
+ blockdev_create(vm, { 'driver': 'file',
536
+ 'filename': disk_path,
537
+ 'size': 0,
538
+ 'preallocation': 'falloc',
539
+ 'nocow': True })
540
+
541
+ blockdev_create(vm, { 'driver': imgfmt,
542
+ 'file': {
543
+ 'driver': 'file',
544
+ 'filename': disk_path,
545
+ },
546
+ 'size': size,
547
+ 'version': 'v3',
548
+ 'cluster-size': 2097152,
549
+ 'preallocation': 'metadata',
550
+ 'lazy-refcounts': True,
551
+ 'refcount-bits': 1 })
552
+ vm.shutdown()
553
+
554
+ iotests.img_info_log(disk_path)
555
+
556
+ #
557
+ # Successful image creation (v2 non-default options)
558
+ #
559
+ iotests.log("=== Successful image creation (v2 non-default options) ===")
560
+ iotests.log("")
561
+
562
+ vm.launch()
563
+ blockdev_create(vm, { 'driver': 'file',
564
+ 'filename': disk_path,
565
+ 'size': 0 })
566
+
567
+ blockdev_create(vm, { 'driver': imgfmt,
568
+ 'file': {
569
+ 'driver': 'file',
570
+ 'filename': disk_path,
571
+ },
572
+ 'size': size,
573
+ 'backing-file': backing_path,
574
+ 'backing-fmt': 'qcow2',
575
+ 'version': 'v2',
576
+ 'cluster-size': 512 })
577
+ vm.shutdown()
578
+
579
+ iotests.img_info_log(disk_path)
580
+
581
+ #
582
+ # Successful image creation (encrypted)
583
+ #
584
+ iotests.log("=== Successful image creation (encrypted) ===")
585
+ iotests.log("")
586
+
587
+ vm.launch()
588
+ blockdev_create(vm, { 'driver': imgfmt,
589
+ 'file': {
590
+ 'driver': 'file',
591
+ 'filename': disk_path,
592
+ },
593
+ 'size': size,
594
+ 'encrypt': {
595
+ 'format': 'luks',
596
+ 'key-secret': 'keysec0',
597
+ 'cipher-alg': 'twofish-128',
598
+ 'cipher-mode': 'ctr',
599
+ 'ivgen-alg': 'plain64',
600
+ 'ivgen-hash-alg': 'md5',
601
+ 'hash-alg': 'sha1',
602
+ 'iter-time': 10,
603
+ }})
604
+ vm.shutdown()
605
+
606
+ iotests.img_info_log(disk_path)
607
+
608
+ #
609
+ # Invalid BlockdevRef
610
+ #
611
+ iotests.log("=== Invalid BlockdevRef ===")
612
+ iotests.log("")
613
+
614
+ vm.launch()
615
+ blockdev_create(vm, { 'driver': imgfmt,
616
+ 'file': "this doesn't exist",
617
+ 'size': size })
618
+ vm.shutdown()
619
+
620
+ #
621
+ # Invalid sizes
622
+ #
623
+ iotests.log("=== Invalid sizes ===")
624
+
625
+ # TODO Negative image sizes aren't handled correctly, but this is a problem
626
+ # with QAPI's implementation of the 'size' type and affects other commands
627
+ # as well. Once this is fixed, we may want to add a test case here.
628
+ #
629
+ # 1. Misaligned image size
630
+ # 2. 2^64 - 512
631
+ # 3. 2^63 = 8 EB (qemu-img enforces image sizes less than this)
632
+ # 4. 2^63 - 512 (generally valid, but qcow2 can't handle images this size)
633
+
634
+ vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path))
635
+
636
+ vm.launch()
637
+ for size in [ 1234, 18446744073709551104, 9223372036854775808,
638
+ 9223372036854775296 ]:
639
+ blockdev_create(vm, { 'driver': imgfmt,
640
+ 'file': 'node0',
641
+ 'size': size })
642
+ vm.shutdown()
643
+
644
+ #
645
+ # Invalid version
646
+ #
647
+ iotests.log("=== Invalid version ===")
648
+
649
+ vm.launch()
650
+ blockdev_create(vm, { 'driver': imgfmt,
651
+ 'file': 'node0',
652
+ 'size': 67108864,
653
+ 'version': 'v1' })
654
+ blockdev_create(vm, { 'driver': imgfmt,
655
+ 'file': 'node0',
656
+ 'size': 67108864,
657
+ 'version': 'v2',
658
+ 'lazy-refcounts': True })
659
+ blockdev_create(vm, { 'driver': imgfmt,
660
+ 'file': 'node0',
661
+ 'size': 67108864,
662
+ 'version': 'v2',
663
+ 'refcount-bits': 8 })
664
+ vm.shutdown()
665
+
666
+ #
667
+ # Invalid backing file options
668
+ #
669
+ iotests.log("=== Invalid backing file options ===")
670
+
671
+ vm.launch()
672
+ blockdev_create(vm, { 'driver': imgfmt,
673
+ 'file': 'node0',
674
+ 'size': 67108864,
675
+ 'backing-file': '/dev/null',
676
+ 'preallocation': 'full' })
677
+ blockdev_create(vm, { 'driver': imgfmt,
678
+ 'file': 'node0',
679
+ 'size': 67108864,
680
+ 'backing-fmt': imgfmt })
681
+ vm.shutdown()
682
+
683
+ #
684
+ # Invalid cluster size
685
+ #
686
+ iotests.log("=== Invalid cluster size ===")
687
+
688
+ vm.launch()
689
+ for csize in [ 1234, 128, 4194304, 0 ]:
690
+ blockdev_create(vm, { 'driver': imgfmt,
691
+ 'file': 'node0',
692
+ 'size': 67108864,
693
+ 'cluster-size': csize })
694
+ blockdev_create(vm, { 'driver': imgfmt,
695
+ 'file': 'node0',
696
+ 'size': 281474976710656,
697
+ 'cluster-size': 512 })
698
+ vm.shutdown()
699
+
700
+ #
701
+ # Invalid refcount width
702
+ #
703
+ iotests.log("=== Invalid refcount width ===")
704
+
705
+ vm.launch()
706
+ for refcount_bits in [ 128, 0, 7 ]:
707
+ blockdev_create(vm, { 'driver': imgfmt,
708
+ 'file': 'node0',
709
+ 'size': 67108864,
710
+ 'refcount-bits': refcount_bits })
711
+ vm.shutdown()
712
diff --git a/tests/qemu-iotests/206.out b/tests/qemu-iotests/206.out
713
index XXXXXXX..XXXXXXX 100644
714
--- a/tests/qemu-iotests/206.out
715
+++ b/tests/qemu-iotests/206.out
716
@@ -XXX,XX +XXX,XX @@
717
-QA output created by 206
718
-
719
=== Successful image creation (defaults) ===
720
721
-Testing:
722
-QMP_VERSION
723
-{"return": {}}
724
-{"return": {}}
725
-{"return": {}}
726
-{"return": {}}
727
-{"return": {}}
728
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
729
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}}
730
+{u'return': {}}
731
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
732
+{u'return': {}}
733
+
734
+{'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}
735
+{u'return': {}}
736
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'imgfile', 'size': 134217728}}}
737
+{u'return': {}}
738
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
739
+{u'return': {}}
740
741
-image: TEST_DIR/t.IMGFMT
742
+image: TEST_IMG
743
file format: IMGFMT
744
virtual size: 128M (134217728 bytes)
745
cluster_size: 65536
746
@@ -XXX,XX +XXX,XX @@ Format specific information:
747
748
=== Successful image creation (inline blockdev-add, explicit defaults) ===
749
750
-Testing:
751
-QMP_VERSION
752
-{"return": {}}
753
-{"return": {}}
754
-{"return": {}}
755
-{"return": {}}
756
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
757
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'nocow': False, 'preallocation': 'off', 'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}}
758
+{u'return': {}}
759
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
760
+{u'return': {}}
761
762
-image: TEST_DIR/t.IMGFMT
763
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 65536, 'refcount-bits': 16, 'version': 'v3', 'preallocation': 'off', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'lazy-refcounts': False, 'driver': 'qcow2', 'size': 67108864}}}
764
+{u'return': {}}
765
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
766
+{u'return': {}}
767
+
768
+image: TEST_IMG
769
file format: IMGFMT
770
virtual size: 64M (67108864 bytes)
771
cluster_size: 65536
772
@@ -XXX,XX +XXX,XX @@ Format specific information:
773
774
=== Successful image creation (v3 non-default options) ===
775
776
-Testing:
777
-QMP_VERSION
778
-{"return": {}}
779
-{"return": {}}
780
-{"return": {}}
781
-{"return": {}}
782
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
783
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'nocow': True, 'preallocation': 'falloc', 'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}}
784
+{u'return': {}}
785
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
786
+{u'return': {}}
787
+
788
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 2097152, 'refcount-bits': 1, 'version': 'v3', 'preallocation': 'metadata', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'lazy-refcounts': True, 'driver': 'qcow2', 'size': 33554432}}}
789
+{u'return': {}}
790
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
791
+{u'return': {}}
792
793
-image: TEST_DIR/t.IMGFMT
794
+image: TEST_IMG
795
file format: IMGFMT
796
virtual size: 32M (33554432 bytes)
797
cluster_size: 2097152
798
@@ -XXX,XX +XXX,XX @@ Format specific information:
799
800
=== Successful image creation (v2 non-default options) ===
801
802
-Testing:
803
-QMP_VERSION
804
-{"return": {}}
805
-{"return": {}}
806
-{"return": {}}
807
-{"return": {}}
808
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
809
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}}}
810
+{u'return': {}}
811
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
812
+{u'return': {}}
813
814
-image: TEST_DIR/t.IMGFMT
815
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 512, 'backing-fmt': 'qcow2', 'driver': 'qcow2', 'version': 'v2', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'backing-file': 'TEST_DIR/PID-t.qcow2.base', 'size': 33554432}}}
816
+{u'return': {}}
817
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
818
+{u'return': {}}
819
+
820
+image: TEST_IMG
821
file format: IMGFMT
822
virtual size: 32M (33554432 bytes)
823
cluster_size: 512
824
-backing file: TEST_DIR/t.IMGFMT.base
825
+backing file: TEST_IMG.base
826
backing file format: IMGFMT
827
Format specific information:
828
compat: 0.10
829
@@ -XXX,XX +XXX,XX @@ Format specific information:
830
831
=== Successful image creation (encrypted) ===
832
833
-Testing: -object secret,id=keysec0,data=foo
834
-QMP_VERSION
835
-{"return": {}}
836
-{"return": {}}
837
-{"return": {}}
838
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
839
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'encrypt': {'key-secret': 'keysec0', 'iter-time': 10, 'cipher-mode': 'ctr', 'ivgen-hash-alg': 'md5', 'cipher-alg': 'twofish-128', 'format': 'luks', 'ivgen-alg': 'plain64', 'hash-alg': 'sha1'}, 'driver': 'qcow2', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.qcow2'}, 'size': 33554432}}}
840
+{u'return': {}}
841
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
842
+{u'return': {}}
843
844
-image: TEST_DIR/t.IMGFMT
845
+image: TEST_IMG
846
file format: IMGFMT
847
virtual size: 32M (33554432 bytes)
848
+encrypted: yes
849
+cluster_size: 65536
850
Format specific information:
851
compat: 1.1
852
lazy refcounts: false
853
@@ -XXX,XX +XXX,XX @@ Format specific information:
854
ivgen alg: plain64
855
hash alg: sha1
856
cipher alg: twofish-128
857
- uuid: 00000000-0000-0000-0000-000000000000
858
+ uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
859
format: luks
860
cipher mode: ctr
861
slots:
862
[0]:
863
active: true
864
- iters: 1024
865
+ iters: XXX
866
key offset: 4096
867
stripes: 4000
868
[1]:
869
@@ -XXX,XX +XXX,XX @@ Format specific information:
870
active: false
871
key offset: 462848
872
payload offset: 528384
873
- master key iters: 1024
874
+ master key iters: XXX
875
corrupt: false
876
877
=== Invalid BlockdevRef ===
878
879
-Testing:
880
-QMP_VERSION
881
-{"return": {}}
882
-{"error": {"class": "GenericError", "desc": "Cannot find device=this doesn't exist nor node_name=this doesn't exist"}}
883
-{"return": {}}
884
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
885
-
886
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': "this doesn't exist", 'size': 33554432}}}
887
+{u'return': {}}
888
+Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist
889
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
890
+{u'return': {}}
891
892
=== Invalid sizes ===
893
-
894
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0
895
-QMP_VERSION
896
-{"return": {}}
897
-{"error": {"class": "GenericError", "desc": "Image size must be a multiple of 512 bytes"}}
898
-{"error": {"class": "GenericError", "desc": "Could not resize image: Image size cannot be negative"}}
899
-{"error": {"class": "GenericError", "desc": "Could not resize image: Image size cannot be negative"}}
900
-{"error": {"class": "GenericError", "desc": "Could not resize image: Failed to grow the L1 table: File too large"}}
901
-{"return": {}}
902
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
903
-
904
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 1234}}}
905
+{u'return': {}}
906
+Job failed: Image size must be a multiple of 512 bytes
907
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
908
+{u'return': {}}
909
+
910
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 18446744073709551104L}}}
911
+{u'return': {}}
912
+Job failed: Could not resize image: Image size cannot be negative
913
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
914
+{u'return': {}}
915
+
916
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 9223372036854775808L}}}
917
+{u'return': {}}
918
+Job failed: Could not resize image: Image size cannot be negative
919
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
920
+{u'return': {}}
921
+
922
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'qcow2', 'file': 'node0', 'size': 9223372036854775296}}}
923
+{u'return': {}}
924
+Job failed: Could not resize image: Failed to grow the L1 table: File too large
925
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
926
+{u'return': {}}
927
928
=== Invalid version ===
929
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'version': 'v1', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
930
+{u'error': {u'class': u'GenericError', u'desc': u"Invalid parameter 'v1'"}}
931
932
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0
933
-QMP_VERSION
934
-{"return": {}}
935
-{"error": {"class": "GenericError", "desc": "Invalid parameter 'v1'"}}
936
-{"error": {"class": "GenericError", "desc": "Lazy refcounts only supported with compatibility level 1.1 and above (use version=v3 or greater)"}}
937
-{"error": {"class": "GenericError", "desc": "Different refcount widths than 16 bits require compatibility level 1.1 or above (use version=v3 or greater)"}}
938
-{"return": {}}
939
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
940
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'lazy-refcounts': True, 'version': 'v2', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
941
+{u'return': {}}
942
+Job failed: Lazy refcounts only supported with compatibility level 1.1 and above (use version=v3 or greater)
943
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
944
+{u'return': {}}
945
946
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 8, 'version': 'v2', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
947
+{u'return': {}}
948
+Job failed: Different refcount widths than 16 bits require compatibility level 1.1 or above (use version=v3 or greater)
949
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
950
+{u'return': {}}
951
952
=== Invalid backing file options ===
953
-
954
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0
955
-QMP_VERSION
956
-{"return": {}}
957
-{"error": {"class": "GenericError", "desc": "Backing file and preallocation cannot be used at the same time"}}
958
-{"error": {"class": "GenericError", "desc": "Backing format cannot be used without backing file"}}
959
-{"return": {}}
960
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
961
-
962
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'preallocation': 'full', 'driver': 'qcow2', 'backing-file': '/dev/null', 'file': 'node0', 'size': 67108864}}}
963
+{u'return': {}}
964
+Job failed: Backing file and preallocation cannot be used at the same time
965
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
966
+{u'return': {}}
967
+
968
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'backing-fmt': 'qcow2', 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
969
+{u'return': {}}
970
+Job failed: Backing format cannot be used without backing file
971
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
972
+{u'return': {}}
973
974
=== Invalid cluster size ===
975
-
976
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0
977
-QMP_VERSION
978
-{"return": {}}
979
-{"error": {"class": "GenericError", "desc": "Cluster size must be a power of two between 512 and 2048k"}}
980
-{"error": {"class": "GenericError", "desc": "Cluster size must be a power of two between 512 and 2048k"}}
981
-{"error": {"class": "GenericError", "desc": "Cluster size must be a power of two between 512 and 2048k"}}
982
-{"error": {"class": "GenericError", "desc": "Cluster size must be a power of two between 512 and 2048k"}}
983
-{"error": {"class": "GenericError", "desc": "Could not resize image: Failed to grow the L1 table: File too large"}}
984
-{"return": {}}
985
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
986
-
987
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 1234, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
988
+{u'return': {}}
989
+Job failed: Cluster size must be a power of two between 512 and 2048k
990
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
991
+{u'return': {}}
992
+
993
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 128, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
994
+{u'return': {}}
995
+Job failed: Cluster size must be a power of two between 512 and 2048k
996
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
997
+{u'return': {}}
998
+
999
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 4194304, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
1000
+{u'return': {}}
1001
+Job failed: Cluster size must be a power of two between 512 and 2048k
1002
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
1003
+{u'return': {}}
1004
+
1005
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 0, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
1006
+{u'return': {}}
1007
+Job failed: Cluster size must be a power of two between 512 and 2048k
1008
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
1009
+{u'return': {}}
1010
+
1011
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'cluster-size': 512, 'driver': 'qcow2', 'file': 'node0', 'size': 281474976710656}}}
1012
+{u'return': {}}
1013
+Job failed: Could not resize image: Failed to grow the L1 table: File too large
1014
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
1015
+{u'return': {}}
1016
1017
=== Invalid refcount width ===
1018
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 128, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
1019
+{u'return': {}}
1020
+Job failed: Refcount width must be a power of two and may not exceed 64 bits
1021
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
1022
+{u'return': {}}
1023
+
1024
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 0, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
1025
+{u'return': {}}
1026
+Job failed: Refcount width must be a power of two and may not exceed 64 bits
1027
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
1028
+{u'return': {}}
1029
+
1030
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'refcount-bits': 7, 'driver': 'qcow2', 'file': 'node0', 'size': 67108864}}}
1031
+{u'return': {}}
1032
+Job failed: Refcount width must be a power of two and may not exceed 64 bits
1033
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
1034
+{u'return': {}}
1035
1036
-Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0
1037
-QMP_VERSION
1038
-{"return": {}}
1039
-{"error": {"class": "GenericError", "desc": "Refcount width must be a power of two and may not exceed 64 bits"}}
1040
-{"error": {"class": "GenericError", "desc": "Refcount width must be a power of two and may not exceed 64 bits"}}
1041
-{"error": {"class": "GenericError", "desc": "Refcount width must be a power of two and may not exceed 64 bits"}}
1042
-{"return": {}}
1043
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
1044
-
1045
-*** done
1046
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
1047
index XXXXXXX..XXXXXXX 100644
1048
--- a/tests/qemu-iotests/group
1049
+++ b/tests/qemu-iotests/group
1050
@@ -XXX,XX +XXX,XX @@
1051
203 rw auto migration
1052
204 rw auto quick
1053
205 rw auto quick
1054
+206 rw auto
1055
# TODO The following commented out tests need to be reworked to work
1056
# with the x-blockdev-create job
1057
-#206 rw auto
1058
#207 rw auto
1059
208 rw auto quick
1060
209 rw auto quick
1061
--
75
--
1062
2.13.6
76
2.25.3
1063
77
1064
78
diff view generated by jsdifflib
1
This adds two helper functions that are useful for test cases that make
1
We want to keep TEST_IMG for the full path of the main test image, but
2
use of a non-file protocol (specifically ssh).
2
filter_testfiles() must be called for other test images before replacing
3
other things like the image format because the test directory path could
4
contain the format as a substring.
5
6
Insert a filter_testfiles() call between both.
3
7
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
Reviewed-by: Jeff Cody <jcody@redhat.com>
10
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Message-Id: <20200424125448.63318-9-kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
13
---
8
tests/qemu-iotests/iotests.py | 17 +++++++++++++++++
14
tests/qemu-iotests/iotests.py | 5 +++--
9
1 file changed, 17 insertions(+)
15
1 file changed, 3 insertions(+), 2 deletions(-)
10
16
11
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
17
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/tests/qemu-iotests/iotests.py
19
--- a/tests/qemu-iotests/iotests.py
14
+++ b/tests/qemu-iotests/iotests.py
20
+++ b/tests/qemu-iotests/iotests.py
15
@@ -XXX,XX +XXX,XX @@ def file_path(*names):
21
@@ -XXX,XX +XXX,XX @@ def filter_img_info(output, filename):
16
22
for line in output.split('\n'):
17
return paths[0] if len(paths) == 1 else paths
23
if 'disk size' in line or 'actual-size' in line:
18
24
continue
19
+def remote_filename(path):
25
- line = line.replace(filename, 'TEST_IMG') \
20
+ if imgproto == 'file':
26
- .replace(imgfmt, 'IMGFMT')
21
+ return path
27
+ line = line.replace(filename, 'TEST_IMG')
22
+ elif imgproto == 'ssh':
28
+ line = filter_testfiles(line)
23
+ return "ssh://127.0.0.1%s" % (path)
29
+ line = line.replace(imgfmt, 'IMGFMT')
24
+ else:
30
line = re.sub('iters: [0-9]+', 'iters: XXX', line)
25
+ raise Exception("Protocol %s not supported" % (imgproto))
31
line = re.sub('uuid: [-a-f0-9]+', 'uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', line)
26
32
line = re.sub('cid: [0-9]+', 'cid: XXXXXXXXXX', line)
27
class VM(qtest.QEMUQtestMachine):
28
'''A QEMU VM'''
29
@@ -XXX,XX +XXX,XX @@ def verify_image_format(supported_fmts=[], unsupported_fmts=[]):
30
if not_sup or (imgfmt in unsupported_fmts):
31
notrun('not suitable for this image format: %s' % imgfmt)
32
33
+def verify_protocol(supported=[], unsupported=[]):
34
+ assert not (supported and unsupported)
35
+
36
+ if 'generic' in supported:
37
+ return
38
+
39
+ not_sup = supported and (imgproto not in supported)
40
+ if not_sup or (imgproto in unsupported):
41
+ notrun('not suitable for this protocol: %s' % imgproto)
42
+
43
def verify_platform(supported_oses=['linux']):
44
if True not in [sys.platform.startswith(x) for x in supported_oses]:
45
notrun('not suitable for this OS: %s' % sys.platform)
46
--
33
--
47
2.13.6
34
2.25.3
48
35
49
36
diff view generated by jsdifflib
1
This rewrites the test case 207 to work with the new x-blockdev-create
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
job rather than the old synchronous version of the command.
2
Message-Id: <20200424125448.63318-10-kwolf@redhat.com>
3
Reviewed-by: Max Reitz <mreitz@redhat.com>
4
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
7
tests/qemu-iotests/274 | 155 +++++++++++++++++++++
8
tests/qemu-iotests/274.out | 268 +++++++++++++++++++++++++++++++++++++
9
tests/qemu-iotests/group | 1 +
10
3 files changed, 424 insertions(+)
11
create mode 100755 tests/qemu-iotests/274
12
create mode 100644 tests/qemu-iotests/274.out
3
13
4
Most of the test cases stay the same as before (the exception being some
14
diff --git a/tests/qemu-iotests/274 b/tests/qemu-iotests/274
5
improved 'size' options that allow distinguishing which command created
15
new file mode 100755
6
the image), but in order to be able to implement proper job handling,
16
index XXXXXXX..XXXXXXX
7
the test case is rewritten in Python.
17
--- /dev/null
8
18
+++ b/tests/qemu-iotests/274
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Reviewed-by: Max Reitz <mreitz@redhat.com>
11
---
12
tests/qemu-iotests/207 | 440 ++++++++++++++++++++-------------------------
13
tests/qemu-iotests/207.out | 107 +++++------
14
tests/qemu-iotests/group | 6 +-
15
3 files changed, 257 insertions(+), 296 deletions(-)
16
17
diff --git a/tests/qemu-iotests/207 b/tests/qemu-iotests/207
18
index XXXXXXX..XXXXXXX 100755
19
--- a/tests/qemu-iotests/207
20
+++ b/tests/qemu-iotests/207
21
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
22
-#!/bin/bash
20
+#!/usr/bin/env python3
23
+#!/usr/bin/env python
21
+#
24
#
22
+# Copyright (C) 2019 Red Hat, Inc.
25
# Test ssh image creation
23
+#
26
#
24
+# This program is free software; you can redistribute it and/or modify
27
# Copyright (C) 2018 Red Hat, Inc.
25
+# it under the terms of the GNU General Public License as published by
28
#
26
+# the Free Software Foundation; either version 2 of the License, or
27
+# (at your option) any later version.
28
+#
29
+# This program is distributed in the hope that it will be useful,
30
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
31
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32
+# GNU General Public License for more details.
33
+#
34
+# You should have received a copy of the GNU General Public License
35
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
36
+#
29
+# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
37
+# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
30
+#
38
+#
31
# This program is free software; you can redistribute it and/or modify
39
+# Some tests for short backing files and short overlays
32
# it under the terms of the GNU General Public License as published by
40
+
33
# the Free Software Foundation; either version 2 of the License, or
41
+import iotests
42
+
43
+iotests.verify_image_format(supported_fmts=['qcow2'])
44
+iotests.verify_platform(['linux'])
45
+
46
+size_short = 1 * 1024 * 1024
47
+size_long = 2 * 1024 * 1024
48
+size_diff = size_long - size_short
49
+
50
+def create_chain() -> None:
51
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, base,
52
+ str(size_long))
53
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, mid,
54
+ str(size_short))
55
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', mid, top,
56
+ str(size_long))
57
+
58
+ iotests.qemu_io_log('-c', 'write -P 1 0 %d' % size_long, base)
59
+
60
+def create_vm() -> iotests.VM:
61
+ vm = iotests.VM()
62
+ vm.add_blockdev('file,filename=%s,node-name=base-file' % base)
63
+ vm.add_blockdev('%s,file=base-file,node-name=base' % iotests.imgfmt)
64
+ vm.add_blockdev('file,filename=%s,node-name=mid-file' % mid)
65
+ vm.add_blockdev('%s,file=mid-file,node-name=mid,backing=base'
66
+ % iotests.imgfmt)
67
+ vm.add_drive(top, 'backing=mid,node-name=top')
68
+ return vm
69
+
70
+with iotests.FilePath('base') as base, \
71
+ iotests.FilePath('mid') as mid, \
72
+ iotests.FilePath('top') as top:
73
+
74
+ iotests.log('== Commit tests ==')
75
+
76
+ create_chain()
77
+
78
+ iotests.log('=== Check visible data ===')
79
+
80
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, top)
81
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), top)
82
+
83
+ iotests.log('=== Checking allocation status ===')
84
+
85
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
86
+ '-c', 'alloc %d %d' % (size_short, size_diff),
87
+ base)
88
+
89
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
90
+ '-c', 'alloc %d %d' % (size_short, size_diff),
91
+ mid)
92
+
93
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
94
+ '-c', 'alloc %d %d' % (size_short, size_diff),
95
+ top)
96
+
97
+ iotests.log('=== Checking map ===')
98
+
99
+ iotests.qemu_img_log('map', '--output=json', base)
100
+ iotests.qemu_img_log('map', '--output=human', base)
101
+ iotests.qemu_img_log('map', '--output=json', mid)
102
+ iotests.qemu_img_log('map', '--output=human', mid)
103
+ iotests.qemu_img_log('map', '--output=json', top)
104
+ iotests.qemu_img_log('map', '--output=human', top)
105
+
106
+ iotests.log('=== Testing qemu-img commit (top -> mid) ===')
107
+
108
+ iotests.qemu_img_log('commit', top)
109
+ iotests.img_info_log(mid)
110
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
111
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
112
+
113
+ iotests.log('=== Testing HMP commit (top -> mid) ===')
114
+
115
+ create_chain()
116
+ with create_vm() as vm:
117
+ vm.launch()
118
+ vm.qmp_log('human-monitor-command', command_line='commit drive0')
119
+
120
+ iotests.img_info_log(mid)
121
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
122
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
123
+
124
+ iotests.log('=== Testing QMP active commit (top -> mid) ===')
125
+
126
+ create_chain()
127
+ with create_vm() as vm:
128
+ vm.launch()
129
+ vm.qmp_log('block-commit', device='top', base_node='mid',
130
+ job_id='job0', auto_dismiss=False)
131
+ vm.run_job('job0', wait=5)
132
+
133
+ iotests.img_info_log(mid)
134
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
135
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
136
+
137
+
138
+ iotests.log('== Resize tests ==')
139
+
140
+ # Use different sizes for different allocation modes:
141
+ #
142
+ # We want to have at least one test where 32 bit truncation in the size of
143
+ # the overlapping area becomes visible. This is covered by the
144
+ # prealloc='off' case (1G to 6G is an overlap of 5G).
145
+ #
146
+ # However, we can only do this for modes that don't preallocate data
147
+ # because otherwise we might run out of space on the test host.
148
+ #
149
+ # We also want to test some unaligned combinations.
150
+ for (prealloc, base_size, top_size_old, top_size_new, off) in [
151
+ ('off', '6G', '1G', '8G', '5G'),
152
+ ('metadata', '32G', '30G', '33G', '31G'),
153
+ ('falloc', '10M', '5M', '15M', '9M'),
154
+ ('full', '16M', '8M', '12M', '11M'),
155
+ ('off', '384k', '253k', '512k', '253k'),
156
+ ('off', '400k', '256k', '512k', '336k'),
157
+ ('off', '512k', '256k', '500k', '436k')]:
158
+
159
+ iotests.log('=== preallocation=%s ===' % prealloc)
160
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, base, base_size)
161
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, top,
162
+ top_size_old)
163
+ iotests.qemu_io_log('-c', 'write -P 1 %s 64k' % off, base)
164
+
165
+ # After this, top_size_old to base_size should be allocated/zeroed.
166
+ #
167
+ # In theory, leaving base_size to top_size_new unallocated would be
168
+ # correct, but in practice, if we zero out anything, we zero out
169
+ # everything up to top_size_new.
170
+ iotests.qemu_img_log('resize', '-f', iotests.imgfmt,
171
+ '--preallocation', prealloc, top, top_size_new)
172
+ iotests.qemu_io_log('-c', 'read -P 0 %s 64k' % off, top)
173
+ iotests.qemu_io_log('-c', 'map', top)
174
+ iotests.qemu_img_log('map', '--output=json', top)
175
diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
176
new file mode 100644
177
index XXXXXXX..XXXXXXX
178
--- /dev/null
179
+++ b/tests/qemu-iotests/274.out
34
@@ -XXX,XX +XXX,XX @@
180
@@ -XXX,XX +XXX,XX @@
35
# along with this program. If not, see <http://www.gnu.org/licenses/>.
181
+== Commit tests ==
36
#
182
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
37
183
+
38
-# creator
184
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
39
-owner=kwolf@redhat.com
185
+
40
-
186
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
41
-seq=`basename $0`
187
+
42
-echo "QA output created by $seq"
188
+wrote 2097152/2097152 bytes at offset 0
43
-
189
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
44
-here=`pwd`
190
+
45
-status=1    # failure is the default!
191
+=== Check visible data ===
46
-
192
+read 1048576/1048576 bytes at offset 0
47
-# get standard environment, filters and checks
193
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
48
-. ./common.rc
194
+
49
-. ./common.filter
195
+read 1048576/1048576 bytes at offset 1048576
50
-
196
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
51
-_supported_fmt raw
197
+
52
-_supported_proto ssh
198
+=== Checking allocation status ===
53
-_supported_os Linux
199
+1048576/1048576 bytes allocated at offset 0 bytes
54
-
200
+1048576/1048576 bytes allocated at offset 1 MiB
55
-function do_run_qemu()
201
+
56
-{
202
+0/1048576 bytes allocated at offset 0 bytes
57
- echo Testing: "$@"
203
+0/0 bytes allocated at offset 1 MiB
58
- $QEMU -nographic -qmp stdio -serial none "$@"
204
+
59
- echo
205
+0/1048576 bytes allocated at offset 0 bytes
60
-}
206
+0/1048576 bytes allocated at offset 1 MiB
61
-
207
+
62
-function run_qemu()
208
+=== Checking map ===
63
-{
209
+[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": 327680}]
64
- do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp \
210
+
65
- | _filter_qemu | _filter_imgfmt \
211
+Offset Length Mapped to File
66
- | _filter_actual_image_size
212
+0 0x200000 0x50000 TEST_DIR/PID-base
67
-}
213
+
68
-
214
+[{ "start": 0, "length": 1048576, "depth": 1, "zero": false, "data": true, "offset": 327680}]
69
-echo
215
+
70
-echo "=== Successful image creation (defaults) ==="
216
+Offset Length Mapped to File
71
-echo
217
+0 0x100000 0x50000 TEST_DIR/PID-base
72
-
218
+
73
-run_qemu <<EOF
219
+[{ "start": 0, "length": 1048576, "depth": 2, "zero": false, "data": true, "offset": 327680},
74
-{ "execute": "qmp_capabilities" }
220
+{ "start": 1048576, "length": 1048576, "depth": 0, "zero": true, "data": false}]
75
-{ "execute": "x-blockdev-create",
221
+
76
- "arguments": {
222
+Offset Length Mapped to File
77
- "driver": "ssh",
223
+0 0x100000 0x50000 TEST_DIR/PID-base
78
- "location": {
224
+
79
- "path": "$TEST_IMG_FILE",
225
+=== Testing qemu-img commit (top -> mid) ===
80
- "server": {
226
+Image committed.
81
- "host": "127.0.0.1",
82
- "port": "22"
83
- }
84
- },
85
- "size": 4194304
86
- }
87
-}
88
-{ "execute": "quit" }
89
-EOF
90
-
91
-_img_info | _filter_img_info
92
-echo
93
-TEST_IMG=$TEST_IMG_FILE _img_info | _filter_img_info
94
-
95
-echo
96
-echo "=== Test host-key-check options ==="
97
-echo
98
-
99
-run_qemu <<EOF
100
-{ "execute": "qmp_capabilities" }
101
-{ "execute": "x-blockdev-create",
102
- "arguments": {
103
- "driver": "ssh",
104
- "location": {
105
- "path": "$TEST_IMG_FILE",
106
- "server": {
107
- "host": "127.0.0.1",
108
- "port": "22"
109
- },
110
- "host-key-check": {
111
- "mode": "none"
112
- }
113
- },
114
- "size": 8388608
115
- }
116
-}
117
-{ "execute": "quit" }
118
-EOF
119
-
120
-_img_info | _filter_img_info
121
-
122
-run_qemu <<EOF
123
-{ "execute": "qmp_capabilities" }
124
-{ "execute": "x-blockdev-create",
125
- "arguments": {
126
- "driver": "ssh",
127
- "location": {
128
- "path": "$TEST_IMG_FILE",
129
- "server": {
130
- "host": "127.0.0.1",
131
- "port": "22"
132
- },
133
- "host-key-check": {
134
- "mode": "known_hosts"
135
- }
136
- },
137
- "size": 4194304
138
- }
139
-}
140
-{ "execute": "quit" }
141
-EOF
142
-
143
-_img_info | _filter_img_info
144
-
145
-
146
-key=$(ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" |
147
- cut -d" " -f3 | base64 -d | md5sum -b | cut -d" " -f1)
148
-
149
-run_qemu <<EOF
150
-{ "execute": "qmp_capabilities" }
151
-{ "execute": "x-blockdev-create",
152
- "arguments": {
153
- "driver": "ssh",
154
- "location": {
155
- "path": "$TEST_IMG_FILE",
156
- "server": {
157
- "host": "127.0.0.1",
158
- "port": "22"
159
- },
160
- "host-key-check": {
161
- "mode": "hash",
162
- "type": "md5",
163
- "hash": "wrong"
164
- }
165
- },
166
- "size": 8388608
167
- }
168
-}
169
-{ "execute": "x-blockdev-create",
170
- "arguments": {
171
- "driver": "ssh",
172
- "location": {
173
- "path": "$TEST_IMG_FILE",
174
- "server": {
175
- "host": "127.0.0.1",
176
- "port": "22"
177
- },
178
- "host-key-check": {
179
- "mode": "hash",
180
- "type": "md5",
181
- "hash": "$key"
182
- }
183
- },
184
- "size": 8388608
185
- }
186
-}
187
-{ "execute": "quit" }
188
-EOF
189
-
190
-_img_info | _filter_img_info
191
-
192
-
193
-key=$(ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" |
194
- cut -d" " -f3 | base64 -d | sha1sum -b | cut -d" " -f1)
195
-
196
-run_qemu <<EOF
197
-{ "execute": "qmp_capabilities" }
198
-{ "execute": "x-blockdev-create",
199
- "arguments": {
200
- "driver": "ssh",
201
- "location": {
202
- "path": "$TEST_IMG_FILE",
203
- "server": {
204
- "host": "127.0.0.1",
205
- "port": "22"
206
- },
207
- "host-key-check": {
208
- "mode": "hash",
209
- "type": "sha1",
210
- "hash": "wrong"
211
- }
212
- },
213
- "size": 4194304
214
- }
215
-}
216
-{ "execute": "x-blockdev-create",
217
- "arguments": {
218
- "driver": "ssh",
219
- "location": {
220
- "path": "$TEST_IMG_FILE",
221
- "server": {
222
- "host": "127.0.0.1",
223
- "port": "22"
224
- },
225
- "host-key-check": {
226
- "mode": "hash",
227
- "type": "sha1",
228
- "hash": "$key"
229
- }
230
- },
231
- "size": 4194304
232
- }
233
-}
234
-{ "execute": "quit" }
235
-EOF
236
-
237
-_img_info | _filter_img_info
238
-
239
-echo
240
-echo "=== Invalid path and user ==="
241
-echo
242
-
243
-run_qemu <<EOF
244
-{ "execute": "qmp_capabilities" }
245
-{ "execute": "x-blockdev-create",
246
- "arguments": {
247
- "driver": "ssh",
248
- "location": {
249
- "path": "/this/is/not/an/existing/path",
250
- "server": {
251
- "host": "127.0.0.1",
252
- "port": "22"
253
- }
254
- },
255
- "size": 4194304
256
- }
257
-}
258
-{ "execute": "x-blockdev-create",
259
- "arguments": {
260
- "driver": "ssh",
261
- "location": {
262
- "path": "$TEST_IMG_FILE",
263
- "user": "invalid user",
264
- "server": {
265
- "host": "127.0.0.1",
266
- "port": "22"
267
- }
268
- },
269
- "size": 4194304
270
- }
271
-}
272
-{ "execute": "quit" }
273
-EOF
274
-
275
-# success, all done
276
-echo "*** done"
277
-rm -f $seq.full
278
-status=0
279
+import iotests
280
+import subprocess
281
+import re
282
+
283
+iotests.verify_image_format(supported_fmts=['raw'])
284
+iotests.verify_protocol(supported=['ssh'])
285
+
286
+def filter_hash(msg):
287
+ return re.sub("'hash': '[0-9a-f]+'", "'hash': HASH", msg)
288
+
289
+def blockdev_create(vm, options):
290
+ result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options,
291
+ filters=[iotests.filter_testfiles, filter_hash])
292
+
293
+ if 'return' in result:
294
+ assert result['return'] == {}
295
+ vm.run_job('job0')
296
+ iotests.log("")
297
+
298
+with iotests.FilePath('t.img') as disk_path, \
299
+ iotests.VM() as vm:
300
+
301
+ remote_path = iotests.remote_filename(disk_path)
302
+
303
+ #
304
+ # Successful image creation (defaults)
305
+ #
306
+ iotests.log("=== Successful image creation (defaults) ===")
307
+ iotests.log("")
308
+
309
+ vm.launch()
310
+ blockdev_create(vm, { 'driver': 'ssh',
311
+ 'location': {
312
+ 'path': disk_path,
313
+ 'server': {
314
+ 'host': '127.0.0.1',
315
+ 'port': '22'
316
+ }
317
+ },
318
+ 'size': 4194304 })
319
+ vm.shutdown()
320
+
321
+ iotests.img_info_log(remote_path, filter_path=disk_path)
322
+ iotests.log("")
323
+ iotests.img_info_log(disk_path)
324
+
325
+ #
326
+ # Test host-key-check options
327
+ #
328
+ iotests.log("=== Test host-key-check options ===")
329
+ iotests.log("")
330
+
331
+ vm.launch()
332
+ blockdev_create(vm, { 'driver': 'ssh',
333
+ 'location': {
334
+ 'path': disk_path,
335
+ 'server': {
336
+ 'host': '127.0.0.1',
337
+ 'port': '22'
338
+ },
339
+ 'host-key-check': {
340
+ 'mode': 'none'
341
+ }
342
+ },
343
+ 'size': 8388608 })
344
+ vm.shutdown()
345
+
346
+ iotests.img_info_log(remote_path, filter_path=disk_path)
347
+
348
+ vm.launch()
349
+ blockdev_create(vm, { 'driver': 'ssh',
350
+ 'location': {
351
+ 'path': disk_path,
352
+ 'server': {
353
+ 'host': '127.0.0.1',
354
+ 'port': '22'
355
+ },
356
+ 'host-key-check': {
357
+ 'mode': 'known_hosts'
358
+ }
359
+ },
360
+ 'size': 4194304 })
361
+ vm.shutdown()
362
+
363
+ iotests.img_info_log(remote_path, filter_path=disk_path)
364
+
365
+ md5_key = subprocess.check_output(
366
+ 'ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' +
367
+ 'cut -d" " -f3 | base64 -d | md5sum -b | cut -d" " -f1',
368
+ shell=True).rstrip()
369
+
370
+ vm.launch()
371
+ blockdev_create(vm, { 'driver': 'ssh',
372
+ 'location': {
373
+ 'path': disk_path,
374
+ 'server': {
375
+ 'host': '127.0.0.1',
376
+ 'port': '22'
377
+ },
378
+ 'host-key-check': {
379
+ 'mode': 'hash',
380
+ 'type': 'md5',
381
+ 'hash': 'wrong',
382
+ }
383
+ },
384
+ 'size': 2097152 })
385
+ blockdev_create(vm, { 'driver': 'ssh',
386
+ 'location': {
387
+ 'path': disk_path,
388
+ 'server': {
389
+ 'host': '127.0.0.1',
390
+ 'port': '22'
391
+ },
392
+ 'host-key-check': {
393
+ 'mode': 'hash',
394
+ 'type': 'md5',
395
+ 'hash': md5_key,
396
+ }
397
+ },
398
+ 'size': 8388608 })
399
+ vm.shutdown()
400
+
401
+ iotests.img_info_log(remote_path, filter_path=disk_path)
402
+
403
+ sha1_key = subprocess.check_output(
404
+ 'ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' +
405
+ 'cut -d" " -f3 | base64 -d | sha1sum -b | cut -d" " -f1',
406
+ shell=True).rstrip()
407
+
408
+ vm.launch()
409
+ blockdev_create(vm, { 'driver': 'ssh',
410
+ 'location': {
411
+ 'path': disk_path,
412
+ 'server': {
413
+ 'host': '127.0.0.1',
414
+ 'port': '22'
415
+ },
416
+ 'host-key-check': {
417
+ 'mode': 'hash',
418
+ 'type': 'sha1',
419
+ 'hash': 'wrong',
420
+ }
421
+ },
422
+ 'size': 2097152 })
423
+ blockdev_create(vm, { 'driver': 'ssh',
424
+ 'location': {
425
+ 'path': disk_path,
426
+ 'server': {
427
+ 'host': '127.0.0.1',
428
+ 'port': '22'
429
+ },
430
+ 'host-key-check': {
431
+ 'mode': 'hash',
432
+ 'type': 'sha1',
433
+ 'hash': sha1_key,
434
+ }
435
+ },
436
+ 'size': 4194304 })
437
+ vm.shutdown()
438
+
439
+ iotests.img_info_log(remote_path, filter_path=disk_path)
440
+
441
+ #
442
+ # Invalid path and user
443
+ #
444
+ iotests.log("=== Invalid path and user ===")
445
+ iotests.log("")
446
+
447
+ vm.launch()
448
+ blockdev_create(vm, { 'driver': 'ssh',
449
+ 'location': {
450
+ 'path': '/this/is/not/an/existing/path',
451
+ 'server': {
452
+ 'host': '127.0.0.1',
453
+ 'port': '22'
454
+ },
455
+ 'host-key-check': {
456
+ 'mode': 'none'
457
+ }
458
+ },
459
+ 'size': 4194304 })
460
+ blockdev_create(vm, { 'driver': 'ssh',
461
+ 'location': {
462
+ 'path': disk_path,
463
+ 'user': 'invalid user',
464
+ 'server': {
465
+ 'host': '127.0.0.1',
466
+ 'port': '22'
467
+ },
468
+ 'host-key-check': {
469
+ 'mode': 'none'
470
+ }
471
+ },
472
+ 'size': 4194304 })
473
+ vm.shutdown()
474
diff --git a/tests/qemu-iotests/207.out b/tests/qemu-iotests/207.out
475
index XXXXXXX..XXXXXXX 100644
476
--- a/tests/qemu-iotests/207.out
477
+++ b/tests/qemu-iotests/207.out
478
@@ -XXX,XX +XXX,XX @@
479
-QA output created by 207
480
-
481
=== Successful image creation (defaults) ===
482
483
-Testing:
484
-QMP_VERSION
485
-{"return": {}}
486
-{"return": {}}
487
-{"return": {}}
488
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
489
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}}
490
+{u'return': {}}
491
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
492
+{u'return': {}}
493
494
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_DIR/t.IMGFMT"}}
495
+image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
496
file format: IMGFMT
497
virtual size: 4.0M (4194304 bytes)
498
499
-image: TEST_DIR/t.IMGFMT
500
+
227
+
501
+image: TEST_IMG
228
+image: TEST_IMG
502
file format: IMGFMT
229
+file format: IMGFMT
503
virtual size: 4.0M (4194304 bytes)
230
+virtual size: 2 MiB (2097152 bytes)
504
231
+cluster_size: 65536
505
=== Test host-key-check options ===
232
+backing file: TEST_DIR/PID-base
506
233
+Format specific information:
507
-Testing:
234
+ compat: 1.1
508
-QMP_VERSION
235
+ lazy refcounts: false
509
-{"return": {}}
236
+ refcount bits: 16
510
-{"return": {}}
237
+ corrupt: false
511
-{"return": {}}
238
+
512
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
239
+read 1048576/1048576 bytes at offset 0
513
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'mode': 'none'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 8388608}}}
240
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
514
+{u'return': {}}
241
+
515
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
242
+read 1048576/1048576 bytes at offset 1048576
516
+{u'return': {}}
243
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
517
244
+
518
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_DIR/t.IMGFMT"}}
245
+=== Testing HMP commit (top -> mid) ===
519
+image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
246
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
520
file format: IMGFMT
247
+
521
virtual size: 8.0M (8388608 bytes)
248
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
522
-Testing:
249
+
523
-QMP_VERSION
250
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
524
-{"return": {}}
251
+
525
-{"return": {}}
252
+wrote 2097152/2097152 bytes at offset 0
526
-{"return": {}}
253
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
527
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
254
+
528
-
255
+{"execute": "human-monitor-command", "arguments": {"command-line": "commit drive0"}}
529
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_DIR/t.IMGFMT"}}
256
+{"return": ""}
530
+
257
+image: TEST_IMG
531
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'mode': 'known_hosts'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}}
258
+file format: IMGFMT
532
+{u'return': {}}
259
+virtual size: 2 MiB (2097152 bytes)
533
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
260
+cluster_size: 65536
534
+{u'return': {}}
261
+backing file: TEST_DIR/PID-base
535
+
262
+Format specific information:
536
+image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
263
+ compat: 1.1
537
file format: IMGFMT
264
+ lazy refcounts: false
538
virtual size: 4.0M (4194304 bytes)
265
+ refcount bits: 16
539
-Testing:
266
+ corrupt: false
540
-QMP_VERSION
267
+
541
-{"return": {}}
268
+read 1048576/1048576 bytes at offset 0
542
-{"error": {"class": "GenericError", "desc": "remote host key does not match host_key_check 'wrong'"}}
269
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
543
-{"return": {}}
270
+
544
-{"return": {}}
271
+read 1048576/1048576 bytes at offset 1048576
545
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
272
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
546
-
273
+
547
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_DIR/t.IMGFMT"}}
274
+=== Testing QMP active commit (top -> mid) ===
548
+
275
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
549
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': 'wrong', 'type': 'md5', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 2097152}}}
276
+
550
+{u'return': {}}
277
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
551
+Job failed: remote host key does not match host_key_check 'wrong'
278
+
552
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
279
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
553
+{u'return': {}}
280
+
554
+
281
+wrote 2097152/2097152 bytes at offset 0
555
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': HASH, 'type': 'md5', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 8388608}}}
282
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
556
+{u'return': {}}
283
+
557
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
284
+{"execute": "block-commit", "arguments": {"auto-dismiss": false, "base-node": "mid", "device": "top", "job-id": "job0"}}
558
+{u'return': {}}
285
+{"return": {}}
559
+
286
+{"execute": "job-complete", "arguments": {"id": "job0"}}
560
+image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
287
+{"return": {}}
561
file format: IMGFMT
288
+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
562
virtual size: 8.0M (8388608 bytes)
289
+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
563
-Testing:
290
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
564
-QMP_VERSION
291
+{"return": {}}
565
-{"return": {}}
292
+image: TEST_IMG
566
-{"error": {"class": "GenericError", "desc": "remote host key does not match host_key_check 'wrong'"}}
293
+file format: IMGFMT
567
-{"return": {}}
294
+virtual size: 2 MiB (2097152 bytes)
568
-{"return": {}}
295
+cluster_size: 65536
569
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
296
+backing file: TEST_DIR/PID-base
570
-
297
+Format specific information:
571
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_DIR/t.IMGFMT"}}
298
+ compat: 1.1
572
+
299
+ lazy refcounts: false
573
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': 'wrong', 'type': 'sha1', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 2097152}}}
300
+ refcount bits: 16
574
+{u'return': {}}
301
+ corrupt: false
575
+Job failed: remote host key does not match host_key_check 'wrong'
302
+
576
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
303
+read 1048576/1048576 bytes at offset 0
577
+{u'return': {}}
304
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
578
+
305
+
579
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'hash': HASH, 'type': 'sha1', 'mode': 'hash'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}}
306
+read 1048576/1048576 bytes at offset 1048576
580
+{u'return': {}}
307
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
581
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
308
+
582
+{u'return': {}}
309
+== Resize tests ==
583
+
310
+=== preallocation=off ===
584
+image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
311
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=6442450944 cluster_size=65536 lazy_refcounts=off refcount_bits=16
585
file format: IMGFMT
312
+
586
virtual size: 4.0M (4194304 bytes)
313
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=1073741824 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
587
314
+
588
=== Invalid path and user ===
315
+wrote 65536/65536 bytes at offset 5368709120
589
316
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
590
-Testing:
317
+
591
-QMP_VERSION
318
+Image resized.
592
-{"return": {}}
319
+
593
-{"error": {"class": "GenericError", "desc": "failed to open remote file '/this/is/not/an/existing/path': Failed opening remote file (libssh2 error code: -31)"}}
320
+read 65536/65536 bytes at offset 5368709120
594
-{"error": {"class": "GenericError", "desc": "failed to authenticate using publickey authentication and the identities held by your ssh-agent"}}
321
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
595
-{"return": {}}
322
+
596
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
323
+1 GiB (0x40000000) bytes not allocated at offset 0 bytes (0x0)
597
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': '/this/is/not/an/existing/path', 'host-key-check': {'mode': 'none'}, 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}}
324
+7 GiB (0x1c0000000) bytes allocated at offset 1 GiB (0x40000000)
598
+{u'return': {}}
325
+
599
+Job failed: failed to open remote file '/this/is/not/an/existing/path': Failed opening remote file (libssh2 error code: -31)
326
+[{ "start": 0, "length": 1073741824, "depth": 1, "zero": true, "data": false},
600
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
327
+{ "start": 1073741824, "length": 7516192768, "depth": 0, "zero": true, "data": false}]
601
+{u'return': {}}
328
+
602
+
329
+=== preallocation=metadata ===
603
+{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'ssh', 'location': {'path': 'TEST_DIR/PID-t.img', 'host-key-check': {'mode': 'none'}, 'user': 'invalid user', 'server': {'host': '127.0.0.1', 'port': '22'}}, 'size': 4194304}}}
330
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=34359738368 cluster_size=65536 lazy_refcounts=off refcount_bits=16
604
+{u'return': {}}
331
+
605
+Job failed: failed to authenticate using publickey authentication and the identities held by your ssh-agent
332
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=32212254720 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
606
+{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
333
+
607
+{u'return': {}}
334
+wrote 65536/65536 bytes at offset 33285996544
608
335
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
609
-*** done
336
+
337
+Image resized.
338
+
339
+read 65536/65536 bytes at offset 33285996544
340
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
341
+
342
+30 GiB (0x780000000) bytes not allocated at offset 0 bytes (0x0)
343
+3 GiB (0xc0000000) bytes allocated at offset 30 GiB (0x780000000)
344
+
345
+[{ "start": 0, "length": 32212254720, "depth": 1, "zero": true, "data": false},
346
+{ "start": 32212254720, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 327680},
347
+{ "start": 32749125632, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 537264128},
348
+{ "start": 33285996544, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 1074200576},
349
+{ "start": 33822867456, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 1611137024},
350
+{ "start": 34359738368, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2148139008},
351
+{ "start": 34896609280, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2685075456}]
352
+
353
+=== preallocation=falloc ===
354
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=10485760 cluster_size=65536 lazy_refcounts=off refcount_bits=16
355
+
356
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=5242880 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
357
+
358
+wrote 65536/65536 bytes at offset 9437184
359
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
360
+
361
+Image resized.
362
+
363
+read 65536/65536 bytes at offset 9437184
364
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
365
+
366
+5 MiB (0x500000) bytes not allocated at offset 0 bytes (0x0)
367
+10 MiB (0xa00000) bytes allocated at offset 5 MiB (0x500000)
368
+
369
+[{ "start": 0, "length": 5242880, "depth": 1, "zero": true, "data": false},
370
+{ "start": 5242880, "length": 10485760, "depth": 0, "zero": true, "data": false, "offset": 327680}]
371
+
372
+=== preallocation=full ===
373
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
374
+
375
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=8388608 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
376
+
377
+wrote 65536/65536 bytes at offset 11534336
378
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
379
+
380
+Image resized.
381
+
382
+read 65536/65536 bytes at offset 11534336
383
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
384
+
385
+8 MiB (0x800000) bytes not allocated at offset 0 bytes (0x0)
386
+4 MiB (0x400000) bytes allocated at offset 8 MiB (0x800000)
387
+
388
+[{ "start": 0, "length": 8388608, "depth": 1, "zero": true, "data": false},
389
+{ "start": 8388608, "length": 4194304, "depth": 0, "zero": true, "data": false, "offset": 327680}]
390
+
391
+=== preallocation=off ===
392
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
393
+
394
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=259072 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
395
+
396
+wrote 65536/65536 bytes at offset 259072
397
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
398
+
399
+Image resized.
400
+
401
+read 65536/65536 bytes at offset 259072
402
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
403
+
404
+192 KiB (0x30000) bytes not allocated at offset 0 bytes (0x0)
405
+320 KiB (0x50000) bytes allocated at offset 192 KiB (0x30000)
406
+
407
+[{ "start": 0, "length": 196608, "depth": 1, "zero": true, "data": false},
408
+{ "start": 196608, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": 327680},
409
+{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
410
+
411
+=== preallocation=off ===
412
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=409600 cluster_size=65536 lazy_refcounts=off refcount_bits=16
413
+
414
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
415
+
416
+wrote 65536/65536 bytes at offset 344064
417
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
418
+
419
+Image resized.
420
+
421
+read 65536/65536 bytes at offset 344064
422
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
423
+
424
+256 KiB (0x40000) bytes not allocated at offset 0 bytes (0x0)
425
+256 KiB (0x40000) bytes allocated at offset 256 KiB (0x40000)
426
+
427
+[{ "start": 0, "length": 262144, "depth": 1, "zero": true, "data": false},
428
+{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
429
+
430
+=== preallocation=off ===
431
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=524288 cluster_size=65536 lazy_refcounts=off refcount_bits=16
432
+
433
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
434
+
435
+wrote 65536/65536 bytes at offset 446464
436
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
437
+
438
+Image resized.
439
+
440
+read 65536/65536 bytes at offset 446464
441
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
442
+
443
+256 KiB (0x40000) bytes not allocated at offset 0 bytes (0x0)
444
+244 KiB (0x3d000) bytes allocated at offset 256 KiB (0x40000)
445
+
446
+[{ "start": 0, "length": 262144, "depth": 1, "zero": true, "data": false},
447
+{ "start": 262144, "length": 249856, "depth": 0, "zero": true, "data": false}]
448
+
610
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
449
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
611
index XXXXXXX..XXXXXXX 100644
450
index XXXXXXX..XXXXXXX 100644
612
--- a/tests/qemu-iotests/group
451
--- a/tests/qemu-iotests/group
613
+++ b/tests/qemu-iotests/group
452
+++ b/tests/qemu-iotests/group
614
@@ -XXX,XX +XXX,XX @@
453
@@ -XXX,XX +XXX,XX @@
615
204 rw auto quick
454
270 rw backing quick
616
205 rw auto quick
455
272 rw
617
206 rw auto
456
273 backing quick
618
-# TODO The following commented out tests need to be reworked to work
457
+274 rw backing
619
-# with the x-blockdev-create job
458
277 rw quick
620
-#207 rw auto
459
279 rw backing quick
621
+207 rw auto
460
280 rw migration quick
622
208 rw auto quick
623
209 rw auto quick
624
+# TODO The following commented out tests need to be reworked to work
625
+# with the x-blockdev-create job
626
#210 rw auto
627
#211 rw auto quick
628
#212 rw auto quick
629
--
461
--
630
2.13.6
462
2.25.3
631
463
632
464
diff view generated by jsdifflib
1
Add an iotests.py function that runs a job and only returns when it is
1
The BDRV_REQ_ZERO_WRITE is currently implemented in a way that first the
2
destroyed. An error is logged when the job failed and job-finalize and
2
image is possibly preallocated and then the zero flag is added to all
3
job-dismiss commands are issued if necessary.
3
clusters. This means that a copy-on-write operation may be needed when
4
writing to these clusters, despite having used preallocation, negating
5
one of the major benefits of preallocation.
6
7
Instead, try to forward the BDRV_REQ_ZERO_WRITE to the protocol driver,
8
and if the protocol driver can ensure that the new area reads as zeros,
9
we can skip setting the zero flag in the qcow2 layer.
10
11
Unfortunately, the same approach doesn't work for metadata
12
preallocation, so we'll still set the zero flag there.
4
13
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Max Reitz <mreitz@redhat.com>
15
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Jeff Cody <jcody@redhat.com>
16
Message-Id: <20200424142701.67053-1-kwolf@redhat.com>
17
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
19
---
9
tests/qemu-iotests/iotests.py | 19 +++++++++++++++++++
20
block/qcow2.c | 22 +++++++++++++++++++---
10
1 file changed, 19 insertions(+)
21
tests/qemu-iotests/274.out | 4 ++--
22
2 files changed, 21 insertions(+), 5 deletions(-)
11
23
12
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
24
diff --git a/block/qcow2.c b/block/qcow2.c
13
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/qemu-iotests/iotests.py
26
--- a/block/qcow2.c
15
+++ b/tests/qemu-iotests/iotests.py
27
+++ b/block/qcow2.c
16
@@ -XXX,XX +XXX,XX @@ class VM(qtest.QEMUQtestMachine):
28
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
17
log(str(result), filters)
29
/* Allocate the data area */
18
return result
30
new_file_size = allocation_start +
19
31
nb_new_data_clusters * s->cluster_size;
20
+ def run_job(self, job, auto_finalize=True, auto_dismiss=False):
32
- /* Image file grows, so @exact does not matter */
21
+ while True:
33
- ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
22
+ for ev in self.get_qmp_events_filtered(wait=True):
34
- errp);
23
+ if ev['event'] == 'JOB_STATUS_CHANGE':
35
+ /*
24
+ status = ev['data']['status']
36
+ * Image file grows, so @exact does not matter.
25
+ if status == 'aborting':
37
+ *
26
+ result = self.qmp('query-jobs')
38
+ * If we need to zero out the new area, try first whether the protocol
27
+ for j in result['return']:
39
+ * driver can already take care of this.
28
+ if j['id'] == job:
40
+ */
29
+ log('Job failed: %s' % (j['error']))
41
+ if (flags & BDRV_REQ_ZERO_WRITE) {
30
+ elif status == 'pending' and not auto_finalize:
42
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc,
31
+ self.qmp_log('job-finalize', id=job)
43
+ BDRV_REQ_ZERO_WRITE, NULL);
32
+ elif status == 'concluded' and not auto_dismiss:
44
+ if (ret >= 0) {
33
+ self.qmp_log('job-dismiss', id=job)
45
+ flags &= ~BDRV_REQ_ZERO_WRITE;
34
+ elif status == 'null':
46
+ }
35
+ return
47
+ } else {
36
+ else:
48
+ ret = -1;
37
+ iotests.log(ev)
49
+ }
38
+
50
+ if (ret < 0) {
39
51
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
40
index_re = re.compile(r'([^\[]+)\[([^\]]+)\]')
52
+ errp);
41
53
+ }
54
if (ret < 0) {
55
error_prepend(errp, "Failed to resize underlying file: ");
56
qcow2_free_clusters(bs, allocation_start,
57
diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
58
index XXXXXXX..XXXXXXX 100644
59
--- a/tests/qemu-iotests/274.out
60
+++ b/tests/qemu-iotests/274.out
61
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 9437184
62
10 MiB (0xa00000) bytes allocated at offset 5 MiB (0x500000)
63
64
[{ "start": 0, "length": 5242880, "depth": 1, "zero": true, "data": false},
65
-{ "start": 5242880, "length": 10485760, "depth": 0, "zero": true, "data": false, "offset": 327680}]
66
+{ "start": 5242880, "length": 10485760, "depth": 0, "zero": false, "data": true, "offset": 327680}]
67
68
=== preallocation=full ===
69
Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
70
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 11534336
71
4 MiB (0x400000) bytes allocated at offset 8 MiB (0x800000)
72
73
[{ "start": 0, "length": 8388608, "depth": 1, "zero": true, "data": false},
74
-{ "start": 8388608, "length": 4194304, "depth": 0, "zero": true, "data": false, "offset": 327680}]
75
+{ "start": 8388608, "length": 4194304, "depth": 0, "zero": false, "data": true, "offset": 327680}]
76
77
=== preallocation=off ===
78
Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
42
--
79
--
43
2.13.6
80
2.25.3
44
81
45
82
diff view generated by jsdifflib
1
This changes the x-blockdev-create QMP command so that it doesn't block
1
From: Andrzej Jakowski <andrzej.jakowski@linux.intel.com>
2
the monitor and the main loop any more, but starts a background job that
3
performs the image creation.
4
2
5
The basic job as implemented here is all that is necessary to make image
3
This patch introduces support for PMR that has been defined as part of NVMe 1.4
6
creation asynchronous and to provide a QMP interface that can be marked
4
spec. User can now specify a pmrdev option that should point to HostMemoryBackend.
7
stable, but it still lacks a few features that jobs usually provide: The
5
pmrdev memory region will subsequently be exposed as PCI BAR 2 in emulated NVMe
8
job will ignore pause commands and it doesn't publish more than very
6
device. Guest OS can perform mmio read and writes to the PMR region that will stay
9
basic progress yet (total-progress is 1 and current-progress advances
7
persistent across system reboot.
10
from 0 to 1 when the driver callbacks returns). These features can be
11
added later without breaking compatibility.
12
8
9
Signed-off-by: Andrzej Jakowski <andrzej.jakowski@linux.intel.com>
10
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
11
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Message-Id: <20200330164656.9348-1-andrzej.jakowski@linux.intel.com>
13
Reviewed-by: Keith Busch <kbusch@kernel.org>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Reviewed-by: Max Reitz <mreitz@redhat.com>
15
Reviewed-by: Jeff Cody <jcody@redhat.com>
16
---
15
---
17
qapi/block-core.json | 14 ++++++----
16
hw/block/nvme.h | 2 +
18
qapi/job.json | 4 ++-
17
include/block/nvme.h | 172 +++++++++++++++++++++++++++++++++++++++++
19
block/create.c | 67 +++++++++++++++++++++++++++++++++---------------
18
hw/block/nvme.c | 109 ++++++++++++++++++++++++++
20
tests/qemu-iotests/group | 14 +++++-----
19
hw/block/Makefile.objs | 2 +-
21
4 files changed, 66 insertions(+), 33 deletions(-)
20
hw/block/trace-events | 4 +
21
5 files changed, 288 insertions(+), 1 deletion(-)
22
22
23
diff --git a/qapi/block-core.json b/qapi/block-core.json
23
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
24
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
25
--- a/qapi/block-core.json
25
--- a/hw/block/nvme.h
26
+++ b/qapi/block-core.json
26
+++ b/hw/block/nvme.h
27
@@ -XXX,XX +XXX,XX @@ typedef struct NvmeCtrl {
28
uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
29
30
char *serial;
31
+ HostMemoryBackend *pmrdev;
32
+
33
NvmeNamespace *namespaces;
34
NvmeSQueue **sq;
35
NvmeCQueue **cq;
36
diff --git a/include/block/nvme.h b/include/block/nvme.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/include/block/nvme.h
39
+++ b/include/block/nvme.h
40
@@ -XXX,XX +XXX,XX @@ typedef struct NvmeBar {
41
uint64_t acq;
42
uint32_t cmbloc;
43
uint32_t cmbsz;
44
+ uint8_t padding[3520]; /* not used by QEMU */
45
+ uint32_t pmrcap;
46
+ uint32_t pmrctl;
47
+ uint32_t pmrsts;
48
+ uint32_t pmrebs;
49
+ uint32_t pmrswtp;
50
+ uint32_t pmrmsc;
51
} NvmeBar;
52
53
enum NvmeCapShift {
54
@@ -XXX,XX +XXX,XX @@ enum NvmeCapShift {
55
CAP_CSS_SHIFT = 37,
56
CAP_MPSMIN_SHIFT = 48,
57
CAP_MPSMAX_SHIFT = 52,
58
+ CAP_PMR_SHIFT = 56,
59
};
60
61
enum NvmeCapMask {
62
@@ -XXX,XX +XXX,XX @@ enum NvmeCapMask {
63
CAP_CSS_MASK = 0xff,
64
CAP_MPSMIN_MASK = 0xf,
65
CAP_MPSMAX_MASK = 0xf,
66
+ CAP_PMR_MASK = 0x1,
67
};
68
69
#define NVME_CAP_MQES(cap) (((cap) >> CAP_MQES_SHIFT) & CAP_MQES_MASK)
70
@@ -XXX,XX +XXX,XX @@ enum NvmeCapMask {
71
<< CAP_MPSMIN_SHIFT)
72
#define NVME_CAP_SET_MPSMAX(cap, val) (cap |= (uint64_t)(val & CAP_MPSMAX_MASK)\
73
<< CAP_MPSMAX_SHIFT)
74
+#define NVME_CAP_SET_PMRS(cap, val) (cap |= (uint64_t)(val & CAP_PMR_MASK)\
75
+ << CAP_PMR_SHIFT)
76
77
enum NvmeCcShift {
78
CC_EN_SHIFT = 0,
79
@@ -XXX,XX +XXX,XX @@ enum NvmeCmbszMask {
80
#define NVME_CMBSZ_GETSIZE(cmbsz) \
81
(NVME_CMBSZ_SZ(cmbsz) * (1 << (12 + 4 * NVME_CMBSZ_SZU(cmbsz))))
82
83
+enum NvmePmrcapShift {
84
+ PMRCAP_RDS_SHIFT = 3,
85
+ PMRCAP_WDS_SHIFT = 4,
86
+ PMRCAP_BIR_SHIFT = 5,
87
+ PMRCAP_PMRTU_SHIFT = 8,
88
+ PMRCAP_PMRWBM_SHIFT = 10,
89
+ PMRCAP_PMRTO_SHIFT = 16,
90
+ PMRCAP_CMSS_SHIFT = 24,
91
+};
92
+
93
+enum NvmePmrcapMask {
94
+ PMRCAP_RDS_MASK = 0x1,
95
+ PMRCAP_WDS_MASK = 0x1,
96
+ PMRCAP_BIR_MASK = 0x7,
97
+ PMRCAP_PMRTU_MASK = 0x3,
98
+ PMRCAP_PMRWBM_MASK = 0xf,
99
+ PMRCAP_PMRTO_MASK = 0xff,
100
+ PMRCAP_CMSS_MASK = 0x1,
101
+};
102
+
103
+#define NVME_PMRCAP_RDS(pmrcap) \
104
+ ((pmrcap >> PMRCAP_RDS_SHIFT) & PMRCAP_RDS_MASK)
105
+#define NVME_PMRCAP_WDS(pmrcap) \
106
+ ((pmrcap >> PMRCAP_WDS_SHIFT) & PMRCAP_WDS_MASK)
107
+#define NVME_PMRCAP_BIR(pmrcap) \
108
+ ((pmrcap >> PMRCAP_BIR_SHIFT) & PMRCAP_BIR_MASK)
109
+#define NVME_PMRCAP_PMRTU(pmrcap) \
110
+ ((pmrcap >> PMRCAP_PMRTU_SHIFT) & PMRCAP_PMRTU_MASK)
111
+#define NVME_PMRCAP_PMRWBM(pmrcap) \
112
+ ((pmrcap >> PMRCAP_PMRWBM_SHIFT) & PMRCAP_PMRWBM_MASK)
113
+#define NVME_PMRCAP_PMRTO(pmrcap) \
114
+ ((pmrcap >> PMRCAP_PMRTO_SHIFT) & PMRCAP_PMRTO_MASK)
115
+#define NVME_PMRCAP_CMSS(pmrcap) \
116
+ ((pmrcap >> PMRCAP_CMSS_SHIFT) & PMRCAP_CMSS_MASK)
117
+
118
+#define NVME_PMRCAP_SET_RDS(pmrcap, val) \
119
+ (pmrcap |= (uint64_t)(val & PMRCAP_RDS_MASK) << PMRCAP_RDS_SHIFT)
120
+#define NVME_PMRCAP_SET_WDS(pmrcap, val) \
121
+ (pmrcap |= (uint64_t)(val & PMRCAP_WDS_MASK) << PMRCAP_WDS_SHIFT)
122
+#define NVME_PMRCAP_SET_BIR(pmrcap, val) \
123
+ (pmrcap |= (uint64_t)(val & PMRCAP_BIR_MASK) << PMRCAP_BIR_SHIFT)
124
+#define NVME_PMRCAP_SET_PMRTU(pmrcap, val) \
125
+ (pmrcap |= (uint64_t)(val & PMRCAP_PMRTU_MASK) << PMRCAP_PMRTU_SHIFT)
126
+#define NVME_PMRCAP_SET_PMRWBM(pmrcap, val) \
127
+ (pmrcap |= (uint64_t)(val & PMRCAP_PMRWBM_MASK) << PMRCAP_PMRWBM_SHIFT)
128
+#define NVME_PMRCAP_SET_PMRTO(pmrcap, val) \
129
+ (pmrcap |= (uint64_t)(val & PMRCAP_PMRTO_MASK) << PMRCAP_PMRTO_SHIFT)
130
+#define NVME_PMRCAP_SET_CMSS(pmrcap, val) \
131
+ (pmrcap |= (uint64_t)(val & PMRCAP_CMSS_MASK) << PMRCAP_CMSS_SHIFT)
132
+
133
+enum NvmePmrctlShift {
134
+ PMRCTL_EN_SHIFT = 0,
135
+};
136
+
137
+enum NvmePmrctlMask {
138
+ PMRCTL_EN_MASK = 0x1,
139
+};
140
+
141
+#define NVME_PMRCTL_EN(pmrctl) ((pmrctl >> PMRCTL_EN_SHIFT) & PMRCTL_EN_MASK)
142
+
143
+#define NVME_PMRCTL_SET_EN(pmrctl, val) \
144
+ (pmrctl |= (uint64_t)(val & PMRCTL_EN_MASK) << PMRCTL_EN_SHIFT)
145
+
146
+enum NvmePmrstsShift {
147
+ PMRSTS_ERR_SHIFT = 0,
148
+ PMRSTS_NRDY_SHIFT = 8,
149
+ PMRSTS_HSTS_SHIFT = 9,
150
+ PMRSTS_CBAI_SHIFT = 12,
151
+};
152
+
153
+enum NvmePmrstsMask {
154
+ PMRSTS_ERR_MASK = 0xff,
155
+ PMRSTS_NRDY_MASK = 0x1,
156
+ PMRSTS_HSTS_MASK = 0x7,
157
+ PMRSTS_CBAI_MASK = 0x1,
158
+};
159
+
160
+#define NVME_PMRSTS_ERR(pmrsts) \
161
+ ((pmrsts >> PMRSTS_ERR_SHIFT) & PMRSTS_ERR_MASK)
162
+#define NVME_PMRSTS_NRDY(pmrsts) \
163
+ ((pmrsts >> PMRSTS_NRDY_SHIFT) & PMRSTS_NRDY_MASK)
164
+#define NVME_PMRSTS_HSTS(pmrsts) \
165
+ ((pmrsts >> PMRSTS_HSTS_SHIFT) & PMRSTS_HSTS_MASK)
166
+#define NVME_PMRSTS_CBAI(pmrsts) \
167
+ ((pmrsts >> PMRSTS_CBAI_SHIFT) & PMRSTS_CBAI_MASK)
168
+
169
+#define NVME_PMRSTS_SET_ERR(pmrsts, val) \
170
+ (pmrsts |= (uint64_t)(val & PMRSTS_ERR_MASK) << PMRSTS_ERR_SHIFT)
171
+#define NVME_PMRSTS_SET_NRDY(pmrsts, val) \
172
+ (pmrsts |= (uint64_t)(val & PMRSTS_NRDY_MASK) << PMRSTS_NRDY_SHIFT)
173
+#define NVME_PMRSTS_SET_HSTS(pmrsts, val) \
174
+ (pmrsts |= (uint64_t)(val & PMRSTS_HSTS_MASK) << PMRSTS_HSTS_SHIFT)
175
+#define NVME_PMRSTS_SET_CBAI(pmrsts, val) \
176
+ (pmrsts |= (uint64_t)(val & PMRSTS_CBAI_MASK) << PMRSTS_CBAI_SHIFT)
177
+
178
+enum NvmePmrebsShift {
179
+ PMREBS_PMRSZU_SHIFT = 0,
180
+ PMREBS_RBB_SHIFT = 4,
181
+ PMREBS_PMRWBZ_SHIFT = 8,
182
+};
183
+
184
+enum NvmePmrebsMask {
185
+ PMREBS_PMRSZU_MASK = 0xf,
186
+ PMREBS_RBB_MASK = 0x1,
187
+ PMREBS_PMRWBZ_MASK = 0xffffff,
188
+};
189
+
190
+#define NVME_PMREBS_PMRSZU(pmrebs) \
191
+ ((pmrebs >> PMREBS_PMRSZU_SHIFT) & PMREBS_PMRSZU_MASK)
192
+#define NVME_PMREBS_RBB(pmrebs) \
193
+ ((pmrebs >> PMREBS_RBB_SHIFT) & PMREBS_RBB_MASK)
194
+#define NVME_PMREBS_PMRWBZ(pmrebs) \
195
+ ((pmrebs >> PMREBS_PMRWBZ_SHIFT) & PMREBS_PMRWBZ_MASK)
196
+
197
+#define NVME_PMREBS_SET_PMRSZU(pmrebs, val) \
198
+ (pmrebs |= (uint64_t)(val & PMREBS_PMRSZU_MASK) << PMREBS_PMRSZU_SHIFT)
199
+#define NVME_PMREBS_SET_RBB(pmrebs, val) \
200
+ (pmrebs |= (uint64_t)(val & PMREBS_RBB_MASK) << PMREBS_RBB_SHIFT)
201
+#define NVME_PMREBS_SET_PMRWBZ(pmrebs, val) \
202
+ (pmrebs |= (uint64_t)(val & PMREBS_PMRWBZ_MASK) << PMREBS_PMRWBZ_SHIFT)
203
+
204
+enum NvmePmrswtpShift {
205
+ PMRSWTP_PMRSWTU_SHIFT = 0,
206
+ PMRSWTP_PMRSWTV_SHIFT = 8,
207
+};
208
+
209
+enum NvmePmrswtpMask {
210
+ PMRSWTP_PMRSWTU_MASK = 0xf,
211
+ PMRSWTP_PMRSWTV_MASK = 0xffffff,
212
+};
213
+
214
+#define NVME_PMRSWTP_PMRSWTU(pmrswtp) \
215
+ ((pmrswtp >> PMRSWTP_PMRSWTU_SHIFT) & PMRSWTP_PMRSWTU_MASK)
216
+#define NVME_PMRSWTP_PMRSWTV(pmrswtp) \
217
+ ((pmrswtp >> PMRSWTP_PMRSWTV_SHIFT) & PMRSWTP_PMRSWTV_MASK)
218
+
219
+#define NVME_PMRSWTP_SET_PMRSWTU(pmrswtp, val) \
220
+ (pmrswtp |= (uint64_t)(val & PMRSWTP_PMRSWTU_MASK) << PMRSWTP_PMRSWTU_SHIFT)
221
+#define NVME_PMRSWTP_SET_PMRSWTV(pmrswtp, val) \
222
+ (pmrswtp |= (uint64_t)(val & PMRSWTP_PMRSWTV_MASK) << PMRSWTP_PMRSWTV_SHIFT)
223
+
224
+enum NvmePmrmscShift {
225
+ PMRMSC_CMSE_SHIFT = 1,
226
+ PMRMSC_CBA_SHIFT = 12,
227
+};
228
+
229
+enum NvmePmrmscMask {
230
+ PMRMSC_CMSE_MASK = 0x1,
231
+ PMRMSC_CBA_MASK = 0xfffffffffffff,
232
+};
233
+
234
+#define NVME_PMRMSC_CMSE(pmrmsc) \
235
+ ((pmrmsc >> PMRMSC_CMSE_SHIFT) & PMRMSC_CMSE_MASK)
236
+#define NVME_PMRMSC_CBA(pmrmsc) \
237
+ ((pmrmsc >> PMRMSC_CBA_SHIFT) & PMRMSC_CBA_MASK)
238
+
239
+#define NVME_PMRMSC_SET_CMSE(pmrmsc, val) \
240
+ (pmrmsc |= (uint64_t)(val & PMRMSC_CMSE_MASK) << PMRMSC_CMSE_SHIFT)
241
+#define NVME_PMRMSC_SET_CBA(pmrmsc, val) \
242
+ (pmrmsc |= (uint64_t)(val & PMRMSC_CBA_MASK) << PMRMSC_CBA_SHIFT)
243
+
244
typedef struct NvmeCmd {
245
uint8_t opcode;
246
uint8_t fuse;
247
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
248
index XXXXXXX..XXXXXXX 100644
249
--- a/hw/block/nvme.c
250
+++ b/hw/block/nvme.c
27
@@ -XXX,XX +XXX,XX @@
251
@@ -XXX,XX +XXX,XX @@
28
##
252
* -drive file=<file>,if=none,id=<drive_id>
29
# @x-blockdev-create:
253
* -device nvme,drive=<drive_id>,serial=<serial>,id=<id[optional]>, \
30
#
254
* cmb_size_mb=<cmb_size_mb[optional]>, \
31
-# Create an image format on a given node.
255
+ * [pmrdev=<mem_backend_file_id>,] \
32
-# TODO Replace with something asynchronous (block job?)
256
* num_queues=<N[optional]>
33
+# Starts a job to create an image format on a given node. The job is
257
*
34
+# automatically finalized, but a manual job-dismiss is required.
258
* Note cmb_size_mb denotes size of CMB in MB. CMB is assumed to be at
35
#
259
* offset 0 in BAR2 and supports only WDS, RDS and SQS for now.
36
-# Since: 2.12
260
+ *
37
+# @job-id: Identifier for the newly created job.
261
+ * cmb_size_mb= and pmrdev= options are mutually exclusive due to limitation
38
+#
262
+ * in available BAR's. cmb_size_mb= will take precedence over pmrdev= when
39
+# @options: Options for the image creation.
263
+ * both provided.
40
+#
264
+ * Enabling pmr emulation can be achieved by pointing to memory-backend-file.
41
+# Since: 3.0
265
+ * For example:
42
##
266
+ * -object memory-backend-file,id=<mem_id>,share=on,mem-path=<file_path>, \
43
{ 'command': 'x-blockdev-create',
267
+ * size=<size> .... -device nvme,...,pmrdev=<mem_id>
44
- 'data': 'BlockdevCreateOptions',
268
*/
45
- 'boxed': true }
269
46
+ 'data': { 'job-id': 'str',
270
#include "qemu/osdep.h"
47
+ 'options': 'BlockdevCreateOptions' } }
48
49
##
50
# @blockdev-open-tray:
51
diff --git a/qapi/job.json b/qapi/job.json
52
index XXXXXXX..XXXXXXX 100644
53
--- a/qapi/job.json
54
+++ b/qapi/job.json
55
@@ -XXX,XX +XXX,XX @@
271
@@ -XXX,XX +XXX,XX @@
56
#
272
#include "sysemu/sysemu.h"
57
# @backup: drive backup job type, see "drive-backup"
58
#
59
+# @create: image creation job type, see "x-blockdev-create" (since 3.0)
60
+#
61
# Since: 1.7
62
##
63
{ 'enum': 'JobType',
64
- 'data': ['commit', 'stream', 'mirror', 'backup'] }
65
+ 'data': ['commit', 'stream', 'mirror', 'backup', 'create'] }
66
67
##
68
# @JobStatus:
69
diff --git a/block/create.c b/block/create.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/block/create.c
72
+++ b/block/create.c
73
@@ -XXX,XX +XXX,XX @@
74
75
#include "qemu/osdep.h"
76
#include "block/block_int.h"
77
+#include "qemu/job.h"
78
#include "qapi/qapi-commands-block-core.h"
79
+#include "qapi/qapi-visit-block-core.h"
80
+#include "qapi/clone-visitor.h"
81
#include "qapi/error.h"
273
#include "qapi/error.h"
82
274
#include "qapi/visitor.h"
83
-typedef struct BlockdevCreateCo {
275
+#include "sysemu/hostmem.h"
84
+typedef struct BlockdevCreateJob {
276
#include "sysemu/block-backend.h"
85
+ Job common;
277
+#include "exec/ram_addr.h"
86
BlockDriver *drv;
278
87
BlockdevCreateOptions *opts;
279
#include "qemu/log.h"
88
int ret;
280
#include "qemu/module.h"
89
- Error **errp;
281
@@ -XXX,XX +XXX,XX @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
90
-} BlockdevCreateCo;
282
NVME_GUEST_ERR(nvme_ub_mmiowr_cmbsz_readonly,
91
+ Error *err;
283
"invalid write to read only CMBSZ, ignored");
92
+} BlockdevCreateJob;
284
return;
93
285
+ case 0xE00: /* PMRCAP */
94
-static void coroutine_fn bdrv_co_create_co_entry(void *opaque)
286
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrcap_readonly,
95
+static void blockdev_create_complete(Job *job, void *opaque)
287
+ "invalid write to PMRCAP register, ignored");
96
{
288
+ return;
97
- BlockdevCreateCo *cco = opaque;
289
+ case 0xE04: /* TODO PMRCTL */
98
- cco->ret = cco->drv->bdrv_co_create(cco->opts, cco->errp);
290
+ break;
99
+ BlockdevCreateJob *s = container_of(job, BlockdevCreateJob, common);
291
+ case 0xE08: /* PMRSTS */
100
+
292
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrsts_readonly,
101
+ job_completed(job, s->ret, s->err);
293
+ "invalid write to PMRSTS register, ignored");
102
}
294
+ return;
103
295
+ case 0xE0C: /* PMREBS */
104
-void qmp_x_blockdev_create(BlockdevCreateOptions *options, Error **errp)
296
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrebs_readonly,
105
+static void coroutine_fn blockdev_create_run(void *opaque)
297
+ "invalid write to PMREBS register, ignored");
106
{
298
+ return;
107
+ BlockdevCreateJob *s = opaque;
299
+ case 0xE10: /* PMRSWTP */
108
+
300
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrswtp_readonly,
109
+ job_progress_set_remaining(&s->common, 1);
301
+ "invalid write to PMRSWTP register, ignored");
110
+ s->ret = s->drv->bdrv_co_create(s->opts, &s->err);
302
+ return;
111
+ job_progress_update(&s->common, 1);
303
+ case 0xE14: /* TODO PMRMSC */
112
+
304
+ break;
113
+ qapi_free_BlockdevCreateOptions(s->opts);
305
default:
114
+ job_defer_to_main_loop(&s->common, blockdev_create_complete, NULL);
306
NVME_GUEST_ERR(nvme_ub_mmiowr_invalid,
115
+}
307
"invalid MMIO write,"
116
+
308
@@ -XXX,XX +XXX,XX @@ static uint64_t nvme_mmio_read(void *opaque, hwaddr addr, unsigned size)
117
+static const JobDriver blockdev_create_job_driver = {
309
}
118
+ .instance_size = sizeof(BlockdevCreateJob),
310
119
+ .job_type = JOB_TYPE_CREATE,
311
if (addr < sizeof(n->bar)) {
120
+ .start = blockdev_create_run,
312
+ /*
121
+};
313
+ * When PMRWBM bit 1 is set then read from
122
+
314
+ * from PMRSTS should ensure prior writes
123
+void qmp_x_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
315
+ * made it to persistent media
124
+ Error **errp)
316
+ */
125
+{
317
+ if (addr == 0xE08 &&
126
+ BlockdevCreateJob *s;
318
+ (NVME_PMRCAP_PMRWBM(n->bar.pmrcap) & 0x02)) {
127
const char *fmt = BlockdevDriver_str(options->driver);
319
+ qemu_ram_writeback(n->pmrdev->mr.ram_block,
128
BlockDriver *drv = bdrv_find_format(fmt);
320
+ 0, n->pmrdev->size);
129
- Coroutine *co;
321
+ }
130
- BlockdevCreateCo cco;
322
memcpy(&val, ptr + addr, size);
131
323
} else {
132
/* If the driver is in the schema, we know that it exists. But it may not
324
NVME_GUEST_ERR(nvme_ub_mmiord_invalid_ofs,
133
* be whitelisted. */
325
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
134
@@ -XXX,XX +XXX,XX @@ void qmp_x_blockdev_create(BlockdevCreateOptions *options, Error **errp)
326
error_setg(errp, "serial property not set");
135
return;
327
return;
136
}
328
}
137
329
+
138
- /* Call callback if it exists */
330
+ if (!n->cmb_size_mb && n->pmrdev) {
139
+ /* Error out if the driver doesn't support .bdrv_co_create */
331
+ if (host_memory_backend_is_mapped(n->pmrdev)) {
140
if (!drv->bdrv_co_create) {
332
+ char *path = object_get_canonical_path_component(OBJECT(n->pmrdev));
141
error_setg(errp, "Driver does not support blockdev-create");
333
+ error_setg(errp, "can't use already busy memdev: %s", path);
142
return;
334
+ g_free(path);
335
+ return;
336
+ }
337
+
338
+ if (!is_power_of_2(n->pmrdev->size)) {
339
+ error_setg(errp, "pmr backend size needs to be power of 2 in size");
340
+ return;
341
+ }
342
+
343
+ host_memory_backend_set_mapped(n->pmrdev, true);
344
+ }
345
+
346
blkconf_blocksizes(&n->conf);
347
if (!blkconf_apply_backend_options(&n->conf, blk_is_read_only(n->conf.blk),
348
false, errp)) {
349
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
350
PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64 |
351
PCI_BASE_ADDRESS_MEM_PREFETCH, &n->ctrl_mem);
352
353
+ } else if (n->pmrdev) {
354
+ /* Controller Capabilities register */
355
+ NVME_CAP_SET_PMRS(n->bar.cap, 1);
356
+
357
+ /* PMR Capabities register */
358
+ n->bar.pmrcap = 0;
359
+ NVME_PMRCAP_SET_RDS(n->bar.pmrcap, 0);
360
+ NVME_PMRCAP_SET_WDS(n->bar.pmrcap, 0);
361
+ NVME_PMRCAP_SET_BIR(n->bar.pmrcap, 2);
362
+ NVME_PMRCAP_SET_PMRTU(n->bar.pmrcap, 0);
363
+ /* Turn on bit 1 support */
364
+ NVME_PMRCAP_SET_PMRWBM(n->bar.pmrcap, 0x02);
365
+ NVME_PMRCAP_SET_PMRTO(n->bar.pmrcap, 0);
366
+ NVME_PMRCAP_SET_CMSS(n->bar.pmrcap, 0);
367
+
368
+ /* PMR Control register */
369
+ n->bar.pmrctl = 0;
370
+ NVME_PMRCTL_SET_EN(n->bar.pmrctl, 0);
371
+
372
+ /* PMR Status register */
373
+ n->bar.pmrsts = 0;
374
+ NVME_PMRSTS_SET_ERR(n->bar.pmrsts, 0);
375
+ NVME_PMRSTS_SET_NRDY(n->bar.pmrsts, 0);
376
+ NVME_PMRSTS_SET_HSTS(n->bar.pmrsts, 0);
377
+ NVME_PMRSTS_SET_CBAI(n->bar.pmrsts, 0);
378
+
379
+ /* PMR Elasticity Buffer Size register */
380
+ n->bar.pmrebs = 0;
381
+ NVME_PMREBS_SET_PMRSZU(n->bar.pmrebs, 0);
382
+ NVME_PMREBS_SET_RBB(n->bar.pmrebs, 0);
383
+ NVME_PMREBS_SET_PMRWBZ(n->bar.pmrebs, 0);
384
+
385
+ /* PMR Sustained Write Throughput register */
386
+ n->bar.pmrswtp = 0;
387
+ NVME_PMRSWTP_SET_PMRSWTU(n->bar.pmrswtp, 0);
388
+ NVME_PMRSWTP_SET_PMRSWTV(n->bar.pmrswtp, 0);
389
+
390
+ /* PMR Memory Space Control register */
391
+ n->bar.pmrmsc = 0;
392
+ NVME_PMRMSC_SET_CMSE(n->bar.pmrmsc, 0);
393
+ NVME_PMRMSC_SET_CBA(n->bar.pmrmsc, 0);
394
+
395
+ pci_register_bar(pci_dev, NVME_PMRCAP_BIR(n->bar.pmrcap),
396
+ PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64 |
397
+ PCI_BASE_ADDRESS_MEM_PREFETCH, &n->pmrdev->mr);
143
}
398
}
144
399
145
- cco = (BlockdevCreateCo) {
400
for (i = 0; i < n->num_namespaces; i++) {
146
- .drv = drv,
401
@@ -XXX,XX +XXX,XX @@ static void nvme_exit(PCIDevice *pci_dev)
147
- .opts = options,
402
if (n->cmb_size_mb) {
148
- .ret = -EINPROGRESS,
403
g_free(n->cmbuf);
149
- .errp = errp,
150
- };
151
-
152
- co = qemu_coroutine_create(bdrv_co_create_co_entry, &cco);
153
- qemu_coroutine_enter(co);
154
- while (cco.ret == -EINPROGRESS) {
155
- aio_poll(qemu_get_aio_context(), true);
156
+ /* Create the block job */
157
+ /* TODO Running in the main context. Block drivers need to error out or add
158
+ * locking when they use a BDS in a different AioContext. */
159
+ s = job_create(job_id, &blockdev_create_job_driver, NULL,
160
+ qemu_get_aio_context(), JOB_DEFAULT | JOB_MANUAL_DISMISS,
161
+ NULL, NULL, errp);
162
+ if (!s) {
163
+ return;
164
}
404
}
165
+
405
+
166
+ s->drv = drv,
406
+ if (n->pmrdev) {
167
+ s->opts = QAPI_CLONE(BlockdevCreateOptions, options),
407
+ host_memory_backend_set_mapped(n->pmrdev, false);
168
+
408
+ }
169
+ job_start(&s->common);
409
msix_uninit_exclusive_bar(pci_dev);
170
}
410
}
171
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
411
412
static Property nvme_props[] = {
413
DEFINE_BLOCK_PROPERTIES(NvmeCtrl, conf),
414
+ DEFINE_PROP_LINK("pmrdev", NvmeCtrl, pmrdev, TYPE_MEMORY_BACKEND,
415
+ HostMemoryBackend *),
416
DEFINE_PROP_STRING("serial", NvmeCtrl, serial),
417
DEFINE_PROP_UINT32("cmb_size_mb", NvmeCtrl, cmb_size_mb, 0),
418
DEFINE_PROP_UINT32("num_queues", NvmeCtrl, num_queues, 64),
419
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
172
index XXXXXXX..XXXXXXX 100644
420
index XXXXXXX..XXXXXXX 100644
173
--- a/tests/qemu-iotests/group
421
--- a/hw/block/Makefile.objs
174
+++ b/tests/qemu-iotests/group
422
+++ b/hw/block/Makefile.objs
175
@@ -XXX,XX +XXX,XX @@
423
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
176
203 rw auto migration
424
common-obj-$(CONFIG_XEN) += xen-block.o
177
204 rw auto quick
425
common-obj-$(CONFIG_ECC) += ecc.o
178
205 rw auto quick
426
common-obj-$(CONFIG_ONENAND) += onenand.o
179
-206 rw auto
427
-common-obj-$(CONFIG_NVME_PCI) += nvme.o
180
-207 rw auto
428
common-obj-$(CONFIG_SWIM) += swim.o
181
+# TODO The following commented out tests need to be reworked to work
429
182
+# with the x-blockdev-create job
430
common-obj-$(CONFIG_SH4) += tc58128.o
183
+#206 rw auto
431
184
+#207 rw auto
432
obj-$(CONFIG_VIRTIO_BLK) += virtio-blk.o
185
208 rw auto quick
433
obj-$(CONFIG_VHOST_USER_BLK) += vhost-user-blk.o
186
209 rw auto quick
434
+obj-$(CONFIG_NVME_PCI) += nvme.o
187
-210 rw auto
435
188
-211 rw auto quick
436
obj-y += dataplane/
189
-212 rw auto quick
437
diff --git a/hw/block/trace-events b/hw/block/trace-events
190
-213 rw auto quick
438
index XXXXXXX..XXXXXXX 100644
191
+#210 rw auto
439
--- a/hw/block/trace-events
192
+#211 rw auto quick
440
+++ b/hw/block/trace-events
193
+#212 rw auto quick
441
@@ -XXX,XX +XXX,XX @@ nvme_ub_mmiowr_ssreset_w1c_unsupported(void) "attempted to W1C CSTS.NSSRO but CA
194
+#213 rw auto quick
442
nvme_ub_mmiowr_ssreset_unsupported(void) "attempted NVM subsystem reset but CAP.NSSRS is zero (not supported)"
195
214 rw auto
443
nvme_ub_mmiowr_cmbloc_reserved(void) "invalid write to reserved CMBLOC when CMBSZ is zero, ignored"
196
215 rw auto quick
444
nvme_ub_mmiowr_cmbsz_readonly(void) "invalid write to read only CMBSZ, ignored"
197
216 rw auto quick
445
+nvme_ub_mmiowr_pmrcap_readonly(void) "invalid write to read only PMRCAP, ignored"
446
+nvme_ub_mmiowr_pmrsts_readonly(void) "invalid write to read only PMRSTS, ignored"
447
+nvme_ub_mmiowr_pmrebs_readonly(void) "invalid write to read only PMREBS, ignored"
448
+nvme_ub_mmiowr_pmrswtp_readonly(void) "invalid write to read only PMRSWTP, ignored"
449
nvme_ub_mmiowr_invalid(uint64_t offset, uint64_t data) "invalid MMIO write, offset=0x%"PRIx64", data=0x%"PRIx64""
450
nvme_ub_mmiord_misaligned32(uint64_t offset) "MMIO read not 32-bit aligned, offset=0x%"PRIx64""
451
nvme_ub_mmiord_toosmall(uint64_t offset) "MMIO read smaller than 32-bits, offset=0x%"PRIx64""
198
--
452
--
199
2.13.6
453
2.25.3
200
454
201
455
diff view generated by jsdifflib
1
.bdrv_co_create() is supposed to return 0 on success, but vdi could
1
The QMP handler qmp_object_add() and the implementation of --object in
2
return a positive value instead. Fix this.
2
qemu-storage-daemon can share most of the code. Currently,
3
qemu-storage-daemon calls qmp_object_add(), but this is not correct
4
because different visitors need to be used.
5
6
As a first step towards a fix, make qmp_object_add() a wrapper around a
7
new function user_creatable_add_dict() that can get an additional
8
parameter. The handling of "props" is only required for compatibility
9
and not required for the qemu-storage-daemon command line, so it stays
10
in qmp_object_add().
3
11
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
Reviewed-by: Jeff Cody <jcody@redhat.com>
7
---
13
---
8
block/vdi.c | 1 +
14
include/qom/object_interfaces.h | 12 ++++++++++++
9
1 file changed, 1 insertion(+)
15
qom/object_interfaces.c | 27 +++++++++++++++++++++++++++
16
qom/qom-qmp-cmds.c | 24 +-----------------------
17
3 files changed, 40 insertions(+), 23 deletions(-)
10
18
11
diff --git a/block/vdi.c b/block/vdi.c
19
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
12
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
13
--- a/block/vdi.c
21
--- a/include/qom/object_interfaces.h
14
+++ b/block/vdi.c
22
+++ b/include/qom/object_interfaces.h
15
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
23
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
16
}
24
const QDict *qdict,
25
Visitor *v, Error **errp);
26
27
+/**
28
+ * user_creatable_add_dict:
29
+ * @qdict: the object definition
30
+ * @errp: if an error occurs, a pointer to an area to store the error
31
+ *
32
+ * Create an instance of the user creatable object that is defined by
33
+ * @qdict. The object type is taken from the QDict key 'qom-type', its
34
+ * ID from the key 'id'. The remaining entries in @qdict are used to
35
+ * initialize the object properties.
36
+ */
37
+void user_creatable_add_dict(QDict *qdict, Error **errp);
38
+
39
/**
40
* user_creatable_add_opts:
41
* @opts: the object definition
42
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/qom/object_interfaces.c
45
+++ b/qom/object_interfaces.c
46
@@ -XXX,XX +XXX,XX @@
47
#include "qapi/qmp/qerror.h"
48
#include "qapi/qmp/qjson.h"
49
#include "qapi/qmp/qstring.h"
50
+#include "qapi/qobject-input-visitor.h"
51
#include "qom/object_interfaces.h"
52
#include "qemu/help_option.h"
53
#include "qemu/module.h"
54
@@ -XXX,XX +XXX,XX @@ out:
55
return obj;
56
}
57
58
+void user_creatable_add_dict(QDict *qdict, Error **errp)
59
+{
60
+ Visitor *v;
61
+ Object *obj;
62
+ g_autofree char *type = NULL;
63
+ g_autofree char *id = NULL;
64
+
65
+ type = g_strdup(qdict_get_try_str(qdict, "qom-type"));
66
+ if (!type) {
67
+ error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
68
+ return;
69
+ }
70
+ qdict_del(qdict, "qom-type");
71
+
72
+ id = g_strdup(qdict_get_try_str(qdict, "id"));
73
+ if (!id) {
74
+ error_setg(errp, QERR_MISSING_PARAMETER, "id");
75
+ return;
76
+ }
77
+ qdict_del(qdict, "id");
78
+
79
+ v = qobject_input_visitor_new(QOBJECT(qdict));
80
+ obj = user_creatable_add_type(type, id, qdict, v, errp);
81
+ visit_free(v);
82
+ object_unref(obj);
83
+}
84
85
Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)
86
{
87
diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/qom/qom-qmp-cmds.c
90
+++ b/qom/qom-qmp-cmds.c
91
@@ -XXX,XX +XXX,XX @@
92
#include "qapi/qapi-commands-qom.h"
93
#include "qapi/qmp/qdict.h"
94
#include "qapi/qmp/qerror.h"
95
-#include "qapi/qobject-input-visitor.h"
96
#include "qemu/cutils.h"
97
#include "qom/object_interfaces.h"
98
#include "qom/qom-qobject.h"
99
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
100
{
101
QObject *props;
102
QDict *pdict;
103
- Visitor *v;
104
- Object *obj;
105
- g_autofree char *type = NULL;
106
- g_autofree char *id = NULL;
107
-
108
- type = g_strdup(qdict_get_try_str(qdict, "qom-type"));
109
- if (!type) {
110
- error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
111
- return;
112
- }
113
- qdict_del(qdict, "qom-type");
114
-
115
- id = g_strdup(qdict_get_try_str(qdict, "id"));
116
- if (!id) {
117
- error_setg(errp, QERR_MISSING_PARAMETER, "id");
118
- return;
119
- }
120
- qdict_del(qdict, "id");
121
122
props = qdict_get(qdict, "props");
123
if (props) {
124
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
125
qobject_unref(pdict);
17
}
126
}
18
127
19
+ ret = 0;
128
- v = qobject_input_visitor_new(QOBJECT(qdict));
20
exit:
129
- obj = user_creatable_add_type(type, id, qdict, v, errp);
21
blk_unref(blk);
130
- visit_free(v);
22
bdrv_unref(bs_file);
131
- object_unref(obj);
132
+ user_creatable_add_dict(qdict, errp);
133
}
134
135
void qmp_object_del(const char *id, Error **errp)
23
--
136
--
24
2.13.6
137
2.25.3
25
138
26
139
diff view generated by jsdifflib
Deleted patch
1
This adds a helper function that returns a list of QMP events that are
2
already filtered through filter_qmp_event().
3
1
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
Reviewed-by: Jeff Cody <jcody@redhat.com>
7
---
8
tests/qemu-iotests/iotests.py | 5 +++++
9
1 file changed, 5 insertions(+)
10
11
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tests/qemu-iotests/iotests.py
14
+++ b/tests/qemu-iotests/iotests.py
15
@@ -XXX,XX +XXX,XX @@ class VM(qtest.QEMUQtestMachine):
16
output_list += [key + '=' + obj[key]]
17
return ','.join(output_list)
18
19
+ def get_qmp_events_filtered(self, wait=True):
20
+ result = []
21
+ for ev in self.get_qmp_events(wait=wait):
22
+ result.append(filter_qmp_event(ev))
23
+ return result
24
25
26
index_re = re.compile(r'([^\[]+)\[([^\]]+)\]')
27
--
28
2.13.6
29
30
diff view generated by jsdifflib
Deleted patch
1
This adds a helper function that logs both the QMP request and the
2
received response before returning it.
3
1
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Jeff Cody <jcody@redhat.com>
6
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
---
8
tests/qemu-iotests/iotests.py | 11 +++++++++++
9
1 file changed, 11 insertions(+)
10
11
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tests/qemu-iotests/iotests.py
14
+++ b/tests/qemu-iotests/iotests.py
15
@@ -XXX,XX +XXX,XX @@ def filter_qmp_event(event):
16
event['timestamp']['microseconds'] = 'USECS'
17
return event
18
19
+def filter_testfiles(msg):
20
+ prefix = os.path.join(test_dir, "%s-" % (os.getpid()))
21
+ return msg.replace(prefix, 'TEST_DIR/PID-')
22
+
23
def log(msg, filters=[]):
24
for flt in filters:
25
msg = flt(msg)
26
@@ -XXX,XX +XXX,XX @@ class VM(qtest.QEMUQtestMachine):
27
result.append(filter_qmp_event(ev))
28
return result
29
30
+ def qmp_log(self, cmd, filters=[filter_testfiles], **kwargs):
31
+ logmsg = "{'execute': '%s', 'arguments': %s}" % (cmd, kwargs)
32
+ log(logmsg, filters)
33
+ result = self.qmp(cmd, **kwargs)
34
+ log(str(result), filters)
35
+ return result
36
+
37
38
index_re = re.compile(r'([^\[]+)\[([^\]]+)\]')
39
40
--
41
2.13.6
42
43
diff view generated by jsdifflib
1
This adds a filter function to postprocess 'qemu-img info' input
1
After processing the option string with the keyval parser, we get a
2
(similar to what _img_info does), and an img_info_log() function that
2
QDict that contains only strings. This QDict must be fed to a keyval
3
calls 'qemu-img info' and logs the filtered output.
3
visitor which converts the strings into the right data types.
4
4
5
qmp_object_add(), however, uses the normal QObject input visitor, which
6
expects a QDict where all properties already have the QType that matches
7
the data type required by the QOM object type.
8
9
Change the --object implementation in qemu-storage-daemon so that it
10
doesn't call qmp_object_add(), but calls user_creatable_add_dict()
11
directly instead and pass it a new keyval boolean that decides which
12
visitor must be used.
13
14
Reported-by: Coiby Xu <coiby.xu@gmail.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Jeff Cody <jcody@redhat.com>
8
---
16
---
9
tests/qemu-iotests/iotests.py | 18 ++++++++++++++++++
17
include/qom/object_interfaces.h | 6 +++++-
10
1 file changed, 18 insertions(+)
18
qemu-storage-daemon.c | 4 +---
19
qom/object_interfaces.c | 8 ++++++--
20
qom/qom-qmp-cmds.c | 2 +-
21
4 files changed, 13 insertions(+), 7 deletions(-)
11
22
12
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
23
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
13
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/qemu-iotests/iotests.py
25
--- a/include/qom/object_interfaces.h
15
+++ b/tests/qemu-iotests/iotests.py
26
+++ b/include/qom/object_interfaces.h
16
@@ -XXX,XX +XXX,XX @@ def qemu_img_pipe(*args):
27
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
17
sys.stderr.write('qemu-img received signal %i: %s\n' % (-exitcode, ' '.join(qemu_img_args + list(args))))
28
/**
18
return subp.communicate()[0]
29
* user_creatable_add_dict:
19
30
* @qdict: the object definition
20
+def img_info_log(filename, filter_path=None):
31
+ * @keyval: if true, use a keyval visitor for processing @qdict (i.e.
21
+ output = qemu_img_pipe('info', '-f', imgfmt, filename)
32
+ * assume that all @qdict values are strings); otherwise, use
22
+ if not filter_path:
33
+ * the normal QObject visitor (i.e. assume all @qdict values
23
+ filter_path = filename
34
+ * have the QType expected by the QOM object type)
24
+ log(filter_img_info(output, filter_path))
35
* @errp: if an error occurs, a pointer to an area to store the error
25
+
36
*
26
def qemu_io(*args):
37
* Create an instance of the user creatable object that is defined by
27
'''Run qemu-io and return the stdout data'''
38
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
28
args = qemu_io_args + list(args)
39
* ID from the key 'id'. The remaining entries in @qdict are used to
29
@@ -XXX,XX +XXX,XX @@ def filter_testfiles(msg):
40
* initialize the object properties.
30
prefix = os.path.join(test_dir, "%s-" % (os.getpid()))
41
*/
31
return msg.replace(prefix, 'TEST_DIR/PID-')
42
-void user_creatable_add_dict(QDict *qdict, Error **errp);
32
43
+void user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp);
33
+def filter_img_info(output, filename):
44
34
+ lines = []
45
/**
35
+ for line in output.split('\n'):
46
* user_creatable_add_opts:
36
+ if 'disk size' in line or 'actual-size' in line:
47
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
37
+ continue
48
index XXXXXXX..XXXXXXX 100644
38
+ line = line.replace(filename, 'TEST_IMG') \
49
--- a/qemu-storage-daemon.c
39
+ .replace(imgfmt, 'IMGFMT')
50
+++ b/qemu-storage-daemon.c
40
+ line = re.sub('iters: [0-9]+', 'iters: XXX', line)
51
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
41
+ line = re.sub('uuid: [-a-f0-9]+', 'uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', line)
52
QemuOpts *opts;
42
+ lines.append(line)
53
const char *type;
43
+ return '\n'.join(lines)
54
QDict *args;
44
+
55
- QObject *ret_data = NULL;
45
def log(msg, filters=[]):
56
46
for flt in filters:
57
/* FIXME The keyval parser rejects 'help' arguments, so we must
47
msg = flt(msg)
58
* unconditionall try QemuOpts first. */
59
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
60
qemu_opts_del(opts);
61
62
args = keyval_parse(optarg, "qom-type", &error_fatal);
63
- qmp_object_add(args, &ret_data, &error_fatal);
64
+ user_creatable_add_dict(args, true, &error_fatal);
65
qobject_unref(args);
66
- qobject_unref(ret_data);
67
break;
68
}
69
default:
70
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/qom/object_interfaces.c
73
+++ b/qom/object_interfaces.c
74
@@ -XXX,XX +XXX,XX @@ out:
75
return obj;
76
}
77
78
-void user_creatable_add_dict(QDict *qdict, Error **errp)
79
+void user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp)
80
{
81
Visitor *v;
82
Object *obj;
83
@@ -XXX,XX +XXX,XX @@ void user_creatable_add_dict(QDict *qdict, Error **errp)
84
}
85
qdict_del(qdict, "id");
86
87
- v = qobject_input_visitor_new(QOBJECT(qdict));
88
+ if (keyval) {
89
+ v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
90
+ } else {
91
+ v = qobject_input_visitor_new(QOBJECT(qdict));
92
+ }
93
obj = user_creatable_add_type(type, id, qdict, v, errp);
94
visit_free(v);
95
object_unref(obj);
96
diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/qom/qom-qmp-cmds.c
99
+++ b/qom/qom-qmp-cmds.c
100
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
101
qobject_unref(pdict);
102
}
103
104
- user_creatable_add_dict(qdict, errp);
105
+ user_creatable_add_dict(qdict, false, errp);
106
}
107
108
void qmp_object_del(const char *id, Error **errp)
48
--
109
--
49
2.13.6
110
2.25.3
50
111
51
112
diff view generated by jsdifflib