1
The following changes since commit 672f9d0df10a68a5c5f2b32cbc8284abf9f5ee18:
1
The following changes since commit 88afdc92b644120e0182c8567e1b1d236e471b12:
2
2
3
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2020-02-18 14:23:43 +0000)
3
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (2021-09-05 15:48:42 +0100)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/XanClic/qemu.git tags/pull-block-2020-02-20
7
https://gitlab.com/stefanha/qemu.git tags/block-pull-request
8
8
9
for you to fetch changes up to dff8d44c96f128480430b0c59ed8760917dbd427:
9
for you to fetch changes up to 9bd2788f49c331b02372cc257b11e4c984d39708:
10
10
11
iotests: Test snapshot -l field separation (2020-02-20 16:43:42 +0100)
11
block/nvme: Only report VFIO error on failed retry (2021-09-07 09:08:24 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block patches:
14
Pull request
15
- qemu-img convert: New --target-is-zero parameter
15
16
- qcow2: Specify non-default compression type flag
16
Userspace NVMe driver patches.
17
- optionally flat output for query-named-block-nodes
18
- some fixes
19
- pseudo-creation of images on block devices is now done by a generic
20
block layer function
21
17
22
----------------------------------------------------------------
18
----------------------------------------------------------------
23
Daniel P. Berrangé (1):
24
block: always fill entire LUKS header space with zeros
25
19
26
David Edmondson (1):
20
Philippe Mathieu-Daudé (11):
27
qemu-img: Add --target-is-zero to convert
21
block/nvme: Use safer trace format string
22
util/vfio-helpers: Let qemu_vfio_verify_mappings() use error_report()
23
util/vfio-helpers: Replace qemu_mutex_lock() calls with
24
QEMU_LOCK_GUARD
25
util/vfio-helpers: Remove unreachable code in qemu_vfio_dma_map()
26
block/nvme: Have nvme_create_queue_pair() report errors consistently
27
util/vfio-helpers: Pass Error handle to qemu_vfio_dma_map()
28
util/vfio-helpers: Extract qemu_vfio_water_mark_reached()
29
util/vfio-helpers: Use error_setg in qemu_vfio_find_[fixed/temp]_iova
30
util/vfio-helpers: Simplify qemu_vfio_dma_map() returning directly
31
util/vfio-helpers: Let qemu_vfio_do_mapping() propagate Error
32
block/nvme: Only report VFIO error on failed retry
28
33
29
Max Reitz (11):
34
include/qemu/vfio-helpers.h | 2 +-
30
iotests/147: Fix drive parameters
35
block/nvme.c | 29 +++++++----
31
iotests/279: Fix for non-qcow2 formats
36
util/vfio-helpers.c | 99 ++++++++++++++++++++-----------------
32
block/nbd: Fix hang in .bdrv_close()
37
block/trace-events | 2 +-
33
block: Generic file creation fallback
38
4 files changed, 76 insertions(+), 56 deletions(-)
34
file-posix: Drop hdev_co_create_opts()
35
iscsi: Drop iscsi_co_create_opts()
36
iotests: Add test for image creation fallback
37
qemu-img: Fix convert -n -B for backing-less targets
38
iotests: Test convert -n -B to backing-less target
39
block: Fix VM size field width in snapshot dump
40
iotests: Test snapshot -l field separation
41
42
Peter Krempa (1):
43
qapi: Allow getting flat output from 'query-named-block-nodes'
44
45
Thomas Huth (1):
46
iotests: Remove the superfluous 2nd check for the availability of
47
quorum
48
49
Vladimir Sementsov-Ogievskiy (3):
50
docs: improve qcow2 spec about extending image header
51
docs: qcow2: introduce compression type feature
52
block/backup-top: fix flags handling
53
54
block.c | 164 +++++++++++++++++++++++++++++++++----
55
block/backup-top.c | 31 ++++---
56
block/file-posix.c | 67 ---------------
57
block/iscsi.c | 56 -------------
58
block/nbd.c | 14 +++-
59
block/qapi.c | 15 +++-
60
block/qcow2.c | 11 ++-
61
blockdev.c | 8 +-
62
docs/interop/qcow2.txt | 64 ++++++++++++++-
63
docs/interop/qemu-img.rst | 9 +-
64
include/block/block.h | 2 +-
65
include/block/qapi.h | 4 +-
66
monitor/hmp-cmds.c | 2 +-
67
qapi/block-core.json | 7 +-
68
qemu-img-cmds.hx | 4 +-
69
qemu-img.c | 28 ++++++-
70
tests/qemu-iotests/122 | 14 ++++
71
tests/qemu-iotests/122.out | 5 ++
72
tests/qemu-iotests/139 | 3 -
73
tests/qemu-iotests/147 | 2 +-
74
tests/qemu-iotests/259 | 62 ++++++++++++++
75
tests/qemu-iotests/259.out | 14 ++++
76
tests/qemu-iotests/279 | 7 +-
77
tests/qemu-iotests/284 | 97 ++++++++++++++++++++++
78
tests/qemu-iotests/284.out | 62 ++++++++++++++
79
tests/qemu-iotests/286 | 76 +++++++++++++++++
80
tests/qemu-iotests/286.out | 8 ++
81
tests/qemu-iotests/group | 3 +
82
28 files changed, 659 insertions(+), 180 deletions(-)
83
create mode 100755 tests/qemu-iotests/259
84
create mode 100644 tests/qemu-iotests/259.out
85
create mode 100755 tests/qemu-iotests/284
86
create mode 100644 tests/qemu-iotests/284.out
87
create mode 100755 tests/qemu-iotests/286
88
create mode 100644 tests/qemu-iotests/286.out
89
39
90
--
40
--
91
2.24.1
41
2.31.1
92
42
93
43
44
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Make it more obvious how to add new fields to the version 3 header and
4
how to interpret them.
5
6
The specification is adjusted so that for new defined optional fields:
7
8
1. Software may support some of these optional fields and ignore the
9
others, which means that features may be backported to downstream
10
Qemu independently.
11
2. If we want to add incompatible field (or a field, for which some of
12
its values would be incompatible), it must be accompanied by
13
incompatible feature bit.
14
15
Also the concept of "default is zero" is clarified, as it's strange to
16
say that the value of the field is assumed to be zero for the software
17
version which don't know about the field at all and don't know how to
18
treat it be it zero or not.
19
20
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
21
Reviewed-by: Eric Blake <eblake@redhat.com>
22
Message-Id: <20200131142219.3264-2-vsementsov@virtuozzo.com>
23
Reviewed-by: Alberto Garcia <berto@igalia.com>
24
[mreitz: s/some its/some of its/]
25
Signed-off-by: Max Reitz <mreitz@redhat.com>
26
---
27
docs/interop/qcow2.txt | 45 +++++++++++++++++++++++++++++++++++++++---
28
1 file changed, 42 insertions(+), 3 deletions(-)
29
30
diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
31
index XXXXXXX..XXXXXXX 100644
32
--- a/docs/interop/qcow2.txt
33
+++ b/docs/interop/qcow2.txt
34
@@ -XXX,XX +XXX,XX @@ The first cluster of a qcow2 image contains the file header:
35
Offset into the image file at which the snapshot table
36
starts. Must be aligned to a cluster boundary.
37
38
-If the version is 3 or higher, the header has the following additional fields.
39
-For version 2, the values are assumed to be zero, unless specified otherwise
40
-in the description of a field.
41
+For version 2, the header is exactly 72 bytes in length, and finishes here.
42
+For version 3 or higher, the header length is at least 104 bytes, including
43
+the next fields through header_length.
44
45
72 - 79: incompatible_features
46
Bitmask of incompatible features. An implementation must
47
@@ -XXX,XX +XXX,XX @@ in the description of a field.
48
100 - 103: header_length
49
Length of the header structure in bytes. For version 2
50
images, the length is always assumed to be 72 bytes.
51
+ For version 3 it's at least 104 bytes and must be a multiple
52
+ of 8.
53
+
54
+
55
+=== Additional fields (version 3 and higher) ===
56
+
57
+In general, these fields are optional and may be safely ignored by the software,
58
+as well as filled by zeros (which is equal to field absence), if software needs
59
+to set field B, but does not care about field A which precedes B. More
60
+formally, additional fields have the following compatibility rules:
61
+
62
+1. If the value of the additional field must not be ignored for correct
63
+handling of the file, it will be accompanied by a corresponding incompatible
64
+feature bit.
65
+
66
+2. If there are no unrecognized incompatible feature bits set, an unknown
67
+additional field may be safely ignored other than preserving its value when
68
+rewriting the image header.
69
+
70
+3. An explicit value of 0 will have the same behavior as when the field is not
71
+present*, if not altered by a specific incompatible bit.
72
+
73
+*. A field is considered not present when header_length is less than or equal
74
+to the field's offset. Also, all additional fields are not present for
75
+version 2.
76
+
77
+ < ... No additional fields in the header currently ... >
78
+
79
+
80
+=== Header padding ===
81
+
82
+@header_length must be a multiple of 8, which means that if the end of the last
83
+additional field is not aligned, some padding is needed. This padding must be
84
+zeroed, so that if some existing (or future) additional field will fall into
85
+the padding, it will be interpreted accordingly to point [3.] of the previous
86
+paragraph, i.e. in the same manner as when this field is not present.
87
+
88
+
89
+=== Header extensions ===
90
91
Directly after the image header, optional sections called header extensions can
92
be stored. Each extension has a structure like the following:
93
--
94
2.24.1
95
96
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
The patch adds a new additional field to the qcow2 header: compression_type,
4
which specifies compression type. If field is absent or zero, default
5
compression type is set: ZLIB, which corresponds to current behavior.
6
7
New compression type (ZSTD) is to be added in further commit.
8
9
Suggested-by: Denis Plotnikov <dplotnikov@virtuozzo.com>
10
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Message-Id: <20200131142219.3264-3-vsementsov@virtuozzo.com>
12
[mreitz: s/Bits 3-63: Reserved/Bits 4-63: Reserved/]
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
15
docs/interop/qcow2.txt | 21 +++++++++++++++++++--
16
1 file changed, 19 insertions(+), 2 deletions(-)
17
18
diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
19
index XXXXXXX..XXXXXXX 100644
20
--- a/docs/interop/qcow2.txt
21
+++ b/docs/interop/qcow2.txt
22
@@ -XXX,XX +XXX,XX @@ the next fields through header_length.
23
An External Data File Name header extension may
24
be present if this bit is set.
25
26
- Bits 3-63: Reserved (set to 0)
27
+ Bit 3: Compression type bit. If this bit is set,
28
+ a non-default compression is used for compressed
29
+ clusters. The compression_type field must be
30
+ present and not zero.
31
+
32
+ Bits 4-63: Reserved (set to 0)
33
34
80 - 87: compatible_features
35
Bitmask of compatible features. An implementation can
36
@@ -XXX,XX +XXX,XX @@ present*, if not altered by a specific incompatible bit.
37
to the field's offset. Also, all additional fields are not present for
38
version 2.
39
40
- < ... No additional fields in the header currently ... >
41
+ 104: compression_type
42
+
43
+ Defines the compression method used for compressed clusters.
44
+ All compressed clusters in an image use the same compression
45
+ type.
46
+
47
+ If the incompatible bit "Compression type" is set: the field
48
+ must be present and non-zero (which means non-zlib
49
+ compression type). Otherwise, this field must not be present
50
+ or must be zero (which means zlib).
51
+
52
+ Available compression type values:
53
+ 0: zlib <https://www.zlib.net/>
54
55
56
=== Header padding ===
57
--
58
2.24.1
59
60
diff view generated by jsdifflib
Deleted patch
1
From: Thomas Huth <thuth@redhat.com>
2
1
3
Commit d9df28e7b07 ("iotests: check whitelisted formats") added the
4
modern @iotests.skip_if_unsupported() to the functions in this test,
5
so we don't need the old explicit test here anymore.
6
7
Signed-off-by: Thomas Huth <thuth@redhat.com>
8
Message-Id: <20200129141751.32652-1-thuth@redhat.com>
9
Reviewed-by: Alberto Garcia <berto@igalia.com>
10
Reviewed-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
11
Tested-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
14
tests/qemu-iotests/139 | 3 ---
15
1 file changed, 3 deletions(-)
16
17
diff --git a/tests/qemu-iotests/139 b/tests/qemu-iotests/139
18
index XXXXXXX..XXXXXXX 100755
19
--- a/tests/qemu-iotests/139
20
+++ b/tests/qemu-iotests/139
21
@@ -XXX,XX +XXX,XX @@ class TestBlockdevDel(iotests.QMPTestCase):
22
23
@iotests.skip_if_unsupported(['quorum'])
24
def testQuorum(self):
25
- if not iotests.supports_quorum():
26
- return
27
-
28
self.addQuorum('quorum0', 'node0', 'node1')
29
# We cannot remove the children of a Quorum device
30
self.delBlockDriverState('node0', expect_error = True)
31
--
32
2.24.1
33
34
diff view generated by jsdifflib
1
s.target_has_backing does not reflect whether the target BDS has a
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
backing file; it only tells whether we should use a backing file during
3
conversion (specified by -B).
4
2
5
As such, if you use convert -n, the target does not necessarily actually
3
Fix when building with -Wshorten-64-to-32:
6
have a backing file, and then dereferencing out_bs->backing fails here.
7
4
8
When converting to an existing file, we should set
5
warning: implicit conversion loses integer precision: 'unsigned long' to 'int' [-Wshorten-64-to-32]
9
target_backing_sectors to a negative value, because first, as the
10
comment explains, this value is only used for optimization, so it is
11
always fine to do that.
12
6
13
Second, we use this value to determine where the target must be
7
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
14
initialized to zeroes (overlays are initialized to zero after the end of
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
their backing file). When converting to an existing file, we cannot
9
Message-id: 20210902070025.197072-2-philmd@redhat.com
16
assume that to be true.
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
17
18
Cc: qemu-stable@nongnu.org
19
Fixes: 351c8efff9ad809c822d55620df54d575d536f68
20
("qemu-img: Special post-backing convert handling")
21
Signed-off-by: Max Reitz <mreitz@redhat.com>
22
Message-Id: <20200121155915.98232-2-mreitz@redhat.com>
23
Reviewed-by: John Snow <jsnow@redhat.com>
24
Signed-off-by: Max Reitz <mreitz@redhat.com>
25
---
11
---
26
qemu-img.c | 2 +-
12
block/trace-events | 2 +-
27
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
28
14
29
diff --git a/qemu-img.c b/qemu-img.c
15
diff --git a/block/trace-events b/block/trace-events
30
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
31
--- a/qemu-img.c
17
--- a/block/trace-events
32
+++ b/qemu-img.c
18
+++ b/block/trace-events
33
@@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv)
19
@@ -XXX,XX +XXX,XX @@ nvme_dsm(void *s, uint64_t offset, uint64_t bytes) "s %p offset 0x%"PRIx64" byte
34
}
20
nvme_dsm_done(void *s, uint64_t offset, uint64_t bytes, int ret) "s %p offset 0x%"PRIx64" bytes %"PRId64" ret %d"
35
}
21
nvme_dma_map_flush(void *s) "s %p"
36
22
nvme_free_req_queue_wait(void *s, unsigned q_index) "s %p q #%u"
37
- if (s.target_has_backing) {
23
-nvme_create_queue_pair(unsigned q_index, void *q, unsigned size, void *aio_context, int fd) "index %u q %p size %u aioctx %p fd %d"
38
+ if (s.target_has_backing && s.target_is_new) {
24
+nvme_create_queue_pair(unsigned q_index, void *q, size_t size, void *aio_context, int fd) "index %u q %p size %zu aioctx %p fd %d"
39
/* Errors are treated as "backing length unknown" (which means
25
nvme_free_queue_pair(unsigned q_index, void *q) "index %u q %p"
40
* s.target_backing_sectors has to be negative, which it will
26
nvme_cmd_map_qiov(void *s, void *cmd, void *req, void *qiov, int entries) "s %p cmd %p req %p qiov %p entries %d"
41
* be automatically). The backing file length is used only
27
nvme_cmd_map_qiov_pages(void *s, int i, uint64_t page) "s %p page[%d] 0x%"PRIx64
42
--
28
--
43
2.24.1
29
2.31.1
44
30
45
31
diff view generated by jsdifflib
1
When printing the snapshot list (e.g. with qemu-img snapshot -l), the VM
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
size field is only seven characters wide. As of de38b5005e9, this is
3
not necessarily sufficient: We generally print three digits, and this
4
may require a decimal point. Also, the unit field grew from something
5
as plain as "M" to " MiB". This means that number and unit may take up
6
eight characters in total; but we also want spaces in front.
7
2
8
Considering previously the maximum width was four characters and the
3
Instead of displaying the error on stderr, use error_report()
9
field width was chosen to be three characters wider, let us adjust the
4
which also report to the monitor.
10
field width to be eleven now.
11
5
12
Fixes: de38b5005e946aa3714963ea4c501e279e7d3666
6
Reviewed-by: Fam Zheng <fam@euphon.net>
13
Buglink: https://bugs.launchpad.net/qemu/+bug/1859989
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
15
Message-Id: <20200117105859.241818-2-mreitz@redhat.com>
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
16
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Message-id: 20210902070025.197072-3-philmd@redhat.com
17
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
18
---
12
---
19
block/qapi.c | 4 ++--
13
util/vfio-helpers.c | 4 ++--
20
1 file changed, 2 insertions(+), 2 deletions(-)
14
1 file changed, 2 insertions(+), 2 deletions(-)
21
15
22
diff --git a/block/qapi.c b/block/qapi.c
16
diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c
23
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
24
--- a/block/qapi.c
18
--- a/util/vfio-helpers.c
25
+++ b/block/qapi.c
19
+++ b/util/vfio-helpers.c
26
@@ -XXX,XX +XXX,XX @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
20
@@ -XXX,XX +XXX,XX @@ static bool qemu_vfio_verify_mappings(QEMUVFIOState *s)
27
char *sizing = NULL;
21
if (QEMU_VFIO_DEBUG) {
28
22
for (i = 0; i < s->nr_mappings - 1; ++i) {
29
if (!sn) {
23
if (!(s->mappings[i].host < s->mappings[i + 1].host)) {
30
- qemu_printf("%-10s%-20s%7s%20s%15s",
24
- fprintf(stderr, "item %d not sorted!\n", i);
31
+ qemu_printf("%-10s%-20s%11s%20s%15s",
25
+ error_report("item %d not sorted!", i);
32
"ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
26
qemu_vfio_dump_mappings(s);
33
} else {
27
return false;
34
ti = sn->date_sec;
28
}
35
@@ -XXX,XX +XXX,XX @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
29
if (!(s->mappings[i].host + s->mappings[i].size <=
36
(int)(secs % 60),
30
s->mappings[i + 1].host)) {
37
(int)((sn->vm_clock_nsec / 1000000) % 1000));
31
- fprintf(stderr, "item %d overlap with next!\n", i);
38
sizing = size_to_str(sn->vm_state_size);
32
+ error_report("item %d overlap with next!", i);
39
- qemu_printf("%-10s%-20s%7s%20s%15s",
33
qemu_vfio_dump_mappings(s);
40
+ qemu_printf("%-10s%-20s%11s%20s%15s",
34
return false;
41
sn->id_str, sn->name,
35
}
42
sizing,
43
date_buf,
44
--
36
--
45
2.24.1
37
2.31.1
46
38
47
39
diff view generated by jsdifflib
1
If a protocol driver does not support image creation, we can see whether
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
maybe the file exists already. If so, just truncating it will be
3
sufficient.
4
2
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
Simplify qemu_vfio_dma_[un]map() handlers by replacing a pair of
6
Message-Id: <20200122164532.178040-3-mreitz@redhat.com>
4
qemu_mutex_lock/qemu_mutex_unlock calls by the WITH_QEMU_LOCK_GUARD
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
macro.
6
7
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20210902070025.197072-4-philmd@redhat.com
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
---
11
---
9
block.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
12
util/vfio-helpers.c | 9 +++------
10
1 file changed, 147 insertions(+), 12 deletions(-)
13
1 file changed, 3 insertions(+), 6 deletions(-)
11
14
12
diff --git a/block.c b/block.c
15
diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/block.c
17
--- a/util/vfio-helpers.c
15
+++ b/block.c
18
+++ b/util/vfio-helpers.c
16
@@ -XXX,XX +XXX,XX @@ out:
19
@@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size,
20
assert(QEMU_PTR_IS_ALIGNED(host, qemu_real_host_page_size));
21
assert(QEMU_IS_ALIGNED(size, qemu_real_host_page_size));
22
trace_qemu_vfio_dma_map(s, host, size, temporary, iova);
23
- qemu_mutex_lock(&s->lock);
24
+ QEMU_LOCK_GUARD(&s->lock);
25
mapping = qemu_vfio_find_mapping(s, host, &index);
26
if (mapping) {
27
iova0 = mapping->iova + ((uint8_t *)host - (uint8_t *)mapping->host);
28
@@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size,
29
*iova = iova0;
30
}
31
out:
32
- qemu_mutex_unlock(&s->lock);
17
return ret;
33
return ret;
18
}
34
}
19
35
20
-int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp)
36
@@ -XXX,XX +XXX,XX @@ void qemu_vfio_dma_unmap(QEMUVFIOState *s, void *host)
21
+/**
22
+ * Helper function for bdrv_create_file_fallback(): Resize @blk to at
23
+ * least the given @minimum_size.
24
+ *
25
+ * On success, return @blk's actual length.
26
+ * Otherwise, return -errno.
27
+ */
28
+static int64_t create_file_fallback_truncate(BlockBackend *blk,
29
+ int64_t minimum_size, Error **errp)
30
{
31
- BlockDriver *drv;
32
+ Error *local_err = NULL;
33
+ int64_t size;
34
+ int ret;
35
+
36
+ ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, &local_err);
37
+ if (ret < 0 && ret != -ENOTSUP) {
38
+ error_propagate(errp, local_err);
39
+ return ret;
40
+ }
41
+
42
+ size = blk_getlength(blk);
43
+ if (size < 0) {
44
+ error_free(local_err);
45
+ error_setg_errno(errp, -size,
46
+ "Failed to inquire the new image file's length");
47
+ return size;
48
+ }
49
+
50
+ if (size < minimum_size) {
51
+ /* Need to grow the image, but we failed to do that */
52
+ error_propagate(errp, local_err);
53
+ return -ENOTSUP;
54
+ }
55
+
56
+ error_free(local_err);
57
+ local_err = NULL;
58
+
59
+ return size;
60
+}
61
+
62
+/**
63
+ * Helper function for bdrv_create_file_fallback(): Zero the first
64
+ * sector to remove any potentially pre-existing image header.
65
+ */
66
+static int create_file_fallback_zero_first_sector(BlockBackend *blk,
67
+ int64_t current_size,
68
+ Error **errp)
69
+{
70
+ int64_t bytes_to_clear;
71
+ int ret;
72
+
73
+ bytes_to_clear = MIN(current_size, BDRV_SECTOR_SIZE);
74
+ if (bytes_to_clear) {
75
+ ret = blk_pwrite_zeroes(blk, 0, bytes_to_clear, BDRV_REQ_MAY_UNMAP);
76
+ if (ret < 0) {
77
+ error_setg_errno(errp, -ret,
78
+ "Failed to clear the new image's first sector");
79
+ return ret;
80
+ }
81
+ }
82
+
83
+ return 0;
84
+}
85
+
86
+static int bdrv_create_file_fallback(const char *filename, BlockDriver *drv,
87
+ QemuOpts *opts, Error **errp)
88
+{
89
+ BlockBackend *blk;
90
+ QDict *options = qdict_new();
91
+ int64_t size = 0;
92
+ char *buf = NULL;
93
+ PreallocMode prealloc;
94
Error *local_err = NULL;
95
int ret;
96
97
+ size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
98
+ buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
99
+ prealloc = qapi_enum_parse(&PreallocMode_lookup, buf,
100
+ PREALLOC_MODE_OFF, &local_err);
101
+ g_free(buf);
102
+ if (local_err) {
103
+ error_propagate(errp, local_err);
104
+ return -EINVAL;
105
+ }
106
+
107
+ if (prealloc != PREALLOC_MODE_OFF) {
108
+ error_setg(errp, "Unsupported preallocation mode '%s'",
109
+ PreallocMode_str(prealloc));
110
+ return -ENOTSUP;
111
+ }
112
+
113
+ qdict_put_str(options, "driver", drv->format_name);
114
+
115
+ blk = blk_new_open(filename, NULL, options,
116
+ BDRV_O_RDWR | BDRV_O_RESIZE, errp);
117
+ if (!blk) {
118
+ error_prepend(errp, "Protocol driver '%s' does not support image "
119
+ "creation, and opening the image failed: ",
120
+ drv->format_name);
121
+ return -EINVAL;
122
+ }
123
+
124
+ size = create_file_fallback_truncate(blk, size, errp);
125
+ if (size < 0) {
126
+ ret = size;
127
+ goto out;
128
+ }
129
+
130
+ ret = create_file_fallback_zero_first_sector(blk, size, errp);
131
+ if (ret < 0) {
132
+ goto out;
133
+ }
134
+
135
+ ret = 0;
136
+out:
137
+ blk_unref(blk);
138
+ return ret;
139
+}
140
+
141
+int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp)
142
+{
143
+ BlockDriver *drv;
144
+
145
drv = bdrv_find_protocol(filename, true, errp);
146
if (drv == NULL) {
147
return -ENOENT;
148
}
37
}
149
38
150
- ret = bdrv_create(drv, filename, opts, &local_err);
39
trace_qemu_vfio_dma_unmap(s, host);
151
- error_propagate(errp, local_err);
40
- qemu_mutex_lock(&s->lock);
152
- return ret;
41
+ QEMU_LOCK_GUARD(&s->lock);
153
+ if (drv->bdrv_co_create_opts) {
42
m = qemu_vfio_find_mapping(s, host, &index);
154
+ return bdrv_create(drv, filename, opts, errp);
43
if (!m) {
155
+ } else {
44
- goto out;
156
+ return bdrv_create_file_fallback(filename, drv, opts, errp);
45
+ return;
157
+ }
46
}
47
qemu_vfio_undo_mapping(s, m, NULL);
48
-out:
49
- qemu_mutex_unlock(&s->lock);
158
}
50
}
159
51
160
/**
52
static void qemu_vfio_reset(QEMUVFIOState *s)
161
@@ -XXX,XX +XXX,XX @@ QemuOptsList bdrv_runtime_opts = {
162
},
163
};
164
165
+static QemuOptsList fallback_create_opts = {
166
+ .name = "fallback-create-opts",
167
+ .head = QTAILQ_HEAD_INITIALIZER(fallback_create_opts.head),
168
+ .desc = {
169
+ {
170
+ .name = BLOCK_OPT_SIZE,
171
+ .type = QEMU_OPT_SIZE,
172
+ .help = "Virtual disk size"
173
+ },
174
+ {
175
+ .name = BLOCK_OPT_PREALLOC,
176
+ .type = QEMU_OPT_STRING,
177
+ .help = "Preallocation mode (allowed values: off)"
178
+ },
179
+ { /* end of list */ }
180
+ }
181
+};
182
+
183
/*
184
* Common part for opening disk images and files
185
*
186
@@ -XXX,XX +XXX,XX @@ void bdrv_img_create(const char *filename, const char *fmt,
187
return;
188
}
189
190
- if (!proto_drv->create_opts) {
191
- error_setg(errp, "Protocol driver '%s' does not support image creation",
192
- proto_drv->format_name);
193
- return;
194
- }
195
-
196
/* Create parameter list */
197
create_opts = qemu_opts_append(create_opts, drv->create_opts);
198
- create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
199
+ if (proto_drv->create_opts) {
200
+ create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
201
+ } else {
202
+ create_opts = qemu_opts_append(create_opts, &fallback_create_opts);
203
+ }
204
205
opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
206
207
--
53
--
208
2.24.1
54
2.31.1
209
55
210
56
diff view generated by jsdifflib
1
Add a test that all fields in "qemu-img snapshot -l"s output are
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
separated by spaces.
3
2
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
qemu_vfio_add_mapping() returns a pointer to an indexed entry
5
Message-Id: <20200117105859.241818-3-mreitz@redhat.com>
4
in pre-allocated QEMUVFIOState::mappings[], thus can not be NULL.
6
Reviewed-by: Eric Blake <eblake@redhat.com>
5
Remove the pointless check.
7
[mreitz: Renamed test from 284 to 286]
6
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20210902070025.197072-5-philmd@redhat.com
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
---
11
---
10
tests/qemu-iotests/286 | 76 ++++++++++++++++++++++++++++++++++++++
12
util/vfio-helpers.c | 4 ----
11
tests/qemu-iotests/286.out | 8 ++++
13
1 file changed, 4 deletions(-)
12
tests/qemu-iotests/group | 1 +
13
3 files changed, 85 insertions(+)
14
create mode 100755 tests/qemu-iotests/286
15
create mode 100644 tests/qemu-iotests/286.out
16
14
17
diff --git a/tests/qemu-iotests/286 b/tests/qemu-iotests/286
15
diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c
18
new file mode 100755
19
index XXXXXXX..XXXXXXX
20
--- /dev/null
21
+++ b/tests/qemu-iotests/286
22
@@ -XXX,XX +XXX,XX @@
23
+#!/usr/bin/env bash
24
+#
25
+# Test qemu-img snapshot -l
26
+#
27
+# Copyright (C) 2019 Red Hat, Inc.
28
+#
29
+# This program is free software; you can redistribute it and/or modify
30
+# it under the terms of the GNU General Public License as published by
31
+# the Free Software Foundation; either version 2 of the License, or
32
+# (at your option) any later version.
33
+#
34
+# This program is distributed in the hope that it will be useful,
35
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
36
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37
+# GNU General Public License for more details.
38
+#
39
+# You should have received a copy of the GNU General Public License
40
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
41
+#
42
+
43
+seq=$(basename "$0")
44
+echo "QA output created by $seq"
45
+
46
+status=1    # failure is the default!
47
+
48
+_cleanup()
49
+{
50
+ _cleanup_test_img
51
+}
52
+trap "_cleanup; exit \$status" 0 1 2 3 15
53
+
54
+# get standard environment, filters and checks
55
+. ./common.rc
56
+. ./common.filter
57
+. ./common.qemu
58
+
59
+_supported_fmt qcow2
60
+_supported_proto file
61
+# Internal snapshots are (currently) impossible with refcount_bits=1,
62
+# and generally impossible with external data files
63
+_unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
64
+
65
+_make_test_img 64M
66
+
67
+# Should be so long as to take up the whole field width
68
+sn_name=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
69
+
70
+# More memory will give us a larger VM state, i.e. one above 1 MB.
71
+# This way, we get a number with a decimal point.
72
+qemu_comm_method=monitor _launch_qemu -m 512 "$TEST_IMG"
73
+
74
+_send_qemu_cmd $QEMU_HANDLE "savevm $sn_name" '(qemu)'
75
+_send_qemu_cmd $QEMU_HANDLE 'quit' '(qemu)'
76
+wait=yes _cleanup_qemu
77
+
78
+# Check that all fields are separated by spaces.
79
+# We first collapse all space sequences into one space each;
80
+# then we turn every space-separated field into a '.';
81
+# and finally, we name the '.'s so the output is not just a confusing
82
+# sequence of dots.
83
+
84
+echo 'Output structure:'
85
+$QEMU_IMG snapshot -l "$TEST_IMG" | tail -n 1 | tr -s ' ' \
86
+ | sed -e 's/\S\+/./g' \
87
+ | sed -e 's/\./(snapshot ID)/' \
88
+ -e 's/\./(snapshot name)/' \
89
+ -e 's/\./(VM state size value)/' \
90
+ -e 's/\./(VM state size unit)/' \
91
+ -e 's/\./(snapshot date)/' \
92
+ -e 's/\./(snapshot time)/' \
93
+ -e 's/\./(VM clock)/'
94
+
95
+# success, all done
96
+echo "*** done"
97
+rm -f $seq.full
98
+status=0
99
diff --git a/tests/qemu-iotests/286.out b/tests/qemu-iotests/286.out
100
new file mode 100644
101
index XXXXXXX..XXXXXXX
102
--- /dev/null
103
+++ b/tests/qemu-iotests/286.out
104
@@ -XXX,XX +XXX,XX @@
105
+QA output created by 286
106
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
107
+QEMU X.Y.Z monitor - type 'help' for more information
108
+(qemu) savevm abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
109
+(qemu) quit
110
+Output structure:
111
+(snapshot ID) (snapshot name) (VM state size value) (VM state size unit) (snapshot date) (snapshot time) (VM clock)
112
+*** done
113
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
114
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
115
--- a/tests/qemu-iotests/group
17
--- a/util/vfio-helpers.c
116
+++ b/tests/qemu-iotests/group
18
+++ b/util/vfio-helpers.c
117
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size,
118
281 rw quick
20
}
119
283 auto quick
21
120
284 rw
22
mapping = qemu_vfio_add_mapping(s, host, size, index + 1, iova0);
121
+286 rw quick
23
- if (!mapping) {
24
- ret = -ENOMEM;
25
- goto out;
26
- }
27
assert(qemu_vfio_verify_mappings(s));
28
ret = qemu_vfio_do_mapping(s, host, size, iova0);
29
if (ret) {
122
--
30
--
123
2.24.1
31
2.31.1
124
32
125
33
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
backup-top "supports" write-unchanged, by skipping CBW operation in
3
nvme_create_queue_pair() does not return a boolean value (indicating
4
backup_top_co_pwritev. But it forgets to do the same in
4
eventual error) but a pointer, and is inconsistent in how it fills the
5
backup_top_co_pwrite_zeroes, as well as declare support for
5
error handler. To fulfill callers expectations, always set an error
6
BDRV_REQ_WRITE_UNCHANGED.
6
message on failure.
7
7
8
Fix this, and, while being here, declare also support for flags
8
Reported-by: Auger Eric <eric.auger@redhat.com>
9
supported by source child.
9
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
10
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Message-id: 20210902070025.197072-6-philmd@redhat.com
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
14
block/nvme.c | 3 +++
15
1 file changed, 3 insertions(+)
10
16
11
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
17
diff --git a/block/nvme.c b/block/nvme.c
12
Message-Id: <20200207161231.32707-1-vsementsov@virtuozzo.com>
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
15
block/backup-top.c | 31 ++++++++++++++++++++-----------
16
1 file changed, 20 insertions(+), 11 deletions(-)
17
18
diff --git a/block/backup-top.c b/block/backup-top.c
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/block/backup-top.c
19
--- a/block/nvme.c
21
+++ b/block/backup-top.c
20
+++ b/block/nvme.c
22
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int backup_top_co_preadv(
21
@@ -XXX,XX +XXX,XX @@ static NVMeQueuePair *nvme_create_queue_pair(BDRVNVMeState *s,
23
}
22
24
23
q = g_try_new0(NVMeQueuePair, 1);
25
static coroutine_fn int backup_top_cbw(BlockDriverState *bs, uint64_t offset,
24
if (!q) {
26
- uint64_t bytes)
25
+ error_setg(errp, "Cannot allocate queue pair");
27
+ uint64_t bytes, BdrvRequestFlags flags)
28
{
29
BDRVBackupTopState *s = bs->opaque;
30
- uint64_t end = QEMU_ALIGN_UP(offset + bytes, s->bcs->cluster_size);
31
- uint64_t off = QEMU_ALIGN_DOWN(offset, s->bcs->cluster_size);
32
+ uint64_t off, end;
33
+
34
+ if (flags & BDRV_REQ_WRITE_UNCHANGED) {
35
+ return 0;
36
+ }
37
+
38
+ off = QEMU_ALIGN_DOWN(offset, s->bcs->cluster_size);
39
+ end = QEMU_ALIGN_UP(offset + bytes, s->bcs->cluster_size);
40
41
return block_copy(s->bcs, off, end - off, NULL);
42
}
43
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int backup_top_cbw(BlockDriverState *bs, uint64_t offset,
44
static int coroutine_fn backup_top_co_pdiscard(BlockDriverState *bs,
45
int64_t offset, int bytes)
46
{
47
- int ret = backup_top_cbw(bs, offset, bytes);
48
+ int ret = backup_top_cbw(bs, offset, bytes, 0);
49
if (ret < 0) {
50
return ret;
51
}
52
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_top_co_pdiscard(BlockDriverState *bs,
53
static int coroutine_fn backup_top_co_pwrite_zeroes(BlockDriverState *bs,
54
int64_t offset, int bytes, BdrvRequestFlags flags)
55
{
56
- int ret = backup_top_cbw(bs, offset, bytes);
57
+ int ret = backup_top_cbw(bs, offset, bytes, flags);
58
if (ret < 0) {
59
return ret;
60
}
61
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int backup_top_co_pwritev(BlockDriverState *bs,
62
uint64_t bytes,
63
QEMUIOVector *qiov, int flags)
64
{
65
- if (!(flags & BDRV_REQ_WRITE_UNCHANGED)) {
66
- int ret = backup_top_cbw(bs, offset, bytes);
67
- if (ret < 0) {
68
- return ret;
69
- }
70
+ int ret = backup_top_cbw(bs, offset, bytes, flags);
71
+ if (ret < 0) {
72
+ return ret;
73
}
74
75
return bdrv_co_pwritev(bs->backing, offset, bytes, qiov, flags);
76
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source,
77
return NULL;
26
return NULL;
78
}
27
}
79
28
trace_nvme_create_queue_pair(idx, q, size, aio_context,
80
- top->total_sectors = source->total_sectors;
29
@@ -XXX,XX +XXX,XX @@ static NVMeQueuePair *nvme_create_queue_pair(BDRVNVMeState *s,
81
state = top->opaque;
30
qemu_real_host_page_size);
82
+ top->total_sectors = source->total_sectors;
31
q->prp_list_pages = qemu_try_memalign(qemu_real_host_page_size, bytes);
83
+ top->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
32
if (!q->prp_list_pages) {
84
+ (BDRV_REQ_FUA & source->supported_write_flags);
33
+ error_setg(errp, "Cannot allocate PRP page list");
85
+ top->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
34
goto fail;
86
+ ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
35
}
87
+ source->supported_zero_flags);
36
memset(q->prp_list_pages, 0, bytes);
88
37
@@ -XXX,XX +XXX,XX @@ static NVMeQueuePair *nvme_create_queue_pair(BDRVNVMeState *s,
89
bdrv_ref(target);
38
r = qemu_vfio_dma_map(s->vfio, q->prp_list_pages, bytes,
90
state->target = bdrv_attach_child(top, target, "target", &child_file, errp);
39
false, &prp_list_iova);
40
if (r) {
41
+ error_setg_errno(errp, -r, "Cannot map buffer for DMA");
42
goto fail;
43
}
44
q->free_req_head = -1;
91
--
45
--
92
2.24.1
46
2.31.1
93
47
94
48
diff view generated by jsdifflib
1
From: Peter Krempa <pkrempa@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
When a management application manages node names there's no reason to
3
Currently qemu_vfio_dma_map() displays errors on stderr.
4
recurse into backing images in the output of query-named-block-nodes.
4
When using management interface, this information is simply
5
lost. Pass qemu_vfio_dma_map() an Error** handle so it can
6
propagate the error to callers.
5
7
6
Add a parameter to the command which will return just the top level
8
Reviewed-by: Fam Zheng <fam@euphon.net>
7
structs.
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
11
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Message-id: 20210902070025.197072-7-philmd@redhat.com
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
---
15
include/qemu/vfio-helpers.h | 2 +-
16
block/nvme.c | 22 +++++++++++-----------
17
util/vfio-helpers.c | 10 ++++++----
18
3 files changed, 18 insertions(+), 16 deletions(-)
8
19
9
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
20
diff --git a/include/qemu/vfio-helpers.h b/include/qemu/vfio-helpers.h
10
Message-Id: <4470f8c779abc404dcf65e375db195cd91a80651.1579509782.git.pkrempa@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
12
[mreitz: Fixed coding style]
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
15
block.c | 5 +++--
16
block/qapi.c | 11 +++++++++--
17
blockdev.c | 8 ++++++--
18
include/block/block.h | 2 +-
19
include/block/qapi.h | 4 +++-
20
monitor/hmp-cmds.c | 2 +-
21
qapi/block-core.json | 7 ++++++-
22
7 files changed, 29 insertions(+), 10 deletions(-)
23
24
diff --git a/block.c b/block.c
25
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
26
--- a/block.c
22
--- a/include/qemu/vfio-helpers.h
27
+++ b/block.c
23
+++ b/include/qemu/vfio-helpers.h
28
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_find_node(const char *node_name)
24
@@ -XXX,XX +XXX,XX @@ typedef struct QEMUVFIOState QEMUVFIOState;
25
QEMUVFIOState *qemu_vfio_open_pci(const char *device, Error **errp);
26
void qemu_vfio_close(QEMUVFIOState *s);
27
int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size,
28
- bool temporary, uint64_t *iova_list);
29
+ bool temporary, uint64_t *iova_list, Error **errp);
30
int qemu_vfio_dma_reset_temporary(QEMUVFIOState *s);
31
void qemu_vfio_dma_unmap(QEMUVFIOState *s, void *host);
32
void *qemu_vfio_pci_map_bar(QEMUVFIOState *s, int index,
33
diff --git a/block/nvme.c b/block/nvme.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/block/nvme.c
36
+++ b/block/nvme.c
37
@@ -XXX,XX +XXX,XX @@ static bool nvme_init_queue(BDRVNVMeState *s, NVMeQueue *q,
38
return false;
39
}
40
memset(q->queue, 0, bytes);
41
- r = qemu_vfio_dma_map(s->vfio, q->queue, bytes, false, &q->iova);
42
+ r = qemu_vfio_dma_map(s->vfio, q->queue, bytes, false, &q->iova, errp);
43
if (r) {
44
- error_setg(errp, "Cannot map queue");
45
- return false;
46
+ error_prepend(errp, "Cannot map queue: ");
47
}
48
- return true;
49
+ return r == 0;
29
}
50
}
30
51
31
/* Put this QMP function here so it can access the static graph_bdrv_states. */
52
static void nvme_free_queue_pair(NVMeQueuePair *q)
32
-BlockDeviceInfoList *bdrv_named_nodes_list(Error **errp)
53
@@ -XXX,XX +XXX,XX @@ static NVMeQueuePair *nvme_create_queue_pair(BDRVNVMeState *s,
33
+BlockDeviceInfoList *bdrv_named_nodes_list(bool flat,
54
qemu_co_queue_init(&q->free_req_queue);
34
+ Error **errp)
55
q->completion_bh = aio_bh_new(aio_context, nvme_process_completion_bh, q);
56
r = qemu_vfio_dma_map(s->vfio, q->prp_list_pages, bytes,
57
- false, &prp_list_iova);
58
+ false, &prp_list_iova, errp);
59
if (r) {
60
- error_setg_errno(errp, -r, "Cannot map buffer for DMA");
61
+ error_prepend(errp, "Cannot map buffer for DMA: ");
62
goto fail;
63
}
64
q->free_req_head = -1;
65
@@ -XXX,XX +XXX,XX @@ static bool nvme_identify(BlockDriverState *bs, int namespace, Error **errp)
66
error_setg(errp, "Cannot allocate buffer for identify response");
67
goto out;
68
}
69
- r = qemu_vfio_dma_map(s->vfio, id, id_size, true, &iova);
70
+ r = qemu_vfio_dma_map(s->vfio, id, id_size, true, &iova, errp);
71
if (r) {
72
- error_setg(errp, "Cannot map buffer for DMA");
73
+ error_prepend(errp, "Cannot map buffer for DMA: ");
74
goto out;
75
}
76
77
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int nvme_cmd_map_qiov(BlockDriverState *bs, NvmeCmd *cmd,
78
try_map:
79
r = qemu_vfio_dma_map(s->vfio,
80
qiov->iov[i].iov_base,
81
- len, true, &iova);
82
+ len, true, &iova, NULL);
83
if (r == -ENOSPC) {
84
/*
85
* In addition to the -ENOMEM error, the VFIO_IOMMU_MAP_DMA
86
@@ -XXX,XX +XXX,XX @@ static void nvme_aio_unplug(BlockDriverState *bs)
87
static void nvme_register_buf(BlockDriverState *bs, void *host, size_t size)
35
{
88
{
36
BlockDeviceInfoList *list, *entry;
89
int ret;
37
BlockDriverState *bs;
90
+ Error *local_err = NULL;
38
91
BDRVNVMeState *s = bs->opaque;
39
list = NULL;
92
40
QTAILQ_FOREACH(bs, &graph_bdrv_states, node_list) {
93
- ret = qemu_vfio_dma_map(s->vfio, host, size, false, NULL);
41
- BlockDeviceInfo *info = bdrv_block_device_info(NULL, bs, errp);
94
+ ret = qemu_vfio_dma_map(s->vfio, host, size, false, NULL, &local_err);
42
+ BlockDeviceInfo *info = bdrv_block_device_info(NULL, bs, flat, errp);
95
if (ret) {
43
if (!info) {
96
/* FIXME: we may run out of IOVA addresses after repeated
44
qapi_free_BlockDeviceInfoList(list);
97
* bdrv_register_buf/bdrv_unregister_buf, because nvme_vfio_dma_unmap
45
return NULL;
98
* doesn't reclaim addresses for fixed mappings. */
46
diff --git a/block/qapi.c b/block/qapi.c
99
- error_report("nvme_register_buf failed: %s", strerror(-ret));
100
+ error_reportf_err(local_err, "nvme_register_buf failed: ");
101
}
102
}
103
104
diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c
47
index XXXXXXX..XXXXXXX 100644
105
index XXXXXXX..XXXXXXX 100644
48
--- a/block/qapi.c
106
--- a/util/vfio-helpers.c
49
+++ b/block/qapi.c
107
+++ b/util/vfio-helpers.c
50
@@ -XXX,XX +XXX,XX @@
108
@@ -XXX,XX +XXX,XX @@ static void qemu_vfio_ram_block_added(RAMBlockNotifier *n, void *host,
51
#include "qemu/cutils.h"
109
size_t size, size_t max_size)
52
53
BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
54
- BlockDriverState *bs, Error **errp)
55
+ BlockDriverState *bs,
56
+ bool flat,
57
+ Error **errp)
58
{
110
{
59
ImageInfo **p_image_info;
111
QEMUVFIOState *s = container_of(n, QEMUVFIOState, ram_notifier);
60
BlockDriverState *bs0;
112
+ Error *local_err = NULL;
61
@@ -XXX,XX +XXX,XX @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
113
int ret;
62
return NULL;
114
63
}
115
trace_qemu_vfio_ram_block_added(s, host, max_size);
64
116
- ret = qemu_vfio_dma_map(s, host, max_size, false, NULL);
65
+ /* stop gathering data for flat output */
117
+ ret = qemu_vfio_dma_map(s, host, max_size, false, NULL, &local_err);
66
+ if (flat) {
118
if (ret) {
67
+ break;
119
- error_report("qemu_vfio_dma_map(%p, %zu) failed: %s", host, max_size,
68
+ }
120
- strerror(-ret));
69
+
121
+ error_reportf_err(local_err,
70
if (bs0->drv && bs0->backing) {
122
+ "qemu_vfio_dma_map(%p, %zu) failed: ",
71
info->backing_file_depth++;
123
+ host, max_size);
72
bs0 = bs0->backing->bs;
124
}
73
@@ -XXX,XX +XXX,XX @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
74
75
if (bs && bs->drv) {
76
info->has_inserted = true;
77
- info->inserted = bdrv_block_device_info(blk, bs, errp);
78
+ info->inserted = bdrv_block_device_info(blk, bs, false, errp);
79
if (info->inserted == NULL) {
80
goto err;
81
}
82
diff --git a/blockdev.c b/blockdev.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/blockdev.c
85
+++ b/blockdev.c
86
@@ -XXX,XX +XXX,XX @@ void qmp_drive_backup(DriveBackup *backup, Error **errp)
87
blockdev_do_action(&action, errp);
88
}
125
}
89
126
90
-BlockDeviceInfoList *qmp_query_named_block_nodes(Error **errp)
127
@@ -XXX,XX +XXX,XX @@ qemu_vfio_find_temp_iova(QEMUVFIOState *s, size_t size, uint64_t *iova)
91
+BlockDeviceInfoList *qmp_query_named_block_nodes(bool has_flat,
128
* mapping status within this area is not allowed).
92
+ bool flat,
129
*/
93
+ Error **errp)
130
int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size,
131
- bool temporary, uint64_t *iova)
132
+ bool temporary, uint64_t *iova, Error **errp)
94
{
133
{
95
- return bdrv_named_nodes_list(errp);
134
int ret = 0;
96
+ bool return_flat = has_flat && flat;
135
int index;
97
+
98
+ return bdrv_named_nodes_list(return_flat, errp);
99
}
100
101
XDbgBlockGraph *qmp_x_debug_query_block_graph(Error **errp)
102
diff --git a/include/block/block.h b/include/block/block.h
103
index XXXXXXX..XXXXXXX 100644
104
--- a/include/block/block.h
105
+++ b/include/block/block.h
106
@@ -XXX,XX +XXX,XX @@ void bdrv_lock_medium(BlockDriverState *bs, bool locked);
107
void bdrv_eject(BlockDriverState *bs, bool eject_flag);
108
const char *bdrv_get_format_name(BlockDriverState *bs);
109
BlockDriverState *bdrv_find_node(const char *node_name);
110
-BlockDeviceInfoList *bdrv_named_nodes_list(Error **errp);
111
+BlockDeviceInfoList *bdrv_named_nodes_list(bool flat, Error **errp);
112
XDbgBlockGraph *bdrv_get_xdbg_block_graph(Error **errp);
113
BlockDriverState *bdrv_lookup_bs(const char *device,
114
const char *node_name,
115
diff --git a/include/block/qapi.h b/include/block/qapi.h
116
index XXXXXXX..XXXXXXX 100644
117
--- a/include/block/qapi.h
118
+++ b/include/block/qapi.h
119
@@ -XXX,XX +XXX,XX @@
120
#include "block/snapshot.h"
121
122
BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
123
- BlockDriverState *bs, Error **errp);
124
+ BlockDriverState *bs,
125
+ bool flat,
126
+ Error **errp);
127
int bdrv_query_snapshot_info_list(BlockDriverState *bs,
128
SnapshotInfoList **p_list,
129
Error **errp);
130
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
131
index XXXXXXX..XXXXXXX 100644
132
--- a/monitor/hmp-cmds.c
133
+++ b/monitor/hmp-cmds.c
134
@@ -XXX,XX +XXX,XX @@ void hmp_info_block(Monitor *mon, const QDict *qdict)
135
}
136
137
/* Print node information */
138
- blockdev_list = qmp_query_named_block_nodes(NULL);
139
+ blockdev_list = qmp_query_named_block_nodes(false, false, NULL);
140
for (blockdev = blockdev_list; blockdev; blockdev = blockdev->next) {
141
assert(blockdev->value->has_node_name);
142
if (device && strcmp(device, blockdev->value->node_name)) {
143
diff --git a/qapi/block-core.json b/qapi/block-core.json
144
index XXXXXXX..XXXXXXX 100644
145
--- a/qapi/block-core.json
146
+++ b/qapi/block-core.json
147
@@ -XXX,XX +XXX,XX @@
148
#
149
# Get the named block driver list
150
#
151
+# @flat: Omit the nested data about backing image ("backing-image" key) if true.
152
+# Default is false (Since 5.0)
153
+#
154
# Returns: the list of BlockDeviceInfo
155
#
156
# Since: 2.0
157
@@ -XXX,XX +XXX,XX @@
158
# } } ] }
159
#
160
##
161
-{ 'command': 'query-named-block-nodes', 'returns': [ 'BlockDeviceInfo' ] }
162
+{ 'command': 'query-named-block-nodes',
163
+ 'returns': [ 'BlockDeviceInfo' ],
164
+ 'data': { '*flat': 'bool' } }
165
166
##
167
# @XDbgBlockGraphNodeType:
168
--
136
--
169
2.24.1
137
2.31.1
170
138
171
139
diff view generated by jsdifflib
1
The generic fallback implementation effectively does the same.
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
3
Extract qemu_vfio_water_mark_reached() for readability,
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
and have it provide an error hint it its Error* handle.
5
Message-Id: <20200122164532.178040-5-mreitz@redhat.com>
5
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Suggested-by: Klaus Jensen <k.jensen@samsung.com>
7
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20210902070025.197072-8-philmd@redhat.com
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
---
11
---
8
block/iscsi.c | 56 ---------------------------------------------------
12
util/vfio-helpers.c | 17 ++++++++++++++++-
9
1 file changed, 56 deletions(-)
13
1 file changed, 16 insertions(+), 1 deletion(-)
10
14
11
diff --git a/block/iscsi.c b/block/iscsi.c
15
diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/block/iscsi.c
17
--- a/util/vfio-helpers.c
14
+++ b/block/iscsi.c
18
+++ b/util/vfio-helpers.c
15
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn iscsi_co_truncate(BlockDriverState *bs, int64_t offset,
19
@@ -XXX,XX +XXX,XX @@ qemu_vfio_find_temp_iova(QEMUVFIOState *s, size_t size, uint64_t *iova)
16
return 0;
20
return -ENOMEM;
17
}
21
}
18
22
19
-static int coroutine_fn iscsi_co_create_opts(const char *filename, QemuOpts *opts,
23
+/**
20
- Error **errp)
24
+ * qemu_vfio_water_mark_reached:
21
-{
25
+ *
22
- int ret = 0;
26
+ * Returns %true if high watermark has been reached, %false otherwise.
23
- int64_t total_size = 0;
27
+ */
24
- BlockDriverState *bs;
28
+static bool qemu_vfio_water_mark_reached(QEMUVFIOState *s, size_t size,
25
- IscsiLun *iscsilun = NULL;
29
+ Error **errp)
26
- QDict *bs_options;
30
+{
27
- Error *local_err = NULL;
31
+ if (s->high_water_mark - s->low_water_mark + 1 < size) {
28
-
32
+ error_setg(errp, "iova exhausted (water mark reached)");
29
- bs = bdrv_new();
33
+ return true;
30
-
34
+ }
31
- /* Read out options */
35
+ return false;
32
- total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
36
+}
33
- BDRV_SECTOR_SIZE);
37
+
34
- bs->opaque = g_new0(struct IscsiLun, 1);
38
/* Map [host, host + size) area into a contiguous IOVA address space, and store
35
- iscsilun = bs->opaque;
39
* the result in @iova if not NULL. The caller need to make sure the area is
36
-
40
* aligned to page size, and mustn't overlap with existing mapping areas (split
37
- bs_options = qdict_new();
41
@@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size,
38
- iscsi_parse_filename(filename, bs_options, &local_err);
42
if (mapping) {
39
- if (local_err) {
43
iova0 = mapping->iova + ((uint8_t *)host - (uint8_t *)mapping->host);
40
- error_propagate(errp, local_err);
44
} else {
41
- ret = -EINVAL;
45
- if (s->high_water_mark - s->low_water_mark + 1 < size) {
42
- } else {
46
+ if (qemu_vfio_water_mark_reached(s, size, errp)) {
43
- ret = iscsi_open(bs, bs_options, 0, NULL);
47
ret = -ENOMEM;
44
- }
48
goto out;
45
- qobject_unref(bs_options);
49
}
46
-
47
- if (ret != 0) {
48
- goto out;
49
- }
50
- iscsi_detach_aio_context(bs);
51
- if (iscsilun->type != TYPE_DISK) {
52
- ret = -ENODEV;
53
- goto out;
54
- }
55
- if (bs->total_sectors < total_size) {
56
- ret = -ENOSPC;
57
- goto out;
58
- }
59
-
60
- ret = 0;
61
-out:
62
- if (iscsilun->iscsi != NULL) {
63
- iscsi_destroy_context(iscsilun->iscsi);
64
- }
65
- g_free(bs->opaque);
66
- bs->opaque = NULL;
67
- bdrv_unref(bs);
68
- return ret;
69
-}
70
-
71
static int iscsi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
72
{
73
IscsiLun *iscsilun = bs->opaque;
74
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_iscsi = {
75
.bdrv_parse_filename = iscsi_parse_filename,
76
.bdrv_file_open = iscsi_open,
77
.bdrv_close = iscsi_close,
78
- .bdrv_co_create_opts = iscsi_co_create_opts,
79
- .create_opts = &iscsi_create_opts,
80
.bdrv_reopen_prepare = iscsi_reopen_prepare,
81
.bdrv_reopen_commit = iscsi_reopen_commit,
82
.bdrv_co_invalidate_cache = iscsi_co_invalidate_cache,
83
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_iser = {
84
.bdrv_parse_filename = iscsi_parse_filename,
85
.bdrv_file_open = iscsi_open,
86
.bdrv_close = iscsi_close,
87
- .bdrv_co_create_opts = iscsi_co_create_opts,
88
- .create_opts = &iscsi_create_opts,
89
.bdrv_reopen_prepare = iscsi_reopen_prepare,
90
.bdrv_reopen_commit = iscsi_reopen_commit,
91
.bdrv_co_invalidate_cache = iscsi_co_invalidate_cache,
92
--
50
--
93
2.24.1
51
2.31.1
94
52
95
53
diff view generated by jsdifflib
1
When nbd_close() is called from a coroutine, the connection_co never
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
gets to run, and thus nbd_teardown_connection() hangs.
3
2
4
This is because aio_co_enter() only puts the connection_co into the main
3
Both qemu_vfio_find_fixed_iova() and qemu_vfio_find_temp_iova()
5
coroutine's wake-up queue, so this main coroutine needs to yield and
4
return an errno which is unused (or overwritten). Have them propagate
6
wait for connection_co to terminate.
5
eventual errors to callers, returning a boolean (which is what the
6
Error API recommends, see commit e3fe3988d78 "error: Document Error
7
API usage rules" for rationale).
7
8
8
Suggested-by: Kevin Wolf <kwolf@redhat.com>
9
Suggested-by: Klaus Jensen <k.jensen@samsung.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
10
Message-Id: <20200122164532.178040-2-mreitz@redhat.com>
11
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Message-id: 20210902070025.197072-9-philmd@redhat.com
12
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
14
---
15
block/nbd.c | 14 +++++++++++++-
15
util/vfio-helpers.c | 24 ++++++++++++++----------
16
1 file changed, 13 insertions(+), 1 deletion(-)
16
1 file changed, 14 insertions(+), 10 deletions(-)
17
17
18
diff --git a/block/nbd.c b/block/nbd.c
18
diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/nbd.c
20
--- a/util/vfio-helpers.c
21
+++ b/block/nbd.c
21
+++ b/util/vfio-helpers.c
22
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVNBDState {
22
@@ -XXX,XX +XXX,XX @@ static bool qemu_vfio_verify_mappings(QEMUVFIOState *s)
23
CoMutex send_mutex;
23
return true;
24
CoQueue free_sema;
24
}
25
Coroutine *connection_co;
25
26
+ Coroutine *teardown_co;
26
-static int
27
QemuCoSleepState *connection_co_sleep_ns_state;
27
-qemu_vfio_find_fixed_iova(QEMUVFIOState *s, size_t size, uint64_t *iova)
28
bool drained;
28
+static bool qemu_vfio_find_fixed_iova(QEMUVFIOState *s, size_t size,
29
bool wait_drained_end;
29
+ uint64_t *iova, Error **errp)
30
@@ -XXX,XX +XXX,XX @@ static void nbd_teardown_connection(BlockDriverState *bs)
30
{
31
qemu_co_sleep_wake(s->connection_co_sleep_ns_state);
31
int i;
32
33
@@ -XXX,XX +XXX,XX @@ qemu_vfio_find_fixed_iova(QEMUVFIOState *s, size_t size, uint64_t *iova)
34
s->usable_iova_ranges[i].end - s->low_water_mark + 1 == 0) {
35
*iova = s->low_water_mark;
36
s->low_water_mark += size;
37
- return 0;
38
+ return true;
32
}
39
}
33
}
40
}
34
- BDRV_POLL_WHILE(bs, s->connection_co);
41
- return -ENOMEM;
35
+ if (qemu_in_coroutine()) {
42
+ error_setg(errp, "fixed iova range not found");
36
+ s->teardown_co = qemu_coroutine_self();
43
+
37
+ /* connection_co resumes us when it terminates */
44
+ return false;
38
+ qemu_coroutine_yield();
39
+ s->teardown_co = NULL;
40
+ } else {
41
+ BDRV_POLL_WHILE(bs, s->connection_co);
42
+ }
43
+ assert(!s->connection_co);
44
}
45
}
45
46
46
static bool nbd_client_connecting(BDRVNBDState *s)
47
-static int
47
@@ -XXX,XX +XXX,XX @@ static coroutine_fn void nbd_connection_entry(void *opaque)
48
-qemu_vfio_find_temp_iova(QEMUVFIOState *s, size_t size, uint64_t *iova)
48
s->ioc = NULL;
49
+static bool qemu_vfio_find_temp_iova(QEMUVFIOState *s, size_t size,
50
+ uint64_t *iova, Error **errp)
51
{
52
int i;
53
54
@@ -XXX,XX +XXX,XX @@ qemu_vfio_find_temp_iova(QEMUVFIOState *s, size_t size, uint64_t *iova)
55
s->high_water_mark - s->usable_iova_ranges[i].start + 1 == 0) {
56
*iova = s->high_water_mark - size;
57
s->high_water_mark = *iova;
58
- return 0;
59
+ return true;
60
}
49
}
61
}
50
62
- return -ENOMEM;
51
+ if (s->teardown_co) {
63
+ error_setg(errp, "temporary iova range not found");
52
+ aio_co_wake(s->teardown_co);
64
+
53
+ }
65
+ return false;
54
aio_wait_kick();
55
}
66
}
56
67
68
/**
69
@@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size,
70
goto out;
71
}
72
if (!temporary) {
73
- if (qemu_vfio_find_fixed_iova(s, size, &iova0)) {
74
+ if (!qemu_vfio_find_fixed_iova(s, size, &iova0, errp)) {
75
ret = -ENOMEM;
76
goto out;
77
}
78
@@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size,
79
}
80
qemu_vfio_dump_mappings(s);
81
} else {
82
- if (qemu_vfio_find_temp_iova(s, size, &iova0)) {
83
+ if (!qemu_vfio_find_temp_iova(s, size, &iova0, errp)) {
84
ret = -ENOMEM;
85
goto out;
86
}
57
--
87
--
58
2.24.1
88
2.31.1
59
89
60
90
diff view generated by jsdifflib
1
The generic fallback implementation effectively does the same.
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
3
To simplify qemu_vfio_dma_map():
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
- reduce 'ret' (returned value) scope by returning errno directly,
5
Message-Id: <20200122164532.178040-4-mreitz@redhat.com>
5
- remove the goto 'out' label.
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
7
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20210902070025.197072-10-philmd@redhat.com
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
---
11
---
8
block/file-posix.c | 67 ----------------------------------------------
12
util/vfio-helpers.c | 23 ++++++++++-------------
9
1 file changed, 67 deletions(-)
13
1 file changed, 10 insertions(+), 13 deletions(-)
10
14
11
diff --git a/block/file-posix.c b/block/file-posix.c
15
diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/block/file-posix.c
17
--- a/util/vfio-helpers.c
14
+++ b/block/file-posix.c
18
+++ b/util/vfio-helpers.c
15
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int hdev_co_pwrite_zeroes(BlockDriverState *bs,
19
@@ -XXX,XX +XXX,XX @@ static bool qemu_vfio_water_mark_reached(QEMUVFIOState *s, size_t size,
16
return raw_do_pwrite_zeroes(bs, offset, bytes, flags, true);
20
int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size,
21
bool temporary, uint64_t *iova, Error **errp)
22
{
23
- int ret = 0;
24
int index;
25
IOVAMapping *mapping;
26
uint64_t iova0;
27
@@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size,
28
if (mapping) {
29
iova0 = mapping->iova + ((uint8_t *)host - (uint8_t *)mapping->host);
30
} else {
31
+ int ret;
32
+
33
if (qemu_vfio_water_mark_reached(s, size, errp)) {
34
- ret = -ENOMEM;
35
- goto out;
36
+ return -ENOMEM;
37
}
38
if (!temporary) {
39
if (!qemu_vfio_find_fixed_iova(s, size, &iova0, errp)) {
40
- ret = -ENOMEM;
41
- goto out;
42
+ return -ENOMEM;
43
}
44
45
mapping = qemu_vfio_add_mapping(s, host, size, index + 1, iova0);
46
assert(qemu_vfio_verify_mappings(s));
47
ret = qemu_vfio_do_mapping(s, host, size, iova0);
48
- if (ret) {
49
+ if (ret < 0) {
50
qemu_vfio_undo_mapping(s, mapping, NULL);
51
- goto out;
52
+ return ret;
53
}
54
qemu_vfio_dump_mappings(s);
55
} else {
56
if (!qemu_vfio_find_temp_iova(s, size, &iova0, errp)) {
57
- ret = -ENOMEM;
58
- goto out;
59
+ return -ENOMEM;
60
}
61
ret = qemu_vfio_do_mapping(s, host, size, iova0);
62
- if (ret) {
63
- goto out;
64
+ if (ret < 0) {
65
+ return ret;
66
}
67
}
68
}
69
@@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size,
70
if (iova) {
71
*iova = iova0;
72
}
73
-out:
74
- return ret;
75
+ return 0;
17
}
76
}
18
77
19
-static int coroutine_fn hdev_co_create_opts(const char *filename, QemuOpts *opts,
78
/* Reset the high watermark and free all "temporary" mappings. */
20
- Error **errp)
21
-{
22
- int fd;
23
- int ret = 0;
24
- struct stat stat_buf;
25
- int64_t total_size = 0;
26
- bool has_prefix;
27
-
28
- /* This function is used by both protocol block drivers and therefore either
29
- * of these prefixes may be given.
30
- * The return value has to be stored somewhere, otherwise this is an error
31
- * due to -Werror=unused-value. */
32
- has_prefix =
33
- strstart(filename, "host_device:", &filename) ||
34
- strstart(filename, "host_cdrom:" , &filename);
35
-
36
- (void)has_prefix;
37
-
38
- ret = raw_normalize_devicepath(&filename, errp);
39
- if (ret < 0) {
40
- return ret;
41
- }
42
-
43
- /* Read out options */
44
- total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
45
- BDRV_SECTOR_SIZE);
46
-
47
- fd = qemu_open(filename, O_WRONLY | O_BINARY);
48
- if (fd < 0) {
49
- ret = -errno;
50
- error_setg_errno(errp, -ret, "Could not open device");
51
- return ret;
52
- }
53
-
54
- if (fstat(fd, &stat_buf) < 0) {
55
- ret = -errno;
56
- error_setg_errno(errp, -ret, "Could not stat device");
57
- } else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode)) {
58
- error_setg(errp,
59
- "The given file is neither a block nor a character device");
60
- ret = -ENODEV;
61
- } else if (lseek(fd, 0, SEEK_END) < total_size) {
62
- error_setg(errp, "Device is too small");
63
- ret = -ENOSPC;
64
- }
65
-
66
- if (!ret && total_size) {
67
- uint8_t buf[BDRV_SECTOR_SIZE] = { 0 };
68
- int64_t zero_size = MIN(BDRV_SECTOR_SIZE, total_size);
69
- if (lseek(fd, 0, SEEK_SET) == -1) {
70
- ret = -errno;
71
- } else {
72
- ret = qemu_write_full(fd, buf, zero_size);
73
- ret = ret == zero_size ? 0 : -errno;
74
- }
75
- }
76
- qemu_close(fd);
77
- return ret;
78
-}
79
-
80
static BlockDriver bdrv_host_device = {
81
.format_name = "host_device",
82
.protocol_name = "host_device",
83
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_device = {
84
.bdrv_reopen_prepare = raw_reopen_prepare,
85
.bdrv_reopen_commit = raw_reopen_commit,
86
.bdrv_reopen_abort = raw_reopen_abort,
87
- .bdrv_co_create_opts = hdev_co_create_opts,
88
- .create_opts = &raw_create_opts,
89
.mutable_opts = mutable_opts,
90
.bdrv_co_invalidate_cache = raw_co_invalidate_cache,
91
.bdrv_co_pwrite_zeroes = hdev_co_pwrite_zeroes,
92
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
93
.bdrv_reopen_prepare = raw_reopen_prepare,
94
.bdrv_reopen_commit = raw_reopen_commit,
95
.bdrv_reopen_abort = raw_reopen_abort,
96
- .bdrv_co_create_opts = hdev_co_create_opts,
97
- .create_opts = &raw_create_opts,
98
.mutable_opts = mutable_opts,
99
.bdrv_co_invalidate_cache = raw_co_invalidate_cache,
100
101
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
102
.bdrv_reopen_prepare = raw_reopen_prepare,
103
.bdrv_reopen_commit = raw_reopen_commit,
104
.bdrv_reopen_abort = raw_reopen_abort,
105
- .bdrv_co_create_opts = hdev_co_create_opts,
106
- .create_opts = &raw_create_opts,
107
.mutable_opts = mutable_opts,
108
109
.bdrv_co_preadv = raw_co_preadv,
110
--
79
--
111
2.24.1
80
2.31.1
112
81
113
82
diff view generated by jsdifflib
1
This must not crash.
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
Pass qemu_vfio_do_mapping() an Error* argument so it can propagate
4
Message-Id: <20200121155915.98232-3-mreitz@redhat.com>
4
any error to callers. Replace error_report() which only report
5
Reviewed-by: John Snow <jsnow@redhat.com>
5
to the monitor by the more generic error_setg_errno().
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
7
Reviewed-by: Fam Zheng <fam@euphon.net>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
10
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Message-id: 20210902070025.197072-11-philmd@redhat.com
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
---
13
---
8
tests/qemu-iotests/122 | 14 ++++++++++++++
14
util/vfio-helpers.c | 8 ++++----
9
tests/qemu-iotests/122.out | 5 +++++
15
1 file changed, 4 insertions(+), 4 deletions(-)
10
2 files changed, 19 insertions(+)
11
16
12
diff --git a/tests/qemu-iotests/122 b/tests/qemu-iotests/122
17
diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c
13
index XXXXXXX..XXXXXXX 100755
14
--- a/tests/qemu-iotests/122
15
+++ b/tests/qemu-iotests/122
16
@@ -XXX,XX +XXX,XX @@ $QEMU_IMG convert -O $IMGFMT -n "$TEST_IMG" "$TEST_IMG".orig
17
18
$QEMU_IMG compare "$TEST_IMG" "$TEST_IMG".orig
19
20
+echo
21
+echo '=== -n -B to an image without a backing file ==='
22
+echo
23
+
24
+# Base for the output
25
+TEST_IMG="$TEST_IMG".base _make_test_img 64M
26
+
27
+# Output that does have $TEST_IMG.base set as its (implicit) backing file
28
+TEST_IMG="$TEST_IMG".orig _make_test_img 64M
29
+
30
+# Convert with -n, which should not confuse -B with "target BDS has a
31
+# backing file"
32
+$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base -n "$TEST_IMG" "$TEST_IMG".orig
33
+
34
# success, all done
35
echo '*** done'
36
rm -f $seq.full
37
diff --git a/tests/qemu-iotests/122.out b/tests/qemu-iotests/122.out
38
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
39
--- a/tests/qemu-iotests/122.out
19
--- a/util/vfio-helpers.c
40
+++ b/tests/qemu-iotests/122.out
20
+++ b/util/vfio-helpers.c
41
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.orig', fmt=IMGFMT size=67108864
21
@@ -XXX,XX +XXX,XX @@ static IOVAMapping *qemu_vfio_add_mapping(QEMUVFIOState *s,
42
wrote 65536/65536 bytes at offset 0
22
43
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
23
/* Do the DMA mapping with VFIO. */
44
Images are identical.
24
static int qemu_vfio_do_mapping(QEMUVFIOState *s, void *host, size_t size,
45
+
25
- uint64_t iova)
46
+=== -n -B to an image without a backing file ===
26
+ uint64_t iova, Error **errp)
47
+
27
{
48
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
28
struct vfio_iommu_type1_dma_map dma_map = {
49
+Formatting 'TEST_DIR/t.IMGFMT.orig', fmt=IMGFMT size=67108864
29
.argsz = sizeof(dma_map),
50
*** done
30
@@ -XXX,XX +XXX,XX @@ static int qemu_vfio_do_mapping(QEMUVFIOState *s, void *host, size_t size,
31
trace_qemu_vfio_do_mapping(s, host, iova, size);
32
33
if (ioctl(s->container, VFIO_IOMMU_MAP_DMA, &dma_map)) {
34
- error_report("VFIO_MAP_DMA failed: %s", strerror(errno));
35
+ error_setg_errno(errp, errno, "VFIO_MAP_DMA failed");
36
return -errno;
37
}
38
return 0;
39
@@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size,
40
41
mapping = qemu_vfio_add_mapping(s, host, size, index + 1, iova0);
42
assert(qemu_vfio_verify_mappings(s));
43
- ret = qemu_vfio_do_mapping(s, host, size, iova0);
44
+ ret = qemu_vfio_do_mapping(s, host, size, iova0, errp);
45
if (ret < 0) {
46
qemu_vfio_undo_mapping(s, mapping, NULL);
47
return ret;
48
@@ -XXX,XX +XXX,XX @@ int qemu_vfio_dma_map(QEMUVFIOState *s, void *host, size_t size,
49
if (!qemu_vfio_find_temp_iova(s, size, &iova0, errp)) {
50
return -ENOMEM;
51
}
52
- ret = qemu_vfio_do_mapping(s, host, size, iova0);
53
+ ret = qemu_vfio_do_mapping(s, host, size, iova0, errp);
54
if (ret < 0) {
55
return ret;
56
}
51
--
57
--
52
2.24.1
58
2.31.1
53
59
54
60
diff view generated by jsdifflib
1
8dff69b94 added an aio parameter to the drive parameter but forgot to
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
add a comma before, thus breaking the test. Fix it again.
3
2
4
Fixes: 8dff69b9415b4287e900358744b732195e1ab2e2
3
We expect the first qemu_vfio_dma_map() to fail (indicating
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
DMA mappings exhaustion, see commit 15a730e7a3a). Do not
6
Message-Id: <20200206130812.612960-1-mreitz@redhat.com>
5
report the first failure as error, since we are going to
7
Reviewed-by: Eric Blake <eblake@redhat.com>
6
flush the mappings and retry.
8
Tested-by: Eric Blake <eblake@redhat.com>
7
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
This removes spurious error message displayed on the monitor:
9
10
(qemu) c
11
(qemu) qemu-kvm: VFIO_MAP_DMA failed: No space left on device
12
(qemu) info status
13
VM status: running
14
15
Reported-by: Tingting Mao <timao@redhat.com>
16
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
17
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
18
Message-id: 20210902070025.197072-12-philmd@redhat.com
19
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
10
---
20
---
11
tests/qemu-iotests/147 | 2 +-
21
block/nvme.c | 8 +++++++-
12
1 file changed, 1 insertion(+), 1 deletion(-)
22
1 file changed, 7 insertions(+), 1 deletion(-)
13
23
14
diff --git a/tests/qemu-iotests/147 b/tests/qemu-iotests/147
24
diff --git a/block/nvme.c b/block/nvme.c
15
index XXXXXXX..XXXXXXX 100755
25
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/qemu-iotests/147
26
--- a/block/nvme.c
17
+++ b/tests/qemu-iotests/147
27
+++ b/block/nvme.c
18
@@ -XXX,XX +XXX,XX @@ class BuiltinNBD(NBDBlockdevAddBase):
28
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int nvme_cmd_map_qiov(BlockDriverState *bs, NvmeCmd *cmd,
19
self.server.add_drive_raw('if=none,id=nbd-export,' +
29
uint64_t *pagelist = req->prp_list_page;
20
'file=%s,' % test_img +
30
int i, j, r;
21
'format=%s,' % imgfmt +
31
int entries = 0;
22
- 'cache=%s' % cachemode +
32
+ Error *local_err = NULL, **errp = NULL;
23
+ 'cache=%s,' % cachemode +
33
24
'aio=%s' % aiomode)
34
assert(qiov->size);
25
self.server.launch()
35
assert(QEMU_IS_ALIGNED(qiov->size, s->page_size));
36
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int nvme_cmd_map_qiov(BlockDriverState *bs, NvmeCmd *cmd,
37
try_map:
38
r = qemu_vfio_dma_map(s->vfio,
39
qiov->iov[i].iov_base,
40
- len, true, &iova, NULL);
41
+ len, true, &iova, errp);
42
if (r == -ENOSPC) {
43
/*
44
* In addition to the -ENOMEM error, the VFIO_IOMMU_MAP_DMA
45
@@ -XXX,XX +XXX,XX @@ try_map:
46
goto fail;
47
}
48
}
49
+ errp = &local_err;
50
+
51
goto try_map;
52
}
53
if (r) {
54
@@ -XXX,XX +XXX,XX @@ fail:
55
* because they are already mapped before calling this function; for
56
* temporary mappings, a later nvme_cmd_(un)map_qiov will reclaim by
57
* calling qemu_vfio_dma_reset_temporary when necessary. */
58
+ if (local_err) {
59
+ error_reportf_err(local_err, "Cannot map buffer for DMA: ");
60
+ }
61
return r;
62
}
26
63
27
--
64
--
28
2.24.1
65
2.31.1
29
66
30
67
diff view generated by jsdifflib
Deleted patch
1
From: David Edmondson <david.edmondson@oracle.com>
2
1
3
In many cases the target of a convert operation is a newly provisioned
4
target that the user knows is blank (reads as zero). In this situation
5
there is no requirement for qemu-img to wastefully zero out the entire
6
device.
7
8
Add a new option, --target-is-zero, allowing the user to indicate that
9
an existing target device will return zeros for all reads.
10
11
Signed-off-by: David Edmondson <david.edmondson@oracle.com>
12
Message-Id: <20200205110248.2009589-2-david.edmondson@oracle.com>
13
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
14
Reviewed-by: Eric Blake <eblake@redhat.com>
15
Signed-off-by: Max Reitz <mreitz@redhat.com>
16
---
17
docs/interop/qemu-img.rst | 9 ++++++++-
18
qemu-img-cmds.hx | 4 ++--
19
qemu-img.c | 26 +++++++++++++++++++++++---
20
3 files changed, 33 insertions(+), 6 deletions(-)
21
22
diff --git a/docs/interop/qemu-img.rst b/docs/interop/qemu-img.rst
23
index XXXXXXX..XXXXXXX 100644
24
--- a/docs/interop/qemu-img.rst
25
+++ b/docs/interop/qemu-img.rst
26
@@ -XXX,XX +XXX,XX @@ Parameters to convert subcommand:
27
will still be printed. Areas that cannot be read from the source will be
28
treated as containing only zeroes.
29
30
+.. option:: --target-is-zero
31
+
32
+ Assume that reading the destination image will always return
33
+ zeros. This parameter is mutually exclusive with a destination image
34
+ that has a backing file. It is required to also use the ``-n``
35
+ parameter to skip image creation.
36
+
37
Parameters to dd subcommand:
38
39
.. program:: qemu-img-dd
40
@@ -XXX,XX +XXX,XX @@ Command description:
41
4
42
Error on reading data
43
44
-.. option:: convert [--object OBJECTDEF] [--image-opts] [--target-image-opts] [-U] [-C] [-c] [-p] [-q] [-n] [-f FMT] [-t CACHE] [-T SRC_CACHE] [-O OUTPUT_FMT] [-B BACKING_FILE] [-o OPTIONS] [-l SNAPSHOT_PARAM] [-S SPARSE_SIZE] [-m NUM_COROUTINES] [-W] FILENAME [FILENAME2 [...]] OUTPUT_FILENAME
45
+.. option:: convert [--object OBJECTDEF] [--image-opts] [--target-image-opts] [--target-is-zero] [-U] [-C] [-c] [-p] [-q] [-n] [-f FMT] [-t CACHE] [-T SRC_CACHE] [-O OUTPUT_FMT] [-B BACKING_FILE] [-o OPTIONS] [-l SNAPSHOT_PARAM] [-S SPARSE_SIZE] [-m NUM_COROUTINES] [-W] FILENAME [FILENAME2 [...]] OUTPUT_FILENAME
46
47
Convert the disk image *FILENAME* or a snapshot *SNAPSHOT_PARAM*
48
to disk image *OUTPUT_FILENAME* using format *OUTPUT_FMT*. It can
49
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
50
index XXXXXXX..XXXXXXX 100644
51
--- a/qemu-img-cmds.hx
52
+++ b/qemu-img-cmds.hx
53
@@ -XXX,XX +XXX,XX @@ SRST
54
ERST
55
56
DEF("convert", img_convert,
57
- "convert [--object objectdef] [--image-opts] [--target-image-opts] [-U] [-C] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] [--salvage] filename [filename2 [...]] output_filename")
58
+ "convert [--object objectdef] [--image-opts] [--target-image-opts] [--target-is-zero] [-U] [-C] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] [--salvage] filename [filename2 [...]] output_filename")
59
SRST
60
-.. option:: convert [--object OBJECTDEF] [--image-opts] [--target-image-opts] [-U] [-C] [-c] [-p] [-q] [-n] [-f FMT] [-t CACHE] [-T SRC_CACHE] [-O OUTPUT_FMT] [-B BACKING_FILE] [-o OPTIONS] [-l SNAPSHOT_PARAM] [-S SPARSE_SIZE] [-m NUM_COROUTINES] [-W] [--salvage] FILENAME [FILENAME2 [...]] OUTPUT_FILENAME
61
+.. option:: convert [--object OBJECTDEF] [--image-opts] [--target-image-opts] [--target-is-zero] [-U] [-C] [-c] [-p] [-q] [-n] [-f FMT] [-t CACHE] [-T SRC_CACHE] [-O OUTPUT_FMT] [-B BACKING_FILE] [-o OPTIONS] [-l SNAPSHOT_PARAM] [-S SPARSE_SIZE] [-m NUM_COROUTINES] [-W] [--salvage] FILENAME [FILENAME2 [...]] OUTPUT_FILENAME
62
ERST
63
64
DEF("create", img_create,
65
diff --git a/qemu-img.c b/qemu-img.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/qemu-img.c
68
+++ b/qemu-img.c
69
@@ -XXX,XX +XXX,XX @@ enum {
70
OPTION_PREALLOCATION = 265,
71
OPTION_SHRINK = 266,
72
OPTION_SALVAGE = 267,
73
+ OPTION_TARGET_IS_ZERO = 268,
74
};
75
76
typedef enum OutputFormat {
77
@@ -XXX,XX +XXX,XX @@ static int convert_do_copy(ImgConvertState *s)
78
int64_t sector_num = 0;
79
80
/* Check whether we have zero initialisation or can get it efficiently */
81
- if (s->target_is_new && s->min_sparse && !s->target_has_backing) {
82
+ if (!s->has_zero_init && s->target_is_new && s->min_sparse &&
83
+ !s->target_has_backing) {
84
s->has_zero_init = bdrv_has_zero_init(blk_bs(s->target));
85
- } else {
86
- s->has_zero_init = false;
87
}
88
89
if (!s->has_zero_init && !s->target_has_backing &&
90
@@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv)
91
{"force-share", no_argument, 0, 'U'},
92
{"target-image-opts", no_argument, 0, OPTION_TARGET_IMAGE_OPTS},
93
{"salvage", no_argument, 0, OPTION_SALVAGE},
94
+ {"target-is-zero", no_argument, 0, OPTION_TARGET_IS_ZERO},
95
{0, 0, 0, 0}
96
};
97
c = getopt_long(argc, argv, ":hf:O:B:Cco:l:S:pt:T:qnm:WU",
98
@@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv)
99
case OPTION_TARGET_IMAGE_OPTS:
100
tgt_image_opts = true;
101
break;
102
+ case OPTION_TARGET_IS_ZERO:
103
+ /*
104
+ * The user asserting that the target is blank has the
105
+ * same effect as the target driver supporting zero
106
+ * initialisation.
107
+ */
108
+ s.has_zero_init = true;
109
+ break;
110
}
111
}
112
113
@@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv)
114
warn_report("This will become an error in future QEMU versions.");
115
}
116
117
+ if (s.has_zero_init && !skip_create) {
118
+ error_report("--target-is-zero requires use of -n flag");
119
+ goto fail_getopt;
120
+ }
121
+
122
s.src_num = argc - optind - 1;
123
out_filename = s.src_num >= 1 ? argv[argc - 1] : NULL;
124
125
@@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv)
126
}
127
s.target_has_backing = (bool) out_baseimg;
128
129
+ if (s.has_zero_init && s.target_has_backing) {
130
+ error_report("Cannot use --target-is-zero when the destination "
131
+ "image has a backing file");
132
+ goto out;
133
+ }
134
+
135
if (s.src_num > 1 && out_baseimg) {
136
error_report("Having a backing file for the target makes no sense when "
137
"concatenating multiple input images");
138
--
139
2.24.1
140
141
diff view generated by jsdifflib
Deleted patch
1
From: Daniel P. Berrangé <berrange@redhat.com>
2
1
3
When initializing the LUKS header the size with default encryption
4
parameters will currently be 2068480 bytes. This is rounded up to
5
a multiple of the cluster size, 2081792, with 64k sectors. If the
6
end of the header is not the same as the end of the cluster we fill
7
the extra space with zeros. This was forgetting that not even the
8
space allocated for the header will be fully initialized, as we
9
only write key material for the first key slot. The space left
10
for the other 7 slots is never written to.
11
12
An optimization to the ref count checking code:
13
14
commit a5fff8d4b4d928311a5005efa12d0991fe3b66f9 (refs/bisect/bad)
15
Author: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
16
Date: Wed Feb 27 16:14:30 2019 +0300
17
18
qcow2-refcount: avoid eating RAM
19
20
made the assumption that every cluster which was allocated would
21
have at least some data written to it. This was violated by way
22
the LUKS header is only partially written, with much space simply
23
reserved for future use.
24
25
Depending on the cluster size this problem was masked by the
26
logic which wrote zeros between the end of the LUKS header and
27
the end of the cluster.
28
29
$ qemu-img create --object secret,id=cluster_encrypt0,data=123456 \
30
-f qcow2 -o cluster_size=2k,encrypt.iter-time=1,\
31
encrypt.format=luks,encrypt.key-secret=cluster_encrypt0 \
32
cluster_size_check.qcow2 100M
33
Formatting 'cluster_size_check.qcow2', fmt=qcow2 size=104857600
34
encrypt.format=luks encrypt.key-secret=cluster_encrypt0
35
encrypt.iter-time=1 cluster_size=2048 lazy_refcounts=off refcount_bits=16
36
37
$ qemu-img check --object secret,id=cluster_encrypt0,data=redhat \
38
'json:{"driver": "qcow2", "encrypt.format": "luks", \
39
"encrypt.key-secret": "cluster_encrypt0", \
40
"file.driver": "file", "file.filename": "cluster_size_check.qcow2"}'
41
ERROR: counting reference for region exceeding the end of the file by one cluster or more: offset 0x2000 size 0x1f9000
42
Leaked cluster 4 refcount=1 reference=0
43
...snip...
44
Leaked cluster 130 refcount=1 reference=0
45
46
1 errors were found on the image.
47
Data may be corrupted, or further writes to the image may corrupt it.
48
49
127 leaked clusters were found on the image.
50
This means waste of disk space, but no harm to data.
51
Image end offset: 268288
52
53
The problem only exists when the disk image is entirely empty. Writing
54
data to the disk image payload will solve the problem by causing the
55
end of the file to be extended further.
56
57
The change fixes it by ensuring that the entire allocated LUKS header
58
region is fully initialized with zeros. The qemu-img check will still
59
fail for any pre-existing disk images created prior to this change,
60
unless at least 1 byte of the payload is written to.
61
62
Fully writing zeros to the entire LUKS header is a good idea regardless
63
as it ensures that space has been allocated on the host filesystem (or
64
whatever block storage backend is used).
65
66
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
67
Message-Id: <20200207135520.2669430-1-berrange@redhat.com>
68
Reviewed-by: Eric Blake <eblake@redhat.com>
69
Signed-off-by: Max Reitz <mreitz@redhat.com>
70
---
71
block/qcow2.c | 11 +++--
72
tests/qemu-iotests/284 | 97 ++++++++++++++++++++++++++++++++++++++
73
tests/qemu-iotests/284.out | 62 ++++++++++++++++++++++++
74
tests/qemu-iotests/group | 1 +
75
4 files changed, 167 insertions(+), 4 deletions(-)
76
create mode 100755 tests/qemu-iotests/284
77
create mode 100644 tests/qemu-iotests/284.out
78
79
diff --git a/block/qcow2.c b/block/qcow2.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/block/qcow2.c
82
+++ b/block/qcow2.c
83
@@ -XXX,XX +XXX,XX @@ static ssize_t qcow2_crypto_hdr_init_func(QCryptoBlock *block, size_t headerlen,
84
s->crypto_header.length = headerlen;
85
s->crypto_header.offset = ret;
86
87
- /* Zero fill remaining space in cluster so it has predictable
88
- * content in case of future spec changes */
89
+ /*
90
+ * Zero fill all space in cluster so it has predictable
91
+ * content, as we may not initialize some regions of the
92
+ * header (eg only 1 out of 8 key slots will be initialized)
93
+ */
94
clusterlen = size_to_clusters(s, headerlen) * s->cluster_size;
95
assert(qcow2_pre_write_overlap_check(bs, 0, ret, clusterlen, false) == 0);
96
ret = bdrv_pwrite_zeroes(bs->file,
97
- ret + headerlen,
98
- clusterlen - headerlen, 0);
99
+ ret,
100
+ clusterlen, 0);
101
if (ret < 0) {
102
error_setg_errno(errp, -ret, "Could not zero fill encryption header");
103
return -1;
104
diff --git a/tests/qemu-iotests/284 b/tests/qemu-iotests/284
105
new file mode 100755
106
index XXXXXXX..XXXXXXX
107
--- /dev/null
108
+++ b/tests/qemu-iotests/284
109
@@ -XXX,XX +XXX,XX @@
110
+#!/usr/bin/env bash
111
+#
112
+# Test ref count checks on encrypted images
113
+#
114
+# Copyright (C) 2019 Red Hat, Inc.
115
+#
116
+# This program is free software; you can redistribute it and/or modify
117
+# it under the terms of the GNU General Public License as published by
118
+# the Free Software Foundation; either version 2 of the License, or
119
+# (at your option) any later version.
120
+#
121
+# This program is distributed in the hope that it will be useful,
122
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
123
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
124
+# GNU General Public License for more details.
125
+#
126
+# You should have received a copy of the GNU General Public License
127
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
128
+#
129
+
130
+# creator
131
+owner=berrange@redhat.com
132
+
133
+seq=`basename $0`
134
+echo "QA output created by $seq"
135
+
136
+status=1 # failure is the default!
137
+
138
+_cleanup()
139
+{
140
+ _cleanup_test_img
141
+}
142
+trap "_cleanup; exit \$status" 0 1 2 3 15
143
+
144
+# get standard environment, filters and checks
145
+. ./common.rc
146
+. ./common.filter
147
+
148
+_supported_fmt qcow2
149
+_supported_proto generic
150
+_supported_os Linux
151
+
152
+
153
+size=1M
154
+
155
+SECRET="secret,id=sec0,data=astrochicken"
156
+
157
+IMGSPEC="driver=$IMGFMT,file.filename=$TEST_IMG,encrypt.key-secret=sec0"
158
+QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
159
+
160
+_run_test()
161
+{
162
+ IMGOPTSSYNTAX=true
163
+ OLD_TEST_IMG="$TEST_IMG"
164
+ TEST_IMG="driver=$IMGFMT,file.filename=$TEST_IMG,encrypt.key-secret=sec0"
165
+ QEMU_IMG_EXTRA_ARGS="--image-opts --object $SECRET"
166
+
167
+ echo
168
+ echo "== cluster size $csize"
169
+ echo "== checking image refcounts =="
170
+ _check_test_img
171
+
172
+ echo
173
+ echo "== writing some data =="
174
+ $QEMU_IO -c "write -P 0x9 0 1" $QEMU_IMG_EXTRA_ARGS $TEST_IMG | _filter_qemu_io | _filter_testdir
175
+ echo
176
+ echo "== rechecking image refcounts =="
177
+ _check_test_img
178
+
179
+ echo
180
+ echo "== writing some more data =="
181
+ $QEMU_IO -c "write -P 0x9 $csize 1" $QEMU_IMG_EXTRA_ARGS $TEST_IMG | _filter_qemu_io | _filter_testdir
182
+ echo
183
+ echo "== rechecking image refcounts =="
184
+ _check_test_img
185
+
186
+ TEST_IMG="$OLD_TEST_IMG"
187
+ QEMU_IMG_EXTRA_ARGS=
188
+ IMGOPTSSYNTAX=
189
+}
190
+
191
+
192
+echo
193
+echo "testing LUKS qcow2 encryption"
194
+echo
195
+
196
+for csize in 512 2048 32768
197
+do
198
+ _make_test_img --object $SECRET -o "encrypt.format=luks,encrypt.key-secret=sec0,encrypt.iter-time=10,cluster_size=$csize" $size
199
+ _run_test
200
+ _cleanup_test_img
201
+done
202
+
203
+# success, all done
204
+echo "*** done"
205
+rm -f $seq.full
206
+status=0
207
diff --git a/tests/qemu-iotests/284.out b/tests/qemu-iotests/284.out
208
new file mode 100644
209
index XXXXXXX..XXXXXXX
210
--- /dev/null
211
+++ b/tests/qemu-iotests/284.out
212
@@ -XXX,XX +XXX,XX @@
213
+QA output created by 284
214
+
215
+testing LUKS qcow2 encryption
216
+
217
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
218
+
219
+== cluster size 512
220
+== checking image refcounts ==
221
+No errors were found on the image.
222
+
223
+== writing some data ==
224
+wrote 1/1 bytes at offset 0
225
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
226
+
227
+== rechecking image refcounts ==
228
+No errors were found on the image.
229
+
230
+== writing some more data ==
231
+wrote 1/1 bytes at offset 512
232
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
233
+
234
+== rechecking image refcounts ==
235
+No errors were found on the image.
236
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
237
+
238
+== cluster size 2048
239
+== checking image refcounts ==
240
+No errors were found on the image.
241
+
242
+== writing some data ==
243
+wrote 1/1 bytes at offset 0
244
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
245
+
246
+== rechecking image refcounts ==
247
+No errors were found on the image.
248
+
249
+== writing some more data ==
250
+wrote 1/1 bytes at offset 2048
251
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
252
+
253
+== rechecking image refcounts ==
254
+No errors were found on the image.
255
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
256
+
257
+== cluster size 32768
258
+== checking image refcounts ==
259
+No errors were found on the image.
260
+
261
+== writing some data ==
262
+wrote 1/1 bytes at offset 0
263
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
264
+
265
+== rechecking image refcounts ==
266
+No errors were found on the image.
267
+
268
+== writing some more data ==
269
+wrote 1/1 bytes at offset 32768
270
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
271
+
272
+== rechecking image refcounts ==
273
+No errors were found on the image.
274
+*** done
275
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
276
index XXXXXXX..XXXXXXX 100644
277
--- a/tests/qemu-iotests/group
278
+++ b/tests/qemu-iotests/group
279
@@ -XXX,XX +XXX,XX @@
280
280 rw migration quick
281
281 rw quick
282
283 auto quick
283
+284 rw
284
--
285
2.24.1
286
287
diff view generated by jsdifflib
Deleted patch
1
First, driver=qcow2 will not work so well with non-qcow2 formats (and
2
this test claims to support qcow, qed, and vmdk).
3
1
4
Second, vmdk will always report the backing file format to be vmdk.
5
Filter that out so the output looks like for all other formats.
6
7
Third, the flat vmdk subformats do not support backing files, so they
8
will not work with this test.
9
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Message-Id: <20191219144243.1763246-1-mreitz@redhat.com>
12
Tested-by: Thomas Huth <thuth@redhat.com>
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
15
tests/qemu-iotests/279 | 7 +++++--
16
1 file changed, 5 insertions(+), 2 deletions(-)
17
18
diff --git a/tests/qemu-iotests/279 b/tests/qemu-iotests/279
19
index XXXXXXX..XXXXXXX 100755
20
--- a/tests/qemu-iotests/279
21
+++ b/tests/qemu-iotests/279
22
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
23
_supported_fmt qcow qcow2 vmdk qed
24
_supported_proto file
25
_supported_os Linux
26
+_unsupported_imgopts "subformat=monolithicFlat" \
27
+ "subformat=twoGbMaxExtentFlat" \
28
29
TEST_IMG="$TEST_IMG.base" _make_test_img 64M
30
TEST_IMG="$TEST_IMG.mid" _make_test_img -b "$TEST_IMG.base"
31
@@ -XXX,XX +XXX,XX @@ _make_test_img -b "$TEST_IMG.mid"
32
33
echo
34
echo '== qemu-img info --backing-chain =='
35
-_img_info --backing-chain | _filter_img_info
36
+_img_info --backing-chain | _filter_img_info | grep -v 'backing file format'
37
38
echo
39
echo '== qemu-img info --backing-chain --image-opts =='
40
-TEST_IMG="driver=qcow2,file.driver=file,file.filename=$TEST_IMG" _img_info --backing-chain --image-opts | _filter_img_info
41
+TEST_IMG="driver=$IMGFMT,file.driver=file,file.filename=$TEST_IMG" _img_info --backing-chain --image-opts \
42
+ | _filter_img_info | grep -v 'backing file format'
43
44
# success, all done
45
echo "*** done"
46
--
47
2.24.1
48
49
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Max Reitz <mreitz@redhat.com>
2
Message-Id: <20200122164532.178040-6-mreitz@redhat.com>
3
Reviewed-by: Eric Blake <eblake@redhat.com>
4
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
5
[mreitz: Added a note that NBD does not support resizing, which is why
6
the second case is expected to fail]
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
---
9
tests/qemu-iotests/259 | 62 ++++++++++++++++++++++++++++++++++++++
10
tests/qemu-iotests/259.out | 14 +++++++++
11
tests/qemu-iotests/group | 1 +
12
3 files changed, 77 insertions(+)
13
create mode 100755 tests/qemu-iotests/259
14
create mode 100644 tests/qemu-iotests/259.out
15
1
16
diff --git a/tests/qemu-iotests/259 b/tests/qemu-iotests/259
17
new file mode 100755
18
index XXXXXXX..XXXXXXX
19
--- /dev/null
20
+++ b/tests/qemu-iotests/259
21
@@ -XXX,XX +XXX,XX @@
22
+#!/usr/bin/env bash
23
+#
24
+# Test generic image creation fallback (by using NBD)
25
+#
26
+# Copyright (C) 2019 Red Hat, Inc.
27
+#
28
+# This program is free software; you can redistribute it and/or modify
29
+# it under the terms of the GNU General Public License as published by
30
+# the Free Software Foundation; either version 2 of the License, or
31
+# (at your option) any later version.
32
+#
33
+# This program is distributed in the hope that it will be useful,
34
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
35
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36
+# GNU General Public License for more details.
37
+#
38
+# You should have received a copy of the GNU General Public License
39
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
40
+#
41
+
42
+# creator
43
+owner=mreitz@redhat.com
44
+
45
+seq=$(basename $0)
46
+echo "QA output created by $seq"
47
+
48
+status=1    # failure is the default!
49
+
50
+_cleanup()
51
+{
52
+ _cleanup_test_img
53
+}
54
+trap "_cleanup; exit \$status" 0 1 2 3 15
55
+
56
+# get standard environment, filters and checks
57
+. ./common.rc
58
+. ./common.filter
59
+
60
+_supported_fmt raw
61
+_supported_proto nbd
62
+_supported_os Linux
63
+
64
+
65
+_make_test_img 64M
66
+
67
+echo
68
+echo '--- Testing creation ---'
69
+
70
+$QEMU_IMG create -f qcow2 "$TEST_IMG" 64M | _filter_img_create
71
+$QEMU_IMG info "$TEST_IMG" | _filter_img_info
72
+
73
+echo
74
+echo '--- Testing creation for which the node would need to grow ---'
75
+
76
+# NBD does not support resizing, so this will fail
77
+$QEMU_IMG create -f qcow2 -o preallocation=metadata "$TEST_IMG" 64M 2>&1 \
78
+ | _filter_img_create
79
+
80
+# success, all done
81
+echo "*** done"
82
+rm -f $seq.full
83
+status=0
84
diff --git a/tests/qemu-iotests/259.out b/tests/qemu-iotests/259.out
85
new file mode 100644
86
index XXXXXXX..XXXXXXX
87
--- /dev/null
88
+++ b/tests/qemu-iotests/259.out
89
@@ -XXX,XX +XXX,XX @@
90
+QA output created by 259
91
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
92
+
93
+--- Testing creation ---
94
+Formatting 'TEST_DIR/t.IMGFMT', fmt=qcow2 size=67108864
95
+image: TEST_DIR/t.IMGFMT
96
+file format: qcow2
97
+virtual size: 64 MiB (67108864 bytes)
98
+disk size: unavailable
99
+
100
+--- Testing creation for which the node would need to grow ---
101
+qemu-img: TEST_DIR/t.IMGFMT: Could not resize image: Image format driver does not support resize
102
+Formatting 'TEST_DIR/t.IMGFMT', fmt=qcow2 size=67108864 preallocation=metadata
103
+*** done
104
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
105
index XXXXXXX..XXXXXXX 100644
106
--- a/tests/qemu-iotests/group
107
+++ b/tests/qemu-iotests/group
108
@@ -XXX,XX +XXX,XX @@
109
256 rw auto quick
110
257 rw
111
258 rw quick
112
+259 rw auto quick
113
260 rw quick
114
261 rw
115
262 rw quick migration
116
--
117
2.24.1
118
119
diff view generated by jsdifflib