90 Commits
Author SHA1 Message Date
Joachim Wiberg ee6d4a1dae service: keep a pending reload across a second conf reload
A service whose condition goes into flux during a reload is paused
with its reload still pending.  If another reload was requested in
the meantime, re-parsing its unchanged .conf file cleared the pending
mark, so the service was resumed without ever being reloaded.  Seen
with sshd <pid/syslogd> on Infix, where a configuration change that
touched both landed as two reloads in a row and sshd kept its old
listen addresses.

The mark is only ever cleared once the change has been applied, so a
mark that is still set when the file is parsed again means exactly
that: not applied yet.  Leave it alone.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-09-27 18:41:05 +02:00
Joachim Wiberg 61b0e0f3e6 Fix #420: run services inside a PAM session
Apply a PAM session to run/task/sysv/services Finit starts, pam_limits
above all, so a service running as a given user picks up that user's
limits the way a login does.

Add a new `pam` setting for the new block format (only), like the
per-service directories, naming a file in /etc/pam.d:

    service weston {
        user    = "weston"
        pam     = "weston-autologin"
        command = "/usr/bin/weston --continue-without-input"
    }

pam_close_session() has to be called by a process still holding the
handle, and the handle does not survive exec().  Hence the keeper: it
holds the handle, drops to the service's credentials, and waits for a
parent-death signal before closing the session.  Same shape as
systemd's (sd-pam), for the same reason, and one per fork, so the
script hooks open and close their own.

The keeper closes the descriptors it inherited from Finit and only
those.  Closing everything would also take out what pam_open_session()
opened for itself, a keyring fd or a lock file, and leave the modules
to close a session with those pulled out from under them.  Closing
nothing, as (sd-pam) does, would leave it holding the write end of the
notify pipe for the service's whole lifetime and starve notify = "s6"
services of their ready signal.  So the fds open before pam_start()
are snapshotted and exactly those are closed, while the ones PAM opens
after are marked close-on-exec so the daemon does not inherit them
either.

A refused value, a denied account stack, an uninstalled pam.d file,
and a build without PAM support all keep the service from starting
rather than running it with the stacks skipped: one that quietly loses
pam_limits and its private /tmp, with nothing said.  Capabilities a
module like pam_cap.so granted are merged into the IAB Finit applies
instead of being replaced by it, which only helps a service that also
sets capabilities, the other arm being a plain setuid() with nothing
left to restore once permitted is empty.

The test sysroot gains pam_permit.so, pam_deny.so and pam_limits.so,
which ldd cannot see, libpam dlopen()s them, and the test skips when
the host has none to stage.  The negative cases pin the exit status
rather than only asserting crashed, which serv reports for any early
exit, so a bad command or an unwritable pidfile cannot pass for a
rejected session.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-09-23 16:30:14 +02:00
Joachim Wiberg 230c65a080 test: cover org.finit.Device1 end to end
Introspection, queue-state properties, immediate and bus-first
settle, Info by devpath, Trigger(add, net) observed via the
DeviceProcessed signal, and RulesReload -- driven by dummy interface
hotplug like keventd.sh.  New call-ss and call-u client modes, and
getprop learns the b and t variants.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-08-16 22:03:44 +02:00
Joachim Wiberg 864a13460c test: add keventd device manager test
The unified keventd has no automated coverage, only the devmon
fallback is exercised by the test suite.  Network interfaces are
the one device class an unprivileged test can hotplug: the sandbox
has its own network namespace, so 'ip link add' makes the kernel
emit genuine uevents.

Verify keventd readiness, <class/net/IFNAME> driving a service --
and <dev/IFNAME> NOT asserted, interfaces are not device nodes --
libudev-compatible n<ifindex> keying in /run/udev/data, conditions
surviving initctl reload, and cleanup on interface remove.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-08-16 22:03:36 +02:00
Joachim Wiberg c28acf21a1 test: fuzz target for the message parser
__msg_parse() turns bytes off a socket into pointers, before anything
has vouched for the peer, and it is the only place in libink that
does.  It had no test of its own beyond whatever the other tests
happened to send it, all of it well-formed.

