Wednesday 13 June 2012

Debian, NIS, Headaches, Wi-Fi and AutoFS

For quite some time now, there has been a lot of hoo-har surrounding startup ordering, dependencies and chain loading of autofs, ypbind and networking.  Historically, it had been solved post-installation by manually modifying insserv directives in the headers of sysinit scripts then recalculating the dependency start order.  Well, that or just simply modifying the rc.d start sequence.  However, with the introduction and adoption of upstart, the dependencies have been fine tuned somewhat, allowing a virtual "start-ypbind.conf" script to be provided as a blocking event, blocking the start up of things that depend on ypbind.  This works exactly as everyone that uses NIS and AutoFS require it to, providing the binding takes less than five seconds.  Historically, binding time-out before ypbind startup was backgrounded, was around a minute.  However, since the upstart edition, this time-out has been reduced to five seconds.  After which, ypbind is backgrounded and upstart startup events are emitted for autofs and other NIS dependent services.  When connecting to a network via a wi-fi connection, connecting to wi-fi alone can take that long.  So obviously, since AutoFS is extremely sensitive to the presence of YP binding, automount fails to start and you are presented with a system in the same age old unusable state.  The simple solution would be to increase the time-out and prey it makes its way into mainstream.  However, wouldn't it be nice if YP could bind in less time, perhaps without there even being a presence of any networking at all?

Well, the answer is "yes".  And the answer to "how we achieve it" is actually quite simple, although it does uncover another little bug with yphelper.

Solution
So how do we bind faster and without any networking?  The answer is that we need to bind locally.  In order to bind locally, it means running a local NIS server, but one intended as a NIS slave.  This is extremely simple to set up, using the /usr/lib/yp/ypinit utility.  Providing the -s option and the fully qualified hostname of the master NIS server, the NIS server will be replicated locally.  Synchronisation with the master will be maintained by ypfxrd on the master NIS server, so no need to setup any nasty cron tasks to update the NIS records periodically.  There are a few configuration settings to ensure the NIS server is only made available locally, but once done, a restart of NIS and autofs will see the system switched to using the local NIS server; ypwhich will confirm this.

Modify the yp.conf file to include your original entry below a duplicate of itself, with the IP or hostname of the NIS server swapped for localhost (127.0.0.1).  It should look somewhat like this:

domain some.domain.com server 127.0.0.1
domain some.domain.com server 10.0.0.1

The host on 10.0.0.1 will be the master, used only as a secondary to the local server.  Effectively, this is a null op, but it serves as a reminder to the real NIS server.

Make sure the only entry that is permitted in ypserv.securenets is the link local address range.  Comment anything else out to ignore all other authentication requests.

That's it!  Configuring NIS in this way will have YP binding completing almost instantaneously, while the networking is able to come online and autofs is able to start.

Issues
There is a bug with ypinit, in that on some NIS master configurations, it is unable to obtain a list of maps for that server.  This can be remedied by modifying the script and replacing the call to yphelper with a call to ypwhich as follows:

maps=`ypwhich -m | awk '($2 == "'$MASTER'") { printf("%s ", $1) }'`

This is a variation of the original method for obtaining maps, and one that works reliably.