* [Qemu-devel] [PULL 0/4] NBD patches for 2.11-rc2
@ 2017-11-17 15:05 Eric Blake
2017-11-17 15:05 ` [Qemu-devel] [PULL 1/4] nbd: Don't crash when server reports NBD_CMD_READ failure Eric Blake
` (4 more replies)
0 siblings, 5 replies; 8+ messages in thread
From: Eric Blake @ 2017-11-17 15:05 UTC (permalink / raw)
To: qemu-devel
The following changes since commit fec035a53fa15c4c8c4e62bfef56a35df4161e38:
Merge remote-tracking branch 'remotes/kraxel/tags/ui-20171117-pull-request' into staging (2017-11-17 10:18:41 +0000)
are available in the git repository at:
git://repo.or.cz/qemu/ericb.git tags/pull-nbd-2017-11-17
for you to fetch changes up to fed5f8f82056c9f222433c41aeb9fca50c89f297:
nbd/server: Fix error reporting for bad requests (2017-11-17 08:38:38 -0600)
----------------------------------------------------------------
nbd patches for 2017-11-17
Eric Blake - nbd: Don't crash when server reports NBD_CMD_READ failure
Eric Blake - nbd/client: Use error_prepend() correctly
Eric Blake - nbd/client: Don't hard-disconnect on ESHUTDOWN from server
Eric Blake - nbd/server: Fix error reporting for bad requests
----------------------------------------------------------------
Eric Blake (4):
nbd: Don't crash when server reports NBD_CMD_READ failure
nbd/client: Use error_prepend() correctly
nbd/client: Don't hard-disconnect on ESHUTDOWN from server
nbd/server: Fix error reporting for bad requests
block/nbd-client.c | 4 ++--
nbd/client.c | 56 +++++++++++++++++++++++++-----------------------------
nbd/server.c | 36 ++++++++++++-----------------------
3 files changed, 40 insertions(+), 56 deletions(-)
--
2.13.6
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Qemu-devel] [PULL 1/4] nbd: Don't crash when server reports NBD_CMD_READ failure
2017-11-17 15:05 [Qemu-devel] [PULL 0/4] NBD patches for 2.11-rc2 Eric Blake
@ 2017-11-17 15:05 ` Eric Blake
2017-11-17 15:05 ` [Qemu-devel] [PULL 2/4] nbd/client: Use error_prepend() correctly Eric Blake
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Eric Blake @ 2017-11-17 15:05 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Kevin Wolf, Max Reitz,
open list:Network Block Dev...
If a server fails a read, for example with EIO, but the connection
is still live, then we would crash trying to print a non-existent
error message in nbd_client_co_preadv(). For consistency, also
change the error printout in nbd_read_reply_entry(), although that
instance does not crash. Bug introduced in commit f140e300.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20171112013936.5942-1-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
block/nbd-client.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/block/nbd-client.c b/block/nbd-client.c
index bcfed0133d..9206652e45 100644
--- a/block/nbd-client.c
+++ b/block/nbd-client.c
@@ -78,7 +78,7 @@ static coroutine_fn void nbd_read_reply_entry(void *opaque)
while (!s->quit) {
assert(s->reply.handle == 0);
ret = nbd_receive_reply(s->ioc, &s->reply, &local_err);
- if (ret < 0) {
+ if (local_err) {
error_report_err(local_err);
}
if (ret <= 0) {
@@ -691,7 +691,7 @@ int nbd_client_co_preadv(BlockDriverState *bs, uint64_t offset,
ret = nbd_co_receive_cmdread_reply(client, request.handle, offset, qiov,
&local_err);
- if (ret < 0) {
+ if (local_err) {
error_report_err(local_err);
}
return ret;
--
2.13.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PULL 2/4] nbd/client: Use error_prepend() correctly
2017-11-17 15:05 [Qemu-devel] [PULL 0/4] NBD patches for 2.11-rc2 Eric Blake
2017-11-17 15:05 ` [Qemu-devel] [PULL 1/4] nbd: Don't crash when server reports NBD_CMD_READ failure Eric Blake
@ 2017-11-17 15:05 ` Eric Blake
2017-11-17 15:05 ` [Qemu-devel] [PULL 3/4] nbd/client: Don't hard-disconnect on ESHUTDOWN from server Eric Blake
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Eric Blake @ 2017-11-17 15:05 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Paolo Bonzini, open list:Network Block Dev...
When using error prepend(), it is necessary to end with a space
in the format string; otherwise, messages come out incorrectly,
such as when connecting to a socket that hangs up immediately:
can't open device nbd://localhost:10809/: Failed to read dataUnexpected end-of-file before all bytes were read
Originally botched in commit e44ed99d, then several more instances
added in the meantime.
Pre-existing and not fixed here: we are inconsistent on capitalization;
some of our messages start with lower case, and others start with upper,
although the use of error_prepend() is much nicer to read when all
fragments consistently start with lower.
CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20171113152424.25381-1-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
---
nbd/client.c | 50 ++++++++++++++++++++++++++------------------------
1 file changed, 26 insertions(+), 24 deletions(-)
diff --git a/nbd/client.c b/nbd/client.c
index 1880103d2a..4e15fc484d 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -79,12 +79,12 @@ static int nbd_send_option_request(QIOChannel *ioc, uint32_t opt,
stl_be_p(&req.length, len);
if (nbd_write(ioc, &req, sizeof(req), errp) < 0) {
- error_prepend(errp, "Failed to send option request header");
+ error_prepend(errp, "Failed to send option request header: ");
return -1;
}
if (len && nbd_write(ioc, (char *) data, len, errp) < 0) {
- error_prepend(errp, "Failed to send option request data");
+ error_prepend(errp, "Failed to send option request data: ");
return -1;
}
@@ -113,7 +113,7 @@ static int nbd_receive_option_reply(QIOChannel *ioc, uint32_t opt,
{
QEMU_BUILD_BUG_ON(sizeof(*reply) != 20);
if (nbd_read(ioc, reply, sizeof(*reply), errp) < 0) {
- error_prepend(errp, "failed to read option reply");
+ error_prepend(errp, "failed to read option reply: ");
nbd_send_opt_abort(ioc);
return -1;
}
@@ -166,7 +166,7 @@ static int nbd_handle_reply_err(QIOChannel *ioc, nbd_opt_reply *reply,
msg = g_malloc(reply->length + 1);
if (nbd_read(ioc, msg, reply->length, errp) < 0) {
error_prepend(errp, "failed to read option error 0x%" PRIx32
- " (%s) message",
+ " (%s) message: ",
reply->type, nbd_rep_lookup(reply->type));
goto cleanup;
}
@@ -277,7 +277,7 @@ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match,
return -1;
}
if (nbd_read(ioc, &namelen, sizeof(namelen), errp) < 0) {
- error_prepend(errp, "failed to read option name length");
+ error_prepend(errp, "failed to read option name length: ");
nbd_send_opt_abort(ioc);
return -1;
}
@@ -290,7 +290,8 @@ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match,
}
if (namelen != strlen(want)) {
if (nbd_drop(ioc, len, errp) < 0) {
- error_prepend(errp, "failed to skip export name with wrong length");
+ error_prepend(errp,
+ "failed to skip export name with wrong length: ");
nbd_send_opt_abort(ioc);
return -1;
}
@@ -299,14 +300,14 @@ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match,
assert(namelen < sizeof(name));
if (nbd_read(ioc, name, namelen, errp) < 0) {
- error_prepend(errp, "failed to read export name");
+ error_prepend(errp, "failed to read export name: ");
nbd_send_opt_abort(ioc);
return -1;
}
name[namelen] = '\0';
len -= namelen;
if (nbd_drop(ioc, len, errp) < 0) {
- error_prepend(errp, "failed to read export description");
+ error_prepend(errp, "failed to read export description: ");
nbd_send_opt_abort(ioc);
return -1;
}
@@ -390,7 +391,7 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname,
return -1;
}
if (nbd_read(ioc, &type, sizeof(type), errp) < 0) {
- error_prepend(errp, "failed to read info type");
+ error_prepend(errp, "failed to read info type: ");
nbd_send_opt_abort(ioc);
return -1;
}
@@ -405,13 +406,13 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname,
return -1;
}
if (nbd_read(ioc, &info->size, sizeof(info->size), errp) < 0) {
- error_prepend(errp, "failed to read info size");
+ error_prepend(errp, "failed to read info size: ");
nbd_send_opt_abort(ioc);
return -1;
}
be64_to_cpus(&info->size);
if (nbd_read(ioc, &info->flags, sizeof(info->flags), errp) < 0) {
- error_prepend(errp, "failed to read info flags");
+ error_prepend(errp, "failed to read info flags: ");
nbd_send_opt_abort(ioc);
return -1;
}
@@ -428,7 +429,7 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname,
}
if (nbd_read(ioc, &info->min_block, sizeof(info->min_block),
errp) < 0) {
- error_prepend(errp, "failed to read info minimum block size");
+ error_prepend(errp, "failed to read info minimum block size: ");
nbd_send_opt_abort(ioc);
return -1;
}
@@ -441,7 +442,8 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname,
}
if (nbd_read(ioc, &info->opt_block, sizeof(info->opt_block),
errp) < 0) {
- error_prepend(errp, "failed to read info preferred block size");
+ error_prepend(errp,
+ "failed to read info preferred block size: ");
nbd_send_opt_abort(ioc);
return -1;
}
@@ -455,7 +457,7 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname,
}
if (nbd_read(ioc, &info->max_block, sizeof(info->max_block),
errp) < 0) {
- error_prepend(errp, "failed to read info maximum block size");
+ error_prepend(errp, "failed to read info maximum block size: ");
nbd_send_opt_abort(ioc);
return -1;
}
@@ -467,7 +469,7 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname,
default:
trace_nbd_opt_go_info_unknown(type, nbd_info_lookup(type));
if (nbd_drop(ioc, len, errp) < 0) {
- error_prepend(errp, "Failed to read info payload");
+ error_prepend(errp, "Failed to read info payload: ");
nbd_send_opt_abort(ioc);
return -1;
}
@@ -618,7 +620,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
}
if (nbd_read(ioc, buf, 8, errp) < 0) {
- error_prepend(errp, "Failed to read data");
+ error_prepend(errp, "Failed to read data: ");
goto fail;
}
@@ -637,7 +639,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
}
if (nbd_read(ioc, &magic, sizeof(magic), errp) < 0) {
- error_prepend(errp, "Failed to read magic");
+ error_prepend(errp, "Failed to read magic: ");
goto fail;
}
magic = be64_to_cpu(magic);
@@ -649,7 +651,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
bool fixedNewStyle = false;
if (nbd_read(ioc, &globalflags, sizeof(globalflags), errp) < 0) {
- error_prepend(errp, "Failed to read server flags");
+ error_prepend(errp, "Failed to read server flags: ");
goto fail;
}
globalflags = be16_to_cpu(globalflags);
@@ -665,7 +667,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
/* client requested flags */
clientflags = cpu_to_be32(clientflags);
if (nbd_write(ioc, &clientflags, sizeof(clientflags), errp) < 0) {
- error_prepend(errp, "Failed to send clientflags field");
+ error_prepend(errp, "Failed to send clientflags field: ");
goto fail;
}
if (tlscreds) {
@@ -727,13 +729,13 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
/* Read the response */
if (nbd_read(ioc, &info->size, sizeof(info->size), errp) < 0) {
- error_prepend(errp, "Failed to read export length");
+ error_prepend(errp, "Failed to read export length: ");
goto fail;
}
be64_to_cpus(&info->size);
if (nbd_read(ioc, &info->flags, sizeof(info->flags), errp) < 0) {
- error_prepend(errp, "Failed to read export flags");
+ error_prepend(errp, "Failed to read export flags: ");
goto fail;
}
be16_to_cpus(&info->flags);
@@ -750,13 +752,13 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
}
if (nbd_read(ioc, &info->size, sizeof(info->size), errp) < 0) {
- error_prepend(errp, "Failed to read export length");
+ error_prepend(errp, "Failed to read export length: ");
goto fail;
}
be64_to_cpus(&info->size);
if (nbd_read(ioc, &oldflags, sizeof(oldflags), errp) < 0) {
- error_prepend(errp, "Failed to read export flags");
+ error_prepend(errp, "Failed to read export flags: ");
goto fail;
}
be32_to_cpus(&oldflags);
@@ -772,7 +774,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
trace_nbd_receive_negotiate_size_flags(info->size, info->flags);
if (zeroes && nbd_drop(ioc, 124, errp) < 0) {
- error_prepend(errp, "Failed to read reserved block");
+ error_prepend(errp, "Failed to read reserved block: ");
goto fail;
}
rc = 0;
--
2.13.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PULL 3/4] nbd/client: Don't hard-disconnect on ESHUTDOWN from server
2017-11-17 15:05 [Qemu-devel] [PULL 0/4] NBD patches for 2.11-rc2 Eric Blake
2017-11-17 15:05 ` [Qemu-devel] [PULL 1/4] nbd: Don't crash when server reports NBD_CMD_READ failure Eric Blake
2017-11-17 15:05 ` [Qemu-devel] [PULL 2/4] nbd/client: Use error_prepend() correctly Eric Blake
@ 2017-11-17 15:05 ` Eric Blake
2017-12-06 16:55 ` Michael Roth
2017-11-17 15:05 ` [Qemu-devel] [PULL 4/4] nbd/server: Fix error reporting for bad requests Eric Blake
2017-11-17 19:07 ` [Qemu-devel] [PULL 0/4] NBD patches for 2.11-rc2 Peter Maydell
4 siblings, 1 reply; 8+ messages in thread
From: Eric Blake @ 2017-11-17 15:05 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Paolo Bonzini, open list:Network Block Dev...
The NBD spec says that a server may fail any transmission request
with ESHUTDOWN when it is apparent that no further request from
the client can be successfully honored. The client is supposed
to then initiate a soft shutdown (wait for all remaining in-flight
requests to be answered, then send NBD_CMD_DISC). However, since
qemu's server never uses ESHUTDOWN errors, this code was mostly
untested since its introduction in commit b6f5d3b5.
More recently, I learned that nbdkit as the NBD server is able to
send ESHUTDOWN errors, so I finally tested this code, and noticed
that our client was special-casing ESHUTDOWN to cause a hard
shutdown (immediate disconnect, with no NBD_CMD_DISC), but only
if the server sends this error as a simple reply. Further
investigation found that commit d2febedb introduced a regression
where structured replies behave differently than simple replies -
but that the structured reply behavior is more in line with the
spec (even if we still lack code in nbd-client.c to properly quit
sending further requests). So this patch reverts the portion of
b6f5d3b5 that introduced an improper hard-disconnect special-case
at the lower level, and leaves the future enhancement of a nicer
soft-disconnect at the higher level for another day.
CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20171113194857.13933-1-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
nbd/client.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/nbd/client.c b/nbd/client.c
index 4e15fc484d..eea236ca06 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -996,15 +996,9 @@ int nbd_receive_reply(QIOChannel *ioc, NBDReply *reply, Error **errp)
if (ret < 0) {
break;
}
-
trace_nbd_receive_simple_reply(reply->simple.error,
nbd_err_lookup(reply->simple.error),
reply->handle);
- if (reply->simple.error == NBD_ESHUTDOWN) {
- /* This works even on mingw which lacks a native ESHUTDOWN */
- error_setg(errp, "server shutting down");
- return -EINVAL;
- }
break;
case NBD_STRUCTURED_REPLY_MAGIC:
ret = nbd_receive_structured_reply_chunk(ioc, &reply->structured, errp);
--
2.13.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PULL 4/4] nbd/server: Fix error reporting for bad requests
2017-11-17 15:05 [Qemu-devel] [PULL 0/4] NBD patches for 2.11-rc2 Eric Blake
` (2 preceding siblings ...)
2017-11-17 15:05 ` [Qemu-devel] [PULL 3/4] nbd/client: Don't hard-disconnect on ESHUTDOWN from server Eric Blake
@ 2017-11-17 15:05 ` Eric Blake
2017-11-17 19:07 ` [Qemu-devel] [PULL 0/4] NBD patches for 2.11-rc2 Peter Maydell
4 siblings, 0 replies; 8+ messages in thread
From: Eric Blake @ 2017-11-17 15:05 UTC (permalink / raw)
To: qemu-devel; +Cc: Paolo Bonzini, open list:Network Block Dev...
The NBD spec says an attempt to NBD_CMD_TRIM on a read-only
export should fail with EPERM, as a trim has the potential
to change disk contents, but we were relying on the block
layer to catch that for us, which might not always give the
right error (and even if it does, it does not let us pass
back a sane message for structured replies).
The NBD spec says an attempt to NBD_CMD_WRITE_ZEROES out of
bounds should fail with ENOSPC, not EINVAL.
Our check for u64 offset + u32 length wraparound up front is
pointless; nothing uses offset until after the second round
of sanity checks, and we can just as easily ensure there is
no wraparound by checking whether offset is in bounds (since
a disk size cannot exceed off_t which is 63 bits, adding a
32-bit number for a valid offset can't overflow). Bonus:
dropping the up-front check lets us keep the connection alive
after NBD_CMD_WRITE, whereas before we would drop the
connection (of course, any client sending a packet that would
trigger the failure is already buggy, so it's also okay to
drop the connection, but better quality-of-implementation
never hurts).
Solve all of these issues by some code motion and improved
request validation.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20171115213557.3548-1-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
nbd/server.c | 36 ++++++++++++------------------------
1 file changed, 12 insertions(+), 24 deletions(-)
diff --git a/nbd/server.c b/nbd/server.c
index df771fd42f..7d6801b427 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1366,15 +1366,6 @@ static int nbd_co_receive_request(NBDRequestData *req, NBDRequest *request,
return -EIO;
}
- /* Check for sanity in the parameters, part 1. Defer as many
- * checks as possible until after reading any NBD_CMD_WRITE
- * payload, so we can try and keep the connection alive. */
- if ((request->from + request->len) < request->from) {
- error_setg(errp,
- "integer overflow detected, you're probably being attacked");
- return -EINVAL;
- }
-
if (request->type == NBD_CMD_READ || request->type == NBD_CMD_WRITE) {
if (request->len > NBD_MAX_BUFFER_SIZE) {
error_setg(errp, "len (%" PRIu32" ) is larger than max len (%u)",
@@ -1399,12 +1390,21 @@ static int nbd_co_receive_request(NBDRequestData *req, NBDRequest *request,
request->len);
}
- /* Sanity checks, part 2. */
- if (request->from + request->len > client->exp->size) {
+ /* Sanity checks. */
+ if (client->exp->nbdflags & NBD_FLAG_READ_ONLY &&
+ (request->type == NBD_CMD_WRITE ||
+ request->type == NBD_CMD_WRITE_ZEROES ||
+ request->type == NBD_CMD_TRIM)) {
+ error_setg(errp, "Export is read-only");
+ return -EROFS;
+ }
+ if (request->from > client->exp->size ||
+ request->from + request->len > client->exp->size) {
error_setg(errp, "operation past EOF; From: %" PRIu64 ", Len: %" PRIu32
", Size: %" PRIu64, request->from, request->len,
(uint64_t)client->exp->size);
- return request->type == NBD_CMD_WRITE ? -ENOSPC : -EINVAL;
+ return (request->type == NBD_CMD_WRITE ||
+ request->type == NBD_CMD_WRITE_ZEROES) ? -ENOSPC : -EINVAL;
}
valid_flags = NBD_CMD_FLAG_FUA;
if (request->type == NBD_CMD_READ && client->structured_reply) {
@@ -1482,12 +1482,6 @@ static coroutine_fn void nbd_trip(void *opaque)
break;
case NBD_CMD_WRITE:
- if (exp->nbdflags & NBD_FLAG_READ_ONLY) {
- error_setg(&local_err, "Export is read-only");
- ret = -EROFS;
- break;
- }
-
flags = 0;
if (request.flags & NBD_CMD_FLAG_FUA) {
flags |= BDRV_REQ_FUA;
@@ -1500,12 +1494,6 @@ static coroutine_fn void nbd_trip(void *opaque)
break;
case NBD_CMD_WRITE_ZEROES:
- if (exp->nbdflags & NBD_FLAG_READ_ONLY) {
- error_setg(&local_err, "Export is read-only");
- ret = -EROFS;
- break;
- }
-
flags = 0;
if (request.flags & NBD_CMD_FLAG_FUA) {
flags |= BDRV_REQ_FUA;
--
2.13.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PULL 0/4] NBD patches for 2.11-rc2
2017-11-17 15:05 [Qemu-devel] [PULL 0/4] NBD patches for 2.11-rc2 Eric Blake
` (3 preceding siblings ...)
2017-11-17 15:05 ` [Qemu-devel] [PULL 4/4] nbd/server: Fix error reporting for bad requests Eric Blake
@ 2017-11-17 19:07 ` Peter Maydell
4 siblings, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2017-11-17 19:07 UTC (permalink / raw)
To: Eric Blake; +Cc: QEMU Developers
On 17 November 2017 at 15:05, Eric Blake <eblake@redhat.com> wrote:
> The following changes since commit fec035a53fa15c4c8c4e62bfef56a35df4161e38:
>
> Merge remote-tracking branch 'remotes/kraxel/tags/ui-20171117-pull-request' into staging (2017-11-17 10:18:41 +0000)
>
> are available in the git repository at:
>
> git://repo.or.cz/qemu/ericb.git tags/pull-nbd-2017-11-17
>
> for you to fetch changes up to fed5f8f82056c9f222433c41aeb9fca50c89f297:
>
> nbd/server: Fix error reporting for bad requests (2017-11-17 08:38:38 -0600)
>
> ----------------------------------------------------------------
> nbd patches for 2017-11-17
>
> Eric Blake - nbd: Don't crash when server reports NBD_CMD_READ failure
> Eric Blake - nbd/client: Use error_prepend() correctly
> Eric Blake - nbd/client: Don't hard-disconnect on ESHUTDOWN from server
> Eric Blake - nbd/server: Fix error reporting for bad requests
>
> ----------------------------------------------------------------
Applied, thanks.
-- PMM
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PULL 3/4] nbd/client: Don't hard-disconnect on ESHUTDOWN from server
2017-11-17 15:05 ` [Qemu-devel] [PULL 3/4] nbd/client: Don't hard-disconnect on ESHUTDOWN from server Eric Blake
@ 2017-12-06 16:55 ` Michael Roth
2017-12-06 17:01 ` Eric Blake
0 siblings, 1 reply; 8+ messages in thread
From: Michael Roth @ 2017-12-06 16:55 UTC (permalink / raw)
To: Eric Blake, qemu-devel
Cc: Paolo Bonzini, qemu-stable, open list:Network Block Dev...
Quoting Eric Blake (2017-11-17 09:05:55)
> The NBD spec says that a server may fail any transmission request
> with ESHUTDOWN when it is apparent that no further request from
> the client can be successfully honored. The client is supposed
> to then initiate a soft shutdown (wait for all remaining in-flight
> requests to be answered, then send NBD_CMD_DISC). However, since
> qemu's server never uses ESHUTDOWN errors, this code was mostly
> untested since its introduction in commit b6f5d3b5.
>
> More recently, I learned that nbdkit as the NBD server is able to
> send ESHUTDOWN errors, so I finally tested this code, and noticed
> that our client was special-casing ESHUTDOWN to cause a hard
> shutdown (immediate disconnect, with no NBD_CMD_DISC), but only
> if the server sends this error as a simple reply. Further
> investigation found that commit d2febedb introduced a regression
> where structured replies behave differently than simple replies -
> but that the structured reply behavior is more in line with the
> spec (even if we still lack code in nbd-client.c to properly quit
> sending further requests). So this patch reverts the portion of
> b6f5d3b5 that introduced an improper hard-disconnect special-case
> at the lower level, and leaves the future enhancement of a nicer
> soft-disconnect at the higher level for another day.
>
> CC: qemu-stable@nongnu.org
Since 2.10.x lacks d2febedb, the patch would look something like:
diff --git a/nbd/client.c b/nbd/client.c
index 4caff77119..f04e95542f 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -945,12 +945,6 @@ ssize_t nbd_receive_reply(QIOChannel *ioc, NBDReply *reply, Error **errp)
reply->handle = ldq_be_p(buf + 8);
reply->error = nbd_errno_to_system_errno(reply->error);
-
- if (reply->error == ESHUTDOWN) {
- /* This works even on mingw which lacks a native ESHUTDOWN */
- error_setg(errp, "server shutting down");
- return -EINVAL;
- }
trace_nbd_receive_reply(magic, reply->error, reply->handle);
if (magic != NBD_REPLY_MAGIC) {
If that seems reasonable I can apply it as such.
> Signed-off-by: Eric Blake <eblake@redhat.com>
> Message-Id: <20171113194857.13933-1-eblake@redhat.com>
> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
> ---
> nbd/client.c | 6 ------
> 1 file changed, 6 deletions(-)
>
> diff --git a/nbd/client.c b/nbd/client.c
> index 4e15fc484d..eea236ca06 100644
> --- a/nbd/client.c
> +++ b/nbd/client.c
> @@ -996,15 +996,9 @@ int nbd_receive_reply(QIOChannel *ioc, NBDReply *reply, Error **errp)
> if (ret < 0) {
> break;
> }
> -
> trace_nbd_receive_simple_reply(reply->simple.error,
> nbd_err_lookup(reply->simple.error),
> reply->handle);
> - if (reply->simple.error == NBD_ESHUTDOWN) {
> - /* This works even on mingw which lacks a native ESHUTDOWN */
> - error_setg(errp, "server shutting down");
> - return -EINVAL;
> - }
> break;
> case NBD_STRUCTURED_REPLY_MAGIC:
> ret = nbd_receive_structured_reply_chunk(ioc, &reply->structured, errp);
> --
> 2.13.6
>
>
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PULL 3/4] nbd/client: Don't hard-disconnect on ESHUTDOWN from server
2017-12-06 16:55 ` Michael Roth
@ 2017-12-06 17:01 ` Eric Blake
0 siblings, 0 replies; 8+ messages in thread
From: Eric Blake @ 2017-12-06 17:01 UTC (permalink / raw)
To: Michael Roth, qemu-devel
Cc: Paolo Bonzini, qemu-stable, open list:Network Block Dev...
[-- Attachment #1: Type: text/plain, Size: 2451 bytes --]
On 12/06/2017 10:55 AM, Michael Roth wrote:
> Quoting Eric Blake (2017-11-17 09:05:55)
>> The NBD spec says that a server may fail any transmission request
>> with ESHUTDOWN when it is apparent that no further request from
>> the client can be successfully honored. The client is supposed
>> to then initiate a soft shutdown (wait for all remaining in-flight
>> requests to be answered, then send NBD_CMD_DISC). However, since
>> qemu's server never uses ESHUTDOWN errors, this code was mostly
>> untested since its introduction in commit b6f5d3b5.
>>
>> More recently, I learned that nbdkit as the NBD server is able to
>> send ESHUTDOWN errors, so I finally tested this code, and noticed
>> that our client was special-casing ESHUTDOWN to cause a hard
>> shutdown (immediate disconnect, with no NBD_CMD_DISC), but only
>> if the server sends this error as a simple reply. Further
>> investigation found that commit d2febedb introduced a regression
>> where structured replies behave differently than simple replies -
>> but that the structured reply behavior is more in line with the
>> spec (even if we still lack code in nbd-client.c to properly quit
>> sending further requests). So this patch reverts the portion of
>> b6f5d3b5 that introduced an improper hard-disconnect special-case
>> at the lower level, and leaves the future enhancement of a nicer
>> soft-disconnect at the higher level for another day.
>>
>> CC: qemu-stable@nongnu.org
>
> Since 2.10.x lacks d2febedb, the patch would look something like:
>
> diff --git a/nbd/client.c b/nbd/client.c
> index 4caff77119..f04e95542f 100644
> --- a/nbd/client.c
> +++ b/nbd/client.c
> @@ -945,12 +945,6 @@ ssize_t nbd_receive_reply(QIOChannel *ioc, NBDReply *reply, Error **errp)
> reply->handle = ldq_be_p(buf + 8);
>
> reply->error = nbd_errno_to_system_errno(reply->error);
> -
> - if (reply->error == ESHUTDOWN) {
> - /* This works even on mingw which lacks a native ESHUTDOWN */
> - error_setg(errp, "server shutting down");
> - return -EINVAL;
> - }
> trace_nbd_receive_reply(magic, reply->error, reply->handle);
>
> if (magic != NBD_REPLY_MAGIC) {
>
> If that seems reasonable I can apply it as such.
Your backport looks correct to me; thanks.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2017-12-06 17:01 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-11-17 15:05 [Qemu-devel] [PULL 0/4] NBD patches for 2.11-rc2 Eric Blake
2017-11-17 15:05 ` [Qemu-devel] [PULL 1/4] nbd: Don't crash when server reports NBD_CMD_READ failure Eric Blake
2017-11-17 15:05 ` [Qemu-devel] [PULL 2/4] nbd/client: Use error_prepend() correctly Eric Blake
2017-11-17 15:05 ` [Qemu-devel] [PULL 3/4] nbd/client: Don't hard-disconnect on ESHUTDOWN from server Eric Blake
2017-12-06 16:55 ` Michael Roth
2017-12-06 17:01 ` Eric Blake
2017-11-17 15:05 ` [Qemu-devel] [PULL 4/4] nbd/server: Fix error reporting for bad requests Eric Blake
2017-11-17 19:07 ` [Qemu-devel] [PULL 0/4] NBD patches for 2.11-rc2 Peter Maydell
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).