Elaborate systemd daemon example with autotools helpers
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.



Funkd provides a simple systemd unix domain socket deamon example with 3
types of implementations supported and with m4 autoconf library helpers for
systemd, and with an example build environemnt provided with just autoconf,
and then also with automake.

The purpose of this example set is to help you get ramped up with systemd with
the different types of build environment requirements you may have, and provide
an m4 library to help you integrate support for systemd autoconf. This example
set also illustrates a small race condition which could be present on many
typical unix daemons, which the sd_notify() interface addresses explicitly.

This sample set provides:

  * src/m4/systemd.m4 - LGPL m4 library for autoconf -- see below for more
  * src/m4/paths.m4   - LGPL m4 library for expanding @VARS@ for service target

  * Legacy unix domain socket daemon example, with race condition addressed
  * Systemd notify daemon, using shared libraries
  * Systemd notify daemon, using dynamic link loader

Funkd legacy unix domain socket example

This example is provided to illustrate what old unix domain sockets
do but more importantly provide an example of a race condition addressed
which some daemons typically do not address, and which the sd_notify()
interface tries to explicitly address when using systemd.

Funk systemd shared library example

In most build environment cases you will want to require building support
for sytsemd as an option, with the legacy behaviour as the alternative. In
this case when systemd support is enabled the resulting binary will require
the systemd libraries present on the target systems, even if the system
was not booted with systemd.

Funk systemd dynamic link loader example

This example is provided for daemons which will require the systemd development
libraries present at build time but which will produce binaries that do not
require systemd. Systemd libraries will only be required on systems that have
booted with systemd as the init system. This is possible using the dynamic link
loader through dlopen() and dlsym(). Another example target is provided,
funk_math which can be used to test / extend usage of the dynamic link loader.

Autoconf systemd m4 helpers

This repository also provides some systmed autoconf helpers:

  * src/m4/systemd.m4

    - AX_ENABLE_SYSTEMD(): enables systemd by default and requires an
      explicit --disable-systemd option flag to configure if you want to
      disable systemd support.

    - AX_ALLOW_SYSTEMD(): systemd will be disabled by default and requires
      you to run configure with --enable-systemd to look for and enable systemd

    - AX_AVAILABLE_SYSTEMD(): systemd will be disabled by default but if your
      build system is detected to have systemd build libraries it will be
      enabled. You can always force disable with --disable-systemd

    - If you want to use the dynamic link loader you should use
      AX_AVAILABLE_SYSTEMD() but must then ensure to use -rdynamic -ldl
      when linking, if using automake autotools will deal with this for you,
      otherwise you must ensure this is in place on your Makefile.

  * src/m4/paths.m4 - AX_LOCAL_EXPAND_CONFIG() path expansion helper
    Helper to allow us to use @VAR@ replacements with AC_CONFIG_FILES() on the
    Makefiles and target service unit files. This is particularly useful for
    systemd deaemons using autotools given that systemd ExectStart does not
    allow variables to be used for the binary specification. AC_CONFIG_FILES()
    will only parse variables already set with AC_SUBST(), this requires
    expansion on some variables that depend on $(prefix) but this isn't set
    until after running configure, so preset that variable with the autoconf
    default. To use this expansion helper just call AX_LOCAL_EXPAND_CONFIG()
    after AC_PROG_CC() and before AC_OUTPUT(). Note that although this example
    doesn't use AC_CONFIG_FILES() substituations on c / header files this is
    is indeed appropriate for some cases, in funkd' case it should be using
    it for the /var/run/funkd/ socket path.

Multiple daemons options

If you have a deamon that can run under two separate binaries and they are
mutually exclusive you have a few options:

  0) Use target file and two separate service unit files for each daemon
  1) Use two service files and have each declare an alias for the main service,
     for example, Alias=funk.service
  2) Use one service file, and environment variables to define the default
     and a launcher which will getenv() and execve() the default daemon
  3) Use sh -c exec "/path/$YOURD" on the ExecStart with Environment=YOURD=foo
     on the service file.

There is no exact prefered strategy, this daemon use sh -c exec given that
the other options require duplicating the service files. This option lets
us avoid implementing a launcher and also advocates avoiding using of
the /etc/default and /etc/sysconfig/ directory for configuration files
by not providing one but still using it in unde the assumption that legacy
daemons used them. Folks should migrate away from those and just define the
configuration preferneces on the unit files themselves.

For a discussion on this topic you can refer to:


Multiple socket note

We support multiple sockets as an example, and provide different permissions
for those sockets, systemd allows right now to specify multiple sockets on
one file however at this point though does not let you specify different
permissions for each of those sockest. To enable you to use different
permissions on different sockets right now you have to split up the sockets
into separate files. The order in which you specify the sockets on the
service unit file matters, in this case the first socket passed gets the
last file descriptor. This will need to be documented on systemd given that
otherwise this could lead to functionality regressions if this should change
at some other point in time. A better solution would keep the current behavior
as-is for multiple sockets but add support to systemd to split let you specify
different permissions for differnet sockets on the same socket file.