2

I have 3 services:

  1. ParentService, which provides the bulk of my application
  2. DependentServiceA, which is strongly dependent on (i.e., is effectively useless without) ParentService running. When DependentServiceA is running, its lifecycle should be tied to ParentService (restarted together, stopped together).
  3. DependentServiceB, which is loosely dependent on (i.e., most functionality is tied to ParentService, but it's still useful without) ParentService. DependentServiceB's lifecycle should not be affected by ParentService (or DependentServiceA, naturally). It should prefer to start after ParentService.

Expected Behavior

  • If ParentService is cold started (i.e., not restarted)
    • Do not start dependent services
  • If ParentService is restarted
    • Restart DependentServiceA if it's already running; otherwise do not start it
    • Do nothing to DependentServiceB
  • If ParentService is stopped
    • Stop DependentServiceA if it's already running
    • Do nothing to DependentServiceB

This all works fine on:

  • CentOS 6 (with init scripts called by SysVinit)
  • CentOS 7 (with systemd 219)
  • RedHat 7 (with systemd 219)
  • Ubuntu 16.04 LTS (with systemd 229)

The Problem

This does not work on:

  • Debian 8/Jessie (with systemd 215)

On Debian 8, if I restart ParentService when DependentServiceA is not running, DependentServiceA starts anyway. This behavior does not occur when only starting ParentService.

I've attached my systemd files below for review. I'm almost certain it's a problem in DependentServiceA's unit file, but I'll admit I don't fully understand all the differences between systemd's dependency directives (e.g., BindsTo, PartOf, WantedBy).

ParentService

[Unit]
Description=Parent service
BindsTo=network.target
After=network.target
Before=soss_svc_rest.service dependent_service_b.service

[Service]
Type=forking
ExecStart=/usr/local/foobar/parent_service
KillMode=process
Restart=on-failure
PIDFile=/var/run/parent_service.pid

[Install]
WantedBy=multi-user.target
WantedBy=dependent_service_a.service

DependentServiceA

[Unit]
Description=Dependent Service A
BindsTo=network.target
After=network.target
After=parent_service.service
BindsTo=parent_service.service
PartOf=parent_service.service

[Service]
Type=forking
PIDFile=/var/run/dependent_service_a.pid
ExecStart=/usr/local/foobar/dependent_service_a
KillMode=process
Restart=on-failure

[Install]
WantedBy=multi-user.target

DependentServiceB

[Unit]
Description=Dependent Service B
BindsTo=network.target
After=network.target
After=parent_service.service

[Service]
Type=forking
PIDFile=/var/run/dependent_service_b.pid
ExecStart=/usr/local/foobar/dependent_service_b
KillMode=process
Restart=on-failure

[Install]
WantedBy=multi-user.target

If it's relevant, ParentService and DependentServiceB are marked as enabled (I want them to startup on system startup), but DependentServiceA is set to disabled by default and should be explicitly started and/or set to enabled by the user to start at system startup.

What have I configured incorrectly in my systemd unit files that causes DependentServiceA to start when it wasn't previously running when ParentService is restarted? And why does this only happen on Debian 8, but none of the other distributions I've tested on? Is it a bug in Debian 8's systemd (release 215) that was fixed between version 216 and 219? (I didn't see anything relevant in systemd's release history.)

  • It certainly sounds like a bug in systemd that was fixed, given that only the oldest version exhibits the issue. – Mark Stosberg Apr 19 '18 at 17:52

Your Answer

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

Browse other questions tagged or ask your own question.