Skip site navigation (1)Skip section navigation (2)
Date:      18 Dec 2000 11:10:21 +0100
From:      assar@freebsd.org
To:        "Renaud Waldura" <renaud@waldura.com>, marcel@freebsd.org
Cc:        <emulation@freebsd.org>
Subject:   Re: q3ded 1.17: linux_socketcall returns errno -11
Message-ID:  <5l3dfmm44y.fsf@assaris.sics.se>
In-Reply-To: "Renaud Waldura"'s message of "Sat, 16 Dec 2000 17:29:40 -0800"
References:  <01a901c067b1$8ced2d00$0402010a@biohz.net> <3A3C0199.8DED329B@cup.hp.com> <000901c067c8$d406a7e0$0402010a@biohz.net>

next in thread | previous in thread | raw e-mail | index | archive | help

--=-=-=

"Renaud Waldura" <renaud@waldura.com> writes:

>  51543 q3ded    CALL  gettimeofday(0xbfbfba48,0xbfbfba50)
>  51543 q3ded    RET   gettimeofday 0
>  51543 q3ded    CALL  linux_newselect(0x1,0xbfbfb9d8,0,0,0xbfbfb9d0)
>  51543 q3ded    RET   linux_newselect 0
>  51543 q3ded    CALL  linux_socketcall(0xc,0xbfbfb9e8)
>  51543 q3ded    RET   linux_socketcall -1 errno 11 Resource deadlock avoided

Note first that the translation of errno 11 is wrong, on Linux errno
11 is EAGAIN.

(marcel: should we add a table of Linux error codes to linux_kdump? )

So I assume that what's happening here is that select says that the fd
is ready to be read from but then recvmsg returns EWOULDBLOCK (aka
EAGAIN).

The only way I can see that currently happening is if MSG_WAITALL for
some reason is set, now wait a moment, MSG_* do not have the same
values on Linux.

Could you try the following patch and tell us how it goes?  I'm afraid
it's against -current.  If it doesn't apply with small amounts of
force to -stable, bug me and I can redo it.  Marcel: does this look ok?

/assar

--=-=-=
Content-Disposition: attachment; filename=cld

Index: sys/compat/linux/linux_socket.c
===================================================================
RCS file: /home/ncvs/src/sys/compat/linux/linux_socket.c,v
retrieving revision 1.24
diff -u -w -r1.24 linux_socket.c
--- sys/compat/linux/linux_socket.c	2000/12/03 01:30:31	1.24
+++ sys/compat/linux/linux_socket.c	2000/12/18 10:04:51
@@ -50,6 +50,7 @@
 #include <machine/../linux/linux.h>
 #include <machine/../linux/linux_proto.h>
 #include <compat/linux/linux_util.h>
+#include <compat/linux/linux_socket.h>
 
 #ifndef __alpha__
 static int
@@ -142,6 +143,46 @@
 	return (-1);
 }
 
+static int
+linux_to_bsd_msg_flags(int flags)
+{
+	int ret_flags = 0;
+
+	if (flags & LINUX_MSG_OOB)
+		ret_flags |= MSG_OOB;
+	if (flags & LINUX_MSG_PEEK)
+		ret_flags |= MSG_PEEK;
+	if (flags & LINUX_MSG_DONTROUTE)
+		ret_flags |= MSG_DONTROUTE;
+	if (flags & LINUX_MSG_CTRUNC)
+		ret_flags |= MSG_CTRUNC;
+	if (flags & LINUX_MSG_TRUNC)
+		ret_flags |= MSG_TRUNC;
+	if (flags & LINUX_MSG_DONTWAIT)
+		ret_flags |= MSG_DONTWAIT;
+	if (flags & LINUX_MSG_EOR)
+		ret_flags |= MSG_EOR;
+	if (flags & LINUX_MSG_WAITALL)
+		ret_flags |= MSG_WAITALL;
+#if 0 /* not handled */
+	if (flags & LINUX_MSG_PROXY)
+		;
+	if (flags & LINUX_MSG_FIN)
+		;
+	if (flags & LINUX_MSG_SYN)
+		;
+	if (flags & LINUX_MSG_CONFIRM)
+		;
+	if (flags & LINUX_MSG_RST)
+		;
+	if (flags & LINUX_MSG_ERRQUEUE)
+		;
+	if (flags & LINUX_MSG_NOSIGNAL)
+		;
+#endif
+	return ret_flags;
+}
+
 /* Return 0 if IP_HDRINCL is set for the given socket. */
 static int
 linux_check_hdrincl(struct proc *p, int s)
@@ -701,12 +742,38 @@
 	bsd_args.s = linux_args.s;
 	bsd_args.buf = linux_args.buf;
 	bsd_args.len = linux_args.len;
-	bsd_args.flags = linux_args.flags;
+	bsd_args.flags = linux_to_bsd_msg_flags(linux_args.flags);
 	bsd_args.from = linux_args.from;
 	bsd_args.fromlenaddr = linux_args.fromlen;
 	return (orecvfrom(p, &bsd_args));
 }
 
+struct linux_recvmsg_args {
+	int s;
+	struct msghdr *msg;
+	int flags;
+};
+
+static int
+linux_recvmsg(struct proc *p, struct linux_recvmsg_args *args)
+{
+	struct linux_recvmsg_args linux_args;
+	struct recvmsg_args /* {
+		int	s;
+		struct	msghdr *msg;
+		int	flags;
+	} */ bsd_args;
+	int error;
+
+	if ((error = copyin(args, &linux_args, sizeof(linux_args))))
+		return (error);
+
+	bsd_args.s = linux_args.s;
+	bsd_args.msg = linux_args.msg;
+	bsd_args.flags = linux_to_bsd_msg_flags(linux_args.flags);
+	return (recvmsg(p, &bsd_args));
+}
+
 struct linux_shutdown_args {
 	int s;
 	int how;
@@ -905,7 +972,7 @@
 			return (sendmsg(p, args->args));
 		} while (0);
 	case LINUX_RECVMSG:
-		return (recvmsg(p, args->args));
+		return (linux_recvmsg(p, args->args));
 	}
 
 	uprintf("LINUX: 'socket' typ=%d not implemented\n", args->what);
--- /dev/null	Mon Dec 18 10:41:33 2000
+++ sys/compat/linux/linux_socket.h	Mon Dec 18 09:52:18 2000
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2000 Assar Westerlund
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer 
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _LINUX_SOCKET_H_
+#define _LINUX_SOCKET_H_
+
+/* msg flags in recvfrom/recvmsg */
+
+#define LINUX_MSG_OOB		0x01
+#define LINUX_MSG_PEEK		0x02
+#define LINUX_MSG_DONTROUTE	0x04
+#define LINUX_MSG_CTRUNC	0x08
+#define LINUX_MSG_PROXY		0x10
+#define LINUX_MSG_TRUNC		0x20
+#define LINUX_MSG_DONTWAIT	0x40
+#define LINUX_MSG_EOR		0x80
+#define LINUX_MSG_WAITALL	0x100
+#define LINUX_MSG_FIN		0x200
+#define LINUX_MSG_SYN		0x400
+#define LINUX_MSG_CONFIRM	0x800
+#define LINUX_MSG_RST		0x1000
+#define LINUX_MSG_ERRQUEUE	0x2000
+#define LINUX_MSG_NOSIGNAL	0x4000
+
+#endif /* _LINUX_SOCKET_H_ */

--=-=-=--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-emulation" in the body of the message




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