The target checks the parser's contract, not merely that it survived.
A header field must point into the header field array, and terminate
inside it, and the parse must never claim more bytes than it was
handed.  Crash-only would pass a parser that walked into the body and
returned fields from there, since those bytes were handed over too.
The expected bounds are derived from the raw header rather than from
the parser, so the two have to agree independently.

Every input is copied into an allocation sized to it first.  Reading
past the end of a roomy buffer stays inside the allocation and the
sanitizer never sees it; against an exact one the same read is a
fault, which is where the sharpest findings come from.

Under libFuzzer it is an ordinary fuzz target and named files replay,
which is how a find gets reproduced.  With no arguments it runs a
fixed sweep -- every truncation, every single-byte corruption, every
value of the length that decides where the header ends, and seeded
garbage -- so the suite covers the same contract on every build,
without clang or a corpus in the tree.  It takes 40 ms.

CI fuzzes it properly on every pull request, keeps the crashers, and
carries the corpus between runs so it reaches deeper over time than
any single run can.  Note that clang links the fuzzer runtime against
the newest GCC tree it finds, so the libstdc++ headers have to match
that one and not the default compiler, which is worth saying since
installing the obvious package leaves you exactly where you started.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-08-13 10:15:19 +02:00
Joachim Wiberg 127049d925 test: Finit against a real dbus-daemon
The other dbus-*.sh tests drive libink's own client, so the wire format
was only ever checked against the implementation that wrote it, and the
broker path had no coverage at all.  Every bug found in it so far was
found by hand on a target.

Let the dbus plugin bring up a real dbus-daemon, wait for Finit to
claim org.finit, then talk to Finit with dbus-send, which shares no
code with us.  The privileged call is the interesting one: it can only
be answered by parking the call and asking the broker who sent it.
The bus reads the policy Finit installs, so a malformed org.finit.conf
fails here rather than on a target.

Tests no longer build --with-libsystemd.  Our replacement carries the
real soname but only the sd_notify() symbols, so in the test root it
shadowed the libsystemd the host's libdbus-1 wants and dbus-daemon
died on a missing sd_is_socket.  Nothing under test needs the shared
library: serv is the only consumer and it compiles sd-daemon.c
straight in, which it now does regardless of the flag so notify.sh
keeps testing notify:systemd either way.

Staged from the host by lib/sysroot.mk like any other binary, and
skipped when the host has neither program.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-08-13 10:15:19 +02:00
Joachim Wiberg 63aabaa6df libink/dbus: identify the caller behind a broker
On the local bus SO_PEERCRED says who is calling and the kernel is the
one saying it.  Behind a broker one connection carries every caller,
so that credential describes dbus-daemon and nothing else, and every
privileged method was refused there, root included.

Ask the bus driver instead.  libink parks the call and hands us the
sender; we ask GetConnectionUnixUser and answer when the reply lands,
through the same event loop as everything else.  Nothing blocks:
blocking in PID 1 is why libuEv exists.  That needs calls libink can
make on a connection it already has, so it gained those too.

Answers are cached, since a bus never reuses a unique name while it
runs.  Not across a restart though: a new dbus-daemon numbers from
scratch and :1.7 becomes somebody else, so the cache goes when the
broker does.  A sender name too long to key on is refused rather than
truncated, two callers sharing a truncated key would share an
identity.

Privilege is no longer uid 0 alone.  The socket is already owned by
the --with-group group, so refusing its members every method that
changes anything left a wheel user able to open the bus and unable to
reboot.  Both gates now say the same thing.

Group membership needs NSS, which the C library loads with dlopen(),
so the lookup is compiled out where Finit is built to link statically.
That leaves such a build root-only, which is worth saying out loud
rather than leaving to be discovered.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-08-13 10:15:06 +02:00
Joachim Wiberg 6310d9e760 initctl: the status views over D-Bus
The summary table, the per-service detail, JSON and the quiet and
ident forms all read state Finit already publishes, so they read it
from the bus like everything else rather than through a second path
that has to be kept in step.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-08-13 09:28:26 +02:00
Joachim Wiberg dd1390a6c2 initctl: monitor and condition control over the bus
The bus can already answer questions and change services, so give
initctl the two things it still did another way: watching signals as
they happen, and getting or setting user conditions.

