Blame SOURCES/kvm-nbd-client-Trace-server-noncompliance-on-structured-.patch

7711c0
From debd78a4fda361c6a78bfc3f0e3577909bad3555 Mon Sep 17 00:00:00 2001
7711c0
From: John Snow <jsnow@redhat.com>
7711c0
Date: Mon, 6 May 2019 17:56:24 +0200
7711c0
Subject: [PATCH 14/53] nbd/client: Trace server noncompliance on structured
7711c0
 reads
7711c0
7711c0
RH-Author: John Snow <jsnow@redhat.com>
7711c0
Message-id: <20190506175629.11079-15-jsnow@redhat.com>
7711c0
Patchwork-id: 87192
7711c0
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH 14/19] nbd/client: Trace server noncompliance on structured reads
7711c0
Bugzilla: 1692018
7711c0
RH-Acked-by: Max Reitz <mreitz@redhat.com>
7711c0
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
7711c0
RH-Acked-by: Thomas Huth <thuth@redhat.com>
7711c0
7711c0
From: Eric Blake <eblake@redhat.com>
7711c0
7711c0
Just as we recently added a trace for a server sending block status
7711c0
that doesn't match the server's advertised minimum block alignment,
7711c0
let's do the same for read chunks.  But since qemu 3.1 is such a
7711c0
server (because it advertised 512-byte alignment, but when serving a
7711c0
file that ends in data but is not sector-aligned, NBD_CMD_READ would
7711c0
detect a mid-sector change between data and hole at EOF and the
7711c0
resulting read chunks are unaligned), we don't want to change our
7711c0
behavior of otherwise tolerating unaligned reads.
7711c0
7711c0
Note that even though we fixed the server for 4.0 to advertise an
7711c0
actual block alignment (which gets rid of the unaligned reads at EOF
7711c0
for posix files), we can still trigger it via other means:
7711c0
7711c0
$ qemu-nbd --image-opts driver=blkdebug,align=512,image.driver=file,image.filename=/path/to/non-aligned-file
7711c0
7711c0
Arguably, that is a bug in the blkdebug block status function, for
7711c0
leaking a block status that is not aligned. It may also be possible to
7711c0
observe issues with a backing layer with smaller alignment than the
7711c0
active layer, although so far I have been unable to write a reliable
7711c0
iotest for that scenario.
7711c0
7711c0
Signed-off-by: Eric Blake <eblake@redhat.com>
7711c0
Message-Id: <20190330165349.32256-1-eblake@redhat.com>
7711c0
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7711c0
(cherry picked from commit 75d34eb98ca0bb2f49d607fcaefd9c482e56b15d)
7711c0
Signed-off-by: John Snow <jsnow@redhat.com>
7711c0
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
7711c0
---
7711c0
 block/nbd-client.c | 12 ++++++++++--
7711c0
 block/trace-events |  1 +
7711c0
 2 files changed, 11 insertions(+), 2 deletions(-)
7711c0
7711c0
diff --git a/block/nbd-client.c b/block/nbd-client.c
7711c0
index a1a84a8..69e3708 100644
7711c0
--- a/block/nbd-client.c
7711c0
+++ b/block/nbd-client.c
7711c0
@@ -198,7 +198,8 @@ static inline uint64_t payload_advance64(uint8_t **payload)
7711c0
     return ldq_be_p(*payload - 8);
7711c0
 }
7711c0
 
7711c0
-static int nbd_parse_offset_hole_payload(NBDStructuredReplyChunk *chunk,
7711c0
+static int nbd_parse_offset_hole_payload(NBDClientSession *client,
7711c0
+                                         NBDStructuredReplyChunk *chunk,
7711c0
                                          uint8_t *payload, uint64_t orig_offset,
7711c0
                                          QEMUIOVector *qiov, Error **errp)
7711c0
 {
7711c0
@@ -220,6 +221,10 @@ static int nbd_parse_offset_hole_payload(NBDStructuredReplyChunk *chunk,
7711c0
                          " region");
7711c0
         return -EINVAL;
7711c0
     }
7711c0
+    if (client->info.min_block &&
7711c0
+        !QEMU_IS_ALIGNED(hole_size, client->info.min_block)) {
7711c0
+        trace_nbd_structured_read_compliance("hole");
7711c0
+    }
7711c0
 
7711c0
     qemu_iovec_memset(qiov, offset - orig_offset, 0, hole_size);
7711c0
 
7711c0
@@ -377,6 +382,9 @@ static int nbd_co_receive_offset_data_payload(NBDClientSession *s,
7711c0
                          " region");
7711c0
         return -EINVAL;
7711c0
     }
7711c0
+    if (s->info.min_block && !QEMU_IS_ALIGNED(data_size, s->info.min_block)) {
7711c0
+        trace_nbd_structured_read_compliance("data");
7711c0
+    }
7711c0
 
7711c0
     qemu_iovec_init(&sub_qiov, qiov->niov);
7711c0
     qemu_iovec_concat(&sub_qiov, qiov, offset - orig_offset, data_size);
7711c0
@@ -699,7 +707,7 @@ static int nbd_co_receive_cmdread_reply(NBDClientSession *s, uint64_t handle,
7711c0
              * in qiov */
7711c0
             break;
7711c0
         case NBD_REPLY_TYPE_OFFSET_HOLE:
7711c0
-            ret = nbd_parse_offset_hole_payload(&reply.structured, payload,
7711c0
+            ret = nbd_parse_offset_hole_payload(s, &reply.structured, payload,
7711c0
                                                 offset, qiov, &local_err);
7711c0
             if (ret < 0) {
7711c0
                 s->quit = true;
7711c0
diff --git a/block/trace-events b/block/trace-events
7711c0
index 59c6f54..19abca2 100644
7711c0
--- a/block/trace-events
7711c0
+++ b/block/trace-events
7711c0
@@ -153,5 +153,6 @@ nvme_cmd_map_qiov_iov(void *s, int i, void *page, int pages) "s %p iov[%d] %p pa
7711c0
 
7711c0
 # block/nbd-client.c
7711c0
 nbd_parse_blockstatus_compliance(const char *err) "ignoring extra data from non-compliant server: %s"
7711c0
+nbd_structured_read_compliance(const char *type) "server sent non-compliant unaligned read %s chunk"
7711c0
 nbd_read_reply_entry_fail(int ret, const char *err) "ret = %d, err: %s"
7711c0
 nbd_co_request_fail(uint64_t from, uint32_t len, uint64_t handle, uint16_t flags, uint16_t type, const char *name, int ret, const char *err) "Request failed { .from = %" PRIu64", .len = %" PRIu32 ", .handle = %" PRIu64 ", .flags = 0x%" PRIx16 ", .type = %" PRIu16 " (%s) } ret = %d, err: %s"
7711c0
-- 
7711c0
1.8.3.1
7711c0