Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 14 Mar 2014 14:54:43 +0100
From:      Jilles Tjoelker <jilles@stack.nl>
To:        Anton Shterenlikht <mexas@bris.ac.uk>
Cc:        freebsd-current@freebsd.org
Subject:   Re: r263096 sparc64: casperd: Unable to receive message from client: Cannot allocate memory.
Message-ID:  <20140314135442.GC5792@stack.nl>
In-Reply-To: <201403131214.s2DCEsvW084517@mech-cluster241.men.bris.ac.uk>
References:  <201403131214.s2DCEsvW084517@mech-cluster241.men.bris.ac.uk>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Mar 13, 2014 at 05:14:56AM -0700, Anton Shterenlikht wrote:
> FreeBSD 11.0-CURRENT #1 r263096

> Is casperd started by default?
> I haven't enabled it in /etc/rc.conf

> I think I get this error when trying
> to use ping, e.g.:

> # ping localhost
> Broken pipe
> # ping freebsd.org
> Broken pipe
> #

> Mar 13 12:08:48 casperd[1313]: [ERROR] (casperd) Unable to receive message from client: Cannot allocate memory.
> Mar 13 12:08:50 last message repeated 2 times
> Mar 13 12:09:57 casperd[1313]: [ERROR] (casperd) Unable to receive message from client: Cannot allocate memory.

> What does this error mean?

It looks like a bug causes the "big endian" flag to be lost. As a
result, the bits are interpreted as little endian and an extremely large
allocation is attempted. Try this patch:

Index: lib/libnv/nvlist.c
===================================================================
--- lib/libnv/nvlist.c	(revision 262358)
+++ lib/libnv/nvlist.c	(working copy)
@@ -582,7 +582,7 @@ nvlist_check_header(struct nvlist_header *nvlhdrp)
 		errno = EINVAL;
 		return (false);
 	}
-	if ((nvlhdrp->nvlh_flags &= ~NV_FLAG_ALL_MASK) != 0) {
+	if ((nvlhdrp->nvlh_flags & ~NV_FLAG_ALL_MASK) != 0) {
 		errno = EINVAL;
 		return (false);
 	}

On another note, I don't think the sends to casperd should be generating
SIGPIPE. Instead, the EPIPE error can be handled as normal, without
immediately terminating the process. I propose the following patch, with
a .Dd bump to the man page (to test it, the first patch should not be
applied):

Index: lib/libnv/msgio.c
===================================================================
--- lib/libnv/msgio.c	(revision 262358)
+++ lib/libnv/msgio.c	(working copy)
@@ -147,7 +147,7 @@ msg_send(int sock, const struct msghdr *msg)
 
 	for (;;) {
 		fd_wait(sock, false);
-		if (sendmsg(sock, msg, 0) == -1) {
+		if (sendmsg(sock, msg, MSG_NOSIGNAL) == -1) {
 			if (errno == EINTR)
 				continue;
 			return (-1);
@@ -345,7 +345,7 @@ buf_send(int sock, void *buf, size_t size)
 	ptr = buf;
 	do {
 		fd_wait(sock, false);
-		done = send(sock, ptr, size, 0);
+		done = send(sock, ptr, size, MSG_NOSIGNAL);
 		if (done == -1) {
 			if (errno == EINTR)
 				continue;
Index: lib/libnv/nv.3
===================================================================
--- lib/libnv/nv.3	(revision 262358)
+++ lib/libnv/nv.3	(working copy)
@@ -310,7 +310,9 @@ The
 .Fn nvlist_send
 function sends the given nvlist over the socket given by the
 .Fa sock
-argument.
+argument,
+without generating
+.Dv SIGPIPE .
 Note that nvlist that contains file descriptors can only be send over
 .Xr unix 4
 domain sockets.

-- 
Jilles Tjoelker



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140314135442.GC5792>