1 | The following changes since commit 9964e96dc9999cf7f7c936ee854a795415d19b60: | 1 | The following changes since commit 6d9dd5fb9d0e9f4a174f53a0e20a39fbe809c71e: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'jasowang/tags/net-pull-request' into staging (2017-05-23 15:01:31 +0100) | 3 | Merge remote-tracking branch 'remotes/armbru/tags/pull-qobject-2018-07-27-v2' into staging (2018-07-30 09:55:47 +0100) |
4 | 4 | ||
5 | are available in the git repository at: | 5 | are available in the git repository at: |
6 | 6 | ||
7 | |||
8 | git://repo.or.cz/qemu/kevin.git tags/for-upstream | 7 | git://repo.or.cz/qemu/kevin.git tags/for-upstream |
9 | 8 | ||
10 | for you to fetch changes up to 42a48128417b3bfade93d1a4721348cc480e9e50: | 9 | for you to fetch changes up to 1239ac241fe170bb9fcf0be74bfff04f6f1c2560: |
11 | 10 | ||
12 | Merge remote-tracking branch 'mreitz/tags/pull-block-2017-05-29-v3' into queue-block (2017-05-29 16:34:27 +0200) | 11 | qemu-iotests: Test query-blockstats with -drive and -blockdev (2018-07-30 15:35:37 +0200) |
13 | 12 | ||
14 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Block layer patches: | ||
15 | 15 | ||
16 | Block layer patches | 16 | - qemu-img convert -C is now required to enable copy offloading |
17 | - file-posix: Fix write_zeroes with unmap on block devices (would fall | ||
18 | back to explicit writes on recent kernels) | ||
19 | - Fix query-blockstats interface for use with -blockdev | ||
20 | - Minor fixes and documentation updates | ||
17 | 21 | ||
18 | ---------------------------------------------------------------- | 22 | ---------------------------------------------------------------- |
19 | Alberto Garcia (2): | 23 | Fam Zheng (6): |
20 | stream: fix crash in stream_start() when block_job_create() fails | 24 | file-posix: Handle EINTR in preallocation=full write |
21 | qcow2: remove extra local_error variable | 25 | docs: Describe using images in writing iotests |
26 | iotests: Don't lock /dev/null in 226 | ||
27 | Revert "qemu-img: Document copy offloading implications with -S and -c" | ||
28 | qemu-img: Add -C option for convert with copy offloading | ||
29 | iotests: Add test for 'qemu-img convert -C' compatibility | ||
22 | 30 | ||
23 | Daniel P. Berrange (4): | 31 | KONRAD Frederic (1): |
24 | qemu-img: add support for --object with 'dd' command | 32 | qcow: fix a reference leak |
25 | qemu-img: fix --image-opts usage with dd command | ||
26 | qemu-img: introduce --target-image-opts for 'convert' command | ||
27 | qemu-img: copy *key-secret opts when opening newly created files | ||
28 | 33 | ||
29 | Eric Blake (1): | 34 | Kevin Wolf (5): |
30 | block: Tweak error message related to qemu-img amend | 35 | block: Fix documentation for BDRV_REQ_MAY_UNMAP |
36 | file-posix: Fix write_zeroes with unmap on block devices | ||
37 | block/qapi: Add 'qdev' field to query-blockstats result | ||
38 | block/qapi: Include anonymous BBs in query-blockstats | ||
39 | qemu-iotests: Test query-blockstats with -drive and -blockdev | ||
31 | 40 | ||
32 | Fam Zheng (3): | 41 | Leonid Bloch (1): |
33 | iotests: 147: Don't test inet6 if not available | 42 | qcow2: A grammar fix in conflicting cache sizing error message |
34 | qemu-img: Fix documentation of convert | ||
35 | qemu-img: Fix leakage of options on error | ||
36 | 43 | ||
37 | Kevin Wolf (3): | 44 | qapi/block-core.json | 14 +++- |
38 | qemu-iotests: Test streaming with missing job ID | 45 | include/block/block.h | 11 +-- |
39 | mirror: Drop permissions on s->target on completion | 46 | block/file-posix.c | 62 ++++++++++---- |
40 | Merge remote-tracking branch 'mreitz/tags/pull-block-2017-05-29-v3' into queue-block | 47 | block/qapi.c | 16 +++- |
48 | block/qcow.c | 1 + | ||
49 | block/qcow2.c | 2 +- | ||
50 | qemu-img.c | 21 ++++- | ||
51 | docs/devel/testing.rst | 11 +++ | ||
52 | qemu-img-cmds.hx | 2 +- | ||
53 | qemu-img.texi | 14 ++-- | ||
54 | tests/qemu-iotests/082 | 8 ++ | ||
55 | tests/qemu-iotests/082.out | 11 +++ | ||
56 | tests/qemu-iotests/103.out | 4 +- | ||
57 | tests/qemu-iotests/137.out | 2 +- | ||
58 | tests/qemu-iotests/226 | 4 +- | ||
59 | tests/qemu-iotests/227 | 101 ++++++++++++++++++++++ | ||
60 | tests/qemu-iotests/227.out | 205 +++++++++++++++++++++++++++++++++++++++++++++ | ||
61 | tests/qemu-iotests/group | 1 + | ||
62 | 18 files changed, 449 insertions(+), 41 deletions(-) | ||
63 | create mode 100755 tests/qemu-iotests/227 | ||
64 | create mode 100644 tests/qemu-iotests/227.out | ||
41 | 65 | ||
42 | Max Reitz (2): | ||
43 | block: Fix backing paths for filenames with colons | ||
44 | block/file-*: *_parse_filename() and colons | ||
45 | |||
46 | Stephen Bates (1): | ||
47 | nvme: Add support for Controller Memory Buffers | ||
48 | |||
49 | block.c | 50 +++++++++++++-- | ||
50 | block/file-posix.c | 17 +----- | ||
51 | block/file-win32.c | 12 +--- | ||
52 | block/mirror.c | 7 ++- | ||
53 | block/qcow2-cluster.c | 3 +- | ||
54 | block/qcow2.c | 5 +- | ||
55 | block/stream.c | 2 +- | ||
56 | hw/block/nvme.c | 75 +++++++++++++++++++++-- | ||
57 | hw/block/nvme.h | 73 ++++++++++++++++++++++ | ||
58 | include/block/block_int.h | 3 + | ||
59 | qemu-img-cmds.hx | 4 +- | ||
60 | qemu-img.c | 148 +++++++++++++++++++++++++++++++++++---------- | ||
61 | qemu-img.texi | 12 +++- | ||
62 | tests/qemu-iotests/030 | 4 ++ | ||
63 | tests/qemu-iotests/030.out | 4 +- | ||
64 | tests/qemu-iotests/060.out | 2 +- | ||
65 | tests/qemu-iotests/147 | 7 +++ | ||
66 | 17 files changed, 351 insertions(+), 77 deletions(-) | ||
67 | diff view generated by jsdifflib |
1 | From: Max Reitz <mreitz@redhat.com> | 1 | From: KONRAD Frederic <frederic.konrad@adacore.com> |
---|---|---|---|
2 | 2 | ||
3 | path_combine() naturally tries to preserve a protocol prefix. However, | 3 | Since 42a3e1ab367cdf38cce093de24eb406b99a4ef96 qemu asserts when using the |
4 | it recognizes such a prefix by scanning for the first colon; which is | 4 | vvfat driver: |
5 | different from what path_has_protocol() does: There only is a protocol | ||
6 | prefix if there is a colon before the first slash. | ||
7 | 5 | ||
8 | A protocol prefix that is not recognized by path_has_protocol() is none, | 6 | git clone git://qemu.org/qemu.git |
9 | and should thus not be taken as one. | 7 | cd qemu |
8 | ./configure --target-list=ppc-softmmu --enable-debug | ||
9 | make -j8 | ||
10 | mkdir foo | ||
11 | touch foo/hello | ||
12 | ./ppc-softmmu/qemu-system-ppc -M prep --nographic --monitor null \ | ||
13 | -hda fat:rw:./foo | ||
10 | 14 | ||
11 | Case in point, before this patch: | 15 | "Ctrl-C" |
12 | $ ./qemu-img create -f qcow2 -b backing.qcow2 ./top:image.qcow2 | ||
13 | qemu-img: ./top:image.qcow2: Could not open './top:backing.qcow2': | ||
14 | No such file or directory | ||
15 | 16 | ||
16 | Afterwards: | 17 | qemu-system-ppc: block.c:3368: bdrv_close_all: Assertion \ |
17 | $ ./qemu-img create -f qcow2 -b backing.qcow2 ./top:image.qcow2 | 18 | `((&all_bdrv_states)->tqh_first == ((void *)0))' failed. |
18 | qemu-img: ./top:image.qcow2: Could not open './backing.qcow2': | ||
19 | No such file or directory | ||
20 | 19 | ||
21 | Reported-by: yangyang <yangyang@redhat.com> | 20 | This is because we reference bs twice in qcow_co_create(..) one time in |
22 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 21 | bdrv_open_blockdev_ref(..) and in blk_insert_bs(..) but we unref it only once |
23 | Reviewed-by: Eric Blake <eblake@redhat.com> | 22 | in blk_unref which leads to the reference leak. |
24 | Message-id: 20170522195217.12991-2-mreitz@redhat.com | 23 | |
25 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 24 | Note that I didn't tested much QCOW after this change as I don't use it much. |
25 | |||
26 | Signed-off-by: KONRAD Frederic <frederic.konrad@adacore.com> | ||
27 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
26 | --- | 28 | --- |
27 | block.c | 15 ++++++++++----- | 29 | block/qcow.c | 1 + |
28 | 1 file changed, 10 insertions(+), 5 deletions(-) | 30 | 1 file changed, 1 insertion(+) |
29 | 31 | ||
30 | diff --git a/block.c b/block.c | 32 | diff --git a/block/qcow.c b/block/qcow.c |
31 | index XXXXXXX..XXXXXXX 100644 | 33 | index XXXXXXX..XXXXXXX 100644 |
32 | --- a/block.c | 34 | --- a/block/qcow.c |
33 | +++ b/block.c | 35 | +++ b/block/qcow.c |
34 | @@ -XXX,XX +XXX,XX @@ void path_combine(char *dest, int dest_size, | 36 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow_co_create(BlockdevCreateOptions *opts, |
35 | if (path_is_absolute(filename)) { | 37 | ret = 0; |
36 | pstrcpy(dest, dest_size, filename); | 38 | exit: |
37 | } else { | 39 | blk_unref(qcow_blk); |
38 | - p = strchr(base_path, ':'); | 40 | + bdrv_unref(bs); |
39 | - if (p) | 41 | qcrypto_block_free(crypto); |
40 | - p++; | 42 | return ret; |
41 | - else | 43 | } |
42 | - p = base_path; | ||
43 | + const char *protocol_stripped = NULL; | ||
44 | + | ||
45 | + if (path_has_protocol(base_path)) { | ||
46 | + protocol_stripped = strchr(base_path, ':'); | ||
47 | + if (protocol_stripped) { | ||
48 | + protocol_stripped++; | ||
49 | + } | ||
50 | + } | ||
51 | + p = protocol_stripped ?: base_path; | ||
52 | + | ||
53 | p1 = strrchr(base_path, '/'); | ||
54 | #ifdef _WIN32 | ||
55 | { | ||
56 | -- | 44 | -- |
57 | 1.8.3.1 | 45 | 2.13.6 |
58 | 46 | ||
59 | 47 | diff view generated by jsdifflib |
1 | From: Alberto Garcia <berto@igalia.com> | 1 | From: Leonid Bloch <lbloch@janustech.com> |
---|---|---|---|
2 | 2 | ||
3 | Commit d7086422b1c1e75e320519cfe26176db6ec97a37 added a local_err | 3 | Signed-off-by: Leonid Bloch <lbloch@janustech.com> |
4 | variable global to the qcow2_amend_options() function, so there's no | 4 | Reviewed-by: John Snow <jsnow@redhat.com> |
5 | need to have this other one. | 5 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
6 | |||
7 | Signed-off-by: Alberto Garcia <berto@igalia.com> | ||
8 | Message-id: 20170511150337.21470-1-berto@igalia.com | ||
9 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
11 | --- | 6 | --- |
12 | block/qcow2.c | 5 ++--- | 7 | block/qcow2.c | 2 +- |
13 | 1 file changed, 2 insertions(+), 3 deletions(-) | 8 | tests/qemu-iotests/103.out | 4 ++-- |
9 | tests/qemu-iotests/137.out | 2 +- | ||
10 | 3 files changed, 4 insertions(+), 4 deletions(-) | ||
14 | 11 | ||
15 | diff --git a/block/qcow2.c b/block/qcow2.c | 12 | diff --git a/block/qcow2.c b/block/qcow2.c |
16 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/block/qcow2.c | 14 | --- a/block/qcow2.c |
18 | +++ b/block/qcow2.c | 15 | +++ b/block/qcow2.c |
19 | @@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, | 16 | @@ -XXX,XX +XXX,XX @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, |
20 | 17 | if (l2_cache_size_set && refcount_cache_size_set) { | |
21 | if (s->refcount_bits != refcount_bits) { | 18 | error_setg(errp, QCOW2_OPT_CACHE_SIZE ", " QCOW2_OPT_L2_CACHE_SIZE |
22 | int refcount_order = ctz32(refcount_bits); | 19 | " and " QCOW2_OPT_REFCOUNT_CACHE_SIZE " may not be set " |
23 | - Error *local_error = NULL; | 20 | - "the same time"); |
24 | 21 | + "at the same time"); | |
25 | if (new_version < 3 && refcount_bits != 16) { | 22 | return; |
26 | error_report("Different refcount widths than 16 bits require " | 23 | } else if (*l2_cache_size > combined_cache_size) { |
27 | @@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, | 24 | error_setg(errp, QCOW2_OPT_L2_CACHE_SIZE " may not exceed " |
28 | helper_cb_info.current_operation = QCOW2_CHANGING_REFCOUNT_ORDER; | 25 | diff --git a/tests/qemu-iotests/103.out b/tests/qemu-iotests/103.out |
29 | ret = qcow2_change_refcount_order(bs, refcount_order, | 26 | index XXXXXXX..XXXXXXX 100644 |
30 | &qcow2_amend_helper_cb, | 27 | --- a/tests/qemu-iotests/103.out |
31 | - &helper_cb_info, &local_error); | 28 | +++ b/tests/qemu-iotests/103.out |
32 | + &helper_cb_info, &local_err); | 29 | @@ -XXX,XX +XXX,XX @@ wrote 65536/65536 bytes at offset 0 |
33 | if (ret < 0) { | 30 | |
34 | - error_report_err(local_error); | 31 | === Testing invalid option combinations === |
35 | + error_report_err(local_err); | 32 | |
36 | return ret; | 33 | -can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set the same time |
37 | } | 34 | +can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set at the same time |
38 | } | 35 | can't open device TEST_DIR/t.IMGFMT: l2-cache-size may not exceed cache-size |
36 | can't open device TEST_DIR/t.IMGFMT: refcount-cache-size may not exceed cache-size | ||
37 | -can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set the same time | ||
38 | +can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set at the same time | ||
39 | can't open device TEST_DIR/t.IMGFMT: L2 cache entry size must be a power of two between 512 and the cluster size (65536) | ||
40 | can't open device TEST_DIR/t.IMGFMT: L2 cache entry size must be a power of two between 512 and the cluster size (65536) | ||
41 | can't open device TEST_DIR/t.IMGFMT: L2 cache entry size must be a power of two between 512 and the cluster size (65536) | ||
42 | diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out | ||
43 | index XXXXXXX..XXXXXXX 100644 | ||
44 | --- a/tests/qemu-iotests/137.out | ||
45 | +++ b/tests/qemu-iotests/137.out | ||
46 | @@ -XXX,XX +XXX,XX @@ read 33554432/33554432 bytes at offset 0 | ||
47 | === Try setting some invalid values === | ||
48 | |||
49 | Parameter 'lazy-refcounts' expects 'on' or 'off' | ||
50 | -cache-size, l2-cache-size and refcount-cache-size may not be set the same time | ||
51 | +cache-size, l2-cache-size and refcount-cache-size may not be set at the same time | ||
52 | l2-cache-size may not exceed cache-size | ||
53 | refcount-cache-size may not exceed cache-size | ||
54 | L2 cache size too big | ||
39 | -- | 55 | -- |
40 | 1.8.3.1 | 56 | 2.13.6 |
41 | 57 | ||
42 | 58 | diff view generated by jsdifflib |
1 | From: Alberto Garcia <berto@igalia.com> | 1 | From: Fam Zheng <famz@redhat.com> |
---|---|---|---|
2 | |||
3 | The code that tries to reopen a BlockDriverState in stream_start() | ||
4 | when the creation of a new block job fails crashes because it attempts | ||
5 | to dereference a pointer that is known to be NULL. | ||
6 | |||
7 | This is a regression introduced in a170a91fd3eab6155da39e740381867e, | ||
8 | likely because the code was copied from stream_complete(). | ||
9 | 2 | ||
10 | Cc: qemu-stable@nongnu.org | 3 | Cc: qemu-stable@nongnu.org |
11 | Reported-by: Kashyap Chamarthy <kchamart@redhat.com> | 4 | Signed-off-by: Fam Zheng <famz@redhat.com> |
12 | Signed-off-by: Alberto Garcia <berto@igalia.com> | ||
13 | Tested-by: Kashyap Chamarthy <kchamart@redhat.com> | ||
14 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 5 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
15 | --- | 6 | --- |
16 | block/stream.c | 2 +- | 7 | block/file-posix.c | 3 +++ |
17 | 1 file changed, 1 insertion(+), 1 deletion(-) | 8 | 1 file changed, 3 insertions(+) |
18 | 9 | ||
19 | diff --git a/block/stream.c b/block/stream.c | 10 | diff --git a/block/file-posix.c b/block/file-posix.c |
20 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100644 |
21 | --- a/block/stream.c | 12 | --- a/block/file-posix.c |
22 | +++ b/block/stream.c | 13 | +++ b/block/file-posix.c |
23 | @@ -XXX,XX +XXX,XX @@ void stream_start(const char *job_id, BlockDriverState *bs, | 14 | @@ -XXX,XX +XXX,XX @@ static int handle_aiocb_truncate(RawPosixAIOData *aiocb) |
24 | 15 | num = MIN(left, 65536); | |
25 | fail: | 16 | result = write(fd, buf, num); |
26 | if (orig_bs_flags != bdrv_get_flags(bs)) { | 17 | if (result < 0) { |
27 | - bdrv_reopen(bs, s->bs_flags, NULL); | 18 | + if (errno == EINTR) { |
28 | + bdrv_reopen(bs, orig_bs_flags, NULL); | 19 | + continue; |
29 | } | 20 | + } |
30 | } | 21 | result = -errno; |
22 | error_setg_errno(errp, -result, | ||
23 | "Could not write zeros for preallocation"); | ||
31 | -- | 24 | -- |
32 | 1.8.3.1 | 25 | 2.13.6 |
33 | 26 | ||
34 | 27 | diff view generated by jsdifflib |
1 | From: Eric Blake <eblake@redhat.com> | 1 | From: Fam Zheng <famz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | When converting a 1.1 image down to 0.10, qemu-iotests 060 forces | 3 | Signed-off-by: Fam Zheng <famz@redhat.com> |
4 | a contrived failure where allocating a cluster used to replace a | 4 | Reviewed-by: Eric Blake <eblake@redhat.com> |
5 | zero cluster reads unaligned data. Since it is a zero cluster | 5 | Reviewed-by: John Snow <jsnow@redhat.com> |
6 | rather than a data cluster being converted, changing the error | 6 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
7 | message to match our earlier change in 'qcow2: Make distinction | 7 | --- |
8 | between zero cluster types obvious' is worthwhile. | 8 | docs/devel/testing.rst | 11 +++++++++++ |
9 | 1 file changed, 11 insertions(+) | ||
9 | 10 | ||
10 | Suggested-by: Max Reitz <mreitz@redhat.com> | 11 | diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst |
11 | Signed-off-by: Eric Blake <eblake@redhat.com> | ||
12 | Message-id: 20170508171302.17805-1-eblake@redhat.com | ||
13 | [mreitz: Commit message fixes] | ||
14 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
15 | --- | ||
16 | block/qcow2-cluster.c | 3 ++- | ||
17 | tests/qemu-iotests/060.out | 2 +- | ||
18 | 2 files changed, 3 insertions(+), 2 deletions(-) | ||
19 | |||
20 | diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c | ||
21 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
22 | --- a/block/qcow2-cluster.c | 13 | --- a/docs/devel/testing.rst |
23 | +++ b/block/qcow2-cluster.c | 14 | +++ b/docs/devel/testing.rst |
24 | @@ -XXX,XX +XXX,XX @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table, | 15 | @@ -XXX,XX +XXX,XX @@ comparable library support for invoking and interacting with QEMU programs. If |
25 | } | 16 | you opt for Python, it is strongly recommended to write Python 3 compatible |
26 | 17 | code. | |
27 | if (offset_into_cluster(s, offset)) { | 18 | |
28 | - qcow2_signal_corruption(bs, true, -1, -1, "Data cluster offset " | 19 | +Both Python and Bash frameworks in iotests provide helpers to manage test |
29 | + qcow2_signal_corruption(bs, true, -1, -1, | 20 | +images. They can be used to create and clean up images under the test |
30 | + "Cluster allocation offset " | 21 | +directory. If no I/O or any protocol specific feature is needed, it is often |
31 | "%#" PRIx64 " unaligned (L2 offset: %#" | 22 | +more convenient to use the pseudo block driver, ``null-co://``, as the test |
32 | PRIx64 ", L2 index: %#x)", offset, | 23 | +image, which doesn't require image creation or cleaning up. Avoid system-wide |
33 | l2_offset, j); | 24 | +devices or files whenever possible, such as ``/dev/null`` or ``/dev/zero``. |
34 | diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out | 25 | +Otherwise, image locking implications have to be considered. For example, |
35 | index XXXXXXX..XXXXXXX 100644 | 26 | +another application on the host may have locked the file, possibly leading to a |
36 | --- a/tests/qemu-iotests/060.out | 27 | +test failure. If using such devices are explicitly desired, consider adding |
37 | +++ b/tests/qemu-iotests/060.out | 28 | +``locking=off`` option to disable image locking. |
38 | @@ -XXX,XX +XXX,XX @@ read failed: Input/output error | 29 | + |
39 | Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 | 30 | Docker based tests |
40 | wrote 65536/65536 bytes at offset 0 | 31 | ================== |
41 | 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | 32 | |
42 | -qcow2: Marking image as corrupt: Data cluster offset 0x52a00 unaligned (L2 offset: 0x40000, L2 index: 0); further corruption events will be suppressed | ||
43 | +qcow2: Marking image as corrupt: Cluster allocation offset 0x52a00 unaligned (L2 offset: 0x40000, L2 index: 0); further corruption events will be suppressed | ||
44 | qemu-img: Error while amending options: Input/output error | ||
45 | |||
46 | === Testing unaligned reftable entry === | ||
47 | -- | 33 | -- |
48 | 1.8.3.1 | 34 | 2.13.6 |
49 | 35 | ||
50 | 36 | diff view generated by jsdifflib |
1 | From: Fam Zheng <famz@redhat.com> | 1 | From: Fam Zheng <famz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | Reported by Coverity. | 3 | On my system (Fedora 28), this script reports a 'failed to get |
4 | "consistent read" lock' error. Following docs/devel/testing.rst, it's | ||
5 | better to add locking=off here. | ||
4 | 6 | ||
5 | Signed-off-by: Fam Zheng <famz@redhat.com> | 7 | Signed-off-by: Fam Zheng <famz@redhat.com> |
6 | Message-id: 20170515141014.25793-1-famz@redhat.com | ||
7 | Reviewed-by: Eric Blake <eblake@redhat.com> | 8 | Reviewed-by: Eric Blake <eblake@redhat.com> |
8 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 9 | Reviewed-by: John Snow <jsnow@redhat.com> |
10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
9 | --- | 11 | --- |
10 | qemu-img.c | 1 + | 12 | tests/qemu-iotests/226 | 4 ++-- |
11 | 1 file changed, 1 insertion(+) | 13 | 1 file changed, 2 insertions(+), 2 deletions(-) |
12 | 14 | ||
13 | diff --git a/qemu-img.c b/qemu-img.c | 15 | diff --git a/tests/qemu-iotests/226 b/tests/qemu-iotests/226 |
14 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100755 |
15 | --- a/qemu-img.c | 17 | --- a/tests/qemu-iotests/226 |
16 | +++ b/qemu-img.c | 18 | +++ b/tests/qemu-iotests/226 |
17 | @@ -XXX,XX +XXX,XX @@ static BlockBackend *img_open_opts(const char *optstr, | 19 | @@ -XXX,XX +XXX,XX @@ for PROTO in "file" "host_device" "host_cdrom"; do |
18 | if (qdict_haskey(options, BDRV_OPT_FORCE_SHARE) | 20 | echo |
19 | && !qdict_get_bool(options, BDRV_OPT_FORCE_SHARE)) { | 21 | echo "== Testing RO ==" |
20 | error_report("--force-share/-U conflicts with image options"); | 22 | $QEMU_IO -c "open -r -o driver=$PROTO,filename=$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt |
21 | + QDECREF(options); | 23 | - $QEMU_IO -c "open -r -o driver=$PROTO,filename=/dev/null" 2>&1 | _filter_imgfmt |
22 | return NULL; | 24 | + $QEMU_IO -c "open -r -o driver=$PROTO,filename=/dev/null,locking=off" 2>&1 | _filter_imgfmt |
23 | } | 25 | echo "== Testing RW ==" |
24 | qdict_put(options, BDRV_OPT_FORCE_SHARE, qbool_from_bool(true)); | 26 | $QEMU_IO -c "open -o driver=$PROTO,filename=$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt |
27 | - $QEMU_IO -c "open -o driver=$PROTO,filename=/dev/null" 2>&1 | _filter_imgfmt | ||
28 | + $QEMU_IO -c "open -o driver=$PROTO,filename=/dev/null,locking=off" 2>&1 | _filter_imgfmt | ||
29 | done | ||
30 | |||
31 | # success, all done | ||
25 | -- | 32 | -- |
26 | 1.8.3.1 | 33 | 2.13.6 |
27 | 34 | ||
28 | 35 | diff view generated by jsdifflib |
1 | From: Fam Zheng <famz@redhat.com> | 1 | From: Fam Zheng <famz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | This is the case in our docker tests, as we use --net=none there. Skip | 3 | This reverts commit eb461485f4558e362fab905735b50987505bca44. |
4 | this method. | 4 | |
5 | Now that we introduce an explicit option, these implicit rules are not | ||
6 | used. | ||
5 | 7 | ||
6 | Signed-off-by: Fam Zheng <famz@redhat.com> | 8 | Signed-off-by: Fam Zheng <famz@redhat.com> |
7 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
8 | --- | 10 | --- |
9 | tests/qemu-iotests/147 | 7 +++++++ | 11 | qemu-img.texi | 6 ++---- |
10 | 1 file changed, 7 insertions(+) | 12 | 1 file changed, 2 insertions(+), 4 deletions(-) |
11 | 13 | ||
12 | diff --git a/tests/qemu-iotests/147 b/tests/qemu-iotests/147 | 14 | diff --git a/qemu-img.texi b/qemu-img.texi |
13 | index XXXXXXX..XXXXXXX 100755 | 15 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/tests/qemu-iotests/147 | 16 | --- a/qemu-img.texi |
15 | +++ b/tests/qemu-iotests/147 | 17 | +++ b/qemu-img.texi |
16 | @@ -XXX,XX +XXX,XX @@ class BuiltinNBD(NBDBlockdevAddBase): | 18 | @@ -XXX,XX +XXX,XX @@ will enumerate information about backing files in a disk image chain. Refer |
17 | self._server_down() | 19 | below for further description. |
18 | 20 | ||
19 | def test_inet6(self): | 21 | @item -c |
20 | + try: | 22 | -indicates that target image must be compressed (qcow format only). If this |
21 | + socket.getaddrinfo("::0", "0", socket.AF_INET6, | 23 | -option is used, copy offloading will not be attempted. |
22 | + socket.SOCK_STREAM, socket.IPPROTO_TCP, | 24 | +indicates that target image must be compressed (qcow format only) |
23 | + socket.AI_ADDRCONFIG | socket.AI_CANONNAME) | 25 | |
24 | + except socket.gaierror: | 26 | @item -h |
25 | + # IPv6 not available, skip | 27 | with or without a command shows help and lists the supported formats |
26 | + return | 28 | @@ -XXX,XX +XXX,XX @@ in case both @var{-q} and @var{-p} options are used. |
27 | address = { 'type': 'inet', | 29 | indicates the consecutive number of bytes that must contain only zeros |
28 | 'data': { | 30 | for qemu-img to create a sparse image during conversion. This value is rounded |
29 | 'host': '::1', | 31 | down to the nearest 512 bytes. You may use the common size suffixes like |
32 | -@code{k} for kilobytes. If this option is used, copy offloading will not be | ||
33 | -attempted. | ||
34 | +@code{k} for kilobytes. | ||
35 | |||
36 | @item -t @var{cache} | ||
37 | specifies the cache mode that should be used with the (destination) file. See | ||
30 | -- | 38 | -- |
31 | 1.8.3.1 | 39 | 2.13.6 |
32 | 40 | ||
33 | 41 | diff view generated by jsdifflib |
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | 1 | From: Fam Zheng <famz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | The '--image-opts' flag indicates whether the source filename | 3 | Signed-off-by: Fam Zheng <famz@redhat.com> |
4 | includes options. The target filename has to remain in the | 4 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
5 | plain filename format though, since it needs to be passed to | 5 | --- |
6 | bdrv_create(). When using --skip-create though, it would be | 6 | qemu-img.c | 21 +++++++++++++++++---- |
7 | possible to use image-opts syntax. This adds --target-image-opts | 7 | qemu-img-cmds.hx | 2 +- |
8 | to indicate that the target filename includes options. Currently | 8 | qemu-img.texi | 8 +++++++- |
9 | this mandates use of the --skip-create flag too. | 9 | 3 files changed, 25 insertions(+), 6 deletions(-) |
10 | 10 | ||
11 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | 11 | diff --git a/qemu-img.c b/qemu-img.c |
12 | Message-id: 20170515164712.6643-4-berrange@redhat.com | 12 | index XXXXXXX..XXXXXXX 100644 |
13 | Reviewed-by: Max Reitz <mreitz@redhat.com> | 13 | --- a/qemu-img.c |
14 | Reviewed-by: Eric Blake <eblake@redhat.com> | 14 | +++ b/qemu-img.c |
15 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 15 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) |
16 | --- | 16 | skip_create = false, progress = false, tgt_image_opts = false; |
17 | qemu-img-cmds.hx | 4 +-- | 17 | int64_t ret = -EINVAL; |
18 | qemu-img.c | 84 ++++++++++++++++++++++++++++++++++++++------------------ | 18 | bool force_share = false; |
19 | qemu-img.texi | 12 ++++++-- | 19 | + bool explict_min_sparse = false; |
20 | 3 files changed, 69 insertions(+), 31 deletions(-) | 20 | |
21 | 21 | ImgConvertState s = (ImgConvertState) { | |
22 | /* Need at least 4k of zeros for sparse detection */ | ||
23 | .min_sparse = 8, | ||
24 | - .copy_range = true, | ||
25 | + .copy_range = false, | ||
26 | .buf_sectors = IO_BUF_SIZE / BDRV_SECTOR_SIZE, | ||
27 | .wr_in_order = true, | ||
28 | .num_coroutines = 8, | ||
29 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
30 | {"target-image-opts", no_argument, 0, OPTION_TARGET_IMAGE_OPTS}, | ||
31 | {0, 0, 0, 0} | ||
32 | }; | ||
33 | - c = getopt_long(argc, argv, ":hf:O:B:co:l:S:pt:T:qnm:WU", | ||
34 | + c = getopt_long(argc, argv, ":hf:O:B:Cco:l:S:pt:T:qnm:WU", | ||
35 | long_options, NULL); | ||
36 | if (c == -1) { | ||
37 | break; | ||
38 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
39 | case 'B': | ||
40 | out_baseimg = optarg; | ||
41 | break; | ||
42 | + case 'C': | ||
43 | + s.copy_range = true; | ||
44 | + break; | ||
45 | case 'c': | ||
46 | s.compressed = true; | ||
47 | - s.copy_range = false; | ||
48 | break; | ||
49 | case 'o': | ||
50 | if (!is_valid_option_list(optarg)) { | ||
51 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
52 | } | ||
53 | |||
54 | s.min_sparse = sval / BDRV_SECTOR_SIZE; | ||
55 | - s.copy_range = false; | ||
56 | + explict_min_sparse = true; | ||
57 | break; | ||
58 | } | ||
59 | case 'p': | ||
60 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
61 | goto fail_getopt; | ||
62 | } | ||
63 | |||
64 | + if (s.compressed && s.copy_range) { | ||
65 | + error_report("Cannot enable copy offloading when -c is used"); | ||
66 | + goto fail_getopt; | ||
67 | + } | ||
68 | + | ||
69 | + if (explict_min_sparse && s.copy_range) { | ||
70 | + error_report("Cannot enable copy offloading when -S is used"); | ||
71 | + goto fail_getopt; | ||
72 | + } | ||
73 | + | ||
74 | if (tgt_image_opts && !skip_create) { | ||
75 | error_report("--target-image-opts requires use of -n flag"); | ||
76 | goto fail_getopt; | ||
22 | diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx | 77 | diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx |
23 | index XXXXXXX..XXXXXXX 100644 | 78 | index XXXXXXX..XXXXXXX 100644 |
24 | --- a/qemu-img-cmds.hx | 79 | --- a/qemu-img-cmds.hx |
25 | +++ b/qemu-img-cmds.hx | 80 | +++ b/qemu-img-cmds.hx |
26 | @@ -XXX,XX +XXX,XX @@ STEXI | 81 | @@ -XXX,XX +XXX,XX @@ STEXI |
27 | ETEXI | 82 | ETEXI |
28 | 83 | ||
29 | DEF("convert", img_convert, | 84 | DEF("convert", img_convert, |
30 | - "convert [--object objectdef] [--image-opts] [-U] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-s snapshot_id_or_name] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename [filename2 [...]] output_filename") | 85 | - "convert [--object objectdef] [--image-opts] [--target-image-opts] [-U] [-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") |
31 | + "convert [--object objectdef] [--image-opts] [--target-image-opts] [-U] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-s snapshot_id_or_name] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename [filename2 [...]] output_filename") | 86 | + "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") |
32 | STEXI | 87 | STEXI |
33 | -@item convert [--object @var{objectdef}] [--image-opts] [-U] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename} | 88 | @item convert [--object @var{objectdef}] [--image-opts] [--target-image-opts] [-U] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename} |
34 | +@item convert [--object @var{objectdef}] [--image-opts] [--target-image-opts] [-U] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename} | ||
35 | ETEXI | 89 | ETEXI |
36 | |||
37 | DEF("dd", img_dd, | ||
38 | diff --git a/qemu-img.c b/qemu-img.c | ||
39 | index XXXXXXX..XXXXXXX 100644 | ||
40 | --- a/qemu-img.c | ||
41 | +++ b/qemu-img.c | ||
42 | @@ -XXX,XX +XXX,XX @@ enum { | ||
43 | OPTION_PATTERN = 260, | ||
44 | OPTION_FLUSH_INTERVAL = 261, | ||
45 | OPTION_NO_DRAIN = 262, | ||
46 | + OPTION_TARGET_IMAGE_OPTS = 263, | ||
47 | }; | ||
48 | |||
49 | typedef enum OutputFormat { | ||
50 | @@ -XXX,XX +XXX,XX @@ static int convert_do_copy(ImgConvertState *s) | ||
51 | static int img_convert(int argc, char **argv) | ||
52 | { | ||
53 | int c, bs_i, flags, src_flags = 0; | ||
54 | - const char *fmt = NULL, *out_fmt = "raw", *cache = "unsafe", | ||
55 | + const char *fmt = NULL, *out_fmt = NULL, *cache = "unsafe", | ||
56 | *src_cache = BDRV_DEFAULT_CACHE, *out_baseimg = NULL, | ||
57 | *out_filename, *out_baseimg_param, *snapshot_name = NULL; | ||
58 | - BlockDriver *drv, *proto_drv; | ||
59 | + BlockDriver *drv = NULL, *proto_drv = NULL; | ||
60 | BlockDriverInfo bdi; | ||
61 | BlockDriverState *out_bs; | ||
62 | QemuOpts *opts = NULL, *sn_opts = NULL; | ||
63 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
64 | char *options = NULL; | ||
65 | Error *local_err = NULL; | ||
66 | bool writethrough, src_writethrough, quiet = false, image_opts = false, | ||
67 | - skip_create = false, progress = false; | ||
68 | + skip_create = false, progress = false, tgt_image_opts = false; | ||
69 | int64_t ret = -EINVAL; | ||
70 | bool force_share = false; | ||
71 | |||
72 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
73 | {"object", required_argument, 0, OPTION_OBJECT}, | ||
74 | {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS}, | ||
75 | {"force-share", no_argument, 0, 'U'}, | ||
76 | + {"target-image-opts", no_argument, 0, OPTION_TARGET_IMAGE_OPTS}, | ||
77 | {0, 0, 0, 0} | ||
78 | }; | ||
79 | c = getopt_long(argc, argv, ":hf:O:B:ce6o:s:l:S:pt:T:qnm:WU", | ||
80 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
81 | case OPTION_IMAGE_OPTS: | ||
82 | image_opts = true; | ||
83 | break; | ||
84 | + case OPTION_TARGET_IMAGE_OPTS: | ||
85 | + tgt_image_opts = true; | ||
86 | + break; | ||
87 | } | ||
88 | } | ||
89 | |||
90 | + if (!out_fmt && !tgt_image_opts) { | ||
91 | + out_fmt = "raw"; | ||
92 | + } | ||
93 | + | ||
94 | if (qemu_opts_foreach(&qemu_object_opts, | ||
95 | user_creatable_add_opts_foreach, | ||
96 | NULL, NULL)) { | ||
97 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
98 | goto fail_getopt; | ||
99 | } | ||
100 | |||
101 | + if (tgt_image_opts && !skip_create) { | ||
102 | + error_report("--target-image-opts requires use of -n flag"); | ||
103 | + goto fail_getopt; | ||
104 | + } | ||
105 | + | ||
106 | s.src_num = argc - optind - 1; | ||
107 | out_filename = s.src_num >= 1 ? argv[argc - 1] : NULL; | ||
108 | |||
109 | if (options && has_help_option(options)) { | ||
110 | - ret = print_block_option_help(out_filename, out_fmt); | ||
111 | - goto fail_getopt; | ||
112 | + if (out_fmt) { | ||
113 | + ret = print_block_option_help(out_filename, out_fmt); | ||
114 | + goto fail_getopt; | ||
115 | + } else { | ||
116 | + error_report("Option help requires a format be specified"); | ||
117 | + goto fail_getopt; | ||
118 | + } | ||
119 | } | ||
120 | |||
121 | if (s.src_num < 1) { | ||
122 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
123 | goto out; | ||
124 | } | ||
125 | |||
126 | - /* Find driver and parse its options */ | ||
127 | - drv = bdrv_find_format(out_fmt); | ||
128 | - if (!drv) { | ||
129 | - error_report("Unknown file format '%s'", out_fmt); | ||
130 | - ret = -1; | ||
131 | - goto out; | ||
132 | - } | ||
133 | + if (!skip_create) { | ||
134 | + /* Find driver and parse its options */ | ||
135 | + drv = bdrv_find_format(out_fmt); | ||
136 | + if (!drv) { | ||
137 | + error_report("Unknown file format '%s'", out_fmt); | ||
138 | + ret = -1; | ||
139 | + goto out; | ||
140 | + } | ||
141 | |||
142 | - proto_drv = bdrv_find_protocol(out_filename, true, &local_err); | ||
143 | - if (!proto_drv) { | ||
144 | - error_report_err(local_err); | ||
145 | - ret = -1; | ||
146 | - goto out; | ||
147 | - } | ||
148 | + proto_drv = bdrv_find_protocol(out_filename, true, &local_err); | ||
149 | + if (!proto_drv) { | ||
150 | + error_report_err(local_err); | ||
151 | + ret = -1; | ||
152 | + goto out; | ||
153 | + } | ||
154 | |||
155 | - if (!skip_create) { | ||
156 | if (!drv->create_opts) { | ||
157 | error_report("Format driver '%s' does not support image creation", | ||
158 | drv->format_name); | ||
159 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
160 | const char *preallocation = | ||
161 | qemu_opt_get(opts, BLOCK_OPT_PREALLOC); | ||
162 | |||
163 | - if (!drv->bdrv_co_pwritev_compressed) { | ||
164 | + if (drv && !drv->bdrv_co_pwritev_compressed) { | ||
165 | error_report("Compression not supported for this file format"); | ||
166 | ret = -1; | ||
167 | goto out; | ||
168 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
169 | goto out; | ||
170 | } | ||
171 | |||
172 | - /* XXX we should allow --image-opts to trigger use of | ||
173 | - * img_open() here, but then we have trouble with | ||
174 | - * the bdrv_create() call which takes different params. | ||
175 | - * Not critical right now, so fix can wait... | ||
176 | - */ | ||
177 | - s.target = img_open_file(out_filename, out_fmt, flags, writethrough, quiet, | ||
178 | - false); | ||
179 | + if (skip_create) { | ||
180 | + s.target = img_open(tgt_image_opts, out_filename, out_fmt, | ||
181 | + flags, writethrough, quiet, false); | ||
182 | + } else { | ||
183 | + /* TODO ultimately we should allow --target-image-opts | ||
184 | + * to be used even when -n is not given. | ||
185 | + * That has to wait for bdrv_create to be improved | ||
186 | + * to allow filenames in option syntax | ||
187 | + */ | ||
188 | + s.target = img_open_file(out_filename, out_fmt, flags, | ||
189 | + writethrough, quiet, false); | ||
190 | + } | ||
191 | if (!s.target) { | ||
192 | ret = -1; | ||
193 | goto out; | ||
194 | } | ||
195 | out_bs = blk_bs(s.target); | ||
196 | |||
197 | + if (s.compressed && !out_bs->drv->bdrv_co_pwritev_compressed) { | ||
198 | + error_report("Compression not supported for this file format"); | ||
199 | + ret = -1; | ||
200 | + goto out; | ||
201 | + } | ||
202 | + | ||
203 | /* increase bufsectors from the default 4096 (2M) if opt_transfer | ||
204 | * or discard_alignment of the out_bs is greater. Limit to 32768 (16MB) | ||
205 | * as maximum. */ | ||
206 | diff --git a/qemu-img.texi b/qemu-img.texi | 90 | diff --git a/qemu-img.texi b/qemu-img.texi |
207 | index XXXXXXX..XXXXXXX 100644 | 91 | index XXXXXXX..XXXXXXX 100644 |
208 | --- a/qemu-img.texi | 92 | --- a/qemu-img.texi |
209 | +++ b/qemu-img.texi | 93 | +++ b/qemu-img.texi |
210 | @@ -XXX,XX +XXX,XX @@ keys. | 94 | @@ -XXX,XX +XXX,XX @@ Number of parallel coroutines for the convert process |
211 | 95 | Allow out-of-order writes to the destination. This option improves performance, | |
212 | @item --image-opts | 96 | but is only recommended for preallocated devices like host devices or other |
213 | 97 | raw block devices. | |
214 | -Indicates that the @var{filename} parameter is to be interpreted as a | 98 | +@item -C |
215 | +Indicates that the source @var{filename} parameter is to be interpreted as a | 99 | +Try to use copy offloading to move data from source image to target. This may |
216 | full option string, not a plain filename. This parameter is mutually | 100 | +improve performance if the data is remote, such as with NFS or iSCSI backends, |
217 | -exclusive with the @var{-f} and @var{-F} parameters. | 101 | +but will not automatically sparsify zero sectors, and may result in a fully |
218 | +exclusive with the @var{-f} parameter. | 102 | +allocated target image depending on the host support for getting allocation |
219 | + | 103 | +information. |
220 | +@item --target-image-opts | 104 | @end table |
221 | + | 105 | |
222 | +Indicates that the @var{output_filename} parameter(s) are to be interpreted as | 106 | Parameters to dd subcommand: |
223 | +a full option string, not a plain filename. This parameter is mutually | 107 | @@ -XXX,XX +XXX,XX @@ Error on reading data |
224 | +exclusive with the @var{-O} parameters. It is currently required to also use | 108 | |
225 | +the @var{-n} parameter to skip image creation. This restriction may be relaxed | 109 | @end table |
226 | +in a future release. | 110 | |
227 | 111 | -@item convert [--object @var{objectdef}] [--image-opts] [--target-image-opts] [-U] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename} | |
228 | @item fmt | 112 | +@item convert [--object @var{objectdef}] [--image-opts] [--target-image-opts] [-U] [-C] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename} |
229 | is the disk image format. It is guessed automatically in most cases. See below | 113 | |
114 | Convert the disk image @var{filename} or a snapshot @var{snapshot_param} | ||
115 | to disk image @var{output_filename} using format @var{output_fmt}. It can be optionally compressed (@code{-c} | ||
230 | -- | 116 | -- |
231 | 1.8.3.1 | 117 | 2.13.6 |
232 | 118 | ||
233 | 119 | diff view generated by jsdifflib |
1 | From: Fam Zheng <famz@redhat.com> | 1 | From: Fam Zheng <famz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | It got lost in commit a8d16f9ca "qemu-img: Update documentation for -U". | 3 | Signed-off-by: Fam Zheng <famz@redhat.com> |
4 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
5 | --- | ||
6 | tests/qemu-iotests/082 | 8 ++++++++ | ||
7 | tests/qemu-iotests/082.out | 11 +++++++++++ | ||
8 | 2 files changed, 19 insertions(+) | ||
4 | 9 | ||
5 | Reported-by: Max Reitz <mreitz@redhat.com> | 10 | diff --git a/tests/qemu-iotests/082 b/tests/qemu-iotests/082 |
6 | Signed-off-by: Fam Zheng <famz@redhat.com> | 11 | index XXXXXXX..XXXXXXX 100755 |
7 | Message-id: 20170515103551.31313-1-famz@redhat.com | 12 | --- a/tests/qemu-iotests/082 |
8 | Reviewed-by: Eric Blake <eblake@redhat.com> | 13 | +++ b/tests/qemu-iotests/082 |
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 14 | @@ -XXX,XX +XXX,XX @@ run_qemu_img convert -o help |
10 | --- | 15 | run_qemu_img convert -O bochs -o help |
11 | qemu-img-cmds.hx | 4 ++-- | 16 | |
12 | 1 file changed, 2 insertions(+), 2 deletions(-) | 17 | echo |
13 | 18 | +echo === convert: -C and other options === | |
14 | diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx | 19 | + |
20 | +# Adding the help option to a command without other -o options | ||
21 | +run_qemu_img convert -C -S 4k -O $IMGFMT "$TEST_IMG" "$TEST_IMG".target | ||
22 | +run_qemu_img convert -C -S 8k -O $IMGFMT "$TEST_IMG" "$TEST_IMG".target | ||
23 | +run_qemu_img convert -C -c -O $IMGFMT "$TEST_IMG" "$TEST_IMG".target | ||
24 | + | ||
25 | +echo | ||
26 | echo === amend: Options specified more than once === | ||
27 | |||
28 | # Last -f should win | ||
29 | diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out | ||
15 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/qemu-img-cmds.hx | 31 | --- a/tests/qemu-iotests/082.out |
17 | +++ b/qemu-img-cmds.hx | 32 | +++ b/tests/qemu-iotests/082.out |
18 | @@ -XXX,XX +XXX,XX @@ STEXI | 33 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size |
19 | ETEXI | 34 | Testing: convert -O bochs -o help |
20 | 35 | qemu-img: Format driver 'bochs' does not support image creation | |
21 | DEF("convert", img_convert, | 36 | |
22 | - "convert [--object objectdef] [--image-opts] [-U] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-o options] [-s snapshot_id_or_name] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename [filename2 [...]] output_filename") | 37 | +=== convert: -C and other options === |
23 | + "convert [--object objectdef] [--image-opts] [-U] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-s snapshot_id_or_name] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename [filename2 [...]] output_filename") | 38 | + |
24 | STEXI | 39 | +Testing: convert -C -S 4k -O qcow2 TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.target |
25 | -@item convert [--object @var{objectdef}] [--image-opts] [-U] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename} | 40 | +qemu-img: Cannot enable copy offloading when -S is used |
26 | +@item convert [--object @var{objectdef}] [--image-opts] [-U] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename} | 41 | + |
27 | ETEXI | 42 | +Testing: convert -C -S 8k -O qcow2 TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.target |
28 | 43 | +qemu-img: Cannot enable copy offloading when -S is used | |
29 | DEF("dd", img_dd, | 44 | + |
45 | +Testing: convert -C -c -O qcow2 TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.target | ||
46 | +qemu-img: Cannot enable copy offloading when -c is used | ||
47 | + | ||
48 | === amend: Options specified more than once === | ||
49 | |||
50 | Testing: amend -f foo -f qcow2 -o lazy_refcounts=on TEST_DIR/t.qcow2 | ||
30 | -- | 51 | -- |
31 | 1.8.3.1 | 52 | 2.13.6 |
32 | 53 | ||
33 | 54 | diff view generated by jsdifflib |
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | 1 | BDRV_REQ_MAY_UNMAP in a write_zeroes request does not only allow the |
---|---|---|---|
2 | driver to unmap the blocks, but it actively requests that the blocks be | ||
3 | unmapped afterwards if at all possible. | ||
2 | 4 | ||
3 | The qemu-img dd command added --image-opts support, but missed | 5 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
4 | the corresponding --object support. This prevented passing | 6 | --- |
5 | secrets (eg auth passwords) needed by certain disk images. | 7 | include/block/block.h | 11 ++++++----- |
8 | 1 file changed, 6 insertions(+), 5 deletions(-) | ||
6 | 9 | ||
7 | Reviewed-by: Fam Zheng <famz@redhat.com> | 10 | diff --git a/include/block/block.h b/include/block/block.h |
8 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
9 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
10 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
11 | Message-id: 20170515164712.6643-2-berrange@redhat.com | ||
12 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
13 | --- | ||
14 | qemu-img.c | 18 ++++++++++++++++++ | ||
15 | 1 file changed, 18 insertions(+) | ||
16 | |||
17 | diff --git a/qemu-img.c b/qemu-img.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/qemu-img.c | 12 | --- a/include/block/block.h |
20 | +++ b/qemu-img.c | 13 | +++ b/include/block/block.h |
21 | @@ -XXX,XX +XXX,XX @@ static int img_dd(int argc, char **argv) | 14 | @@ -XXX,XX +XXX,XX @@ typedef struct BlockFragInfo { |
22 | }; | 15 | typedef enum { |
23 | const struct option long_options[] = { | 16 | BDRV_REQ_COPY_ON_READ = 0x1, |
24 | { "help", no_argument, 0, 'h'}, | 17 | BDRV_REQ_ZERO_WRITE = 0x2, |
25 | + { "object", required_argument, 0, OPTION_OBJECT}, | 18 | - /* The BDRV_REQ_MAY_UNMAP flag is used to indicate that the block driver |
26 | { "image-opts", no_argument, 0, OPTION_IMAGE_OPTS}, | 19 | - * is allowed to optimize a write zeroes request by unmapping (discarding) |
27 | { "force-share", no_argument, 0, 'U'}, | 20 | - * blocks if it is guaranteed that the result will read back as |
28 | { 0, 0, 0, 0 } | 21 | - * zeroes. The flag is only passed to the driver if the block device is |
29 | @@ -XXX,XX +XXX,XX @@ static int img_dd(int argc, char **argv) | 22 | - * opened with BDRV_O_UNMAP. |
30 | case 'U': | ||
31 | force_share = true; | ||
32 | break; | ||
33 | + case OPTION_OBJECT: { | ||
34 | + QemuOpts *opts; | ||
35 | + opts = qemu_opts_parse_noisily(&qemu_object_opts, | ||
36 | + optarg, true); | ||
37 | + if (!opts) { | ||
38 | + ret = -1; | ||
39 | + goto out; | ||
40 | + } | ||
41 | + } break; | ||
42 | case OPTION_IMAGE_OPTS: | ||
43 | image_opts = true; | ||
44 | break; | ||
45 | @@ -XXX,XX +XXX,XX @@ static int img_dd(int argc, char **argv) | ||
46 | ret = -1; | ||
47 | goto out; | ||
48 | } | ||
49 | + | 23 | + |
50 | + if (qemu_opts_foreach(&qemu_object_opts, | 24 | + /* |
51 | + user_creatable_add_opts_foreach, | 25 | + * The BDRV_REQ_MAY_UNMAP flag is used in write_zeroes requests to indicate |
52 | + NULL, NULL)) { | 26 | + * that the block driver should unmap (discard) blocks if it is guaranteed |
53 | + ret = -1; | 27 | + * that the result will read back as zeroes. The flag is only passed to the |
54 | + goto out; | 28 | + * driver if the block device is opened with BDRV_O_UNMAP. |
55 | + } | 29 | */ |
56 | + | 30 | BDRV_REQ_MAY_UNMAP = 0x4, |
57 | blk1 = img_open(image_opts, in.filename, fmt, 0, false, false, | ||
58 | force_share); | ||
59 | 31 | ||
60 | -- | 32 | -- |
61 | 1.8.3.1 | 33 | 2.13.6 |
62 | 34 | ||
63 | 35 | diff view generated by jsdifflib |
1 | From: Max Reitz <mreitz@redhat.com> | 1 | The BLKDISCARD ioctl doesn't guarantee that the discarded blocks read as |
---|---|---|---|
2 | all-zero afterwards, so don't try to abuse it for zero writing. We try | ||
3 | to only use this if BLKDISCARDZEROES tells us that it is safe, but this | ||
4 | is unreliable on older kernels and a constant 0 in newer kernels. In | ||
5 | other words, this code path is never actually used with newer kernels, | ||
6 | so we don't even try to unmap while writing zeros. | ||
2 | 7 | ||
3 | The file drivers' *_parse_filename() implementations just strip the | 8 | This patch removes the abuse of discard for writing zeroes from |
4 | optional protocol prefix off the filename. However, for e.g. | 9 | file-posix and instead adds a new function that uses interfaces that are |
5 | "file:foo:bar", this would lead to "foo:bar" being stored as the BDS's | 10 | actually meant to deallocate and zero out at the same time. Only if |
6 | filename which looks like it should be managed using the "foo" protocol. | 11 | those fail, it falls back to zeroing out without unmap. We never fall |
7 | This is especially troublesome if you then try to resolve a backing | 12 | back to a discard operation any more that may or may not result in |
8 | filename based on "foo:bar". | 13 | zeros. |
9 | 14 | ||
10 | This issue can only occur if the stripped part is a relative filename | 15 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
11 | ("file:/foo:bar" will be shortened to "/foo:bar" and having a slash | 16 | --- |
12 | before the first colon means that "/foo" is not recognized as a protocol | 17 | block/file-posix.c | 59 ++++++++++++++++++++++++++++++++++++++++-------------- |
13 | part). Therefore, we can easily fix it by prepending "./" to such | 18 | 1 file changed, 44 insertions(+), 15 deletions(-) |
14 | filenames. | ||
15 | 19 | ||
16 | Before this patch: | ||
17 | $ ./qemu-img create -f qcow2 backing.qcow2 64M | ||
18 | Formatting 'backing.qcow2', fmt=qcow2 size=67108864 encryption=off | ||
19 | cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
20 | $ ./qemu-img create -f qcow2 -b backing.qcow2 file:top:image.qcow2 | ||
21 | Formatting 'file:top:image.qcow2', fmt=qcow2 size=67108864 | ||
22 | backing_file=backing.qcow2 encryption=off cluster_size=65536 | ||
23 | lazy_refcounts=off refcount_bits=16 | ||
24 | $ ./qemu-io file:top:image.qcow2 | ||
25 | can't open device file:top:image.qcow2: Could not open backing file: | ||
26 | Unknown protocol 'top' | ||
27 | |||
28 | After this patch: | ||
29 | $ ./qemu-io file:top:image.qcow2 | ||
30 | [no error] | ||
31 | |||
32 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
33 | Message-id: 20170522195217.12991-3-mreitz@redhat.com | ||
34 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
35 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
36 | --- | ||
37 | block.c | 35 +++++++++++++++++++++++++++++++++++ | ||
38 | block/file-posix.c | 17 +++-------------- | ||
39 | block/file-win32.c | 12 ++---------- | ||
40 | include/block/block_int.h | 3 +++ | ||
41 | 4 files changed, 43 insertions(+), 24 deletions(-) | ||
42 | |||
43 | diff --git a/block.c b/block.c | ||
44 | index XXXXXXX..XXXXXXX 100644 | ||
45 | --- a/block.c | ||
46 | +++ b/block.c | ||
47 | @@ -XXX,XX +XXX,XX @@ void path_combine(char *dest, int dest_size, | ||
48 | } | ||
49 | } | ||
50 | |||
51 | +/* | ||
52 | + * Helper function for bdrv_parse_filename() implementations to remove optional | ||
53 | + * protocol prefixes (especially "file:") from a filename and for putting the | ||
54 | + * stripped filename into the options QDict if there is such a prefix. | ||
55 | + */ | ||
56 | +void bdrv_parse_filename_strip_prefix(const char *filename, const char *prefix, | ||
57 | + QDict *options) | ||
58 | +{ | ||
59 | + if (strstart(filename, prefix, &filename)) { | ||
60 | + /* Stripping the explicit protocol prefix may result in a protocol | ||
61 | + * prefix being (wrongly) detected (if the filename contains a colon) */ | ||
62 | + if (path_has_protocol(filename)) { | ||
63 | + QString *fat_filename; | ||
64 | + | ||
65 | + /* This means there is some colon before the first slash; therefore, | ||
66 | + * this cannot be an absolute path */ | ||
67 | + assert(!path_is_absolute(filename)); | ||
68 | + | ||
69 | + /* And we can thus fix the protocol detection issue by prefixing it | ||
70 | + * by "./" */ | ||
71 | + fat_filename = qstring_from_str("./"); | ||
72 | + qstring_append(fat_filename, filename); | ||
73 | + | ||
74 | + assert(!path_has_protocol(qstring_get_str(fat_filename))); | ||
75 | + | ||
76 | + qdict_put(options, "filename", fat_filename); | ||
77 | + } else { | ||
78 | + /* If no protocol prefix was detected, we can use the shortened | ||
79 | + * filename as-is */ | ||
80 | + qdict_put_str(options, "filename", filename); | ||
81 | + } | ||
82 | + } | ||
83 | +} | ||
84 | + | ||
85 | + | ||
86 | /* Returns whether the image file is opened as read-only. Note that this can | ||
87 | * return false and writing to the image file is still not possible because the | ||
88 | * image is inactivated. */ | ||
89 | diff --git a/block/file-posix.c b/block/file-posix.c | 20 | diff --git a/block/file-posix.c b/block/file-posix.c |
90 | index XXXXXXX..XXXXXXX 100644 | 21 | index XXXXXXX..XXXXXXX 100644 |
91 | --- a/block/file-posix.c | 22 | --- a/block/file-posix.c |
92 | +++ b/block/file-posix.c | 23 | +++ b/block/file-posix.c |
93 | @@ -XXX,XX +XXX,XX @@ static void raw_parse_flags(int bdrv_flags, int *open_flags) | 24 | @@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options, |
94 | static void raw_parse_filename(const char *filename, QDict *options, | 25 | } |
95 | Error **errp) | 26 | #endif |
27 | |||
28 | - bs->supported_zero_flags = s->discard_zeroes ? BDRV_REQ_MAY_UNMAP : 0; | ||
29 | + bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP; | ||
30 | ret = 0; | ||
31 | fail: | ||
32 | if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) { | ||
33 | @@ -XXX,XX +XXX,XX @@ static ssize_t handle_aiocb_write_zeroes(RawPosixAIOData *aiocb) | ||
34 | return -ENOTSUP; | ||
35 | } | ||
36 | |||
37 | +static ssize_t handle_aiocb_write_zeroes_unmap(RawPosixAIOData *aiocb) | ||
38 | +{ | ||
39 | + BDRVRawState *s G_GNUC_UNUSED = aiocb->bs->opaque; | ||
40 | + int ret; | ||
41 | + | ||
42 | + /* First try to write zeros and unmap at the same time */ | ||
43 | + | ||
44 | +#ifdef CONFIG_FALLOCATE_PUNCH_HOLE | ||
45 | + ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, | ||
46 | + aiocb->aio_offset, aiocb->aio_nbytes); | ||
47 | + if (ret != -ENOTSUP) { | ||
48 | + return ret; | ||
49 | + } | ||
50 | +#endif | ||
51 | + | ||
52 | +#ifdef CONFIG_XFS | ||
53 | + if (s->is_xfs) { | ||
54 | + /* xfs_discard() guarantees that the discarded area reads as all-zero | ||
55 | + * afterwards, so we can use it here. */ | ||
56 | + return xfs_discard(s, aiocb->aio_offset, aiocb->aio_nbytes); | ||
57 | + } | ||
58 | +#endif | ||
59 | + | ||
60 | + /* If we couldn't manage to unmap while guaranteed that the area reads as | ||
61 | + * all-zero afterwards, just write zeroes without unmapping */ | ||
62 | + ret = handle_aiocb_write_zeroes(aiocb); | ||
63 | + return ret; | ||
64 | +} | ||
65 | + | ||
66 | #ifndef HAVE_COPY_FILE_RANGE | ||
67 | static off_t copy_file_range(int in_fd, off_t *in_off, int out_fd, | ||
68 | off_t *out_off, size_t len, unsigned int flags) | ||
69 | @@ -XXX,XX +XXX,XX @@ static int aio_worker(void *arg) | ||
70 | case QEMU_AIO_WRITE_ZEROES: | ||
71 | ret = handle_aiocb_write_zeroes(aiocb); | ||
72 | break; | ||
73 | + case QEMU_AIO_WRITE_ZEROES | QEMU_AIO_DISCARD: | ||
74 | + ret = handle_aiocb_write_zeroes_unmap(aiocb); | ||
75 | + break; | ||
76 | case QEMU_AIO_COPY_RANGE: | ||
77 | ret = handle_aiocb_copy_range(aiocb); | ||
78 | break; | ||
79 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_pwrite_zeroes( | ||
80 | int bytes, BdrvRequestFlags flags) | ||
96 | { | 81 | { |
97 | - /* The filename does not have to be prefixed by the protocol name, since | 82 | BDRVRawState *s = bs->opaque; |
98 | - * "file" is the default protocol; therefore, the return value of this | 83 | + int operation = QEMU_AIO_WRITE_ZEROES; |
99 | - * function call can be ignored. */ | 84 | |
100 | - strstart(filename, "file:", &filename); | 85 | - if (!(flags & BDRV_REQ_MAY_UNMAP)) { |
101 | - | 86 | - return paio_submit_co(bs, s->fd, offset, NULL, bytes, |
102 | - qdict_put_str(options, "filename", filename); | 87 | - QEMU_AIO_WRITE_ZEROES); |
103 | + bdrv_parse_filename_strip_prefix(filename, "file:", options); | 88 | - } else if (s->discard_zeroes) { |
89 | - return paio_submit_co(bs, s->fd, offset, NULL, bytes, | ||
90 | - QEMU_AIO_DISCARD); | ||
91 | + if (flags & BDRV_REQ_MAY_UNMAP) { | ||
92 | + operation |= QEMU_AIO_DISCARD; | ||
93 | } | ||
94 | - return -ENOTSUP; | ||
95 | + | ||
96 | + return paio_submit_co(bs, s->fd, offset, NULL, bytes, operation); | ||
104 | } | 97 | } |
105 | 98 | ||
106 | static QemuOptsList raw_runtime_opts = { | 99 | static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) |
107 | @@ -XXX,XX +XXX,XX @@ static int check_hdev_writable(BDRVRawState *s) | 100 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int hdev_co_pwrite_zeroes(BlockDriverState *bs, |
108 | static void hdev_parse_filename(const char *filename, QDict *options, | 101 | int64_t offset, int bytes, BdrvRequestFlags flags) |
109 | Error **errp) | ||
110 | { | 102 | { |
111 | - /* The prefix is optional, just as for "file". */ | 103 | BDRVRawState *s = bs->opaque; |
112 | - strstart(filename, "host_device:", &filename); | 104 | + int operation = QEMU_AIO_WRITE_ZEROES | QEMU_AIO_BLKDEV; |
113 | - | 105 | int rc; |
114 | - qdict_put_str(options, "filename", filename); | 106 | |
115 | + bdrv_parse_filename_strip_prefix(filename, "host_device:", options); | 107 | rc = fd_open(bs); |
108 | if (rc < 0) { | ||
109 | return rc; | ||
110 | } | ||
111 | - if (!(flags & BDRV_REQ_MAY_UNMAP)) { | ||
112 | - return paio_submit_co(bs, s->fd, offset, NULL, bytes, | ||
113 | - QEMU_AIO_WRITE_ZEROES|QEMU_AIO_BLKDEV); | ||
114 | - } else if (s->discard_zeroes) { | ||
115 | - return paio_submit_co(bs, s->fd, offset, NULL, bytes, | ||
116 | - QEMU_AIO_DISCARD|QEMU_AIO_BLKDEV); | ||
117 | + | ||
118 | + if (flags & BDRV_REQ_MAY_UNMAP) { | ||
119 | + operation |= QEMU_AIO_DISCARD; | ||
120 | } | ||
121 | - return -ENOTSUP; | ||
122 | + | ||
123 | + return paio_submit_co(bs, s->fd, offset, NULL, bytes, operation); | ||
116 | } | 124 | } |
117 | 125 | ||
118 | static bool hdev_is_sg(BlockDriverState *bs) | 126 | static int coroutine_fn hdev_co_create_opts(const char *filename, QemuOpts *opts, |
119 | @@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_device = { | ||
120 | static void cdrom_parse_filename(const char *filename, QDict *options, | ||
121 | Error **errp) | ||
122 | { | ||
123 | - /* The prefix is optional, just as for "file". */ | ||
124 | - strstart(filename, "host_cdrom:", &filename); | ||
125 | - | ||
126 | - qdict_put_str(options, "filename", filename); | ||
127 | + bdrv_parse_filename_strip_prefix(filename, "host_cdrom:", options); | ||
128 | } | ||
129 | #endif | ||
130 | |||
131 | diff --git a/block/file-win32.c b/block/file-win32.c | ||
132 | index XXXXXXX..XXXXXXX 100644 | ||
133 | --- a/block/file-win32.c | ||
134 | +++ b/block/file-win32.c | ||
135 | @@ -XXX,XX +XXX,XX @@ static void raw_parse_flags(int flags, bool use_aio, int *access_flags, | ||
136 | static void raw_parse_filename(const char *filename, QDict *options, | ||
137 | Error **errp) | ||
138 | { | ||
139 | - /* The filename does not have to be prefixed by the protocol name, since | ||
140 | - * "file" is the default protocol; therefore, the return value of this | ||
141 | - * function call can be ignored. */ | ||
142 | - strstart(filename, "file:", &filename); | ||
143 | - | ||
144 | - qdict_put_str(options, "filename", filename); | ||
145 | + bdrv_parse_filename_strip_prefix(filename, "file:", options); | ||
146 | } | ||
147 | |||
148 | static QemuOptsList raw_runtime_opts = { | ||
149 | @@ -XXX,XX +XXX,XX @@ static int hdev_probe_device(const char *filename) | ||
150 | static void hdev_parse_filename(const char *filename, QDict *options, | ||
151 | Error **errp) | ||
152 | { | ||
153 | - /* The prefix is optional, just as for "file". */ | ||
154 | - strstart(filename, "host_device:", &filename); | ||
155 | - | ||
156 | - qdict_put_str(options, "filename", filename); | ||
157 | + bdrv_parse_filename_strip_prefix(filename, "host_device:", options); | ||
158 | } | ||
159 | |||
160 | static int hdev_open(BlockDriverState *bs, QDict *options, int flags, | ||
161 | diff --git a/include/block/block_int.h b/include/block/block_int.h | ||
162 | index XXXXXXX..XXXXXXX 100644 | ||
163 | --- a/include/block/block_int.h | ||
164 | +++ b/include/block/block_int.h | ||
165 | @@ -XXX,XX +XXX,XX @@ int get_tmp_filename(char *filename, int size); | ||
166 | BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size, | ||
167 | const char *filename); | ||
168 | |||
169 | +void bdrv_parse_filename_strip_prefix(const char *filename, const char *prefix, | ||
170 | + QDict *options); | ||
171 | + | ||
172 | |||
173 | /** | ||
174 | * bdrv_add_before_write_notifier: | ||
175 | -- | 127 | -- |
176 | 1.8.3.1 | 128 | 2.13.6 |
177 | 129 | ||
178 | 130 | diff view generated by jsdifflib |
1 | This fixes an assertion failure that was triggered by qemu-iotests 129 | 1 | Like for query-block, the client needs to identify which BlockBackend |
---|---|---|---|
2 | on some CI host, while the same test case didn't seem to fail on other | 2 | the returned data is for. Anonymous BlockBackends are identified by the |
3 | hosts. | 3 | device model they are attached to. Add a 'qdev' field that contains the |
4 | qdev ID or QOM path of the attached device model. | ||
4 | 5 | ||
5 | Essentially the problem is that the blk_unref(s->target) in | 6 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
6 | mirror_exit() doesn't necessarily mean that the BlockBackend goes away | 7 | Reviewed-by: Eric Blake <eblake@redhat.com> |
7 | immediately. It is possible that the job completion was triggered nested | 8 | --- |
8 | in mirror_drain(), which looks like this: | 9 | qapi/block-core.json | 14 ++++++++++---- |
10 | block/qapi.c | 10 ++++++++++ | ||
11 | 2 files changed, 20 insertions(+), 4 deletions(-) | ||
9 | 12 | ||
10 | BlockBackend *target = s->target; | 13 | diff --git a/qapi/block-core.json b/qapi/block-core.json |
11 | blk_ref(target); | ||
12 | blk_drain(target); | ||
13 | blk_unref(target); | ||
14 | |||
15 | In this case, the write permissions for s->target are retained until | ||
16 | after blk_drain(), which makes removing mirror_top_bs fail for the | ||
17 | active commit case (can't have a writable backing file in the chain | ||
18 | without the filter driver). | ||
19 | |||
20 | Explicitly dropping the permissions first means that the additional | ||
21 | reference doesn't hurt and the job can complete successfully even if | ||
22 | called from the nested blk_drain(). | ||
23 | |||
24 | Cc: qemu-stable@nongnu.org | ||
25 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
26 | Acked-by: Paolo Bonzini <pbonzini@redhat.com> | ||
27 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
28 | --- | ||
29 | block/mirror.c | 7 ++++++- | ||
30 | 1 file changed, 6 insertions(+), 1 deletion(-) | ||
31 | |||
32 | diff --git a/block/mirror.c b/block/mirror.c | ||
33 | index XXXXXXX..XXXXXXX 100644 | 14 | index XXXXXXX..XXXXXXX 100644 |
34 | --- a/block/mirror.c | 15 | --- a/qapi/block-core.json |
35 | +++ b/block/mirror.c | 16 | +++ b/qapi/block-core.json |
36 | @@ -XXX,XX +XXX,XX @@ static void mirror_exit(BlockJob *job, void *opaque) | 17 | @@ -XXX,XX +XXX,XX @@ |
37 | 18 | # | |
38 | /* Remove target parent that still uses BLK_PERM_WRITE/RESIZE before | 19 | # @node-name: The node name of the device. (Since 2.3) |
39 | * inserting target_bs at s->to_replace, where we might not be able to get | 20 | # |
40 | - * these permissions. */ | 21 | +# @qdev: The qdev ID, or if no ID is assigned, the QOM path of the block |
41 | + * these permissions. | 22 | +# device. (since 3.0) |
42 | + * | 23 | +# |
43 | + * Note that blk_unref() alone doesn't necessarily drop permissions because | 24 | # @stats: A @BlockDeviceStats for the device. |
44 | + * we might be running nested inside mirror_drain(), which takes an extra | 25 | # |
45 | + * reference, so use an explicit blk_set_perm() first. */ | 26 | # @parent: This describes the file block device if it has one. |
46 | + blk_set_perm(s->target, 0, BLK_PERM_ALL, &error_abort); | 27 | @@ -XXX,XX +XXX,XX @@ |
47 | blk_unref(s->target); | 28 | # Since: 0.14.0 |
48 | s->target = NULL; | 29 | ## |
30 | { 'struct': 'BlockStats', | ||
31 | - 'data': {'*device': 'str', '*node-name': 'str', | ||
32 | + 'data': {'*device': 'str', '*qdev': 'str', '*node-name': 'str', | ||
33 | 'stats': 'BlockDeviceStats', | ||
34 | '*parent': 'BlockStats', | ||
35 | '*backing': 'BlockStats'} } | ||
36 | @@ -XXX,XX +XXX,XX @@ | ||
37 | # "idle_time_ns":2953431879, | ||
38 | # "account_invalid":true, | ||
39 | # "account_failed":false | ||
40 | -# } | ||
41 | +# }, | ||
42 | +# "qdev": "/machine/unattached/device[23]" | ||
43 | # }, | ||
44 | # { | ||
45 | # "device":"ide1-cd0", | ||
46 | @@ -XXX,XX +XXX,XX @@ | ||
47 | # "wr_merged":0, | ||
48 | # "account_invalid":false, | ||
49 | # "account_failed":false | ||
50 | -# } | ||
51 | +# }, | ||
52 | +# "qdev": "/machine/unattached/device[24]" | ||
53 | # }, | ||
54 | # { | ||
55 | # "device":"floppy0", | ||
56 | @@ -XXX,XX +XXX,XX @@ | ||
57 | # "wr_merged":0, | ||
58 | # "account_invalid":false, | ||
59 | # "account_failed":false | ||
60 | -# } | ||
61 | +# }, | ||
62 | +# "qdev": "/machine/unattached/device[16]" | ||
63 | # }, | ||
64 | # { | ||
65 | # "device":"sd0", | ||
66 | diff --git a/block/qapi.c b/block/qapi.c | ||
67 | index XXXXXXX..XXXXXXX 100644 | ||
68 | --- a/block/qapi.c | ||
69 | +++ b/block/qapi.c | ||
70 | @@ -XXX,XX +XXX,XX @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes, | ||
71 | BlockStatsList *info = g_malloc0(sizeof(*info)); | ||
72 | AioContext *ctx = blk_get_aio_context(blk); | ||
73 | BlockStats *s; | ||
74 | + char *qdev; | ||
75 | |||
76 | aio_context_acquire(ctx); | ||
77 | s = bdrv_query_bds_stats(blk_bs(blk), true); | ||
78 | s->has_device = true; | ||
79 | s->device = g_strdup(blk_name(blk)); | ||
80 | + | ||
81 | + qdev = blk_get_attached_dev_id(blk); | ||
82 | + if (qdev && *qdev) { | ||
83 | + s->has_qdev = true; | ||
84 | + s->qdev = qdev; | ||
85 | + } else { | ||
86 | + g_free(qdev); | ||
87 | + } | ||
88 | + | ||
89 | bdrv_query_blk_stats(s->stats, blk); | ||
90 | aio_context_release(ctx); | ||
49 | 91 | ||
50 | -- | 92 | -- |
51 | 1.8.3.1 | 93 | 2.13.6 |
52 | 94 | ||
53 | 95 | diff view generated by jsdifflib |
1 | This adds a small test for the image streaming error path for failing | 1 | Consistent with query-block, query-blockstats should not only include |
---|---|---|---|
2 | block_job_create(), which would have found the null pointer dereference | 2 | named BlockBackends, but also those that are anonymous, but belong to a |
3 | in commit a170a91f. | 3 | device model. |
4 | 4 | ||
5 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 5 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
6 | Reviewed-by: Alberto Garcia <berto@igalia.com> | 6 | Reviewed-by: Eric Blake <eblake@redhat.com> |
7 | Reviewed-by: Kashyap Chamarthy <kchamart@redhat.com> | ||
8 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
9 | Reviewed-by: Jeff Cody <jcody@redhat.com> | ||
10 | --- | 7 | --- |
11 | tests/qemu-iotests/030 | 4 ++++ | 8 | block/qapi.c | 6 +++++- |
12 | tests/qemu-iotests/030.out | 4 ++-- | 9 | 1 file changed, 5 insertions(+), 1 deletion(-) |
13 | 2 files changed, 6 insertions(+), 2 deletions(-) | ||
14 | 10 | ||
15 | diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030 | 11 | diff --git a/block/qapi.c b/block/qapi.c |
16 | index XXXXXXX..XXXXXXX 100755 | 12 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/tests/qemu-iotests/030 | 13 | --- a/block/qapi.c |
18 | +++ b/tests/qemu-iotests/030 | 14 | +++ b/block/qapi.c |
19 | @@ -XXX,XX +XXX,XX @@ class TestSingleDrive(iotests.QMPTestCase): | 15 | @@ -XXX,XX +XXX,XX @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes, |
20 | result = self.vm.qmp('block-stream', device='nonexistent') | 16 | p_next = &info->next; |
21 | self.assert_qmp(result, 'error/class', 'GenericError') | 17 | } |
22 | 18 | } else { | |
23 | + def test_job_id_missing(self): | 19 | - for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { |
24 | + result = self.vm.qmp('block-stream', device='mid') | 20 | + for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) { |
25 | + self.assert_qmp(result, 'error/class', 'GenericError') | 21 | BlockStatsList *info = g_malloc0(sizeof(*info)); |
22 | AioContext *ctx = blk_get_aio_context(blk); | ||
23 | BlockStats *s; | ||
24 | char *qdev; | ||
25 | |||
26 | + if (!*blk_name(blk) && !blk_get_attached_dev(blk)) { | ||
27 | + continue; | ||
28 | + } | ||
26 | + | 29 | + |
27 | 30 | aio_context_acquire(ctx); | |
28 | class TestParallelOps(iotests.QMPTestCase): | 31 | s = bdrv_query_bds_stats(blk_bs(blk), true); |
29 | num_ops = 4 # Number of parallel block-stream operations | 32 | s->has_device = true; |
30 | diff --git a/tests/qemu-iotests/030.out b/tests/qemu-iotests/030.out | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/tests/qemu-iotests/030.out | ||
33 | +++ b/tests/qemu-iotests/030.out | ||
34 | @@ -XXX,XX +XXX,XX @@ | ||
35 | -...................... | ||
36 | +....................... | ||
37 | ---------------------------------------------------------------------- | ||
38 | -Ran 22 tests | ||
39 | +Ran 23 tests | ||
40 | |||
41 | OK | ||
42 | -- | 33 | -- |
43 | 1.8.3.1 | 34 | 2.13.6 |
44 | 35 | ||
45 | 36 | diff view generated by jsdifflib |
1 | From: Stephen Bates <sbates@raithlin.com> | 1 | Make sure that query-blockstats returns information for every |
---|---|---|---|
2 | BlockBackend that is named or attached to a device model (or both). | ||
2 | 3 | ||
3 | Implement NVMe Controller Memory Buffers (CMBs) which were added in | 4 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
4 | version 1.2 of the NVMe Specification. This patch adds an optional | 5 | Reviewed-by: Eric Blake <eblake@redhat.com> |
5 | argument (cmb_size_mb) which indicates the size of the CMB (in | ||
6 | MB). Currently only the Submission Queue Support (SQS) is enabled | ||
7 | which aligns with the current Linux driver for NVMe. | ||
8 | |||
9 | Signed-off-by: Stephen Bates <sbates@raithlin.com> | ||
10 | Acked-by: Keith Busch <keith.busch@intel.com> | ||
11 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 6 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
12 | --- | 7 | --- |
13 | hw/block/nvme.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- | 8 | tests/qemu-iotests/227 | 101 ++++++++++++++++++++++ |
14 | hw/block/nvme.h | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 9 | tests/qemu-iotests/227.out | 205 +++++++++++++++++++++++++++++++++++++++++++++ |
15 | 2 files changed, 144 insertions(+), 4 deletions(-) | 10 | tests/qemu-iotests/group | 1 + |
11 | 3 files changed, 307 insertions(+) | ||
12 | create mode 100755 tests/qemu-iotests/227 | ||
13 | create mode 100644 tests/qemu-iotests/227.out | ||
16 | 14 | ||
17 | diff --git a/hw/block/nvme.c b/hw/block/nvme.c | 15 | diff --git a/tests/qemu-iotests/227 b/tests/qemu-iotests/227 |
16 | new file mode 100755 | ||
17 | index XXXXXXX..XXXXXXX | ||
18 | --- /dev/null | ||
19 | +++ b/tests/qemu-iotests/227 | ||
20 | @@ -XXX,XX +XXX,XX @@ | ||
21 | +#!/bin/bash | ||
22 | +# | ||
23 | +# Test query-blockstats with different ways to create a BB | ||
24 | +# | ||
25 | +# Copyright (C) 2018 Red Hat, Inc. | ||
26 | +# | ||
27 | +# This program is free software; you can redistribute it and/or modify | ||
28 | +# it under the terms of the GNU General Public License as published by | ||
29 | +# the Free Software Foundation; either version 2 of the License, or | ||
30 | +# (at your option) any later version. | ||
31 | +# | ||
32 | +# This program is distributed in the hope that it will be useful, | ||
33 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
34 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
35 | +# GNU General Public License for more details. | ||
36 | +# | ||
37 | +# You should have received a copy of the GNU General Public License | ||
38 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
39 | +# | ||
40 | + | ||
41 | +# creator | ||
42 | +owner=kwolf@redhat.com | ||
43 | + | ||
44 | +seq=$(basename $0) | ||
45 | +echo "QA output created by $seq" | ||
46 | + | ||
47 | +here=$PWD | ||
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 generic | ||
61 | +_supported_proto file | ||
62 | +_supported_os Linux | ||
63 | + | ||
64 | +function do_run_qemu() | ||
65 | +{ | ||
66 | + echo Testing: "$@" | ||
67 | + $QEMU -nographic -qmp-pretty stdio -serial none "$@" | ||
68 | + echo | ||
69 | +} | ||
70 | + | ||
71 | +function run_qemu() | ||
72 | +{ | ||
73 | + do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp \ | ||
74 | + | _filter_qemu | _filter_imgfmt \ | ||
75 | + | _filter_generated_node_ids | ||
76 | +} | ||
77 | + | ||
78 | +echo | ||
79 | +echo '=== blockstats with -drive if=virtio ===' | ||
80 | +echo | ||
81 | + | ||
82 | +run_qemu -drive driver=null-co,if=virtio <<EOF | ||
83 | +{ "execute": "qmp_capabilities" } | ||
84 | +{ "execute": "query-blockstats"} | ||
85 | +{ "execute": "quit" } | ||
86 | +EOF | ||
87 | + | ||
88 | +echo | ||
89 | +echo '=== blockstats with -drive if=none ===' | ||
90 | +echo | ||
91 | + | ||
92 | +run_qemu -drive driver=null-co,if=none <<EOF | ||
93 | +{ "execute": "qmp_capabilities" } | ||
94 | +{ "execute": "query-blockstats"} | ||
95 | +{ "execute": "quit" } | ||
96 | +EOF | ||
97 | + | ||
98 | +echo | ||
99 | +echo '=== blockstats with -blockdev ===' | ||
100 | +echo | ||
101 | + | ||
102 | +run_qemu -blockdev driver=null-co,node-name=null <<EOF | ||
103 | +{ "execute": "qmp_capabilities" } | ||
104 | +{ "execute": "query-blockstats"} | ||
105 | +{ "execute": "quit" } | ||
106 | +EOF | ||
107 | + | ||
108 | +echo | ||
109 | +echo '=== blockstats with -blockdev and -device ===' | ||
110 | +echo | ||
111 | + | ||
112 | +run_qemu -blockdev driver=null-co,node-name=null -device virtio-blk,drive=null,id=virtio0 <<EOF | ||
113 | +{ "execute": "qmp_capabilities" } | ||
114 | +{ "execute": "query-blockstats"} | ||
115 | +{ "execute": "quit" } | ||
116 | +EOF | ||
117 | + | ||
118 | +# success, all done | ||
119 | +echo "*** done" | ||
120 | +rm -f $seq.full | ||
121 | +status=0 | ||
122 | diff --git a/tests/qemu-iotests/227.out b/tests/qemu-iotests/227.out | ||
123 | new file mode 100644 | ||
124 | index XXXXXXX..XXXXXXX | ||
125 | --- /dev/null | ||
126 | +++ b/tests/qemu-iotests/227.out | ||
127 | @@ -XXX,XX +XXX,XX @@ | ||
128 | +QA output created by 227 | ||
129 | + | ||
130 | +=== blockstats with -drive if=virtio === | ||
131 | + | ||
132 | +Testing: -drive driver=null-co,if=virtio | ||
133 | +{ | ||
134 | + QMP_VERSION | ||
135 | +} | ||
136 | +{ | ||
137 | + "return": { | ||
138 | + } | ||
139 | +} | ||
140 | +{ | ||
141 | + "return": [ | ||
142 | + { | ||
143 | + "device": "virtio0", | ||
144 | + "stats": { | ||
145 | + "flush_total_time_ns": 0, | ||
146 | + "wr_highest_offset": 0, | ||
147 | + "wr_total_time_ns": 0, | ||
148 | + "failed_wr_operations": 0, | ||
149 | + "failed_rd_operations": 0, | ||
150 | + "wr_merged": 0, | ||
151 | + "wr_bytes": 0, | ||
152 | + "timed_stats": [ | ||
153 | + ], | ||
154 | + "failed_flush_operations": 0, | ||
155 | + "account_invalid": true, | ||
156 | + "rd_total_time_ns": 0, | ||
157 | + "flush_operations": 0, | ||
158 | + "wr_operations": 0, | ||
159 | + "rd_merged": 0, | ||
160 | + "rd_bytes": 0, | ||
161 | + "invalid_flush_operations": 0, | ||
162 | + "account_failed": true, | ||
163 | + "rd_operations": 0, | ||
164 | + "invalid_wr_operations": 0, | ||
165 | + "invalid_rd_operations": 0 | ||
166 | + }, | ||
167 | + "node-name": "NODE_NAME", | ||
168 | + "qdev": "/machine/peripheral-anon/device[0]/virtio-backend" | ||
169 | + } | ||
170 | + ] | ||
171 | +} | ||
172 | +{ | ||
173 | + "return": { | ||
174 | + } | ||
175 | +} | ||
176 | +{ | ||
177 | + "timestamp": { | ||
178 | + "seconds": TIMESTAMP, | ||
179 | + "microseconds": TIMESTAMP | ||
180 | + }, | ||
181 | + "event": "SHUTDOWN", | ||
182 | + "data": { | ||
183 | + "guest": false | ||
184 | + } | ||
185 | +} | ||
186 | + | ||
187 | + | ||
188 | +=== blockstats with -drive if=none === | ||
189 | + | ||
190 | +Testing: -drive driver=null-co,if=none | ||
191 | +{ | ||
192 | + QMP_VERSION | ||
193 | +} | ||
194 | +{ | ||
195 | + "return": { | ||
196 | + } | ||
197 | +} | ||
198 | +{ | ||
199 | + "return": [ | ||
200 | + { | ||
201 | + "device": "none0", | ||
202 | + "stats": { | ||
203 | + "flush_total_time_ns": 0, | ||
204 | + "wr_highest_offset": 0, | ||
205 | + "wr_total_time_ns": 0, | ||
206 | + "failed_wr_operations": 0, | ||
207 | + "failed_rd_operations": 0, | ||
208 | + "wr_merged": 0, | ||
209 | + "wr_bytes": 0, | ||
210 | + "timed_stats": [ | ||
211 | + ], | ||
212 | + "failed_flush_operations": 0, | ||
213 | + "account_invalid": true, | ||
214 | + "rd_total_time_ns": 0, | ||
215 | + "flush_operations": 0, | ||
216 | + "wr_operations": 0, | ||
217 | + "rd_merged": 0, | ||
218 | + "rd_bytes": 0, | ||
219 | + "invalid_flush_operations": 0, | ||
220 | + "account_failed": true, | ||
221 | + "rd_operations": 0, | ||
222 | + "invalid_wr_operations": 0, | ||
223 | + "invalid_rd_operations": 0 | ||
224 | + }, | ||
225 | + "node-name": "NODE_NAME" | ||
226 | + } | ||
227 | + ] | ||
228 | +} | ||
229 | +{ | ||
230 | + "return": { | ||
231 | + } | ||
232 | +} | ||
233 | +{ | ||
234 | + "timestamp": { | ||
235 | + "seconds": TIMESTAMP, | ||
236 | + "microseconds": TIMESTAMP | ||
237 | + }, | ||
238 | + "event": "SHUTDOWN", | ||
239 | + "data": { | ||
240 | + "guest": false | ||
241 | + } | ||
242 | +} | ||
243 | + | ||
244 | + | ||
245 | +=== blockstats with -blockdev === | ||
246 | + | ||
247 | +Testing: -blockdev driver=null-co,node-name=null | ||
248 | +{ | ||
249 | + QMP_VERSION | ||
250 | +} | ||
251 | +{ | ||
252 | + "return": { | ||
253 | + } | ||
254 | +} | ||
255 | +{ | ||
256 | + "return": [ | ||
257 | + ] | ||
258 | +} | ||
259 | +{ | ||
260 | + "return": { | ||
261 | + } | ||
262 | +} | ||
263 | +{ | ||
264 | + "timestamp": { | ||
265 | + "seconds": TIMESTAMP, | ||
266 | + "microseconds": TIMESTAMP | ||
267 | + }, | ||
268 | + "event": "SHUTDOWN", | ||
269 | + "data": { | ||
270 | + "guest": false | ||
271 | + } | ||
272 | +} | ||
273 | + | ||
274 | + | ||
275 | +=== blockstats with -blockdev and -device === | ||
276 | + | ||
277 | +Testing: -blockdev driver=null-co,node-name=null -device virtio-blk,drive=null,id=virtio0 | ||
278 | +{ | ||
279 | + QMP_VERSION | ||
280 | +} | ||
281 | +{ | ||
282 | + "return": { | ||
283 | + } | ||
284 | +} | ||
285 | +{ | ||
286 | + "return": [ | ||
287 | + { | ||
288 | + "device": "", | ||
289 | + "stats": { | ||
290 | + "flush_total_time_ns": 0, | ||
291 | + "wr_highest_offset": 0, | ||
292 | + "wr_total_time_ns": 0, | ||
293 | + "failed_wr_operations": 0, | ||
294 | + "failed_rd_operations": 0, | ||
295 | + "wr_merged": 0, | ||
296 | + "wr_bytes": 0, | ||
297 | + "timed_stats": [ | ||
298 | + ], | ||
299 | + "failed_flush_operations": 0, | ||
300 | + "account_invalid": false, | ||
301 | + "rd_total_time_ns": 0, | ||
302 | + "flush_operations": 0, | ||
303 | + "wr_operations": 0, | ||
304 | + "rd_merged": 0, | ||
305 | + "rd_bytes": 0, | ||
306 | + "invalid_flush_operations": 0, | ||
307 | + "account_failed": false, | ||
308 | + "rd_operations": 0, | ||
309 | + "invalid_wr_operations": 0, | ||
310 | + "invalid_rd_operations": 0 | ||
311 | + }, | ||
312 | + "node-name": "null", | ||
313 | + "qdev": "/machine/peripheral/virtio0/virtio-backend" | ||
314 | + } | ||
315 | + ] | ||
316 | +} | ||
317 | +{ | ||
318 | + "return": { | ||
319 | + } | ||
320 | +} | ||
321 | +{ | ||
322 | + "timestamp": { | ||
323 | + "seconds": TIMESTAMP, | ||
324 | + "microseconds": TIMESTAMP | ||
325 | + }, | ||
326 | + "event": "SHUTDOWN", | ||
327 | + "data": { | ||
328 | + "guest": false | ||
329 | + } | ||
330 | +} | ||
331 | + | ||
332 | +*** done | ||
333 | diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group | ||
18 | index XXXXXXX..XXXXXXX 100644 | 334 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/hw/block/nvme.c | 335 | --- a/tests/qemu-iotests/group |
20 | +++ b/hw/block/nvme.c | 336 | +++ b/tests/qemu-iotests/group |
21 | @@ -XXX,XX +XXX,XX @@ | 337 | @@ -XXX,XX +XXX,XX @@ |
22 | */ | 338 | 223 rw auto quick |
23 | 339 | 225 rw auto quick | |
24 | /** | 340 | 226 auto quick |
25 | - * Reference Specs: http://www.nvmexpress.org, 1.1, 1.0e | 341 | +227 auto quick |
26 | + * Reference Specs: http://www.nvmexpress.org, 1.2, 1.1, 1.0e | ||
27 | * | ||
28 | * http://www.nvmexpress.org/resources/ | ||
29 | */ | ||
30 | @@ -XXX,XX +XXX,XX @@ | ||
31 | /** | ||
32 | * Usage: add options: | ||
33 | * -drive file=<file>,if=none,id=<drive_id> | ||
34 | - * -device nvme,drive=<drive_id>,serial=<serial>,id=<id[optional]> | ||
35 | + * -device nvme,drive=<drive_id>,serial=<serial>,id=<id[optional]>, \ | ||
36 | + * cmb_size_mb=<cmb_size_mb[optional]> | ||
37 | + * | ||
38 | + * Note cmb_size_mb denotes size of CMB in MB. CMB is assumed to be at | ||
39 | + * offset 0 in BAR2 and supports SQS only for now. | ||
40 | */ | ||
41 | |||
42 | #include "qemu/osdep.h" | ||
43 | @@ -XXX,XX +XXX,XX @@ | ||
44 | |||
45 | static void nvme_process_sq(void *opaque); | ||
46 | |||
47 | +static void nvme_addr_read(NvmeCtrl *n, hwaddr addr, void *buf, int size) | ||
48 | +{ | ||
49 | + if (n->cmbsz && addr >= n->ctrl_mem.addr && | ||
50 | + addr < (n->ctrl_mem.addr + int128_get64(n->ctrl_mem.size))) { | ||
51 | + memcpy(buf, (void *)&n->cmbuf[addr - n->ctrl_mem.addr], size); | ||
52 | + } else { | ||
53 | + pci_dma_read(&n->parent_obj, addr, buf, size); | ||
54 | + } | ||
55 | +} | ||
56 | + | ||
57 | static int nvme_check_sqid(NvmeCtrl *n, uint16_t sqid) | ||
58 | { | ||
59 | return sqid < n->num_queues && n->sq[sqid] != NULL ? 0 : -1; | ||
60 | @@ -XXX,XX +XXX,XX @@ static void nvme_process_sq(void *opaque) | ||
61 | |||
62 | while (!(nvme_sq_empty(sq) || QTAILQ_EMPTY(&sq->req_list))) { | ||
63 | addr = sq->dma_addr + sq->head * n->sqe_size; | ||
64 | - pci_dma_read(&n->parent_obj, addr, (void *)&cmd, sizeof(cmd)); | ||
65 | + nvme_addr_read(n, addr, (void *)&cmd, sizeof(cmd)); | ||
66 | nvme_inc_sq_head(sq); | ||
67 | |||
68 | req = QTAILQ_FIRST(&sq->req_list); | ||
69 | @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps nvme_mmio_ops = { | ||
70 | }, | ||
71 | }; | ||
72 | |||
73 | +static void nvme_cmb_write(void *opaque, hwaddr addr, uint64_t data, | ||
74 | + unsigned size) | ||
75 | +{ | ||
76 | + NvmeCtrl *n = (NvmeCtrl *)opaque; | ||
77 | + memcpy(&n->cmbuf[addr], &data, size); | ||
78 | +} | ||
79 | + | ||
80 | +static uint64_t nvme_cmb_read(void *opaque, hwaddr addr, unsigned size) | ||
81 | +{ | ||
82 | + uint64_t val; | ||
83 | + NvmeCtrl *n = (NvmeCtrl *)opaque; | ||
84 | + | ||
85 | + memcpy(&val, &n->cmbuf[addr], size); | ||
86 | + return val; | ||
87 | +} | ||
88 | + | ||
89 | +static const MemoryRegionOps nvme_cmb_ops = { | ||
90 | + .read = nvme_cmb_read, | ||
91 | + .write = nvme_cmb_write, | ||
92 | + .endianness = DEVICE_LITTLE_ENDIAN, | ||
93 | + .impl = { | ||
94 | + .min_access_size = 2, | ||
95 | + .max_access_size = 8, | ||
96 | + }, | ||
97 | +}; | ||
98 | + | ||
99 | static int nvme_init(PCIDevice *pci_dev) | ||
100 | { | ||
101 | NvmeCtrl *n = NVME(pci_dev); | ||
102 | @@ -XXX,XX +XXX,XX @@ static int nvme_init(PCIDevice *pci_dev) | ||
103 | NVME_CAP_SET_CSS(n->bar.cap, 1); | ||
104 | NVME_CAP_SET_MPSMAX(n->bar.cap, 4); | ||
105 | |||
106 | - n->bar.vs = 0x00010100; | ||
107 | + n->bar.vs = 0x00010200; | ||
108 | n->bar.intmc = n->bar.intms = 0; | ||
109 | |||
110 | + if (n->cmb_size_mb) { | ||
111 | + | ||
112 | + NVME_CMBLOC_SET_BIR(n->bar.cmbloc, 2); | ||
113 | + NVME_CMBLOC_SET_OFST(n->bar.cmbloc, 0); | ||
114 | + | ||
115 | + NVME_CMBSZ_SET_SQS(n->bar.cmbsz, 1); | ||
116 | + NVME_CMBSZ_SET_CQS(n->bar.cmbsz, 0); | ||
117 | + NVME_CMBSZ_SET_LISTS(n->bar.cmbsz, 0); | ||
118 | + NVME_CMBSZ_SET_RDS(n->bar.cmbsz, 0); | ||
119 | + NVME_CMBSZ_SET_WDS(n->bar.cmbsz, 0); | ||
120 | + NVME_CMBSZ_SET_SZU(n->bar.cmbsz, 2); /* MBs */ | ||
121 | + NVME_CMBSZ_SET_SZ(n->bar.cmbsz, n->cmb_size_mb); | ||
122 | + | ||
123 | + n->cmbuf = g_malloc0(NVME_CMBSZ_GETSIZE(n->bar.cmbsz)); | ||
124 | + memory_region_init_io(&n->ctrl_mem, OBJECT(n), &nvme_cmb_ops, n, | ||
125 | + "nvme-cmb", NVME_CMBSZ_GETSIZE(n->bar.cmbsz)); | ||
126 | + pci_register_bar(&n->parent_obj, NVME_CMBLOC_BIR(n->bar.cmbloc), | ||
127 | + PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64 | | ||
128 | + PCI_BASE_ADDRESS_MEM_PREFETCH, &n->ctrl_mem); | ||
129 | + | ||
130 | + } | ||
131 | + | ||
132 | for (i = 0; i < n->num_namespaces; i++) { | ||
133 | NvmeNamespace *ns = &n->namespaces[i]; | ||
134 | NvmeIdNs *id_ns = &ns->id_ns; | ||
135 | @@ -XXX,XX +XXX,XX @@ static void nvme_exit(PCIDevice *pci_dev) | ||
136 | g_free(n->namespaces); | ||
137 | g_free(n->cq); | ||
138 | g_free(n->sq); | ||
139 | + if (n->cmbsz) { | ||
140 | + memory_region_unref(&n->ctrl_mem); | ||
141 | + } | ||
142 | + | ||
143 | msix_uninit_exclusive_bar(pci_dev); | ||
144 | } | ||
145 | |||
146 | static Property nvme_props[] = { | ||
147 | DEFINE_BLOCK_PROPERTIES(NvmeCtrl, conf), | ||
148 | DEFINE_PROP_STRING("serial", NvmeCtrl, serial), | ||
149 | + DEFINE_PROP_UINT32("cmb_size_mb", NvmeCtrl, cmb_size_mb, 0), | ||
150 | DEFINE_PROP_END_OF_LIST(), | ||
151 | }; | ||
152 | |||
153 | diff --git a/hw/block/nvme.h b/hw/block/nvme.h | ||
154 | index XXXXXXX..XXXXXXX 100644 | ||
155 | --- a/hw/block/nvme.h | ||
156 | +++ b/hw/block/nvme.h | ||
157 | @@ -XXX,XX +XXX,XX @@ typedef struct NvmeBar { | ||
158 | uint32_t aqa; | ||
159 | uint64_t asq; | ||
160 | uint64_t acq; | ||
161 | + uint32_t cmbloc; | ||
162 | + uint32_t cmbsz; | ||
163 | } NvmeBar; | ||
164 | |||
165 | enum NvmeCapShift { | ||
166 | @@ -XXX,XX +XXX,XX @@ enum NvmeAqaMask { | ||
167 | #define NVME_AQA_ASQS(aqa) ((aqa >> AQA_ASQS_SHIFT) & AQA_ASQS_MASK) | ||
168 | #define NVME_AQA_ACQS(aqa) ((aqa >> AQA_ACQS_SHIFT) & AQA_ACQS_MASK) | ||
169 | |||
170 | +enum NvmeCmblocShift { | ||
171 | + CMBLOC_BIR_SHIFT = 0, | ||
172 | + CMBLOC_OFST_SHIFT = 12, | ||
173 | +}; | ||
174 | + | ||
175 | +enum NvmeCmblocMask { | ||
176 | + CMBLOC_BIR_MASK = 0x7, | ||
177 | + CMBLOC_OFST_MASK = 0xfffff, | ||
178 | +}; | ||
179 | + | ||
180 | +#define NVME_CMBLOC_BIR(cmbloc) ((cmbloc >> CMBLOC_BIR_SHIFT) & \ | ||
181 | + CMBLOC_BIR_MASK) | ||
182 | +#define NVME_CMBLOC_OFST(cmbloc)((cmbloc >> CMBLOC_OFST_SHIFT) & \ | ||
183 | + CMBLOC_OFST_MASK) | ||
184 | + | ||
185 | +#define NVME_CMBLOC_SET_BIR(cmbloc, val) \ | ||
186 | + (cmbloc |= (uint64_t)(val & CMBLOC_BIR_MASK) << CMBLOC_BIR_SHIFT) | ||
187 | +#define NVME_CMBLOC_SET_OFST(cmbloc, val) \ | ||
188 | + (cmbloc |= (uint64_t)(val & CMBLOC_OFST_MASK) << CMBLOC_OFST_SHIFT) | ||
189 | + | ||
190 | +enum NvmeCmbszShift { | ||
191 | + CMBSZ_SQS_SHIFT = 0, | ||
192 | + CMBSZ_CQS_SHIFT = 1, | ||
193 | + CMBSZ_LISTS_SHIFT = 2, | ||
194 | + CMBSZ_RDS_SHIFT = 3, | ||
195 | + CMBSZ_WDS_SHIFT = 4, | ||
196 | + CMBSZ_SZU_SHIFT = 8, | ||
197 | + CMBSZ_SZ_SHIFT = 12, | ||
198 | +}; | ||
199 | + | ||
200 | +enum NvmeCmbszMask { | ||
201 | + CMBSZ_SQS_MASK = 0x1, | ||
202 | + CMBSZ_CQS_MASK = 0x1, | ||
203 | + CMBSZ_LISTS_MASK = 0x1, | ||
204 | + CMBSZ_RDS_MASK = 0x1, | ||
205 | + CMBSZ_WDS_MASK = 0x1, | ||
206 | + CMBSZ_SZU_MASK = 0xf, | ||
207 | + CMBSZ_SZ_MASK = 0xfffff, | ||
208 | +}; | ||
209 | + | ||
210 | +#define NVME_CMBSZ_SQS(cmbsz) ((cmbsz >> CMBSZ_SQS_SHIFT) & CMBSZ_SQS_MASK) | ||
211 | +#define NVME_CMBSZ_CQS(cmbsz) ((cmbsz >> CMBSZ_CQS_SHIFT) & CMBSZ_CQS_MASK) | ||
212 | +#define NVME_CMBSZ_LISTS(cmbsz)((cmbsz >> CMBSZ_LISTS_SHIFT) & CMBSZ_LISTS_MASK) | ||
213 | +#define NVME_CMBSZ_RDS(cmbsz) ((cmbsz >> CMBSZ_RDS_SHIFT) & CMBSZ_RDS_MASK) | ||
214 | +#define NVME_CMBSZ_WDS(cmbsz) ((cmbsz >> CMBSZ_WDS_SHIFT) & CMBSZ_WDS_MASK) | ||
215 | +#define NVME_CMBSZ_SZU(cmbsz) ((cmbsz >> CMBSZ_SZU_SHIFT) & CMBSZ_SZU_MASK) | ||
216 | +#define NVME_CMBSZ_SZ(cmbsz) ((cmbsz >> CMBSZ_SZ_SHIFT) & CMBSZ_SZ_MASK) | ||
217 | + | ||
218 | +#define NVME_CMBSZ_SET_SQS(cmbsz, val) \ | ||
219 | + (cmbsz |= (uint64_t)(val & CMBSZ_SQS_MASK) << CMBSZ_SQS_SHIFT) | ||
220 | +#define NVME_CMBSZ_SET_CQS(cmbsz, val) \ | ||
221 | + (cmbsz |= (uint64_t)(val & CMBSZ_CQS_MASK) << CMBSZ_CQS_SHIFT) | ||
222 | +#define NVME_CMBSZ_SET_LISTS(cmbsz, val) \ | ||
223 | + (cmbsz |= (uint64_t)(val & CMBSZ_LISTS_MASK) << CMBSZ_LISTS_SHIFT) | ||
224 | +#define NVME_CMBSZ_SET_RDS(cmbsz, val) \ | ||
225 | + (cmbsz |= (uint64_t)(val & CMBSZ_RDS_MASK) << CMBSZ_RDS_SHIFT) | ||
226 | +#define NVME_CMBSZ_SET_WDS(cmbsz, val) \ | ||
227 | + (cmbsz |= (uint64_t)(val & CMBSZ_WDS_MASK) << CMBSZ_WDS_SHIFT) | ||
228 | +#define NVME_CMBSZ_SET_SZU(cmbsz, val) \ | ||
229 | + (cmbsz |= (uint64_t)(val & CMBSZ_SZU_MASK) << CMBSZ_SZU_SHIFT) | ||
230 | +#define NVME_CMBSZ_SET_SZ(cmbsz, val) \ | ||
231 | + (cmbsz |= (uint64_t)(val & CMBSZ_SZ_MASK) << CMBSZ_SZ_SHIFT) | ||
232 | + | ||
233 | +#define NVME_CMBSZ_GETSIZE(cmbsz) \ | ||
234 | + (NVME_CMBSZ_SZ(cmbsz) * (1 << (12 + 4 * NVME_CMBSZ_SZU(cmbsz)))) | ||
235 | + | ||
236 | typedef struct NvmeCmd { | ||
237 | uint8_t opcode; | ||
238 | uint8_t fuse; | ||
239 | @@ -XXX,XX +XXX,XX @@ typedef struct NvmeNamespace { | ||
240 | typedef struct NvmeCtrl { | ||
241 | PCIDevice parent_obj; | ||
242 | MemoryRegion iomem; | ||
243 | + MemoryRegion ctrl_mem; | ||
244 | NvmeBar bar; | ||
245 | BlockConf conf; | ||
246 | |||
247 | @@ -XXX,XX +XXX,XX @@ typedef struct NvmeCtrl { | ||
248 | uint32_t num_queues; | ||
249 | uint32_t max_q_ents; | ||
250 | uint64_t ns_size; | ||
251 | + uint32_t cmb_size_mb; | ||
252 | + uint32_t cmbsz; | ||
253 | + uint32_t cmbloc; | ||
254 | + uint8_t *cmbuf; | ||
255 | |||
256 | char *serial; | ||
257 | NvmeNamespace *namespaces; | ||
258 | -- | 342 | -- |
259 | 1.8.3.1 | 343 | 2.13.6 |
260 | 344 | ||
261 | 345 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | The --image-opts flag can only be used to affect the parsing | ||
4 | of the source image. The target image has to be specified in | ||
5 | the traditional style regardless, since it needs to be passed | ||
6 | to the bdrv_create() API which does not support the new style | ||
7 | opts. | ||
8 | |||
9 | Reviewed-by: Fam Zheng <famz@redhat.com> | ||
10 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
11 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
12 | Message-id: 20170515164712.6643-3-berrange@redhat.com | ||
13 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
14 | --- | ||
15 | qemu-img.c | 9 +++++++-- | ||
16 | 1 file changed, 7 insertions(+), 2 deletions(-) | ||
17 | |||
18 | diff --git a/qemu-img.c b/qemu-img.c | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/qemu-img.c | ||
21 | +++ b/qemu-img.c | ||
22 | @@ -XXX,XX +XXX,XX @@ static int img_dd(int argc, char **argv) | ||
23 | goto out; | ||
24 | } | ||
25 | |||
26 | - blk2 = img_open(image_opts, out.filename, out_fmt, BDRV_O_RDWR, | ||
27 | - false, false, false); | ||
28 | + /* TODO, we can't honour --image-opts for the target, | ||
29 | + * since it needs to be given in a format compatible | ||
30 | + * with the bdrv_create() call above which does not | ||
31 | + * support image-opts style. | ||
32 | + */ | ||
33 | + blk2 = img_open_file(out.filename, out_fmt, BDRV_O_RDWR, | ||
34 | + false, false, false); | ||
35 | |||
36 | if (!blk2) { | ||
37 | ret = -1; | ||
38 | -- | ||
39 | 1.8.3.1 | ||
40 | |||
41 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | The qemu-img dd/convert commands will create an image file and | ||
4 | then try to open it. Historically it has been possible to open | ||
5 | new files without passing any options. With encrypted files | ||
6 | though, the *key-secret options are mandatory, so we need to | ||
7 | provide those options when opening the newly created file. | ||
8 | |||
9 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
10 | Message-id: 20170515164712.6643-5-berrange@redhat.com | ||
11 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
12 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
13 | --- | ||
14 | qemu-img.c | 42 +++++++++++++++++++++++++++++++++++++----- | ||
15 | 1 file changed, 37 insertions(+), 5 deletions(-) | ||
16 | |||
17 | diff --git a/qemu-img.c b/qemu-img.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/qemu-img.c | ||
20 | +++ b/qemu-img.c | ||
21 | @@ -XXX,XX +XXX,XX @@ static BlockBackend *img_open_opts(const char *optstr, | ||
22 | } | ||
23 | |||
24 | static BlockBackend *img_open_file(const char *filename, | ||
25 | + QDict *options, | ||
26 | const char *fmt, int flags, | ||
27 | bool writethrough, bool quiet, | ||
28 | bool force_share) | ||
29 | { | ||
30 | BlockBackend *blk; | ||
31 | Error *local_err = NULL; | ||
32 | - QDict *options = qdict_new(); | ||
33 | |||
34 | + if (!options) { | ||
35 | + options = qdict_new(); | ||
36 | + } | ||
37 | if (fmt) { | ||
38 | qdict_put_str(options, "driver", fmt); | ||
39 | } | ||
40 | @@ -XXX,XX +XXX,XX @@ static BlockBackend *img_open_file(const char *filename, | ||
41 | } | ||
42 | |||
43 | |||
44 | +static int img_add_key_secrets(void *opaque, | ||
45 | + const char *name, const char *value, | ||
46 | + Error **errp) | ||
47 | +{ | ||
48 | + QDict *options = opaque; | ||
49 | + | ||
50 | + if (g_str_has_suffix(name, "key-secret")) { | ||
51 | + qdict_put(options, name, qstring_from_str(value)); | ||
52 | + } | ||
53 | + | ||
54 | + return 0; | ||
55 | +} | ||
56 | + | ||
57 | +static BlockBackend *img_open_new_file(const char *filename, | ||
58 | + QemuOpts *create_opts, | ||
59 | + const char *fmt, int flags, | ||
60 | + bool writethrough, bool quiet, | ||
61 | + bool force_share) | ||
62 | +{ | ||
63 | + QDict *options = NULL; | ||
64 | + | ||
65 | + options = qdict_new(); | ||
66 | + qemu_opt_foreach(create_opts, img_add_key_secrets, options, &error_abort); | ||
67 | + | ||
68 | + return img_open_file(filename, options, fmt, flags, writethrough, quiet, | ||
69 | + force_share); | ||
70 | +} | ||
71 | + | ||
72 | + | ||
73 | static BlockBackend *img_open(bool image_opts, | ||
74 | const char *filename, | ||
75 | const char *fmt, int flags, bool writethrough, | ||
76 | @@ -XXX,XX +XXX,XX @@ static BlockBackend *img_open(bool image_opts, | ||
77 | blk = img_open_opts(filename, opts, flags, writethrough, quiet, | ||
78 | force_share); | ||
79 | } else { | ||
80 | - blk = img_open_file(filename, fmt, flags, writethrough, quiet, | ||
81 | + blk = img_open_file(filename, NULL, fmt, flags, writethrough, quiet, | ||
82 | force_share); | ||
83 | } | ||
84 | return blk; | ||
85 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
86 | * That has to wait for bdrv_create to be improved | ||
87 | * to allow filenames in option syntax | ||
88 | */ | ||
89 | - s.target = img_open_file(out_filename, out_fmt, flags, | ||
90 | - writethrough, quiet, false); | ||
91 | + s.target = img_open_new_file(out_filename, opts, out_fmt, | ||
92 | + flags, writethrough, quiet, false); | ||
93 | } | ||
94 | if (!s.target) { | ||
95 | ret = -1; | ||
96 | @@ -XXX,XX +XXX,XX @@ static int img_dd(int argc, char **argv) | ||
97 | * with the bdrv_create() call above which does not | ||
98 | * support image-opts style. | ||
99 | */ | ||
100 | - blk2 = img_open_file(out.filename, out_fmt, BDRV_O_RDWR, | ||
101 | + blk2 = img_open_file(out.filename, NULL, out_fmt, BDRV_O_RDWR, | ||
102 | false, false, false); | ||
103 | |||
104 | if (!blk2) { | ||
105 | -- | ||
106 | 1.8.3.1 | ||
107 | |||
108 | diff view generated by jsdifflib |