I've encountered two socket related problems with the Linux emulation: 1. A Linux application passing the MSG_NOSIGNAL flag in calls to recv() or recvfrom() will still receive a SIGPIPE if the condition for sending the signal is met. 2. An attempt to set socket timeouts with a call to setsocktopt() using the SO_RECVTIMEO or SO_SNDTIMEO option will fail with [EINVAL] on amd64. Fix: 1. Call linux_to_bsd_msg_flags() in linux_recv(). 2. Translate l_timeval arg to native struct timeval in linux_setsockopt(). Patch attached. Patch attached with submission follows:
Responsible Changed From-To: freebsd-bugs->freebsd-emulation Over to maintainer(s).
On Wed, May 06, 2009 at 04:57:50PM +0000, Thomas Mueller wrote: > > >Number: 134276 > >Category: kern > >Synopsis: [linux][patch] MSG_NOSIGNAL not translated for recv(), socket timeout incorrect for 64-bit hosts > >Confidential: no > >Severity: non-critical > >Priority: low > >Responsible: freebsd-bugs > >State: open > >Quarter: > >Keywords: > >Date-Required: > >Class: sw-bug > >Submitter-Id: current-users > >Arrival-Date: Wed May 06 17:00:07 UTC 2009 > >Closed-Date: > >Last-Modified: > >Originator: Thomas Mueller > >Release: 7.2-STABLE > >Organization: > >Environment: > FreeBSD tom.ulm.sysgo.com 7.2-STABLE FreeBSD 7.2-STABLE #16: Mon May 4 15:12:43 CEST 2009 toor@tom.ulm.sysgo.com:/usr/obj/usr/src/sys/TOM amd64 > >Description: > I've encountered two socket related problems with the Linux emulation: > > 1. A Linux application passing the MSG_NOSIGNAL flag in calls to > recv() or recvfrom() will still receive a SIGPIPE if the condition > for sending the signal is met. > > 2. An attempt to set socket timeouts with a call to setsocktopt() using the > SO_RECVTIMEO or SO_SNDTIMEO option will fail with [EINVAL] on amd64. > What the Linux application you have mentioned? I should know it to test patches. Thank you. -- Have fun! chd
On Sat, 9 May 2009 00:10:03 +0400, Chagin Dmitry wrote: > On Wed, May 06, 2009 at 04:57:50PM +0000, Thomas Mueller wrote: > > > > >Number: 134276 > > >Category: kern > > >Synopsis: [linux][patch] MSG_NOSIGNAL not translated for recv(), socket timeout incorrect for 64-bit hosts > > >Confidential: no > > >Severity: non-critical > > >Priority: low > > >Responsible: freebsd-bugs > > >State: open > > >Quarter: > > >Keywords: > > >Date-Required: > > >Class: sw-bug > > >Submitter-Id: current-users > > >Arrival-Date: Wed May 06 17:00:07 UTC 2009 > > >Closed-Date: > > >Last-Modified: > > >Originator: Thomas Mueller > > >Release: 7.2-STABLE > > >Organization: > > >Environment: > > FreeBSD tom.ulm.sysgo.com 7.2-STABLE FreeBSD 7.2-STABLE #16: Mon May 4 15:12:43 CEST 2009 toor@tom.ulm.sysgo.com:/usr/obj/usr/src/sys/TOM amd64 > > >Description: > > I've encountered two socket related problems with the Linux emulation: > > > > 1. A Linux application passing the MSG_NOSIGNAL flag in calls to > > recv() or recvfrom() will still receive a SIGPIPE if the condition > > for sending the signal is met. > > > > 2. An attempt to set socket timeouts with a call to setsocktopt() using the > > SO_RECVTIMEO or SO_SNDTIMEO option will fail with [EINVAL] on amd64. > > > > What the Linux application you have mentioned? > I should know it to test patches. Thank you. Sorry for not mentioning it in the PR. The applications are part of the LM-X License Manager package by X-Formation (http://www.x-formation.com/). It looks like they offer a trial download but require registration. When back in the office (next weeek), I could revert my local changes and provide you with an output of linux_kdump if that helps. I would also test patches. -- Thomas Mueller
Author: dchagin Date: Mon May 11 13:42:40 2009 New Revision: 191988 URL: http://svn.freebsd.org/changeset/base/191988 Log: Add forgotten linux to bsd flags argument mapping into the linux_recv(). PR: kern/134276 Submitted by: Thomas Mueller <tmueller sysgo com> Approved by: kib (mentor) MFC after: 2 weeks Modified: head/sys/compat/linux/linux_socket.c Modified: head/sys/compat/linux/linux_socket.c ============================================================================== --- head/sys/compat/linux/linux_socket.c Mon May 11 07:57:29 2009 (r191987) +++ head/sys/compat/linux/linux_socket.c Mon May 11 13:42:40 2009 (r191988) @@ -924,7 +924,7 @@ linux_recv(struct thread *td, struct lin bsd_args.s = args->s; bsd_args.buf = (caddr_t)PTRIN(args->msg); bsd_args.len = args->len; - bsd_args.flags = args->flags; + bsd_args.flags = linux_to_bsd_msg_flags(args->flags); bsd_args.from = NULL; bsd_args.fromlenaddr = 0; return (recvfrom(td, &bsd_args)); _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Author: dchagin Date: Mon May 11 13:50:42 2009 New Revision: 191989 URL: http://svn.freebsd.org/changeset/base/191989 Log: Translate l_timeval arg to native struct timeval in linux_setsockopt()/linux_getsockopt() for SO_RCVTIMEO, SO_SNDTIMEO opts as l_timeval has MD members. Remove bogus __packed attribute from l_timeval struct on __amd64__. PR: kern/134276 Submitted by: Thomas Mueller <tmueller sysgo com> Approved by: kib (mentor) MFC after: 2 weeks Modified: head/sys/amd64/linux32/linux.h head/sys/compat/linux/linux_socket.c Modified: head/sys/amd64/linux32/linux.h ============================================================================== --- head/sys/amd64/linux32/linux.h Mon May 11 13:42:40 2009 (r191988) +++ head/sys/amd64/linux32/linux.h Mon May 11 13:50:42 2009 (r191989) @@ -96,7 +96,7 @@ typedef struct { typedef struct { l_time_t tv_sec; l_suseconds_t tv_usec; -} __packed l_timeval; +} l_timeval; #define l_fd_set fd_set Modified: head/sys/compat/linux/linux_socket.c ============================================================================== --- head/sys/compat/linux/linux_socket.c Mon May 11 13:42:40 2009 (r191988) +++ head/sys/compat/linux/linux_socket.c Mon May 11 13:50:42 2009 (r191989) @@ -1278,6 +1278,8 @@ linux_setsockopt(struct thread *td, stru caddr_t val; int valsize; } */ bsd_args; + l_timeval linux_tv; + struct timeval tv; int error, name; bsd_args.s = args->s; @@ -1285,6 +1287,23 @@ linux_setsockopt(struct thread *td, stru switch (bsd_args.level) { case SOL_SOCKET: name = linux_to_bsd_so_sockopt(args->optname); + switch (name) { + case SO_RCVTIMEO: + /* FALLTHROUGH */ + case SO_SNDTIMEO: + error = copyin(PTRIN(args->optval), &linux_tv, + sizeof(linux_tv)); + if (error) + return (error); + tv.tv_sec = linux_tv.tv_sec; + tv.tv_usec = linux_tv.tv_usec; + return (kern_setsockopt(td, args->s, bsd_args.level, + name, &tv, UIO_SYSSPACE, sizeof(tv))); + /* NOTREACHED */ + break; + default: + break; + } break; case IPPROTO_IP: name = linux_to_bsd_ip_sockopt(args->optname); @@ -1333,6 +1352,9 @@ linux_getsockopt(struct thread *td, stru caddr_t val; int *avalsize; } */ bsd_args; + l_timeval linux_tv; + struct timeval tv; + socklen_t tv_len; int error, name; bsd_args.s = args->s; @@ -1340,6 +1362,24 @@ linux_getsockopt(struct thread *td, stru switch (bsd_args.level) { case SOL_SOCKET: name = linux_to_bsd_so_sockopt(args->optname); + switch (name) { + case SO_RCVTIMEO: + /* FALLTHROUGH */ + case SO_SNDTIMEO: + tv_len = sizeof(tv); + error = kern_getsockopt(td, args->s, bsd_args.level, + name, &tv, UIO_SYSSPACE, &tv_len); + if (error) + return (error); + linux_tv.tv_sec = tv.tv_sec; + linux_tv.tv_usec = tv.tv_usec; + return (copyout(&linux_tv, PTRIN(args->optval), + sizeof(linux_tv))); + /* NOTREACHED */ + break; + default: + break; + } break; case IPPROTO_IP: name = linux_to_bsd_ip_sockopt(args->optname); _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
State Changed From-To: open->patched dchagin@ has committed a fix as revision 191988 so bump this to 'patched' state as MFC reminder.
Responsible Changed From-To: freebsd-emulation->dchagin Over to dchagin@.
Author: dchagin Date: Mon May 25 19:55:00 2009 New Revision: 192767 URL: http://svn.freebsd.org/changeset/base/192767 Log: Merge r191988 from HEAD to stable/7: Add forgotten linux to bsd flags argument mapping into the linux_recv(). PR: kern/134276 Submitted by: Thomas Mueller <tmueller sysgo com> Approved by: kib (mentor) Modified: stable/7/sys/ (props changed) stable/7/sys/compat/linux/linux_socket.c stable/7/sys/contrib/pf/ (props changed) stable/7/sys/dev/ath/ath_hal/ (props changed) stable/7/sys/dev/cxgb/ (props changed) Modified: stable/7/sys/compat/linux/linux_socket.c ============================================================================== --- stable/7/sys/compat/linux/linux_socket.c Mon May 25 17:06:24 2009 (r192766) +++ stable/7/sys/compat/linux/linux_socket.c Mon May 25 19:55:00 2009 (r192767) @@ -871,7 +871,7 @@ linux_recv(struct thread *td, struct lin bsd_args.s = args->s; bsd_args.buf = (caddr_t)PTRIN(args->msg); bsd_args.len = args->len; - bsd_args.flags = args->flags; + bsd_args.flags = linux_to_bsd_msg_flags(args->flags); bsd_args.from = NULL; bsd_args.fromlenaddr = 0; return (recvfrom(td, &bsd_args)); _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Author: dchagin Date: Mon May 25 20:24:36 2009 New Revision: 192769 URL: http://svn.freebsd.org/changeset/base/192769 Log: Merge r191989 from HEAD to stable/7: Translate l_timeval arg to native struct timeval in linux_setsockopt()/linux_getsockopt() for SO_RCVTIMEO, SO_SNDTIMEO opts as l_timeval has MD members. Remove bogus __packed attribute from l_timeval struct on __amd64__. PR: kern/134276 Submitted by: Thomas Mueller <tmueller sysgo com> Approved by: kib (mentor) Modified: stable/7/sys/ (props changed) stable/7/sys/amd64/linux32/linux.h stable/7/sys/compat/linux/linux_socket.c stable/7/sys/contrib/pf/ (props changed) stable/7/sys/dev/ath/ath_hal/ (props changed) stable/7/sys/dev/cxgb/ (props changed) Modified: stable/7/sys/amd64/linux32/linux.h ============================================================================== --- stable/7/sys/amd64/linux32/linux.h Mon May 25 20:07:41 2009 (r192768) +++ stable/7/sys/amd64/linux32/linux.h Mon May 25 20:24:36 2009 (r192769) @@ -94,7 +94,7 @@ typedef struct { typedef struct { l_time_t tv_sec; l_suseconds_t tv_usec; -} __packed l_timeval; +} l_timeval; #define l_fd_set fd_set Modified: stable/7/sys/compat/linux/linux_socket.c ============================================================================== --- stable/7/sys/compat/linux/linux_socket.c Mon May 25 20:07:41 2009 (r192768) +++ stable/7/sys/compat/linux/linux_socket.c Mon May 25 20:24:36 2009 (r192769) @@ -1073,6 +1073,8 @@ linux_setsockopt(struct thread *td, stru caddr_t val; int valsize; } */ bsd_args; + l_timeval linux_tv; + struct timeval tv; int error, name; bsd_args.s = args->s; @@ -1080,6 +1082,23 @@ linux_setsockopt(struct thread *td, stru switch (bsd_args.level) { case SOL_SOCKET: name = linux_to_bsd_so_sockopt(args->optname); + switch (name) { + case SO_RCVTIMEO: + /* FALLTHROUGH */ + case SO_SNDTIMEO: + error = copyin(PTRIN(args->optval), &linux_tv, + sizeof(linux_tv)); + if (error) + return (error); + tv.tv_sec = linux_tv.tv_sec; + tv.tv_usec = linux_tv.tv_usec; + return (kern_setsockopt(td, args->s, bsd_args.level, + name, &tv, UIO_SYSSPACE, sizeof(tv))); + /* NOTREACHED */ + break; + default: + break; + } break; case IPPROTO_IP: name = linux_to_bsd_ip_sockopt(args->optname); @@ -1128,6 +1147,9 @@ linux_getsockopt(struct thread *td, stru caddr_t val; int *avalsize; } */ bsd_args; + l_timeval linux_tv; + struct timeval tv; + socklen_t tv_len; int error, name; bsd_args.s = args->s; @@ -1135,6 +1157,24 @@ linux_getsockopt(struct thread *td, stru switch (bsd_args.level) { case SOL_SOCKET: name = linux_to_bsd_so_sockopt(args->optname); + switch (name) { + case SO_RCVTIMEO: + /* FALLTHROUGH */ + case SO_SNDTIMEO: + tv_len = sizeof(tv); + error = kern_getsockopt(td, args->s, bsd_args.level, + name, &tv, UIO_SYSSPACE, &tv_len); + if (error) + return (error); + linux_tv.tv_sec = tv.tv_sec; + linux_tv.tv_usec = tv.tv_usec; + return (copyout(&linux_tv, PTRIN(args->optval), + sizeof(linux_tv))); + /* NOTREACHED */ + break; + default: + break; + } break; case IPPROTO_IP: name = linux_to_bsd_ip_sockopt(args->optname); _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
State Changed From-To: patched->closed The submitter confirmed that the problem fixed.