2

I have two service oneshots:

  • one that creates snapshots
  • one that sends snapshots

The second one (send) should always be executed after the first one (create) is finished. Currently the services, which are of type oneshot, run at the same time.

The services are defined as follows (the exact used command from the following examples doesn't matter for this question, detailed requirements below the examples):

  • Service to create snapshots (pyznap.service):
    [Unit]
    Description=Create ZFS snapshots
    Documentation=man:pyznap(1)
    Requires=local-fs.target
    After=local-fs.target
    
    [Service]
    Type=oneshot
    ExecStart=/usr/bin/pyznap snap
    
  • Service to send snapshots (pyznap-send.service):
    [Unit]
    Description=Send ZFS snapshots
    Documentation=man:pyznap(1)
    Requires=local-fs.target network-online.target
    After=local-fs.target network-online.target pyznap.service
    
    [Service]
    Type=oneshot
    ExecStart=/usr/bin/pyznap send
    

Currently, they are triggered by individual (and independent) timers:

  • The timer for the create snapshot (pyznap.timer):
    [Unit]
    Description=Run pyznap snap every 15 minutes
    
    [Timer]
    OnCalendar=*:0/15
    Persistent=true
    
    [Install]
    WantedBy=timers.target
    
  • The timer for the send snapshot (pyznap-send.timer):
    [Unit]
    Description=Run pyznap send every 15 minutes
    
    [Timer]
    OnCalendar=*:0/15
    Persistent=true
    
    [Install]
    WantedBy=timers.target
    

Additional notes:

  • The question is related to "How do you configure multiple systemd services to use one timer?, but this solution still runs the services at the same time
  • As per systemd design, only one service can be referenced by Timer.Unit.
  • The units are separated due to different requirements:
    • only the "send" service needs network
    • the "create" service must run also without network
    • I am fine with skipping those services if requirements are not met
  • The "send" service should run immediately after the previous "create" service.
  • If there's only one timer:
    • the timer cannot activate only the send snapshot service as the create snapshot service needs also to run without network
    • but the timer could activate only the create snapshot service if there's a way to run the send snapshot service directly afterwards
  • We don't know how long the first create snapshot service takes.

1 Answer 1

1

Your primary question seems to be how to start a second systemd service immediately after a first one was successfully started. It doesn't state what to do in case the pyznap.service is finished but the pyznap-send.service lacks the network connection to actually send the snapshots, so I will assume that you don't intend a sophisticated retry-logic.

In that case, you may consider omitting the second service and adding an ExecStartPost line to the pyznap.service that calls pyznap with the send option:

ExecStartPost=/usr/bin/pyznap send

Alternatively, if you want to have slightly more of systemd's control features, you could still define the pyznap-send.service, but activate it from the pyznap.service via an ExecStartPost statement:

ExecStartPost=/usr/sbin/systemctl start pyznap-send.service

In that case, you will need to remove the After=pyznap.service statement in the pyznap-send.service file, since the pyznap.service may not yet be registered as "started" when the ExecStartPost line starting the pyznap-send.service is called.

1
  • I like this second approach with ExecStartPost! Didn't think of that. It still allows it to require on network-online.target and makes sure it at least tried to run the second oneshot.
    – Dionysius
    Jan 9, 2023 at 14:38

You must log in to answer this question.

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