mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
nbd: Minimal structured read for client
Minimal implementation: for structured error only error_report error message. Note that test 83 is now more verbose, because the implementation prints more warnings about unexpected communication errors; perhaps future patches should tone things down by using trace messages instead of traces, but the common case of successful communication is no noisier than before. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Signed-off-by: Eric Blake <eblake@redhat.com> Message-Id: <20171027104037.8319-13-eblake@redhat.com>
This commit is contained in:
committed by
Eric Blake
parent
56dc682bf5
commit
f140e30003
+462
-36
File diff suppressed because it is too large
Load Diff
@@ -19,6 +19,7 @@
|
||||
|
||||
typedef struct {
|
||||
Coroutine *coroutine;
|
||||
uint64_t offset; /* original offset of the request */
|
||||
bool receiving; /* waiting for read_reply_co? */
|
||||
} NBDClientRequest;
|
||||
|
||||
|
||||
@@ -197,6 +197,11 @@ enum {
|
||||
#define NBD_REPLY_TYPE_ERROR NBD_REPLY_ERR(1)
|
||||
#define NBD_REPLY_TYPE_ERROR_OFFSET NBD_REPLY_ERR(2)
|
||||
|
||||
static inline bool nbd_reply_type_is_error(int type)
|
||||
{
|
||||
return type & (1 << 15);
|
||||
}
|
||||
|
||||
/* NBD errors are based on errno numbers, so there is a 1:1 mapping,
|
||||
* but only a limited set of errno values is specified in the protocol.
|
||||
* Everything else is squashed to EINVAL.
|
||||
@@ -214,6 +219,11 @@ enum {
|
||||
struct NBDExportInfo {
|
||||
/* Set by client before nbd_receive_negotiate() */
|
||||
bool request_sizes;
|
||||
|
||||
/* In-out fields, set by client before nbd_receive_negotiate() and
|
||||
* updated by server results during nbd_receive_negotiate() */
|
||||
bool structured_reply;
|
||||
|
||||
/* Set by server results during nbd_receive_negotiate() */
|
||||
uint64_t size;
|
||||
uint16_t flags;
|
||||
@@ -284,4 +294,6 @@ static inline bool nbd_reply_is_structured(NBDReply *reply)
|
||||
return reply->magic == NBD_STRUCTURED_REPLY_MAGIC;
|
||||
}
|
||||
|
||||
const char *nbd_reply_type_lookup(uint16_t type);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -602,9 +602,11 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
|
||||
uint64_t magic;
|
||||
int rc;
|
||||
bool zeroes = true;
|
||||
bool structured_reply = info->structured_reply;
|
||||
|
||||
trace_nbd_receive_negotiate(tlscreds, hostname ? hostname : "<null>");
|
||||
|
||||
info->structured_reply = false;
|
||||
rc = -EINVAL;
|
||||
|
||||
if (outioc) {
|
||||
@@ -685,6 +687,16 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
|
||||
if (fixedNewStyle) {
|
||||
int result;
|
||||
|
||||
if (structured_reply) {
|
||||
result = nbd_request_simple_option(ioc,
|
||||
NBD_OPT_STRUCTURED_REPLY,
|
||||
errp);
|
||||
if (result < 0) {
|
||||
goto fail;
|
||||
}
|
||||
info->structured_reply = result == 1;
|
||||
}
|
||||
|
||||
/* Try NBD_OPT_GO first - if it works, we are done (it
|
||||
* also gives us a good message if the server requires
|
||||
* TLS). If it is not available, fall back to
|
||||
|
||||
@@ -104,7 +104,6 @@ const char *nbd_opt_lookup(uint32_t opt);
|
||||
const char *nbd_rep_lookup(uint32_t rep);
|
||||
const char *nbd_info_lookup(uint16_t info);
|
||||
const char *nbd_cmd_lookup(uint16_t info);
|
||||
const char *nbd_reply_type_lookup(uint16_t type);
|
||||
const char *nbd_err_lookup(int err);
|
||||
|
||||
int nbd_drop(QIOChannel *ioc, size_t size, Error **errp);
|
||||
|
||||
@@ -41,6 +41,7 @@ can't open device nbd+tcp://127.0.0.1:PORT/foo
|
||||
|
||||
=== Check disconnect after neg2 ===
|
||||
|
||||
Connection closed
|
||||
read failed: Input/output error
|
||||
|
||||
=== Check disconnect 8 neg2 ===
|
||||
@@ -53,32 +54,39 @@ can't open device nbd+tcp://127.0.0.1:PORT/foo
|
||||
|
||||
=== Check disconnect before request ===
|
||||
|
||||
Connection closed
|
||||
read failed: Input/output error
|
||||
|
||||
=== Check disconnect after request ===
|
||||
|
||||
Connection closed
|
||||
read failed: Input/output error
|
||||
|
||||
=== Check disconnect before reply ===
|
||||
|
||||
Connection closed
|
||||
read failed: Input/output error
|
||||
|
||||
=== Check disconnect after reply ===
|
||||
|
||||
Unexpected end-of-file before all bytes were read
|
||||
read failed: Input/output error
|
||||
|
||||
=== Check disconnect 4 reply ===
|
||||
|
||||
Unexpected end-of-file before all bytes were read
|
||||
Connection closed
|
||||
read failed: Input/output error
|
||||
|
||||
=== Check disconnect 8 reply ===
|
||||
|
||||
Unexpected end-of-file before all bytes were read
|
||||
Connection closed
|
||||
read failed: Input/output error
|
||||
|
||||
=== Check disconnect before data ===
|
||||
|
||||
Unexpected end-of-file before all bytes were read
|
||||
read failed: Input/output error
|
||||
|
||||
=== Check disconnect after data ===
|
||||
@@ -108,6 +116,7 @@ can't open device nbd+tcp://127.0.0.1:PORT/
|
||||
|
||||
=== Check disconnect after neg-classic ===
|
||||
|
||||
Connection closed
|
||||
read failed: Input/output error
|
||||
|
||||
=== Check disconnect before neg1 ===
|
||||
@@ -168,28 +177,34 @@ read failed: Input/output error
|
||||
|
||||
=== Check disconnect after request ===
|
||||
|
||||
Connection closed
|
||||
read failed: Input/output error
|
||||
|
||||
=== Check disconnect before reply ===
|
||||
|
||||
Connection closed
|
||||
read failed: Input/output error
|
||||
|
||||
=== Check disconnect after reply ===
|
||||
|
||||
Unexpected end-of-file before all bytes were read
|
||||
read failed: Input/output error
|
||||
|
||||
=== Check disconnect 4 reply ===
|
||||
|
||||
Unexpected end-of-file before all bytes were read
|
||||
Connection closed
|
||||
read failed: Input/output error
|
||||
|
||||
=== Check disconnect 8 reply ===
|
||||
|
||||
Unexpected end-of-file before all bytes were read
|
||||
Connection closed
|
||||
read failed: Input/output error
|
||||
|
||||
=== Check disconnect before data ===
|
||||
|
||||
Unexpected end-of-file before all bytes were read
|
||||
read failed: Input/output error
|
||||
|
||||
=== Check disconnect after data ===
|
||||
|
||||
Reference in New Issue
Block a user