[systemd-devel] Have timers fire after boot is complete
christian at iwakd.de
Thu Sep 27 01:33:45 PDT 2012
one of the most-requested features that is not present in systemd
currently is a true rc.local-type functionality that runs after all
I haven't read all past discussions, but from what I've gathered the
main objection from the systemd developers is that having a catch-all
After=* dependency would not be the sane thing to do.
That said, the frequency of people requesting this feature indicates
that there are valid use cases for this kind of functionality. To give a
- remove /etc/nologin after everything is started
(some administrators may want this as a policy,
while other's don't)
- send an email to the admin "btw. computer XYZ just
finished rebooting and here are the log entries generated
from the boot process"
- in linux HA you may want to defer the node rejoining the
cluster to the point when you know that the server has
correctly booted and none of the core services failed in
I'm sure there are quite a few more.
Current solutions are type=idle units (which don't really work for many
of the above use cases, since type=idle is essentially type=simple) or
setting SysVStartPriority to 99 (as done in Fedora), but that only
orders relative to sysv services, not to native services - and in a
setup where most if not all services are native, this will not have the
In order to implement this feature in systemd, I've gone another
direction: Instead of having a service for which some ordering
constraints are ensured, why not have a timer? There is already
OnBootSec=, which is relative to the time when the kernel was activated,
so the idea was to have another timer base for this specific purpose.
The patch I'm going to send as a reply to this email will implement
OnTransactionFinishedSec=. When a timer is started and contains such an
entry, it will tell the manager to ping it as soon as the transaction is
complete. The manager then proceeds to activate all other units in the
transaction and as soon as it reaches manager_check_finished and no jobs
are left in the run_queue, and after it closes the idle pipe to trigger
the type=idle jobs, it pings the timers again. The timers will then
remember the finish time of the current transaction and use that as a
base for all OnTransactionFinishedSec= entries.
This also has some nice semantics if you want to run something not
immediately after boot but e.g. 5 minutes later. If you think, well,
boot time is ~30s, I just put in OnBootSec=330s, this will usually give
the expected results. However, if for some reason you first boot into
rescue.target, then do some stuff for 10 minutes and then run systemctl
isolate default.target, the timer will fire immediately while the system
is still in the process of booting, which may not be what you want. On
the other hand, OnTransactionFinishedSec= will only start counting once
you reach the transaction that started the timer, which usually would be
the boot transaction (if timer is in default.target) but could also be
the isolate transaction in the above scenario.
Anyway, I hope I've provided a rationale why this can be a useful
feature to have in systemd. The patch will follow in a reply to this mail.
More information about the systemd-devel