Thank you very little and thank you very much, Apple

Please note that all blog posts before 8 April 2007 were automatically imported from LiveJournal.  To see the comments and any LiveJournal-specific extras such as polls and user icons, please find the source posting at http://brianenigma.livejournal.com/2006/07/

So it turns out that there is a bug in OS X's udp socket library. Either that, or this is an expected behavior that I have never, in my life, run into before. When the nfs server starts, it binds to a TCP and UDP port. You then can't easily kill it. The nfsd process ignores most signals (such as the standard “killall.”) You have to “killall -TRAP nfsd nfsd-master nfsd-server” for it to exit, and even then it does not seem to cleanly exit. The OS thinks that the UDP socket is still open.

After some experimentation, it seems that the way around this is, immediately after creating the socket, to do a setsockopt() with SO_REUSEPORT. If you don't do this after opening the port, it simply isn't available again. This isn't normally a big deal with the way OS X does NFS. The service starts at boot and never dies. It can be reconfigured with a “killall -HUP,” but never needs to be restarted. I don't know how big this problem is–for instance, could a malicious person momentarily open every UDP port from 1024 to 65535 for listening, and with this bug, would it prevent all other processes from listening on the socket again?

Anyway, that's my Apple gripe. On the other hand, they get much praise. Because the operating system is based on Open Source code, I was able to grab the source code for the service, make some changes to add the SO_REUSEPORT, and replace my nfsd executable. This is then wrapped by a shell script that has a list of what you want to share and who you want to share it with, which will poke/remove those values from your NetInfo “registry” and start or stop the service like a standard Unix daemon wrapper.

Note that this only works for OS X 10.4. Previous versions started portmap and mountd using different things in /System/Library/StartupItems.

Posted in: Code

Leave a Reply

Your email address will not be published.