6

I want to install my own service by dropping a .service file in /etc/systemd/system. My source .service file is in /opt/something.service.

I have two choices when installing:

  • cp /opt/something.service /etc/systemd/system
  • ln -s /opt/something.service /etc/systemd/system

Both approaches work when I start and enable the service (the service works correctly).

There is however a difference when disabling the service:

  • in the case of the copy, /etc/systemd/system/something.service remains
  • in the case of the link, /etc/systemd/system/something.service is removed

Is this by design? This is quite annoying because after disabling the service created via a link, it is not enough to enable it - the service unit must be recreated too.

5

Yes, this is by design.

The man page for systemctl disable says:

Disables one or more units. This removes all symlinks to the specified unit files from the unit configuration directory, and hence undoes the changes made by enable. Note however that this removes all symlinks to the unit files (i.e. including manual additions), not just those actually created by enable.

Here's the link for it: https://www.freedesktop.org/software/systemd/man/systemctl.html#

It does not explain why but I can hazard a guess that it cannot differentiate between links created using systemctl enable and the ones created manually since it is looking for links that point to the unit file.

You should use the link option in systemctl when you create a symlink to a source file outside the systemd search path. Also from the same man page.

link FILENAME...

Link a unit file that is not in the unit file search paths into the unit file search path. This requires an absolute path to a unit file. The effect of this can be undone with disable. The effect of this command is that a unit file is available for start and other commands although it is not installed directly in the unit search path.

6
  • Thanks for the link to the doc. It describes what happens to links pointing to the unit file, not to the file (or in my case - link) itself.
    – WoJ
    Jun 9 '16 at 19:32
  • But isn't that the same situation that you have? /etc/systemd/system/something.service points to /opt/something.service which makes it a link pointing to a service file. Hence, it gets deleted. The file itself doesn't. Basically, if /etc/systemd/system/something.service is a link, it gets deleted when you disable something.service, if it is a file it stays.
    – Munir
    Jun 9 '16 at 19:35
  • Well the docs explicitely state that *This removes all symlinks to the specified unit files from the unit configuration directory *. It should therefore not touch the source file (called template in the docs).
    – WoJ
    Jun 9 '16 at 19:46
  • 2
    /etc/systemd/system is a unit configuration directory. Your source file is in /opt which remains untouched.
    – Munir
    Jun 9 '16 at 19:52
  • You are creating a link so that systemd can access the source file which is probably why you are confused. The source file for systemd is still /opt/something.service and the /etc/systemd/system/something.service is a link to it. So it gets deleted.
    – Munir
    Jun 9 '16 at 19:55
1

I'm not sure the distro you're using, but I'll approach from RHEL 7 (because that's what I'm using, and it should be similar).

systemd normally looks for service files in /usr/lib/systemd/system/*.service (you can look at other service links to get an idea on your distro)

To enable a service it should have an [install] section, and inside that install section it should have a WantedBy= tag. This WantedBy specifies under what conditions it should be enabled (such as the runlevel). The WantedBy should match a directory in /etc/systemd/system/*.target.wants.

Then, if you enable the service a link is created in /etc/systemd/system/*.target.wants/ to point to the service file in /usr/lib/systemd/system/. Disabling the service should only delete this link as well.

For example, if you had a service file (test.service) that included:

[install]
WantedBy=multi-user.target

then:

systemctl enable test.service

Would create a link inside

/etc/systemd/system/multi-user.target.wants/

Called test.service that points to /usr/lib/systemd/system/test.service

And disabling the service should only remove the link.

1
  • Thanks for all the details, but my question was about the unit file being itself a link (a manual one) to an actual file.
    – WoJ
    Jun 10 '16 at 19:03
0

You must have links for your enabled services. Its a bad practice to have the real file, just because the idea of this folder is to permit you from disabling or enabling services, and not for saving its scripts inside it.

1
  • This is not entirely true. /etc/systemd/system is mainly meant to allow custom unit files to override vendor settings. Even the man page says that the way to override vendor settings is by copying a custom unit file to /etc/systemd/system. Enabling/disabling services is handled by the systemctl command, not the files or links in the folder. You could have service file in the /etc/systemd/system directory, but still have a disabled service.
    – Munir
    Jun 9 '16 at 18:31
0

One workaround is to use the directories which systemd won't remove the symlinks.

For system links: /usr/local/lib/systemd/system/

For user links: ~/.config/systemd/user.control or /usr/local/lib/systemd/user/

Put your symlinks in the above directories. systemctl disable followed by systemctl enable works as expected.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.