This was a tough nut to crack. Spent 3-4 calendar weeks (getting blurry
now) to try and figure it all out. In the end, the following changes
were necessary:
- Ensure setup-root.sh is guaranteed to run before any of the tests
- Give all tests their unique /etc, /tmp, and /run inside the chroot.
Turns out tmpfs+overlayfs can be used unprivileged inside an unshare
- A static BusyBox binary with support for mount helpers so we can
do the mkdir magic in skel/etc/fstab for the /etc overlay
The last item turned out to be a bit of a roller coaster ride of its
own. First of all, the original binary we used was from the upstream
BusyBox project[1]. I was sure it couldn't be that hard to enable the
CONFIG_FEATURE_MOUNT_HELPERS ... oh boy was I wrong. To make long and
tedious story short; two new projects on GitHub were created for this
task: 1) troglobit/misc[2] to house a mirror of https://musl.cc
toolchains and 2) troglobit/busybox-builder[3] to download, patch, and
build the thing using a .config from the myLinux[4] project. Patching
this .config was necessary, however, since musl libc is strict POSIX
and does not have any of the BSD extensions, e.g. REG_STARTEND that is
in GLIBC regex(3).
[1]: https://busybox.net/downloads/binaries/1.31.0-defconfig-multiarch-musl/
[2]: https://github.com/troglobit/misc/releases/tag/11-20211120
[3]: https://github.com/troglobit/busybox-builder/releases/tag/1_35_0
[4]: https://github.com/troglobit/myLinux
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This delays the start of the .conf monitor and service initialization
slightly to allow the event loop to run earlier to process any events
from the initial setup.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch renames the internal states for run/task/services to avoid
any confusion with the introduction of 'ready:scripts'.
* WAITING -> PAUSED
* READY -> WAITING
A service condition that used, e.g., <service/foo/ready> should now
instead use <service/foo/waiting>.
Note: A new condition with the old name <service/foo/ready> will be
introduced shortly to signify service "readiness", a concept
used in other PID 1, like systemd and s6.
For details, see issue #299.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In Finit a daemon can signal its readiness by creating/touching its PID
file. An ancient UNIX concept -- a daemon creates its PID file when it
has set up signal handlers and is ready to receive IPC (signals), right
before entering its while(1) loop.
Finit took the concept a bit further, adding readiness signalling also
to daemon's by touching their PID file after having processed a SIGHUP.
For both these conditions Finit now supports a ready:script, called when
readiness is detected. In later commits support for s6 and systemd
style readiness notification will be added that will hook the mechanism
implemented in this commit as well.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This support API is for running things like pre:script, post:script and
the upcoming ready:script for services. A ready:script will be called
when a service notifies Finit of its readyness.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch adds the mdevd[1] plugin from Andy's fork of Finit, only
minor whitespace adjustment and group fix introduced, along with
updates to configure.ac and the documentation.
Currently the hotplug.sh calls mdevd-coldplug (instad of mdev -s), but
since mdevd is not guaranteed to have started and be ready, it is also
started with mdevd -C. A better solution is to use the s6 notify code
to synchronize the start of mdevd-coldplug. Support for this is coming
soon to Finit.
[1]: https://github.com/hongkongkiwi/finit/blob/master/plugins/mdevd.c
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Service/task/run are today identified by name:id this means the path to
a command is not necessarily the basis for the identity. Hence, an
svc_t can now be updated with new the correct path to a command.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
As a real life example, this can be useful for a mfgtest mode for the
device, wherein the bootloader can be set to finit.cond=test_mode or
finit.cond=user_mode and then specific services can start up in test
mode which wouldn't normally start.
Or even custom firmware update mode such as finit.cond=fw_update_mode
which performs some specific firmware update steps and doesn't launch
normal processes.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In fbcd7d2 and 96257cc the state machine transitions were changed to
ensure that pre:scripts only run when conditions have been asserted, and
that manual:yes run/tasks end properly in 'DONE' as their siblilngs.
Also include SVG in repo for reference since that's the best export from
the original at draw.io
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This is a follow-up to #274, in which Andy pointed out that ending up in
state 'stopped' was a bit confusing for manual:yes run/tasks.
With the following change we let all run/tasks end in state 'done', yet
still allow manual:yes ones to transition to 'ready' when the user calls
`initctl start foo`.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The whole point of pre: scripts is that they run just before the actual
run/task/service process, hence they need to be locked behind the same
conditions as the process. Otherwise pre: scripts would be nothing more
than plain tasks.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This is a fix to a regression introduced in e51587c. The idea is to
have 'initctl status foo' show all instances of foo, provided there are
more than one. E.g.
root@anarchy:~# initctl -t status foo
0 foo:1 stopped [--234-----] hej knekt
0 foo:2 stopped [--234-----] hej snigel
0 foo:3 stopped [--234-----] hej kalas
And not foobar:
0 foo:1 stopped [--234-----] hej knekt
0 foo:2 stopped [--234-----] hej snigel
0 foo:3 stopped [--234-----] hej kalas
0 foobar stopped [--234-----] hej foobar
If you type an exact match you can drill down like so:
root@anarchy:~# initctl status foo:1
Status : stopped (code=exited, status=0/SUCCESS, manual=yes)
Identity : foo:1
Description : hej knekt
...
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Prior to this change only service stanzas respected the manual:yes
option, now it (should) work on any svc_t type. Not tested on ttys.
The initctl tool has been given an extra manual=yes output for these
types of run/task/service entries, shown only when the manual option
is set.
Example:
root@anarchy:~# initctl status foo.sh
Status : stopped (code=exited, status=0/SUCCESS, manual=yes)
Identity : foo.sh ~~~~~~~~~~~~
Description : Hej foo
Origin : /etc/finit.d/enabled/foo.conf
Environment :
Condition(s):
Command : /root/foo.sh
PID file : none
PID : 0
User : root
Group : root
Uptime : N/A
Starts : 1
Restarts : 0 (0/10)
Runlevels : [--2345----]
Notice also the new `Starts : 1` which is a counter for the number of
starts in the current runlevel. On runlevel change it is reset to 0.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change makes it possible tell the bundled/built-in getty to call
/bin/login with the '-p' flag, to preserve any environment set in the
Finit .conf files.
Issue #286
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Allow filtering of conditions in raw dump, i.e., the possibility to show
only conditions of a certain type. The TYPE argument is not validated
in any way, so any prefix match is allowed, e.g.
initctl cond dump service/s
Shows all conditions for services starting with 's'.
Fixes issue #272
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When adding a new service option recently, I copy-pasted and forgot to
update the length argument to strncasecmp(), so it was time to fix that
once and for all.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change allows endless restarts, similar to `respawn` but honors
`restart_sec`. There is no upper limit on the number of times Finit
tries to restart a crashing service. Same as `restart:-1`
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This seemed odd at first, but it turns out we seem to have adjusted the
time scale for the bootstrap worker, so we were off by ... a factor 10.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Move the stop+start from initctl to the state machine by allowing
stopped tasks to restart once it has been collected. This should
prevent finit from blocking, allowing it to handle other requests
while waiting for the service's PID to be collected.
Effectively, this will allow a service to call initctl to restart
itself, as reported in issue #280.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change diversifies the exit codes used by initctl on fatal errors.
Previously only Std C codes 0 and 1 were used, with the initctl specific
255 for some cases.
Both the LSB init script codes and BSD sysexits.h codes are used. See
util.c exitcodes[] for the full list. The idea is to complement the
change in 9a76f08, issue #266, so that initctl can be used silently for
scripting purposes.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch introduces ERR(), ERRX(), WARN(), and WARNX() as replacements
to their lower case counterparts. These log macros respect the 'quiet'
flag to initctl, leaving only the return code as indicator to user.
Fixes#266
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
No need for the verbose output on error, simply state the cause of the
problem. The user can issue `initctl -h` to check the syntax of the
command.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Drop `| tail -10` from 'log foo' command. Let user call tail themselves
and only limit with tail on status command.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Grep in /var/log/syslog, or messages, for both the service identity (not
just svc->cmd) and also try to find [PID] for more relevant information.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Drop basename() of svc->cmd from remaining code
- Replace uses of svc->cmd with svc_ident(svc)
- Use svc_ident() as default log tag
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
What a ride, apparently we support restarting run/tasks in the same
runlevel they have already started once in. Still unsure if adding
support for reloading a particular Finit .conf file for a service
should be in the context of this command (it isn't now). Maybe it
is better left as a future expansion when we switch to the new .conf
format?
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A user with no cgroup support in kernel does not know what they are
missing, and a user running in a container has someone else managing
cgroups.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Init script return pretty quickly after launch, so we cannot use that to
detect if they, or the daemon they launched, have crashed. So we start
the service_retry() with a 2 sec delay, which should be ample time to
allow the pidfile plugin to detect a forking service's new PID.
In release-cycle regression, no public issue needed.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In some conditions, typically when the same command is used for multiple
services, e.g. the modules-load plugin, the svc_find() function returned
an existing "similar" entry instead of NULL, causing loss of config.
When creating, and searching for, a run/task/service we must follow the
new name:id paradigm to the letter. Always create based on name:id and
always search for matching name:id. The name may be derived from the
command, but they cannot be used interchangably.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change makes it possible to see the new service's resulting name
and id before we create it with svc_new(). We extend the debug output
slightly to see what's going on and why we sometimes lose modules from
the modules-load plugin ...
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>