* [Qemu-devel] [PATCH v2 0/3] nbd: Drop BDS backpointer @ 2015-02-06 21:06 Max Reitz 2015-02-06 21:06 ` [Qemu-devel] [PATCH v2 1/3] " Max Reitz ` (3 more replies) 0 siblings, 4 replies; 9+ messages in thread From: Max Reitz @ 2015-02-06 21:06 UTC (permalink / raw) To: qemu-devel; +Cc: Kevin Wolf, Paolo Bonzini, Stefan Hajnoczi, Max Reitz Right now, bdrv_swap() on NBD BDSs results in a segmentation fault pretty much all of the time. This series fixes this. Note that this is not a common case, as bdrv_swap() is generally only performed on root BDSs (there are exceptions, though) and NBD BDSs normally have a format BDS above them. However, due to misconfiguration (or maybe it is not even a misconfiguration, but just a strange configuration) these cases may indeed occur. I took the second patch in this series from my other series "block: Rework bdrv_close_all()" (which has 21 patches itself and depends on 64 other patches, so making this series rely on that one probably would not have been a very good idea). v2: - Rename all functions which now take a BlockDriverState * instead of an NbdClientSession * from nbd_client_session_* to nbd_client_* [Paolo] - Rename nbd_client_close() in nbd.c to client_close() and make it static; otherwise, it would conflict with the "new" nbd_client_close() in block/nbd-client.c git-backport-diff against v1: Key: [----] : patches are identical [####] : number of functional differences between upstream/downstream patch [down] : patch is downstream-only The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively 001/3:[0089] [FC] 'nbd: Drop BDS backpointer' 002/3:[----] [--] 'iotests: Add "wait" functionality to _cleanup_qemu' 003/3:[----] [--] 'iotests: Add test for drive-mirror with NBD target' Max Reitz (3): nbd: Drop BDS backpointer iotests: Add "wait" functionality to _cleanup_qemu iotests: Add test for drive-mirror with NBD target block/nbd-client.c | 101 +++++++++++++++++++++-------------------- block/nbd-client.h | 34 +++++++------- block/nbd.c | 37 ++++++--------- include/block/nbd.h | 1 - nbd.c | 8 ++-- tests/qemu-iotests/094 | 81 +++++++++++++++++++++++++++++++++ tests/qemu-iotests/094.out | 11 +++++ tests/qemu-iotests/common.qemu | 12 ++++- tests/qemu-iotests/group | 1 + 9 files changed, 191 insertions(+), 95 deletions(-) create mode 100755 tests/qemu-iotests/094 create mode 100644 tests/qemu-iotests/094.out -- 2.1.0 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH v2 1/3] nbd: Drop BDS backpointer 2015-02-06 21:06 [Qemu-devel] [PATCH v2 0/3] nbd: Drop BDS backpointer Max Reitz @ 2015-02-06 21:06 ` Max Reitz 2015-02-09 12:33 ` Paolo Bonzini 2015-02-06 21:06 ` [Qemu-devel] [PATCH v2 2/3] iotests: Add "wait" functionality to _cleanup_qemu Max Reitz ` (2 subsequent siblings) 3 siblings, 1 reply; 9+ messages in thread From: Max Reitz @ 2015-02-06 21:06 UTC (permalink / raw) To: qemu-devel; +Cc: Kevin Wolf, Paolo Bonzini, Stefan Hajnoczi, Max Reitz Before this patch, the "opaque" pointer in an NBD BDS points to a BDRVNBDState, which contains an NbdClientSession object, which in turn contains a pointer to the BDS. This pointer may become invalid due to bdrv_swap(), so drop it, and instead pass the BDS directly to the nbd-client.c functions which then retrieve the NbdClientSession object from there. Signed-off-by: Max Reitz <mreitz@redhat.com> --- block/nbd-client.c | 101 +++++++++++++++++++++++++++------------------------- block/nbd-client.h | 34 +++++++++--------- block/nbd.c | 37 ++++++++----------- include/block/nbd.h | 1 - nbd.c | 8 ++--- 5 files changed, 87 insertions(+), 94 deletions(-) diff --git a/block/nbd-client.c b/block/nbd-client.c index 28bfb62..a01a37f 100644 --- a/block/nbd-client.c +++ b/block/nbd-client.c @@ -43,20 +43,23 @@ static void nbd_recv_coroutines_enter_all(NbdClientSession *s) } } -static void nbd_teardown_connection(NbdClientSession *client) +static void nbd_teardown_connection(BlockDriverState *bs) { + NbdClientSession *client = nbd_get_client_session(bs); + /* finish any pending coroutines */ shutdown(client->sock, 2); nbd_recv_coroutines_enter_all(client); - nbd_client_session_detach_aio_context(client); + nbd_client_detach_aio_context(bs); closesocket(client->sock); client->sock = -1; } static void nbd_reply_ready(void *opaque) { - NbdClientSession *s = opaque; + BlockDriverState *bs = opaque; + NbdClientSession *s = nbd_get_client_session(bs); uint64_t i; int ret; @@ -89,28 +92,29 @@ static void nbd_reply_ready(void *opaque) } fail: - nbd_teardown_connection(s); + nbd_teardown_connection(bs); } static void nbd_restart_write(void *opaque) { - NbdClientSession *s = opaque; + BlockDriverState *bs = opaque; - qemu_coroutine_enter(s->send_coroutine, NULL); + qemu_coroutine_enter(nbd_get_client_session(bs)->send_coroutine, NULL); } -static int nbd_co_send_request(NbdClientSession *s, - struct nbd_request *request, - QEMUIOVector *qiov, int offset) +static int nbd_co_send_request(BlockDriverState *bs, + struct nbd_request *request, + QEMUIOVector *qiov, int offset) { + NbdClientSession *s = nbd_get_client_session(bs); AioContext *aio_context; int rc, ret; qemu_co_mutex_lock(&s->send_mutex); s->send_coroutine = qemu_coroutine_self(); - aio_context = bdrv_get_aio_context(s->bs); + aio_context = bdrv_get_aio_context(bs); aio_set_fd_handler(aio_context, s->sock, - nbd_reply_ready, nbd_restart_write, s); + nbd_reply_ready, nbd_restart_write, bs); if (qiov) { if (!s->is_unix) { socket_set_cork(s->sock, 1); @@ -129,7 +133,7 @@ static int nbd_co_send_request(NbdClientSession *s, } else { rc = nbd_send_request(s->sock, request); } - aio_set_fd_handler(aio_context, s->sock, nbd_reply_ready, NULL, s); + aio_set_fd_handler(aio_context, s->sock, nbd_reply_ready, NULL, bs); s->send_coroutine = NULL; qemu_co_mutex_unlock(&s->send_mutex); return rc; @@ -195,10 +199,11 @@ static void nbd_coroutine_end(NbdClientSession *s, } } -static int nbd_co_readv_1(NbdClientSession *client, int64_t sector_num, +static int nbd_co_readv_1(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int offset) { + NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_READ }; struct nbd_reply reply; ssize_t ret; @@ -207,7 +212,7 @@ static int nbd_co_readv_1(NbdClientSession *client, int64_t sector_num, request.len = nb_sectors * 512; nbd_coroutine_start(client, &request); - ret = nbd_co_send_request(client, &request, NULL, 0); + ret = nbd_co_send_request(bs, &request, NULL, 0); if (ret < 0) { reply.error = -ret; } else { @@ -218,15 +223,16 @@ static int nbd_co_readv_1(NbdClientSession *client, int64_t sector_num, } -static int nbd_co_writev_1(NbdClientSession *client, int64_t sector_num, +static int nbd_co_writev_1(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int offset) { + NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_WRITE }; struct nbd_reply reply; ssize_t ret; - if (!bdrv_enable_write_cache(client->bs) && + if (!bdrv_enable_write_cache(bs) && (client->nbdflags & NBD_FLAG_SEND_FUA)) { request.type |= NBD_CMD_FLAG_FUA; } @@ -235,7 +241,7 @@ static int nbd_co_writev_1(NbdClientSession *client, int64_t sector_num, request.len = nb_sectors * 512; nbd_coroutine_start(client, &request); - ret = nbd_co_send_request(client, &request, qiov, offset); + ret = nbd_co_send_request(bs, &request, qiov, offset); if (ret < 0) { reply.error = -ret; } else { @@ -249,14 +255,13 @@ static int nbd_co_writev_1(NbdClientSession *client, int64_t sector_num, * remain aligned to 4K. */ #define NBD_MAX_SECTORS 2040 -int nbd_client_session_co_readv(NbdClientSession *client, int64_t sector_num, - int nb_sectors, QEMUIOVector *qiov) +int nbd_client_co_readv(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov) { int offset = 0; int ret; while (nb_sectors > NBD_MAX_SECTORS) { - ret = nbd_co_readv_1(client, sector_num, - NBD_MAX_SECTORS, qiov, offset); + ret = nbd_co_readv_1(bs, sector_num, NBD_MAX_SECTORS, qiov, offset); if (ret < 0) { return ret; } @@ -264,17 +269,16 @@ int nbd_client_session_co_readv(NbdClientSession *client, int64_t sector_num, sector_num += NBD_MAX_SECTORS; nb_sectors -= NBD_MAX_SECTORS; } - return nbd_co_readv_1(client, sector_num, nb_sectors, qiov, offset); + return nbd_co_readv_1(bs, sector_num, nb_sectors, qiov, offset); } -int nbd_client_session_co_writev(NbdClientSession *client, int64_t sector_num, - int nb_sectors, QEMUIOVector *qiov) +int nbd_client_co_writev(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov) { int offset = 0; int ret; while (nb_sectors > NBD_MAX_SECTORS) { - ret = nbd_co_writev_1(client, sector_num, - NBD_MAX_SECTORS, qiov, offset); + ret = nbd_co_writev_1(bs, sector_num, NBD_MAX_SECTORS, qiov, offset); if (ret < 0) { return ret; } @@ -282,11 +286,12 @@ int nbd_client_session_co_writev(NbdClientSession *client, int64_t sector_num, sector_num += NBD_MAX_SECTORS; nb_sectors -= NBD_MAX_SECTORS; } - return nbd_co_writev_1(client, sector_num, nb_sectors, qiov, offset); + return nbd_co_writev_1(bs, sector_num, nb_sectors, qiov, offset); } -int nbd_client_session_co_flush(NbdClientSession *client) +int nbd_client_co_flush(BlockDriverState *bs) { + NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_FLUSH }; struct nbd_reply reply; ssize_t ret; @@ -303,7 +308,7 @@ int nbd_client_session_co_flush(NbdClientSession *client) request.len = 0; nbd_coroutine_start(client, &request); - ret = nbd_co_send_request(client, &request, NULL, 0); + ret = nbd_co_send_request(bs, &request, NULL, 0); if (ret < 0) { reply.error = -ret; } else { @@ -313,9 +318,10 @@ int nbd_client_session_co_flush(NbdClientSession *client) return -reply.error; } -int nbd_client_session_co_discard(NbdClientSession *client, int64_t sector_num, - int nb_sectors) +int nbd_client_co_discard(BlockDriverState *bs, int64_t sector_num, + int nb_sectors) { + NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_TRIM }; struct nbd_reply reply; ssize_t ret; @@ -327,7 +333,7 @@ int nbd_client_session_co_discard(NbdClientSession *client, int64_t sector_num, request.len = nb_sectors * 512; nbd_coroutine_start(client, &request); - ret = nbd_co_send_request(client, &request, NULL, 0); + ret = nbd_co_send_request(bs, &request, NULL, 0); if (ret < 0) { reply.error = -ret; } else { @@ -338,43 +344,41 @@ int nbd_client_session_co_discard(NbdClientSession *client, int64_t sector_num, } -void nbd_client_session_detach_aio_context(NbdClientSession *client) +void nbd_client_detach_aio_context(BlockDriverState *bs) { - aio_set_fd_handler(bdrv_get_aio_context(client->bs), client->sock, - NULL, NULL, NULL); + aio_set_fd_handler(bdrv_get_aio_context(bs), + nbd_get_client_session(bs)->sock, NULL, NULL, NULL); } -void nbd_client_session_attach_aio_context(NbdClientSession *client, - AioContext *new_context) +void nbd_client_attach_aio_context(BlockDriverState *bs, + AioContext *new_context) { - aio_set_fd_handler(new_context, client->sock, - nbd_reply_ready, NULL, client); + aio_set_fd_handler(new_context, nbd_get_client_session(bs)->sock, + nbd_reply_ready, NULL, bs); } -void nbd_client_session_close(NbdClientSession *client) +void nbd_client_close(BlockDriverState *bs) { + NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_DISC, .from = 0, .len = 0 }; - if (!client->bs) { - return; - } if (client->sock == -1) { return; } nbd_send_request(client->sock, &request); - nbd_teardown_connection(client); - client->bs = NULL; + nbd_teardown_connection(bs); } -int nbd_client_session_init(NbdClientSession *client, BlockDriverState *bs, - int sock, const char *export, Error **errp) +int nbd_client_init(BlockDriverState *bs, int sock, const char *export, + Error **errp) { + NbdClientSession *client = nbd_get_client_session(bs); int ret; /* NBD handshake */ @@ -391,13 +395,12 @@ int nbd_client_session_init(NbdClientSession *client, BlockDriverState *bs, qemu_co_mutex_init(&client->send_mutex); qemu_co_mutex_init(&client->free_sema); - client->bs = bs; client->sock = sock; /* Now that we're connected, set the socket to be non-blocking and * kick the reply mechanism. */ qemu_set_nonblock(sock); - nbd_client_session_attach_aio_context(client, bdrv_get_aio_context(bs)); + nbd_client_attach_aio_context(bs, bdrv_get_aio_context(bs)); logout("Established connection with NBD server\n"); return 0; diff --git a/block/nbd-client.h b/block/nbd-client.h index cfeecc2..fa4ff42 100644 --- a/block/nbd-client.h +++ b/block/nbd-client.h @@ -31,24 +31,24 @@ typedef struct NbdClientSession { struct nbd_reply reply; bool is_unix; - - BlockDriverState *bs; } NbdClientSession; -int nbd_client_session_init(NbdClientSession *client, BlockDriverState *bs, - int sock, const char *export_name, Error **errp); -void nbd_client_session_close(NbdClientSession *client); - -int nbd_client_session_co_discard(NbdClientSession *client, int64_t sector_num, - int nb_sectors); -int nbd_client_session_co_flush(NbdClientSession *client); -int nbd_client_session_co_writev(NbdClientSession *client, int64_t sector_num, - int nb_sectors, QEMUIOVector *qiov); -int nbd_client_session_co_readv(NbdClientSession *client, int64_t sector_num, - int nb_sectors, QEMUIOVector *qiov); - -void nbd_client_session_detach_aio_context(NbdClientSession *client); -void nbd_client_session_attach_aio_context(NbdClientSession *client, - AioContext *new_context); +NbdClientSession *nbd_get_client_session(BlockDriverState *bs); + +int nbd_client_init(BlockDriverState *bs, int sock, const char *export_name, + Error **errp); +void nbd_client_close(BlockDriverState *bs); + +int nbd_client_co_discard(BlockDriverState *bs, int64_t sector_num, + int nb_sectors); +int nbd_client_co_flush(BlockDriverState *bs); +int nbd_client_co_writev(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov); +int nbd_client_co_readv(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov); + +void nbd_client_detach_aio_context(BlockDriverState *bs); +void nbd_client_attach_aio_context(BlockDriverState *bs, + AioContext *new_context); #endif /* NBD_CLIENT_H */ diff --git a/block/nbd.c b/block/nbd.c index b05d1d0..2f3b9ad 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -224,6 +224,12 @@ static void nbd_config(BDRVNBDState *s, QDict *options, char **export, } } +NbdClientSession *nbd_get_client_session(BlockDriverState *bs) +{ + BDRVNBDState *s = bs->opaque; + return &s->client; +} + static int nbd_establish_connection(BlockDriverState *bs, Error **errp) { BDRVNBDState *s = bs->opaque; @@ -271,7 +277,7 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags, } /* NBD handshake */ - result = nbd_client_session_init(&s->client, bs, sock, export, errp); + result = nbd_client_init(bs, sock, export, errp); g_free(export); return result; } @@ -279,26 +285,18 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags, static int nbd_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) { - BDRVNBDState *s = bs->opaque; - - return nbd_client_session_co_readv(&s->client, sector_num, - nb_sectors, qiov); + return nbd_client_co_readv(bs, sector_num, nb_sectors, qiov); } static int nbd_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) { - BDRVNBDState *s = bs->opaque; - - return nbd_client_session_co_writev(&s->client, sector_num, - nb_sectors, qiov); + return nbd_client_co_writev(bs, sector_num, nb_sectors, qiov); } static int nbd_co_flush(BlockDriverState *bs) { - BDRVNBDState *s = bs->opaque; - - return nbd_client_session_co_flush(&s->client); + return nbd_client_co_flush(bs); } static void nbd_refresh_limits(BlockDriverState *bs, Error **errp) @@ -310,10 +308,7 @@ static void nbd_refresh_limits(BlockDriverState *bs, Error **errp) static int nbd_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) { - BDRVNBDState *s = bs->opaque; - - return nbd_client_session_co_discard(&s->client, sector_num, - nb_sectors); + return nbd_client_co_discard(bs, sector_num, nb_sectors); } static void nbd_close(BlockDriverState *bs) @@ -321,7 +316,7 @@ static void nbd_close(BlockDriverState *bs) BDRVNBDState *s = bs->opaque; qemu_opts_del(s->socket_opts); - nbd_client_session_close(&s->client); + nbd_client_close(bs); } static int64_t nbd_getlength(BlockDriverState *bs) @@ -333,17 +328,13 @@ static int64_t nbd_getlength(BlockDriverState *bs) static void nbd_detach_aio_context(BlockDriverState *bs) { - BDRVNBDState *s = bs->opaque; - - nbd_client_session_detach_aio_context(&s->client); + nbd_client_detach_aio_context(bs); } static void nbd_attach_aio_context(BlockDriverState *bs, AioContext *new_context) { - BDRVNBDState *s = bs->opaque; - - nbd_client_session_attach_aio_context(&s->client, new_context); + nbd_client_attach_aio_context(bs, new_context); } static void nbd_refresh_filename(BlockDriverState *bs) diff --git a/include/block/nbd.h b/include/block/nbd.h index b759595..ca9a5ac 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -99,7 +99,6 @@ void nbd_export_close_all(void); NBDClient *nbd_client_new(NBDExport *exp, int csock, void (*close)(NBDClient *)); -void nbd_client_close(NBDClient *client); void nbd_client_get(NBDClient *client); void nbd_client_put(NBDClient *client); diff --git a/nbd.c b/nbd.c index e56afbc1..71159af 100644 --- a/nbd.c +++ b/nbd.c @@ -874,7 +874,7 @@ void nbd_client_put(NBDClient *client) { if (--client->refcount == 0) { /* The last reference should be dropped by client->close, - * which is called by nbd_client_close. + * which is called by client_close. */ assert(client->closing); @@ -889,7 +889,7 @@ void nbd_client_put(NBDClient *client) } } -void nbd_client_close(NBDClient *client) +static void client_close(NBDClient *client) { if (client->closing) { return; @@ -1026,7 +1026,7 @@ void nbd_export_close(NBDExport *exp) nbd_export_get(exp); QTAILQ_FOREACH_SAFE(client, &exp->clients, next, next) { - nbd_client_close(client); + client_close(client); } nbd_export_set_name(exp, NULL); nbd_export_put(exp); @@ -1311,7 +1311,7 @@ done: out: nbd_request_put(req); - nbd_client_close(client); + client_close(client); } static void nbd_read(void *opaque) -- 2.1.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH v2 1/3] nbd: Drop BDS backpointer 2015-02-06 21:06 ` [Qemu-devel] [PATCH v2 1/3] " Max Reitz @ 2015-02-09 12:33 ` Paolo Bonzini 0 siblings, 0 replies; 9+ messages in thread From: Paolo Bonzini @ 2015-02-09 12:33 UTC (permalink / raw) To: Max Reitz, qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi On 06/02/2015 22:06, Max Reitz wrote: > @@ -889,7 +889,7 @@ void nbd_client_put(NBDClient *client) > } > } > > -void nbd_client_close(NBDClient *client) > +static void client_close(NBDClient *client) > { > if (client->closing) { > return; Probably NBDClient should be renamed to NBDServerSession. Can be done on top. Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Paolo ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH v2 2/3] iotests: Add "wait" functionality to _cleanup_qemu 2015-02-06 21:06 [Qemu-devel] [PATCH v2 0/3] nbd: Drop BDS backpointer Max Reitz 2015-02-06 21:06 ` [Qemu-devel] [PATCH v2 1/3] " Max Reitz @ 2015-02-06 21:06 ` Max Reitz 2015-02-09 15:01 ` Stefan Hajnoczi 2015-02-06 21:06 ` [Qemu-devel] [PATCH v2 3/3] iotests: Add test for drive-mirror with NBD target Max Reitz 2015-02-09 17:54 ` [Qemu-devel] [PATCH v2 0/3] nbd: Drop BDS backpointer Stefan Hajnoczi 3 siblings, 1 reply; 9+ messages in thread From: Max Reitz @ 2015-02-06 21:06 UTC (permalink / raw) To: qemu-devel; +Cc: Kevin Wolf, Paolo Bonzini, Stefan Hajnoczi, Max Reitz The qemu process does not always need to be killed, just waiting for it can be fine, too. This introduces a way to do so. Signed-off-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> --- tests/qemu-iotests/common.qemu | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu index 8e618b5..4e1996c 100644 --- a/tests/qemu-iotests/common.qemu +++ b/tests/qemu-iotests/common.qemu @@ -187,13 +187,23 @@ function _launch_qemu() # Silenty kills the QEMU process +# +# If $wait is set to anything other than the empty string, the process will not +# be killed but only waited for, and any output will be forwarded to stdout. If +# $wait is empty, the process will be killed and all output will be suppressed. function _cleanup_qemu() { # QEMU_PID[], QEMU_IN[], QEMU_OUT[] all use same indices for i in "${!QEMU_OUT[@]}" do - kill -KILL ${QEMU_PID[$i]} 2>/dev/null + if [ -z "${wait}" ]; then + kill -KILL ${QEMU_PID[$i]} 2>/dev/null + fi wait ${QEMU_PID[$i]} 2>/dev/null # silent kill + if [ -n "${wait}" ]; then + cat <&${QEMU_OUT[$i]} | _filter_testdir | _filter_qemu \ + | _filter_qemu_io | _filter_qmp + fi rm -f "${QEMU_FIFO_IN}_${i}" "${QEMU_FIFO_OUT}_${i}" eval "exec ${QEMU_IN[$i]}<&-" # close file descriptors eval "exec ${QEMU_OUT[$i]}<&-" -- 2.1.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH v2 2/3] iotests: Add "wait" functionality to _cleanup_qemu 2015-02-06 21:06 ` [Qemu-devel] [PATCH v2 2/3] iotests: Add "wait" functionality to _cleanup_qemu Max Reitz @ 2015-02-09 15:01 ` Stefan Hajnoczi 2015-02-09 15:37 ` Max Reitz 0 siblings, 1 reply; 9+ messages in thread From: Stefan Hajnoczi @ 2015-02-09 15:01 UTC (permalink / raw) To: Max Reitz; +Cc: Kevin Wolf, Paolo Bonzini, qemu-devel, Stefan Hajnoczi [-- Attachment #1: Type: text/plain, Size: 992 bytes --] On Fri, Feb 06, 2015 at 04:06:17PM -0500, Max Reitz wrote: > diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu > index 8e618b5..4e1996c 100644 > --- a/tests/qemu-iotests/common.qemu > +++ b/tests/qemu-iotests/common.qemu > @@ -187,13 +187,23 @@ function _launch_qemu() > > > # Silenty kills the QEMU process > +# > +# If $wait is set to anything other than the empty string, the process will not > +# be killed but only waited for, and any output will be forwarded to stdout. If > +# $wait is empty, the process will be killed and all output will be suppressed. > function _cleanup_qemu() > { > # QEMU_PID[], QEMU_IN[], QEMU_OUT[] all use same indices > for i in "${!QEMU_OUT[@]}" > do > - kill -KILL ${QEMU_PID[$i]} 2>/dev/null > + if [ -z "${wait}" ]; then Is the global variable (with a common name) necessary? function _cleanup_qemu() { wait=$1 ... _cleanup_qemu OR _cleanup_qemu --wait [-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH v2 2/3] iotests: Add "wait" functionality to _cleanup_qemu 2015-02-09 15:01 ` Stefan Hajnoczi @ 2015-02-09 15:37 ` Max Reitz 2015-02-09 17:49 ` Stefan Hajnoczi 0 siblings, 1 reply; 9+ messages in thread From: Max Reitz @ 2015-02-09 15:37 UTC (permalink / raw) To: Stefan Hajnoczi; +Cc: Kevin Wolf, Paolo Bonzini, qemu-devel, Stefan Hajnoczi On 2015-02-09 at 10:01, Stefan Hajnoczi wrote: > On Fri, Feb 06, 2015 at 04:06:17PM -0500, Max Reitz wrote: >> diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu >> index 8e618b5..4e1996c 100644 >> --- a/tests/qemu-iotests/common.qemu >> +++ b/tests/qemu-iotests/common.qemu >> @@ -187,13 +187,23 @@ function _launch_qemu() >> >> >> # Silenty kills the QEMU process >> +# >> +# If $wait is set to anything other than the empty string, the process will not >> +# be killed but only waited for, and any output will be forwarded to stdout. If >> +# $wait is empty, the process will be killed and all output will be suppressed. >> function _cleanup_qemu() >> { >> # QEMU_PID[], QEMU_IN[], QEMU_OUT[] all use same indices >> for i in "${!QEMU_OUT[@]}" >> do >> - kill -KILL ${QEMU_PID[$i]} 2>/dev/null >> + if [ -z "${wait}" ]; then > Is the global variable (with a common name) necessary? > > function _cleanup_qemu() > { > wait=$1 > ... > > _cleanup_qemu > OR > _cleanup_qemu --wait Well, it's probably not necessary, but it conforms with the _launch_qemu ($qemu_comm_method), the _send_qemu_cmd ($qemu_error_not_set), and the _timed_wait_for ($silent) interfaces. Max ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH v2 2/3] iotests: Add "wait" functionality to _cleanup_qemu 2015-02-09 15:37 ` Max Reitz @ 2015-02-09 17:49 ` Stefan Hajnoczi 0 siblings, 0 replies; 9+ messages in thread From: Stefan Hajnoczi @ 2015-02-09 17:49 UTC (permalink / raw) To: Max Reitz; +Cc: Kevin Wolf, Stefan Hajnoczi, qemu-devel, Paolo Bonzini [-- Attachment #1: Type: text/plain, Size: 1401 bytes --] On Mon, Feb 09, 2015 at 10:37:22AM -0500, Max Reitz wrote: > On 2015-02-09 at 10:01, Stefan Hajnoczi wrote: > >On Fri, Feb 06, 2015 at 04:06:17PM -0500, Max Reitz wrote: > >>diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu > >>index 8e618b5..4e1996c 100644 > >>--- a/tests/qemu-iotests/common.qemu > >>+++ b/tests/qemu-iotests/common.qemu > >>@@ -187,13 +187,23 @@ function _launch_qemu() > >> # Silenty kills the QEMU process > >>+# > >>+# If $wait is set to anything other than the empty string, the process will not > >>+# be killed but only waited for, and any output will be forwarded to stdout. If > >>+# $wait is empty, the process will be killed and all output will be suppressed. > >> function _cleanup_qemu() > >> { > >> # QEMU_PID[], QEMU_IN[], QEMU_OUT[] all use same indices > >> for i in "${!QEMU_OUT[@]}" > >> do > >>- kill -KILL ${QEMU_PID[$i]} 2>/dev/null > >>+ if [ -z "${wait}" ]; then > >Is the global variable (with a common name) necessary? > > > >function _cleanup_qemu() > >{ > > wait=$1 > >... > > > >_cleanup_qemu > >OR > >_cleanup_qemu --wait > > Well, it's probably not necessary, but it conforms with the _launch_qemu > ($qemu_comm_method), the _send_qemu_cmd ($qemu_error_not_set), and the > _timed_wait_for ($silent) interfaces. Okay, let's stay consistent. Stefan [-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH v2 3/3] iotests: Add test for drive-mirror with NBD target 2015-02-06 21:06 [Qemu-devel] [PATCH v2 0/3] nbd: Drop BDS backpointer Max Reitz 2015-02-06 21:06 ` [Qemu-devel] [PATCH v2 1/3] " Max Reitz 2015-02-06 21:06 ` [Qemu-devel] [PATCH v2 2/3] iotests: Add "wait" functionality to _cleanup_qemu Max Reitz @ 2015-02-06 21:06 ` Max Reitz 2015-02-09 17:54 ` [Qemu-devel] [PATCH v2 0/3] nbd: Drop BDS backpointer Stefan Hajnoczi 3 siblings, 0 replies; 9+ messages in thread From: Max Reitz @ 2015-02-06 21:06 UTC (permalink / raw) To: qemu-devel; +Cc: Kevin Wolf, Paolo Bonzini, Stefan Hajnoczi, Max Reitz When the drive-mirror block job is completed, it will call bdrv_swap() on the source and the target BDS; this should obviously not result in a segmentation fault. Signed-off-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> --- tests/qemu-iotests/094 | 81 ++++++++++++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/094.out | 11 +++++++ tests/qemu-iotests/group | 1 + 3 files changed, 93 insertions(+) create mode 100755 tests/qemu-iotests/094 create mode 100644 tests/qemu-iotests/094.out diff --git a/tests/qemu-iotests/094 b/tests/qemu-iotests/094 new file mode 100755 index 0000000..27a2be2 --- /dev/null +++ b/tests/qemu-iotests/094 @@ -0,0 +1,81 @@ +#!/bin/bash +# +# Test case for drive-mirror to NBD (especially bdrv_swap() on NBD BDS) +# +# Copyright (C) 2015 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +# creator +owner=mreitz@redhat.com + +seq="$(basename $0)" +echo "QA output created by $seq" + +here="$PWD" +tmp=/tmp/$$ +status=1 # failure is the default! + +trap "exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter +. ./common.qemu + +_supported_fmt generic +_supported_proto nbd +_supported_os Linux +_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" + +_make_test_img 64M +$QEMU_IMG create -f $IMGFMT "$TEST_DIR/source.$IMGFMT" 64M | _filter_img_create + +_launch_qemu -drive if=none,id=src,file="$TEST_DIR/source.$IMGFMT",format=raw \ + -nodefaults + +_send_qemu_cmd $QEMU_HANDLE \ + "{'execute': 'qmp_capabilities'}" \ + 'return' + +# 'format': 'nbd' is not actually "correct", but this is probably the only way +# to test bdrv_swap() on an NBD BDS +_send_qemu_cmd $QEMU_HANDLE \ + "{'execute': 'drive-mirror', + 'arguments': {'device': 'src', + 'target': '$TEST_IMG', + 'format': 'nbd', + 'sync':'full', + 'mode':'existing'}}" \ + 'BLOCK_JOB_READY' + +_send_qemu_cmd $QEMU_HANDLE \ + "{'execute': 'block-job-complete', + 'arguments': {'device': 'src'}}" \ + 'BLOCK_JOB_COMPLETE' + +_send_qemu_cmd $QEMU_HANDLE \ + "{'execute': 'quit'}" \ + 'return' + +wait=1 _cleanup_qemu + +_cleanup_test_img +rm -f "$TEST_DIR/source.$IMGFMT" + +# success, all done +echo '*** done' +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/094.out b/tests/qemu-iotests/094.out new file mode 100644 index 0000000..b66dc07 --- /dev/null +++ b/tests/qemu-iotests/094.out @@ -0,0 +1,11 @@ +QA output created by 094 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 +Formatting 'TEST_DIR/source.IMGFMT', fmt=IMGFMT size=67108864 +{"return": {}} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"} +*** done diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 4b2b93b..6e2447a 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -99,6 +99,7 @@ 090 rw auto quick 091 rw auto 092 rw auto quick +094 rw auto quick 095 rw auto quick 097 rw auto backing 098 rw auto backing quick -- 2.1.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH v2 0/3] nbd: Drop BDS backpointer 2015-02-06 21:06 [Qemu-devel] [PATCH v2 0/3] nbd: Drop BDS backpointer Max Reitz ` (2 preceding siblings ...) 2015-02-06 21:06 ` [Qemu-devel] [PATCH v2 3/3] iotests: Add test for drive-mirror with NBD target Max Reitz @ 2015-02-09 17:54 ` Stefan Hajnoczi 3 siblings, 0 replies; 9+ messages in thread From: Stefan Hajnoczi @ 2015-02-09 17:54 UTC (permalink / raw) To: Max Reitz; +Cc: Kevin Wolf, Paolo Bonzini, qemu-devel [-- Attachment #1: Type: text/plain, Size: 2547 bytes --] On Fri, Feb 06, 2015 at 04:06:15PM -0500, Max Reitz wrote: > Right now, bdrv_swap() on NBD BDSs results in a segmentation fault > pretty much all of the time. This series fixes this. > > Note that this is not a common case, as bdrv_swap() is generally only > performed on root BDSs (there are exceptions, though) and NBD BDSs > normally have a format BDS above them. However, due to misconfiguration > (or maybe it is not even a misconfiguration, but just a strange > configuration) these cases may indeed occur. > > I took the second patch in this series from my other series > "block: Rework bdrv_close_all()" (which has 21 patches itself and > depends on 64 other patches, so making this series rely on that one > probably would not have been a very good idea). > > > v2: > - Rename all functions which now take a BlockDriverState * instead of an > NbdClientSession * from nbd_client_session_* to nbd_client_* [Paolo] > - Rename nbd_client_close() in nbd.c to client_close() and make it > static; otherwise, it would conflict with the "new" nbd_client_close() > in block/nbd-client.c > > > git-backport-diff against v1: > > Key: > [----] : patches are identical > [####] : number of functional differences between upstream/downstream patch > [down] : patch is downstream-only > The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively > > 001/3:[0089] [FC] 'nbd: Drop BDS backpointer' > 002/3:[----] [--] 'iotests: Add "wait" functionality to _cleanup_qemu' > 003/3:[----] [--] 'iotests: Add test for drive-mirror with NBD target' > > > Max Reitz (3): > nbd: Drop BDS backpointer > iotests: Add "wait" functionality to _cleanup_qemu > iotests: Add test for drive-mirror with NBD target > > block/nbd-client.c | 101 +++++++++++++++++++++-------------------- > block/nbd-client.h | 34 +++++++------- > block/nbd.c | 37 ++++++--------- > include/block/nbd.h | 1 - > nbd.c | 8 ++-- > tests/qemu-iotests/094 | 81 +++++++++++++++++++++++++++++++++ > tests/qemu-iotests/094.out | 11 +++++ > tests/qemu-iotests/common.qemu | 12 ++++- > tests/qemu-iotests/group | 1 + > 9 files changed, 191 insertions(+), 95 deletions(-) > create mode 100755 tests/qemu-iotests/094 > create mode 100644 tests/qemu-iotests/094.out > > -- > 2.1.0 > Thanks, applied to my block tree: https://github.com/stefanha/qemu/commits/block Stefan [-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2015-02-09 17:55 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-02-06 21:06 [Qemu-devel] [PATCH v2 0/3] nbd: Drop BDS backpointer Max Reitz 2015-02-06 21:06 ` [Qemu-devel] [PATCH v2 1/3] " Max Reitz 2015-02-09 12:33 ` Paolo Bonzini 2015-02-06 21:06 ` [Qemu-devel] [PATCH v2 2/3] iotests: Add "wait" functionality to _cleanup_qemu Max Reitz 2015-02-09 15:01 ` Stefan Hajnoczi 2015-02-09 15:37 ` Max Reitz 2015-02-09 17:49 ` Stefan Hajnoczi 2015-02-06 21:06 ` [Qemu-devel] [PATCH v2 3/3] iotests: Add test for drive-mirror with NBD target Max Reitz 2015-02-09 17:54 ` [Qemu-devel] [PATCH v2 0/3] nbd: Drop BDS backpointer Stefan Hajnoczi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).