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 |