Skip to content

Commit 0b63052

Browse files
committed
Merge tag 'pull-nbd-2023-09-07-v2' of https://repo.or.cz/qemu/ericb into staging
NBD patches for 2023-09-07 - Andrey Drobyshev - fix regression in iotest 197 under -nbd - Stefan Hajnoczi - allow coroutine read and write context to split across threads - Philippe Mathieu-Daudé - remove a VLA allocation - Denis V. Lunev - fix regression in iotest 233 with qemu-nbd -v --fork # -----BEGIN PGP SIGNATURE----- # # iQEzBAABCAAdFiEEccLMIrHEYCkn0vOqp6FrSiUnQ2oFAmT7EsUACgkQp6FrSiUn # Q2qiKgf9EqCWPmcsH2nvXrDvZmDc0/I4tineaNY+hSdPtSb6RFA1IH8AvzkrkPYU # 9ojX6QFp1Z30fUs+pwweQhBMYta03QyjCFhsbPRmDq391dtIDCeww3o+RD1kw/pg # 2ZC+P9N1U3pi2Hi8FhxH17GYYgOQnHMKM9gt1V7JOQvFsDFWbTo9sFj8p/BPoWxV # I3TeLQDWqVnNjf57lG2pwhdKc8DbKoqRmA3XNiXiKI5inEBeRJsTdMMGn4YWpwJE # Y5imM/PbyCqRKQ6MYyJenVk4QVTe1IKO6D4vf1ZHLDBEiaw9NaeYHlk6lnDC4O9v # PeTycAwND6cMKYlKMyEzcJXv9IdRBw== # =jAZi # -----END PGP SIGNATURE----- # gpg: Signature made Fri 08 Sep 2023 08:25:41 EDT # gpg: using RSA key 71C2CC22B1C4602927D2F3AAA7A16B4A2527436A # gpg: Good signature from "Eric Blake <[email protected]>" [full] # gpg: aka "Eric Blake (Free Software Programmer) <[email protected]>" [full] # gpg: aka "[jpeg image of size 6874]" [full] # Primary key fingerprint: 71C2 CC22 B1C4 6029 27D2 F3AA A7A1 6B4A 2527 436A * tag 'pull-nbd-2023-09-07-v2' of https://repo.or.cz/qemu/ericb: qemu-nbd: document -v behavior in respect to --fork in man qemu-nbd: Restore "qemu-nbd -v --fork" output qemu-nbd: invent nbd_client_release_pipe() helper qemu-nbd: put saddr into into struct NbdClientOpts qemu-nbd: move srcpath into struct NbdClientOpts qemu-nbd: define struct NbdClientOpts when HAVE_NBD_DEVICE is not defined qemu-nbd: improve error message for dup2 error util/iov: Avoid dynamic stack allocation io: follow coroutine AioContext in qio_channel_yield() io: check there are no qio_channel_yield() coroutines during ->finalize() nbd: drop unused nbd_start_negotiate() aio_context argument nbd: drop unused nbd_receive_negotiate() aio_context argument qemu-iotests/197: use more generic commands for formats other than qcow2 Signed-off-by: Stefan Hajnoczi <[email protected]>
2 parents 2f352bc + 35e087d commit 0b63052

File tree

24 files changed

+325
-216
lines changed

24 files changed

+325
-216
lines changed

block/nbd.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ int coroutine_fn nbd_co_do_establish_connection(BlockDriverState *bs,
352352
}
353353

354354
qio_channel_set_blocking(s->ioc, false, NULL);
355-
qio_channel_attach_aio_context(s->ioc, bdrv_get_aio_context(bs));
355+
qio_channel_set_follow_coroutine_ctx(s->ioc, true);
356356

