418638d3e4
The reason that NBD added structured reply in the first place was to allow for efficient reads of sparse files, by allowing the reply to include chunks to quickly communicate holes to the client without sending lots of zeroes over the wire. Time to implement this in the server; our client can already read such data. We can only skip holes insofar as the block layer can query them; and only if the client is okay with a fragmented request (if a client requests NBD_CMD_FLAG_DF and the entire read is a hole, we could technically return a single NBD_REPLY_TYPE_OFFSET_HOLE, but that's a fringe case not worth catering to here). Sadly, the control flow is a bit wonkier than I would have preferred, but it was minimally invasive to have a split in the action between a fragmented read (handled directly where we recognize NBD_CMD_READ with the right conditions, and sending multiple chunks) vs. a single read (handled at the end of nbd_trip, for both simple and structured replies, when we know there is only one thing being read). Likewise, I didn't make any effort to optimize the final chunk of a fragmented read to set the NBD_REPLY_FLAG_DONE, but unconditionally send that as a separate NBD_REPLY_TYPE_NONE. Signed-off-by: Eric Blake <eblake@redhat.com> Message-Id: <20171107030912.23930-2-eblake@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
66 lines
6.1 KiB
Plaintext
66 lines
6.1 KiB
Plaintext
# nbd/client.c
|
|
nbd_send_option_request(uint32_t opt, const char *name, uint32_t len) "Sending option request %" PRIu32" (%s), len %" PRIu32
|
|
nbd_receive_option_reply(uint32_t option, const char *optname, uint32_t type, const char *typename, uint32_t length) "Received option reply 0x%" PRIx32" (%s), type 0x%" PRIx32" (%s), len %" PRIu32
|
|
nbd_reply_err_unsup(uint32_t option, const char *name) "server doesn't understand request 0x%" PRIx32 " (%s), attempting fallback"
|
|
nbd_opt_go_start(const char *name) "Attempting NBD_OPT_GO for export '%s'"
|
|
nbd_opt_go_success(void) "Export is good to go"
|
|
nbd_opt_go_info_unknown(int info, const char *name) "Ignoring unknown info %d (%s)"
|
|
nbd_opt_go_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'"
|
|
nbd_receive_query_exports_success(const char *wantname) "Found desired export name '%s'"
|
|
nbd_receive_starttls_new_client(void) "Setting up TLS"
|
|
nbd_receive_starttls_tls_handshake(void) "Starting TLS handshake"
|
|
nbd_receive_negotiate(void *tlscreds, const char *hostname) "Receiving negotiation tlscreds=%p hostname=%s"
|
|
nbd_receive_negotiate_magic(uint64_t magic) "Magic is 0x%" PRIx64
|
|
nbd_receive_negotiate_server_flags(uint32_t globalflags) "Global flags are 0x%" PRIx32
|
|
nbd_receive_negotiate_default_name(void) "Using default NBD export name \"\""
|
|
nbd_receive_negotiate_size_flags(uint64_t size, uint16_t flags) "Size is %" PRIu64 ", export flags 0x%" PRIx16
|
|
nbd_init_set_socket(void) "Setting NBD socket"
|
|
nbd_init_set_block_size(unsigned long block_size) "Setting block size to %lu"
|
|
nbd_init_set_size(unsigned long sectors) "Setting size to %lu block(s)"
|
|
nbd_init_trailing_bytes(int ignored_bytes) "Ignoring trailing %d bytes of export"
|
|
nbd_init_set_readonly(void) "Setting readonly attribute"
|
|
nbd_init_finish(void) "Negotiation ended"
|
|
nbd_client_loop(void) "Doing NBD loop"
|
|
nbd_client_loop_ret(int ret, const char *error) "NBD loop returned %d: %s"
|
|
nbd_client_clear_queue(void) "Clearing NBD queue"
|
|
nbd_client_clear_socket(void) "Clearing NBD socket"
|
|
nbd_send_request(uint64_t from, uint32_t len, uint64_t handle, uint16_t flags, uint16_t type, const char *name) "Sending request to server: { .from = %" PRIu64", .len = %" PRIu32 ", .handle = %" PRIu64 ", .flags = 0x%" PRIx16 ", .type = %" PRIu16 " (%s) }"
|
|
nbd_receive_simple_reply(int32_t error, const char *errname, uint64_t handle) "Got simple reply: { .error = %" PRId32 " (%s), handle = %" PRIu64" }"
|
|
nbd_receive_structured_reply_chunk(uint16_t flags, uint16_t type, const char *name, uint64_t handle, uint32_t length) "Got structured reply chunk: { flags = 0x%" PRIx16 ", type = %d (%s), handle = %" PRIu64 ", length = %" PRIu32 " }"
|
|
|
|
# nbd/common.c
|
|
nbd_unknown_error(int err) "Squashing unexpected error %d to EINVAL"
|
|
|
|
# nbd/server.c
|
|
nbd_negotiate_send_rep_len(uint32_t opt, const char *optname, uint32_t type, const char *typename, uint32_t len) "Reply opt=0x%" PRIx32 " (%s), type=0x%" PRIx32 " (%s), len=%" PRIu32
|
|
nbd_negotiate_send_rep_err(const char *msg) "sending error message \"%s\""
|
|
nbd_negotiate_send_rep_list(const char *name, const char *desc) "Advertising export name '%s' description '%s'"
|
|
nbd_negotiate_handle_export_name(void) "Checking length"
|
|
nbd_negotiate_handle_export_name_request(const char *name) "Client requested export '%s'"
|
|
nbd_negotiate_send_info(int info, const char *name, uint32_t length) "Sending NBD_REP_INFO type %d (%s) with remaining length %" PRIu32
|
|
nbd_negotiate_handle_info_requests(int requests) "Client requested %d items of info"
|
|
nbd_negotiate_handle_info_request(int request, const char *name) "Client requested info %d (%s)"
|
|
nbd_negotiate_handle_info_block_size(uint32_t minimum, uint32_t preferred, uint32_t maximum) "advertising minimum 0x%" PRIx32 ", preferred 0x%" PRIx32 ", maximum 0x%" PRIx32
|
|
nbd_negotiate_handle_starttls(void) "Setting up TLS"
|
|
nbd_negotiate_handle_starttls_handshake(void) "Starting TLS handshake"
|
|
nbd_negotiate_options_flags(uint32_t flags) "Received client flags 0x%" PRIx32
|
|
nbd_negotiate_options_check_magic(uint64_t magic) "Checking opts magic 0x%" PRIx64
|
|
nbd_negotiate_options_check_option(uint32_t option, const char *name) "Checking option 0x%" PRIx32 " (%s)"
|
|
nbd_negotiate_begin(void) "Beginning negotiation"
|
|
nbd_negotiate_old_style(uint64_t size, unsigned flags) "advertising size %" PRIu64 " and flags 0x%x"
|
|
nbd_negotiate_new_style_size_flags(uint64_t size, unsigned flags) "advertising size %" PRIu64 " and flags 0x%x"
|
|
nbd_negotiate_success(void) "Negotiation succeeded"
|
|
nbd_receive_request(uint32_t magic, uint16_t flags, uint16_t type, uint64_t from, uint32_t len) "Got request: { magic = 0x%" PRIx32 ", .flags = 0x%" PRIx16 ", .type = 0x%" PRIx16 ", from = %" PRIu64 ", len = %" PRIu32 " }"
|
|
nbd_blk_aio_attached(const char *name, void *ctx) "Export %s: Attaching clients to AIO context %p\n"
|
|
nbd_blk_aio_detach(const char *name, void *ctx) "Export %s: Detaching clients from AIO context %p\n"
|
|
nbd_co_send_simple_reply(uint64_t handle, uint32_t error, const char *errname, int len) "Send simple reply: handle = %" PRIu64 ", error = %" PRIu32 " (%s), len = %d"
|
|
nbd_co_send_structured_done(uint64_t handle) "Send structured reply done: handle = %" PRIu64
|
|
nbd_co_send_structured_read(uint64_t handle, uint64_t offset, void *data, size_t size) "Send structured read data reply: handle = %" PRIu64 ", offset = %" PRIu64 ", data = %p, len = %zu"
|
|
nbd_co_send_structured_read_hole(uint64_t handle, uint64_t offset, size_t size) "Send structured read hole reply: handle = %" PRIu64 ", offset = %" PRIu64 ", len = %zu"
|
|
nbd_co_send_structured_error(uint64_t handle, int err, const char *errname, const char *msg) "Send structured error reply: handle = %" PRIu64 ", error = %d (%s), msg = '%s'"
|
|
nbd_co_receive_request_decode_type(uint64_t handle, uint16_t type, const char *name) "Decoding type: handle = %" PRIu64 ", type = %" PRIu16 " (%s)"
|
|
nbd_co_receive_request_payload_received(uint64_t handle, uint32_t len) "Payload received: handle = %" PRIu64 ", len = %" PRIu32
|
|
nbd_co_receive_request_cmd_write(uint32_t len) "Reading %" PRIu32 " byte(s)"
|
|
nbd_trip(void) "Reading request"
|