From owner-freebsd-ports@FreeBSD.ORG Mon Jun 24 00:18:45 2013 Return-Path: Delivered-To: freebsd-ports@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id DDF479FD for ; Mon, 24 Jun 2013 00:18:45 +0000 (UTC) (envelope-from freebsd@grem.de) Received: from mail.grem.de (outcast.grem.de [213.239.217.27]) by mx1.freebsd.org (Postfix) with SMTP id 118CA135B for ; Mon, 24 Jun 2013 00:18:44 +0000 (UTC) Received: (qmail 83474 invoked by uid 89); 24 Jun 2013 00:18:43 -0000 Received: from unknown (HELO bsd64.grem.de) (mg@grem.de@93.215.183.247) by mail.grem.de with ESMTPA; 24 Jun 2013 00:18:43 -0000 Date: Mon, 24 Jun 2013 02:18:42 +0200 From: Michael Gmelin To: Dimitry Andric Subject: Re: Are ports supposed to build and run on 10-CURRENT? Message-ID: <20130624021842.66888fe4@bsd64.grem.de> In-Reply-To: <20130623221607.7e1e7754@bsd64.grem.de> References: <20130613031535.4087d7f9@bsd64.grem.de> <20130623080905.17f77d71@bsd64.grem.de> <20130623221607.7e1e7754@bsd64.grem.de> X-Mailer: Claws Mail 3.9.1 (GTK+ 2.24.18; amd64-portbld-freebsd9.1) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Cc: Matthias Andree , "freebsd-ports@freebsd.org Ports" X-BeenThere: freebsd-ports@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Porting software to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 24 Jun 2013 00:18:45 -0000 On Sun, 23 Jun 2013 22:16:07 +0200 Michael Gmelin wrote: > On Sun, 23 Jun 2013 08:09:05 +0200 > Michael Gmelin wrote: > > > On Sat, 22 Jun 2013 00:27:53 +0200 > > Dimitry Andric wrote: > > > > > On Jun 21, 2013, at 22:07, Dimitry Andric wrote: > > > > On Jun 13, 2013, at 03:15, Michael Gmelin > > > > wrote: > > > ... > > > >> - system clang + std=c++11 + system libc++: Build fails, due > > > >> to a dependency (databases/db5) not building with those flags. > > > >> It looks like a problem in libc++ to me, but I didn't have > > > >> much time to investigate. It might be one of those things that > > > >> might just go away after a while. > > > > > > > > No, db5 does not build because it is redefining a C++11 standard > > > > library identifier, atomic_init(). It should probably prefix > > > > all its internal defines with 'db_', to avoid collisions. The > > > > db-5.3.21/src/dbinc/atomic.h file is already patched by our port > > > > to avoid one such collision, but it is probably necessary to do > > > > this again for any other identifiers that are used either by > > > > C++, or are compiler builtins. > > > > > > Attached is a diff to fix the db5 port, so it correctly builds > > > with CXXFLAGS?=-std=c++11 -stdlib=libc++. Matthias, could you > > > please have a look at it? > > > > > > After db5 (compiled with libc++) was installed, I retried > > > devel/ice again, but the Slice/keyword test failed in exactly the > > > same way. If you comment out the "delete factoryTable" line in > > > cpp/src/Ice/FactoryTableInit.cpp, the Slice/keyword test does > > > succeed. > > > > > > Many other tests after that also go well, and the next failure I > > > get was: > > > > > > *** running tests 39/83 > > > in /usr/work/usr/ports/devel/ice/work/Ice-3.5.0/cpp/test/Ice/udp > > > *** configuration: Default *** test started: 06/22/13 00:20:11 > > > starting server #1... ok > > > starting server #2... Traceback (most recent call last): > > > File > > > "/usr/work/usr/ports/devel/ice/work/Ice-3.5.0/cpp/test/Ice/udp/run.py", > > > line 41, in > > > serverProc.append(TestUtil.startServer(server, "%d" % i , > > > adapter="McastTestAdapter")) File > > > "/usr/work/usr/ports/devel/ice/work/Ice-3.5.0/scripts/TestUtil.py", > > > line 1396, in startServer return spawnServer(cmd, env = env, > > > adapter = adapter, count = count, echo = > > > echo,lang=config.lang,mx=config.mx) File > > > "/usr/work/usr/ports/devel/ice/work/Ice-3.5.0/scripts/TestUtil.py", > > > line 1131, in spawnServer server.expect("%s ready\n" % adapter) > > > File > > > "/usr/work/usr/ports/devel/ice/work/Ice-3.5.0/scripts/Expect.py", > > > line 394, in expect raise e Expect.TIMEOUT: timeout exceeded in > > > match pattern: "McastTestAdapter ready\n" buffer: "ControlAdapter > > > ready Network.cpp:1701: Ice::SocketException: socket exception: > > > Address already in use " > > > > > > ('test > > > in /usr/work/usr/ports/devel/ice/work/Ice-3.5.0/cpp/test/Ice/udp > > > failed with exit status', 256) > > > > > > Whatever the source of this problem is, it is not very likely that > > > is caused by a compiler or C++ library issue, but more likely some > > > unexpected API change in sockets. > > > > > > -Dimitry > > > > Hi Dimitry, > > > > I've been able to analyze issue further and developed a fix (make > > factoryTable's lifetime dependant on the lifetime of generated _Init > > classes). I filed a bug report upstream: > > > > http://www.zeroc.com/forums/bug-reports/6030-ice-3-5-0-slice2cpp-generated-code-relies-static-initialization-order-crash.html#post26001 > > > > The second issue is a little bit more tricky. Since I was building > > the port in a jail, the UDP based unit test didn't run and it didn't > > notice it fail. Therefore it's not limited to CURRENT and, as it > > turns out, it is a kernel bug. > > > > Digging a little bit deeper into the problem I noticed that there > > seems to be a multicast problem in the kernel. Usually setting > > SO_REUSEADDR on a multicast address should implicitly set > > SO_REUSEPORT as well. Staring at the kernel code this only seems to > > work on the currently created socket, but the cached flag of already > > listening multicast sockets is not retrieved correctly, which makes > > me believe that the cached flag is initialized correctly when > > creating it. I think that this problem might have been introduced a > > while ago in or after revision 227428: > > > > http://svnweb.freebsd.org/base?view=revision&revision=227428 > > > > Which MFC'd 227207 > > > > Which says: > > > > "Cache SO_REUSEPORT socket option in inpcb-layer in order to avoid > > inp_socket->so_options dereference when we may not acquire the lock > > on the inpcb." > > > > I did some testing using a small test program that listened to a > > multicast address and noticed: > > - First invocation SO_REUSEADDR, second invocation SO_REUSEADDR > > => fail > > - First invocation SO_REUSEADDR, second invocation SO_REUSEPORT > > => fail > > - First invocation SO_REUSEPORT, second invocation SO_REUSEADDR > > => success > > - First invocation SO_REUSEPORT, second invocation SO_REUSEPORT > > => success > > > > My gut feeling tells me that the code used to set the correct values > > for inp_flags2 only works when setsockopt is called after the socket > > has been bound and testing verified that this is actually the case. > > Adding an additional setsockopt call after calling bind makes things > > work as expected. For comparison I also tested in a VM running > > ancient 7.x, where things worked as expected. > > > > So... if this was just about this port, the obvious fix would be > > patching devel/ice to use SO_REUSEPORT explicitly for multicast > > (which actually makes that unit test run ok), but this seems more > > like an issue that really needs to be fixed on a system level. > > Should I open a PR, or can you take it from here? > > > > Cheers, > > Michael > > > > p.s. - I attached the C program I used for testing and demonstrating > > the problem: > > > > [user@bsd64 /tmp]$ cc -o multicast multicast.c > > [user@bsd64 /tmp]$ ./multicast reuseaddr & > > [1] 9040 > > [user@bsd64 /tmp]$ ./multicast reuseaddr > > binding datagram socket: Address already in use > > [user@bsd64 /tmp]$ killall multicast > > ... > > [user@bsd64 /tmp]$ ./multicast reuseport & > > [1] 9093 > > [user@bsd64 /tmp]$ ./multicast reuseaddr & > > [2] 9098 > > [user@bsd64 /tmp]$ ./multicast reuseaddr & > > [3] 9107 > > [user@bsd64 /tmp]$ binding datagram socket: Address already in use > > [user@bsd64 /tmp]$ killall multicast > > ... > > [user@bsd64 /tmp]$ ./multicast reuseaddrafter & > > [1] 9132 > > [user@bsd64 /tmp]$ ./multicast reuseaddrafter & > > [2] 9135 > > [user@bsd64 /tmp]$ ./multicast reuseaddrafter & > > [3] 9136 > > [user@bsd64 /tmp]$ ./multicast reuseaddrafter & > > [4] 9137 > > [user@bsd64 /tmp]$ ./multicast reuseport & > > [5] 9140 > > [user@bsd64 /tmp]$ ./multicast reuseaddr & > > [6] 9181 > > [user@bsd64 /tmp]$ ./multicast reuseaddr & > > [7] 9184 > > [user@bsd64 /tmp]$ binding datagram socket: Address already in use > > > > > > I took a closer look and this actually makes a lot of sense. > > The cached value of the flags is set in ip_ctloutput when setsockopt > is called, the part controlling automatic setting of SO_REUSEPORT is > (from sys/netinet/ip_output.c): > > switch (sopt->sopt_name) { > case SO_REUSEADDR: > INP_WLOCK(inp); > if (IN_MULTICAST(ntohl(inp->inp_laddr.s_addr))) > { if ((so->so_options & > (SO_REUSEADDR | SO_REUSEPORT)) != > 0) inp->inp_flags2 |= INP_REUSEPORT; > else > inp->inp_flags2 &= > ~INP_REUSEPORT; } > INP_WUNLOCK(inp); > error = 0; > > This cannot work though, since at the point setsockopt is called, the > address is not known and IN_MULTICAST won't evaluate as true. The > address is only known once bind is executed. That's why setting the > option after the call to bind works. It still has to be set before > bind is called, since bind uses the actual information at the point > of initialization as well (or set SO_REUSEPORT to begin with). > > I'll file a bug report. > > Cheers, > Michael > Filed a PR including a patch: http://www.freebsd.org/cgi/query-pr.cgi?pr=179901 -- Michael Gmelin