nbdkit/0007-protocol-Send-limited-...

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/11] 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