NSD 4.1: zonefile-mode and fork fix

NSD 4.1 has a new feature where it does not use the nsd.db file, but uses the zonefiles directly.

NSD 4.1: zonefile-mode and fork fix

By Wouter Wijngaards

Use zone files and not nsd.db

NSD 4.1 has been released and it contains a new feature where NSD does not use the nsd.db file, but uses the zonefiles directly. The feature can be turned on by configuring one line in nsd.conf, it can also be turned off by changing that line back, the server needs to be restarted to effect the change.

nsd.conf excerpt:

# this line disables nsd.db, and the text format zonefiles
# are used directly
database: ""

With this config statement NSD reads the zonefiles for zones upon startup. This takes about the same time as reading the nsd.db file. The memory usage without the nsd.db file is about 50%-60% lower. When zone transfers (for secondary zones) update the zone information, NSD writes the new contents back to the zonefile.

The zonefiles are written every hour, with a timer that can be configured with the zonefiles-write: 3600 configuration statement. This sets the time in seconds when you want the zonefiles to be written back to disk. NSD first writes the file to file~ and then renames that to the original filename to protect against filesystem space problems. Read and write to zonefiles is slightly slower than to nsd.db, the performance of NSD in queries per second is not impacted. NSD does not write the entire zonefile everytime a change occurs because that would be very slow, especially in the case of many incremental zone transfers, that is why the zonefiles-write timer only writes the entire file after a specified time has elapsed.

You can check zonefiles before loading them with the new nsd-checkzone tool that prints if the zonefile contains errors. It uses the same parse code as NSD.

Linux fork problems fixed

The NSD mode of operation forks processes, specifically for every zone update that is processed. Because NSD4 supports provisioning of many more zones than NSD3 does, many more forks are performed when these zones update frequently. This caused problems in Linux systems, because Linux cannot handle this specific sequence of fork operations that NSD used.

The system leaked memory for the NSD process, until the system became unstable (after days). The workaround, in NSD 4.1, forks in a different pattern that does not cause the Linux implementation to leak the vm chunk information in the Linux process memory tables. This information was not really leaked, it was cleaned up on process exit, so a stop and start of the daemon could also workaround the problem, but it accumulated while the daemon was running.

The fork pattern that caused the failures for Linux was a pattern where the deepest forked process forks new copies that replace all the older processes, and this in a sequence. The new pattern takes efforts to have a higher up (parent) process fork the new copies, at the expense of having the UNIX signals delivered to the wrong processes afterwards, NSD now uses pipes to communicate that information, where for SIGCHILD it uses the property that pipes are closed by Linux when a process exits (and it was the only process that held that file descriptor).