1
The following changes since commit 89ea03a7dc83ca36b670ba7f787802791fcb04b1:
1
The following changes since commit 16aaacb307ed607b9780c12702c44f0fe52edc7e:
2
2
3
Merge remote-tracking branch 'remotes/huth-gitlab/tags/m68k-pull-2019-09-07' into staging (2019-09-09 09:48:34 +0100)
3
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20200430' into staging (2020-04-30 14:00:36 +0100)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
8
8
9
for you to fetch changes up to 65f9f0c2a53b1572043501bb4e99500914e88cc6:
9
for you to fetch changes up to eaae29ef89d498d0eac553c77b554f310a47f809:
10
10
11
qcow2: Stop overwriting compressed clusters one by one (2019-09-12 11:26:59 +0200)
11
qemu-storage-daemon: Fix non-string --object properties (2020-04-30 17:51:07 +0200)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches:
15
15
16
- qcow2: Allow overwriting multiple compressed clusters at once for
16
- Fix resize (extending) of short overlays
17
better performance
17
- nvme: introduce PMR support from NVMe 1.4 spec
18
- nfs: add support for nfs_umount
18
- qemu-storage-daemon: Fix non-string --object properties
19
- file-posix: write_zeroes fixes
20
- qemu-io, blockdev-create, pr-manager: Fix crashes and memory leaks
21
- qcow2: Fix the calculation of the maximum L2 cache size
22
- vpc: Fix return code for vpc_co_create()
23
- blockjob: Code cleanup
24
- iotests improvements (e.g. for use with valgrind)
25
19
26
----------------------------------------------------------------
20
----------------------------------------------------------------
27
Alberto Garcia (2):
21
Alberto Garcia (1):
28
qcow2: Fix the calculation of the maximum L2 cache size
22
qcow2: Add incompatibility note between backing files and raw external data files
29
qcow2: Stop overwriting compressed clusters one by one
30
23
31
Andrey Shinkevich (6):
24
Andrzej Jakowski (1):
32
iotests: allow Valgrind checking all QEMU processes
25
nvme: introduce PMR support from NVMe 1.4 spec
33
iotests: exclude killed processes from running under Valgrind
34
iotests: Add casenotrun report to bash tests
35
iotests: Valgrind fails with nonexistent directory
36
iotests: extended timeout under Valgrind
37
iotests: extend sleeping time under Valgrind
38
26
39
Kevin Wolf (2):
27
Kevin Wolf (12):
40
file-posix: Fix has_write_zeroes after NO_FALLBACK
28
block: Add flags to BlockDriver.bdrv_co_truncate()
41
qemu-io: Don't leak pattern file in error path
29
block: Add flags to bdrv(_co)_truncate()
30
block-backend: Add flags to blk_truncate()
31
qcow2: Support BDRV_REQ_ZERO_WRITE for truncate
32
raw-format: Support BDRV_REQ_ZERO_WRITE for truncate
33
file-posix: Support BDRV_REQ_ZERO_WRITE for truncate
34
block: truncate: Don't make backing file data visible
35
iotests: Filter testfiles out in filter_img_info()
36
iotests: Test committing to short backing file
37
qcow2: Forward ZERO_WRITE flag for full preallocation
38
qom: Factor out user_creatable_add_dict()
39
qemu-storage-daemon: Fix non-string --object properties
42
40
43
Markus Armbruster (1):
41
Paolo Bonzini (1):
44
pr-manager: Fix invalid g_free() crash bug
42
qemu-iotests: allow qcow2 external discarded clusters to contain stale data
45
43
46
Max Reitz (7):
44
docs/interop/qcow2.txt | 3 +
47
block/file-posix: Reduce xfsctl() use
45
hw/block/nvme.h | 2 +
48
iotests: Test reverse sub-cluster qcow2 writes
46
include/block/block.h | 5 +-
49
vpc: Return 0 from vpc_co_create() on success
47
include/block/block_int.h | 10 +-
50
iotests: Add supported protocols to execute_test()
48
include/block/nvme.h | 172 ++++++++++++++++++++++++++
51
iotests: Restrict file Python tests to file
49
include/qom/object_interfaces.h | 16 +++
52
iotests: Restrict nbd Python tests to nbd
50
include/sysemu/block-backend.h | 2 +-
53
iotests: Test blockdev-create for vpc
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
54
96
55
Peter Lieven (1):
56
block/nfs: add support for nfs_umount
57
97
58
Philippe Mathieu-Daudé (1):
59
block/create: Do not abort if a block driver is not available
60
61
Vladimir Sementsov-Ogievskiy (2):
62
job: drop job_drain
63
iotests: skip 232 when run tests as root
64
65
include/block/blockjob_int.h | 19 ------
66
include/qemu/job.h | 13 ----
67
block/backup.c | 19 +-----
68
block/commit.c | 1 -
69
block/create.c | 6 +-
70
block/file-posix.c | 83 ++---------------------
71
block/mirror.c | 28 +-------
72
block/nfs.c | 5 +-
73
block/qcow2-cluster.c | 8 +--
74
block/qcow2.c | 6 +-
75
block/stream.c | 1 -
76
block/vpc.c | 3 +-
77
blockjob.c | 13 ----
78
job.c | 12 +---
79
qemu-io-cmds.c | 4 ++
80
scsi/pr-manager.c | 1 -
81
tests/test-bdrv-drain.c | 3 -
82
tests/test-block-iothread.c | 1 -
83
tests/test-blockjob-txn.c | 1 -
84
tests/test-blockjob.c | 2 -
85
tests/qemu-iotests/028 | 6 +-
86
tests/qemu-iotests/030 | 3 +-
87
tests/qemu-iotests/039 | 5 ++
88
tests/qemu-iotests/039.out | 30 ++-------
89
tests/qemu-iotests/040 | 3 +-
90
tests/qemu-iotests/041 | 3 +-
91
tests/qemu-iotests/044 | 3 +-
92
tests/qemu-iotests/045 | 3 +-
93
tests/qemu-iotests/051 | 4 ++
94
tests/qemu-iotests/055 | 3 +-
95
tests/qemu-iotests/056 | 3 +-
96
tests/qemu-iotests/057 | 3 +-
97
tests/qemu-iotests/061 | 2 +
98
tests/qemu-iotests/061.out | 12 +---
99
tests/qemu-iotests/065 | 3 +-
100
tests/qemu-iotests/096 | 3 +-
101
tests/qemu-iotests/118 | 3 +-
102
tests/qemu-iotests/124 | 3 +-
103
tests/qemu-iotests/129 | 3 +-
104
tests/qemu-iotests/132 | 3 +-
105
tests/qemu-iotests/137 | 1 +
106
tests/qemu-iotests/137.out | 6 +-
107
tests/qemu-iotests/139 | 3 +-
108
tests/qemu-iotests/147 | 5 +-
109
tests/qemu-iotests/148 | 3 +-
110
tests/qemu-iotests/151 | 3 +-
111
tests/qemu-iotests/152 | 3 +-
112
tests/qemu-iotests/155 | 3 +-
113
tests/qemu-iotests/163 | 3 +-
114
tests/qemu-iotests/165 | 3 +-
115
tests/qemu-iotests/169 | 3 +-
116
tests/qemu-iotests/183 | 9 ++-
117
tests/qemu-iotests/192 | 6 +-
118
tests/qemu-iotests/196 | 3 +-
119
tests/qemu-iotests/199 | 3 +-
120
tests/qemu-iotests/205 | 3 +-
121
tests/qemu-iotests/232 | 6 ++
122
tests/qemu-iotests/245 | 3 +-
123
tests/qemu-iotests/247 | 6 +-
124
tests/qemu-iotests/257 | 3 +-
125
tests/qemu-iotests/265 | 67 ++++++++++++++++++
126
tests/qemu-iotests/265.out | 6 ++
127
tests/qemu-iotests/266 | 153 ++++++++++++++++++++++++++++++++++++++++++
128
tests/qemu-iotests/266.out | 137 +++++++++++++++++++++++++++++++++++++
129
tests/qemu-iotests/common.rc | 105 ++++++++++++++++++++++++-----
130
tests/qemu-iotests/group | 2 +
131
tests/qemu-iotests/iotests.py | 4 +-
132
67 files changed, 590 insertions(+), 292 deletions(-)
133
create mode 100755 tests/qemu-iotests/265
134
create mode 100644 tests/qemu-iotests/265.out
135
create mode 100755 tests/qemu-iotests/266
136
create mode 100644 tests/qemu-iotests/266.out
137
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Alberto Garcia <berto@igalia.com>
2
2
3
The 'blockdev-create' QMP command was introduced as experimental
3
Backing files and raw external data files are mutually exclusive.
4
feature in commit b0292b851b8, using the assert() debug call.
4
The documentation of the raw external data bit (in autoclear_features)
5
It got promoted to 'stable' command in 3fb588a0f2c, but the
5
already indicates that, but we should also mention it on the other
6
assert call was not removed.
6
side.
7
7
8
Some block drivers are optional, and bdrv_find_format() might
8
Suggested-by: Eric Blake <eblake@redhat.com>
9
return a NULL value, triggering the assertion.
9
Signed-off-by: Alberto Garcia <berto@igalia.com>
10
10
Message-Id: <20200410121816.8334-1-berto@igalia.com>
11
Stable code is not expected to abort, so return an error instead.
12
13
This is easily reproducible when libnfs is not installed:
14
15
./configure
16
[...]
17
module support no
18
Block whitelist (rw)
19
Block whitelist (ro)
20
libiscsi support yes
21
libnfs support no
22
[...]
23
24
Start QEMU:
25
26
$ qemu-system-x86_64 -S -qmp unix:/tmp/qemu.qmp,server,nowait
27
28
Send the 'blockdev-create' with the 'nfs' driver:
29
30
$ ( cat << 'EOF'
31
{'execute': 'qmp_capabilities'}
32
{'execute': 'blockdev-create', 'arguments': {'job-id': 'x', 'options': {'size': 0, 'driver': 'nfs', 'location': {'path': '/', 'server': {'host': '::1', 'type': 'inet'}}}}, 'id': 'x'}
33
EOF
34
) | socat STDIO UNIX:/tmp/qemu.qmp
35
{"QMP": {"version": {"qemu": {"micro": 50, "minor": 1, "major": 4}, "package": "v4.1.0-733-g89ea03a7dc"}, "capabilities": ["oob"]}}
36
{"return": {}}
37
38
QEMU crashes:
39
40
$ gdb qemu-system-x86_64 core
41
Program received signal SIGSEGV, Segmentation fault.
42
(gdb) bt
43
#0 0x00007ffff510957f in raise () at /lib64/libc.so.6
44
#1 0x00007ffff50f3895 in abort () at /lib64/libc.so.6
45
#2 0x00007ffff50f3769 in _nl_load_domain.cold.0 () at /lib64/libc.so.6
46
#3 0x00007ffff5101a26 in .annobin_assert.c_end () at /lib64/libc.so.6
47
#4 0x0000555555d7e1f1 in qmp_blockdev_create (job_id=0x555556baee40 "x", options=0x555557666610, errp=0x7fffffffc770) at block/create.c:69
48
#5 0x0000555555c96b52 in qmp_marshal_blockdev_create (args=0x7fffdc003830, ret=0x7fffffffc7f8, errp=0x7fffffffc7f0) at qapi/qapi-commands-block-core.c:1314
49
#6 0x0000555555deb0a0 in do_qmp_dispatch (cmds=0x55555645de70 <qmp_commands>, request=0x7fffdc005c70, allow_oob=false, errp=0x7fffffffc898) at qapi/qmp-dispatch.c:131
50
#7 0x0000555555deb2a1 in qmp_dispatch (cmds=0x55555645de70 <qmp_commands>, request=0x7fffdc005c70, allow_oob=false) at qapi/qmp-dispatch.c:174
51
52
With this patch applied, QEMU returns a QMP error:
53
54
{'execute': 'blockdev-create', 'arguments': {'job-id': 'x', 'options': {'size': 0, 'driver': 'nfs', 'location': {'path': '/', 'server': {'host': '::1', 'type': 'inet'}}}}, 'id': 'x'}
55
{"id": "x", "error": {"class": "GenericError", "desc": "Block driver 'nfs' not found or not supported"}}
56
57
Cc: qemu-stable@nongnu.org
58
Reported-by: Xu Tian <xutian@redhat.com>
59
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
60
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
61
Reviewed-by: John Snow <jsnow@redhat.com>
62
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
63
---
13
---
64
block/create.c | 6 +++++-
14
docs/interop/qcow2.txt | 3 +++
65
1 file changed, 5 insertions(+), 1 deletion(-)
15
1 file changed, 3 insertions(+)
66
16
67
diff --git a/block/create.c b/block/create.c
17
diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
68
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
69
--- a/block/create.c
19
--- a/docs/interop/qcow2.txt
70
+++ b/block/create.c
20
+++ b/docs/interop/qcow2.txt
71
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
21
@@ -XXX,XX +XXX,XX @@ The first cluster of a qcow2 image contains the file header:
72
const char *fmt = BlockdevDriver_str(options->driver);
22
is stored (NB: The string is not null terminated). 0 if the
73
BlockDriver *drv = bdrv_find_format(fmt);
23
image doesn't have a backing file.
74
24
75
+ if (!drv) {
25
+ Note: backing files are incompatible with raw external data
76
+ error_setg(errp, "Block driver '%s' not found or not supported", fmt);
26
+ files (auto-clear feature bit 1).
77
+ return;
78
+ }
79
+
27
+
80
/* If the driver is in the schema, we know that it exists. But it may not
28
16 - 19: backing_file_size
81
* be whitelisted. */
29
Length of the backing file name in bytes. Must not be
82
- assert(drv);
30
longer than 1023 bytes. Undefined if the image doesn't have
83
if (bdrv_uses_whitelist() && !bdrv_is_whitelisted(drv, false)) {
84
error_setg(errp, "Driver is not whitelisted");
85
return;
86
--
31
--
87
2.20.1
32
2.25.3
88
33
89
34
diff view generated by jsdifflib
1
From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
To synchronize the time when QEMU is running longer under the Valgrind,
3
Test 244 checks the expected behavior of qcow2 external data files
4
increase the sleeping time in the test 247.
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.
5
9
6
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
10
This fixes docker tests on RHEL8.
7
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
8
Reviewed-by: John Snow <jsnow@redhat.com>
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>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
17
---
11
tests/qemu-iotests/247 | 6 +++++-
18
tests/qemu-iotests/244 | 10 ++++++++--
12
1 file changed, 5 insertions(+), 1 deletion(-)
19
tests/qemu-iotests/244.out | 9 ++++++---
20
2 files changed, 14 insertions(+), 5 deletions(-)
13
21
14
diff --git a/tests/qemu-iotests/247 b/tests/qemu-iotests/247
22
diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244
15
index XXXXXXX..XXXXXXX 100755
23
index XXXXXXX..XXXXXXX 100755
16
--- a/tests/qemu-iotests/247
24
--- a/tests/qemu-iotests/244
17
+++ b/tests/qemu-iotests/247
25
+++ b/tests/qemu-iotests/244
18
@@ -XXX,XX +XXX,XX @@ TEST_IMG="$TEST_IMG.4" _make_test_img $size
26
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'read -P 0 0 1M' \
19
{"execute":"block-commit",
27
echo
20
"arguments":{"device":"format-4", "top-node": "format-2", "base-node":"format-0", "job-id":"job0"}}
28
$QEMU_IO -c 'read -P 0 0 1M' \
21
EOF
29
-c 'read -P 0x11 1M 1M' \
22
-sleep 1
30
- -c 'read -P 0 2M 2M' \
23
+if [ "${VALGRIND_QEMU}" == "y" ]; then
31
-c 'read -P 0x11 4M 1M' \
24
+ sleep 10
32
-c 'read -P 0 5M 1M' \
25
+else
33
-f raw "$TEST_IMG.data" |
26
+ sleep 1
34
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'read -P 0 0 1M' \
27
+fi
35
-f $IMGFMT "$TEST_IMG" |
28
echo '{"execute":"quit"}'
36
_filter_qemu_io
29
) | $QEMU -qmp stdio -nographic -nodefaults \
37
30
-blockdev file,node-name=file-0,filename=$TEST_IMG.0,auto-read-only=on \
38
+# Discarded clusters are only marked as such in the qcow2 metadata, but
39
+# they can contain stale data in the external data file. Instead, zero
40
+# clusters must be zeroed in the external data file too.
41
echo
42
-$QEMU_IMG compare "$TEST_IMG" "$TEST_IMG.data"
43
+$QEMU_IO -c 'read -P 0 0 1M' \
44
+ -c 'read -P 0x11 1M 1M' \
45
+ -c 'read -P 0 3M 3M' \
46
+ -f raw "$TEST_IMG".data |
47
+ _filter_qemu_io
48
49
echo -n "qcow2 file size after I/O: "
50
du -b $TEST_IMG | cut -f1
51
diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
52
index XXXXXXX..XXXXXXX 100644
53
--- a/tests/qemu-iotests/244.out
54
+++ b/tests/qemu-iotests/244.out
55
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 0
56
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
57
read 1048576/1048576 bytes at offset 1048576
58
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
59
-read 2097152/2097152 bytes at offset 2097152
60
-2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
61
read 1048576/1048576 bytes at offset 4194304
62
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
63
read 1048576/1048576 bytes at offset 5242880
64
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 1048576
65
read 4194304/4194304 bytes at offset 2097152
66
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
67
68
-Images are identical.
69
+read 1048576/1048576 bytes at offset 0
70
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
71
+read 1048576/1048576 bytes at offset 1048576
72
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
73
+read 3145728/3145728 bytes at offset 3145728
74
+3 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
75
qcow2 file size after I/O: 327680
76
77
=== bdrv_co_block_status test for file and offset=0 ===
31
--
78
--
32
2.20.1
79
2.25.3
33
80
34
81
diff view generated by jsdifflib
1
From: Peter Lieven <pl@kamp.de>
1
This adds a new BdrvRequestFlags parameter to the .bdrv_co_truncate()
2
2
driver callbacks, and a supported_truncate_flags field in
3
libnfs recently added support for unmounting. Add support
3
BlockDriverState that allows drivers to advertise support for request
4
in Qemu too.
4
flags in the context of truncate.
5
5
6
Signed-off-by: Peter Lieven <pl@kamp.de>
6
For now, we always pass 0 and no drivers declare support for any flag.
7
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>
11
Reviewed-by: Max Reitz <mreitz@redhat.com>
12
Message-Id: <20200424125448.63318-2-kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
14
---
9
block/nfs.c | 5 ++++-
15
include/block/block_int.h | 10 +++++++++-
10
1 file changed, 4 insertions(+), 1 deletion(-)
16
block/crypto.c | 3 ++-
11
17
block/file-posix.c | 2 +-
18
block/file-win32.c | 2 +-
19
block/gluster.c | 1 +
20
block/io.c | 8 +++++++-
21
block/iscsi.c | 2 +-
22
block/nfs.c | 3 ++-
23
block/qcow2.c | 2 +-
24
block/qed.c | 1 +
25
block/raw-format.c | 2 +-
26
block/rbd.c | 1 +
27
block/sheepdog.c | 4 ++--
28
block/ssh.c | 2 +-
29
tests/test-block-iothread.c | 3 ++-
30
15 files changed, 33 insertions(+), 13 deletions(-)
31
32
diff --git a/include/block/block_int.h b/include/block/block_int.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/include/block/block_int.h
35
+++ b/include/block/block_int.h
36
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
37
*/
38
int coroutine_fn (*bdrv_co_truncate)(BlockDriverState *bs, int64_t offset,
39
bool exact, PreallocMode prealloc,
40
- Error **errp);
41
+ BdrvRequestFlags flags, Error **errp);
42
43
int64_t (*bdrv_getlength)(BlockDriverState *bs);
44
bool has_variable_length;
45
@@ -XXX,XX +XXX,XX @@ struct BlockDriverState {
46
/* Flags honored during pwrite_zeroes (so far: BDRV_REQ_FUA,
47
* BDRV_REQ_MAY_UNMAP, BDRV_REQ_WRITE_UNCHANGED) */
48
unsigned int supported_zero_flags;
49
+ /*
50
+ * Flags honoured during truncate (so far: BDRV_REQ_ZERO_WRITE).
51
+ *
52
+ * If BDRV_REQ_ZERO_WRITE is given, the truncate operation must make sure
53
+ * that any added space reads as all zeros. If this can't be guaranteed,
54
+ * the operation must fail.
55
+ */
56
+ unsigned int supported_truncate_flags;
57
58
/* the following member gives a name to every node on the bs graph. */
59
char node_name[32];
60
diff --git a/block/crypto.c b/block/crypto.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/block/crypto.c
63
+++ b/block/crypto.c
64
@@ -XXX,XX +XXX,XX @@ static int block_crypto_co_create_generic(BlockDriverState *bs,
65
66
static int coroutine_fn
67
block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
68
- PreallocMode prealloc, Error **errp)
69
+ PreallocMode prealloc, BdrvRequestFlags flags,
70
+ Error **errp)
71
{
72
BlockCrypto *crypto = bs->opaque;
73
uint64_t payload_offset =
74
diff --git a/block/file-posix.c b/block/file-posix.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/block/file-posix.c
77
+++ b/block/file-posix.c
78
@@ -XXX,XX +XXX,XX @@ raw_regular_truncate(BlockDriverState *bs, int fd, int64_t offset,
79
80
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
81
bool exact, PreallocMode prealloc,
82
- Error **errp)
83
+ BdrvRequestFlags flags, Error **errp)
84
{
85
BDRVRawState *s = bs->opaque;
86
struct stat st;
87
diff --git a/block/file-win32.c b/block/file-win32.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/block/file-win32.c
90
+++ b/block/file-win32.c
91
@@ -XXX,XX +XXX,XX @@ static void raw_close(BlockDriverState *bs)
92
93
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
94
bool exact, PreallocMode prealloc,
95
- Error **errp)
96
+ BdrvRequestFlags flags, Error **errp)
97
{
98
BDRVRawState *s = bs->opaque;
99
LONG low, high;
100
diff --git a/block/gluster.c b/block/gluster.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/block/gluster.c
103
+++ b/block/gluster.c
104
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qemu_gluster_co_truncate(BlockDriverState *bs,
105
int64_t offset,
106
bool exact,
107
PreallocMode prealloc,
108
+ BdrvRequestFlags flags,
109
Error **errp)
110
{
111
BDRVGlusterState *s = bs->opaque;
112
diff --git a/block/io.c b/block/io.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/block/io.c
115
+++ b/block/io.c
116
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
117
BlockDriverState *bs = child->bs;
118
BlockDriver *drv = bs->drv;
119
BdrvTrackedRequest req;
120
+ BdrvRequestFlags flags = 0;
121
int64_t old_size, new_bytes;
122
int ret;
123
124
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
125
}
126
127
if (drv->bdrv_co_truncate) {
128
- ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, errp);
129
+ if (flags & ~bs->supported_truncate_flags) {
130
+ error_setg(errp, "Block driver does not support requested flags");
131
+ ret = -ENOTSUP;
132
+ goto out;
133
+ }
134
+ ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, flags, errp);
135
} else if (bs->file && drv->is_filter) {
136
ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
137
} else {
138
diff --git a/block/iscsi.c b/block/iscsi.c
139
index XXXXXXX..XXXXXXX 100644
140
--- a/block/iscsi.c
141
+++ b/block/iscsi.c
142
@@ -XXX,XX +XXX,XX @@ static void iscsi_reopen_commit(BDRVReopenState *reopen_state)
143
144
static int coroutine_fn iscsi_co_truncate(BlockDriverState *bs, int64_t offset,
145
bool exact, PreallocMode prealloc,
146
- Error **errp)
147
+ BdrvRequestFlags flags, Error **errp)
148
{
149
IscsiLun *iscsilun = bs->opaque;
150
int64_t cur_length;
12
diff --git a/block/nfs.c b/block/nfs.c
151
diff --git a/block/nfs.c b/block/nfs.c
13
index XXXXXXX..XXXXXXX 100644
152
index XXXXXXX..XXXXXXX 100644
14
--- a/block/nfs.c
153
--- a/block/nfs.c
15
+++ b/block/nfs.c
154
+++ b/block/nfs.c
16
@@ -XXX,XX +XXX,XX @@
155
@@ -XXX,XX +XXX,XX @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
17
/*
156
18
* QEMU Block driver for native access to files on NFS shares
157
static int coroutine_fn
19
*
158
nfs_file_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
20
- * Copyright (c) 2014-2017 Peter Lieven <pl@kamp.de>
159
- PreallocMode prealloc, Error **errp)
21
+ * Copyright (c) 2014-2019 Peter Lieven <pl@kamp.de>
160
+ PreallocMode prealloc, BdrvRequestFlags flags,
22
*
161
+ Error **errp)
23
* Permission is hereby granted, free of charge, to any person obtaining a copy
162
{
24
* of this software and associated documentation files (the "Software"), to deal
163
NFSClient *client = bs->opaque;
25
@@ -XXX,XX +XXX,XX @@ static void nfs_client_close(NFSClient *client)
164
int ret;
26
nfs_close(client->context, client->fh);
165
diff --git a/block/qcow2.c b/block/qcow2.c
27
client->fh = NULL;
166
index XXXXXXX..XXXXXXX 100644
167
--- a/block/qcow2.c
168
+++ b/block/qcow2.c
169
@@ -XXX,XX +XXX,XX @@ fail:
170
171
static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
172
bool exact, PreallocMode prealloc,
173
- Error **errp)
174
+ BdrvRequestFlags flags, Error **errp)
175
{
176
BDRVQcow2State *s = bs->opaque;
177
uint64_t old_length;
178
diff --git a/block/qed.c b/block/qed.c
179
index XXXXXXX..XXXXXXX 100644
180
--- a/block/qed.c
181
+++ b/block/qed.c
182
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_truncate(BlockDriverState *bs,
183
int64_t offset,
184
bool exact,
185
PreallocMode prealloc,
186
+ BdrvRequestFlags flags,
187
Error **errp)
188
{
189
BDRVQEDState *s = bs->opaque;
190
diff --git a/block/raw-format.c b/block/raw-format.c
191
index XXXXXXX..XXXXXXX 100644
192
--- a/block/raw-format.c
193
+++ b/block/raw-format.c
194
@@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
195
196
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
197
bool exact, PreallocMode prealloc,
198
- Error **errp)
199
+ BdrvRequestFlags flags, Error **errp)
200
{
201
BDRVRawState *s = bs->opaque;
202
203
diff --git a/block/rbd.c b/block/rbd.c
204
index XXXXXXX..XXXXXXX 100644
205
--- a/block/rbd.c
206
+++ b/block/rbd.c
207
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qemu_rbd_co_truncate(BlockDriverState *bs,
208
int64_t offset,
209
bool exact,
210
PreallocMode prealloc,
211
+ BdrvRequestFlags flags,
212
Error **errp)
213
{
214
int r;
215
diff --git a/block/sheepdog.c b/block/sheepdog.c
216
index XXXXXXX..XXXXXXX 100644
217
--- a/block/sheepdog.c
218
+++ b/block/sheepdog.c
219
@@ -XXX,XX +XXX,XX @@ static int64_t sd_getlength(BlockDriverState *bs)
220
221
static int coroutine_fn sd_co_truncate(BlockDriverState *bs, int64_t offset,
222
bool exact, PreallocMode prealloc,
223
- Error **errp)
224
+ BdrvRequestFlags flags, Error **errp)
225
{
226
BDRVSheepdogState *s = bs->opaque;
227
int ret, fd;
228
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
229
230
assert(!flags);
231
if (offset > s->inode.vdi_size) {
232
- ret = sd_co_truncate(bs, offset, false, PREALLOC_MODE_OFF, NULL);
233
+ ret = sd_co_truncate(bs, offset, false, PREALLOC_MODE_OFF, 0, NULL);
234
if (ret < 0) {
235
return ret;
28
}
236
}
29
+#ifdef LIBNFS_FEATURE_UMOUNT
237
diff --git a/block/ssh.c b/block/ssh.c
30
+ nfs_umount(client->context);
238
index XXXXXXX..XXXXXXX 100644
31
+#endif
239
--- a/block/ssh.c
32
aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
240
+++ b/block/ssh.c
33
false, NULL, NULL, NULL, NULL);
241
@@ -XXX,XX +XXX,XX @@ static int64_t ssh_getlength(BlockDriverState *bs)
34
nfs_destroy_context(client->context);
242
243
static int coroutine_fn ssh_co_truncate(BlockDriverState *bs, int64_t offset,
244
bool exact, PreallocMode prealloc,
245
- Error **errp)
246
+ BdrvRequestFlags flags, Error **errp)
247
{
248
BDRVSSHState *s = bs->opaque;
249
250
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
251
index XXXXXXX..XXXXXXX 100644
252
--- a/tests/test-block-iothread.c
253
+++ b/tests/test-block-iothread.c
254
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_test_co_pdiscard(BlockDriverState *bs,
255
256
static int coroutine_fn
257
bdrv_test_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
258
- PreallocMode prealloc, Error **errp)
259
+ PreallocMode prealloc, BdrvRequestFlags flags,
260
+ Error **errp)
261
{
262
return 0;
263
}
35
--
264
--
36
2.20.1
265
2.25.3
37
266
38
267
diff view generated by jsdifflib
1
From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
1
Now that block drivers can support flags for .bdrv_co_truncate, expose
2
the parameter in the node level interfaces bdrv_co_truncate() and
3
bdrv_truncate().
2
4
3
As the iotests run longer under the Valgrind, the QEMU_COMM_TIMEOUT is
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
to be increased in the test cases 028, 183 and 192 when running under
5
the Valgrind.
6
7
Suggested-by: Roman Kagan <rkagan@virtuozzo.com>
8
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Reviewed-by: John Snow <jsnow@redhat.com>
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Message-Id: <20200424125448.63318-3-kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
11
---
13
tests/qemu-iotests/028 | 6 +++++-
12
include/block/block.h | 5 +++--
14
tests/qemu-iotests/183 | 9 ++++++++-
13
block/block-backend.c | 2 +-
15
tests/qemu-iotests/192 | 6 +++++-
14
block/crypto.c | 2 +-
16
3 files changed, 18 insertions(+), 3 deletions(-)
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(-)
17
26
18
diff --git a/tests/qemu-iotests/028 b/tests/qemu-iotests/028
27
diff --git a/include/block/block.h b/include/block/block.h
19
index XXXXXXX..XXXXXXX 100755
28
index XXXXXXX..XXXXXXX 100644
20
--- a/tests/qemu-iotests/028
29
--- a/include/block/block.h
21
+++ b/tests/qemu-iotests/028
30
+++ b/include/block/block.h
22
@@ -XXX,XX +XXX,XX @@ echo
31
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
23
qemu_comm_method="monitor"
32
void bdrv_refresh_filename(BlockDriverState *bs);
24
_launch_qemu -drive file="${TEST_IMG}",cache=${CACHEMODE},id=disk
33
25
h=$QEMU_HANDLE
34
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
26
-QEMU_COMM_TIMEOUT=1
35
- PreallocMode prealloc, Error **errp);
27
+if [ "${VALGRIND_QEMU}" == "y" ]; then
36
+ PreallocMode prealloc, BdrvRequestFlags flags,
28
+ QEMU_COMM_TIMEOUT=7
37
+ Error **errp);
29
+else
38
int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
30
+ QEMU_COMM_TIMEOUT=1
39
- PreallocMode prealloc, Error **errp);
31
+fi
40
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
32
41
33
# Silence output since it contains the disk image path and QEMU's readline
42
int64_t bdrv_nb_sectors(BlockDriverState *bs);
34
# character echoing makes it very hard to filter the output. Plus, there
43
int64_t bdrv_getlength(BlockDriverState *bs);
35
diff --git a/tests/qemu-iotests/183 b/tests/qemu-iotests/183
44
diff --git a/block/block-backend.c b/block/block-backend.c
36
index XXXXXXX..XXXXXXX 100755
45
index XXXXXXX..XXXXXXX 100644
37
--- a/tests/qemu-iotests/183
46
--- a/block/block-backend.c
38
+++ b/tests/qemu-iotests/183
47
+++ b/block/block-backend.c
39
@@ -XXX,XX +XXX,XX @@ if echo "$reply" | grep "compiled without old-style" > /dev/null; then
48
@@ -XXX,XX +XXX,XX @@ int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
40
_notrun "migrate -b support not compiled in"
49
return -ENOMEDIUM;
41
fi
50
}
42
51
43
-QEMU_COMM_TIMEOUT=0.1 qemu_cmd_repeat=50 silent=yes \
52
- return bdrv_truncate(blk->root, offset, exact, prealloc, errp);
44
+timeout_comm=$QEMU_COMM_TIMEOUT
53
+ return bdrv_truncate(blk->root, offset, exact, prealloc, 0, errp);
45
+if [ "${VALGRIND_QEMU}" == "y" ]; then
54
}
46
+ QEMU_COMM_TIMEOUT=4
55
47
+else
56
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
48
+ QEMU_COMM_TIMEOUT=0.1
57
diff --git a/block/crypto.c b/block/crypto.c
49
+fi
58
index XXXXXXX..XXXXXXX 100644
50
+qemu_cmd_repeat=50 silent=yes \
59
--- a/block/crypto.c
51
_send_qemu_cmd $src "{ 'execute': 'query-migrate' }" '"status": "completed"'
60
+++ b/block/crypto.c
52
+QEMU_COMM_TIMEOUT=$timeout_comm
61
@@ -XXX,XX +XXX,XX @@ block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
53
_send_qemu_cmd $src "{ 'execute': 'query-status' }" "return"
62
54
63
offset += payload_offset;
55
echo
64
56
diff --git a/tests/qemu-iotests/192 b/tests/qemu-iotests/192
65
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
57
index XXXXXXX..XXXXXXX 100755
66
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
58
--- a/tests/qemu-iotests/192
67
}
59
+++ b/tests/qemu-iotests/192
68
60
@@ -XXX,XX +XXX,XX @@ fi
69
static void block_crypto_close(BlockDriverState *bs)
61
qemu_comm_method="monitor"
70
diff --git a/block/io.c b/block/io.c
62
_launch_qemu -drive $DRIVE_ARG -incoming defer
71
index XXXXXXX..XXXXXXX 100644
63
h=$QEMU_HANDLE
72
--- a/block/io.c
64
-QEMU_COMM_TIMEOUT=1
73
+++ b/block/io.c
65
+if [ "${VALGRIND_QEMU}" == "y" ]; then
74
@@ -XXX,XX +XXX,XX @@ static void bdrv_parent_cb_resize(BlockDriverState *bs)
66
+ QEMU_COMM_TIMEOUT=7
75
* 'offset' bytes in length.
67
+else
76
*/
68
+ QEMU_COMM_TIMEOUT=1
77
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
69
+fi
78
- PreallocMode prealloc, Error **errp)
70
79
+ PreallocMode prealloc, BdrvRequestFlags flags,
71
_send_qemu_cmd $h "nbd_server_start unix:$TEST_DIR/nbd" "(qemu)"
80
+ Error **errp)
72
_send_qemu_cmd $h "nbd_server_add -w drive0" "(qemu)"
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
}
282
diff --git a/block/vhdx.c b/block/vhdx.c
283
index XXXXXXX..XXXXXXX 100644
284
--- a/block/vhdx.c
285
+++ b/block/vhdx.c
286
@@ -XXX,XX +XXX,XX @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
287
}
288
289
return bdrv_truncate(bs->file, *new_offset + s->block_size, false,
290
- PREALLOC_MODE_OFF, NULL);
291
+ PREALLOC_MODE_OFF, 0, NULL);
292
}
293
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;
73
--
334
--
74
2.20.1
335
2.25.3
75
336
76
337
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
Now that node level interface bdrv_truncate() supports passing request
2
2
flags to the block driver, expose this on the BlockBackend level, too.
3
In job_finish_sync job_enter should be enough for a job to make some
3
4
progress and draining is a wrong tool for it. So use job_enter directly
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
here and drop job_drain with all related staff not used more.
5
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
7
Suggested-by: Kevin Wolf <kwolf@redhat.com>
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Message-Id: <20200424125448.63318-4-kwolf@redhat.com>
9
Tested-by: John Snow <jsnow@redhat.com>
10
Reviewed-by: John Snow <jsnow@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
10
---
13
include/block/blockjob_int.h | 19 -------------------
11
include/sysemu/block-backend.h | 2 +-
14
include/qemu/job.h | 13 -------------
12
block.c | 3 ++-
15
block/backup.c | 19 +------------------
13
block/block-backend.c | 4 ++--
16
block/commit.c | 1 -
14
block/commit.c | 4 ++--
17
block/mirror.c | 28 +++-------------------------
15
block/crypto.c | 2 +-
18
block/stream.c | 1 -
16
block/mirror.c | 2 +-
19
blockjob.c | 13 -------------
17
block/qcow2.c | 4 ++--
20
job.c | 12 +-----------
18
block/qed.c | 2 +-
21
tests/test-bdrv-drain.c | 3 ---
19
block/vdi.c | 2 +-
22
tests/test-block-iothread.c | 1 -
20
block/vhdx.c | 4 ++--
23
tests/test-blockjob-txn.c | 1 -
21
block/vmdk.c | 6 +++---
24
tests/test-blockjob.c | 2 --
22
block/vpc.c | 2 +-
25
12 files changed, 5 insertions(+), 108 deletions(-)
23
blockdev.c | 2 +-
26
24
qemu-img.c | 2 +-
27
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
25
qemu-io-cmds.c | 2 +-
28
index XXXXXXX..XXXXXXX 100644
26
15 files changed, 22 insertions(+), 21 deletions(-)
29
--- a/include/block/blockjob_int.h
27
30
+++ b/include/block/blockjob_int.h
28
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
31
@@ -XXX,XX +XXX,XX @@ struct BlockJobDriver {
29
index XXXXXXX..XXXXXXX 100644
32
* besides job->blk to the new AioContext.
30
--- a/include/sysemu/block-backend.h
33
*/
31
+++ b/include/sysemu/block-backend.h
34
void (*attached_aio_context)(BlockJob *job, AioContext *new_context);
32
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
35
-
33
int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
36
- /*
34
int bytes);
37
- * If the callback is not NULL, it will be invoked when the job has to be
35
int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
38
- * synchronously cancelled or completed; it should drain BlockDriverStates
36
- PreallocMode prealloc, Error **errp);
39
- * as required to ensure progress.
37
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
40
- *
38
int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes);
41
- * Block jobs must use the default implementation for job_driver.drain,
39
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
42
- * which will in turn call this callback after doing generic block job
40
int64_t pos, int size);
43
- * stuff.
41
diff --git a/block.c b/block.c
44
- */
42
index XXXXXXX..XXXXXXX 100644
45
- void (*drain)(BlockJob *job);
43
--- a/block.c
46
};
44
+++ b/block.c
47
45
@@ -XXX,XX +XXX,XX @@ static int64_t create_file_fallback_truncate(BlockBackend *blk,
48
/**
46
int64_t size;
49
@@ -XXX,XX +XXX,XX @@ void block_job_free(Job *job);
47
int ret;
50
*/
48
51
void block_job_user_resume(Job *job);
49
- ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, &local_err);
52
50
+ ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, 0,
53
-/**
51
+ &local_err);
54
- * block_job_drain:
52
if (ret < 0 && ret != -ENOTSUP) {
55
- * Callback to be used for JobDriver.drain in all block jobs. Drains the main
53
error_propagate(errp, local_err);
56
- * block node associated with the block jobs and calls BlockJobDriver.drain for
54
return ret;
57
- * job-specific actions.
55
diff --git a/block/block-backend.c b/block/block-backend.c
58
- */
56
index XXXXXXX..XXXXXXX 100644
59
-void block_job_drain(Job *job);
57
--- a/block/block-backend.c
60
-
58
+++ b/block/block-backend.c
61
/**
59
@@ -XXX,XX +XXX,XX @@ int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
62
* block_job_ratelimit_get_delay:
63
*
64
diff --git a/include/qemu/job.h b/include/qemu/job.h
65
index XXXXXXX..XXXXXXX 100644
66
--- a/include/qemu/job.h
67
+++ b/include/qemu/job.h
68
@@ -XXX,XX +XXX,XX @@ struct JobDriver {
69
*/
70
void (*complete)(Job *job, Error **errp);
71
72
- /*
73
- * If the callback is not NULL, it will be invoked when the job has to be
74
- * synchronously cancelled or completed; it should drain any activities
75
- * as required to ensure progress.
76
- */
77
- void (*drain)(Job *job);
78
-
79
/**
80
* If the callback is not NULL, prepare will be invoked when all the jobs
81
* belonging to the same transaction complete; or upon this job's completion
82
@@ -XXX,XX +XXX,XX @@ bool job_user_paused(Job *job);
83
*/
84
void job_user_resume(Job *job, Error **errp);
85
86
-/*
87
- * Drain any activities as required to ensure progress. This can be called in a
88
- * loop to synchronously complete a job.
89
- */
90
-void job_drain(Job *job);
91
-
92
/**
93
* Get the next element from the list of block jobs after @job, or the
94
* first one if @job is %NULL.
95
diff --git a/block/backup.c b/block/backup.c
96
index XXXXXXX..XXXXXXX 100644
97
--- a/block/backup.c
98
+++ b/block/backup.c
99
@@ -XXX,XX +XXX,XX @@ void backup_do_checkpoint(BlockJob *job, Error **errp)
100
bdrv_set_dirty_bitmap(backup_job->copy_bitmap, 0, backup_job->len);
101
}
60
}
102
61
103
-static void backup_drain(BlockJob *job)
62
int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
104
-{
63
- PreallocMode prealloc, Error **errp)
105
- BackupBlockJob *s = container_of(job, BackupBlockJob, common);
64
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
106
-
107
- /* Need to keep a reference in case blk_drain triggers execution
108
- * of backup_complete...
109
- */
110
- if (s->target) {
111
- BlockBackend *target = s->target;
112
- blk_ref(target);
113
- blk_drain(target);
114
- blk_unref(target);
115
- }
116
-}
117
-
118
static BlockErrorAction backup_error_action(BackupBlockJob *job,
119
bool read, int error)
120
{
65
{
121
@@ -XXX,XX +XXX,XX @@ static const BlockJobDriver backup_job_driver = {
66
if (!blk_is_available(blk)) {
122
.job_type = JOB_TYPE_BACKUP,
67
error_setg(errp, "No medium inserted");
123
.free = block_job_free,
68
return -ENOMEDIUM;
124
.user_resume = block_job_user_resume,
69
}
125
- .drain = block_job_drain,
70
126
.run = backup_run,
71
- return bdrv_truncate(blk->root, offset, exact, prealloc, 0, errp);
127
.commit = backup_commit,
72
+ return bdrv_truncate(blk->root, offset, exact, prealloc, flags, errp);
128
.abort = backup_abort,
73
}
129
.clean = backup_clean,
74
130
- },
75
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
131
- .drain = backup_drain,
132
+ }
133
};
134
135
static int64_t backup_calculate_cluster_size(BlockDriverState *target,
136
diff --git a/block/commit.c b/block/commit.c
76
diff --git a/block/commit.c b/block/commit.c
137
index XXXXXXX..XXXXXXX 100644
77
index XXXXXXX..XXXXXXX 100644
138
--- a/block/commit.c
78
--- a/block/commit.c
139
+++ b/block/commit.c
79
+++ b/block/commit.c
140
@@ -XXX,XX +XXX,XX @@ static const BlockJobDriver commit_job_driver = {
80
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn commit_run(Job *job, Error **errp)
141
.job_type = JOB_TYPE_COMMIT,
81
}
142
.free = block_job_free,
82
143
.user_resume = block_job_user_resume,
83
if (base_len < len) {
144
- .drain = block_job_drain,
84
- ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, NULL);
145
.run = commit_run,
85
+ ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, 0, NULL);
146
.prepare = commit_prepare,
86
if (ret) {
147
.abort = commit_abort,
87
goto out;
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
148
diff --git a/block/mirror.c b/block/mirror.c
111
diff --git a/block/mirror.c b/block/mirror.c
149
index XXXXXXX..XXXXXXX 100644
112
index XXXXXXX..XXXXXXX 100644
150
--- a/block/mirror.c
113
--- a/block/mirror.c
151
+++ b/block/mirror.c
114
+++ b/block/mirror.c
152
@@ -XXX,XX +XXX,XX @@ static int mirror_exit_common(Job *job)
115
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
153
bdrv_ref(mirror_top_bs);
116
154
bdrv_ref(target_bs);
117
if (s->bdev_length > base_length) {
155
118
ret = blk_truncate(s->target, s->bdev_length, false,
156
- /* Remove target parent that still uses BLK_PERM_WRITE/RESIZE before
119
- PREALLOC_MODE_OFF, NULL);
157
+ /*
120
+ PREALLOC_MODE_OFF, 0, NULL);
158
+ * Remove target parent that still uses BLK_PERM_WRITE/RESIZE before
121
if (ret < 0) {
159
* inserting target_bs at s->to_replace, where we might not be able to get
122
goto immediate_exit;
160
* these permissions.
123
}
161
- *
124
diff --git a/block/qcow2.c b/block/qcow2.c
162
- * Note that blk_unref() alone doesn't necessarily drop permissions because
125
index XXXXXXX..XXXXXXX 100644
163
- * we might be running nested inside mirror_drain(), which takes an extra
126
--- a/block/qcow2.c
164
- * reference, so use an explicit blk_set_perm() first. */
127
+++ b/block/qcow2.c
165
- blk_set_perm(s->target, 0, BLK_PERM_ALL, &error_abort);
128
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
166
+ */
129
167
blk_unref(s->target);
130
/* Okay, now that we have a valid image, let's give it the right size */
168
s->target = NULL;
131
ret = blk_truncate(blk, qcow2_opts->size, false, qcow2_opts->preallocation,
169
132
- errp);
170
@@ -XXX,XX +XXX,XX @@ static bool mirror_drained_poll(BlockJob *job)
133
+ 0, errp);
171
return !!s->in_flight;
134
if (ret < 0) {
172
}
135
error_prepend(errp, "Could not resize image: ");
173
136
goto out;
174
-static void mirror_drain(BlockJob *job)
137
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
175
-{
138
* Amending image options should ensure that the image has
176
- MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
139
* exactly the given new values, so pass exact=true here.
177
-
140
*/
178
- /* Need to keep a reference in case blk_drain triggers execution
141
- ret = blk_truncate(blk, new_size, true, PREALLOC_MODE_OFF, errp);
179
- * of mirror_complete...
142
+ ret = blk_truncate(blk, new_size, true, PREALLOC_MODE_OFF, 0, errp);
180
- */
143
blk_unref(blk);
181
- if (s->target) {
144
if (ret < 0) {
182
- BlockBackend *target = s->target;
145
return ret;
183
- blk_ref(target);
146
diff --git a/block/qed.c b/block/qed.c
184
- blk_drain(target);
147
index XXXXXXX..XXXXXXX 100644
185
- blk_unref(target);
148
--- a/block/qed.c
186
- }
149
+++ b/block/qed.c
187
-}
150
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
188
-
151
* The QED format associates file length with allocation status,
189
static const BlockJobDriver mirror_job_driver = {
152
* so a new file (which is empty) must have a length of 0.
190
.job_driver = {
153
*/
191
.instance_size = sizeof(MirrorBlockJob),
154
- ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, errp);
192
.job_type = JOB_TYPE_MIRROR,
155
+ ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, 0, errp);
193
.free = block_job_free,
156
if (ret < 0) {
194
.user_resume = block_job_user_resume,
157
goto out;
195
- .drain = block_job_drain,
158
}
196
.run = mirror_run,
159
diff --git a/block/vdi.c b/block/vdi.c
197
.prepare = mirror_prepare,
160
index XXXXXXX..XXXXXXX 100644
198
.abort = mirror_abort,
161
--- a/block/vdi.c
199
@@ -XXX,XX +XXX,XX @@ static const BlockJobDriver mirror_job_driver = {
162
+++ b/block/vdi.c
200
.complete = mirror_complete,
163
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
201
},
164
202
.drained_poll = mirror_drained_poll,
165
if (image_type == VDI_TYPE_STATIC) {
203
- .drain = mirror_drain,
166
ret = blk_truncate(blk, offset + blocks * block_size, false,
204
};
167
- PREALLOC_MODE_OFF, errp);
205
168
+ PREALLOC_MODE_OFF, 0, errp);
206
static const BlockJobDriver commit_active_job_driver = {
169
if (ret < 0) {
207
@@ -XXX,XX +XXX,XX @@ static const BlockJobDriver commit_active_job_driver = {
170
error_prepend(errp, "Failed to statically allocate file");
208
.job_type = JOB_TYPE_COMMIT,
171
goto exit;
209
.free = block_job_free,
172
diff --git a/block/vhdx.c b/block/vhdx.c
210
.user_resume = block_job_user_resume,
173
index XXXXXXX..XXXXXXX 100644
211
- .drain = block_job_drain,
174
--- a/block/vhdx.c
212
.run = mirror_run,
175
+++ b/block/vhdx.c
213
.prepare = mirror_prepare,
176
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
214
.abort = mirror_abort,
177
/* All zeroes, so we can just extend the file - the end of the BAT
215
@@ -XXX,XX +XXX,XX @@ static const BlockJobDriver commit_active_job_driver = {
178
* is the furthest thing we have written yet */
216
.complete = mirror_complete,
179
ret = blk_truncate(blk, data_file_offset, false, PREALLOC_MODE_OFF,
217
},
180
- errp);
218
.drained_poll = mirror_drained_poll,
181
+ 0, errp);
219
- .drain = mirror_drain,
182
if (ret < 0) {
220
};
183
goto exit;
221
184
}
222
static void coroutine_fn
185
} else if (type == VHDX_TYPE_FIXED) {
223
diff --git a/block/stream.c b/block/stream.c
186
ret = blk_truncate(blk, data_file_offset + image_size, false,
224
index XXXXXXX..XXXXXXX 100644
187
- PREALLOC_MODE_OFF, errp);
225
--- a/block/stream.c
188
+ PREALLOC_MODE_OFF, 0, errp);
226
+++ b/block/stream.c
189
if (ret < 0) {
227
@@ -XXX,XX +XXX,XX @@ static const BlockJobDriver stream_job_driver = {
190
goto exit;
228
.abort = stream_abort,
191
}
229
.clean = stream_clean,
192
diff --git a/block/vmdk.c b/block/vmdk.c
230
.user_resume = block_job_user_resume,
193
index XXXXXXX..XXXXXXX 100644
231
- .drain = block_job_drain,
194
--- a/block/vmdk.c
232
},
195
+++ b/block/vmdk.c
233
};
196
@@ -XXX,XX +XXX,XX @@ static int vmdk_init_extent(BlockBackend *blk,
234
197
int gd_buf_size;
235
diff --git a/blockjob.c b/blockjob.c
198
236
index XXXXXXX..XXXXXXX 100644
199
if (flat) {
237
--- a/blockjob.c
200
- ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, errp);
238
+++ b/blockjob.c
201
+ ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, 0, errp);
239
@@ -XXX,XX +XXX,XX @@ void block_job_free(Job *job)
202
goto exit;
240
error_free(bjob->blocker);
203
}
241
}
204
magic = cpu_to_be32(VMDK4_MAGIC);
242
205
@@ -XXX,XX +XXX,XX @@ static int vmdk_init_extent(BlockBackend *blk,
243
-void block_job_drain(Job *job)
206
}
244
-{
207
245
- BlockJob *bjob = container_of(job, BlockJob, job);
208
ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9, false,
246
- const JobDriver *drv = job->driver;
209
- PREALLOC_MODE_OFF, errp);
247
- BlockJobDriver *bjdrv = container_of(drv, BlockJobDriver, job_driver);
210
+ PREALLOC_MODE_OFF, 0, errp);
248
-
211
if (ret < 0) {
249
- blk_drain(bjob->blk);
212
goto exit;
250
- if (bjdrv->drain) {
213
}
251
- bjdrv->drain(bjob);
214
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
252
- }
215
/* bdrv_pwrite write padding zeros to align to sector, we don't need that
253
-}
216
* for description file */
254
-
217
if (desc_offset == 0) {
255
static char *child_job_get_parent_desc(BdrvChild *c)
218
- ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, errp);
256
{
219
+ ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, 0, errp);
257
BlockJob *job = c->opaque;
220
if (ret < 0) {
258
@@ -XXX,XX +XXX,XX @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
221
goto exit;
259
assert(is_block_job(&job->job));
222
}
260
assert(job->job.driver->free == &block_job_free);
223
diff --git a/block/vpc.c b/block/vpc.c
261
assert(job->job.driver->user_resume == &block_job_user_resume);
224
index XXXXXXX..XXXXXXX 100644
262
- assert(job->job.driver->drain == &block_job_drain);
225
--- a/block/vpc.c
263
226
+++ b/block/vpc.c
264
job->blk = blk;
227
@@ -XXX,XX +XXX,XX @@ static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
265
228
/* Add footer to total size */
266
diff --git a/job.c b/job.c
229
total_size += HEADER_SIZE;
267
index XXXXXXX..XXXXXXX 100644
230
268
--- a/job.c
231
- ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, errp);
269
+++ b/job.c
232
+ ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, 0, errp);
270
@@ -XXX,XX +XXX,XX @@ void coroutine_fn job_sleep_ns(Job *job, int64_t ns)
233
if (ret < 0) {
271
job_pause_point(job);
234
return ret;
272
}
235
}
273
236
diff --git a/blockdev.c b/blockdev.c
274
-void job_drain(Job *job)
237
index XXXXXXX..XXXXXXX 100644
275
-{
238
--- a/blockdev.c
276
- /* If job is !busy this kicks it into the next pause point. */
239
+++ b/blockdev.c
277
- job_enter(job);
240
@@ -XXX,XX +XXX,XX @@ void qmp_block_resize(bool has_device, const char *device,
278
-
241
}
279
- if (job->driver->drain) {
242
280
- job->driver->drain(job);
243
bdrv_drained_begin(bs);
281
- }
244
- ret = blk_truncate(blk, size, false, PREALLOC_MODE_OFF, errp);
282
-}
245
+ ret = blk_truncate(blk, size, false, PREALLOC_MODE_OFF, 0, errp);
283
-
246
bdrv_drained_end(bs);
284
/* Assumes the block_job_mutex is held */
247
285
static bool job_timer_not_pending(Job *job)
248
out:
286
{
249
diff --git a/qemu-img.c b/qemu-img.c
287
@@ -XXX,XX +XXX,XX @@ int job_finish_sync(Job *job, void (*finish)(Job *, Error **errp), Error **errp)
250
index XXXXXXX..XXXXXXX 100644
288
}
251
--- a/qemu-img.c
289
252
+++ b/qemu-img.c
290
AIO_WAIT_WHILE(job->aio_context,
253
@@ -XXX,XX +XXX,XX @@ static int img_resize(int argc, char **argv)
291
- (job_drain(job), !job_is_completed(job)));
254
* resizing, so pass @exact=true. It is of no use to report
292
+ (job_enter(job), !job_is_completed(job)));
255
* success when the image has not actually been resized.
293
256
*/
294
ret = (job_is_cancelled(job) && job->ret == 0) ? -ECANCELED : job->ret;
257
- ret = blk_truncate(blk, total_size, true, prealloc, &err);
295
job_unref(job);
258
+ ret = blk_truncate(blk, total_size, true, prealloc, 0, &err);
296
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
259
if (!ret) {
297
index XXXXXXX..XXXXXXX 100644
260
qprintf(quiet, "Image resized.\n");
298
--- a/tests/test-bdrv-drain.c
261
} else {
299
+++ b/tests/test-bdrv-drain.c
262
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
300
@@ -XXX,XX +XXX,XX @@ BlockJobDriver test_job_driver = {
263
index XXXXXXX..XXXXXXX 100644
301
.instance_size = sizeof(TestBlockJob),
264
--- a/qemu-io-cmds.c
302
.free = block_job_free,
265
+++ b/qemu-io-cmds.c
303
.user_resume = block_job_user_resume,
266
@@ -XXX,XX +XXX,XX @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
304
- .drain = block_job_drain,
267
* exact=true. It is better to err on the "emit more errors" side
305
.run = test_job_run,
268
* than to be overly permissive.
306
.complete = test_job_complete,
269
*/
307
.prepare = test_job_prepare,
270
- ret = blk_truncate(blk, offset, true, PREALLOC_MODE_OFF, &local_err);
308
@@ -XXX,XX +XXX,XX @@ static const BlockJobDriver test_drop_backing_job_driver = {
271
+ ret = blk_truncate(blk, offset, true, PREALLOC_MODE_OFF, 0, &local_err);
309
.instance_size = sizeof(TestDropBackingBlockJob),
272
if (ret < 0) {
310
.free = block_job_free,
273
error_report_err(local_err);
311
.user_resume = block_job_user_resume,
274
return ret;
312
- .drain = block_job_drain,
313
.run = test_drop_backing_job_run,
314
.commit = test_drop_backing_job_commit,
315
}
316
@@ -XXX,XX +XXX,XX @@ static const BlockJobDriver test_simple_job_driver = {
317
.instance_size = sizeof(TestSimpleBlockJob),
318
.free = block_job_free,
319
.user_resume = block_job_user_resume,
320
- .drain = block_job_drain,
321
.run = test_simple_job_run,
322
.clean = test_simple_job_clean,
323
},
324
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
325
index XXXXXXX..XXXXXXX 100644
326
--- a/tests/test-block-iothread.c
327
+++ b/tests/test-block-iothread.c
328
@@ -XXX,XX +XXX,XX @@ BlockJobDriver test_job_driver = {
329
.instance_size = sizeof(TestBlockJob),
330
.free = block_job_free,
331
.user_resume = block_job_user_resume,
332
- .drain = block_job_drain,
333
.run = test_job_run,
334
.complete = test_job_complete,
335
.prepare = test_job_prepare,
336
diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c
337
index XXXXXXX..XXXXXXX 100644
338
--- a/tests/test-blockjob-txn.c
339
+++ b/tests/test-blockjob-txn.c
340
@@ -XXX,XX +XXX,XX @@ static const BlockJobDriver test_block_job_driver = {
341
.instance_size = sizeof(TestBlockJob),
342
.free = block_job_free,
343
.user_resume = block_job_user_resume,
344
- .drain = block_job_drain,
345
.run = test_block_job_run,
346
.clean = test_block_job_clean,
347
},
348
diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c
349
index XXXXXXX..XXXXXXX 100644
350
--- a/tests/test-blockjob.c
351
+++ b/tests/test-blockjob.c
352
@@ -XXX,XX +XXX,XX @@ static const BlockJobDriver test_block_job_driver = {
353
.instance_size = sizeof(BlockJob),
354
.free = block_job_free,
355
.user_resume = block_job_user_resume,
356
- .drain = block_job_drain,
357
},
358
};
359
360
@@ -XXX,XX +XXX,XX @@ static const BlockJobDriver test_cancel_driver = {
361
.instance_size = sizeof(CancelJob),
362
.free = block_job_free,
363
.user_resume = block_job_user_resume,
364
- .drain = block_job_drain,
365
.run = cancel_job_run,
366
.complete = cancel_job_complete,
367
},
368
--
275
--
369
2.20.1
276
2.25.3
370
277
371
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
handle_alloc() tries to find as many contiguous clusters that need
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
copy-on-write as possible in order to allocate all of them at the same
8
Message-Id: <20200424125448.63318-5-kwolf@redhat.com>
5
time.
9
Reviewed-by: Eric Blake <eblake@redhat.com>
6
10
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
However, compressed clusters are only overwritten one by one, so let's
8
say that we have an image with 1024 consecutive compressed clusters:
9
10
qemu-img create -f qcow2 hd.qcow2 64M
11
for f in `seq 0 64 65472`; do
12
qemu-io -c "write -c ${f}k 64k" hd.qcow2
13
done
14
15
In this case trying to overwrite the whole image with one large write
16
request results in 1024 separate allocations:
17
18
qemu-io -c "write 0 64M" hd.qcow2
19
20
This restriction comes from commit 095a9c58ce12afeeb90c2 from 2008.
21
Nowadays QEMU can overwrite multiple compressed clusters just fine,
22
and in fact it already does: as long as the first cluster that
23
handle_alloc() finds is not compressed, all other compressed clusters
24
in the same batch will be overwritten in one go:
25
26
qemu-img create -f qcow2 hd.qcow2 64M
27
qemu-io -c "write -z 0 64k" hd.qcow2
28
for f in `seq 64 64 65472`; do
29
qemu-io -c "write -c ${f}k 64k" hd.qcow2
30
done
31
32
Compared to the previous one, overwriting this image on my computer
33
goes from 8.35s down to 230ms.
34
35
Signed-off-by: Alberto Garcia <berto@igalia.com>
36
Reviewed-by: John Snow <jsnow@redhat.com
37
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
38
---
12
---
39
block/qcow2-cluster.c | 8 +-------
13
block/qcow2-cluster.c | 2 +-
40
1 file changed, 1 insertion(+), 7 deletions(-)
14
block/qcow2.c | 34 ++++++++++++++++++++++++++++++++++
15
2 files changed, 35 insertions(+), 1 deletion(-)
41
16
42
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
17
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
43
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
44
--- a/block/qcow2-cluster.c
19
--- a/block/qcow2-cluster.c
45
+++ b/block/qcow2-cluster.c
20
+++ b/block/qcow2-cluster.c
46
@@ -XXX,XX +XXX,XX @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
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) {
30
diff --git a/block/qcow2.c b/block/qcow2.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/block/qcow2.c
33
+++ b/block/qcow2.c
34
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
35
36
bs->supported_zero_flags = header.version >= 3 ?
37
BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK : 0;
38
+ bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
39
40
/* Repair image if dirty */
41
if (!(flags & (BDRV_O_CHECK | BDRV_O_INACTIVE)) && !bs->read_only &&
42
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
43
g_assert_not_reached();
47
}
44
}
48
45
49
entry = be64_to_cpu(l2_slice[l2_index]);
46
+ if ((flags & BDRV_REQ_ZERO_WRITE) && offset > old_length) {
50
-
47
+ uint64_t zero_start = QEMU_ALIGN_UP(old_length, s->cluster_size);
51
- /* For the moment, overwrite compressed clusters one by one */
48
+
52
- if (entry & QCOW_OFLAG_COMPRESSED) {
49
+ /*
53
- nb_clusters = 1;
50
+ * Use zero clusters as much as we can. qcow2_cluster_zeroize()
54
- } else {
51
+ * requires a cluster-aligned start. The end may be unaligned if it is
55
- nb_clusters = count_cow_clusters(bs, nb_clusters, l2_slice, l2_index);
52
+ * at the end of the image (which it is here).
56
- }
53
+ */
57
+ nb_clusters = count_cow_clusters(bs, nb_clusters, l2_slice, l2_index);
54
+ ret = qcow2_cluster_zeroize(bs, zero_start, offset - zero_start, 0);
58
55
+ if (ret < 0) {
59
/* This function is only called when there were no non-COW clusters, so if
56
+ error_setg_errno(errp, -ret, "Failed to zero out new clusters");
60
* we can't find any unallocated or COW clusters either, something is
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);
61
--
82
--
62
2.20.1
83
2.25.3
63
84
64
85
diff view generated by jsdifflib
1
qemu_io_alloc_from_file() needs to close the pattern file even if some
1
The raw format driver can simply forward the flag and let its bs->file
2
error occurred.
2
child take care of actually providing the zeros.
3
3
4
Setting f = NULL in the success path and checking it for NULL in the
5
error path isn't strictly necessary at this point, but let's do it
6
anyway in case someone later adds a 'goto error' after closing the file.
7
8
Coverity: CID 1405303
9
Fixes: 4d731510d34f280ed45a6de621d016f67a49ea48
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Reviewed-by: Max Reitz <mreitz@redhat.com>
5
Reviewed-by: Max Reitz <mreitz@redhat.com>
12
Reviewed-by: Stefano Garzarella <sgarzare@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>
13
---
10
---
14
qemu-io-cmds.c | 4 ++++
11
block/raw-format.c | 4 +++-
15
1 file changed, 4 insertions(+)
12
1 file changed, 3 insertions(+), 1 deletion(-)
16
13
17
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
14
diff --git a/block/raw-format.c b/block/raw-format.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/qemu-io-cmds.c
16
--- a/block/raw-format.c
20
+++ b/qemu-io-cmds.c
17
+++ b/block/raw-format.c
21
@@ -XXX,XX +XXX,XX @@ static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
18
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
22
}
19
23
20
s->size = offset;
24
fclose(f);
21
offset += s->offset;
25
+ f = NULL;
22
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
26
23
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
27
if (len > pattern_len) {
28
len -= pattern_len;
29
@@ -XXX,XX +XXX,XX @@ static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
30
31
error:
32
qemu_io_free(buf_origin);
33
+ if (f) {
34
+ fclose(f);
35
+ }
36
return NULL;
37
}
24
}
38
25
26
static void raw_eject(BlockDriverState *bs, bool eject_flag)
27
@@ -XXX,XX +XXX,XX @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
28
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
29
((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
30
bs->file->bs->supported_zero_flags);
31
+ bs->supported_truncate_flags = bs->file->bs->supported_truncate_flags &
32
+ BDRV_REQ_ZERO_WRITE;
33
34
if (bs->probed && !bdrv_is_read_only(bs)) {
35
bdrv_refresh_filename(bs->file->bs);
39
--
36
--
40
2.20.1
37
2.25.3
41
38
42
39
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
For regular files, we always get BDRV_REQ_ZERO_WRITE behaviour from the
2
OS, so we can advertise the flag and just ignore it.
2
3
3
This patch removes xfs_write_zeroes() and xfs_discard(). Both functions
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
have been added just before the same feature was present through
5
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
5
fallocate():
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
6
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
- fallocate() has supported PUNCH_HOLE for XFS since Linux 2.6.38 (March
8
Message-Id: <20200424125448.63318-7-kwolf@redhat.com>
8
2011); xfs_discard() was added in December 2010.
9
10
- fallocate() has supported ZERO_RANGE for XFS since Linux 3.15 (June
11
2014); xfs_write_zeroes() was added in November 2013.
12
13
Nowadays, all systems that qemu runs on should support both fallocate()
14
features (RHEL 7's kernel does).
15
16
xfsctl() is still useful for getting the request alignment for O_DIRECT,
17
so this patch does not remove our dependency on it completely.
18
19
Note that xfs_write_zeroes() had a bug: It calls ftruncate() when the
20
file is shorter than the specified range (because ZERO_RANGE does not
21
increase the file length). ftruncate() may yield and then discard data
22
that parallel write requests have written past the EOF in the meantime.
23
Dropping the function altogether fixes the bug.
24
25
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
26
Fixes: 50ba5b2d994853b38fed10e0841b119da0f8b8e5
27
Reported-by: Lukáš Doktor <ldoktor@redhat.com>
28
Cc: qemu-stable@nongnu.org
29
Signed-off-by: Max Reitz <mreitz@redhat.com>
30
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
31
Reviewed-by: John Snow <jsnow@redhat.com>
32
Tested-by: Stefano Garzarella <sgarzare@redhat.com>
33
Tested-by: John Snow <jsnow@redhat.com>
34
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
35
---
10
---
36
block/file-posix.c | 77 +---------------------------------------------
11
block/file-posix.c | 4 ++++
37
1 file changed, 1 insertion(+), 76 deletions(-)
12
1 file changed, 4 insertions(+)
38
13
39
diff --git a/block/file-posix.c b/block/file-posix.c
14
diff --git a/block/file-posix.c b/block/file-posix.c
40
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
41
--- a/block/file-posix.c
16
--- a/block/file-posix.c
42
+++ b/block/file-posix.c
17
+++ b/block/file-posix.c
43
@@ -XXX,XX +XXX,XX @@ out:
18
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
44
}
45
}
46
47
-#ifdef CONFIG_XFS
48
-static int xfs_write_zeroes(BDRVRawState *s, int64_t offset, uint64_t bytes)
49
-{
50
- int64_t len;
51
- struct xfs_flock64 fl;
52
- int err;
53
-
54
- len = lseek(s->fd, 0, SEEK_END);
55
- if (len < 0) {
56
- return -errno;
57
- }
58
-
59
- if (offset + bytes > len) {
60
- /* XFS_IOC_ZERO_RANGE does not increase the file length */
61
- if (ftruncate(s->fd, offset + bytes) < 0) {
62
- return -errno;
63
- }
64
- }
65
-
66
- memset(&fl, 0, sizeof(fl));
67
- fl.l_whence = SEEK_SET;
68
- fl.l_start = offset;
69
- fl.l_len = bytes;
70
-
71
- if (xfsctl(NULL, s->fd, XFS_IOC_ZERO_RANGE, &fl) < 0) {
72
- err = errno;
73
- trace_file_xfs_write_zeroes(strerror(errno));
74
- return -err;
75
- }
76
-
77
- return 0;
78
-}
79
-
80
-static int xfs_discard(BDRVRawState *s, int64_t offset, uint64_t bytes)
81
-{
82
- struct xfs_flock64 fl;
83
- int err;
84
-
85
- memset(&fl, 0, sizeof(fl));
86
- fl.l_whence = SEEK_SET;
87
- fl.l_start = offset;
88
- fl.l_len = bytes;
89
-
90
- if (xfsctl(NULL, s->fd, XFS_IOC_UNRESVSP64, &fl) < 0) {
91
- err = errno;
92
- trace_file_xfs_discard(strerror(errno));
93
- return -err;
94
- }
95
-
96
- return 0;
97
-}
98
-#endif
99
-
100
static int translate_err(int err)
101
{
102
if (err == -ENODEV || err == -ENOSYS || err == -EOPNOTSUPP ||
103
@@ -XXX,XX +XXX,XX @@ static ssize_t handle_aiocb_write_zeroes_block(RawPosixAIOData *aiocb)
104
static int handle_aiocb_write_zeroes(void *opaque)
105
{
106
RawPosixAIOData *aiocb = opaque;
107
-#if defined(CONFIG_FALLOCATE) || defined(CONFIG_XFS)
108
- BDRVRawState *s = aiocb->bs->opaque;
109
-#endif
110
#ifdef CONFIG_FALLOCATE
111
+ BDRVRawState *s = aiocb->bs->opaque;
112
int64_t len;
113
#endif
19
#endif
114
20
115
@@ -XXX,XX +XXX,XX @@ static int handle_aiocb_write_zeroes(void *opaque)
21
bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK;
116
return handle_aiocb_write_zeroes_block(aiocb);
22
+ if (S_ISREG(st.st_mode)) {
117
}
23
+ /* When extending regular files, we get zeros from the OS */
118
24
+ bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
119
-#ifdef CONFIG_XFS
25
+ }
120
- if (s->is_xfs) {
26
ret = 0;
121
- return xfs_write_zeroes(s, aiocb->aio_offset, aiocb->aio_nbytes);
27
fail:
122
- }
28
if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
123
-#endif
124
-
125
#ifdef CONFIG_FALLOCATE_ZERO_RANGE
126
if (s->has_write_zeroes) {
127
int ret = do_fallocate(s->fd, FALLOC_FL_ZERO_RANGE,
128
@@ -XXX,XX +XXX,XX @@ static int handle_aiocb_write_zeroes_unmap(void *opaque)
129
}
130
#endif
131
132
-#ifdef CONFIG_XFS
133
- if (s->is_xfs) {
134
- /* xfs_discard() guarantees that the discarded area reads as all-zero
135
- * afterwards, so we can use it here. */
136
- return xfs_discard(s, aiocb->aio_offset, aiocb->aio_nbytes);
137
- }
138
-#endif
139
-
140
/* If we couldn't manage to unmap while guaranteed that the area reads as
141
* all-zero afterwards, just write zeroes without unmapping */
142
ret = handle_aiocb_write_zeroes(aiocb);
143
@@ -XXX,XX +XXX,XX @@ static int handle_aiocb_discard(void *opaque)
144
ret = -errno;
145
#endif
146
} else {
147
-#ifdef CONFIG_XFS
148
- if (s->is_xfs) {
149
- return xfs_discard(s, aiocb->aio_offset, aiocb->aio_nbytes);
150
- }
151
-#endif
152
-
153
#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
154
ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
155
aiocb->aio_offset, aiocb->aio_nbytes);
156
--
29
--
157
2.20.1
30
2.25.3
158
31
159
32
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
When extending the size of an image that has a backing file larger than
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.
2
4
3
blockdev_create_run() directly uses .bdrv_co_create()'s return value as
5
Consider the following scenario where the overlay is shorter than its
4
the job's return value. Jobs must return 0 on success, not just any
6
backing file:
5
nonnegative value. Therefore, using blockdev-create for VPC images may
6
currently fail as the vpc driver may return a positive integer.
7
7
8
Because there is no point in returning a positive integer anywhere in
8
base.qcow2: AAAAAAAA
9
the block layer (all non-negative integers are generally treated as
9
overlay.qcow2: BBBB
10
complete success), we probably do not want to add more such cases.
11
Therefore, fix this problem by making the vpc driver always return 0 in
12
case of success.
13
10
14
Suggested-by: Kevin Wolf <kwolf@redhat.com>
11
When resizing (extending) overlay.qcow2, the new blocks should not stay
15
Cc: qemu-stable@nongnu.org
12
unallocated and make the additional As from base.qcow2 visible like
16
Signed-off-by: Max Reitz <mreitz@redhat.com>
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.
29
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>
33
Reviewed-by: Max Reitz <mreitz@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
34
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
35
---
19
block/vpc.c | 3 ++-
36
block/io.c | 25 +++++++++++++++++++++++++
20
1 file changed, 2 insertions(+), 1 deletion(-)
37
1 file changed, 25 insertions(+)
21
38
22
diff --git a/block/vpc.c b/block/vpc.c
39
diff --git a/block/io.c b/block/io.c
23
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
24
--- a/block/vpc.c
41
--- a/block/io.c
25
+++ b/block/vpc.c
42
+++ b/block/io.c
26
@@ -XXX,XX +XXX,XX @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
43
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
27
goto fail;
44
goto out;
28
}
45
}
29
46
30
+ ret = 0;
47
+ /*
31
fail:
48
+ * If the image has a backing file that is large enough that it would
32
return ret;
49
+ * provide data for the new area, we cannot leave it unallocated because
33
}
50
+ * then the backing file content would become visible. Instead, zero-fill
34
@@ -XXX,XX +XXX,XX @@ static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
51
+ * the new area.
35
return ret;
52
+ *
36
}
53
+ * Note that if the image has a backing file, but was opened without the
37
54
+ * backing file, taking care of keeping things consistent with that backing
38
- return ret;
55
+ * file is the user's responsibility.
39
+ return 0;
56
+ */
40
}
57
+ if (new_bytes && bs->backing) {
41
58
+ int64_t backing_len;
42
static int calculate_rounded_image_size(BlockdevCreateOptionsVpc *vpc_opts,
59
+
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
+ }
66
+
67
+ if (backing_len > old_size) {
68
+ flags |= BDRV_REQ_ZERO_WRITE;
69
+ }
70
+ }
71
+
72
if (drv->bdrv_co_truncate) {
73
if (flags & ~bs->supported_truncate_flags) {
74
error_setg(errp, "Block driver does not support requested flags");
43
--
75
--
44
2.20.1
76
2.25.3
45
77
46
78
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
We want to keep TEST_IMG for the full path of the main test image, but
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.
2
5
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Insert a filter_testfiles() call between both.
7
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Max Reitz <mreitz@redhat.com>
10
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Message-Id: <20200424125448.63318-9-kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
---
13
---
6
tests/qemu-iotests/iotests.py | 4 +++-
14
tests/qemu-iotests/iotests.py | 5 +++--
7
1 file changed, 3 insertions(+), 1 deletion(-)
15
1 file changed, 3 insertions(+), 2 deletions(-)
8
16
9
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
10
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
11
--- a/tests/qemu-iotests/iotests.py
19
--- a/tests/qemu-iotests/iotests.py
12
+++ b/tests/qemu-iotests/iotests.py
20
+++ b/tests/qemu-iotests/iotests.py
13
@@ -XXX,XX +XXX,XX @@ def execute_unittest(output, verbosity, debug):
21
@@ -XXX,XX +XXX,XX @@ def filter_img_info(output, filename):
14
22
for line in output.split('\n'):
15
def execute_test(test_function=None,
23
if 'disk size' in line or 'actual-size' in line:
16
supported_fmts=[], supported_oses=['linux'],
24
continue
17
- supported_cache_modes=[], unsupported_fmts=[]):
25
- line = line.replace(filename, 'TEST_IMG') \
18
+ supported_cache_modes=[], unsupported_fmts=[],
26
- .replace(imgfmt, 'IMGFMT')
19
+ supported_protocols=[], unsupported_protocols=[]):
27
+ line = line.replace(filename, 'TEST_IMG')
20
"""Run either unittest or script-style tests."""
28
+ line = filter_testfiles(line)
21
29
+ line = line.replace(imgfmt, 'IMGFMT')
22
# We are using TEST_DIR and QEMU_DEFAULT_MACHINE as proxies to
30
line = re.sub('iters: [0-9]+', 'iters: XXX', line)
23
@@ -XXX,XX +XXX,XX @@ def execute_test(test_function=None,
31
line = re.sub('uuid: [-a-f0-9]+', 'uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', line)
24
debug = '-d' in sys.argv
32
line = re.sub('cid: [0-9]+', 'cid: XXXXXXXXXX', line)
25
verbosity = 1
26
verify_image_format(supported_fmts, unsupported_fmts)
27
+ verify_protocol(supported_protocols, unsupported_protocols)
28
verify_platform(supported_oses)
29
verify_cache_mode(supported_cache_modes)
30
31
--
33
--
32
2.20.1
34
2.25.3
33
35
34
36
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
2
Message-Id: <20200424125448.63318-10-kwolf@redhat.com>
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
Reviewed-by: Max Reitz <mreitz@redhat.com>
4
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
---
6
---
6
tests/qemu-iotests/266 | 153 +++++++++++++++++++++++++++++++++++++
7
tests/qemu-iotests/274 | 155 +++++++++++++++++++++
7
tests/qemu-iotests/266.out | 137 +++++++++++++++++++++++++++++++++
8
tests/qemu-iotests/274.out | 268 +++++++++++++++++++++++++++++++++++++
8
tests/qemu-iotests/group | 1 +
9
tests/qemu-iotests/group | 1 +
9
3 files changed, 291 insertions(+)
10
3 files changed, 424 insertions(+)
10
create mode 100755 tests/qemu-iotests/266
11
create mode 100755 tests/qemu-iotests/274
11
create mode 100644 tests/qemu-iotests/266.out
12
create mode 100644 tests/qemu-iotests/274.out
12
13
13
diff --git a/tests/qemu-iotests/266 b/tests/qemu-iotests/266
14
diff --git a/tests/qemu-iotests/274 b/tests/qemu-iotests/274
14
new file mode 100755
15
new file mode 100755
15
index XXXXXXX..XXXXXXX
16
index XXXXXXX..XXXXXXX
16
--- /dev/null
17
--- /dev/null
17
+++ b/tests/qemu-iotests/266
18
+++ b/tests/qemu-iotests/274
18
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
19
+#!/usr/bin/env python
20
+#!/usr/bin/env python3
20
+#
21
+# Test VPC and file image creation
22
+#
21
+#
23
+# Copyright (C) 2019 Red Hat, Inc.
22
+# Copyright (C) 2019 Red Hat, Inc.
24
+#
23
+#
25
+# This program is free software; you can redistribute it and/or modify
24
+# This program is free software; you can redistribute it and/or modify
26
+# it under the terms of the GNU General Public License as published by
25
+# it under the terms of the GNU General Public License as published by
...
...
33
+# GNU General Public License for more details.
32
+# GNU General Public License for more details.
34
+#
33
+#
35
+# You should have received a copy of the GNU General Public License
34
+# You should have received a copy of the GNU General Public License
36
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
35
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
37
+#
36
+#
37
+# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
38
+#
39
+# Some tests for short backing files and short overlays
38
+
40
+
39
+import iotests
41
+import iotests
40
+from iotests import imgfmt
42
+
41
+
43
+iotests.verify_image_format(supported_fmts=['qcow2'])
42
+
44
+iotests.verify_platform(['linux'])
43
+def blockdev_create(vm, options):
45
+
44
+ result = vm.qmp_log('blockdev-create', job_id='job0', options=options,
46
+size_short = 1 * 1024 * 1024
45
+ filters=[iotests.filter_qmp_testfiles])
47
+size_long = 2 * 1024 * 1024
46
+
48
+size_diff = size_long - size_short
47
+ if 'return' in result:
49
+
48
+ assert result['return'] == {}
50
+def create_chain() -> None:
49
+ vm.run_job('job0')
51
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, base,
50
+
52
+ str(size_long))
51
+
53
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, mid,
52
+# Successful image creation (defaults)
54
+ str(size_short))
53
+def implicit_defaults(vm, file_path):
55
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', mid, top,
54
+ iotests.log("=== Successful image creation (defaults) ===")
56
+ str(size_long))
55
+ iotests.log("")
57
+
56
+
58
+ iotests.qemu_io_log('-c', 'write -P 1 0 %d' % size_long, base)
57
+ # 8 heads, 964 cyls/head, 17 secs/cyl
59
+
58
+ # (Close to 64 MB)
60
+def create_vm() -> iotests.VM:
59
+ size = 8 * 964 * 17 * 512
61
+ vm = iotests.VM()
60
+
62
+ vm.add_blockdev('file,filename=%s,node-name=base-file' % base)
61
+ blockdev_create(vm, { 'driver': imgfmt,
63
+ vm.add_blockdev('%s,file=base-file,node-name=base' % iotests.imgfmt)
62
+ 'file': 'protocol-node',
64
+ vm.add_blockdev('file,filename=%s,node-name=mid-file' % mid)
63
+ 'size': size })
65
+ vm.add_blockdev('%s,file=mid-file,node-name=mid,backing=base'
64
+
66
+ % iotests.imgfmt)
65
+
67
+ vm.add_drive(top, 'backing=mid,node-name=top')
66
+# Successful image creation (explicit defaults)
68
+ return vm
67
+def explicit_defaults(vm, file_path):
69
+
68
+ iotests.log("=== Successful image creation (explicit defaults) ===")
70
+with iotests.FilePath('base') as base, \
69
+ iotests.log("")
71
+ iotests.FilePath('mid') as mid, \
70
+
72
+ iotests.FilePath('top') as top:
71
+ # 16 heads, 964 cyls/head, 17 secs/cyl
73
+
72
+ # (Close to 128 MB)
74
+ iotests.log('== Commit tests ==')
73
+ size = 16 * 964 * 17 * 512
75
+
74
+
76
+ create_chain()
75
+ blockdev_create(vm, { 'driver': imgfmt,
77
+
76
+ 'file': 'protocol-node',
78
+ iotests.log('=== Check visible data ===')
77
+ 'size': size,
79
+
78
+ 'subformat': 'dynamic',
80
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, top)
79
+ 'force-size': False })
81
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), top)
80
+
82
+
81
+
83
+ iotests.log('=== Checking allocation status ===')
82
+# Successful image creation (non-default options)
84
+
83
+def non_defaults(vm, file_path):
85
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
84
+ iotests.log("=== Successful image creation (non-default options) ===")
86
+ '-c', 'alloc %d %d' % (size_short, size_diff),
85
+ iotests.log("")
87
+ base)
86
+
88
+
87
+ # Not representable in CHS (fine with force-size=True)
89
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
88
+ size = 1048576
90
+ '-c', 'alloc %d %d' % (size_short, size_diff),
89
+
91
+ mid)
90
+ blockdev_create(vm, { 'driver': imgfmt,
92
+
91
+ 'file': 'protocol-node',
93
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
92
+ 'size': size,
94
+ '-c', 'alloc %d %d' % (size_short, size_diff),
93
+ 'subformat': 'fixed',
95
+ top)
94
+ 'force-size': True })
96
+
95
+
97
+ iotests.log('=== Checking map ===')
96
+
98
+
97
+# Size not representable in CHS with force-size=False
99
+ iotests.qemu_img_log('map', '--output=json', base)
98
+def non_chs_size_without_force(vm, file_path):
100
+ iotests.qemu_img_log('map', '--output=human', base)
99
+ iotests.log("=== Size not representable in CHS ===")
101
+ iotests.qemu_img_log('map', '--output=json', mid)
100
+ iotests.log("")
102
+ iotests.qemu_img_log('map', '--output=human', mid)
101
+
103
+ iotests.qemu_img_log('map', '--output=json', top)
102
+ # Not representable in CHS (will not work with force-size=False)
104
+ iotests.qemu_img_log('map', '--output=human', top)
103
+ size = 1048576
105
+
104
+
106
+ iotests.log('=== Testing qemu-img commit (top -> mid) ===')
105
+ blockdev_create(vm, { 'driver': imgfmt,
107
+
106
+ 'file': 'protocol-node',
108
+ iotests.qemu_img_log('commit', top)
107
+ 'size': size,
109
+ iotests.img_info_log(mid)
108
+ 'force-size': False })
110
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
109
+
111
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
110
+
112
+
111
+# Zero size
113
+ iotests.log('=== Testing HMP commit (top -> mid) ===')
112
+def zero_size(vm, file_path):
114
+
113
+ iotests.log("=== Zero size===")
115
+ create_chain()
114
+ iotests.log("")
116
+ with create_vm() as vm:
115
+
117
+ vm.launch()
116
+ blockdev_create(vm, { 'driver': imgfmt,
118
+ vm.qmp_log('human-monitor-command', command_line='commit drive0')
117
+ 'file': 'protocol-node',
119
+
118
+ 'size': 0 })
120
+ iotests.img_info_log(mid)
119
+
121
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
120
+
122
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
121
+# Maximum CHS size
123
+
122
+def maximum_chs_size(vm, file_path):
124
+ iotests.log('=== Testing QMP active commit (top -> mid) ===')
123
+ iotests.log("=== Maximum CHS size===")
125
+
124
+ iotests.log("")
126
+ create_chain()
125
+
127
+ with create_vm() as vm:
126
+ blockdev_create(vm, { 'driver': imgfmt,
128
+ vm.launch()
127
+ 'file': 'protocol-node',
129
+ vm.qmp_log('block-commit', device='top', base_node='mid',
128
+ 'size': 16 * 65535 * 255 * 512 })
130
+ job_id='job0', auto_dismiss=False)
129
+
131
+ vm.run_job('job0', wait=5)
130
+
132
+
131
+# Actual maximum size
133
+ iotests.img_info_log(mid)
132
+def maximum_size(vm, file_path):
134
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
133
+ iotests.log("=== Actual maximum size===")
135
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
134
+ iotests.log("")
136
+
135
+
137
+
136
+ blockdev_create(vm, { 'driver': imgfmt,
138
+ iotests.log('== Resize tests ==')
137
+ 'file': 'protocol-node',
139
+
138
+ 'size': 0xff000000 * 512,
140
+ # Use different sizes for different allocation modes:
139
+ 'force-size': True })
141
+ #
140
+
142
+ # We want to have at least one test where 32 bit truncation in the size of
141
+
143
+ # the overlapping area becomes visible. This is covered by the
142
+def main():
144
+ # prealloc='off' case (1G to 6G is an overlap of 5G).
143
+ for test_func in [implicit_defaults, explicit_defaults, non_defaults,
145
+ #
144
+ non_chs_size_without_force, zero_size, maximum_chs_size,
146
+ # However, we can only do this for modes that don't preallocate data
145
+ maximum_size]:
147
+ # because otherwise we might run out of space on the test host.
146
+
148
+ #
147
+ with iotests.FilePath('t.vpc') as file_path, \
149
+ # We also want to test some unaligned combinations.
148
+ iotests.VM() as vm:
150
+ for (prealloc, base_size, top_size_old, top_size_new, off) in [
149
+
151
+ ('off', '6G', '1G', '8G', '5G'),
150
+ vm.launch()
152
+ ('metadata', '32G', '30G', '33G', '31G'),
151
+
153
+ ('falloc', '10M', '5M', '15M', '9M'),
152
+ iotests.log('--- Creating empty file ---')
154
+ ('full', '16M', '8M', '12M', '11M'),
153
+ blockdev_create(vm, { 'driver': 'file',
155
+ ('off', '384k', '253k', '512k', '253k'),
154
+ 'filename': file_path,
156
+ ('off', '400k', '256k', '512k', '336k'),
155
+ 'size': 0 })
157
+ ('off', '512k', '256k', '500k', '436k')]:
156
+
158
+
157
+ vm.qmp_log('blockdev-add', driver='file', filename=file_path,
159
+ iotests.log('=== preallocation=%s ===' % prealloc)
158
+ node_name='protocol-node',
160
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, base, base_size)
159
+ filters=[iotests.filter_qmp_testfiles])
161
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, top,
160
+ iotests.log('')
162
+ top_size_old)
161
+
163
+ iotests.qemu_io_log('-c', 'write -P 1 %s 64k' % off, base)
162
+ print_info = test_func(vm, file_path)
164
+
163
+ iotests.log('')
165
+ # After this, top_size_old to base_size should be allocated/zeroed.
164
+
166
+ #
165
+ vm.shutdown()
167
+ # In theory, leaving base_size to top_size_new unallocated would be
166
+ iotests.img_info_log(file_path)
168
+ # correct, but in practice, if we zero out anything, we zero out
167
+
169
+ # everything up to top_size_new.
168
+
170
+ iotests.qemu_img_log('resize', '-f', iotests.imgfmt,
169
+iotests.script_main(main,
171
+ '--preallocation', prealloc, top, top_size_new)
170
+ supported_fmts=['vpc'],
172
+ iotests.qemu_io_log('-c', 'read -P 0 %s 64k' % off, top)
171
+ supported_protocols=['file'])
173
+ iotests.qemu_io_log('-c', 'map', top)
172
diff --git a/tests/qemu-iotests/266.out b/tests/qemu-iotests/266.out
174
+ iotests.qemu_img_log('map', '--output=json', top)
175
diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
173
new file mode 100644
176
new file mode 100644
174
index XXXXXXX..XXXXXXX
177
index XXXXXXX..XXXXXXX
175
--- /dev/null
178
--- /dev/null
176
+++ b/tests/qemu-iotests/266.out
179
+++ b/tests/qemu-iotests/274.out
177
@@ -XXX,XX +XXX,XX @@
180
@@ -XXX,XX +XXX,XX @@
178
+--- Creating empty file ---
181
+== Commit tests ==
179
+{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "size": 0}}}
182
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
183
+
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
185
+
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
187
+
188
+wrote 2097152/2097152 bytes at offset 0
189
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
190
+
191
+=== Check visible data ===
192
+read 1048576/1048576 bytes at offset 0
193
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
194
+
195
+read 1048576/1048576 bytes at offset 1048576
196
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
197
+
198
+=== Checking allocation status ===
199
+1048576/1048576 bytes allocated at offset 0 bytes
200
+1048576/1048576 bytes allocated at offset 1 MiB
201
+
202
+0/1048576 bytes allocated at offset 0 bytes
203
+0/0 bytes allocated at offset 1 MiB
204
+
205
+0/1048576 bytes allocated at offset 0 bytes
206
+0/1048576 bytes allocated at offset 1 MiB
207
+
208
+=== Checking map ===
209
+[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": 327680}]
210
+
211
+Offset Length Mapped to File
212
+0 0x200000 0x50000 TEST_DIR/PID-base
213
+
214
+[{ "start": 0, "length": 1048576, "depth": 1, "zero": false, "data": true, "offset": 327680}]
215
+
216
+Offset Length Mapped to File
217
+0 0x100000 0x50000 TEST_DIR/PID-base
218
+
219
+[{ "start": 0, "length": 1048576, "depth": 2, "zero": false, "data": true, "offset": 327680},
220
+{ "start": 1048576, "length": 1048576, "depth": 0, "zero": true, "data": false}]
221
+
222
+Offset Length Mapped to File
223
+0 0x100000 0x50000 TEST_DIR/PID-base
224
+
225
+=== Testing qemu-img commit (top -> mid) ===
226
+Image committed.
227
+
228
+image: TEST_IMG
229
+file format: IMGFMT
230
+virtual size: 2 MiB (2097152 bytes)
231
+cluster_size: 65536
232
+backing file: TEST_DIR/PID-base
233
+Format specific information:
234
+ compat: 1.1
235
+ lazy refcounts: false
236
+ refcount bits: 16
237
+ corrupt: false
238
+
239
+read 1048576/1048576 bytes at offset 0
240
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
241
+
242
+read 1048576/1048576 bytes at offset 1048576
243
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
244
+
245
+=== Testing HMP commit (top -> mid) ===
246
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
247
+
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
249
+
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
251
+
252
+wrote 2097152/2097152 bytes at offset 0
253
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
254
+
255
+{"execute": "human-monitor-command", "arguments": {"command-line": "commit drive0"}}
256
+{"return": ""}
257
+image: TEST_IMG
258
+file format: IMGFMT
259
+virtual size: 2 MiB (2097152 bytes)
260
+cluster_size: 65536
261
+backing file: TEST_DIR/PID-base
262
+Format specific information:
263
+ compat: 1.1
264
+ lazy refcounts: false
265
+ refcount bits: 16
266
+ corrupt: false
267
+
268
+read 1048576/1048576 bytes at offset 0
269
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
270
+
271
+read 1048576/1048576 bytes at offset 1048576
272
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
273
+
274
+=== Testing QMP active commit (top -> mid) ===
275
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
276
+
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
278
+
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
280
+
281
+wrote 2097152/2097152 bytes at offset 0
282
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
283
+
284
+{"execute": "block-commit", "arguments": {"auto-dismiss": false, "base-node": "mid", "device": "top", "job-id": "job0"}}
180
+{"return": {}}
285
+{"return": {}}
286
+{"execute": "job-complete", "arguments": {"id": "job0"}}
287
+{"return": {}}
288
+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
289
+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
181
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
290
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
182
+{"return": {}}
291
+{"return": {}}
183
+{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
184
+{"return": {}}
185
+
186
+=== Successful image creation (defaults) ===
187
+
188
+{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vpc", "file": "protocol-node", "size": 67125248}}}
189
+{"return": {}}
190
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
191
+{"return": {}}
192
+
193
+image: TEST_IMG
292
+image: TEST_IMG
194
+file format: IMGFMT
293
+file format: IMGFMT
195
+virtual size: 64 MiB (67125248 bytes)
294
+virtual size: 2 MiB (2097152 bytes)
196
+cluster_size: 2097152
295
+cluster_size: 65536
197
+
296
+backing file: TEST_DIR/PID-base
198
+--- Creating empty file ---
297
+Format specific information:
199
+{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "size": 0}}}
298
+ compat: 1.1
200
+{"return": {}}
299
+ lazy refcounts: false
201
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
300
+ refcount bits: 16
202
+{"return": {}}
301
+ corrupt: false
203
+{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
302
+
204
+{"return": {}}
303
+read 1048576/1048576 bytes at offset 0
205
+
304
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
206
+=== Successful image creation (explicit defaults) ===
305
+
207
+
306
+read 1048576/1048576 bytes at offset 1048576
208
+{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vpc", "file": "protocol-node", "force-size": false, "size": 134250496, "subformat": "dynamic"}}}
307
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
209
+{"return": {}}
308
+
210
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
309
+== Resize tests ==
211
+{"return": {}}
310
+=== preallocation=off ===
212
+
311
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=6442450944 cluster_size=65536 lazy_refcounts=off refcount_bits=16
213
+image: TEST_IMG
312
+
214
+file format: IMGFMT
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
215
+virtual size: 128 MiB (134250496 bytes)
314
+
216
+cluster_size: 2097152
315
+wrote 65536/65536 bytes at offset 5368709120
217
+
316
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
218
+--- Creating empty file ---
317
+
219
+{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "size": 0}}}
318
+Image resized.
220
+{"return": {}}
319
+
221
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
320
+read 65536/65536 bytes at offset 5368709120
222
+{"return": {}}
321
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
223
+{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
322
+
224
+{"return": {}}
323
+1 GiB (0x40000000) bytes not allocated at offset 0 bytes (0x0)
225
+
324
+7 GiB (0x1c0000000) bytes allocated at offset 1 GiB (0x40000000)
226
+=== Successful image creation (non-default options) ===
325
+
227
+
326
+[{ "start": 0, "length": 1073741824, "depth": 1, "zero": true, "data": false},
228
+{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vpc", "file": "protocol-node", "force-size": true, "size": 1048576, "subformat": "fixed"}}}
327
+{ "start": 1073741824, "length": 7516192768, "depth": 0, "zero": true, "data": false}]
229
+{"return": {}}
328
+
230
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
329
+=== preallocation=metadata ===
231
+{"return": {}}
330
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=34359738368 cluster_size=65536 lazy_refcounts=off refcount_bits=16
232
+
331
+
233
+image: TEST_IMG
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
234
+file format: IMGFMT
333
+
235
+virtual size: 1 MiB (1048576 bytes)
334
+wrote 65536/65536 bytes at offset 33285996544
236
+
335
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
237
+--- Creating empty file ---
336
+
238
+{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "size": 0}}}
337
+Image resized.
239
+{"return": {}}
338
+
240
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
339
+read 65536/65536 bytes at offset 33285996544
241
+{"return": {}}
340
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
242
+{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
341
+
243
+{"return": {}}
342
+30 GiB (0x780000000) bytes not allocated at offset 0 bytes (0x0)
244
+
343
+3 GiB (0xc0000000) bytes allocated at offset 30 GiB (0x780000000)
245
+=== Size not representable in CHS ===
344
+
246
+
345
+[{ "start": 0, "length": 32212254720, "depth": 1, "zero": true, "data": false},
247
+{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vpc", "file": "protocol-node", "force-size": false, "size": 1048576}}}
346
+{ "start": 32212254720, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 327680},
248
+{"return": {}}
347
+{ "start": 32749125632, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 537264128},
249
+Job failed: The requested image size cannot be represented in CHS geometry
348
+{ "start": 33285996544, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 1074200576},
250
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
349
+{ "start": 33822867456, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 1611137024},
251
+{"return": {}}
350
+{ "start": 34359738368, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2148139008},
252
+
351
+{ "start": 34896609280, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2685075456}]
253
+qemu-img: Could not open 'TEST_IMG': File too small for a VHD header
352
+
254
+
353
+=== preallocation=falloc ===
255
+--- Creating empty file ---
354
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=10485760 cluster_size=65536 lazy_refcounts=off refcount_bits=16
256
+{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "size": 0}}}
355
+
257
+{"return": {}}
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
258
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
357
+
259
+{"return": {}}
358
+wrote 65536/65536 bytes at offset 9437184
260
+{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
359
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
261
+{"return": {}}
360
+
262
+
361
+Image resized.
263
+=== Zero size===
362
+
264
+
363
+read 65536/65536 bytes at offset 9437184
265
+{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vpc", "file": "protocol-node", "size": 0}}}
364
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
266
+{"return": {}}
365
+
267
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
366
+5 MiB (0x500000) bytes not allocated at offset 0 bytes (0x0)
268
+{"return": {}}
367
+10 MiB (0xa00000) bytes allocated at offset 5 MiB (0x500000)
269
+
368
+
270
+image: TEST_IMG
369
+[{ "start": 0, "length": 5242880, "depth": 1, "zero": true, "data": false},
271
+file format: IMGFMT
370
+{ "start": 5242880, "length": 10485760, "depth": 0, "zero": true, "data": false, "offset": 327680}]
272
+virtual size: 0 B (0 bytes)
371
+
273
+cluster_size: 2097152
372
+=== preallocation=full ===
274
+
373
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
275
+--- Creating empty file ---
374
+
276
+{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "size": 0}}}
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
277
+{"return": {}}
376
+
278
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
377
+wrote 65536/65536 bytes at offset 11534336
279
+{"return": {}}
378
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
280
+{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
379
+
281
+{"return": {}}
380
+Image resized.
282
+
381
+
283
+=== Maximum CHS size===
382
+read 65536/65536 bytes at offset 11534336
284
+
383
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
285
+{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vpc", "file": "protocol-node", "size": 136899993600}}}
384
+
286
+{"return": {}}
385
+8 MiB (0x800000) bytes not allocated at offset 0 bytes (0x0)
287
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
386
+4 MiB (0x400000) bytes allocated at offset 8 MiB (0x800000)
288
+{"return": {}}
387
+
289
+
388
+[{ "start": 0, "length": 8388608, "depth": 1, "zero": true, "data": false},
290
+image: TEST_IMG
389
+{ "start": 8388608, "length": 4194304, "depth": 0, "zero": true, "data": false, "offset": 327680}]
291
+file format: IMGFMT
390
+
292
+virtual size: 127 GiB (136899993600 bytes)
391
+=== preallocation=off ===
293
+cluster_size: 2097152
392
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
294
+
393
+
295
+--- Creating empty file ---
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
296
+{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "size": 0}}}
395
+
297
+{"return": {}}
396
+wrote 65536/65536 bytes at offset 259072
298
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
397
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
299
+{"return": {}}
398
+
300
+{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
399
+Image resized.
301
+{"return": {}}
400
+
302
+
401
+read 65536/65536 bytes at offset 259072
303
+=== Actual maximum size===
402
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
304
+
403
+
305
+{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vpc", "file": "protocol-node", "force-size": true, "size": 2190433320960}}}
404
+192 KiB (0x30000) bytes not allocated at offset 0 bytes (0x0)
306
+{"return": {}}
405
+320 KiB (0x50000) bytes allocated at offset 192 KiB (0x30000)
307
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
406
+
308
+{"return": {}}
407
+[{ "start": 0, "length": 196608, "depth": 1, "zero": true, "data": false},
309
+
408
+{ "start": 196608, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": 327680},
310
+image: TEST_IMG
409
+{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
311
+file format: IMGFMT
410
+
312
+virtual size: 1.99 TiB (2190433320960 bytes)
411
+=== preallocation=off ===
313
+cluster_size: 2097152
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}]
314
+
448
+
315
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
316
index XXXXXXX..XXXXXXX 100644
450
index XXXXXXX..XXXXXXX 100644
317
--- a/tests/qemu-iotests/group
451
--- a/tests/qemu-iotests/group
318
+++ b/tests/qemu-iotests/group
452
+++ b/tests/qemu-iotests/group
319
@@ -XXX,XX +XXX,XX @@
453
@@ -XXX,XX +XXX,XX @@
320
258 rw quick
454
270 rw backing quick
321
262 rw quick migration
455
272 rw
322
265 rw auto quick
456
273 backing quick
323
+266 rw quick
457
+274 rw backing
458
277 rw quick
459
279 rw backing quick
460
280 rw migration quick
324
--
461
--
325
2.20.1
462
2.25.3
326
463
327
464
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
The BDRV_REQ_ZERO_WRITE is currently implemented in a way that first the
2
image is possibly preallocated and then the zero flag is added to all
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.
2
6
3
The size of the qcow2 L2 cache defaults to 32 MB, which can be easily
7
Instead, try to forward the BDRV_REQ_ZERO_WRITE to the protocol driver,
4
larger than the maximum amount of L2 metadata that the image can have.
8
and if the protocol driver can ensure that the new area reads as zeros,
5
For example: with 64 KB clusters the user would need a qcow2 image
9
we can skip setting the zero flag in the qcow2 layer.
6
with a virtual size of 256 GB in order to have 32 MB of L2 metadata.
7
10
8
Because of that, since commit b749562d9822d14ef69c9eaa5f85903010b86c30
11
Unfortunately, the same approach doesn't work for metadata
9
we forbid the L2 cache to become larger than the maximum amount of L2
12
preallocation, so we'll still set the zero flag there.
10
metadata for the image, calculated using this formula:
11
13
12
uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8);
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
15
Reviewed-by: Max Reitz <mreitz@redhat.com>
14
The problem with this formula is that the result should be rounded up
16
Message-Id: <20200424142701.67053-1-kwolf@redhat.com>
15
to the cluster size because an L2 table on disk always takes one full
17
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
16
cluster.
17
18
For example, a 1280 MB qcow2 image with 64 KB clusters needs exactly
19
160 KB of L2 metadata, but we need 192 KB on disk (3 clusters) even if
20
the last 32 KB of those are not going to be used.
21
22
However QEMU rounds the numbers down and only creates 2 cache tables
23
(128 KB), which is not enough for the image.
24
25
A quick test doing 4KB random writes on a 1280 MB image gives me
26
around 500 IOPS, while with the correct cache size I get 16K IOPS.
27
28
Cc: qemu-stable@nongnu.org
29
Signed-off-by: Alberto Garcia <berto@igalia.com>
30
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
31
---
19
---
32
block/qcow2.c | 6 +++++-
20
block/qcow2.c | 22 +++++++++++++++++++---
33
1 file changed, 5 insertions(+), 1 deletion(-)
21
tests/qemu-iotests/274.out | 4 ++--
22
2 files changed, 21 insertions(+), 5 deletions(-)
34
23
35
diff --git a/block/qcow2.c b/block/qcow2.c
24
diff --git a/block/qcow2.c b/block/qcow2.c
36
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
37
--- a/block/qcow2.c
26
--- a/block/qcow2.c
38
+++ b/block/qcow2.c
27
+++ b/block/qcow2.c
39
@@ -XXX,XX +XXX,XX @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
28
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
40
bool l2_cache_entry_size_set;
29
/* Allocate the data area */
41
int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size;
30
new_file_size = allocation_start +
42
uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
31
nb_new_data_clusters * s->cluster_size;
43
- uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8);
32
- /* Image file grows, so @exact does not matter */
44
+ uint64_t max_l2_entries = DIV_ROUND_UP(virtual_disk_size, s->cluster_size);
33
- ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
45
+ /* An L2 table is always one cluster in size so the max cache size
34
- errp);
46
+ * should be a multiple of the cluster size. */
35
+ /*
47
+ uint64_t max_l2_cache = ROUND_UP(max_l2_entries * sizeof(uint64_t),
36
+ * Image file grows, so @exact does not matter.
48
+ s->cluster_size);
37
+ *
49
38
+ * If we need to zero out the new area, try first whether the protocol
50
combined_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_CACHE_SIZE);
39
+ * driver can already take care of this.
51
l2_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_SIZE);
40
+ */
41
+ if (flags & BDRV_REQ_ZERO_WRITE) {
42
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc,
43
+ BDRV_REQ_ZERO_WRITE, NULL);
44
+ if (ret >= 0) {
45
+ flags &= ~BDRV_REQ_ZERO_WRITE;
46
+ }
47
+ } else {
48
+ ret = -1;
49
+ }
50
+ if (ret < 0) {
51
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
52
+ errp);
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
52
--
79
--
53
2.20.1
80
2.25.3
54
81
55
82
diff view generated by jsdifflib
Deleted patch
1
From: Max Reitz <mreitz@redhat.com>
2
1
3
This exercises the regression introduced in commit
4
50ba5b2d994853b38fed10e0841b119da0f8b8e5. On my machine, it has close
5
to a 50 % false-negative rate, but that should still be sufficient to
6
test the fix.
7
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
10
Reviewed-by: John Snow <jsnow@redhat.com>
11
Tested-by: Stefano Garzarella <sgarzare@redhat.com>
12
Tested-by: John Snow <jsnow@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
tests/qemu-iotests/265 | 67 ++++++++++++++++++++++++++++++++++++++
16
tests/qemu-iotests/265.out | 6 ++++
17
tests/qemu-iotests/group | 1 +
18
3 files changed, 74 insertions(+)
19
create mode 100755 tests/qemu-iotests/265
20
create mode 100644 tests/qemu-iotests/265.out
21
22
diff --git a/tests/qemu-iotests/265 b/tests/qemu-iotests/265
23
new file mode 100755
24
index XXXXXXX..XXXXXXX
25
--- /dev/null
26
+++ b/tests/qemu-iotests/265
27
@@ -XXX,XX +XXX,XX @@
28
+#!/usr/bin/env bash
29
+#
30
+# Test reverse-ordered qcow2 writes on a sub-cluster level
31
+#
32
+# Copyright (C) 2019 Red Hat, Inc.
33
+#
34
+# This program is free software; you can redistribute it and/or modify
35
+# it under the terms of the GNU General Public License as published by
36
+# the Free Software Foundation; either version 2 of the License, or
37
+# (at your option) any later version.
38
+#
39
+# This program is distributed in the hope that it will be useful,
40
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
41
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
42
+# GNU General Public License for more details.
43
+#
44
+# You should have received a copy of the GNU General Public License
45
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
46
+#
47
+
48
+seq=$(basename $0)
49
+echo "QA output created by $seq"
50
+
51
+status=1    # failure is the default!
52
+
53
+_cleanup()
54
+{
55
+ _cleanup_test_img
56
+}
57
+trap "_cleanup; exit \$status" 0 1 2 3 15
58
+
59
+# get standard environment, filters and checks
60
+. ./common.rc
61
+. ./common.filter
62
+
63
+# qcow2-specific test
64
+_supported_fmt qcow2
65
+_supported_proto file
66
+_supported_os Linux
67
+
68
+echo '--- Writing to the image ---'
69
+
70
+# Reduce cluster size so we get more and quicker I/O
71
+IMGOPTS='cluster_size=4096' _make_test_img 1M
72
+(for ((kb = 1024 - 4; kb >= 0; kb -= 4)); do \
73
+ echo "aio_write -P 42 $((kb + 1))k 2k"; \
74
+ done) \
75
+ | $QEMU_IO "$TEST_IMG" > /dev/null
76
+
77
+echo '--- Verifying its content ---'
78
+
79
+(for ((kb = 0; kb < 1024; kb += 4)); do \
80
+ echo "read -P 0 ${kb}k 1k"; \
81
+ echo "read -P 42 $((kb + 1))k 2k"; \
82
+ echo "read -P 0 $((kb + 3))k 1k"; \
83
+ done) \
84
+ | $QEMU_IO "$TEST_IMG" | _filter_qemu_io | grep 'verification'
85
+
86
+# Status of qemu-io
87
+if [ ${PIPESTATUS[1]} = 0 ]; then
88
+ echo 'Content verified.'
89
+fi
90
+
91
+# success, all done
92
+echo "*** done"
93
+rm -f $seq.full
94
+status=0
95
diff --git a/tests/qemu-iotests/265.out b/tests/qemu-iotests/265.out
96
new file mode 100644
97
index XXXXXXX..XXXXXXX
98
--- /dev/null
99
+++ b/tests/qemu-iotests/265.out
100
@@ -XXX,XX +XXX,XX @@
101
+QA output created by 265
102
+--- Writing to the image ---
103
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
104
+--- Verifying its content ---
105
+Content verified.
106
+*** done
107
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
108
index XXXXXXX..XXXXXXX 100644
109
--- a/tests/qemu-iotests/group
110
+++ b/tests/qemu-iotests/group
111
@@ -XXX,XX +XXX,XX @@
112
257 rw
113
258 rw quick
114
262 rw quick migration
115
+265 rw auto quick
116
--
117
2.20.1
118
119
diff view generated by jsdifflib
Deleted patch
1
From: Markus Armbruster <armbru@redhat.com>
2
1
3
pr_manager_worker() passes its @opaque argument to g_free(). Wrong;
4
it points to pr_manager_worker()'s automatic @data. Broken when
5
commit 2f3a7ab39be converted @data from heap- to stack-allocated. Fix
6
by deleting the g_free().
7
8
Fixes: 2f3a7ab39bec4ba8022dc4d42ea641165b004e3e
9
Cc: qemu-stable@nongnu.org
10
Signed-off-by: Markus Armbruster <armbru@redhat.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
scsi/pr-manager.c | 1 -
16
1 file changed, 1 deletion(-)
17
18
diff --git a/scsi/pr-manager.c b/scsi/pr-manager.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/scsi/pr-manager.c
21
+++ b/scsi/pr-manager.c
22
@@ -XXX,XX +XXX,XX @@ static int pr_manager_worker(void *opaque)
23
int fd = data->fd;
24
int r;
25
26
- g_free(data);
27
trace_pr_manager_run(fd, hdr->cmdp[0], hdr->cmdp[1]);
28
29
/* The reference was taken in pr_manager_execute. */
30
--
31
2.20.1
32
33
diff view generated by jsdifflib
Deleted patch
1
If QEMU_AIO_NO_FALLBACK is given, we always return failure and don't
2
even try to use the BLKZEROOUT ioctl. In this failure case, we shouldn't
3
disable has_write_zeroes because we didn't learn anything about the
4
ioctl. The next request might not set QEMU_AIO_NO_FALLBACK and we can
5
still use the ioctl then.
6
1
7
Fixes: 738301e1175
8
Reported-by: Eric Blake <eblake@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Reviewed-by: Eric Blake <eblake@redhat.com>
11
---
12
block/file-posix.c | 6 +++---
13
1 file changed, 3 insertions(+), 3 deletions(-)
14
15
diff --git a/block/file-posix.c b/block/file-posix.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/file-posix.c
18
+++ b/block/file-posix.c
19
@@ -XXX,XX +XXX,XX @@ static ssize_t handle_aiocb_write_zeroes_block(RawPosixAIOData *aiocb)
20
} while (errno == EINTR);
21
22
ret = translate_err(-errno);
23
+ if (ret == -ENOTSUP) {
24
+ s->has_write_zeroes = false;
25
+ }
26
}
27
#endif
28
29
- if (ret == -ENOTSUP) {
30
- s->has_write_zeroes = false;
31
- }
32
return ret;
33
}
34
35
--
36
2.20.1
37
38
diff view generated by jsdifflib
Deleted patch
1
From: Max Reitz <mreitz@redhat.com>
2
1
3
Most of our Python unittest-style tests only support the file protocol.
4
You can run them with any other protocol, but the test will simply
5
ignore your choice and use file anyway.
6
7
We should let them signal that they require the file protocol so they
8
are skipped when you want to test some other protocol.
9
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
tests/qemu-iotests/030 | 3 ++-
14
tests/qemu-iotests/040 | 3 ++-
15
tests/qemu-iotests/041 | 3 ++-
16
tests/qemu-iotests/044 | 3 ++-
17
tests/qemu-iotests/045 | 3 ++-
18
tests/qemu-iotests/055 | 3 ++-
19
tests/qemu-iotests/056 | 3 ++-
20
tests/qemu-iotests/057 | 3 ++-
21
tests/qemu-iotests/065 | 3 ++-
22
tests/qemu-iotests/096 | 3 ++-
23
tests/qemu-iotests/118 | 3 ++-
24
tests/qemu-iotests/124 | 3 ++-
25
tests/qemu-iotests/129 | 3 ++-
26
tests/qemu-iotests/132 | 3 ++-
27
tests/qemu-iotests/139 | 3 ++-
28
tests/qemu-iotests/148 | 3 ++-
29
tests/qemu-iotests/151 | 3 ++-
30
tests/qemu-iotests/152 | 3 ++-
31
tests/qemu-iotests/155 | 3 ++-
32
tests/qemu-iotests/163 | 3 ++-
33
tests/qemu-iotests/165 | 3 ++-
34
tests/qemu-iotests/169 | 3 ++-
35
tests/qemu-iotests/196 | 3 ++-
36
tests/qemu-iotests/199 | 3 ++-
37
tests/qemu-iotests/245 | 3 ++-
38
tests/qemu-iotests/257 | 3 ++-
39
26 files changed, 52 insertions(+), 26 deletions(-)
40
41
diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
42
index XXXXXXX..XXXXXXX 100755
43
--- a/tests/qemu-iotests/030
44
+++ b/tests/qemu-iotests/030
45
@@ -XXX,XX +XXX,XX @@ class TestSetSpeed(iotests.QMPTestCase):
46
self.cancel_and_wait(resume=True)
47
48
if __name__ == '__main__':
49
- iotests.main(supported_fmts=['qcow2', 'qed'])
50
+ iotests.main(supported_fmts=['qcow2', 'qed'],
51
+ supported_protocols=['file'])
52
diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040
53
index XXXXXXX..XXXXXXX 100755
54
--- a/tests/qemu-iotests/040
55
+++ b/tests/qemu-iotests/040
56
@@ -XXX,XX +XXX,XX @@ class TestReopenOverlay(ImageCommitTestCase):
57
self.run_commit_test(self.img1, self.img0)
58
59
if __name__ == '__main__':
60
- iotests.main(supported_fmts=['qcow2', 'qed'])
61
+ iotests.main(supported_fmts=['qcow2', 'qed'],
62
+ supported_protocols=['file'])
63
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
64
index XXXXXXX..XXXXXXX 100755
65
--- a/tests/qemu-iotests/041
66
+++ b/tests/qemu-iotests/041
67
@@ -XXX,XX +XXX,XX @@ class TestOrphanedSource(iotests.QMPTestCase):
68
self.assert_qmp(result, 'error/class', 'GenericError')
69
70
if __name__ == '__main__':
71
- iotests.main(supported_fmts=['qcow2', 'qed'])
72
+ iotests.main(supported_fmts=['qcow2', 'qed'],
73
+ supported_protocols=['file'])
74
diff --git a/tests/qemu-iotests/044 b/tests/qemu-iotests/044
75
index XXXXXXX..XXXXXXX 100755
76
--- a/tests/qemu-iotests/044
77
+++ b/tests/qemu-iotests/044
78
@@ -XXX,XX +XXX,XX @@ class TestRefcountTableGrowth(iotests.QMPTestCase):
79
pass
80
81
if __name__ == '__main__':
82
- iotests.main(supported_fmts=['qcow2'])
83
+ iotests.main(supported_fmts=['qcow2'],
84
+ supported_protocols=['file'])
85
diff --git a/tests/qemu-iotests/045 b/tests/qemu-iotests/045
86
index XXXXXXX..XXXXXXX 100755
87
--- a/tests/qemu-iotests/045
88
+++ b/tests/qemu-iotests/045
89
@@ -XXX,XX +XXX,XX @@ class TestSCMFd(iotests.QMPTestCase):
90
"File descriptor named '%s' not found" % fdname)
91
92
if __name__ == '__main__':
93
- iotests.main(supported_fmts=['raw'])
94
+ iotests.main(supported_fmts=['raw'],
95
+ supported_protocols=['file'])
96
diff --git a/tests/qemu-iotests/055 b/tests/qemu-iotests/055
97
index XXXXXXX..XXXXXXX 100755
98
--- a/tests/qemu-iotests/055
99
+++ b/tests/qemu-iotests/055
100
@@ -XXX,XX +XXX,XX @@ class TestDriveCompression(iotests.QMPTestCase):
101
target='drive1')
102
103
if __name__ == '__main__':
104
- iotests.main(supported_fmts=['raw', 'qcow2'])
105
+ iotests.main(supported_fmts=['raw', 'qcow2'],
106
+ supported_protocols=['file'])
107
diff --git a/tests/qemu-iotests/056 b/tests/qemu-iotests/056
108
index XXXXXXX..XXXXXXX 100755
109
--- a/tests/qemu-iotests/056
110
+++ b/tests/qemu-iotests/056
111
@@ -XXX,XX +XXX,XX @@ class BackupTest(iotests.QMPTestCase):
112
self.dismissal_failure(True)
113
114
if __name__ == '__main__':
115
- iotests.main(supported_fmts=['qcow2', 'qed'])
116
+ iotests.main(supported_fmts=['qcow2', 'qed'],
117
+ supported_protocols=['file'])
118
diff --git a/tests/qemu-iotests/057 b/tests/qemu-iotests/057
119
index XXXXXXX..XXXXXXX 100755
120
--- a/tests/qemu-iotests/057
121
+++ b/tests/qemu-iotests/057
122
@@ -XXX,XX +XXX,XX @@ class TestSnapshotDelete(ImageSnapshotTestCase):
123
self.assert_qmp(result, 'error/class', 'GenericError')
124
125
if __name__ == '__main__':
126
- iotests.main(supported_fmts=['qcow2'])
127
+ iotests.main(supported_fmts=['qcow2'],
128
+ supported_protocols=['file'])
129
diff --git a/tests/qemu-iotests/065 b/tests/qemu-iotests/065
130
index XXXXXXX..XXXXXXX 100755
131
--- a/tests/qemu-iotests/065
132
+++ b/tests/qemu-iotests/065
133
@@ -XXX,XX +XXX,XX @@ TestQemuImgInfo = None
134
TestQMP = None
135
136
if __name__ == '__main__':
137
- iotests.main(supported_fmts=['qcow2'])
138
+ iotests.main(supported_fmts=['qcow2'],
139
+ supported_protocols=['file'])
140
diff --git a/tests/qemu-iotests/096 b/tests/qemu-iotests/096
141
index XXXXXXX..XXXXXXX 100755
142
--- a/tests/qemu-iotests/096
143
+++ b/tests/qemu-iotests/096
144
@@ -XXX,XX +XXX,XX @@ class TestLiveSnapshot(iotests.QMPTestCase):
145
self.checkConfig('target')
146
147
if __name__ == '__main__':
148
- iotests.main(supported_fmts=['qcow2'])
149
+ iotests.main(supported_fmts=['qcow2'],
150
+ supported_protocols=['file'])
151
diff --git a/tests/qemu-iotests/118 b/tests/qemu-iotests/118
152
index XXXXXXX..XXXXXXX 100755
153
--- a/tests/qemu-iotests/118
154
+++ b/tests/qemu-iotests/118
155
@@ -XXX,XX +XXX,XX @@ if __name__ == '__main__':
156
iotests.qemu_default_machine)
157
# Need to support image creation
158
iotests.main(supported_fmts=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2',
159
- 'vmdk', 'raw', 'vhdx', 'qed'])
160
+ 'vmdk', 'raw', 'vhdx', 'qed'],
161
+ supported_protocols=['file'])
162
diff --git a/tests/qemu-iotests/124 b/tests/qemu-iotests/124
163
index XXXXXXX..XXXXXXX 100755
164
--- a/tests/qemu-iotests/124
165
+++ b/tests/qemu-iotests/124
166
@@ -XXX,XX +XXX,XX @@ class TestIncrementalBackupBlkdebug(TestIncrementalBackupBase):
167
168
169
if __name__ == '__main__':
170
- iotests.main(supported_fmts=['qcow2'])
171
+ iotests.main(supported_fmts=['qcow2'],
172
+ supported_protocols=['file'])
173
diff --git a/tests/qemu-iotests/129 b/tests/qemu-iotests/129
174
index XXXXXXX..XXXXXXX 100755
175
--- a/tests/qemu-iotests/129
176
+++ b/tests/qemu-iotests/129
177
@@ -XXX,XX +XXX,XX @@ class TestStopWithBlockJob(iotests.QMPTestCase):
178
self.do_test_stop("block-commit", device="drive0")
179
180
if __name__ == '__main__':
181
- iotests.main(supported_fmts=["qcow2"])
182
+ iotests.main(supported_fmts=["qcow2"],
183
+ supported_protocols=["file"])
184
diff --git a/tests/qemu-iotests/132 b/tests/qemu-iotests/132
185
index XXXXXXX..XXXXXXX 100755
186
--- a/tests/qemu-iotests/132
187
+++ b/tests/qemu-iotests/132
188
@@ -XXX,XX +XXX,XX @@ class TestSingleDrive(iotests.QMPTestCase):
189
'target image does not match source after mirroring')
190
191
if __name__ == '__main__':
192
- iotests.main(supported_fmts=['raw', 'qcow2'])
193
+ iotests.main(supported_fmts=['raw', 'qcow2'],
194
+ supported_protocols=['file'])
195
diff --git a/tests/qemu-iotests/139 b/tests/qemu-iotests/139
196
index XXXXXXX..XXXXXXX 100755
197
--- a/tests/qemu-iotests/139
198
+++ b/tests/qemu-iotests/139
199
@@ -XXX,XX +XXX,XX @@ class TestBlockdevDel(iotests.QMPTestCase):
200
201
202
if __name__ == '__main__':
203
- iotests.main(supported_fmts=["qcow2"])
204
+ iotests.main(supported_fmts=["qcow2"],
205
+ supported_protocols=["file"])
206
diff --git a/tests/qemu-iotests/148 b/tests/qemu-iotests/148
207
index XXXXXXX..XXXXXXX 100755
208
--- a/tests/qemu-iotests/148
209
+++ b/tests/qemu-iotests/148
210
@@ -XXX,XX +XXX,XX @@ class TestFifoQuorumEvents(TestQuorumEvents):
211
212
if __name__ == '__main__':
213
iotests.verify_quorum()
214
- iotests.main(supported_fmts=["raw"])
215
+ iotests.main(supported_fmts=["raw"],
216
+ supported_protocols=["file"])
217
diff --git a/tests/qemu-iotests/151 b/tests/qemu-iotests/151
218
index XXXXXXX..XXXXXXX 100755
219
--- a/tests/qemu-iotests/151
220
+++ b/tests/qemu-iotests/151
221
@@ -XXX,XX +XXX,XX @@ class TestActiveMirror(iotests.QMPTestCase):
222
223
224
if __name__ == '__main__':
225
- iotests.main(supported_fmts=['qcow2', 'raw'])
226
+ iotests.main(supported_fmts=['qcow2', 'raw'],
227
+ supported_protocols=['file'])
228
diff --git a/tests/qemu-iotests/152 b/tests/qemu-iotests/152
229
index XXXXXXX..XXXXXXX 100755
230
--- a/tests/qemu-iotests/152
231
+++ b/tests/qemu-iotests/152
232
@@ -XXX,XX +XXX,XX @@ class TestUnaligned(iotests.QMPTestCase):
233
234
235
if __name__ == '__main__':
236
- iotests.main(supported_fmts=['raw', 'qcow2'])
237
+ iotests.main(supported_fmts=['raw', 'qcow2'],
238
+ supported_protocols=['file'])
239
diff --git a/tests/qemu-iotests/155 b/tests/qemu-iotests/155
240
index XXXXXXX..XXXXXXX 100755
241
--- a/tests/qemu-iotests/155
242
+++ b/tests/qemu-iotests/155
243
@@ -XXX,XX +XXX,XX @@ BaseClass = None
244
MirrorBaseClass = None
245
246
if __name__ == '__main__':
247
- iotests.main(supported_fmts=['qcow2'])
248
+ iotests.main(supported_fmts=['qcow2'],
249
+ supported_protocols=['file'])
250
diff --git a/tests/qemu-iotests/163 b/tests/qemu-iotests/163
251
index XXXXXXX..XXXXXXX 100755
252
--- a/tests/qemu-iotests/163
253
+++ b/tests/qemu-iotests/163
254
@@ -XXX,XX +XXX,XX @@ class TestShrink1M(ShrinkBaseClass):
255
ShrinkBaseClass = None
256
257
if __name__ == '__main__':
258
- iotests.main(supported_fmts=['raw', 'qcow2'])
259
+ iotests.main(supported_fmts=['raw', 'qcow2'],
260
+ supported_protocols=['file'])
261
diff --git a/tests/qemu-iotests/165 b/tests/qemu-iotests/165
262
index XXXXXXX..XXXXXXX 100755
263
--- a/tests/qemu-iotests/165
264
+++ b/tests/qemu-iotests/165
265
@@ -XXX,XX +XXX,XX @@ class TestPersistentDirtyBitmap(iotests.QMPTestCase):
266
self.vm.shutdown()
267
268
if __name__ == '__main__':
269
- iotests.main(supported_fmts=['qcow2'])
270
+ iotests.main(supported_fmts=['qcow2'],
271
+ supported_protocols=['file'])
272
diff --git a/tests/qemu-iotests/169 b/tests/qemu-iotests/169
273
index XXXXXXX..XXXXXXX 100755
274
--- a/tests/qemu-iotests/169
275
+++ b/tests/qemu-iotests/169
276
@@ -XXX,XX +XXX,XX @@ for cmb in list(itertools.product((True, False), repeat=2)):
277
'do_test_migration_resume_source', *list(cmb))
278
279
if __name__ == '__main__':
280
- iotests.main(supported_fmts=['qcow2'])
281
+ iotests.main(supported_fmts=['qcow2'],
282
+ supported_protocols=['file'])
283
diff --git a/tests/qemu-iotests/196 b/tests/qemu-iotests/196
284
index XXXXXXX..XXXXXXX 100755
285
--- a/tests/qemu-iotests/196
286
+++ b/tests/qemu-iotests/196
287
@@ -XXX,XX +XXX,XX @@ class TestInvalidateAutoclear(iotests.QMPTestCase):
288
self.assertEqual(f.read(1), b'\x00')
289
290
if __name__ == '__main__':
291
- iotests.main(supported_fmts=['qcow2'])
292
+ iotests.main(supported_fmts=['qcow2'],
293
+ supported_protocols=['file'])
294
diff --git a/tests/qemu-iotests/199 b/tests/qemu-iotests/199
295
index XXXXXXX..XXXXXXX 100755
296
--- a/tests/qemu-iotests/199
297
+++ b/tests/qemu-iotests/199
298
@@ -XXX,XX +XXX,XX @@ class TestDirtyBitmapPostcopyMigration(iotests.QMPTestCase):
299
self.assert_qmp(result, 'return/sha256', sha256);
300
301
if __name__ == '__main__':
302
- iotests.main(supported_fmts=['qcow2'], supported_cache_modes=['none'])
303
+ iotests.main(supported_fmts=['qcow2'], supported_cache_modes=['none'],
304
+ supported_protocols=['file'])
305
diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245
306
index XXXXXXX..XXXXXXX 100644
307
--- a/tests/qemu-iotests/245
308
+++ b/tests/qemu-iotests/245
309
@@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase):
310
self.reopen(opts, {'backing': 'hd2'})
311
312
if __name__ == '__main__':
313
- iotests.main(supported_fmts=["qcow2"])
314
+ iotests.main(supported_fmts=["qcow2"],
315
+ supported_protocols=["file"])
316
diff --git a/tests/qemu-iotests/257 b/tests/qemu-iotests/257
317
index XXXXXXX..XXXXXXX 100755
318
--- a/tests/qemu-iotests/257
319
+++ b/tests/qemu-iotests/257
320
@@ -XXX,XX +XXX,XX @@ def main():
321
test_backup_api()
322
323
if __name__ == '__main__':
324
- iotests.script_main(main, supported_fmts=['qcow2'])
325
+ iotests.script_main(main, supported_fmts=['qcow2'],
326
+ supported_protocols=['file'])
327
--
328
2.20.1
329
330
diff view generated by jsdifflib
Deleted patch
1
From: Max Reitz <mreitz@redhat.com>
2
1
3
We have two Python unittest-style tests that test NBD. As such, they
4
should specify supported_protocols=['nbd'] so they are skipped when the
5
user wants to test some other protocol.
6
7
Furthermore, we should restrict their choice of formats to 'raw'. The
8
idea of a protocol/format combination is to use some format over some
9
protocol; but we always use the raw format over NBD. It does not really
10
matter what the NBD server uses on its end, and it is not a useful test
11
of the respective format driver anyway.
12
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
16
tests/qemu-iotests/147 | 5 ++---
17
tests/qemu-iotests/205 | 3 ++-
18
2 files changed, 4 insertions(+), 4 deletions(-)
19
20
diff --git a/tests/qemu-iotests/147 b/tests/qemu-iotests/147
21
index XXXXXXX..XXXXXXX 100755
22
--- a/tests/qemu-iotests/147
23
+++ b/tests/qemu-iotests/147
24
@@ -XXX,XX +XXX,XX @@ class BuiltinNBD(NBDBlockdevAddBase):
25
26
27
if __name__ == '__main__':
28
- # Need to support image creation
29
- iotests.main(supported_fmts=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2',
30
- 'vmdk', 'raw', 'vhdx', 'qed'])
31
+ iotests.main(supported_fmts=['raw'],
32
+ supported_protocols=['nbd'])
33
diff --git a/tests/qemu-iotests/205 b/tests/qemu-iotests/205
34
index XXXXXXX..XXXXXXX 100755
35
--- a/tests/qemu-iotests/205
36
+++ b/tests/qemu-iotests/205
37
@@ -XXX,XX +XXX,XX @@ class TestNbdServerRemove(iotests.QMPTestCase):
38
39
40
if __name__ == '__main__':
41
- iotests.main(supported_fmts=['generic'])
42
+ iotests.main(supported_fmts=['raw'],
43
+ supported_protocols=['nbd'])
44
--
45
2.20.1
46
47
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
chmod a-w don't help under root, so skip the test in such case.
4
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
8
tests/qemu-iotests/232 | 6 ++++++
9
1 file changed, 6 insertions(+)
10
11
diff --git a/tests/qemu-iotests/232 b/tests/qemu-iotests/232
12
index XXXXXXX..XXXXXXX 100755
13
--- a/tests/qemu-iotests/232
14
+++ b/tests/qemu-iotests/232
15
@@ -XXX,XX +XXX,XX @@ if [ -n "$TEST_IMG_FILE" ]; then
16
TEST_IMG=$TEST_IMG_FILE
17
fi
18
19
+chmod a-w $TEST_IMG
20
+(echo test > $TEST_IMG) 2>/dev/null && \
21
+ _notrun "Readonly attribute is ignored, probably you run this test as" \
22
+ "root, which is unsupported."
23
+chmod a+w $TEST_IMG
24
+
25
echo
26
echo "=== -drive with read-write image: read-only/auto-read-only combinations ==="
27
echo
28
--
29
2.20.1
30
31
diff view generated by jsdifflib
1
From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
1
From: Andrzej Jakowski <andrzej.jakowski@linux.intel.com>
2
2
3
The Valgrind tool fails to manage its termination in multi-threaded
3
This patch introduces support for PMR that has been defined as part of NVMe 1.4
4
processes when they raise the signal SIGKILL. The bug has been reported
4
spec. User can now specify a pmrdev option that should point to HostMemoryBackend.
5
to the Valgrind maintainers and was registered as the bug #409141:
5
pmrdev memory region will subsequently be exposed as PCI BAR 2 in emulated NVMe
6
https://bugs.kde.org/show_bug.cgi?id=409141
6
device. Guest OS can perform mmio read and writes to the PMR region that will stay
7
Let's exclude such test cases from running under the Valgrind until a
7
persistent across system reboot.
8
new version with the bug fix is released because checking for the
9
memory issues is covered by other test cases.
10
8
11
Suggested-by: John Snow <jsnow@redhat.com>
9
Signed-off-by: Andrzej Jakowski <andrzej.jakowski@linux.intel.com>
12
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
10
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
13
Reviewed-by: John Snow <jsnow@redhat.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>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
15
---
16
tests/qemu-iotests/039 | 5 +++++
16
hw/block/nvme.h | 2 +
17
tests/qemu-iotests/061 | 2 ++
17
include/block/nvme.h | 172 +++++++++++++++++++++++++++++++++++++++++
18
tests/qemu-iotests/137 | 1 +
18
hw/block/nvme.c | 109 ++++++++++++++++++++++++++
19
tests/qemu-iotests/common.rc | 12 ++++++++++--
19
hw/block/Makefile.objs | 2 +-
20
4 files changed, 18 insertions(+), 2 deletions(-)
20
hw/block/trace-events | 4 +
21
5 files changed, 288 insertions(+), 1 deletion(-)
21
22
22
diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039
23
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
23
index XXXXXXX..XXXXXXX 100755
24
--- a/tests/qemu-iotests/039
25
+++ b/tests/qemu-iotests/039
26
@@ -XXX,XX +XXX,XX @@ echo "== Creating a dirty image file =="
27
IMGOPTS="compat=1.1,lazy_refcounts=on"
28
_make_test_img $size
29
30
+_NO_VALGRIND \
31
$QEMU_IO -c "write -P 0x5a 0 512" \
32
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
33
| _filter_qemu_io
34
@@ -XXX,XX +XXX,XX @@ echo "== Opening a dirty image read/write should repair it =="
35
IMGOPTS="compat=1.1,lazy_refcounts=on"
36
_make_test_img $size
37
38
+_NO_VALGRIND \
39
$QEMU_IO -c "write -P 0x5a 0 512" \
40
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
41
| _filter_qemu_io
42
@@ -XXX,XX +XXX,XX @@ echo "== Creating an image file with lazy_refcounts=off =="
43
IMGOPTS="compat=1.1,lazy_refcounts=off"
44
_make_test_img $size
45
46
+_NO_VALGRIND \
47
$QEMU_IO -c "write -P 0x5a 0 512" \
48
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
49
| _filter_qemu_io
50
@@ -XXX,XX +XXX,XX @@ echo "== Changing lazy_refcounts setting at runtime =="
51
IMGOPTS="compat=1.1,lazy_refcounts=off"
52
_make_test_img $size
53
54
+_NO_VALGRIND \
55
$QEMU_IO -c "reopen -o lazy-refcounts=on" \
56
-c "write -P 0x5a 0 512" \
57
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
58
@@ -XXX,XX +XXX,XX @@ _check_test_img
59
IMGOPTS="compat=1.1,lazy_refcounts=on"
60
_make_test_img $size
61
62
+_NO_VALGRIND \
63
$QEMU_IO -c "reopen -o lazy-refcounts=off" \
64
-c "write -P 0x5a 0 512" \
65
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
66
diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061
67
index XXXXXXX..XXXXXXX 100755
68
--- a/tests/qemu-iotests/061
69
+++ b/tests/qemu-iotests/061
70
@@ -XXX,XX +XXX,XX @@ echo
71
echo "=== Testing dirty version downgrade ==="
72
echo
73
IMGOPTS="compat=1.1,lazy_refcounts=on" _make_test_img 64M
74
+_NO_VALGRIND \
75
$QEMU_IO -c "write -P 0x2a 0 128k" -c flush \
76
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 | _filter_qemu_io
77
$PYTHON qcow2.py "$TEST_IMG" dump-header
78
@@ -XXX,XX +XXX,XX @@ echo
79
echo "=== Testing dirty lazy_refcounts=off ==="
80
echo
81
IMGOPTS="compat=1.1,lazy_refcounts=on" _make_test_img 64M
82
+_NO_VALGRIND \
83
$QEMU_IO -c "write -P 0x2a 0 128k" -c flush \
84
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 | _filter_qemu_io
85
$PYTHON qcow2.py "$TEST_IMG" dump-header
86
diff --git a/tests/qemu-iotests/137 b/tests/qemu-iotests/137
87
index XXXXXXX..XXXXXXX 100755
88
--- a/tests/qemu-iotests/137
89
+++ b/tests/qemu-iotests/137
90
@@ -XXX,XX +XXX,XX @@ echo
91
92
# Whether lazy-refcounts was actually enabled can easily be tested: Check if
93
# the dirty bit is set after a crash
94
+_NO_VALGRIND \
95
$QEMU_IO \
96
-c "reopen -o lazy-refcounts=on,overlap-check=blubb" \
97
-c "write -P 0x5a 0 512" \
98
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
99
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
100
--- a/tests/qemu-iotests/common.rc
25
--- a/hw/block/nvme.h
101
+++ b/tests/qemu-iotests/common.rc
26
+++ b/hw/block/nvme.h
102
@@ -XXX,XX +XXX,XX @@ _qemu_proc_exec()
27
@@ -XXX,XX +XXX,XX @@ typedef struct NvmeCtrl {
103
{
28
uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
104
local VALGRIND_LOGFILE="$1"
29
105
shift
30
char *serial;
106
- if [ "${VALGRIND_QEMU}" == "y" ]; then
31
+ HostMemoryBackend *pmrdev;
107
+ if [[ "${VALGRIND_QEMU}" == "y" && "${NO_VALGRIND}" != "y" ]]; then
32
+
108
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$@"
33
NvmeNamespace *namespaces;
109
else
34
NvmeSQueue **sq;
110
exec "$@"
35
NvmeCQueue **cq;
111
@@ -XXX,XX +XXX,XX @@ _qemu_proc_valgrind_log()
36
diff --git a/include/block/nvme.h b/include/block/nvme.h
112
{
37
index XXXXXXX..XXXXXXX 100644
113
local VALGRIND_LOGFILE="$1"
38
--- a/include/block/nvme.h
114
local RETVAL="$2"
39
+++ b/include/block/nvme.h
115
- if [ "${VALGRIND_QEMU}" == "y" ]; then
40
@@ -XXX,XX +XXX,XX @@ typedef struct NvmeBar {
116
+ if [[ "${VALGRIND_QEMU}" == "y" && "${NO_VALGRIND}" != "y" ]]; then
41
uint64_t acq;
117
if [ $RETVAL == 99 ]; then
42
uint32_t cmbloc;
118
cat "${VALGRIND_LOGFILE}"
43
uint32_t cmbsz;
119
fi
44
+ uint8_t padding[3520]; /* not used by QEMU */
120
@@ -XXX,XX +XXX,XX @@ _qemu_vxhs_wrapper()
45
+ uint32_t pmrcap;
121
return $RETVAL
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
251
@@ -XXX,XX +XXX,XX @@
252
* -drive file=<file>,if=none,id=<drive_id>
253
* -device nvme,drive=<drive_id>,serial=<serial>,id=<id[optional]>, \
254
* cmb_size_mb=<cmb_size_mb[optional]>, \
255
+ * [pmrdev=<mem_backend_file_id>,] \
256
* num_queues=<N[optional]>
257
*
258
* Note cmb_size_mb denotes size of CMB in MB. CMB is assumed to be at
259
* offset 0 in BAR2 and supports only WDS, RDS and SQS for now.
260
+ *
261
+ * cmb_size_mb= and pmrdev= options are mutually exclusive due to limitation
262
+ * in available BAR's. cmb_size_mb= will take precedence over pmrdev= when
263
+ * both provided.
264
+ * Enabling pmr emulation can be achieved by pointing to memory-backend-file.
265
+ * For example:
266
+ * -object memory-backend-file,id=<mem_id>,share=on,mem-path=<file_path>, \
267
+ * size=<size> .... -device nvme,...,pmrdev=<mem_id>
268
*/
269
270
#include "qemu/osdep.h"
271
@@ -XXX,XX +XXX,XX @@
272
#include "sysemu/sysemu.h"
273
#include "qapi/error.h"
274
#include "qapi/visitor.h"
275
+#include "sysemu/hostmem.h"
276
#include "sysemu/block-backend.h"
277
+#include "exec/ram_addr.h"
278
279
#include "qemu/log.h"
280
#include "qemu/module.h"
281
@@ -XXX,XX +XXX,XX @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
282
NVME_GUEST_ERR(nvme_ub_mmiowr_cmbsz_readonly,
283
"invalid write to read only CMBSZ, ignored");
284
return;
285
+ case 0xE00: /* PMRCAP */
286
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrcap_readonly,
287
+ "invalid write to PMRCAP register, ignored");
288
+ return;
289
+ case 0xE04: /* TODO PMRCTL */
290
+ break;
291
+ case 0xE08: /* PMRSTS */
292
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrsts_readonly,
293
+ "invalid write to PMRSTS register, ignored");
294
+ return;
295
+ case 0xE0C: /* PMREBS */
296
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrebs_readonly,
297
+ "invalid write to PMREBS register, ignored");
298
+ return;
299
+ case 0xE10: /* PMRSWTP */
300
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrswtp_readonly,
301
+ "invalid write to PMRSWTP register, ignored");
302
+ return;
303
+ case 0xE14: /* TODO PMRMSC */
304
+ break;
305
default:
306
NVME_GUEST_ERR(nvme_ub_mmiowr_invalid,
307
"invalid MMIO write,"
308
@@ -XXX,XX +XXX,XX @@ static uint64_t nvme_mmio_read(void *opaque, hwaddr addr, unsigned size)
309
}
310
311
if (addr < sizeof(n->bar)) {
312
+ /*
313
+ * When PMRWBM bit 1 is set then read from
314
+ * from PMRSTS should ensure prior writes
315
+ * made it to persistent media
316
+ */
317
+ if (addr == 0xE08 &&
318
+ (NVME_PMRCAP_PMRWBM(n->bar.pmrcap) & 0x02)) {
319
+ qemu_ram_writeback(n->pmrdev->mr.ram_block,
320
+ 0, n->pmrdev->size);
321
+ }
322
memcpy(&val, ptr + addr, size);
323
} else {
324
NVME_GUEST_ERR(nvme_ub_mmiord_invalid_ofs,
325
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
326
error_setg(errp, "serial property not set");
327
return;
328
}
329
+
330
+ if (!n->cmb_size_mb && n->pmrdev) {
331
+ if (host_memory_backend_is_mapped(n->pmrdev)) {
332
+ char *path = object_get_canonical_path_component(OBJECT(n->pmrdev));
333
+ error_setg(errp, "can't use already busy memdev: %s", path);
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);
398
}
399
400
for (i = 0; i < n->num_namespaces; i++) {
401
@@ -XXX,XX +XXX,XX @@ static void nvme_exit(PCIDevice *pci_dev)
402
if (n->cmb_size_mb) {
403
g_free(n->cmbuf);
404
}
405
+
406
+ if (n->pmrdev) {
407
+ host_memory_backend_set_mapped(n->pmrdev, false);
408
+ }
409
msix_uninit_exclusive_bar(pci_dev);
122
}
410
}
123
411
124
+# Valgrind bug #409141 https://bugs.kde.org/show_bug.cgi?id=409141
412
static Property nvme_props[] = {
125
+# Until valgrind 3.16+ is ubiquitous, we must work around a hang in
413
DEFINE_BLOCK_PROPERTIES(NvmeCtrl, conf),
126
+# valgrind when issuing sigkill. Disable valgrind for this invocation.
414
+ DEFINE_PROP_LINK("pmrdev", NvmeCtrl, pmrdev, TYPE_MEMORY_BACKEND,
127
+_NO_VALGRIND()
415
+ HostMemoryBackend *),
128
+{
416
DEFINE_PROP_STRING("serial", NvmeCtrl, serial),
129
+ NO_VALGRIND="y" "$@"
417
DEFINE_PROP_UINT32("cmb_size_mb", NvmeCtrl, cmb_size_mb, 0),
130
+}
418
DEFINE_PROP_UINT32("num_queues", NvmeCtrl, num_queues, 64),
131
+
419
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
132
export QEMU=_qemu_wrapper
420
index XXXXXXX..XXXXXXX 100644
133
export QEMU_IMG=_qemu_img_wrapper
421
--- a/hw/block/Makefile.objs
134
export QEMU_IO=_qemu_io_wrapper
422
+++ b/hw/block/Makefile.objs
423
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
424
common-obj-$(CONFIG_XEN) += xen-block.o
425
common-obj-$(CONFIG_ECC) += ecc.o
426
common-obj-$(CONFIG_ONENAND) += onenand.o
427
-common-obj-$(CONFIG_NVME_PCI) += nvme.o
428
common-obj-$(CONFIG_SWIM) += swim.o
429
430
common-obj-$(CONFIG_SH4) += tc58128.o
431
432
obj-$(CONFIG_VIRTIO_BLK) += virtio-blk.o
433
obj-$(CONFIG_VHOST_USER_BLK) += vhost-user-blk.o
434
+obj-$(CONFIG_NVME_PCI) += nvme.o
435
436
obj-y += dataplane/
437
diff --git a/hw/block/trace-events b/hw/block/trace-events
438
index XXXXXXX..XXXXXXX 100644
439
--- a/hw/block/trace-events
440
+++ b/hw/block/trace-events
441
@@ -XXX,XX +XXX,XX @@ nvme_ub_mmiowr_ssreset_w1c_unsupported(void) "attempted to W1C CSTS.NSSRO but CA
442
nvme_ub_mmiowr_ssreset_unsupported(void) "attempted NVM subsystem reset but CAP.NSSRS is zero (not supported)"
443
nvme_ub_mmiowr_cmbloc_reserved(void) "invalid write to reserved CMBLOC when CMBSZ is zero, ignored"
444
nvme_ub_mmiowr_cmbsz_readonly(void) "invalid write to read only CMBSZ, ignored"
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""
135
--
452
--
136
2.20.1
453
2.25.3
137
454
138
455
diff view generated by jsdifflib
1
From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
1
The QMP handler qmp_object_add() and the implementation of --object in
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.
2
5
3
The new function _casenotrun() is to be invoked if a test case cannot
6
As a first step towards a fix, make qmp_object_add() a wrapper around a
4
be run for some reason. The user will be notified by a message passed
7
new function user_creatable_add_dict() that can get an additional
5
to the function. It is the caller's responsibility to make skipped a
8
parameter. The handling of "props" is only required for compatibility
6
particular test.
9
and not required for the qemu-storage-daemon command line, so it stays
10
in qmp_object_add().
7
11
8
Suggested-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
10
Reviewed-by: John Snow <jsnow@redhat.com>
11
Reviewed-by: Cleber Rosa <crosa@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
13
---
14
tests/qemu-iotests/common.rc | 9 +++++++++
14
include/qom/object_interfaces.h | 12 ++++++++++++
15
1 file changed, 9 insertions(+)
15
qom/object_interfaces.c | 27 +++++++++++++++++++++++++++
16
qom/qom-qmp-cmds.c | 24 +-----------------------
17
3 files changed, 40 insertions(+), 23 deletions(-)
16
18
17
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
19
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/qemu-iotests/common.rc
21
--- a/include/qom/object_interfaces.h
20
+++ b/tests/qemu-iotests/common.rc
22
+++ b/include/qom/object_interfaces.h
21
@@ -XXX,XX +XXX,XX @@ _notrun()
23
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
22
exit
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;
23
}
56
}
24
57
25
+# bail out, setting up .casenotrun file
58
+void user_creatable_add_dict(QDict *qdict, Error **errp)
26
+# The function _casenotrun() is used as a notifier. It is the
27
+# caller's responsibility to make skipped a particular test.
28
+#
29
+_casenotrun()
30
+{
59
+{
31
+ echo " [case not run] $*" >>"$OUTPUT_DIR/$seq.casenotrun"
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);
32
+}
83
+}
33
+
84
34
# just plain bail out
85
Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)
35
#
86
{
36
_fail()
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);
126
}
127
128
- v = qobject_input_visitor_new(QOBJECT(qdict));
129
- obj = user_creatable_add_type(type, id, qdict, v, errp);
130
- visit_free(v);
131
- object_unref(obj);
132
+ user_creatable_add_dict(qdict, errp);
133
}
134
135
void qmp_object_del(const char *id, Error **errp)
37
--
136
--
38
2.20.1
137
2.25.3
39
138
40
139
diff view generated by jsdifflib
1
From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
1
After processing the option string with the keyval parser, we get a
2
QDict that contains only strings. This QDict must be fed to a keyval
3
visitor which converts the strings into the right data types.
2
4
3
With the '-valgrind' option, let all the QEMU processes be run under
5
qmp_object_add(), however, uses the normal QObject input visitor, which
4
the Valgrind tool. The Valgrind own parameters may be set with its
6
expects a QDict where all properties already have the QType that matches
5
environment variable VALGRIND_OPTS, e.g.
7
the data type required by the QOM object type.
6
$ VALGRIND_OPTS="--leak-check=yes" ./check -valgrind <test#>
7
or they may be listed in the Valgrind checked file ./.valgrindrc or
8
~/.valgrindrc like
9
--memcheck:leak-check=no
10
--memcheck:track-origins=yes
11
To exclude a specific process from running under the Valgrind, the
12
corresponding environment variable VALGRIND_QEMU_<name> is to be set
13
to the empty string:
14
$ VALGRIND_QEMU_IO= ./check -valgrind <test#>
15
When QEMU-IO process is being killed, the shell report refers to the
16
text of the command in _qemu_io_wrapper(), which was modified with this
17
patch. So, the benchmark output for the tests 039, 061 and 137 is to be
18
changed also.
19
8
20
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
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>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
---
16
---
23
tests/qemu-iotests/039.out | 30 ++----------
17
include/qom/object_interfaces.h | 6 +++++-
24
tests/qemu-iotests/061.out | 12 +----
18
qemu-storage-daemon.c | 4 +---
25
tests/qemu-iotests/137.out | 6 +--
19
qom/object_interfaces.c | 8 ++++++--
26
tests/qemu-iotests/common.rc | 88 ++++++++++++++++++++++++++++--------
20
qom/qom-qmp-cmds.c | 2 +-
27
4 files changed, 78 insertions(+), 58 deletions(-)
21
4 files changed, 13 insertions(+), 7 deletions(-)
28
22
29
diff --git a/tests/qemu-iotests/039.out b/tests/qemu-iotests/039.out
23
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
30
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
31
--- a/tests/qemu-iotests/039.out
25
--- a/include/qom/object_interfaces.h
32
+++ b/tests/qemu-iotests/039.out
26
+++ b/include/qom/object_interfaces.h
33
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
27
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
34
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
28
/**
35
wrote 512/512 bytes at offset 0
29
* user_creatable_add_dict:
36
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
30
* @qdict: the object definition
37
-./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
31
+ * @keyval: if true, use a keyval visitor for processing @qdict (i.e.
38
- exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
32
+ * assume that all @qdict values are strings); otherwise, use
39
-else
33
+ * the normal QObject visitor (i.e. assume all @qdict values
40
- exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
34
+ * have the QType expected by the QOM object type)
41
-fi )
35
* @errp: if an error occurs, a pointer to an area to store the error
42
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
36
*
43
incompatible_features 0x1
37
* Create an instance of the user creatable object that is defined by
44
ERROR cluster 5 refcount=0 reference=1
38
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
45
ERROR OFLAG_COPIED data cluster: l2_entry=8000000000050000 refcount=0
39
* ID from the key 'id'. The remaining entries in @qdict are used to
46
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
40
* initialize the object properties.
47
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
41
*/
48
wrote 512/512 bytes at offset 0
42
-void user_creatable_add_dict(QDict *qdict, Error **errp);
49
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
43
+void user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp);
50
-./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
44
51
- exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
45
/**
52
-else
46
* user_creatable_add_opts:
53
- exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
47
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
54
-fi )
55
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
56
incompatible_features 0x1
57
ERROR cluster 5 refcount=0 reference=1
58
Rebuilding refcount structure
59
@@ -XXX,XX +XXX,XX @@ incompatible_features 0x0
60
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
61
wrote 512/512 bytes at offset 0
62
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
63
-./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
64
- exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
65
-else
66
- exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
67
-fi )
68
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
69
incompatible_features 0x0
70
No errors were found on the image.
71
72
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
73
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
74
wrote 512/512 bytes at offset 0
75
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
76
-./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
77
- exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
78
-else
79
- exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
80
-fi )
81
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
82
incompatible_features 0x1
83
ERROR cluster 5 refcount=0 reference=1
84
ERROR OFLAG_COPIED data cluster: l2_entry=8000000000050000 refcount=0
85
@@ -XXX,XX +XXX,XX @@ Data may be corrupted, or further writes to the image may corrupt it.
86
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
87
wrote 512/512 bytes at offset 0
88
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
89
-./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
90
- exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
91
-else
92
- exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
93
-fi )
94
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
95
incompatible_features 0x0
96
No errors were found on the image.
97
*** done
98
diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
99
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
100
--- a/tests/qemu-iotests/061.out
49
--- a/qemu-storage-daemon.c
101
+++ b/tests/qemu-iotests/061.out
50
+++ b/qemu-storage-daemon.c
102
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
51
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
103
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
52
QemuOpts *opts;
104
wrote 131072/131072 bytes at offset 0
53
const char *type;
105
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
54
QDict *args;
106
-./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
55
- QObject *ret_data = NULL;
107
- exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
56
108
-else
57
/* FIXME The keyval parser rejects 'help' arguments, so we must
109
- exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
58
* unconditionall try QemuOpts first. */
110
-fi )
59
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
111
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
60
qemu_opts_del(opts);
112
magic 0x514649fb
61
113
version 3
62
args = keyval_parse(optarg, "qom-type", &error_fatal);
114
backing_file_offset 0x0
63
- qmp_object_add(args, &ret_data, &error_fatal);
115
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
64
+ user_creatable_add_dict(args, true, &error_fatal);
116
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
65
qobject_unref(args);
117
wrote 131072/131072 bytes at offset 0
66
- qobject_unref(ret_data);
118
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
67
break;
119
-./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
68
}
120
- exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
69
default:
121
-else
70
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
122
- exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
123
-fi )
124
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
125
magic 0x514649fb
126
version 3
127
backing_file_offset 0x0
128
diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out
129
index XXXXXXX..XXXXXXX 100644
71
index XXXXXXX..XXXXXXX 100644
130
--- a/tests/qemu-iotests/137.out
72
--- a/qom/object_interfaces.c
131
+++ b/tests/qemu-iotests/137.out
73
+++ b/qom/object_interfaces.c
132
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
74
@@ -XXX,XX +XXX,XX @@ out:
133
qemu-io: Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
75
return obj;
134
wrote 512/512 bytes at offset 0
76
}
135
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
77
136
-./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
78
-void user_creatable_add_dict(QDict *qdict, Error **errp)
137
- exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
79
+void user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp)
138
-else
80
{
139
- exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
81
Visitor *v;
140
-fi )
82
Object *obj;
141
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
83
@@ -XXX,XX +XXX,XX @@ void user_creatable_add_dict(QDict *qdict, Error **errp)
142
incompatible_features 0x0
84
}
143
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
85
qdict_del(qdict, "id");
144
wrote 65536/65536 bytes at offset 0
86
145
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
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
146
index XXXXXXX..XXXXXXX 100644
97
index XXXXXXX..XXXXXXX 100644
147
--- a/tests/qemu-iotests/common.rc
98
--- a/qom/qom-qmp-cmds.c
148
+++ b/tests/qemu-iotests/common.rc
99
+++ b/qom/qom-qmp-cmds.c
149
@@ -XXX,XX +XXX,XX @@ if ! . ./common.config
100
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
150
exit 1
101
qobject_unref(pdict);
151
fi
102
}
152
103
153
+# Set the variables to the empty string to turn Valgrind off
104
- user_creatable_add_dict(qdict, errp);
154
+# for specific processes, e.g.
105
+ user_creatable_add_dict(qdict, false, errp);
155
+# $ VALGRIND_QEMU_IO= ./check -qcow2 -valgrind 015
156
+
157
+: ${VALGRIND_QEMU_VM=$VALGRIND_QEMU}
158
+: ${VALGRIND_QEMU_IMG=$VALGRIND_QEMU}
159
+: ${VALGRIND_QEMU_IO=$VALGRIND_QEMU}
160
+: ${VALGRIND_QEMU_NBD=$VALGRIND_QEMU}
161
+: ${VALGRIND_QEMU_VXHS=$VALGRIND_QEMU}
162
+
163
+# The Valgrind own parameters may be set with
164
+# its environment variable VALGRIND_OPTS, e.g.
165
+# $ VALGRIND_OPTS="--leak-check=yes" ./check -qcow2 -valgrind 015
166
+
167
+_qemu_proc_exec()
168
+{
169
+ local VALGRIND_LOGFILE="$1"
170
+ shift
171
+ if [ "${VALGRIND_QEMU}" == "y" ]; then
172
+ exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$@"
173
+ else
174
+ exec "$@"
175
+ fi
176
+}
177
+
178
+_qemu_proc_valgrind_log()
179
+{
180
+ local VALGRIND_LOGFILE="$1"
181
+ local RETVAL="$2"
182
+ if [ "${VALGRIND_QEMU}" == "y" ]; then
183
+ if [ $RETVAL == 99 ]; then
184
+ cat "${VALGRIND_LOGFILE}"
185
+ fi
186
+ rm -f "${VALGRIND_LOGFILE}"
187
+ fi
188
+}
189
+
190
_qemu_wrapper()
191
{
192
+ local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
193
(
194
if [ -n "${QEMU_NEED_PID}" ]; then
195
echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid"
196
fi
197
- exec "$QEMU_PROG" $QEMU_OPTIONS "$@"
198
+ VALGRIND_QEMU="${VALGRIND_QEMU_VM}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \
199
+ "$QEMU_PROG" $QEMU_OPTIONS "$@"
200
)
201
+ RETVAL=$?
202
+ _qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL
203
+ return $RETVAL
204
}
106
}
205
107
206
_qemu_img_wrapper()
108
void qmp_object_del(const char *id, Error **errp)
207
{
208
- (exec "$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS "$@")
209
+ local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
210
+ (
211
+ VALGRIND_QEMU="${VALGRIND_QEMU_IMG}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \
212
+ "$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS "$@"
213
+ )
214
+ RETVAL=$?
215
+ _qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL
216
+ return $RETVAL
217
}
218
219
_qemu_io_wrapper()
220
@@ -XXX,XX +XXX,XX @@ _qemu_io_wrapper()
221
QEMU_IO_ARGS="--object secret,id=keysec0,data=$IMGKEYSECRET $QEMU_IO_ARGS"
222
fi
223
fi
224
- local RETVAL
225
(
226
- if [ "${VALGRIND_QEMU}" == "y" ]; then
227
- exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"
228
- else
229
- exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"
230
- fi
231
+ VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \
232
+ "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"
233
)
234
RETVAL=$?
235
- if [ "${VALGRIND_QEMU}" == "y" ]; then
236
- if [ $RETVAL == 99 ]; then
237
- cat "${VALGRIND_LOGFILE}"
238
- fi
239
- rm -f "${VALGRIND_LOGFILE}"
240
- fi
241
- (exit $RETVAL)
242
+ _qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL
243
+ return $RETVAL
244
}
245
246
_qemu_nbd_wrapper()
247
{
248
- "$QEMU_NBD_PROG" --pid-file="${QEMU_TEST_DIR}/qemu-nbd.pid" \
249
- $QEMU_NBD_OPTIONS "$@"
250
+ local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
251
+ (
252
+ VALGRIND_QEMU="${VALGRIND_QEMU_NBD}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \
253
+ "$QEMU_NBD_PROG" --pid-file="${QEMU_TEST_DIR}/qemu-nbd.pid" \
254
+ $QEMU_NBD_OPTIONS "$@"
255
+ )
256
+ RETVAL=$?
257
+ _qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL
258
+ return $RETVAL
259
}
260
261
_qemu_vxhs_wrapper()
262
{
263
+ local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
264
(
265
echo $BASHPID > "${TEST_DIR}/qemu-vxhs.pid"
266
- exec "$QEMU_VXHS_PROG" $QEMU_VXHS_OPTIONS "$@"
267
+ VALGRIND_QEMU="${VALGRIND_QEMU_VXHS}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \
268
+ "$QEMU_VXHS_PROG" $QEMU_VXHS_OPTIONS "$@"
269
)
270
+ RETVAL=$?
271
+ _qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL
272
+ return $RETVAL
273
}
274
275
export QEMU=_qemu_wrapper
276
--
109
--
277
2.20.1
110
2.25.3
278
111
279
112
diff view generated by jsdifflib
Deleted patch
1
From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
2
1
3
The Valgrind uses the exported variable TMPDIR and fails if the
4
directory does not exist. Let us exclude such a test case from
5
being run under the Valgrind and notify the user of it.
6
7
Suggested-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
9
Reviewed-by: John Snow <jsnow@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
tests/qemu-iotests/051 | 4 ++++
13
1 file changed, 4 insertions(+)
14
15
diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
16
index XXXXXXX..XXXXXXX 100755
17
--- a/tests/qemu-iotests/051
18
+++ b/tests/qemu-iotests/051
19
@@ -XXX,XX +XXX,XX @@ printf %b "qemu-io $device_id \"write -P 0x33 0 4k\"\ncommit $device_id\n" |
20
$QEMU_IO -c "read -P 0x33 0 4k" "$TEST_IMG" | _filter_qemu_io
21
22
# Using snapshot=on with a non-existent TMPDIR
23
+if [ "${VALGRIND_QEMU_VM}" == "y" ]; then
24
+ _casenotrun "Valgrind needs a valid TMPDIR for itself"
25
+fi
26
+VALGRIND_QEMU_VM= \
27
TMPDIR=/nonexistent run_qemu -drive driver=null-co,snapshot=on
28
29
# Using snapshot=on together with read-only=on
30
--
31
2.20.1
32
33
diff view generated by jsdifflib