The dbus tests move with it, split by area rather than one file that
grew every time the library did.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-08-13 09:28:14 +02:00
Joachim Wiberg 0a269f3298 libink: a brokerless D-Bus implementation for Finit
Finit had no way to answer the question every service manager gets
asked: what is running, and change it.  D-Bus is how the rest of
userspace asks, but linking libdbus, sd-bus or GIO into PID 1 buys a
dependency, an allocator and a main loop we do not control.

So libink: the wire format, an object tree, and a bus of Finit's own
at /run/finit/bus, gated like INIT_SOCKET.  It speaks the standard
org.freedesktop.DBus, .Peer, .Introspectable interfaces, and Finit's
own Manager1, Service1 and Cond1 on top.  Methods that change
something are marked privileged and answered only for a caller the
kernel vouched for, via SO_PEERCRED.

Server and client both, since initctl is the first thing that needs
to talk to it, and its Start/Stop/Restart/Reload now go over the bus
rather than the legacy socket.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-08-13 09:28:14 +02:00
Joachim Wiberg 6b77a16f8b conf: add missing passenv to tty blocks
The line-based format has had the flag since v4.4 (issue #286), where
it prepends -p to the built-in getty, which turns it into login -p and
passes the environment on.  The block format was written from the three
documented tty variants and the flags listed in the tty documentation,
and passenv was in neither, so it was left out.  Converting a tty line
that used it therefore lost it, with nothing said.

It only reaches the built-in getty.  An external getty is handed its
arguments through command, so there is nowhere to put a -p, and the
setting is refused with a warning rather than quietly ignored.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-08-05 17:59:11 +02:00
Joachim Wiberg ffb1db7d2d conf: add provides, additional conditions a service supplies
A block title is a service identity, so two variants of one service
gated differently per platform cannot share a title.  They do need to
share the barrier condition downstream services wait for, which until
now was spelled by the identity alone and so could not be shared:

    service syslogd:udev {
        if         = "udevd"
        conditions = { "run/udevadm:5/success" }
        provides   = "pid/syslogd"
        command    = "-syslogd -F"
    }

Any namespace is allowed, since the point is publishing a name that
existing configurations already wait on.  A claim on a condition that
is already owned is dropped with a warning naming the owner, and the
service still registers: the overlap is a configuration bug, and an
init system is more useful degraded than refusing to boot.  A real
identity outranks a claim, pid/<ident> is how Finit tracks its own
services, so it is not up for grabs.

Claims are dropped before each reload re-reads the .conf files.  Doing
it per service as it re-registers is not enough, since services are
read in file order and one re-registering would lose to a claim
another had not dropped yet, flipping the owner on every reload.

initctl cond dump asked who owned a condition only for the pid/
namespace and printed 'static' for usr/, which now hides a provider.
It asks first and falls back to what the namespace implies.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-08-05 17:58:43 +02:00
Joachim Wiberg cfae4a0e10 conf: support list of candidate commands for services
A daemon known under more than one name had to be declared once per
name, each stanza carrying nowarn so the ones that were not installed
were skipped quietly.  That leaned on the line-based format having no
titles.  With a title as the service identity the repetition is no
longer available, so the candidates move inside the block:

    command = { "/lib/systemd/systemd-udevd", "-udevd" }

Finit starts the first one whose binary resolves.  A candidate that is
not installed is expected here, so nothing is logged for the ones that
lose, and only the winner is looked up again by service_register().
The leading '-' keeps its meaning and is read from the candidate that
wins, or from the last one when none resolve.

libconfuse accepts a bare string for a list option, so the common
`command = "prog args"` is unchanged, and whichp() already skips any
arguments to the command, so the candidate goes to it as written.

tty blocks take the same list.  Their command is the getty to run, and
it has the same reason to name alternatives.  Both block types now
share svc_command(), which also puts the leading '-' rule back in one
place: tty_translate() had its own copy.  A tty needs no command at
all, it may name a device or notty instead, so svc_command() returns
NULL for an empty section and each caller decides whether that is an
error.

system/10-hotplug.conf.in returns to one udevd block, which is what it
meant all along.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-08-05 17:57:27 +02:00
Joachim Wiberg 516ee41494 conf: reject .conf files that declare duplicate block titles
The block title is the service identity, and libconfuse merges two
sections that share one, without a word.  Two blocks titled the same
in one file therefore loaded as a single service holding a mix of both
declarations, with scalars taken from the last block and lists reset
by it.

system/10-hotplug.conf.in is written this way: two udevd blocks, one
per candidate binary, the way the line-based format spelled a
fallback.  Only the second survived the merge, so a system that has
/lib/systemd/systemd-udevd but no udevd got no udevd service at all,
and the whole `if = "udevd"` chain behind it went with it.

CFGF_NO_TITLE_DUPES turns the merge into a parse error naming the file
and the title, and the file is then rejected as a whole.  The same
title in another file is untouched, that is how an administrator
overrides a system .conf.

Format detection had to stop agreeing with it.  is_new_format() probes
by parsing, so a duplicate title made it answer "not block format" and
conf_parse_file() handed the file to the legacy parser, whose errors
buried the real message.  The probe now clears the flag on its own
copy of the option array, keeping the verdict syntactic.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-08-05 17:56:40 +02:00
Joachim Wiberg f0d7257374 Fix #492: add per-service directories, systemd RuntimeDirectory style
A service that drops privileges cannot create its own PID file in
/run, root owns it.  Finit can create the file with pidfile-create,
but the daemon still cannot touch it to confirm a SIGHUP.

Five new settings, block format only: runtime-dir, state-dir,
cache-dir, logs-dir, and config-dir.  The value is a directory name,
resolved under /run, /var/lib, /var/cache, /var/log, and /etc,
respectively.  The directory is created before the service starts,
mode 0755 owned by user/group, and the full path is exported to the
process as RUNTIME_DIRECTORY, STATE_DIRECTORY, CACHE_DIRECTORY,
LOGS_DIRECTORY, and CONFIGURATION_DIRECTORY.  Mode and ownership are
asserted at creation only, a daemon may tighten them afterwards.

The runtime directory is removed when the unit stops, after any
exec-stop-post script, like systemd with RuntimeDirectoryPreserve=no.
A completed run/task counts as stopped unless remain-after-exit keeps
it up.  The other four persist across restarts.

These are the first settings with no legacy token: they are validated
by service_set_dir() and stored on the svc that service_register()
now returns.  systemd accepts a list of directories per setting; this
is a single name for now, widening later is compatible since
libconfuse accepts a bare value for a list option.

The test sysroot gains libnss_files.so.2, which ldd cannot see, glibc
dlopen()s it.  Without it getpwnam() fails inside the chroot, so
user/group settings never resolved and directory ownership could not
be tested.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-07-30 15:23:37 +02:00
Joachim Wiberg be28436c2d conf: drop the angle brackets from if, infer from the value
The block format spells conditions as bare strings everywhere else, so
requiring `if = "<usr/foo>"` left one sigil behind, carried over from
the line-based `if:` token.  A namespace separator already tells the two
apart: a value with a '/' is a condition, anything else is a service
name.

svc_ifthen() picks its mode from the start of the statement and applies
it to the whole, so a statement naming both kinds cannot be evaluated.
That is now an error, as are the old angle brackets, and either one
skips the block:

    /etc/finit.conf: mixed: if: cannot mix a service name with a
    condition in 'anchor,usr/enable-me', a statement must be all of
    one kind, skipping

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-07-30 15:23:36 +02:00
Joachim Wiberg 2a5190ecff service: do not let a script timeout take PID 1 with it
A stop: or reload: script written with a timeout killed Finit at
config load:

    service stop:5,/bin/true service.sh -- Boom

parse_script() takes the timeout as a pointer and the caller decides
whether it wants one.  However, both stop: and reload: scripts so far
have no timeout, i.e., NULL.  Guard the branch that reads a leading
number.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-07-30 15:21:27 +02:00
Joachim Wiberg f1393ff8a1 conf: instantiate %i templates for the block format
A template in the block format registered garbage.  conf_parse_file()
routed every file with an '@' in its name straight to the legacy
parser, which read the block line by line: the section header became a
service whose command was the section title, and each key = value line
below it became an environment variable.

    service serv:%i { ... }   ->  service 'serv:eth0' with argument '{'

Substitute %i over the whole file before parsing instead, so format
detection and both parsers see finished text.  A bare name@.conf is
still skipped, it is the template rather than an instance of one.

The legacy parser no longer opens the file or substitutes per line, it
is handed the instantiated buffer, so the template convention now has
one implementation instead of two.  conf_is_template() applies
basenm(), a directory with an '@' in its name is not a template.

libconfuse cannot name a buffer it parses before 3.4, so a typo in a
template would be reported against "[buf]".  Parse through fmemopen()
with the file name preset until the floor moves.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-07-30 15:21:26 +02:00
Joachim Wiberg 3b866c95e0 conf: add libconfuse block format alongside the one-liner format
The one-liner format has grown crowded and very wide, and every new
service option makes it worse.

Add a second, block-based format, parsed with libconfuse:

    service sshd {
        description = "OpenSSH daemon"
        runlevel    = "2345"
        command     = "/usr/sbin/sshd -D $SSHD_OPTS"
    }

Both formats keep the .conf extension and are detected per file by
content.  Try-parse strictly with libconfuse; on a parse error,
re-parse leniently to tell a block file with a typo from a one-liner
file.  Only a one-liner file reaches the legacy parser, a typo is
reported with its file and line.

Each block is translated to the canonical one-liner and registered
through the existing entry points, so the two formats cannot drift.

The one-liner parser is frozen at the 4.x feature set, new options
land only in the block schema.  libconfuse 3.3 or later is required,
CFGF_KEYSTRVAL does not exist before it.

Covers service, task, run, sysv and tty blocks, the static directives,
and the cgroup, rlimit, set and log blocks.  Templating and the
documentation rewrite are still to come.

The regression test covers translation of a service block to the
one-liner, a block-format /etc/finit.conf booting with set {} applied
at bootstrap, both formats side by side, and rejection of a typo at
block and at root level.

A rejected file must not fall through to the legacy parser, which
registers a bogus unstartable service per line.  assert_num_children
cannot see that, the bogus service has no children either, so the
check is assert_num_services.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-07-30 15:21:25 +02:00
Joachim Wiberg 3febc7d513 test: regression for stale pidfile cleanup after unclean exit
Cover the scenario fixed in "service: clean stale pidfile after
unclean daemon exit": a daemon with a pid:!/path config dies via
SIGKILL, leaving its pidfile behind, and the next instance must
still come up.

Add a 'serv -x' flag (refuse to start when the pidfile already
exists, dbus-style) so the test actually exercises the cleanup --
without it, plain 'serv' would happily overwrite the file and the
test would pass with or without the fix.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-05-12 10:11:49 +02:00
Joachim Wiberg ab81272083 test: new regression test to verify multi-chain deps
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-02-13 07:30:10 +01:00
Joachim Wiberg 329f11b4da test: add barebones /etc/{passwd,group} and an ld.so.conf
Finit now requires being able to query at least for the root user and
group before starting any services.

Also, add support for using libraries installed in /usr/local

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-01-01 09:45:06 +01:00
Joachim Wiberg 5265eee25d test: slightly more robust checkself.sh
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-11 10:17:35 +01:00
Joachim Wiberg bbc83eaa64 test: new test
New test adds /bin/fail.sh to verify that a failing pre:script (that
also takes too long to run) is detected: exit code and timeout.

Ensure existing test pass full path to /sbin/fail.sh script.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-02-11 10:17:33 +01:00
Joachim Wiberg 5913217808 test: add finit.d/available and finit.d/enabled/ dirs
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-03-23 08:17:03 +01:00
Joachim Wiberg 77cf72cb40 test: regression test to reproduce issue #392
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-06 12:03:33 +01:00
Joachim Wiberg 50e587f447 test: new test, verify env:file variable expansion
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 13:31:36 +01:00
Joachim Wiberg e4163b7221 test: new test, issue #382
Alexander Zangerl reports that <service/foo/STATE> conditions seem to be
removed when calling `initctl reload`, even though no .conf changes have
been made.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-10-30 00:58:28 +01:00
Joachim Wiberg 6ae1083c99 Add support for SysV-only scripts in runparts
This patch extens the SysV compatibility support in Finit by adding
support for limiting `runparts` to run only SNNfoo, or KNNfoo, style
scripts from a directory.

Additionally, by default `runparts` now runs entirely in the background
without any progress.  To enable progress, an optional argument has been
added to the runparts command line.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-24 13:25:35 +02:00
Joachim Wiberg ea68413512 test: add missing scripts to dist for new runparts test
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-14 09:15:17 +02:00
Joachim Wiberg b41b4ce989 test: new, verify runparts order
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 14:04:26 +02:00
Joachim Wiberg 443700a88e test: new, verify that a run task can call initctl
Follow-up to #362

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 13:30:57 +02:00
Joachim Wiberg b39a4498a3 test: enable bootstrap-crash, regression test for #351
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-09-10 13:16:09 +02:00
Joachim Wiberg aeff68b598 test/rclocal.sh: new test
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-05-01 23:50:57 +02:00
Joachim Wiberg 13dddb6912 test: new regression test for issue #351
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-03-21 11:24:17 +01:00
Joachim Wiberg ab5a983bf7 test: only run checkself.sh on enabled tests
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-28 00:48:25 +01:00
Joachim Wiberg 4f7e726a3e test: initial regression test for #351 (WIP)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-11 16:48:21 +01:00
Joachim Wiberg 9c727ed08d test: namespace cleanup, common -> src, tenv -> lib, etc.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 19:04:48 +01:00
Joachim Wiberg 8b9258aa73 test: rename tenv-root -> sysroot
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 18:19:23 +01:00
Joachim Wiberg a67b2ba9a7 test: new regression test, //run/foo.pid -> /var/run///run/foo.pid
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 18:07:12 +01:00
Joachim Wiberg f0a888c0d1 test: update Makefile.am and build instructions, new testserv plugin
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-02-05 12:07:35 +01:00
Joachim Wiberg f98be8540f test/devmon.sh: new test
Issue #185

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-12-19 17:20:21 +01:00
Joachim Wiberg 2a7abf1db0 test: enable new depserv test
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-15 00:56:03 +01:00
Joachim Wiberg 726f7ba229 test: new regression test for bug #313
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-11 15:53:48 +01:00
Joachim Wiberg fb86042cb3 test: add crashing.sh, verify oncrash:script support
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-11-06 13:07:10 +01:00
Joachim Wiberg c9f1bff419 Refactor ready:script to support new notify framework
Follow-up to abcb3ce, calling the service ready:script when readiness
has been signaled to or detected by Finit.

Issue #300

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-16 22:11:12 +02:00
Joachim Wiberg ff08038bdc test: add notify.sh to distribution
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-16 20:13:04 +02:00
Joachim Wiberg 47d837bf6a test: new test, notify.sh, systemd and s6 readiness notification
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-10-16 20:06:26 +02:00
Joachim Wiberg 29dea38f50 test: fix path to setup-root.sh in distcheck mode
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-09-25 05:53:57 +02:00
Joachim Wiberg 165d0633f6 test: add support for make -j17 check massive parallel testing
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>
2022-09-25 04:38:24 +02:00