1 | The following changes since commit 9964e96dc9999cf7f7c936ee854a795415d19b60: | 1 | The following changes since commit 7f21573c822805a8e6be379d9bcf3ad9effef3dc: |
---|---|---|---|
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/huth-gitlab/tags/pull-request-2019-10-01' into staging (2019-10-01 13:13:38 +0100) |
4 | 4 | ||
5 | are available in the git repository at: | 5 | are available in the Git repository at: |
6 | |||
7 | 6 | ||
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 352492e5541e293ea8117412ffd171ce1c7ac15d: |
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 | iotests: Remove Python 2 compatibility code (2019-10-02 16:47:23 +0200) |
13 | 12 | ||
14 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Block layer patches: | ||
15 | 15 | ||
16 | Block layer patches | 16 | - Fix internal snapshots with typical -blockdev setups |
17 | - iotests: Require Python 3.6 or later | ||
17 | 18 | ||
18 | ---------------------------------------------------------------- | 19 | ---------------------------------------------------------------- |
19 | Alberto Garcia (2): | 20 | Kevin Wolf (4): |
20 | stream: fix crash in stream_start() when block_job_create() fails | 21 | block/snapshot: Restrict set of snapshot nodes |
21 | qcow2: remove extra local_error variable | 22 | iotests: Test internal snapshots with -blockdev |
23 | iotests: Require Python 3.6 or later | ||
24 | iotests: Remove Python 2 compatibility code | ||
22 | 25 | ||
23 | Daniel P. Berrange (4): | 26 | block/snapshot.c | 26 ++++-- |
24 | qemu-img: add support for --object with 'dd' command | 27 | tests/qemu-iotests/044 | 3 - |
25 | qemu-img: fix --image-opts usage with dd command | 28 | tests/qemu-iotests/163 | 3 - |
26 | qemu-img: introduce --target-image-opts for 'convert' command | 29 | tests/qemu-iotests/267 | 168 ++++++++++++++++++++++++++++++++++++ |
27 | qemu-img: copy *key-secret opts when opening newly created files | 30 | tests/qemu-iotests/267.out | 182 +++++++++++++++++++++++++++++++++++++++ |
31 | tests/qemu-iotests/check | 13 ++- | ||
32 | tests/qemu-iotests/common.filter | 11 ++- | ||
33 | tests/qemu-iotests/group | 1 + | ||
34 | tests/qemu-iotests/iotests.py | 13 +-- | ||
35 | 9 files changed, 392 insertions(+), 28 deletions(-) | ||
36 | create mode 100755 tests/qemu-iotests/267 | ||
37 | create mode 100644 tests/qemu-iotests/267.out | ||
28 | 38 | ||
29 | Eric Blake (1): | ||
30 | block: Tweak error message related to qemu-img amend | ||
31 | |||
32 | Fam Zheng (3): | ||
33 | iotests: 147: Don't test inet6 if not available | ||
34 | qemu-img: Fix documentation of convert | ||
35 | qemu-img: Fix leakage of options on error | ||
36 | |||
37 | Kevin Wolf (3): | ||
38 | qemu-iotests: Test streaming with missing job ID | ||
39 | mirror: Drop permissions on s->target on completion | ||
40 | Merge remote-tracking branch 'mreitz/tags/pull-block-2017-05-29-v3' into queue-block | ||
41 | |||
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 |
Deleted patch | |||
---|---|---|---|
1 | From: Alberto Garcia <berto@igalia.com> | ||
2 | 1 | ||
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 | |||
10 | Cc: qemu-stable@nongnu.org | ||
11 | Reported-by: Kashyap Chamarthy <kchamart@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> | ||
15 | --- | ||
16 | block/stream.c | 2 +- | ||
17 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
18 | |||
19 | diff --git a/block/stream.c b/block/stream.c | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/block/stream.c | ||
22 | +++ b/block/stream.c | ||
23 | @@ -XXX,XX +XXX,XX @@ void stream_start(const char *job_id, BlockDriverState *bs, | ||
24 | |||
25 | fail: | ||
26 | if (orig_bs_flags != bdrv_get_flags(bs)) { | ||
27 | - bdrv_reopen(bs, s->bs_flags, NULL); | ||
28 | + bdrv_reopen(bs, orig_bs_flags, NULL); | ||
29 | } | ||
30 | } | ||
31 | -- | ||
32 | 1.8.3.1 | ||
33 | |||
34 | diff view generated by jsdifflib |
1 | This fixes an assertion failure that was triggered by qemu-iotests 129 | 1 | Nodes involved in internal snapshots were those that were returned by |
---|---|---|---|
2 | on some CI host, while the same test case didn't seem to fail on other | 2 | bdrv_next(), inserted and not read-only. bdrv_next() in turn returns all |
3 | hosts. | 3 | nodes that are either the root node of a BlockBackend or monitor-owned |
4 | nodes. | ||
4 | 5 | ||
5 | Essentially the problem is that the blk_unref(s->target) in | 6 | With the typical -drive use, this worked well enough. However, in the |
6 | mirror_exit() doesn't necessarily mean that the BlockBackend goes away | 7 | typical -blockdev case, the user defines one node per option, making all |
7 | immediately. It is possible that the job completion was triggered nested | 8 | nodes monitor-owned nodes. This includes protocol nodes etc. which often |
8 | in mirror_drain(), which looks like this: | 9 | are not snapshottable, so "savevm" only returns an error. |
9 | 10 | ||
10 | BlockBackend *target = s->target; | 11 | Change the conditions so that internal snapshot still include all nodes |
11 | blk_ref(target); | 12 | that have a BlockBackend attached (we definitely want to snapshot |
12 | blk_drain(target); | 13 | anything attached to a guest device and probably also the built-in NBD |
13 | blk_unref(target); | 14 | server; snapshotting block job BlockBackends is more of an accident, but |
15 | a preexisting one), but other monitor-owned nodes are only included if | ||
16 | they have no parents. | ||
14 | 17 | ||
15 | In this case, the write permissions for s->target are retained until | 18 | This makes internal snapshots usable again with typical -blockdev |
16 | after blk_drain(), which makes removing mirror_top_bs fail for the | 19 | configurations. |
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 | 20 | ||
24 | Cc: qemu-stable@nongnu.org | 21 | Cc: qemu-stable@nongnu.org |
25 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 22 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
26 | Acked-by: Paolo Bonzini <pbonzini@redhat.com> | 23 | Reviewed-by: Eric Blake <eblake@redhat.com> |
27 | Reviewed-by: Max Reitz <mreitz@redhat.com> | 24 | Reviewed-by: Peter Krempa <pkrempa@redhat.com> |
25 | Tested-by: Peter Krempa <pkrempa@redhat.com> | ||
28 | --- | 26 | --- |
29 | block/mirror.c | 7 ++++++- | 27 | block/snapshot.c | 26 +++++++++++++++++++------- |
30 | 1 file changed, 6 insertions(+), 1 deletion(-) | 28 | 1 file changed, 19 insertions(+), 7 deletions(-) |
31 | 29 | ||
32 | diff --git a/block/mirror.c b/block/mirror.c | 30 | diff --git a/block/snapshot.c b/block/snapshot.c |
33 | index XXXXXXX..XXXXXXX 100644 | 31 | index XXXXXXX..XXXXXXX 100644 |
34 | --- a/block/mirror.c | 32 | --- a/block/snapshot.c |
35 | +++ b/block/mirror.c | 33 | +++ b/block/snapshot.c |
36 | @@ -XXX,XX +XXX,XX @@ static void mirror_exit(BlockJob *job, void *opaque) | 34 | @@ -XXX,XX +XXX,XX @@ |
37 | 35 | #include "qapi/qmp/qerror.h" | |
38 | /* Remove target parent that still uses BLK_PERM_WRITE/RESIZE before | 36 | #include "qapi/qmp/qstring.h" |
39 | * inserting target_bs at s->to_replace, where we might not be able to get | 37 | #include "qemu/option.h" |
40 | - * these permissions. */ | 38 | +#include "sysemu/block-backend.h" |
41 | + * these permissions. | 39 | |
42 | + * | 40 | QemuOptsList internal_snapshot_opts = { |
43 | + * Note that blk_unref() alone doesn't necessarily drop permissions because | 41 | .name = "snapshot", |
44 | + * we might be running nested inside mirror_drain(), which takes an extra | 42 | @@ -XXX,XX +XXX,XX @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs, |
45 | + * reference, so use an explicit blk_set_perm() first. */ | 43 | return ret; |
46 | + blk_set_perm(s->target, 0, BLK_PERM_ALL, &error_abort); | 44 | } |
47 | blk_unref(s->target); | 45 | |
48 | s->target = NULL; | 46 | +static bool bdrv_all_snapshots_includes_bs(BlockDriverState *bs) |
49 | 47 | +{ | |
48 | + if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { | ||
49 | + return false; | ||
50 | + } | ||
51 | + | ||
52 | + /* Include all nodes that are either in use by a BlockBackend, or that | ||
53 | + * aren't attached to any node, but owned by the monitor. */ | ||
54 | + return bdrv_has_blk(bs) || QLIST_EMPTY(&bs->parents); | ||
55 | +} | ||
56 | |||
57 | /* Group operations. All block drivers are involved. | ||
58 | * These functions will properly handle dataplane (take aio_context_acquire | ||
59 | @@ -XXX,XX +XXX,XX @@ bool bdrv_all_can_snapshot(BlockDriverState **first_bad_bs) | ||
60 | AioContext *ctx = bdrv_get_aio_context(bs); | ||
61 | |||
62 | aio_context_acquire(ctx); | ||
63 | - if (bdrv_is_inserted(bs) && !bdrv_is_read_only(bs)) { | ||
64 | + if (bdrv_all_snapshots_includes_bs(bs)) { | ||
65 | ok = bdrv_can_snapshot(bs); | ||
66 | } | ||
67 | aio_context_release(ctx); | ||
68 | @@ -XXX,XX +XXX,XX @@ int bdrv_all_delete_snapshot(const char *name, BlockDriverState **first_bad_bs, | ||
69 | AioContext *ctx = bdrv_get_aio_context(bs); | ||
70 | |||
71 | aio_context_acquire(ctx); | ||
72 | - if (bdrv_can_snapshot(bs) && | ||
73 | - bdrv_snapshot_find(bs, snapshot, name) >= 0) { | ||
74 | + if (bdrv_all_snapshots_includes_bs(bs) && | ||
75 | + bdrv_snapshot_find(bs, snapshot, name) >= 0) | ||
76 | + { | ||
77 | ret = bdrv_snapshot_delete(bs, snapshot->id_str, | ||
78 | snapshot->name, err); | ||
79 | } | ||
80 | @@ -XXX,XX +XXX,XX @@ int bdrv_all_goto_snapshot(const char *name, BlockDriverState **first_bad_bs, | ||
81 | AioContext *ctx = bdrv_get_aio_context(bs); | ||
82 | |||
83 | aio_context_acquire(ctx); | ||
84 | - if (bdrv_can_snapshot(bs)) { | ||
85 | + if (bdrv_all_snapshots_includes_bs(bs)) { | ||
86 | ret = bdrv_snapshot_goto(bs, name, errp); | ||
87 | } | ||
88 | aio_context_release(ctx); | ||
89 | @@ -XXX,XX +XXX,XX @@ int bdrv_all_find_snapshot(const char *name, BlockDriverState **first_bad_bs) | ||
90 | AioContext *ctx = bdrv_get_aio_context(bs); | ||
91 | |||
92 | aio_context_acquire(ctx); | ||
93 | - if (bdrv_can_snapshot(bs)) { | ||
94 | + if (bdrv_all_snapshots_includes_bs(bs)) { | ||
95 | err = bdrv_snapshot_find(bs, &sn, name); | ||
96 | } | ||
97 | aio_context_release(ctx); | ||
98 | @@ -XXX,XX +XXX,XX @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn, | ||
99 | if (bs == vm_state_bs) { | ||
100 | sn->vm_state_size = vm_state_size; | ||
101 | err = bdrv_snapshot_create(bs, sn); | ||
102 | - } else if (bdrv_can_snapshot(bs)) { | ||
103 | + } else if (bdrv_all_snapshots_includes_bs(bs)) { | ||
104 | sn->vm_state_size = 0; | ||
105 | err = bdrv_snapshot_create(bs, sn); | ||
106 | } | ||
107 | @@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_all_find_vmstate_bs(void) | ||
108 | bool found; | ||
109 | |||
110 | aio_context_acquire(ctx); | ||
111 | - found = bdrv_can_snapshot(bs); | ||
112 | + found = bdrv_all_snapshots_includes_bs(bs) && bdrv_can_snapshot(bs); | ||
113 | aio_context_release(ctx); | ||
114 | |||
115 | if (found) { | ||
50 | -- | 116 | -- |
51 | 1.8.3.1 | 117 | 2.20.1 |
52 | 118 | ||
53 | 119 | diff view generated by jsdifflib |
1 | From: Max Reitz <mreitz@redhat.com> | 1 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
---|---|---|---|
2 | Reviewed-by: Peter Krempa <pkrempa@redhat.com> | ||
3 | Tested-by: Peter Krempa <pkrempa@redhat.com> | ||
4 | --- | ||
5 | tests/qemu-iotests/267 | 168 ++++++++++++++++++++++++++++ | ||
6 | tests/qemu-iotests/267.out | 182 +++++++++++++++++++++++++++++++ | ||
7 | tests/qemu-iotests/common.filter | 11 +- | ||
8 | tests/qemu-iotests/group | 1 + | ||
9 | 4 files changed, 358 insertions(+), 4 deletions(-) | ||
10 | create mode 100755 tests/qemu-iotests/267 | ||
11 | create mode 100644 tests/qemu-iotests/267.out | ||
2 | 12 | ||
3 | The file drivers' *_parse_filename() implementations just strip the | 13 | diff --git a/tests/qemu-iotests/267 b/tests/qemu-iotests/267 |
4 | optional protocol prefix off the filename. However, for e.g. | 14 | new file mode 100755 |
5 | "file:foo:bar", this would lead to "foo:bar" being stored as the BDS's | 15 | index XXXXXXX..XXXXXXX |
6 | filename which looks like it should be managed using the "foo" protocol. | 16 | --- /dev/null |
7 | This is especially troublesome if you then try to resolve a backing | 17 | +++ b/tests/qemu-iotests/267 |
8 | filename based on "foo:bar". | 18 | @@ -XXX,XX +XXX,XX @@ |
9 | 19 | +#!/usr/bin/env bash | |
10 | This issue can only occur if the stripped part is a relative filename | 20 | +# |
11 | ("file:/foo:bar" will be shortened to "/foo:bar" and having a slash | 21 | +# Test which nodes are involved in internal snapshots |
12 | before the first colon means that "/foo" is not recognized as a protocol | 22 | +# |
13 | part). Therefore, we can easily fix it by prepending "./" to such | 23 | +# Copyright (C) 2019 Red Hat, Inc. |
14 | filenames. | 24 | +# |
15 | 25 | +# This program is free software; you can redistribute it and/or modify | |
16 | Before this patch: | 26 | +# it under the terms of the GNU General Public License as published by |
17 | $ ./qemu-img create -f qcow2 backing.qcow2 64M | 27 | +# the Free Software Foundation; either version 2 of the License, or |
18 | Formatting 'backing.qcow2', fmt=qcow2 size=67108864 encryption=off | 28 | +# (at your option) any later version. |
19 | cluster_size=65536 lazy_refcounts=off refcount_bits=16 | 29 | +# |
20 | $ ./qemu-img create -f qcow2 -b backing.qcow2 file:top:image.qcow2 | 30 | +# This program is distributed in the hope that it will be useful, |
21 | Formatting 'file:top:image.qcow2', fmt=qcow2 size=67108864 | 31 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
22 | backing_file=backing.qcow2 encryption=off cluster_size=65536 | 32 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
23 | lazy_refcounts=off refcount_bits=16 | 33 | +# GNU General Public License for more details. |
24 | $ ./qemu-io file:top:image.qcow2 | 34 | +# |
25 | can't open device file:top:image.qcow2: Could not open backing file: | 35 | +# You should have received a copy of the GNU General Public License |
26 | Unknown protocol 'top' | 36 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
27 | 37 | +# | |
28 | After this patch: | 38 | + |
29 | $ ./qemu-io file:top:image.qcow2 | 39 | +# creator |
30 | [no error] | 40 | +owner=kwolf@redhat.com |
31 | 41 | + | |
32 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 42 | +seq=`basename $0` |
33 | Message-id: 20170522195217.12991-3-mreitz@redhat.com | 43 | +echo "QA output created by $seq" |
34 | Reviewed-by: Eric Blake <eblake@redhat.com> | 44 | + |
35 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 45 | +status=1 # failure is the default! |
36 | --- | 46 | + |
37 | block.c | 35 +++++++++++++++++++++++++++++++++++ | 47 | +_cleanup() |
38 | block/file-posix.c | 17 +++-------------- | 48 | +{ |
39 | block/file-win32.c | 12 ++---------- | 49 | + _cleanup_test_img |
40 | include/block/block_int.h | 3 +++ | 50 | + rm -f "$TEST_DIR/nbd" |
41 | 4 files changed, 43 insertions(+), 24 deletions(-) | 51 | +} |
42 | 52 | +trap "_cleanup; exit \$status" 0 1 2 3 15 | |
43 | diff --git a/block.c b/block.c | 53 | + |
54 | +# get standard environment, filters and checks | ||
55 | +. ./common.rc | ||
56 | +. ./common.filter | ||
57 | + | ||
58 | +_supported_fmt qcow2 | ||
59 | +_supported_proto file | ||
60 | +_supported_os Linux | ||
61 | + | ||
62 | +# Internal snapshots are (currently) impossible with refcount_bits=1 | ||
63 | +_unsupported_imgopts 'refcount_bits=1[^0-9]' | ||
64 | + | ||
65 | +do_run_qemu() | ||
66 | +{ | ||
67 | + echo Testing: "$@" | ||
68 | + ( | ||
69 | + if ! test -t 0; then | ||
70 | + while read cmd; do | ||
71 | + echo $cmd | ||
72 | + done | ||
73 | + fi | ||
74 | + echo quit | ||
75 | + ) | $QEMU -nographic -monitor stdio -nodefaults "$@" | ||
76 | + echo | ||
77 | +} | ||
78 | + | ||
79 | +run_qemu() | ||
80 | +{ | ||
81 | + do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_hmp | | ||
82 | + _filter_generated_node_ids | _filter_imgfmt | _filter_vmstate_size | ||
83 | +} | ||
84 | + | ||
85 | +size=128M | ||
86 | + | ||
87 | +run_test() | ||
88 | +{ | ||
89 | + _make_test_img $size | ||
90 | + printf "savevm snap0\ninfo snapshots\nloadvm snap0\n" | run_qemu "$@" | _filter_date | ||
91 | +} | ||
92 | + | ||
93 | + | ||
94 | +echo | ||
95 | +echo "=== No block devices at all ===" | ||
96 | +echo | ||
97 | + | ||
98 | +run_test | ||
99 | + | ||
100 | +echo | ||
101 | +echo "=== -drive if=none ===" | ||
102 | +echo | ||
103 | + | ||
104 | +run_test -drive driver=file,file="$TEST_IMG",if=none | ||
105 | +run_test -drive driver=$IMGFMT,file="$TEST_IMG",if=none | ||
106 | +run_test -drive driver=$IMGFMT,file="$TEST_IMG",if=none -device virtio-blk,drive=none0 | ||
107 | + | ||
108 | +echo | ||
109 | +echo "=== -drive if=virtio ===" | ||
110 | +echo | ||
111 | + | ||
112 | +run_test -drive driver=file,file="$TEST_IMG",if=virtio | ||
113 | +run_test -drive driver=$IMGFMT,file="$TEST_IMG",if=virtio | ||
114 | + | ||
115 | +echo | ||
116 | +echo "=== Simple -blockdev ===" | ||
117 | +echo | ||
118 | + | ||
119 | +run_test -blockdev driver=file,filename="$TEST_IMG",node-name=file | ||
120 | +run_test -blockdev driver=file,filename="$TEST_IMG",node-name=file \ | ||
121 | + -blockdev driver=$IMGFMT,file=file,node-name=fmt | ||
122 | +run_test -blockdev driver=file,filename="$TEST_IMG",node-name=file \ | ||
123 | + -blockdev driver=raw,file=file,node-name=raw \ | ||
124 | + -blockdev driver=$IMGFMT,file=raw,node-name=fmt | ||
125 | + | ||
126 | +echo | ||
127 | +echo "=== -blockdev with a filter on top ===" | ||
128 | +echo | ||
129 | + | ||
130 | +run_test -blockdev driver=file,filename="$TEST_IMG",node-name=file \ | ||
131 | + -blockdev driver=$IMGFMT,file=file,node-name=fmt \ | ||
132 | + -blockdev driver=copy-on-read,file=fmt,node-name=filter | ||
133 | + | ||
134 | +echo | ||
135 | +echo "=== -blockdev with a backing file ===" | ||
136 | +echo | ||
137 | + | ||
138 | +TEST_IMG="$TEST_IMG.base" _make_test_img $size | ||
139 | + | ||
140 | +IMGOPTS="backing_file=$TEST_IMG.base" \ | ||
141 | +run_test -blockdev driver=file,filename="$TEST_IMG.base",node-name=backing-file \ | ||
142 | + -blockdev driver=file,filename="$TEST_IMG",node-name=file \ | ||
143 | + -blockdev driver=$IMGFMT,file=file,backing=backing-file,node-name=fmt | ||
144 | + | ||
145 | +IMGOPTS="backing_file=$TEST_IMG.base" \ | ||
146 | +run_test -blockdev driver=file,filename="$TEST_IMG.base",node-name=backing-file \ | ||
147 | + -blockdev driver=$IMGFMT,file=backing-file,node-name=backing-fmt \ | ||
148 | + -blockdev driver=file,filename="$TEST_IMG",node-name=file \ | ||
149 | + -blockdev driver=$IMGFMT,file=file,backing=backing-fmt,node-name=fmt | ||
150 | + | ||
151 | +# A snapshot should be present on the overlay, but not the backing file | ||
152 | +echo Internal snapshots on overlay: | ||
153 | +$QEMU_IMG snapshot -l "$TEST_IMG" | _filter_date | _filter_vmstate_size | ||
154 | + | ||
155 | +echo Internal snapshots on backing file: | ||
156 | +$QEMU_IMG snapshot -l "$TEST_IMG.base" | _filter_date | _filter_vmstate_size | ||
157 | + | ||
158 | +echo | ||
159 | +echo "=== -blockdev with NBD server on the backing file ===" | ||
160 | +echo | ||
161 | + | ||
162 | +IMGOPTS="backing_file=$TEST_IMG.base" _make_test_img $size | ||
163 | +cat <<EOF | | ||
164 | +nbd_server_start unix:$TEST_DIR/nbd | ||
165 | +nbd_server_add -w backing-fmt | ||
166 | +savevm snap0 | ||
167 | +info snapshots | ||
168 | +loadvm snap0 | ||
169 | +EOF | ||
170 | +run_qemu -blockdev driver=file,filename="$TEST_IMG.base",node-name=backing-file \ | ||
171 | + -blockdev driver=$IMGFMT,file=backing-file,node-name=backing-fmt \ | ||
172 | + -blockdev driver=file,filename="$TEST_IMG",node-name=file \ | ||
173 | + -blockdev driver=$IMGFMT,file=file,backing=backing-fmt,node-name=fmt | | ||
174 | + _filter_date | ||
175 | + | ||
176 | +# This time, a snapshot should be created on both files | ||
177 | +echo Internal snapshots on overlay: | ||
178 | +$QEMU_IMG snapshot -l "$TEST_IMG" | _filter_date | _filter_vmstate_size | ||
179 | + | ||
180 | +echo Internal snapshots on backing file: | ||
181 | +$QEMU_IMG snapshot -l "$TEST_IMG.base" | _filter_date | _filter_vmstate_size | ||
182 | + | ||
183 | +# success, all done | ||
184 | +echo "*** done" | ||
185 | +rm -f $seq.full | ||
186 | +status=0 | ||
187 | diff --git a/tests/qemu-iotests/267.out b/tests/qemu-iotests/267.out | ||
188 | new file mode 100644 | ||
189 | index XXXXXXX..XXXXXXX | ||
190 | --- /dev/null | ||
191 | +++ b/tests/qemu-iotests/267.out | ||
192 | @@ -XXX,XX +XXX,XX @@ | ||
193 | +QA output created by 267 | ||
194 | + | ||
195 | +=== No block devices at all === | ||
196 | + | ||
197 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 | ||
198 | +Testing: | ||
199 | +QEMU X.Y.Z monitor - type 'help' for more information | ||
200 | +(qemu) savevm snap0 | ||
201 | +Error: No block device can accept snapshots | ||
202 | +(qemu) info snapshots | ||
203 | +No available block device supports snapshots | ||
204 | +(qemu) loadvm snap0 | ||
205 | +Error: No block device supports snapshots | ||
206 | +(qemu) quit | ||
207 | + | ||
208 | + | ||
209 | +=== -drive if=none === | ||
210 | + | ||
211 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 | ||
212 | +Testing: -drive driver=file,file=TEST_DIR/t.IMGFMT,if=none | ||
213 | +QEMU X.Y.Z monitor - type 'help' for more information | ||
214 | +(qemu) savevm snap0 | ||
215 | +Error: Device 'none0' is writable but does not support snapshots | ||
216 | +(qemu) info snapshots | ||
217 | +No available block device supports snapshots | ||
218 | +(qemu) loadvm snap0 | ||
219 | +Error: Device 'none0' is writable but does not support snapshots | ||
220 | +(qemu) quit | ||
221 | + | ||
222 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 | ||
223 | +Testing: -drive driver=IMGFMT,file=TEST_DIR/t.IMGFMT,if=none | ||
224 | +QEMU X.Y.Z monitor - type 'help' for more information | ||
225 | +(qemu) savevm snap0 | ||
226 | +(qemu) info snapshots | ||
227 | +List of snapshots present on all disks: | ||
228 | +ID TAG VM SIZE DATE VM CLOCK | ||
229 | +-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 | ||
230 | +(qemu) loadvm snap0 | ||
231 | +(qemu) quit | ||
232 | + | ||
233 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 | ||
234 | +Testing: -drive driver=IMGFMT,file=TEST_DIR/t.IMGFMT,if=none -device virtio-blk,drive=none0 | ||
235 | +QEMU X.Y.Z monitor - type 'help' for more information | ||
236 | +(qemu) savevm snap0 | ||
237 | +(qemu) info snapshots | ||
238 | +List of snapshots present on all disks: | ||
239 | +ID TAG VM SIZE DATE VM CLOCK | ||
240 | +-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 | ||
241 | +(qemu) loadvm snap0 | ||
242 | +(qemu) quit | ||
243 | + | ||
244 | + | ||
245 | +=== -drive if=virtio === | ||
246 | + | ||
247 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 | ||
248 | +Testing: -drive driver=file,file=TEST_DIR/t.IMGFMT,if=virtio | ||
249 | +QEMU X.Y.Z monitor - type 'help' for more information | ||
250 | +(qemu) savevm snap0 | ||
251 | +Error: Device 'virtio0' is writable but does not support snapshots | ||
252 | +(qemu) info snapshots | ||
253 | +No available block device supports snapshots | ||
254 | +(qemu) loadvm snap0 | ||
255 | +Error: Device 'virtio0' is writable but does not support snapshots | ||
256 | +(qemu) quit | ||
257 | + | ||
258 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 | ||
259 | +Testing: -drive driver=IMGFMT,file=TEST_DIR/t.IMGFMT,if=virtio | ||
260 | +QEMU X.Y.Z monitor - type 'help' for more information | ||
261 | +(qemu) savevm snap0 | ||
262 | +(qemu) info snapshots | ||
263 | +List of snapshots present on all disks: | ||
264 | +ID TAG VM SIZE DATE VM CLOCK | ||
265 | +-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 | ||
266 | +(qemu) loadvm snap0 | ||
267 | +(qemu) quit | ||
268 | + | ||
269 | + | ||
270 | +=== Simple -blockdev === | ||
271 | + | ||
272 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 | ||
273 | +Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=file | ||
274 | +QEMU X.Y.Z monitor - type 'help' for more information | ||
275 | +(qemu) savevm snap0 | ||
276 | +Error: Device '' is writable but does not support snapshots | ||
277 | +(qemu) info snapshots | ||
278 | +No available block device supports snapshots | ||
279 | +(qemu) loadvm snap0 | ||
280 | +Error: Device '' is writable but does not support snapshots | ||
281 | +(qemu) quit | ||
282 | + | ||
283 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 | ||
284 | +Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=file -blockdev driver=IMGFMT,file=file,node-name=fmt | ||
285 | +QEMU X.Y.Z monitor - type 'help' for more information | ||
286 | +(qemu) savevm snap0 | ||
287 | +(qemu) info snapshots | ||
288 | +List of snapshots present on all disks: | ||
289 | +ID TAG VM SIZE DATE VM CLOCK | ||
290 | +-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 | ||
291 | +(qemu) loadvm snap0 | ||
292 | +(qemu) quit | ||
293 | + | ||
294 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 | ||
295 | +Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=file -blockdev driver=raw,file=file,node-name=raw -blockdev driver=IMGFMT,file=raw,node-name=fmt | ||
296 | +QEMU X.Y.Z monitor - type 'help' for more information | ||
297 | +(qemu) savevm snap0 | ||
298 | +(qemu) info snapshots | ||
299 | +List of snapshots present on all disks: | ||
300 | +ID TAG VM SIZE DATE VM CLOCK | ||
301 | +-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 | ||
302 | +(qemu) loadvm snap0 | ||
303 | +(qemu) quit | ||
304 | + | ||
305 | + | ||
306 | +=== -blockdev with a filter on top === | ||
307 | + | ||
308 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 | ||
309 | +Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=file -blockdev driver=IMGFMT,file=file,node-name=fmt -blockdev driver=copy-on-read,file=fmt,node-name=filter | ||
310 | +QEMU X.Y.Z monitor - type 'help' for more information | ||
311 | +(qemu) savevm snap0 | ||
312 | +(qemu) info snapshots | ||
313 | +List of snapshots present on all disks: | ||
314 | +ID TAG VM SIZE DATE VM CLOCK | ||
315 | +-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 | ||
316 | +(qemu) loadvm snap0 | ||
317 | +(qemu) quit | ||
318 | + | ||
319 | + | ||
320 | +=== -blockdev with a backing file === | ||
321 | + | ||
322 | +Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728 | ||
323 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base | ||
324 | +Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT.base,node-name=backing-file -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=file -blockdev driver=IMGFMT,file=file,backing=backing-file,node-name=fmt | ||
325 | +QEMU X.Y.Z monitor - type 'help' for more information | ||
326 | +(qemu) savevm snap0 | ||
327 | +(qemu) info snapshots | ||
328 | +List of snapshots present on all disks: | ||
329 | +ID TAG VM SIZE DATE VM CLOCK | ||
330 | +-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 | ||
331 | +(qemu) loadvm snap0 | ||
332 | +(qemu) quit | ||
333 | + | ||
334 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base | ||
335 | +Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT.base,node-name=backing-file -blockdev driver=IMGFMT,file=backing-file,node-name=backing-fmt -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=file -blockdev driver=IMGFMT,file=file,backing=backing-fmt,node-name=fmt | ||
336 | +QEMU X.Y.Z monitor - type 'help' for more information | ||
337 | +(qemu) savevm snap0 | ||
338 | +(qemu) info snapshots | ||
339 | +List of snapshots present on all disks: | ||
340 | +ID TAG VM SIZE DATE VM CLOCK | ||
341 | +-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 | ||
342 | +(qemu) loadvm snap0 | ||
343 | +(qemu) quit | ||
344 | + | ||
345 | +Internal snapshots on overlay: | ||
346 | +Snapshot list: | ||
347 | +ID TAG VM SIZE DATE VM CLOCK | ||
348 | +1 snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 | ||
349 | +Internal snapshots on backing file: | ||
350 | + | ||
351 | +=== -blockdev with NBD server on the backing file === | ||
352 | + | ||
353 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base | ||
354 | +Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT.base,node-name=backing-file -blockdev driver=IMGFMT,file=backing-file,node-name=backing-fmt -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=file -blockdev driver=IMGFMT,file=file,backing=backing-fmt,node-name=fmt | ||
355 | +QEMU X.Y.Z monitor - type 'help' for more information | ||
356 | +(qemu) nbd_server_start unix:TEST_DIR/nbd | ||
357 | +(qemu) nbd_server_add -w backing-fmt | ||
358 | +(qemu) savevm snap0 | ||
359 | +(qemu) info snapshots | ||
360 | +List of snapshots present on all disks: | ||
361 | +ID TAG VM SIZE DATE VM CLOCK | ||
362 | +-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 | ||
363 | +(qemu) loadvm snap0 | ||
364 | +(qemu) quit | ||
365 | + | ||
366 | +Internal snapshots on overlay: | ||
367 | +Snapshot list: | ||
368 | +ID TAG VM SIZE DATE VM CLOCK | ||
369 | +1 snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 | ||
370 | +Internal snapshots on backing file: | ||
371 | +Snapshot list: | ||
372 | +ID TAG VM SIZE DATE VM CLOCK | ||
373 | +1 snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000 | ||
374 | +*** done | ||
375 | diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter | ||
44 | index XXXXXXX..XXXXXXX 100644 | 376 | index XXXXXXX..XXXXXXX 100644 |
45 | --- a/block.c | 377 | --- a/tests/qemu-iotests/common.filter |
46 | +++ b/block.c | 378 | +++ b/tests/qemu-iotests/common.filter |
47 | @@ -XXX,XX +XXX,XX @@ void path_combine(char *dest, int dest_size, | 379 | @@ -XXX,XX +XXX,XX @@ |
48 | } | 380 | # standard filters |
381 | # | ||
382 | |||
383 | -# ctime(3) dates | ||
384 | -# | ||
385 | _filter_date() | ||
386 | { | ||
387 | - $SED \ | ||
388 | - -e 's/[A-Z][a-z][a-z] [A-z][a-z][a-z] *[0-9][0-9]* [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9][0-9][0-9][0-9]$/DATE/' | ||
389 | + $SED -re 's/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/yyyy-mm-dd hh:mm:ss/' | ||
390 | +} | ||
391 | + | ||
392 | +_filter_vmstate_size() | ||
393 | +{ | ||
394 | + $SED -re 's/[0-9. ]{5} [KMGT]iB/ SIZE/' \ | ||
395 | + -re 's/[0-9. ]{5} B/ SIZE/' | ||
49 | } | 396 | } |
50 | 397 | ||
51 | +/* | 398 | _filter_generated_node_ids() |
52 | + * Helper function for bdrv_parse_filename() implementations to remove optional | 399 | diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group |
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 | ||
90 | index XXXXXXX..XXXXXXX 100644 | 400 | index XXXXXXX..XXXXXXX 100644 |
91 | --- a/block/file-posix.c | 401 | --- a/tests/qemu-iotests/group |
92 | +++ b/block/file-posix.c | 402 | +++ b/tests/qemu-iotests/group |
93 | @@ -XXX,XX +XXX,XX @@ static void raw_parse_flags(int bdrv_flags, int *open_flags) | 403 | @@ -XXX,XX +XXX,XX @@ |
94 | static void raw_parse_filename(const char *filename, QDict *options, | 404 | 263 rw quick |
95 | Error **errp) | 405 | 265 rw auto quick |
96 | { | 406 | 266 rw quick |
97 | - /* The filename does not have to be prefixed by the protocol name, since | 407 | +267 rw auto quick snapshot |
98 | - * "file" is the default protocol; therefore, the return value of this | ||
99 | - * function call can be ignored. */ | ||
100 | - strstart(filename, "file:", &filename); | ||
101 | - | ||
102 | - qdict_put_str(options, "filename", filename); | ||
103 | + bdrv_parse_filename_strip_prefix(filename, "file:", options); | ||
104 | } | ||
105 | |||
106 | static QemuOptsList raw_runtime_opts = { | ||
107 | @@ -XXX,XX +XXX,XX @@ static int check_hdev_writable(BDRVRawState *s) | ||
108 | static void hdev_parse_filename(const char *filename, QDict *options, | ||
109 | Error **errp) | ||
110 | { | ||
111 | - /* The prefix is optional, just as for "file". */ | ||
112 | - strstart(filename, "host_device:", &filename); | ||
113 | - | ||
114 | - qdict_put_str(options, "filename", filename); | ||
115 | + bdrv_parse_filename_strip_prefix(filename, "host_device:", options); | ||
116 | } | ||
117 | |||
118 | static bool hdev_is_sg(BlockDriverState *bs) | ||
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 | -- | 408 | -- |
176 | 1.8.3.1 | 409 | 2.20.1 |
177 | 410 | ||
178 | 411 | diff view generated by jsdifflib |
1 | From: Max Reitz <mreitz@redhat.com> | 1 | Running iotests is not required to build QEMU, so we can have stricter |
---|---|---|---|
2 | version requirements for Python here and can make use of new features | ||
3 | and drop compatibility code earlier. | ||
2 | 4 | ||
3 | path_combine() naturally tries to preserve a protocol prefix. However, | 5 | This makes qemu-iotests skip all Python tests if a Python version before |
4 | it recognizes such a prefix by scanning for the first colon; which is | 6 | 3.6 is used for the build. |
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 | 7 | ||
8 | A protocol prefix that is not recognized by path_has_protocol() is none, | 8 | Suggested-by: Eduardo Habkost <ehabkost@redhat.com> |
9 | and should thus not be taken as one. | 9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
10 | Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> | ||
11 | Reviewed-by: Thomas Huth <thuth@redhat.com> | ||
12 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
13 | Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
14 | --- | ||
15 | tests/qemu-iotests/check | 13 ++++++++++++- | ||
16 | 1 file changed, 12 insertions(+), 1 deletion(-) | ||
10 | 17 | ||
11 | Case in point, before this patch: | 18 | diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check |
12 | $ ./qemu-img create -f qcow2 -b backing.qcow2 ./top:image.qcow2 | 19 | index XXXXXXX..XXXXXXX 100755 |
13 | qemu-img: ./top:image.qcow2: Could not open './top:backing.qcow2': | 20 | --- a/tests/qemu-iotests/check |
14 | No such file or directory | 21 | +++ b/tests/qemu-iotests/check |
15 | 22 | @@ -XXX,XX +XXX,XX @@ then | |
16 | Afterwards: | 23 | export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper" |
17 | $ ./qemu-img create -f qcow2 -b backing.qcow2 ./top:image.qcow2 | 24 | fi |
18 | qemu-img: ./top:image.qcow2: Could not open './backing.qcow2': | 25 | |
19 | No such file or directory | 26 | +python_usable=false |
20 | 27 | +if $PYTHON -c 'import sys; sys.exit(0 if sys.version_info >= (3,6) else 1)' | |
21 | Reported-by: yangyang <yangyang@redhat.com> | 28 | +then |
22 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 29 | + python_usable=true |
23 | Reviewed-by: Eric Blake <eblake@redhat.com> | 30 | +fi |
24 | Message-id: 20170522195217.12991-2-mreitz@redhat.com | ||
25 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
26 | --- | ||
27 | block.c | 15 ++++++++++----- | ||
28 | 1 file changed, 10 insertions(+), 5 deletions(-) | ||
29 | |||
30 | diff --git a/block.c b/block.c | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/block.c | ||
33 | +++ b/block.c | ||
34 | @@ -XXX,XX +XXX,XX @@ void path_combine(char *dest, int dest_size, | ||
35 | if (path_is_absolute(filename)) { | ||
36 | pstrcpy(dest, dest_size, filename); | ||
37 | } else { | ||
38 | - p = strchr(base_path, ':'); | ||
39 | - if (p) | ||
40 | - p++; | ||
41 | - else | ||
42 | - p = base_path; | ||
43 | + const char *protocol_stripped = NULL; | ||
44 | + | 31 | + |
45 | + if (path_has_protocol(base_path)) { | 32 | default_machine=$($QEMU_PROG -machine help | sed -n '/(default)/ s/ .*//p') |
46 | + protocol_stripped = strchr(base_path, ':'); | 33 | default_alias_machine=$($QEMU_PROG -machine help | \ |
47 | + if (protocol_stripped) { | 34 | sed -n "/(alias of $default_machine)/ { s/ .*//p; q; }") |
48 | + protocol_stripped++; | 35 | @@ -XXX,XX +XXX,XX @@ do |
49 | + } | 36 | start=$(_wallclock) |
50 | + } | 37 | |
51 | + p = protocol_stripped ?: base_path; | 38 | if [ "$(head -n 1 "$source_iotests/$seq")" == "#!/usr/bin/env python" ]; then |
52 | + | 39 | - run_command="$PYTHON $seq" |
53 | p1 = strrchr(base_path, '/'); | 40 | + if $python_usable; then |
54 | #ifdef _WIN32 | 41 | + run_command="$PYTHON $seq" |
55 | { | 42 | + else |
43 | + run_command="false" | ||
44 | + echo "Unsupported Python version" > $seq.notrun | ||
45 | + fi | ||
46 | else | ||
47 | run_command="./$seq" | ||
48 | fi | ||
56 | -- | 49 | -- |
57 | 1.8.3.1 | 50 | 2.20.1 |
58 | 51 | ||
59 | 52 | diff view generated by jsdifflib |
1 | This adds a small test for the image streaming error path for failing | 1 | Some scripts check the Python version number and have two code paths to |
---|---|---|---|
2 | block_job_create(), which would have found the null pointer dereference | 2 | accomodate both Python 2 and 3. Remove the code specific to Python 2 and |
3 | in commit a170a91f. | 3 | assert the minimum version of 3.6 instead (check skips Python tests in |
4 | this case, so the assertion would only ever trigger if a Python script | ||
5 | is executed manually). | ||
4 | 6 | ||
5 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 7 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
6 | Reviewed-by: Alberto Garcia <berto@igalia.com> | 8 | Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> |
7 | Reviewed-by: Kashyap Chamarthy <kchamart@redhat.com> | 9 | Reviewed-by: Thomas Huth <thuth@redhat.com> |
8 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | 10 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> |
9 | Reviewed-by: Jeff Cody <jcody@redhat.com> | 11 | Reviewed-by: John Snow <jsnow@redhat.com> |
12 | Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
10 | --- | 13 | --- |
11 | tests/qemu-iotests/030 | 4 ++++ | 14 | tests/qemu-iotests/044 | 3 --- |
12 | tests/qemu-iotests/030.out | 4 ++-- | 15 | tests/qemu-iotests/163 | 3 --- |
13 | 2 files changed, 6 insertions(+), 2 deletions(-) | 16 | tests/qemu-iotests/iotests.py | 13 +++---------- |
17 | 3 files changed, 3 insertions(+), 16 deletions(-) | ||
14 | 18 | ||
15 | diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030 | 19 | diff --git a/tests/qemu-iotests/044 b/tests/qemu-iotests/044 |
16 | index XXXXXXX..XXXXXXX 100755 | 20 | index XXXXXXX..XXXXXXX 100755 |
17 | --- a/tests/qemu-iotests/030 | 21 | --- a/tests/qemu-iotests/044 |
18 | +++ b/tests/qemu-iotests/030 | 22 | +++ b/tests/qemu-iotests/044 |
19 | @@ -XXX,XX +XXX,XX @@ class TestSingleDrive(iotests.QMPTestCase): | 23 | @@ -XXX,XX +XXX,XX @@ import struct |
20 | result = self.vm.qmp('block-stream', device='nonexistent') | 24 | import subprocess |
21 | self.assert_qmp(result, 'error/class', 'GenericError') | 25 | import sys |
22 | 26 | ||
23 | + def test_job_id_missing(self): | 27 | -if sys.version_info.major == 2: |
24 | + result = self.vm.qmp('block-stream', device='mid') | 28 | - range = xrange |
25 | + self.assert_qmp(result, 'error/class', 'GenericError') | 29 | - |
26 | + | 30 | test_img = os.path.join(iotests.test_dir, 'test.img') |
27 | 31 | ||
28 | class TestParallelOps(iotests.QMPTestCase): | 32 | class TestRefcountTableGrowth(iotests.QMPTestCase): |
29 | num_ops = 4 # Number of parallel block-stream operations | 33 | diff --git a/tests/qemu-iotests/163 b/tests/qemu-iotests/163 |
30 | diff --git a/tests/qemu-iotests/030.out b/tests/qemu-iotests/030.out | 34 | index XXXXXXX..XXXXXXX 100755 |
35 | --- a/tests/qemu-iotests/163 | ||
36 | +++ b/tests/qemu-iotests/163 | ||
37 | @@ -XXX,XX +XXX,XX @@ | ||
38 | import os, random, iotests, struct, qcow2, sys | ||
39 | from iotests import qemu_img, qemu_io, image_size | ||
40 | |||
41 | -if sys.version_info.major == 2: | ||
42 | - range = xrange | ||
43 | - | ||
44 | test_img = os.path.join(iotests.test_dir, 'test.img') | ||
45 | check_img = os.path.join(iotests.test_dir, 'check.img') | ||
46 | |||
47 | diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py | ||
31 | index XXXXXXX..XXXXXXX 100644 | 48 | index XXXXXXX..XXXXXXX 100644 |
32 | --- a/tests/qemu-iotests/030.out | 49 | --- a/tests/qemu-iotests/iotests.py |
33 | +++ b/tests/qemu-iotests/030.out | 50 | +++ b/tests/qemu-iotests/iotests.py |
34 | @@ -XXX,XX +XXX,XX @@ | 51 | @@ -XXX,XX +XXX,XX @@ from collections import OrderedDict |
35 | -...................... | 52 | sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) |
36 | +....................... | 53 | from qemu import qtest |
37 | ---------------------------------------------------------------------- | 54 | |
38 | -Ran 22 tests | 55 | +assert sys.version_info >= (3,6) |
39 | +Ran 23 tests | 56 | |
40 | 57 | # This will not work if arguments contain spaces but is necessary if we | |
41 | OK | 58 | # want to support the override options that ./check supports. |
59 | @@ -XXX,XX +XXX,XX @@ def image_size(img): | ||
60 | return json.loads(r)['virtual-size'] | ||
61 | |||
62 | def is_str(val): | ||
63 | - if sys.version_info.major >= 3: | ||
64 | - return isinstance(val, str) | ||
65 | - else: | ||
66 | - return isinstance(val, str) or isinstance(val, unicode) | ||
67 | + return isinstance(val, str) | ||
68 | |||
69 | test_dir_re = re.compile(r"%s" % test_dir) | ||
70 | def filter_test_dir(msg): | ||
71 | @@ -XXX,XX +XXX,XX @@ def execute_test(test_function=None, | ||
72 | else: | ||
73 | # We need to filter out the time taken from the output so that | ||
74 | # qemu-iotest can reliably diff the results against master output. | ||
75 | - if sys.version_info.major >= 3: | ||
76 | - output = io.StringIO() | ||
77 | - else: | ||
78 | - # io.StringIO is for unicode strings, which is not what | ||
79 | - # 2.x's test runner emits. | ||
80 | - output = io.BytesIO() | ||
81 | + output = io.StringIO() | ||
82 | |||
83 | logging.basicConfig(level=(logging.DEBUG if debug else logging.WARN)) | ||
84 | |||
42 | -- | 85 | -- |
43 | 1.8.3.1 | 86 | 2.20.1 |
44 | 87 | ||
45 | 88 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Fam Zheng <famz@redhat.com> | ||
2 | 1 | ||
3 | This is the case in our docker tests, as we use --net=none there. Skip | ||
4 | this method. | ||
5 | |||
6 | Signed-off-by: Fam Zheng <famz@redhat.com> | ||
7 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
8 | --- | ||
9 | tests/qemu-iotests/147 | 7 +++++++ | ||
10 | 1 file changed, 7 insertions(+) | ||
11 | |||
12 | diff --git a/tests/qemu-iotests/147 b/tests/qemu-iotests/147 | ||
13 | index XXXXXXX..XXXXXXX 100755 | ||
14 | --- a/tests/qemu-iotests/147 | ||
15 | +++ b/tests/qemu-iotests/147 | ||
16 | @@ -XXX,XX +XXX,XX @@ class BuiltinNBD(NBDBlockdevAddBase): | ||
17 | self._server_down() | ||
18 | |||
19 | def test_inet6(self): | ||
20 | + try: | ||
21 | + socket.getaddrinfo("::0", "0", socket.AF_INET6, | ||
22 | + socket.SOCK_STREAM, socket.IPPROTO_TCP, | ||
23 | + socket.AI_ADDRCONFIG | socket.AI_CANONNAME) | ||
24 | + except socket.gaierror: | ||
25 | + # IPv6 not available, skip | ||
26 | + return | ||
27 | address = { 'type': 'inet', | ||
28 | 'data': { | ||
29 | 'host': '::1', | ||
30 | -- | ||
31 | 1.8.3.1 | ||
32 | |||
33 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Stephen Bates <sbates@raithlin.com> | ||
2 | 1 | ||
3 | Implement NVMe Controller Memory Buffers (CMBs) which were added in | ||
4 | version 1.2 of the NVMe Specification. This patch adds an optional | ||
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> | ||
12 | --- | ||
13 | hw/block/nvme.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- | ||
14 | hw/block/nvme.h | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
15 | 2 files changed, 144 insertions(+), 4 deletions(-) | ||
16 | |||
17 | diff --git a/hw/block/nvme.c b/hw/block/nvme.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/hw/block/nvme.c | ||
20 | +++ b/hw/block/nvme.c | ||
21 | @@ -XXX,XX +XXX,XX @@ | ||
22 | */ | ||
23 | |||
24 | /** | ||
25 | - * Reference Specs: http://www.nvmexpress.org, 1.1, 1.0e | ||
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 | -- | ||
259 | 1.8.3.1 | ||
260 | |||
261 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Alberto Garcia <berto@igalia.com> | ||
2 | 1 | ||
3 | Commit d7086422b1c1e75e320519cfe26176db6ec97a37 added a local_err | ||
4 | variable global to the qcow2_amend_options() function, so there's no | ||
5 | need to have this other one. | ||
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 | --- | ||
12 | block/qcow2.c | 5 ++--- | ||
13 | 1 file changed, 2 insertions(+), 3 deletions(-) | ||
14 | |||
15 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/block/qcow2.c | ||
18 | +++ b/block/qcow2.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, | ||
20 | |||
21 | if (s->refcount_bits != refcount_bits) { | ||
22 | int refcount_order = ctz32(refcount_bits); | ||
23 | - Error *local_error = NULL; | ||
24 | |||
25 | if (new_version < 3 && refcount_bits != 16) { | ||
26 | error_report("Different refcount widths than 16 bits require " | ||
27 | @@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, | ||
28 | helper_cb_info.current_operation = QCOW2_CHANGING_REFCOUNT_ORDER; | ||
29 | ret = qcow2_change_refcount_order(bs, refcount_order, | ||
30 | &qcow2_amend_helper_cb, | ||
31 | - &helper_cb_info, &local_error); | ||
32 | + &helper_cb_info, &local_err); | ||
33 | if (ret < 0) { | ||
34 | - error_report_err(local_error); | ||
35 | + error_report_err(local_err); | ||
36 | return ret; | ||
37 | } | ||
38 | } | ||
39 | -- | ||
40 | 1.8.3.1 | ||
41 | |||
42 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Fam Zheng <famz@redhat.com> | ||
2 | 1 | ||
3 | It got lost in commit a8d16f9ca "qemu-img: Update documentation for -U". | ||
4 | |||
5 | Reported-by: Max Reitz <mreitz@redhat.com> | ||
6 | Signed-off-by: Fam Zheng <famz@redhat.com> | ||
7 | Message-id: 20170515103551.31313-1-famz@redhat.com | ||
8 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
10 | --- | ||
11 | qemu-img-cmds.hx | 4 ++-- | ||
12 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
13 | |||
14 | diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/qemu-img-cmds.hx | ||
17 | +++ b/qemu-img-cmds.hx | ||
18 | @@ -XXX,XX +XXX,XX @@ STEXI | ||
19 | ETEXI | ||
20 | |||
21 | DEF("convert", img_convert, | ||
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") | ||
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") | ||
24 | STEXI | ||
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} | ||
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} | ||
27 | ETEXI | ||
28 | |||
29 | DEF("dd", img_dd, | ||
30 | -- | ||
31 | 1.8.3.1 | ||
32 | |||
33 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | The qemu-img dd command added --image-opts support, but missed | ||
4 | the corresponding --object support. This prevented passing | ||
5 | secrets (eg auth passwords) needed by certain disk images. | ||
6 | |||
7 | Reviewed-by: Fam Zheng <famz@redhat.com> | ||
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 | ||
19 | --- a/qemu-img.c | ||
20 | +++ b/qemu-img.c | ||
21 | @@ -XXX,XX +XXX,XX @@ static int img_dd(int argc, char **argv) | ||
22 | }; | ||
23 | const struct option long_options[] = { | ||
24 | { "help", no_argument, 0, 'h'}, | ||
25 | + { "object", required_argument, 0, OPTION_OBJECT}, | ||
26 | { "image-opts", no_argument, 0, OPTION_IMAGE_OPTS}, | ||
27 | { "force-share", no_argument, 0, 'U'}, | ||
28 | { 0, 0, 0, 0 } | ||
29 | @@ -XXX,XX +XXX,XX @@ static int img_dd(int argc, char **argv) | ||
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 | + | ||
50 | + if (qemu_opts_foreach(&qemu_object_opts, | ||
51 | + user_creatable_add_opts_foreach, | ||
52 | + NULL, NULL)) { | ||
53 | + ret = -1; | ||
54 | + goto out; | ||
55 | + } | ||
56 | + | ||
57 | blk1 = img_open(image_opts, in.filename, fmt, 0, false, false, | ||
58 | force_share); | ||
59 | |||
60 | -- | ||
61 | 1.8.3.1 | ||
62 | |||
63 | 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 '--image-opts' flag indicates whether the source filename | ||
4 | includes options. The target filename has to remain in the | ||
5 | plain filename format though, since it needs to be passed to | ||
6 | bdrv_create(). When using --skip-create though, it would be | ||
7 | possible to use image-opts syntax. This adds --target-image-opts | ||
8 | to indicate that the target filename includes options. Currently | ||
9 | this mandates use of the --skip-create flag too. | ||
10 | |||
11 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
12 | Message-id: 20170515164712.6643-4-berrange@redhat.com | ||
13 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
14 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
15 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
16 | --- | ||
17 | qemu-img-cmds.hx | 4 +-- | ||
18 | qemu-img.c | 84 ++++++++++++++++++++++++++++++++++++++------------------ | ||
19 | qemu-img.texi | 12 ++++++-- | ||
20 | 3 files changed, 69 insertions(+), 31 deletions(-) | ||
21 | |||
22 | diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx | ||
23 | index XXXXXXX..XXXXXXX 100644 | ||
24 | --- a/qemu-img-cmds.hx | ||
25 | +++ b/qemu-img-cmds.hx | ||
26 | @@ -XXX,XX +XXX,XX @@ STEXI | ||
27 | ETEXI | ||
28 | |||
29 | 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") | ||
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") | ||
32 | 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} | ||
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 | ||
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 | ||
207 | index XXXXXXX..XXXXXXX 100644 | ||
208 | --- a/qemu-img.texi | ||
209 | +++ b/qemu-img.texi | ||
210 | @@ -XXX,XX +XXX,XX @@ keys. | ||
211 | |||
212 | @item --image-opts | ||
213 | |||
214 | -Indicates that the @var{filename} parameter is to be interpreted as a | ||
215 | +Indicates that the source @var{filename} parameter is to be interpreted as a | ||
216 | full option string, not a plain filename. This parameter is mutually | ||
217 | -exclusive with the @var{-f} and @var{-F} parameters. | ||
218 | +exclusive with the @var{-f} parameter. | ||
219 | + | ||
220 | +@item --target-image-opts | ||
221 | + | ||
222 | +Indicates that the @var{output_filename} parameter(s) are to be interpreted as | ||
223 | +a full option string, not a plain filename. This parameter is mutually | ||
224 | +exclusive with the @var{-O} parameters. It is currently required to also use | ||
225 | +the @var{-n} parameter to skip image creation. This restriction may be relaxed | ||
226 | +in a future release. | ||
227 | |||
228 | @item fmt | ||
229 | is the disk image format. It is guessed automatically in most cases. See below | ||
230 | -- | ||
231 | 1.8.3.1 | ||
232 | |||
233 | 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 |
Deleted patch | |||
---|---|---|---|
1 | From: Fam Zheng <famz@redhat.com> | ||
2 | 1 | ||
3 | Reported by Coverity. | ||
4 | |||
5 | 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 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
9 | --- | ||
10 | qemu-img.c | 1 + | ||
11 | 1 file changed, 1 insertion(+) | ||
12 | |||
13 | diff --git a/qemu-img.c b/qemu-img.c | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/qemu-img.c | ||
16 | +++ b/qemu-img.c | ||
17 | @@ -XXX,XX +XXX,XX @@ static BlockBackend *img_open_opts(const char *optstr, | ||
18 | if (qdict_haskey(options, BDRV_OPT_FORCE_SHARE) | ||
19 | && !qdict_get_bool(options, BDRV_OPT_FORCE_SHARE)) { | ||
20 | error_report("--force-share/-U conflicts with image options"); | ||
21 | + QDECREF(options); | ||
22 | return NULL; | ||
23 | } | ||
24 | qdict_put(options, BDRV_OPT_FORCE_SHARE, qbool_from_bool(true)); | ||
25 | -- | ||
26 | 1.8.3.1 | ||
27 | |||
28 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Eric Blake <eblake@redhat.com> | ||
2 | 1 | ||
3 | When converting a 1.1 image down to 0.10, qemu-iotests 060 forces | ||
4 | a contrived failure where allocating a cluster used to replace a | ||
5 | zero cluster reads unaligned data. Since it is a zero cluster | ||
6 | rather than a data cluster being converted, changing the error | ||
7 | message to match our earlier change in 'qcow2: Make distinction | ||
8 | between zero cluster types obvious' is worthwhile. | ||
9 | |||
10 | Suggested-by: Max Reitz <mreitz@redhat.com> | ||
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 | ||
22 | --- a/block/qcow2-cluster.c | ||
23 | +++ b/block/qcow2-cluster.c | ||
24 | @@ -XXX,XX +XXX,XX @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table, | ||
25 | } | ||
26 | |||
27 | if (offset_into_cluster(s, offset)) { | ||
28 | - qcow2_signal_corruption(bs, true, -1, -1, "Data cluster offset " | ||
29 | + qcow2_signal_corruption(bs, true, -1, -1, | ||
30 | + "Cluster allocation offset " | ||
31 | "%#" PRIx64 " unaligned (L2 offset: %#" | ||
32 | PRIx64 ", L2 index: %#x)", offset, | ||
33 | l2_offset, j); | ||
34 | diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out | ||
35 | index XXXXXXX..XXXXXXX 100644 | ||
36 | --- a/tests/qemu-iotests/060.out | ||
37 | +++ b/tests/qemu-iotests/060.out | ||
38 | @@ -XXX,XX +XXX,XX @@ read failed: Input/output error | ||
39 | Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 | ||
40 | wrote 65536/65536 bytes at offset 0 | ||
41 | 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
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 | -- | ||
48 | 1.8.3.1 | ||
49 | |||
50 | diff view generated by jsdifflib |