All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Blake <eblake@redhat.com>
To: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>,
	qemu-devel@nongnu.org
Cc: pbonzini@redhat.com, qemu-block@nongnu.org,
	Kevin Wolf <kwolf@redhat.com>, Max Reitz <mreitz@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v5 11/11] nbd: Minimal structured read for client
Date: Fri, 20 Oct 2017 15:46:30 -0500	[thread overview]
Message-ID: <4509afab-6d76-405a-d025-7c634491f54d@redhat.com> (raw)
In-Reply-To: <799e98b5-4013-0118-1cd1-3fba39fe6bdc@virtuozzo.com>

[-- Attachment #1: Type: text/plain, Size: 5690 bytes --]

On 10/20/2017 02:58 PM, Vladimir Sementsov-Ogievskiy wrote:
> 20.10.2017 01:26, Eric Blake wrote:
>> From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
>>
>> Minimal implementation: for structured error only error_report error
>> message.
>>
>> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
>> Signed-off-by: Eric Blake <eblake@redhat.com>
>>

>> +static int nbd_parse_offset_hole_payload(NBDStructuredReplyChunk *chunk,
>> +                                         uint8_t *payload,
>> QEMUIOVector *qiov,
>> +                                         Error **errp)
>> +{
>> +    uint64_t offset;
>> +    uint32_t hole_size;
>> +
>> +    if (chunk->length != sizeof(offset) + sizeof(hole_size)) {
>> +        error_setg(errp, "Protocol error: invalid payload for "
>> +                         "NBD_REPLY_TYPE_OFFSET_HOLE");
>> +        return -EINVAL;
>> +    }
>> +
>> +    offset = payload_advance64(&payload);
>> +    hole_size = payload_advance32(&payload);
>> +
>> +    if (offset > qiov->size - hole_size) {
> 
> hmm, you've changed order to prevent overflow.. can it overflow anyway
> through negative minimum on 32-bit system with some unhappy size and
> hole_size?

Good catch; qiov->size is size_t, hole_size is uint32_t.  qiov->size
happens to be bounded by NBD_MAX_BUFFER_SIZE (we wouldn't have sent the
request otherwise, to be getting the reply now), but hole_size came over
the wire and must be considered untrusted.  So you are correct that we
don't know that we avoided overflow unless we also compare the two
values, as in:

if (hole_size > qiov->size || offset > qiov->size - hole_size)

in both affected functions.


>> +    *request_ret = -error;
>> +    message_size = payload_advance16(&payload);
>> +
>> +    if (message_size > chunk->length - sizeof(error) -
>> sizeof(message_size)) {
>> +        error_setg(errp, "Protocol error: server sent structured
>> error chunk"
>> +                         "with incorrect message size");
>> +        return -EINVAL;
>> +    }
>> +
> 
> you removed my error message from errp, but didn't change comment..
> 
> And you lose the message.. At least add a "TODO" for it...
> 
>> +    /* TODO: Add a trace point to mention the server complaint */

...

>> +
>> +#define NBD_MAX_MALLOC_PAYLOAD 1000
>> +/* nbd_co_receive_structured_payload
>> + * The resulting pointer stored in @payload requires g_free() to free
>> it.
> 
> I think now it is an extra comment..
> (and all it's duplication)

True. g_new() is normal enough that the comment doesn't add as much (the
comment was important when we were using the unusual qemu_memalign(),
but we don't need that).


>> +
>> +    if (nbd_reply_type_is_error(chunk->type)) {
>> +        ret = nbd_parse_error_payload(chunk, local_payload,
>> request_ret, errp);
>> +        g_free(local_payload);
> 
> and error message is lost.. So you don't like an idea of saving it in errp?

...because storing in errp, but returning 0, is wrong.  We do NOT need
to be spamming stderr with every time the server replied with an error,
because that is NORMAL behavior that can (sometimes) be gracefully
recovered from - the most obvious situation is ENOSPC errors resulting
from write(), where we add the proposed NBD resize extension to allow
the client to resize the server and then try again.  Tracing server
messages might be useful, but reporting them indiscriminately is not.  I
dropped the setting of errp in these two places because of the
regression I mentioned in this mail:
https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg04796.html

where setting errp but returning 0 led to duplicate or
poorly-constructed messages.

In my testing, it worked best to set errp ONLY in the situations where
we are giving up all future communication with the server, and not
merely because the server reported an error but we are still fine to
keep talking to the server.


>> -    return nbd_co_receive_reply(client, request->handle,
>> -                                request->type == NBD_CMD_READ ? qiov
>> : NULL);
>> +    ret = nbd_co_receive_return_code(client, request->handle,
>> &local_err);
>> +    if (local_err) {
> 
> hmm, you changed it from "if (ret < 0)"... It doesn't matter, just note
> that here (local_err != NULL) <=> (ret < 0).

This was the trick to the errp stuff above: we HAVE to return a negative
errno code to the caller whether the connection was fatally wounded or
whether it is just reporting a server error code; so at this point, ret
< 0 is NOT equivalent to local_err != NULL.  I got a coredump if I used
'if (ret < 0)' on situations where the server replied with an error, but
where it was not fatal so we did not set local_err, because you can't
error_report_err(NULL).

> 
>> +        error_report_err(local_err);
>> +    }
>> +    return ret;
>>   }
> 
> [...]
> 
> 
> I'm ok with this, we can improve error handling later.

Indeed - I'd like to get as much in as possible for soft freeze, then
focus on polishing things before hard freeze.  I don't know if we'll get
block status in, or just structured read; and I'd really like to be able
to read holes, but one thing at a time...

-- 
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 --]

  reply	other threads:[~2017-10-20 20:46 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-19 22:26 [Qemu-devel] [PATCH v5 00/11] nbd minimal structured read Eric Blake
2017-10-19 22:26 ` [Qemu-devel] [PATCH v5 01/11] nbd: Include error names in trace messages Eric Blake
2017-10-19 22:26 ` [Qemu-devel] [PATCH v5 02/11] nbd: Move nbd_errno_to_system_errno() to public header Eric Blake
2017-10-19 22:26 ` [Qemu-devel] [PATCH v5 03/11] nbd: Expose constants and structs for structured read Eric Blake
2017-10-20  8:00   ` Vladimir Sementsov-Ogievskiy
2017-10-19 22:26 ` [Qemu-devel] [PATCH v5 04/11] nbd/server: Report error for write to read-only export Eric Blake
2017-10-20  8:06   ` Vladimir Sementsov-Ogievskiy
2017-10-19 22:26 ` [Qemu-devel] [PATCH v5 05/11] nbd/server: Refactor zero-length option check Eric Blake
2017-10-20  8:34   ` Vladimir Sementsov-Ogievskiy
2017-10-20 15:07     ` Eric Blake
2017-10-20 18:12       ` Vladimir Sementsov-Ogievskiy
2017-10-19 22:26 ` [Qemu-devel] [PATCH v5 06/11] nbd: Minimal structured read for server Eric Blake
2017-10-20 19:03   ` Vladimir Sementsov-Ogievskiy
2017-10-20 19:11     ` Eric Blake
2017-10-20 19:30       ` Vladimir Sementsov-Ogievskiy
2017-10-21 16:02         ` Eric Blake
2017-10-19 22:26 ` [Qemu-devel] [PATCH v5 07/11] nbd/server: Include human-readable message in structured errors Eric Blake
2017-10-20 19:08   ` Vladimir Sementsov-Ogievskiy
2017-10-19 22:26 ` [Qemu-devel] [PATCH v5 08/11] nbd/client: refactor nbd_receive_starttls Eric Blake
2017-10-20 19:26   ` Vladimir Sementsov-Ogievskiy
2017-10-20 19:33     ` Eric Blake
2017-10-19 22:26 ` [Qemu-devel] [PATCH v5 09/11] nbd/client: prepare nbd_receive_reply for structured reply Eric Blake
2017-10-19 22:26 ` [Qemu-devel] [PATCH v5 10/11] nbd: Move nbd_read() to common header Eric Blake
2017-10-19 22:26 ` [Qemu-devel] [PATCH v5 11/11] nbd: Minimal structured read for client Eric Blake
2017-10-20 19:58   ` Vladimir Sementsov-Ogievskiy
2017-10-20 20:46     ` Eric Blake [this message]
2017-10-23 11:57   ` Eric Blake
2017-10-23 12:24     ` Vladimir Sementsov-Ogievskiy
2017-10-24  7:31   ` Eric Blake
2017-10-19 23:07 ` [Qemu-devel] [PATCH v5 00/11] nbd minimal structured read no-reply
2017-10-20 15:09   ` Eric Blake

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4509afab-6d76-405a-d025-7c634491f54d@redhat.com \
    --to=eblake@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=vsementsov@virtuozzo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.