Re: [Qemu-devel] [PATCH v3 7/6] nbd/client: Ignore inaccessible tail of inconsistent server

2019-03-29 Thread Eric Blake
On 3/29/19 11:54 AM, Vladimir Sementsov-Ogievskiy wrote:
> 29.03.2019 19:34, Eric Blake wrote:
>> The NBD spec suggests that a server should never advertise a size
>> inconsistent with its minimum block alignment, as that tail is
>> effectively inaccessible to a compliant client obeying those block
>> constraints. Although the block layer likes to round up, here, we'd
>> prefer to truncate down to obey the spec, and note that it is the
>> server's fault for advertising bogus size.
>>
>> Does not impact either qemu (which always sends properly aligned
>> sizes) or nbdkit (which does not send minimum block requirements yet);
>> so this is mostly theoretical, to avoid potential asserts elsewhere in
>> the code that assume the size is aligned.
>>

>>   }
>> +if (info->min_block &&
>> +!QEMU_IS_ALIGNED(info->size, info->min_block)) {
>> +trace_nbd_opt_info_go_unaligned_size(info->size,
>> + info->min_block);
>> +info->size = QEMU_ALIGN_DOWN(info->size, info->min_block);
>> +}
>>   trace_nbd_receive_negotiate_size_flags(info->size, 
>> info->flags);

> 
> And this again leads to silently skip file tail on qemu-img convert from such 
> nbd export.
> I don't really care, but if not Qemu neither nbdkit are affected, isn't it 
> better just
> nbd_send_opt_abort and return -1 in this case? So we'll never have hidden 
> troubles with
> third-party bad servers, and their developers will have to fix their code 
> instead (even
> not written yet, I suppose).

The code below is an example of killing connection to an impossible server:

