1
The following changes since commit 672f9d0df10a68a5c5f2b32cbc8284abf9f5ee18:
1
The following changes since commit eaefea537b476cb853e2edbdc68e969ec777e4bb:
2
2
3
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2020-02-18 14:23:43 +0000)
3
Merge remote-tracking branch 'remotes/mjt/tags/trivial-patches-fetch' into staging (2017-12-18 14:17:42 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/XanClic/qemu.git tags/pull-block-2020-02-20
7
git://github.com/stefanha/qemu.git tags/block-pull-request
8
8
9
for you to fetch changes up to dff8d44c96f128480430b0c59ed8760917dbd427:
9
for you to fetch changes up to 7a9dda0d7f9831c2432620dcfefdadbb7ae888dc:
10
10
11
iotests: Test snapshot -l field separation (2020-02-20 16:43:42 +0100)
11
qemu-iotests: add 203 savevm with IOThreads test (2017-12-19 10:25:09 +0000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block patches:
14
Pull request
15
- qemu-img convert: New --target-is-zero parameter
15
16
- qcow2: Specify non-default compression type flag
16
v2:
17
- optionally flat output for query-named-block-nodes
17
* Fixed incorrect virtio_blk_data_plane_create() local_err refactoring in
18
- some fixes
18
"hw/block: Use errp directly rather than local_err" that broke virtio-blk
19
- pseudo-creation of images on block devices is now done by a generic
19
over virtio-mmio [Peter]
20
block layer function
21
20
22
----------------------------------------------------------------
21
----------------------------------------------------------------
23
Daniel P. Berrangé (1):
24
block: always fill entire LUKS header space with zeros
25
22
26
David Edmondson (1):
23
Mao Zhongyi (4):
27
qemu-img: Add --target-is-zero to convert
24
hw/block/nvme: Convert to realize
25
hw/block: Fix the return type
26
hw/block: Use errp directly rather than local_err
27
dev-storage: Fix the unusual function name
28
28
29
Max Reitz (11):
29
Mark Kanda (2):
30
iotests/147: Fix drive parameters
30
virtio-blk: make queue size configurable
31
iotests/279: Fix for non-qcow2 formats
31
virtio-blk: reject configs with logical block size > physical block
32
block/nbd: Fix hang in .bdrv_close()
32
size
33
block: Generic file creation fallback
34
file-posix: Drop hdev_co_create_opts()
35
iscsi: Drop iscsi_co_create_opts()
36
iotests: Add test for image creation fallback
37
qemu-img: Fix convert -n -B for backing-less targets
38
iotests: Test convert -n -B to backing-less target
39
block: Fix VM size field width in snapshot dump
40
iotests: Test snapshot -l field separation
41
33
42
Peter Krempa (1):
34
Paolo Bonzini (1):
43
qapi: Allow getting flat output from 'query-named-block-nodes'
35
block: avoid recursive AioContext acquire in bdrv_inactivate_all()
44
36
45
Thomas Huth (1):
37
Stefan Hajnoczi (16):
46
iotests: Remove the superfluous 2nd check for the availability of
38
coroutine: simplify co_aio_sleep_ns() prototype
47
quorum
39
qdev: drop unused #include "sysemu/iothread.h"
40
blockdev: hold AioContext for bdrv_unref() in
41
external_snapshot_clean()
42
block: don't keep AioContext acquired after
43
external_snapshot_prepare()
44
block: don't keep AioContext acquired after drive_backup_prepare()
45
block: don't keep AioContext acquired after blockdev_backup_prepare()
46
block: don't keep AioContext acquired after
47
internal_snapshot_prepare()
48
block: drop unused BlockDirtyBitmapState->aio_context field
49
iothread: add iothread_by_id() API
50
blockdev: add x-blockdev-set-iothread testing command
51
qemu-iotests: add 202 external snapshots IOThread test
52
docs: mark nested AioContext locking as a legacy API
53
blockdev: add x-blockdev-set-iothread force boolean
54
iotests: add VM.add_object()
55
iothread: fix iothread_stop() race condition
56
qemu-iotests: add 203 savevm with IOThreads test
48
57
49
Vladimir Sementsov-Ogievskiy (3):
58
docs/devel/multiple-iothreads.txt | 7 +-
50
docs: improve qcow2 spec about extending image header
59
qapi/block-core.json | 40 ++++++
51
docs: qcow2: introduce compression type feature
60
hw/block/dataplane/virtio-blk.h | 2 +-
52
block/backup-top: fix flags handling
61
include/hw/block/block.h | 4 +-
53
62
include/hw/virtio/virtio-blk.h | 1 +
54
block.c | 164 +++++++++++++++++++++++++++++++++----
63
include/qemu/coroutine.h | 6 +-
55
block/backup-top.c | 31 ++++---
64
include/sysemu/iothread.h | 4 +-
56
block/file-posix.c | 67 ---------------
65
block.c | 14 ++-
57
block/iscsi.c | 56 -------------
66
block/null.c | 3 +-
58
block/nbd.c | 14 +++-
67
block/sheepdog.c | 3 +-
59
block/qapi.c | 15 +++-
68
blockdev.c | 259 +++++++++++++++++++++++++++-----------
60
block/qcow2.c | 11 ++-
69
hw/block/block.c | 15 ++-
61
blockdev.c | 8 +-
70
hw/block/dataplane/virtio-blk.c | 12 +-
62
docs/interop/qcow2.txt | 64 ++++++++++++++-
71
hw/block/fdc.c | 17 +--
63
docs/interop/qemu-img.rst | 9 +-
72
hw/block/nvme.c | 23 ++--
64
include/block/block.h | 2 +-
73
hw/block/virtio-blk.c | 30 +++--
65
include/block/qapi.h | 4 +-
74
hw/core/qdev-properties-system.c | 1 -
66
monitor/hmp-cmds.c | 2 +-
75
hw/ide/qdev.c | 12 +-
67
qapi/block-core.json | 7 +-
76
hw/scsi/scsi-disk.c | 13 +-
68
qemu-img-cmds.hx | 4 +-
77
hw/usb/dev-storage.c | 29 ++---
69
qemu-img.c | 28 ++++++-
78
iothread.c | 27 +++-
70
tests/qemu-iotests/122 | 14 ++++
79
util/qemu-coroutine-sleep.c | 4 +-
71
tests/qemu-iotests/122.out | 5 ++
80
tests/qemu-iotests/202 | 95 ++++++++++++++
72
tests/qemu-iotests/139 | 3 -
81
tests/qemu-iotests/202.out | 11 ++
73
tests/qemu-iotests/147 | 2 +-
82
tests/qemu-iotests/203 | 59 +++++++++
74
tests/qemu-iotests/259 | 62 ++++++++++++++
83
tests/qemu-iotests/203.out | 6 +
75
tests/qemu-iotests/259.out | 14 ++++
84
tests/qemu-iotests/group | 2 +
76
tests/qemu-iotests/279 | 7 +-
85
tests/qemu-iotests/iotests.py | 5 +
77
tests/qemu-iotests/284 | 97 ++++++++++++++++++++++
86
28 files changed, 531 insertions(+), 173 deletions(-)
78
tests/qemu-iotests/284.out | 62 ++++++++++++++
87
create mode 100755 tests/qemu-iotests/202
79
tests/qemu-iotests/286 | 76 +++++++++++++++++
88
create mode 100644 tests/qemu-iotests/202.out
80
tests/qemu-iotests/286.out | 8 ++
89
create mode 100755 tests/qemu-iotests/203
81
tests/qemu-iotests/group | 3 +
90
create mode 100644 tests/qemu-iotests/203.out
82
28 files changed, 659 insertions(+), 180 deletions(-)
83
create mode 100755 tests/qemu-iotests/259
84
create mode 100644 tests/qemu-iotests/259.out
85
create mode 100755 tests/qemu-iotests/284
86
create mode 100644 tests/qemu-iotests/284.out
87
create mode 100755 tests/qemu-iotests/286
88
create mode 100644 tests/qemu-iotests/286.out
89
91
90
--
92
--
91
2.24.1
93
2.14.3
92
94
93
95
diff view generated by jsdifflib
New patch
1
The AioContext pointer argument to co_aio_sleep_ns() is only used for
2
the sleep timer. It does not affect where the caller coroutine is
3
resumed.
1
4
5
Due to changes to coroutine and AIO APIs it is now possible to drop the
6
AioContext pointer argument. This is safe to do since no caller has
7
specific requirements for which AioContext the timer must run in.
8
9
This patch drops the AioContext pointer argument and renames the
10
function to simplify the API.
11
12
Reported-by: Paolo Bonzini <pbonzini@redhat.com>
13
Reported-by: Eric Blake <eblake@redhat.com>
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Reviewed-by: Eric Blake <eblake@redhat.com>
16
Message-id: 20171109102652.6360-1-stefanha@redhat.com
17
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
18
---
19
include/qemu/coroutine.h | 6 +-----
20
block/null.c | 3 +--
21
block/sheepdog.c | 3 +--
22
util/qemu-coroutine-sleep.c | 4 ++--
23
4 files changed, 5 insertions(+), 11 deletions(-)
24
25
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/qemu/coroutine.h
28
+++ b/include/qemu/coroutine.h
29
@@ -XXX,XX +XXX,XX @@ void qemu_co_rwlock_unlock(CoRwlock *lock);
30
31
/**
32
* Yield the coroutine for a given duration
33
- *
34
- * Behaves similarly to co_sleep_ns(), but the sleeping coroutine will be
35
- * resumed when using aio_poll().
36
*/
37
-void coroutine_fn co_aio_sleep_ns(AioContext *ctx, QEMUClockType type,
38
- int64_t ns);
39
+void coroutine_fn qemu_co_sleep_ns(QEMUClockType type, int64_t ns);
40
41
/**
42
* Yield until a file descriptor becomes readable
43
diff --git a/block/null.c b/block/null.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/block/null.c
46
+++ b/block/null.c
47
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int null_co_common(BlockDriverState *bs)
48
BDRVNullState *s = bs->opaque;
49
50
if (s->latency_ns) {
51
- co_aio_sleep_ns(bdrv_get_aio_context(bs), QEMU_CLOCK_REALTIME,
52
- s->latency_ns);
53
+ qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, s->latency_ns);
54
}
55
return 0;
56
}
57
diff --git a/block/sheepdog.c b/block/sheepdog.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/block/sheepdog.c
60
+++ b/block/sheepdog.c
61
@@ -XXX,XX +XXX,XX @@ static coroutine_fn void reconnect_to_sdog(void *opaque)
62
if (s->fd < 0) {
63
DPRINTF("Wait for connection to be established\n");
64
error_report_err(local_err);
65
- co_aio_sleep_ns(bdrv_get_aio_context(s->bs), QEMU_CLOCK_REALTIME,
66
- 1000000000ULL);
67
+ qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000000ULL);
68
}
69
};
70
71
diff --git a/util/qemu-coroutine-sleep.c b/util/qemu-coroutine-sleep.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/util/qemu-coroutine-sleep.c
74
+++ b/util/qemu-coroutine-sleep.c
75
@@ -XXX,XX +XXX,XX @@ static void co_sleep_cb(void *opaque)
76
aio_co_wake(sleep_cb->co);
77
}
78
79
-void coroutine_fn co_aio_sleep_ns(AioContext *ctx, QEMUClockType type,
80
- int64_t ns)
81
+void coroutine_fn qemu_co_sleep_ns(QEMUClockType type, int64_t ns)
82
{
83
+ AioContext *ctx = qemu_get_current_aio_context();
84
CoSleepCB sleep_cb = {
85
.co = qemu_coroutine_self(),
86
};
87
--
88
2.14.3
89
90
diff view generated by jsdifflib
1
From: David Edmondson <david.edmondson@oracle.com>
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
2
2
3
In many cases the target of a convert operation is a newly provisioned
3
Convert nvme_init() to realize and rename it to nvme_realize().
4
target that the user knows is blank (reads as zero). In this situation
5
there is no requirement for qemu-img to wastefully zero out the entire
6
device.
7
4
8
Add a new option, --target-is-zero, allowing the user to indicate that
5
Cc: John Snow <jsnow@redhat.com>
9
an existing target device will return zeros for all reads.
6
Cc: Keith Busch <keith.busch@intel.com>
7
Cc: Kevin Wolf <kwolf@redhat.com>
8
Cc: Max Reitz <mreitz@redhat.com>
9
Cc: Markus Armbruster <armbru@redhat.com>
10
10
11
Signed-off-by: David Edmondson <david.edmondson@oracle.com>
11
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
12
Message-Id: <20200205110248.2009589-2-david.edmondson@oracle.com>
12
Message-id: 2882e72d795e04cbe2120f569d551aef2467ac60.1511317952.git.maozy.fnst@cn.fujitsu.com
13
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Reviewed-by: Eric Blake <eblake@redhat.com>
15
Signed-off-by: Max Reitz <mreitz@redhat.com>
16
---
14
---
17
docs/interop/qemu-img.rst | 9 ++++++++-
15
hw/block/nvme.c | 18 ++++++++++--------
18
qemu-img-cmds.hx | 4 ++--
16
1 file changed, 10 insertions(+), 8 deletions(-)
19
qemu-img.c | 26 +++++++++++++++++++++++---
20
3 files changed, 33 insertions(+), 6 deletions(-)
21
17
22
diff --git a/docs/interop/qemu-img.rst b/docs/interop/qemu-img.rst
18
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
23
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
24
--- a/docs/interop/qemu-img.rst
20
--- a/hw/block/nvme.c
25
+++ b/docs/interop/qemu-img.rst
21
+++ b/hw/block/nvme.c
26
@@ -XXX,XX +XXX,XX @@ Parameters to convert subcommand:
22
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps nvme_cmb_ops = {
27
will still be printed. Areas that cannot be read from the source will be
23
},
28
treated as containing only zeroes.
29
30
+.. option:: --target-is-zero
31
+
32
+ Assume that reading the destination image will always return
33
+ zeros. This parameter is mutually exclusive with a destination image
34
+ that has a backing file. It is required to also use the ``-n``
35
+ parameter to skip image creation.
36
+
37
Parameters to dd subcommand:
38
39
.. program:: qemu-img-dd
40
@@ -XXX,XX +XXX,XX @@ Command description:
41
4
42
Error on reading data
43
44
-.. option:: convert [--object OBJECTDEF] [--image-opts] [--target-image-opts] [-U] [-C] [-c] [-p] [-q] [-n] [-f FMT] [-t CACHE] [-T SRC_CACHE] [-O OUTPUT_FMT] [-B BACKING_FILE] [-o OPTIONS] [-l SNAPSHOT_PARAM] [-S SPARSE_SIZE] [-m NUM_COROUTINES] [-W] FILENAME [FILENAME2 [...]] OUTPUT_FILENAME
45
+.. option:: convert [--object OBJECTDEF] [--image-opts] [--target-image-opts] [--target-is-zero] [-U] [-C] [-c] [-p] [-q] [-n] [-f FMT] [-t CACHE] [-T SRC_CACHE] [-O OUTPUT_FMT] [-B BACKING_FILE] [-o OPTIONS] [-l SNAPSHOT_PARAM] [-S SPARSE_SIZE] [-m NUM_COROUTINES] [-W] FILENAME [FILENAME2 [...]] OUTPUT_FILENAME
46
47
Convert the disk image *FILENAME* or a snapshot *SNAPSHOT_PARAM*
48
to disk image *OUTPUT_FILENAME* using format *OUTPUT_FMT*. It can
49
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
50
index XXXXXXX..XXXXXXX 100644
51
--- a/qemu-img-cmds.hx
52
+++ b/qemu-img-cmds.hx
53
@@ -XXX,XX +XXX,XX @@ SRST
54
ERST
55
56
DEF("convert", img_convert,
57
- "convert [--object objectdef] [--image-opts] [--target-image-opts] [-U] [-C] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] [--salvage] filename [filename2 [...]] output_filename")
58
+ "convert [--object objectdef] [--image-opts] [--target-image-opts] [--target-is-zero] [-U] [-C] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] [--salvage] filename [filename2 [...]] output_filename")
59
SRST
60
-.. option:: convert [--object OBJECTDEF] [--image-opts] [--target-image-opts] [-U] [-C] [-c] [-p] [-q] [-n] [-f FMT] [-t CACHE] [-T SRC_CACHE] [-O OUTPUT_FMT] [-B BACKING_FILE] [-o OPTIONS] [-l SNAPSHOT_PARAM] [-S SPARSE_SIZE] [-m NUM_COROUTINES] [-W] [--salvage] FILENAME [FILENAME2 [...]] OUTPUT_FILENAME
61
+.. option:: convert [--object OBJECTDEF] [--image-opts] [--target-image-opts] [--target-is-zero] [-U] [-C] [-c] [-p] [-q] [-n] [-f FMT] [-t CACHE] [-T SRC_CACHE] [-O OUTPUT_FMT] [-B BACKING_FILE] [-o OPTIONS] [-l SNAPSHOT_PARAM] [-S SPARSE_SIZE] [-m NUM_COROUTINES] [-W] [--salvage] FILENAME [FILENAME2 [...]] OUTPUT_FILENAME
62
ERST
63
64
DEF("create", img_create,
65
diff --git a/qemu-img.c b/qemu-img.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/qemu-img.c
68
+++ b/qemu-img.c
69
@@ -XXX,XX +XXX,XX @@ enum {
70
OPTION_PREALLOCATION = 265,
71
OPTION_SHRINK = 266,
72
OPTION_SALVAGE = 267,
73
+ OPTION_TARGET_IS_ZERO = 268,
74
};
24
};
75
25
76
typedef enum OutputFormat {
26
-static int nvme_init(PCIDevice *pci_dev)
77
@@ -XXX,XX +XXX,XX @@ static int convert_do_copy(ImgConvertState *s)
27
+static void nvme_realize(PCIDevice *pci_dev, Error **errp)
78
int64_t sector_num = 0;
28
{
79
29
NvmeCtrl *n = NVME(pci_dev);
80
/* Check whether we have zero initialisation or can get it efficiently */
30
NvmeIdCtrl *id = &n->id_ctrl;
81
- if (s->target_is_new && s->min_sparse && !s->target_has_backing) {
31
@@ -XXX,XX +XXX,XX @@ static int nvme_init(PCIDevice *pci_dev)
82
+ if (!s->has_zero_init && s->target_is_new && s->min_sparse &&
32
Error *local_err = NULL;
83
+ !s->target_has_backing) {
33
84
s->has_zero_init = bdrv_has_zero_init(blk_bs(s->target));
34
if (!n->conf.blk) {
85
- } else {
35
- return -1;
86
- s->has_zero_init = false;
36
+ error_setg(errp, "drive property not set");
37
+ return;
87
}
38
}
88
39
89
if (!s->has_zero_init && !s->target_has_backing &&
40
bs_size = blk_getlength(n->conf.blk);
90
@@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv)
41
if (bs_size < 0) {
91
{"force-share", no_argument, 0, 'U'},
42
- return -1;
92
{"target-image-opts", no_argument, 0, OPTION_TARGET_IMAGE_OPTS},
43
+ error_setg(errp, "could not get backing file size");
93
{"salvage", no_argument, 0, OPTION_SALVAGE},
44
+ return;
94
+ {"target-is-zero", no_argument, 0, OPTION_TARGET_IS_ZERO},
95
{0, 0, 0, 0}
96
};
97
c = getopt_long(argc, argv, ":hf:O:B:Cco:l:S:pt:T:qnm:WU",
98
@@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv)
99
case OPTION_TARGET_IMAGE_OPTS:
100
tgt_image_opts = true;
101
break;
102
+ case OPTION_TARGET_IS_ZERO:
103
+ /*
104
+ * The user asserting that the target is blank has the
105
+ * same effect as the target driver supporting zero
106
+ * initialisation.
107
+ */
108
+ s.has_zero_init = true;
109
+ break;
110
}
111
}
45
}
112
46
113
@@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv)
47
blkconf_serial(&n->conf, &n->serial);
114
warn_report("This will become an error in future QEMU versions.");
48
if (!n->serial) {
49
- return -1;
50
+ error_setg(errp, "serial property not set");
51
+ return;
115
}
52
}
116
53
blkconf_blocksizes(&n->conf);
117
+ if (s.has_zero_init && !skip_create) {
54
blkconf_apply_backend_options(&n->conf, blk_is_read_only(n->conf.blk),
118
+ error_report("--target-is-zero requires use of -n flag");
55
false, &local_err);
119
+ goto fail_getopt;
56
if (local_err) {
120
+ }
57
- error_report_err(local_err);
121
+
58
- return -1;
122
s.src_num = argc - optind - 1;
59
+ error_propagate(errp, local_err);
123
out_filename = s.src_num >= 1 ? argv[argc - 1] : NULL;
60
+ return;
124
125
@@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv)
126
}
61
}
127
s.target_has_backing = (bool) out_baseimg;
62
128
63
pci_conf = pci_dev->config;
129
+ if (s.has_zero_init && s.target_has_backing) {
64
@@ -XXX,XX +XXX,XX @@ static int nvme_init(PCIDevice *pci_dev)
130
+ error_report("Cannot use --target-is-zero when the destination "
65
cpu_to_le64(n->ns_size >>
131
+ "image has a backing file");
66
id_ns->lbaf[NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas)].ds);
132
+ goto out;
67
}
133
+ }
68
- return 0;
134
+
69
}
135
if (s.src_num > 1 && out_baseimg) {
70
136
error_report("Having a backing file for the target makes no sense when "
71
static void nvme_exit(PCIDevice *pci_dev)
137
"concatenating multiple input images");
72
@@ -XXX,XX +XXX,XX @@ static void nvme_class_init(ObjectClass *oc, void *data)
73
DeviceClass *dc = DEVICE_CLASS(oc);
74
PCIDeviceClass *pc = PCI_DEVICE_CLASS(oc);
75
76
- pc->init = nvme_init;
77
+ pc->realize = nvme_realize;
78
pc->exit = nvme_exit;
79
pc->class_id = PCI_CLASS_STORAGE_EXPRESS;
80
pc->vendor_id = PCI_VENDOR_ID_INTEL;
138
--
81
--
139
2.24.1
82
2.14.3
140
83
141
84
diff view generated by jsdifflib
New patch
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
1
2
3
When the function no success value to transmit, it usually make the
4
function return void. It has turned out not to be a success, because
5
it means that the extra local_err variable and error_propagate() will
6
be needed. It leads to cumbersome code, therefore, transmit success/
7
failure in the return value is worth.
8
9
So fix the return type of blkconf_apply_backend_options(),
10
blkconf_geometry() and virtio_blk_data_plane_create() to avoid it.
11
12
Cc: John Snow <jsnow@redhat.com>
13
Cc: Kevin Wolf <kwolf@redhat.com>
14
Cc: Max Reitz <mreitz@redhat.com>
15
Cc: Stefan Hajnoczi <stefanha@redhat.com>
16
17
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
18
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
19
Message-id: ac0edc1fc70c4457e5cec94405eb7d1f89f9c2c1.1511317952.git.maozy.fnst@cn.fujitsu.com
20
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
21
---
22
hw/block/dataplane/virtio-blk.h | 2 +-
23
include/hw/block/block.h | 4 ++--
24
hw/block/block.c | 15 +++++++++------
25
hw/block/dataplane/virtio-blk.c | 12 +++++++-----
26
4 files changed, 19 insertions(+), 14 deletions(-)
27
28
diff --git a/hw/block/dataplane/virtio-blk.h b/hw/block/dataplane/virtio-blk.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/block/dataplane/virtio-blk.h
31
+++ b/hw/block/dataplane/virtio-blk.h
32
@@ -XXX,XX +XXX,XX @@
33
34
typedef struct VirtIOBlockDataPlane VirtIOBlockDataPlane;
35
36
-void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
37
+bool virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
38
VirtIOBlockDataPlane **dataplane,
39
Error **errp);
40
void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s);
41
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/include/hw/block/block.h
44
+++ b/include/hw/block/block.h
45
@@ -XXX,XX +XXX,XX @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
46
/* Configuration helpers */
47
48
void blkconf_serial(BlockConf *conf, char **serial);
49
-void blkconf_geometry(BlockConf *conf, int *trans,
50
+bool blkconf_geometry(BlockConf *conf, int *trans,
51
unsigned cyls_max, unsigned heads_max, unsigned secs_max,
52
Error **errp);
53
void blkconf_blocksizes(BlockConf *conf);
54
-void blkconf_apply_backend_options(BlockConf *conf, bool readonly,
55
+bool blkconf_apply_backend_options(BlockConf *conf, bool readonly,
56
bool resizable, Error **errp);
57
58
/* Hard disk geometry */
59
diff --git a/hw/block/block.c b/hw/block/block.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/block/block.c
62
+++ b/hw/block/block.c
63
@@ -XXX,XX +XXX,XX @@ void blkconf_blocksizes(BlockConf *conf)
64
}
65
}
66
67
-void blkconf_apply_backend_options(BlockConf *conf, bool readonly,
68
+bool blkconf_apply_backend_options(BlockConf *conf, bool readonly,
69
bool resizable, Error **errp)
70
{
71
BlockBackend *blk = conf->blk;
72
@@ -XXX,XX +XXX,XX @@ void blkconf_apply_backend_options(BlockConf *conf, bool readonly,
73
74
ret = blk_set_perm(blk, perm, shared_perm, errp);
75
if (ret < 0) {
76
- return;
77
+ return false;
78
}
79
80
switch (conf->wce) {
81
@@ -XXX,XX +XXX,XX @@ void blkconf_apply_backend_options(BlockConf *conf, bool readonly,
82
83
blk_set_enable_write_cache(blk, wce);
84
blk_set_on_error(blk, rerror, werror);
85
+
86
+ return true;
87
}
88
89
-void blkconf_geometry(BlockConf *conf, int *ptrans,
90
+bool blkconf_geometry(BlockConf *conf, int *ptrans,
91
unsigned cyls_max, unsigned heads_max, unsigned secs_max,
92
Error **errp)
93
{
94
@@ -XXX,XX +XXX,XX @@ void blkconf_geometry(BlockConf *conf, int *ptrans,
95
if (conf->cyls || conf->heads || conf->secs) {
96
if (conf->cyls < 1 || conf->cyls > cyls_max) {
97
error_setg(errp, "cyls must be between 1 and %u", cyls_max);
98
- return;
99
+ return false;
100
}
101
if (conf->heads < 1 || conf->heads > heads_max) {
102
error_setg(errp, "heads must be between 1 and %u", heads_max);
103
- return;
104
+ return false;
105
}
106
if (conf->secs < 1 || conf->secs > secs_max) {
107
error_setg(errp, "secs must be between 1 and %u", secs_max);
108
- return;
109
+ return false;
110
}
111
}
112
+ return true;
113
}
114
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/hw/block/dataplane/virtio-blk.c
117
+++ b/hw/block/dataplane/virtio-blk.c
118
@@ -XXX,XX +XXX,XX @@ static void notify_guest_bh(void *opaque)
119
}
120
121
/* Context: QEMU global mutex held */
122
-void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
123
+bool virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
124
VirtIOBlockDataPlane **dataplane,
125
Error **errp)
126
{
127
@@ -XXX,XX +XXX,XX @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
128
error_setg(errp,
129
"device is incompatible with iothread "
130
"(transport does not support notifiers)");
131
- return;
132
+ return false;
133
}
134
if (!virtio_device_ioeventfd_enabled(vdev)) {
135
error_setg(errp, "ioeventfd is required for iothread");
136
- return;
137
+ return false;
138
}
139
140
/* If dataplane is (re-)enabled while the guest is running there could
141
@@ -XXX,XX +XXX,XX @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
142
*/
143
if (blk_op_is_blocked(conf->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) {
144
error_prepend(errp, "cannot start virtio-blk dataplane: ");
145
- return;
146
+ return false;
147
}
148
}
149
/* Don't try if transport does not support notifiers. */
150
if (!virtio_device_ioeventfd_enabled(vdev)) {
151
- return;
152
+ return false;
153
}
154
155
s = g_new0(VirtIOBlockDataPlane, 1);
156
@@ -XXX,XX +XXX,XX @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
157
s->batch_notify_vqs = bitmap_new(conf->num_queues);
158
159
*dataplane = s;
160
+
161
+ return true;
162
}
163
164
/* Context: QEMU global mutex held */
165
--
166
2.14.3
167
168
diff view generated by jsdifflib
New patch
1
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
2
3
[Drop virtio_blk_data_plane_create() change that misinterprets return
4
value when the virtio transport does not support dataplane.
5
--Stefan]
6
7
Cc: John Snow <jsnow@redhat.com>
8
Cc: Kevin Wolf <kwolf@redhat.com>
9
Cc: Max Reitz <mreitz@redhat.com>
10
Cc: Keith Busch <keith.busch@intel.com>
11
Cc: Stefan Hajnoczi <stefanha@redhat.com>
12
Cc: "Michael S. Tsirkin" <mst@redhat.com>
13
Cc: Paolo Bonzini <pbonzini@redhat.com>
14
Cc: Gerd Hoffmann <kraxel@redhat.com>
15
Cc: Markus Armbruster <armbru@redhat.com>
16
17
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
18
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
19
Message-id: e77848d3735ba590f23ffbf8094379c646c33d79.1511317952.git.maozy.fnst@cn.fujitsu.com
20
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
21
---
22
hw/block/fdc.c | 17 ++++++-----------
23
hw/block/nvme.c | 7 ++-----
24
hw/block/virtio-blk.c | 13 +++++--------
25
hw/ide/qdev.c | 12 ++++--------
26
hw/scsi/scsi-disk.c | 13 ++++---------
27
hw/usb/dev-storage.c | 9 +++------
28
6 files changed, 24 insertions(+), 47 deletions(-)
29
30
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/block/fdc.c
33
+++ b/hw/block/fdc.c
34
@@ -XXX,XX +XXX,XX @@ static void fd_revalidate(FDrive *drv)
35
static void fd_change_cb(void *opaque, bool load, Error **errp)
36
{
37
FDrive *drive = opaque;
38
- Error *local_err = NULL;
39
40
if (!load) {
41
blk_set_perm(drive->blk, 0, BLK_PERM_ALL, &error_abort);
42
} else {
43
- blkconf_apply_backend_options(drive->conf,
44
- blk_is_read_only(drive->blk), false,
45
- &local_err);
46
- if (local_err) {
47
- error_propagate(errp, local_err);
48
+ if (!blkconf_apply_backend_options(drive->conf,
49
+ blk_is_read_only(drive->blk), false,
50
+ errp)) {
51
return;
52
}
53
}
54
@@ -XXX,XX +XXX,XX @@ static void floppy_drive_realize(DeviceState *qdev, Error **errp)
55
FloppyDrive *dev = FLOPPY_DRIVE(qdev);
56
FloppyBus *bus = FLOPPY_BUS(qdev->parent_bus);
57
FDrive *drive;
58
- Error *local_err = NULL;
59
int ret;
60
61
if (dev->unit == -1) {
62
@@ -XXX,XX +XXX,XX @@ static void floppy_drive_realize(DeviceState *qdev, Error **errp)
63
dev->conf.rerror = BLOCKDEV_ON_ERROR_AUTO;
64
dev->conf.werror = BLOCKDEV_ON_ERROR_AUTO;
65
66
- blkconf_apply_backend_options(&dev->conf, blk_is_read_only(dev->conf.blk),
67
- false, &local_err);
68
- if (local_err) {
69
- error_propagate(errp, local_err);
70
+ if (!blkconf_apply_backend_options(&dev->conf,
71
+ blk_is_read_only(dev->conf.blk),
72
+ false, errp)) {
73
return;
74
}
75
76
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/hw/block/nvme.c
79
+++ b/hw/block/nvme.c
80
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
81
int i;
82
int64_t bs_size;
83
uint8_t *pci_conf;
84
- Error *local_err = NULL;
85
86
if (!n->conf.blk) {
87
error_setg(errp, "drive property not set");
88
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
89
return;
90
}
91
blkconf_blocksizes(&n->conf);
92
- blkconf_apply_backend_options(&n->conf, blk_is_read_only(n->conf.blk),
93
- false, &local_err);
94
- if (local_err) {
95
- error_propagate(errp, local_err);
96
+ if (!blkconf_apply_backend_options(&n->conf, blk_is_read_only(n->conf.blk),
97
+ false, errp)) {
98
return;
99
}
100
101
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/hw/block/virtio-blk.c
104
+++ b/hw/block/virtio-blk.c
105
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
106
}
107
108
blkconf_serial(&conf->conf, &conf->serial);
109
- blkconf_apply_backend_options(&conf->conf,
110
- blk_is_read_only(conf->conf.blk), true,
111
- &err);
112
- if (err) {
113
- error_propagate(errp, err);
114
+ if (!blkconf_apply_backend_options(&conf->conf,
115
+ blk_is_read_only(conf->conf.blk), true,
116
+ errp)) {
117
return;
118
}
119
s->original_wce = blk_enable_write_cache(conf->conf.blk);
120
- blkconf_geometry(&conf->conf, NULL, 65535, 255, 255, &err);
121
- if (err) {
122
- error_propagate(errp, err);
123
+ if (!blkconf_geometry(&conf->conf, NULL, 65535, 255, 255, errp)) {
124
return;
125
}
126
+
127
blkconf_blocksizes(&conf->conf);
128
129
virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK,
130
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
131
index XXXXXXX..XXXXXXX 100644
132
--- a/hw/ide/qdev.c
133
+++ b/hw/ide/qdev.c
134
@@ -XXX,XX +XXX,XX @@ static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind, Error **errp)
135
{
136
IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
137
IDEState *s = bus->ifs + dev->unit;
138
- Error *err = NULL;
139
int ret;
140
141
if (!dev->conf.blk) {
142
@@ -XXX,XX +XXX,XX @@ static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind, Error **errp)
143
144
blkconf_serial(&dev->conf, &dev->serial);
145
if (kind != IDE_CD) {
146
- blkconf_geometry(&dev->conf, &dev->chs_trans, 65535, 16, 255, &err);
147
- if (err) {
148
- error_propagate(errp, err);
149
+ if (!blkconf_geometry(&dev->conf, &dev->chs_trans, 65535, 16, 255,
150
+ errp)) {
151
return;
152
}
153
}
154
- blkconf_apply_backend_options(&dev->conf, kind == IDE_CD, kind != IDE_CD,
155
- &err);
156
- if (err) {
157
- error_propagate(errp, err);
158
+ if (!blkconf_apply_backend_options(&dev->conf, kind == IDE_CD,
159
+ kind != IDE_CD, errp)) {
160
return;
161
}
162
163
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
164
index XXXXXXX..XXXXXXX 100644
165
--- a/hw/scsi/scsi-disk.c
166
+++ b/hw/scsi/scsi-disk.c
167
@@ -XXX,XX +XXX,XX @@ static void scsi_disk_unit_attention_reported(SCSIDevice *dev)
168
static void scsi_realize(SCSIDevice *dev, Error **errp)
169
{
170
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
171
- Error *err = NULL;
172
173
if (!s->qdev.conf.blk) {
174
error_setg(errp, "drive property not set");
175
@@ -XXX,XX +XXX,XX @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
176
}
177
178
if (dev->type == TYPE_DISK) {
179
- blkconf_geometry(&dev->conf, NULL, 65535, 255, 255, &err);
180
- if (err) {
181
- error_propagate(errp, err);
182
+ if (!blkconf_geometry(&dev->conf, NULL, 65535, 255, 255, errp)) {
183
return;
184
}
185
}
186
- blkconf_apply_backend_options(&dev->conf,
187
- blk_is_read_only(s->qdev.conf.blk),
188
- dev->type == TYPE_DISK, &err);
189
- if (err) {
190
- error_propagate(errp, err);
191
+ if (!blkconf_apply_backend_options(&dev->conf,
192
+ blk_is_read_only(s->qdev.conf.blk),
193
+ dev->type == TYPE_DISK, errp)) {
194
return;
195
}
196
197
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
198
index XXXXXXX..XXXXXXX 100644
199
--- a/hw/usb/dev-storage.c
200
+++ b/hw/usb/dev-storage.c
201
@@ -XXX,XX +XXX,XX @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
202
MSDState *s = USB_STORAGE_DEV(dev);
203
BlockBackend *blk = s->conf.blk;
204
SCSIDevice *scsi_dev;
205
- Error *err = NULL;
206
207
if (!blk) {
208
error_setg(errp, "drive property not set");
209
@@ -XXX,XX +XXX,XX @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
210
211
blkconf_serial(&s->conf, &dev->serial);
212
blkconf_blocksizes(&s->conf);
213
- blkconf_apply_backend_options(&s->conf, blk_is_read_only(blk), true, &err);
214
- if (err) {
215
- error_propagate(errp, err);
216
+ if (!blkconf_apply_backend_options(&s->conf, blk_is_read_only(blk), true,
217
+ errp)) {
218
return;
219
}
220
221
@@ -XXX,XX +XXX,XX @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
222
&usb_msd_scsi_info_storage, NULL);
223
scsi_dev = scsi_bus_legacy_add_drive(&s->bus, blk, 0, !!s->removable,
224
s->conf.bootindex, dev->serial,
225
- &err);
226
+ errp);
227
blk_unref(blk);
228
if (!scsi_dev) {
229
- error_propagate(errp, err);
230
return;
231
}
232
usb_msd_handle_reset(dev);
233
--
234
2.14.3
235
236
diff view generated by jsdifflib
New patch
1
From: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
1
2
3
The function name of usb_msd_{realize,unrealize}_*,
4
usb_msd_class_initfn_* are unusual. Rename it to
5
usb_msd_*_{realize,unrealize}, usb_msd_class_*_initfn.
6
7
Cc: Gerd Hoffmann <kraxel@redhat.com>
8
9
Signed-off-by: Mao Zhongyi <maozy.fnst@cn.fujitsu.com>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 11e6003433abce35f3f4970e1acc71ee92dbcf51.1511317952.git.maozy.fnst@cn.fujitsu.com
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
14
hw/usb/dev-storage.c | 20 ++++++++++----------
15
1 file changed, 10 insertions(+), 10 deletions(-)
16
17
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/usb/dev-storage.c
20
+++ b/hw/usb/dev-storage.c
21
@@ -XXX,XX +XXX,XX @@ static void usb_msd_unrealize_storage(USBDevice *dev, Error **errp)
22
object_unref(OBJECT(&s->bus));
23
}
24
25
-static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
26
+static void usb_msd_storage_realize(USBDevice *dev, Error **errp)
27
{
28
MSDState *s = USB_STORAGE_DEV(dev);
29
BlockBackend *blk = s->conf.blk;
30
@@ -XXX,XX +XXX,XX @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
31
s->scsi_dev = scsi_dev;
32
}
33
34
-static void usb_msd_unrealize_bot(USBDevice *dev, Error **errp)
35
+static void usb_msd_bot_unrealize(USBDevice *dev, Error **errp)
36
{
37
MSDState *s = USB_STORAGE_DEV(dev);
38
39
object_unref(OBJECT(&s->bus));
40
}
41
42
-static void usb_msd_realize_bot(USBDevice *dev, Error **errp)
43
+static void usb_msd_bot_realize(USBDevice *dev, Error **errp)
44
{
45
MSDState *s = USB_STORAGE_DEV(dev);
46
DeviceState *d = DEVICE(dev);
47
@@ -XXX,XX +XXX,XX @@ static void usb_msd_class_initfn_common(ObjectClass *klass, void *data)
48
dc->vmsd = &vmstate_usb_msd;
49
}
50
51
-static void usb_msd_class_initfn_storage(ObjectClass *klass, void *data)
52
+static void usb_msd_class_storage_initfn(ObjectClass *klass, void *data)
53
{
54
DeviceClass *dc = DEVICE_CLASS(klass);
55
USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
56
57
- uc->realize = usb_msd_realize_storage;
58
+ uc->realize = usb_msd_storage_realize;
59
uc->unrealize = usb_msd_unrealize_storage;
60
dc->props = msd_properties;
61
}
62
@@ -XXX,XX +XXX,XX @@ static void usb_msd_instance_init(Object *obj)
63
object_property_set_int(obj, -1, "bootindex", NULL);
64
}
65
66
-static void usb_msd_class_initfn_bot(ObjectClass *klass, void *data)
67
+static void usb_msd_class_bot_initfn(ObjectClass *klass, void *data)
68
{
69
USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
70
71
- uc->realize = usb_msd_realize_bot;
72
- uc->unrealize = usb_msd_unrealize_bot;
73
+ uc->realize = usb_msd_bot_realize;
74
+ uc->unrealize = usb_msd_bot_unrealize;
75
uc->attached_settable = true;
76
}
77
78
static const TypeInfo msd_info = {
79
.name = "usb-storage",
80
.parent = TYPE_USB_STORAGE,
81
- .class_init = usb_msd_class_initfn_storage,
82
+ .class_init = usb_msd_class_storage_initfn,
83
.instance_init = usb_msd_instance_init,
84
};
85
86
static const TypeInfo bot_info = {
87
.name = "usb-bot",
88
.parent = TYPE_USB_STORAGE,
89
- .class_init = usb_msd_class_initfn_bot,
90
+ .class_init = usb_msd_class_bot_initfn,
91
};
92
93
static void usb_msd_register_types(void)
94
--
95
2.14.3
96
97
diff view generated by jsdifflib
1
When printing the snapshot list (e.g. with qemu-img snapshot -l), the VM
1
Commit 1351d1ec89eabebc9fdff20451a62c413d7accc1 ("qdev: drop iothread
2
size field is only seven characters wide. As of de38b5005e9, this is
2
property type") forgot to remove this include.
3
not necessarily sufficient: We generally print three digits, and this
4
may require a decimal point. Also, the unit field grew from something
5
as plain as "M" to " MiB". This means that number and unit may take up
6
eight characters in total; but we also want spaces in front.
7
3
8
Considering previously the maximum width was four characters and the
4
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
field width was chosen to be three characters wider, let us adjust the
5
Message-id: 20171205133954.31006-1-stefanha@redhat.com
10
field width to be eleven now.
6
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
---
8
hw/core/qdev-properties-system.c | 1 -
9
1 file changed, 1 deletion(-)
11
10
12
Fixes: de38b5005e946aa3714963ea4c501e279e7d3666
11
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
13
Buglink: https://bugs.launchpad.net/qemu/+bug/1859989
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
Message-Id: <20200117105859.241818-2-mreitz@redhat.com>
16
Reviewed-by: Eric Blake <eblake@redhat.com>
17
Signed-off-by: Max Reitz <mreitz@redhat.com>
18
---
19
block/qapi.c | 4 ++--
20
1 file changed, 2 insertions(+), 2 deletions(-)
21
22
diff --git a/block/qapi.c b/block/qapi.c
23
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
24
--- a/block/qapi.c
13
--- a/hw/core/qdev-properties-system.c
25
+++ b/block/qapi.c
14
+++ b/hw/core/qdev-properties-system.c
26
@@ -XXX,XX +XXX,XX @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
15
@@ -XXX,XX +XXX,XX @@
27
char *sizing = NULL;
16
#include "qapi/visitor.h"
28
17
#include "chardev/char-fe.h"
29
if (!sn) {
18
#include "sysemu/tpm_backend.h"
30
- qemu_printf("%-10s%-20s%7s%20s%15s",
19
-#include "sysemu/iothread.h"
31
+ qemu_printf("%-10s%-20s%11s%20s%15s",
20
32
"ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
21
static void get_pointer(Object *obj, Visitor *v, Property *prop,
33
} else {
22
char *(*print)(void *ptr),
34
ti = sn->date_sec;
35
@@ -XXX,XX +XXX,XX @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
36
(int)(secs % 60),
37
(int)((sn->vm_clock_nsec / 1000000) % 1000));
38
sizing = size_to_str(sn->vm_state_size);
39
- qemu_printf("%-10s%-20s%7s%20s%15s",
40
+ qemu_printf("%-10s%-20s%11s%20s%15s",
41
sn->id_str, sn->name,
42
sizing,
43
date_buf,
44
--
23
--
45
2.24.1
24
2.14.3
46
25
47
26
diff view generated by jsdifflib
1
8dff69b94 added an aio parameter to the drive parameter but forgot to
1
bdrv_unref() requires the AioContext lock because bdrv_flush() uses
2
add a comma before, thus breaking the test. Fix it again.
2
BDRV_POLL_WHILE(), which assumes the AioContext is currently held. If
3
BDRV_POLL_WHILE() runs without AioContext held the
4
pthread_mutex_unlock() call in aio_context_release() fails.
3
5
4
Fixes: 8dff69b9415b4287e900358744b732195e1ab2e2
6
This patch moves bdrv_unref() into the AioContext locked region to solve
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
the following pthread_mutex_unlock() failure:
6
Message-Id: <20200206130812.612960-1-mreitz@redhat.com>
8
9
#0 0x00007f566181969b in raise () at /lib64/libc.so.6
10
#1 0x00007f566181b3b1 in abort () at /lib64/libc.so.6
11
#2 0x00005592cd590458 in error_exit (err=<optimized out>, msg=msg@entry=0x5592cdaf6d60 <__func__.23977> "qemu_mutex_unlock") at util/qemu-thread-posix.c:36
12
#3 0x00005592cd96e738 in qemu_mutex_unlock (mutex=mutex@entry=0x5592ce9505e0) at util/qemu-thread-posix.c:96
13
#4 0x00005592cd969b69 in aio_context_release (ctx=ctx@entry=0x5592ce950580) at util/async.c:507
14
#5 0x00005592cd8ead78 in bdrv_flush (bs=bs@entry=0x5592cfa87210) at block/io.c:2478
15
#6 0x00005592cd89df30 in bdrv_close (bs=0x5592cfa87210) at block.c:3207
16
#7 0x00005592cd89df30 in bdrv_delete (bs=0x5592cfa87210) at block.c:3395
17
#8 0x00005592cd89df30 in bdrv_unref (bs=0x5592cfa87210) at block.c:4418
18
#9 0x00005592cd6b7f86 in qmp_transaction (dev_list=<optimized out>, has_props=<optimized out>, props=<optimized out>, errp=errp@entry=0x7ffe4a1fc9d8) at blockdev.c:2308
19
20
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
21
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
22
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Tested-by: Eric Blake <eblake@redhat.com>
23
Message-id: 20171206144550.22295-2-stefanha@redhat.com
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
24
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
10
---
25
---
11
tests/qemu-iotests/147 | 2 +-
26
blockdev.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
27
1 file changed, 1 insertion(+), 1 deletion(-)
13
28
14
diff --git a/tests/qemu-iotests/147 b/tests/qemu-iotests/147
29
diff --git a/blockdev.c b/blockdev.c
15
index XXXXXXX..XXXXXXX 100755
30
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/qemu-iotests/147
31
--- a/blockdev.c
17
+++ b/tests/qemu-iotests/147
32
+++ b/blockdev.c
18
@@ -XXX,XX +XXX,XX @@ class BuiltinNBD(NBDBlockdevAddBase):
33
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_clean(BlkActionState *common)
19
self.server.add_drive_raw('if=none,id=nbd-export,' +
34
DO_UPCAST(ExternalSnapshotState, common, common);
20
'file=%s,' % test_img +
35
if (state->aio_context) {
21
'format=%s,' % imgfmt +
36
bdrv_drained_end(state->old_bs);
22
- 'cache=%s' % cachemode +
37
- aio_context_release(state->aio_context);
23
+ 'cache=%s,' % cachemode +
38
bdrv_unref(state->new_bs);
24
'aio=%s' % aiomode)
39
+ aio_context_release(state->aio_context);
25
self.server.launch()
40
}
41
}
26
42
27
--
43
--
28
2.24.1
44
2.14.3
29
45
30
46
diff view generated by jsdifflib
New patch
1
1
It is not necessary to hold AioContext across transactions anymore since
2
bdrv_drained_begin/end() is used to keep the nodes quiesced. In fact,
3
using the AioContext lock for this purpose was always buggy.
4
5
This patch reduces the scope of AioContext locked regions. This is not
6
just a cleanup but also fixes hangs that occur in BDRV_POLL_WHILE()
7
because it is unware of recursive locking and does not release the
8
AioContext the necessary number of times to allow progress to be made.
9
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
12
Reviewed-by: Eric Blake <eblake@redhat.com>
13
Message-id: 20171206144550.22295-3-stefanha@redhat.com
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
---
16
blockdev.c | 71 ++++++++++++++++++++++++++++++++++++++++++--------------------
17
1 file changed, 48 insertions(+), 23 deletions(-)
18
19
diff --git a/blockdev.c b/blockdev.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/blockdev.c
22
+++ b/blockdev.c
23
@@ -XXX,XX +XXX,XX @@ typedef struct ExternalSnapshotState {
24
BlkActionState common;
25
BlockDriverState *old_bs;
26
BlockDriverState *new_bs;
27
- AioContext *aio_context;
28
bool overlay_appended;
29
} ExternalSnapshotState;
30
31
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
32
ExternalSnapshotState *state =
33
DO_UPCAST(ExternalSnapshotState, common, common);
34
TransactionAction *action = common->action;
35
+ AioContext *aio_context;
36
37
/* 'blockdev-snapshot' and 'blockdev-snapshot-sync' have similar
38
* purpose but a different set of parameters */
39
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
40
return;
41
}
42
43
- /* Acquire AioContext now so any threads operating on old_bs stop */
44
- state->aio_context = bdrv_get_aio_context(state->old_bs);
45
- aio_context_acquire(state->aio_context);
46
+ aio_context = bdrv_get_aio_context(state->old_bs);
47
+ aio_context_acquire(aio_context);
48
+
49
+ /* Paired with .clean() */
50
bdrv_drained_begin(state->old_bs);
51
52
if (!bdrv_is_inserted(state->old_bs)) {
53
error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
54
- return;
55
+ goto out;
56
}
57
58
if (bdrv_op_is_blocked(state->old_bs,
59
BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT, errp)) {
60
- return;
61
+ goto out;
62
}
63
64
if (!bdrv_is_read_only(state->old_bs)) {
65
if (bdrv_flush(state->old_bs)) {
66
error_setg(errp, QERR_IO_ERROR);
67
- return;
68
+ goto out;
69
}
70
}
71
72
if (!bdrv_is_first_non_filter(state->old_bs)) {
73
error_setg(errp, QERR_FEATURE_DISABLED, "snapshot");
74
- return;
75
+ goto out;
76
}
77
78
if (action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC) {
79
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
80
81
if (node_name && !snapshot_node_name) {
82
error_setg(errp, "New snapshot node name missing");
83
- return;
84
+ goto out;
85
}
86
87
if (snapshot_node_name &&
88
bdrv_lookup_bs(snapshot_node_name, snapshot_node_name, NULL)) {
89
error_setg(errp, "New snapshot node name already in use");
90
- return;
91
+ goto out;
92
}
93
94
flags = state->old_bs->open_flags;
95
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
96
int64_t size = bdrv_getlength(state->old_bs);
97
if (size < 0) {
98
error_setg_errno(errp, -size, "bdrv_getlength failed");
99
- return;
100
+ goto out;
101
}
102
bdrv_img_create(new_image_file, format,
103
state->old_bs->filename,
104
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
105
NULL, size, flags, false, &local_err);
106
if (local_err) {
107
error_propagate(errp, local_err);
108
- return;
109
+ goto out;
110
}
111
}
112
113
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
114
errp);
115
/* We will manually add the backing_hd field to the bs later */
116
if (!state->new_bs) {
117
- return;
118
+ goto out;
119
}
120
121
if (bdrv_has_blk(state->new_bs)) {
122
error_setg(errp, "The snapshot is already in use");
123
- return;
124
+ goto out;
125
}
126
127
if (bdrv_op_is_blocked(state->new_bs, BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT,
128
errp)) {
129
- return;
130
+ goto out;
131
}
132
133
if (state->new_bs->backing != NULL) {
134
error_setg(errp, "The snapshot already has a backing image");
135
- return;
136
+ goto out;
137
}
138
139
if (!state->new_bs->drv->supports_backing) {
140
error_setg(errp, "The snapshot does not support backing images");
141
- return;
142
+ goto out;
143
}
144
145
- bdrv_set_aio_context(state->new_bs, state->aio_context);
146
+ bdrv_set_aio_context(state->new_bs, aio_context);
147
148
/* This removes our old bs and adds the new bs. This is an operation that
149
* can fail, so we need to do it in .prepare; undoing it for abort is
150
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
151
bdrv_append(state->new_bs, state->old_bs, &local_err);
152
if (local_err) {
153
error_propagate(errp, local_err);
154
- return;
155
+ goto out;
156
}
157
state->overlay_appended = true;
158
+
159
+out:
160
+ aio_context_release(aio_context);
161
}
162
163
static void external_snapshot_commit(BlkActionState *common)
164
{
165
ExternalSnapshotState *state =
166
DO_UPCAST(ExternalSnapshotState, common, common);
167
+ AioContext *aio_context;
168
+
169
+ aio_context = bdrv_get_aio_context(state->old_bs);
170
+ aio_context_acquire(aio_context);
171
172
/* We don't need (or want) to use the transactional
173
* bdrv_reopen_multiple() across all the entries at once, because we
174
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_commit(BlkActionState *common)
175
bdrv_reopen(state->old_bs, state->old_bs->open_flags & ~BDRV_O_RDWR,
176
NULL);
177
}
178
+
179
+ aio_context_release(aio_context);
180
}
181
182
static void external_snapshot_abort(BlkActionState *common)
183
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_abort(BlkActionState *common)
184
DO_UPCAST(ExternalSnapshotState, common, common);
185
if (state->new_bs) {
186
if (state->overlay_appended) {
187
+ AioContext *aio_context;
188
+
189
+ aio_context = bdrv_get_aio_context(state->old_bs);
190
+ aio_context_acquire(aio_context);
191
+
192
bdrv_ref(state->old_bs); /* we can't let bdrv_set_backind_hd()
193
close state->old_bs; we need it */
194
bdrv_set_backing_hd(state->new_bs, NULL, &error_abort);
195
bdrv_replace_node(state->new_bs, state->old_bs, &error_abort);
196
bdrv_unref(state->old_bs); /* bdrv_replace_node() ref'ed old_bs */
197
+
198
+ aio_context_release(aio_context);
199
}
200
}
201
}
202
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_clean(BlkActionState *common)
203
{
204
ExternalSnapshotState *state =
205
DO_UPCAST(ExternalSnapshotState, common, common);
206
- if (state->aio_context) {
207
- bdrv_drained_end(state->old_bs);
208
- bdrv_unref(state->new_bs);
209
- aio_context_release(state->aio_context);
210
+ AioContext *aio_context;
211
+
212
+ if (!state->old_bs) {
213
+ return;
214
}
215
+
216
+ aio_context = bdrv_get_aio_context(state->old_bs);
217
+ aio_context_acquire(aio_context);
218
+
219
+ bdrv_drained_end(state->old_bs);
220
+ bdrv_unref(state->new_bs);
221
+
222
+ aio_context_release(aio_context);
223
}
224
225
typedef struct DriveBackupState {
226
--
227
2.14.3
228
229
diff view generated by jsdifflib
1
s.target_has_backing does not reflect whether the target BDS has a
1
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2
backing file; it only tells whether we should use a backing file during
2
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
3
conversion (specified by -B).
3
Reviewed-by: Eric Blake <eblake@redhat.com>
4
Message-id: 20171206144550.22295-4-stefanha@redhat.com
5
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
6
---
7
blockdev.c | 42 ++++++++++++++++++++++++++++++++++--------
8
1 file changed, 34 insertions(+), 8 deletions(-)
4
9
5
As such, if you use convert -n, the target does not necessarily actually
10
diff --git a/blockdev.c b/blockdev.c
6
have a backing file, and then dereferencing out_bs->backing fails here.
7
8
When converting to an existing file, we should set
9
target_backing_sectors to a negative value, because first, as the
10
comment explains, this value is only used for optimization, so it is
11
always fine to do that.
12
13
Second, we use this value to determine where the target must be
14
initialized to zeroes (overlays are initialized to zero after the end of
15
their backing file). When converting to an existing file, we cannot
16
assume that to be true.
17
18
Cc: qemu-stable@nongnu.org
19
Fixes: 351c8efff9ad809c822d55620df54d575d536f68
20
("qemu-img: Special post-backing convert handling")
21
Signed-off-by: Max Reitz <mreitz@redhat.com>
22
Message-Id: <20200121155915.98232-2-mreitz@redhat.com>
23
Reviewed-by: John Snow <jsnow@redhat.com>
24
Signed-off-by: Max Reitz <mreitz@redhat.com>
25
---
26
qemu-img.c | 2 +-
27
1 file changed, 1 insertion(+), 1 deletion(-)
28
29
diff --git a/qemu-img.c b/qemu-img.c
30
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
31
--- a/qemu-img.c
12
--- a/blockdev.c
32
+++ b/qemu-img.c
13
+++ b/blockdev.c
33
@@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv)
14
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_clean(BlkActionState *common)
34
}
15
typedef struct DriveBackupState {
16
BlkActionState common;
17
BlockDriverState *bs;
18
- AioContext *aio_context;
19
BlockJob *job;
20
} DriveBackupState;
21
22
@@ -XXX,XX +XXX,XX @@ static void drive_backup_prepare(BlkActionState *common, Error **errp)
23
DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
24
BlockDriverState *bs;
25
DriveBackup *backup;
26
+ AioContext *aio_context;
27
Error *local_err = NULL;
28
29
assert(common->action->type == TRANSACTION_ACTION_KIND_DRIVE_BACKUP);
30
@@ -XXX,XX +XXX,XX @@ static void drive_backup_prepare(BlkActionState *common, Error **errp)
31
return;
35
}
32
}
36
33
37
- if (s.target_has_backing) {
34
- /* AioContext is released in .clean() */
38
+ if (s.target_has_backing && s.target_is_new) {
35
- state->aio_context = bdrv_get_aio_context(bs);
39
/* Errors are treated as "backing length unknown" (which means
36
- aio_context_acquire(state->aio_context);
40
* s.target_backing_sectors has to be negative, which it will
37
+ aio_context = bdrv_get_aio_context(bs);
41
* be automatically). The backing file length is used only
38
+ aio_context_acquire(aio_context);
39
+
40
+ /* Paired with .clean() */
41
bdrv_drained_begin(bs);
42
+
43
state->bs = bs;
44
45
state->job = do_drive_backup(backup, common->block_job_txn, &local_err);
46
if (local_err) {
47
error_propagate(errp, local_err);
48
- return;
49
+ goto out;
50
}
51
+
52
+out:
53
+ aio_context_release(aio_context);
54
}
55
56
static void drive_backup_commit(BlkActionState *common)
57
{
58
DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
59
+ AioContext *aio_context;
60
+
61
+ aio_context = bdrv_get_aio_context(state->bs);
62
+ aio_context_acquire(aio_context);
63
+
64
assert(state->job);
65
block_job_start(state->job);
66
+
67
+ aio_context_release(aio_context);
68
}
69
70
static void drive_backup_abort(BlkActionState *common)
71
@@ -XXX,XX +XXX,XX @@ static void drive_backup_abort(BlkActionState *common)
72
DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
73
74
if (state->job) {
75
+ AioContext *aio_context;
76
+
77
+ aio_context = bdrv_get_aio_context(state->bs);
78
+ aio_context_acquire(aio_context);
79
+
80
block_job_cancel_sync(state->job);
81
+
82
+ aio_context_release(aio_context);
83
}
84
}
85
86
static void drive_backup_clean(BlkActionState *common)
87
{
88
DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
89
+ AioContext *aio_context;
90
91
- if (state->aio_context) {
92
- bdrv_drained_end(state->bs);
93
- aio_context_release(state->aio_context);
94
+ if (!state->bs) {
95
+ return;
96
}
97
+
98
+ aio_context = bdrv_get_aio_context(state->bs);
99
+ aio_context_acquire(aio_context);
100
+
101
+ bdrv_drained_end(state->bs);
102
+
103
+ aio_context_release(aio_context);
104
}
105
106
typedef struct BlockdevBackupState {
42
--
107
--
43
2.24.1
108
2.14.3
44
109
45
110
diff view generated by jsdifflib
1
The generic fallback implementation effectively does the same.
1
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
3
Reviewed-by: Eric Blake <eblake@redhat.com>
4
Message-id: 20171206144550.22295-5-stefanha@redhat.com
5
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
6
---
7
blockdev.c | 44 ++++++++++++++++++++++++++++++++++----------
8
1 file changed, 34 insertions(+), 10 deletions(-)
2
9
3
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
10
diff --git a/blockdev.c b/blockdev.c
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
Message-Id: <20200122164532.178040-5-mreitz@redhat.com>
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
---
8
block/iscsi.c | 56 ---------------------------------------------------
9
1 file changed, 56 deletions(-)
10
11
diff --git a/block/iscsi.c b/block/iscsi.c
12
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
13
--- a/block/iscsi.c
12
--- a/blockdev.c
14
+++ b/block/iscsi.c
13
+++ b/blockdev.c
15
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn iscsi_co_truncate(BlockDriverState *bs, int64_t offset,
14
@@ -XXX,XX +XXX,XX @@ typedef struct BlockdevBackupState {
16
return 0;
15
BlkActionState common;
16
BlockDriverState *bs;
17
BlockJob *job;
18
- AioContext *aio_context;
19
} BlockdevBackupState;
20
21
static BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
22
@@ -XXX,XX +XXX,XX @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
23
BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common);
24
BlockdevBackup *backup;
25
BlockDriverState *bs, *target;
26
+ AioContext *aio_context;
27
Error *local_err = NULL;
28
29
assert(common->action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP);
30
@@ -XXX,XX +XXX,XX @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
31
return;
32
}
33
34
- /* AioContext is released in .clean() */
35
- state->aio_context = bdrv_get_aio_context(bs);
36
- if (state->aio_context != bdrv_get_aio_context(target)) {
37
- state->aio_context = NULL;
38
+ aio_context = bdrv_get_aio_context(bs);
39
+ if (aio_context != bdrv_get_aio_context(target)) {
40
error_setg(errp, "Backup between two IO threads is not implemented");
41
return;
42
}
43
- aio_context_acquire(state->aio_context);
44
+ aio_context_acquire(aio_context);
45
state->bs = bs;
46
+
47
+ /* Paired with .clean() */
48
bdrv_drained_begin(state->bs);
49
50
state->job = do_blockdev_backup(backup, common->block_job_txn, &local_err);
51
if (local_err) {
52
error_propagate(errp, local_err);
53
- return;
54
+ goto out;
55
}
56
+
57
+out:
58
+ aio_context_release(aio_context);
17
}
59
}
18
60
19
-static int coroutine_fn iscsi_co_create_opts(const char *filename, QemuOpts *opts,
61
static void blockdev_backup_commit(BlkActionState *common)
20
- Error **errp)
21
-{
22
- int ret = 0;
23
- int64_t total_size = 0;
24
- BlockDriverState *bs;
25
- IscsiLun *iscsilun = NULL;
26
- QDict *bs_options;
27
- Error *local_err = NULL;
28
-
29
- bs = bdrv_new();
30
-
31
- /* Read out options */
32
- total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
33
- BDRV_SECTOR_SIZE);
34
- bs->opaque = g_new0(struct IscsiLun, 1);
35
- iscsilun = bs->opaque;
36
-
37
- bs_options = qdict_new();
38
- iscsi_parse_filename(filename, bs_options, &local_err);
39
- if (local_err) {
40
- error_propagate(errp, local_err);
41
- ret = -EINVAL;
42
- } else {
43
- ret = iscsi_open(bs, bs_options, 0, NULL);
44
- }
45
- qobject_unref(bs_options);
46
-
47
- if (ret != 0) {
48
- goto out;
49
- }
50
- iscsi_detach_aio_context(bs);
51
- if (iscsilun->type != TYPE_DISK) {
52
- ret = -ENODEV;
53
- goto out;
54
- }
55
- if (bs->total_sectors < total_size) {
56
- ret = -ENOSPC;
57
- goto out;
58
- }
59
-
60
- ret = 0;
61
-out:
62
- if (iscsilun->iscsi != NULL) {
63
- iscsi_destroy_context(iscsilun->iscsi);
64
- }
65
- g_free(bs->opaque);
66
- bs->opaque = NULL;
67
- bdrv_unref(bs);
68
- return ret;
69
-}
70
-
71
static int iscsi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
72
{
62
{
73
IscsiLun *iscsilun = bs->opaque;
63
BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common);
74
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_iscsi = {
64
+ AioContext *aio_context;
75
.bdrv_parse_filename = iscsi_parse_filename,
65
+
76
.bdrv_file_open = iscsi_open,
66
+ aio_context = bdrv_get_aio_context(state->bs);
77
.bdrv_close = iscsi_close,
67
+ aio_context_acquire(aio_context);
78
- .bdrv_co_create_opts = iscsi_co_create_opts,
68
+
79
- .create_opts = &iscsi_create_opts,
69
assert(state->job);
80
.bdrv_reopen_prepare = iscsi_reopen_prepare,
70
block_job_start(state->job);
81
.bdrv_reopen_commit = iscsi_reopen_commit,
71
+
82
.bdrv_co_invalidate_cache = iscsi_co_invalidate_cache,
72
+ aio_context_release(aio_context);
83
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_iser = {
73
}
84
.bdrv_parse_filename = iscsi_parse_filename,
74
85
.bdrv_file_open = iscsi_open,
75
static void blockdev_backup_abort(BlkActionState *common)
86
.bdrv_close = iscsi_close,
76
@@ -XXX,XX +XXX,XX @@ static void blockdev_backup_abort(BlkActionState *common)
87
- .bdrv_co_create_opts = iscsi_co_create_opts,
77
BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common);
88
- .create_opts = &iscsi_create_opts,
78
89
.bdrv_reopen_prepare = iscsi_reopen_prepare,
79
if (state->job) {
90
.bdrv_reopen_commit = iscsi_reopen_commit,
80
+ AioContext *aio_context;
91
.bdrv_co_invalidate_cache = iscsi_co_invalidate_cache,
81
+
82
+ aio_context = bdrv_get_aio_context(state->bs);
83
+ aio_context_acquire(aio_context);
84
+
85
block_job_cancel_sync(state->job);
86
+
87
+ aio_context_release(aio_context);
88
}
89
}
90
91
static void blockdev_backup_clean(BlkActionState *common)
92
{
93
BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common);
94
+ AioContext *aio_context;
95
96
- if (state->aio_context) {
97
- bdrv_drained_end(state->bs);
98
- aio_context_release(state->aio_context);
99
+ if (!state->bs) {
100
+ return;
101
}
102
+
103
+ aio_context = bdrv_get_aio_context(state->bs);
104
+ aio_context_acquire(aio_context);
105
+
106
+ bdrv_drained_end(state->bs);
107
+
108
+ aio_context_release(aio_context);
109
}
110
111
typedef struct BlockDirtyBitmapState {
92
--
112
--
93
2.24.1
113
2.14.3
94
114
95
115
diff view generated by jsdifflib
1
When nbd_close() is called from a coroutine, the connection_co never
1
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2
gets to run, and thus nbd_teardown_connection() hangs.
2
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
3
Reviewed-by: Eric Blake <eblake@redhat.com>
4
Message-id: 20171206144550.22295-6-stefanha@redhat.com
5
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
6
---
7
blockdev.c | 47 +++++++++++++++++++++++++++++++----------------
8
1 file changed, 31 insertions(+), 16 deletions(-)
3
9
4
This is because aio_co_enter() only puts the connection_co into the main
10
diff --git a/blockdev.c b/blockdev.c
5
coroutine's wake-up queue, so this main coroutine needs to yield and
6
wait for connection_co to terminate.
7
8
Suggested-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Message-Id: <20200122164532.178040-2-mreitz@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
15
block/nbd.c | 14 +++++++++++++-
16
1 file changed, 13 insertions(+), 1 deletion(-)
17
18
diff --git a/block/nbd.c b/block/nbd.c
19
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
20
--- a/block/nbd.c
12
--- a/blockdev.c
21
+++ b/block/nbd.c
13
+++ b/blockdev.c
22
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVNBDState {
14
@@ -XXX,XX +XXX,XX @@ struct BlkActionState {
23
CoMutex send_mutex;
15
typedef struct InternalSnapshotState {
24
CoQueue free_sema;
16
BlkActionState common;
25
Coroutine *connection_co;
17
BlockDriverState *bs;
26
+ Coroutine *teardown_co;
18
- AioContext *aio_context;
27
QemuCoSleepState *connection_co_sleep_ns_state;
19
QEMUSnapshotInfo sn;
28
bool drained;
20
bool created;
29
bool wait_drained_end;
21
} InternalSnapshotState;
30
@@ -XXX,XX +XXX,XX @@ static void nbd_teardown_connection(BlockDriverState *bs)
22
@@ -XXX,XX +XXX,XX @@ static void internal_snapshot_prepare(BlkActionState *common,
31
qemu_co_sleep_wake(s->connection_co_sleep_ns_state);
23
qemu_timeval tv;
32
}
24
BlockdevSnapshotInternal *internal;
25
InternalSnapshotState *state;
26
+ AioContext *aio_context;
27
int ret1;
28
29
g_assert(common->action->type ==
30
@@ -XXX,XX +XXX,XX @@ static void internal_snapshot_prepare(BlkActionState *common,
31
return;
33
}
32
}
34
- BDRV_POLL_WHILE(bs, s->connection_co);
33
35
+ if (qemu_in_coroutine()) {
34
- /* AioContext is released in .clean() */
36
+ s->teardown_co = qemu_coroutine_self();
35
- state->aio_context = bdrv_get_aio_context(bs);
37
+ /* connection_co resumes us when it terminates */
36
- aio_context_acquire(state->aio_context);
38
+ qemu_coroutine_yield();
37
+ aio_context = bdrv_get_aio_context(bs);
39
+ s->teardown_co = NULL;
38
+ aio_context_acquire(aio_context);
40
+ } else {
39
41
+ BDRV_POLL_WHILE(bs, s->connection_co);
40
state->bs = bs;
42
+ }
41
+
43
+ assert(!s->connection_co);
42
+ /* Paired with .clean() */
43
bdrv_drained_begin(bs);
44
45
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, errp)) {
46
- return;
47
+ goto out;
48
}
49
50
if (bdrv_is_read_only(bs)) {
51
error_setg(errp, "Device '%s' is read only", device);
52
- return;
53
+ goto out;
54
}
55
56
if (!bdrv_can_snapshot(bs)) {
57
error_setg(errp, "Block format '%s' used by device '%s' "
58
"does not support internal snapshots",
59
bs->drv->format_name, device);
60
- return;
61
+ goto out;
62
}
63
64
if (!strlen(name)) {
65
error_setg(errp, "Name is empty");
66
- return;
67
+ goto out;
68
}
69
70
/* check whether a snapshot with name exist */
71
@@ -XXX,XX +XXX,XX @@ static void internal_snapshot_prepare(BlkActionState *common,
72
&local_err);
73
if (local_err) {
74
error_propagate(errp, local_err);
75
- return;
76
+ goto out;
77
} else if (ret) {
78
error_setg(errp,
79
"Snapshot with name '%s' already exists on device '%s'",
80
name, device);
81
- return;
82
+ goto out;
83
}
84
85
/* 3. take the snapshot */
86
@@ -XXX,XX +XXX,XX @@ static void internal_snapshot_prepare(BlkActionState *common,
87
error_setg_errno(errp, -ret1,
88
"Failed to create snapshot '%s' on device '%s'",
89
name, device);
90
- return;
91
+ goto out;
92
}
93
94
/* 4. succeed, mark a snapshot is created */
95
state->created = true;
96
+
97
+out:
98
+ aio_context_release(aio_context);
44
}
99
}
45
100
46
static bool nbd_client_connecting(BDRVNBDState *s)
101
static void internal_snapshot_abort(BlkActionState *common)
47
@@ -XXX,XX +XXX,XX @@ static coroutine_fn void nbd_connection_entry(void *opaque)
102
@@ -XXX,XX +XXX,XX @@ static void internal_snapshot_abort(BlkActionState *common)
48
s->ioc = NULL;
103
DO_UPCAST(InternalSnapshotState, common, common);
104
BlockDriverState *bs = state->bs;
105
QEMUSnapshotInfo *sn = &state->sn;
106
+ AioContext *aio_context;
107
Error *local_error = NULL;
108
109
if (!state->created) {
110
return;
49
}
111
}
50
112
51
+ if (s->teardown_co) {
113
+ aio_context = bdrv_get_aio_context(state->bs);
52
+ aio_co_wake(s->teardown_co);
114
+ aio_context_acquire(aio_context);
53
+ }
115
+
54
aio_wait_kick();
116
if (bdrv_snapshot_delete(bs, sn->id_str, sn->name, &local_error) < 0) {
117
error_reportf_err(local_error,
118
"Failed to delete snapshot with id '%s' and "
119
@@ -XXX,XX +XXX,XX @@ static void internal_snapshot_abort(BlkActionState *common)
120
sn->id_str, sn->name,
121
bdrv_get_device_name(bs));
122
}
123
+
124
+ aio_context_release(aio_context);
55
}
125
}
56
126
127
static void internal_snapshot_clean(BlkActionState *common)
128
{
129
InternalSnapshotState *state = DO_UPCAST(InternalSnapshotState,
130
common, common);
131
+ AioContext *aio_context;
132
133
- if (state->aio_context) {
134
- if (state->bs) {
135
- bdrv_drained_end(state->bs);
136
- }
137
- aio_context_release(state->aio_context);
138
+ if (!state->bs) {
139
+ return;
140
}
141
+
142
+ aio_context = bdrv_get_aio_context(state->bs);
143
+ aio_context_acquire(aio_context);
144
+
145
+ bdrv_drained_end(state->bs);
146
+
147
+ aio_context_release(aio_context);
148
}
149
150
/* external snapshot private data */
57
--
151
--
58
2.24.1
152
2.14.3
59
153
60
154
diff view generated by jsdifflib
1
The generic fallback implementation effectively does the same.
1
The dirty bitmap actions in qmp_transaction have not used AioContext
2
since the dirty bitmap locking discipline was introduced in commit
3
2119882c7eb7e2c612b24fc0c8d86f5887d6f1c3 ("block: introduce
4
dirty_bitmap_mutex"). Remove the unused field.
2
5
3
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
6
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
5
Message-Id: <20200122164532.178040-4-mreitz@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Message-id: 20171206144550.22295-7-stefanha@redhat.com
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
---
11
---
8
block/file-posix.c | 67 ----------------------------------------------
12
blockdev.c | 13 -------------
9
1 file changed, 67 deletions(-)
13
1 file changed, 13 deletions(-)
10
14
11
diff --git a/block/file-posix.c b/block/file-posix.c
15
diff --git a/blockdev.c b/blockdev.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/block/file-posix.c
17
--- a/blockdev.c
14
+++ b/block/file-posix.c
18
+++ b/blockdev.c
15
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int hdev_co_pwrite_zeroes(BlockDriverState *bs,
19
@@ -XXX,XX +XXX,XX @@ typedef struct BlockDirtyBitmapState {
16
return raw_do_pwrite_zeroes(bs, offset, bytes, flags, true);
20
BlkActionState common;
21
BdrvDirtyBitmap *bitmap;
22
BlockDriverState *bs;
23
- AioContext *aio_context;
24
HBitmap *backup;
25
bool prepared;
26
} BlockDirtyBitmapState;
27
@@ -XXX,XX +XXX,XX @@ static void block_dirty_bitmap_clear_prepare(BlkActionState *common,
28
}
29
30
bdrv_clear_dirty_bitmap(state->bitmap, &state->backup);
31
- /* AioContext is released in .clean() */
17
}
32
}
18
33
19
-static int coroutine_fn hdev_co_create_opts(const char *filename, QemuOpts *opts,
34
static void block_dirty_bitmap_clear_abort(BlkActionState *common)
20
- Error **errp)
35
@@ -XXX,XX +XXX,XX @@ static void block_dirty_bitmap_clear_commit(BlkActionState *common)
36
hbitmap_free(state->backup);
37
}
38
39
-static void block_dirty_bitmap_clear_clean(BlkActionState *common)
21
-{
40
-{
22
- int fd;
41
- BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
23
- int ret = 0;
42
- common, common);
24
- struct stat stat_buf;
25
- int64_t total_size = 0;
26
- bool has_prefix;
27
-
43
-
28
- /* This function is used by both protocol block drivers and therefore either
44
- if (state->aio_context) {
29
- * of these prefixes may be given.
45
- aio_context_release(state->aio_context);
30
- * The return value has to be stored somewhere, otherwise this is an error
31
- * due to -Werror=unused-value. */
32
- has_prefix =
33
- strstart(filename, "host_device:", &filename) ||
34
- strstart(filename, "host_cdrom:" , &filename);
35
-
36
- (void)has_prefix;
37
-
38
- ret = raw_normalize_devicepath(&filename, errp);
39
- if (ret < 0) {
40
- return ret;
41
- }
46
- }
42
-
43
- /* Read out options */
44
- total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
45
- BDRV_SECTOR_SIZE);
46
-
47
- fd = qemu_open(filename, O_WRONLY | O_BINARY);
48
- if (fd < 0) {
49
- ret = -errno;
50
- error_setg_errno(errp, -ret, "Could not open device");
51
- return ret;
52
- }
53
-
54
- if (fstat(fd, &stat_buf) < 0) {
55
- ret = -errno;
56
- error_setg_errno(errp, -ret, "Could not stat device");
57
- } else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode)) {
58
- error_setg(errp,
59
- "The given file is neither a block nor a character device");
60
- ret = -ENODEV;
61
- } else if (lseek(fd, 0, SEEK_END) < total_size) {
62
- error_setg(errp, "Device is too small");
63
- ret = -ENOSPC;
64
- }
65
-
66
- if (!ret && total_size) {
67
- uint8_t buf[BDRV_SECTOR_SIZE] = { 0 };
68
- int64_t zero_size = MIN(BDRV_SECTOR_SIZE, total_size);
69
- if (lseek(fd, 0, SEEK_SET) == -1) {
70
- ret = -errno;
71
- } else {
72
- ret = qemu_write_full(fd, buf, zero_size);
73
- ret = ret == zero_size ? 0 : -errno;
74
- }
75
- }
76
- qemu_close(fd);
77
- return ret;
78
-}
47
-}
79
-
48
-
80
static BlockDriver bdrv_host_device = {
49
static void abort_prepare(BlkActionState *common, Error **errp)
81
.format_name = "host_device",
50
{
82
.protocol_name = "host_device",
51
error_setg(errp, "Transaction aborted using Abort action");
83
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_device = {
52
@@ -XXX,XX +XXX,XX @@ static const BlkActionOps actions[] = {
84
.bdrv_reopen_prepare = raw_reopen_prepare,
53
.prepare = block_dirty_bitmap_clear_prepare,
85
.bdrv_reopen_commit = raw_reopen_commit,
54
.commit = block_dirty_bitmap_clear_commit,
86
.bdrv_reopen_abort = raw_reopen_abort,
55
.abort = block_dirty_bitmap_clear_abort,
87
- .bdrv_co_create_opts = hdev_co_create_opts,
56
- .clean = block_dirty_bitmap_clear_clean,
88
- .create_opts = &raw_create_opts,
57
}
89
.mutable_opts = mutable_opts,
58
};
90
.bdrv_co_invalidate_cache = raw_co_invalidate_cache,
59
91
.bdrv_co_pwrite_zeroes = hdev_co_pwrite_zeroes,
92
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
93
.bdrv_reopen_prepare = raw_reopen_prepare,
94
.bdrv_reopen_commit = raw_reopen_commit,
95
.bdrv_reopen_abort = raw_reopen_abort,
96
- .bdrv_co_create_opts = hdev_co_create_opts,
97
- .create_opts = &raw_create_opts,
98
.mutable_opts = mutable_opts,
99
.bdrv_co_invalidate_cache = raw_co_invalidate_cache,
100
101
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
102
.bdrv_reopen_prepare = raw_reopen_prepare,
103
.bdrv_reopen_commit = raw_reopen_commit,
104
.bdrv_reopen_abort = raw_reopen_abort,
105
- .bdrv_co_create_opts = hdev_co_create_opts,
106
- .create_opts = &raw_create_opts,
107
.mutable_opts = mutable_opts,
108
109
.bdrv_co_preadv = raw_co_preadv,
110
--
60
--
111
2.24.1
61
2.14.3
112
62
113
63
diff view generated by jsdifflib
1
This must not crash.
1
Encapsulate IOThread QOM object lookup so that callers don't need to
2
know how and where IOThread objects live.
2
3
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
4
Message-Id: <20200121155915.98232-3-mreitz@redhat.com>
5
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: John Snow <jsnow@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Message-id: 20171206144550.22295-8-stefanha@redhat.com
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
---
9
---
8
tests/qemu-iotests/122 | 14 ++++++++++++++
10
include/sysemu/iothread.h | 1 +
9
tests/qemu-iotests/122.out | 5 +++++
11
iothread.c | 7 +++++++
10
2 files changed, 19 insertions(+)
12
2 files changed, 8 insertions(+)
11
13
12
diff --git a/tests/qemu-iotests/122 b/tests/qemu-iotests/122
14
diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h
13
index XXXXXXX..XXXXXXX 100755
15
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/qemu-iotests/122
16
--- a/include/sysemu/iothread.h
15
+++ b/tests/qemu-iotests/122
17
+++ b/include/sysemu/iothread.h
16
@@ -XXX,XX +XXX,XX @@ $QEMU_IMG convert -O $IMGFMT -n "$TEST_IMG" "$TEST_IMG".orig
18
@@ -XXX,XX +XXX,XX @@ typedef struct {
17
19
OBJECT_CHECK(IOThread, obj, TYPE_IOTHREAD)
18
$QEMU_IMG compare "$TEST_IMG" "$TEST_IMG".orig
20
19
21
char *iothread_get_id(IOThread *iothread);
20
+echo
22
+IOThread *iothread_by_id(const char *id);
21
+echo '=== -n -B to an image without a backing file ==='
23
AioContext *iothread_get_aio_context(IOThread *iothread);
22
+echo
24
void iothread_stop_all(void);
25
GMainContext *iothread_get_g_main_context(IOThread *iothread);
26
diff --git a/iothread.c b/iothread.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/iothread.c
29
+++ b/iothread.c
30
@@ -XXX,XX +XXX,XX @@ void iothread_destroy(IOThread *iothread)
31
{
32
object_unparent(OBJECT(iothread));
33
}
23
+
34
+
24
+# Base for the output
35
+/* Lookup IOThread by its id. Only finds user-created objects, not internal
25
+TEST_IMG="$TEST_IMG".base _make_test_img 64M
36
+ * iothread_create() objects. */
26
+
37
+IOThread *iothread_by_id(const char *id)
27
+# Output that does have $TEST_IMG.base set as its (implicit) backing file
38
+{
28
+TEST_IMG="$TEST_IMG".orig _make_test_img 64M
39
+ return IOTHREAD(object_resolve_path_type(id, TYPE_IOTHREAD, NULL));
29
+
40
+}
30
+# Convert with -n, which should not confuse -B with "target BDS has a
31
+# backing file"
32
+$QEMU_IMG convert -O $IMGFMT -B "$TEST_IMG".base -n "$TEST_IMG" "$TEST_IMG".orig
33
+
34
# success, all done
35
echo '*** done'
36
rm -f $seq.full
37
diff --git a/tests/qemu-iotests/122.out b/tests/qemu-iotests/122.out
38
index XXXXXXX..XXXXXXX 100644
39
--- a/tests/qemu-iotests/122.out
40
+++ b/tests/qemu-iotests/122.out
41
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.orig', fmt=IMGFMT size=67108864
42
wrote 65536/65536 bytes at offset 0
43
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
44
Images are identical.
45
+
46
+=== -n -B to an image without a backing file ===
47
+
48
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
49
+Formatting 'TEST_DIR/t.IMGFMT.orig', fmt=IMGFMT size=67108864
50
*** done
51
--
41
--
52
2.24.1
42
2.14.3
53
43
54
44
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
Currently there is no easy way for iotests to ensure that a BDS is bound
2
to a particular IOThread. Normally the virtio-blk device calls
3
blk_set_aio_context() when dataplane is enabled during guest driver
4
initialization. This never happens in iotests since -machine
5
accel=qtest means there is no guest activity (including device driver
6
initialization).
2
7
3
backup-top "supports" write-unchanged, by skipping CBW operation in
8
This patch adds a QMP command to explicitly assign IOThreads in test
4
backup_top_co_pwritev. But it forgets to do the same in
9
cases. See qapi/block-core.json for a description of the command.
5
backup_top_co_pwrite_zeroes, as well as declare support for
6
BDRV_REQ_WRITE_UNCHANGED.
7
10
8
Fix this, and, while being here, declare also support for flags
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
supported by source child.
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
13
Reviewed-by: Eric Blake <eblake@redhat.com>
14
Message-id: 20171206144550.22295-9-stefanha@redhat.com
15
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
16
---
17
qapi/block-core.json | 36 ++++++++++++++++++++++++++++++++++++
18
blockdev.c | 41 +++++++++++++++++++++++++++++++++++++++++
19
2 files changed, 77 insertions(+)
10
20
11
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
21
diff --git a/qapi/block-core.json b/qapi/block-core.json
12
Message-Id: <20200207161231.32707-1-vsementsov@virtuozzo.com>
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
15
block/backup-top.c | 31 ++++++++++++++++++++-----------
16
1 file changed, 20 insertions(+), 11 deletions(-)
17
18
diff --git a/block/backup-top.c b/block/backup-top.c
19
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
20
--- a/block/backup-top.c
23
--- a/qapi/block-core.json
21
+++ b/block/backup-top.c
24
+++ b/qapi/block-core.json
22
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int backup_top_co_preadv(
25
@@ -XXX,XX +XXX,XX @@
26
'data' : { 'parent': 'str',
27
'*child': 'str',
28
'*node': 'str' } }
29
+
30
+##
31
+# @x-blockdev-set-iothread:
32
+#
33
+# Move @node and its children into the @iothread. If @iothread is null then
34
+# move @node and its children into the main loop.
35
+#
36
+# The node must not be attached to a BlockBackend.
37
+#
38
+# @node-name: the name of the block driver node
39
+#
40
+# @iothread: the name of the IOThread object or null for the main loop
41
+#
42
+# Note: this command is experimental and intended for test cases that need
43
+# control over IOThreads only.
44
+#
45
+# Since: 2.12
46
+#
47
+# Example:
48
+#
49
+# 1. Move a node into an IOThread
50
+# -> { "execute": "x-blockdev-set-iothread",
51
+# "arguments": { "node-name": "disk1",
52
+# "iothread": "iothread0" } }
53
+# <- { "return": {} }
54
+#
55
+# 2. Move a node into the main loop
56
+# -> { "execute": "x-blockdev-set-iothread",
57
+# "arguments": { "node-name": "disk1",
58
+# "iothread": null } }
59
+# <- { "return": {} }
60
+#
61
+##
62
+{ 'command': 'x-blockdev-set-iothread',
63
+ 'data' : { 'node-name': 'str',
64
+ 'iothread': 'StrOrNull' } }
65
diff --git a/blockdev.c b/blockdev.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/blockdev.c
68
+++ b/blockdev.c
69
@@ -XXX,XX +XXX,XX @@
70
#include "qapi/qmp/qerror.h"
71
#include "qapi/qobject-output-visitor.h"
72
#include "sysemu/sysemu.h"
73
+#include "sysemu/iothread.h"
74
#include "block/block_int.h"
75
#include "qmp-commands.h"
76
#include "block/trace.h"
77
@@ -XXX,XX +XXX,XX @@ BlockJobInfoList *qmp_query_block_jobs(Error **errp)
78
return head;
23
}
79
}
24
80
25
static coroutine_fn int backup_top_cbw(BlockDriverState *bs, uint64_t offset,
81
+void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread,
26
- uint64_t bytes)
82
+ Error **errp)
27
+ uint64_t bytes, BdrvRequestFlags flags)
83
+{
28
{
84
+ AioContext *old_context;
29
BDRVBackupTopState *s = bs->opaque;
85
+ AioContext *new_context;
30
- uint64_t end = QEMU_ALIGN_UP(offset + bytes, s->bcs->cluster_size);
86
+ BlockDriverState *bs;
31
- uint64_t off = QEMU_ALIGN_DOWN(offset, s->bcs->cluster_size);
32
+ uint64_t off, end;
33
+
87
+
34
+ if (flags & BDRV_REQ_WRITE_UNCHANGED) {
88
+ bs = bdrv_find_node(node_name);
35
+ return 0;
89
+ if (!bs) {
90
+ error_setg(errp, "Cannot find node %s", node_name);
91
+ return;
36
+ }
92
+ }
37
+
93
+
38
+ off = QEMU_ALIGN_DOWN(offset, s->bcs->cluster_size);
94
+ /* If we want to allow more extreme test scenarios this guard could be
39
+ end = QEMU_ALIGN_UP(offset + bytes, s->bcs->cluster_size);
95
+ * removed. For now it protects against accidents. */
40
96
+ if (bdrv_has_blk(bs)) {
41
return block_copy(s->bcs, off, end - off, NULL);
97
+ error_setg(errp, "Node %s is in use", node_name);
42
}
98
+ return;
43
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int backup_top_cbw(BlockDriverState *bs, uint64_t offset,
99
+ }
44
static int coroutine_fn backup_top_co_pdiscard(BlockDriverState *bs,
100
+
45
int64_t offset, int bytes)
101
+ if (iothread->type == QTYPE_QSTRING) {
46
{
102
+ IOThread *obj = iothread_by_id(iothread->u.s);
47
- int ret = backup_top_cbw(bs, offset, bytes);
103
+ if (!obj) {
48
+ int ret = backup_top_cbw(bs, offset, bytes, 0);
104
+ error_setg(errp, "Cannot find iothread %s", iothread->u.s);
49
if (ret < 0) {
105
+ return;
50
return ret;
106
+ }
51
}
107
+
52
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_top_co_pdiscard(BlockDriverState *bs,
108
+ new_context = iothread_get_aio_context(obj);
53
static int coroutine_fn backup_top_co_pwrite_zeroes(BlockDriverState *bs,
109
+ } else {
54
int64_t offset, int bytes, BdrvRequestFlags flags)
110
+ new_context = qemu_get_aio_context();
55
{
111
+ }
56
- int ret = backup_top_cbw(bs, offset, bytes);
112
+
57
+ int ret = backup_top_cbw(bs, offset, bytes, flags);
113
+ old_context = bdrv_get_aio_context(bs);
58
if (ret < 0) {
114
+ aio_context_acquire(old_context);
59
return ret;
115
+
60
}
116
+ bdrv_set_aio_context(bs, new_context);
61
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int backup_top_co_pwritev(BlockDriverState *bs,
117
+
62
uint64_t bytes,
118
+ aio_context_release(old_context);
63
QEMUIOVector *qiov, int flags)
119
+}
64
{
120
+
65
- if (!(flags & BDRV_REQ_WRITE_UNCHANGED)) {
121
QemuOptsList qemu_common_drive_opts = {
66
- int ret = backup_top_cbw(bs, offset, bytes);
122
.name = "drive",
67
- if (ret < 0) {
123
.head = QTAILQ_HEAD_INITIALIZER(qemu_common_drive_opts.head),
68
- return ret;
69
- }
70
+ int ret = backup_top_cbw(bs, offset, bytes, flags);
71
+ if (ret < 0) {
72
+ return ret;
73
}
74
75
return bdrv_co_pwritev(bs->backing, offset, bytes, qiov, flags);
76
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source,
77
return NULL;
78
}
79
80
- top->total_sectors = source->total_sectors;
81
state = top->opaque;
82
+ top->total_sectors = source->total_sectors;
83
+ top->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
84
+ (BDRV_REQ_FUA & source->supported_write_flags);
85
+ top->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
86
+ ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
87
+ source->supported_zero_flags);
88
89
bdrv_ref(target);
90
state->target = bdrv_attach_child(top, target, "target", &child_file, errp);
91
--
124
--
92
2.24.1
125
2.14.3
93
126
94
127
diff view generated by jsdifflib
1
Add a test that all fields in "qemu-img snapshot -l"s output are
1
QMP 'transaction' blockdev-snapshot-sync with multiple disks in an
2
separated by spaces.
2
IOThread is an untested code path. Several bugs have been found in
3
connection with this command. This patch adds a test case to prevent
4
future regressions.
3
5
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Message-Id: <20200117105859.241818-3-mreitz@redhat.com>
7
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
7
[mreitz: Renamed test from 284 to 286]
9
Message-id: 20171206144550.22295-10-stefanha@redhat.com
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
---
11
---
10
tests/qemu-iotests/286 | 76 ++++++++++++++++++++++++++++++++++++++
12
tests/qemu-iotests/202 | 95 ++++++++++++++++++++++++++++++++++++++++++++++
11
tests/qemu-iotests/286.out | 8 ++++
13
tests/qemu-iotests/202.out | 11 ++++++
12
tests/qemu-iotests/group | 1 +
14
tests/qemu-iotests/group | 1 +
13
3 files changed, 85 insertions(+)
15
3 files changed, 107 insertions(+)
14
create mode 100755 tests/qemu-iotests/286
16
create mode 100755 tests/qemu-iotests/202
15
create mode 100644 tests/qemu-iotests/286.out
17
create mode 100644 tests/qemu-iotests/202.out
16
18
17
diff --git a/tests/qemu-iotests/286 b/tests/qemu-iotests/286
19
diff --git a/tests/qemu-iotests/202 b/tests/qemu-iotests/202
18
new file mode 100755
20
new file mode 100755
19
index XXXXXXX..XXXXXXX
21
index XXXXXXX..XXXXXXX
20
--- /dev/null
22
--- /dev/null
21
+++ b/tests/qemu-iotests/286
23
+++ b/tests/qemu-iotests/202
22
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
23
+#!/usr/bin/env bash
25
+#!/usr/bin/env python
24
+#
26
+#
25
+# Test qemu-img snapshot -l
27
+# Copyright (C) 2017 Red Hat, Inc.
26
+#
27
+# Copyright (C) 2019 Red Hat, Inc.
28
+#
28
+#
29
+# This program is free software; you can redistribute it and/or modify
29
+# This program is free software; you can redistribute it and/or modify
30
+# it under the terms of the GNU General Public License as published by
30
+# it under the terms of the GNU General Public License as published by
31
+# the Free Software Foundation; either version 2 of the License, or
31
+# the Free Software Foundation; either version 2 of the License, or
32
+# (at your option) any later version.
32
+# (at your option) any later version.
...
...
37
+# GNU General Public License for more details.
37
+# GNU General Public License for more details.
38
+#
38
+#
39
+# You should have received a copy of the GNU General Public License
39
+# You should have received a copy of the GNU General Public License
40
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
40
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
41
+#
41
+#
42
+# Creator/Owner: Stefan Hajnoczi <stefanha@redhat.com>
43
+#
44
+# Check that QMP 'transaction' blockdev-snapshot-sync with multiple drives on a
45
+# single IOThread completes successfully. This particular command triggered a
46
+# hang due to recursive AioContext locking and BDRV_POLL_WHILE(). Protect
47
+# against regressions.
42
+
48
+
43
+seq=$(basename "$0")
49
+import iotests
44
+echo "QA output created by $seq"
45
+
50
+
46
+status=1    # failure is the default!
51
+iotests.verify_image_format(supported_fmts=['qcow2'])
52
+iotests.verify_platform(['linux'])
47
+
53
+
48
+_cleanup()
54
+with iotests.FilePath('disk0.img') as disk0_img_path, \
49
+{
55
+ iotests.FilePath('disk1.img') as disk1_img_path, \
50
+ _cleanup_test_img
56
+ iotests.FilePath('disk0-snap.img') as disk0_snap_img_path, \
51
+}
57
+ iotests.FilePath('disk1-snap.img') as disk1_snap_img_path, \
52
+trap "_cleanup; exit \$status" 0 1 2 3 15
58
+ iotests.VM() as vm:
53
+
59
+
54
+# get standard environment, filters and checks
60
+ img_size = '10M'
55
+. ./common.rc
61
+ iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk0_img_path, img_size)
56
+. ./common.filter
62
+ iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk1_img_path, img_size)
57
+. ./common.qemu
58
+
63
+
59
+_supported_fmt qcow2
64
+ iotests.log('Launching VM...')
60
+_supported_proto file
65
+ vm.launch()
61
+# Internal snapshots are (currently) impossible with refcount_bits=1,
62
+# and generally impossible with external data files
63
+_unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
64
+
66
+
65
+_make_test_img 64M
67
+ iotests.log('Adding IOThread...')
68
+ iotests.log(vm.qmp('object-add',
69
+ qom_type='iothread',
70
+ id='iothread0'))
66
+
71
+
67
+# Should be so long as to take up the whole field width
72
+ iotests.log('Adding blockdevs...')
68
+sn_name=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
73
+ iotests.log(vm.qmp('blockdev-add',
74
+ driver=iotests.imgfmt,
75
+ node_name='disk0',
76
+ file={
77
+ 'driver': 'file',
78
+ 'filename': disk0_img_path,
79
+ }))
80
+ iotests.log(vm.qmp('blockdev-add',
81
+ driver=iotests.imgfmt,
82
+ node_name='disk1',
83
+ file={
84
+ 'driver': 'file',
85
+ 'filename': disk1_img_path,
86
+ }))
69
+
87
+
70
+# More memory will give us a larger VM state, i.e. one above 1 MB.
88
+ iotests.log('Setting iothread...')
71
+# This way, we get a number with a decimal point.
89
+ iotests.log(vm.qmp('x-blockdev-set-iothread',
72
+qemu_comm_method=monitor _launch_qemu -m 512 "$TEST_IMG"
90
+ node_name='disk0',
91
+ iothread='iothread0'))
92
+ iotests.log(vm.qmp('x-blockdev-set-iothread',
93
+ node_name='disk1',
94
+ iothread='iothread0'))
73
+
95
+
74
+_send_qemu_cmd $QEMU_HANDLE "savevm $sn_name" '(qemu)'
96
+ iotests.log('Creating external snapshots...')
75
+_send_qemu_cmd $QEMU_HANDLE 'quit' '(qemu)'
97
+ iotests.log(vm.qmp(
76
+wait=yes _cleanup_qemu
98
+ 'transaction',
77
+
99
+ actions=[
78
+# Check that all fields are separated by spaces.
100
+ {
79
+# We first collapse all space sequences into one space each;
101
+ 'data': {
80
+# then we turn every space-separated field into a '.';
102
+ 'node-name': 'disk0',
81
+# and finally, we name the '.'s so the output is not just a confusing
103
+ 'snapshot-file': disk0_snap_img_path,
82
+# sequence of dots.
104
+ 'snapshot-node-name': 'disk0-snap',
83
+
105
+ 'mode': 'absolute-paths',
84
+echo 'Output structure:'
106
+ 'format': iotests.imgfmt,
85
+$QEMU_IMG snapshot -l "$TEST_IMG" | tail -n 1 | tr -s ' ' \
107
+ },
86
+ | sed -e 's/\S\+/./g' \
108
+ 'type': 'blockdev-snapshot-sync'
87
+ | sed -e 's/\./(snapshot ID)/' \
109
+ }, {
88
+ -e 's/\./(snapshot name)/' \
110
+ 'data': {
89
+ -e 's/\./(VM state size value)/' \
111
+ 'node-name': 'disk1',
90
+ -e 's/\./(VM state size unit)/' \
112
+ 'snapshot-file': disk1_snap_img_path,
91
+ -e 's/\./(snapshot date)/' \
113
+ 'snapshot-node-name': 'disk1-snap',
92
+ -e 's/\./(snapshot time)/' \
114
+ 'mode': 'absolute-paths',
93
+ -e 's/\./(VM clock)/'
115
+ 'format': iotests.imgfmt
94
+
116
+ },
95
+# success, all done
117
+ 'type': 'blockdev-snapshot-sync'
96
+echo "*** done"
118
+ }
97
+rm -f $seq.full
119
+ ]))
98
+status=0
120
diff --git a/tests/qemu-iotests/202.out b/tests/qemu-iotests/202.out
99
diff --git a/tests/qemu-iotests/286.out b/tests/qemu-iotests/286.out
100
new file mode 100644
121
new file mode 100644
101
index XXXXXXX..XXXXXXX
122
index XXXXXXX..XXXXXXX
102
--- /dev/null
123
--- /dev/null
103
+++ b/tests/qemu-iotests/286.out
124
+++ b/tests/qemu-iotests/202.out
104
@@ -XXX,XX +XXX,XX @@
125
@@ -XXX,XX +XXX,XX @@
105
+QA output created by 286
126
+Launching VM...
106
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
127
+Adding IOThread...
107
+QEMU X.Y.Z monitor - type 'help' for more information
128
+{u'return': {}}
108
+(qemu) savevm abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
129
+Adding blockdevs...
109
+(qemu) quit
130
+{u'return': {}}
110
+Output structure:
131
+{u'return': {}}
111
+(snapshot ID) (snapshot name) (VM state size value) (VM state size unit) (snapshot date) (snapshot time) (VM clock)
132
+Setting iothread...
112
+*** done
133
+{u'return': {}}
134
+{u'return': {}}
135
+Creating external snapshots...
136
+{u'return': {}}
113
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
137
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
114
index XXXXXXX..XXXXXXX 100644
138
index XXXXXXX..XXXXXXX 100644
115
--- a/tests/qemu-iotests/group
139
--- a/tests/qemu-iotests/group
116
+++ b/tests/qemu-iotests/group
140
+++ b/tests/qemu-iotests/group
117
@@ -XXX,XX +XXX,XX @@
141
@@ -XXX,XX +XXX,XX @@
118
281 rw quick
142
197 rw auto quick
119
283 auto quick
143
198 rw auto
120
284 rw
144
200 rw auto
121
+286 rw quick
145
+202 rw auto quick
122
--
146
--
123
2.24.1
147
2.14.3
124
148
125
149
diff view generated by jsdifflib
1
First, driver=qcow2 will not work so well with non-qcow2 formats (and
1
From: Mark Kanda <mark.kanda@oracle.com>
2
this test claims to support qcow, qed, and vmdk).
3
2
4
Second, vmdk will always report the backing file format to be vmdk.
3
Depending on the configuration, it can be beneficial to adjust the virtio-blk
5
Filter that out so the output looks like for all other formats.
4
queue size to something other than the current default of 128. Add a new
5
property to make the queue size configurable.
6
6
7
Third, the flat vmdk subformats do not support backing files, so they
7
Signed-off-by: Mark Kanda <mark.kanda@oracle.com>
8
will not work with this test.
8
Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com>
9
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
10
Reviewed-by: Ameya More <ameya.more@oracle.com>
11
Message-id: 52e6d742811f10dbd16e996e86cf375b9577c187.1513005190.git.mark.kanda@oracle.com
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
14
include/hw/virtio/virtio-blk.h | 1 +
15
hw/block/virtio-blk.c | 10 +++++++++-
16
2 files changed, 10 insertions(+), 1 deletion(-)
9
17
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
18
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
11
Message-Id: <20191219144243.1763246-1-mreitz@redhat.com>
19
index XXXXXXX..XXXXXXX 100644
12
Tested-by: Thomas Huth <thuth@redhat.com>
20
--- a/include/hw/virtio/virtio-blk.h
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
21
+++ b/include/hw/virtio/virtio-blk.h
14
---
22
@@ -XXX,XX +XXX,XX @@ struct VirtIOBlkConf
15
tests/qemu-iotests/279 | 7 +++++--
23
uint32_t config_wce;
16
1 file changed, 5 insertions(+), 2 deletions(-)
24
uint32_t request_merging;
17
25
uint16_t num_queues;
18
diff --git a/tests/qemu-iotests/279 b/tests/qemu-iotests/279
26
+ uint16_t queue_size;
19
index XXXXXXX..XXXXXXX 100755
27
};
20
--- a/tests/qemu-iotests/279
28
21
+++ b/tests/qemu-iotests/279
29
struct VirtIOBlockDataPlane;
22
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
30
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
23
_supported_fmt qcow qcow2 vmdk qed
31
index XXXXXXX..XXXXXXX 100644
24
_supported_proto file
32
--- a/hw/block/virtio-blk.c
25
_supported_os Linux
33
+++ b/hw/block/virtio-blk.c
26
+_unsupported_imgopts "subformat=monolithicFlat" \
34
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
27
+ "subformat=twoGbMaxExtentFlat" \
35
error_setg(errp, "num-queues property must be larger than 0");
28
36
return;
29
TEST_IMG="$TEST_IMG.base" _make_test_img 64M
37
}
30
TEST_IMG="$TEST_IMG.mid" _make_test_img -b "$TEST_IMG.base"
38
+ if (!is_power_of_2(conf->queue_size) ||
31
@@ -XXX,XX +XXX,XX @@ _make_test_img -b "$TEST_IMG.mid"
39
+ conf->queue_size > VIRTQUEUE_MAX_SIZE) {
32
40
+ error_setg(errp, "invalid queue-size property (%" PRIu16 "), "
33
echo
41
+ "must be a power of 2 (max %d)",
34
echo '== qemu-img info --backing-chain =='
42
+ conf->queue_size, VIRTQUEUE_MAX_SIZE);
35
-_img_info --backing-chain | _filter_img_info
43
+ return;
36
+_img_info --backing-chain | _filter_img_info | grep -v 'backing file format'
44
+ }
37
45
38
echo
46
blkconf_serial(&conf->conf, &conf->serial);
39
echo '== qemu-img info --backing-chain --image-opts =='
47
if (!blkconf_apply_backend_options(&conf->conf,
40
-TEST_IMG="driver=qcow2,file.driver=file,file.filename=$TEST_IMG" _img_info --backing-chain --image-opts | _filter_img_info
48
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
41
+TEST_IMG="driver=$IMGFMT,file.driver=file,file.filename=$TEST_IMG" _img_info --backing-chain --image-opts \
49
s->sector_mask = (s->conf.conf.logical_block_size / BDRV_SECTOR_SIZE) - 1;
42
+ | _filter_img_info | grep -v 'backing file format'
50
43
51
for (i = 0; i < conf->num_queues; i++) {
44
# success, all done
52
- virtio_add_queue(vdev, 128, virtio_blk_handle_output);
45
echo "*** done"
53
+ virtio_add_queue(vdev, conf->queue_size, virtio_blk_handle_output);
54
}
55
virtio_blk_data_plane_create(vdev, conf, &s->dataplane, &err);
56
if (err != NULL) {
57
@@ -XXX,XX +XXX,XX @@ static Property virtio_blk_properties[] = {
58
DEFINE_PROP_BIT("request-merging", VirtIOBlock, conf.request_merging, 0,
59
true),
60
DEFINE_PROP_UINT16("num-queues", VirtIOBlock, conf.num_queues, 1),
61
+ DEFINE_PROP_UINT16("queue-size", VirtIOBlock, conf.queue_size, 128),
62
DEFINE_PROP_LINK("iothread", VirtIOBlock, conf.iothread, TYPE_IOTHREAD,
63
IOThread *),
64
DEFINE_PROP_END_OF_LIST(),
46
--
65
--
47
2.24.1
66
2.14.3
48
67
49
68
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Mark Kanda <mark.kanda@oracle.com>
2
2
3
Commit d9df28e7b07 ("iotests: check whitelisted formats") added the
3
virtio-blk logical block size should never be larger than physical block
4
modern @iotests.skip_if_unsupported() to the functions in this test,
4
size because it doesn't make sense to have such configurations. QEMU doesn't
5
so we don't need the old explicit test here anymore.
5
have a way to effectively express this condition; the best it can do is
6
report the physical block exponent as 0 - indicating the logical block size
7
equals the physical block size.
6
8
7
Signed-off-by: Thomas Huth <thuth@redhat.com>
9
This is identical to commit 3da023b5827543ee4c022986ea2ad9d1274410b2
8
Message-Id: <20200129141751.32652-1-thuth@redhat.com>
10
but applied to virtio-blk (instead of virtio-scsi).
9
Reviewed-by: Alberto Garcia <berto@igalia.com>
11
10
Reviewed-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
12
Signed-off-by: Mark Kanda <mark.kanda@oracle.com>
11
Tested-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
13
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
Reviewed-by: Ameya More <ameya.more@oracle.com>
15
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
16
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
17
Message-id: 773169891f9f2deb4cb7c4ef2655580dbe24c1d1.1513005190.git.mark.kanda@oracle.com
18
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
19
---
14
tests/qemu-iotests/139 | 3 ---
20
hw/block/virtio-blk.c | 7 +++++++
15
1 file changed, 3 deletions(-)
21
1 file changed, 7 insertions(+)
16
22
17
diff --git a/tests/qemu-iotests/139 b/tests/qemu-iotests/139
23
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
18
index XXXXXXX..XXXXXXX 100755
24
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/qemu-iotests/139
25
--- a/hw/block/virtio-blk.c
20
+++ b/tests/qemu-iotests/139
26
+++ b/hw/block/virtio-blk.c
21
@@ -XXX,XX +XXX,XX @@ class TestBlockdevDel(iotests.QMPTestCase):
27
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
22
28
23
@iotests.skip_if_unsupported(['quorum'])
29
blkconf_blocksizes(&conf->conf);
24
def testQuorum(self):
30
25
- if not iotests.supports_quorum():
31
+ if (conf->conf.logical_block_size >
26
- return
32
+ conf->conf.physical_block_size) {
27
-
33
+ error_setg(errp,
28
self.addQuorum('quorum0', 'node0', 'node1')
34
+ "logical_block_size > physical_block_size not supported");
29
# We cannot remove the children of a Quorum device
35
+ return;
30
self.delBlockDriverState('node0', expect_error = True)
36
+ }
37
+
38
virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK,
39
sizeof(struct virtio_blk_config));
40
31
--
41
--
32
2.24.1
42
2.14.3
33
43
34
44
diff view generated by jsdifflib
1
If a protocol driver does not support image creation, we can see whether
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
maybe the file exists already. If so, just truncating it will be
3
sufficient.
4
2
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
BDRV_POLL_WHILE() does not support recursive AioContext locking. It
6
Message-Id: <20200122164532.178040-3-mreitz@redhat.com>
4
only releases the AioContext lock once regardless of how many times the
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
caller has acquired it. This results in a hang since the IOThread does
6
not make progress while the AioContext is still locked.
7
8
The following steps trigger the hang:
9
10
$ qemu-system-x86_64 -M accel=kvm -m 1G -cpu host \
11
-object iothread,id=iothread0 \
12
-device virtio-scsi-pci,iothread=iothread0 \
13
-drive if=none,id=drive0,file=test.img,format=raw \
14
-device scsi-hd,drive=drive0 \
15
-drive if=none,id=drive1,file=test.img,format=raw \
16
-device scsi-hd,drive=drive1
17
$ qemu-system-x86_64 ...same options... \
18
-incoming tcp::1234
19
(qemu) migrate tcp:127.0.0.1:1234
20
...hang...
21
22
Tested-by: Stefan Hajnoczi <stefanha@redhat.com>
23
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
24
Reviewed-by: Eric Blake <eblake@redhat.com>
25
Message-id: 20171207201320.19284-2-stefanha@redhat.com
26
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
---
27
---
9
block.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
28
block.c | 14 +++++++++++---
10
1 file changed, 147 insertions(+), 12 deletions(-)
29
1 file changed, 11 insertions(+), 3 deletions(-)
11
30
12
diff --git a/block.c b/block.c
31
diff --git a/block.c b/block.c
13
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
14
--- a/block.c
33
--- a/block.c
15
+++ b/block.c
34
+++ b/block.c
16
@@ -XXX,XX +XXX,XX @@ out:
35
@@ -XXX,XX +XXX,XX @@ int bdrv_inactivate_all(void)
36
BdrvNextIterator it;
37
int ret = 0;
38
int pass;
39
+ GSList *aio_ctxs = NULL, *ctx;
40
41
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
42
- aio_context_acquire(bdrv_get_aio_context(bs));
43
+ AioContext *aio_context = bdrv_get_aio_context(bs);
44
+
45
+ if (!g_slist_find(aio_ctxs, aio_context)) {
46
+ aio_ctxs = g_slist_prepend(aio_ctxs, aio_context);
47
+ aio_context_acquire(aio_context);
48
+ }
49
}
50
51
/* We do two passes of inactivation. The first pass calls to drivers'
52
@@ -XXX,XX +XXX,XX @@ int bdrv_inactivate_all(void)
53
}
54
55
out:
56
- for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
57
- aio_context_release(bdrv_get_aio_context(bs));
58
+ for (ctx = aio_ctxs; ctx != NULL; ctx = ctx->next) {
59
+ AioContext *aio_context = ctx->data;
60
+ aio_context_release(aio_context);
61
}
62
+ g_slist_free(aio_ctxs);
63
17
return ret;
64
return ret;
18
}
65
}
19
20
-int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp)
21
+/**
22
+ * Helper function for bdrv_create_file_fallback(): Resize @blk to at
23
+ * least the given @minimum_size.
24
+ *
25
+ * On success, return @blk's actual length.
26
+ * Otherwise, return -errno.
27
+ */
28
+static int64_t create_file_fallback_truncate(BlockBackend *blk,
29
+ int64_t minimum_size, Error **errp)
30
{
31
- BlockDriver *drv;
32
+ Error *local_err = NULL;
33
+ int64_t size;
34
+ int ret;
35
+
36
+ ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, &local_err);
37
+ if (ret < 0 && ret != -ENOTSUP) {
38
+ error_propagate(errp, local_err);
39
+ return ret;
40
+ }
41
+
42
+ size = blk_getlength(blk);
43
+ if (size < 0) {
44
+ error_free(local_err);
45
+ error_setg_errno(errp, -size,
46
+ "Failed to inquire the new image file's length");
47
+ return size;
48
+ }
49
+
50
+ if (size < minimum_size) {
51
+ /* Need to grow the image, but we failed to do that */
52
+ error_propagate(errp, local_err);
53
+ return -ENOTSUP;
54
+ }
55
+
56
+ error_free(local_err);
57
+ local_err = NULL;
58
+
59
+ return size;
60
+}
61
+
62
+/**
63
+ * Helper function for bdrv_create_file_fallback(): Zero the first
64
+ * sector to remove any potentially pre-existing image header.
65
+ */
66
+static int create_file_fallback_zero_first_sector(BlockBackend *blk,
67
+ int64_t current_size,
68
+ Error **errp)
69
+{
70
+ int64_t bytes_to_clear;
71
+ int ret;
72
+
73
+ bytes_to_clear = MIN(current_size, BDRV_SECTOR_SIZE);
74
+ if (bytes_to_clear) {
75
+ ret = blk_pwrite_zeroes(blk, 0, bytes_to_clear, BDRV_REQ_MAY_UNMAP);
76
+ if (ret < 0) {
77
+ error_setg_errno(errp, -ret,
78
+ "Failed to clear the new image's first sector");
79
+ return ret;
80
+ }
81
+ }
82
+
83
+ return 0;
84
+}
85
+
86
+static int bdrv_create_file_fallback(const char *filename, BlockDriver *drv,
87
+ QemuOpts *opts, Error **errp)
88
+{
89
+ BlockBackend *blk;
90
+ QDict *options = qdict_new();
91
+ int64_t size = 0;
92
+ char *buf = NULL;
93
+ PreallocMode prealloc;
94
Error *local_err = NULL;
95
int ret;
96
97
+ size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
98
+ buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
99
+ prealloc = qapi_enum_parse(&PreallocMode_lookup, buf,
100
+ PREALLOC_MODE_OFF, &local_err);
101
+ g_free(buf);
102
+ if (local_err) {
103
+ error_propagate(errp, local_err);
104
+ return -EINVAL;
105
+ }
106
+
107
+ if (prealloc != PREALLOC_MODE_OFF) {
108
+ error_setg(errp, "Unsupported preallocation mode '%s'",
109
+ PreallocMode_str(prealloc));
110
+ return -ENOTSUP;
111
+ }
112
+
113
+ qdict_put_str(options, "driver", drv->format_name);
114
+
115
+ blk = blk_new_open(filename, NULL, options,
116
+ BDRV_O_RDWR | BDRV_O_RESIZE, errp);
117
+ if (!blk) {
118
+ error_prepend(errp, "Protocol driver '%s' does not support image "
119
+ "creation, and opening the image failed: ",
120
+ drv->format_name);
121
+ return -EINVAL;
122
+ }
123
+
124
+ size = create_file_fallback_truncate(blk, size, errp);
125
+ if (size < 0) {
126
+ ret = size;
127
+ goto out;
128
+ }
129
+
130
+ ret = create_file_fallback_zero_first_sector(blk, size, errp);
131
+ if (ret < 0) {
132
+ goto out;
133
+ }
134
+
135
+ ret = 0;
136
+out:
137
+ blk_unref(blk);
138
+ return ret;
139
+}
140
+
141
+int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp)
142
+{
143
+ BlockDriver *drv;
144
+
145
drv = bdrv_find_protocol(filename, true, errp);
146
if (drv == NULL) {
147
return -ENOENT;
148
}
149
150
- ret = bdrv_create(drv, filename, opts, &local_err);
151
- error_propagate(errp, local_err);
152
- return ret;
153
+ if (drv->bdrv_co_create_opts) {
154
+ return bdrv_create(drv, filename, opts, errp);
155
+ } else {
156
+ return bdrv_create_file_fallback(filename, drv, opts, errp);
157
+ }
158
}
159
160
/**
161
@@ -XXX,XX +XXX,XX @@ QemuOptsList bdrv_runtime_opts = {
162
},
163
};
164
165
+static QemuOptsList fallback_create_opts = {
166
+ .name = "fallback-create-opts",
167
+ .head = QTAILQ_HEAD_INITIALIZER(fallback_create_opts.head),
168
+ .desc = {
169
+ {
170
+ .name = BLOCK_OPT_SIZE,
171
+ .type = QEMU_OPT_SIZE,
172
+ .help = "Virtual disk size"
173
+ },
174
+ {
175
+ .name = BLOCK_OPT_PREALLOC,
176
+ .type = QEMU_OPT_STRING,
177
+ .help = "Preallocation mode (allowed values: off)"
178
+ },
179
+ { /* end of list */ }
180
+ }
181
+};
182
+
183
/*
184
* Common part for opening disk images and files
185
*
186
@@ -XXX,XX +XXX,XX @@ void bdrv_img_create(const char *filename, const char *fmt,
187
return;
188
}
189
190
- if (!proto_drv->create_opts) {
191
- error_setg(errp, "Protocol driver '%s' does not support image creation",
192
- proto_drv->format_name);
193
- return;
194
- }
195
-
196
/* Create parameter list */
197
create_opts = qemu_opts_append(create_opts, drv->create_opts);
198
- create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
199
+ if (proto_drv->create_opts) {
200
+ create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
201
+ } else {
202
+ create_opts = qemu_opts_append(create_opts, &fallback_create_opts);
203
+ }
204
205
opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
206
207
--
66
--
208
2.24.1
67
2.14.3
209
68
210
69
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
See the patch for why nested AioContext locking is no longer allowed.
2
2
3
The patch adds a new additional field to the qcow2 header: compression_type,
3
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
4
which specifies compression type. If field is absent or zero, default
4
Reviewed-by: Eric Blake <eblake@redhat.com>
5
compression type is set: ZLIB, which corresponds to current behavior.
5
Message-id: 20171207201320.19284-3-stefanha@redhat.com
6
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
---
8
docs/devel/multiple-iothreads.txt | 7 ++++---
9
1 file changed, 4 insertions(+), 3 deletions(-)
6
10
7
New compression type (ZSTD) is to be added in further commit.
11
diff --git a/docs/devel/multiple-iothreads.txt b/docs/devel/multiple-iothreads.txt
8
9
Suggested-by: Denis Plotnikov <dplotnikov@virtuozzo.com>
10
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Message-Id: <20200131142219.3264-3-vsementsov@virtuozzo.com>
12
[mreitz: s/Bits 3-63: Reserved/Bits 4-63: Reserved/]
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
15
docs/interop/qcow2.txt | 21 +++++++++++++++++++--
16
1 file changed, 19 insertions(+), 2 deletions(-)
17
18
diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
19
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
20
--- a/docs/interop/qcow2.txt
13
--- a/docs/devel/multiple-iothreads.txt
21
+++ b/docs/interop/qcow2.txt
14
+++ b/docs/devel/multiple-iothreads.txt
22
@@ -XXX,XX +XXX,XX @@ the next fields through header_length.
15
@@ -XXX,XX +XXX,XX @@
23
An External Data File Name header extension may
16
-Copyright (c) 2014 Red Hat Inc.
24
be present if this bit is set.
17
+Copyright (c) 2014-2017 Red Hat Inc.
25
18
26
- Bits 3-63: Reserved (set to 0)
19
This work is licensed under the terms of the GNU GPL, version 2 or later. See
27
+ Bit 3: Compression type bit. If this bit is set,
20
the COPYING file in the top-level directory.
28
+ a non-default compression is used for compressed
21
@@ -XXX,XX +XXX,XX @@ aio_context_acquire()/aio_context_release() for mutual exclusion. Once the
29
+ clusters. The compression_type field must be
22
context is acquired no other thread can access it or run event loop iterations
30
+ present and not zero.
23
in this AioContext.
31
+
24
32
+ Bits 4-63: Reserved (set to 0)
25
-aio_context_acquire()/aio_context_release() calls may be nested. This
33
26
-means you can call them if you're not sure whether #2 applies.
34
80 - 87: compatible_features
27
+Legacy code sometimes nests aio_context_acquire()/aio_context_release() calls.
35
Bitmask of compatible features. An implementation can
28
+Do not use nesting anymore, it is incompatible with the BDRV_POLL_WHILE() macro
36
@@ -XXX,XX +XXX,XX @@ present*, if not altered by a specific incompatible bit.
29
+used in the block layer and can lead to hangs.
37
to the field's offset. Also, all additional fields are not present for
30
38
version 2.
31
There is currently no lock ordering rule if a thread needs to acquire multiple
39
32
AioContexts simultaneously. Therefore, it is only safe for code holding the
40
- < ... No additional fields in the header currently ... >
41
+ 104: compression_type
42
+
43
+ Defines the compression method used for compressed clusters.
44
+ All compressed clusters in an image use the same compression
45
+ type.
46
+
47
+ If the incompatible bit "Compression type" is set: the field
48
+ must be present and non-zero (which means non-zlib
49
+ compression type). Otherwise, this field must not be present
50
+ or must be zero (which means zlib).
51
+
52
+ Available compression type values:
53
+ 0: zlib <https://www.zlib.net/>
54
55
56
=== Header padding ===
57
--
33
--
58
2.24.1
34
2.14.3
59
35
60
36
diff view generated by jsdifflib
1
From: Peter Krempa <pkrempa@redhat.com>
1
When a node is already associated with a BlockBackend the
2
x-blockdev-set-iothread command refuses to set the IOThread. This is to
3
prevent accidentally changing the IOThread when the nodes are in use.
2
4
3
When a management application manages node names there's no reason to
5
When the nodes are created with -drive they automatically get a
4
recurse into backing images in the output of query-named-block-nodes.
6
BlockBackend. In that case we know nothing is using them yet and it's
7
safe to set the IOThread. Add a force boolean to override the check.
5
8
6
Add a parameter to the command which will return just the top level
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
structs.
10
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Message-id: 20171207201320.19284-4-stefanha@redhat.com
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
14
qapi/block-core.json | 6 +++++-
15
blockdev.c | 11 ++++++-----
16
2 files changed, 11 insertions(+), 6 deletions(-)
8
17
9
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
10
Message-Id: <4470f8c779abc404dcf65e375db195cd91a80651.1579509782.git.pkrempa@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
12
[mreitz: Fixed coding style]
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
15
block.c | 5 +++--
16
block/qapi.c | 11 +++++++++--
17
blockdev.c | 8 ++++++--
18
include/block/block.h | 2 +-
19
include/block/qapi.h | 4 +++-
20
monitor/hmp-cmds.c | 2 +-
21
qapi/block-core.json | 7 ++++++-
22
7 files changed, 29 insertions(+), 10 deletions(-)
23
24
diff --git a/block.c b/block.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/block.c
27
+++ b/block.c
28
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_find_node(const char *node_name)
29
}
30
31
/* Put this QMP function here so it can access the static graph_bdrv_states. */
32
-BlockDeviceInfoList *bdrv_named_nodes_list(Error **errp)
33
+BlockDeviceInfoList *bdrv_named_nodes_list(bool flat,
34
+ Error **errp)
35
{
36
BlockDeviceInfoList *list, *entry;
37
BlockDriverState *bs;
38
39
list = NULL;
40
QTAILQ_FOREACH(bs, &graph_bdrv_states, node_list) {
41
- BlockDeviceInfo *info = bdrv_block_device_info(NULL, bs, errp);
42
+ BlockDeviceInfo *info = bdrv_block_device_info(NULL, bs, flat, errp);
43
if (!info) {
44
qapi_free_BlockDeviceInfoList(list);
45
return NULL;
46
diff --git a/block/qapi.c b/block/qapi.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/block/qapi.c
49
+++ b/block/qapi.c
50
@@ -XXX,XX +XXX,XX @@
51
#include "qemu/cutils.h"
52
53
BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
54
- BlockDriverState *bs, Error **errp)
55
+ BlockDriverState *bs,
56
+ bool flat,
57
+ Error **errp)
58
{
59
ImageInfo **p_image_info;
60
BlockDriverState *bs0;
61
@@ -XXX,XX +XXX,XX @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
62
return NULL;
63
}
64
65
+ /* stop gathering data for flat output */
66
+ if (flat) {
67
+ break;
68
+ }
69
+
70
if (bs0->drv && bs0->backing) {
71
info->backing_file_depth++;
72
bs0 = bs0->backing->bs;
73
@@ -XXX,XX +XXX,XX @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
74
75
if (bs && bs->drv) {
76
info->has_inserted = true;
77
- info->inserted = bdrv_block_device_info(blk, bs, errp);
78
+ info->inserted = bdrv_block_device_info(blk, bs, false, errp);
79
if (info->inserted == NULL) {
80
goto err;
81
}
82
diff --git a/blockdev.c b/blockdev.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/blockdev.c
85
+++ b/blockdev.c
86
@@ -XXX,XX +XXX,XX @@ void qmp_drive_backup(DriveBackup *backup, Error **errp)
87
blockdev_do_action(&action, errp);
88
}
89
90
-BlockDeviceInfoList *qmp_query_named_block_nodes(Error **errp)
91
+BlockDeviceInfoList *qmp_query_named_block_nodes(bool has_flat,
92
+ bool flat,
93
+ Error **errp)
94
{
95
- return bdrv_named_nodes_list(errp);
96
+ bool return_flat = has_flat && flat;
97
+
98
+ return bdrv_named_nodes_list(return_flat, errp);
99
}
100
101
XDbgBlockGraph *qmp_x_debug_query_block_graph(Error **errp)
102
diff --git a/include/block/block.h b/include/block/block.h
103
index XXXXXXX..XXXXXXX 100644
104
--- a/include/block/block.h
105
+++ b/include/block/block.h
106
@@ -XXX,XX +XXX,XX @@ void bdrv_lock_medium(BlockDriverState *bs, bool locked);
107
void bdrv_eject(BlockDriverState *bs, bool eject_flag);
108
const char *bdrv_get_format_name(BlockDriverState *bs);
109
BlockDriverState *bdrv_find_node(const char *node_name);
110
-BlockDeviceInfoList *bdrv_named_nodes_list(Error **errp);
111
+BlockDeviceInfoList *bdrv_named_nodes_list(bool flat, Error **errp);
112
XDbgBlockGraph *bdrv_get_xdbg_block_graph(Error **errp);
113
BlockDriverState *bdrv_lookup_bs(const char *device,
114
const char *node_name,
115
diff --git a/include/block/qapi.h b/include/block/qapi.h
116
index XXXXXXX..XXXXXXX 100644
117
--- a/include/block/qapi.h
118
+++ b/include/block/qapi.h
119
@@ -XXX,XX +XXX,XX @@
120
#include "block/snapshot.h"
121
122
BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
123
- BlockDriverState *bs, Error **errp);
124
+ BlockDriverState *bs,
125
+ bool flat,
126
+ Error **errp);
127
int bdrv_query_snapshot_info_list(BlockDriverState *bs,
128
SnapshotInfoList **p_list,
129
Error **errp);
130
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
131
index XXXXXXX..XXXXXXX 100644
132
--- a/monitor/hmp-cmds.c
133
+++ b/monitor/hmp-cmds.c
134
@@ -XXX,XX +XXX,XX @@ void hmp_info_block(Monitor *mon, const QDict *qdict)
135
}
136
137
/* Print node information */
138
- blockdev_list = qmp_query_named_block_nodes(NULL);
139
+ blockdev_list = qmp_query_named_block_nodes(false, false, NULL);
140
for (blockdev = blockdev_list; blockdev; blockdev = blockdev->next) {
141
assert(blockdev->value->has_node_name);
142
if (device && strcmp(device, blockdev->value->node_name)) {
143
diff --git a/qapi/block-core.json b/qapi/block-core.json
18
diff --git a/qapi/block-core.json b/qapi/block-core.json
144
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
145
--- a/qapi/block-core.json
20
--- a/qapi/block-core.json
146
+++ b/qapi/block-core.json
21
+++ b/qapi/block-core.json
147
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@
148
#
23
#
149
# Get the named block driver list
24
# @iothread: the name of the IOThread object or null for the main loop
150
#
25
#
151
+# @flat: Omit the nested data about backing image ("backing-image" key) if true.
26
+# @force: true if the node and its children should be moved when a BlockBackend
152
+# Default is false (Since 5.0)
27
+# is already attached
153
+#
28
+#
154
# Returns: the list of BlockDeviceInfo
29
# Note: this command is experimental and intended for test cases that need
30
# control over IOThreads only.
155
#
31
#
156
# Since: 2.0
157
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@
158
# } } ] }
159
#
160
##
33
##
161
-{ 'command': 'query-named-block-nodes', 'returns': [ 'BlockDeviceInfo' ] }
34
{ 'command': 'x-blockdev-set-iothread',
162
+{ 'command': 'query-named-block-nodes',
35
'data' : { 'node-name': 'str',
163
+ 'returns': [ 'BlockDeviceInfo' ],
36
- 'iothread': 'StrOrNull' } }
164
+ 'data': { '*flat': 'bool' } }
37
+ 'iothread': 'StrOrNull',
165
38
+ '*force': 'bool' } }
166
##
39
diff --git a/blockdev.c b/blockdev.c
167
# @XDbgBlockGraphNodeType:
40
index XXXXXXX..XXXXXXX 100644
41
--- a/blockdev.c
42
+++ b/blockdev.c
43
@@ -XXX,XX +XXX,XX @@ BlockJobInfoList *qmp_query_block_jobs(Error **errp)
44
}
45
46
void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread,
47
- Error **errp)
48
+ bool has_force, bool force, Error **errp)
49
{
50
AioContext *old_context;
51
AioContext *new_context;
52
@@ -XXX,XX +XXX,XX @@ void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread,
53
return;
54
}
55
56
- /* If we want to allow more extreme test scenarios this guard could be
57
- * removed. For now it protects against accidents. */
58
- if (bdrv_has_blk(bs)) {
59
- error_setg(errp, "Node %s is in use", node_name);
60
+ /* Protects against accidents. */
61
+ if (!(has_force && force) && bdrv_has_blk(bs)) {
62
+ error_setg(errp, "Node %s is associated with a BlockBackend and could "
63
+ "be in use (use force=true to override this check)",
64
+ node_name);
65
return;
66
}
67
168
--
68
--
169
2.24.1
69
2.14.3
170
70
171
71
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
The VM.add_object() method can be used to add IOThreads or memory
2
backend objects.
2
3
3
Make it more obvious how to add new fields to the version 3 header and
4
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
4
how to interpret them.
5
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Message-id: 20171207201320.19284-5-stefanha@redhat.com
7
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
---
9
tests/qemu-iotests/iotests.py | 5 +++++
10
1 file changed, 5 insertions(+)
5
11
6
The specification is adjusted so that for new defined optional fields:
12
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
7
8
1. Software may support some of these optional fields and ignore the
9
others, which means that features may be backported to downstream
10
Qemu independently.
11
2. If we want to add incompatible field (or a field, for which some of
12
its values would be incompatible), it must be accompanied by
13
incompatible feature bit.
14
15
Also the concept of "default is zero" is clarified, as it's strange to
16
say that the value of the field is assumed to be zero for the software
17
version which don't know about the field at all and don't know how to
18
treat it be it zero or not.
19
20
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
21
Reviewed-by: Eric Blake <eblake@redhat.com>
22
Message-Id: <20200131142219.3264-2-vsementsov@virtuozzo.com>
23
Reviewed-by: Alberto Garcia <berto@igalia.com>
24
[mreitz: s/some its/some of its/]
25
Signed-off-by: Max Reitz <mreitz@redhat.com>
26
---
27
docs/interop/qcow2.txt | 45 +++++++++++++++++++++++++++++++++++++++---
28
1 file changed, 42 insertions(+), 3 deletions(-)
29
30
diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
31
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
32
--- a/docs/interop/qcow2.txt
14
--- a/tests/qemu-iotests/iotests.py
33
+++ b/docs/interop/qcow2.txt
15
+++ b/tests/qemu-iotests/iotests.py
34
@@ -XXX,XX +XXX,XX @@ The first cluster of a qcow2 image contains the file header:
16
@@ -XXX,XX +XXX,XX @@ class VM(qtest.QEMUQtestMachine):
35
Offset into the image file at which the snapshot table
17
socket_scm_helper=socket_scm_helper)
36
starts. Must be aligned to a cluster boundary.
18
self._num_drives = 0
37
19
38
-If the version is 3 or higher, the header has the following additional fields.
20
+ def add_object(self, opts):
39
-For version 2, the values are assumed to be zero, unless specified otherwise
21
+ self._args.append('-object')
40
-in the description of a field.
22
+ self._args.append(opts)
41
+For version 2, the header is exactly 72 bytes in length, and finishes here.
23
+ return self
42
+For version 3 or higher, the header length is at least 104 bytes, including
43
+the next fields through header_length.
44
45
72 - 79: incompatible_features
46
Bitmask of incompatible features. An implementation must
47
@@ -XXX,XX +XXX,XX @@ in the description of a field.
48
100 - 103: header_length
49
Length of the header structure in bytes. For version 2
50
images, the length is always assumed to be 72 bytes.
51
+ For version 3 it's at least 104 bytes and must be a multiple
52
+ of 8.
53
+
24
+
54
+
25
def add_device(self, opts):
55
+=== Additional fields (version 3 and higher) ===
26
self._args.append('-device')
56
+
27
self._args.append(opts)
57
+In general, these fields are optional and may be safely ignored by the software,
58
+as well as filled by zeros (which is equal to field absence), if software needs
59
+to set field B, but does not care about field A which precedes B. More
60
+formally, additional fields have the following compatibility rules:
61
+
62
+1. If the value of the additional field must not be ignored for correct
63
+handling of the file, it will be accompanied by a corresponding incompatible
64
+feature bit.
65
+
66
+2. If there are no unrecognized incompatible feature bits set, an unknown
67
+additional field may be safely ignored other than preserving its value when
68
+rewriting the image header.
69
+
70
+3. An explicit value of 0 will have the same behavior as when the field is not
71
+present*, if not altered by a specific incompatible bit.
72
+
73
+*. A field is considered not present when header_length is less than or equal
74
+to the field's offset. Also, all additional fields are not present for
75
+version 2.
76
+
77
+ < ... No additional fields in the header currently ... >
78
+
79
+
80
+=== Header padding ===
81
+
82
+@header_length must be a multiple of 8, which means that if the end of the last
83
+additional field is not aligned, some padding is needed. This padding must be
84
+zeroed, so that if some existing (or future) additional field will fall into
85
+the padding, it will be interpreted accordingly to point [3.] of the previous
86
+paragraph, i.e. in the same manner as when this field is not present.
87
+
88
+
89
+=== Header extensions ===
90
91
Directly after the image header, optional sections called header extensions can
92
be stored. Each extension has a structure like the following:
93
--
28
--
94
2.24.1
29
2.14.3
95
30
96
31
diff view generated by jsdifflib
1
From: Daniel P. Berrangé <berrange@redhat.com>
1
There is a small chance that iothread_stop() hangs as follows:
2
2
3
When initializing the LUKS header the size with default encryption
3
Thread 3 (Thread 0x7f63eba5f700 (LWP 16105)):
4
parameters will currently be 2068480 bytes. This is rounded up to
4
#0 0x00007f64012c09b6 in ppoll () at /lib64/libc.so.6
5
a multiple of the cluster size, 2081792, with 64k sectors. If the
5
#1 0x000055959992eac9 in ppoll (__ss=0x0, __timeout=0x0, __nfds=<optimized out>, __fds=<optimized out>) at /usr/include/bits/poll2.h:77
6
end of the header is not the same as the end of the cluster we fill
6
#2 0x000055959992eac9 in qemu_poll_ns (fds=<optimized out>, nfds=<optimized out>, timeout=<optimized out>) at util/qemu-timer.c:322
7
the extra space with zeros. This was forgetting that not even the
7
#3 0x0000559599930711 in aio_poll (ctx=0x55959bdb83c0, blocking=blocking@entry=true) at util/aio-posix.c:629
8
space allocated for the header will be fully initialized, as we
8
#4 0x00005595996806fe in iothread_run (opaque=0x55959bd78400) at iothread.c:59
9
only write key material for the first key slot. The space left
9
#5 0x00007f640159f609 in start_thread () at /lib64/libpthread.so.0
10
for the other 7 slots is never written to.
10
#6 0x00007f64012cce6f in clone () at /lib64/libc.so.6
11
11
12
An optimization to the ref count checking code:
12
Thread 1 (Thread 0x7f640b45b280 (LWP 16103)):
13
#0 0x00007f64015a0b6d in pthread_join () at /lib64/libpthread.so.0
14
#1 0x00005595999332ef in qemu_thread_join (thread=<optimized out>) at util/qemu-thread-posix.c:547
15
#2 0x00005595996808ae in iothread_stop (iothread=<optimized out>) at iothread.c:91
16
#3 0x000055959968094d in iothread_stop_iter (object=<optimized out>, opaque=<optimized out>) at iothread.c:102
17
#4 0x0000559599857d97 in do_object_child_foreach (obj=obj@entry=0x55959bdb8100, fn=fn@entry=0x559599680930 <iothread_stop_iter>, opaque=opaque@entry=0x0, recurse=recurse@entry=false) at qom/object.c:852
18
#5 0x0000559599859477 in object_child_foreach (obj=obj@entry=0x55959bdb8100, fn=fn@entry=0x559599680930 <iothread_stop_iter>, opaque=opaque@entry=0x0) at qom/object.c:867
19
#6 0x0000559599680a6e in iothread_stop_all () at iothread.c:341
20
#7 0x000055959955b1d5 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at vl.c:4913
13
21
14
commit a5fff8d4b4d928311a5005efa12d0991fe3b66f9 (refs/bisect/bad)
22
The relevant code from iothread_run() is:
15
Author: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
16
Date: Wed Feb 27 16:14:30 2019 +0300
17
23
18
qcow2-refcount: avoid eating RAM
24
while (!atomic_read(&iothread->stopping)) {
25
aio_poll(iothread->ctx, true);
19
26
20
made the assumption that every cluster which was allocated would
27
and iothread_stop():
21
have at least some data written to it. This was violated by way
22
the LUKS header is only partially written, with much space simply
23
reserved for future use.
24
28
25
Depending on the cluster size this problem was masked by the
29
iothread->stopping = true;
26
logic which wrote zeros between the end of the LUKS header and
30
aio_notify(iothread->ctx);
27
the end of the cluster.
31
...
32
qemu_thread_join(&iothread->thread);
28
33
29
$ qemu-img create --object secret,id=cluster_encrypt0,data=123456 \
34
The following scenario can occur:
30
-f qcow2 -o cluster_size=2k,encrypt.iter-time=1,\
31
encrypt.format=luks,encrypt.key-secret=cluster_encrypt0 \
32
cluster_size_check.qcow2 100M
33
Formatting 'cluster_size_check.qcow2', fmt=qcow2 size=104857600
34
encrypt.format=luks encrypt.key-secret=cluster_encrypt0
35
encrypt.iter-time=1 cluster_size=2048 lazy_refcounts=off refcount_bits=16
36
35
37
$ qemu-img check --object secret,id=cluster_encrypt0,data=redhat \
36
1. IOThread:
38
'json:{"driver": "qcow2", "encrypt.format": "luks", \
37
while (!atomic_read(&iothread->stopping)) -> stopping=false
39
"encrypt.key-secret": "cluster_encrypt0", \
40
"file.driver": "file", "file.filename": "cluster_size_check.qcow2"}'
41
ERROR: counting reference for region exceeding the end of the file by one cluster or more: offset 0x2000 size 0x1f9000
42
Leaked cluster 4 refcount=1 reference=0
43
...snip...
44
Leaked cluster 130 refcount=1 reference=0
45
38
46
1 errors were found on the image.
39
2. Main loop:
47
Data may be corrupted, or further writes to the image may corrupt it.
40
iothread->stopping = true;
41
aio_notify(iothread->ctx);
48
42
49
127 leaked clusters were found on the image.
43
3. IOThread:
50
This means waste of disk space, but no harm to data.
44
aio_poll(iothread->ctx, true); -> hang
51
Image end offset: 268288
52
45
53
The problem only exists when the disk image is entirely empty. Writing
46
The bug is explained by the AioContext->notify_me doc comments:
54
data to the disk image payload will solve the problem by causing the
55
end of the file to be extended further.
56
47
57
The change fixes it by ensuring that the entire allocated LUKS header
48
"If this field is 0, everything (file descriptors, bottom halves,
58
region is fully initialized with zeros. The qemu-img check will still
49
timers) will be re-evaluated before the next blocking poll(), thus the
59
fail for any pre-existing disk images created prior to this change,
50
event_notifier_set call can be skipped."
60
unless at least 1 byte of the payload is written to.
61
51
62
Fully writing zeros to the entire LUKS header is a good idea regardless
52
The problem is that "everything" does not include checking
63
as it ensures that space has been allocated on the host filesystem (or
53
iothread->stopping. This means iothread_run() will block in aio_poll()
64
whatever block storage backend is used).
54
if aio_notify() was called just before aio_poll().
65
55
66
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
56
This patch fixes the hang by replacing aio_notify() with
67
Message-Id: <20200207135520.2669430-1-berrange@redhat.com>
57
aio_bh_schedule_oneshot(). This makes aio_poll() or g_main_loop_run()
58
to return.
59
60
Implementing this properly required a new bool running flag. The new
61
flag prevents races that are tricky if we try to use iothread->stopping.
62
Now iothread->stopping is purely for iothread_stop() and
63
iothread->running is purely for the iothread_run() thread.
64
65
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
68
Reviewed-by: Eric Blake <eblake@redhat.com>
66
Reviewed-by: Eric Blake <eblake@redhat.com>
69
Signed-off-by: Max Reitz <mreitz@redhat.com>
67
Message-id: 20171207201320.19284-6-stefanha@redhat.com
68
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
70
---
69
---
71
block/qcow2.c | 11 +++--
70
include/sysemu/iothread.h | 3 ++-
72
tests/qemu-iotests/284 | 97 ++++++++++++++++++++++++++++++++++++++
71
iothread.c | 20 +++++++++++++++-----
73
tests/qemu-iotests/284.out | 62 ++++++++++++++++++++++++
72
2 files changed, 17 insertions(+), 6 deletions(-)
74
tests/qemu-iotests/group | 1 +
75
4 files changed, 167 insertions(+), 4 deletions(-)
76
create mode 100755 tests/qemu-iotests/284
77
create mode 100644 tests/qemu-iotests/284.out
78
73
79
diff --git a/block/qcow2.c b/block/qcow2.c
74
diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h
80
index XXXXXXX..XXXXXXX 100644
75
index XXXXXXX..XXXXXXX 100644
81
--- a/block/qcow2.c
76
--- a/include/sysemu/iothread.h
82
+++ b/block/qcow2.c
77
+++ b/include/sysemu/iothread.h
83
@@ -XXX,XX +XXX,XX @@ static ssize_t qcow2_crypto_hdr_init_func(QCryptoBlock *block, size_t headerlen,
78
@@ -XXX,XX +XXX,XX @@ typedef struct {
84
s->crypto_header.length = headerlen;
79
GOnce once;
85
s->crypto_header.offset = ret;
80
QemuMutex init_done_lock;
86
81
QemuCond init_done_cond; /* is thread initialization done? */
87
- /* Zero fill remaining space in cluster so it has predictable
82
- bool stopping;
88
- * content in case of future spec changes */
83
+ bool stopping; /* has iothread_stop() been called? */
89
+ /*
84
+ bool running; /* should iothread_run() continue? */
90
+ * Zero fill all space in cluster so it has predictable
85
int thread_id;
91
+ * content, as we may not initialize some regions of the
86
92
+ * header (eg only 1 out of 8 key slots will be initialized)
87
/* AioContext poll parameters */
93
+ */
88
diff --git a/iothread.c b/iothread.c
94
clusterlen = size_to_clusters(s, headerlen) * s->cluster_size;
89
index XXXXXXX..XXXXXXX 100644
95
assert(qcow2_pre_write_overlap_check(bs, 0, ret, clusterlen, false) == 0);
90
--- a/iothread.c
96
ret = bdrv_pwrite_zeroes(bs->file,
91
+++ b/iothread.c
97
- ret + headerlen,
92
@@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque)
98
- clusterlen - headerlen, 0);
93
qemu_cond_signal(&iothread->init_done_cond);
99
+ ret,
94
qemu_mutex_unlock(&iothread->init_done_lock);
100
+ clusterlen, 0);
95
101
if (ret < 0) {
96
- while (!atomic_read(&iothread->stopping)) {
102
error_setg_errno(errp, -ret, "Could not zero fill encryption header");
97
+ while (iothread->running) {
103
return -1;
98
aio_poll(iothread->ctx, true);
104
diff --git a/tests/qemu-iotests/284 b/tests/qemu-iotests/284
99
105
new file mode 100755
100
if (atomic_read(&iothread->worker_context)) {
106
index XXXXXXX..XXXXXXX
101
@@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque)
107
--- /dev/null
102
return NULL;
108
+++ b/tests/qemu-iotests/284
103
}
109
@@ -XXX,XX +XXX,XX @@
104
110
+#!/usr/bin/env bash
105
+/* Runs in iothread_run() thread */
111
+#
106
+static void iothread_stop_bh(void *opaque)
112
+# Test ref count checks on encrypted images
107
+{
113
+#
108
+ IOThread *iothread = opaque;
114
+# Copyright (C) 2019 Red Hat, Inc.
115
+#
116
+# This program is free software; you can redistribute it and/or modify
117
+# it under the terms of the GNU General Public License as published by
118
+# the Free Software Foundation; either version 2 of the License, or
119
+# (at your option) any later version.
120
+#
121
+# This program is distributed in the hope that it will be useful,
122
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
123
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
124
+# GNU General Public License for more details.
125
+#
126
+# You should have received a copy of the GNU General Public License
127
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
128
+#
129
+
109
+
130
+# creator
110
+ iothread->running = false; /* stop iothread_run() */
131
+owner=berrange@redhat.com
132
+
111
+
133
+seq=`basename $0`
112
+ if (iothread->main_loop) {
134
+echo "QA output created by $seq"
113
+ g_main_loop_quit(iothread->main_loop);
135
+
114
+ }
136
+status=1 # failure is the default!
137
+
138
+_cleanup()
139
+{
140
+ _cleanup_test_img
141
+}
142
+trap "_cleanup; exit \$status" 0 1 2 3 15
143
+
144
+# get standard environment, filters and checks
145
+. ./common.rc
146
+. ./common.filter
147
+
148
+_supported_fmt qcow2
149
+_supported_proto generic
150
+_supported_os Linux
151
+
152
+
153
+size=1M
154
+
155
+SECRET="secret,id=sec0,data=astrochicken"
156
+
157
+IMGSPEC="driver=$IMGFMT,file.filename=$TEST_IMG,encrypt.key-secret=sec0"
158
+QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
159
+
160
+_run_test()
161
+{
162
+ IMGOPTSSYNTAX=true
163
+ OLD_TEST_IMG="$TEST_IMG"
164
+ TEST_IMG="driver=$IMGFMT,file.filename=$TEST_IMG,encrypt.key-secret=sec0"
165
+ QEMU_IMG_EXTRA_ARGS="--image-opts --object $SECRET"
166
+
167
+ echo
168
+ echo "== cluster size $csize"
169
+ echo "== checking image refcounts =="
170
+ _check_test_img
171
+
172
+ echo
173
+ echo "== writing some data =="
174
+ $QEMU_IO -c "write -P 0x9 0 1" $QEMU_IMG_EXTRA_ARGS $TEST_IMG | _filter_qemu_io | _filter_testdir
175
+ echo
176
+ echo "== rechecking image refcounts =="
177
+ _check_test_img
178
+
179
+ echo
180
+ echo "== writing some more data =="
181
+ $QEMU_IO -c "write -P 0x9 $csize 1" $QEMU_IMG_EXTRA_ARGS $TEST_IMG | _filter_qemu_io | _filter_testdir
182
+ echo
183
+ echo "== rechecking image refcounts =="
184
+ _check_test_img
185
+
186
+ TEST_IMG="$OLD_TEST_IMG"
187
+ QEMU_IMG_EXTRA_ARGS=
188
+ IMGOPTSSYNTAX=
189
+}
115
+}
190
+
116
+
191
+
117
void iothread_stop(IOThread *iothread)
192
+echo
118
{
193
+echo "testing LUKS qcow2 encryption"
119
if (!iothread->ctx || iothread->stopping) {
194
+echo
120
return;
195
+
121
}
196
+for csize in 512 2048 32768
122
iothread->stopping = true;
197
+do
123
- aio_notify(iothread->ctx);
198
+ _make_test_img --object $SECRET -o "encrypt.format=luks,encrypt.key-secret=sec0,encrypt.iter-time=10,cluster_size=$csize" $size
124
- if (atomic_read(&iothread->main_loop)) {
199
+ _run_test
125
- g_main_loop_quit(iothread->main_loop);
200
+ _cleanup_test_img
126
- }
201
+done
127
+ aio_bh_schedule_oneshot(iothread->ctx, iothread_stop_bh, iothread);
202
+
128
qemu_thread_join(&iothread->thread);
203
+# success, all done
129
}
204
+echo "*** done"
130
205
+rm -f $seq.full
131
@@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp)
206
+status=0
132
char *name, *thread_name;
207
diff --git a/tests/qemu-iotests/284.out b/tests/qemu-iotests/284.out
133
208
new file mode 100644
134
iothread->stopping = false;
209
index XXXXXXX..XXXXXXX
135
+ iothread->running = true;
210
--- /dev/null
136
iothread->thread_id = -1;
211
+++ b/tests/qemu-iotests/284.out
137
iothread->ctx = aio_context_new(&local_error);
212
@@ -XXX,XX +XXX,XX @@
138
if (!iothread->ctx) {
213
+QA output created by 284
214
+
215
+testing LUKS qcow2 encryption
216
+
217
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
218
+
219
+== cluster size 512
220
+== checking image refcounts ==
221
+No errors were found on the image.
222
+
223
+== writing some data ==
224
+wrote 1/1 bytes at offset 0
225
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
226
+
227
+== rechecking image refcounts ==
228
+No errors were found on the image.
229
+
230
+== writing some more data ==
231
+wrote 1/1 bytes at offset 512
232
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
233
+
234
+== rechecking image refcounts ==
235
+No errors were found on the image.
236
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
237
+
238
+== cluster size 2048
239
+== checking image refcounts ==
240
+No errors were found on the image.
241
+
242
+== writing some data ==
243
+wrote 1/1 bytes at offset 0
244
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
245
+
246
+== rechecking image refcounts ==
247
+No errors were found on the image.
248
+
249
+== writing some more data ==
250
+wrote 1/1 bytes at offset 2048
251
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
252
+
253
+== rechecking image refcounts ==
254
+No errors were found on the image.
255
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
256
+
257
+== cluster size 32768
258
+== checking image refcounts ==
259
+No errors were found on the image.
260
+
261
+== writing some data ==
262
+wrote 1/1 bytes at offset 0
263
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
264
+
265
+== rechecking image refcounts ==
266
+No errors were found on the image.
267
+
268
+== writing some more data ==
269
+wrote 1/1 bytes at offset 32768
270
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
271
+
272
+== rechecking image refcounts ==
273
+No errors were found on the image.
274
+*** done
275
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
276
index XXXXXXX..XXXXXXX 100644
277
--- a/tests/qemu-iotests/group
278
+++ b/tests/qemu-iotests/group
279
@@ -XXX,XX +XXX,XX @@
280
280 rw migration quick
281
281 rw quick
282
283 auto quick
283
+284 rw
284
--
139
--
285
2.24.1
140
2.14.3
286
141
287
142
diff view generated by jsdifflib
1
Signed-off-by: Max Reitz <mreitz@redhat.com>
1
This test case will prevent future regressions with savevm and
2
Message-Id: <20200122164532.178040-6-mreitz@redhat.com>
2
IOThreads.
3
4
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
3
Reviewed-by: Eric Blake <eblake@redhat.com>
5
Reviewed-by: Eric Blake <eblake@redhat.com>
4
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
6
Message-id: 20171207201320.19284-7-stefanha@redhat.com
5
[mreitz: Added a note that NBD does not support resizing, which is why
7
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
6
the second case is expected to fail]
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
---
8
---
9
tests/qemu-iotests/259 | 62 ++++++++++++++++++++++++++++++++++++++
9
tests/qemu-iotests/203 | 59 ++++++++++++++++++++++++++++++++++++++++++++++
10
tests/qemu-iotests/259.out | 14 +++++++++
10
tests/qemu-iotests/203.out | 6 +++++
11
tests/qemu-iotests/group | 1 +
11
tests/qemu-iotests/group | 1 +
12
3 files changed, 77 insertions(+)
12
3 files changed, 66 insertions(+)
13
create mode 100755 tests/qemu-iotests/259
13
create mode 100755 tests/qemu-iotests/203
14
create mode 100644 tests/qemu-iotests/259.out
14
create mode 100644 tests/qemu-iotests/203.out
15
15
16
diff --git a/tests/qemu-iotests/259 b/tests/qemu-iotests/259
16
diff --git a/tests/qemu-iotests/203 b/tests/qemu-iotests/203
17
new file mode 100755
17
new file mode 100755
18
index XXXXXXX..XXXXXXX
18
index XXXXXXX..XXXXXXX
19
--- /dev/null
19
--- /dev/null
20
+++ b/tests/qemu-iotests/259
20
+++ b/tests/qemu-iotests/203
21
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
22
+#!/usr/bin/env bash
22
+#!/usr/bin/env python
23
+#
23
+#
24
+# Test generic image creation fallback (by using NBD)
24
+# Copyright (C) 2017 Red Hat, Inc.
25
+#
26
+# Copyright (C) 2019 Red Hat, Inc.
27
+#
25
+#
28
+# This program is free software; you can redistribute it and/or modify
26
+# This program is free software; you can redistribute it and/or modify
29
+# it under the terms of the GNU General Public License as published by
27
+# it under the terms of the GNU General Public License as published by
30
+# the Free Software Foundation; either version 2 of the License, or
28
+# the Free Software Foundation; either version 2 of the License, or
31
+# (at your option) any later version.
29
+# (at your option) any later version.
...
...
36
+# GNU General Public License for more details.
34
+# GNU General Public License for more details.
37
+#
35
+#
38
+# You should have received a copy of the GNU General Public License
36
+# You should have received a copy of the GNU General Public License
39
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
37
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
40
+#
38
+#
39
+# Creator/Owner: Stefan Hajnoczi <stefanha@redhat.com>
40
+#
41
+# Check that QMP 'migrate' with multiple drives on a single IOThread completes
42
+# successfully. This particular command triggered a hang in the source QEMU
43
+# process due to recursive AioContext locking in bdrv_invalidate_all() and
44
+# BDRV_POLL_WHILE().
41
+
45
+
42
+# creator
46
+import iotests
43
+owner=mreitz@redhat.com
44
+
47
+
45
+seq=$(basename $0)
48
+iotests.verify_image_format(supported_fmts=['qcow2'])
46
+echo "QA output created by $seq"
49
+iotests.verify_platform(['linux'])
47
+
50
+
48
+status=1    # failure is the default!
51
+with iotests.FilePath('disk0.img') as disk0_img_path, \
52
+ iotests.FilePath('disk1.img') as disk1_img_path, \
53
+ iotests.VM() as vm:
49
+
54
+
50
+_cleanup()
55
+ img_size = '10M'
51
+{
56
+ iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk0_img_path, img_size)
52
+ _cleanup_test_img
57
+ iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk1_img_path, img_size)
53
+}
54
+trap "_cleanup; exit \$status" 0 1 2 3 15
55
+
58
+
56
+# get standard environment, filters and checks
59
+ iotests.log('Launching VM...')
57
+. ./common.rc
60
+ (vm.add_object('iothread,id=iothread0')
58
+. ./common.filter
61
+ .add_drive(disk0_img_path, 'node-name=drive0-node', interface='none')
62
+ .add_drive(disk1_img_path, 'node-name=drive1-node', interface='none')
63
+ .launch())
59
+
64
+
60
+_supported_fmt raw
65
+ iotests.log('Setting IOThreads...')
61
+_supported_proto nbd
66
+ iotests.log(vm.qmp('x-blockdev-set-iothread',
62
+_supported_os Linux
67
+ node_name='drive0-node', iothread='iothread0',
68
+ force=True))
69
+ iotests.log(vm.qmp('x-blockdev-set-iothread',
70
+ node_name='drive1-node', iothread='iothread0',
71
+ force=True))
63
+
72
+
64
+
73
+ iotests.log('Starting migration...')
65
+_make_test_img 64M
74
+ iotests.log(vm.qmp('migrate', uri='exec:cat >/dev/null'))
66
+
75
+ while True:
67
+echo
76
+ vm.get_qmp_event(wait=60.0)
68
+echo '--- Testing creation ---'
77
+ result = vm.qmp('query-migrate')
69
+
78
+ status = result.get('return', {}).get('status', None)
70
+$QEMU_IMG create -f qcow2 "$TEST_IMG" 64M | _filter_img_create
79
+ if status == 'completed':
71
+$QEMU_IMG info "$TEST_IMG" | _filter_img_info
80
+ break
72
+
81
diff --git a/tests/qemu-iotests/203.out b/tests/qemu-iotests/203.out
73
+echo
74
+echo '--- Testing creation for which the node would need to grow ---'
75
+
76
+# NBD does not support resizing, so this will fail
77
+$QEMU_IMG create -f qcow2 -o preallocation=metadata "$TEST_IMG" 64M 2>&1 \
78
+ | _filter_img_create
79
+
80
+# success, all done
81
+echo "*** done"
82
+rm -f $seq.full
83
+status=0
84
diff --git a/tests/qemu-iotests/259.out b/tests/qemu-iotests/259.out
85
new file mode 100644
82
new file mode 100644
86
index XXXXXXX..XXXXXXX
83
index XXXXXXX..XXXXXXX
87
--- /dev/null
84
--- /dev/null
88
+++ b/tests/qemu-iotests/259.out
85
+++ b/tests/qemu-iotests/203.out
89
@@ -XXX,XX +XXX,XX @@
86
@@ -XXX,XX +XXX,XX @@
90
+QA output created by 259
87
+Launching VM...
91
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
88
+Setting IOThreads...
92
+
89
+{u'return': {}}
93
+--- Testing creation ---
90
+{u'return': {}}
94
+Formatting 'TEST_DIR/t.IMGFMT', fmt=qcow2 size=67108864
91
+Starting migration...
95
+image: TEST_DIR/t.IMGFMT
92
+{u'return': {}}
96
+file format: qcow2
97
+virtual size: 64 MiB (67108864 bytes)
98
+disk size: unavailable
99
+
100
+--- Testing creation for which the node would need to grow ---
101
+qemu-img: TEST_DIR/t.IMGFMT: Could not resize image: Image format driver does not support resize
102
+Formatting 'TEST_DIR/t.IMGFMT', fmt=qcow2 size=67108864 preallocation=metadata
103
+*** done
104
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
93
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
105
index XXXXXXX..XXXXXXX 100644
94
index XXXXXXX..XXXXXXX 100644
106
--- a/tests/qemu-iotests/group
95
--- a/tests/qemu-iotests/group
107
+++ b/tests/qemu-iotests/group
96
+++ b/tests/qemu-iotests/group
108
@@ -XXX,XX +XXX,XX @@
97
@@ -XXX,XX +XXX,XX @@
109
256 rw auto quick
98
198 rw auto
110
257 rw
99
200 rw auto
111
258 rw quick
100
202 rw auto quick
112
+259 rw auto quick
101
+203 rw auto
113
260 rw quick
114
261 rw
115
262 rw quick migration
116
--
102
--
117
2.24.1
103
2.14.3
118
104
119
105
diff view generated by jsdifflib