117 lines
3.4 KiB
Diff
117 lines
3.4 KiB
Diff
|
From f141228d1b6baddadcd516137d76b3d852af8cde Mon Sep 17 00:00:00 2001
|
||
|
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||
|
Date: Tue, 12 Jan 2016 12:16:48 +0000
|
||
|
Subject: [PATCH 07/10] protocol: Send limited range of errno values to the
|
||
|
client.
|
||
|
|
||
|
See the proposal here:
|
||
|
http://article.gmane.org/gmane.linux.drivers.nbd.general/3154
|
||
|
|
||
|
This implementation is based on Paolo Bonzini's for qemu-nbd:
|
||
|
http://git.qemu.org/?p=qemu.git;a=commitdiff;h=ca4414804114fd0095b317785bc0b51862e62ebb
|
||
|
---
|
||
|
TODO | 6 ------
|
||
|
src/connections.c | 36 +++++++++++++++++++++++++++++++++++-
|
||
|
src/protocol.h | 12 +++++++++++-
|
||
|
3 files changed, 46 insertions(+), 8 deletions(-)
|
||
|
|
||
|
diff --git a/TODO b/TODO
|
||
|
index d39e64c..177a07c 100644
|
||
|
--- a/TODO
|
||
|
+++ b/TODO
|
||
|
@@ -1,9 +1,3 @@
|
||
|
-* There is a proposal to narrow the range of possible errnos that the
|
||
|
- server can return, and also to encode them in an OS-independent way.
|
||
|
- See: http://article.gmane.org/gmane.linux.drivers.nbd.general/3154
|
||
|
- Implemented in QEMU already:
|
||
|
- http://git.qemu.org/?p=qemu.git;a=commitdiff;h=ca4414804114fd0095b317785bc0b51862e62ebb
|
||
|
-
|
||
|
* Can we do language bindings using #!'s?
|
||
|
You would enter:
|
||
|
nbdkit foo [args]
|
||
|
diff --git a/src/connections.c b/src/connections.c
|
||
|
index 6bdf4ef..f0a7662 100644
|
||
|
--- a/src/connections.c
|
||
|
+++ b/src/connections.c
|
||
|
@@ -639,6 +639,31 @@ skip_over_write_buffer (int sock, size_t count)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+/* Convert a system errno to an NBD_E* error code. */
|
||
|
+static int
|
||
|
+nbd_errno (int error)
|
||
|
+{
|
||
|
+ switch (error) {
|
||
|
+ case 0:
|
||
|
+ return NBD_SUCCESS;
|
||
|
+ case EPERM:
|
||
|
+ return NBD_EPERM;
|
||
|
+ case EIO:
|
||
|
+ return NBD_EIO;
|
||
|
+ case ENOMEM:
|
||
|
+ return NBD_ENOMEM;
|
||
|
+#ifdef EDQUOT
|
||
|
+ case EDQUOT:
|
||
|
+#endif
|
||
|
+ case EFBIG:
|
||
|
+ case ENOSPC:
|
||
|
+ return NBD_ENOSPC;
|
||
|
+ case EINVAL:
|
||
|
+ default:
|
||
|
+ return NBD_EINVAL;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
static int
|
||
|
recv_request_send_reply (struct connection *conn)
|
||
|
{
|
||
|
@@ -722,7 +747,16 @@ recv_request_send_reply (struct connection *conn)
|
||
|
send_reply:
|
||
|
reply.magic = htobe32 (NBD_REPLY_MAGIC);
|
||
|
reply.handle = request.handle;
|
||
|
- reply.error = htobe32 (error);
|
||
|
+ reply.error = htobe32 (nbd_errno (error));
|
||
|
+
|
||
|
+ if (error != 0) {
|
||
|
+ /* Since we're about to send only the limited NBD_E* errno to the
|
||
|
+ * client, don't lose the information about what really happened
|
||
|
+ * on the server side. Make sure there is a way for the operator
|
||
|
+ * to retrieve the real error.
|
||
|
+ */
|
||
|
+ debug ("sending error reply: %s", strerror (error));
|
||
|
+ }
|
||
|
|
||
|
r = xwrite (conn->sockout, &reply, sizeof reply);
|
||
|
if (r == -1) {
|
||
|
diff --git a/src/protocol.h b/src/protocol.h
|
||
|
index 2f9a341..fcbc145 100644
|
||
|
--- a/src/protocol.h
|
||
|
+++ b/src/protocol.h
|
||
|
@@ -118,7 +118,7 @@ struct request {
|
||
|
/* Reply (server -> client). */
|
||
|
struct reply {
|
||
|
uint32_t magic; /* NBD_REPLY_MAGIC. */
|
||
|
- uint32_t error; /* 0 = ok, error code */
|
||
|
+ uint32_t error; /* NBD_SUCCESS or one of NBD_E*. */
|
||
|
uint64_t handle; /* Opaque handle. */
|
||
|
} __attribute__((packed));
|
||
|
|
||
|
@@ -133,4 +133,14 @@ struct reply {
|
||
|
#define NBD_CMD_MASK_COMMAND 0xffff
|
||
|
#define NBD_CMD_FLAG_FUA (1<<16)
|
||
|
|
||
|
+/* Error codes (previously errno).
|
||
|
+ * See http://git.qemu.org/?p=qemu.git;a=commitdiff;h=ca4414804114fd0095b317785bc0b51862e62ebb
|
||
|
+ */
|
||
|
+#define NBD_SUCCESS 0
|
||
|
+#define NBD_EPERM 1
|
||
|
+#define NBD_EIO 5
|
||
|
+#define NBD_ENOMEM 12
|
||
|
+#define NBD_EINVAL 22
|
||
|
+#define NBD_ENOSPC 28
|
||
|
+
|
||
|
#endif /* NBDKIT_PROTOCOL_H */
|
||
|
--
|
||
|
2.7.4
|
||
|
|