1

I have a long-running systemd service, let's call it db.service. It is enabled to start on system boot, but can also be restarted manually.

I also have a oneshot service, les's call it check.service, that performs an integrity check on the database file.

check.service should be run on system boot, and during boot db.service should not start if check.service fails.

But! Here's the caveat: check.service should NOT be run when db.service is restated manually using systemctl restart db.service. And it should be possible to start db.service manually even if check.service fails on boot.

Question

Is there a way to achieve this using systemd services?

Thoughts and observations

  • I though I could achieve this by using RequiredBy=db.service in check.service. But that still triggers check.service when db.service is started.

  • Maybe the problem can be solved in some way by creating a third service, db-boot.service, that has dependencies on boot db.service and check.service. But I haven't been able to figure out how.

1 Answer 1

2

You need check.service to be of Type=oneshot with RemainAfterExit=yes, and it needs also be WantedBy=db.service and ordered Before=db.service

Then at boot time (or before the first startup of the database, if the database is not configured to start at boot time), the check.service runs to completion and is left in active (exited) state. So when db.service is restarted, check.service is already active and satisfies the dependency, so check.service won't restart.

With this setup, if check.service fails on boot, db.service will not be started (but since using a Want dependency instead of Require, the rest of the system will start up normally instead of dropping into emergency mode). If db.service is then started manually, it will require check.service to run once successfully first. After check.service is run successfully, then db.service can be started and stopped at will.


If db.service needs to be able to be started manually when check.service is failing, then you might instead want to configure db.service to not start automatically at all (i.e. systemctl disable db.service), and remove the WantedBy=db.service from check.service. Instead, you would have check.service explicitly run sudo systemctl start db.service if and only if the check is successful.

This way, there will be no dependencies requiring check.service to run when starting db.service manually, but check.service will auto-start the database only if the check is successful (presumably at boot time).

2
  • Thanks telco. I will evaluate this. I am currently messing with a solution that uses a third service, db-boot.service, that has Requires=check.service and OnSuccess=db.service. I am optimistic about this, but haven't gotten it to work yet.
    – Lii
    Commented Feb 25, 2022 at 13:31
  • Thanks telecoM, I ended up using a variation of solution. I use a separate db-boot.service that depends check.service. In db-boot.service I use ExecStart=systemctl start db.service. In that way I can also run check.service manually, without starting db.service as a result.
    – Lii
    Commented Mar 17, 2022 at 10:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .