0

There are lots of instructions out there for creating basic systemd service files, but they all seem (rightfully so) to instruct you to make calls to systemctl daemon-reload and systemctl enable. If you need to add a service to a drive you have mounted but not booted (think system orchestration), how would you do that purely by writing to the file system (files, directories, symlinks).

I'm sure there will be a few "it depends on where your X lives" and that is okay. This can have limited (or no) portability. I just want to make sure that my plan works.

That plan being:

  1. Write a service file in /usr/lib/systemd/system/
  2. Symlink to it from /etc/systemd/system/multi-user.target.wants/

2 Answers2

2

What you're suggesting is essentially how systemctl enable works: it looks in the [Install] section of the service file and adds a symlink to the appropriate .target.wants directory indicated by WantedBy=. According to the systemd.unit man page, there are a few other directives that you need to look at to duplicate how systemctl does it:

  • Alias= creates a symlink in the same directory as the unit
  • RequiredBy= creates a symlink in the appropriate .target.requires directory
  • Also= installs related units (look at each of those for linked installs)
  • DefaultInstance= adds a symlink with a default name for instanced units (e.g. multi-user.target.wants/foobar@default.service -> foobar@.service)

However, unless your mounted filesystem is for a completely different architecture, you probably don't have to manually create these. systemctl works just fine for installing/uninstalling unit files even if systemd isn't currently running, so you should have no issues using systemctl enable and disable (use chroot to run in the correct directory root); obviously you don't need to run daemon-reload as there's no daemon process! I use this method at the end of a Gentoo installation to add startup units like systemd-networkd and friends, and it has worked with no issues for me.

ErikF
  • 4,042
1

Use systemctl enable with the --root flag. That flag not only sets the root directory for unit search files, but also instructs systemctl to operate on the file system directly instead of communicating with the system daemon.