94

I have installed the pimd service by means of apt. This comes with an upstream systemd unit file (/lib/systemd/system/pimd.service).

I want the service to be restarted when for some reason it gets killed, hence I wish to add the line Restart = always in the unit file.

However, I don’t want to modify the upstream unit file.

Is there any workaround for this?

giomanda
  • 2,014

3 Answers3

141

Systemd provides two mechanisms to edit unit files:

  • systemctl edit <unit file>

    E.g. systemctl edit pimd (in the absence of a file extension, systemd assumes .service). This creates /etc/systemd/system/<unit file>.d/override.conf and opens a text editor for you to enter your overriding options in systemd unit syntax. The options you enter are merged with the package's defaults at runtime, with your overrides taking precedence.

    Note that some options require 'clearing' by setting them to a blank string before setting them to the desired value on a subsequent line. See this answer on Ask Ubuntu for more info and a thorough breakdown of editing systemd units.

  • systemctl edit --full <unit file>

    This is equivalent to copying <unit file> (such as pimd.service) from /usr/lib/systemd/system/ to /etc/systemd/system/. An editor opens for you to make changes, and the resulting file completely supersedes the unit file supplied by the package maintainer.

The former command (without --full) is recommended unless you are largely overhauling the existing unit file, as it allows for future package updates to the unit file to take effect. With a --full edit, you assume responsibility for ensuring your unit file maintains compatibility with any updates.

Using the systemd-provided commands is preferable to creating/copying files yourself as it's less error-prone and systemd is immediately aware of the changes. Manual file modifications require you run systemctl daemon-reload for them to take effect.

See man systemctl for more information on systemctl edit and other commands for working with systemd unit files.

HBruijn
  • 84,206
  • 24
  • 145
  • 224
30

The RHEL documentation recommends two ways:

  1. Extend the default unit file by creating a configuration directory and file under /etc/systemd/system/[name-goes-here].service.d/config_name.conf

In this case the file would need to contain something like this:

[Service]
Restart=always

This is what systemctl edit [name-goes-here] does, it creates that directory and override.conf within it.

  1. Create a copy of the original unit file /usr/lib/systemd/system/ in /etc/systemd/system/ and make changes there.

I would try option one but they are both viable options. Either way remember to run systemctl daemon-reload after making the changes.

RHEL documentation on Creating and Modifying systemd Unit Files

3

Consider using a script to read the upstream configuration, modify it, and spit it out to drop-in file.

For example, I use Chef and here's a piece of ruby (library) that parses marathon systemd unit file to get original ExecStart from it

require 'inifile'

module Dcos
  def get_execstart_from_unit_file
    marathon_systemd_unit_file = 
    IniFile.load('/etc/systemd/system/dcos-marathon.service')
    return marathon_systemd_unit_file['Service']['ExecStart']
  end
end

Then in the recipe, I create the drop-in file to append an option to ExecStart

chef_gem 'inifile'

exec_start_orig = get_execstart_from_unit_file

systemd_service_drop_in 'dcos-marathon' do
  override 'dcos-marathon.service'
  precursor 'Service' => { 'ExecStart' => nil }
  service do
    exec_start exec_start_orig + ' --env_vars_prefix "DCOS_MARATHON_"'
  end
end
ZedTuX
  • 201
riemann
  • 53