if (!is_power_of_2(info->min_block)) {
error_setg(errp, "server minimum block size %" PRIu32
   " is not a power of two", info->min_block);
nbd_send_opt_abort(ioc);
return -1;

I'll copy that instead of silently truncating and proceeding on.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v3 7/6] nbd/client: Ignore inaccessible tail of inconsistent server

2019-03-29 Thread Eric Blake
The NBD spec suggests that a server should never advertise a size
inconsistent with its minimum block alignment, as that tail is
effectively inaccessible to a compliant client obeying those block
constraints. Although the block layer likes to round up, here, we'd
prefer to truncate down to obey the spec, and note that it is the
server's fault for advertising bogus size.

Does not impact either qemu (which always sends properly aligned
sizes) or nbdkit (which does not send minimum block requirements yet);
so this is mostly theoretical, to avoid potential asserts elsewhere in
the code that assume the size is aligned.

Signed-off-by: Eric Blake 
---
 nbd/client.c | 8 +++-
 nbd/trace-events | 1 +
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/nbd/client.c b/nbd/client.c
index de7da48246b..be437051429 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2016-2018 Red Hat, Inc.
+ *  Copyright (C) 2016-2019 Red Hat, Inc.
  *  Copyright (C) 2005  Anthony Liguori 
  *
  *  Network Block Device Client Side
@@ -426,6 +426,12 @@ static int nbd_opt_info_or_go(QIOChannel *ioc, uint32_t 
opt,
 nbd_send_opt_abort(ioc);
 return -1;
 }
+if (info->min_block &&
+!QEMU_IS_ALIGNED(info->size, info->min_block)) {
+trace_nbd_opt_info_go_unaligned_size(info->size,
+ info->min_block);
+info->size = QEMU_ALIGN_DOWN(info->size, info->min_block);
+}
 trace_nbd_receive_negotiate_size_flags(info->size, info->flags);
 break;

diff --git a/nbd/trace-events b/nbd/trace-events
index a6cca8fdf83..49dd48c9620 100644
--- a/nbd/trace-events
+++ b/nbd/trace-events
@@ -8,6 +8,7 @@ nbd_reply_err_unsup(uint32_t option, const char *name) "server 
doesn't understan
 nbd_receive_list(const char *name, const char *desc) "export list includes 
'%s', description '%s'"
 nbd_opt_info_go_start(const char *opt, const char *name) "Attempting %s for 
export '%s'"
 nbd_opt_info_go_success(const char *opt) "Export is ready after %s request"
+nbd_opt_info_go_unaligned_size(uint64_t size, uint32_t align) "Server reported 
unaligned size 0x%" PRIx64 " for alignment 0x%x; truncating"
 nbd_opt_info_unknown(int info, const char *name) "Ignoring unknown info %d 
(%s)"
 nbd_opt_info_block_size(uint32_t minimum, uint32_t preferred, uint32_t 
maximum) "Block sizes are 0x%" PRIx32 ", 0x%" PRIx32 ", 0x%" PRIx32
 nbd_receive_query_exports_start(const char *wantname) "Querying export list 
for '%s'"
-- 
2.20.1




Re: [Qemu-devel] [PATCH v3 7/6] nbd/client: Ignore inaccessible tail of inconsistent server

2019-03-29 Thread Vladimir Sementsov-Ogievskiy
29.03.2019 19:34, Eric Blake wrote:
> The NBD spec suggests that a server should never advertise a size
> inconsistent with its minimum block alignment, as that tail is
> effectively inaccessible to a compliant client obeying those block
> constraints. Although the block layer likes to round up, here, we'd
> prefer to truncate down to obey the spec, and note that it is the
> server's fault for advertising bogus size.
> 
> Does not impact either qemu (which always sends properly aligned
> sizes) or nbdkit (which does not send minimum block requirements yet);
> so this is mostly theoretical, to avoid potential asserts elsewhere in
> the code that assume the size is aligned.
> 
> Signed-off-by: Eric Blake 
> ---
>   nbd/client.c | 8 +++-
>   nbd/trace-events | 1 +
>   2 files changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/nbd/client.c b/nbd/client.c
> index de7da48246b..be437051429 100644
> --- a/nbd/client.c
> +++ b/nbd/client.c
> @@ -1,5 +1,5 @@
>   /*
> - *  Copyright (C) 2016-2018 Red Hat, Inc.
> + *  Copyright (C) 2016-2019 Red Hat, Inc.
>*  Copyright (C) 2005  Anthony Liguori 
>*
>*  Network Block Device Client Side
> @@ -426,6 +426,12 @@ static int nbd_opt_info_or_go(QIOChannel *ioc, uint32_t 
> opt,
>   nbd_send_opt_abort(ioc);
>   return -1;
>   }
> +if (info->min_block &&
> +!QEMU_IS_ALIGNED(info->size, info->min_block)) {
> +trace_nbd_opt_info_go_unaligned_size(info->size,
> + info->min_block);
> +info->size = QEMU_ALIGN_DOWN(info->size, info->min_block);
> +}
>   trace_nbd_receive_negotiate_size_flags(info->size, info->flags);
>   break;
> 
> diff --git a/nbd/trace-events b/nbd/trace-events
> index a6cca8fdf83..49dd48c9620 100644
> --- a/nbd/trace-events
> +++ b/nbd/trace-events
> @@ -8,6 +8,7 @@ nbd_reply_err_unsup(uint32_t option, const char *name) 
> "server doesn't understan
>   nbd_receive_list(const char *name, const char *desc) "export list includes 
> '%s', description '%s'"
>   nbd_opt_info_go_start(const char *opt, const char *name) "Attempting %s for 
> export '%s'"
>   nbd_opt_info_go_success(const char *opt) "Export is ready after %s request"
> +nbd_opt_info_go_unaligned_size(uint64_t size, uint32_t align) "Server 
> reported unaligned size 0x%" PRIx64 " for alignment 0x%x; truncating"
>   nbd_opt_info_unknown(int info, const char *name) "Ignoring unknown info %d 
> (%s)"
>   nbd_opt_info_block_size(uint32_t minimum, uint32_t preferred, uint32_t 
> maximum) "Block sizes are 0x%" PRIx32 ", 0x%" PRIx32 ", 0x%" PRIx32
>   nbd_receive_query_exports_start(const char *wantname) "Querying export list 
> for '%s'"
> 


And this again leads to silently skip file tail on qemu-img convert from such 
nbd export.
I don't really care, but if not Qemu neither nbdkit are affected, isn't it 
better just
nbd_send_opt_abort and return -1 in this case? So we'll never have hidden 
troubles with
third-party bad servers, and their developers will have to fix their code 
instead (even
not written yet, I suppose).


-- 
Best regards,
Vladimir