1
The following changes since commit 0280396a33c7210c4df5306afeab63411a41535a:
1
The following changes since commit ec11dc41eec5142b4776db1296972c6323ba5847:
2
2
3
Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-gdbstub-150221-1' into staging (2021-02-15 10:13:13 +0000)
3
Merge tag 'pull-misc-2022-05-11' of git://repo.or.cz/qemu/armbru into staging (2022-05-11 09:00:26 -0700)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
8
8
9
for you to fetch changes up to b248e61652e20c3353af4b0ccb90f17d76f4db21:
9
for you to fetch changes up to f70625299ecc9ba577c87f3d1d75012c747c7d88:
10
10
11
monitor/qmp: Stop processing requests when shutdown is requested (2021-02-15 15:10:14 +0100)
11
qemu-iotests: inline common.config into common.rc (2022-05-12 15:42:49 +0200)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches
15
15
16
- qemu-storage-daemon: Enable object-add
16
- coroutine: Fix crashes due to too large pool batch size
17
- blockjob: Fix crash with IOthread when block commit after snapshot
17
- fdc: Prevent end-of-track overrun
18
- monitor: Shutdown fixes
18
- nbd: MULTI_CONN for shared writable exports
19
- xen-block: fix reporting of discard feature
19
- iotests test runner improvements
20
- qcow2: Remove half-initialised image file after failed image creation
21
- ahci: Fix DMA direction
22
- iotests fixes
23
20
24
----------------------------------------------------------------
21
----------------------------------------------------------------
25
Alexander Bulekov (1):
22
Daniel P. Berrangé (2):
26
hw/ide/ahci: map cmd_fis as DMA_DIRECTION_TO_DEVICE
23
tests/qemu-iotests: print intent to run a test in TAP mode
24
.gitlab-ci.d: export meson testlog.txt as an artifact
27
25
28
Kevin Wolf (3):
26
Eric Blake (2):
29
qemu-storage-daemon: Enable object-add
27
qemu-nbd: Pass max connections to blockdev layer
30
monitor: Fix assertion failure on shutdown
28
nbd/server: Allow MULTI_CONN for shared writable exports
31
monitor/qmp: Stop processing requests when shutdown is requested
32
29
33
Max Reitz (1):
30
Hanna Reitz (1):
34
iotests: Consistent $IMGOPTS boundary matching
31
iotests/testrunner: Flush after run_test()
35
32
36
Maxim Levitsky (3):
33
Kevin Wolf (2):
37
crypto: luks: Fix tiny memory leak
34
coroutine: Rename qemu_coroutine_inc/dec_pool_size()
38
block: add bdrv_co_delete_file_noerr
35
coroutine: Revert to constant batch size
39
block: qcow2: remove the created file on initialization error
40
36
41
Michael Qiu (1):
37
Paolo Bonzini (1):
42
blockjob: Fix crash with IOthread when block commit after snapshot
38
qemu-iotests: inline common.config into common.rc
43
39
44
Roger Pau Monné (1):
40
Philippe Mathieu-Daudé (2):
45
xen-block: fix reporting of discard feature
41
hw/block/fdc: Prevent end-of-track overrun (CVE-2021-3507)
42
tests/qtest/fdc-test: Add a regression test for CVE-2021-3507
46
43
47
Thomas Huth (1):
44
qapi/block-export.json | 8 +-
48
tests/qemu-iotests: Remove test 259 from the "auto" group
45
docs/interop/nbd.txt | 1 +
49
46
docs/tools/qemu-nbd.rst | 3 +-
50
include/block/block.h | 1 +
47
include/block/nbd.h | 5 +-
51
block.c | 22 ++++++++++++++++++++++
48
include/qemu/coroutine.h | 6 +-
52
block/crypto.c | 13 ++-----------
49
blockdev-nbd.c | 13 +-
53
block/qcow2.c | 8 +++++---
50
hw/block/fdc.c | 8 ++
54
blockjob.c | 8 ++++++--
51
hw/block/virtio-blk.c | 6 +-
55
hw/block/xen-block.c | 1 +
52
nbd/server.c | 10 +-
56
hw/ide/ahci.c | 12 ++++++------
53
qemu-nbd.c | 2 +-
57
monitor/monitor.c | 25 +++++++++++++++----------
54
tests/qtest/fdc-test.c | 21 ++++
58
monitor/qmp.c | 5 +++++
55
util/qemu-coroutine.c | 26 ++--
59
storage-daemon/qemu-storage-daemon.c | 2 ++
56
tests/qemu-iotests/testrunner.py | 4 +
60
tests/qemu-iotests/259 | 2 +-
57
.gitlab-ci.d/buildtest-template.yml | 12 +-
61
tests/qemu-iotests/common.rc | 4 +++-
58
MAINTAINERS | 1 +
62
12 files changed, 69 insertions(+), 34 deletions(-)
59
tests/qemu-iotests/common.config | 41 -------
60
tests/qemu-iotests/common.rc | 31 +++--
61
tests/qemu-iotests/tests/nbd-multiconn | 145 +++++++++++++++++++++++
62
tests/qemu-iotests/tests/nbd-multiconn.out | 5 +
63
tests/qemu-iotests/tests/nbd-qemu-allocation.out | 2 +-
64
20 files changed, 261 insertions(+), 89 deletions(-)
65
delete mode 100644 tests/qemu-iotests/common.config
66
create mode 100755 tests/qemu-iotests/tests/nbd-multiconn
67
create mode 100644 tests/qemu-iotests/tests/nbd-multiconn.out
63
68
64
69
diff view generated by jsdifflib
Deleted patch
1
As we don't have a fully QAPIfied version of object-add yet and it still
2
has 'gen': false in the schema, it needs to be registered explicitly in
3
init_qmp_commands() to be available for users.
4
1
5
Fixes: 2af282ec51a27116d0402cab237b8970800f870c
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Message-Id: <20210204072137.19663-1-kwolf@redhat.com>
8
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
storage-daemon/qemu-storage-daemon.c | 2 ++
12
1 file changed, 2 insertions(+)
13
14
diff --git a/storage-daemon/qemu-storage-daemon.c b/storage-daemon/qemu-storage-daemon.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/storage-daemon/qemu-storage-daemon.c
17
+++ b/storage-daemon/qemu-storage-daemon.c
18
@@ -XXX,XX +XXX,XX @@ static void init_qmp_commands(void)
19
qmp_init_marshal(&qmp_commands);
20
qmp_register_command(&qmp_commands, "query-qmp-schema",
21
qmp_query_qmp_schema, QCO_ALLOW_PRECONFIG);
22
+ qmp_register_command(&qmp_commands, "object-add", qmp_object_add,
23
+ QCO_NO_OPTIONS);
24
25
QTAILQ_INIT(&qmp_cap_negotiation_commands);
26
qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
27
--
28
2.29.2
29
30
diff view generated by jsdifflib
1
Commit 357bda95 already tried to fix the order in monitor_cleanup() by
1
It's true that these functions currently affect the batch size in which
2
moving shutdown of the dispatcher coroutine further to the start.
2
coroutines are reused (i.e. moved from the global release pool to the
3
However, it didn't go far enough:
3
allocation pool of a specific thread), but this is a bug and will be
4
fixed in a separate patch.
4
5
5
iothread_stop() makes sure that all pending work (bottom halves) in the
6
In fact, the comment in the header file already just promises that it
6
AioContext of the monitor iothread is completed. iothread_destroy()
7
influences the pool size, so reflect this in the name of the functions.
7
depends on this and fails an assertion if there is still a pending BH.
8
As a nice side effect, the shorter function name makes some line
9
wrapping unnecessary.
8
10
9
While the dispatcher coroutine is running, it will try to resume the
11
Cc: qemu-stable@nongnu.org
10
monitor after taking a request out of the queue, which involves a BH.
11
The dispatcher is run until it terminates in the AIO_WAIT_WHILE() loop.
12
However, adding new BHs between iothread_stop() and iothread_destroy()
13
is forbidden.
14
15
Fix this by stopping the dispatcher first before shutting down the other
16
parts of the monitor. This means we can now receive requests that aren't
17
handled any more when QEMU is shutting down, but this is unlikely to be
18
a problem for QMP clients.
19
20
Fixes: 357bda9590784ff75803d52de43150d4107ed98e
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
Message-Id: <20210212172028.288825-2-kwolf@redhat.com>
13
Message-Id: <20220510151020.105528-2-kwolf@redhat.com>
23
Tested-by: Markus Armbruster <armbru@redhat.com>
24
Reviewed-by: Markus Armbruster <armbru@redhat.com>
25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26
---
15
---
27
monitor/monitor.c | 25 +++++++++++++++----------
16
include/qemu/coroutine.h | 6 +++---
28
1 file changed, 15 insertions(+), 10 deletions(-)
17
hw/block/virtio-blk.c | 6 ++----
18
util/qemu-coroutine.c | 4 ++--
19
3 files changed, 7 insertions(+), 9 deletions(-)
29
20
30
diff --git a/monitor/monitor.c b/monitor/monitor.c
21
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
31
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
32
--- a/monitor/monitor.c
23
--- a/include/qemu/coroutine.h
33
+++ b/monitor/monitor.c
24
+++ b/include/qemu/coroutine.h
34
@@ -XXX,XX +XXX,XX @@ void monitor_data_destroy(Monitor *mon)
25
@@ -XXX,XX +XXX,XX @@ void coroutine_fn yield_until_fd_readable(int fd);
35
26
/**
36
void monitor_cleanup(void)
27
* Increase coroutine pool size
28
*/
29
-void qemu_coroutine_increase_pool_batch_size(unsigned int additional_pool_size);
30
+void qemu_coroutine_inc_pool_size(unsigned int additional_pool_size);
31
32
/**
33
- * Devcrease coroutine pool size
34
+ * Decrease coroutine pool size
35
*/
36
-void qemu_coroutine_decrease_pool_batch_size(unsigned int additional_pool_size);
37
+void qemu_coroutine_dec_pool_size(unsigned int additional_pool_size);
38
39
#include "qemu/lockable.h"
40
41
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/block/virtio-blk.c
44
+++ b/hw/block/virtio-blk.c
45
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
46
for (i = 0; i < conf->num_queues; i++) {
47
virtio_add_queue(vdev, conf->queue_size, virtio_blk_handle_output);
48
}
49
- qemu_coroutine_increase_pool_batch_size(conf->num_queues * conf->queue_size
50
- / 2);
51
+ qemu_coroutine_inc_pool_size(conf->num_queues * conf->queue_size / 2);
52
virtio_blk_data_plane_create(vdev, conf, &s->dataplane, &err);
53
if (err != NULL) {
54
error_propagate(errp, err);
55
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_unrealize(DeviceState *dev)
56
for (i = 0; i < conf->num_queues; i++) {
57
virtio_del_queue(vdev, i);
58
}
59
- qemu_coroutine_decrease_pool_batch_size(conf->num_queues * conf->queue_size
60
- / 2);
61
+ qemu_coroutine_dec_pool_size(conf->num_queues * conf->queue_size / 2);
62
qemu_del_vm_change_state_handler(s->change);
63
blockdev_mark_auto_del(s->blk);
64
virtio_cleanup(vdev);
65
diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/util/qemu-coroutine.c
68
+++ b/util/qemu-coroutine.c
69
@@ -XXX,XX +XXX,XX @@ AioContext *coroutine_fn qemu_coroutine_get_aio_context(Coroutine *co)
70
return co->ctx;
71
}
72
73
-void qemu_coroutine_increase_pool_batch_size(unsigned int additional_pool_size)
74
+void qemu_coroutine_inc_pool_size(unsigned int additional_pool_size)
37
{
75
{
38
- /*
76
qatomic_add(&pool_batch_size, additional_pool_size);
39
- * We need to explicitly stop the I/O thread (but not destroy it),
77
}
40
- * clean up the monitor resources, then destroy the I/O thread since
78
41
- * we need to unregister from chardev below in
79
-void qemu_coroutine_decrease_pool_batch_size(unsigned int removing_pool_size)
42
- * monitor_data_destroy(), and chardev is not thread-safe yet
80
+void qemu_coroutine_dec_pool_size(unsigned int removing_pool_size)
43
- */
81
{
44
- if (mon_iothread) {
82
qatomic_sub(&pool_batch_size, removing_pool_size);
45
- iothread_stop(mon_iothread);
83
}
46
- }
47
-
48
/*
49
* The dispatcher needs to stop before destroying the monitor and
50
* the I/O thread.
51
@@ -XXX,XX +XXX,XX @@ void monitor_cleanup(void)
52
* eventually terminates. qemu_aio_context is automatically
53
* polled by calling AIO_WAIT_WHILE on it, but we must poll
54
* iohandler_ctx manually.
55
+ *
56
+ * Letting the iothread continue while shutting down the dispatcher
57
+ * means that new requests may still be coming in. This is okay,
58
+ * we'll just leave them in the queue without sending a response
59
+ * and monitor_data_destroy() will free them.
60
*/
61
qmp_dispatcher_co_shutdown = true;
62
if (!qatomic_xchg(&qmp_dispatcher_co_busy, true)) {
63
@@ -XXX,XX +XXX,XX @@ void monitor_cleanup(void)
64
(aio_poll(iohandler_get_aio_context(), false),
65
qatomic_mb_read(&qmp_dispatcher_co_busy)));
66
67
+ /*
68
+ * We need to explicitly stop the I/O thread (but not destroy it),
69
+ * clean up the monitor resources, then destroy the I/O thread since
70
+ * we need to unregister from chardev below in
71
+ * monitor_data_destroy(), and chardev is not thread-safe yet
72
+ */
73
+ if (mon_iothread) {
74
+ iothread_stop(mon_iothread);
75
+ }
76
+
77
/* Flush output buffers and destroy monitors */
78
qemu_mutex_lock(&monitor_lock);
79
monitor_destroyed = true;
80
--
84
--
81
2.29.2
85
2.35.3
82
83
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
Commit 4c41c69e changed the way the coroutine pool is sized because for
2
virtio-blk devices with a large queue size and heavy I/O, it was just
3
too small and caused coroutines to be deleted and reallocated soon
4
afterwards. The change made the size dynamic based on the number of
5
queues and the queue size of virtio-blk devices.
2
6
3
If the qcow initialization fails, we should remove the file if it was
7
There are two important numbers here: Slightly simplified, when a
4
already created, to avoid leaving stale files around.
8
coroutine terminates, it is generally stored in the global release pool
9
up to a certain pool size, and if the pool is full, it is freed.
10
Conversely, when allocating a new coroutine, the coroutines in the
11
release pool are reused if the pool already has reached a certain
12
minimum size (the batch size), otherwise we allocate new coroutines.
5
13
6
We already do this for luks raw images.
14
The problem after commit 4c41c69e is that it not only increases the
15
maximum pool size (which is the intended effect), but also the batch
16
size for reusing coroutines (which is a bug). It means that in cases
17
with many devices and/or a large queue size (which defaults to the
18
number of vcpus for virtio-blk-pci), many thousand coroutines could be
19
sitting in the release pool without being reused.
7
20
8
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
21
This is not only a waste of memory and allocations, but it actually
9
Reviewed-by: Alberto Garcia <berto@igalia.com>
22
makes the QEMU process likely to hit the vm.max_map_count limit on Linux
10
Message-Id: <20201217170904.946013-4-mlevitsk@redhat.com>
23
because each coroutine requires two mappings (its stack and the guard
11
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
24
page for the stack), causing it to abort() in qemu_alloc_stack() because
25
when the limit is hit, mprotect() starts to fail with ENOMEM.
26
27
In order to fix the problem, change the batch size back to 64 to avoid
28
uselessly accumulating coroutines in the release pool, but keep the
29
dynamic maximum pool size so that coroutines aren't freed too early
30
in heavy I/O scenarios.
31
32
Note that this fix doesn't strictly make it impossible to hit the limit,
33
but this would only happen if most of the coroutines are actually in use
34
at the same time, not just sitting in a pool. This is the same behaviour
35
as we already had before commit 4c41c69e. Fully preventing this would
36
require allowing qemu_coroutine_create() to return an error, but it
37
doesn't seem to be a scenario that people hit in practice.
38
39
Cc: qemu-stable@nongnu.org
40
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2079938
41
Fixes: 4c41c69e05fe28c0f95f8abd2ebf407e95a4f04b
42
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
43
Message-Id: <20220510151020.105528-3-kwolf@redhat.com>
44
Tested-by: Hiroki Narukawa <hnarukaw@yahoo-corp.jp>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
45
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
46
---
14
block/qcow2.c | 8 +++++---
47
util/qemu-coroutine.c | 22 ++++++++++++++--------
15
1 file changed, 5 insertions(+), 3 deletions(-)
48
1 file changed, 14 insertions(+), 8 deletions(-)
16
49
17
diff --git a/block/qcow2.c b/block/qcow2.c
50
diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c
18
index XXXXXXX..XXXXXXX 100644
51
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qcow2.c
52
--- a/util/qemu-coroutine.c
20
+++ b/block/qcow2.c
53
+++ b/util/qemu-coroutine.c
21
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_create_opts(BlockDriver *drv,
54
@@ -XXX,XX +XXX,XX @@
22
55
#include "qemu/coroutine-tls.h"
23
/* Create the qcow2 image (format layer) */
56
#include "block/aio.h"
24
ret = qcow2_co_create(create_options, errp);
57
25
+finish:
58
-/** Initial batch size is 64, and is increased on demand */
26
if (ret < 0) {
59
+/**
27
- goto finish;
60
+ * The minimal batch size is always 64, coroutines from the release_pool are
28
+ bdrv_co_delete_file_noerr(bs);
61
+ * reused as soon as there are 64 coroutines in it. The maximum pool size starts
29
+ bdrv_co_delete_file_noerr(data_bs);
62
+ * with 64 and is increased on demand so that coroutines are not deleted even if
30
+ } else {
63
+ * they are not immediately reused.
31
+ ret = 0;
64
+ */
32
}
65
enum {
33
66
- POOL_INITIAL_BATCH_SIZE = 64,
34
- ret = 0;
67
+ POOL_MIN_BATCH_SIZE = 64,
35
-finish:
68
+ POOL_INITIAL_MAX_SIZE = 64,
36
qobject_unref(qdict);
69
};
37
bdrv_unref(bs);
70
38
bdrv_unref(data_bs);
71
/** Free list to speed up creation */
72
static QSLIST_HEAD(, Coroutine) release_pool = QSLIST_HEAD_INITIALIZER(pool);
73
-static unsigned int pool_batch_size = POOL_INITIAL_BATCH_SIZE;
74
+static unsigned int pool_max_size = POOL_INITIAL_MAX_SIZE;
75
static unsigned int release_pool_size;
76
77
typedef QSLIST_HEAD(, Coroutine) CoroutineQSList;
78
@@ -XXX,XX +XXX,XX @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque)
79
80
co = QSLIST_FIRST(alloc_pool);
81
if (!co) {
82
- if (release_pool_size > qatomic_read(&pool_batch_size)) {
83
+ if (release_pool_size > POOL_MIN_BATCH_SIZE) {
84
/* Slow path; a good place to register the destructor, too. */
85
Notifier *notifier = get_ptr_coroutine_pool_cleanup_notifier();
86
if (!notifier->notify) {
87
@@ -XXX,XX +XXX,XX @@ static void coroutine_delete(Coroutine *co)
88
co->caller = NULL;
89
90
if (CONFIG_COROUTINE_POOL) {
91
- if (release_pool_size < qatomic_read(&pool_batch_size) * 2) {
92
+ if (release_pool_size < qatomic_read(&pool_max_size) * 2) {
93
QSLIST_INSERT_HEAD_ATOMIC(&release_pool, co, pool_next);
94
qatomic_inc(&release_pool_size);
95
return;
96
}
97
- if (get_alloc_pool_size() < qatomic_read(&pool_batch_size)) {
98
+ if (get_alloc_pool_size() < qatomic_read(&pool_max_size)) {
99
QSLIST_INSERT_HEAD(get_ptr_alloc_pool(), co, pool_next);
100
set_alloc_pool_size(get_alloc_pool_size() + 1);
101
return;
102
@@ -XXX,XX +XXX,XX @@ AioContext *coroutine_fn qemu_coroutine_get_aio_context(Coroutine *co)
103
104
void qemu_coroutine_inc_pool_size(unsigned int additional_pool_size)
105
{
106
- qatomic_add(&pool_batch_size, additional_pool_size);
107
+ qatomic_add(&pool_max_size, additional_pool_size);
108
}
109
110
void qemu_coroutine_dec_pool_size(unsigned int removing_pool_size)
111
{
112
- qatomic_sub(&pool_batch_size, removing_pool_size);
113
+ qatomic_sub(&pool_max_size, removing_pool_size);
114
}
39
--
115
--
40
2.29.2
116
2.35.3
41
42
diff view generated by jsdifflib
1
From: Roger Pau Monne <roger.pau@citrix.com>
1
From: Hanna Reitz <hreitz@redhat.com>
2
2
3
Linux blkfront expects both "discard-granularity" and
3
When stdout is not a terminal, the buffer may not be flushed at each end
4
"discard-alignment" present on xenbus in order to properly enable the
4
of line, so we should flush after each test is done. This is especially
5
feature, not exposing "discard-alignment" left some Linux blkfront
5
apparent when run by check-block, in two ways:
6
versions with a broken discard setup. This has also been addressed in
7
Linux with:
8
6
9
https://lore.kernel.org/lkml/20210118151528.81668-1-roger.pau@citrix.com/T/#u
7
First, when running make check-block -jX with X > 1, progress indication
8
was missing, even though testrunner.py does theoretically print each
9
test's status once it has been run, even in multi-processing mode.
10
Flushing after each test restores this progress indication.
10
11
11
Fix QEMU to report a "discard-alignment" of 0, in order for it to work
12
Second, sometimes make check-block failed altogether, with an error
12
with older Linux frontends.
13
message that "too few tests [were] run". I presume that's because one
14
worker process in the job pool did not get to flush its stdout before
15
the main process exited, and so meson did not get to see that worker's
16
test results. In any case, by flushing at the end of run_test(), the
17
problem has disappeared for me.
13
18
14
Reported-by: Arthur Borsboom <arthurborsboom@gmail.com>
19
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
15
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
20
Message-Id: <20220506134215.10086-1-hreitz@redhat.com>
16
Message-Id: <20210118153330.82324-1-roger.pau@citrix.com>
21
Reviewed-by: Eric Blake <eblake@redhat.com>
17
Reviewed-by: Paul Durrant <paul@xen.org>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
23
---
20
hw/block/xen-block.c | 1 +
24
tests/qemu-iotests/testrunner.py | 1 +
21
1 file changed, 1 insertion(+)
25
1 file changed, 1 insertion(+)
22
26
23
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
27
diff --git a/tests/qemu-iotests/testrunner.py b/tests/qemu-iotests/testrunner.py
24
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/block/xen-block.c
29
--- a/tests/qemu-iotests/testrunner.py
26
+++ b/hw/block/xen-block.c
30
+++ b/tests/qemu-iotests/testrunner.py
27
@@ -XXX,XX +XXX,XX @@ static void xen_block_realize(XenDevice *xendev, Error **errp)
31
@@ -XXX,XX +XXX,XX @@ def run_test(self, test: str,
28
xen_device_backend_printf(xendev, "feature-discard", "%u", 1);
32
else:
29
xen_device_backend_printf(xendev, "discard-granularity", "%u",
33
print(res.casenotrun)
30
conf->discard_granularity);
34
31
+ xen_device_backend_printf(xendev, "discard-alignment", "%u", 0);
35
+ sys.stdout.flush()
32
}
36
return res
33
37
34
xen_device_backend_printf(xendev, "feature-flush-cache", "%u", 1);
38
def run_tests(self, tests: List[str], jobs: int = 1) -> bool:
35
--
39
--
36
2.29.2
40
2.35.3
37
38
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
From: Daniel P. Berrangé <berrange@redhat.com>
2
2
3
When the underlying block device doesn't support the
3
When running I/O tests using TAP output mode, we get a single TAP test
4
bdrv_co_delete_file interface, an 'Error' object was leaked.
4
with a sub-test reported for each I/O test that is run. The output looks
5
something like this:
5
6
6
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
7
1..123
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
8
ok qcow2 011
8
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
ok qcow2 012
9
Message-Id: <20201217170904.946013-2-mlevitsk@redhat.com>
10
ok qcow2 013
11
ok qcow2 217
12
...
13
14
If everything runs or fails normally this is fine, but periodically we
15
have been seeing the test harness abort early before all 123 tests have
16
been run, just leaving a fairly useless message like
17
18
TAP parsing error: Too few tests run (expected 123, got 107)
19
20
we have no idea which tests were running at the time the test harness
21
abruptly exited. This change causes us to print a message about our
22
intent to run each test, so we have a record of what is active at the
23
time the harness exits abnormally.
24
25
1..123
26
# running qcow2 011
27
ok qcow2 011
28
# running qcow2 012
29
ok qcow2 012
30
# running qcow2 013
31
ok qcow2 013
32
# running qcow2 217
33
ok qcow2 217
34
...
35
36
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
37
Message-Id: <20220509124134.867431-2-berrange@redhat.com>
38
Reviewed-by: Thomas Huth <thuth@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
39
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
40
---
12
block/crypto.c | 2 ++
41
tests/qemu-iotests/testrunner.py | 3 +++
13
1 file changed, 2 insertions(+)
42
1 file changed, 3 insertions(+)
14
43
15
diff --git a/block/crypto.c b/block/crypto.c
44
diff --git a/tests/qemu-iotests/testrunner.py b/tests/qemu-iotests/testrunner.py
16
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
17
--- a/block/crypto.c
46
--- a/tests/qemu-iotests/testrunner.py
18
+++ b/block/crypto.c
47
+++ b/tests/qemu-iotests/testrunner.py
19
@@ -XXX,XX +XXX,XX @@ fail:
48
@@ -XXX,XX +XXX,XX @@ def run_test(self, test: str,
20
*/
49
starttime=start,
21
if ((r_del < 0) && (r_del != -ENOTSUP)) {
50
lasttime=last_el,
22
error_report_err(local_delete_err);
51
end = '\n' if mp else '\r')
23
+ } else {
52
+ else:
24
+ error_free(local_delete_err);
53
+ testname = os.path.basename(test)
25
}
54
+ print(f'# running {self.env.imgfmt} {testname}')
26
}
55
56
res = self.do_run_test(test, mp)
27
57
28
--
58
--
29
2.29.2
59
2.35.3
30
60
31
61
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Daniel P. Berrangé <berrange@redhat.com>
2
2
3
Tests in the "auto" group should support qcow2 so that they can
3
When running 'make check' we only get a summary of progress on the
4
be run during "make check-block". Test 259 only supports "raw", so
4
console. Fortunately meson/ninja have saved the raw test output to a
5
it currently always gets skipped when running "make check-block".
5
logfile. Exposing this log will make it easier to debug failures that
6
Let's skip this unnecessary step and remove it from the auto group.
6
happen in CI.
7
7
8
Signed-off-by: Thomas Huth <thuth@redhat.com>
8
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
9
Message-Id: <20210215103835.1129145-1-thuth@redhat.com>
9
Message-Id: <20220509124134.867431-3-berrange@redhat.com>
10
Reviewed-by: Thomas Huth <thuth@redhat.com>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
13
---
12
tests/qemu-iotests/259 | 2 +-
14
.gitlab-ci.d/buildtest-template.yml | 12 ++++++++++--
13
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 10 insertions(+), 2 deletions(-)
14
16
15
diff --git a/tests/qemu-iotests/259 b/tests/qemu-iotests/259
17
diff --git a/.gitlab-ci.d/buildtest-template.yml b/.gitlab-ci.d/buildtest-template.yml
16
index XXXXXXX..XXXXXXX 100755
18
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/qemu-iotests/259
19
--- a/.gitlab-ci.d/buildtest-template.yml
18
+++ b/tests/qemu-iotests/259
20
+++ b/.gitlab-ci.d/buildtest-template.yml
19
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
20
#!/usr/bin/env bash
22
make -j"$JOBS" $MAKE_CHECK_ARGS ;
21
-# group: rw auto quick
23
fi
22
+# group: rw quick
24
23
#
25
-.native_test_job_template:
24
# Test generic image creation fallback (by using NBD)
26
+.common_test_job_template:
25
#
27
stage: test
28
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:latest
29
script:
30
@@ -XXX,XX +XXX,XX @@
31
# Avoid recompiling by hiding ninja with NINJA=":"
32
- make NINJA=":" $MAKE_CHECK_ARGS
33
34
+.native_test_job_template:
35
+ extends: .common_test_job_template
36
+ artifacts:
37
+ name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
38
+ expire_in: 7 days
39
+ paths:
40
+ - build/meson-logs/testlog.txt
41
+
42
.avocado_test_job_template:
43
- extends: .native_test_job_template
44
+ extends: .common_test_job_template
45
cache:
46
key: "${CI_JOB_NAME}-cache"
47
paths:
26
--
48
--
27
2.29.2
49
2.35.3
28
50
29
51
diff view generated by jsdifflib
1
Before this patch, monitor_qmp_dispatcher_co() used to check whether
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
shutdown is requested only when it would have to wait for new requests.
3
If there were still some queued requests, it would try to execute all of
4
them before shutting down.
5
2
6
This can be surprising when the queued QMP commands take long or hang
3
Per the 82078 datasheet, if the end-of-track (EOT byte in
7
because Ctrl-C may not actually exit QEMU as soon as possible.
4
the FIFO) is more than the number of sectors per side, the
5
command is terminated unsuccessfully:
8
6
9
Change monitor_qmp_dispatcher_co() so that it additionally checks
7
* 5.2.5 DATA TRANSFER TERMINATION
10
whether shutdown is request before it gets a new request from the queue.
11
8
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
The 82078 supports terminal count explicitly through
13
Message-Id: <20210212172028.288825-3-kwolf@redhat.com>
10
the TC pin and implicitly through the underrun/over-
14
Tested-by: Markus Armbruster <armbru@redhat.com>
11
run and end-of-track (EOT) functions. For full sector
15
Reviewed-by: Markus Armbruster <armbru@redhat.com>
12
transfers, the EOT parameter can define the last
13
sector to be transferred in a single or multisector
14
transfer. If the last sector to be transferred is a par-
15
tial sector, the host can stop transferring the data in
16
mid-sector, and the 82078 will continue to complete
17
the sector as if a hardware TC was received. The
18
only difference between these implicit functions and
19
TC is that they return "abnormal termination" result
20
status. Such status indications can be ignored if they
21
were expected.
22
23
* 6.1.3 READ TRACK
24
25
This command terminates when the EOT specified
26
number of sectors have been read. If the 82078
27
does not find an I D Address Mark on the diskette
28
after the second· occurrence of a pulse on the
29
INDX# pin, then it sets the IC code in Status Regis-
30
ter 0 to "01" (Abnormal termination), sets the MA bit
31
in Status Register 1 to "1", and terminates the com-
32
mand.
33
34
* 6.1.6 VERIFY
35
36
Refer to Table 6-6 and Table 6-7 for information
37
concerning the values of MT and EC versus SC and
38
EOT value.
39
40
* Table 6·6. Result Phase Table
41
42
* Table 6-7. Verify Command Result Phase Table
43
44
Fix by aborting the transfer when EOT > # Sectors Per Side.
45
46
Cc: qemu-stable@nongnu.org
47
Cc: Hervé Poussineau <hpoussin@reactos.org>
48
Fixes: baca51faff0 ("floppy driver: disk geometry auto detect")
49
Reported-by: Alexander Bulekov <alxndr@bu.edu>
50
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/339
51
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
52
Message-Id: <20211118115733.4038610-2-philmd@redhat.com>
53
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
54
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
55
---
18
monitor/qmp.c | 5 +++++
56
hw/block/fdc.c | 8 ++++++++
19
1 file changed, 5 insertions(+)
57
1 file changed, 8 insertions(+)
20
58
21
diff --git a/monitor/qmp.c b/monitor/qmp.c
59
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
22
index XXXXXXX..XXXXXXX 100644
60
index XXXXXXX..XXXXXXX 100644
23
--- a/monitor/qmp.c
61
--- a/hw/block/fdc.c
24
+++ b/monitor/qmp.c
62
+++ b/hw/block/fdc.c
25
@@ -XXX,XX +XXX,XX @@ void coroutine_fn monitor_qmp_dispatcher_co(void *data)
63
@@ -XXX,XX +XXX,XX @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int direction)
26
*/
64
int tmp;
27
qatomic_mb_set(&qmp_dispatcher_co_busy, false);
65
fdctrl->data_len = 128 << (fdctrl->fifo[5] > 7 ? 7 : fdctrl->fifo[5]);
28
66
tmp = (fdctrl->fifo[6] - ks + 1);
29
+ /* On shutdown, don't take any more requests from the queue */
67
+ if (tmp < 0) {
30
+ if (qmp_dispatcher_co_shutdown) {
68
+ FLOPPY_DPRINTF("invalid EOT: %d\n", tmp);
69
+ fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00);
70
+ fdctrl->fifo[3] = kt;
71
+ fdctrl->fifo[4] = kh;
72
+ fdctrl->fifo[5] = ks;
31
+ return;
73
+ return;
32
+ }
74
+ }
33
+
75
if (fdctrl->fifo[0] & 0x80)
34
while (!(req_obj = monitor_qmp_requests_pop_any_with_lock())) {
76
tmp += fdctrl->fifo[6];
35
/*
77
fdctrl->data_len *= tmp;
36
* No more requests to process. Wait to be reentered from
37
--
78
--
38
2.29.2
79
2.35.3
39
80
40
81
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
This function wraps bdrv_co_delete_file for the common case of removing a file,
3
Add the reproducer from https://gitlab.com/qemu-project/qemu/-/issues/339
4
which was just created by format driver, on an error condition.
5
4
6
It hides the -ENOTSUPP error, and reports all other errors otherwise.
5
Without the previous commit, when running 'make check-qtest-i386'
6
with QEMU configured with '--enable-sanitizers' we get:
7
7
8
Use it in luks driver
8
==4028352==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x619000062a00 at pc 0x5626d03c491a bp 0x7ffdb4199410 sp 0x7ffdb4198bc0
9
READ of size 786432 at 0x619000062a00 thread T0
10
#0 0x5626d03c4919 in __asan_memcpy (qemu-system-i386+0x1e65919)
11
#1 0x5626d1c023cc in flatview_write_continue softmmu/physmem.c:2787:13
12
#2 0x5626d1bf0c0f in flatview_write softmmu/physmem.c:2822:14
13
#3 0x5626d1bf0798 in address_space_write softmmu/physmem.c:2914:18
14
#4 0x5626d1bf0f37 in address_space_rw softmmu/physmem.c:2924:16
15
#5 0x5626d1bf14c8 in cpu_physical_memory_rw softmmu/physmem.c:2933:5
16
#6 0x5626d0bd5649 in cpu_physical_memory_write include/exec/cpu-common.h:82:5
17
#7 0x5626d0bd0a07 in i8257_dma_write_memory hw/dma/i8257.c:452:9
18
#8 0x5626d09f825d in fdctrl_transfer_handler hw/block/fdc.c:1616:13
19
#9 0x5626d0a048b4 in fdctrl_start_transfer hw/block/fdc.c:1539:13
20
#10 0x5626d09f4c3e in fdctrl_write_data hw/block/fdc.c:2266:13
21
#11 0x5626d09f22f7 in fdctrl_write hw/block/fdc.c:829:9
22
#12 0x5626d1c20bc5 in portio_write softmmu/ioport.c:207:17
9
23
10
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
24
0x619000062a00 is located 0 bytes to the right of 512-byte region [0x619000062800,0x619000062a00)
11
Reviewed-by: Alberto Garcia <berto@igalia.com>
25
allocated by thread T0 here:
12
Message-Id: <20201217170904.946013-3-mlevitsk@redhat.com>
26
#0 0x5626d03c66ec in posix_memalign (qemu-system-i386+0x1e676ec)
13
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
27
#1 0x5626d2b988d4 in qemu_try_memalign util/oslib-posix.c:210:11
28
#2 0x5626d2b98b0c in qemu_memalign util/oslib-posix.c:226:27
29
#3 0x5626d09fbaf0 in fdctrl_realize_common hw/block/fdc.c:2341:20
30
#4 0x5626d0a150ed in isabus_fdc_realize hw/block/fdc-isa.c:113:5
31
#5 0x5626d2367935 in device_set_realized hw/core/qdev.c:531:13
32
33
SUMMARY: AddressSanitizer: heap-buffer-overflow (qemu-system-i386+0x1e65919) in __asan_memcpy
34
Shadow bytes around the buggy address:
35
0x0c32800044f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
36
0x0c3280004500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
37
0x0c3280004510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
38
0x0c3280004520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
39
0x0c3280004530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40
=>0x0c3280004540:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
41
0x0c3280004550: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
42
0x0c3280004560: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
43
0x0c3280004570: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
44
0x0c3280004580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
45
0x0c3280004590: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
46
Shadow byte legend (one shadow byte represents 8 application bytes):
47
Addressable: 00
48
Heap left redzone: fa
49
Freed heap region: fd
50
==4028352==ABORTING
51
52
[ kwolf: Added snapshot=on to prevent write file lock failure ]
53
54
Reported-by: Alexander Bulekov <alxndr@bu.edu>
55
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
56
Reviewed-by: Alexander Bulekov <alxndr@bu.edu>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
57
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
58
---
16
include/block/block.h | 1 +
59
tests/qtest/fdc-test.c | 21 +++++++++++++++++++++
17
block.c | 22 ++++++++++++++++++++++
60
1 file changed, 21 insertions(+)
18
block/crypto.c | 15 ++-------------
19
3 files changed, 25 insertions(+), 13 deletions(-)
20
61
21
diff --git a/include/block/block.h b/include/block/block.h
62
diff --git a/tests/qtest/fdc-test.c b/tests/qtest/fdc-test.c
22
index XXXXXXX..XXXXXXX 100644
63
index XXXXXXX..XXXXXXX 100644
23
--- a/include/block/block.h
64
--- a/tests/qtest/fdc-test.c
24
+++ b/include/block/block.h
65
+++ b/tests/qtest/fdc-test.c
25
@@ -XXX,XX +XXX,XX @@ int bdrv_freeze_backing_chain(BlockDriverState *bs, BlockDriverState *base,
66
@@ -XXX,XX +XXX,XX @@ static void test_cve_2021_20196(void)
26
Error **errp);
67
qtest_quit(s);
27
void bdrv_unfreeze_backing_chain(BlockDriverState *bs, BlockDriverState *base);
28
int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp);
29
+void coroutine_fn bdrv_co_delete_file_noerr(BlockDriverState *bs);
30
31
32
typedef struct BdrvCheckResult {
33
diff --git a/block.c b/block.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/block.c
36
+++ b/block.c
37
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp)
38
return ret;
39
}
68
}
40
69
41
+void coroutine_fn bdrv_co_delete_file_noerr(BlockDriverState *bs)
70
+static void test_cve_2021_3507(void)
42
+{
71
+{
43
+ Error *local_err = NULL;
72
+ QTestState *s;
44
+ int ret;
45
+
73
+
46
+ if (!bs) {
74
+ s = qtest_initf("-nographic -m 32M -nodefaults "
47
+ return;
75
+ "-drive file=%s,format=raw,if=floppy,snapshot=on",
48
+ }
76
+ test_image);
49
+
77
+ qtest_outl(s, 0x9, 0x0a0206);
50
+ ret = bdrv_co_delete_file(bs, &local_err);
78
+ qtest_outw(s, 0x3f4, 0x1600);
51
+ /*
79
+ qtest_outw(s, 0x3f4, 0x0000);
52
+ * ENOTSUP will happen if the block driver doesn't support
80
+ qtest_outw(s, 0x3f4, 0x0000);
53
+ * the 'bdrv_co_delete_file' interface. This is a predictable
81
+ qtest_outw(s, 0x3f4, 0x0000);
54
+ * scenario and shouldn't be reported back to the user.
82
+ qtest_outw(s, 0x3f4, 0x0200);
55
+ */
83
+ qtest_outw(s, 0x3f4, 0x0200);
56
+ if (ret == -ENOTSUP) {
84
+ qtest_outw(s, 0x3f4, 0x0000);
57
+ error_free(local_err);
85
+ qtest_outw(s, 0x3f4, 0x0000);
58
+ } else if (ret < 0) {
86
+ qtest_outw(s, 0x3f4, 0x0000);
59
+ error_report_err(local_err);
87
+ qtest_quit(s);
60
+ }
61
+}
88
+}
62
+
89
+
63
/**
90
int main(int argc, char **argv)
64
* Try to get @bs's logical and physical block size.
91
{
65
* On success, store them in @bsz struct and return 0.
92
int fd;
66
diff --git a/block/crypto.c b/block/crypto.c
93
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
67
index XXXXXXX..XXXXXXX 100644
94
qtest_add_func("/fdc/read_no_dma_19", test_read_no_dma_19);
68
--- a/block/crypto.c
95
qtest_add_func("/fdc/fuzz-registers", fuzz_registers);
69
+++ b/block/crypto.c
96
qtest_add_func("/fdc/fuzz/cve_2021_20196", test_cve_2021_20196);
70
@@ -XXX,XX +XXX,XX @@ fail:
97
+ qtest_add_func("/fdc/fuzz/cve_2021_3507", test_cve_2021_3507);
71
* If an error occurred, delete 'filename'. Even if the file existed
98
72
* beforehand, it has been truncated and corrupted in the process.
99
ret = g_test_run();
73
*/
100
74
- if (ret && bs) {
75
- Error *local_delete_err = NULL;
76
- int r_del = bdrv_co_delete_file(bs, &local_delete_err);
77
- /*
78
- * ENOTSUP will happen if the block driver doesn't support
79
- * the 'bdrv_co_delete_file' interface. This is a predictable
80
- * scenario and shouldn't be reported back to the user.
81
- */
82
- if ((r_del < 0) && (r_del != -ENOTSUP)) {
83
- error_report_err(local_delete_err);
84
- } else {
85
- error_free(local_delete_err);
86
- }
87
+ if (ret) {
88
+ bdrv_co_delete_file_noerr(bs);
89
}
90
91
bdrv_unref(bs);
92
--
101
--
93
2.29.2
102
2.35.3
94
103
95
104
diff view generated by jsdifflib
1
From: Alexander Bulekov <alxndr@bu.edu>
1
From: Eric Blake <eblake@redhat.com>
2
2
3
cmd_fis is mapped as DMA_DIRECTION_FROM_DEVICE, however, it is read
3
The next patch wants to adjust whether the NBD server code advertises
4
from, and not written to anywhere. Fix the DMA_DIRECTION and mark
4
MULTI_CONN based on whether it is known if the server limits to
5
cmd_fis as read-only in the code.
5
exactly one client. For a server started by QMP, this information is
6
obtained through nbd_server_start (which can support more than one
7
export); but for qemu-nbd (which supports exactly one export), it is
8
controlled only by the command-line option -e/--shared. Since we
9
already have a hook function used by qemu-nbd, it's easiest to just
10
alter its signature to fit our needs.
6
11
7
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
12
Signed-off-by: Eric Blake <eblake@redhat.com>
8
Message-Id: <20210119164051.89268-1-alxndr@bu.edu>
13
Message-Id: <20220512004924.417153-2-eblake@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
15
---
11
hw/ide/ahci.c | 12 ++++++------
16
include/block/nbd.h | 2 +-
12
1 file changed, 6 insertions(+), 6 deletions(-)
17
blockdev-nbd.c | 8 ++++----
18
qemu-nbd.c | 2 +-
19
3 files changed, 6 insertions(+), 6 deletions(-)
13
20
14
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
21
diff --git a/include/block/nbd.h b/include/block/nbd.h
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/ide/ahci.c
23
--- a/include/block/nbd.h
17
+++ b/hw/ide/ahci.c
24
+++ b/include/block/nbd.h
18
@@ -XXX,XX +XXX,XX @@ static void ahci_reset_port(AHCIState *s, int port)
25
@@ -XXX,XX +XXX,XX @@ void nbd_client_new(QIOChannelSocket *sioc,
26
void nbd_client_get(NBDClient *client);
27
void nbd_client_put(NBDClient *client);
28
29
-void nbd_server_is_qemu_nbd(bool value);
30
+void nbd_server_is_qemu_nbd(int max_connections);
31
bool nbd_server_is_running(void);
32
void nbd_server_start(SocketAddress *addr, const char *tls_creds,
33
const char *tls_authz, uint32_t max_connections,
34
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/blockdev-nbd.c
37
+++ b/blockdev-nbd.c
38
@@ -XXX,XX +XXX,XX @@ typedef struct NBDServerData {
39
} NBDServerData;
40
41
static NBDServerData *nbd_server;
42
-static bool is_qemu_nbd;
43
+static int qemu_nbd_connections = -1; /* Non-negative if this is qemu-nbd */
44
45
static void nbd_update_server_watch(NBDServerData *s);
46
47
-void nbd_server_is_qemu_nbd(bool value)
48
+void nbd_server_is_qemu_nbd(int max_connections)
49
{
50
- is_qemu_nbd = value;
51
+ qemu_nbd_connections = max_connections;
19
}
52
}
20
53
21
/* Buffer pretty output based on a raw FIS structure. */
54
bool nbd_server_is_running(void)
22
-static char *ahci_pretty_buffer_fis(uint8_t *fis, int cmd_len)
23
+static char *ahci_pretty_buffer_fis(const uint8_t *fis, int cmd_len)
24
{
55
{
25
int i;
56
- return nbd_server || is_qemu_nbd;
26
GString *s = g_string_new("FIS:");
57
+ return nbd_server || qemu_nbd_connections >= 0;
27
@@ -XXX,XX +XXX,XX @@ static void execute_ncq_command(NCQTransferState *ncq_tfs)
28
}
58
}
29
59
30
60
static void nbd_blockdev_client_closed(NBDClient *client, bool ignored)
31
-static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
61
diff --git a/qemu-nbd.c b/qemu-nbd.c
32
+static void process_ncq_command(AHCIState *s, int port, const uint8_t *cmd_fis,
62
index XXXXXXX..XXXXXXX 100644
33
uint8_t slot)
63
--- a/qemu-nbd.c
34
{
64
+++ b/qemu-nbd.c
35
AHCIDevice *ad = &s->dev[port];
65
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
36
- NCQFrame *ncq_fis = (NCQFrame*)cmd_fis;
66
37
+ const NCQFrame *ncq_fis = (NCQFrame *)cmd_fis;
67
bs->detect_zeroes = detect_zeroes;
38
uint8_t tag = ncq_fis->tag >> 3;
68
39
NCQTransferState *ncq_tfs = &ad->ncq_tfs[tag];
69
- nbd_server_is_qemu_nbd(true);
40
size_t size;
70
+ nbd_server_is_qemu_nbd(shared);
41
@@ -XXX,XX +XXX,XX @@ static AHCICmdHdr *get_cmd_header(AHCIState *s, uint8_t port, uint8_t slot)
71
42
}
72
export_opts = g_new(BlockExportOptions, 1);
43
73
*export_opts = (BlockExportOptions) {
44
static void handle_reg_h2d_fis(AHCIState *s, int port,
45
- uint8_t slot, uint8_t *cmd_fis)
46
+ uint8_t slot, const uint8_t *cmd_fis)
47
{
48
IDEState *ide_state = &s->dev[port].port.ifs[0];
49
AHCICmdHdr *cmd = get_cmd_header(s, port, slot);
50
@@ -XXX,XX +XXX,XX @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
51
tbl_addr = le64_to_cpu(cmd->tbl_addr);
52
cmd_len = 0x80;
53
cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len,
54
- DMA_DIRECTION_FROM_DEVICE);
55
+ DMA_DIRECTION_TO_DEVICE);
56
if (!cmd_fis) {
57
trace_handle_cmd_badfis(s, port);
58
return -1;
59
@@ -XXX,XX +XXX,XX @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
60
}
61
62
out:
63
- dma_memory_unmap(s->as, cmd_fis, cmd_len, DMA_DIRECTION_FROM_DEVICE,
64
+ dma_memory_unmap(s->as, cmd_fis, cmd_len, DMA_DIRECTION_TO_DEVICE,
65
cmd_len);
66
67
if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
68
--
74
--
69
2.29.2
75
2.35.3
70
71
diff view generated by jsdifflib
1
From: Michael Qiu <qiudayu@huayun.com>
1
From: Eric Blake <eblake@redhat.com>
2
2
3
Currently, if guest has workloads, IO thread will acquire aio_context
3
According to the NBD spec, a server that advertises
4
lock before do io_submit, it leads to segmentfault when do block commit
4
NBD_FLAG_CAN_MULTI_CONN promises that multiple client connections will
5
after snapshot. Just like below:
5
not see any cache inconsistencies: when properly separated by a single
6
6
flush, actions performed by one client will be visible to another
7
Program received signal SIGSEGV, Segmentation fault.
7
client, regardless of which client did the flush.
8
8
9
[Switching to Thread 0x7f7c7d91f700 (LWP 99907)]
9
We always satisfy these conditions in qemu - even when we support
10
0x00005576d0f65aab in bdrv_mirror_top_pwritev at ../block/mirror.c:1437
10
multiple clients, ALL clients go through a single point of reference
11
1437 ../block/mirror.c: No such file or directory.
11
into the block layer, with no local caching. The effect of one client
12
(gdb) p s->job
12
is instantly visible to the next client. Even if our backend were a
13
$17 = (MirrorBlockJob *) 0x0
13
network device, we argue that any multi-path caching effects that
14
(gdb) p s->stop
14
would cause inconsistencies in back-to-back actions not seeing the
15
$18 = false
15
effect of previous actions would be a bug in that backend, and not the
16
16
fault of caching in qemu. As such, it is safe to unconditionally
17
Call trace of IO thread:
17
advertise CAN_MULTI_CONN for any qemu NBD server situation that
18
0 0x00005576d0f65aab in bdrv_mirror_top_pwritev at ../block/mirror.c:1437
18
supports parallel clients.
19
1 0x00005576d0f7f3ab in bdrv_driver_pwritev at ../block/io.c:1174
19
20
2 0x00005576d0f8139d in bdrv_aligned_pwritev at ../block/io.c:1988
20
Note, however, that we don't want to advertise CAN_MULTI_CONN when we
21
3 0x00005576d0f81b65 in bdrv_co_pwritev_part at ../block/io.c:2156
21
know that a second client cannot connect (for historical reasons,
22
4 0x00005576d0f8e6b7 in blk_do_pwritev_part at ../block/block-backend.c:1260
22
qemu-nbd defaults to a single connection while nbd-server-add and QMP
23
5 0x00005576d0f8e84d in blk_aio_write_entry at ../block/block-backend.c:1476
23
commands default to unlimited connections; but we already have
24
...
24
existing means to let either style of NBD server creation alter those
25
25
defaults). This is visible by no longer advertising MULTI_CONN for
26
Switch to qemu main thread:
26
'qemu-nbd -r' without -e, as in the iotest nbd-qemu-allocation.
27
0 0x00007f903be704ed in __lll_lock_wait at
27
28
/lib/../lib64/libpthread.so.0
28
The harder part of this patch is setting up an iotest to demonstrate
29
1 0x00007f903be6bde6 in _L_lock_941 at /lib/../lib64/libpthread.so.0
29
behavior of multiple NBD clients to a single server. It might be
30
2 0x00007f903be6bcdf in pthread_mutex_lock at
30
possible with parallel qemu-io processes, but I found it easier to do
31
/lib/../lib64/libpthread.so.0
31
in python with the help of libnbd, and help from Nir and Vladimir in
32
3 0x0000564b21456889 in qemu_mutex_lock_impl at
32
writing the test.
33
../util/qemu-thread-posix.c:79
33
34
4 0x0000564b213af8a5 in block_job_add_bdrv at ../blockjob.c:224
34
Signed-off-by: Eric Blake <eblake@redhat.com>
35
5 0x0000564b213b00ad in block_job_create at ../blockjob.c:440
35
Suggested-by: Nir Soffer <nsoffer@redhat.com>
36
6 0x0000564b21357c0a in mirror_start_job at ../block/mirror.c:1622
36
Suggested-by: Vladimir Sementsov-Ogievskiy <v.sementsov-og@mail.ru>
37
7 0x0000564b2135a9af in commit_active_start at ../block/mirror.c:1867
37
Message-Id: <20220512004924.417153-3-eblake@redhat.com>
38
8 0x0000564b2133d132 in qmp_block_commit at ../blockdev.c:2768
39
9 0x0000564b2141fef3 in qmp_marshal_block_commit at
40
qapi/qapi-commands-block-core.c:346
41
10 0x0000564b214503c9 in do_qmp_dispatch_bh at
42
../qapi/qmp-dispatch.c:110
43
11 0x0000564b21451996 in aio_bh_poll at ../util/async.c:164
44
12 0x0000564b2146018e in aio_dispatch at ../util/aio-posix.c:381
45
13 0x0000564b2145187e in aio_ctx_dispatch at ../util/async.c:306
46
14 0x00007f9040239049 in g_main_context_dispatch at
47
/lib/../lib64/libglib-2.0.so.0
48
15 0x0000564b21447368 in main_loop_wait at ../util/main-loop.c:232
49
16 0x0000564b21447368 in main_loop_wait at ../util/main-loop.c:255
50
17 0x0000564b21447368 in main_loop_wait at ../util/main-loop.c:531
51
18 0x0000564b212304e1 in qemu_main_loop at ../softmmu/runstate.c:721
52
19 0x0000564b20f7975e in main at ../softmmu/main.c:50
53
54
In IO thread when do bdrv_mirror_top_pwritev, the job is NULL, and stop field
55
is false, this means the MirrorBDSOpaque "s" object has not been initialized
56
yet, and this object is initialized by block_job_create(), but the initialize
57
process is stuck in acquiring the lock.
58
59
In this situation, IO thread come to bdrv_mirror_top_pwritev(),which means that
60
mirror-top node is already inserted into block graph, but its bs->opaque->job
61
is not initialized.
62
63
The root cause is that qemu main thread do release/acquire when hold the lock,
64
at the same time, IO thread get the lock after release stage, and the crash
65
occured.
66
67
Actually, in this situation, job->job.aio_context will not equal to
68
qemu_get_aio_context(), and will be the same as bs->aio_context,
69
thus, no need to release the lock, becasue bdrv_root_attach_child()
70
will not change the context.
71
72
This patch fix this issue.
73
74
Fixes: 132ada80 "block: Adjust AioContexts when attaching nodes"
75
76
Signed-off-by: Michael Qiu <qiudayu@huayun.com>
77
Message-Id: <20210203024059.52683-1-08005325@163.com>
78
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
38
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
79
---
39
---
80
blockjob.c | 8 ++++++--
40
qapi/block-export.json | 8 +-
81
1 file changed, 6 insertions(+), 2 deletions(-)
41
docs/interop/nbd.txt | 1 +
82
42
docs/tools/qemu-nbd.rst | 3 +-
83
diff --git a/blockjob.c b/blockjob.c
43
include/block/nbd.h | 3 +-
84
index XXXXXXX..XXXXXXX 100644
44
blockdev-nbd.c | 5 +
85
--- a/blockjob.c
45
nbd/server.c | 10 +-
86
+++ b/blockjob.c
46
MAINTAINERS | 1 +
87
@@ -XXX,XX +XXX,XX @@ int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
47
tests/qemu-iotests/tests/nbd-multiconn | 145 ++++++++++++++++++
88
uint64_t perm, uint64_t shared_perm, Error **errp)
48
tests/qemu-iotests/tests/nbd-multiconn.out | 5 +
49
.../tests/nbd-qemu-allocation.out | 2 +-
50
10 files changed, 172 insertions(+), 11 deletions(-)
51
create mode 100755 tests/qemu-iotests/tests/nbd-multiconn
52
create mode 100644 tests/qemu-iotests/tests/nbd-multiconn.out
53
54
diff --git a/qapi/block-export.json b/qapi/block-export.json
55
index XXXXXXX..XXXXXXX 100644
56
--- a/qapi/block-export.json
57
+++ b/qapi/block-export.json
58
@@ -XXX,XX +XXX,XX @@
59
# recreated on the fly while the NBD server is active.
60
# If missing, it will default to denying access (since 4.0).
61
# @max-connections: The maximum number of connections to allow at the same
62
-# time, 0 for unlimited. (since 5.2; default: 0)
63
+# time, 0 for unlimited. Setting this to 1 also stops
64
+# the server from advertising multiple client support
65
+# (since 5.2; default: 0)
66
#
67
# Since: 4.2
68
##
69
@@ -XXX,XX +XXX,XX @@
70
# recreated on the fly while the NBD server is active.
71
# If missing, it will default to denying access (since 4.0).
72
# @max-connections: The maximum number of connections to allow at the same
73
-# time, 0 for unlimited. (since 5.2; default: 0)
74
+# time, 0 for unlimited. Setting this to 1 also stops
75
+# the server from advertising multiple client support
76
+# (since 5.2; default: 0).
77
#
78
# Returns: error if the server is already running.
79
#
80
diff --git a/docs/interop/nbd.txt b/docs/interop/nbd.txt
81
index XXXXXXX..XXXXXXX 100644
82
--- a/docs/interop/nbd.txt
83
+++ b/docs/interop/nbd.txt
84
@@ -XXX,XX +XXX,XX @@ NBD_CMD_BLOCK_STATUS for "qemu:dirty-bitmap:", NBD_CMD_CACHE
85
* 4.2: NBD_FLAG_CAN_MULTI_CONN for shareable read-only exports,
86
NBD_CMD_FLAG_FAST_ZERO
87
* 5.2: NBD_CMD_BLOCK_STATUS for "qemu:allocation-depth"
88
+* 7.1: NBD_FLAG_CAN_MULTI_CONN for shareable writable exports
89
diff --git a/docs/tools/qemu-nbd.rst b/docs/tools/qemu-nbd.rst
90
index XXXXXXX..XXXXXXX 100644
91
--- a/docs/tools/qemu-nbd.rst
92
+++ b/docs/tools/qemu-nbd.rst
93
@@ -XXX,XX +XXX,XX @@ driver options if :option:`--image-opts` is specified.
94
.. option:: -e, --shared=NUM
95
96
Allow up to *NUM* clients to share the device (default
97
- ``1``), 0 for unlimited. Safe for readers, but for now,
98
- consistency is not guaranteed between multiple writers.
99
+ ``1``), 0 for unlimited.
100
101
.. option:: -t, --persistent
102
103
diff --git a/include/block/nbd.h b/include/block/nbd.h
104
index XXXXXXX..XXXXXXX 100644
105
--- a/include/block/nbd.h
106
+++ b/include/block/nbd.h
107
@@ -XXX,XX +XXX,XX @@
108
/*
109
- * Copyright (C) 2016-2020 Red Hat, Inc.
110
+ * Copyright (C) 2016-2022 Red Hat, Inc.
111
* Copyright (C) 2005 Anthony Liguori <anthony@codemonkey.ws>
112
*
113
* Network Block Device
114
@@ -XXX,XX +XXX,XX @@ void nbd_client_put(NBDClient *client);
115
116
void nbd_server_is_qemu_nbd(int max_connections);
117
bool nbd_server_is_running(void);
118
+int nbd_server_max_connections(void);
119
void nbd_server_start(SocketAddress *addr, const char *tls_creds,
120
const char *tls_authz, uint32_t max_connections,
121
Error **errp);
122
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/blockdev-nbd.c
125
+++ b/blockdev-nbd.c
126
@@ -XXX,XX +XXX,XX @@ bool nbd_server_is_running(void)
127
return nbd_server || qemu_nbd_connections >= 0;
128
}
129
130
+int nbd_server_max_connections(void)
131
+{
132
+ return nbd_server ? nbd_server->max_connections : qemu_nbd_connections;
133
+}
134
+
135
static void nbd_blockdev_client_closed(NBDClient *client, bool ignored)
89
{
136
{
90
BdrvChild *c;
137
nbd_client_put(client);
91
+ bool need_context_ops;
138
diff --git a/nbd/server.c b/nbd/server.c
92
139
index XXXXXXX..XXXXXXX 100644
93
bdrv_ref(bs);
140
--- a/nbd/server.c
94
- if (job->job.aio_context != qemu_get_aio_context()) {
141
+++ b/nbd/server.c
95
+
142
@@ -XXX,XX +XXX,XX @@
96
+ need_context_ops = bdrv_get_aio_context(bs) != job->job.aio_context;
143
/*
97
+
144
- * Copyright (C) 2016-2021 Red Hat, Inc.
98
+ if (need_context_ops && job->job.aio_context != qemu_get_aio_context()) {
145
+ * Copyright (C) 2016-2022 Red Hat, Inc.
99
aio_context_release(job->job.aio_context);
146
* Copyright (C) 2005 Anthony Liguori <anthony@codemonkey.ws>
100
}
147
*
101
c = bdrv_root_attach_child(bs, name, &child_job, 0,
148
* Network Block Device Server Side
102
job->job.aio_context, perm, shared_perm, job,
149
@@ -XXX,XX +XXX,XX @@ static int nbd_export_create(BlockExport *blk_exp, BlockExportOptions *exp_args,
103
errp);
150
int64_t size;
104
- if (job->job.aio_context != qemu_get_aio_context()) {
151
uint64_t perm, shared_perm;
105
+ if (need_context_ops && job->job.aio_context != qemu_get_aio_context()) {
152
bool readonly = !exp_args->writable;
106
aio_context_acquire(job->job.aio_context);
153
- bool shared = !exp_args->writable;
107
}
154
BlockDirtyBitmapOrStrList *bitmaps;
108
if (c == NULL) {
155
size_t i;
156
int ret;
157
@@ -XXX,XX +XXX,XX @@ static int nbd_export_create(BlockExport *blk_exp, BlockExportOptions *exp_args,
158
exp->description = g_strdup(arg->description);
159
exp->nbdflags = (NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_FLUSH |
160
NBD_FLAG_SEND_FUA | NBD_FLAG_SEND_CACHE);
161
+
162
+ if (nbd_server_max_connections() != 1) {
163
+ exp->nbdflags |= NBD_FLAG_CAN_MULTI_CONN;
164
+ }
165
if (readonly) {
166
exp->nbdflags |= NBD_FLAG_READ_ONLY;
167
- if (shared) {
168
- exp->nbdflags |= NBD_FLAG_CAN_MULTI_CONN;
169
- }
170
} else {
171
exp->nbdflags |= (NBD_FLAG_SEND_TRIM | NBD_FLAG_SEND_WRITE_ZEROES |
172
NBD_FLAG_SEND_FAST_ZERO);
173
diff --git a/MAINTAINERS b/MAINTAINERS
174
index XXXXXXX..XXXXXXX 100644
175
--- a/MAINTAINERS
176
+++ b/MAINTAINERS
177
@@ -XXX,XX +XXX,XX @@ F: qemu-nbd.*
178
F: blockdev-nbd.c
179
F: docs/interop/nbd.txt
180
F: docs/tools/qemu-nbd.rst
181
+F: tests/qemu-iotests/tests/*nbd*
182
T: git https://repo.or.cz/qemu/ericb.git nbd
183
T: git https://src.openvz.org/scm/~vsementsov/qemu.git nbd
184
185
diff --git a/tests/qemu-iotests/tests/nbd-multiconn b/tests/qemu-iotests/tests/nbd-multiconn
186
new file mode 100755
187
index XXXXXXX..XXXXXXX
188
--- /dev/null
189
+++ b/tests/qemu-iotests/tests/nbd-multiconn
190
@@ -XXX,XX +XXX,XX @@
191
+#!/usr/bin/env python3
192
+# group: rw auto quick
193
+#
194
+# Test cases for NBD multi-conn advertisement
195
+#
196
+# Copyright (C) 2022 Red Hat, Inc.
197
+#
198
+# This program is free software; you can redistribute it and/or modify
199
+# it under the terms of the GNU General Public License as published by
200
+# the Free Software Foundation; either version 2 of the License, or
201
+# (at your option) any later version.
202
+#
203
+# This program is distributed in the hope that it will be useful,
204
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
205
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
206
+# GNU General Public License for more details.
207
+#
208
+# You should have received a copy of the GNU General Public License
209
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
210
+
211
+import os
212
+from contextlib import contextmanager
213
+import iotests
214
+from iotests import qemu_img_create, qemu_io
215
+
216
+
217
+disk = os.path.join(iotests.test_dir, 'disk')
218
+size = '4M'
219
+nbd_sock = os.path.join(iotests.sock_dir, 'nbd_sock')
220
+nbd_uri = 'nbd+unix:///{}?socket=' + nbd_sock
221
+
222
+
223
+@contextmanager
224
+def open_nbd(export_name):
225
+ h = nbd.NBD()
226
+ try:
227
+ h.connect_uri(nbd_uri.format(export_name))
228
+ yield h
229
+ finally:
230
+ h.shutdown()
231
+
232
+class TestNbdMulticonn(iotests.QMPTestCase):
233
+ def setUp(self):
234
+ qemu_img_create('-f', iotests.imgfmt, disk, size)
235
+ qemu_io('-c', 'w -P 1 0 2M', '-c', 'w -P 2 2M 2M', disk)
236
+
237
+ self.vm = iotests.VM()
238
+ self.vm.launch()
239
+ result = self.vm.qmp('blockdev-add', {
240
+ 'driver': 'qcow2',
241
+ 'node-name': 'n',
242
+ 'file': {'driver': 'file', 'filename': disk}
243
+ })
244
+ self.assert_qmp(result, 'return', {})
245
+
246
+ def tearDown(self):
247
+ self.vm.shutdown()
248
+ os.remove(disk)
249
+ try:
250
+ os.remove(nbd_sock)
251
+ except OSError:
252
+ pass
253
+
254
+ @contextmanager
255
+ def run_server(self, max_connections=None):
256
+ args = {
257
+ 'addr': {
258
+ 'type': 'unix',
259
+ 'data': {'path': nbd_sock}
260
+ }
261
+ }
262
+ if max_connections is not None:
263
+ args['max-connections'] = max_connections
264
+
265
+ result = self.vm.qmp('nbd-server-start', args)
266
+ self.assert_qmp(result, 'return', {})
267
+ yield
268
+
269
+ result = self.vm.qmp('nbd-server-stop')
270
+ self.assert_qmp(result, 'return', {})
271
+
272
+ def add_export(self, name, writable=None):
273
+ args = {
274
+ 'type': 'nbd',
275
+ 'id': name,
276
+ 'node-name': 'n',
277
+ 'name': name,
278
+ }
279
+ if writable is not None:
280
+ args['writable'] = writable
281
+
282
+ result = self.vm.qmp('block-export-add', args)
283
+ self.assert_qmp(result, 'return', {})
284
+
285
+ def test_default_settings(self):
286
+ with self.run_server():
287
+ self.add_export('r')
288
+ self.add_export('w', writable=True)
289
+ with open_nbd('r') as h:
290
+ self.assertTrue(h.can_multi_conn())
291
+ with open_nbd('w') as h:
292
+ self.assertTrue(h.can_multi_conn())
293
+
294
+ def test_limited_connections(self):
295
+ with self.run_server(max_connections=1):
296
+ self.add_export('r')
297
+ self.add_export('w', writable=True)
298
+ with open_nbd('r') as h:
299
+ self.assertFalse(h.can_multi_conn())
300
+ with open_nbd('w') as h:
301
+ self.assertFalse(h.can_multi_conn())
302
+
303
+ def test_parallel_writes(self):
304
+ with self.run_server():
305
+ self.add_export('w', writable=True)
306
+
307
+ clients = [nbd.NBD() for _ in range(3)]
308
+ for c in clients:
309
+ c.connect_uri(nbd_uri.format('w'))
310
+ self.assertTrue(c.can_multi_conn())
311
+
312
+ initial_data = clients[0].pread(1024 * 1024, 0)
313
+ self.assertEqual(initial_data, b'\x01' * 1024 * 1024)
314
+
315
+ updated_data = b'\x03' * 1024 * 1024
316
+ clients[1].pwrite(updated_data, 0)
317
+ clients[2].flush()
318
+ current_data = clients[0].pread(1024 * 1024, 0)
319
+
320
+ self.assertEqual(updated_data, current_data)
321
+
322
+ for i in range(3):
323
+ clients[i].shutdown()
324
+
325
+
326
+if __name__ == '__main__':
327
+ try:
328
+ # Easier to use libnbd than to try and set up parallel
329
+ # 'qemu-nbd --list' or 'qemu-io' processes, but not all systems
330
+ # have libnbd installed.
331
+ import nbd # type: ignore
332
+
333
+ iotests.main(supported_fmts=['qcow2'])
334
+ except ImportError:
335
+ iotests.notrun('libnbd not installed')
336
diff --git a/tests/qemu-iotests/tests/nbd-multiconn.out b/tests/qemu-iotests/tests/nbd-multiconn.out
337
new file mode 100644
338
index XXXXXXX..XXXXXXX
339
--- /dev/null
340
+++ b/tests/qemu-iotests/tests/nbd-multiconn.out
341
@@ -XXX,XX +XXX,XX @@
342
+...
343
+----------------------------------------------------------------------
344
+Ran 3 tests
345
+
346
+OK
347
diff --git a/tests/qemu-iotests/tests/nbd-qemu-allocation.out b/tests/qemu-iotests/tests/nbd-qemu-allocation.out
348
index XXXXXXX..XXXXXXX 100644
349
--- a/tests/qemu-iotests/tests/nbd-qemu-allocation.out
350
+++ b/tests/qemu-iotests/tests/nbd-qemu-allocation.out
351
@@ -XXX,XX +XXX,XX @@ wrote 2097152/2097152 bytes at offset 1048576
352
exports available: 1
353
export: ''
354
size: 4194304
355
- flags: 0x58f ( readonly flush fua df multi cache )
356
+ flags: 0x48f ( readonly flush fua df cache )
357
min block: 1
358
opt block: 4096
359
max block: 33554432
109
--
360
--
110
2.29.2
361
2.35.3
111
112
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
To disallow certain refcount_bits values, some _unsupported_imgopts
3
common.rc has some complicated logic to find the common.config that
4
invocations look like "refcount_bits=1[^0-9]", i.e. they match an
4
dates back to xfstests and is completely unnecessary now. Just include
5
integer boundary with [^0-9]. This expression does not match the end of
5
the contents of the file.
6
the string, though, so it breaks down when refcount_bits is the last
7
option (which it tends to be after the rewrite of the check script in
8
Python).
9
6
10
Those invocations could use \b or \> instead, but those are not
7
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
11
portable. They could use something like \([^0-9]\|$\), but that would
8
Message-Id: <20220505094723.732116-1-pbonzini@redhat.com>
12
be cumbersome. To make it simple and keep the existing invocations
13
working, just let _unsupported_imgopts match the regex against $IMGOPTS
14
plus a trailing space.
15
16
Suggested-by: Eric Blake <eblake@redhat.com>
17
Signed-off-by: Max Reitz <mreitz@redhat.com>
18
Message-Id: <20210210095128.22732-1-mreitz@redhat.com>
19
Reviewed-by: Eric Blake <eblake@redhat.com>
20
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
21
---
10
---
22
tests/qemu-iotests/common.rc | 4 +++-
11
tests/qemu-iotests/common.config | 41 --------------------------------
23
1 file changed, 3 insertions(+), 1 deletion(-)
12
tests/qemu-iotests/common.rc | 31 ++++++++++++++----------
13
2 files changed, 19 insertions(+), 53 deletions(-)
14
delete mode 100644 tests/qemu-iotests/common.config
24
15
16
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
17
deleted file mode 100644
18
index XXXXXXX..XXXXXXX
19
--- a/tests/qemu-iotests/common.config
20
+++ /dev/null
21
@@ -XXX,XX +XXX,XX @@
22
-#!/usr/bin/env bash
23
-#
24
-# Copyright (C) 2009 Red Hat, Inc.
25
-# Copyright (c) 2000-2003,2006 Silicon Graphics, Inc. All Rights Reserved.
26
-#
27
-# This program is free software; you can redistribute it and/or
28
-# modify it under the terms of the GNU General Public License as
29
-# published by the Free Software Foundation.
30
-#
31
-# This program is distributed in the hope that it would be useful,
32
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
33
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34
-# GNU General Public License for more details.
35
-#
36
-# You should have received a copy of the GNU General Public License
37
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
38
-#
39
-# all tests should use a common language setting to prevent golden
40
-# output mismatches.
41
-export LANG=C
42
-
43
-PATH=".:$PATH"
44
-
45
-HOSTOS=$(uname -s)
46
-arch=$(uname -m)
47
-[[ "$arch" =~ "ppc64" ]] && qemu_arch=ppc64 || qemu_arch="$arch"
48
-
49
-# make sure we have a standard umask
50
-umask 022
51
-
52
-_optstr_add()
53
-{
54
- if [ -n "$1" ]; then
55
- echo "$1,$2"
56
- else
57
- echo "$2"
58
- fi
59
-}
60
-
61
-# make sure this script returns success
62
-true
25
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
63
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
26
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
27
--- a/tests/qemu-iotests/common.rc
65
--- a/tests/qemu-iotests/common.rc
28
+++ b/tests/qemu-iotests/common.rc
66
+++ b/tests/qemu-iotests/common.rc
29
@@ -XXX,XX +XXX,XX @@ _unsupported_imgopts()
67
@@ -XXX,XX +XXX,XX @@
68
# along with this program. If not, see <http://www.gnu.org/licenses/>.
69
#
70
71
+export LANG=C
72
+
73
+PATH=".:$PATH"
74
+
75
+HOSTOS=$(uname -s)
76
+arch=$(uname -m)
77
+[[ "$arch" =~ "ppc64" ]] && qemu_arch=ppc64 || qemu_arch="$arch"
78
+
79
+# make sure we have a standard umask
80
+umask 022
81
+
82
# bail out, setting up .notrun file
83
_notrun()
30
{
84
{
31
for bad_opt
85
@@ -XXX,XX +XXX,XX @@ peek_file_raw()
32
do
86
dd if="$1" bs=1 skip="$2" count="$3" status=none
33
- if echo "$IMGOPTS" | grep -q 2>/dev/null "$bad_opt"
87
}
34
+ # Add a space so tests can match for whitespace that marks the
88
35
+ # end of an option (\b or \> are not portable)
89
-config=common.config
36
+ if echo "$IMGOPTS " | grep -q 2>/dev/null "$bad_opt"
90
-test -f $config || config=../common.config
37
then
91
-if ! test -f $config
38
_notrun "not suitable for image option: $bad_opt"
92
-then
39
fi
93
- echo "$0: failed to find common.config"
94
- exit 1
95
-fi
96
-if ! . $config
97
- then
98
- echo "$0: failed to source common.config"
99
- exit 1
100
-fi
101
+_optstr_add()
102
+{
103
+ if [ -n "$1" ]; then
104
+ echo "$1,$2"
105
+ else
106
+ echo "$2"
107
+ fi
108
+}
109
110
# Set the variables to the empty string to turn Valgrind off
111
# for specific processes, e.g.
40
--
112
--
41
2.29.2
113
2.35.3
42
43
diff view generated by jsdifflib