Tips en Trucs 2020

Systemd Timers

Systemd is al een tijdje het systeem dat gebruikt wordt om alles wat gestart moet worden om het systeem op te starten te regelen. En dat gaat ver, voor sommigen te ver. Zo kan je met systemd ook tijdafhankelijke zaken opstarten, waarvoor je vroeger cron gebruikte.

Wat moet er uitgevoerd worden?

Systemd gebruikt service bestanden met een beschrijving van hoe, wanneer, enz. een programma of script moet uitgevoerd worden. Systemd service bestanden maak je als root aan in de map /etc/systemd/system/ en geef je een unieke naam. Bijvoorbeeld met de teksteditor nano:

dany@pindabook:~> sudo nano -P /etc/systemd/system/PindaNetTimer.service 
[sudo] wachtwoord voor root:

Let op dat nano regels niet splitst op twee of meer regels. Ons test service bestand wordt:

# PindaNetTimer.service
[Unit]
Description= Service die door Timer wordt uitgevoerd
Documentation= https://linux.pindanet.be/faq/tips20/timer.html

[Service]
Type= simple

ExecStart= /usr/bin/echo "De PindaNet service werd uitgevoerd."

[Install]
WantedBy= multi-user.target

Deze test service geeft een tekst door aan systemd. Dit gebeurt met de opdracht /usr/bin/echo (let op het volledige pad, dat je kan opvragen met de which opdracht). Bij het starten van de service wordt een bericht doorgegeven. Het wordt pas echt interessant als je een eigen script laat uitvoeren, bijvoorbeeld om een back-up op geregelde tijdstippen uit te voeren.

Om systemd op de hoogte te brengen van een aangepaste of nieuwe service, voer je de volgende opdracht uit:

dany@pindabook:~> sudo systemctl daemon-reload
[sudo] wachtwoord voor root:

Daarna start je de service met de opdracht:

dany@pindabook:~> sudo systemctl start PindaNetTimer.service

Om de uitvoer van de service en eventuele fouten op te sporen, kan je gebruik maken van twee opdrachten: ten eerste:

