Compare commits

..
11 Commits
Author SHA1 Message Date
Joachim Wiberg 58e31dbd22 .github: try running with older Ubuntu version
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-06 19:57:46 +02:00
Joachim Wiberg 85058b54a8 plugins: bootmisc: use relative symlink for /var/run
In an upside world, much like the Finit test cases, the root may be
relocated.  This make /var/run relative to /var, instead of /.  Which
hopefully is safer and covers more use-cases.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-05 17:46:43 +02:00
Joachim Wiberg f16df142d7 Minor shellcheck fixes to debug code
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-05 17:46:20 +02:00
Joachim Wiberg f9f52a46a6 Debug sys plugin
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-05 07:27:22 +02:00
Joachim Wiberg ef1bfb869f test: HUP Finit from inside container instead ...
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-05 06:49:52 +02:00
Joachim Wiberg 5002c74876 test: force enable debug logs and HUP Finit before test
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-05 06:39:23 +02:00
Joachim Wiberg a0bc23c48f test: enable finit debug to see why API socket isn't created
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-04 20:52:08 +02:00
Joachim Wiberg 350cf6e578 test: dump contents of /var/run/finit/ to check for socket
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-04 20:46:48 +02:00
Joachim Wiberg b96a8d8766 test: dump correct root dir and add more PID 1 debug
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-04 20:31:13 +02:00
Joachim Wiberg a419828dea .github: no ~/.cache, check rest
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-04 20:22:05 +02:00
Joachim Wiberg 702b22d4a3 .github: check if ~/.cache exists, dump test root files
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-04 20:19:13 +02:00
90 changed files with 245 additions and 504 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ name: Release General
on: on:
push: push:
tags: tags:
- '[0-9]+.[0-9]+*' - '[0-9]+.[0-9]+'
jobs: jobs:
release: release:
+3 -39
View File
@@ -10,40 +10,14 @@ All relevant changes are documented in this file.
Critical bug fix release. If you run a 32-bit target with GLIBC 2.34 Critical bug fix release. If you run a 32-bit target with GLIBC 2.34
you *need* to upgrade! you *need* to upgrade!
> **Note:** system verbosity on console at start and shutdown has been
> increased. Now the output of all commands is logged to the
> system logger, for early services `/dev/kmsg` is used.
>
> **Also:** please notice the updated support for enabling and disabling
> kernel and Finit debug messages on the system console. Very
> useful when debugging either of them, e.g., a kernel module.
> For details, see [cmdline.md](doc/cmdline.md).
### Changes ### Changes
* Loading `module`s no longer shows arguments in progress output * Loading `module`s no longer shows arguments in progress output
* Warning messages in progress output now in yellow, not red, issue #214 * Warning messages in progress output now in yellow, not red, issue 214
* `initctl`, new command line option `-v,--version` for ease of use * `initctl`, new command line option `-v,--version` for ease of use
* Extended environment variables for pre/post scripts, issue #189 * Extended environment variables for pre/post scripts, issue #189
* New condition `done` for run task, issue #207 by Ming Liu, Atlas Copco * New condition `done` for run task, issue #207 by Ming Liu, Atlas Copco
* Refactor parts of shutdown and reboot sequence for PREEMPT-RT kernels, * Refactor parts of shutdown and reboot sequence for PREEMPT-RT kernels,
by Robert Andersson, Mathias Thore, and Ming Liu, Atlas Copco by Robert Andersson, Mathias Thore, and Ming Liu, Atlas Copco
* Conditions for run/task/sysv status, e.g. `run/foo/success` and
`task/bar/failure`. Issue #232, by Ming Liu, Atlas Copco
* initctl support for sending signals to services, by Jörgen
Sigvardsson, issue #225
* `[WARN]` messages on console now printed in yellow, issue #214
* Network services now also stopped when going to runlevel 6 (reboot),
not just runlevel 0 (shutdown) or 1 (single-user)
* When `ifup` is missing on the system, bring at least `lo` up at boot
* Log output from `ifup -a` (and `ifdown -a`), to syslog
* Avoid blocking PID 1 when starting SysV init scripts
* Allow custom `pid:` for SysV init scripts
* Document supported types of forking/non-forking services
* Auto-detect running in some common forms of containers
* Simplify shutdown/reboot when running in a container
* Log to `stderr` when running in a container w/o syslog daemon
* Add support for `type:forking` to services, already supported but
with a very difficult `pid:` syntax. Documentation updated
### Fixes ### Fixes
* Fix nasty 32/64-bit alignment issue between finit and its plugins, * Fix nasty 32/64-bit alignment issue between finit and its plugins,
@@ -53,16 +27,6 @@ you *need* to upgrade!
or does not have the required controllers (cpu) or does not have the required controllers (cpu)
* Fix #217: iwatcher initialization issue, by Ming Liu, Atlas Copco * Fix #217: iwatcher initialization issue, by Ming Liu, Atlas Copco
* Fix #218: initctl matches too many services, by Ming Liu, Atlas Copco * Fix #218: initctl matches too many services, by Ming Liu, Atlas Copco
* Fix #219: not all filesystems unmounted at shutdown, by Ming Liu,
Mathias Thore, and Robert Andersson, Atlas Copco
* Fix #226: initctl shows wrong PID for crashing services
* Fix #227: reboot stalls if process stopped with `[WARN]`
* Fix #233: initctl shows wrong status for run/task, by Sergio Morlans
and Ming Liu, Atlas Copco
* Fix start/stop of SysV init scripts
* Fix call to `swapoff` at shutdown, does not support `-e` flag
* Fix suspend to RAM issue. Previously `reboot(RB_SW_SUSPEND)` was
used, now the modern `/sys/power/state` API is used instead.
[4.2][] - 2022-01-16 [4.2][] - 2022-01-16
@@ -817,7 +781,7 @@ The inetd release.
### Changes ### Changes
* Add support for built-in inetd super server -- launch services on * Add support for built-in inetd super server -- launch services on
demand. Supports filtering per interface and custom Inet ports. demand. Supports filtering per interface and custom Inet ports.
* Upgrade to [libuEv][] v1.1.0 to better handle error conditions. * Upgrade to [libuEv] v1.1.0 to better handle error conditions.
* Allow mixed case config directives in `finit.conf` * Allow mixed case config directives in `finit.conf`
* Add support for RFC 868 (rdate) time plugin, start as inetd service. * Add support for RFC 868 (rdate) time plugin, start as inetd service.
* Load plugins before parsing `finit.conf`, this makes it possible to * Load plugins before parsing `finit.conf`, this makes it possible to
@@ -848,7 +812,7 @@ The inetd release.
[1.11][] - 2015-01-24 [YANKED] [1.11][] - 2015-01-24 [YANKED]
------------------------------ ------------------------------
The [libuEv][] release. The [libuEv] release.
**Note:** This release has been *yanked* from distribution due to a **Note:** This release has been *yanked* from distribution due to a
regression in launching background processes and TTY's. Fixed in regression in launching background processes and TTY's. Fixed in
-6
View File
@@ -54,11 +54,6 @@ on server and desktop systems as well. For working examples, see the
* [Alpine Linux](contrib/alpine/), and * [Alpine Linux](contrib/alpine/), and
* [Debian GNU/Linux](contrib/debian/) * [Debian GNU/Linux](contrib/debian/)
> **Note:** support for various Linux distributions does not mean Finit
> installs easily on all architectures. The bundled install scripts are
> examples for standard installations, tested on x86_64 systems. Custom
> setups, targeted at embedded systems, can be found in [myLinux][].
Example Example
------- -------
@@ -603,7 +598,6 @@ and proposed extensions.
[Joachim Wiberg]: https://troglobit.com [Joachim Wiberg]: https://troglobit.com
[License]: https://en.wikipedia.org/wiki/MIT_License [License]: https://en.wikipedia.org/wiki/MIT_License
[License Badge]: https://img.shields.io/badge/License-MIT-teal.svg [License Badge]: https://img.shields.io/badge/License-MIT-teal.svg
[GitHub]: https://github.com/troglobit/myLinux/
[GitHub]: https://github.com/troglobit/finit/actions/workflows/build.yml/ [GitHub]: https://github.com/troglobit/finit/actions/workflows/build.yml/
[GitHub Status]: https://github.com/troglobit/finit/actions/workflows/build.yml/badge.svg [GitHub Status]: https://github.com/troglobit/finit/actions/workflows/build.yml/badge.svg
[Coverity Scan]: https://scan.coverity.com/projects/3545 [Coverity Scan]: https://scan.coverity.com/projects/3545
+1 -1
View File
@@ -1,4 +1,4 @@
AC_INIT(Finit, 4.3-rc1, https://github.com/troglobit/finit/issues, finit, https://troglobit.com/finit.html) AC_INIT(Finit, 4.3-dev, https://github.com/troglobit/finit/issues, finit, https://troglobit.com/finit.html)
AC_CONFIG_AUX_DIR(aux) AC_CONFIG_AUX_DIR(aux)
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects]) AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects])
AM_SILENT_RULES([yes]) AM_SILENT_RULES([yes])
+10 -19
View File
@@ -29,8 +29,8 @@ optional plugins to enable. It depends on two external libraries:
The configure script checks for all dependencies, including the correct The configure script checks for all dependencies, including the correct
version of the above mentioned libraries. Currently required versions: version of the above mentioned libraries. Currently required versions:
- libite v2.2.0, or later - libite v2.2.0
- libuEv v2.2.0, or later - libuEv v2.2.0
Configure Configure
@@ -54,7 +54,7 @@ Below are a few of the main switches to configure:
will be linked statically. will be linked statically.
* `--enable-kernel-cmdline`: Enable Finit pre-4.1 parsing of init args from * `--enable-kernel-cmdline`: Enable Finit pre-4.1 parsing of init args from
`/proc/cmdline`, this is *not recommended* since Finit may be running as the `/proc/cmdline`, this is not recommended since Finit may be running as the
init for container apps that can see the host's `/proc` filesystem init for container apps that can see the host's `/proc` filesystem
* `--enable-alsa-utils-plugin`: Enable the optional `alsa-utils.so` sound plugin. * `--enable-alsa-utils-plugin`: Enable the optional `alsa-utils.so` sound plugin.
@@ -67,13 +67,6 @@ Below are a few of the main switches to configure:
For more configure flags, see <kbd>./configure --help</kbd> For more configure flags, see <kbd>./configure --help</kbd>
> **Note:** the configure script is not available in the GIT sources. It is
> however included in (officially supported) released tarballs. The
> idea is that you should not need GNU autotools to build, only the
> above mentioned dependencies, a POSIX shell, a C compiler and make.
> Any contributing to Finit can generate it from `configure.ac` using
> the `autogen.sh` script.
Example Example
------- -------
@@ -81,8 +74,8 @@ Example
First, unpack the archive: First, unpack the archive:
```shell ```shell
$ tar xf finit-4.3.tar.gz $ tar xf finit-4.1.tar.gz
$ cd finit-4.3/ $ cd finit-4.1/
``` ```
Then configure, build and install: Then configure, build and install:
@@ -90,7 +83,7 @@ Then configure, build and install:
```shell ```shell
$ ./configure --prefix=/usr --exec-prefix= \ $ ./configure --prefix=/usr --exec-prefix= \
--sysconfdir=/etc --localstatedir=/var \ --sysconfdir=/etc --localstatedir=/var \
--with-keventd --with-watchdog --with-keventd --with-watchdog
$ make $ make
. .
. .
@@ -98,7 +91,7 @@ $ make
$ DESTDIR=/tmp/finit make install $ DESTDIR=/tmp/finit make install
``` ```
In this example the [finit-4.3.tar.gz][1] archive is unpacked to the In this example the [finit-4.1.tar.gz][1] archive is unpacked to the
user's home directory, configured, built and installed to a temporary user's home directory, configured, built and installed to a temporary
staging directory. The environment variable `DESTDIR` controls the staging directory. The environment variable `DESTDIR` controls the
destination directory when installing, very useful for building binary destination directory when installing, very useful for building binary
@@ -158,14 +151,12 @@ Debugging
--------- ---------
Edit, or append to, the kernel command line: remove `quiet` to enable Edit, or append to, the kernel command line: remove `quiet` to enable
kernel messages and add `finit.debug` to enable Finit debug messages. kernel messages and add `debug` to enable Finit debug messages.
```shell ```shell
append="init=/sbin/finit -- finit.debug" append="init=/sbin/finit debug"
``` ```
Notice the `--` separator.
To debug startup issues, in particular issues with getty/login, add To debug startup issues, in particular issues with getty/login, add
the following to your Finit .conf file: the following to your Finit .conf file:
@@ -184,6 +175,6 @@ it only for debugging start up issues when Finit crashes.
systems since they can potentially give a user root access. systems since they can potentially give a user root access.
[1]: ftp://troglobit.com/finit/finit-4.3.tar.gz [1]: ftp://troglobit.com/finit/finit-4.1.tar.gz
[libuEv]: https://github.com/troglobit/libuev [libuEv]: https://github.com/troglobit/libuev
[libite]: https://github.com/troglobit/libite [libite]: https://github.com/troglobit/libite
+6 -13
View File
@@ -10,13 +10,13 @@ The `bool` setting is one of `on, off, true false, 1, 0`.
> parameters to init. E.g., `init=/sbin/finit -- finit.debug rescue` > parameters to init. E.g., `init=/sbin/finit -- finit.debug rescue`
* `debug`: Enable kernel debug. Debug messages are printed to the * `debug`: Enable kernel debug. Debug messages are printed to the
console until Finit starts up, unless `loglevel=7` (below) is used. console until Finit starts up.
* `finit.debug[=bool]`: Enable finit debug. This is operated * `finit.debug[=bool]`: Enable finit debug. This is operated
independently of the kernel `debug` setting. New as of Finit v4. independently of the kernel debug setting. New as of Finit v4.
* `finit.status[=bool]`: Control finit boot progress, including banner. * `finit.show_status[=bool]`: Control finit boot progress, including
(Used to be `finit.show_status`, which works but is deprecated.) banner.
* `finit.status_style=<classic,modern>`: Set Finit boot progress style, * `finit.status_style=<classic,modern>`: Set Finit boot progress style,
when enabled. when enabled.
@@ -26,18 +26,11 @@ The `bool` setting is one of `on, off, true false, 1, 0`.
signals and has no job control. Recommend using, and modifying, signals and has no job control. Recommend using, and modifying,
`rescue` mode instead. `rescue` mode instead.
* `loglevel=<0-7>`, sets the kernel's log level, which is more granular
than `debug`. Also, when `loglevel=7`, Finit will *not disable*
kernel logs to the console. This is very useful when debugging the
kernel at system bring-up. Since `loglevel=7` is the same as `debug`
this means you have to use `quiet` for a quiet boot, until sysklogd
takes over logging of kernel events.
* `panic=SEC`: By default the kernel does not reboot after a kernel * `panic=SEC`: By default the kernel does not reboot after a kernel
panic. This setting will cause a kernel reboot after SEC seconds. panic. This setting will cause a kernel reboot after SEC seconds.
* `quiet`: Suppress kernel logging to console, except for warnings and * `quiet`: Suppress kernel logging to console, except for warnings and
errors. Also, see `loglevel` and `quiet` above. errors.
* `rescue`: Start rescue/maintenance mode. If your system comes with * `rescue`: Start rescue/maintenance mode. If your system comes with
the bundled `sulogin` program (Finit, or from util-linux/Busybox), the bundled `sulogin` program (Finit, or from util-linux/Busybox),
@@ -53,5 +46,5 @@ The `bool` setting is one of `on, off, true false, 1, 0`.
For more on kernel boot parameters, see the man page [bootparam(7)][]. For more on kernel boot parameters, see the man page [bootparam(7)][].
[config.md]: config.md#rescue-mode [config.md][]: config.md#rescue-mode
[bootparam(7)]: https://www.man7.org/linux/man-pages/man7/bootparam.7.html [bootparam(7)]: https://www.man7.org/linux/man-pages/man7/bootparam.7.html
+3 -17
View File
@@ -323,10 +323,6 @@ calls `init-script restart` on `initctl reload`. Similar to how
Forking services started with `sysv` scripts can be monitored by Finit Forking services started with `sysv` scripts can be monitored by Finit
by declaring the PID file to look for: `pid:!/path/to/pidfile.pid`. by declaring the PID file to look for: `pid:!/path/to/pidfile.pid`.
Notice the leading `!`, it signifies Finit should not try to create the
file, but rather watch that file for the resulting forked-off PID. This
syntax also works for forking daemons that do not have a command line
option to run it in the foreground, more on this below in `service`.
> `<COND>` is described in the [Services](#services) section. > `<COND>` is described in the [Services](#services) section.
@@ -348,19 +344,9 @@ prevent them from forking off a sub-process in the background. This is
the most reliable way to monitor a service. the most reliable way to monitor a service.
However, not all daemons support running in the foreground, or they may However, not all daemons support running in the foreground, or they may
start logging to the foreground as well, these are forking daemons and start logging to the foreground as well, these are called forking
are supported using the same syntax as forking `sysv` services, using services and are supported using the same syntax as forking `sysv`
the `pid:!/path/to/pidfile.pid` syntax. There is an alternative syntax services, using the `pid:!/path/to/pidfile.pid` syntax.
that may be more intuitive, where Finit can also guess the PID file
based on the daemon's command name:
service type:forking ntpd -- NTP daemon
This example lets BusyBox `ntpd` daemonize itself. Finit uses the
basename of the binary to guess the PID file to watch for the PID:
`/var/run/ntpd.pid`. If Finit guesses wrong, you have to submit the
full `pid:!/path/to/file.pid`.
**Example:** **Example:**
+4 -6
View File
@@ -35,27 +35,25 @@ For your convenience a set of *optional* plugins are available:
_Optional plugin._ _Optional plugin._
* *hotplug.so*: Setup and start either udev or mdev hotplug daemon, if * *hotplug.so*: Setup and start either udev or mdev hotplug daemon, if
available. Enabled by default. available.
* *rtc.so*: Restore and save system clock from/to RTC on boot/halt. * *rtc.so*: Restore and save system clock from/to RTC on boot/halt.
Enabled by default.
* *modules-load.so*: Scans /etc/modules-load.d for modules to modprobe. * *modules-load.so*: Scans /etc/modules-load.d for modules to modprobe.
* *netlink.so*: Listens to Linux kernel Netlink events for gateway and * *netlink.so*: Listens to Linux kernel Netlink events for gateway and
interfaces. These events are then sent to the Finit service monitor interfaces. These events are then sent to the Finit service monitor
for services that may want to be SIGHUP'ed on new default route or for services that may want to be SIGHUP'ed on new default route or
interfaces going up/down. Enabled by default. interfaces going up/down.
* *resolvconf.so*: Setup necessary files for `resolvconf` at startup. * *resolvconf.so*: Setup necessary files for `resolvconf` at startup.
_Optional plugin._ _Optional plugin._
* *tty.so*: Watches `/dev`, using inotify, for new device nodes (TTY's) * *tty.so*: Watches `/dev`, using inotify, for new device nodes (TTY's)
to start/stop getty consoles on them on demand. Useful when plugging to start/stop getty consoles on them on demand. Useful when plugging
in a usb2serial converter to login to your embedded device. Enabled in a usb2serial converter to login to your embedded device.
by default.
* *urandom.so*: Setup random seed at startup. Enabled by default. * *urandom.so*: Setup random seed at startup.
* *x11-common.so*: Setup necessary files for X-Window. _Optional plugin._ * *x11-common.so*: Setup necessary files for X-Window. _Optional plugin._
+1 -11
View File
@@ -27,17 +27,7 @@ Finit can *not* start and monitor a daemon that:
### Forks to Background w/ PID File ### Forks to Background w/ PID File
There are two syntax variants, type 1 and type 2. The former is the service pid:!/run/serv.pid serv -- Forking service
traditional one used also for `sysv` start/stop scripts, and the latter
is inspired by systemd, with a twist -- it lets Finit guess the pifdile
to look for based on the standard path and the basename of the command.
service pid:!/run/serv.pid serv -- Forking service, type 1
service type:forking serv -- Forking service, type 2
In this example the resulting files to watch for are `/run/serv.pid` and
`/var/run/serv.pid`, respectively. On most modern Linux systems this is
the same directory (`/var/run` is a symlink to `../run`).
### Runs in Foreground w/ PID File ### Runs in Foreground w/ PID File
+2 -3
View File
@@ -11,9 +11,8 @@
.Nd Fast init for Linux systems .Nd Fast init for Linux systems
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm /sbin/finit .Nm /sbin/finit
.Op -- .Op finit.status_style=classic
.Op finit.status=[on,off] .Op finit.show_status=[on,off]
.Op finit.status_style=[classic,modern]
.Op finit.debug .Op finit.debug
.Op rescue | recover .Op rescue | recover
.Op single | S .Op single | S
+1 -15
View File
@@ -194,21 +194,7 @@ services and are supported using the same syntax as forking
.Cm sysv .Cm sysv
services, using the services, using the
.Cm pid:!/path/to/pidfile.pid .Cm pid:!/path/to/pidfile.pid
command modifier syntax. There is an alternative syntax that may be command modifier syntax.
more intuitive, where Finit can also guess the PID file based on the
daemon's command name:
.Bd -unfilled -offset indent
service type:forking ntpd -- NTP daemon
.Ed
.Pp
Here we let BusyBox
.Nm ntpd
daemonize itself. Finit uses the basename of the binary to guess the
PID file to watch for the PID:
.Pa /var/run/ntpd.pid .
If Finit guesses wrong, you have to submit the full
.Cm pid:!/path/to/file.pid
option to your service stanza.
.Pp .Pp
.Sy Example: in the case of .Sy Example: in the case of
.Cm ospfd .Cm ospfd
+1 -1
View File
@@ -135,7 +135,7 @@ static void setup(void *arg)
ln("/dev/shm", "/run/shm"); ln("/dev/shm", "/run/shm");
/* compat only, should really be set up by OS/dist */ /* compat only, should really be set up by OS/dist */
ln("/run", "/var/run"); ln("../run", "/var/run");
} else { } else {
makedir("/var/lock", 1777); makedir("/var/lock", 1777);
makedir("/var/run", 0755); makedir("/var/run", 0755);
+1 -3
View File
@@ -1,4 +1,3 @@
/* Netlink plugin for IFUP/IFDN and GW events /* Netlink plugin for IFUP/IFDN and GW events
* *
* Copyright (C) 2009-2011 Mårten Wikström <marten.wikstrom@keystream.se> * Copyright (C) 2009-2011 Mårten Wikström <marten.wikstrom@keystream.se>
@@ -253,7 +252,7 @@ static int nl_parse(int sd)
return -1; return -1;
} }
_d("recv %zd bytes", len); _d("recv %lld bytes", len);
l = (size_t)len; l = (size_t)len;
for (nh = (struct nlmsghdr *)nl_buf; NLMSG_OK(nh, l); nh = NLMSG_NEXT(nh, l)) { for (nh = (struct nlmsghdr *)nl_buf; NLMSG_OK(nh, l); nh = NLMSG_NEXT(nh, l)) {
struct nlmsgerr *nle; struct nlmsgerr *nle;
@@ -450,7 +449,6 @@ PLUGIN_INIT(plugin_init)
PLUGIN_EXIT(plugin_exit) PLUGIN_EXIT(plugin_exit)
{ {
plugin_unregister(&plugin); plugin_unregister(&plugin);
close(plugin.io.fd);
} }
/** /**
+1 -1
View File
@@ -305,8 +305,8 @@ PLUGIN_INIT(plugin_init)
PLUGIN_EXIT(plugin_exit) PLUGIN_EXIT(plugin_exit)
{ {
plugin_unregister(&plugin);
iwatch_exit(&iw_pidfile); iwatch_exit(&iw_pidfile);
plugin_unregister(&plugin);
} }
/** /**
+5 -1
View File
@@ -160,19 +160,23 @@ static void sys_init(void *arg)
char sysdir[MAX_ARG_LEN]; char sysdir[MAX_ARG_LEN];
char *path; char *path;
_d("Calling mkpath() on sys conds");
if (mkpath(pid_runpath(_PATH_CONDSYS, sysdir, sizeof(sysdir)), 0755) && errno != EEXIST) { if (mkpath(pid_runpath(_PATH_CONDSYS, sysdir, sizeof(sysdir)), 0755) && errno != EEXIST) {
_pe("Failed creating %s condition directory, %s", COND_SYS, _PATH_CONDSYS); _pe("Failed creating %s condition directory, %s", COND_SYS, _PATH_CONDSYS);
return; return;
} }
_d("Calling realpth() on condsys");
path = realpath(_PATH_CONDSYS, NULL); path = realpath(_PATH_CONDSYS, NULL);
if (!path) { if (!path) {
_pe("Cannot figure out real path to %s, aborting", _PATH_CONDSYS); _pe("Cannot figure out real path to %s, aborting", _PATH_CONDSYS);
return; return;
} }
_d("Calling iwatch_add()");
if (iwatch_add(&iw_sys, path, IN_ONLYDIR)) if (iwatch_add(&iw_sys, path, IN_ONLYDIR))
iwatch_exit(&iw_sys); iwatch_exit(&iw_sys);
_d("Done.");
} }
static plugin_t plugin = { static plugin_t plugin = {
@@ -197,8 +201,8 @@ PLUGIN_INIT(plugin_init)
PLUGIN_EXIT(plugin_exit) PLUGIN_EXIT(plugin_exit)
{ {
plugin_unregister(&plugin);
iwatch_exit(&iw_sys); iwatch_exit(&iw_sys);
plugin_unregister(&plugin);
} }
/** /**
+2 -1
View File
@@ -116,9 +116,10 @@ PLUGIN_INIT(plugin_init)
PLUGIN_EXIT(plugin_exit) PLUGIN_EXIT(plugin_exit)
{ {
plugin_unregister(&plugin);
if (plugin.io.fd) if (plugin.io.fd)
close(plugin.io.fd); close(plugin.io.fd);
plugin_unregister(&plugin);
} }
/** /**
+1 -1
View File
@@ -123,8 +123,8 @@ PLUGIN_INIT(plugin_init)
PLUGIN_EXIT(plugin_exit) PLUGIN_EXIT(plugin_exit)
{ {
plugin_unregister(&plugin);
iwatch_exit(&iw_usr); iwatch_exit(&iw_usr);
plugin_unregister(&plugin);
} }
/** /**
+2 -2
View File
@@ -250,10 +250,10 @@ static int do_reboot(int cmd, char *buf, size_t len)
case INIT_CMD_SUSPEND: case INIT_CMD_SUSPEND:
_d("suspend"); _d("suspend");
sync(); sync();
rc = suspend(); rc = reboot(RB_SW_SUSPEND);
if (rc) { if (rc) {
if (errno == EINVAL) if (errno == EINVAL)
snprintf(buf, len, "Kernel does not support suspend to RAM."); snprintf(buf, len, "Kernel does not support suspend.");
else else
snprintf(buf, len, "Failed: %s", strerror(errno)); snprintf(buf, len, "Failed: %s", strerror(errno));
} }
+1 -1
View File
@@ -526,7 +526,7 @@ void cgroup_init(uev_ctx_t *ctx)
/* Move ourselves to init (best effort, otherwise run in 'root' group */ /* Move ourselves to init (best effort, otherwise run in 'root' group */
if (fnwrite("1", FINIT_CGPATH "/init/cgroup.procs")) { if (fnwrite("1", FINIT_CGPATH "/init/cgroup.procs")) {
_pe("Failed moving PID 1 to cgroup %s", FINIT_CGPATH "/init"); _pe("Failed moving PID 1 to cgroup ", FINIT_CGPATH "/init");
uev_io_stop(&cgw); uev_io_stop(&cgw);
iwatch_exit(&iw_cgroup); iwatch_exit(&iw_cgroup);
close(fd); close(fd);
+5 -3
View File
@@ -86,8 +86,8 @@ fallback:
} }
/* /*
* finit.debug = [on,off] * finit.debug = [on,off]
* finit.status = [on,off] (compat finit.show_status) * finit.show_status = [on,off]
* finit.status_style = [old,classic,modern] * finit.status_style = [old,classic,modern]
*/ */
static void parse_finit_opts(char *opt) static void parse_finit_opts(char *opt)
@@ -116,7 +116,7 @@ static void parse_finit_opts(char *opt)
return; return;
} }
if (string_compare(opt, "status") || string_compare(opt, "show_status")) { if (string_compare(opt, "show_status")) {
show_progress(get_bool(arg, 1) ? PROGRESS_DEFAULT : PROGRESS_SILENT); show_progress(get_bool(arg, 1) ? PROGRESS_DEFAULT : PROGRESS_SILENT);
return; return;
} }
@@ -205,6 +205,8 @@ void conf_parse_cmdline(int argc, char *argv[])
parse_kernel_cmdline(); parse_kernel_cmdline();
parse_kernel_loglevel(); parse_kernel_loglevel();
log_init();
} }
static int kmod_exists(char *mod) static int kmod_exists(char *mod)
+2 -4
View File
@@ -97,14 +97,12 @@ static int do_redirect(void)
*/ */
int run(char *cmd, char *log) int run(char *cmd, char *log)
{ {
char *args[NUM_ARGS + 1] = { 0 };
int status, result, i = 0; int status, result, i = 0;
char *args[NUM_ARGS + 1], *arg;
char *backup = NULL; char *backup = NULL;
pid_t pid; pid_t pid;
if (!log) { if (!log) {
char *arg;
/* We must create a copy that is possible to modify. */ /* We must create a copy that is possible to modify. */
backup = arg = strdup(cmd); backup = arg = strdup(cmd);
if (!arg) if (!arg)
@@ -166,7 +164,7 @@ int run(char *cmd, char *log)
_exit(rc); _exit(rc);
} else if (-1 == pid) { } else if (-1 == pid) {
_pe("%s", !log ? args[0] : cmd); _pe("%s", args[0]);
if (backup) if (backup)
free(backup); free(backup);
+4 -4
View File
@@ -334,7 +334,7 @@ static void fs_mount_all(void)
plugin_run_hooks(HOOK_MOUNT_POST); plugin_run_hooks(HOOK_MOUNT_POST);
if (whichp("swapon")) if (whichp("swapon"))
run_interactive("swapon -ea", "Enabling system swap"); run("swapon -ea", "swapon");
_d("Finalize, ensure common file systems are available ..."); _d("Finalize, ensure common file systems are available ...");
fs_finalize(); fs_finalize();
@@ -570,7 +570,7 @@ int main(int argc, char *argv[])
}; };
uev_ctx_t loop; uev_ctx_t loop;
/* user calling telinit or init */ /* telinit or stand-alone process monitor */
if (getpid() != 1) if (getpid() != 1)
return telinit(argc, argv); return telinit(argc, argv);
@@ -581,12 +581,12 @@ int main(int argc, char *argv[])
/* /*
* Parse /proc/cmdline (debug, rescue, console=, etc.) * Parse /proc/cmdline (debug, rescue, console=, etc.)
* Also calls log_init() to set correct log level
*/ */
conf_parse_cmdline(argc, argv); conf_parse_cmdline(argc, argv);
/* /*
* Figure out system console(s) and call log_init() to set * Figure out system console(s)
* correct log level, possibly finit.debug enabled.
*/ */
console_init(); console_init();
+8 -14
View File
@@ -81,7 +81,7 @@ char *console(void)
void console_init(void) void console_init(void)
{ {
log_init(); ttinit();
} }
ssize_t cprintf(const char *fmt, ...) ssize_t cprintf(const char *fmt, ...)
@@ -500,25 +500,20 @@ void networking(int updown)
if (fexist("/etc/network/interfaces")) { if (fexist("/etc/network/interfaces")) {
pid_t pid; pid_t pid;
if (!updown) {
run_interactive("ifdown -a", "Stopping networking");
goto done;
}
pid = fork(); pid = fork();
if (pid == 0) { if (pid == 0) {
int rc = EX_OSERR; int rc = EX_OSERR;
const char *cmd;
FILE *pp; FILE *pp;
setsid(); setsid();
sig_unblock(); sig_unblock();
if (updown) pp = popen("ifup -a 2>&1", "r");
cmd = "ifup -a 2>&1";
else if (whichp("ifquery"))
/* Regular ifodwn supports --force but not -f */
cmd = "ifdown -a --force 2>&1";
else
/* Busybox ifdown support -f, but not --force */
cmd = "ifdown -a -f 2>&1";
pp = popen(cmd, "r");
if (pp) { if (pp) {
char buf[256]; char buf[256];
@@ -531,8 +526,7 @@ void networking(int updown)
_exit(rc); _exit(rc);
} }
cgroup_service("network", pid, NULL); cgroup_service("network", pid, NULL);
print(pid > 0 ? 0 : 1, "%s network interfaces ...", print(pid > 0 ? 0 : 1, "Bringing up network interfaces ...");
updown ? "Bringing up" : "Taking down");
goto done; goto done;
} }
+3 -3
View File
@@ -65,7 +65,7 @@ struct fstab *getfsent (void);
char *console (void); char *console (void);
void console_init (void); void console_init (void);
ssize_t cprintf (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); ssize_t cprintf (const char *fmt, ...);
char *strip_line (char *line); char *strip_line (char *line);
@@ -79,7 +79,7 @@ void stty (int fd, speed_t speed);
void print_banner (const char *heading); void print_banner (const char *heading);
void printv (const char *fmt, va_list ap); void printv (const char *fmt, va_list ap);
void print (int action, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); void print (int action, const char *fmt, ...);
void print_desc (char *action, char *desc); void print_desc (char *action, char *desc);
int print_result (int fail); int print_result (int fail);
@@ -97,7 +97,7 @@ int in_container (void);
int complete (char *cmd, int pid); int complete (char *cmd, int pid);
int run (char *cmd, char *log); int run (char *cmd, char *log);
int run_interactive (char *cmd, char *fmt, ...) __attribute__ ((format (printf, 2, 3))); int run_interactive (char *cmd, char *fmt, ...);
int exec_runtask (char *cmd, char *args[]); int exec_runtask (char *cmd, char *args[]);
pid_t run_getty (char *tty, char *cmd, char *args[], int noclear, int nowait, struct rlimit rlimit[]); pid_t run_getty (char *tty, char *cmd, char *args[], int noclear, int nowait, struct rlimit rlimit[]);
pid_t run_sh (char *tty, int noclear, int nowait, struct rlimit rlimit[]); pid_t run_sh (char *tty, int noclear, int nowait, struct rlimit rlimit[]);
+1 -1
View File
@@ -34,7 +34,7 @@ extern int heading; /* initctl -t */
extern int verbose; /* initctl -v */ extern int verbose; /* initctl -v */
extern int plain; /* initctl -p */ extern int plain; /* initctl -p */
extern void print_header(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); extern void print_header(const char *fmt, ...);
#endif /* FINIT_INITCTL_H_ */ #endif /* FINIT_INITCTL_H_ */
+2 -4
View File
@@ -62,10 +62,8 @@ int iwatch_init(struct iwatch *iw)
* reconf of systems with lots of services. * reconf of systems with lots of services.
*/ */
len = sizeof(sz); len = sizeof(sz);
if (!getsockopt(iw->fd, SOL_SOCKET, SO_RCVBUF, &sz, &len)) { if (!getsockopt(iw->fd, SOL_SOCKET, SO_RCVBUF, &sz, &len))
if (setsockopt(iw->fd, SOL_SOCKET, SO_RCVBUF, &sz, sizeof(sz))) setsockopt(iw->fd, SOL_SOCKET, SO_RCVBUF, &sz, sizeof(sz));
_pe("Failed increasing size of inotify socket");
}
initialized = 1; initialized = 1;
+5 -41
View File
@@ -24,7 +24,6 @@
#include <errno.h> #include <errno.h>
#include <dirent.h> #include <dirent.h>
#include <poll.h> #include <poll.h>
#include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
@@ -53,10 +52,6 @@
static int num_ac_online; static int num_ac_online;
static int num_ac; static int num_ac;
static int running = 1;
static int level;
static int logon;
int debug; /* debug in other modules as well */ int debug; /* debug in other modules as well */
void logit(int prio, const char *fmt, ...) void logit(int prio, const char *fmt, ...)
@@ -64,9 +59,9 @@ void logit(int prio, const char *fmt, ...)
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
if (logon) if (!debug)
vsyslog(prio, fmt, ap); vsyslog(prio, fmt, ap);
else if (prio <= level) { else {
vfprintf(stderr, fmt, ap); vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
@@ -184,26 +179,6 @@ static void init(void)
sys_cond("pwr/ac", 1); sys_cond("pwr/ac", 1);
} }
static void set_logging(int prio)
{
setlogmask(LOG_UPTO(prio));
level = prio;
}
static void toggle_debug(int signo)
{
(void)signo;
debug ^= 1;
set_logging(debug ? LOG_DEBUG : LOG_NOTICE);
}
static void shut_down(int signo)
{
(void)signo;
running = 0;
}
/* /*
* Started by Finit as soon as possible when base filesystem is up, * Started by Finit as soon as possible when base filesystem is up,
* modules have been probed, or insmodded from /etc/finit.conf, so by * modules have been probed, or insmodded from /etc/finit.conf, so by
@@ -223,13 +198,10 @@ int main(int argc, char *argv[])
} }
if (!debug) { if (!debug) {
openlog("keventd", LOG_PID, LOG_DAEMON); openlog("keventd", LOG_CONS | LOG_PID, LOG_DAEMON);
set_logging(LOG_NOTICE); setlogmask(LOG_UPTO(LOG_NOTICE));
logon = 1;
} }
signal(SIGUSR1, toggle_debug);
signal(SIGTERM, shut_down);
init(); init();
pfd.events = POLLIN; pfd.events = POLLIN;
@@ -244,18 +216,11 @@ int main(int argc, char *argv[])
panic("bind failed"); panic("bind failed");
logit(LOG_DEBUG, "Waiting for events ..."); logit(LOG_DEBUG, "Waiting for events ...");
while (running) { while (-1 != poll(&pfd, 1, -1)) {
char *path = NULL; char *path = NULL;
int ac = 0; int ac = 0;
int i, len; int i, len;
if (-1 == poll(&pfd, 1, -1)) {
if (errno == EINTR)
continue;
break;
}
len = recv(pfd.fd, buf, sizeof(buf), MSG_DONTWAIT); len = recv(pfd.fd, buf, sizeof(buf), MSG_DONTWAIT);
if (len == -1) { if (len == -1) {
switch (errno) { switch (errno) {
@@ -270,7 +235,6 @@ int main(int argc, char *argv[])
} }
} }
buf[len] = 0; buf[len] = 0;
logit(LOG_DEBUG, "%s", buf);
/* skip libusb events, focus on kernel events/changes */ /* skip libusb events, focus on kernel events/changes */
if (strncmp(buf, "change@", 7)) if (strncmp(buf, "change@", 7))
+7 -10
View File
@@ -40,8 +40,6 @@ static int loglevel = LOG_INFO;
void log_init(void) void log_init(void)
{ {
ttinit();
if (debug) if (debug)
loglevel = LOG_DEBUG; loglevel = LOG_DEBUG;
else else
@@ -74,25 +72,24 @@ static int log_open(void)
if (debug) if (debug)
opts |= LOG_PERROR; opts |= LOG_PERROR;
closelog();
openlog("finit", opts, LOG_DAEMON); openlog("finit", opts, LOG_DAEMON);
setlogmask(LOG_UPTO(loglevel)); setlogmask(LOG_UPTO(loglevel));
return up = 1; return up = 1;
} }
static void log_close(void)
{
closelog();
up = 0;
}
/* Toggle debug mode */ /* Toggle debug mode */
void log_debug(void) void log_debug(void)
{ {
debug = !debug; debug = !debug;
log_close(); if (debug) {
log_init(); loglevel = LOG_DEBUG;
} else {
loglevel = LOG_NOTICE;
ttinit();
}
log_open(); log_open();
logit(LOG_NOTICE, "Debug mode %s", debug ? "enabled" : "disabled"); logit(LOG_NOTICE, "Debug mode %s", debug ? "enabled" : "disabled");
+3 -3
View File
@@ -43,14 +43,14 @@
#define _d(fmt, args...) logit(LOG_DEBUG, "%s():" fmt, __func__, ##args) #define _d(fmt, args...) logit(LOG_DEBUG, "%s():" fmt, __func__, ##args)
#define _w(fmt, args...) logit(LOG_WARNING, "%s():" fmt, __func__, ##args) #define _w(fmt, args...) logit(LOG_WARNING, "%s():" fmt, __func__, ##args)
#define _e(fmt, args...) logit(LOG_ERR, "%s():" fmt, __func__, ##args) #define _e(fmt, args...) logit(LOG_ERR, "%s():" fmt, __func__, ##args)
#define _pe(fmt, args...) logit(LOG_ERR, "%s():" fmt ": %s", __func__, ##args, strerror(errno)) #define _pe(fmt, args...) logit(LOG_ERR, "%s():" fmt ": %n", __func__, ##args, strerror(errno))
void log_init (void); void log_init (void);
void log_exit (void); void log_exit (void);
void log_debug (void); void log_debug (void);
void logit (int prio, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); void logit (int prio, const char *fmt, ...);
void flog (char *file, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); void flog (char *file, const char *fmt, ...);
#endif /* FINIT_LOG_H_ */ #endif /* FINIT_LOG_H_ */
+2 -19
View File
@@ -21,13 +21,10 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include <errno.h>
#include <string.h> #include <string.h>
#include <mntent.h> #include <mntent.h>
#include <sys/mount.h> #include <sys/mount.h>
#include "helpers.h"
/* /*
* SysV init on Debian/Ubuntu skips these protected mount points * SysV init on Debian/Ubuntu skips these protected mount points
* *
@@ -89,27 +86,13 @@ static struct mntent *iterator(char *fstab, FILE **fp)
return NULL; return NULL;
} }
static int unmount(const char *target)
{
int rc;
rc = umount(target);
if (rc && errno != EBUSY) {
print(2, "Failed unmounting %s, error %d: %s", target, errno, strerror(errno));
return rc;
}
print(0, "Unmounting %s", target);
return 0;
}
void unmount_tmpfs(void) void unmount_tmpfs(void)
{ {
struct mntent *mnt; struct mntent *mnt;
FILE *fp = NULL; FILE *fp = NULL;
while ((mnt = iterator("/proc/mounts", &fp))) { while ((mnt = iterator("/proc/mounts", &fp))) {
if (!strcmp("tmpfs", mnt->mnt_fsname) && !unmount(mnt->mnt_dir)) if (!strcmp("tmpfs", mnt->mnt_fsname) && !umount(mnt->mnt_dir))
iterator_end(&fp); /* Restart iteration */ iterator_end(&fp); /* Restart iteration */
} }
} }
@@ -120,7 +103,7 @@ void unmount_regular(void)
FILE *fp = NULL; FILE *fp = NULL;
while ((mnt = iterator("/proc/mounts", &fp))) { while ((mnt = iterator("/proc/mounts", &fp))) {
if (!unmount(mnt->mnt_dir)) if (!umount(mnt->mnt_dir))
iterator_end(&fp); /* Restart iteration */ iterator_end(&fp); /* Restart iteration */
} }
} }
+4 -10
View File
@@ -69,11 +69,10 @@ int pid_alive(pid_t pid)
*/ */
char *pid_get_name(pid_t pid, char *name, size_t len) char *pid_get_name(pid_t pid, char *name, size_t len)
{ {
static char line[64];
char *pname = NULL;
char path[32];
int ret = 1; int ret = 1;
FILE *fp; FILE *fp;
char *pname, path[32];
static char line[64];
snprintf(path, sizeof(path), "/proc/%d/status", pid); snprintf(path, sizeof(path), "/proc/%d/status", pid);
fp = fopen(path, "r"); fp = fopen(path, "r");
@@ -114,8 +113,8 @@ char *pid_file(svc_t *svc)
pid_t pid_file_read(const char *fn) pid_t pid_file_read(const char *fn)
{ {
pid_t pid = 0; pid_t pid = 0;
char buf[42];
FILE *fp; FILE *fp;
char buf[42];
fp = fopen(fn, "r"); fp = fopen(fn, "r");
if (!fp) if (!fp)
@@ -158,11 +157,6 @@ int pid_file_set(svc_t *svc, char *file, int not)
file++; file++;
} }
if (svc_is_forking(svc) && !not) {
logit(LOG_WARNING, "Service %s is forking, adjusting to pid:!%s", svc->name, file);
not = 1;
}
pid_runpath(file, &svc->pidfile[not], sizeof(svc->pidfile) - not); pid_runpath(file, &svc->pidfile[not], sizeof(svc->pidfile) - not);
if (not) if (not)
svc->pidfile[0] = '!'; svc->pidfile[0] = '!';
@@ -205,8 +199,8 @@ int pid_file_parse(svc_t *svc, char *arg)
/* 'pid:' implies argument following*/ /* 'pid:' implies argument following*/
if (!strncmp(arg, "pid:", 4)) { if (!strncmp(arg, "pid:", 4)) {
char path[MAX_ARG_LEN];
int len, not = 0; int len, not = 0;
char path[MAX_ARG_LEN];
arg += 4; arg += 4;
if ((arg[0] == '!' && arg[1] == '/') || arg[0] == '/') if ((arg[0] == '!' && arg[1] == '/') || arg[0] == '/')
+2 -4
View File
@@ -160,8 +160,6 @@ int reboot_main(int argc, char *argv[])
transform(NULL); transform(NULL);
if (force) { if (force) {
sync();
switch (cmd) { switch (cmd) {
case CMD_REBOOT: case CMD_REBOOT:
c = reboot(RB_AUTOBOOT); c = reboot(RB_AUTOBOOT);
@@ -176,9 +174,9 @@ int reboot_main(int argc, char *argv[])
break; break;
case CMD_SUSPEND: case CMD_SUSPEND:
c = suspend(); c = reboot(RB_SW_SUSPEND);
if (c && errno == EINVAL) if (c && errno == EINVAL)
errx(1, "Kernel does not support suspend to RAM."); errx(1, "Kernel does not support suspend.");
break; break;
case CMD_UNKNOWN: case CMD_UNKNOWN:
+1 -31
View File
@@ -34,24 +34,9 @@
# include <lite/lite.h> # include <lite/lite.h>
#endif #endif
#include "client.h"
#include "initctl.h" #include "initctl.h"
static int is_builtin(char *arg)
{
svc_t *svc;
svc = client_svc_find(arg);
if (!svc)
return 0;
if (svc->file[0])
return 0;
return 1;
}
static int calc_width(char *arr[], size_t len) static int calc_width(char *arr[], size_t len)
{ {
int width = 0; int width = 0;
@@ -307,8 +292,6 @@ int serv_touch(char *arg)
if (!fexist(fn)) { if (!fexist(fn)) {
if (!strstr(arg, "finit.conf")) if (!strstr(arg, "finit.conf"))
errx(1, "%s not available.", arg); errx(1, "%s not available.", arg);
if (is_builtin(arg))
errx(1, "%s is a built-in service.", arg);
strlcpy(path, FINIT_CONF, sizeof(path)); strlcpy(path, FINIT_CONF, sizeof(path));
fn = path; fn = path;
@@ -328,9 +311,6 @@ int serv_show(char *arg)
fn = conf(path, sizeof(path), arg, 0); fn = conf(path, sizeof(path), arg, 0);
if (!fexist(fn)) { if (!fexist(fn)) {
if (is_builtin(arg))
errx(1, "%s is a built-in service.", arg);
warnx("Cannot find %s", arg); warnx("Cannot find %s", arg);
return 1; return 1;
} }
@@ -365,9 +345,6 @@ static int do_edit(char *arg, int creat)
fn = conf(path, sizeof(path), arg, creat); fn = conf(path, sizeof(path), arg, creat);
if (!fexist(fn)) { if (!fexist(fn)) {
if (is_builtin(arg))
errx(1, "%s is a built-in service.", arg);
if (!creat) { if (!creat) {
warnx("Cannot find %s, use -c flag, create command, or select one of:", arg); warnx("Cannot find %s, use -c flag, create command, or select one of:", arg);
return serv_list(NULL); return serv_list(NULL);
@@ -394,7 +371,6 @@ int serv_edit(char *arg)
if (!arg || !arg[0]) { if (!arg || !arg[0]) {
if (!yorn("Do you want to edit %s (y/N)? ", FINIT_CONF)) if (!yorn("Do you want to edit %s (y/N)? ", FINIT_CONF))
return 0; return 0;
arg = "";
} }
return do_edit(arg, icreate); return do_edit(arg, icreate);
@@ -409,9 +385,6 @@ int serv_creat(char *arg)
if (!arg || !arg[0]) if (!arg || !arg[0])
errx(1, "missing argument to create"); errx(1, "missing argument to create");
if (is_builtin(arg))
errx(1, "%s is a built-in service.", arg);
/* Input from a pipe or a proper TTY? */ /* Input from a pipe or a proper TTY? */
if (isatty(STDIN_FILENO)) if (isatty(STDIN_FILENO))
return do_edit(arg, 1); return do_edit(arg, 1);
@@ -447,11 +420,8 @@ int serv_delete(char *arg)
} }
fn = conf(buf, sizeof(buf), arg, 0); fn = conf(buf, sizeof(buf), arg, 0);
if (!fn) { if (!fn)
if (is_builtin(arg))
errx(1, "%s is a built-in service.", arg);
errx(1, FINIT_RCSD " missing on system."); errx(1, FINIT_RCSD " missing on system.");
}
if (!fexist(fn)) if (!fexist(fn))
warnx("cannot find %s", fn); warnx("cannot find %s", fn);
+13 -41
View File
@@ -558,7 +558,7 @@ static int service_start(svc_t *svc)
for (i = 0; i < we.we_wordc; i++) { for (i = 0; i < we.we_wordc; i++) {
if (strlen(we.we_wordv[i]) >= sizeof(svc->args[i])) { if (strlen(we.we_wordv[i]) >= sizeof(svc->args[i])) {
logit(LOG_ERR, "%s: expanded arg. '%s' too long", svc->cmd, we.we_wordv[i]); logit(LOG_ERR, "%s: expanded arg. '%s' too long", we.we_wordv[i]);
rc = WRDE_NOSPACE; rc = WRDE_NOSPACE;
goto nomem; goto nomem;
} }
@@ -747,14 +747,6 @@ static int service_stop(svc_t *svc)
*/ */
svc_started(svc); svc_started(svc);
/*
* Verify there's still something there before we send the reaper.
*/
if (svc->pid > 1 && !pid_alive(svc->pid)) {
svc->pid = 0;
return 0;
}
if (!svc->desc[0]) if (!svc->desc[0])
do_progress = 0; do_progress = 0;
@@ -931,7 +923,7 @@ static void parse_env(svc_t *svc, char *env)
return; return;
if (strlen(env) >= sizeof(svc->env)) { if (strlen(env) >= sizeof(svc->env)) {
_e("%s: env file is too long (>%zu chars)", svc->cmd, sizeof(svc->env)); _e("%s: env file is too long (>%d chars)", svc->cmd, sizeof(svc->env));
return; return;
} }
@@ -955,7 +947,7 @@ static void parse_cgroup(svc_t *svc, char *cgroup)
} }
if (strlen(ptr) >= sizeof(svc->cgroup)) { if (strlen(ptr) >= sizeof(svc->cgroup)) {
_e("%s: cgroup settings too long (>%zu chars)", svc->cmd, sizeof(svc->cgroup)); _e("%s: cgroup settings too long (>%d chars)", svc->cmd, sizeof(svc->cgroup));
return; return;
} }
@@ -991,7 +983,7 @@ static void parse_killdelay(svc_t *svc, char *delay)
static void parse_script(char *type, char *script, char *buf, size_t len) static void parse_script(char *type, char *script, char *buf, size_t len)
{ {
if (access(script, X_OK)) if (access(script, X_OK))
logit(LOG_WARNING, "%s:%s is missing or not executable, skipping.", type, script); logit(LOG_WARNING, "%s: %s:%s is missing or not executable, skipping.", type, script);
else else
strlcpy(buf, script, len); strlcpy(buf, script, len);
} }
@@ -1162,7 +1154,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
char *dev = NULL; char *dev = NULL;
int respawn = 0; int respawn = 0;
int levels = 0; int levels = 0;
int forking = 0, manual = 0; int manual = 0;
int restart_max = SVC_RESPAWN_MAX; int restart_max = SVC_RESPAWN_MAX;
int restart_tmo = 0; int restart_tmo = 0;
unsigned oncrash_action = SVC_ONCRASH_IGNORE; unsigned oncrash_action = SVC_ONCRASH_IGNORE;
@@ -1221,8 +1213,6 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
pid = cmd; pid = cmd;
else if (!strncasecmp(cmd, "name:", 5)) else if (!strncasecmp(cmd, "name:", 5))
name = cmd; name = cmd;
else if (!strncasecmp(cmd, "type:forking", 10))
forking = 1;
else if (!strncasecmp(cmd, "manual:yes", 10)) else if (!strncasecmp(cmd, "manual:yes", 10))
manual = 1; manual = 1;
else if (!strncasecmp(cmd, "restart:", 8)) else if (!strncasecmp(cmd, "restart:", 8))
@@ -1334,6 +1324,10 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
svc_unblock(svc); svc_unblock(svc);
} }
/* Decode any optional pid:/optional/path/to/file.pid */
if (pid && (svc_is_daemon(svc) || svc_is_sysv(svc)) && pid_file_parse(svc, pid))
_e("Invalid 'pid' argument to service: %s", pid);
if (username) { if (username) {
char *ptr = strchr(username, ':'); char *ptr = strchr(username, ':');
@@ -1411,26 +1405,8 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
parse_env(svc, env); parse_env(svc, env);
if (file) if (file)
strlcpy(svc->file, file, sizeof(svc->file)); strlcpy(svc->file, file, sizeof(svc->file));
svc->respawn = respawn; if (respawn)
svc->forking = forking; svc->respawn = 1;
/* Decode any (optional) pid:/optional/path/to/file.pid */
if (svc_is_daemon(svc) || svc_is_sysv(svc)) {
char tmp[sizeof(svc->name) + 6]; /* pid:! + svc->name */
/* no pid: set, figure out a default to track this svc */
if (!pid && forking) {
snprintf(tmp, sizeof(tmp), "pid:!%s", svc->name);
pid = tmp;
logit(LOG_INFO, "%s: forking but no pid:!file set, guessing -> %s", svc->name, tmp);
}
if (pid && pid_file_parse(svc, pid))
logit(LOG_WARNING, "%s: service has invalid 'pid:' config: %s", svc->name, pid);
if (svc->pidfile[0] == '!')
svc->forking = 1;
}
/* Set configured limits */ /* Set configured limits */
memcpy(svc->rlimit, rlimit, sizeof(svc->rlimit)); memcpy(svc->rlimit, rlimit, sizeof(svc->rlimit));
@@ -1509,10 +1485,8 @@ void service_monitor(pid_t lost, int status)
} }
/* Forking sysv/services declare themselves with pid:!/path/to/pid.file */ /* Forking sysv/services declare themselves with pid:!/path/to/pid.file */
if (svc_is_starting(svc) && svc_is_forking(svc)) { if (svc_is_starting(svc) && svc_is_forking(svc))
svc->pid = 0; /* Expect no more activity from this one */
return; return;
}
/* Terminate any children in the same proess group, e.g. logit */ /* Terminate any children in the same proess group, e.g. logit */
kill(-svc->pid, SIGKILL); kill(-svc->pid, SIGKILL);
@@ -1599,6 +1573,7 @@ static void set_pre_post_envs(svc_t *svc, const char *type)
if (!access(fn, R_OK)) if (!access(fn, R_OK))
exist = "1"; exist = "1";
} }
setenv("SERVICE_ENV_FILE", fn, 1);
setenv("SERVICE_ENV_FILE_EXIST", exist, 1); setenv("SERVICE_ENV_FILE_EXIST", exist, 1);
#ifdef FINIT_SYSCONFIG #ifdef FINIT_SYSCONFIG
@@ -1871,9 +1846,6 @@ restart:
if (!svc->pid) { if (!svc->pid) {
if (svc_is_daemon(svc) || svc_is_tty(svc)) { if (svc_is_daemon(svc) || svc_is_tty(svc)) {
if (svc_is_forking(svc))
break;
svc_restarting(svc); svc_restarting(svc);
svc_set_state(svc, SVC_HALTED_STATE); svc_set_state(svc, SVC_HALTED_STATE);
+4 -13
View File
@@ -207,8 +207,7 @@ void do_iterate_proc(int (*cb)(int, void *), void *data)
_d("Skipping %s ...", &file[1]); _d("Skipping %s ...", &file[1]);
else else
if (cb(pid, data)) { if (cb(pid, data)) {
_d("PID %d is still alive (%s)", pid, file); print(0, "PID %d is still alive (%s)", pid, file);
fclose(fp);
break; break;
} }
} }
@@ -324,21 +323,13 @@ void do_shutdown(shutop_t op)
/* Unmount any tmpfs before unmounting swap ... */ /* Unmount any tmpfs before unmounting swap ... */
unmount_tmpfs(); unmount_tmpfs();
if (whichp("swapoff")) if (whichp("swapoff"))
run_interactive("swapoff -a", "Disabling system swap"); run("swapoff -e -a", "swapoff");
/* ... unmount remaining regular file systems. */ /* ... unmount remaining regular file systems. */
unmount_regular(); unmount_regular();
/* /* We sit on / so we must remount it read-only */
* We sit on / so we must remount it ro, try all the things! run("mount -n -o remount,ro -t none rootfs /", "mount");
* See the following links for details:
* - https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=339023
* - https://bugs.launchpad.net/ubuntu/+source/util-linux/+bug/29187
*/
sync();
run("mount -n -o remount,ro -t dummytype dummydev /", NULL);
run("mount -n -o remount,ro dummydev /", NULL);
run("mount -n -o remount,ro /", "mount");
/* Call mdadm to mark any RAID array(s) as clean before halting. */ /* Call mdadm to mark any RAID array(s) as clean before halting. */
mdadm_wait(); mdadm_wait();
+1 -2
View File
@@ -127,7 +127,6 @@ typedef struct svc {
int starting; /* ... waiting for pidfile to be re-asserted */ int starting; /* ... waiting for pidfile to be re-asserted */
int runlevels; int runlevels;
int sighup; /* This service supports SIGHUP :) */ int sighup; /* This service supports SIGHUP :) */
int forking; /* This is a service/sysv daemon that forks, wait for it ... */
svc_block_t block; /* Reason that this service is currently stopped */ svc_block_t block; /* Reason that this service is currently stopped */
char cond[MAX_COND_LEN]; char cond[MAX_COND_LEN];
@@ -229,7 +228,7 @@ static inline int svc_is_daemon (svc_t *svc) { return svc && SVC_TYPE_SERVICE
static inline int svc_is_sysv (svc_t *svc) { return svc && SVC_TYPE_SYSV == svc->type; } static inline int svc_is_sysv (svc_t *svc) { return svc && SVC_TYPE_SYSV == svc->type; }
static inline int svc_is_tty (svc_t *svc) { return svc && SVC_TYPE_TTY == svc->type; } static inline int svc_is_tty (svc_t *svc) { return svc && SVC_TYPE_TTY == svc->type; }
static inline int svc_is_runtask (svc_t *svc) { return svc && (SVC_TYPE_RUNTASK & svc->type);} static inline int svc_is_runtask (svc_t *svc) { return svc && (SVC_TYPE_RUNTASK & svc->type);}
static inline int svc_is_forking (svc_t *svc) { return svc && svc->forking; } static inline int svc_is_forking (svc_t *svc) { return (svc_is_daemon(svc) || svc_is_sysv(svc)) && svc->pidfile[0] == '!'; }
static inline int svc_in_runlevel (svc_t *svc, int runlevel) { return svc && ISSET(svc->runlevels, runlevel); } static inline int svc_in_runlevel (svc_t *svc, int runlevel) { return svc && ISSET(svc->runlevels, runlevel); }
static inline int svc_nohup (svc_t *svc) { return svc && (0 == svc->sighup || 0 != svc->args_dirty); } static inline int svc_nohup (svc_t *svc) { return svc && (0 == svc->sighup || 0 != svc->args_dirty); }
+1 -35
View File
@@ -224,7 +224,7 @@ int fngetint(char *path, int *val)
{ {
char buf[64]; char buf[64];
if (fnread(buf, sizeof(buf), "%s", path) <= 0) if (fnread(buf, sizeof(buf), path) <= 0)
return -1; return -1;
errno = 0; errno = 0;
@@ -235,40 +235,6 @@ int fngetint(char *path, int *val)
return 0; return 0;
} }
/*
* This is a replacement for the non-working reboot(RB_SW_SUSPEND). It
* checks for suspend to RAM support, assuming `mem_sleep` has a sane
* default, e.g. 'deep' or 's2idle'. The latter should be possible to
* select from finit.conf, but for now we go with the kernel default.
* For more information on kernel sleep states, see:
* https://www.kernel.org/doc/html/latest/admin-guide/pm/sleep-states.html
*/
int suspend(void)
{
char buf[80];
char *ptr;
if (fnread(buf, sizeof(buf), "/sys/power/state") <= 0) {
opnotsup:
errno = EINVAL;
return 1;
}
chomp(buf);
ptr = strtok(buf, " ");
while (ptr) {
if (!strcmp(ptr, "mem"))
break;
ptr = strtok(NULL, " ");
}
if (!ptr)
goto opnotsup;
return fnwrite("mem", "/sys/power/state");
}
int strtobytes(char *arg) int strtobytes(char *arg)
{ {
int mod = 0, bytes; int mod = 0, bytes;
+4 -6
View File
@@ -54,13 +54,11 @@ extern char *prognm;
char *progname (char *arg0); char *progname (char *arg0);
char *str (char *fmt, ...) __attribute__ ((format (printf, 1, 2))); char *str (char *fmt, ...);
int fnread (char *buf, size_t len, char *fmt, ...) __attribute__ ((format (printf, 3, 4))); int fnread (char *buf, size_t len, char *fmt, ...);
int fnwrite (char *value, char *fmt, ...) __attribute__ ((format (printf, 2, 3))); int fnwrite (char *value, char *fmt, ...);
int fngetint (char *path, int *val); int fngetint (char *path, int *val);
int suspend (void);
int strtobytes (char *arg); int strtobytes (char *arg);
char *sig2str (int sig); char *sig2str (int sig);
int str2sig (char *sig); int str2sig (char *sig);
@@ -87,7 +85,7 @@ int ttcooked (void);
#define ttcooked() 0 #define ttcooked() 0
#endif #endif
static __attribute__ ((format (printf, 1, 2))) inline void dbg(char *fmt, ...) static inline void dbg(char *fmt, ...)
{ {
va_list ap; va_list ap;
+1 -16
View File
@@ -1,21 +1,6 @@
SUBDIRS = common tenv SUBDIRS = common tenv
EXTRA_DIST = skel/bin/busybox-x86_64.md5 skel/sbin/service.sh skel/bin/slay \ EXTRA_DIST = setup-root.sh
skel/cdrom/.empty skel/dev/shm/.empty skel/dev/pts/.empty \
skel/etc/inittab skel/etc/hostname skel/etc/fstab \
skel/etc/init.d/rcS skel/etc/init.d/rcK skel/tmp/.empty \
skel/etc/init.d/S01-service.sh skel/home/.empty \
skel/proc/.empty skel/root/.empty skel/run/.empty \
skel/sbin/chrootsetup.sh skel/srv/.empty skel/sys/.empty \
skel/usr/bin/.empty skel/usr/lib/.empty skel/usr/sbin/.empty \
skel/usr/games/.empty skel/usr/src/.empty \
skel/usr/share/.empty skel/usr/include/.empty \
skel/usr/local/games/.empty skel/usr/local/sbin/.empty \
skel/usr/local/share/.empty skel/usr/local/src/.empty \
skel/usr/local/lib/.empty skel/usr/local/bin/.empty \
skel/usr/local/etc/.empty skel/var/.empty
EXTRA_DIST += setup-root.sh
EXTRA_DIST += add-remove-dynamic-service.sh EXTRA_DIST += add-remove-dynamic-service.sh
EXTRA_DIST += add-remove-dynamic-service-sub-config.sh EXTRA_DIST += add-remove-dynamic-service-sub-config.sh
EXTRA_DIST += start-stop-service.sh EXTRA_DIST += start-stop-service.sh
@@ -13,12 +13,15 @@ test_teardown()
say "Running test teardown." say "Running test teardown."
texec rm -f "$FINIT_RCSD/service.conf" texec rm -f "$FINIT_RCSD/service.conf"
texec rm -f /test_assets/service.sh
} }
say "Test start $(date)" say "Test start $(date)"
cp "$TEST_DIR"/common/service.sh "$TENV_ROOT"/test_assets/
say "Add a dynamic service in $FINIT_RCSD/service.conf" say "Add a dynamic service in $FINIT_RCSD/service.conf"
texec sh -c "echo 'service [2345] kill:20 log service.sh -- Dyn serv' > $FINIT_RCSD/service.conf" texec sh -c "echo 'service [2345] kill:20 log /test_assets/service.sh -- Dyn serv' > $FINIT_RCSD/service.conf"
say 'Reload Finit' say 'Reload Finit'
texec sh -c "initctl reload" texec sh -c "initctl reload"
+10 -1
View File
@@ -3,6 +3,7 @@
set -eu set -eu
TEST_DIR=$(dirname "$0") TEST_DIR=$(dirname "$0")
export DEBUG=1
# shellcheck source=/dev/null # shellcheck source=/dev/null
. "$TEST_DIR/tenv/lib.sh" . "$TEST_DIR/tenv/lib.sh"
@@ -13,12 +14,20 @@ test_teardown()
say "Running test teardown." say "Running test teardown."
texec rm -f "$FINIT_CONF" texec rm -f "$FINIT_CONF"
texec rm -f /test_assets/service.sh
} }
say "Hi, this is /run et al"
texec sh -c "echo 'ROOT:/bin'; ls -l /bin/; echo 'ROOT:/sbin'; ls -l /sbin/; echo 'ROOT:/run'; ls -l /run/; echo 'ROOT:/run/finit/'; ls -l /run/finit/; echo 'ROOT:/dev'; ls -l /dev/; ps; ls -l /proc/1/fd/"
say "HUPing PID 1 ..."
texec sh -c "kill -HUP 1"
say "Test start $(date)" say "Test start $(date)"
cp "$TEST_DIR"/common/service.sh "$TENV_ROOT"/test_assets/
say "Add a dynamic service in $FINIT_CONF" say "Add a dynamic service in $FINIT_CONF"
texec sh -c "echo 'service [2345] kill:20 log service.sh -- Dyn service' > $FINIT_CONF" texec sh -c "echo 'service [2345] kill:20 log /test_assets/service.sh -- Dyn service' > $FINIT_CONF"
say 'Reload Finit' say 'Reload Finit'
texec sh -c "initctl reload" texec sh -c "initctl reload"
+2
View File
@@ -1,2 +1,4 @@
EXTRA_DIST = service.conf service.sh S01-service.sh slay.sh
noinst_PROGRAMS = serv noinst_PROGRAMS = serv
serv_SOURCES = serv.c serv_SOURCES = serv.c
@@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# SysV style start script for service.sh # SysV style start script for service.sh
DAEMON="/sbin/service.sh" DAEMON="/test_assets/service.sh"
PIDFILE="/var/run/service.pid" PIDFILE="/var/run/service.pid"
start() start()
+1
View File
@@ -0,0 +1 @@
service [2345] kill:20 log /test_assets/service.sh
+10 -3
View File
@@ -5,9 +5,6 @@ set -eu
# shellcheck disable=SC2154 # shellcheck disable=SC2154
make -C "$top_builddir" DESTDIR="$TENV_ROOT" install make -C "$top_builddir" DESTDIR="$TENV_ROOT" install
mkdir -p "$TENV_ROOT/sbin/"
cp "$top_builddir/test/common/serv" "$TENV_ROOT/sbin/"
# shellcheck disable=SC2154 # shellcheck disable=SC2154
FINITBIN="$(pwd)/$top_builddir/src/finit" DEST="$TENV_ROOT" make -f "$srcdir/tenv/root.mk" FINITBIN="$(pwd)/$top_builddir/src/finit" DEST="$TENV_ROOT" make -f "$srcdir/tenv/root.mk"
@@ -15,3 +12,13 @@ FINITBIN="$(pwd)/$top_builddir/src/finit" DEST="$TENV_ROOT" make -f "$srcdir/ten
for plugin in tty.so urandom.so rtc.so modprobe.so hotplug.so; do for plugin in tty.so urandom.so rtc.so modprobe.so hotplug.so; do
find "$TENV_ROOT" -name $plugin -delete find "$TENV_ROOT" -name $plugin -delete
done done
echo "$TENV_ROOT:"
ls -l "$TENV_ROOT"
echo "$TENV_ROOT:/bin"
ls -l "$TENV_ROOT"/bin
echo "$TENV_ROOT:/sbin"
ls -l "$TENV_ROOT"/sbin
echo "$TENV_ROOT:/var"
ls -l "$TENV_ROOT"/var/
+4 -1
View File
@@ -14,15 +14,18 @@ test_teardown()
say "Running test teardown." say "Running test teardown."
texec rm -f "$FINIT_CONF" texec rm -f "$FINIT_CONF"
texec rm -f /test_assets/service.sh
} }
say "Test start $(date)" say "Test start $(date)"
cp "$TEST_DIR"/common/service.sh "$TENV_ROOT"/test_assets/
say 'Ensure file system is cleared' say 'Ensure file system is cleared'
texec rm -f /tmp/usr1.log texec rm -f /tmp/usr1.log
say "Add service stanza in $FINIT_CONF" say "Add service stanza in $FINIT_CONF"
texec sh -c "echo 'service [2345] kill:20 log service.sh -- Test service' > $FINIT_CONF" texec sh -c "echo 'service [2345] kill:20 log /test_assets/service.sh -- Test service' > $FINIT_CONF"
say 'Reload Finit' say 'Reload Finit'
texec sh -c "initctl reload" texec sh -c "initctl reload"
View File
View File
View File
View File
-1
View File
@@ -1 +0,0 @@
test
-4
View File
@@ -1,4 +0,0 @@
#!/bin/sh
echo "Shutting down ..."
exit 0
-5
View File
@@ -1,5 +0,0 @@
#!/bin/sh
echo "Starting up ..."
poweroff -d 2
-40
View File
@@ -1,40 +0,0 @@
# /etc/inittab
#
# Copyright (C) 2001 Erik Andersen <andersen@codepoet.org>
#
# Note: BusyBox init doesn't support runlevels. The runlevels field is
# completely ignored by BusyBox init. If you want runlevels, use
# sysvinit.
#
# Format for each entry: <id>:<runlevels>:<action>:<process>
#
# id == tty to run on, or empty for /dev/console
# runlevels == ignored
# action == one of sysinit, respawn, askfirst, wait, and once
# process == program to run
# Startup the system
#::sysinit:/bin/mount -t proc proc /proc
#::sysinit:/bin/mount -o remount,rw /
#::sysinit:/bin/mkdir -p /dev/pts /dev/shm
#::sysinit:/bin/mount -a
#::sysinit:/bin/mkdir -p /run/lock/subsys
#::sysinit:/sbin/swapon -a
null::sysinit:/bin/ln -sf /proc/self/fd /dev/fd
null::sysinit:/bin/ln -sf /proc/self/fd/0 /dev/stdin
null::sysinit:/bin/ln -sf /proc/self/fd/1 /dev/stdout
null::sysinit:/bin/ln -sf /proc/self/fd/2 /dev/stderr
::sysinit:/bin/hostname -F /etc/hostname
# now run any rc scripts
::sysinit:/etc/init.d/rcS
# Put a getty on the serial port
#ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100 # GENERIC_SERIAL
# Stuff to do for the 3-finger salute
#::ctrlaltdel:/sbin/reboot
# Stuff to do before rebooting
::shutdown:/etc/init.d/rcK
#::shutdown:/sbin/swapoff -a
#::shutdown:/bin/umount -a -r
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
+6 -2
View File
@@ -15,13 +15,17 @@ test_teardown()
say "Running test teardown." say "Running test teardown."
texec rm -f "$FINIT_CONF" texec rm -f "$FINIT_CONF"
texec rm -f /test_assets/service.sh
} }
say "Test start $(date)" say "Test start $(date)"
cp "$TEST_DIR"/common/slay.sh "$TENV_ROOT"/test_assets/
cp "$TEST_DIR"/common/service.sh "$TENV_ROOT"/test_assets/
rm -f "$TENV_ROOT"/oldpid rm -f "$TENV_ROOT"/oldpid
say "Add service stanza in $FINIT_CONF" say "Add service stanza in $FINIT_CONF"
texec sh -c "echo 'service [2345] respawn log service.sh -- Test service' > $FINIT_CONF" texec sh -c "echo 'service [2345] respawn log /test_assets/service.sh -- Test service' > $FINIT_CONF"
say 'Reload Finit' say 'Reload Finit'
texec sh -c "initctl reload" texec sh -c "initctl reload"
@@ -36,7 +40,7 @@ laps=1000
while [ $i -lt $laps ]; do while [ $i -lt $laps ]; do
i=$((i + 1)) i=$((i + 1))
say "Lap $i/$laps, killing service ..." # we have this, no sleep needed say "Lap $i/$laps, killing service ..." # we have this, no sleep needed
texec sh -c "slay service.sh" texec sh -c "/test_assets/slay.sh service.sh"
done done
retry 'assert_new_pid service.sh /run/service.pid' retry 'assert_new_pid service.sh /run/service.pid'
+7 -6
View File
@@ -6,6 +6,7 @@ TEST_DIR=$(dirname "$0")
test_setup() test_setup()
{ {
say "Test start $(date)" say "Test start $(date)"
cp "$TENV_ROOT"/../common/serv "$TENV_ROOT"/test_assets/
} }
test_teardown() test_teardown()
@@ -14,6 +15,7 @@ test_teardown()
say "Running test teardown." say "Running test teardown."
texec rm -f "$FINIT_CONF" texec rm -f "$FINIT_CONF"
texec rm -f /test_assets/serv
} }
test_one() test_one()
@@ -55,12 +57,11 @@ test_one()
# shellcheck source=/dev/null # shellcheck source=/dev/null
. "$TEST_DIR/tenv/lib.sh" . "$TEST_DIR/tenv/lib.sh"
test_one "/run/serv.pid" "service pid:!/run/serv.pid serv -- Forking service, type 1" test_one "/run/serv.pid" "service pid:!/run/serv.pid /test_assets/serv -- Forking service"
test_one "/run/serv.pid" "service type:forking serv -- Forking service, type 2"
# This one could never be started by and monitored by Finit: it forks to # This one could never be started by and monitored by Finit: it forks to
# background and does not create a PID file. Essentially it's lost to # background and does not create a PID file. Essentially it's lost to
# Finit, and any other sane process monitor. # Finit, and any other sane process monitor.
#test_one "/run/serv.pid" "service pid:/run/serv.pid serv -p -- Forking service w/o PID file" #test_one "/run/serv.pid" "service pid:/run/serv.pid /test_assets/serv -p -- Forking service w/o PID file"
test_one "/run/serv.pid" "service pid:/run/serv.pid serv -n -- Foreground service w/o PID file" test_one "/run/serv.pid" "service pid:/run/serv.pid /test_assets/serv -n -- Foreground service w/o PID file"
test_one "/run/serv.pid" "service serv -n -p -- Foreground service w/ PID file" test_one "/run/serv.pid" "service /test_assets/serv -n -p -- Foreground service w/ PID file"
test_one "/run/servy.pid" "service pid:/run/servy.pid serv -n -p -P /run/servy.pid -- Foreground service w/ custom PID file" test_one "/run/servy.pid" "service pid:/run/servy.pid /test_assets/serv -n -p -P /run/servy.pid -- Foreground service w/ custom PID file"
+4 -4
View File
@@ -13,19 +13,19 @@ test_teardown()
say "Running test teardown." say "Running test teardown."
texec rm -f "$FINIT_RCSD/service.conf" texec rm -f "$FINIT_RCSD/service.conf"
texec rm -f /test_assets/service.sh
} }
say "Test start $(date)" say "Test start $(date)"
cp "$TEST_DIR"/common/service.sh "$TENV_ROOT"/test_assets/
say "Add service stanza in $FINIT_RCSD/service.conf" say "Add service stanza in $FINIT_RCSD/service.conf"
texec sh -c "echo 'service [2345] kill:20 log service.sh -- Subserv' > $FINIT_RCSD/service.conf" texec sh -c "echo 'service [2345] kill:20 log /test_assets/service.sh -- Subserv' > $FINIT_RCSD/service.conf"
say 'Reload Finit' say 'Reload Finit'
texec sh -c "initctl reload" texec sh -c "initctl reload"
sleep 2
texec sh -c "ps"
retry 'assert_num_children 1 service.sh' retry 'assert_num_children 1 service.sh'
say 'Stop the service' say 'Stop the service'
+4 -1
View File
@@ -13,12 +13,15 @@ test_teardown()
say "Running test teardown." say "Running test teardown."
texec rm -f "$FINIT_CONF" texec rm -f "$FINIT_CONF"
texec rm -f /test_assets/service.sh
} }
say "Test start $(date)" say "Test start $(date)"
cp "$TEST_DIR"/common/service.sh "$TENV_ROOT"/test_assets/
say "Add service stanza in $FINIT_CONF" say "Add service stanza in $FINIT_CONF"
texec sh -c "echo 'service [2345] kill:20 log service.sh -- Test service' > $FINIT_CONF" texec sh -c "echo 'service [2345] kill:20 log /test_assets/service.sh -- Test service' > $FINIT_CONF"
say 'Reload Finit' say 'Reload Finit'
texec sh -c "initctl reload" texec sh -c "initctl reload"
+6 -1
View File
@@ -12,12 +12,17 @@ test_teardown() {
say "Running test teardown." say "Running test teardown."
texec rm -f "$FINIT_CONF" texec rm -f "$FINIT_CONF"
texec rm -f /test_assets/service.sh
} }
say "Test start $(date)" say "Test start $(date)"
cp "$TEST_DIR"/common/service.sh "$TENV_ROOT"/test_assets/
cp "$TEST_DIR"/common/S01-service.sh "$TENV_ROOT"/test_assets/
chmod +x "$TENV_ROOT"/test_assets/*.sh
say "Add sysv stanza in $FINIT_CONF" say "Add sysv stanza in $FINIT_CONF"
texec sh -c "echo 'sysv [2345] pid:!/run/service.pid name:service.sh /etc/init.d/S01-service.sh -- SysV test service' > $FINIT_CONF" texec sh -c "echo 'sysv [2345] pid:!/run/service.pid name:service.sh /test_assets/S01-service.sh -- SysV test service' > $FINIT_CONF"
say 'Reload Finit' say 'Reload Finit'
texec sh -c "initctl reload" texec sh -c "initctl reload"
+2 -1
View File
@@ -1 +1,2 @@
EXTRA_DIST = lib.sh exec.sh start.sh root.mk EXTRA_DIST = lib.sh exec.sh start.sh root.mk busybox-x86_64.md5
EXTRA_DIST += chrootsetup.sh
@@ -12,7 +12,7 @@
# furnished to do so, subject to the following conditions: # furnished to do so, subject to the following conditions:
# #
# The above copyright notice and this permission notice shall be included in # The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software. # all copies or substantial portions of the Software.
# #
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
@@ -23,14 +23,11 @@
# THE SOFTWARE. # THE SOFTWARE.
set -eu set -eu
export PATH=$PATH:/usr/bin:/usr/sbin
# It would have been nice to mount /dev as devtmpfs, but unfortunately # It would have been nice to mount /dev as devtmpfs, but unfortunately
# that's not possible if you're not privileged. For now tmpfs will # that's not possible if you're not privileged. For now tmpfs will
# have to do. # have to do.
mount -n -t tmpfs none /dev mount -n -t tmpfs none /dev
# Silence BusyBox init
touch /dev/null
mount -t proc none /proc mount -t proc none /proc
mount -t sysfs none /sys mount -t sysfs none /sys
+5 -3
View File
@@ -154,12 +154,13 @@ if [ -n "${DEBUG:-}" ]; then
FINIT_ARGS="${FINIT_ARGS:-} finit.debug=on" FINIT_ARGS="${FINIT_ARGS:-} finit.debug=on"
fi fi
# shellcheck disable=2086 # shellcheck disable=2086
"$TEST_DIR/tenv/start.sh" finit ${FINIT_ARGS:-} & "$TEST_DIR/tenv/start.sh" finit ${FINIT_ARGS:-} finit.debug=on &
finit_ppid=$! finit_ppid=$!
echo "$finit_ppid" > "$TENV_ROOT"/running_test.pid echo "$finit_ppid" > "$TENV_ROOT"/running_test.pid
>&2 echo "Finit runs as PID $finit_ppid outside of container."
>&2 echo "Hint: Execute 'TENV_ROOT=$TENV_ROOT $TEST_DIR/tenv/enter.sh' to enter the test namespace" >&2 echo "Hint: Execute 'TENV_ROOT=$TENV_ROOT $TEST_DIR/tenv/enter.sh' to enter the test namespace"
log "$color_reset" 'Setup of test environment done, waiting for Finit to start up ...' '' log "$color_reset" 'Setup of test environment done' ''
finit_pid=$(retry "pgrep -P $finit_ppid") finit_pid=$(retry "pgrep -P $finit_ppid")
@@ -169,4 +170,5 @@ fi
#tty=/dev/$(texec cat /sys/class/tty/console/active) #tty=/dev/$(texec cat /sys/class/tty/console/active)
#texec cat "$tty" & #texec cat "$tty" &
#sleep 1 sleep 5
+57 -17
View File
@@ -20,9 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE. # THE SOFTWARE.
srcdir ?= ../
SKEL ?= $(srcdir)/skel
DEST ?= ../tenv-root DEST ?= ../tenv-root
srcdir ?= ../
CACHE ?= ~/.cache CACHE ?= ~/.cache
ARCH ?= x86_64 ARCH ?= x86_64
@@ -31,27 +30,60 @@ FINITBIN ?= ./sbin/finit
BBVER ?= 1.31.0 BBVER ?= 1.31.0
BBBIN = busybox-$(ARCH) BBBIN = busybox-$(ARCH)
BBHOME ?= https://www.busybox.net/downloads/binaries BBURL ?= https://www.busybox.net/downloads/binaries/$(BBVER)-defconfig-multiarch-musl/$(BBBIN)
BBURL ?= $(BBHOME)/$(BBVER)-defconfig-multiarch-musl/$(BBBIN)
binaries = $(DEST)/bin/awk \
$(DEST)/bin/cat \
$(DEST)/bin/cp \
$(DEST)/bin/date \
$(DEST)/bin/echo \
$(DEST)/bin/env \
$(DEST)/bin/find \
$(DEST)/bin/grep \
$(DEST)/bin/kill \
$(DEST)/bin/ls \
$(DEST)/bin/mkdir \
$(DEST)/bin/mkfifo \
$(DEST)/bin/mknod \
$(DEST)/bin/mount \
$(DEST)/bin/printf \
$(DEST)/bin/pgrep \
$(DEST)/bin/ps \
$(DEST)/bin/rm \
$(DEST)/bin/sh \
$(DEST)/bin/sleep \
$(DEST)/bin/tail \
$(DEST)/bin/top \
$(DEST)/bin/touch \
$(DEST)/bin/start-stop-daemon
dirs = $(DEST)/bin \
$(DEST)/dev \
$(DEST)/etc \
$(DEST)/proc \
$(DEST)/sbin \
$(DEST)/var \
$(DEST)/run \
$(DEST)/sys \
$(DEST)/test_assets \
$(DEST)/tmp
_libs_src = $(shell ldd $(FINITBIN) | grep -Eo '/[^ ]+') _libs_src = $(shell ldd $(FINITBIN) | grep -Eo '/[^ ]+')
libs = $(foreach path,$(_libs_src),$(abspath $(DEST))$(path)) libs = $(foreach path,$(_libs_src),$(abspath $(DEST))$(path))
all: $(libs) $(DEST)/bin/$(BBBIN) all: $(dirs) $(binaries) $(libs) $(DEST)/bin/chrootsetup.sh
@(cd $(DEST); \ touch $(DEST)/etc/fstab
for prg in `./bin/$(BBBIN) --list-full`; do \
ln -sf /bin/$(BBBIN) $$prg; \ $(dirs):
done) mkdir -p $@
$(DEST)/bin/$(BBBIN).md5: $(DEST)/bin/$(BBBIN).md5:
@mkdir -p $(DEST) cp $(srcdir)/tenv/$(notdir $@) $@
@cp -a $(SKEL)/* $(DEST)/
@chmod -R u+w $(DEST)/
@find $(DEST) -name .empty -delete
.PHONY: $(DEST)/bin/$(BBBIN)
$(DEST)/bin/$(BBBIN): $(DEST)/bin/$(BBBIN).md5 $(DEST)/bin/$(BBBIN): $(DEST)/bin/$(BBBIN).md5
@(cd $(dir $@); \ @cd $(dir $@)
if ! md5sum --status -c $(BBBIN).md5 2>/dev/null; then \ @if ! md5sum --status -c $(BBBIN).md5 2>/dev/null; then \
if [ -d $(CACHE) ]; then \ if [ -d $(CACHE) ]; then \
echo "Cannot find $(BBBIN), checking $(CACHE) ..."; \ echo "Cannot find $(BBBIN), checking $(CACHE) ..."; \
cd $(CACHE); \ cd $(CACHE); \
@@ -69,9 +101,17 @@ $(DEST)/bin/$(BBBIN): $(DEST)/bin/$(BBBIN).md5
fi; \ fi; \
cd $(dir $@); \ cd $(dir $@); \
md5sum -c $(BBBIN).md5; \ md5sum -c $(BBBIN).md5; \
fi) fi
@chmod +x $@ @chmod +x $@
$(libs): $(DEST)/bin/$(BBBIN).md5 $(DEST)/bin/chrootsetup.sh:
cp $(srcdir)/tenv/$(notdir $@) $@
$(binaries): $(DEST)/bin/$(BBBIN)
cd $(DEST)/bin; \
rm -f $(notdir $@); \
ln -s $(BBBIN) $(notdir $@)
$(libs):
mkdir -p $(dir $@) mkdir -p $(dir $@)
cp $(patsubst $(abspath $(DEST))%,%,$@) $@ cp $(patsubst $(abspath $(DEST))%,%,$@) $@
+1 -1
View File
@@ -46,4 +46,4 @@ exec "$unshare" \
--mount \ --mount \
--mount-proc \ --mount-proc \
--uts --ipc --net \ --uts --ipc --net \
"$chroot" "$TENV_ROOT" /sbin/chrootsetup.sh "$@" "$chroot" "$TENV_ROOT" /bin/chrootsetup.sh "$@"
+1 -1
View File
@@ -1,6 +1,6 @@
prefix=@prefix@ prefix=@prefix@
exec_prefix=@exec_prefix@ exec_prefix=@exec_prefix@
export TESTENV_PATH=/bin:/sbin:/usr/bin:/usr/sbin:"@bindir@":"@sbindir@" export TESTENV_PATH=/bin:/sbin:"@bindir@":"@sbindir@"
export FINIT_CONF="@FINIT_CONF@" export FINIT_CONF="@FINIT_CONF@"
export FINIT_RCSD="@FINIT_RCSD@" export FINIT_RCSD="@FINIT_RCSD@"