changeset 117:55b2945bcee5

common: add xdrfd - a file descriptor based XDR backend Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Sat, 17 Oct 2015 19:00:44 -0400
parents c3422700267c
children d01f527b9718
files src/common/CMakeLists.txt src/common/include/nomad/rpc.h src/common/xdrfd.c
diffstat 3 files changed, 172 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/common/CMakeLists.txt	Sat Oct 17 18:59:16 2015 -0400
+++ b/src/common/CMakeLists.txt	Sat Oct 17 19:00:44 2015 -0400
@@ -31,6 +31,7 @@
 	rand.c
 	uuid.c
 	vclock.c
+	xdrfd.c
 
 	rpc_fs_xdr.c
 )
--- a/src/common/include/nomad/rpc.h	Sat Oct 17 18:59:16 2015 -0400
+++ b/src/common/include/nomad/rpc.h	Sat Oct 17 19:00:44 2015 -0400
@@ -23,10 +23,14 @@
 #ifndef __NOMAD_RPC_H
 #define __NOMAD_RPC_H
 
+#include <rpc/rpc.h>
+
 /* RPC error codes */
 #define NERR_UNKNOWN_ERROR     -1
 #define NERR_SUCCESS           0
 #define NERR_ENOENT            2
 #define NERR_EEXIST            17
 
+extern void xdrfd_create(XDR *xdr, int fd, enum xdr_op op);
+
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/xdrfd.c	Sat Oct 17 19:00:44 2015 -0400
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2015 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <unistd.h>
+
+#include <nomad/error.h>
+#include <nomad/rpc.h>
+
+static void invalid_op(void)
+{
+	ASSERT(0);
+}
+
+static ssize_t safe_read(int fd, void *buf, size_t nbyte)
+{
+	char *ptr = buf;
+	size_t total;
+	ssize_t ret;
+
+	total = 0;
+
+	while (nbyte) {
+		ret = read(fd, ptr, nbyte);
+		if (ret < 0)
+			return -1;
+
+		if (ret == 0)
+			break;
+
+		nbyte -= ret;
+		total += ret;
+		ptr   += ret;
+	}
+
+	return total;
+}
+
+static ssize_t safe_write(int fd, void *buf, size_t nbyte)
+{
+	const char *ptr = buf;
+	size_t total;
+	ssize_t ret;
+
+	total = 0;
+
+	while (nbyte) {
+		ret = write(fd, ptr, nbyte);
+		if (ret < 0)
+			return -1;
+
+		if (ret == 0)
+			break;
+
+		nbyte -= ret;
+		total += ret;
+		ptr   += ret;
+	}
+
+	return total;
+}
+
+static bool_t xdrfd_getbytes(XDR *xdr, caddr_t addr, int len)
+{
+	int fd = xdr->x_handy;
+
+	if (safe_read(fd, addr, len) != len)
+		return FALSE;
+	return TRUE;
+}
+
+static bool_t xdrfd_putbytes(XDR *xdr, caddr_t addr, int len)
+{
+	int fd = xdr->x_handy;
+
+	if (safe_write(fd, addr, len) != len)
+		return FALSE;
+	return TRUE;
+}
+
+static void xdrfd_destroy(XDR *xdr)
+{
+	fsync(xdr->x_handy);
+}
+
+static bool_t xdrfd_getint32(XDR *xdr, int32_t *p)
+{
+	int fd = xdr->x_handy;
+	int32_t buf = 0;
+
+	if (safe_read(fd, &buf, sizeof(buf)) != sizeof(buf))
+		return FALSE;
+
+	*p = ntohl(buf);
+	return TRUE;
+}
+
+static bool_t xdrfd_putint32(XDR *xdr, int32_t *p)
+{
+	int fd = xdr->x_handy;
+	int32_t buf;
+
+	buf = htonl(*p);
+
+	if (safe_write(fd, &buf, sizeof(buf)) != sizeof(buf))
+		return FALSE;
+
+	return TRUE;
+}
+
+static bool_t xdrfd_getlong(XDR *xdrs, long *p)
+{
+        int32_t tmp;
+
+        if (!xdrfd_getint32(xdrs, &tmp))
+                return FALSE;
+
+        *p = (long) tmp;
+        return TRUE;
+}
+
+static bool_t xdrfd_putlong(XDR *xdrs, long *p)
+{
+        int32_t tmp = *p;
+
+        return xdrfd_putint32(xdrs, &tmp);
+}
+
+static const struct xdr_ops ops = {
+	.x_getbytes = xdrfd_getbytes,
+	.x_putbytes = xdrfd_putbytes,
+	.x_getpostn = (void*) invalid_op,
+	.x_setpostn = (void*) invalid_op,
+	.x_inline   = (void*) invalid_op,
+	.x_destroy  = xdrfd_destroy,
+#ifdef _LP64
+	.x_getint32 = xdrfd_getint32,
+	.x_putint32 = xdrfd_putint32,
+#endif
+	.x_getlong  = xdrfd_getlong,
+	.x_putlong  = xdrfd_putlong,
+};
+
+void xdrfd_create(XDR *xdr, int fd, enum xdr_op op)
+{
+	xdr->x_op = op;
+	xdr->x_ops = (struct xdr_ops *) &ops;
+	xdr->x_handy = fd;
+}