1 | The following changes since commit ba29883206d92a29ad5a466e679ccfc2ee6132ef: | 1 | The following changes since commit 7f21573c822805a8e6be379d9bcf3ad9effef3dc: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'remotes/borntraeger/tags/s390x-20200310' into staging (2020-03-10 16:50:28 +0000) | 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 | 6 | ||
7 | git://repo.or.cz/qemu/kevin.git tags/for-upstream | 7 | git://repo.or.cz/qemu/kevin.git tags/for-upstream |
8 | 8 | ||
9 | for you to fetch changes up to 8bb3b023f2055054ee119cb45b42d2b14be7fc8a: | 9 | for you to fetch changes up to 352492e5541e293ea8117412ffd171ce1c7ac15d: |
10 | 10 | ||
11 | qemu-iotests: adding LUKS cleanup for non-UTF8 secret error (2020-03-11 15:54:38 +0100) | 11 | iotests: Remove Python 2 compatibility code (2019-10-02 16:47:23 +0200) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Block layer patches: | 14 | Block layer patches: |
15 | 15 | ||
16 | - Relax restrictions for blockdev-snapshot (allows libvirt to do live | 16 | - Fix internal snapshots with typical -blockdev setups |
17 | storage migration with blockdev-mirror) | 17 | - iotests: Require Python 3.6 or later |
18 | - luks: Delete created files when block_crypto_co_create_opts_luks fails | ||
19 | - Fix memleaks in qmp_object_add | ||
20 | 18 | ||
21 | ---------------------------------------------------------------- | 19 | ---------------------------------------------------------------- |
22 | Daniel Henrique Barboza (4): | 20 | Kevin Wolf (4): |
23 | block: introducing 'bdrv_co_delete_file' interface | 21 | block/snapshot: Restrict set of snapshot nodes |
24 | block.c: adding bdrv_co_delete_file | 22 | iotests: Test internal snapshots with -blockdev |
25 | crypto.c: cleanup created file when block_crypto_co_create_opts_luks fails | 23 | iotests: Require Python 3.6 or later |
26 | qemu-iotests: adding LUKS cleanup for non-UTF8 secret error | 24 | iotests: Remove Python 2 compatibility code |
27 | 25 | ||
28 | Kevin Wolf (6): | 26 | block/snapshot.c | 26 ++++-- |
29 | block: Make bdrv_get_cumulative_perm() public | 27 | tests/qemu-iotests/044 | 3 - |
30 | block: Relax restrictions for blockdev-snapshot | 28 | tests/qemu-iotests/163 | 3 - |
31 | iotests: Fix run_job() with use_log=False | 29 | tests/qemu-iotests/267 | 168 ++++++++++++++++++++++++++++++++++++ |
32 | iotests: Test mirror with temporarily disabled target backing file | 30 | tests/qemu-iotests/267.out | 182 +++++++++++++++++++++++++++++++++++++++ |
33 | block: Fix cross-AioContext blockdev-snapshot | 31 | tests/qemu-iotests/check | 13 ++- |
34 | iotests: Add iothread cases to 155 | 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 | ||
35 | 38 | ||
36 | Pan Nengyuan (1): | ||
37 | qom-qmp-cmds: fix two memleaks in qmp_object_add | ||
38 | |||
39 | Peter Krempa (1): | ||
40 | qapi: Add '@allow-write-only-overlay' feature for 'blockdev-snapshot' | ||
41 | |||
42 | Philippe Mathieu-Daudé (1): | ||
43 | tests/qemu-iotests: Fix socket_scm_helper build path | ||
44 | |||
45 | qapi/block-core.json | 9 ++++- | ||
46 | include/block/block.h | 1 + | ||
47 | include/block/block_int.h | 7 ++++ | ||
48 | block.c | 33 ++++++++++++++-- | ||
49 | block/crypto.c | 18 +++++++++ | ||
50 | block/file-posix.c | 23 +++++++++++ | ||
51 | blockdev.c | 30 ++++----------- | ||
52 | qom/qom-qmp-cmds.c | 16 +++----- | ||
53 | tests/qemu-iotests/iotests.py | 5 ++- | ||
54 | tests/Makefile.include | 1 + | ||
55 | tests/qemu-iotests/085.out | 4 +- | ||
56 | tests/qemu-iotests/155 | 88 ++++++++++++++++++++++++++++++++++++------- | ||
57 | tests/qemu-iotests/155.out | 4 +- | ||
58 | tests/qemu-iotests/282 | 67 ++++++++++++++++++++++++++++++++ | ||
59 | tests/qemu-iotests/282.out | 11 ++++++ | ||
60 | tests/qemu-iotests/group | 1 + | ||
61 | tests/qtest/Makefile.include | 1 - | ||
62 | 17 files changed, 262 insertions(+), 57 deletions(-) | ||
63 | create mode 100755 tests/qemu-iotests/282 | ||
64 | create mode 100644 tests/qemu-iotests/282.out | ||
65 | |||
66 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Pan Nengyuan <pannengyuan@huawei.com> | ||
2 | 1 | ||
3 | 'type/id' forgot to free in qmp_object_add, this patch fix that. | ||
4 | |||
5 | The leak stack: | ||
6 | Direct leak of 84 byte(s) in 6 object(s) allocated from: | ||
7 | #0 0x7fe2a5ebf768 in __interceptor_malloc (/lib64/libasan.so.5+0xef768) | ||
8 | #1 0x7fe2a5044445 in g_malloc (/lib64/libglib-2.0.so.0+0x52445) | ||
9 | #2 0x7fe2a505dd92 in g_strdup (/lib64/libglib-2.0.so.0+0x6bd92) | ||
10 | #3 0x56344954e692 in qmp_object_add /mnt/sdb/qemu-new/qemu_test/qemu/qom/qom-qmp-cmds.c:258 | ||
11 | #4 0x563449960f5a in do_qmp_dispatch /mnt/sdb/qemu-new/qemu_test/qemu/qapi/qmp-dispatch.c:132 | ||
12 | #5 0x563449960f5a in qmp_dispatch /mnt/sdb/qemu-new/qemu_test/qemu/qapi/qmp-dispatch.c:175 | ||
13 | #6 0x563449498a30 in monitor_qmp_dispatch /mnt/sdb/qemu-new/qemu_test/qemu/monitor/qmp.c:145 | ||
14 | #7 0x56344949a64f in monitor_qmp_bh_dispatcher /mnt/sdb/qemu-new/qemu_test/qemu/monitor/qmp.c:234 | ||
15 | #8 0x563449a92a3a in aio_bh_call /mnt/sdb/qemu-new/qemu_test/qemu/util/async.c:136 | ||
16 | |||
17 | Direct leak of 54 byte(s) in 6 object(s) allocated from: | ||
18 | #0 0x7fe2a5ebf768 in __interceptor_malloc (/lib64/libasan.so.5+0xef768) | ||
19 | #1 0x7fe2a5044445 in g_malloc (/lib64/libglib-2.0.so.0+0x52445) | ||
20 | #2 0x7fe2a505dd92 in g_strdup (/lib64/libglib-2.0.so.0+0x6bd92) | ||
21 | #3 0x56344954e6c4 in qmp_object_add /mnt/sdb/qemu-new/qemu_test/qemu/qom/qom-qmp-cmds.c:267 | ||
22 | #4 0x563449960f5a in do_qmp_dispatch /mnt/sdb/qemu-new/qemu_test/qemu/qapi/qmp-dispatch.c:132 | ||
23 | #5 0x563449960f5a in qmp_dispatch /mnt/sdb/qemu-new/qemu_test/qemu/qapi/qmp-dispatch.c:175 | ||
24 | #6 0x563449498a30 in monitor_qmp_dispatch /mnt/sdb/qemu-new/qemu_test/qemu/monitor/qmp.c:145 | ||
25 | #7 0x56344949a64f in monitor_qmp_bh_dispatcher /mnt/sdb/qemu-new/qemu_test/qemu/monitor/qmp.c:234 | ||
26 | #8 0x563449a92a3a in aio_bh_call /mnt/sdb/qemu-new/qemu_test/qemu/util/async.c:136 | ||
27 | |||
28 | Fixes: 5f07c4d60d091320186e7b0edaf9ed2cc16b2d1e | ||
29 | Reported-by: Euler Robot <euler.robot@huawei.com> | ||
30 | Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com> | ||
31 | Message-Id: <20200310064640.5059-1-pannengyuan@huawei.com> | ||
32 | Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> | ||
33 | Acked-by: Igor Mammedov <imammedo@redhat.com> | ||
34 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
35 | --- | ||
36 | qom/qom-qmp-cmds.c | 16 ++++++---------- | ||
37 | 1 file changed, 6 insertions(+), 10 deletions(-) | ||
38 | |||
39 | diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c | ||
40 | index XXXXXXX..XXXXXXX 100644 | ||
41 | --- a/qom/qom-qmp-cmds.c | ||
42 | +++ b/qom/qom-qmp-cmds.c | ||
43 | @@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp) | ||
44 | QDict *pdict; | ||
45 | Visitor *v; | ||
46 | Object *obj; | ||
47 | - const char *type; | ||
48 | - const char *id; | ||
49 | + g_autofree char *type = NULL; | ||
50 | + g_autofree char *id = NULL; | ||
51 | |||
52 | - type = qdict_get_try_str(qdict, "qom-type"); | ||
53 | + type = g_strdup(qdict_get_try_str(qdict, "qom-type")); | ||
54 | if (!type) { | ||
55 | error_setg(errp, QERR_MISSING_PARAMETER, "qom-type"); | ||
56 | return; | ||
57 | - } else { | ||
58 | - type = g_strdup(type); | ||
59 | - qdict_del(qdict, "qom-type"); | ||
60 | } | ||
61 | + qdict_del(qdict, "qom-type"); | ||
62 | |||
63 | - id = qdict_get_try_str(qdict, "id"); | ||
64 | + id = g_strdup(qdict_get_try_str(qdict, "id")); | ||
65 | if (!id) { | ||
66 | error_setg(errp, QERR_MISSING_PARAMETER, "id"); | ||
67 | return; | ||
68 | - } else { | ||
69 | - id = g_strdup(id); | ||
70 | - qdict_del(qdict, "id"); | ||
71 | } | ||
72 | + qdict_del(qdict, "id"); | ||
73 | |||
74 | props = qdict_get(qdict, "props"); | ||
75 | if (props) { | ||
76 | -- | ||
77 | 2.20.1 | ||
78 | |||
79 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
2 | Message-Id: <20200310113831.27293-2-kwolf@redhat.com> | ||
3 | Reviewed-by: Peter Krempa <pkrempa@redhat.com> | ||
4 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
5 | --- | ||
6 | include/block/block_int.h | 3 +++ | ||
7 | block.c | 6 ++---- | ||
8 | 2 files changed, 5 insertions(+), 4 deletions(-) | ||
9 | 1 | ||
10 | diff --git a/include/block/block_int.h b/include/block/block_int.h | ||
11 | index XXXXXXX..XXXXXXX 100644 | ||
12 | --- a/include/block/block_int.h | ||
13 | +++ b/include/block/block_int.h | ||
14 | @@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs, | ||
15 | void *opaque, Error **errp); | ||
16 | void bdrv_root_unref_child(BdrvChild *child); | ||
17 | |||
18 | +void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm, | ||
19 | + uint64_t *shared_perm); | ||
20 | + | ||
21 | /** | ||
22 | * Sets a BdrvChild's permissions. Avoid if the parent is a BDS; use | ||
23 | * bdrv_child_refresh_perms() instead and make the parent's | ||
24 | diff --git a/block.c b/block.c | ||
25 | index XXXXXXX..XXXXXXX 100644 | ||
26 | --- a/block.c | ||
27 | +++ b/block.c | ||
28 | @@ -XXX,XX +XXX,XX @@ static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q, | ||
29 | bool *tighten_restrictions, Error **errp); | ||
30 | static void bdrv_child_abort_perm_update(BdrvChild *c); | ||
31 | static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared); | ||
32 | -static void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm, | ||
33 | - uint64_t *shared_perm); | ||
34 | |||
35 | typedef struct BlockReopenQueueEntry { | ||
36 | bool prepared; | ||
37 | @@ -XXX,XX +XXX,XX @@ static void bdrv_set_perm(BlockDriverState *bs, uint64_t cumulative_perms, | ||
38 | } | ||
39 | } | ||
40 | |||
41 | -static void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm, | ||
42 | - uint64_t *shared_perm) | ||
43 | +void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm, | ||
44 | + uint64_t *shared_perm) | ||
45 | { | ||
46 | BdrvChild *c; | ||
47 | uint64_t cumulative_perms = 0; | ||
48 | -- | ||
49 | 2.20.1 | ||
50 | |||
51 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | blockdev-snapshot returned an error if the overlay was already in use, | ||
2 | which it defined as having any BlockBackend parent. This is in fact both | ||
3 | too strict (some parents can tolerate the change of visible data caused | ||
4 | by attaching a backing file) and too loose (some non-BlockBackend | ||
5 | parents may not be happy with it). | ||
6 | 1 | ||
7 | One important use case that is prevented by the too strict check is live | ||
8 | storage migration with blockdev-mirror. Here, the target node is | ||
9 | usually opened without a backing file so that the active layer is | ||
10 | mirrored while its backing chain can be copied in the background. | ||
11 | |||
12 | The backing chain should be attached to the mirror target node when | ||
13 | finalising the job, just before switching the users of the source node | ||
14 | to the new copy (at which point the mirror job still has a reference to | ||
15 | the node). drive-mirror did this automatically, but with blockdev-mirror | ||
16 | this is the job of the QMP client, so it needs a way to do this. | ||
17 | |||
18 | blockdev-snapshot is the obvious way, so this patch makes it work in | ||
19 | this scenario. The new condition is that no parent uses CONSISTENT_READ | ||
20 | permissions. This will ensure that the operation will still be blocked | ||
21 | when the node is attached to the guest device, so blockdev-snapshot | ||
22 | remains safe. | ||
23 | |||
24 | (For the sake of completeness, x-blockdev-reopen can be used to achieve | ||
25 | the same, however it is a big hammer, performs the graph change | ||
26 | completely unchecked and is still experimental. So even with the option | ||
27 | of using x-blockdev-reopen, there are reasons why blockdev-snapshot | ||
28 | should be able to perform this operation.) | ||
29 | |||
30 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
31 | Message-Id: <20200310113831.27293-3-kwolf@redhat.com> | ||
32 | Reviewed-by: Peter Krempa <pkrempa@redhat.com> | ||
33 | Tested-by: Peter Krempa <pkrempa@redhat.com> | ||
34 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
35 | --- | ||
36 | blockdev.c | 14 ++++++++------ | ||
37 | tests/qemu-iotests/085.out | 4 ++-- | ||
38 | 2 files changed, 10 insertions(+), 8 deletions(-) | ||
39 | |||
40 | diff --git a/blockdev.c b/blockdev.c | ||
41 | index XXXXXXX..XXXXXXX 100644 | ||
42 | --- a/blockdev.c | ||
43 | +++ b/blockdev.c | ||
44 | @@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common, | ||
45 | TransactionAction *action = common->action; | ||
46 | AioContext *aio_context; | ||
47 | AioContext *old_context; | ||
48 | + uint64_t perm, shared; | ||
49 | int ret; | ||
50 | |||
51 | /* 'blockdev-snapshot' and 'blockdev-snapshot-sync' have similar | ||
52 | @@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common, | ||
53 | goto out; | ||
54 | } | ||
55 | |||
56 | - if (bdrv_has_blk(state->new_bs)) { | ||
57 | + /* | ||
58 | + * Allow attaching a backing file to an overlay that's already in use only | ||
59 | + * if the parents don't assume that they are already seeing a valid image. | ||
60 | + * (Specifically, allow it as a mirror target, which is write-only access.) | ||
61 | + */ | ||
62 | + bdrv_get_cumulative_perm(state->new_bs, &perm, &shared); | ||
63 | + if (perm & BLK_PERM_CONSISTENT_READ) { | ||
64 | error_setg(errp, "The overlay is already in use"); | ||
65 | goto out; | ||
66 | } | ||
67 | |||
68 | - if (bdrv_op_is_blocked(state->new_bs, BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT, | ||
69 | - errp)) { | ||
70 | - goto out; | ||
71 | - } | ||
72 | - | ||
73 | if (state->new_bs->backing != NULL) { | ||
74 | error_setg(errp, "The overlay already has a backing image"); | ||
75 | goto out; | ||
76 | diff --git a/tests/qemu-iotests/085.out b/tests/qemu-iotests/085.out | ||
77 | index XXXXXXX..XXXXXXX 100644 | ||
78 | --- a/tests/qemu-iotests/085.out | ||
79 | +++ b/tests/qemu-iotests/085.out | ||
80 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/12-snapshot-v0.IMGFMT', fmt=IMGFMT size=134217728 backing_f | ||
81 | === Invalid command - cannot create a snapshot using a file BDS === | ||
82 | |||
83 | { 'execute': 'blockdev-snapshot', 'arguments': { 'node':'virtio0', 'overlay':'file_12' } } | ||
84 | -{"error": {"class": "GenericError", "desc": "The overlay does not support backing images"}} | ||
85 | +{"error": {"class": "GenericError", "desc": "The overlay is already in use"}} | ||
86 | |||
87 | === Invalid command - snapshot node used as active layer === | ||
88 | |||
89 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/12-snapshot-v0.IMGFMT', fmt=IMGFMT size=134217728 backing_f | ||
90 | === Invalid command - snapshot node used as backing hd === | ||
91 | |||
92 | { 'execute': 'blockdev-snapshot', 'arguments': { 'node': 'virtio0', 'overlay':'snap_11' } } | ||
93 | -{"error": {"class": "GenericError", "desc": "Node 'snap_11' is busy: node is used as backing hd of 'snap_12'"}} | ||
94 | +{"error": {"class": "GenericError", "desc": "The overlay is already in use"}} | ||
95 | |||
96 | === Invalid command - snapshot node has a backing image === | ||
97 | |||
98 | -- | ||
99 | 2.20.1 | ||
100 | |||
101 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <danielhb413@gmail.com> | 1 | Nodes involved in internal snapshots were those that were returned by |
---|---|---|---|
2 | bdrv_next(), inserted and not read-only. bdrv_next() in turn returns all | ||
3 | nodes that are either the root node of a BlockBackend or monitor-owned | ||
4 | nodes. | ||
2 | 5 | ||
3 | Using the new 'bdrv_co_delete_file' interface, a pure co_routine function | 6 | With the typical -drive use, this worked well enough. However, in the |
4 | 'bdrv_co_delete_file' inside block.c can can be used in a way similar of | 7 | typical -blockdev case, the user defines one node per option, making all |
5 | the existing bdrv_create_file to to clean up a created file. | 8 | nodes monitor-owned nodes. This includes protocol nodes etc. which often |
9 | are not snapshottable, so "savevm" only returns an error. | ||
6 | 10 | ||
7 | We're creating a pure co_routine because the only caller of | 11 | Change the conditions so that internal snapshot still include all nodes |
8 | 'bdrv_co_delete_file' will be already in co_routine context, thus there | 12 | that have a BlockBackend attached (we definitely want to snapshot |
9 | is no need to add all the machinery to check for qemu_in_coroutine() and | 13 | anything attached to a guest device and probably also the built-in NBD |
10 | create a separated co_routine to do the job. | 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. | ||
11 | 17 | ||
12 | Suggested-by: Daniel P. Berrangé <berrange@redhat.com> | 18 | This makes internal snapshots usable again with typical -blockdev |
13 | Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> | 19 | configurations. |
14 | Message-Id: <20200130213907.2830642-3-danielhb413@gmail.com> | 20 | |
21 | Cc: qemu-stable@nongnu.org | ||
15 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 22 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
23 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
24 | Reviewed-by: Peter Krempa <pkrempa@redhat.com> | ||
25 | Tested-by: Peter Krempa <pkrempa@redhat.com> | ||
16 | --- | 26 | --- |
17 | include/block/block.h | 1 + | 27 | block/snapshot.c | 26 +++++++++++++++++++------- |
18 | block.c | 26 ++++++++++++++++++++++++++ | 28 | 1 file changed, 19 insertions(+), 7 deletions(-) |
19 | 2 files changed, 27 insertions(+) | ||
20 | 29 | ||
21 | diff --git a/include/block/block.h b/include/block/block.h | 30 | diff --git a/block/snapshot.c b/block/snapshot.c |
22 | index XXXXXXX..XXXXXXX 100644 | 31 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/include/block/block.h | 32 | --- a/block/snapshot.c |
24 | +++ b/include/block/block.h | 33 | +++ b/block/snapshot.c |
25 | @@ -XXX,XX +XXX,XX @@ bool bdrv_is_backing_chain_frozen(BlockDriverState *bs, BlockDriverState *base, | 34 | @@ -XXX,XX +XXX,XX @@ |
26 | int bdrv_freeze_backing_chain(BlockDriverState *bs, BlockDriverState *base, | 35 | #include "qapi/qmp/qerror.h" |
27 | Error **errp); | 36 | #include "qapi/qmp/qstring.h" |
28 | void bdrv_unfreeze_backing_chain(BlockDriverState *bs, BlockDriverState *base); | 37 | #include "qemu/option.h" |
29 | +int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp); | 38 | +#include "sysemu/block-backend.h" |
30 | 39 | ||
31 | 40 | QemuOptsList internal_snapshot_opts = { | |
32 | typedef struct BdrvCheckResult { | 41 | .name = "snapshot", |
33 | diff --git a/block.c b/block.c | 42 | @@ -XXX,XX +XXX,XX @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs, |
34 | index XXXXXXX..XXXXXXX 100644 | 43 | return ret; |
35 | --- a/block.c | ||
36 | +++ b/block.c | ||
37 | @@ -XXX,XX +XXX,XX @@ int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp) | ||
38 | } | ||
39 | } | 44 | } |
40 | 45 | ||
41 | +int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp) | 46 | +static bool bdrv_all_snapshots_includes_bs(BlockDriverState *bs) |
42 | +{ | 47 | +{ |
43 | + Error *local_err = NULL; | 48 | + if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { |
44 | + int ret; | 49 | + return false; |
45 | + | ||
46 | + assert(bs != NULL); | ||
47 | + | ||
48 | + if (!bs->drv) { | ||
49 | + error_setg(errp, "Block node '%s' is not opened", bs->filename); | ||
50 | + return -ENOMEDIUM; | ||
51 | + } | 50 | + } |
52 | + | 51 | + |
53 | + if (!bs->drv->bdrv_co_delete_file) { | 52 | + /* Include all nodes that are either in use by a BlockBackend, or that |
54 | + error_setg(errp, "Driver '%s' does not support image deletion", | 53 | + * aren't attached to any node, but owned by the monitor. */ |
55 | + bs->drv->format_name); | 54 | + return bdrv_has_blk(bs) || QLIST_EMPTY(&bs->parents); |
56 | + return -ENOTSUP; | ||
57 | + } | ||
58 | + | ||
59 | + ret = bs->drv->bdrv_co_delete_file(bs, &local_err); | ||
60 | + if (ret < 0) { | ||
61 | + error_propagate(errp, local_err); | ||
62 | + } | ||
63 | + | ||
64 | + return ret; | ||
65 | +} | 55 | +} |
66 | + | 56 | |
67 | /** | 57 | /* Group operations. All block drivers are involved. |
68 | * Try to get @bs's logical and physical block size. | 58 | * These functions will properly handle dataplane (take aio_context_acquire |
69 | * On success, store them in @bsz struct and return 0. | 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) { | ||
70 | -- | 116 | -- |
71 | 2.20.1 | 117 | 2.20.1 |
72 | 118 | ||
73 | 119 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <danielhb413@gmail.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 | This patch adds a new test file to exercise the case where | 13 | diff --git a/tests/qemu-iotests/267 b/tests/qemu-iotests/267 |
4 | qemu-img fails to complete for the LUKS format when a non-UTF8 | ||
5 | secret is used. | ||
6 | |||
7 | Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> | ||
8 | Message-Id: <20200130213907.2830642-5-danielhb413@gmail.com> | ||
9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
10 | --- | ||
11 | tests/qemu-iotests/282 | 67 ++++++++++++++++++++++++++++++++++++++ | ||
12 | tests/qemu-iotests/282.out | 11 +++++++ | ||
13 | tests/qemu-iotests/group | 1 + | ||
14 | 3 files changed, 79 insertions(+) | ||
15 | create mode 100755 tests/qemu-iotests/282 | ||
16 | create mode 100644 tests/qemu-iotests/282.out | ||
17 | |||
18 | diff --git a/tests/qemu-iotests/282 b/tests/qemu-iotests/282 | ||
19 | new file mode 100755 | 14 | new file mode 100755 |
20 | index XXXXXXX..XXXXXXX | 15 | index XXXXXXX..XXXXXXX |
21 | --- /dev/null | 16 | --- /dev/null |
22 | +++ b/tests/qemu-iotests/282 | 17 | +++ b/tests/qemu-iotests/267 |
23 | @@ -XXX,XX +XXX,XX @@ | 18 | @@ -XXX,XX +XXX,XX @@ |
24 | +#!/usr/bin/env bash | 19 | +#!/usr/bin/env bash |
25 | +# | 20 | +# |
26 | +# Test qemu-img file cleanup for LUKS when using a non-UTF8 secret | 21 | +# Test which nodes are involved in internal snapshots |
27 | +# | 22 | +# |
28 | +# Copyright (C) 2020, IBM Corporation. | 23 | +# Copyright (C) 2019 Red Hat, Inc. |
29 | +# | 24 | +# |
30 | +# This program is free software; you can redistribute it and/or modify | 25 | +# This program is free software; you can redistribute it and/or modify |
31 | +# it under the terms of the GNU General Public License as published by | 26 | +# it under the terms of the GNU General Public License as published by |
32 | +# the Free Software Foundation; either version 2 of the License, or | 27 | +# the Free Software Foundation; either version 2 of the License, or |
33 | +# (at your option) any later version. | 28 | +# (at your option) any later version. |
... | ... | ||
39 | +# | 34 | +# |
40 | +# You should have received a copy of the GNU General Public License | 35 | +# You should have received a copy of the GNU General Public License |
41 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | 36 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
42 | +# | 37 | +# |
43 | + | 38 | + |
39 | +# creator | ||
40 | +owner=kwolf@redhat.com | ||
41 | + | ||
44 | +seq=`basename $0` | 42 | +seq=`basename $0` |
45 | +echo "QA output created by $seq" | 43 | +echo "QA output created by $seq" |
46 | + | 44 | + |
47 | +status=1 # failure is the default! | 45 | +status=1 # failure is the default! |
48 | +TEST_IMAGE_FILE='vol.img' | ||
49 | + | 46 | + |
50 | +_cleanup() | 47 | +_cleanup() |
51 | +{ | 48 | +{ |
52 | + _cleanup_test_img | 49 | + _cleanup_test_img |
53 | + rm non_utf8_secret | 50 | + rm -f "$TEST_DIR/nbd" |
54 | + rm -f $TEST_IMAGE_FILE | ||
55 | +} | 51 | +} |
56 | +trap "_cleanup; exit \$status" 0 1 2 3 15 | 52 | +trap "_cleanup; exit \$status" 0 1 2 3 15 |
57 | + | 53 | + |
58 | +# get standard environment, filters and checks | 54 | +# get standard environment, filters and checks |
59 | +. ./common.rc | 55 | +. ./common.rc |
60 | +. ./common.filter | 56 | +. ./common.filter |
61 | + | 57 | + |
62 | +_supported_fmt luks | 58 | +_supported_fmt qcow2 |
63 | +_supported_proto generic | 59 | +_supported_proto file |
64 | +_unsupported_proto vxhs | 60 | +_supported_os Linux |
65 | + | 61 | + |
66 | +echo "== Create non-UTF8 secret ==" | 62 | +# Internal snapshots are (currently) impossible with refcount_bits=1 |
67 | +echo -n -e '\x3a\x3c\x3b\xff' > non_utf8_secret | 63 | +_unsupported_imgopts 'refcount_bits=1[^0-9]' |
68 | +SECRET="secret,id=sec0,file=non_utf8_secret" | 64 | + |
69 | + | 65 | +do_run_qemu() |
70 | +echo "== Throws an error because of invalid UTF-8 secret ==" | 66 | +{ |
71 | +$QEMU_IMG create -f $IMGFMT --object $SECRET -o "key-secret=sec0" $TEST_IMAGE_FILE 4M | 67 | + echo Testing: "$@" |
72 | + | 68 | + ( |
73 | +echo "== Image file should not exist after the error ==" | 69 | + if ! test -t 0; then |
74 | +if test -f "$TEST_IMAGE_FILE"; then | 70 | + while read cmd; do |
75 | + exit 1 | 71 | + echo $cmd |
76 | +fi | 72 | + done |
77 | + | 73 | + fi |
78 | +echo "== Create a stub image file and run qemu-img again ==" | 74 | + echo quit |
79 | +touch $TEST_IMAGE_FILE | 75 | + ) | $QEMU -nographic -monitor stdio -nodefaults "$@" |
80 | +$QEMU_IMG create -f $IMGFMT --object $SECRET -o "key-secret=sec0" $TEST_IMAGE_FILE 4M | 76 | + echo |
81 | + | 77 | +} |
82 | +echo "== Pre-existing image file should also be deleted after the error ==" | 78 | + |
83 | +if test -f "$TEST_IMAGE_FILE"; then | 79 | +run_qemu() |
84 | + exit 1 | 80 | +{ |
85 | +fi | 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 | ||
86 | + | 182 | + |
87 | +# success, all done | 183 | +# success, all done |
88 | +echo "*** done" | 184 | +echo "*** done" |
89 | +rm -f $seq.full | 185 | +rm -f $seq.full |
90 | +status=0 | 186 | +status=0 |
91 | diff --git a/tests/qemu-iotests/282.out b/tests/qemu-iotests/282.out | 187 | diff --git a/tests/qemu-iotests/267.out b/tests/qemu-iotests/267.out |
92 | new file mode 100644 | 188 | new file mode 100644 |
93 | index XXXXXXX..XXXXXXX | 189 | index XXXXXXX..XXXXXXX |
94 | --- /dev/null | 190 | --- /dev/null |
95 | +++ b/tests/qemu-iotests/282.out | 191 | +++ b/tests/qemu-iotests/267.out |
96 | @@ -XXX,XX +XXX,XX @@ | 192 | @@ -XXX,XX +XXX,XX @@ |
97 | +QA output created by 282 | 193 | +QA output created by 267 |
98 | +== Create non-UTF8 secret == | 194 | + |
99 | +== Throws an error because of invalid UTF-8 secret == | 195 | +=== No block devices at all === |
100 | +qemu-img: vol.img: Data from secret sec0 is not valid UTF-8 | 196 | + |
101 | +Formatting 'vol.img', fmt=luks size=4194304 key-secret=sec0 | 197 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 |
102 | +== Image file should not exist after the error == | 198 | +Testing: |
103 | +== Create a stub image file and run qemu-img again == | 199 | +QEMU X.Y.Z monitor - type 'help' for more information |
104 | +qemu-img: vol.img: Data from secret sec0 is not valid UTF-8 | 200 | +(qemu) savevm snap0 |
105 | +Formatting 'vol.img', fmt=luks size=4194304 key-secret=sec0 | 201 | +Error: No block device can accept snapshots |
106 | +== Pre-existing image file should also be deleted after the error == | 202 | +(qemu) info snapshots |
107 | + *** done | 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 | ||
376 | index XXXXXXX..XXXXXXX 100644 | ||
377 | --- a/tests/qemu-iotests/common.filter | ||
378 | +++ b/tests/qemu-iotests/common.filter | ||
379 | @@ -XXX,XX +XXX,XX @@ | ||
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/' | ||
396 | } | ||
397 | |||
398 | _filter_generated_node_ids() | ||
108 | diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group | 399 | diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group |
109 | index XXXXXXX..XXXXXXX 100644 | 400 | index XXXXXXX..XXXXXXX 100644 |
110 | --- a/tests/qemu-iotests/group | 401 | --- a/tests/qemu-iotests/group |
111 | +++ b/tests/qemu-iotests/group | 402 | +++ b/tests/qemu-iotests/group |
112 | @@ -XXX,XX +XXX,XX @@ | 403 | @@ -XXX,XX +XXX,XX @@ |
113 | 279 rw backing quick | 404 | 263 rw quick |
114 | 280 rw migration quick | 405 | 265 rw auto quick |
115 | 281 rw quick | 406 | 266 rw quick |
116 | +282 rw img quick | 407 | +267 rw auto quick snapshot |
117 | 283 auto quick | ||
118 | 284 rw | ||
119 | 286 rw quick | ||
120 | -- | 408 | -- |
121 | 2.20.1 | 409 | 2.20.1 |
122 | 410 | ||
123 | 411 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <danielhb413@gmail.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 | When using a non-UTF8 secret to create a volume using qemu-img, the | 5 | This makes qemu-iotests skip all Python tests if a Python version before |
4 | following error happens: | 6 | 3.6 is used for the build. |
5 | 7 | ||
6 | $ qemu-img create -f luks --object secret,id=vol_1_encrypt0,file=vol_resize_pool.vol_1.secret.qzVQrI -o key-secret=vol_1_encrypt0 /var/tmp/pool_target/vol_1 10240K | 8 | Suggested-by: Eduardo Habkost <ehabkost@redhat.com> |
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(-) | ||
7 | 17 | ||
8 | Formatting '/var/tmp/pool_target/vol_1', fmt=luks size=10485760 key-secret=vol_1_encrypt0 | 18 | diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check |
9 | qemu-img: /var/tmp/pool_target/vol_1: Data from secret vol_1_encrypt0 is not valid UTF-8 | 19 | index XXXXXXX..XXXXXXX 100755 |
10 | 20 | --- a/tests/qemu-iotests/check | |
11 | However, the created file '/var/tmp/pool_target/vol_1' is left behind in the | 21 | +++ b/tests/qemu-iotests/check |
12 | file system after the failure. This behavior can be observed when creating | 22 | @@ -XXX,XX +XXX,XX @@ then |
13 | the volume using Libvirt, via 'virsh vol-create', and then getting "volume | 23 | export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper" |
14 | target path already exist" errors when trying to re-create the volume. | 24 | fi |
15 | 25 | ||
16 | The volume file is created inside block_crypto_co_create_opts_luks(), in | 26 | +python_usable=false |
17 | block/crypto.c. If the bdrv_create_file() call is successful but any | 27 | +if $PYTHON -c 'import sys; sys.exit(0 if sys.version_info >= (3,6) else 1)' |
18 | succeeding step fails*, the existing 'fail' label does not take into | 28 | +then |
19 | account the created file, leaving it behind. | 29 | + python_usable=true |
20 | 30 | +fi | |
21 | This patch changes block_crypto_co_create_opts_luks() to delete | ||
22 | 'filename' in case of failure. A failure in this point means that | ||
23 | the volume is now truncated/corrupted, so even if 'filename' was an | ||
24 | existing volume before calling qemu-img, it is now unusable. Deleting | ||
25 | the file it is not much worse than leaving it in the filesystem in | ||
26 | this scenario, and we don't have to deal with checking the file | ||
27 | pre-existence in the code. | ||
28 | |||
29 | * in our case, block_crypto_co_create_generic calls qcrypto_block_create, | ||
30 | which calls qcrypto_block_luks_create, and this function fails when | ||
31 | calling qcrypto_secret_lookup_as_utf8. | ||
32 | |||
33 | Reported-by: Srikanth Aithal <bssrikanth@in.ibm.com> | ||
34 | Suggested-by: Kevin Wolf <kwolf@redhat.com> | ||
35 | Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> | ||
36 | Message-Id: <20200130213907.2830642-4-danielhb413@gmail.com> | ||
37 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
38 | --- | ||
39 | block/crypto.c | 18 ++++++++++++++++++ | ||
40 | 1 file changed, 18 insertions(+) | ||
41 | |||
42 | diff --git a/block/crypto.c b/block/crypto.c | ||
43 | index XXXXXXX..XXXXXXX 100644 | ||
44 | --- a/block/crypto.c | ||
45 | +++ b/block/crypto.c | ||
46 | @@ -XXX,XX +XXX,XX @@ | ||
47 | #include "qapi/error.h" | ||
48 | #include "qemu/module.h" | ||
49 | #include "qemu/option.h" | ||
50 | +#include "qemu/cutils.h" | ||
51 | #include "crypto.h" | ||
52 | |||
53 | typedef struct BlockCrypto BlockCrypto; | ||
54 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn block_crypto_co_create_opts_luks(const char *filename, | ||
55 | |||
56 | ret = 0; | ||
57 | fail: | ||
58 | + /* | ||
59 | + * If an error occurred, delete 'filename'. Even if the file existed | ||
60 | + * beforehand, it has been truncated and corrupted in the process. | ||
61 | + */ | ||
62 | + if (ret && bs) { | ||
63 | + Error *local_delete_err = NULL; | ||
64 | + int r_del = bdrv_co_delete_file(bs, &local_delete_err); | ||
65 | + /* | ||
66 | + * ENOTSUP will happen if the block driver doesn't support | ||
67 | + * the 'bdrv_co_delete_file' interface. This is a predictable | ||
68 | + * scenario and shouldn't be reported back to the user. | ||
69 | + */ | ||
70 | + if ((r_del < 0) && (r_del != -ENOTSUP)) { | ||
71 | + error_report_err(local_delete_err); | ||
72 | + } | ||
73 | + } | ||
74 | + | 31 | + |
75 | bdrv_unref(bs); | 32 | default_machine=$($QEMU_PROG -machine help | sed -n '/(default)/ s/ .*//p') |
76 | qapi_free_QCryptoBlockCreateOptions(create_opts); | 33 | default_alias_machine=$($QEMU_PROG -machine help | \ |
77 | qobject_unref(cryptoopts); | 34 | sed -n "/(alias of $default_machine)/ { s/ .*//p; q; }") |
35 | @@ -XXX,XX +XXX,XX @@ do | ||
36 | start=$(_wallclock) | ||
37 | |||
38 | if [ "$(head -n 1 "$source_iotests/$seq")" == "#!/usr/bin/env python" ]; then | ||
39 | - run_command="$PYTHON $seq" | ||
40 | + if $python_usable; then | ||
41 | + run_command="$PYTHON $seq" | ||
42 | + else | ||
43 | + run_command="false" | ||
44 | + echo "Unsupported Python version" > $seq.notrun | ||
45 | + fi | ||
46 | else | ||
47 | run_command="./$seq" | ||
48 | fi | ||
78 | -- | 49 | -- |
79 | 2.20.1 | 50 | 2.20.1 |
80 | 51 | ||
81 | 52 | diff view generated by jsdifflib |
1 | The 'job-complete' QMP command should be run with qmp() rather than | 1 | Some scripts check the Python version number and have two code paths to |
---|---|---|---|
2 | qmp_log() if use_log=False is passed. | 2 | accomodate both Python 2 and 3. Remove the code specific to Python 2 and |
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). | ||
3 | 6 | ||
4 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 7 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
5 | Message-Id: <20200310113831.27293-4-kwolf@redhat.com> | 8 | Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> |
6 | Reviewed-by: Peter Krempa <pkrempa@redhat.com> | 9 | Reviewed-by: Thomas Huth <thuth@redhat.com> |
7 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 10 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> |
11 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
12 | Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
8 | --- | 13 | --- |
9 | tests/qemu-iotests/iotests.py | 5 ++++- | 14 | tests/qemu-iotests/044 | 3 --- |
10 | 1 file changed, 4 insertions(+), 1 deletion(-) | 15 | tests/qemu-iotests/163 | 3 --- |
16 | tests/qemu-iotests/iotests.py | 13 +++---------- | ||
17 | 3 files changed, 3 insertions(+), 16 deletions(-) | ||
11 | 18 | ||
19 | diff --git a/tests/qemu-iotests/044 b/tests/qemu-iotests/044 | ||
20 | index XXXXXXX..XXXXXXX 100755 | ||
21 | --- a/tests/qemu-iotests/044 | ||
22 | +++ b/tests/qemu-iotests/044 | ||
23 | @@ -XXX,XX +XXX,XX @@ import struct | ||
24 | import subprocess | ||
25 | import sys | ||
26 | |||
27 | -if sys.version_info.major == 2: | ||
28 | - range = xrange | ||
29 | - | ||
30 | test_img = os.path.join(iotests.test_dir, 'test.img') | ||
31 | |||
32 | class TestRefcountTableGrowth(iotests.QMPTestCase): | ||
33 | diff --git a/tests/qemu-iotests/163 b/tests/qemu-iotests/163 | ||
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 | |||
12 | diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py | 47 | diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py |
13 | index XXXXXXX..XXXXXXX 100644 | 48 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/tests/qemu-iotests/iotests.py | 49 | --- a/tests/qemu-iotests/iotests.py |
15 | +++ b/tests/qemu-iotests/iotests.py | 50 | +++ b/tests/qemu-iotests/iotests.py |
16 | @@ -XXX,XX +XXX,XX @@ class VM(qtest.QEMUQtestMachine): | 51 | @@ -XXX,XX +XXX,XX @@ from collections import OrderedDict |
17 | if use_log: | 52 | sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) |
18 | log('Job failed: %s' % (j['error'])) | 53 | from qemu import qtest |
19 | elif status == 'ready': | 54 | |
20 | - self.qmp_log('job-complete', id=job) | 55 | +assert sys.version_info >= (3,6) |
21 | + if use_log: | 56 | |
22 | + self.qmp_log('job-complete', id=job) | 57 | # This will not work if arguments contain spaces but is necessary if we |
23 | + else: | 58 | # want to support the override options that ./check supports. |
24 | + self.qmp('job-complete', id=job) | 59 | @@ -XXX,XX +XXX,XX @@ def image_size(img): |
25 | elif status == 'pending' and not auto_finalize: | 60 | return json.loads(r)['virtual-size'] |
26 | if pre_finalize: | 61 | |
27 | pre_finalize() | 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 | |||
28 | -- | 85 | -- |
29 | 2.20.1 | 86 | 2.20.1 |
30 | 87 | ||
31 | 88 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | The newly tested scenario is a common live storage migration scenario: | ||
2 | The target node is opened without a backing file so that the active | ||
3 | layer is mirrored while its backing chain can be copied in the | ||
4 | background. | ||
5 | 1 | ||
6 | The backing chain should be attached to the mirror target node when | ||
7 | finalising the job, just before switching the users of the source node | ||
8 | to the new copy (at which point the mirror job still has a reference to | ||
9 | the node). drive-mirror did this automatically, but with blockdev-mirror | ||
10 | this is the job of the QMP client. | ||
11 | |||
12 | This patch adds test cases for two ways to achieve the desired result, | ||
13 | using either x-blockdev-reopen or blockdev-snapshot. | ||
14 | |||
15 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
16 | Message-Id: <20200310113831.27293-5-kwolf@redhat.com> | ||
17 | Reviewed-by: Peter Krempa <pkrempa@redhat.com> | ||
18 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
19 | --- | ||
20 | tests/qemu-iotests/155 | 56 ++++++++++++++++++++++++++++++++++---- | ||
21 | tests/qemu-iotests/155.out | 4 +-- | ||
22 | 2 files changed, 53 insertions(+), 7 deletions(-) | ||
23 | |||
24 | diff --git a/tests/qemu-iotests/155 b/tests/qemu-iotests/155 | ||
25 | index XXXXXXX..XXXXXXX 100755 | ||
26 | --- a/tests/qemu-iotests/155 | ||
27 | +++ b/tests/qemu-iotests/155 | ||
28 | @@ -XXX,XX +XXX,XX @@ target_img = os.path.join(iotests.test_dir, 'target.' + iotests.imgfmt) | ||
29 | # image during runtime, only makes sense if | ||
30 | # target_blockdev_backing is not None | ||
31 | # (None: same as target_backing) | ||
32 | +# target_open_with_backing: If True, the target image is added with its backing | ||
33 | +# chain opened right away. If False, blockdev-add | ||
34 | +# opens it without a backing file and job completion | ||
35 | +# is supposed to open the backing chain. | ||
36 | |||
37 | class BaseClass(iotests.QMPTestCase): | ||
38 | target_blockdev_backing = None | ||
39 | target_real_backing = None | ||
40 | + target_open_with_backing = True | ||
41 | |||
42 | def setUp(self): | ||
43 | qemu_img('create', '-f', iotests.imgfmt, back0_img, '1440K') | ||
44 | @@ -XXX,XX +XXX,XX @@ class BaseClass(iotests.QMPTestCase): | ||
45 | options = { 'node-name': 'target', | ||
46 | 'driver': iotests.imgfmt, | ||
47 | 'file': { 'driver': 'file', | ||
48 | + 'node-name': 'target-file', | ||
49 | 'filename': target_img } } | ||
50 | - if self.target_blockdev_backing: | ||
51 | - options['backing'] = self.target_blockdev_backing | ||
52 | + | ||
53 | + if not self.target_open_with_backing: | ||
54 | + options['backing'] = None | ||
55 | + elif self.target_blockdev_backing: | ||
56 | + options['backing'] = self.target_blockdev_backing | ||
57 | |||
58 | result = self.vm.qmp('blockdev-add', **options) | ||
59 | self.assert_qmp(result, 'return', {}) | ||
60 | @@ -XXX,XX +XXX,XX @@ class BaseClass(iotests.QMPTestCase): | ||
61 | # cmd: Mirroring command to execute, either drive-mirror or blockdev-mirror | ||
62 | |||
63 | class MirrorBaseClass(BaseClass): | ||
64 | + def openBacking(self): | ||
65 | + pass | ||
66 | + | ||
67 | def runMirror(self, sync): | ||
68 | if self.cmd == 'blockdev-mirror': | ||
69 | result = self.vm.qmp(self.cmd, job_id='mirror-job', device='source', | ||
70 | - sync=sync, target='target') | ||
71 | + sync=sync, target='target', | ||
72 | + auto_finalize=False) | ||
73 | else: | ||
74 | if self.existing: | ||
75 | mode = 'existing' | ||
76 | @@ -XXX,XX +XXX,XX @@ class MirrorBaseClass(BaseClass): | ||
77 | result = self.vm.qmp(self.cmd, job_id='mirror-job', device='source', | ||
78 | sync=sync, target=target_img, | ||
79 | format=iotests.imgfmt, mode=mode, | ||
80 | - node_name='target') | ||
81 | + node_name='target', auto_finalize=False) | ||
82 | |||
83 | self.assert_qmp(result, 'return', {}) | ||
84 | |||
85 | - self.complete_and_wait('mirror-job') | ||
86 | + self.vm.run_job('mirror-job', use_log=False, auto_finalize=False, | ||
87 | + pre_finalize=self.openBacking, auto_dismiss=True) | ||
88 | |||
89 | def testFull(self): | ||
90 | self.runMirror('full') | ||
91 | @@ -XXX,XX +XXX,XX @@ class TestBlockdevMirrorForcedBacking(MirrorBaseClass): | ||
92 | target_blockdev_backing = { 'driver': 'null-co' } | ||
93 | target_real_backing = 'null-co://' | ||
94 | |||
95 | +# Attach the backing chain only during completion, with blockdev-reopen | ||
96 | +class TestBlockdevMirrorReopen(MirrorBaseClass): | ||
97 | + cmd = 'blockdev-mirror' | ||
98 | + existing = True | ||
99 | + target_backing = 'null-co://' | ||
100 | + target_open_with_backing = False | ||
101 | + | ||
102 | + def openBacking(self): | ||
103 | + if not self.target_open_with_backing: | ||
104 | + result = self.vm.qmp('blockdev-add', node_name="backing", | ||
105 | + driver="null-co") | ||
106 | + self.assert_qmp(result, 'return', {}) | ||
107 | + result = self.vm.qmp('x-blockdev-reopen', node_name="target", | ||
108 | + driver=iotests.imgfmt, file="target-file", | ||
109 | + backing="backing") | ||
110 | + self.assert_qmp(result, 'return', {}) | ||
111 | + | ||
112 | +# Attach the backing chain only during completion, with blockdev-snapshot | ||
113 | +class TestBlockdevMirrorSnapshot(MirrorBaseClass): | ||
114 | + cmd = 'blockdev-mirror' | ||
115 | + existing = True | ||
116 | + target_backing = 'null-co://' | ||
117 | + target_open_with_backing = False | ||
118 | + | ||
119 | + def openBacking(self): | ||
120 | + if not self.target_open_with_backing: | ||
121 | + result = self.vm.qmp('blockdev-add', node_name="backing", | ||
122 | + driver="null-co") | ||
123 | + self.assert_qmp(result, 'return', {}) | ||
124 | + result = self.vm.qmp('blockdev-snapshot', node="backing", | ||
125 | + overlay="target") | ||
126 | + self.assert_qmp(result, 'return', {}) | ||
127 | |||
128 | class TestCommit(BaseClass): | ||
129 | existing = False | ||
130 | diff --git a/tests/qemu-iotests/155.out b/tests/qemu-iotests/155.out | ||
131 | index XXXXXXX..XXXXXXX 100644 | ||
132 | --- a/tests/qemu-iotests/155.out | ||
133 | +++ b/tests/qemu-iotests/155.out | ||
134 | @@ -XXX,XX +XXX,XX @@ | ||
135 | -................... | ||
136 | +......................... | ||
137 | ---------------------------------------------------------------------- | ||
138 | -Ran 19 tests | ||
139 | +Ran 25 tests | ||
140 | |||
141 | OK | ||
142 | -- | ||
143 | 2.20.1 | ||
144 | |||
145 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | external_snapshot_prepare() tries to move the overlay to the AioContext | ||
2 | of the backing file (the snapshotted node). However, it's possible that | ||
3 | this doesn't work, but the backing file can instead be moved to the | ||
4 | overlay's AioContext (e.g. opening the backing chain for a mirror | ||
5 | target). | ||
6 | 1 | ||
7 | bdrv_append() already indirectly uses bdrv_attach_node(), which takes | ||
8 | care to move nodes to make sure they use the same AioContext and which | ||
9 | tries both directions. | ||
10 | |||
11 | So the problem has a simple fix: Just delete the unnecessary extra | ||
12 | bdrv_try_set_aio_context() call in external_snapshot_prepare() and | ||
13 | instead assert in bdrv_append() that both nodes were indeed moved to the | ||
14 | same AioContext. | ||
15 | |||
16 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
17 | Message-Id: <20200310113831.27293-6-kwolf@redhat.com> | ||
18 | Tested-by: Peter Krempa <pkrempa@redhat.com> | ||
19 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
20 | --- | ||
21 | block.c | 1 + | ||
22 | blockdev.c | 16 ---------------- | ||
23 | 2 files changed, 1 insertion(+), 16 deletions(-) | ||
24 | |||
25 | diff --git a/block.c b/block.c | ||
26 | index XXXXXXX..XXXXXXX 100644 | ||
27 | --- a/block.c | ||
28 | +++ b/block.c | ||
29 | @@ -XXX,XX +XXX,XX @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to, | ||
30 | bdrv_ref(from); | ||
31 | |||
32 | assert(qemu_get_current_aio_context() == qemu_get_aio_context()); | ||
33 | + assert(bdrv_get_aio_context(from) == bdrv_get_aio_context(to)); | ||
34 | bdrv_drained_begin(from); | ||
35 | |||
36 | /* Put all parents into @list and calculate their cumulative permissions */ | ||
37 | diff --git a/blockdev.c b/blockdev.c | ||
38 | index XXXXXXX..XXXXXXX 100644 | ||
39 | --- a/blockdev.c | ||
40 | +++ b/blockdev.c | ||
41 | @@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common, | ||
42 | DO_UPCAST(ExternalSnapshotState, common, common); | ||
43 | TransactionAction *action = common->action; | ||
44 | AioContext *aio_context; | ||
45 | - AioContext *old_context; | ||
46 | uint64_t perm, shared; | ||
47 | - int ret; | ||
48 | |||
49 | /* 'blockdev-snapshot' and 'blockdev-snapshot-sync' have similar | ||
50 | * purpose but a different set of parameters */ | ||
51 | @@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common, | ||
52 | goto out; | ||
53 | } | ||
54 | |||
55 | - /* Honor bdrv_try_set_aio_context() context acquisition requirements. */ | ||
56 | - old_context = bdrv_get_aio_context(state->new_bs); | ||
57 | - aio_context_release(aio_context); | ||
58 | - aio_context_acquire(old_context); | ||
59 | - | ||
60 | - ret = bdrv_try_set_aio_context(state->new_bs, aio_context, errp); | ||
61 | - | ||
62 | - aio_context_release(old_context); | ||
63 | - aio_context_acquire(aio_context); | ||
64 | - | ||
65 | - if (ret < 0) { | ||
66 | - goto out; | ||
67 | - } | ||
68 | - | ||
69 | /* This removes our old bs and adds the new bs. This is an operation that | ||
70 | * can fail, so we need to do it in .prepare; undoing it for abort is | ||
71 | * always possible. */ | ||
72 | -- | ||
73 | 2.20.1 | ||
74 | |||
75 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This patch adds test cases for attaching the backing chain to a mirror | ||
2 | job target right before finalising the job, where the image is in a | ||
3 | non-mainloop AioContext (i.e. the backing chain needs to be moved to the | ||
4 | AioContext of the mirror target). | ||
5 | 1 | ||
6 | This requires switching the test case from virtio-blk to virtio-scsi | ||
7 | because virtio-blk only actually starts using the iothreads when the | ||
8 | guest driver initialises the device (which never happens in a test case | ||
9 | without a guest OS). virtio-scsi always keeps its block nodes in the | ||
10 | AioContext of the the requested iothread without guest interaction. | ||
11 | |||
12 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
13 | Message-Id: <20200310113831.27293-7-kwolf@redhat.com> | ||
14 | Reviewed-by: Peter Krempa <pkrempa@redhat.com> | ||
15 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
16 | --- | ||
17 | tests/qemu-iotests/155 | 32 +++++++++++++++++++++++--------- | ||
18 | tests/qemu-iotests/155.out | 4 ++-- | ||
19 | 2 files changed, 25 insertions(+), 11 deletions(-) | ||
20 | |||
21 | diff --git a/tests/qemu-iotests/155 b/tests/qemu-iotests/155 | ||
22 | index XXXXXXX..XXXXXXX 100755 | ||
23 | --- a/tests/qemu-iotests/155 | ||
24 | +++ b/tests/qemu-iotests/155 | ||
25 | @@ -XXX,XX +XXX,XX @@ target_img = os.path.join(iotests.test_dir, 'target.' + iotests.imgfmt) | ||
26 | # chain opened right away. If False, blockdev-add | ||
27 | # opens it without a backing file and job completion | ||
28 | # is supposed to open the backing chain. | ||
29 | +# use_iothread: If True, an iothread is configured for the virtio-blk device | ||
30 | +# that uses the image being mirrored | ||
31 | |||
32 | class BaseClass(iotests.QMPTestCase): | ||
33 | target_blockdev_backing = None | ||
34 | target_real_backing = None | ||
35 | target_open_with_backing = True | ||
36 | + use_iothread = False | ||
37 | |||
38 | def setUp(self): | ||
39 | qemu_img('create', '-f', iotests.imgfmt, back0_img, '1440K') | ||
40 | @@ -XXX,XX +XXX,XX @@ class BaseClass(iotests.QMPTestCase): | ||
41 | 'file': {'driver': 'file', | ||
42 | 'filename': source_img}} | ||
43 | self.vm.add_blockdev(self.vm.qmp_to_opts(blockdev)) | ||
44 | - self.vm.add_device('virtio-blk,id=qdev0,drive=source') | ||
45 | + | ||
46 | + if self.use_iothread: | ||
47 | + self.vm.add_object('iothread,id=iothread0') | ||
48 | + iothread = ",iothread=iothread0" | ||
49 | + else: | ||
50 | + iothread = "" | ||
51 | + | ||
52 | + self.vm.add_device('virtio-scsi%s' % iothread) | ||
53 | + self.vm.add_device('scsi-hd,id=qdev0,drive=source') | ||
54 | + | ||
55 | self.vm.launch() | ||
56 | |||
57 | self.assertIntactSourceBackingChain() | ||
58 | @@ -XXX,XX +XXX,XX @@ class MirrorBaseClass(BaseClass): | ||
59 | def testFull(self): | ||
60 | self.runMirror('full') | ||
61 | |||
62 | - node = self.findBlockNode('target', | ||
63 | - '/machine/peripheral/qdev0/virtio-backend') | ||
64 | + node = self.findBlockNode('target', 'qdev0') | ||
65 | self.assertCorrectBackingImage(node, None) | ||
66 | self.assertIntactSourceBackingChain() | ||
67 | |||
68 | def testTop(self): | ||
69 | self.runMirror('top') | ||
70 | |||
71 | - node = self.findBlockNode('target', | ||
72 | - '/machine/peripheral/qdev0/virtio-backend') | ||
73 | + node = self.findBlockNode('target', 'qdev0') | ||
74 | self.assertCorrectBackingImage(node, back2_img) | ||
75 | self.assertIntactSourceBackingChain() | ||
76 | |||
77 | def testNone(self): | ||
78 | self.runMirror('none') | ||
79 | |||
80 | - node = self.findBlockNode('target', | ||
81 | - '/machine/peripheral/qdev0/virtio-backend') | ||
82 | + node = self.findBlockNode('target', 'qdev0') | ||
83 | self.assertCorrectBackingImage(node, source_img) | ||
84 | self.assertIntactSourceBackingChain() | ||
85 | |||
86 | @@ -XXX,XX +XXX,XX @@ class TestBlockdevMirrorReopen(MirrorBaseClass): | ||
87 | backing="backing") | ||
88 | self.assert_qmp(result, 'return', {}) | ||
89 | |||
90 | +class TestBlockdevMirrorReopenIothread(TestBlockdevMirrorReopen): | ||
91 | + use_iothread = True | ||
92 | + | ||
93 | # Attach the backing chain only during completion, with blockdev-snapshot | ||
94 | class TestBlockdevMirrorSnapshot(MirrorBaseClass): | ||
95 | cmd = 'blockdev-mirror' | ||
96 | @@ -XXX,XX +XXX,XX @@ class TestBlockdevMirrorSnapshot(MirrorBaseClass): | ||
97 | overlay="target") | ||
98 | self.assert_qmp(result, 'return', {}) | ||
99 | |||
100 | +class TestBlockdevMirrorSnapshotIothread(TestBlockdevMirrorSnapshot): | ||
101 | + use_iothread = True | ||
102 | + | ||
103 | class TestCommit(BaseClass): | ||
104 | existing = False | ||
105 | |||
106 | @@ -XXX,XX +XXX,XX @@ class TestCommit(BaseClass): | ||
107 | |||
108 | self.vm.event_wait('BLOCK_JOB_COMPLETED') | ||
109 | |||
110 | - node = self.findBlockNode(None, | ||
111 | - '/machine/peripheral/qdev0/virtio-backend') | ||
112 | + node = self.findBlockNode(None, 'qdev0') | ||
113 | self.assert_qmp(node, 'image' + '/backing-image' * 0 + '/filename', | ||
114 | back1_img) | ||
115 | self.assert_qmp(node, 'image' + '/backing-image' * 1 + '/filename', | ||
116 | diff --git a/tests/qemu-iotests/155.out b/tests/qemu-iotests/155.out | ||
117 | index XXXXXXX..XXXXXXX 100644 | ||
118 | --- a/tests/qemu-iotests/155.out | ||
119 | +++ b/tests/qemu-iotests/155.out | ||
120 | @@ -XXX,XX +XXX,XX @@ | ||
121 | -......................... | ||
122 | +............................... | ||
123 | ---------------------------------------------------------------------- | ||
124 | -Ran 25 tests | ||
125 | +Ran 31 tests | ||
126 | |||
127 | OK | ||
128 | -- | ||
129 | 2.20.1 | ||
130 | |||
131 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Peter Krempa <pkrempa@redhat.com> | ||
2 | 1 | ||
3 | Anounce that 'blockdev-snapshot' command's permissions allow changing | ||
4 | of the backing file if the 'consistent_read' permission is not required. | ||
5 | |||
6 | This is useful for libvirt to allow late opening of the backing chain | ||
7 | during a blockdev-mirror. | ||
8 | |||
9 | Signed-off-by: Peter Krempa <pkrempa@redhat.com> | ||
10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
11 | Message-Id: <20200310113831.27293-8-kwolf@redhat.com> | ||
12 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
13 | --- | ||
14 | qapi/block-core.json | 9 ++++++++- | ||
15 | 1 file changed, 8 insertions(+), 1 deletion(-) | ||
16 | |||
17 | diff --git a/qapi/block-core.json b/qapi/block-core.json | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/qapi/block-core.json | ||
20 | +++ b/qapi/block-core.json | ||
21 | @@ -XXX,XX +XXX,XX @@ | ||
22 | # | ||
23 | # For the arguments, see the documentation of BlockdevSnapshot. | ||
24 | # | ||
25 | +# Features: | ||
26 | +# @allow-write-only-overlay: If present, the check whether this operation is safe | ||
27 | +# was relaxed so that it can be used to change | ||
28 | +# backing file of a destination of a blockdev-mirror. | ||
29 | +# (since 5.0) | ||
30 | +# | ||
31 | # Since: 2.5 | ||
32 | # | ||
33 | # Example: | ||
34 | @@ -XXX,XX +XXX,XX @@ | ||
35 | # | ||
36 | ## | ||
37 | { 'command': 'blockdev-snapshot', | ||
38 | - 'data': 'BlockdevSnapshot' } | ||
39 | + 'data': 'BlockdevSnapshot', | ||
40 | + 'features': [ 'allow-write-only-overlay' ] } | ||
41 | |||
42 | ## | ||
43 | # @change-backing-file: | ||
44 | -- | ||
45 | 2.20.1 | ||
46 | |||
47 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
2 | 1 | ||
3 | The socket_scm_helper path got corrupted during the mechanical | ||
4 | refactor moving the qtests files into their own sub-directory. | ||
5 | |||
6 | Fixes: 1e8a1fae7 ("test: Move qtests to a separate directory") | ||
7 | Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
8 | Message-Id: <20200306165751.18986-1-philmd@redhat.com> | ||
9 | Reviewed-by: Laurent Vivier <laurent@vivier.eu> | ||
10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
11 | --- | ||
12 | tests/Makefile.include | 1 + | ||
13 | tests/qtest/Makefile.include | 1 - | ||
14 | 2 files changed, 1 insertion(+), 1 deletion(-) | ||
15 | |||
16 | diff --git a/tests/Makefile.include b/tests/Makefile.include | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/tests/Makefile.include | ||
19 | +++ b/tests/Makefile.include | ||
20 | @@ -XXX,XX +XXX,XX @@ include $(SRC_PATH)/tests/qtest/Makefile.include | ||
21 | tests/test-qga$(EXESUF): qemu-ga$(EXESUF) | ||
22 | tests/test-qga$(EXESUF): tests/test-qga.o $(qtest-obj-y) | ||
23 | tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o $(test-util-obj-y) libvhost-user.a | ||
24 | +tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o | ||
25 | |||
26 | SPEED = quick | ||
27 | |||
28 | diff --git a/tests/qtest/Makefile.include b/tests/qtest/Makefile.include | ||
29 | index XXXXXXX..XXXXXXX 100644 | ||
30 | --- a/tests/qtest/Makefile.include | ||
31 | +++ b/tests/qtest/Makefile.include | ||
32 | @@ -XXX,XX +XXX,XX @@ tests/qtest/usb-hcd-ehci-test$(EXESUF): tests/qtest/usb-hcd-ehci-test.o $(libqos | ||
33 | tests/qtest/usb-hcd-xhci-test$(EXESUF): tests/qtest/usb-hcd-xhci-test.o $(libqos-usb-obj-y) | ||
34 | tests/qtest/cpu-plug-test$(EXESUF): tests/qtest/cpu-plug-test.o | ||
35 | tests/qtest/migration-test$(EXESUF): tests/qtest/migration-test.o tests/qtest/migration-helpers.o | ||
36 | -tests/qtest/qemu-iotests/qtest/socket_scm_helper$(EXESUF): tests/qtest/qemu-iotests/qtest/socket_scm_helper.o | ||
37 | tests/qtest/test-netfilter$(EXESUF): tests/qtest/test-netfilter.o $(qtest-obj-y) | ||
38 | tests/qtest/test-filter-mirror$(EXESUF): tests/qtest/test-filter-mirror.o $(qtest-obj-y) | ||
39 | tests/qtest/test-filter-redirector$(EXESUF): tests/qtest/test-filter-redirector.o $(qtest-obj-y) | ||
40 | -- | ||
41 | 2.20.1 | ||
42 | |||
43 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Daniel Henrique Barboza <danielhb413@gmail.com> | ||
2 | 1 | ||
3 | Adding to Block Drivers the capability of being able to clean up | ||
4 | its created files can be useful in certain situations. For the | ||
5 | LUKS driver, for instance, a failure in one of its authentication | ||
6 | steps can leave files in the host that weren't there before. | ||
7 | |||
8 | This patch adds the 'bdrv_co_delete_file' interface to block | ||
9 | drivers and add it to the 'file' driver in file-posix.c. The | ||
10 | implementation is given by 'raw_co_delete_file'. | ||
11 | |||
12 | Suggested-by: Daniel P. Berrangé <berrange@redhat.com> | ||
13 | Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> | ||
14 | Message-Id: <20200130213907.2830642-2-danielhb413@gmail.com> | ||
15 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
16 | --- | ||
17 | include/block/block_int.h | 4 ++++ | ||
18 | block/file-posix.c | 23 +++++++++++++++++++++++ | ||
19 | 2 files changed, 27 insertions(+) | ||
20 | |||
21 | diff --git a/include/block/block_int.h b/include/block/block_int.h | ||
22 | index XXXXXXX..XXXXXXX 100644 | ||
23 | --- a/include/block/block_int.h | ||
24 | +++ b/include/block/block_int.h | ||
25 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
26 | */ | ||
27 | int coroutine_fn (*bdrv_co_flush)(BlockDriverState *bs); | ||
28 | |||
29 | + /* Delete a created file. */ | ||
30 | + int coroutine_fn (*bdrv_co_delete_file)(BlockDriverState *bs, | ||
31 | + Error **errp); | ||
32 | + | ||
33 | /* | ||
34 | * Flushes all data that was already written to the OS all the way down to | ||
35 | * the disk (for example file-posix.c calls fsync()). | ||
36 | diff --git a/block/file-posix.c b/block/file-posix.c | ||
37 | index XXXXXXX..XXXXXXX 100644 | ||
38 | --- a/block/file-posix.c | ||
39 | +++ b/block/file-posix.c | ||
40 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_create_opts(const char *filename, QemuOpts *opts, | ||
41 | return raw_co_create(&options, errp); | ||
42 | } | ||
43 | |||
44 | +static int coroutine_fn raw_co_delete_file(BlockDriverState *bs, | ||
45 | + Error **errp) | ||
46 | +{ | ||
47 | + struct stat st; | ||
48 | + int ret; | ||
49 | + | ||
50 | + if (!(stat(bs->filename, &st) == 0) || !S_ISREG(st.st_mode)) { | ||
51 | + error_setg_errno(errp, ENOENT, "%s is not a regular file", | ||
52 | + bs->filename); | ||
53 | + return -ENOENT; | ||
54 | + } | ||
55 | + | ||
56 | + ret = unlink(bs->filename); | ||
57 | + if (ret < 0) { | ||
58 | + ret = -errno; | ||
59 | + error_setg_errno(errp, -ret, "Error when deleting file %s", | ||
60 | + bs->filename); | ||
61 | + } | ||
62 | + | ||
63 | + return ret; | ||
64 | +} | ||
65 | + | ||
66 | /* | ||
67 | * Find allocation range in @bs around offset @start. | ||
68 | * May change underlying file descriptor's file offset. | ||
69 | @@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_file = { | ||
70 | .bdrv_co_block_status = raw_co_block_status, | ||
71 | .bdrv_co_invalidate_cache = raw_co_invalidate_cache, | ||
72 | .bdrv_co_pwrite_zeroes = raw_co_pwrite_zeroes, | ||
73 | + .bdrv_co_delete_file = raw_co_delete_file, | ||
74 | |||
75 | .bdrv_co_preadv = raw_co_preadv, | ||
76 | .bdrv_co_pwritev = raw_co_pwritev, | ||
77 | -- | ||
78 | 2.20.1 | ||
79 | |||
80 | diff view generated by jsdifflib |