357357
/* successfully connected */
358358
WITH_QEMU_LOCK_GUARD(&s->requests_lock) {
@@ -397,7 +397,6 @@ static void coroutine_fn GRAPH_RDLOCK nbd_reconnect_attempt(BDRVNBDState *s)
397397

398398
/* Finalize previous connection if any */
399399
if (s->ioc) {
400-
qio_channel_detach_aio_context(s->ioc);
401400
yank_unregister_function(BLOCKDEV_YANK_INSTANCE(s->bs->node_name),
402401
nbd_yank, s->bs);
403402
object_unref(OBJECT(s->ioc));
@@ -2089,10 +2088,6 @@ static void nbd_attach_aio_context(BlockDriverState *bs,
20892088
* the reconnect_delay_timer cannot be active here.
20902089
*/
20912090
assert(!s->reconnect_delay_timer);
2092-
2093-
if (s->ioc) {
2094-
qio_channel_attach_aio_context(s->ioc, new_context);
2095-
}
20962091
}
20972092

20982093
static void nbd_detach_aio_context(BlockDriverState *bs)
@@ -2101,10 +2096,6 @@ static void nbd_detach_aio_context(BlockDriverState *bs)
21012096

21022097
assert(!s->open_timer);
21032098
assert(!s->reconnect_delay_timer);
2104-
2105-
if (s->ioc) {
2106-
qio_channel_detach_aio_context(s->ioc);
2107-
}
21082099
}
21092100

21102101
static BlockDriver bdrv_nbd = {

docs/tools/qemu-nbd.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,9 @@ driver options if :option:`--image-opts` is specified.
197197

198198
.. option:: -v, --verbose
199199

200-
Display extra debugging information.
200+
Display extra debugging information. This option also keeps the original
201+
*STDERR* stream open if the ``qemu-nbd`` process is daemonized due to
202+
other options like :option:`--fork` or :option:`-c`.
201203

202204
.. option:: -h, --help
203205

include/block/nbd.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,7 @@ typedef struct NBDExportInfo {
324324
char **contexts;
325325
} NBDExportInfo;
326326

327-
int nbd_receive_negotiate(AioContext *aio_context, QIOChannel *ioc,
328-
QCryptoTLSCreds *tlscreds,
327+
int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCreds *tlscreds,
329328
const char *hostname, QIOChannel **outioc,
330329
NBDExportInfo *info, Error **errp);
331330
void nbd_free_export_list(NBDExportInfo *info, int count);

include/io/channel-util.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,27 @@
4949
QIOChannel *qio_channel_new_fd(int fd,
5050
Error **errp);
5151

52+
/**
53+
* qio_channel_util_set_aio_fd_handler:
54+
* @read_fd: the file descriptor for the read handler
55+
* @read_ctx: the AioContext for the read handler
56+
* @io_read: the read handler
57+
* @write_fd: the file descriptor for the write handler
58+
* @write_ctx: the AioContext for the write handler
59+
* @io_write: the write handler
60+
* @opaque: the opaque argument to the read and write handler
61+
*
62+
* Set the read and write handlers when @read_ctx and @write_ctx are non-NULL,
63+
* respectively. To leave a handler in its current state, pass a NULL
64+
* AioContext. To clear a handler, pass a non-NULL AioContext and a NULL
65+
* handler.
66+
*/
67+
void qio_channel_util_set_aio_fd_handler(int read_fd,
68+
AioContext *read_ctx,
69+
IOHandler *io_read,
70+
int write_fd,
71+
AioContext *write_ctx,
72+
IOHandler *io_write,
73+
void *opaque);
74+
5275
#endif /* QIO_CHANNEL_UTIL_H */

include/io/channel.h

Lines changed: 30 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,11 @@ struct QIOChannel {
8181
Object parent;
8282
unsigned int features; /* bitmask of QIOChannelFeatures */
8383
char *name;
84-
AioContext *ctx;
84+
AioContext *read_ctx;
8585
Coroutine *read_coroutine;
86+
AioContext *write_ctx;
8687
Coroutine *write_coroutine;
88+
bool follow_coroutine_ctx;
8789
#ifdef _WIN32
8890
HANDLE event; /* For use with GSource on Win32 */
8991
#endif
@@ -140,8 +142,9 @@ struct QIOChannelClass {
140142
int whence,
141143
Error **errp);
142144
void (*io_set_aio_fd_handler)(QIOChannel *ioc,
143-
AioContext *ctx,
145+
AioContext *read_ctx,
144146
IOHandler *io_read,
147+
AioContext *write_ctx,
145148
IOHandler *io_write,
146149
void *opaque);
147150
int (*io_flush)(QIOChannel *ioc,
@@ -498,6 +501,21 @@ int qio_channel_set_blocking(QIOChannel *ioc,
498501
bool enabled,
499502
Error **errp);
500503

504+
/**
505+
* qio_channel_set_follow_coroutine_ctx:
506+
* @ioc: the channel object
507+
* @enabled: whether or not to follow the coroutine's AioContext
508+
*
509+
* If @enabled is true, calls to qio_channel_yield() use the current
510+
* coroutine's AioContext. Usually this is desirable.
511+
*
512+
* If @enabled is false, calls to qio_channel_yield() use the global iohandler
513+
* AioContext. This is may be used by coroutines that run in the main loop and
514+
* do not wish to respond to I/O during nested event loops. This is the
515+
* default for compatibility with code that is not aware of AioContexts.
516+
*/
517+
void qio_channel_set_follow_coroutine_ctx(QIOChannel *ioc, bool enabled);
518+
501519
/**
502520
* qio_channel_close:
503521
* @ioc: the channel object
@@ -703,41 +721,6 @@ GSource *qio_channel_add_watch_source(QIOChannel *ioc,
703721
GDestroyNotify notify,
704722
GMainContext *context);
705723

706-
/**
707-
* qio_channel_attach_aio_context:
708-
* @ioc: the channel object
709-
* @ctx: the #AioContext to set the handlers on
710-
*
711-
* Request that qio_channel_yield() sets I/O handlers on
712-
* the given #AioContext. If @ctx is %NULL, qio_channel_yield()
713-
* uses QEMU's main thread event loop.
714-
*
715-
* You can move a #QIOChannel from one #AioContext to another even if
716-
* I/O handlers are set for a coroutine. However, #QIOChannel provides
717-
* no synchronization between the calls to qio_channel_yield() and
718-
* qio_channel_attach_aio_context().
719-
*
720-
* Therefore you should first call qio_channel_detach_aio_context()
721-
* to ensure that the coroutine is not entered concurrently. Then,
722-
* while the coroutine has yielded, call qio_channel_attach_aio_context(),
723-
* and then aio_co_schedule() to place the coroutine on the new
724-
* #AioContext. The calls to qio_channel_detach_aio_context()
725-
* and qio_channel_attach_aio_context() should be protected with
726-
* aio_context_acquire() and aio_context_release().
727-
*/
728-
void qio_channel_attach_aio_context(QIOChannel *ioc,
729-
AioContext *ctx);
730-
731-
/**
732-
* qio_channel_detach_aio_context:
733-
* @ioc: the channel object
734-
*
735-
* Disable any I/O handlers set by qio_channel_yield(). With the
736-
* help of aio_co_schedule(), this allows moving a coroutine that was
737-
* paused by qio_channel_yield() to another context.
738-
*/
739-
void qio_channel_detach_aio_context(QIOChannel *ioc);
740-
741724
/**
742725
* qio_channel_yield:
743726
* @ioc: the channel object
@@ -785,19 +768,27 @@ void qio_channel_wait(QIOChannel *ioc,
785768
/**
786769
* qio_channel_set_aio_fd_handler:
787770
* @ioc: the channel object
788-
* @ctx: the AioContext to set the handlers on
771+
* @read_ctx: the AioContext to set the read handler on or NULL
789772
* @io_read: the read handler
773+
* @write_ctx: the AioContext to set the write handler on or NULL
790774
* @io_write: the write handler
791775
* @opaque: the opaque value passed to the handler
792776
*
793777
* This is used internally by qio_channel_yield(). It can
794778
* be used by channel implementations to forward the handlers
795779
* to another channel (e.g. from #QIOChannelTLS to the
796780
* underlying socket).
781+
*
782+
* When @read_ctx is NULL, don't touch the read handler. When @write_ctx is
783+
* NULL, don't touch the write handler. Note that setting the read handler
784+
* clears the write handler, and vice versa, if they share the same AioContext.
785+
* Therefore the caller must pass both handlers together when sharing the same
786+
* AioContext.
797787
*/
798788
void qio_channel_set_aio_fd_handler(QIOChannel *ioc,
799-
AioContext *ctx,
789+
AioContext *read_ctx,
800790
IOHandler *io_read,
791+
AioContext *write_ctx,
801792
IOHandler *io_write,
802793
void *opaque);
803794

include/qemu/vhost-user-server.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ typedef struct {
4343
unsigned int in_flight; /* atomic */
4444

4545
/* Protected by ctx lock */
46+
bool in_qio_channel_yield;
4647
bool wait_idle;
4748
VuDev vu_dev;
4849
QIOChannel *ioc; /* The I/O channel with the client */

io/channel-command.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "qemu/osdep.h"
2222
#include "io/channel-command.h"
23+
#include "io/channel-util.h"
2324
#include "io/channel-watch.h"
2425
#include "qapi/error.h"
2526
#include "qemu/module.h"
@@ -331,14 +332,17 @@ static int qio_channel_command_close(QIOChannel *ioc,
331332

332333

333334
static void qio_channel_command_set_aio_fd_handler(QIOChannel *ioc,
334-
AioContext *ctx,
335+
AioContext *read_ctx,
335336
IOHandler *io_read,
337+
AioContext *write_ctx,
336338
IOHandler *io_write,
337339
void *opaque)
338340
{
339341
QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc);
340-
aio_set_fd_handler(ctx, cioc->readfd, io_read, NULL, NULL, NULL, opaque);
341-
aio_set_fd_handler(ctx, cioc->writefd, NULL, io_write, NULL, NULL, opaque);
342+
343+
qio_channel_util_set_aio_fd_handler(cioc->readfd, read_ctx, io_read,
344+
cioc->writefd, write_ctx, io_write,
345+
opaque);
342346
}
343347

344348

io/channel-file.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "qemu/osdep.h"
2222
#include "io/channel-file.h"
23+
#include "io/channel-util.h"
2324
#include "io/channel-watch.h"
2425
#include "qapi/error.h"
2526
#include "qemu/module.h"
@@ -192,13 +193,17 @@ static int qio_channel_file_close(QIOChannel *ioc,
192193

193194

194195
static void qio_channel_file_set_aio_fd_handler(QIOChannel *ioc,
195-
AioContext *ctx,
196+
AioContext *read_ctx,
196197
IOHandler *io_read,
198+
AioContext *write_ctx,
197199
IOHandler *io_write,
198200
void *opaque)
199201
{
200202
QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);
201-
aio_set_fd_handler(ctx, fioc->fd, io_read, io_write, NULL, NULL, opaque);
203+
204+
qio_channel_util_set_aio_fd_handler(fioc->fd, read_ctx, io_read,
205+
fioc->fd, write_ctx, io_write,
206+
opaque);
202207
}
203208

204209
static GSource *qio_channel_file_create_watch(QIOChannel *ioc,

io/channel-null.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,9 @@ qio_channel_null_close(QIOChannel *ioc,
128128

129129
static void
130130
qio_channel_null_set_aio_fd_handler(QIOChannel *ioc G_GNUC_UNUSED,
131-
AioContext *ctx G_GNUC_UNUSED,
131+
AioContext *read_ctx G_GNUC_UNUSED,
132132
IOHandler *io_read G_GNUC_UNUSED,
133+
AioContext *write_ctx G_GNUC_UNUSED,
133134
IOHandler *io_write G_GNUC_UNUSED,
134135
void *opaque G_GNUC_UNUSED)
135136
{

io/channel-socket.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "qapi/qapi-visit-sockets.h"
2323
#include "qemu/module.h"
2424
#include "io/channel-socket.h"
25+
#include "io/channel-util.h"
2526
#include "io/channel-watch.h"
2627
#include "trace.h"
2728
#include "qapi/clone-visitor.h"
@@ -893,13 +894,17 @@ qio_channel_socket_shutdown(QIOChannel *ioc,
893894
}
894895

895896
static void qio_channel_socket_set_aio_fd_handler(QIOChannel *ioc,
896-
AioContext *ctx,
897+
AioContext *read_ctx,
897898
IOHandler *io_read,
899+
AioContext *write_ctx,
898900
IOHandler *io_write,
899901
void *opaque)
900902
{
901903
QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
902-
aio_set_fd_handler(ctx, sioc->fd, io_read, io_write, NULL, NULL, opaque);
904+
905+
qio_channel_util_set_aio_fd_handler(sioc->fd, read_ctx, io_read,
906+
sioc->fd, write_ctx, io_write,
907+
opaque);
903908
}
904909

905910
static GSource *qio_channel_socket_create_watch(QIOChannel *ioc,

0 commit comments

Comments
 (0)