dany@pindabook:~> sudo systemctl status PindaNetTimer.service
● PindaNetTimer.service - Service die door Timer wordt uitgevoerd
   Loaded: loaded (/etc/systemd/system/PindaNetTimer.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
     Docs: https://linux.pindanet.be/faq/tips20/timer.html

apr 04 15:14:22 pindabook.lan echo[5864]: De PindaNet service werd uitgevoerd.

En:

dany@pindabook:~> sudo journalctl -u PindaNetTimer.service       
-- Logs begin at Sat 2020-04-04 13:33:37 CEST, end at Sat 2020-04-04 15:17:05 CEST. --
apr 04 13:46:34 pindabook.lan systemd[1]: Started Service die door Timer wordt uitgevoerd.
...
apr 04 15:14:22 pindabook.lan systemd[1]: Started Service die door Timer wordt uitgevoerd.
apr 04 15:14:22 pindabook.lan echo[5864]: De PindaNet service werd uitgevoerd.
apr 04 15:16:55 pindabook.lan systemd[1]: Started Service die door Timer wordt uitgevoerd.
apr 04 15:16:55 pindabook.lan echo[5974]: De PindaNet service werd uitgevoerd.
lines 14-42/42 (END)

Druk Spatie om de volgende pagina met meldingen te bekijken en druk q om journalctl te verlaten.

Na het aanpassen van een service bestand, kan je de aanpassing testen door de service opnieuw te starten:

dany@pindabook:~> sudo systemctl daemon-reload
[sudo] wachtwoord voor root: 
dany@pindabook:~> sudo systemctl restart PindaNetTimer.service

Wanneer en met welke tussenpozen voeren we de service uit?

Dit wordt beschreven in een timer bestand met dezelfde naam als het service bestand waarvoor je de timer maakt:

dany@pindabook:~> sudo nano -P /etc/systemd/system/PindaNetTimer.timer

Met bijvoorbeeld de volgende inhoud:

# PindanNetTimer.timer
[Unit]
Description=Start de PindanNetTimer.service na 1 minuut na het starten van het systeem

[Timer]
OnBootSec=1m
#OnUnitActiveSec=1m

[Install]
WantedBy=timers.target

De OnBootSec zorgt dat de PindanNetTimer.service pas 1 minuut na de systeemstart zal opgestart worden. Dan is het systeem reeds klaar met de rest en kan uw service starten wanneer het systeem het wat minder druk heeft. Met de uitgecommentarieerde optie OnUnitActiveSec kan je de service zelf elke minuut laten uitvoeren. De tijd tussen de service uitvoeringen kan je zelf vastleggen (bijvoorbeeld in uren [h], zie handleiding) of op bepaalde tijdstippen (OnCalendar), enz. Opnieuw brengen we systemd op de hoogte van onze nieuwe timer:

dany@pindabook:~> sudo systemctl daemon-reload
[sudo] wachtwoord voor root:

En starten we de timer met:

dany@pindabook:~> sudo systemctl start PindaNetTimer.timer
[sudo] wachtwoord voor root:

De werking van de timer controleer je met:

dany@pindabook:~> sudo journalctl -u PindaNetTimer.timer
-- Logs begin at Sat 2020-04-04 13:33:37 CEST, end at Sat 2020-04-04 15:48:00 CEST. --
apr 04 14:21:26 pindabook.lan systemd[1]: PindaNetTimer.timer: Refusing to start, unit to trigger not loaded.
apr 04 14:21:26 pindabook.lan systemd[1]: Failed to start Start de PindanNetTimer.service na 1 minuut an het starten van het systeem.
apr 04 14:22:28 pindabook.lan systemd[1]: Started Start de PindanNetTimer.service na 1 minuut an het starten van het systeem.
apr 04 15:05:59 pindabook.lan systemd[1]: Stopped Start de PindanNetTimer.service na 1 minuut na het starten van het systeem.
apr 04 15:46:42 pindabook.lan systemd[1]: Started Start de PindanNetTimer.service na 1 minuut na het starten van het systeem.

En of de timer de service goed heeft gestart:

dany@pindabook:~> sudo systemctl status PindaNetTimer.service
● PindaNetTimer.service - Service die door Timer wordt uitgevoerd
   Loaded: loaded (/etc/systemd/system/PindaNetTimer.service; disabled; vendor preset: disabled)
   Active: inactive (dead) since Sat 2020-04-04 15:46:42 CEST; 3min 38s ago
     Docs: https://linux.pindanet.be/faq/tips20/timer.html
  Process: 6810 ExecStart=/usr/bin/echo De PindaNet service werd uitgevoerd. (code=exited, status=0/SUCCESS)
 Main PID: 6810 (code=exited, status=0/SUCCESS)

apr 04 15:46:42 pindabook.lan systemd[1]: Started Service die door Timer wordt uitgevoerd.
apr 04 15:46:42 pindabook.lan echo[6810]: De PindaNet service werd uitgevoerd.

Om een overzicht te krijgen van alle actieve en/of uitgevoerde timers, voer je de volgende opdracht uit:

dany@pindabook:~> systemctl list-timers
NEXT                          LEFT          LAST                          PASSED        UNIT                         ACTIVATES
Sun 2020-04-05 00:00:00 CEST  8h left       Sat 2020-04-04 10:35:19 CEST  5h 16min ago  logrotate.timer              logrotate.servi>
Sun 2020-04-05 00:00:00 CEST  8h left       Sat 2020-04-04 10:35:19 CEST  5h 16min ago  mandb.timer                  mandb.service
Sun 2020-04-05 01:16:24 CEST  9h left       Sat 2020-04-04 10:35:19 CEST  5h 16min ago  backup-sysconfig.timer       backup-sysconfi>
Sun 2020-04-05 01:33:33 CEST  9h left       Sat 2020-04-04 10:35:19 CEST  5h 16min ago  check-battery.timer          check-battery.s>
Sun 2020-04-05 01:55:16 CEST  10h left      Sat 2020-04-04 10:35:19 CEST  5h 16min ago  backup-rpmdb.timer           backup-rpmdb.se>
Sun 2020-04-05 13:48:44 CEST  21h left      Sat 2020-04-04 13:48:44 CEST  2h 3min ago   systemd-tmpfiles-clean.timer systemd-tmpfile>
Mon 2020-04-06 00:00:00 CEST  1 day 8h left Thu 2020-04-02 18:23:15 CEST  1 day 21h ago fstrim.timer                 fstrim.service
n/a                           n/a           Sat 2020-04-04 15:46:42 CEST  5min ago      PindaNetTimer.timer          PindaNetTimer.s>

8 timers listed.
Pass --all to see loaded but inactive timers, too.
lines 1-12/12 (END)

Druk opnieuw q om het overzicht te verlaten.

Automatisch starten

Als de service en de timer na grondig testen werken zoals het hoort, mag de timer automatisch bij elke systeemstart starten. Om de timer in het opstartsysteem van systemd op te nemen, gebruik je:

dany@pindabook:~> sudo systemctl enable PindaNetTimer.timer
[sudo] wachtwoord voor root: 
Created symlink /etc/systemd/system/timers.target.wants/PindaNetTimer.timer → /etc/systemd/system/PindaNetTimer.timer.

Een timer wordt niet meer automatisch met het systeem opgestart na het uitvoeren van:

dany@pindabook:~> sudo systemctl disable PindaNetTimer.timer
Removed /etc/systemd/system/timers.target.wants/PindaNetTimer.timer.

Documentatie

Naast de standaard documentatie (man systemd.timer) kan je overzichtelijke informatie vinden op de wiki pagina van archlinux.

Systemd timer