November 4, 2014

Starting a Perforce Server on Mac OS X with Launchd

Helix Core

launching mac desktop
Image: Jason Corneveaux via Flickr

A few years ago I switched from a laptop running Windows 7 to a MacBook Pro with OS X. One of the few things that bothered me was that my many Perforce Servers (P4D) I have running on my machine (to be able to quickly demonstrate different configurations such as replication) did not start automatically.

On Windows I simply installed a service for each Perforce Server I needed using srvinst.exe that Perforce provides with the standard installer. On Linux I can use initd and p4dctl, but initd is deprecated on Mac OS X. Instead, you are supposed to use Launchd.

To use Launchd you need to create an XML file called a plist file that defines the service you want to start automatically and its parameters. There are several locations where a plist file is stored, but the definitions for your private files are in your home directory under “~/Library/LaunchAgents/”. Here is an example for a plist file I use to start my main Perforce Server:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" 
<plist version="1.0">
        <string>p4d [1666]</string>
      <string>Launches main Perforce Server</string>

There are several noteworthy aspects to this file:

  • The service starts automatically at boot time (RunAtLoad)
  • I can specify which executable to run (here: /usr/local/bin/p4d)
  • I can define environment variables (e.g., P4ROOT)
  • I can pass in any program arguments

The first program argument is especially interesting. This is the name that is listed in the process list (shown with the standard Unix “ps” command). Normally, this is just the executable name (here “p4d”), but you can easily add additional information like the port the server is listening on to it. When I try to find out which Perforce Servers are currently active I simply run

$ ps –aef | grep p4d
  501 27542   276   0 Tue09am ??     0:00.03 p4d [1666] --pid-file
  501 46982   276   0  9:44am ??     0:00.02 p4d [ssl:20101] --pid-file
  501 47120   276   0  9:46am ??     0:00.02 p4d-main-g [2001] --pid-file
  501 47554   276   0  9:50am ??     0:00.01 p4d replica [1667] --pid-file
  501 47560 47554   0  9:50am ??     0:00.50 p4d replica [1667] --pid-file
  501 47561 47554   0  9:50am ??     0:00.38 p4d replica [1667] --pid-file
  501 47562 47554   0  9:50am ??     0:00.37 p4d replica [1667] --pid-file
  501 47563 47554   0  9:50am ??     0:00.38 p4d replica [1667] --pid-file
  501 47568 27542   0  9:50am ??     0:01.98 p4d [1666] --pid-file
  501 47660   276   0  9:54am ??     0:00.01 p4d unicode [1999] --pid-file

The –pid-file argument is worth mentioning as well. This is a new feature in Perforce Server 2014.2 that writes the process id of a started P4D service to a file called in the server root directory. You can also specify a file name with the –pid-file argument to change the name or location. This feature makes it easier for administrators to identify what P4D process corresponds to what process id.

You can test and control the service, for example, with command-line launchctl from the Terminal application:

launchctl load ~/Library/LaunchAgents/com.perforce.main.plist
launchctl unload ~/Library/LaunchAgents/com.perforce.main.plist

An amusing side effect of processes started with Launchd is that OS X will restart the service automatically if you shut it down without unloading it, so a Perforce Server stopped with “p4 admin stop” will automatically be restarted. Unload the process instead if you want it permanently shut down.

Happy hacking.