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>".
2016-01-05 14:50:13 +01:00
238 changed files with 20729 additions and 8795 deletions
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([hotplug], [yes], [Setup and start udev or mdev hotplug daemon])
# Check for extra arguments or packages
AC_ARG_WITH(heading,
AS_HELP_STRING([--with-heading=GREET], [Display GREET instead of Finit version at boot]),
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.