pmtr daemon manager

The pmtr utility is for starting your daemons (not the system daemons) at system boot, and letting you control them at runtime. It’s free, open-source and for Linux. What makes pmtr different from sysvinit and similar is that all your jobs are defined in one configuration file, and the syntax is friendly.

job {
  name doppler
  cmd /usr/bin/doppler
}

This would start up the doppler job, with default settings- discard stdout and stderr, and set the working directory to /. If we wanted to set those explicitly, we can do that using extra options:

job {
  name demux
  cmd /usr/bin/demux -v
  dir /data
  err demux.err
  out demux.out
}

You can also set environment variables and control the user under which the job runs. The full options are documented below.

Why did I write it?

I wrote pmtr because I wanted to have all my application daemons in one configuration file, separate from the "system-oriented" daemons that run from sysvinit (and similar) mechanisms.

Configuration file /etc/pmtr.conf

When pmtr is started at system boot, it reads the configuration file — by default /etc/pmtr.conf — and starts up the jobs defined there. You can define as many jobs as you want.

Status messages

Status messages are sent to syslog. Typically these go to /var/log/messages:

Nov  7 21:38:10 ubuntu pmtr[18477]: pmtr: managing 1 jobs
Nov  7 21:38:10 ubuntu pmtr[18477]: started job doppler [18478]

Runtime job control

When you edit and save pmtr.conf, the changes you made get applied immediately. That’s because pmtr watches for changes to the configuration file. If you add a job, it gets started; if you delete a job (or give it the disable option, or comment it out) it gets terminated. When you change a job, it gets restarted with the new settings. Other running jobs are left alone- they’re not needlessly restarted. All this happens instantly whenever the configuration file is saved. This message is shown in the logs, with whatever further actions pmtr takes.

Nov  7 22:01:09 ubuntu pmtr[18477]: rescanning job configuration

Who starts pmtr?

There is still a need to start pmtr itself at system boot. There is an upstart job (for Ubuntu Linux) included, described below. (On the to-do list: add a sysvinit init.d script for RedHat/CentOS compatibility).

When a job exits

When a job exits (after it’s been running at least ten seconds), pmtr restarts it. But note, a job can say "do not restart me" by exiting with status 33.

Jobs that exit too quickly

If you define a job that exits within 10 seconds of when it started, pmtr delays its restart (by 10 seconds). This avoids rapid-cycle restart loops. Since pmtr is oriented toward running daemons, a quick exit usually means the job has some kind of problem (bad arguments, etc) that you need to fix.

Nov  7 22:01:13 ubuntu pmtr[18477]: job stub 18552 exited after 3 sec: exit status 0
Nov  7 22:01:13 ubuntu pmtr[18477]: job restarting too fast, delaying restart

Shutting down

If you stop pmtr (for example, by running service pmtr stop on Ubuntu), it gracefully terminates its jobs before exiting. Job termination is handled by first sending SIGTERM, then SIGKILL shortly afterward.

Installation

Download the pmtr source:

git clone git://github.com/troydhanson/pmtr.git

Then build and install:

cd pmtr
make
sudo make install

Running pmtr at boot

Ubuntu

There is an "upstart" script included. You’ll need to manually copy it into place. Then it can be started initially.

cp upstart/pmtr.conf /etc/init
service pmtr start

RedHat/CentOS

TO-DO: include a sysvinit script.

Startup options

The supported options to pmtr are:

-v verbose
-F foreground
-c <file> specify configuration file
-t test only; parse config file only (implies -F)

You can start pmtr by hand to test the configuration file for syntax errors using the -t option.

Configuration file syntax

The configuration file (normally pmtr.conf) contains any number of jobs. Each job is in a curly-brace delimited block. Comments should be on their own line and prefaced with #. Indentation is optional. Blank lines are ok.

#################
# the weather job
#################
job {
  name weather
  cmd /usr/bin/weather
  err weather.err
}

Only name and cmd are required. The full list of options are:

Job options

Table 1. Job configuration options
option argument

name

job name

cmd

absolute path to executable with optional arguments

dir

absolute path to the working directory

out

file to receive standard output

err

file to receive standard error

user

user under whose uid the job should run

env

VAR=VALUE specification of an environment variable (repeatable)

disable

name

The name must be unique. It is used to make log messages more readable.

cmd

The cmd is the absolute pathname to an executable, with optional arguments. Quoting (using double-quotes only) is supported in the arguments.

dir

Sets the working directory that the job will have upon startup.

out

file (may be relative to the working directory) to receive stdout. Default: /dev/null

err

file (may be relative to the working directory) to receive stderr. Default: /dev/null

user

If specified, the job is run under the user’s uid rather than root’s uid

env

sets an environment variables for the job, e.g., env XLIB=/usr/lib/xlib.so (repeatable)

disable

causes the job definition to be inactive. This is sometimes more convenient than commenting out the whole job definition.

One-time jobs

Sometimes we want to run one or more "setup" jobs before our daemons. The setup job should run to completion, and not be restarted when it exits. For this, you can use the wait option and the once option. When a job has the wait option, pmtr waits until it exits before starting up subsequent jobs (those which appear later in the configuration file). This is used with once to prevent the job from restarting. (You can also use once without wait).

job {
  name setup
  cmd /bin/mkdir /dev/shm/ramdisk
  wait
  once
}

Resources

News

Updates are posted to the author’s blog. (RSS)

Contact

Please send bug reports or suggestions to tdh@tkhanson.net.

License

See the LICENSE file.