When a service without SIGHUP reload support (noreload) is touched and
'initctl reload' is called, service_update_rdeps() correctly identifies
its reverse dependencies but only marks them dirty. It does not clear
the service's condition, so when service_step_all() runs:
- rdeps supporting SIGHUP hit the sm_in_reload() guard and break early,
left running while their dependency is being killed.
- rdeps without SIGHUP support may receive SIGTERM too late, after the
dependency has already died and broken their connection, causing them
to exit from RUNNING state and have their restart counter incremented.
Fix by calling cond_clear() on the service's condition immediately in
service_update_rdeps(), before service_step_all() runs. cond_clear()
calls cond_update() which calls service_step() inline on all affected
services, which see COND_OFF and transition to STOPPING_STATE — all
before SIGTERM is ever sent to the dependency itself.
This mirrors the pattern already used in api.c:do_reload() for direct
'initctl reload <svc>' calls.
Fixes: avahi/mdns stop causing mdns-alias restart counter increment
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Add support for the --exclude-prefix=PATH option to skip rules whose
path starts with the specified prefix. The option can be specified
multiple times to exclude multiple path prefixes.
The -E flag is a shortcut for:
--exclude-prefix=/dev --exclude-prefix=/proc \
--exclude-prefix=/run --exclude-prefix=/sys
This is useful to avoid creating files below virtual or memory-backed
file system mount points.
devmon: assert condition immediately if device already exists
1. udev fires early, creates device nodes in /dev/
2. Config is parsed later, calling devmon_add_cond() for each dev/ condition
3. At this point the device already exists but the inotify event was missed
4. The PR's fexist() check catches this — new node is added to the TAILQ and condition is immediately asserted
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The config parsing happens after udev triggers the initial event,
make sure to assert the condition if the device node exists when adding
it from configuration.
Signed-off-by: Mattias Walström <lazzer@gmail.com>
A service that is reloaded should not trigger dependants to be reloaded
unless the new <~cond> is used. Which is reserve for tightly coupled
services.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
For SysV services with pid:!/path, the pidfile belongs to the service
itself and Finit shouldn't delete it.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This fixes a real bug where `initctl reload syslogd` unconditionally
clears syslogd's pid condition, causing all dependent services (dbus,
dnsmasq, etc.) to be stopped even though syslogd handles SIGHUP
gracefully and its PID/pidfile persist.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A reload: script, like 'frrinit.sh reload' could potentially take a
while to finish, during which Finit would be blocked. This change
reuses the service_script_add(), used for ready: scripts, to track
these background helpers.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When the kernel manages to reap a child process before we've moved it to
its proper cgroup it will return ESRCH (No such process), we can safely
ignore such errors for short-lived processes.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Conditions in Finit are dependencies: if A is asserted, service B is
allowed to run. When A goes through FLUX (e.g., upstream reloads),
dependents are PAUSED and then simply resumed when the condition is
reasserted -- this is the correct behavior for barrier-style deps
like <pid/syslogd>.
However, some setups have tightly coupled services where dependents
must be reloaded/restarted when an upstream service reloads, not just
resumed. E.g., the FRR routing stack on Infix OS:
netd <pid/mgmtd> ← zebra <!pid/netd> ← {staticd,ripd} <!pid/zebra>
When netd reloads (SIGHUP), zebra and its dependents must be restarted
to pick up the new configuration.
The new '~' condition prefix marks a dependency as flux-sensitive:
service <!~pid/netd> name:zebra ...
When the upstream condition goes FLUX and returns to ON, the dependent
is reloaded (SIGHUP) or restarted (noreload '!') instead of merely
resumed. Transitivity follows naturally through the condition chain.
Closes#416Closes#476
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When 'initctl reload' is called after marking a service in a dependency
chain dirty, Finit fails to restart (unfreeze) affected services.
This patch updates the pidfile plugin to watch for IN_ATTRIB changes,
e.g. when a process uses utimensat() to update its pidfile, and adds
service_step_all() at end of reload cycle to guarantee convergence
after conditions are reasserted.
Issue #476
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In a setup like this, when 'netd' is marked dirty and subsequently is
reloaded, e.g., using 'initctl reload', zebra is properly restarted,
but staticd isn't:
mgmtd <!> ← netd <pid/mgmtd> ← zebra <!pid/netd> ← staticd <!pid/zebra>
Finit must invalidate the condition of zebra to trigger a restart also
of staticd. This to guard against daemons like zebra that may fail to
clean up their pidfiles.
Fixes#475
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Device conditions tracked by devmon were lost on `initctl reload`
because the reconf path did not re-assert them. Add devmon_reconf()
to iterate all tracked device nodes and set or clear their conditions
based on current device presence.
Signed-off-by: Mattias Walström <lazzer@gmail.com>
Verify that 'initctl reload foo' properly triggers dependent
services by checking that bar gets a new PID after the reload.
Also change the second test case from service/foo/running to
service/foo/ready which is the actual condition set by pidfile.so.
Fix a race in slay where the target process could exit between
the PID lookup and kill -9, causing spurious test failures in
tight kill loops (e.g., start-kill-service.sh).
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When reloading a specific service with 'initctl reload foo', the
pid/foo and service/foo/ready conditions were never cleared, so
dependent services were not notified of the reload.
Clear the service's pid condition and, for pid/none notify types,
the ready condition before reloading. The conditions are then
reasserted by the pidfile inotify handler when the service touches
its PID file after processing SIGHUP.
For s6/systemd services the ready condition is left intact since
their readiness notification may not re-trigger on SIGHUP.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Users starting Finit based systems using U-Boot or Barebox may otherwise
not get a visible cursor at their prompt.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Similar to systemd's RemainAfterExit=yes. Prevents the task from
re-running on runlevel re-entry and ensures the post: script runs
when explicitly stopped or when leaving valid runlevels.
Useful for tasks that set up persistent state like firewall rules:
task [2345] remain:yes \
post:/usr/sbin/teardown-firewall \
/usr/sbin/setup-firewall -- Firewall setup
Not supported for bootstrap-only tasks (runlevel S only) since these
are deleted immediately after completion.
Define __NR_clone3 (435) ourselves when not provided by the toolchain
headers. The syscall number is stable kernel ABI and the same on all
architectures since Linux 5.3.
The existing runtime fallback to fork() handles older kernels that don't
support the syscall.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In containerized or virtualized environments, standard mount point
directories may not exist at boot. Ensure they are created before
attempting to mount.
When f or F types write content to a file, the mode and ownership
specified in the config should be applied. Previously, ownership was
only applied when create() was used (i.e., when no argument was
specified).
Now we explicitly apply mode and ownership after writing content to
the file.
According to tmpfiles.d(5), the 'e' type adjusts the mode and ownership
of existing paths but should not create them. Previously, mksubsys()
was used which could create directories.
Now we explicitly check if the path is an existing directory before
adjusting its permissions.
Add parse_uid() and parse_gid() helper functions that support both
numeric IDs and name lookups. Update the d/D directory creation
handlers to use these new functions.
This allows config files to specify ownership using numeric UIDs and
GIDs instead of only usernames and group names, matching systemd-tmpfiles
behavior.
The L+ type should replace existing entries with a symlink. Previously,
rmrf() was always called which is only appropriate for directories.
Now we check if the path is a directory first, and use erase() for
files and symlinks.
Allow specifying one or more configuration files as command line
arguments instead of always processing all files in the standard
tmpfiles.d directories.
This enables targeted operations on specific config files:
tmpfiles --create /etc/tmpfiles.d/myapp.conf
tmpfiles --clean /tmp/test.conf /tmp/other.conf
When no config files are specified, the existing behavior of
processing all *.conf files in the standard directories is preserved.
Also refactors file processing into a helper function to reduce
code duplication.
Add support for the --clean (-C) flag to remove files and directories
older than the age specified in tmpfiles.d configuration entries.
The age field (6th column) in tmpfiles.d entries can now be used with
'd', 'D', and 'e' type entries to clean up old files. Supported time
suffixes are: s (seconds), m (minutes), h (hours), d (days), w (weeks).
Example configuration:
d /tmp/cache 0755 root root 10d
When run with --clean, files in /tmp/cache older than 10 days will be
removed. The directory itself is preserved.
Uses a conservative cleanup approach matching systemd-tmpfiles:
- Files: kept if ANY of atime, ctime, mtime is recent
- Directories: kept if ANY of atime, mtime is recent (ctime excluded
because cleanup itself updates directory ctime)
A value of "-" or "0" for age disables cleanup for that entry.
Note: x/X exclusion patterns are recognized but not yet implemented.
Strings like command, description, and environment may contain characters
that need escaping for valid JSON, e.g., embedded quotes in command line
arguments like -V "NanoPi R2S".
Add json_escape() helper to handle quotes, backslashes, and control chars.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The netlink plugin only receives RTM_NEWLINK events for interfaces that
appear after the plugin starts. Interfaces that already exist at boot
(e.g., virtio-net in QEMU) never generate events, so their conditions
like net/eth0/exist were never set.
Moving enumeration to PLUGIN_INIT doesn't work because it runs before
cond_init(), so the condition filesystem isn't ready yet.
Fix by registering an HOOK_SVC_PLUGIN callback that queries existing
interfaces and routes. This hook runs during conf_init(), after the
condition system is initialized.
When a TTY exited with non-zero code (e.g., user with shell=/sbin/false),
it would enter restart state but never recover, requiring manual restart.
The throttling logic from commit f0032ab had two issues:
1. Duplicate exit code check in service_retry() created infinite timer loop
2. TTYs lacked default restart_tmo, causing timer to never start
Fix by removing duplicate check and ensuring TTYs get a 2-second default
restart_tmo for proper throttling.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When a service is configured to run as a non-root user (@user), finit
correctly drops privileges via setuid() and sets HOME and PATH, but
does not set the USER and LOGNAME environment variables. They remain
set to "root" from boot time.
This causes problems for software that determines its identity from
the environment rather than getuid(). For example, rootless Podman
checks os.Getenv("USER") first when looking up subordinate UID/GID
ranges in /etc/subuid and /etc/subgid.
With USER=root but UID=1000, Podman looks up root's subuid entry
instead of the actual user's, causing applications like newuidmap
to fail. Setting USER and LOGNAME to match the actual user identity
follows POSIX conventions and matches the behavior of su, sudo, and
login.
The do_ prefix is conventionally reserved for local helper functions.
Move switch_root() declaration to private.h alongside iterate_proc()
and remove the now-empty initramfs.h header.
in an initramfs, then transition to the real root filesystem. Useful
for systems requiring early boot tasks like LUKS unlock, LVM activation,
or network boot before mounting the real root.
Adds INIT_CMD_SWITCH_ROOT API command, `initctl switch-root` subcommand,
and HOOK_SWITCH_ROOT plugin hook point. The implementation gracefully
stops services, moves virtual filesystems (/dev, /proc, /sys, /run) to
the new root, deletes initramfs contents to free memory, then execs the
new init as PID 1.
See GitHub Discussion #292 for background.
Add handling for EBUSY when mounting cgroup2 filesystem, which occurs
when cgroups are already mounted. This can happen after switch_root
when cgroups were moved from the initramfs, or in container environments.
Verify the existing mount is actually cgroup2 before proceeding, and
track whether we mounted to avoid unmounting on error if we didn't.
At least the sysvpart.sh regression test cannot run in parallel yet with
other tests (probably runparts.sh), so we must ensure the tests never
run in parallel, in particular at release.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
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>
Finit has support for "Please press Enter to activate this console."
which means there's no getty yet running. However, when profiling
systems with Finit, and embedded systems in general, a common metric
is the time from power-on to getty has started.
This commit makes sure to rename the process so that BusyBox pidof is
capable of detecting that "getty" has started. This is mostly for the
bootchart2 project's bootchartd, the native BusyBox bootchartd does not
have this issue.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This is a refactor of getuser() and getgroup() so that they always
return a valid user, and group, for all normal use-cases. When an
error occurs we now handle it properly in service_fork() so as to
not attempt to start services with an invalid user/group setting
as root.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When running Finit under boothcartd (bootchart2 project) the PATH is
lost due to a bug. This was a wakeup, so set critical variables in
main() early, before calling fs_init().
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Try out navigation.tabs, if we don't like it we can revert.
Reorg for stricter sections, what information actually belongs where?
E.g., introduction is now in a Getting Started section.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Some 'respawn' type services, like gettys, may hog the CPU in error
states if the service immediately exits. E.g., due to missing dev.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
During /bin/login phase the TTY device node is chowned and chmodded to
the authenticated user. It will remain in this state until the next
call to getty.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A user reports inability to re-start getty on the console after logging
out from a serial console. After some digging it was found that the tty
was owned by the last user logged in and 600. Even thougn getty runs as
root, it did not have permission to re-open the device node.
Turns out there was a minor bug in the new capability code that cleared
all capabilities from the root user. A surprising amount of programs
worked just fine, but restarting getty gave it away.
The fix is to only call cap_setuid() when capabilities are set for the
service, otherwise we just fall back to setuid().
Also, refactor service_register() wrt. capabilities a bit so that we can
give users an early warning if the configuration is invalid, by adding a
parse_caps() helper function that calls cap_iab_from_text() to verify.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Implement supplementary group support for services, allowing them to
access resources owned by multiple groups. Uses the @user:group,sup1,sup2
syntax to explicitly specify supplementary groups, in addition to now
reading group membership from /etc/group.
Cgroups v2 limits are hierarchical - a process is constrained by the
most restrictive limit in its ancestor chain, not just its immediate
cgroup. This patch updates cg_conf() to walk up the hierarchy and
report effective limits by comparing values at each level.
This fixes incorrect "max" (unlimited) reporting in 'initctl --json
status', 'initctl cgroup', and 'initctl top' when child cgroups have
no explicit limits but parents do.
For memory.max and cpu.max: take minimum (most restrictive)
For memory.min: take maximum (most protection)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Comment-out code that makes the cursor "jump" around at boot before
displaying: Please press Enter to activate this console.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
libite v2.6.2 is not yet in Buildroot, so let's relax the dependency a
bit. Load bearing functionality was in v2.6.0, any fixes on top is a
nice-to-have only.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
We now require readsnf() introduced in libite 2.6.0, with bug fixes
this effectively means v2.6.2.
The libuev bump is for 64-bit time_t, with bug fix => v2.4.1
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Fixes an issue where the mouse scroll wheel and Shift+PgUp/PgDn
sometimes would not work properly after login.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Drop clear screen to fix flickering in 'initctl top' output. Also, make
sure to not garble the display if the the terminal is too small.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Instead of /system/10-hotplug/ we now place udevd, mdevd, and others, in
more aptly named groups using the new 'name:' syntax.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This should not be needed, but for some reason we don't get events when
early processes exit, so we end up with lingering cgroups.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The container monitor that podman forks off when starting a container
instance creates subgroups in the cgroup v2 hieararchy that we want to
reuse. This patch adds cgroup_move_svc() which we call from the pidfile
plugins to relocate the conmon process.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit activates the use of clone3() for service_fork(), to allow
Linux to create the new process directly in the correct cgroup instead
of later moving it there -- much cheaper and less error prone.
To facilitate this a few new helper cgroup functions have been added and
two new configuration directives introduced: delegate and name:leafname.
The delegate option is for running, e.g., container runtimes that want
to create their own cgroup v2 structur, and the name:leafname allows a
user to change the name of the subgroup under user/system/init.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The PTY approach caused isatty() to return true for services using
the log directive, triggering programs like fprintd (using glib) to
emit ANSI escape codes and other TTY-specific formatting in syslog.
Using a standard pipe ensures isatty() correctly returns false, so
programs produce plain text output suitable for logging.
For services that require line-buffered output, users can wrap the
command with `stdbuf -oL` as documented in doc/config/logging.md.
Fixes#455
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When setting up a new system with Finit it is very common to make small
logical mistakes that cause "hangs" at boot. This is when Finit waits
for 180 sec. for run/tasks to complete before moving to the configured
runlevel. This patch adds console input monitoring during bootstrap
wait that allows users to press Ctrl-C to skip waiting and proceed to
the configured runlevel.
When Ctrl-C is detected, all incomplete run/task/services are logged
to syslog for later troubleshooting after login.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Relax the constraints introduced in a39ee0b, for issue #342, a bit on
when start/stop/restart/reload service can be called. Also, allow
'initctl reload', but ignore it when the system is in runlevels S/0/6.
This makes it possible to start manual:yes type services at botostrap,
for example, which has been a common feature request.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Add missing memory information to JSON output in json_status_one().
The memory field shows cgroup memory usage in bytes when cgroup
support is available and the service has a valid PID, matching
the behavior of the text status output.
Signed-off-by: Richard Alpe <richard@bit42.se>
Implement Linux capability support for services, allowing them to run
with minimal required privileges instead of running as root. This uses
the modern IAB (Inheritable, Ambient, Bounding) API from libcap.
There are some invalid condition checks in rtc.c, when rtc_file is
missing, it should not consider that as a error and return, otherwise,
it can lead to the case that time_set wont be called at all.
With this fix, when both RTC and file restore fail, it will fall back
to call time_set(NULL) and restore time from rtc_timestamp, this
ensures the OS has a valid time at the very first boot.
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
Allow service IDs up to 64 characters to support SHA-256 hashes,
UUIDs, and other long unique identifiers. This increases memory
usage by ~98 bytes per service instance, which is negligible for
typical deployments.
The IDENT column width in initctl output adapts dynamically based
on actual ID lengths in use, so short IDs remain unaffected.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Both service and sysv stanzas support a cleanup:script (since v4.10), with an
optional timeout. These timers must be stopped when collecting a PID for an
svc_t, or when unregistering an svc_t, otherwise the timer callback will be
continuously called, reporting "spurious problem", and cause 100% CPU usage.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Many packages fail to detect that this replacement libsystemd does not
support the logging API (yet), so let's disable it by default.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch fixes an ordering issue where the configuration generation is
stepped before all old/disabled services had been stopped. Finit should
ensure disabled services are stopped before entering the next generation.
If the genation is stepped first, all conditions are put in "flux" state,
so, e.g, a podman container running as a sysv service may lock-up until
it is killed by Finit. Found in the Infix OS project.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A following compilation error was observed:
| libsystemd/sd-daemon.c:64: undefined reference to `strlcpy'
fix it by include the required libite dependency.
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
Also, added benefit, we don't get compiler warnings for ignoring the
return value of system(), which we don't care about in this case.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Allow scripts to take space separated arguments with quoting
- Simplify script-exists check, which already checks for leading /
- Unset current script on parse error
- Allow setting no timeout
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
These variables really belong in conf.c. Relocate and move external
decls. from finit.h -> conf.h to simplify linking of other programs.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
With the relocation of several functions, including inline functions,
from helpers to util, we no longer need to include log.h. Which is a
good thing, since any subsystem that needs logging should explicitly
include log.h
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The file helpers.c should strictly only be used for misc. helper
functions to the main Finit daemon. The functions moved in this
commit are generic enough to be used by any deamon or programs,
and for that we have util.c
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Prevent name clash with upcoming refactor and any confusion with
src/plugin.c functions with the same name.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This refactor should have been done years ago when we first introduced
the big state machine. The old functions service_runvel() and the oddly
named service_reload_dynamic() are actually state machine control fns,
so let relocate them.
Also in this commit, remove the global variable 'sm' and rename a few of
the critical functions to better names.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Historically we've kept these two apart, but their commonalities are far
more than what separates them.
This fixes a bug where ready:scripts were not called for sysv daemons,
and also opens up for adding support for a reload:script for both types.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit also switches the stdout/stderr log capture backend for all
notify:systemd services from the sysklogd project's logger tool to the
bundled logit tool.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
clang-tidy complained that parse_prio() always returned OK(0), turns out
it was right. This patch adds validation of the parsing.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit introduces a bare-bones replacement for libsystemd:
- Build .so file and add --with-libsystemd to configure
- Add capabilities support to test/src/serv.c
- Update tests to account for a Finit built w/o libsystemd support
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A systemd service should only use NOTIFY_SOCKET and an s6 style
service reads its notify descript from the command line. For
details, see notify.sh
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit introduces a stripped down sd_notify(), taken from the
systemd man page example, which is used by the serv daemon in lieu
of the previous broken implementation.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch fixes issue #440 which details how systemd readiness
notification has been broken since its inception in Finit.
In addition to now providing a proper abstract socket, the refactor
also drops the reliance on the Finit client API to fetch a socket.
Now an s6 descriptor is the write end of a pipe() and the systemd
socket is instead created before forking off the service.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When building with global CFLAGS=-Wunused-parameter the output from the
build looks terrible. This commit explicitly declares unused variables
to prevent triggering -Wunused-parameter
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Fix the following warnings:
| cgroup.c:296:13: warning: implicit declaration of function 'conf_any_change' [-Wimplicit-function-declaration]
| cgroup.c:297:17: warning: implicit declaration of function 'service_reload_dynamic' [-Wimplicit-function-declaration]
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
Fix the following linking issues of tmpfiles:
| exec.c:308: warning: stty is not implemented and will always fail
| plugin.c:237: undefined reference to `run_parts'
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
The existing implementation seemed useful enough to warrant a new
helper function. Care was taken to ensure the revised code no longer
suffers any memory leaks.
The tmpfiles.d spec contains entry types that should be acted upon in different modes
of operation: create, clean, remove, and purge - split up create & remove logic to
clarify the modes of operation finit supports.
The tmpfiles.d spec has proven useful in systemd, enough so that some developers
are starting to ship tmpfiles.d configuration files with their software.
By splitting the tmpfiles functionality in finit out into a separate executable
we are providing a useful piece of software that package managers can hook into.
An svc_t (service/sysv) that is in setup, teardown, or cleanup state
must be ignored by the pidfile plugin for any events regarding PID
files. E.g., a setup script for a sysv service may create a PID file
to alert the system that a setup process for the service is running.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The service_fork() function blocks all signals for the new process, it
is up to the callee to call sig_unblock() before calling exec().
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
All run/tasks must complete before Finit moves to runlevel 2. This
critical piece of information has mysteriously been missing from the
documentation since the start.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Add explicit argument separator before username to ensure correct
parsing of the login command regardless of username format. This
follows best practices for command execution and prevents unexpected
behavior when processing special characters in usernames.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When a service is stopped, but does not respond to the default SIGTERM,
a fallback kicks in after 3 seconds (default) to send SIGKILL. Since
91a9c83 (v3.2-rc2) this has however not worked since the signal was
only sent to the process group.
It is the job of service_monitor(), when it reaps the process leader,
to forward the signal to the process group.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Don't try to source an optional env:file if it is missing. Otherwise
execution of pre/post/ready/cleanup script will fail.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Introduced to work-around systems with broken RTCs, it also introduced a
dormant bug in Finit, triggered at shutdown on some systems. The call
to dlclose() removed the memory to the rtc_timer which libuev later then
referenced.
Fixes#429
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Initiating a shutdown/reboot from `initctl` should not cause `initctl`
to be killed in do_shutdown().
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When a user sets up a TTY without a device, triggering the tty->notty
code path, the tty->dev will be NULL and tty_parse_args() still return
OK result.
Found by Coverity Scan
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Enhance fallback entropy generation by mixing in multiple sources:
runtime statistics, PID, and high-resolution timestamps.
This provides better initialization for the PRNG when neither saved
entropy nor hardware RNG are available during early boot.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When using Finit with an external getty that supports alternative login
program argument, the tty_parse_args() function did not check if a getty
command had already been registered:
tty [12345] /sbin/agetty -L -l /bin/login console noclear
This caused Finit to try /bin/login as the getty program.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change introduces two new states for the big Finit state machine:
runlevel-clean and reload-clean. Here Finit now waits for any post or
cleanup script to finish before returning OK to the initctl command.
Additionally, the service state machine has been updated to ensure a
run/task/sysv/service calls any post or cleanup script before they are
removed. A new 'dead' state for svc_t is introduced which any removed
svc_t ends up in now instead of becing collected from 'halted' state.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Add cleanup:script support, runs at service removal
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Some subsystems call iwatch_add() without first calling iwatch_del() on
the same path. E.g., cgroup_config().
Issue #417 but unclear atm. if this is the root cause.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A long running pre/post/ready script must be killed properly, not by
targeting its process group. Process group cleanup is handled by the
service_monitor() when reaping the script's PID.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
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>
Check exit status of `pre:` scripts, on failure drive service/sysv to
`crashed` state. The exit code of `post:` scripts remain ignored for
now.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Syntax:
[pre|post|ready]:[0-3600,]/path/to/script
Description:
Before this patch all pre/post/ready scripts used the global kill
delay as timeout. After this patch it is possible to disable the
timeout as well as set a timeout >60, which is max kill delay.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Follow-up to 465bc17, which addressed unintended restart of siblings.
This patch fixes a problem where template instantiated services are not
properly reloaded/restarted when marked as "dirty" with `initctl touch`.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
add support for 'nofail' fstab option. if present, finit's fsck invocation ignores errors for this device.
this is useful if you have an fstab entry for a device with UUID= or LABEL= which isn't always present and which you'd like to not
bail on (so you set nofail). in this case finit leaves the presence-or-not decision to fsck, which exits nonzero.
for block devices that are directly listed in fstab this change isn't important, because for such finit looks for the blockdev's existence and skips the fsck if n/a.
Consider the case where container@.conf is an available template. When
creating a container@foo.conf it will share the same base .conf as an
existing container@bar.conf, but we do not expect to restart bar just
because foo is instantiated.
Up until this change, all template siblings were considered "dirty" if a
new one was created or updated. Skipping realpath() for all files that
have a '@' works around the problem.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
These plugins signal success and failure directly to the console, the
user should inspect syslog for more information.
This change is a follow-up to 340cae4, where kernel logs of LOG_ERR and
higher are allowed to log directly to the console. Since syslogd has
not been started before these plugins, the log messages would otherwise
leak to the console.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In 42ef3d3c, for v4.4-rc1, support for setting a custom RTC restore date
was introduced. Unfortunately the configure script was wrong and caused
config.h to contain
#define RTC_TIMESTAMP_CUSTOM "$rtc_date"
instead of
#define RTC_TIMESTAMP_CUSTOM "2023-04-10 14:35:42"
Furthermore, the error handling for strptime() was wrong, so the restore
date was always reverted to the default.
This patch fixes both issues and extends the DATE of --with-rtc-date to
also include seconds.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch introduces a new configure option --with-rtc-file=FILE. When
enabled the RTC plugin detects missing RTC device and falls back to save
and restore system time from a file instead. When --with-rtc-file is
used without an argument the default file is /var/lib/misc/rtc, but the
feature itself is disabled by default.
The usefulness of this feature may not be obvious at first, but some
systems are equipped with an RTC that resets to a random date at power
on. This can be really bad in the case the date is far in the future,
because an NTP sync would then cause time skips backwards, which shows
up in logs and causes a whole lot of pain in alarm systems.
The solution is to disable the RTC driver or device tree node, and when
Finit starts up, the RTC plugin detects a the device node and instead
restores time from the last save game. Meaning time will always only
move forwards.
NOTE: when Finit is built --with-rtc-file we always save to disk, but
only restore from the "save game" if restoring from RTC fails.
If the system has no RTC we always restore from disk.
As an added bonus, this change also makes sure to periodically
sync also the RTC with the system clock. Useful for systems
that do not run an NTP client.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Some boot loaders, like GRUB, leave background color artifacts from
their boot menu. This patch resets the foreground and background
color attributes, and then clears the screen, without clearing the
scrollback buffer.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch changes a behavior that's been default since Finit 4.0,
introduced in 4d05bf9 with 4.0-rc2.
If service B depends on A and A needs to be reloaded, then B may be
affected. If A is declared as NOHUP <!>, then A will be stopped and
restarted, during which time the condition it provides is removed,
and B will also be stopped.
However, and as of this patch, if A is declared supporting HUP, then the
condition A provides will only go into flux, during which time B will be
SIGSTOPed instead of needing to be reloaded.
Fix#415
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When dealing with "L+" and "R", the function call 'nftw' should not
follow symbolic links, otherwise, it would also delete the targets
which is wrong.
For instance, if there is already a symbolic link:
```
/path/to/the/link -> /path/to/some/folder
```
if we set the following in a tmpfile conf:
```
L+ /path/to/the/link - - - - /path/to/the/target
```
the result would be /path/to/some/folder also get deleted, which it
should not.
it could be even worse, when the symbolic link already is pointing to:
/path/to/the/target, the whole /path/to/the/target would be deleted on
next system boot.
Signed-off-by: Mathias Thore <mathias.thore@atlascopco.com>
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
Adds the function fistmpfs to determine if a new tmpfs mount should be
performed on /run and /tmp. The function supports cases where more
complex mount hierarchies are in use, including overlayfs backed mounts.
Signed-off-by: Mathias Thore <mathias.thore@atlascopco.com>
A Linux system booted with the kernel command line option 'quiet' only
logs error (and above) severity messages to the console. For embedded
systems, which is the primary target for Finit, this is what you want
to see.
Hence, and after careful consideration, this patch changes the default
behavior of Finit to allow kernel logs to the console. A build-time
configure flags, --disable-kernel-logging, has been added to restore
legacy behavior.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Systems that have the following tty setup and multiple consoles listed
in /sys/class/tty/console/active misbehave:
tty [12345789] @console 0 xterm noclear passenv
Only the first listed console is started properly, the remaining ones
were registered using the wrong :ID and no arguments to getty.
This patch fixes the parsing and re-use of the base paramenters for
all consoles listed in the active file.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Currently no code checks the return code of ifupdown at runlevel
changes, but for future reference this code has been refactored
to match the changes made in cbdb949 to fix issue #400.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This problem affects all calls to run_interactive() that check the
return value of the command. Causing HOOK_MOUNT_ERROR to *not* run
on mount failure, and sulogin() to *not* be started on fsck error.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Silence log warnings for command x/X (ignore clean for path), because
Finit does not do tmpfiles cleaning at runtime.
x /tmp/podman-run-*
x /tmp/containers-user-*
x /tmp/run-*/libpod
D! /var/lib/containers/storage/tmp 0700 root root
D! /run/podman 0700 root root
D! /var/lib/cni/networks
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
After reports from the field, see issue #397, of lockups at reboot,
we've decided to drop this code from PID 1. It was added before the 4.x
series, when the current progress output was introduced. For the older
style progress it served a purpose since the placement of [OK]/[FAIL]
was on the right hand side.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When the system shuts down, or user changes runlevels, we don't have to
call cond_clear_update(), because this can lead to nested service_stop()
calls, which in turn lead to out of sync progress updates:
[ .. ] Stopping Foo
[ OK ] Stopping Bar
[ OK ]
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The /etc/issue file on Alpine Linux says "Kernel \r on an \m (\l)", so
\r needs to return the uts release rather than os-release VERSION.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The responsibility of the kernel event daemon is to relay kernel events
to Finit. At shutdown and reboot it is too late for more events and the
daemon should just shut down with other services.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Fix copy-paste of error message from cond-w.c
A read-only root filesystem may have /var/lock, while we want to remove
it and add a symlink to ../run/lock. Ignore errors from this since we
cannot do anything about it. It is up to the user to fix their skeleton
or use an overlay.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Inspired by Alpine Linux, add /dev/mqueue if missing. We should check
the /proc/filesystems first, but this is quicker.
The sticky bit ensures only the owner of files in /dev/shm can delete or
rename files. This is also what Alpine Linux use.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A service with notify:pid is 'ready' when the pidfile has been created,
the converse also holds true -- when a pidfile is removed the service is
no longer 'ready'.
The state transition for the service has probably already been done, in
svc_set_state(), clearing all <service/foo/*> conditions when the PID
was collected. The pidfile event may arrive later, so for completeness
we make sure the 'ready' condition is not recreated at least.
Problem introduced in 912a281 with the original supoport for service
readiness notification.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
There exist two possible basename functions, a xpg compliant one in libgen.h
and a GLIBC exclusive one declared in string.h, that was previously also declared by musl libc.
Both implementations are expecting different parameter types (`const char *` for GLIBC and `char *` for xpg)
With the removal of the basename function from string.h in musl libc, we could only rely on the xpg implementation.
Unfortunately, the xpg implementation of basename does modify the contents of whatever you put in it,
even though that there really is no need for it.
This is an issue in some cases, where we might want to get the basename of a read-only variable, e.g. a `const char *`,
as trying to modify something read-only is undefined behavior.
So in order to keep things consistent for us, we implement our own version of basename called `basenm`,
that does not modify the passed argument.
As of Finit v4.6 we no longer assert the PID condition for services
declaring themselves as notify != pid. We replace D with a forking
service to catch any future regressions in the pidfile plugin.
No need to check reload PID of D, it is enough to check PID of C.
Also, reduce the number of retries at startup. If we haven't gone
up within 10 sec with this tiny config something is really wrong.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Premise, a service declaring itself 'notify:none' should never assert a
pid condition. However, forking services still need to be supported and
the only way to do that is if they create a pid file. Hence, instead of
skipping pidfile_update_conds() completely we need to filter the type.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2023-11-13T04:02:23 [WRN]: conf_change_act():failed registering /etc/finit.conf/ event mask 00000004: Not a directory
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This fixes an issue when finding a global environment variable with
spaces in the variable name:
set COLORTERM=yes
Literally, 'set COLORTERM' was the name of the variable.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change expands the readiness notification system in Finit with the
native 'pid' style, which will remain the default readiness in Finit 4.x
For systems that want to transition to Finit 5.x early, a global option
to set 'readiness none' in /etc/finit.conf, has been added. This change
the service default notification mode to 'notify:none', which can also
be set by Finit 4.x ('readiness pid') for select services.
Fixes#386.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This fixes an annying buglet that creeped in just before the v4.5 release
causing none of the internal services to be registered properly:
conf_save_service():Failed creating ${localstatedir}/run/finit/system/dbus.conf: No such file or directory
plugin_run_hook():Calling modules-load hook n:o 5 (arg: 0x55c4c8133621) ...
load():Scanning /etc/modules-load.d for config files ...
cond_set_oneshot():hook/svc/plugin
cond_set_oneshot_noupdate():hook/svc/plugin => /run/finit/cond/hook/svc/plugin
cond_update():hook/svc/plugin
parse_conf():*** Parsing /etc/finit.conf
conf_save_service():Failed creating ${localstatedir}/run/finit/system/runparts.conf: No such file or directory
The fix, like most, is simple when you find it. We must expand $runstatedir
before creating the #define in config.h
For convenience, here's the patch for the generated configure script:
&<---------------------------[cut here]---------------------------
--- a/configure 2023-11-05 23:39:51.907334321 +0100
+++ b/configure 2023-11-05 23:39:58.339299795 +0100
@@ -15352,7 +15352,15 @@
printf "%s\n" "#define FINIT_EXECPATH_ \"$pkglibexecdir\"" >>confdefs.h
-printf "%s\n" "#define FINIT_RUNPATH_ \"$runstatedir/finit/system\"" >>confdefs.h
+ finit_runpath="$runstatedir/finit/system"
+ finit_runpath=`(
+ test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+ test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
+ eval echo \""$finit_runpath"\"
+ )`
+
+
+printf "%s\n" "#define FINIT_RUNPATH_ \"$finit_runpath\"" >>confdefs.h
&<---------------------------[cut here]---------------------------
Ensure you include the three empty lines for context at the end!
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
We cannot rely on the auto-detection of Bash completion dir during 'make
distcheck' because autotools does not use DESTDIR, only --prefix for the
install check, and pkg-config returns a system path.
Also, show detected path in configure summary for debug.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In Finit v4.5 we've moved the start of rc.local and runparts to the
transtion from bootstrap to multi-user, so we must give it time to
finish.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In Finit v4.5 we've moved the start of rc.local and runparts to the
transtion from bootstrap to multi-user, so we must give it time to
finish.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This odd little feature makes it possible to declare run/tasks with a
condition that does not block Finit transitioning from bootstrap to the
next runlevel.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Regression in v4.5 release cycle, no changelog notice needed.
Reported as part of issue #378 by Alexander Zangerl.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change allows us to support constructs like this:
RUNDIR=/var/run/somesvc
DAEMON_ARGS=--workdir $RUNDIR --other-args...
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Introduced back in v4.3-rc2, 82cc10be8, the support for automatic
service conditions have had a weird and unintended behavior. Any
change in state (see doc/svc-machine.png) caused Finit to clear
out *all* previously acquired service conditions.
However, when moving between RUNNING and PAUSED states, a service
should not have its conditions cleared. The PAUSED state, seen
also by all conditions moving to FLUX, is only temporary while an
`initctl reload` is processed. If a service has no changes to be
applied it will move back to RUNNING.
Also, we cannot clear the service conditions because other run/task
or services may depend on it and clearing them would cause Finit to
SIGTERM these processes (since they are no longer eligible to run).
This patch not only adds this pre-condition to `cond_clearn()`, it
also clarifies which state (before or after) the particular code
is interested in.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Renamed .conf file for udev/mdev etc. caused 'mdev -df' to start in
tests. This fix closes that again since none of that is needed in
our small namespaced world.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
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>
The delayed matcehd works when all run/task/services provide their own
unique identity, but for replacements this is sometimes not the case.
Example from system/10-hotplug.conf.in:
run nowarn conflict:udevd,mdev cgroup.init name:coldplug <service/mdevd/ready> \
[S] mdevd-coldplug -- Cold plugging system
vs
run nowarn conflict:udevd,mdevd cgroup.init name:coldplug if:!mdevd <service/mdev/running> \
[S] @pkglibexecdir@/coldplug -- Cold plugging system
Here they both provide the <run/coldplug/*> conditions, and if the first
is loaded, because we found mdevd, then we should not attempt to load
this one.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The updated 10-hotplug.conf now ensures modules are loaded, so we no
longer need the modprobe.so plugin to be enabled by default.
Also, update the hotplug "plugin" description, it is kept entirely
for backwards compatibility reasons after the plugin was converted
to 10-hotplug.conf.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit replaces the `mdev -s` call to populate the device tree with
the "new" `mdev -df` daemon mode, introduced in BusyBox 1.31.0, 2019.
In daemon mode mdev listens to kernel uevents, replacing the hotplug use
of mdev. After creating the netlink socket, 'mdev -df' performs the same
initial scan as 'mdev -s' did.
To perform device (re)discovery, module loading and setup, including any
firmware loading, a coldplug operation is typically required. This is
done by the new /libexec/finit/coldplug script, by Alexander Zangerl.
Unlike 'mdevadm settle', mdev does not offer any mechanism to detect when
the discovery operation is done: on slower systems the triggering side,
the coldplug script, often completes quite a bit earlier than mdev's
uevent processing. I.e., depending on <run/coldplug/success> is not an
indicator of all devices having been (re)discovered and fully set up.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
On some systems udev may very well take more than five seconds to complete.
Probing modules, loading firmware, etc. Note, the timeout only sets the
maximum wait time.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The directory may hold various custom generated conditions that are not
managed by Finit. Not being able to remove the directory is not a
critical error.
finit[1]: cond_delpath():Failed removing condition path /var/run/finit/cond/: Directory not empty
Therefore, ignore ENOENT and ENOTEMPTY and log everything/anything else.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This fixes the regression in the tests, which runs in a very stripped
down world without tmpfiles.d etc.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This adds a new function conf_save_service() replacing service_register() for
plugins and bundled services like watchdogd, keventd, runparts, etc.
The benefits to this change are several:
- Plugin/Bundled services no longer risk starting before udev or other
critical services/task have started
- Definitions can be overridden by an administrator (see docs)
- Increases visibility (user: where are all these services coming from?)
Previously the origin (file the service was loaded from) was NULL.
- Adds another level of extensibility to Finit
The most notable change is that dbus is no longer started before udevd.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The system/10-hotplug.conf needs to index its calls to udevadm for all
calls to udevadm, not just the trigger calls. Otherwise the first
udevadm is overloaded with all subseequent (unindexed) udevamd stanzas.
Also, make sure all udevadm calls to settle/reload are hidden.
Fix#372
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The if: statement, introduced in v4.4, allows for discarding run/task/services
that depend on other services, based on that service's name, or condition.
Discarding in this context means unloading from the configuration.
At runtime, however, it has proven quite useful to be able to conditionally
qualify a run/task/service based on a condition. Consider this example from
the Infix operating system:
run name:startup log:prio:user.notice \
[S] <pid/sysrepo> confd -b --load startup-config -- Loading startup-config
run name:failure log:prio:user.critical if:<usr/fail-startup> \
[S] <pid/sysrepo> confd --load failure-config -- Loading failure-config
The two run statements reside in the same .conf file so Finit runs them in true
sequence. If loading the file `startup-config` fails confd sets the condition
usr/fail-startup, thus allowing the next run statement to load `failure-config`.
Notice the difference between <pid/sysrepo> condition and if:<usr/fail-startup>.
The former is a condition for starting and the latter is a condition to check if
a run/task/service is qualified to even be considerered. The best comparison is
with the [runlevel] option, it too is used to qualify.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change opens up the runlevel change API from bootstrap. The twist
is that the change is only queued, i.e., the call `initctl runlevel 9`
during bootstrap only changes the configured runlevel to go to after
bootstrap has completed.
Effectively, this change allows overriding the `runlevel` directive in
/etc/finit.conf without having to change the file.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
No more changes are expected after -rc3. Will be used for testing in
Infix and br2-ext-finit before the final v4.5 GA.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
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>
As pointed out in #366, the configure options --enable-fastboot and
--enable-fsckfix should just alter the default values of the two fsck
command line options.
This commit simplifies the code and makes it possible to override using
the command line regardless of the two build options.
Finally, add the two command line options to doc/cmdline.md
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
We use LOG_CONS to ensure log messages reach the operator, but since
watchdogd starts very early this means non-critical messages like the
initial greeting leaks to console because syslogd has not yet started.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
With non-standard paths, e.g., when running `make distcheck`, the
absolute path to some commands become ridiculously long. However,
this has been a recurring issue for some users in the past, so it
is time to increase the capabilibieies of Finit to cover this.
Yes, a better way is probably to allocate all these strings when they
are used, but that would require a redesign of the initctl API and
likely cause a lot of regressions before everything has stabilized.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The rescue mode that can be invoked from the kernel command line is
potentially unsafe. Many systems lock the root user account, or use
another account for managing, e.g. 'admin'. The sulogin program(s)
would on such systems give the user a root prompt.
In #357 we added support for setting a custom sulogin user, but for some
systems that is not enough. On many embedded systems the /etc/passwd
and shadow files are populated at bootstrap and at the time rescue mode
runs, these files will be unpopulated.
The only, truly safe, approach on such systems is to disable rescue mode
completely. Otherwise intricate Finit plugins have to be used that run
before rescue mode is started -- increasing the complexity of the system
as a whole.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In issue #357 there's a proposal for optionally allowing /bin/login, but
after intense discussions we've agreed that would be opening up for all
sorts of potential (security) issues.
it's better to keep things as-is but with the added twist of supporting
a custom user at configure time, e.g., 'admin'.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Non-trivial systems, like Infix[1], require more than one lap around the
track to warm up. This is a follow-up to issue #362, commit 4701ede, in
fixing an obvious oversight in the new sm_check_bootstrap() work. While
there are still outstanding bootstrap tasks or services that have not
yet started, we must reschedule the worker.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Drop complete() logic, waiting for run tasks to finish, from the
service_start() funciton to the general service_monitor(). This
refactor frees up the main loop and allows us to answer any API
calls from initctl even from the run task itself.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
For some specialized forms of runparts, e.g., start-stop scripts in SysV
init replacements, there is a need to append an argument. Typically
this is 'start' or 'stop'.
This functionality has been broken for quite some time, meaning we
should consider it being unused by current users of Finit.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Bootstrap-only tests that just verify basic functionality are often very
short. This change handles that by retrying SIGUSR2 until Finit has had
the chance to finalize bootstrap and enable signals.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The code refactored in this commit has long been an eyesore. The
hand-over, from the sequential main() function, to the event loop
was clumsy at best and was very difficult to debug.
Instead of using a series of workers we now delegate everything to
the big state machine by introducing a new SM_BOOTSRTAP_WAIT_STATE.
Both the runparts and rc.local scripts now run in the background, no
longer blocking the event loop from responding to initctl calls. To
ensure they run at the same point in time two things have been done:
1. A new <int/bootstrap> condition has been added which triggers
runparts, which now is a regular task created by conf_init()
2. /etc/rc.local is started from SM_RUNLEVEL_WAIT_STATE when we
transition from runlevel S to any other runlevel.
Fixes#356
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This should clarify the messup on the behalf of the mainatiner in not
documenting this properly, including the deviations introduced in v4.4
See issue #359 for a background.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- iwatch events return filenames in dir field, ignore file for those
- improve warning message on failure
- drop bogus "Out of memory" error log message
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The execvp() call always fails with -1, so only logging exit code when
collecting the PID is not enough. When debugging the user needs to see
the errno from execvp(), e.g., "No such file or directory", when the
command was missing the absolute path to the executable.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Related to 6f0d448 in that we check if the kernel knows about this
process before we try to stop it. If it's already dead we clean up
and return.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This turns out to be the root-cause of #227. Finit is waiting forever
for proceeses to stop at shutdown/reboot, while a subreaper has already
collected the PID, or Finit for some reason did not collect the PID.
When the process timeout calls service_kill() we now check if the kernel
actually knows of this process or not. If it's already been collected,
we can notify Finit of this by calling service_monitor() to clean up the
'svc' and in turn call sm_step() to finalize the state transition.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When calling `initctl -b create` from a start script at bootstrap you
risk blocking the boot since Finit currently cannot reply to IPC during
that period.
This patch allows -f to override this builtin check for the following
initctl commands:
- touch
- show
- edit
- create
- delete
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
These changes add a new svc_block_t type: SVC_BLOCK_CONFLICT so a user
can more clearly see why a run/task/service has not been started by
Finit. The reason for the block is by default logged, which can be
escaped by using the `nowarn` flag.
Also, when the conflict is resolved, allow the service to start.
With these changes, the system/hotplug.conf should work better and
cause less questions about "strange" log messages.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Apparently the qemu-system-x86_64 in -nographics mode does all sorts of
crazy things to the terminal. Most annoying, it disables linewrap.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In 91a9c83 a regression was introduced that affects the way Finit stops
a supervised process and its process group.
Instead of sending SIGTERM to the process, delegating the responsibility
to that process to inform any children it may have, Finit as of 91a9c83
sends SIGTERM to the entire process group. For SIGKILL this is fine,
SIGKILL only runs as cleanup and as a last ditch effort if the process
doesn't respond to SIGTERM.
This regression, introduced in v3.2, directly affects services like
avahi-autoipd that have forked off children that it needs to tell to
exit cleanly before it returns. With the patch in question these
children are never allowed to complete, which in turn causes lingering
169.254 link-local addresses on interfaces.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When started as a monitor in a container, or for the test suite run from
distcheck, we must allow Finit to find its own tools like initctl. This
should also be a more generic solution that cover more cases.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A simple distcheck revealed that the local path[] was too small to store
something like /home/jocke/src/finit/finit-4.4-rc1/usr/lib/finit/system/
This refactor should cover all cases.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The user may have their own setup of things, by default we should not
cause unnecessary warnings in syslog.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Due to an old design decision runlevel S was encoded internally as '0',
meaning it was the same as halt/poweroff. If you want to run scripts at
system shutdown this was less then ideal since it meant your scripts
also ran at bootstrap.
This change is quite invasive. It introduces INIT_LEVEL (10) as the
value for runlevel S, meaning all code that parses and/or evaluates
anything for runlevel 0/S was affected and had to be reworked.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Some services (openresolv) tries to talk to it very early, so lets get
dbus up and running as soon as possible.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The logger redirection process was sometimes in the init group instead
of the system/<svc>/ group. This was due to the parent PID being moved
after the logger was forked.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When we've started a run task, regardless of its exit status, we must
mark it as not dirty to prevent it from being endlessly restarted.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When the inotify callback is called for a file that has been removed,
the call to realpath() obviously fails (ENOENT). This fix only takes
the regular case into account, files removed from a symlinked enabled
directory is not handled -- needs more work for that.
Regression introduced in 0a94f3f, PR #347, issue #346.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Post audit, concensus is to drop if: and always do post-eval of all
ifdef: statements. Also, rename ifdef: to if: for completeness.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Multiple parallel tests writing to the same /var leads to quite
unexpected results. Let's start fresh in each test instead.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This is the first example of the just minted advanced stanza syntax with
if-statements, conflict handling, and nowarn flags.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Conditional loading of stanza depending on ident is already loaded. The
if: checks as in-band while ifdef: checks out-of-band, i.e., post eval.
The optional leading '!' negates the comparison, if NOT foo then ...
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Slowly migrating away from hard-coded services in plugins. This way
it's possible for the user to both inspect and override as needed.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The tmpfilesd() glob sorts files according to name, we could name our
.conf as 00finit.conf to prevent ordering issues with, e.g. dnsmasq,
but this is more elegant and allows for multi-level override.
NOTE: bootmisc depends on the pidfile plugins since the latter need
to set up its iwatches of /run before bootmisc creates /run.
Depending on if it's a system with /var/run or /run we need to
drop /var/run before recreating it.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This changes the semantics of Finit a bit by checking for the command to
run when registering it, skipping commands that cannot be found in the
absolute path provided in the command, or in $PATH.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Then it works to run the applets from outside the unshare. Useful for
testing and test development.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change adds very basic tmpfiles.d/ support to Finit. Much of the
basic types are supported, but not all, so for now, please check the
code for details on what is working.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Starting a service like this works fine:
service [2345789] env:-/etc/default/nginx nginx -g 'daemon off;'
However, on `initctl reload` the previous argument was lost while
parsing the end of the new one. So the comparison always resulted
in a 'diff' causing the service to be unnecessarily restarted.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
initctl: Follow priciple of least surprise for "cond get"
Fixes regression in 4.4 release cycle, commit c3c662f, when support for FLUX condition state was added.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The accepted standard in Unix is to report successful executions with
exitcode 0. Therefore, map a "initctl cond get" of a condition to the
following exitcodes:
- On: 0
- Off: 1
- Flux: 255
Fixes: c3c662fe64 ("initctl: ensure 'cond get' support flux state")
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
The TTY and log configuration is overloaded using a union in svc_t, so
we cannot "reset" the log attribute on reload. In fact, a TTY should
never be allowed to have a tty:anything set, so change the parser to
ignore log options for ttys.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Unfortunately we cannot use realpath(3) here since the the PID files
usually do not yet exist at this point.
Add and modify my ugly de_dotdot() from Merecat httpd.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When this code was moved from finit.c we rely on WDT_DEVNODE to be
defined in config.h, which is controlled by configure. Meaning, before
the relocation, Finit did not honor the configure settings.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This issue was found when the test pre-post-serv.sh suddnely started
failing, unclear how it could ever have worked before considering the
nature of this patch.
The trick here is when reloading a service like this:
service env:/etc/env serv -np -e foo:bar
into this:
service pre:/bin/pre.sh serv -np
In the second the env: has been removed and pre: added. But with Finit
prior to this patch, env: was kept leading to unintended behavior. The
same goes for the other options included in this patch.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In particular watchdogd we want to start in runlevel S to ensure we
start kicking the WDT. (Some HW WDTs are enabled from power on.)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
All services registered in the system rely on conf_init() having been
set up properly, e.g., global_rlimit. Having conf_init() be responsible
also for registering static services is only logical, and also helps us
clean up main() a bit.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Instead of the revert in c9fe9afa, we restore HOOK_BASFFS_UP to its
proper place at the end of fs_mount_all(). For this to not cause any
regressions we add a new hook, HOOK_SVC_PLUGIN, and update all plugins
that call service_register() to run at the new hook.
This will cause regressions for external 3rd party plugins that rely on
HOOK_BASEFS_UP to be called at its previous postion. Nevertheless, this
is the proper fix to the problem.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
With all the change and revert mess of the HOOK_BASEFS_UP tests started
failing due to usr.so and sys.so failed to set up their conditions. It
then became clear that boomisc.so cleaned up /run ... with the revert
we got service_register() to be called before global_rlimit[] was setup
causing services registered by plugins, before conf_init(), to crash.
This plugin and test is here to ensure we catch this problem in case of
any future refactor.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Not all Linux systems are based on Debian, and even if they are inspired
by Debian (Buildroot), they do not necessarily use the same defaults.
This patch probes the current system for:
- dbus user and group
- dbus PID file
If the user/group cannot be found we fall back to "root", if the PID
file cannot be determined we ignore PID file readiness.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This reverts commit 5b41c6e since it causes regressions in plugins
adding services to the system. The proper fix for early bootmisc
is to add a new hook, which will be added in subsequent commits.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
No need for special handling of s6 services, we now have the new
service_notify_reconf() function that is called on init reload.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The sysklogd logger is capable of logging the PID of the actual service,
rather than just the logger tool itself (which would be a differet PID
every time).
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When 'initctl reload' is called new "configuration generation" is
started by Finit. This mechanism ensures services reaffirm their
readiness and helps distinguish between their ready before reload
and after.
For native services the pidfile plugin handles this. The s6 style
services are one-shot only, and thus use a static ready condition.
This patch adds support for stepping the configuration generation
of unmodified systemd style services.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
To reset the crash counter of the 'serv' daemon we need to remove it
from /etc/finit.conf (and reload) between each test phase.
The repeated test phases can now be dropped, since the lack of reset
was the root cause for it failing sometimes in extended runs.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Correct an obvious oversight, we need to ensure the native pidfile based
daemons also work as intended in the new readiness notification world.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Ensure the test mimics actual real-world scenario where daemons do not
create a PID file at all.
Issue #343.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The 'initctl cond' commands were initiallý added to only manage usr
conditions. Recently the 'cond get' command was expanded to allow
reading general conditions as well.
However, since general conditions support three states the command
returned 'on' for conditions that were in flux. This patch fixes
that oversight.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The svc_set_state() function not only handles state transitions, it also
makes sure to cancel any outstaing service timeouts. Before the service
readiness support was added, service conditions were simply a single bit
of information, so clearing its conditions before changing states had no
impact. With readiness we have multiple bits of information that are
set as conditions.
When restarting a crashing service we set a timeout to retry restarting,
or ensure the service is now running. This means that the service can
signal READY before RUNNING is reasserted, but the RUNNING state can be
set also by the service state machine, so we need to ensure we do not
re-assert RUNNING if it's already set, and thereby clearing READY.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Issue #343 reports that readiness notification on crash/restart is lost.
This update to notify.sh reproduces that bug.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Principle of least surprise. When no even the maintainer remembers
the correct command, it is time to add an alias.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Over the years there have been multiple cases of invalid and/or unsafe
uses of signals and initctl commands at bootstrap and shutdown. These
cases cannot be safely supported. This commit locks down finit a bit
to avoid the most common cases.
If you run into this, please open a new discussion at GitHub and we'll
talk about it. Maybe I've been overzealous or you have another use-case
that warrants opening up some or parts of the API.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Not until fs_mount_all() has completed do we have /run, or /var/run, and
never after shutdown has been initiated.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
As pointed out by Jack Newman in issue #338, when conditions are not
available (at boot before cond_init(), or shutdown when /var or /var/run
have been unmounted) we should not try to create any conditions.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Slightly different take on issue #334 making it optional, possible to
enable per system.
reboot-delay <0-60> # default: 0 (disabled)
When enabled (non-zero), runs after filesystems have been unmounted,
the root filesystems has been remounted read-only, and sync(2) has
been called, twice.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The bootmisc plugin sets up the base path for finit and figures out if
the system has /run or /var/run -- needed by the other plugins.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This to save time during regular pushes and pull requests, the tests
run from distcheck take a long time, and they're not getting fewer.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
At this hook point the bootmisc.so plugin runs and creates all relevant
system directories. Much of the rest of system bootstrap relies on this
so it should be called together with the other FS hooks as soon as all
the filesystems have been mounted.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Works locally with/without this patch, but I cannot understand why it
would ever be needed in the first place, so removing.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When the /etc/finit.d/enabled directory is a symlink elsehwere, e.g.,
/var/finit.d/enabled, a relative symlink will not work.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
sig.c was calling plugin_run_hooks for the shutdown hooks, but the
shutdown hooks do not have registered callbacks in hook-scripts.c
Instead directly call plugin_script_run()
This fixes `initctl reload` correctly restarting all daemons that have new
command line arguments.
Previously command line arguments changes were only acted upon if the
service was explicitly reloaded `initctl reload myservice`.
We use strtok() quite extensively in .conf parser. Parsing of a service
line is split in two, with the command arguments being parsed very late.
Adding a new sub-option parser, based on strtok(), risk losing command
arguments. Thus, change to use strtok_r() so that we always know where
the arg parser is.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Last update of plugin before dropping it in favor of an equivalent .conf
snippet. (Pending new finit-conf repository).
Issue #327
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch changes the way progress for unmounting filesystems is
displayed. To see each filesystem being unmounted Finit now must
be in debug mode.
A general "Unmounting filesystems ..." have been added instead as well
as progress for last hook script and finall call to reboot().
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change drops the confusing status progress output, which was always
OK since the actual modprobe operation runs in the background. No need
to show status of the "added a task to finit, found modprobe" command.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Instead of waiting until runlevel 2, 3, 4, or 5 to load modules with
this plugin, we should load modules as soon as possible, i.e., in
runlevel S. This also means that Finit will clean up all the tasks
so we don't have to see them in `initctl status`.
To allow users to revert to the old behavior, we add a new setting
set runlevel 2345
that per modules-load.d/file changes the runlevel for all modprobe
commands.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
GitHub have now stepped their 'ubuntu-latest' image to Ubuntu 22.04.
With that comes the GLIBC bump to >= 2.34 which require aligning the
time bits and file offset bits to 64 bits. This is libuev v2.4.0.
We also make sure to align libite to the same version between the
workflows to avoid any nasty surprises.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
All hook scripts are called with at least one environment variable set,
FINIT_HOOK_NAME, useful when reusing the same hook script for multiple
hook points. It is set to the string name, also used by the path, e.g.,
hook/net/up.
For all hook points from hook/sys/shutdown and later, FINIT_SHUTDOWN is
also set, to one of: halt, poweroff, reboot.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
For all other run_parts() use-cases we just give the script control over
stdout/stderr to prevent clobbering ANSI color escape codes.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This reverts commit 03c08d3970 due to it
breaking handling of bootstrap tasks, causing endless boot loop.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This protects against any hook scripts or services calling initctl when
we're going down. There's no way to service these requests anyway, so
no point in keeping the socket open. This way initctl can check for
the existence of the socket before attempting any IPC command.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Add support for /etC/os-release, with fallback to /usr/lib/os-release,
overriding some traditional modifiers with the os-release variant. The
traditional values for these modifiers are taken from uname, which on
Linux systems are pretty useless since they always return the kernel
name and version instead of the distro/OS values.
E.g., \s becomes PRETTY_NAME instead of 'Linux' and \v becomes the
pretty VERSION, while \r becomes VERSION_ID.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change makes it possible to use the standard continuation character
in .conf files. For example:
service [23456] \
log:stderr \
<!pid/foo> \
bar \
-- This is the bar service, it depends on foo # comment that's dropped
Notice the additional support for comments on .conf lines. If you use
the comment character today you must change to escape it. Like this:
service :2 foo -- Foo \#2
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When removing a whole tree of conditions we need to walk through each
and call cond_update() to ensure that all dependant tasks are stopped
and put back in waiting.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change prevents Finit from attempting to continue restarting
crashing services that've lost their conditions.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Hopefully prevent spurious failures, dunno why atm., parallel checks
should work now. (Works locally with make -j20 check)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When a service starts up the pidfile.so plugin automatically detects any
new pidfiles that show up in the system. If it finds a matching service
which does not have a custom configured pidfile, it auto-assigns the
detected pidfile to the service.
However, when the user later calls `initctl reload` to update the
running configuration set, Finit service_register() mistakenly will
set the service to forking since it now suddenly has a pidfile ...
The new style way of configuring a forking service is to set the
type:forking
option. The old compat way was to set `pid:!/path/to/pidfile`, so
in service_register() we must be very careful not to interpret the
registered pidfile as confiugred by the user -- i.e., check the pid
option.
Bug #313
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When a service crashes Finit launches a restart timer that periodically
will try restart the service. If a user calls `initctl stop foo` finit
must cancel this timer callback, otherwise we may end up with a weird
state where Finit thinkgs the service is running, but pid: 0, i.e., not
started.
Note: this fix has been expanded upon from the proof of concept
submitted by Jack Newman.
Bug #313
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Running tests in massive parallel causes failing startk-kill-service.sh.
This in turn was caused by the shared test tool 'slay' that cached its
"oldpid" file to a shared area of the rootfs (tenv-root). It must use a
test instance-specific ramdisk.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change adds support for a new command line option finit.config=PATH
which can be used to tell Finit to start with /etc/factory.conf instead
of /etc/finit.conf.
For the complete experience a new top-level configuration file directive
`rcsd PATH` has aslo been added. It in turn can be used by factory.conf
as follows to override /etc/finit.d:
rcsd /etc/factory.d
Manually verified in myLinux
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Since the s6 readiness notification mechanism closes the notification
socket to Finit (as per s6 spec.) the 'ready' condition should then
always be asserted, even across system reconfiguration events.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Services that have not been changed, or otherwise needed to be reloaded,
need to have their 'ready' condition reasserted on 'initctl reload',
otherwise it will remain in 'flux'.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change adds support for JSON output to `initctl status` using a
`-j` or `--json` command line option.
Example:
root@anarchy:~# initctl status -j mdevd
{
"identity": "mdevd",
"description": "MDEVD Extended Hotplug Daemon",
"status": "crashed",
"exit": { "code": 100 },
"origin": "built-in",
"command": "/bin/mdevd -C -O 4",
"restarts": 10,
"pidfile": "/run/mdevd.pid",
"pid": 0,
"user": "root",
"group": "root",
"uptime": 0,
"runlevels": [ "S", 1, 2, 3, 4, 5, 7, 8, 9 ]
}
The excellent tool `jq` can be used to extract certain parts of the
output for further scripting. E.g. `initctl status -j foo | jq .exit`
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This was added for the benefit of `initctl status foo`, but we have
other users of these functions that don't expect a leading slash.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The condition subsystem starts very late, this should not affect running
callbacks in plugins. In d810ac0 an extra return statement was included
in a new if() statement block that run plugins hooks. This caused a
massive regression in how Finit starts up and runs.
- drop return; statement that causes regression
- move #ifdefs to surround if() statement
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change adds support for running hook scripts at two new hook points
during the shutdown process:
- HOOK_SVC_DN: after all services and non-reserved processes have been
killed (and collected)
- HOOK_SYS_DN: after all file systems have been unmounted, *just prior*
to Finit calling reboot() to shut down or reboot the system
See doc/plugins.md for details and an example.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Leave the system as it was when we found it. Also, we'll build things
on top of cond_is_available() to handle pre bootstrap and pre shutdown
tasks.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Always use the configured restart delay for crashing services. If no
delay is configured, we default to an initial 2000 msec for forking
daemons and start-stop scripts, and 1 msec for non-forking daemons.
We must track the increasing delay in the svc_t because processes can
fail quickly in differing ways. E.g, the test daemon 'serv' behaves
extra evil by crashing right after having created its pidile (i.e.,
when it's signaled to Finit it is 'ready' and all is dandy ...). If
we don't track the delay per svc_t we would restart 'serv' after only
1 msec every (other) time.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When there is no log daemon, and we are running in a container, or we
cannot log to the kernel ring buffer, then we log to stderr. This patch
improves the log output by prefixing each message with a timestamp.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
We want to stress test Finit as much as possible. We add a small log
though (which admittedly gives us a little bit of a delay) just to see
what happens when debugging failing tests.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch adds the oncrash:script option to call the post:script
action, if defined, for a crashing service. The EXIT_CODE variable
sent to the script is set to `crashed`.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
By definition, the readiness notification is reserved for daemons. May
possibly be extended also to sysv services later. If you arrive hare
with that request, please file an issue with the project.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
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>
Always better to have at least one sulogin available, if the system
provided sulogin isn't available we fall back to the built-in one.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch adds service readiness notification to support daemons
employing systemd and s6 notification. Complementing the native
Finit readiness support using PID files that exist already.
The two have slightly different ways of implementing readiness:
- https://www.freedesktop.org/software/systemd/man/sd_notify.html
- https://skarnet.org/software/s6/notifywhenup.html
Finit now provides both a NOTIFY_SOCKET environemnt variable, for
systemd, and a way to start s6 daemons with a descriptor argument.
For details on the syntax, see the `service` documentation.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Before we clear all conditions for a service, ensure pid_file_read()
didn't fail due to the PID file not (yet) containing a valid number.
If the process dies while starting up, and subsequently removes its
PID file, then the file shouldn't exist. However, if we get inotify
before the process has finished writing the PID, then we just return
and wait for the next event.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
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>
As it turns out, not all buses in Linux will add `modalias` attributes
to their devices in sysfs. One notable exception are MDIO buses. The
plugin's scan routine would thus not pick them up.
Fortunately, the information is always available in the device's
`uevent` attribute.
Therefore, default to looking for modaliases in the device's `uevent`
attribute instead, falling back to `modalias` only if `uevent` is not
availble (this should never happen).
Since the modprobe plugin (unsurpricingly) may cause new modules to be
loaded, it makes sense to to delay the initial device node scan until
we know that no mode nodes will show up within the next few
microseconds.
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>
- Prefix plugin defines with DBUS_ to allow overriding at build-time
- Create missing directories for modern d-bus
Signed-off-by: Andy Savage <andy@savage.hk>
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>
Add a plugin that will allow the user to trigger the execution of
scripts from plugin hook points. This is particularly useful for early
boot debugging that needs to take place before regular services are
available.
For example, let's say that you want to enable some kernel tracing
before modules are loaded. With hook-scripts, you can just drop in a
shell script in /libexec/finit/hook/mount/all/ that will poke the
right control files in tracefs.
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>
For many usecases, e.g. the modules-load plugin, the same command can be
used to create multple run/task/services makeing it real difficult to
debug such systems when Finit does not show the correct task name. It
also hides nasty bugs, as will be shown in a later commit.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This adds support for a `set` directive in the modules-load plugin.
Currently only `set noindex` and `set index = NUM` are supported and
either disable indexing (:ID) of modules, or reset the index to NUM,
for the given file. For each new file read the index is reset to
the value it would have had. E.g.
01-foo.conf: => name:id
esp4.ko => modprobe.esp4.ko:1
set noindex
deflate.ko => modprobe.deflate.ko
02-bar.conf:
nls_iso8859-15.ko => modprobe.nls_iso8859-15.ko:3
nls_utf8.ko => modprobe.nls_utf8.ko:4
Fixes issue #257
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Drop the config.h include from helpers.h after a report from a colleague
trying to build an external plugin from the latest GIT sources.
Instead, make sure config.h is included, and properly commented, in all
.c files that have configure #ifdefs and other deps. Also, move more
ot the includes from helpers.h to their respective .c file instead to
reduce the amount of headers an external plugin pulls in.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The bundled sulogin could be considered insecure, so leave it up to the
administrator, or system integrator, to decide which sulogin(8) is best
suited.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Finit can now track and set environment variables from finit.conf. The
syntax is pretty much what you'd expect:
foo=bar
baz="qux"
On reload of .conf files, all tracked environment variables are cleared
so if `foo=bar` is removed from finit.conf, or any finit.d/*.conf file,
it will no longer be used by Finit or any new (!) started run/tasks or
services.
The only variables reset to sane defaults on .conf reload are:
PATH=_PATH_STDPATH
SHELL=_PATH_BSHELL
LOGNAME=root
USER=root
It is entirely possible to override these as well from the .conf files,
but be careful. Changing SHELL changes the behavior of system() and a
lot of other commands as well.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When iterating over the system fstab file to call fsck, Finit calls the
helper function ismnt(), which opens /proc/mounts to make sure mounted
file systems are not fsck'ed. Both the main function and ismnt() used
the same non-reentrant getmntent() API which caused ismnt() to set the
fstab pointer for the first out of whack.
This change replaces getmntent() in the two critical functions with the
getmntent_r() API instead.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Some systems have /dev/root declared in their /etc/fastb as /. This is
as special device node created by the kernel based on the root=, and a
few other variables. This may be a symlink, and if so, and on a mdev
system, the symlink may point to the wrong device node ... so we must
try to figure out the major:minor from / and then traverse /sys/block
to find our root device.
Note: this commit also does a bit of refactoring for readability and
also adds a few debug lines that may be dropped before release.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A subtle regression was introduced in 5593372f, when moving to get
getmntent() family of APIs. Finding the 'ro' flag (or not) in the
system fstab broke and Finit never tried to remount / read-write.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change basically add this for pre/post scripts:
sh -ac '. /path/to/env; exec ./pre-post.sh'
Meaning the env file can be a simple foo=bar file, which Finit reads and
call setenv() on all variables, and the user do not need to call export
on all variables -- additionally, any functions defined in an env file
can be used by the pre-post scripts, but are ignored by Finit. I.e.,
the service only gets the variables set, no functions.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The swapon and swapoff commands do not support a custom fstab, they
assume /etc/fstab is the only true source of swap devices and files.
This change adds rudimentary (!) support for figuring out any swap
device or file to use from any finit.fstab. Please note, options are
not supported at the moment.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Since a forking service, e.g. a sysv init script, will exit very early
we cannot log the same as for regular services "Starting foo[123]", so
instead we log "Started bar[321]" when we get the pidfile update and
the same when stopping a forking service, log "Stopped bar[321]" when
we collect the PID.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change adds the following service conditions, which can be used to
synchronize other stanzas:
- service/foo/running
- service/foo/halted
- service/foo/missing
- service/foo/crashed
- service/foo/stopped
- service/foo/busy
- service/foo/restart
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This reverts commit c63279630b which
clearly was not needed to fix the problem. After this revert the
test(s) still pass, but now we can also start bridge-stp, e.g.
bridge-stp br0 start
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Default debug level for the netlink plugin is just too noisy. Let's
drop debug messages (mostly) intended for developers.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When logged in from sulogin we cannot send IPC to Finit, not even
signals, to delegate reboot. For usability, attempt to tell reboot that
it's in sulogin mode -- provided the bundled sulogin is used -- to let
reboot trigger over to forced reboot.
We cannot do much about initctl, just document this as a limitation.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This lets any callers of client_connect() decide what to do wrt. error
recovery and fallback mechanisms. E.g., reboot may want to check if
it's in sulogin mode, or fall back to sending signals to PID 1.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This adds support for bringing up the system with an alternate fstab at
boot. E.g., when using a primary/secondary setup for boot partitions.
By default /etc/fstab is read, like before, this can now be changed
using configure --with-fstab=/path/to/fstab.primary, which sets the
default that can be overridden using finit.fstab=/etc/fstab.secondary
If mounting, or fsck, fails in any way, Finit calls its own bundled
sulogin, or the system sulogin(8), to let the user handle the issue.
If there is no sulogin available, Finit will try to start up in its
rescue.conf boot mode.
Please note, in either of these rescue modes, use `reboot -f` to get the
system to reboot. Finit is on pause in the background in rescue mode
and cannot be relied on (since there may not be any writable filesystems
available.).
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The iterator works on any fstab like file, but to keep confusion to a
minimum, rename local variable.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The setfsent() family of APIs was never standardized and on Linux only
GLIBC implement them. We've tried to overcome this limitation, and to
support uClibc/uClibc-ng and musl libc, by providing replacements APIs
in helpers.c.
However, and since we want to support alternative /etc/fstab files, the
setmntent() family of APIs is more widespread and supports reading from
any fstab or mtab file.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Calling `initctl debug` is supposed to toggle Finit debug messages on
the boot console. This broke in ae09272b when improving support for
running Finit in containers.
Part of this change is a slight refactor of who calles log_init() when
starting up, and when to call ttinit(). We now call ttinit() every time
we toggle debug.
Also, toggling back to normal logging had a bug. The new default log
level for Finit is LOG_INFO, but toggling back set it to LOG_NOTICE.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Usability.
Remains backwards compatible for now, but finit.show_status is as of 4.3
deprecated. Likely to be removed int 5.0
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Explicitly set arg to non-NULL value. The call to conf() later will
steer up the value to point to the full path of the user's finit.conf
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When we added support for using popen() to run(), to log the output, we
forgot to update the error handling path. Found by Coverity Scan.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
We don't want repeats of issue #236, so let's start by tracking down any
bugs hidden in logging functions.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
On regular desktop systems, like Debian, the dbus-daemon forks off a
dbus-launch process to start up things like your desktop for you. This
process is not known to Finit and lingers in the background since it's
been reparented to init, and to top things off it seems to ignore any
SIGTERMs send to it.
Obviously this makes a shutdown on such systems very noisy, so this
patch changes the print() to a _d() so anyone debugging a system can see
it with `-- finit.debug` on the kernel command line, or `initctl debug`.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This split unmount is a bit crude, unfortunately. A user may have set
up a bind or overlayfs mount on top of a tmpfs -- so unmounting tmpfs
first will then always result in EBUSY.
Avoid logging busy errors and fake OK. We'll catch it later in the
second stage unmount.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Turns out that on Debian `ifdown -a` can block for quite a while at
shutdown/reboot. So we'd like to use the --force option. However,
the BusyBox ifdown tool doesn't support --force, only -f, which in
turn the regular ifdown tool doesn't support.
Regardless, we can allow network shutdown to run in the background
like bring-up, at reboot we want to reboot quickly and don't care
so much, and on runlevel change to single-user mode we can allow
for some lagging behind in the background.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Mention why configure script is missing from GIT
- Adjust command line for enabling Finit debug
- Plus some minor formatting issues
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Useful to debug system events after the system has started up and you
don't want to rebuild Finit to add the `-d` command line flag.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This is needed since 5ff27c4f when support for debugging Finit and the
kernel independently was added.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A forking service, e.g. a SysV init script, that returns is no longer
running, even though the monitored service may still be starting. We
must mark the svc->pid as terminated until we know more -- otherwise
we may stall on a shutdown at that exact point.
Also, when shutting down, and stopping all services, ensure we do not
start the carousel for non-existing PIDs. This might also cause our
stalling at shutdown.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Instead of having to create files, and copying them in place for each
test, we move all static test files to a skeleton rootfs. This makes
it a lot easier to get an overview of how things and how they work.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Note: we need to add /usr/bin and /usr/sbin to the standard PATH
for tests and the test environment itself.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In https://github.com/actions/virtual-environments/commit/12fa229 the
ubuntu-latest runner was updated to Ubuntu 20.04.4, with Linux kernel
version: 5.13.0-1014-azure. This broke the Finit tests completely
and the only possible solution, for now, seems to be reverting back
to the ubuntu-18.04 runner instead.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In an upside world, much like the Finit test cases, the root may be
relocated. This make /var/run relative to /var, instead of /. Which
hopefully is safer and covers more use-cases.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
All tests except the first two now suddenly started failing. Might be
the new caching support for the busybox binary, but that works on other
clean clones -- working theory now is that there's something subtle
with the setup-root.sh test -- which PASSes ...
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Add `type:forking` service option to trigger guessing pidfile to
watch for, instead of `pid:!foo` option, which is not intuitive.
This option may likely also survive into the new file format :)
- Update docs and add examples
- Update start-stop-serv.sh test case with this new variant
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Before this fix, a service declared with respawn could not be changed at
runtime to remove the respawn flag.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
While without a working Internet connection today I ran into the issue
of not being able to run the tests. This adds a basic caching mechanism
to setup-root.sh which saves busybox-x86_64 in ~/.cache, if available.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
serv: add support for foregrounding, running with and without PID file,
including custom PID filename.
test: verify Finit can start & monitor services that:
1) Fork and creates a PID file in a known location
2) Don't fork and don't create a PID file, but Finit does
3) Don't fork but create a PID file
4) Don't fork and create custom named PID file
Note: Finit cannot support a service that forks and doesn't create a PID
file. This combination is impossible to support without tracking
all processes created in /proc -- which Finit does not do atm.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Calling sync is not needed, remount does this for us.
Remount with 'dummydev' causes warnings and is not needed. It appears
sysvinit used this to try and fix a sparc related bug. Instead, use the
rootfs keyword to ensure we don't accidentally remount a bind mounted /.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Coding style for shell scripts:
- Tabs for indent (change in Emacs needed)
- Braces on their own line, like C functions
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
No point waiting for SysV start/stop scripts to finish, PID 1 should not
risk getting blocked forever by broken scripts. Instead we fork them off
and forget about them until they terminate. If they are buggy and don't
finish, it's the problem of the admin.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
I'll have to ask Jacques what this was for, because it doesn't seem to
be needed to run and monitor the test. Also, it lingers at shutdown,
causing some unintended side effects in Finit.
Commenting out for now, as a reminder to myself.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When a SysV init script starts a daemon, Finit knows nothing of the PID
it should monitor. The PID is written, by start-stop-daemon or the
daemon itself, to the PID file. Finit monitors for new PID files and
can match the PID in such files with an svc_t.
For the regular use-case, we prefer first looking up the matching svc_t
based on the PID -- assuming we start and monitor the service. As a
fallback we resort to mathching the svc_t's declared PID file with the
new file we just discovered.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
We want to find the PID of the daemon the init script starts, so we need
a way to declare this to Finit.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
SysV init scripts should not go to "done" state but "halted" so we can
do: `initctl stop foo; initctl start foo`, like we do for our regular
monitored services.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Install start-stop-daemon in test root. Add S01-service.sh, which uses
start-stop-daemon to start service.sh. Modify service.sh to respect
signals, and not exit immediately when sleep exits due to SIGTERM.
Remove PID file in signal callback and make sure to exit OK
The test itself is basically a copy of the start-stop-service.sh test.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The slay script checks for common errors and gives some logs and status
of Finit when something goes wrong. Helps detect issue #226 when the
start-kill-service.sh test runs at 100000 laps.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When running in a container we still want to use any syslog daemon
available for our logging needs. However, the time between the first
logit() in Finit and any such daemon having started can be long. In a
normal (non-containerized) setup we log to the kernel ring buffer, but
that's not available in a container scenario. At least not for
unprivileged containers. So we need to detect all these cases and be
prepared to fall back to log to the console, either using these LOG_CONS
flag to openlog(), or by simply calling vfprintf() to stderr.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This trick can also be used by others who want to run Finit in an
unshare. Set the container environment variable to 'unshare',
like lxc and docker do for their products.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Turns out the kill(2) syscall returns ENOENT, not ESRCH, in our test
suite. Don't know why, the man page never mentions ENOENT, only the
ESRCH code. Let's check for both, either way ithe PID is not there.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A service may have unexpectedly died, and we never got the signal, so
when stopping services we must set the new state after we've tried to
stop the service. Otherwise the svc_set_state() function starts a
background timer for the SIGKILL job, which may block a reboot.
The kill() syscall tells us if the service was there or not, if not we
must clean up and go to HALTED state.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
At startup (and reconf) of systems with lots of services there is a risk
of losing inotify events, e.g., PID file creation/delete events. This
patch increase the receive buffer (doubles it).
On Linux the getsockopt() for SO_RCVBUF returns double the set size, due
to housekeeping in the kernel. So we don't have to do any adjustments
when setting it.
Issue #226
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In some (error) cases the PID known to Finit may no longer exist, or may
not have been added to a cgroup (yet). Handle this case by skipping the
output of cgroup info in such conditions.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
On, e.g., a container based system logs may not be available so check
also that the messages fallback exists instead of causing confusing
error in the status output for the service.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
To silence warnings at startup/shutdown, check for existance of swapon
and swapoff before calling them.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When a run task is started with svc->started = 1, it should be
considered started successfully or failed on the other hand.
Signed-off-by: Sergio Morlans <sergio.morlans@atlascopco.com>
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
This patch adds support for optional logging of output from all run()
commands. For run_interactive() we've opted to log instead of just
redirect, meaning output on error is till on console but also in log.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
We've been discussing, over the years, that we'd like to have an easier
way to debug bringup with Finit. Network bringup is one such case where
it's hard to debug if/what you've misspelled in /etc/network/interfaces
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This fixes a seemingly long-running bug; we only brought down networking
in shutdown/halt and for runlevel 1, single-user mode -- not reboot.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In commit f0f358a13:
[ service.c: set/clear condition 'done' for run tasks ]
a runtask done condition would be set/cleared when entering DONE/HALTED
states, but it did not cover all the user cases, for instance, sometimes
an end user may want to know if a runtask has finished sucessfully or
to decide what to do on its failures.
So we now change the conditions to: tsktype/tskname/success and
tsktype/tskname/failure.
And this change not only applies to run/task types, but also applies to
sysv type, in case it fails, a sysv/tskname/failure condition would be
set.
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
Refactor new kill/shutdown implementation from 3e0063e to fix the
regression in compiler output:
sig.c: In function ‘kill_callback’:
sig.c:222:12: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
222 | kill(pid, (int)context);
| ^
Also, some minor renames and simplificactions to match project style.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Check all pointers
- Declaratons always at top of func/scope
- Use established variable nomenclature
- Skip useless if() stmt
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Comments preferably at beginning of func/sect
- Reorder code slightly, add whitespace for readability
- Drop useless comment
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit implements a test for the signal feature of initctl. The
existing service used in tests (`common/service.sh`) has been extended
with a signal trap handler. When SIGUSR1 is received, it will write the
string `'USR1'` to `/tmp/usr1.log`. The test will run `initctl signal
service.sh SIGUSR1` and assert that the contents of the file
`/tmp/usr1.log` really is `USR1`.
The implementation looks up the named service by using
`svc_parse_jobstr`. The callbacks for `svc_parse_jobstr` has been
augmented to accept a user data parameter. For this use case,
a carrier for the actual signal was needed. The address of the
signal parameter is taken and passed on as a `void *`. The
callback then simply deferences it as an int - the signal number.
In the test framework for finit, a set of shell scripts are used to
setup a test harness, run tests, and finalize tests. In the setup, a
file system is created for the virtualized/containerized environment in
which all tests are run, located at `$FINIT_SRC/test/tenv-root`. In the
tear down phase of each test, the file `/var/lock` is made readable
using `chmod +r`. It is not clear _why_ the teardown code does this, as
there are no references in the test framework to this path anywhere
else. It is conceivable that the teardown phase attempted to "reset the
state" for next test.
The code that that this commit removes does not always work. When
`/var/lock` is a symlink, and resolves to an absolute path, the test
framework does not function properly. The teardown code is run in the
context of the host computer, and touching files outside of the
virtualized environment is not ok.
The removal of the offending code does not seem to affect tests: all
tests pass without it, so its existence is questionable.
Signed-off-by: Jörgen Sigvardsson <jorgen.sigvardsson@gmail.com>
Blocking SIGTERM means Finit will wait another two seconds before it
sends SIGKILL, which casues a delayed [WARN] Killing ... before we can
proceed to shutdown/reboot -- not OK. Don't know what I was smoking
back in 2017, but it must've been good.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When running in a container we might not have the necessary privileges
to mount cgroups. Don't cause error in this case, just log it.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch allows disabling (enabled by default) the modprobe and tty
plugins. They are not particularly useful in container use-cases.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
We extend the service.sh to emulate a well behaving service that creates
and removes its own PID file.
The new test emulates a crash by sending SIGKILL to service.sh. We then
verify that Finit restarts it, and eventually registers the new PID when
the services recreates the PID file.
Issue #226
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- We need a working /var and /run for some features, e.g. PID
monitoring and status files for urandom.so
- Add empty fstab to silence mount errors from finit
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A regression was introduced by commit f0f358a1:
[ service.c: set/clear condition 'done' for run tasks ]
svc->type is a integer but mistakenly being used as string, which will
cause crash.
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
Instead of unconditionally waiting 2 seconds for processes to die,
check continuously for remaining processes, and break the loop when
none remain.
Turn PID 1 to a RT process with highest priority 99 during shutdown,
this ensures it would not be preempted by other RT processes.
Signed-off-by: Robert Andersson <robert.m.andersson@atlascopco.com>
Signed-off-by: Mathias Thore <mathias.thore@atlascopco.com>
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
We like to know when a runtask (run/task/sysv)is done, so as to start
the services that depending on it, set a oneshot condition 'done' for
that case and clear it when runtask services enter HALTED state.
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
It should not use relaxed comparison in some places, otherwise it mess
up with scenarios like:
```
$ initctl status ntpdpre
$ initctl status ntpd
```
the output might be same for both of the above commands without this
fix.
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
This patch adds the -v,--version option to initctl, which acts as an
alias to the 'version' command. For now they end up in the same old
function, printing the program version. However, in time this will be
changed so that the 'version' command asks a running Finit for its
version instead of assuming the daemon is of the same version.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A 'module foo args ...' line in finit.conf can be looooooong. This
patch drops the module args from the progress output for brevity.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
With the introduction of GLIBC v2.34, all 32-bit devices running Linux
get the option of having a 64-bit time_t to survice the UNIX 2038
apocalypse.
Support for 64-bit time_t was added to libuev in v2.4.0. The build
flags for linking against libuev are defined in the library's .pc
files, which basically gives you -D_TIME_BITS=64 for your CPPFLAGS.
However, it turns out the $(uev_CFLAGS) from pkg-config were only used
when building the main finit binary -- not for the plugins, causing
some really wacky behavior as a result. All plugins and Finit itself
had some very different opinions on what `struct plugin` looked like,
including offsets and size. This led to all I/O plugins initializing
their sockets at the wrong offset -- little-endian 32-bit targets set
the HOOK_SHUTDOWN callback hook to address 0x1 -- which the reboot
code then tried to execute, of course leading to a segfault.
This is quite possibly the root cause of issue #216
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Previous patches only checked if cgroups v2 support was available in
the kernel. If mounting failed cgroups support was disabled.
However, much of the core logic to cgroups in Finit revolve around the
CPU controller. This patch adds checks to ensure that the kernel has
basic controller support as well.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch prevents bogus error messages from Finit for when
directories or symlinks already exist.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Traditionally we've reset the service restart counter on two occasions:
1) when a service reaches its max crash count (default 10), and
2) when a service somehow "stabilizes"
In the second case the service is restored to normal running state and
we "forget" its bad previous behavior. Meaning we cannot catch daemons
that act in an unstable manner outside the "rage quit" scenario.
This patch allows for slowing aging (decrementing) the restart counter
once every five minutes. Meaning we still catch rage quitters but now
are also able catch other types of misbehavior.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch adds a recent feature request to keep track of the total
number of restarts (including crashes and initctl restart) of both
service and sysv daemons.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Clearing of the svc->pidfile was introduced in e1b87d70 for a
restriction that has now been removed.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch adds support for detecting if the Linux kernel Fint runs on
has support for cgroups v2. The probe is done very early, in runlevel
S, when attempting to mount /sys/fs/cgroup. Meaning, the log message
may be lost on systems that do not run sysklogd[1].
Here's the relevant logs from a system running myLinux on a kernel
that has cgroups v2 support disabled:
Jan 10 20:19:40 anarchy finit[1]: myLinux 2021.11-696-g8fddaf36ed, entering runlevel S
Jan 10 20:19:40 anarchy finit[1]: Kernel does not support cgroups v2, disabling.
Jan 10 20:19:41 anarchy finit[1]: myLinux 2021.11-696-g8fddaf36ed, entering runlevel 2
All code paths that attempt to set or query kernel cgroups config has
been short circuited when this happens. However, this does not apply
to any cgroup related config in the Finit .conf files -- which may of
course be omitted. Yet, if configuration directives exist, they will
be parsed and may cause error.
Also, the initctl tool checks if /sys/fs/cgroup is mounted at runtime
and disables all status output and commands that rely on the feature.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
initctl cannot link with helpers.c, so let's relocate these helper
functions to util.c instead. Need them to probe for cgroup support.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A timeout is not the same as a restart delay, which this option really
controls, but the name restart_delay is a bit too long. Hence, this
obvious name so there's no ambiguity what unit we're dealing with.
Keeping restarttmo:SEC as a compatibility setting for the benefit of
the original authors, for now.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Minor coding style cleanup. Also, clang complained of a signed vs
unsigned comparison in service_retry(), max(timeout, svc->restart_tmo)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
As suggested in issue #197, this new command: 'initctl id [NAME]'
lists identities of all, or named, services. E.g,
# initctl id telnetd
telnetd:23
telnetd:2323
The NAME argument is optional, when omitted it lists all enabled
run/task/sysv/service in the system, with their full name, and any
optional identitty. E.g.
# initctl id
dropbear
tty:console
mdnsd
mini-snmpd
smcrouted
sntpd
ssdpd
sysklogd
watchdogd
httpd
telnetd:23
telnetd:2323
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When the system has multiple services 'foo' the initctl command
'status foo' should give a focused overview of all matching foo:*,
whereas a 'status foo:2' should show the detailed view of that
particular instance.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Since Finit v4.0 kernel console output has been silenced just prior to
the banner being printed, unless finit.debug mode was enabled. This
patch makes sure to check the kernel loglevel, if it's >= 7, finit no
longer disables kernel console ouput.
Consequently, you now need 'quiet' on your kernel command line, or a
loglevel < 7 for a quiet boot, at least until a syslogd takes over.
This means that you now can debug the kernel and finit independently,
which should be a great comfort to anyone doing bringup or any form of
kernel debugging.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch switches from "cp /var/lib/misc/random-seed /dev/urandom"
to use the kernel RNDADDENTROPY ioctl, which actually increments the
entropy count.
Also, the amount of random data saved at reboot is increased from the
fairly low 512 to 32768 bytes.
All in all, this should greatly improve the stability of most systems
during, or close to, bootstrap. In particular embedded systems with
limited or no HWRNG.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Since we just want to clear the complete line, and are already a the
beginning of the line, we can use the simpler \e[K which also seems
to fix the display resize bug in #210.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Due to an unfortunate name clash with the DirectFB project LiTE, the
libite (-lite) project had to change its header namespace from
lite/*.h -> libite/*.h
This patch adds support for the new namepace in Finit, triggered by the
define _LIBITE_LITE, from the .pc file read by pkg-config. This should
only be needed on systems that install libite without the compatibility
symlink lite -> libite/ in the staging include directory.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
It would be good if we can control the services more specifically with
the following parameters like:
restart:N - how many times shall the service to be restarted on
failures (<10), the default max is 10.
restart_tmo - the timeout of the restarting.
norestart - dont restart on failures.
oncrash - once all retrying also fail, how to deal with it,
rebooting or ignoring the failures.
Signed-off-by: Robert Andersson <robert.m.andersson@atlascopco.com>
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
Both DBUS user and pidfile is configurable in DBUS compilation, by
passing "--with-dbus-user=" and "--with-system-pid-file=", let's avoid
hard-coding them here, use macros instead.
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
It's configurable in /etc/login.defs as NOLOGINS_FILE, avoid to hard
coding it here, introduce a macro FINIT_NOLOGIN_PATH instead which is
configurable from compiler flags, it's not defined, then back to
_PATH_NOLOGIN from /usr/include/paths.h.
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
fastboot: once enabled, fsck would be skipped on filesystems listed in
/etc/fstab.
fsckfix: once enabled, 'fsck -ys' would be run instead of 'fsck -a',
and check the return value larger than 1 as a failure and goes
to login console.
They are both disabled by default, no functional changes unless an end
user choose to enable them.
The idea derives from Sysvinit's "FASTBOOT" and "FSCKFIX".
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
The iterator function getmntent() is not stable. It may skip
entries if the contents of the iterated file changes, which
is the case with /proc/mounts when filesystems are unmounted.
As a result, some filesystems were never unmounted.
To fix this, iteratation is now restarted after every
sucessful unmount.
Signed-off-by: Robert Andersson <robert.m.andersson@atlascopco.com>
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
"protected" is a C++ key word, replace it with "is_protected" avoid
compiling failures with C++ compiler.
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
There are small typos in:
- doc/conditions.md
- src/mount.c
- src/svc.h
Fixes:
- Should read `satisfied` rather than `satsifed`.
- Should read `process` rather than `prorcess`.
- Should read `measure` rather than `meausre`.
We've had several logit() messages of LOG_INFO level that never
really made it to syslog because we classified it as "debug".
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch adds "the missing" first runlevel log entry when Finit has
printed the console banner and begins its bootstrap phase.
At this point we know syslogd hasn't been started yet, so we rely on
logit() to redirect this to /dev/kmsg in the meantime. Later syslogd
will pick this up, see that it's not from the kernel, and log it to
the proper log file.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
If any of these mount() calls fail, not counting EBUSY because that
would mean sth is already mounted, there really isn't much we can do.
So the least we should do is warn on console if it happens.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Note, this is dead code, currently unsused in Finit. Possibly an
external plugin makes use of it, but even that is highly unlikely.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
I'm writing this in X started on a system running Finit v4.1-pre that
does not have elogind installed. It does, however, still have systemd
installed, so systemd-logind is available.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Fix bug when calling sys_update_conds() when dir already exists
and we're not being called from the scandir() handler. I.e.,
every time but the first for each new condition sub-family
- Drop sys conditions that don't affect any svc_t. This may seem
counterintuitive, and we should probably not use oneshot conds,
but if we leave these conds asserted they may cause inadvertent
trigger if a finit.conf is loaded which ha this sys cond. E.g.,
if ctrlaltdel is asserted and we enable a task in finit.conf and
call `initctl reload`, the task would start immediately, even
though ctrl-alt-del may have been pressed a week ago
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch removes the cognitive overhead of having to manually set your
OS heading, --with-heading="Foo OS vX.YY". As of this patch, Finit by
default extracts PRETTY_NAME from /etc/os-release. It is now possible
to also disable the heading entirely using --without-heading
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Shouldn't be needed for real cases, but we have seen automated scripts send
'\n' instead of '\r', or '\r' + '\n'.
Signed-off-by: Jacques de Laval <Jacques.De.Laval@westermo.com>
Similar to 6224166 (previous commit), this old code is a remnant of a
bygone era and not needed anymore.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Once upon a time, SIGSTOP was used to pause Finit during flashing (MTD)
of a system image. This to prevent Finit from accidentally starting any
programs, i.e., reading from flash disk during or after upgrade.
This was quite intrusive, and has possible nasty side effects, e.g., any
process with root access sends SIGSTOP prevents TTY login. So this patch
now removes the functionality and recommends using a dedcicated runlevel
for such critical tasks instead.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When a service is started and then stopped before it has created it's pid file,
it could be left forever in the "stopping" state, if we don't reset the
starting flag.
Signed-off-by: Jacques de Laval <Jacques.De.Laval@westermo.com>
The waitpid() function can return -1 due to EINTR (signal), so we should
restart it to make sure we collect all zombies.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Some systems may want to handle RTC and /dev/urandom by themselves, or
not at all as in the case of containers where the host does all this.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
For most use-cases the kernel will give Finit its arguments as proper
command line args in argc + argv[], like any other program. However,
for some users, most notably Alpine Linux, there is a slightly broken
initramfs that cannot forward more than one argument using init_args,
for such systems you can re-enable the old behavior with a configure
switch --enable-kernel-cmdline -- it's not ideal but what can you do.
The main reason for removing this feature by default is to support
use-cases where Finit runs as the init for container apps that can read
/proc -- we do not want them to use the init args from the host.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
It has barely worked and only caused more problems than solved annoying
issues. We have one console for output, /dev/console, which the kernel
sets up for us.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Also, fix default: case in error handling, must always continue back to
poll() on any recv() error.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Progress at startup has been hidden for services w/o -- description, but
for some reason this check was not added to service_stop(). This patch
rectifies the situation, finally.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch adds a `respawn` flag for services and ttys, always set for
ttys, that allows bypassing the crash/restart counter and immediately
restart a 'crashing' service.
For tty type services this is the expected behavior, but for regular
services it is not. That is why `respawn` flags is not advertised in
the docs.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Basic security measure, don't bail to shell if we cannot find/exec
login, instead try sulogin before falling back to plain shell.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
By default, Linux gives us /dev/console for output. This is a pseudo
device that uses the same actual device as the last console=foo listed
in /proc/cmdline. The last one listed is the main console, which is
also the *first* one listed in /sys/class/tty/console/active, so we skip
that when we check for system consoles to avoid duplicating output.
The getty code in tty.c currently has its own handling of @console,
which we keep for now. Ideally, however, the code should be merged.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
By moving the built-in getty to a stand-alone bundled getty we can now
refactor the old run_getty() functions into a single one.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When TTYs became first class citizens in Finit 4.0 much of the
boilerplate setup is now down by service_start(). Also, the calls to
TIOCSCTTY, VINTR, and SIGINT ignore is not necessary to do here, it
should be done by the getty used, if any.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
We must detach from the controlling TTY before enabling signals and
setting up new stdio. TTYs have their own handling of stdio.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch moves the built-in getty out of Finit into /libexec/finit/,
reducing the size of the Finit binary and simplifying the code.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When starting a getty Finit checks first that the configured TTY device
actually exists and is a TTY. This patch, by Tobias Waldekranz, ensures
Finit (PID 1) doesn't acquire the TTY device as a controlling TTY. If
that happens PID 1 will get all signals sent to the process actually
started with the device as its controlling TTY.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When an external getty is used, and an absolute path is not given, the
parser tried to use access() to determine built-in vs external getty.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
If we don't extract the level (disregarding facility), statements such as
"logit(LOG_CONSOLE | LOG_NOTICE, ...)" would never reach the kernel log.
Signed-off-by: Jacques de Laval <Jacques.De.Laval@westermo.com>
This patch drops the default signal handlers for SIGPWR and SIGINT with
optional tasks in /etc/finit.conf, triggered by two new conditions:
sys/pwr/fail and sys/key/ctrlaltdel, respectively.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Apparently fgetln() is available in musl libc, but not glibc. This is a
funciton that first appeared in 4.4BSD. We take a risk that fgetline()
is free in all libc's, getline() is not.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch is a refactor of the prototype sys condition plugin. It
moves most of the logic to monitor kernel events into a keventd that,
currently only, sets and clears the sys/pwr/ac condition. The sys
plugin itself is now only a monitor of conditions and ensures Finit
follows them. This is a lot more secure and moves (at least one piece
of) netlink processing out from PID 1.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The top-level cgroup init is a leaf group and should be treated as such,
even for user setup tasks/services.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The udevd, dbus, bundled watchdog, and others were started without a
valid cgroup. This is a workaround to ensure they are assigned one.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This fixes a long-standanding issue with finit not controlling the
reboot when the user presses ctrl-alt-delete (PC systems).
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch does several things related to /run and system reliability.
- Mount /run with MAX 10% of usable RAM
- Create and mount /run/lock as a separate tmpfs with max 5 MiB
As a spin-off, this patch also fixes permisions on /run/lock to 0777
so regular users can create lock files.
Note: none of this code runs if /run is mounted alread in /etc/fstab
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Handle EAGAIN properly, for both regular and resync flow, on any error
in the regular flow (unless ENOBUFS) we want to check for nl_ifdown on
any of the successfully parsed messages.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch adds support for calling recv() repeatedly to get the netlink
response from the kernel. As a result, the recv() buffer can be reduced
down to 4k again.
Both the regular flow and the resync flow now follow the exact same code
path, except for the ENOBUFS handling. If we get ENOBUFS in resync, we
are screwed anyway.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
For RTM_GETLINK we need a `struct ifinfomsg`, not `struct rtmsg`,
otherwise the kernel will get 8 extra bytes and complain about it.
This patch makes sure to set the correct iface change mask as well, and
increases the debug logs a bit to get a fix on sizes used. We increase
the recv() buffer 8k -> 64k to make sure we can get all data in one big
swoop. Plan is to refactor this mess in a later commit.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This is a major redesign of the netlink plugin to be able to handle
ENOBUFS¹ properly. Pending verification, this change replaces the patch
to increase socket buffer size, which in real life turned out to be
insufficient.
When nl_callback() calls recv() and it fails with ENOBUFS, we consider
our cache of the kernel state invalid and thus:
1. deassert all net/ conditions
2. open a new (temporary) netlink socket
3. send RTM_GETLINK and re-assert all interfaces using nl_link()
4. send RTM_GETROUTE and re-assert all routes with nl_route()
Like before, the kernel will not send us a RTM_DELROUTE when it removes
the default route, so we still have to track this ourselves. This patch
also refactors that functionality to only resync routes when the ifindex
associated previosly with the default route goes down or is removed.
The previous change that added nl_default() to recheck, has been dropped
to instead reuse the standard nl_route() callback.
___
¹ see netlink(7) for details.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch fixes the problem with Linux not sending netlink route change
notifications when interfaces for these routes goes down. When an iface
goes down we now send a route request to the kernel and check the return
message, if no default route is found we deassert net/default/route.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch restores parts of 4febd28, but in a more orderly fashion, in
order to get a standard Debian system to boot properly with X and tools.
The patch adds fs_finalize() which checks if /dev/sh/, /dev/pts, /run,
and /tmp have been mounted properly from /etc/fstab. If not, then the
function makes sure to mount tmfps (or devpts) file systems as expected
by most modern systems.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch changes the behavior of SIGUSR1. Previously USR1 could be
used to halt a running Finit system, similar to BusyBox init. However,
compatibility with sysvinit and systemd has been deemed more important.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Coverity suggests validating against only a set of known characters.
However, the kernel allows just about all characters in an interface
name. This version of valdiate_ifname() is blatantly stolen, more
or less, from linux/net/core/dev.c
https://code.woboq.org/linux/linux/net/core/dev.c.html#1020
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
sulogin should return OK (exit code 0) when the user presses Ctrl-D,
regardless of the prompt shown. Otherwise Finit may look for another
sulogin to run straight after this one.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Simplify build system.
The logit tool is, as of v4.0, installed into /libexec/finit/logit and
thus not part of the system $PATH. If a sysadmin or distro wants to
remove it from the system it's entirely possible since Finit always
checks for logit availability before attempting to use it.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Before 4e5d06b the only way to go into rescue mode was to skip certain
steps and then attempt to load /lib/finit/rescue.conf. After 4e5d06b
we keep the old handling as a fallback in case early sulogin fails.
The new tty option 'rescue' is added, which recue.conf is updated with.
This option implies notty mode and will try sulogin (again) before it
falls back to start /bin/sh as a login shell.
The reason we keep this is to be able to handle all possible use-cases
and also allow sysadmins to set up the behavior that fits their needs.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch does two things:
1. A system with a root account that has no password is now
allowed to login without password, as one expects.
2. A systems with a locked root account, is treated as (1).
The latter of the two may very well turn out to be a really bad idea.
Much angst have been poured into it, yet the end decision is to allow
access.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Most major init systems have a way to start a rescue shell. This is
usally started when the string `rescue` is read from the kernel's
command line.
The traditional Finit way of handling this has been to skip certain
phases of the standard boot, skip /etc/finit.conf et al, and go for a
/lib/finit/rescue.conf instead. This pratice has been imroved over
the last few commits with a sulogin. However, there was no way to
resume boot, like most other init systems offer.
This patch implements a very simple rescue mode, utilizing the new
sulogin, replacing the old (and experimental) emergency shell. If
Ctrl-D is pressed at the maintenance login prompt the boot is now
resumed. The same goes for exit/Ctrl-D from the maintenace shell.
The preferred sulogin is the bundled /libexec/finit/sulogin, but
if that isn't installed, the first one in $PATH is used. If no
sulogin at all is found, Finit proceeds as before this patch, to
skip certains steps and go for a /lib/finit/rescue.conf. Hence,
al steps can be controlled by an administrator.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- splice out sh() as a separate function
- make sh() session leader and set controlling TTY (TIOCSCTTY)
to make it a proper login shell with Ctrl-C functionality
- simplify call to execl()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
These plugins should not run in rescue mode, because the system may be
in a very bad state and we do not want to make the situation any worse
than it already is.
Essentially, only services in rescue.conf should run in rescue mode.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Check if watchdogd *and* `WDT_DEVNODE` exists before registering the
built-in watchdogd at boot
- Update bootstrap.md with this additional constraint
- Update config.md with references to bootstrap and the new constraint
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch fixes an issue where services that support SIGHUP are not
properly stop/started on changes to their command line arguments.
A change to a service's env: file, e.g. /etc/default/foo for service
foo, must also be counted as a change to the foo args.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This changes the default to redirect output from run/task/services to
/dev/null. Use --disable-redirect to get the old pre v4.0 behavior.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
We need at least the softdog watchdog driver loaded for proper watchdog
reset at reboot. This can safely be replaced with a hardware specific
module that provides /dev/watchdog ... without one Finit will try to
restart the built-in finit-watchdog service 10 times to no avail.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch changes the configure option to enable the built-in watchdog
from --enable-watchdog to --with-watchdog[=DEV]. This is the convention
for features that take arguments.
Also, improve log messages to aid debugging when finit-watchdogd does
not start properly. This means flushing logs to syslogd with closelog()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch restores the start of the built-in/bundled watchdogd. It is
tracked in the `wdog` variable and handled as an exception at shutdown.
This is also a follow-up to 7b74c99, ensuring that we only kill/stop the
built-in watchdog, not any external. External ones can register to be
the controlling watchdogd in the system -- Finit is not the arbiter for
singletons, this is up to the system engineer.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
If we get a notification and the service dies immediately, and also
removes its pid file, we need to take corrective action.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch updates the service state machine with two new states: SETUP
and CLEANUP. If an executable pre:/path/to/script is defined for a
service, it is called every time the task goes to READY state. If an
executable post:/path/to/script is defined for a service, it is called
when the task goes to HALTED state.
Each of these two scripts default to a three (3) second execution time
before they are SIGKILLed. This can be adjusted with the `kill:SEC`
option for the service. There are no execution guarantees, nor are
there any way of detecting if the script was killed before completion or
not -- except for running Finit in debug mode and inspecting the result
printed by system_monitor().
Note: the post:script MUST be idempotent since transitions between READY
and HALTED can take place any number of times before a task goes
to its RUNNING state.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
These two BusyBox daemon's run in concert so it makes sense they also
share the same cgroup. In Finit that means sharing the same .conf file.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Before this patch bootclean() ran first in setup() which caused to to
remove the entire /var/run/finit directory, and other files as well,
created earlier. Only possible fix is to split clean and setup in
two and make sure to call clean as soon as we've mounted everything.
Note: this introduces a new behavior, and anyone hooking into the
same point to do good-stuff(tm) may be affected by this.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Avoid using reserved C++ keyword 'new'
- Rename new -> next
- Rename old -> prev
- Add debug for value being set to cond path
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Drop vhangup(), how did things ever work *with* this in?!
- setsid() + TIOCSCTTY are best buds, see notty code
- Allow storing any non-NULL string as tty->dev, expand in service_register()
- Reorder parse_cmdline_args(), we need to expand @console to current dev
- Fix tty arg parser, swapparoo for external getty
- Refactor tty_atcon(), iterated over by service_register()
- New arg format, need to translate for old run_getty2()
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch re-enables the fallback shell handling after the big TTY
refactor. We do this by allowing the fallback shell to run as a
regular service.
Note: this also adds the "hidden" support for 'notty' option for
tty configurations stanzas. This is just to pick up from
where the kernel left us, reusing stdin + stdout.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
As soon as we collect a PID we should cancel any outstanding timer
actions. Because we may very soon svc_del() it ...
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Some C-lib, like GLIBC, convert NULL to <nil> when printing %p,
which we shouldn't rely on since others just bite the dust.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Initial refactor of the tty implementation to use the service/run/task
general backend. This enables all the features of services also for
ttys, except logging because it makes no sense.
Work in progress:
- plugins/tty.c does not work anymore, could possibly be removed in
favor of usinga (a new) condition instead (if-tty-exists)
- fallback tty does not work anymore, should we remove it, or can we
handle it as an optional built-in with (a new) condition?
- @console does not work anymore, needs to generate N cloned services
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Calling `tree /tmp` causes too long execution time and Travis timing out
the job. So let's install to a sane directory.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Show if exited/signaled
- Show status code and the std /NAME
- Show signal value and the std /NAME
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- List /etc/finit.conf
- Allow edit of /etc/finit.conf, using finit/finit.conf or NULL
- Add helpful question to edit /etc/finit.conf if no edit arg.
- Show available files if delete has no arg, like disable
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The main purpose of this patch is to remove top-level cgroups when they
are remvoed from finit.conf. However, this is tricky, becasue there may
still be supervised services (and children of them) running. We must
postpone removal until a cgroup.events change. To make matters worse,
events may arrive out-of-order, i.e. the last-child event for the parent
cgroup before the sub-group.
A spin-off from this patch is that we can now support arbitrarily long
group names and group config. (Only applies to top-level cgroups, not
run/task/services.)
Limitations:
- Processes in "removed" cgroups are not migrated/orphaned, the reasons
are several: overhead and complexity and the fact that memory cannot
be migrated
- A lingering child of a moved service may prevent an old top-level
cgroup from being removed.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
We have these neat extras for added value, if they should fail, for
whatever reason, we still want to present 'top' to the user, which may
have to use 'reset' if exited improperly and lost cooked/cursor.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
We check it everywhere else, and a log message for failing to move PID 1
to the init cgroup is useful as well.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
No need to zero out whole buffer for strlcat(), or other string check
ops. Also drop a few completely useless memset() calls.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Set TTY in raw mode to be able read a single char at a time
- Hide cursor
- Trap 'q', Ctrl-C, Ctrl-\ and SIGTERM to restore TTY and cursor
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This is intended to be used with the 'top' command to aid in setting up
and verifying proper limits for services.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Replacing write() with dprint() without thinking leads to duplicate
output in getty. In particular '\n login: foo login: ".
Must check if length is > 0, or dprint() will calculate it on its own.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch corrects a logical glitch, or design flaw, in initctl. The
'restart FOO' command did not stop+start FOO only send SIGHUP (provided
FOO supports SIGHUP). Hence, a new command 'reload FOO' is introduced,
which does exactly that, and 'restart FOO' now stops and restarts FOO.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Fixes the GCC warning for unchecked return value from write():
... ignoring return value of ‘write’, declared with attribute warn_unused_result
The new dprint() function wraps write() in a bounded retry-loop that
catches EINTR. The length argument is optional computed with strlen()
if omitted (zero).
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
By keeping track of when a full restart is needed, Finit can relieve
the user of having to track modifications to service configuration. This
also makes initctl reload easier to explain and reason about as the effect
of a reload should now be that any configuration updates to services will
be fully "commited" by initctl reload.
Signed-off-by: Jacques de Laval <Jacques.De.Laval@westermo.com>
This patch adds support for modifying settings for the default cgroups;
init, user, and system, as well as adding up to a total of eight groups
for the system.
Services can now be assigned to a cgroup, with optional extra settings
for that particular process group. The syntax is slightly contrivied
but follows the overall Finit syntax of prop:value,prop':value', e.g.
cgroup maint cpu.weight:123,mem.max:10000
Starting with the introduction of rlimits, a group of services sharing
the same .conf file can share the same (locally "global") rlimits, and
now also the same cgroup, e.g.
cgroup.maint
service foo
service bar cgroup:mem.max:1000
This puts foo and bar in the same top-level cgroup 'maint', with an
extra memory restriction on bar for max 1000 bytes memory.
NOTE: 'mem.' is a Finit extension, a shorthand for cgroups2 'memory.'
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Since the introduction of the iwatch framework we can now safely free
the memory allocated by realpath() and prevent leaks in a more elegant
way than before.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When reloading we check if service .conf files have been modified since
the last time we read them. In 3bb1e41 we changed it so we load only
the enabled/*.conf files, which led to our no longer properly detecting
changed files since we monitor changes in what the symlinks point to.
This patch fixes that by checking the target for changes.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Since Linux 2.6.4 the SOCK_SEQPACKET socket type is available for UNIX
domain sockets on Linux. It is intended for; "a sequenced-packet socket
that is connection-oriented, preserves message boundaries, and delivers
messages in the order that they were sent." which sounds like us.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The finalize() function is a bit too long, which means it may block the
API socket initctl (from the final runlevel switch at the beginning) use
to contact os via.
We should perhaps break it up even more, but at least once like this to
give the event loop a chance to interleave with an API callback.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In particular this can happen from cgroup.c when multiple services map
to the same cgroup.events (due to being in the same cgroup)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When calling initctl early in the boot process, e.g. just when Finit is
switching to the final runlevel, it may take a few milliseconds for it
to actually be ready to process our request.
This patch adds poll() to both the write(REQ) and the read(RSP) steps
to prevent from getting weird errors when Finit is busy. The timeout
is currently 2 sec in both directions, which should be enough.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The bootmisc plugin creates lots of required system directories which
udev, and possibly also mdev, need to operate. E.g., a system which
has an empty tmpfs for /var need to populate that before we run.
The plugin loader handled this dependency implicitly before, loading all
plugins in alphabetical order. We should not rely on that for proper
operation.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This plugin should be able to start much earlier than on network UP,
it uses a UNIX domain socket to communicate so loopback should not be
needed.
Also, Finit supports runvels up to 9 (0 and 6 are special), so allow
dbus to run in all these runlevels. It is up to the user/OS to set
any policy for what runlevels to use.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
For commands like `initctl show foo`, initctl looks in the available/
subdirectory for `foo.conf`. This patch adds support for falling back
to return `/etc/finit.d/foo.conf` if the service doesn't exist in the
`/etc/finit.d/available/` subdirectory.
Static services, outside of the `enabled/` handling, live in the base
dirctory and this is what you expect from the tool. "Do what I mean"
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Older kernels (4.19) don't have the summary cpu.stat in the cgroup2
root, so let's ignore that problem and return zero.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In debug mode it's highly confusing to see Finit load available/*.conf
files when you expect it to only load finit.conf and enabled/*.conf,
so let's keep the dangling symlink check to itself and actually load
and parse from enabled/ as it was intended :)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Sneaky bug, when switching between different sets of configurations, a
new instance of a previously removed svc can have its condition removed
by svc_gc() of the old instance. This patch prevents such accidents.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Having removal status stored in the dirty status resulted in removal
status being forgotten when a service was marked as dirty, for instance
when a dependency was updated. This side effect of marke_dirty seems a bit
unexpected and instead of adding exceptions to the logic for when marking
a service dirty - let's separate the two things (dirty and removed) from each
other.
Signed-off-by: Jacques de Laval <Jacques.De.Laval@westermo.com>
More often than not, the file to write to in sysfs changes rather than
the value. This patch changes echo() into a fnwrite(), flipping what
is vsnprintf()'ed, and adds a stupid str() function that converts any
value (float/int/double/uint64_t) to a static string buffer.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The strlen() function can easiliy go out of bounds. Use memchr()
instead, we have the max buffer len as argument anyway.
Also fix call to sanitize() which used wrong length.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Replaces previous cgreaper.sh functionality for release notification and
cleanup of service groups.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Since the cgroups support in Finit is not yet officially released, we
decided to change the back-end to use cgroups v2 instead of the aging
and rather clumsy cgroups v1. Even this initial refactor is a lot
easier to read and understand, more can still be done since there's
a lot of concepts, data values and the ilk that can now be shared
between different controllers.
Still ToDo: inotify for cgroup.events to clean up leaf nodes, which
in cgroups v1 was handled by cgreaper.sh. This is fixed
in the next commit in the series.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Even systemd have collapsed a few of the cgroup controllers into a
semi-unified hierarchy and uses this approach. We just take it to
the extreme and have collapsed all of them (like cgroup v2).
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Two major bugs: `if (!cg)` and missing `strdup(path)`.
Also convert to use std hash table for lookup of previous cpu load value
for a given cgroup path. The hash table is sized after the current num.
rows on the screen -- resize currently not supported. The value given
to hcreate() should be 25% greater than the estimated num of entries,
but we take a wild guess just to make sure we don't run out of space at
runtime.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Fix obvious refactor mistake in cpu.shares assignment
- For unified memory hierarchy we need to set .use_hierarch=1
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The ps command currently only lists processes in the three main control
groups: init, system, user. Kernel threads are not show at all.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
As of now, the default finit cgroup behavior is to use a unified
hierarchy of controllers under /sys/fs/cgroup/finit.
We mount cpu,cpuacct,cpuset,memory (if available) and gain the
ability to control our three major groups: init, system, user.
The default CPU share setup is ~10% for init and user, and 90% for
system. These are guaranteed CPU shares to ensure we do not starve
PID 1 or user processes. Support for configuring these limits will
be added in a later commit.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
With the new practise of keeping record of process pid files, we no
longer need to log/update when reading back the same PID we already
have on file.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The previous patch just added dynamic tracking of non-declared pid
files, so we no longer need to make stuff up.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Services that create their own PID files usually don't declare one with
Finit. This patch adds support to track those PID files anywayt at
runtime for the purpose of identifying match svc_t when a PID file is
removed, i.e. when a service exits.
- On IN_CREATE the pidfile.so plugin saves the pid file name in svc_t
- On ON_DELETE the pidfile.so plugin finds svc_t based on pid file
Quicker tracking and less dead code, win-win.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Transitioning to runlevel 0 or 6 handles graceful shutdown of any
managed run/task/sysv/services. So we can replace the old 2 sec delay
with a shorter one for any non-managed still lingering process.
Also, some minor cleanup.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
To aid with debugging, highlight if env file, binary, or both are the
missing component(s) and causing status 'missing'.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Protect against corner cases where pid conditions are not cleaned up.
We don't want such conditions to remain asserted when the process has
terminated.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When we try to start a service/run/task we call whichp() to see if the
binary exists, either tha absolute path given in the .conf file, or in
the $PATH we run with. If binary, or the env: file, doesn't exist we
now set svc_missing() state.
On `initctl reload` we unblock the service to be able to check again.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch fixes a few really hard problems wrt PID files:
1. Listening for IN_CREATE events means we get notified immediately by
the kernel when someone calls open()/fopen() on a PID file. Reading
the contents returns 0, thank you atoi() ... so we drop IN_CREATE
and instead look for IN_CLOSE_WRITE, there fixed it! Not quite ...
2. Some programs, like Zebra, and other Quagga/Frr daemons, don't
close() their PID files after creation. Instead they ftruncate()
and keep them open, and locked. Presumably to get a mechanism to
detect already running instances -- messes life up a bit for the
rest of us though. So we need to read files after IN_MODIFY too.
3. We also want to track IN_DELETE so we can deassert conditions when
services exit gracefully and clean up their PID files
The rest fo the commit is debug instrumentation changes.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In 7447192 we dropped support for 'cond set' and 'cond clear' commands
with the motivation they were unsafe and sent the wrong message to the
user. That was true, but mostly because it was too generic and required
the user to call `initctl reload` to apply the changes.
This patch restores the behavior, albeit in a very reduced and simple
format. All conditions set with this command are constrained to the
'usr/...' namespace. No subdirectories are allowed. The argument to
the 'cond set|clear' command is disallowed if it contains '/' or '.'
but anything else is supported, for example:
initctl cond set foo:2
creates a static/oneshot condition in /run/finit/cond/usr/foo:2
These conditions are static and are fully handled by the user. The
initctl command is the recommended, and only supported, way of setting
and clearing usr conditions.
This patch also includes a new plugin, usr.so, which is a very simple
inotify plugin for the /run/finit/cond/usr/ directory. When files are
created or removed here the plugin tells the Finit condition engine to
update and trigger service changes.
For instance, the following service is not started by default at boot:
service <usr/foo> myservice -- MyService
However, as soon as `initctl cond set foo` is called, myservice starts.
Consequently, it is stopped when `initctl cond clr foo` is called.
Another major difference from the original is that this implementation
doesn't send IPC commands to create/delete the conditions. This makes
calling these new commands non-blocking so they can be used very early
in the bootstrap, by plugins, if needed.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Use _PATH_foo for all condition paths, *with* trailing /
- Read condition file first, may not exist, in which case we save time
- Change from libte makepath() to mkpath(), this changes from hard-coded
0777 perms on all cond dirs to 0755 -- possible security fix
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Provided a configuration that looks like this:
ospfd.conf:
service [2345] <!pid/zebra> log ospfd -A 127.0.0.1 -u root -g root -- OSPF daemon
zebra.conf:
service [2345] <!> log zebra -A 127.0.0.1 -u root -g root -- Zebra Routing daemon
If zebra.conf is changed, we restart it when `initctl reload` is issued.
This change ensures that ospfd is also restarted, because ospfd depends
on zebra, we must restart it too.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Check if ifname contains double periods, this should *not* be a valid
name, though eth0.10 is, et0..10 is not. Should protect better against
directory traversal attacks.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Fix ev->len validation; must check against sz read(), not total buffer
size. Also, fix off-by-one in comparison.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Fix ev->len validation; must check against sz read(), not total buffer
size. Also, fix off-by-one in comparison.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Fix ev->len validation; must check against sz read(), not total buffer
size. Also, fix off-by-one in comparison.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Check for spaces and slashes in interface name to prevent path based
attacks. Found by Coverity Scan.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This is a major refactor to use the same construct as in the pidfile.so
plugin to parse kernel inotify events for when TTYs are added removed
from the system.
Found by Coverity Scan.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Align the two implementations in logit.c and utmp-api.c
- Use libite APIs to handle common constructs
- If gzip fails, don't remove rotated-to file
- Don't try gzip if rename fails
- Issues found by Coverity Scan
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Ignore EBUSY errors, the kernel has the ability to automount /dev as
soon as the rootfs has been mounted. This may be added to procfs and
sysfs later, so we make this a general change in fs_init().
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Decleare some return values with (void)fn(), for cases where
we don't care (dropping table headers), or best effor
- Check return value from fgets() and chdir() in some cases that
are valid, i.e., continuing execution is pointless
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
No point in using rq.data, which could have been modified, instead use
the input argument to the function in the error message.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
While skimming through the results of the latest Coverity Scan, I
discovered that that the reset logic of global rlimits was broken.
This it seems to have been since its first introduction in Finit.
We fix this by reading initial rlimits at bootstrap, then for each
reconf, including the first, we seed global rlimits with the initial
ones -- thus resetting between each reconf.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The utmp_set() function allows id==NULL, so default the line to NULL and
avoid parsing empty lines. Which is better code anyway.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Mostly used during development, doesn't really provide any value to the
user at normal runtime. Leave it commented out though so user can do
debug themselves if needed.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Refactor screen_init()
- use native impl. of TTY probing from pimd project
- check if TIOCWINSZ works
- check if we're running in watch(1), for initctl
- check if ANSI goto(999,999) escape seq. works (invasive)
- fallback to 80x24
- Drop screen_exit()
- Rename screen_init() to get_width(), for now, matching pimd
- Relocate call in main() to banner(), first fn to write to TTY
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
With the recent changes to the condition handling it has become more and
more evident that the canonical reference for a task/run/service is the
NAME:ID representation. Up until now we've kept the older JOB:ID for
some sort of compatibility fallback.
This patch removes the support to simplify maintenance going forward.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This is quite possibly the ugliest pieces of code in this project.
It is a quick fix to the problem with strtok() to split up the cmd into
cmd + args[]. Without it wordexp() will later get very cranky about
trying to expand `"Partial` strings from commands like this:
/sbin/udhcpc-wrapper.sh -f -S -V "myOS v9.99" -t 8 -T 5 -A 10 -R -p \
/var/run/udhcpc-vlan1.pid -i vlan1 -x hostname:myos-12-34-50 -o \
-O 1 -O 3 -O 6 -O 7 -O 12 -O 15 -O 42 -O 121 -a
Yes really.
It's an obviously far from perfect solution. One might even start to
question why we have an args[64[64] per svc_t and not just a cmd + arg?
Well, there's a lot of improvement potential here, let's talk!
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
If mg doesn't exist, command doesn't evaluate the second argument (vi),
so we need to use `... || command -v vi` instead. Found during demo,
because why not.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch fixes an issue with rescue mode on Alpine Linux where the
rescue shell was never properly started.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Turns out that on some systems, that has none of the first two, and
neither of the two environment variables set in ${VISUAL:-${EDITOR}},
they evaluate to 'sh /etc/finit.d/file.conf', which is true, so we
wouldn't even try mg or vi ...
This patch reverts to the spirit of Andreas Egebergs initial commit,
which turns out to be a better solution anyway :)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Both Debian and Builroot based systems use /etc/default and
Alpine Linux use /etc/conf.d, so let's just put both in by
default. If the directories exist we monitor them.
The --with-syconfig configure option is now disabled by default.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The module setting is deprecated, other mechanisms exist. This change
is to ensure we don't try to (re)load any modules at runtime, only at
bootstrap.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch collapses the two similar functions parse_conf() and
parse_conf_dynamic() into a single function. It also lifts old
restrictions on what config stanzas are allowed in /etc/finit.d
The only remaining restriction is the global rlimits, they remain
as the last setting only possible to define /etc/finit.conf which
then applies to all other services.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The enable/disable commands require either both the available/ and
enabled/ subdirectories in /etc/finit.d, or at least available/
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A system may, or may not, have the available/ and enabled/
subdirectories in /etc/finit.d. This is up to distros but
we support the following, example uses /etc/finit.d as the
FINIT_RCSD base directory:
1. No subdirectories
- enable: nop
- disable: nop
2. Only available/
- enable: checks if there's a service in available/
then symlinks to /etc/finit.d/
- disable: checks if service in /etc/finit.d is a
symlink, then removes it
3. Both available/ and enabled/
- enable: relative symlink in enabled/ is created if
service is available in available/
- disable: symlink in enabled/ is removed if exists
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Gamble a bit by redirecting stderr to /dev/null instead of command -v
- Drop vi from VISUAL/EDITOR expansion alternatives, tested later anyway
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Services that are instantiated by plugins, and thus don't have a .conf
file, tried to use uninitialized rlimits. This caused the kernel to
immediately kill those services for violating their own rlimits.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Check for env in /etc/conf.d on Alpine
- Update all services with their respective env: file
- Disable default modules, noew modprobe plugin should handle this
- Add watchdog service
- Rename syslogd -> syslog, in case we want to integrate sysklogd
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Command Edit <CONF> opens file /etc/finit.d/available/<CONF>.conf in
the editor referenced by Linux environment variable $EDITOR
If $EDITOR is not set it will try to open emacs and if emacs is not
found it will try to open the file in vim.
Signed-off-by: Andreas Egeberg <andreas.egeberg@gmail.com>
Add support for monitoring environment files for services declared with
the `env:[-]/path/to/file` option. The default path to such files has
been chosen to follow Debian and Buildroot /etc/default/*
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Services that are instantiated by plugins, and thus don't have a .conf
file, tried to use uninitialized rlimits. This caused the kernel to
immediately kill those services for violating their own rlimits.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Check for env in /etc/conf.d on Alpine
- Update all services with their respective env: file
- Disable default modules, noew modprobe plugin should handle this
- Add watchdog service
- Rename syslogd -> syslog, in case we want to integrate sysklogd
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Add support for monitoring environment files for services declared with
the `env:[-]/path/to/file` option. The default path to such files has
been chosen to follow Debian and Buildroot /etc/default/*
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Use iwatch, modeled after pidfile plugin
- Use one .conf watcher for all *.conf paths/files
- Use full path of conf file for changes, from realpath().
This fixes a long-standing limitation on unique filenames
for services, that absolutely nobody knew about
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
We don't want to show progress (starting/stopping/restaring) at
runtime, since Finit v3. Many systems hooked up to a console
get confused by sudden output, or even ansi escape sequences.
This patch drops code added recently which caused a regression
in this policy. The resulting code is even more readable.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch handles a corner case when Finit may not have detected a
supervised process has died. When a user calls `initctl restart foo`
we now send such lost PIDs to the service_monitor() for restart.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Really kill them, our monitored process may be about to restart, so we
don't want any unintended side effects from lingering children in prior
instances.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch fixes a long standing issue where removing a service from
/etc/finit.conf does not stop and unregister it. The issue was caused
by the Finit support for "protected" services, e.g. services created
by plugins like hotplug.so
To reproduce issue before this fix:
cat /etc/finit.d/available/ntpd.conf >> /etc/finit.conf
initctl reload
The NTP service now runs smoothly, as expected. Later on, we decide to
drop it from our system:
sed -i 1,2d /etc/finit.conf
initctl reload
... and the NTP service continues to run unaffected. Not what most sane
users expect.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The cond_reload() fn is called on `initctl reload`, thus we don't need
to call service_step(), since we call service_step_all() later in that
cycle. So we can drop cond_update(NULL), which calls service_step().
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
With the redesign from <svc/path/to/pidfile> to <pid/name:id> in d1fac6f
we moved to matching svc_t only against their PID, which could pop up in
any *.pid or */pid in /var/run. This patch drops the (hopefully) last
remnants of the old <svc/> legacy.
To ensure we don't try reading the PID value from socket files, like
/var/run/initctl, we add simple fnmatch() of the inotified file. Two
calls to fnmatch(), for portability reasons, not every system has GNU
libc extensions like FNM_EXTMATCH.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
* test_start_stop_service
Test that we can start/stop (via initctl) a service configured in
finit.conf
* test_start_stop_service_sub_config
Test that we can start/stop (via initctl) a service configured in
finit.d/ files
Signed-off-by: Magnus Malm <magnusmalm@gmail.com>
For now, do not mount /etc as tmpfs, but instead create the dir when
building the rootfs via test/test_root/Makefile.
Signed-off-by: Magnus Malm <magnusmalm@gmail.com>
The script testenv_enter.sh, by default, runs /bin/sh in the environment
currently setup.
A bit easier than copy pasting the old hint text printed before test run.
Signed-off-by: Magnus Malm <magnusmalm@gmail.com>
If a test defines a function 'test_teardown(), that function will be
called before the test env teardown is run.
Signed-off-by: Magnus Malm <magnusmalm@gmail.com>
This patch makes it possible to create a service with optional
arguments, similar to the systemd EnvironmentFile= setting.
The major difference to systemd, is that Finit does not attempt
to start a service if it cannot find the env. file, unless it
is prefixed with '-'.
Example:
/etc/default/syslogd:
SYSLOGD_OPTS="-m0 -r 128k:10 -s"
/etc/finit.d/enabled/syslogd.conf
service env:-/etc/default/syslogd syslogd -F $SYSLOGD_OPTS
Only downside, right now, is that changing the contents of the file
/etc/default/syslogd does not mark the syslogd.conf as modified and
a subsequent `initctl reload` will *not* restart syslogd.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch drops the stand-alone reboot binary and folds it into the
initctl tool, which now becomes a multi-call binary.
With this change the reboot/shutdown/poweroff/halt/suspend commands also
no longer default to sending signals to PID 1, instead it now uses the
initctl <--> finit UNIX domain socket API. Signals are only used as a
fallback in case of non-working domain socket. The -f,--force mode of
operation still works, where `reboot(2)` is called directly.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
On systems with udevd, or systemd-udevd, we must wait for udevd to start
before calling udevadm. This patch updates service and runtask stanzas
to the new condition system naming and adds 'log' to the udevadm cmds.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The refactor in 13893b9 caused a regression in composing service
arguments. This patch should rectify that.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Add a new test that verifies that Finit will:
- Start a service that's been added to the config
- Stop the service once it's removed from the config
The second step is currently failing.
Signed-off-by: Jacques de Laval <jacques@de-laval.se>
Simplify log redirection, probe for logit early and fall back to
use a while-loop of syslog() instead.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
By not putting logit in the same process group as the service whose
output is consumed by logit, we can send signals to the service,
and it's group, without affecting logit. This means that logit will
continue to log away until it's stdin is closed, which will happen
when the service is reaped.
Signed-off-by: Jacques de Laval <jacques@de-laval.se>
Delay duplication of stdout/stderr until after forking a logit
process, otherwise we'd have a ligering reference to stdout/stderr.
Signed-off-by: Jacques de Laval <jacques@de-laval.se>
The tzset() function sets the global variables 'daylight', 'timezone' and 'tzname'
according to the value of the TZ environment variable, or to the value of the
_CS_TIMEZONE configuration string if TZ isn't set, or to UTC0 if neither is set.
Signed-off-by: Andreas Egeberg <andreas.egeberg@gmail.com>
Modeled after systemd.show_status, currently without the 'auto' setting.
- finit.debug[=bool]
- finit.show_status[=bool]
- finit.status_style[=old,classic,new,modern]
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch reverts back to the progress/status behavior of Finit < v3.0
because this is what most users expect, including the maintainer. The
resulting code and configure script is a lot simpler to understand and
maintain:
- No more --enable-progress or --enable-progress-classic configure
flags. Instead a progress_style variable in helpers.c that can
be changed at compile time for those that really need it.
- No more 'splash' kernel commnand line option. This turned out to
be *very* confusing to many users who believed it was some sort of
graphical splash screen à la Plymouth.
Also, when Finit debug is enabled we now have a global 'debug' flag
which now alo controls if klogctl() should be called to prevent the
kernel logs to the console or not.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Default to power-off the system, even for shutdown command
- Fix -h switch for SysV init shutdown command compatibility
- Add -P switch for systemd shutdown command compatibility
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This reverts commit 8a71f2d323 because
if no other application has a working utmp then there's no poit for
Finit to have one. Instead we'll be disabling all utmp support when
running on a musl based system.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Instead of just walking /run/finit/cond, also show the source of each
condition. The hook and net conditions are hard-coded to init[1] atm.
and unknown conditions are shown as unknown[0].
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In the v4 bump we removed tar.xz archives in favor of bringing back
tar.gz. This was a bit premature and could easily cause unnecessary
headaches downstream.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Printing the progress of run-parts script just like for `rc.local`
seems reasonable. Also log a warning if any script exits abnormally.
Signed-off-by: Jacques de Laval <jacques@de-laval.se>
Purpose of script is to restore an Alpine Linux install to its default
state. Some trace elements of Finit may remain, but critical parts like
reverting back to /bin/busybox as /sbin/init are in place at least.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The SysV API compatibility layer gives too little value to be worth
the effort of maintaining it. Users are encouraged to use the
`initctl` tool instead.
Signed-off-by: Jacques de Laval <jacques@de-laval.se>
Slight reshuffle of columns so status and condition listings are more
similar. Also, calculate and adjust necessary column widths.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
With the recent change in the condition handling we've decided to put
the (name,id) tuple in focus for everything Finit.
This patch changes from job:id in the status listing to name:id instead.
In verbose mode we change to show the job:id and the command + args.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch removes the built-in inetd support from Finit. We recommend
using an external inetd instead, e.g. xinetd.
If you liked the feature set our inetd provided; filtering per interface
and port redirection, then please let us know or use the code in this
patch (MIT licensed) to recreate it. We are open to reintroducing it,
but then as a stand-alone daemon like the bundled watchdogd and getty.
So long for now, old friend.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Change service conditions from the non-obvious <svc/path/to/foo> to
<pid/foo:id>, utilizing the unique name of the service instead of the
weird composition of paths from /run and PID file names. Hopefully
making it more clear that one service's pidfile is another service's
`<pid/foo>` condition.
Note: this is an incompatible change to the condition system!
The Finit major version will be stepped to indicate this.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
From, e.g.,
Starting foo:, PID: 123
to
Starting foo[123]
or, when an ID has been given
Starting foo:id[123]
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This fixes the problem with lingering Makefile's in /etc/finit.d/ on the
target systems. We also get the new enabled services properly set up.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The initctl tool's enable/disable command can then be used to manage
these services after install. This is what most users expect.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Planned changes will directly change the behavior of conditions, and
instead of having to implement compatibility wrappers and further
complicate the code, we've taken the decision to go for v4 directly.
This allows us to also rip out the complex inetd support.
Other changes in this commit:
- Revert back to .tar.gz distribution archives, by popular demand
- Add .sha256 checksum for .tar.gz archive
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
We have our own subdirectory alread in /run, for conditions, and the FHS
recommends services maintain their own subdirectory if they have >1 file
for runtime storage.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The <svc/foo> condition was created to synchronize starting services,
hence the abbreviation. Example: the Quagga ripd needs to start after
the zebra daemon to ensure its UNIX domain socket is active, otherwise
events may be lost.
However, considering that synchronization was implemented with UNIX PID
files, e.g. waiting for /var/run/quagga/zebra.pid to be created, the
condition abbreviation name <svc/foo> was hard to understand by most
newcomers to Finit. To make matters worse, a new feature to track or
even create PID files for services that don't create one themselves,
using the syntax 'pid:/path/to/foo.pid' was added.
Connecting the dots between these wasn't obvious.
This patch renames service conditions pid conditions and also adds
a compatibility wrapper to the Finit .conf parser. Any condition
given in old .conf files with 'svc/' prefix are internally renamed
'pid/', along with a LOG_INFO notice in syslog.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This to ensure that services, and conditions they may create, actually
are recorded in the condition subsystem.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The recently updated pidfile plugin now also watches the subdirectories
in /var/run, but for that to work it must witness the creation of these
subdirectories. The bootmisc plugin creates several, e.g., /run/quagga/
in which PID files like zebra.pid are created.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Absolut paths are only necessary in case of ambiguities
- Without absulute paths conditions are shorter, e.g. <svc/syslogd>
- Drop <net/lo/up> condition for SSH daemons, not necessary
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
As documented in the kernel docs and systemd[1], the default system
console is the first listed in /sys/class/tty/console/active, which
is the reverse order of console= given on the kernel cmdline.
Some distros don't have console= on their default command line in
their bootloader, e.g. Alpine Linux, some multiple, e.g Buildroot.
Instead of relying on the value given at configure time we probe
sysfs and open all (at most three) consoles listed. This way we
at least get the default console for our progress output.
- drop old --with-console from configure script
- drop /proc/cmdline fishing in favor of sysfs
- replace CONSOLE from configure with new console()
[1]: http://0pointer.de/blog/projects/serial-console.html
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Changing the GNU defaults is messy. The best way is to leave them
alone and let the user set their install locations themselves.
- Show --exec-prefix in config Summary, that's where the binaries go
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
From the start, the output from the 'list' command has been different
from the output of the 'show' command. No longer.
Also, drop the 'AVAILABLE', 'ENABLED', and 'STATIC' prefixes. They were
a bit screamy and superfluous. 'STATIC' wasn't even a good name for the
locally administered ones.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
All Debian based distros are moving towards a /etc/network/interfaces.d/
world. Adding support for that is too complex, so we're reverting back
to calling 'ifup -a' or 'ifdown -a'. We still guard this by checking
both for 'ifup' and the existence of /etc/network/interfaces (which in
the new world only contains a line to source per-interface files).
By popular demand, this patch also changes to bring up/down networking
in the background. Useful for embedded system bringup and containers.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Even musl libc supports %m today, as well as most syslog daemons, but
that's no excuse to use this.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Some targets, like Raspberry Pi, have both serial and HDMI console
enabled. Depending on the order of arguments on the kernel cmdline
either one were selected the default 'stderr', which finit used.
This patch adds support for parsing the console= string(s) and
opening multiple outputs for system startup/progress. In the
end, however, a getty still needs to be started on each of the
consoles to use.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
We need /proc for rs_remount_root() and conf_parse_cmdline(), /dev for
early multi-console support, and /sys for the cgroups support. All of
these may be in the system /etc/fstab, which fs_mount() later remounts.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Many systems have a very verbose kernel by default. This patch calls
`klogctl(SYSLOG_ACTION_CONSOLE_OFF, NULL, 0)`, which is sysklogd also
calls but later when it starts emptying /dev/kmsg.
We do this to get an undisturbed console while starting up.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This seems to be inline with Busybox init, SysV init and, according
to the comments in code, the intended behaviour of Finit.
The effect is that `SIGPWR` will lead to Finit issuing the syscall `reboot`
with `cmd` parameter set to `RB_POWER_OFF` (rather than `RB_AUTOBOOT`), which
in turn will lead to a halt rather than a reboot.
The effect of the above inside a PID namespace other than the initial PID
namespace is that `wait` inside the parent of Finit will report that Finit was
killed with a `SIGINT` signal rather than `SIGHUP`.
The contents of /etc/finit.conf and friends could potentially change
after mounting /etc/fstab. If, for example, /etc was to be re-mounted
from ro to rw using an overlay filesystem, we want any user changes to
the configuration to take effect.
Instead of heuristically trying to determine the correct hotplug
daemon to use (mdev/udev), defer to the user to specify it in the
configuration. Same goes for the built-in watchdog.
Traditionally, Finit has setup _some_ filesystems that are Nice To
Have (tm), using options that do the Right Thing (tm).
On the one hand, this is very convenient for users that don't
necessarily know what a reasonable mode= value is for /tmp etc. (pun
intended). It also means that mountpoints can be created if they
don't exist.
On the other hand it means that all users are forced to submit to the
choices made by Finit. Also, different filesystems where spread out
at many different points in `main()`, meaning that the fact that
`/proc` was available at a given hook point did not imply that `/sys`
was, for example.
Instead, defer _all_ filesystem setup to the user by simply calling
`mount -a`. We then ship an example `fstab` that shows how to
re-create the old behavior.
This patch to the banner "hello" is hopefully the last in this new style
progress. Previous efforts have used unicode symbols not available in
all fonts. This time we standardize on one that looks good both the
default Ubuntu Mono and Source Code Pro fonts. It's a bit small in my
preferred font, Envy Code R, but that might be a mistake in the font.
Not tested with PuTTY or Windows Hyper Terminal. I think they use the
Courier font by default, both of them, which I have tested.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Some ppl have their own '.' in service descriptions, adding anther just
messes things up and is confusing. The old style progress still adds
dots, but thats for padding up to [ OK ].
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Because we want to reserve @console for going dumpster diving in
/sys/class/tty/console/active and 'console' to mean the literal
/dev/console
This reverts commit 217df432d6.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Up until now Finit has only read /proc/cmdline to determine debug level,
single user mode, etc. This patch is one in a series to make enable it
to run also in containers.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Define MODULES_LOAD_PATH only when it's unset, this allows it to be
overridden, for instance, by passing CFLAGS.
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
This patch makes the RTC plugin a bit more stand-alone, it is now also
back in the hands of the user to set a default timezone.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Most of the helper functions around TTYs assumed that STDIN_FILENO was
already set up and unique for the give TTY they operated on. It turns
out it wasn't. This patch refactors the open() of TTYs to ensure we
do not clobber our TTY settings with multiple calls to tcsetattr() for
the same TTY.
Took a while to track this one down. Usually I don't run systems with
more than one TTY, but the Alpine system on my home server did, and boy
I've never been this close to giving up on computers, ever.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
On Alpine Linux 3.6 the tcsetattr() calls failed. This turned out to be
a deeply rooted issue not limited to just musl libc. The workaround is
to call tcsetattr() in several rounds. In particular the modem signals,
c_cflag bits, always fail, so we take a bet on Linux having set up the
terminals (hope as a strategy) and ignore that problem, for now.
Also, use TCSAFLUSH with tcsetattr(), that seems to work better and is
what BusyBox stty use.
The local CTL() macro is replaced with CTL() from ttydefaults.h, which
exists also in musl libc.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The svc_find_by_pidfile() function is called async from the pidfile
plugin, so by the time the queue is processed the origin may have
moved or been removed even. Safe to ignore.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch sets the TZ variable to a sane default, UTC. Fixing, at
least, the time restore problems of the RTC plugin.
Also, let the C library figure out DST, as the docs say -1 does ...
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When starting up a system booted from initramfs / may already be
mounted (read-only), so we can safely fsck it before proceeding
to remount it as read-write later (possibly).
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
In case we run into problems mounting /sys or /proc we should have
signals and the optional emergency shell available for recovery.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Unlike find(1), nftw(3) defaults to follow symlinks. For some kernel
configurations this turned out to be detrimental and caused the plugin
to loop forever scanning modalias files.
Also, check if /sys is mounted before even calling nftw().
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch is a follow-up to the idea introduced in 1d6737e, but this
time we make sure to always append the svc ID to conditions if their
.conf has been declared with :ID
Meaning, the following .conf:
service :0 /sbin/teamd --config-file /etc/teamd-lag0.conf
service :1 /sbin/teamd --config-file /etc/teamd-lag0.conf
results in the following two conditions:
svc/sbin/teamd/0
svc/sbin/teamd/1
With a custom 'name:foo':
service name:lag :0 /sbin/teamd
service name:lag :1 /sbin/teamd
the resulting conditions look even prettier:
svc/lag/0
svc/lag/1
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch makes the ':ID' field optional when registering non-inetd
run/taks/service etc. It has always been optional in the .conf files,
but internally we defaulted to ':1'.
To open up for more useful conditions we now default to zero/NULL :ID,
meaning the user now *must* keep track of the :ID field if they have
multiple services with the same name. This should already have been
an issue since such services would likely have conflicted with their
PID files (same name). So it's unlikely to affect any user severely.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When registering a service there is the option to set a custom PID file,
and even tell Finit to maintain that PID file in case the daemon doesn't
Until now there hasn't been a way to create custom conditions though ...
This patch leverages the new 'name:foo' argument to tas/run/services to
trigger condition 'svc/foo' (notice lack of path!) when a custom name is
set and either the default, or the custom, PID file is created.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch makes it possible to declare tty's using the magic keyword 'console',
an alias for the already existing '@console' keyword, which automatically detect
valid console(s) from the console=foo kernel command line.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The default runlevels are otherwise 2-5. Usually, however, when
debugging a system you may want to have runlevel 1 (single user
level) available to log in.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This is a more sane default, and also what systems expect, and what
other getty implementations support. I.e., unless specified, or set
to 0, the tty baud rate is zero -- which means do not change speed
at all.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The svc_find_by_pidfile() function may be called with "/run/./foo.pid",
or similar, which must be sanitized before being compared to the PID
file of each svc_t.
This patch introduce realpath() to untangle the paths and check if the
file actually exists.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Services may exist in multiple runlevels, i.e. one behavior at bootstrap
and another at runtime. If the user does not set a specific PID file to
be used as condition finit can match the wrong svc.
This patch extends svc_find_by_pidfile() to also compare the contents of
the PID file with the PID of the registered svc_t.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch removes the --enable-rw-rootfs build flag. Like OpenRC we
now check /etc/fstab instad; if `/` is listed *and* doesn't have the
`ro` flag set, we remount / read-write.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
We want to have unique cgroups per instance. I.e., a DHCP client for
eth0 should have its own cgroup separate from a DHCP client for eth1.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When stopping a run/task/service we must send SIGTERM/KILL to all every
process in the same process group. Otherwise we may end up with stray
processes like 'logit' when log redirection is enabled.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The logit tool is not just used by scripts and such, when logger is
absent. It is also used by Finit internally to redirect logging of
services to syslog and/or log file, with log rotation.
This patch reverts the default to enabled. Someone explicitly has
to disable logit now to get less functionality.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
`--disable-logit` at configure time means redirecting stdout from a
service to a file is completely disabled. Fallback to `logger` can
not be guaranteed to provide log file rotation, so all logs will be
sent to syslog instead. In case logger is also missing, a simple
redirect using fork() + syslog() is used as fallback.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch refactors redirect_null() and adds support for redirecting
stdout to console when 'log:console' is enabled. This was previously
sort of the default, but with the addition of the long-sought-after
setsid() call we needed to change things.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Usually a wrapper script is recommended, but for some use-cases it
is more efficient to just be able to use more command line args.
Example application that needs this; udhcpc
Note, we should refactor this to use a dynamically allocated array
instead of this static one. We relied heavily on static arrays in
Finit 1, when everything had to fit i shm. This is just legacy.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Services, like dbus and teamd for instance, may create their PID files
in a subdirectory of /var/run (today often /run). E.g.,
- /var/run/teamd/a1.pid -- For aggregate A1
- /var/run/dbus/pid
- /var/run/lxc/foo.pid -- For container foo
This patch adds support for dynamically adding inotify watchers to any
new subdirectory created in /var/run (discarding too deep directories).
To match services in this directory the run/task/service/sysv stanza
must contain the pid:!/path/to/pidfile.pid syntax. This pid file name
is also used to create the condition this service asserts using the
following formula:
svc/ + <dirname of service> + <subdir and file without .pid>
E.g., the case of teamd (above) gives condition 'svc/usr/bin/teamd/a1'
The special case of dbus is interesting, since it may not be a special
case, but rather the norm for services using a subdirectory. It is
handled as follows; when a new subdirectory is detected, the directory
is scanned for files matching *.pid. Matching files follow the teamd
case. The directory is also scanned for 'pid', which then gives us the
condition 'svc/usr/bin/dbus'
One last example, illustrated by lxc-start, where we want to track the
condition for the LXC container foo. The service stanza:
service pid:!/run/lxc/foo.pid lxc-start -n foo -F -p /run/lxc/foo.pid -- Container foo
This command has no leading path so the condition is composed entirely
from the PID file location:
svc/ + '' + lxc/foo => svc/lxc/foo
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
If a start/stop script returns OK we classify it as 'started' and leave
it in running state, despite having collected its PID. This way we can
track what scripts need to be called with 'stop' when changing to a
runlevel they are not declared for.
Also, clean up related debug messages from earlier commit.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Remnant from when processes were collected in service_start(), now all
handled by service_monitor() from SIGCHLD and service_step().
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch fixes an annoying thing when typing reboot/shutdown/poweroff
that caused an extra newline to be printed before displaying services
stopping.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The remaining sleep time returned by sleep is not accurate enough to be
used as a means to achieve "signal safe"-sleep. nanosleep can be used
in similar fashion instead and is granular enough for our purposes.
This issue was identified during reboot, when Finit is bombarded with
SIGCHLD, aborting the sleep that we do to give daemons a chance to shut
down gracefully. The total delay ended up being less than a second when
in fact two seconds were the intended delay.
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 adds a new plugin to Finit called modprobe. It probes in
/sys/devices after modalias files and then calls 'modprobe -ab' for
each alias listed.
For hot-plugging we recommend adding the following to /etc/mdev.conf
$MODALIAS=.* root:root 0660 @modprobe -b "$MODALIAS"
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>
This issue may arise in situations where the name of the service being
compared is a sub-string of the service we want to see if it exist.
Example:
- Two different services: teamd, teamdagentd
- They have the same id, 1 being the default if none is specified
- The service with the shortest name is created first
While checking if the "teamdagentd" service exists we eventually compare
it to the "teamd" service. Prior to this fix we only compare the names
names with the length of the existing service. Hence, teamdagentd will
seem to be the same as teamd since the first part of the string is equal
to the existing.
Signed-off-by: Jonas Holmberg <jonas.holmberg@westermo.se>
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Since sysklogd now ships an excellent enhanced logger tool there is no
need for Finit to provide its own tool for the same purpose by default.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This is a really tight check for a single "job[:id]" tuple, not much
escapes it, Coverity should be a lot more happy about our addressing
CWE-20 with this one.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This is a safer version of strtok() that makes sure we do not step
outside of string bounds. Coverity complained about this, but was
likely more concerned with the lacking sanitize() and trusting data
read from a UNIX domain socket ...
Note: not only is tokstr() not re-entrant, it is also hard-coded
to only check for whitespace as token separator.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Increase size of resulting path buffer, unlikely a real problem
- Check return value from snprintf() to detect errors and truncation
- Add logit() function wrapper to initctl, maps to _e()/_d()/_pe()
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The commands are both unsafe (insecure) and send the wrong message,
that initctl can be used to script conditions. Only plugins are
officially supported to manage conditions.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When reading data from (presumably) initctl over the UNIX domain socket
we might actually be receiving corrupt data from a malicious attacker.
This patch is an attempt at, the very least, guarding against C string
functions reading out of bounds due to non-NULL terminated strings.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When logging out from the shell, e.g. with Ctrl-D, artifacts from that
session may remain on the current line. This patch makes sure to clear
up that line before issuing a newline and starting the built-in getty.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Refactor code to figure out device so it works for both the built-in
and external getty code paths
- Fix memory leak when user edits an existing tty device
- Replace @console in argument list to external getty
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Many users found it very frustrating that it was impossible to use
standard commands like Ctrl-U and Ctrl-D at the login: prompt. It
was never the intention to hamper users for no reason like that.
Also, compensate for cursor-up in "Please press Enter" wait-handler.
Curiously, this makes everything very neat looking also when having
'nowait' enabled for the tty.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Also, while leading with a \n for the activation text and clearing the
line before getty is called, some getty implementations, e.g. BusyBox,
write an extra \n before printing /etc/issue. For perfectionists that
want a single newline separating started services and the first line
of /etc/issue we now not only clear the line, we also move the cursor
one line up before handing over to getty.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The built-in gety in Finit forks but does not execv(). To prevent
confusion on the part of the user, this patch hides all command line
arguments to PID 1 so it won't show up in ps listings of children.
Finit currently reads its arguments from the kernel /proc/cmdline,
it has hard-coded paths to /etc/finit.conf etc. A future version
of Finit may take command line params, in which case this patch
should be moved after any getopt() handling.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The BusyBox hwclock is really bad at handling, or rather displaying,
errors properly. When the kernel signals EINVAL, or ENOENT, it just
shows that message on stderr.
This patch implements proper RTC load/store at boot/halt with quite
some improved error handling suitable for embedded systems.
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>
This patch is an attempt to address an issue with runparts scripts found
by Magnus Malm, @magnusmalm. Any script in:
runparts /foo/bar.d/
were required to have the #!/bin/sh she-bang, otherwise Finit would not
start them. He tested with the standard run-parts tool, which had no
such restrictions.
The patch not only makes sure to start scripts using `/bin/sh -c`
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
We can now rely on service_step() to continue stepping run/taks/services
until no more state transitions are made.
Signed-off-by: Joachim Nilsson <troglobit@gmail.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>
In cases where you have multiple events pending in the cache and some
event may cause later ones, already sent by the kernel to userspace,
to be deleted the pointer returned to the event loop for this later
event may be deleted.
There are two ways around this (accessing deleted memory); 1) use this
function to initialize your event loop and set maxevents to 1, 2) use a
free list in you application that you garbage collect at intervals
relevant to your application.
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>
When a process, that has been sent SIGTERM by us, takes a full 3 sec to
terminate, the event loop may have both the SIGCHLD event (where we do
the svc_del()) and the 3 sec timeout event to send SIGKILL in its event
cache.
When we call svc_del() it releases the svc_t memory, which can then be
dereferenced by the SIGKILL timer callback and we're doomed.
There are two fixes to this; 1) the event loop, that uses epoll_wait(),
can set maxevents=1 (instead of today's 10). The kernel will then drop
the SIGKILL timer event before it's delivered to the userspace process.
2) we can postpone deleting the svc_t to a "later stage" when all events
in the event cache have been processed.
This patch implements (2). A later patch will use uev_init1(ctx, 1) to
ensure the event cache handles only one event at a time.
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>
In massively parallel builds we've seen finit fail in the install phase
of the contrib section with:
ln: failed to create symbolic link '/home/bob/jenkins/workspace/WeOS-feature_5.x_igmp-mld-snooping/staging/share/doc/finit/contrib/alpine/finit.d/getty.conf': No such file or directory
ln: failed to create symbolic link '/home/bob/jenkins/workspace/WeOS-feature_5.x_igmp-mld-snooping/staging/share/doc/finit/contrib/alpine/finit.d/keymap.conf': No such file or directory
ln: failed to create symbolic link '/home/bob/jenkins/workspace/WeOS-feature_5.x_igmp-mld-snooping/staging/share/doc/finit/contrib/alpine/finit.d/modules.conf': No such file or directory
ln: failed to create symbolic link '/home/bob/jenkins/workspace/WeOS-feature_5.x_igmp-mld-snooping/staging/share/doc/finit/contrib/alpine/finit.d/klogd.conf': No such file or directory
ln: failed to create symbolic link '/home/bob/jenkins/workspace/WeOS-feature_5.x_igmp-mld-snooping/staging/share/doc/finit/contrib/alpine/finit.d/syslogd.conf': No such file or directory
This patch is a countermeasure since fixing the root cause may take a
while (to be prioritized).
Signed-off-by: Joachim Nilsson <troglobit@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>
We cannot allow pid_runpath() to return its 'file' argument because that
may be a stack variable in a helper function.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
On systems with the new /run hierarchy the compat symlink from /var/run
may be missing, or not yet be set up by bootmisc.so. This patch adds a
layer of safety to the condition layer, both set and get cond ops now
perform an adjustmed of the condition path if needed.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
In case a user forgets to type in the service to enable, disable, or
touch, we try to be helpful and list available services instead of
bugging out.
Signed-off-by: Joachim Nilsson <troglobit@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>
We must wait for udevd to be started before we call udevadm. However,
udevd doesn't create a PID file, so we must also fake this. There is
still a slight risk of a race condition: udevd not having properly
started before udevadm tries to connect, but it works OK in Debian.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This reverts commit df89cc79b9. Not all
distros (Debian, Alpine) have a dbus-daemon that supports --syslog-only
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Running Finit on a kernel or system without WDT support built-in should
not trigger an error message from Finit.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Issue #52 suggested calling service_reload_dynamic() automatically after
run-parts and /etc/rc.local. This may seem like a good idea, but not
only does it create extra overhead, it currently also freezes the boot
and fails to present a login prompt if a run-parts directory exists.
Yes, the directory can be empty, it just have to exist to trigger this
regression.
While trying to find the root cause I realized this was all just wrong.
If the user does something that requires reloading finit, they should
call `initctl reload` from the script instead.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When finit calls out to external tools, like `ifup $IFACE`, that tool in
turn may use other external tools. On systems with BusyBox our calling
`ifup $IFACE` will result in BusyBox casting a magic spell: if $SHELL is
unset it goes looking in the file /etc/passwd for the shell of $USER
which may not be set to a Bourne compatible UNIX shell, so commands like
`ip link ...` or `run-parts ...` will fail hard.
This patch adds SHELL=/bin/sh as a sane early default.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Some systems, usually those built around BusyBox, have mdev installed
but have an option to install udev. In those cases the user likely
prefers to use udev over mdev and this patch addresses that.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch introduces a new option to initctl; -b, --batch skips
screen_init(), which might otherwise leak ANSI screen resize codes
to the console.
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>
Starting in debug mode and disabling debug at runtime did not exhibit
the same behavior as if starting in normal mode and toggling debug mode
at runtime. This patch adds toggling of silent mode (progress output)
to runtime debug toggling.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The screen_init() call for each print() & C:o caused serious screen
artefacts in debug mode. This patch reworks f858d94 to only re-init
screen when toggling debug.
Also, avoid screen_init() completely if started in debug mode.
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>
On `initctl reload` we reassert conditions, i.e. bring each still viable
condition back in sync with the new reconf generation. This patch fixes
an assumption in the reassert() callback that caused the following nasty
transformation:
/run/finit/cond/net/lo/up --> /run/finit/cond/lo/up
The transformation was caused by the reassert() code assuming a /var/run
prefix rather than /run. We must check the actual runpath, or like this
patch does, use a path neutral way to find the base condition string.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The cond_init() function is called before the bootmisc.so plugin has
run. It is responsble for setting up the /var/run symlink to /run on
systems with the new layout. Therefore we must wrap COND_PATH with
pid_runpath() to create the correct runtime path.
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>
To improve debug possibilities at shutdown, keep gdbserver running even
during shutdown.
Note: The gdbserver service runlevels must be sth like [123456789] for
this to work in the first place.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
On most modern Linux systems /run is a tmpfs that replaces /var/run.
The latter is set up as a symlink to /run by the bootmisc.so plugin.
However, Finit conditions rely on the /var/run/finit/cond prefix, which
does not exist until bootmisc.so has run, which is *after* `mount -a`
has run. Therefore, to have working conditions before we run `mount -a`
we must normalize the path constructed by cond_path() to use either the
/run or /var/run (default) prefix.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This gives the operator a way to add a post-mount script, e.g. to peform
a 2nd stage mount or mount preparations, before the bootmisc.so plugin
and others run in hook/mount/all
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The job:id field can now be used to display job:INET_PORT_NUMBER, e.g.
100:16161 for job 100 localhost SNMP port 16161.
The service name field has been reduced from 20 --> 16 bytes since the
full path has been reduced to display the basename.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
An external plugin to set up /etc can use HOOK_BASEFS_UP, but the Finit
conf_monitor() must then be called *after* not before that hook, or the
inotify watchers will listen on the wrong inode.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The file plugin.h is installed to $prefix/include and used by external
plugins. Therefore it must not include, or depend on, features set by
the configure script in config.h
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This is the first patch in a series to add support for
log:/path/to/logfile,priority:facility.level,tag:ident
In this patch support for 'priority:' and 'tag:', log file support
coming later.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The SVC_RECONF, SVC_LOST, SVC_START, and RUNLEVEL_CHANGE hooks are not
one-shot, they are also not regular conditions since there exist no
mechanism to reset them from flux.
One idea was to turn them into actions, but the lost + start hooks need
to be called multiple times per trigger, e.g. `initctl reload`, which
turned out to be non-trivial to implement right now.
Therefore, for (at least) the Finit v3.1 release these conditions have
been disabled ("nop") and ignored by Finit. Only actual C-style plugins
will be called.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch cleans up the implmentation, adds documentation and also
makes sure to adjust the prefix path of a pid:/prefix/path argument.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The pidfile plugin just listens to changes in files in /run or /var/run,
so when trying to locate an svc_t from a file change we need to compare
using the proper prefix path.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
A service may now have a custom PID file, possibly because it doesn't
really create one itself. This needs to be taken into account also in
the pidfile plugin.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds support for creating, and removing, a PID file for
programs (services) that for some reason does not create one. With
Finit this is very useful since it allows us to use our condition
support even for "broken" daemons.
To enable this for a service, use the following syntax:
service pid[:[/path/to/]file[.pid]] /path/to/daemon
I.e., `pid` is a required argument if you want to enable the feature,
but the rest is optional:
pid --> /run/`basename $CMD`.pid
pid:file --> /run/file.pid
pid:file.dip --> /run/file.dip
pid:/mnt/k --> /mnt/k.pid
pid:/mnt/k.foo --> /mnt/k.foo
There is an additional feature with this patch. For daemons that run
with a different identiy one usually wants to create the PID file with
that identity, e.g.:
service inadyn -I dyn -- Dyn.com DDNS client
service inadyn -I freedns -- FreeDNS DDNS client
Here inadyn will look for /etc/dyn.conf and create /run/dyn.pid, and
/etc/freedns.conf and create /run/freedns.pid, respetively. While Finit
will in both cases assume the PID file is /run/inadyn.pid ... err fail!
To get out of this mess the `pid` argument can be used to tell Finit
what the real PID file the daemon creates is called:
service pid:!dyn inadyn -I dyn -- Dyn.com DDNS client
service pid:!freedns inadyn -I freedns -- FreeDNS DDNS client
The same composition rules listed above applies also to the `!` variant.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The service_step() function may call svc_del() on an svc from the
service_monitor(), so we need a way to tell the latter that it no
longer can dereference the pointer.
This regression is limited to v3.1, due to the introduction of the
new non-shared-memory store of svc_t.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Per service rlimit is new in v3.1. When an inetd service connection is
created we do a selective copy from the parent inetd. We also need to
copy the parent's rlimits, otherwise the child will be killed as soon
as the kernel starts it.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch increases the default wait, 2 --> 5 sec, while pending for
Finit + watchdogd controlled reboot/shutdown. We don't want to hand
back the prompt when we're not really ready yet.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch builds on top of the recently introduced "silent by default"
and support for kernel cmdline `splash` to disable silent operation.
At shutdown/reboot `log_exit()` is called, the intention is to re-enable
progress output so the user can see what's going on. So, we need to re-
set `silent` to the same setting as log_init() started with, hence the
new `muffler()`.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Automatic redirection of output was introduced in v3.0 and for the
upcoming v3.1 a configure option was added to disable it.
By popular demand this patch flips the default. One now has to
explicitly enable this feature to get redirection.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds support for restarting the API socket on SIGHUP, similar
to how SysV init and systemd use SIGUSR1 to restart their FIFO or D-Bus.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
An interface may come up with IFF_RUNNING already set, but we would
only detect IFF_UP. This patch simplfies the code a lot by pivoting
the qualifier from using ifi_change to ifi_flags, which is the actual
current status of an interface.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This is a quite intrusive change. In addition to the already reserved
runlevels 0 and 6, halt and reboot, respectively, this patch reserves
runlevel 1 as *no networking*, like the traditional SysV init did. One
of the reasons for this change is the new 'single' user mode, introduced
earlier. Most users when entering 'S' or 'single' on the kernel cmdline
expect the single user mode (runlevel 1) to be without networking.
This leaves 2, 3, 4, 5, and 7, 8, 9 as fully user-configurable runlevels
with networking.
Of course, networking can still be enabled in runlevel 1 using ifconfig
or ifupdown, or change runlevel.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
If hostname is missing from /lib/finit/rescue.conf the system will
default to the configured default hostname (noname).
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds a rescue (revovery) mode to Finit. Simply add `rescue`
to the kernel cmdline at boot and the following steps at bootstrap will
be skipped:
- Load of services/run/task/etc in /etc/finit.conf + /etc/finit.d/*.conf
- fsck of filesystems in /etc/fstab
- Remount of / to read-write
- Mount of all filesystems in /etc/fstab
- swapon
- A few plugin hooks:
- HOOK_ROOTFS_UP
- HOOK_MOUNT_ERROR
- HOOK_BASEFS_UP
- `runparts DIR`
- /etc/rc.local
Instead of loading /etc/finit.conf and /etc/finit.d/*.conf Finit loads
the file /lib/finit/rescue.conf, which can be overridden by the operator
if needed. If this file is removed (or lost), Finit falls back to start
a simple root shell, without any login.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The /lib/finit/plugins path is as of this patch not longer possible to
change. Use --prefix or --libdir instead to change the leading path.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Finit v3.1 adds support for reloading /etc/finit.conf, document what
actually is read at runtime, compared to at bootstrap, and clarify
which stanzas are for what part of the boot process.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The difference between `runparts DIR` and `/etc/rc.local` is that one
should run just before the first runlevel change (to the configured
runlevel) at the end of bootstrap, whereas the other should run just
before launcing the TTYs, i.e. after all tasks in the configured
runlevel have been started.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch is an optimization. Now that we monitor for any .conf file
changes (as soon as the event loop starts) we can skip automatic reload
of all .conf files and services if no .conf file has changed. Unless
the user issues an `initctl reload`, `init q`, or sends us SIGHUP.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
As reported in #92, systems with an udevd very early register a service
using global_rlimit[]. The change was introduced in b68c5c1 but did
not take the ordering problem into consideration, global_rlimit[] was
left uninitialized, which likely led to severely limited udevd that
was continously crashing.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Validate function argument
- Skip¹ shutdown() when closing a TCP socket, not needed
___
¹ also, shutdown() segfaults a late shutdown/reboot
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
On shutdown/reboot, send SIGPR as a heads-up to watchdogd that the
system is going down. All file systems are about to be unmounted.
It's just about the last process left running in the system, so we
give it two seconds to complete its work before we continue.
When everything has been unmounted and we're ready to call reboot(),
we send SIGTERM to the registered watchdog, to give ti the chance to
let the WDT reset the system.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When Finit enters shutdown/reboot we need to advise any watchdogd that
we are going down *before* we unmount any file systems. This to let
the user save any state, e.g. reboot counters, to disk. Right before
we call reboot() in Finit we send SIGTERM to the watchdogd to give it
the chance to use the WDT to reboot the system.
The WDT cricuitry on embedded systems is often connected to the RESETn
logic of all relevant board compoents, whereas reboot() only reboots the
SoC with the CPU. Hence, a WDT reboot is more efficient and more like a
regular power cycle, which users of embedded systems often want.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch makes it possible to control the default redirection of
(misbehaving) services output to /dev/null. With this disabled,
a service may write to its stdout/stderr and mess up the console.
By default all service/run/tasks stdout/stderr is redirected.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds a `nologin` flag to the `tty` configuration directive,
making it possible to set up really simple embedded systems with no
login.
Example, put the following line in `/etc/finit.d/getty.conf` to get
a "Please press Enter to ..." prompt before being presented with a
root shell prompt.
tty [12345] @console noclear nologin
Needless to say, this is not very secure, but can be really useful
for developer setups, during board bringup, or similar.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
In f3669c7 the difference between static and dynamic services was
removed. This led to a regression in handling internally created
services for, e.g., dbus-daemon and udevd, mentioned in issue #90.
This patch introduces a "protected" flag for svc_t to prevent the
mark-and-sweep handling of regularly loaded services.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The new condition triggered hooks requrie /var/run/finit/cond to
be set up before calling the first user-configurable hooks.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Add newline to cond generation ID, like PID files, easier when
debugging. Does not affect fscanf() in cond_get_gen()
- Update copyright years
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Until now Finit has used mtime to determine if a file has been changed,
or simply touched to request reload, when `initctl reload` is called.
Using mtime for this purpose is a monumentally bad idea since time can
be changed at any point: a user may adjust the time, NTP continously
tunes the clock, and time stamps are stored as the walltime. So if we
compare timestamps against the last time we (booted or) did reload, we
would miss .conf file changes.
This patch replaces the mtime mistake with an inotify watcher for the
following files: /etc/finit.d/*.conf, /etc/finit.d/available/*.conf,
and /etc/finit.conf. All file changes between (bootstraps and) calls
to `initctl reload` are tracked, like the mtime backend it replaces.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
TIL, using mtimes for tracking event orderings is a monumentally bad
idea (queue the nodding UNIX-beards). Mtimes are in wallclock time which
is not necessarily monotonically increasing. A user may adjust the time,
an NTP daemon will continously tune the clock and so on.
Instead, store an explicit generation number in each condition file,
which will be monotonically increased by finit on each reconf.
The following configuration directives, previously only allowed
in /etc/finit.conf, are now also only allowed in runlevel S, i.e.
at bootstrap:
- host
- mknod
- network
- runparts
- runlevel
This change is in preparation for allowing reload of finit.conf
as well as /etc/finit.d/*.conf, which we already support.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This is a prelude to a major behavioral change. The difference between
a static and dynamic service will be removed in Finit v3.1. This means
all .conf files, including /etc/finit.conf, will be re-read on reload.
However, not all configuration directives will be re-read, some will
only be applicable at bootstrap, i.e. runlevel S.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch moves the networking bit to the latter part of bootstrap,
called finalize(), in favor of starting the event loop earlier.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This change removes a long standing kernel requirement and architectural
mishap in the design of Finit v1. It is no longer necessary to include
CONFIG_SYSVIPC in the kernel to use Finit and its command line tool
initctl. It is also no longer possible to connect to the internals of
PID 1 using shmat(), the initctl tool has already been updated to use
the domain socket API.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This change is one of the required intermediate steps to remove the
shared memory store for all svc_t, this in turn to avoid any external
programs manipulating the internal memory of PID 1.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
For ease of use, allow short forms of commands, like:
initctl h
initctl c d
initctl l
Also, default to show conditions if no argument to cond is given.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
We need the name client.c for the client side of api.c, so let's rename
the client to its traditional name.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Previously UDP packets were never dropped and if a request came
from a not valid interface inetd got stuck in an inifinite
loop looking at the same packet every time and not dropping it.
Signed-off-by: Lennart Eriksson <lennart.eriksson@westermo.se>
This patch fixes the problem with run/task jobs with conditions, run at
runlevel S (bootstrap), not being given enough time to actually start
and run even once.
The new svc counter 'once' is now inspected before transitioning away
from runlevel S to the configured runlevel. A global (currently hard
coded) timeout of 10 sec is given to all run/tasks.
As a spin-off, this patch starts up the event loop much earlier than
before. Meaning the initial runlevel change at boot is now done in
a finalize() callback when all run/tasks have completed, or when the
global timeout has expired. Starting the event loop earlier gives us
the possibility to rely on the pidfile plugin to provide our run/tasks
with the conditions necessary to start.
TODO: What remains is to add similar handling to all runlevel
transitions, not just the initial one at boot.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch implements support for calling run/task jobs on the built-in
`HOOK_*` points in Finit. To map each HOOK point to a condition a new
classification was made, as shown in plugin.h and in the example below.
task <hook/mount/root> /sbin/attachubi.sh # run in parallel with other tasks/services
run <hook/net/up> /sbin/dosomething.sh # run in sequence with other commands
Please note, only rudimentary tested.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Make svc state transition to RUNNING *before* service_start(), because
in that function we may call service_step() as well, which would start
the svc again (since it was still in READY).
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Only run HOOK_SVC_START on successful start, and *after* having printed
the result of the started service, otherwise any print-outs from plugins
or tasks we start may overwrite the started service's progress.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Don't really see the point of this code anymore, was possibly an issue
before we refactored the logging subsystem. Comment out for now, and
remove later.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
If you have lots of service/run/tasks using the same cmd it's impossible
to tell them apart in debug mode. This patch logs description as well
as cmd to improve on this situation a bit.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds a 'once' counter to the svc_t for run/task jobs. This
counter is incremented when Finit calls service_start() and is reset on
runlevel changes.
Also, at the end of a runlevel each run/task have their state reset to
SVC_HALTED_STATE so they can be launched again for the new runlevel, if
so declared.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Systems running OverlayFS, or similar, on /etc may have new/modified
.conf files in /etc/finit.d. This patch makes sure to reload them
after `mount -a` has run so any configured bootstrap tasks and the
new hook callback scripts may run as expected.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch fixes a rather nasty bug in the SIGTERM+SIGKILL logic
employed by Finit when stopping tasks, e.g. at a runlevel change.
When a process terminates, after Finit having sent it SIGTERM, and the
SIGKILL timer expires *before* the timer has been cancelled, then the
timer callback would cause kill(0, SIGKILL).
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch extends the existing rlimit implementation to support setting
limits per service, run/task, inetd, and tty.
Use rlimit in /etc/finit.conf to change the global setting, which is
then inherited to each /etc/finit.d/*.conf. For each .conf file the
rlimit is reinitialized to the global finit.conf settings.
Also, add `unlimited` keyword, to replace the now deprecated `infinity`
keyword. The latter is however kept, for compatibility with previous
releases, for the foreseeable future.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch not only greatly simplifies the registration of the built-in
watchdog daemon, it also fixes a nasty race condition with an external
watchdog daemon. The INIT_CMD_WDOG_HELLO could reach finit in reversed
order, leading to the built-in daemon shutting down, but finit killing
the just registered external daemon.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Most Linux distributions, embedded or otherwise, do not need this
and only confuses the user of an OS with Finit.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Most Linux distributions, embedded or otherwise, do not need this
and only confuses the user of an OS with Finit.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Some systems use /var/db while others use /var/lib/misc, we need to
support both and cannot rely on _PATH_VARDB, since it too might not
be set properly.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When alibuEv event watcher callback has `UEV_ERROR` in the events mask
we must handle the error. Unfortunately, in most cases there is not
much we can do but ignore it or log the error.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
If the speed argument to the `tty` stanza is invalid we should not
default to some other random speed. Instead, leave the line speed
as-is, like we do when starting an external getty.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch relocates the speed parser so that exec.c can set the TTY
speed properly as soon as possible. For external getty we make sure
to not touch the TTY speed.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch makes the Finit built-in getty behave a bit more like other
getty implementations. We now not only disable ISIG but also VEOF and
VINTR when prearing the TTY for the getty (built-in or external).
Like before, it is up to the getty process to leave the TTY in a
usable state to /bin/login, so we also move the stty() call to
just before calling /bin/login in getty.c
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch moves the stty() function from getty.c to a separate file so
it can be called from exec.c as well. The fix to #84 is simply to call
stty() in prepare_tty(), which is shared by run_getty() and run_getty2()
and called before "Please press Enter ...".
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Time comparision should be >= not just >. May seem a bit silly to
nitpick like this since we're comparing nano seconds, but on systems
with no high-res timers this happens more often than you would like.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When performing an `initctl reload` with one (unchanged) service
depending on, e.g. `net/iface/lo`, its condition will not be set
to ON by the pidfile plugin unless the netlink plugin hook runs
first.
Example:
service <net/iface/lo> /sbin/dropbear ...
Which provides the <svc/sbin/dropbear> condition, will not be
set by pidfile.so during `initctl reload` because dropbear is
still SIGSTP:ed waiting for <net/iface/lo>.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
All this code did was trigger prctl() to set process name to "console",
which you could use as a simple means of figuring out if a process was
started from the system console.
There are other ways to do this, which Finit should not be involved in.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Before we call screen_init(), which in turn calls libite:initscr(),
which in turn does a lot of tcgetattr() and termios to STDOUT to figure
out the size, we need to check that we're not backgrounded, or don't
actually have a TTY. Problem reported by @wkz
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds support for a new TTY device keyword `@console` which
auto-detects the system console by reading the SysFS file:
/sys/class/tty/console/active
Embedded systems with one of /dev/ttyAMA0, /tty/ttyMXC0 or the original
/dev/ttyS0, as their active serial console can now instead use a single
line to /etc/finit.d/getty.conf to start the built-in getty on the same
TTY as the kernel already runs on:
tty [12345789] @console 115200 noclear
With no TTY defined Finit will either do nothing (default), or start a
fallback shell if enabled in the configure script.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Disable INTR, QUIT, SUSP, and DSUSP while handing over to getty. It is
up to the getty process to allow ISIG again.
This patch is due to the differences in control line setup between ARM,
x86/x86_64, and most notably PPC. PPC in particular seem to have ISIG
set by default from the kernel.
Without this patch pressing Ctrl-C before getty is started will lead to
Finit receiving SIGINT and defaulting to a reboot, as introduced in the
BusyBox init signal adoption in eeb59eb.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
In GCC 7 the -Wall infers the new -Wformat-truncation which finds
problems with string truncation in functions like snprintf().
This patch suppresses the warning by allowing only a subset of the
parent inetd service description to be copied to the child connection.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
In GCC 7 the -Wall infers the new -Wformat-truncation which finds
problems with string truncation in functions like snprintf().
This patch fixes a possibly problem in path name creation which,
combined with the scandir() function, might cause loss of .conf
files, failure to call run-parts properly, and kill services at
shutdown.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
In GCC 7 the -Wall infers the new -Wformat-truncation which finds
problems with string truncation in functions like snprintf().
This patch fixes a problem in condition parsing for very long
PID filenames which might be truncated in internal buffers
causing a mismatch in Finit condition tracking.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
In GCC 7 the -Wextra infers the new -Wimplicit-fallthrough which can be
suppressed by adding a simple comment
/* fallthrough */
Which we had, but was too verbose (and misspelled) for GCC to notice.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
In commit 34a1524 the start of udevd was refactored to allow it to be a
properly monitored service caused systems using eudev to malfunction.
This patch reverts part of that commit and adds a workaround found when
trying to reproduce issue #82 on Void Linux:
- Start a temporary udevd in the background
- Call udevadm to trigger bringup of all subsystems and devices
- Wait for everything to settle
- Tell temporary udevd to exit (new)
In the world of `mdev` this song and dance act is not required.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Finit has long since supported an @user:group syntax to services, tasks,
and run stanzas. Setting UID was implemented at that time, but setting
GID never was. This patch fixes that oversight.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch fixes an invalid use of strpbrk() causing all cond
sub-commands, except initctl cond show, to fail.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds a '-' for each runlevel a service/task is not part of.
The resulting listings are easier to read and also makes it clearer to
the user what happens when changing runlevels.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch, similar to the work done in the d-bus plugin, converts the
udevd service from a non-monitored run_interactive() task that forks
itself into the background, to a proper Finit monitored service.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch prevents output of stderr/stdout from services to leak to the
console. Use the 'log' keyword to service/run/task stanza to redirect
output to syslog.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch changes how the D-Bus plugin starts dbus-daemon, from being
started in the background to letting Finit start and monitor it.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
For some reason PPC is much more sensitive than ARM when it comes to
termios changes. This patch fixes a regression in Ctrl-C handling
after login introduced in 907595d when blocking of Ctrl-C was added
to prevent breaking the login-prompt.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch removes the following very annoying warning for TTY devices
not yet available, i.e. plugged-in to the system.
Loading configuration ............................................................................. [ OK ]
[ 11.097414] finit[1]:tty_register():Incomplete or non-existing TTY device given, cannot register.
[ 11.101457] finit[1]:tty_register():Incomplete or non-existing TTY device given, cannot register.
Mounting filesystems .............................................................................. [ OK ]
Finit will not start a getty (built-in or external) if the TTY does not
exist, but having the configuration enabled makes it possible to do a
simple `initctl reload` to activate a plugged in TTY.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
In case the kernel is incapable of handling a reboot,
power-off, or halt request we want to be able to let
the user perform some basic diagnose of the system.
The existing debug messages are good enough, and use
the correct grammar form, to be enabled always.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When collecting a bootstrap task we need to allow its state machine to
complete before cleaning them out.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
During the runlevel change from S --> 2 the state machine will pause,
waiting to collect all S-only tasks/services, before continuing.
When an S-only task/service is collected we therefore need to call the
state machine again so that it can reassert all conditions properly.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
We should not let PID 1 fail on systems where Linux is built without
CONFIG_SYSVIPC, or the libc does not support shmget()/shmat().
This workaround implements a fallback to using calloc() for PID 1,
which means the initctl tool will not work properly. A better fix
would be to refactor the shm implementation to instead have initctl
call Finit using api.c for each svc_t. This has been added to the
TODO file as future work.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Building finit with a uclibc-ng-toolchain fails with:
```
../src/helpers.h:53:43: error: unknown type name ‘va_list’
void printv (const char *fmt, va_list ap);
```
- Detail limitations in separate section
- Focus on syntax early in document
- Overhaul and simplify introduction
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Enable LXDM using:
initctl enable lxdm
initctl reload
The latter command reloads all /etc/finit.d/*.conf files and starts lxdm
in runlevels 2-5.
Remember to first edit /etc/lxdm/lxdm.conf, necessary to get a session.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch enables support for bootstrap services in /etc/finit.d/
Please note, however, that this does not mean that all configuration
directives are now allowed in /etc/finit.d/*.conf -- the intention is
only to simplify distribution setups.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Restore original file layout somewhat, it's better if we clear the space
at the end of the file for easy `cat BOOTSTRAP.conf >>/etc/finit.conf`
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Finit now supports pipes and redirects in run/task stanzas. Hence, we
can reduce rc.local to an example template.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
A run stanza blocks operation by calling waitpid(), so it will never be
caught by the service_monitor() function. Hence, we need to clean up
any bootsrap calls after waitpid(), or at least perform a manual state
change.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch extends the capabilities of task and run .conf stanzas by
enabling pipes and redirects.
Example:
task [s] echo "foo" | cat >/tmp/bar
run [s] echo "$HOME" >/tmp/secret
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Show progress when booting
- Use noclear + nowait on TTY's
- Update `loadkmap` args
Works on Alpine Linux 3.4 .. 3.6
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch aligns the two tty configuration stanzas, thus clear and wait
are now the default for both.
tty [LVLS] <DEV> [BAUD] [noclear] [nowait] [TERM]
tty [LVLS] <CMD> <ARGS> [noclear] [nowait]
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch makes it possible to disable the "Please press Enter" prompt
when using an external getty. Simply append `nowait` to the .conf entry
and Finit will spawn the getty immediately.
A future patch will add support for `noclear` as well to external getty,
as well as a change in default (=> `wait`) for the built-in getty.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
It is strongly recommended to instead use the service stanza to start
XDM/GDM, or use startx after a regular login.
Note: the `user NAME` setting was always reserved for use with startx
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The emergency shell is just a Finit debug mode. This patch adresses a
concern from GitHub issue #76, with zombie processes in this mode.
Emergency shell could be further improved, e.g. informing the real Finit
process of each collected child (zombie) to be restarted if needed.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
In commit eec32e2 support for reloading TTY configurations was added.
This patch is a follow-up to that with support for cleaning up and
removing allocated TTYs.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
With the new scheme using /etc/finit.d/available/, and symlinks from
there to the enabled directory, we need to check mtime of .conf files
using stat(), not lstat() which we need to check if .conf is a symlink.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch disables console heading and bootup progress messages by
default. Use --enable-progress to get the old behavior back, or try
the new HOOK_BANNER and HOOK_SVC_UP to run a custom progress.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When the TTY fallback mechanism is enabled tty_fallback() prints this
annoying debug message whenever *any* is process is collected by PID 1:
"Not starting fallback (%d) shell, lost pid %d", fallback, lost"
This patch removes it, and a two other useless debug messages.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch moves the plugin loader much earlier, making it possible to
provide a custom banner/logo in a plugin.
To facilitate this move we need to also move banner later and parsing
of the kernel cmdline earlier, right after mouting /proc.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch changes the traditional look of the Finit boot sequence.
Now we stick to the screen width probed by screen_init(), or max
132 chars.
Also, some minor cleanup of the currently unused print_timestamp()
method used by printv() when showing [ OK ] or [FAIL] of services
at boot.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch introduces the screen_width() method from the SMCRoute
project. The code is hereby also available under MIT/X11.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Since at least a44daf2 both run() and run_interactive() can access all
system tools in _PATH_STDPATH. A system that uses non-standard paths,
e.g. /system/bin and /apps/bin, should update _PATH_STDPATH.
For reference, see issue #69 and PRs #70 and #72.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch implemements a new feature of libite v1.9.1, whichp(), which
instead of fexist() that requires an absolute path, searches $PATH.
For reference, see issue #69 and PRs #70 and #72.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Ways to log:
- Set debug, using kernel cmdline, or edit the sources
- Change loglevel severity, default blocks > LOG_NOTICE
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The generic term for a non-running service is blocked, but a service may
be blocked for several different reasons. When a user stops a service
with `initctl stop` the intuitive expected output from `initctl show` is
"stopped" not "blocked".
When the user later restarts the service with `initctl start` it may of
course be blocked due to wrong runlevel or a missing condition. As can
be expected from the service's configuration.
The rest of the patch refactors the internal API names a bit to reflect
this change.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch is a follow-up to 1f1c2e0 which introduced the new semantics
for the very confusing quiet and silent modes.
The initial idea was to loosely follow the kernel cmdline 'quiet' option
and as a working concept this was good. The resulting code, however,
became unnecessarily complex and the configure options impossible to
explain.
With this patch the quiet mode, and thus the --disable-quiet configure
option, is removed. Finit now defaults to a sane behavior: services are
shown only at startup. The --enable-silent option works like it did
before, silencing everything.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch is the first in a series of changes to clean up the internal
logging APIs of Finit:
1. Convert log macros to use logit() for everything (this patch)
2. Set correct syslog() log level based on debug flag
3. Do closelog()/openlog() when toggling debug flag to control LOG_PERROR
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds support for enabling and disabling services in
/etc/finit.d/ by adding another subdirectory:
/etc/finit.d/available
Enabled service/run/task stanzas are by convention symlinked
to the parent dir. The initctl tool has three new convenience
commands to facilitate operating with this:
initctl list
initctl enable <CONF>
initctl disable <CONF>
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
getprotobyname() returns p_proto in host endian, so it should not be
converted with ntoh. (Note: getservbyname() on the other hand does
return s_port in network endian)
Signed-off-by: Petrus Hellgren <petrus.hellgren@westermo.se>
Check first ifup exists before using it since
this is really something only exits on some
distros an in different ways. Debian/Ubunu has
an package for this while others have it in the
initscripts package(s) , meaning the file can be
around even without the prog.
Signed-off-by: crazy <crazy@frugalware.org>
This should allow us to run 'prog' without
absolute paths. Eg:
run("/bin/foo"); -> run("foo");
However we still need absolute PATH for
checking since fexist() need full path right now.
Signed-off-by: crazy <crazy@frugalware.org>
That should never be needed , however I saw
already systems with broken paths.h so better
have something around in case something breaks.
Signed-off-by: crazy <crazy@frugalware.org>
Also, update the service help text in doc/config.md to include info on
both runlevels and explain the condition in the listed example.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch to the logrotate() function extends the log rotattion of a
file with a gzip of .2 and older log files. If gzip is not available
in $PATH then @num files are left uncompressed.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds a simple log-rotate function to the UTMP, WTMP, BTMP,
and lastlog files. Enabled by default, disable with:
configure --disable-logrotate
Even though it can rotate /run/utmp it is unlikely this file will grow
that much during a system's uptime.
The hard-coded defaults are to keep up to two (2) previous versions
of the files and rotate on file size >= 100k.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
For issue #64 we need to have /proc/mounts, or /etc/mtab but that's
usually symlinked to /proc/mounts.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Remove verbose of initctl cond, and replace it with 'initctl cond dump'
Show all conditions if they are in flux/on even if there are no other
services depending on this condition.
Signed-off-by: Mattias Walström <lazzer@gmail.com>
We have repeatedly seen use-cases when sub-second resolution for
updatating the mtime of files have been needed. Yes, all those
cases have been Autobots.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch improves the error handling of initctl so that it returns
non-zero if a service does not exist.
$ initctl <start|stop|restart> SVC
$ echo $?
1
In verbose mode an error message is also returned:
$ initctl -v <start|stop|restart> SVC
No such service SVC
$ echo $?
1
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch breaks out the JOB:ID parser from api.c, placing it in a new
function called svc_parse_jobstr().
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
We want to emulate the behavior of the reboot() syscall on success.
Primarily for a coherency/symmetry, but also to prevent printing
a new shell prompt in the middle of system shutdown messages.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When finit completes quicker than one second it will
not find if any configurations has been changed.
Signed-off-by: Mattias Walström <mattias.walstrom@westermo.se>
If a service depend on the service last in the list the application
will be kept in flux state forever.
Signed-off-by: Mattias Walström <mattias.walstrom@westermo.se>
This patch changes the confusing logic in all #ifndef INETD_DISABLED
statements to instead be #ifdef INETD_ENABLED, which is quite a bit
more readable.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This (initial) patch for issue #56 adds a very basic validation of the
device before attempting to start a getty on it.
TODO: Verify a USB/serial device can be plugged in at any point at
runtime, either automatically start getty or by `initctl reload`
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch (untested) patch calls `service_reload_dynamic()` after both
run-parts (if directory exists) and after `/etc/rc.local` has run. The
intention is to reload any services modified/added/removed by a user
script so the system is properly up to date.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch allows all services to go from READY -> RUNNING, this to
prevent started inetd connections from being treated as "stubborn"
and inadvertently killing them off after a few seconds.
The same actually applies to run/task applications.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch fixes issue #51 by reverting b4b63d3, which is not needed
anymore since service callbacks have been removed from Finit3.
The `sig_unblock()` function, called for each forked off child, should
now be balanced with caught signals.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
We can safely skip tmpfs, nothing to clean from previous boot there.
In fact, if we clean it we may spoil things for udev, which saves
pre-boot files in /run/udev.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch removes the long standing Watchdog daemon from the TODO list.
We now have a bare-bones watchdog service built-in to Finit, with
support for handing over to an external, and possibly more advanced,
using the initctl API.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds a simple but effective watchdog daemon with support for
handover to an external daemon, should one register using the API.
Disabled by default, enable by:
configure --enable-watchdog
The watchdog forks to the background, opening /dev/watchdog setting a
three second timeout, and kicking every second. At shutdown/reboot the
daemon will receive SIGPWR from Finit to exit and cause a WDT reboot.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
To prevent returning the prompt too soon, and thereby messing up the
output from Finit, wait a bit after successful delivery of signal to
reboot/halt/poweroff.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds initial support for registering a watchdog daemon with
Finit. Needed for situations when you want the system to actually be
rebooted by the watchdog timer (WDT) circuitry rather than the kernel.
The initctl API has been extended with a INIT_CMD_WDOG_HELLO command
that is used to both register and "ping" Finit periodically. As long as
Finit responds (with an ACK) the watchdog daemon knows Finit is alive.
At shutdown Finit stops all services (except kernel threads and daemons
marked with @ in the first character of their process name) and, if a
watchdog has registered, SIGPWR is sent to it when Finit has finished
unmounting etc., just prior to kernel reboot/halt/poweroff.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Now that we change runlevel at shutdown/reboot, we also need to restore
terse mode before calling the shutdown hooks, like before.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch replaces kill(-1, signo) with a more fine grained
do_kill(signo) that traverses each /proc/PID, skipping kernel
threads and special [0][0] == '@' processes.
The reason for this patch is not only future compliance with
freedesktop.org standards, but also a way of not killing any
critical processes at shutdown, e.g. mdadm or watchdogd.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The shutdown hook is supposed to run right before services start
receiving SIGTERM. Change due to previous refactor.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch moves both the definition and the call to bootclean() from
finit.c to the bootmisc plugin. We want to call bootclean() *after*
any /run and /var file systems have been mounted.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- New requirements section about what Finit expects from the system
- Remove commented out `udevadm settle` code, now in README
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
On systems with systemd-udev/udevadm the trigger addition of devices at
boot wrecks havoc of /dev/console. This patch forces Finit to go silent
by default on such systems. Far from ideal, but since the actual root
cause for this messup is unknown this will have to do for now.
Also, add a settle timeout of 120 sec to the udev device tree population.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch factors out the fgetint() fallback code for parsing
/etc/services and /etc/protocols. Useful on systems with a
malfunctioning C library.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Without trigger, kernel modules won't be loaded automatically. Also
devices are not managed. For example, i915 was not loaded after boot
and my network card was not renamed from wlan0 to wlp3s0, which means
it was not handled properly by udev.
Signed-off-by: Wang He <xw897002528@gmail.com>
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch fixes a long-standing issue with how Finit handles shutdown,
reboot and poweroff -- and even runlevel changes to runlevel 0 and 6.
Prior to this patch sig.c:do_shutdown() was called immediately on any
of the above events, disregarding any services that a user might have
wanted to run as part of the shutdown/reboot.
With this change the handling is unified in all frontends to instead
do a runlevel change followed by the do_shutdown() action.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The /etc/nologin file must be set as soon as the runlevel change to
0/1/6 comes in, not when done with runlevel change and services have
been started, if any.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
As a last ditch effort to understand why an embedded system doesn't
boot, the operator should be able to see as much logs as possible
when enabling --debug mode on the kernel command line.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds an `--enable-fallback-shell` option to confiugre.
When enabled Finit will start `/bin/sh` on the console, but only
if there are no active TTYs running in the current runlevel.
With this it will be easier to do board bringup with Finit, but it also
enables using the fallback shell in a rescue mode (runlevel) where no
TTYs are allowed to run.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Also changes the default to set $HOME to / instead of nothing. This can
of course be improved immensely. Pull requests always welcome ;-)
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch removes the now heavily outdated (and non-working) support
for callback plugins. I.e. plugins that attach themselves to services
listed in /etc/finit.conf and can be queried to determine if a service
should be started or stopped.
The Finit3 support for adding/removing services at runtime with plain
text *.conf files in /etc/finit.d and `initctl reload`, this old, and
rather cumbersome service callback feature, is not longer supported.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Add support for registering callbacks to be called after a given
timeout.
Use this to implement forceful termination of services that refuse to
terminate upon receiving a SIGTERM. If the service PID is not collected
within 3 seconds, send a SIGKILL to it.
Also, rework restarting of crashing services. When a service crashes for
the first time, try to restart it immediately. If it crashes again, wait
a few seconds before trying again. Just as before, if it continues to
crash, block the service.
This patch prevents double critical/error messages from being printed on
the console when there is no syslog daemon running yet.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Delay setup of initctl plugin to after the base filesystems are up and
after the bootmisc plugin has run.
This patch factors out the I/O initialization of plugins so it does not
have to run when plugins are loaded. Instead, plugins can now call this
API to register an I/O callback when they are ready.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
In UTMP a terminating zero in string fields is optional, so we need to
take that into account when preparing entrys.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch makes Finit require libuEv v1.4.2, a minor bugfix update, and
libite (-lite) v1.8.2, which is quite a bit more than just a few bug
fixes. The most relevant fixes are the removal of implicit logging for
touch(), makedir(), makefifo(), and erase() inline functions. The
release also removed implicit logging to stderr on error, as well as a
a few build fixes for running on musl libc.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds a very special debug mode to Finit. With this feature
enabled the actual duties of PID 1 is forked off early to a child. If
that child ever dies, usually due to a SIGSEGV, this wakes up the real
PID 1 which lauches a debug shell on the console.
Remember to disable 'quiet' and enable '--debug' on the kernel command
line to get all the debug logs -- which these days goes into the kernel
log in /dev/kmsg -- simply `cat /dev/kmsg` and use Ctrl-C to get the
shell prompt back.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Very early, before syslogd has started, we have traditionally been
forced to use stdout/stderr for debug, warning and error messages.
With this patch we can now rely on /dev/kmsg to preserve all logs
from early Finit problems. When syslogd/klogd starts up they read
/dev/kmsg and copy logs to /var/log/* files.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Refactor getent() for improved separation and readability
- Warn and exit if /etc/protocols or /etc/services is missing
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Adjust debug levels slightly and add _w() macro for LOG_WARNING,
useful when having /dev/kmsg as backend. The latter outputs any
log <= LOG_ERR to console as well.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch fixes a build problem when configured without inetd support.
Signed-off-by: Markus Svilans <msvilans@aeonyx.ca>
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Add support for SysV init setenv to activate poweroff
- Update help text considerably to be more helpful
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The UTMP db tracks currently logged in users and WTMP is an audit trail
of all user logins and logouts, as well as runlevel changes and reboot.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The new logit() function takes care to print to stderr if syslogd has
not yet started. The _d(), _e(), and _pe() macros have an additional
requirement: to always print on stderr.
After the boot we also want to see what happned during, so this patch
simply adds syslog() support to _d(), _e(), and _pe().
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch removes internal logging macros and adds support for logging
to stderr until a syslogd is up and running, i.e. /dev/log appears.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch removes accounting for all processes to instead implement the
traditional SysV getty accounting. (Telnet/SSH et al maintain their own
accounding for UTMP.)
TODO: WTMP support
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch fixes the /etc/grub.d/40_custom generation for the Debian
sample so that it properly extracts the UUID For /boot and /
Note: the maintenance free symlinks /vmlinuz and /initrd.img may not
work properly with /boot on a separate partition or disk. If only
the symlinks where in /boot as well ...
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Instead of ugly #ifdefs we now probe for mdev or udevd at runtime. Take
care to check for udev-finalize and location of udevd, it differs a lot
between distros.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds initial support for handling MD RAID arrays. Adding
a pass at the very end of the shutdown sequence to signal any external
RAID controller to clear its state before we proceed to halt/reboot.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds support for a more fine grained approach to what
filesystems are unmounted at shutdown/reboot. This so we later
can add support for `mdadm --wait-clean --scan`, which relies on
/proc, /sys, and /dev being there before we call reboot().
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Also, this code will be refactored soon to be a part of the finit
binary, like telinit, and then we will be called after unmount to
do a forced halt/reboot/poweroff.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch is a complete rewrite of the Finit reboot command. Not only
does it bring it up to speed with the new signal model, but it also adds
new features like poweroff, halt, and suspend -- including a forced mode
that goes for reboot(2) immediately.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Still TODO, replace `run_interactive()` start of dbus-daemon with a
proper service. Possibly only service_register() is needed.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch fixes the ordering of UTMP events. The first event that is
expected in /var/run/utmp is reboot, next is the runlevel change to
the configured runlevel, e.g. from S --> 2.
Let the bootmisc plugin handle this, it knows when /var/run/utmp has
been created and is writable. It is not the eact boot time, but close
enough for most usees.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds support for initializing /var/run/utmp with the initial
reboot as well as a shutdown record in the UTMP db.
Also, the run level change now properly records ~ and ~~ as line and id,
respectively, and the kernel release and time of each UTMP record is now
set properly.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Minor coding style cleanup, code simplification, and change service
'crashing' status text to 'crashed' to fit column width.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Simple wrappers for the signals Finit responds to. Will need complete
rewrite when support for delayed reboot/halt is added.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The condition flux state does not work like that, so keeping
this sub-command is only confusing to the user.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
These scripts help a user to configure, build, and install Finit
correctly on a Debian 8 (Jessie) server install.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The fs.fs_type is only for *BSD, we hard-code it to "rw"
in the meantime. Should be safe in most cases.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The debug mode cannot be used in run_interactive() that early, so we
must disable it during the complete fsck run.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds support for the following /etc/fstab API's on systems
that do not have them, e.g. musl libc on Alpine Linux.
- setfsent()
- getfsent(), and
- endfsent()
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Run fsck much earlier, as soon as we can in fact.
The first 13 characters of the UUID, label or device name should
be sufficient to identify the device, without violating max width
of 78 chars.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds support for running fsck on all file systems listed in
/etc/fstab with a passno > 0. The fsck runs sequentially, starting with
the root fs (passno 1).
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Disabled until we decide on config to disable/enable. It is quite
annoying to not be able to see the boot messages with it on ...
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Plugins without declared name registered with full path + ext
=> Strip path and extension
- Plugins registered with __NAME__ => strip extension
- Do *not* call dlclose() from destructor, must be called by Finit
Also, some minor cleanup and code simplifcation.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Fix compat INIT_CMD_ defines so Finit clients can talk to SysV init
- Add setenv support, only for INIT_HALT={POWERDOWN,HALT} to runlevel 6
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adopts the BusyBox init signals for handling halt, reboot,
and poweroff. The SIGINT and SIGPWR signals still behave the same as
before, even though they likely will become configurable in a future
release.
Note: the disabling of Ctrl-Alt-Delete (SIGINT) is also removed!
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
That's maybe a bit unfair. This patch implements a brief version of
what is really needed to safely unmount all file systems on a modern
Linux distribution. Yes, it's this insane. (Who am I kidding, it's
worse! Just have a look at the ancient scrolls hidden in your /etc!)
Here is where we use the new plugin_exit() and api_exit() API's from an
earlier patch. Making sure to exit and close any kernel descriptors.
Then follows a bizarre spell cast on leaking descriptors, rebooting in
a child, remounting / as read-only, and a whole slew of other R rated
stuff to prevent mount/umount from returning 32 ...
Stay safe people, use protection always!
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
FIFOs, PID files, and other non-devices belong in /var/run (or /run
these days), not /dev -- as per FHS. Compat with Debian SysV init.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The TTY handling in Finit has always been a bit of a patch work. This
commit is an attempt at a first cleanup and simplification.
Included is a brand new built-in getty which should work fine on both
virtual and serial consoles. It is however completely untested on the
latter serial consoles.
Still TODO: add support for /etc/securetty, add support for actually
setting TERM when calling /bin/login.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Embedded Linux systems usually employ BusyBox mdev. This patch assumes
that all non-embedded systems employ udev. Adding support for cleaning
up the udev db after the initramfs, or mounting /dev if that not done.
It also runs the udev-finish script at the end.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Look for 'auto' *and* 'allow-hotplug' in /etc/network/interfaces when
bringing up Debian/BusyBox interfaces at boot.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
If the user specifies no 'tty /dev/ttyN' in finit.conf this code
took upon itself to add a backdoor to the system. Let's remove
it and rely on the operator deciding what is best practise.
With this patch no getty, or fallback shell, will be started if
no tty line in finit.conf is available.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds prototype support for the Debian/Ubuntu/Busybox network
configuration file /etc/netork/interfaces. If this file exists Finit
will call `ifup` for each (non-commented-out) interface marked `auto`.
With this implementation we block boot until all ifup commands have
returned, which is less than ideal. A better approach would be to ifup
only loopback and create deferred tasklets to be run in parallel with
the rest of the boot.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch fixes a long standing problem with TTY's. The original code
tried to workaround a limitation in the console of some embedded systems
that was detrimental on actual TTYs.
As an added benefit, the console specific "Press Enter" prompt for the
console port is now available on all TTYs -- meaning no getty needs to
be started and kept needlessly in the background until it is needed.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
We never get any NEWLINK message for lo since it as an interface exists
very early. So we add this workaround when lo comes up so services can
depend on exists for lo as well as for other interfaces.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The introduction of conditions to Finit only focused on
services (monitored daemons) and not parallell one-shot
tasks or blocking one-shot runs.
This patch enables condition support for 'task' and 'run'
stanzas in both finit.conf and finit.d
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
By default the urandom plugin will use /var/lib/misc/random-seed across
reboots to seed /dev/urandom at boot.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Do not tag log messages with service description, but use process name.
Possibly add :ID later to denote instance if multiple instances exist.
Also, add priority daemon.info log level.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
If user has no start script fall back to set up at least loopback. This
fixes (at least) a problem on Alpine Linux where `ifup -a` returns error
if `lo` is already up.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Modern systems today use a RAM disk for /run and /run/lock, with
symlinks to the FHS locations in /var/run and /var/lock. See the
following link for details http://lwn.net/Articles/436012/
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds protection against a common inetd attack vector wherein
the reply port to UDP inetd services is forged to an internal inetd
service port.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch replaces the old 'initctl emit <EV>' idea with a more
full blown condition generator:
initctl cond <set|clear|flux> <COND>
This aligns better with terminology used elsewhere in the new Finit
service state machine and dependency handling already documented.
The 'flux' sub-command is mostly intended for simulation/test of
Finit itself and should perhaps not be documented.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This is a first effort at cleaning up and consolidating all information
about the new service state machine and how conditions control this
state machine.
Also, clarified and added sections for all documents regarding how
services and conditions relate.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Some vendors provide their own Netlink plugin to Finit. This patch
makes it possible to disable the default netlink plugin from being
built. However, even before this patch it was possible to overload
the plugin. This just discards it from being built.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The AC_PLUGIN() could not properly handle if a plugin is to be enabled
by default. This patch adds support for outputting the correct help
text.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Libraries and system headers should be included with <> instead of "".
This makes a great difference for the automatic dependency tracking.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Prune standard configure flags and focus on the most important, whatever
they may be. Mention --disable-inetd and describe how --enable-static
works.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch fixes regressions in --enable-static introduced with the
conversion to the GNU configure and build system.
The default link flag to libtool is set to -static-libtool-libs, meaning
not a fully static build -- the C library will still be used as an .so
which is usually what people want -- whereas libite (-lite) and libuEv
are linked statically.
$ ldd /sbin/finit /sbin/initctl
/sbin/finit:
linux-vdso.so.1 => (0x00007ffffde62000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6979ad8000)
/lib64/ld-linux-x86-64.so.2 (0x000055d893e96000)
/sbin/initctl:
linux-vdso.so.1 => (0x00007ffed0dd6000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007feb3a29c000)
/lib64/ld-linux-x86-64.so.2 (0x00005556ebd2b000)
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Now that we have a proper GNU configure script there is no such thing as
lightweight, and the respected environment variables are listed at the
end of `./configure --help`
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch corrects a long standing issue with Finit. System initial
bootstrap runlevel must be set to 'S' (0), not the configured fallback
runlevel 'RUNLEVEL', which likely is '2'.
Also, minor cleanup, reduce code duplication.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The new state machine handling is not necessary to export to external
plugins, so this patch reduces the exposure of the global variable sm
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Setting O_NONBLOCK on an inetd server socket may fail, we
must check for this or the event loop may stall and block
Finit completely.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Make sure to check return value of remove(), it may actually signal
something useful. Log useful errors.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Must check return value from open(), found by Coverity Scan
- Minor refactor (and cleanup) to reduce code complexity
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Must initialize init_request buffer to zero before communicating with
Finit. Found by Coverity Scan.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
If no console is configured, then the following code gets executed:
int conf_parse_config(void)
{
...
char *fallback = FALLBACK_SHELL;
...
tty_register(fallback);
...
}
int tty_register(char *line)
{
...
cmd = strtok(line, " ");
...
}
FALLBACK_SHELL is constant character array and strtok tries to modify
the first argument, which causes a crash.
Finit <3 did not use GNU configure and build system. This patch adds an
install-dev rule that is used by some to install required headers for
external plugin developers.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Add support for changing the initial hard and soft resource limits for
finit and any processes it launches.
See /etc/finit.conf section in README.md for more information.
When a service changes type from inetd to a regular daemon we must make
sure to first deregister the currently running inetd service properly.
Example: a system boots up with httpd.conf as an inetd service, so Finit
opens a socket 0.0.0.0:80 pending connections to start `httpd -i`.
After a while a user changes httpd.conf to be a regular service and
calls `initctl reload`. Without this patch the socket will remain
open and prevent httpd from opening and binding to the same port.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch fixes a problem with lingering inet sockets when inetd
services are removed. When removing an inetd service we must stop
the watcher and close the socket.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
We cannot clear the svc_t memory because other applications may have
connected to the same shared memory. An application may be inspecting
the current list of services (initctl) and pulling the rug from under
them could cause some really unpredicatble results.
This reverts commit 06d1e90bac.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Both the original MIT Athena inetd and the GNU inetutils inetd only keep
a backlog of 10 connections in listen() for TCP sockets. This patch
adjusts the Finit hard coded default accordingly.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When starting an inetd service in verbose mode we print a progress
message to the console appended with "Connection". This patch simply
changes that to append with "connection" in lower case.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch fixes several issues related to the problem of launching
UDP inetd services:
- Make sure to disable O_NONBLOCK on the socket before passing it to
the inetd service, that's what is expected. This goes for both UDP
and TCP (accepted) connections -- there is no guarantee even for TCP
sockets that they do *not* inherit the parent socket's flags.
- Mark the UDP inetd parent's SVC as busy and stop its watcher before
starting the child task to service the connection. The watcher must
be stopped or multiple child tasks may be spawned!
- Only copy the most relevant parts to the UDP task. In particular
must *not* copy the libuEv watcher data to the task!
- With the child task done and the parent inetd service unblocked we
must restore O_NONBLOCK to the socket before restarting the watcher
When a UDP inetd service connection is handled we create a child task
to service the request, meanwhile we block the parent service. There
was a problem with blocking the parent since we called inetd_stop(),
which both did a shutdown() and close() of the socket ... this patch
introduces separate handling of blocked (busy) inetd services in the
inetd_stop() function and also make sure to handle restarting the
parent watcher in inetd_start() when the child task is done.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Both the new initctl API and the new pidfile watcher plugin failed to
set CLOEXEC on their sockets. This caused forked-off and exec()'d
children to inherit all these descriptors.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Patrick Stewart added the optional `log` keyword to service, run, task
and inetd stanzas in 889bce1. It redirects stdout/stderr to syslog
using the logger tool. This addition to the README is mainly just a
place holder so it's not forgotten before the upcoming README refactor.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Adds an extra 'log' parameter to services that routes STDOUT and STDERR to syslog.
Uses a PTY rather than a pipe, as this prevents log messages hanging around in a buffer indefinitely.
In service_start() the SIGCHLD handler is reenabled before calling complete(), so the service could be reaped by the SIGCHLD handler leaving service_start() waiting forever
Also remove code that duplicates sig_unblock()
The alsa-utils, dbus, lost (PID), resolvconf, and x11-common plugins are
rarely used in the main use-case for Finit (embedded head-less systems).
This patch disables them by default and makes them possible to enable by
configure --enable-$PLUGIN switches.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Slightly more readable code and fix issue with --enable-$PLUGIN not
biting properly in the generated Makefile.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch replaces the verbose and kernel-quiet runtime options with
a (hopefully) more useful quiet and silent modes of operation.
By default Finit progressively shows all services it starts at boot, but
when boot has completed and services are started/restarted Finit prints
nothing. If `--disable-quiet` is given all started/restared/stoppping
messages are shown even after boot.
However, if `--enable-silent` is given Finit is completely silent even
at boot, no progress is shown, until the first service is started, which
on most systems is login.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Remove confusing `--with-aix-soname` option to configure. Replace with
hard-coded `aix-soname=both` => shared + static archives are build as to
be expected.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch prevents too early start of services depending on other
services. E.g, if service B depends on A then we must wait for A to
signal that it is ready before we allow B to start -- in a Finit based
system A does this by creating, or touching (updating mtime), its PID
file. Services (like A) that support SIGHUP should call utime(), or
utimensat(), on the PID file at the end of their SIGHUP handler.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
From now on the user is required to have libuEv and libite installed
before building and installing finit. This is for maintenance reasons.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds support for the runtime `HOOK_SVC_LOST` and the (very
noisy) *example* plugin `lost.so`.
Customer request.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
To distinguish between variables and functions in comments Finit use ()
at the end of function names.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch builds Finit dynamically, including both plugins and GIT
submodules for libite and libuev. This causes libite.so and libuev.so
to be installed in a public path, which is not good if the user has
other versions of the same libraries already installed.
The correct fix is to remove the GIT submodules for now and require
users of Finit to build and install libite and libuev separately.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Flush any existing filter rules when a configuration file is
updated. Otherwise filters are simply appended to the old
configuration which can cause finit to accept connections on
interfaces that are blocked in the new configuration.
Same as for libite, libuev has also changed to autotools, so
call its autogen.sh and configure script in cascade from our
own. Aslo add safeguards to clean/distclean targets so we
do not attempt to enter the libuev subdirectory if it's not
configured.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The new libite uses autotools to build, and since we use it as a GIT
submodule we have to call its autogen.sh before we call the configure
script, from within the Finit configure script. We may have to move
to use autotools even for Finit ...
Also, make sure to only call clean/distclean on libite if the local
version is selected at configure time.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When a service's condition transitions to `flux`, put it in the
waiting state, even if it does not support SIGHUP. That way, if the
condition returns to `on` we can simply SIGCONT it. If it goes to
`off` it will still be stop/started as before.
When reloading dynamic services, inetd services deleted marker was not
being cleaned. This caused finit to stop and start all inetd services
at every other reload.
This patch introduces a new service type called SVC_TYPE_INETD_CONN,
which represents a running inetd connection. These are handled in much
the same way as tasks. I.e. they are considered one-time jobs, with
the difference that they are removed upon completion.
When cleaning up removed services, the assumption was made that if a
service was not 'removed', it was 'clean'. In reality, it could also
be 'updated', which was then overwritten, causing services not being
restarted. Don't do that.
As a future precaution, make the dirty field const, only allowing
updates from accessor methods.
During documentation of the state machine, some theoretical problems
where discovered that could have lead finit to spawn a new instance of
a daemon before the previous one had been collected.
Now a service will always go through the STOPPING state when leaving
RUNNING. This ensures that the PID has been collected before any calls
to service_start.
...documenting your work is, apparently, not a bad idea. :)
Old event system has been replaced with a more generic condition
concept. The idea is that finit plugins may provide arbitrary
conditions that services may specify as dependencies that they require
to run.
In order to accomodate this, the service management has been
redesigned to use a state machine.
Parser would erroneously interpret an event specification containing
slashes as an inet service/proto specification.
E.g. "<net/gw>" was interpreted as port "<net" using protocol "gw>".
Stopped services are now (again) listed as "stopped" and halted
services, due to a runlevel change, are listed as "halted". Several
users complained that this change was just not intuitive. I agreee.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
By popular request, this patch adds support for querying status of a
single service. The syntax is similar to that of stop/start/reload.
Both `initctl show ...` and `initctl status ...` is supported.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When no services were stopped we must ensure to start/SIGHUP any new or
SIGHUP:able services as the last pass of the `initctl reload` cycle.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch fixes a hang when performing a system reconfiguration using
`initctl reload`, `SIGHUP` or running `(f)init q`, which caused Finit
to wait for SIGHUP:able services to stop.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch reenables verbose mode at shutdown/reboot, if it was disabled
at boot. This allows the user to see the output from the `urandom.so`
and `hwclock.so` plugins at reboot.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The urandom.so plugin uncovered that `print_desc()` does not honor the
`verbose` flag. At runtime `print_desc()` et al should no be displaying
anyting when we finit operates in terse mode.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Leverage new svc_t states in initctl status/show output. Also, ensure
different svc_t types have correct start state.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
new postponed stop handling tried to reload already stopped and removed
services. We should of course skip already stopped services and halt
those that have been removed.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch reverts the change in behavior introduced in Finit v2.2,
commit 924bf041, where `initctl restart JOB` changed from 'stop + start'
to `SIGHUP` for services that support `SIGHUP`.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When `service_stop_done()` is called with a `NULL` argument and no
dynamic services have been stopped, this regression is triggered.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch makes it possible to see debug traces when running the client
program initctl, using `--debug`. Please note, this does not affect the
debug command to the daemon.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds support for declaring *why* a service is being stopped
or reloaded. This is later used when all stopped services have been
collected by the `service_monitor()` to issue start or postponed SIGHUP.
As an added benefit we can now also see why a service is not running.
If it has been paused by a user, halted when moving to another runlevel,
waiting for a condition (event), or similar.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The `initctl reload <JOB>` command did not work properly. This
was due to the service not being properly initialized to default
settings when reading the Finit configuration file.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch fixes a race condition when doing an ordered RELOAD and STOP
event sequence. For services that shall be stopped it is imperative
that we wait for them to be colleced by the `service_monitor()`, so that
we know they have really been stopped, before calling HOOK_SVC_RECONF.
The latter is a promise to external services that all services have been
indeed stopped.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The TTY plugin might fail in read() with EINVAL if the inotify event
buffer is too small. Fix: set the receive event buffer to the size
recommended in inotify(7). Also add a handler for EINVAL to close and
reinitialize the inotify descriptor so we do not accidentally overrun
the CPU with any unhandled errors.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When building a static Finit the plugins do not get a unique name
automatically from the file. This led to only the first plugin being
loaded, since its name was 'unknown' it was registered as such and all
other plugins conflicted, since 'unknown' was already ... known and
loaded.
This patch gives all plugins a default name, __FILE__, making it
possible to use all of them when building a static Finit.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
For embedded systems with no initial random seed, usually stored in
/var/lib/urandom/urandom-seed on desktops, servers and laptops, we now
provide an initial seed file using a built-in PRNG.
Also, let the configure script default to *enable* the random seeding
at boot, granted the urandom plugin is enabled. We should encourage
users to properly seed their random, for security reasons.
Moreover, the plugin did not properly regenerate the random seed on
reboot, or shutdown, this patch also rectifies that problem.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Upgrade libite (LITE) for new UNIX file parser API to improve static
builds of Finit.
- Re-enable bootmisc plugin for static builds by adding built-in support
for reading GID from /etc/group.
- Allow inetd support for static builds by adding built-in support for
reading service and protocol from /etc/services and /etc/protocols.
- Do not try to install/uninstall any plugins for static builds.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
service.c:
Don't declare find_inetd_svc() if inetd is disabled.
api.c:
Disable inetd API
initctl.c:
Disable presentation of inetd services
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
After forking off a new child, all signals that are blocked by finit
should be unblocked before exec-ing the final binary. Also, finit now
blocks SIGHUP, so add it to the set of signals that should be
unblocked.
We should not use -Os as default optimization, it is sometimes unstable
in cross compilers. Instead, default to -O2, which is the more tried
and tested path.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When integrating finit as a component in another system, that build
system may set VERSION as an environment variable for that OS -- we do
not want that version to be set as the version of finit.
Also, bump version to 2.0.1-dev for upcoming patch release cycle.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Check return code from `mount -na`, if there where any errors give
plugins a chance to do something about it.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds a simple `service <script> <stop|start|reload|restart>`
script for for SysV init compatibility. Very common with users of the
Ubuntu upstart init as well.
Also, fixed `make uninstall` for plugins.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Even though libite and libuEv can be disabled, using the --with-libnnn
option to configure, we let make descend into those submodules for the
clean and distclean targets. This way we can rely on make dev to work.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit makes it possible to build Finit with an external libuEv.
Without this configure script option the libuev submodule is used.
With an external libuEv we make sure to set the SONAME to libuev.so.1
to prevent any future runtime ABI issues.
Fixes issue #4.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit makes it possible to build Finit with an external libite.
Without this configure script option the libite submodule is used.
With an external libite we make sure to set the SONAME to libite.so.2
to prevent runtime ABI issues with older libite versions.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit adds support for event based services to Finit. Along with
the previously added support for multiple instances of the same process,
the feature scope for Finit v2.0 has been reached!
As of now a service can be declared in /etc/finit.conf or /etc/finit.d/
like this:
service :1 [2345] <!IFUP:eth0,GW> /sbin/dropbear -R -F -p 22 -- SSH daemon
Here the first instance `:1` of dropbear is declared to run in runlevels
2-5, but only if eth0 `IFUP:eth0` is up and a gateway `GW` is set. When
the configuration changes, a new gateway is set, or somehow a new `IFUP`
event for eth0 is received, then dropbear is not SIGHUP'ed, but instead
stop-started `<!>`. The latter trick applies to all services, even
those that do not define any events.
Currently inetd services are not supported for event based starting, but
it could easily be added. Likely scenario is to deny incoming requests
on, e.g., eth0 if there is no gateway.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The event API, including Netlink events to services, looks OK now
to build the remaining two features on:
- Netlink plugin for GW and IFUP IFDN events
- Generic event support for services
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Previously `HOOK_SVC_RECONF` was only called on `initctl reload`,
now we also call it on `initctl emit "STOP"`. This seems like a
good idea atm, hopefully it will remain a good idea.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This part of the README must be completely overhauled before the
release, so much of the contents is basically just TODO or design
ideas atm.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The tempfile() replacement in Finit leaked temporary files in /tmp.
The mkstemp() based implementation does not remove temporary files
when they are closed.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When Finit receives SIGHUP or a reload command all services listed in
/etc/finit.d/*.conf are first stopped and then started again. I.e.,
removed/changed services are stopped and then new/changed services are
started again. In between we call HOOK_SVC_RECONF. It should always be
called, even though no services were removed/changed/added. This to
allow plugins connected to that hook may need to run as intended.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch makes it possible to communicate process name or JOB[:ID]
from initctl to Finit. When the process name translates into a service
with multiple instances Finit applies the requested command to all
instances. For example, two Dropbear SSH services running on two
different ports, calling `initctl stop dropbear` stops both services.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Fix side effect with run stanza children not being collected if finit is
not run in verbose mode. Regression introduced in release cycle.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Replace `remove()` with our own `erase()` which checks the return value
and warns on actual real failure.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The new iterators `svc_inetd_iterator()` and `svc_dynamic_iterator()`
used unsafe constructs that could cause them, at least the latter, to
dereference a `NULL` pointer.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
We must check the return value from `accept()`, it may fail. Also, we
should probably retry the syscall in some cases ...
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When receiving a start/stop/reload/restart request from initctl we must
make sure to validate and NUL terminate the job ID. The `read()` API
does not NUL terminate strings for us and we cannot rely on `initctl` or
any other external API user to do so for us.
This patch improves error and boundary checking.
- Use memcpy() + hard termination instead.
- Fix use of strchr() on possibly non-NUL terminated string.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch changes the syntax for custom inetd services and adds support
for deny filters. The new syntax is:
inetd service/proto[@iface,!iface,...] </path/to/cmd | internal[.service]>
This means the second column now defines what@from and the third to/what
process. For internal services on a custom port the internal.service
syntax must be specified, so Finit can properly bind the inetd service
to the correct plugin. Here follows a few examples:
inetd time/udp wait [2345] internal -- UNIX rdate service
inetd time/tcp nowait [2345] internal -- UNIX rdate service
inetd 3737/tcp nowait [2345] internal.time -- UNIX rdate service
inetd telnet/tcp@*,!eth1,!eth0, nowait [2345] /sbin/telnetd -i -F -- Telnet service
inetd 2323/tcp@eth1,eth2,eth0 nowait [2345] /sbin/telnetd -i -F -- Telnet service
inetd 222/tcp@eth0 nowait [2345] /sbin/dropbear -i -R -F -- SSH service
inetd ssh/tcp@*,!eth0 nowait [2345] /sbin/dropbear -i -R -F -- SSH service
Access to telnet on port `2323` is only possible from interfaces `eth0`,
`eth1` and `eth2`. The standard telnet port (`23`) is available from
all other interfaces, but also `eth2`. The `*` notation used in the ssh
stanza means *any* interface, however, here `eth0` is not allowed.
NOTE: This patch breaks syntax compatibility with Finit v1.12!
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Reduce size of `helpers.c`, for linking against new `initctl` tool,
by moving out functions to `pid.c` and `exec.c`
- Add `AF_UNIX` API to Finit, to complement old `/dev/initctl` FIFO
- Let old FIFO API be used by init/telinit: `init <q | 1-9>`
- Move all advanced initctl code from `client.c` to `initctl.c`, yes
its a bit confusing to call the *new* tool the same as the old FIFO
but this is more in line with what, e.g Upstart does.
- Move all advanced server side code from `plugins/initctl.c` to `api.c`
- Update TODO with upcoming inetd syntax change and dynamic events.
- Temporarily fix display of inetd services from `initctl status -v`
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch further extends the capabilities of the client with the
ability to control the running state of services:
finit <stop|start|reload|restart> JOB
Since services can now exist with multiple instances the concept of
"jobs" is introduced in this patch. A job is a numeric identifier of
the form `NUM[:NUM]`, the latter `:NUM` is the new instance syntax
introduced earlier. See the output of `finit status` for the JOB id.
Also, with the introduction of multiple instances we broke support for
multiple related inetd services. This became obvious when the shiny new
`finit status` was tested ... hence, this patch also contains fixes to
the inetd support.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Turns out that #ID syntax for multiple instances, introduced in cb07556,
was very cumbersome to reference from the shell command line in the new
Finit client. This patch changes the syntax from #ID to :ID, which also
means that listing services/jobs in the shell will look like JOB:ID.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Further refactoring of the client code. Supported commands:
- debug: Toggle PID 1 debug flag
- version: Show Finit version or custom header string
- reload: Reload config files in /etc/finit.d/, same as SIGHUP
Also supported is the legacy 'init q' command, to reload config.
The 'status' command now supports an optiona '-v', either as an
argument to init itself, or as argument to the command. When it
is given 'status' lists verbose information about all services.
Currently only the service arguments are listed.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch refactors svc.c into two files: svc.c now as a low-level
svc_t API and service.c for the more advanced rest.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
These two new hooks run when SIGHUP is received and when changing
system runlevel. The hooks are called when all services have been
stopped, just before starting up new/modified services. Making it
the perfect hook for reconfiguring the system/hardware before new
services or modified services are started up again.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When receiving SIGCHLD we must reap *all* children. We only receive one
signal, but multiple processes may have exited.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds support for starting and supervising multiple
services (run, task, or service) using an extra #ID number.
service #1 [2345] /sbin/httpd -f -h /http -p 80 -- Web server
service #2 [2345] /sbin/httpd -f -h /http -p 8080 -- Old web server
Also included in this patch is a fix for endless respawn of faulty
services. For instance, a buggy daemon that crashes repeatedly will now
be stopped after 10 respawns.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds support for adding and removing services from Finit at
runtime. Configuration file stanzas for service, run and task may now
be written to files in /etc/finit.d/*.conf, using the exact same syntax
as before in /etc/finit.conf. When a file is added, removed or modified
the user may simply SIGHUP Finit (PID 1) to activate the changes.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When a user changes runlevel, or wants to reload the config, we want the
command to return only when the operation has completed. For instance,
rolling in a new system configuration in runlevel 1 requires that we are
sure we've actually entered that runlevel before rolling it in.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds support for a configure script and with it
support for disabling inetd support. See the output from
./configure --help
* Add configure script
* Sprinkle #ifdef fairy dust on svc.c when inetd support is disabled
* Use GCC built-in autodep calculator (-MMD -MP)
* Fix name space issue with include files, use relative paths
* Disable username/group name to uid/gid functions in static builds
* Bug out (error) if a user tries to build the bootmisc plugin static
Possibly fixes GitHub issue #5 and issue #6.
NOTE: The static build has not received any testing at all!
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adresses issue #5. However, there still remains a few issues
to work around before Finit can be built completely standalone.
$ make clean all STATIC=1
LINK finit
helpers.o: In function `getgroup':
helpers.c:(.text+0x10a7): warning: Using 'getgrnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
helpers.o: In function `getuser':
helpers.c:(.text+0x108e): warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
inetd.o: In function `getent':
inetd.c:(.text+0x127): warning: Using 'getprotobyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
inetd.c:(.text+0xce): warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
The problem is the NSS plugins and similar issues that prevent static
linking when using the above functions. See issue #5 for more on this.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Without this patch binding to sockets when restarting them fails. This
was found when quickly changing between runlevels where a service runs,
not runs, then back to a runlevel where is shall run.
Also, refactor previous setsockopt() call to use new common macro.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
There seems to have been a regression from earlier when this worked.
I'm sure it worked ... or am I? This patch makes the whole thing look
a lot more sane, so I wonder ... might have worked in my unit tests on
x86, but not when I cross-compile to ARM.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When changing runlevels netstat still listed closed sockets as being
open and listening. With this patch all sockets are properly shut down
before we close them.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
With O_CLOEXEC we prevent forked+exec'ed children from accessing the
initctl fifo via that socket.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Stop event watcher before running callback, the plugin may manipulate
the descriptor and cause the kernel into a EPOLLHUP frenzy.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
If no tty is configured in finit.conf, only use FALLBACK_SHELL (usually
/bin/sh on UNIX) when no console is configured either.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Fix `restart_any_lost_procs()`, called when finit recovers from being
stopped for a while. This function should not restart task/run/inetd
services when called -- must check for type `SVC_CMD_SERVICE` when
iterating over all registered `svc_t`, just like a regular lost pid.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Fix double close of TCP socket introduced in GIT ded4b39,
replaced with closing all open stdio descriptors, which
shouldn't really be needed.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Fixes, or rather works around the Coverity warning of possible NULL
pointer dereference. (Not an error.)
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds support for custom port and interface filtering to inetd
services, in a very condensed syntax:
inetd ssh@eth0:222/tcp nowait [2345] /usr/sbin/sshd -i
inetd ssh@eth1:22/tcp nowait [2345] /usr/sbin/sshd -i
In this example eth0 and eth1 are allowed inbound interfaces for SSH
connections, on port 222 and 22, respectively. Attempting to connect
from any other interface is denied. Also, if the system is not in
runlevel 2, 3, 4, or 5, ports 222 and 22 will not even be opened.
If eth0 is your upstream interface you may want to avoid using the
default port. To run ssh on port 222, and all others on port 22:
inetd ssh@eth0:222/tcp nowait [2345] /usr/sbin/sshd -i
inetd ssh/tcp nowait [2345] /usr/sbin/sshd -i
This actually adds a deny rule for eth0 on ssh/tcp, implicitly. You can
even list the services in the reverse order with the same result:
inetd ssh/tcp nowait [2345] /usr/sbin/sshd -i
inetd ssh@eth0:222/tcp nowait [2345] /usr/sbin/sshd -i
There is no specific deny syntax available yet, see the TODO file for
more details on how this can be implemented.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Initial support for unloading plugins. Currently we only save dlopen()
handle. The plugin_unregister() function itself is never called atm.
This should at the very least make Coverity happy.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch is slightly sub-optimal, since it will causes us to load all
availble plugins, not just those referenced by finit.conf. However, in
the short term perspective we need to reference internal inted services
provided by plugins from finit.conf, so the dependency order is clear.
In the midterm perspective we want to add support for SIGHUP to reload
finit.conf, but not plugins. So again, this is an OK patch.
One fix would be to allow loading of all plugins, parse finit.conf and
then unload all unused plugins before continuing.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch adds initial support (only SOCK_STREAM verified!) for
figuring out the inbound interface for inetd service connections.
The intention is to use this later on for a very simple tcpwrappers
replacement, e.g: `deny telnet eth0 eth3`
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch traps segfaults caused by 3rd party service callbacks in a
separate process context. Effectively preventing a single programming
mistake from taking down the entire system. Previously it was up to the
callback coder to write error free code so that PID 1 did not crash.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This reverts commit 074686b520. Which
turned out to not work so well after all. For instance, launching TTYs
in a background process completely blocked inetd services from even
starting up listening sockets ... proper fork seems to work fine though.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
We don't want to run out of scan tokens for every README update. This
also means the introduction of a new workflow. All new development must
be staged to the dev branch before being merged to master.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Bump version for coming 1.11 release
- Update `make dist` to use Kentzo's `git-archive-all` from
https://github.com/Kentzo/git-archive-all
- Rename NEWS --> CHANGELOG and update for coming release
- Update CHANGELOG with info on the libuEv migration
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Make sure to close dup()'ed descriptors when we're done with them.
Thanks to Coverity Scan for finding this nasty one!
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
If not standard finit.conf, then we want to show just the base name.
E.g., loading first /etc/finit.conf then /etc/finit.d/services.conf
Loading configuration ............. vs
Loading services configuration ....
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Try to do better by the user, by default, if no tty is specified in the
finit.conf. This way the user will at least have a way to interact with
the system and repair it.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Simplify: reduce indentation depth
- Always check for error condition first, cleaner code
- Make sure buffer is always freed, use same exit everyhere
- Use readable, but still short, local variable names
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The cppcheck tool raised an alert to the missing close() for
stdin when a console is opened for a getty. This patch fixes
that warning and also makes the code slighlty more readable.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Add support for symlinks to copyfile()
- Fix memory leak in copy_filep()
- New function, fsendfile(), copy data between FILE streams
Also, minor whitespace and coding style cleanup.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Revert crazy BANNER macro idea from 5ba7bc1. It is simply too difficult to
set -DBANNER='"Some distributions specific text"' in a parent Makefile
without entering Shell/Make escape hell ... instead, downstream will
have to patch the banner() function.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
On some platforms GCC does not zero the heap. This can lead to
serious problems, e.g., tty->pid may be non-zero while never
having been started.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Standard init implementations save current and previous runlevels
in utmp, now finit does too. Also, the initial runlevel at boot
has changed from 10 to the more obvious 0.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Add support for runlevels to tty command and support for reading baud
rate and TERM variable from finit.conf.
The tty-watcher thread has been converted to a standard I/O plugin.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Most systems need an early bootstrap phase for one-shot tasks and
necessary one-time probing. This phase usually runs well before any
networking is setup. This commit adds support for that 'S' runlevel,
and also extends the number of possible total runlevels to nine.
For the one-shot tasks that run in bootstrap two new finit.conf cmds
have been added:
- task: For one-shot tasks that can be started in parallell
- run: For one-shot tasks that must run in sequence
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is a refactor of how arguments to finit.conf file settings
are parsed. Not all settings are run directly, but only need the arg
for future use. The code should be a lot easier to understand now.
Also, added support for specifying the desired runlevel in finit.conf
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
chomp():
Removed first \n instead of last \n
set_hostname():
If /etc/hostname exists we need to realloc the size of
the current hostname variable. Also, only try to set
the hostname if !NULL
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The ROOTDIR variable was only set in the top-level Makefile,
so when building from a subdirectory the output was slightly
garbled. Moved ROOTDIR declaration to common.mk.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Remove indentation of module loading and device node creation
- Clarify that we load kernel modules
- Clarify that we load Finit plugins
- Remove cls()
- Remove verbose condition for echo()
- Make banner a separate function with optional distribution banner
- Add a few neat ANSI escape sequences for cls(), clreol(), delline(), etc.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
More inspiration and courage from the launchd Google Talk video!
Fascinating stuff about replacing init/inetd/cron/watchdogd that
I've been thinking about for ages!
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit adds a line: "Loading kernel modules ..." before increasing
indentation level of module loading messages.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit adds support for -d, --debug option to init, which can
be used to toggle the finit debug mode at runtime.
Signed-off-by: Mattias Walström <lazzer@gmail.com>
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Like most other init implementations do, when entering runlevel 1, finit
creates the file /etc/nologin to prevent users from logging in during
single-user mode, this file is then removed upon leaving runlevel 1.
Also, bugfix how FIFO I/O plugins are handled in finit. A FIFO will
need to be reopened by the server side when the client closes the pipe.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit adds support for specifying TTY and console to be used
for starting a getty to login to the system
Add the following to your finit.conf to use this feature:
tty ttyS0
tty ttyUSB0
console ttyS0
Signed-off-by: Mattias Walström <lazzer@gmail.com>
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit adds a statistics counter to the finit svc_t process struct
which is incremented every time a process is restarted by the service
monitor.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This patch reorders the shutdown/reboot handler slightly and fixes
a bug in sleep(). It seems the sleep() syscall was interrupted by
receiving lots of SIGCHLD. Unsurprisingly since we just sent all
processes SIGTERM, but unfortunate since that was too short time
to deliver SIGTERM to watchdogd.
We now call sleep() again, as long as it returns a non-zero value,
until at most two (2) seconds have passed. During this time we
basically pend for watchdogd to do its job and let the WDT reboot
the system. If the two second timeout passes we send SIGKILL and
forcibly reboot(RB_AUTOBOOT) the system.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
When using the simple rsync() or copyfile() functions of libite some
error codes should not be interpreted as error. I.e., if a file or
directory already exists when attempting to create it.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The ROOTDIR variable is used for pretty formatting during compilation.
Some users might want to have this display the build from the top of
their tree instead of the finit build tree.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This also adds support for monitor /dev for TTYs appering after boot,
USB-to-serial converters for example.
Some limitations: Baudrate (and other settings) is hardcoded for now,
should be read from config file.
This is a bugfix to 785c21d, which introduced the new runparts
directive in finit.conf
- Do not attempt to free() a static string, use same approach as
username and hostname.
- Do not overwrite hostname, set the correct variable if runparts
directive is found in finit.conf
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Many callbacks check their svc->pid to determine SVC_RELOAD or SVC_START,
they rely on it to be updated. When a service is lost we must therefore
clear its recorded PID before asking the callback what to do.
Also, swap comparison in debug code for dumping service arguments ...
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The run_parts() implementation used variable arguments in a bad way,
resulting in it not working properly. Replaced va_*() code with a
simple cmd argument that's passed to each script called.
Also, the opendir()/readdir() code has been replaced with scandir()
using regular alphasort(). This simplifies the code somewhat as well.
Otherwise, minor cleanups.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Sometimes people type in the wrong path to a service directive in
finit.conf, or the executable isn't installed. This commit makes
sure to check if the command exists before attempting to start it.
This also means that we now require service commands to start with
/ to indicate an absolute path. We used to search the PATH for a
suitable executable, using execvp(), but that's rather insecure as
well, so we now use only execv().
Also, added support for adding "start" or "stop" to entries found
in /etc/finit.d starting with SNNname, or KNNname, where NN is a
number. This makes it possible to simply import sysvinit style
start scripts from /etc/rcS.d and /etc/rcN.d/.
The alsa-utils plugin also had some minor fixes, added -g option
to ignore non-existing soundcards and fixed cut-paste bug on the
_d() debug messages.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit adds support for the "runparts <DIR>" directive to
finit.conf. Enabling the user to override the built-in default,
which by default is /etc/finit.d.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Fix from field testing. Need to skip "." and ".." directory entries
when loading plugins from /lib/finit/plugins. Also, trigger an error
when a required plugin fails to load. We need to print to console
since syslogd has not started yet.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This has been something I wanted to avoid, but then I stumbled so hard
on it myself I simply had to add it. With this commit finit actually
comes of age -- it's now possible to do anything a modern init can --
only faster! :-)
Included in this commit is the OpenBSD version of sys/queue.h, which
unline all versions of the same file on Linux has the _FOREACH_SAFE
macros for iterating over a linked list.
The plugins are now in a TAILQ, loaded in alphabetic order and, unless
the dependency resolver says otherwise, added last in the queue. So,
naming your plugins according to standard sysvinit rules: S01, S02,
etc. takes care of the most basic dependency resolution. When that is
not sufficient, simply add a line ".depends = { "other_plugin",
"another_plugin" }," to your plugin_t definition. Be careful though
for circular dependencies, we don't check for those.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This was missing from the 1.4 release due to it being hidden in one
of my private plugins. Sorry!
Also, add another log macro. Warnings are quite useful things to have.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Restructure start by calling the plugin loader earlier. This makes it
possible to run hooks even earlier. This also adds a new hook:
HOOK_ROOTFS_UP which runs as soon as the system root (/) is available.
Another very notable change is the slow refactor of helpers.c into a finit
helper library called libite.so (-lite). This is a light-weight
Also, lots of misc. fixes all over the place. Signal handling still really
needs to be looked into once more!
Makefile:
Add dependency handling for parallell build
Add libite library
ChangeLog:
Update with new 1.4 release. There is a lot of fixes!
libite/:
Collection of utility functions and C library extensions for
finit & its plugins
reboot.c:
New reboot tool. Simply sends SIGINT to PID 1
finit.h:
Cleanup old LISTEN_INITCTL define, code is in an optional plugin now
finit.c:
Let mdev/udev run *after* cls()
Add useful debug statement for /proc/cmdline
Earlier plugin load => new early hook point
Show OK/FAIL for total plugin load, not for each plugin => speedup
helpers.h:
Rename syslog macros to prevent common name clashes (DEBUG/ERROR)
Add __FILE__ to _e(), _d() and _pe() macros
helpers.c:
In ifconfig() the addr and mask arguments are now optional
The copyfile() has been moved to libite.so
Temporarily remove const directive from some functions to build
Use DFLSIG() macro in run_getty() to simplify code
plugin.h:
Add new HOOK_ROOTFS_UP hook
plugin.c:
Fix init_plugins() to actually register the plugin's I/O fd
Skip verbose listing of all plugins in plugin_load_all()
svc.c:
svc_start(): Dito
plugins/Makefile:
Inherit CFLAGS and LDFLAGS, but make sure to filter out -rdynamic
from LDFLAGS, it's used by the daemon, only
plugins/initctl.c:
New includes after helpers.h refactor
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Use RTLD_GLOBAL flag to tell dynamic loader to load dependent .so
files as well. Also lets other plugins use globally scoped symbols.
- Check for plugin hooks as well before dismissing plugin as unused.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit removes a lot of unnecessary overhead for handling external
service plugins. Instead of traversing the plugin array every time a
service callback should run we set the plugin callback in the svc_t when
the plugin is registered.
Also, make sure to check for norespawn/SIGSTOP in svc_reload() as well.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Improve upon API names, both internal and external, to make it clearer
where methods are located and clarify responsibility.
Add new Makefile target "dev" to create untagged development snapshots.
Bump version for upcoming release.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Updates to README include changed environment variables and a
clarification of why there is no default /etc/finit.conf after make
install.
Also, the /etc/finit.d directory is now created, as expected, by
make install.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
- Makefile fixes for installation, paths encoded wrong
- Strip binaries + .so files, support for $(CROSS) toolchain strip
- Default install is now to /sbin/finit and /usr/
- Use the 'plugindir' environemnt variable instead of 'PLUGIN_DIR'
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Break up install/uninstall targets in top Makefile into separate
install-exec, install-data, and install-dev for packagers and
distributions wishing to call Makefile with different DESTDIR's
depending on building -bin or -devel package.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Minor cleanup of Makefile and added support for installing necessary
header files, for developing external plugins, to system include path.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Move utility macros from finit.h to helpers.h and continue refactoring
and streamlining of public plugin API.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit adds support for calling plugin hooks when all services
have been started properly. Useful for, e.g., a 3rd party service
monitor to trigger further events on.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
The installation path for plugins was encoded wrong in the finit binary
if *not* unset, i.e., "prefix=".
Updated the README with information on all build related environment
variables. Much of it is perhaps only needed for packagers and
distributions.
New version bump, v1.2 already.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit fixes the following warning on an ARM eabi/uClibc system.
helpers.c:86: error: dereferencing pointer 'a' does break strict-aliasing rules
The fix is trivial. Simply set IPv4 addressing scheme in the
struct ifreq instead of the struct sockaddr_in, whic is just
a pointer into the same ifreq anyway.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Tried to solve the signal.h name clash by using #include_next, but
seeing as this is not recommended[1] and breaks builds on some cross
compilers, the files were simply renamed: signal.[ch] --> sig.[ch]
[1] - http://gcc.gnu.org/onlinedocs/cpp/Wrapper-Headers.html
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This change is purely for people interacting with the GitHub interface.
The README itself is written in the plain text reST format.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Due to time constraints I had to revert the new libev backend to the
service, I/O and signals monitor. Employed instead is the tried and
tested signals based service monitor, with a small extension for an
additional I/O monitor using poll() for the I/O plugins to use.
Tried restoring the startx finit.conf directive on top of the service
implementation. However, it's currently not usable to run /usr/bin/startx
for any other user than root. I recommend using the examples/finit.conf
and run /usr/sbin/gdm instead.
finit.c:
New run_loop() function, replaces libev ev_run().
helpers.c:
Refactor start_process() into svc_start().
plugin.c:
Add fds[] array for use in the io_monitor() called by the
new run_loop().
signal.c:
Ignore SIGCHLD. Handled by waitpid() in svc_monitor() now,
which is called by the new run_loop().
svc.c:
svc_register(): Optional @username parsing for the command line.
svc_monitor(): Replaced libev callback with waitpid()
svc_start(): Refactored to use most of helpers.c:start_process()
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
New function helpers.c:run_getty() refactored from main(). Used to
start a default console getty.
Removed startx finit.conf option, superseded by service statement,
see examples/finit.conf for a working use case.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Lots of cleanup and simplification of the main code in this commit.
Most notably libev has been added to take care of the main loop and
monitor services. Still TODO is migrating to use the libev signal
handling.
Convert initctl.c:listen_initctl() to a plugin instead. This also
meant introducing a new form of I/O plugin to finit, also handled
by libev.
Load plugins *after* we've setup the base filesystem (BASEFS) in case
plugins reside on a filesystem not reachable before "mount -a" has run.
This also has the side effect of lining up nicely with the first level
plugin hooks.
If a plugin wants to hook up with a loded service we connect them by
their respective numeric IDs in plugin_register(). I.e., the service
monitor checks if a service has a registered callback, which in turn
decides if a service should be started, stopped or reloaded.
Rip out old EeePC distribution defines from finit.h, none of it really
applies anymore. If you need distribution specific settings this is
the place to put them.
Make hookpoint names (#defines) clearer: after BASEFS, after networking,
after all setup, etc.
Use #inlude_next <signal.h> in signal.h to include system header file!
Simplify service monitor: move essential code to svc.c and rip out
the TIPC dependency. Write your own service.so plugin, or wait for
a more complete example of how to extend service monitoring using
the primitives in svc.c
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
finit.conf:
Use this as /etc/finit.conf on a Debian 6.0 based system with X
installed and sysklogd instead of rsyslogd. Works.
services:
Alternative method for extending the finit boot procedure. Simply
place this script file in an /etc/finit.d/ directory. The script
uses the standard run-parts tool to chain load other start scripts.
helpers.c:
o New functions:
- run(): home grown system() replacement
- run_interactive(): display progress and status when called
o Bugfix start_process(), make sure to use same signal setup for
children as in run() and run_interactive(). Also, use execvp()
instead of execv() to allow searching $PATH for executables.
finit.h:
o Move signal specific code to new signal.h.
o Bypass verbosity setting to let echo() always print to screen.
finit.c:
o Make run_parts() the default, remove external deps, it works.
o Use run() and run_interactive() to speed up execution further
on embedded systems where forking is expensive.
o Kernel cmdline "quiet" should not close STDIO since this makes
it impossible to run some daemons and start scripts. Instead,
we let "quiet" toggle the finit verbosity setting.
o Remove kernel cmdline "--verbose" (Upstart compat), to be used
to enable verbose finit when kernel should be quiet.
o Setup kernel specific settings in /etc/sysctl.conf
o Fix D-Bus startup problems. Probably what caused X from not
working initially. Silly rabbit.
o Use system() workaround to start X, cannot get it to start
at all using run() or run_interactive() at the moment.
signal.h:
New file, header file for signal.c. Was about time.
signal.c:
Remove blocking of SIGCHLD from sig_setup(), instead we setup
SIGCHLD early in sig_init() to handle fork() in run() & C:o.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
finit.c:
o New service and shell_service stanzas for finit.conf
o Run service_startup() before /etc/finit.d/ hooks
o Run service_monitor() at end of startup
helpers.c:
o Several new functions:
- print_desc() displays a service starting up
- print_result() shows if service started OK or not
- start_process() is used by the services framework
svc.c:
Generic API for managing svc_t structures
ipc.o:
TIPC based framework for communicating with the service monitor.
E.g., to relay (re)configuration signals from a Web/CLI
front-end via finit to one or many setup daemons, and back.
services.c:
Service monitor framework
strlcpy.c:
Secure strncpy() replacement from OpenBSD under the free ISC License.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Update license and copyright information details in all files.
Much cleanup by moving hard coded strings/data to #defines and using more
common default values for each such #define.
finit.c:
o Make sdown[], startx[] allocated strings by default NULL
o This fixes the issues where the shutdown handler segfaulted
o Add ability to handle NULL input to build_cmd() by allocating space
o Ignore kernel cmdline "quiet" if in debug mode
o Add support for "network" stanza in finit.conf
o Mount -n to skip removing /etc/mtab
o Call swapon to enable swap if enabled in /etc/fstab
o Cleanup /tmp, /var/run and /var/lock
o Move sig_setup() *after* mount, sig_init() otoh runs early
o Start initctl monitor before forking off startx/getty process
o The startx process is now the console process. Only a getty is
started when in debug mode. Otherwise only X is started if it
is properly setup in /etc/finit.conf
o NOTE: Currently X evdev does not work!
o Support for /usr/sbin/services.sh has been replaced with finit
now instead supporting builtin run-parts for /etc/finit.d/
helpers.c:
o Bug fixes in run_parts() and also added chdir(oldpwd) at bottom.
o New functions:
- getuser() similar to getgroup()
- cls() clear screen, only runs when not in debug mode
- set_procname() used to set name "console" on console process
- set_hostname() encapsulates /etc/hostname and sethostname()
signal.c:
o Split sig_setup() in two: sig_init() and sig_setup()
The former to be called as soon as possible, while latter is
supposed to run when the base filesystem is properly up.
o Remove hard coded distribution specific progress bar write()
o Add debug messages to do_shutdown()
o Remove any lingering sync files in sig_setup()
initctl.c:
o Add debug messages and a new default: case to catch stray runlevels
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Cleanup device creation and initial mount by assuming that the kernel
has devtmpfs enabled. This is the default for most modern GNU/Linux
distributions. See http://lwn.net/Articles/331818/ for more info.
Also, since finit is targeted at deeply embedded systems hooks for the
BusyBox udev replacement, mdev has been added. If MDEV is defined in
the build it will take care of both hotplugging of devices and initial
setup of /dev
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Check for "--verbose", as well as "finit_debug", on kernel command
line to enable debugging of finit. The former is a compatibility
option with upstart, see http://upstart.ubuntu.com/wiki/Debugging
Add the following to the kernel command line to enable:
"init=/sbin/finit --verbose"
Without the quote characters.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
finit.c:
Skip standard UNIX comment character '#' if it appears at the
beginning of a row in finit.conf
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
finit.c:
o Perform signal setup as soon as possible, no need to do any
mounting of /proc or /sys beforehand
o Move signal setup and callbacks to a file of its own
o Use more #defines for hard coded strings
o Use a more neutral default hostname
signal.c:
o New file, for setup and signal handlers
o Add support for SIGSTOP/SIGSTP and SIGCONT. This pauses finit
respawning of xinit/shell. Useful for, e.g., debugging
o Document each ignored and handled signal better
o Disable SIGUSR1 and SIGUSR2 for now, will be reenabled later
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is in preparation for importing the Westermo code changes.
Slowly refactoring the finit core into a more modularized unit to be a
bit more maintainable.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This is a followup to Olivier Blin's patch from 88ffb93 in that it
applies the same patch to finit-mod.c that is already in finit.c, or
finit-alt.c as it was called then.
Also, the optional --directisa argument to hwclock is not necessary.
The hwclock utility has a built-in fallback to use excplicit I/O over
the /dev/rtc in case the latter does not exist. See the hwclock(8) man
page for more information on this.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
o Make finit-alt.c the new finit.c, save old finit.c as finit-org.c
o Keep original finit-alt.c for reference.
o Update README and ChangeLog with direction of this fork
o Correct ChangeLog date for v0.1 and set release date for
the 0.6-pre release to 20100614, which is the last commit
by the original author.
o Add standard LICENSE file for MIT License
o Add standard AUTHORS file to document history of project
o Bump version to 1.0-pre to distance fork from original
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
Example:
gcc -c -Os -Wall -DVERSION=\"0.6-pre\" -DWHOAMI=\"`whoami`@`hostname`\" -march=pentium-m -DBUILTIN_RUNPARTS -o finit-mod.o finit-mod.c
finit-mod.c: In function ‘main’:
finit-mod.c:107: warning: ignoring return value of ‘chdir’, declared with attribute warn_unused_result
finit-mod.c:137: warning: ignoring return value of ‘fgets’, declared with attribute warn_unused_result
finit-mod.c:164: warning: ignoring return value of ‘write’, declared with attribute warn_unused_result
finit-mod.c:168: warning: ignoring return value of ‘system’, declared with attribute warn_unused_result
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
Unsetting TERM in distributions using bash as /bin/sh prevents execution
of loadkeys from bashrc when creating the user environment to run X
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
Fsck filesystems before mounting root as read-write. Mountdev and
device creation can stay there because they're tmpfs.
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
If "mountdev" is specified in /etc/finit.conf, finit-alt will try
to mount tmpfs on /dev prior to creating device nodes.
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
By doing so we'll be masking a symptom of the problem instead of fixing
it. If permissions of /dev/null fail, most likely other problems will
also happen (e.g. pts permissions). Keep /dev/null alarm (which leads
to X server starting problems) to alert us if something is wrong.
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
If we handle it using pselect() in the parent process we'll end up
with a lot of zombie processes because SIGCHLD is not handled correctly.
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
AC_PLUGIN([netlink], [yes], [Basic netlink plugin for IFUP/IFDN and GW events. Can be replaced with externally built plugin that links with libnl or similar.])
AC_PLUGIN([hook-scripts], [no], [Trigger script execution from hook points])
AC_PLUGIN([hotplug], [yes], [Start udevd or mdev kernel event datamon])
AC_PLUGIN([rtc], [yes], [Save and restore RTC using hwclock])
AC_PLUGIN([tty], [yes], [Automatically activate new TTYs, e.g. USB-to-serial])
AC_PLUGIN([urandom], [yes], [Setup and save random seed at boot/shutdown])
AC_PLUGIN([testserv], [no], [Test plugin to start test serv daemon])
# Check for extra arguments or packages
AC_ARG_WITH([bash-completion-dir],
AS_HELP_STRING([--with-bash-completion-dir[=PATH]], [Directory to install Bash completion, default: auto]),
AS_HELP_STRING([--with-sulogin@<:@=USER@:>@], [Enable built-in sulogin, optional USER to request password for (default root), default: no.]),[sulogin=$withval],[with_sulogin=no])
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.