This patch adds initial support for starting a SysV init script in a
runlevel, and stopping it when leaving a runlevel.
sysv [LVLS] <COND> /path/to/script.sh -- Optional Description
The SysV /etc/inittab file, which may use /etc/init.d, or /etc/rcN.d,
is still not supported. A separate plugin would be required for this,
see the documentation for more information.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch introduces the LOG_CONSOLE syslog facility for logging common
events. In industrial applications aiming for IEC 62443 compliance the
following events are central for system observability:
- Change of runlevel - i.e., starting up, shutting down, upgrade, etc.
Facility: console, severity: notice
- Service starting
Facility: console, severity: notice
- Service restarting
Facility: console, severity: notice
- Service stopping
Facility: console, severity: notice
- Service failed to start
Facility: console, severity: warning
The use of facility console for this makes it easier to filter out when
forwarding syslog messages from an embedded system to a remote log sink.
Otherwise messages of facility daemon would be used, which include a lot
more, and mostly irrelevant, information.
Signed-off-by: Jonas Holmberg <jonas.holmberg@westermo.se>
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Similar to how systemd creates cgroups for all services, for purposes of
tracking, Finit now does the same. We also mount all available cgroups
in the /sys/fs/cgroup namespace.
This patch adds support for grouping processes in logical cgroups, like
systemd, and an `initctl ps` command to list the hieararchy.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Allows the service/task name derived from the binary to be
overridden with a custom name.
Example:
service name:dhcpd [2] /usr/sbin/udhcpd -f -- DHCP Server
Signed-off-by: Robert Andersson <robert.m.andersson@se.atlascopco.com>
Instead of changing the API of service_step(), and relying on all the
different callers to step again, we can schedule another event to do
this for us.
In addition to handling the cond_update() case this also handles all
other callers of service_step(). Ensuring that nested conditions do
trigger changes.
Also, reverting dddd45e fixes a minor regression in service_monitor()
which caused it to not clean up collected bootstrap tasks.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
We allow all run/task/services to complete before changing runlevel.
This means stepping them all while we wait for their completion, since
services may depend on each other.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Reassert condition when an unchanged/unmodified process goes from
WAITING state to RUNNING. I.e. it had a condition that went to flux
during `initctl reload`, which drove it to WAITING and was then sent
SIGSTOP during reconf.
Also, on condition update, loop through all services until no more state
changes are observed. This allows long dependency chains of services to
resolve and actually go back to RUNNING state as intended whenever any
condition changes at runtime.
Signed-off-by: Jonas Johansson <jonasj76@gmail.com>
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Reduce the noise: we don't need to notify the user if a process started
in bootstrap is simply SIGHUPed.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
If we delete bootstrap (only) run tasks in service_start() when they
complete they may be found and run again if *.conf reload takes place.
Instead, mark them as having been run, like regular runtasks, and set
their state directly to STOPPING. The once flag ensures the svc is not
restarted if its .conf file is reloaded.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
An SVC_TYPE_RUN may be deleted by svc_clean_bootstrap() as soon as it's
been collected. We must not try to dereference that pointer afterwards,
e.g. in svc_is_daemon().
Refactor the whole of it to make the code easier to follow.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
An operator wanting to monitor processes started by Finit could use the
kernel ftrace framework. E.g. execsnoop in perf-tools.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
If an inetd service is changed, finit must update the command line
arguments associated with the service.
Signed-off-by: Petrus Hellgren <petrus.hellgren@westermo.se>
Signed-off-by: Petrus Hellgren <petrus.hellgren@gmail.com>
Do not restart a inetd service if the listening interface is changed.
Only bring down established connection which are no longer allowed,
i.e. do not touch already allowed established connections.
Signed-off-by: Jonas Johansson <jonasj76@gmail.com>
All service/task commands are tracked by the state machine, but run
commands are a bit special since they must run in sequence. Hence,
we must increment their 'once' counter in service_start() instead.
This should fix the issue mentioned in #96 "took a long time before
the next line" -- because Finit was waiting for udevadm to reach a
once count > 0, which we didn't increment.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
As a precaution, services who are being stopped are automatically sent
a SIGKILL after 3 seconds if they refuse to go away willingly.
Unfortunately this backup mechanism was also enabled for inetd
services which are not backed by a real process. When the service was
freed the timer was not stopped, since it was not expected to be
armed. The timer would then trigger, causing a use-after-free on the
timer watcher containing a bogus callback pointer.
When an UDP inetd connection terminates we must make sure to unblock the
parent, which is (currently) blocked during the transaction.
This patch is a fix to a regression introduced in 2c904b5, for v3.1
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Don't warn of missing PID, even if only _d(), perfectly normal
- Allow stopping restart timer of non-services (e.g. task/run)
- Allow stopping services with no PID rn, i.e. stop libuEv timer
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Finit tries to restart crashing services. If a service is removed
before Finit has given up restarting it, then the background timer
responsible the restart may dereference a free():d svc_t.
Hence, make sure to properly stop (and step) a service and its timer
callbacks in service_unregister() before calling svc_del().
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
In service_stop() we call svc_del() which, as of Finit v3.1, free():s
the svc_t, so we don't want any lingering restart timers to wake up
after free() and start dereferencing the svc_t.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>