Luke Evers

Running cjdns as a daemon on OS X

Posted on 17 February 2014

If you're running cjdns on OS X you might be wondering how to run cjdns as a deamon. As of today (Monday, February 17, 2014) there is still no official property list (plist) file in the repository. There will most likely never be an offical plist file in the of the repo, but there most likely will be one in the contrib folder that is maintained by the community. There is currently a pull request by codeThatThinks to add a plist file into the contrib folder, and it should be in the repo any day now.

What's a daemon, and why should I care?

In multitasking computer operating systems, a daemon is a computer program that runs as a background process, rather than being under the direct control of an interactive user.

Wikipedia

In simple terms, by running cjdns as a daemon, when we boot our computers, it'll automatically be running. Also, if cjdns dies, it'll restart it in the background without us having to do anything, or even know what's going on.

Installing

If this page exists (the launchd folder in the contrib folder of the cjdns repository) then the README file is going to be the most up-to-date guide, but this guide most likely will be kept up-to-date.

When installing a deamon on OS X there are four locations where the plist file for the deamon could be placed, but there is really only one location that the plist file for cjdns should be placed.

# Reserved for system processes 
/System/Library/LaunchAgents
/System/Library/LaunchDaemons

# All other processes
/Library/LaunchAgents
/Library/LaunchDaemons

For our purposes, we are going to be putting our plist file in /Library/LaunchDaemons.

You can really call your plist file whatever you want, but you should call it something so you know what it actually is. Let's call it cjdns.plist.

cjdns.plist

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">  
<plist version="1.0">  
  <dict>
    <key>Label</key>
    <string>cjdns</string>
    <key>ProgramArguments</key>
    <array>
      <string>sh</string>
      <string>-c</string>
      <string>/opt/cjdns/cjdroute &lt; /etc/cjdroute.conf</string>
    </array>
    <key>KeepAlive</key>
    <true/>
    <key>RunAtLoad</key>
    <true/>
    <key>ProcessType</key>
    <string>Interactive</string>
  </dict>
</plist>  

Depending on your setup, you are going to have to change two fields in the plist file. The first field that you may have to change is the path to the executable. My executable is always at /opt/cjdns/cjdroute, but yours may be somewhere else! In the plist file, change the path to where it should be. The second thing you may have to change is the path to your configuration file. My configuration file is always at /etc/cjdroute.conf, but yours also may be somewhere else! In the plist file, change the path to where it should be

<key>ProgramArguments</key>  
<array>  
  <string>sh</string>
  <string>-c</string>
  <string>/path/to/cjdroute &lt; /path/to/cjdroute.conf</string>
</array>  

Configuration file

Now in your configuration file that you just defined the location of above, there is one field that we have to change. If we do not change it then cjdns will not run as a daemon properly because it will try to daemonize itself.

In your file configuration file there is currently an option that is set to this:

"noBackground":0  

This tells cjdns to daemonize itself, and we do not want that! We need to change it from 0 to 1 so that this does not happen. This is very important! Your new line should look like this:

"noBackground": 1  

If you do not have the noBackground option in your configuration file because you have an older configuration file, just add it to the bottom.

Loading and Unloading

After you get both files configured, now we are going to load cjdns into launchctl.

Launchctl interfaces with launchd to load, unload daemons/agents and generally control launchd.

Apple Developer Library

It is highly recommened that you never run launchd, and if you try to run launchd you'll see a nice little error message.

launchd: This program is not meant to be run directly.  

Assuming you placed cjdns.plist in the correct spot, we're going to load it into launchctl now.

launchctl load /Library/LaunchDaemons/cjdns.plist  

To unload we just replace load with unload in our command.

launchctl unload /Library/LaunchDaemons/cjdns.plist  

If we load our file as root and we try to unload it as any other user we get an error, and the same goes the other way around. It's best to run this as root, but it won't complain (although it may not work) if you run it as a user.

launchctl: Error unloading: cjdns  

Important to Know

When cjdns daemonizes itself you only see two processes when running pgrep cjdroute or checking the process list. When we run cjdns as a daemon with our plist file we see three processes instead of two.

Comments

It seems like cjdns runs much better on OS X as a daemon than it does when it daemonizes itself. In the way that if you close your laptop (assuming you're on a laptop) and then reopen it, it seems that it reconnects with Hyperboria much faster than it ever did before. Since these are just speculations and I haven't actually ran any tests comparing the two, I can't say that for sure.

comments powered by Disqus