How can I launch a systemd service at startup before another systemd service starts?

24,768

The reason you are having this problem is because you are using After= while you also need Requires= or Wants=.

There are 3 main properties for managing dependencies. I'll try to briefly explain the difference but you can find more details at [Unit] Section Options | freedesktop.org

  1. After=

    This option only sets the order of the units, it doesn't guarantee that the service has finished starting up.

  2. Wants=

    This option allows your unit to start only after another unit has finished starting up. (Doesn't matter if it started successfully or not)

  3. Requires=

    Just like Wants=, however, this will make your unit start only after the dependencies have successfully started.

You can also use the inverse of each of those options.

  1. After= is inversed by Before=
  2. Wants= is inversed by WantedBy=
  3. Requires= is inversed by RequiredBy=

To fix your problem, you need to change your mount service to:

[Unit]
Description=MountSmokeScreen
After=network.target
Before=sonarr.service radarr.service

[Service]
Type=oneshot
ExecStart=/home/samsepioldoloresh4ze/bin/check.mount
TimeoutStopSec=20
KillMode=process
Restart=on-failure

[Install]
WantedBy=multi-user.target sonarr.service radarr.service

Or you can add Wants=mountgdrive.service to the sonarr.service and radarr.service units.

You can do that without modifying the default files by running the following (You need to do the same for radarr.service):

systemctl edit sonarr.service

And insert the following:

[Unit]
Wants=mountgdrive.service

Note: You can replace Wants= with Requires or WantedBy= with RequiredBy= if you don't want the two services to start at all if mountgdrive.service fails (Though Wants= is usually enough and even recommended in the docs).

EDIT: The WantedBy and RequiredBy options can only be used under the [Install] section. (Thanks @Yankee)

Share:
24,768
samsepioldoloresh4ze
Author by

samsepioldoloresh4ze

Updated on September 18, 2022

Comments

  • samsepioldoloresh4ze
    samsepioldoloresh4ze over 1 year

    I'm running Ubuntu 16.04 on an old HP Laptop

    I've installed some software on it to create a small homemade plex server. I've installed sonarr, radarr, deluge, jackett, etc etc and they all automatically launch at startup!

    A couple of days ago I decided to install rclone too and I've created (thanks to a GitHub project) a couple of folders that have to be mounted at each startup by launching a script (I launch it via terminal writing sudo ~/bin/check.mount). Sonarr and Radarr are set up to download stuff via deluge to a temp folder and then export it to one of these two mounted folders.

    The problem is, by the time I manually launch the script Sonarr/Radarr are already up and running and can't find their root folders, so they give me an error.

    What I'd like to do is create a mountgdrive.service (service, or whatever is necessary) to automatically launch the check.mount script and, if that's not enough, insert a delay in sonarr.service and radarr.service! Is that possible?

    I wrote this with sudo nano /etc/systemd/system/mountgdrive.service

    [Unit]
    Description=MountSmokeScreen
    After=network.target
    
    [Service]
    Type=oneshot
    ExecStart=/home/samsepioldoloresh4ze/bin/check.mount
    TimeoutStopSec=20
    KillMode=process
    Restart=on-failure
    
    [Install]
    WantedBy=multi-user.target
    

    and added to sonarr.service and radarr.service mountgdrive.service in the After= bit, like this

    [Unit]
    Description=Sonarr
    After=syslog.target network.target mountgdrive.service
    
    [Service]
    User=samsepioldoresh4ze
    etcetc
    ....
    

    But it's not working! Sonarr and Radarr start normally, but the drives are not mounted! What am I doing wrong?


    Also, rtcwake doesn't work on my laptop - I think it's a kernel issue?! Is there a way to fix that?

    • Dan
      Dan about 6 years
      If I understand correctly, you want sonarr.service and radarr.service to be run after mountgdrive.service is up and running?
    • samsepioldoloresh4ze
      samsepioldoloresh4ze about 6 years
      @Dan exactly! the problem is, the way I wrote it apparently mountgdrive.service runs but does nothing (it doesn't mount the drives), and then sonarr.service and radarr.service run normally because ubuntu executed mountgdrive.service
    • Dan
      Dan about 6 years
      I would also recommend you look into .mount units. If all your mountgdrive.service is doing is mounting a directory or similar, you may be able to change it to a .mount service. As it makes it more reliable specially since you have dependencies on it.
  • samsepioldoloresh4ze
    samsepioldoloresh4ze about 6 years
    thanks for Wants= and WantedBy=, I'll definitely used them!! I get this error though when I restart the laptop i.imgur.com/a3LE3G9.png
  • Dan
    Dan about 6 years
    There seems to be an error in the script. You can see it from the line ending with Can't open /.config/SmokeScreen/smokescreen.conf. Maybe you have "~/.config/..." in yoru script. You should replace the tilde (~) with the full path i.e. /home/you_user_name/.config/.... (Or use relative paths to your script)
  • samsepioldoloresh4ze
    samsepioldoloresh4ze about 6 years
    github.com/FourFingerLifeHug/SmokeScreen/blob/master/… - this is the check.mount script, so I should change all the $(HOME) and $(bindir) with the full paths? Thanks!
  • Dan
    Dan about 6 years
    @samsepioldoloresh4ze Yep, $HOME isn't available at boot time, because there isn't a logged in user yet.
  • Yankee
    Yankee over 4 years
    Should WantedBy= be in the [Unit] section? I thought it can only go in [Install].
  • Yankee
    Yankee over 4 years
    I dont think it can go under [Unit]. Whenever I add a WantedBy= clause under the [Unit] section, I get this message in the syslog everytime I invoke any systemctl command: Unknown lvalue 'WantedBy' in section 'Unit', ignoring. EDIT: And actually, the documentation link you posted shows it is supposed to go under [Install].