Compare commits

..
53 Commits
Author SHA1 Message Date
Joachim Wiberg 5d8fcfdf13 .github: allow release builds for -rcN
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 12:06:10 +02:00
Joachim Wiberg e4830c5614 Don't try to restart forking daemons
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 11:43:33 +02:00
Joachim Wiberg f33261af6b Fix fnread() string fmt, no format args.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 11:30:43 +02:00
Joachim Wiberg e7516f2b63 Bump version for v4.3-rc1
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 11:08:15 +02:00
Joachim Wiberg d18167fe1d Update ChangeLog, ref cmdline.doc and fix libuEv linking
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 11:07:13 +02:00
Joachim Wiberg 7d3f95c0a9 doc: minor, emphasize 'debug' like all other kernel cmdline keywords
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 11:06:31 +02:00
Joachim Wiberg 86c5bbb03d doc: fix markdown syntax
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 11:06:07 +02:00
Joachim Wiberg 7530bb74f6 Update ChangeLog for upcoming v4.3 release
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 00:56:54 +02:00
Joachim Wiberg 54dd726d16 Follow-up to bd9bb92, missing API change
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-17 00:01:10 +02:00
Joachim Wiberg bd9bb92ca0 Replace reboot(RB_SW_SUSPEND) w/ internal /sys/power/state API
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-16 23:59:32 +02:00
Joachim Wiberg 01cb088e51 Fix initctl debug toggle regression introduced in ae09272b
Calling `initctl debug` is supposed to toggle Finit debug messages on
the boot console.  This broke in ae09272b when improving support for
running Finit in containers.

Part of this change is a slight refactor of who calles log_init() when
starting up, and when to call ttinit().  We now call ttinit() every time
we toggle debug.

Also, toggling back to normal logging had a bug.  The new default log
level for Finit is LOG_INFO, but toggling back set it to LOG_NOTICE.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 11:55:17 +02:00
Joachim Wiberg 3d91112e0d Rename finit command line option finit.show_status -> finit.status
Usability.

Remains backwards compatible for now, but finit.show_status is as of 4.3
deprecated.  Likely to be removed int 5.0

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 10:55:48 +02:00
Joachim Wiberg 16aef80682 Silence Coverity Scan NULL ptr deref warning
Explicitly set arg to non-NULL value.  The call to conf() later will
steer up the value to point to the full path of the user's finit.conf

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 10:02:11 +02:00
Joachim Wiberg fd34914936 Fix unchecked return value, found by Coverity Scan
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 09:57:04 +02:00
Joachim Wiberg 21a890a04e Fix NULL ptr deref, introduced in 8e2d0060 for issue #189
Found by Coverity Scan.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 09:53:58 +02:00
Joachim Wiberg 7f5f7e8ef6 Fix resource leak in shutdown, found by Coverity Scan
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 09:48:42 +02:00
Joachim Wiberg ff937576ea Fix possible NULL deref in run() error handling
When we added support for using popen() to run(), to log the output, we
forgot to update the error handling path.  Found by Coverity Scan.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 09:45:41 +02:00
Joachim Wiberg 7d831170ae plugins: close/exit iwatch *after* event loop has been detached
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 08:33:24 +02:00
Joachim Wiberg 6a21ac55ad Enable more printf format attributes
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 08:32:18 +02:00
Joachim Wiberg a0820c7f20 Fix printf format specifier and formatting issues in use of log fns
Almost all related to and (less likely) possible causes of issue #236.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 00:26:14 +02:00
Joachim Wiberg 6d58c9ed0b Enable printf format attributes to logit() and flog()
We don't want repeats of issue #236, so let's start by tracking down any
bugs hidden in logging functions.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 00:17:15 +02:00
Joachim Wiberg bc2ffbc767 Fix printf style function missing argument to %s
This is very likely the root cause of issue #236, let's see.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-14 00:10:30 +02:00
Joachim Wiberg 4c1fc2410e Show progress output also for unmount
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 22:41:12 +02:00
Joachim Wiberg 70e1aa889a Ignore errors from the first two remount,ro they are just decoys
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 22:28:10 +02:00
Joachim Wiberg c8c5e4e88a Revert "Simplify shutdown, no need for workarounds to remount / read-only"
This reverts commit 7c42986800 since we
seem to still need this werid thing on some systems.  The key seems
to use 'any' device at remount[1].  Anyway, the key issue before was
the noisy output, but like Debian we'll just redirect to /dev/null.

[1]: https://bugs.launchpad.net/ubuntu/+source/util-linux/+bug/29187

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 22:22:18 +02:00
Joachim Wiberg 86c1398778 Run swapoff interactively, let user know what's happening.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 22:21:52 +02:00
Joachim Wiberg b37fa2b417 Silence process killer at shutdown, too noisy on regular systems
On regular desktop systems, like Debian, the dbus-daemon forks off a
dbus-launch process to start up things like your desktop for you.  This
process is not known to Finit and lingers in the background since it's
been reparented to init, and to top things off it seems to ignore any
SIGTERMs send to it.

Obviously this makes a shutdown on such systems very noisy, so this
patch changes the print() to a _d() so anyone debugging a system can see
it with `-- finit.debug` on the kernel command line, or `initctl debug`.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 22:16:57 +02:00
Joachim Wiberg a91e197553 Avoid looping forever trying to unmount busy tmpfs
This split unmount is a bit crude, unfortunately.  A user may have set
up a bind or overlayfs mount on top of a tmpfs -- so unmounting tmpfs
first will then always result in EBUSY.

Avoid logging busy errors and fake OK.  We'll catch it later in the
second stage unmount.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 21:57:14 +02:00
Joachim Wiberg 5adb92ca1b Catch and print any errors when unmounting filesystems at reboot
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 21:45:37 +02:00
Joachim Wiberg cfc99c4e8b Follow-up to ef9e9ec, run ifdown also in background, with --force
Turns out that on Debian `ifdown -a` can block for quite a while at
shutdown/reboot.  So we'd like to use the --force option.  However,
the BusyBox ifdown tool doesn't support --force, only -f, which in
turn the regular ifdown tool doesn't support.

Regardless, we can allow network shutdown to run in the background
like bring-up, at reboot we want to reboot quickly and don't care
so much, and on runlevel change to single-user mode we can allow
for some lagging behind in the background.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 21:45:37 +02:00
Joachim Wiberg 3e51ed1c55 Run swapon interactively, let user know what's happening.
Let's try this, should be OK for all types of systems.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 21:45:37 +02:00
Joachim Wiberg b5df0a6274 Fix swapoff at shutdown, does not support -e flag
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 21:33:54 +02:00
Joachim Wiberg cbe8d56042 Mention lack of mainline distro testing on non-x86 archs
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 08:35:13 +02:00
Joachim Wiberg a3ec792b44 doc: minor updates to build script, again
- Mention why configure script is missing from GIT
  - Adjust command line for enabling Finit debug
  - Plus some minor formatting issues

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-12 08:33:50 +02:00
Joachim Wiberg c24855d4d5 keventd: add support for toggling debug messages w/ SIGUSR1
Useful to debug system events after the system has started up and you
don't want to rebuild Finit to add the `-d` command line flag.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-11 22:38:35 +02:00
Joachim Wiberg 014e457fda doc: note which plugins are enabled by default
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-11 21:35:16 +02:00
Joachim Wiberg 21d89c7e24 doc: mention kernel command line option loglevel=7
This is needed since 5ff27c4f when support for debugging Finit and the
kernel independently was added.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-11 21:32:28 +02:00
Joachim Wiberg 639fb76f5a doc: update build ref, add "or later" to required libraries
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-11 21:14:35 +02:00
Joachim Wiberg 30c189b116 initctl: add helpful hint when showing/editing built-in services
Built-in services, like keventd, do not have a .conf file to edit.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-11 20:51:46 +02:00
Joachim Wiberg e2a8803f7a test: minor, extend log message a bit
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-10 22:46:45 +02:00
Joachim Wiberg 209e140ddd test: let Finit's bootmisc plugin create the /var/run symlink
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-10 22:46:15 +02:00
Joachim Wiberg 2e3fa72924 Revert "plugins: bootmisc: use relative symlink for /var/run"
This reverts commit f0e328edc9.
2022-04-10 22:38:27 +02:00
Joachim Wiberg 1502838a0d Fix regression in _pe() log macro, introduced in 685f332
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-10 12:39:20 +02:00
Joachim Wiberg 377c8bce8c test: fix dist and tenv-root/ regression from refactor
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-09 17:52:48 +02:00
Joachim Wiberg a39d958d25 Follow-up to 7dc7f9a, protect against stalling on non-existing pids
A forking service, e.g. a SysV init script, that returns is no longer
running, even though the monitored service may still be starting.  We
must mark the svc->pid as terminated until we know more -- otherwise
we may stall on a shutdown at that exact point.

Also, when shutting down, and stopping all services, ensure we do not
start the carousel for non-existing PIDs.  This might also cause our
stalling at shutdown.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-08 07:27:42 +02:00
Joachim Wiberg 7f8a96a73e test: refactor test framework to use a rootfs skeleton
Instead of having to create files, and copying them in place for each
test, we move all static test files to a skeleton rootfs.  This makes
it a lot easier to get an overview of how things and how they work.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-08 07:22:33 +02:00
Joachim Wiberg 5c2577214d test: ask BusyBox its tools and recommended paths
Note: we need to add /usr/bin and /usr/sbin to the standard PATH
      for tests and the test environment itself.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-06 22:42:49 +02:00
Joachim Wiberg f03206a694 .github: due to regression in ubuntu-latest, use older ubuntu runner
In https://github.com/actions/virtual-environments/commit/12fa229 the
ubuntu-latest runner was updated to Ubuntu 20.04.4, with Linux kernel
version: 5.13.0-1014-azure.  This broke the Finit tests completely
and the only possible solution, for now, seems to be reverting back
to the ubuntu-18.04 runner instead.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-06 21:16:46 +02:00
Joachim Wiberg f0e328edc9 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-06 21:13:43 +02:00
Joachim Wiberg 13342f2bd9 .github: debug failing tests again, see what setup-root does
All tests except the first two now suddenly started failing.  Might be
the new caching support for the busybox binary, but that works on other
clean clones -- working theory now is that there's something subtle
with the setup-root.sh test -- which PASSes ...

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-04 19:43:43 +02:00
Joachim Wiberg c926160853 Issue #223: add type:forking service option, with updated docs
- Add `type:forking` service option to trigger guessing pidfile to
   watch for, instead of `pid:!foo` option, which is not intuitive.
   This option may likely also survive into the new file format :)
 - Update docs and add examples
 - Update start-stop-serv.sh test case with this new variant

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-04 19:13:28 +02:00
Joachim Wiberg 462d5b22b4 Fix parse bug, always set service's respawn flag
Before this fix, a service declared with respawn could not be changed at
runtime to remove the respawn flag.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-04 18:06:35 +02:00
Joachim Wiberg b1bfab08f3 Coding style, reverse Christmas tree ordering
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2022-04-04 08:26:13 +02:00
90 changed files with 504 additions and 245 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:
+39 -3
View File
@@ -10,14 +10,40 @@ 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,
@@ -27,6 +53,16 @@ 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
@@ -781,7 +817,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
@@ -812,7 +848,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,6 +54,11 @@ 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
------- -------
@@ -598,6 +603,7 @@ 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-dev, https://github.com/troglobit/finit/issues, finit, https://troglobit.com/finit.html) AC_INIT(Finit, 4.3-rc1, 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])
+19 -10
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 - libite v2.2.0, or later
- libuEv v2.2.0 - libuEv v2.2.0, or later
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,6 +67,13 @@ 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
------- -------
@@ -74,8 +81,8 @@ Example
First, unpack the archive: First, unpack the archive:
```shell ```shell
$ tar xf finit-4.1.tar.gz $ tar xf finit-4.3.tar.gz
$ cd finit-4.1/ $ cd finit-4.3/
``` ```
Then configure, build and install: Then configure, build and install:
@@ -83,7 +90,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
. .
. .
@@ -91,7 +98,7 @@ $ make
$ DESTDIR=/tmp/finit make install $ DESTDIR=/tmp/finit make install
``` ```
In this example the [finit-4.1.tar.gz][1] archive is unpacked to the In this example the [finit-4.3.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
@@ -151,12 +158,14 @@ 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 `debug` to enable Finit debug messages. kernel messages and add `finit.debug` to enable Finit debug messages.
```shell ```shell
append="init=/sbin/finit debug" append="init=/sbin/finit -- 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:
@@ -175,6 +184,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.1.tar.gz [1]: ftp://troglobit.com/finit/finit-4.3.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
+13 -6
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. console until Finit starts up, unless `loglevel=7` (below) is used.
* `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.show_status[=bool]`: Control finit boot progress, including * `finit.status[=bool]`: Control finit boot progress, including banner.
banner. (Used to be `finit.show_status`, which works but is deprecated.)
* `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,11 +26,18 @@ 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. errors. Also, see `loglevel` and `quiet` above.
* `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),
@@ -46,5 +53,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
+17 -3
View File
@@ -323,6 +323,10 @@ 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.
@@ -344,9 +348,19 @@ 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 called forking start logging to the foreground as well, these are forking daemons and
services and are supported using the same syntax as forking `sysv` are supported using the same syntax as forking `sysv` services, using
services, using the `pid:!/path/to/pidfile.pid` syntax. the `pid:!/path/to/pidfile.pid` syntax. There is an alternative 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:**
+6 -4
View File
@@ -35,25 +35,27 @@ 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. available. Enabled by default.
* *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. interfaces going up/down. Enabled by default.
* *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. in a usb2serial converter to login to your embedded device. Enabled
by default.
* *urandom.so*: Setup random seed at startup. * *urandom.so*: Setup random seed at startup. Enabled by default.
* *x11-common.so*: Setup necessary files for X-Window. _Optional plugin._ * *x11-common.so*: Setup necessary files for X-Window. _Optional plugin._
+11 -1
View File
@@ -27,7 +27,17 @@ Finit can *not* start and monitor a daemon that:
### Forks to Background w/ PID File ### Forks to Background w/ PID File
service pid:!/run/serv.pid serv -- Forking service There are two syntax variants, type 1 and type 2. The former is the
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
+3 -2
View File
@@ -11,8 +11,9 @@
.Nd Fast init for Linux systems .Nd Fast init for Linux systems
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm /sbin/finit .Nm /sbin/finit
.Op finit.status_style=classic .Op --
.Op finit.show_status=[on,off] .Op finit.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
+15 -1
View File
@@ -194,7 +194,21 @@ 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. command modifier syntax. There is an alternative syntax that may be
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);
+3 -1
View File
@@ -1,3 +1,4 @@
/* 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>
@@ -252,7 +253,7 @@ static int nl_parse(int sd)
return -1; return -1;
} }
_d("recv %lld bytes", len); _d("recv %zd 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;
@@ -449,6 +450,7 @@ 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)
{ {
iwatch_exit(&iw_pidfile);
plugin_unregister(&plugin); plugin_unregister(&plugin);
iwatch_exit(&iw_pidfile);
} }
/** /**
+1 -5
View File
@@ -160,23 +160,19 @@ 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 = {
@@ -201,8 +197,8 @@ PLUGIN_INIT(plugin_init)
PLUGIN_EXIT(plugin_exit) PLUGIN_EXIT(plugin_exit)
{ {
iwatch_exit(&iw_sys);
plugin_unregister(&plugin); plugin_unregister(&plugin);
iwatch_exit(&iw_sys);
} }
/** /**
+1 -2
View File
@@ -116,10 +116,9 @@ 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)
{ {
iwatch_exit(&iw_usr);
plugin_unregister(&plugin); plugin_unregister(&plugin);
iwatch_exit(&iw_usr);
} }
/** /**
+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 = reboot(RB_SW_SUSPEND); rc = suspend();
if (rc) { if (rc) {
if (errno == EINVAL) if (errno == EINVAL)
snprintf(buf, len, "Kernel does not support suspend."); snprintf(buf, len, "Kernel does not support suspend to RAM.");
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 ", FINIT_CGPATH "/init"); _pe("Failed moving PID 1 to cgroup %s", FINIT_CGPATH "/init");
uev_io_stop(&cgw); uev_io_stop(&cgw);
iwatch_exit(&iw_cgroup); iwatch_exit(&iw_cgroup);
close(fd); close(fd);
+3 -5
View File
@@ -86,8 +86,8 @@ fallback:
} }
/* /*
* finit.debug = [on,off] * finit.debug = [on,off]
* finit.show_status = [on,off] * finit.status = [on,off] (compat finit.show_status)
* 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, "show_status")) { if (string_compare(opt, "status") || 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,8 +205,6 @@ 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)
+4 -2
View File
@@ -97,12 +97,14 @@ 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)
@@ -164,7 +166,7 @@ int run(char *cmd, char *log)
_exit(rc); _exit(rc);
} else if (-1 == pid) { } else if (-1 == pid) {
_pe("%s", args[0]); _pe("%s", !log ? args[0] : cmd);
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("swapon -ea", "swapon"); run_interactive("swapon -ea", "Enabling system swap");
_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;
/* telinit or stand-alone process monitor */ /* user calling telinit or init */
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) * Figure out system console(s) and call log_init() to set
* correct log level, possibly finit.debug enabled.
*/ */
console_init(); console_init();
+14 -8
View File
@@ -81,7 +81,7 @@ char *console(void)
void console_init(void) void console_init(void)
{ {
ttinit(); log_init();
} }
ssize_t cprintf(const char *fmt, ...) ssize_t cprintf(const char *fmt, ...)
@@ -500,20 +500,25 @@ 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();
pp = popen("ifup -a 2>&1", "r"); if (updown)
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];
@@ -526,7 +531,8 @@ void networking(int updown)
_exit(rc); _exit(rc);
} }
cgroup_service("network", pid, NULL); cgroup_service("network", pid, NULL);
print(pid > 0 ? 0 : 1, "Bringing up network interfaces ..."); print(pid > 0 ? 0 : 1, "%s 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, ...); ssize_t cprintf (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
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, ...); void print (int action, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
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, ...); int run_interactive (char *cmd, char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
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, ...); extern void print_header(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
#endif /* FINIT_INITCTL_H_ */ #endif /* FINIT_INITCTL_H_ */
+4 -2
View File
@@ -62,8 +62,10 @@ 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)) {
setsockopt(iw->fd, SOL_SOCKET, SO_RCVBUF, &sz, sizeof(sz)); if (setsockopt(iw->fd, SOL_SOCKET, SO_RCVBUF, &sz, sizeof(sz)))
_pe("Failed increasing size of inotify socket");
}
initialized = 1; initialized = 1;
+41 -5
View File
@@ -24,6 +24,7 @@
#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>
@@ -52,6 +53,10 @@
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, ...)
@@ -59,9 +64,9 @@ void logit(int prio, const char *fmt, ...)
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
if (!debug) if (logon)
vsyslog(prio, fmt, ap); vsyslog(prio, fmt, ap);
else { else if (prio <= level) {
vfprintf(stderr, fmt, ap); vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
@@ -179,6 +184,26 @@ 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
@@ -198,10 +223,13 @@ int main(int argc, char *argv[])
} }
if (!debug) { if (!debug) {
openlog("keventd", LOG_CONS | LOG_PID, LOG_DAEMON); openlog("keventd", LOG_PID, LOG_DAEMON);
setlogmask(LOG_UPTO(LOG_NOTICE)); set_logging(LOG_NOTICE);
logon = 1;
} }
signal(SIGUSR1, toggle_debug);
signal(SIGTERM, shut_down);
init(); init();
pfd.events = POLLIN; pfd.events = POLLIN;
@@ -216,11 +244,18 @@ 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 (-1 != poll(&pfd, 1, -1)) { while (running) {
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) {
@@ -235,6 +270,7 @@ 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))
+10 -7
View File
@@ -40,6 +40,8 @@ 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
@@ -72,24 +74,25 @@ 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;
if (debug) { log_close();
loglevel = LOG_DEBUG; log_init();
} 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 ": %n", __func__, ##args, strerror(errno)) #define _pe(fmt, args...) logit(LOG_ERR, "%s():" fmt ": %s", __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, ...); void logit (int prio, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
void flog (char *file, const char *fmt, ...); void flog (char *file, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
#endif /* FINIT_LOG_H_ */ #endif /* FINIT_LOG_H_ */
+19 -2
View File
@@ -21,10 +21,13 @@
* 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
* *
@@ -86,13 +89,27 @@ 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) && !umount(mnt->mnt_dir)) if (!strcmp("tmpfs", mnt->mnt_fsname) && !unmount(mnt->mnt_dir))
iterator_end(&fp); /* Restart iteration */ iterator_end(&fp); /* Restart iteration */
} }
} }
@@ -103,7 +120,7 @@ void unmount_regular(void)
FILE *fp = NULL; FILE *fp = NULL;
while ((mnt = iterator("/proc/mounts", &fp))) { while ((mnt = iterator("/proc/mounts", &fp))) {
if (!umount(mnt->mnt_dir)) if (!unmount(mnt->mnt_dir))
iterator_end(&fp); /* Restart iteration */ iterator_end(&fp); /* Restart iteration */
} }
} }
+10 -4
View File
@@ -69,10 +69,11 @@ 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");
@@ -113,8 +114,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;
FILE *fp;
char buf[42]; char buf[42];
FILE *fp;
fp = fopen(fn, "r"); fp = fopen(fn, "r");
if (!fp) if (!fp)
@@ -157,6 +158,11 @@ 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] = '!';
@@ -199,8 +205,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)) {
int len, not = 0;
char path[MAX_ARG_LEN]; char path[MAX_ARG_LEN];
int len, not = 0;
arg += 4; arg += 4;
if ((arg[0] == '!' && arg[1] == '/') || arg[0] == '/') if ((arg[0] == '!' && arg[1] == '/') || arg[0] == '/')
+4 -2
View File
@@ -160,6 +160,8 @@ 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);
@@ -174,9 +176,9 @@ int reboot_main(int argc, char *argv[])
break; break;
case CMD_SUSPEND: case CMD_SUSPEND:
c = reboot(RB_SW_SUSPEND); c = suspend();
if (c && errno == EINVAL) if (c && errno == EINVAL)
errx(1, "Kernel does not support suspend."); errx(1, "Kernel does not support suspend to RAM.");
break; break;
case CMD_UNKNOWN: case CMD_UNKNOWN:
+31 -1
View File
@@ -34,9 +34,24 @@
# 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;
@@ -292,6 +307,8 @@ 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;
@@ -311,6 +328,9 @@ 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;
} }
@@ -345,6 +365,9 @@ 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);
@@ -371,6 +394,7 @@ 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);
@@ -385,6 +409,9 @@ 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);
@@ -420,8 +447,11 @@ 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);
+41 -13
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", we.we_wordv[i]); logit(LOG_ERR, "%s: expanded arg. '%s' too long", svc->cmd, we.we_wordv[i]);
rc = WRDE_NOSPACE; rc = WRDE_NOSPACE;
goto nomem; goto nomem;
} }
@@ -747,6 +747,14 @@ 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;
@@ -923,7 +931,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 (>%d chars)", svc->cmd, sizeof(svc->env)); _e("%s: env file is too long (>%zu chars)", svc->cmd, sizeof(svc->env));
return; return;
} }
@@ -947,7 +955,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 (>%d chars)", svc->cmd, sizeof(svc->cgroup)); _e("%s: cgroup settings too long (>%zu chars)", svc->cmd, sizeof(svc->cgroup));
return; return;
} }
@@ -983,7 +991,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:%s is missing or not executable, skipping.", type, script); logit(LOG_WARNING, "%s:%s is missing or not executable, skipping.", type, script);
else else
strlcpy(buf, script, len); strlcpy(buf, script, len);
} }
@@ -1154,7 +1162,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 manual = 0; int forking = 0, 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;
@@ -1213,6 +1221,8 @@ 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))
@@ -1324,10 +1334,6 @@ 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, ':');
@@ -1405,8 +1411,26 @@ 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));
if (respawn) svc->respawn = respawn;
svc->respawn = 1; svc->forking = forking;
/* 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));
@@ -1485,8 +1509,10 @@ 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);
@@ -1573,7 +1599,6 @@ 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
@@ -1846,6 +1871,9 @@ 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);
+13 -4
View File
@@ -207,7 +207,8 @@ 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)) {
print(0, "PID %d is still alive (%s)", pid, file); _d("PID %d is still alive (%s)", pid, file);
fclose(fp);
break; break;
} }
} }
@@ -323,13 +324,21 @@ 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("swapoff -e -a", "swapoff"); run_interactive("swapoff -a", "Disabling system swap");
/* ... unmount remaining regular file systems. */ /* ... unmount remaining regular file systems. */
unmount_regular(); unmount_regular();
/* We sit on / so we must remount it read-only */ /*
run("mount -n -o remount,ro -t none rootfs /", "mount"); * We sit on / so we must remount it ro, try all the things!
* 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();
+2 -1
View File
@@ -127,6 +127,7 @@ 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];
@@ -228,7 +229,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_is_daemon(svc) || svc_is_sysv(svc)) && svc->pidfile[0] == '!'; } static inline int svc_is_forking (svc_t *svc) { return svc && svc->forking; }
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); }
+35 -1
View File
@@ -224,7 +224,7 @@ int fngetint(char *path, int *val)
{ {
char buf[64]; char buf[64];
if (fnread(buf, sizeof(buf), path) <= 0) if (fnread(buf, sizeof(buf), "%s", path) <= 0)
return -1; return -1;
errno = 0; errno = 0;
@@ -235,6 +235,40 @@ 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;
+6 -4
View File
@@ -54,11 +54,13 @@ extern char *prognm;
char *progname (char *arg0); char *progname (char *arg0);
char *str (char *fmt, ...); char *str (char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
int fnread (char *buf, size_t len, char *fmt, ...); int fnread (char *buf, size_t len, char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
int fnwrite (char *value, char *fmt, ...); int fnwrite (char *value, char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
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);
@@ -85,7 +87,7 @@ int ttcooked (void);
#define ttcooked() 0 #define ttcooked() 0
#endif #endif
static inline void dbg(char *fmt, ...) static __attribute__ ((format (printf, 1, 2))) inline void dbg(char *fmt, ...)
{ {
va_list ap; va_list ap;
+16 -1
View File
@@ -1,6 +1,21 @@
SUBDIRS = common tenv SUBDIRS = common tenv
EXTRA_DIST = setup-root.sh EXTRA_DIST = skel/bin/busybox-x86_64.md5 skel/sbin/service.sh skel/bin/slay \
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,15 +13,12 @@ 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 /test_assets/service.sh -- Dyn serv' > $FINIT_RCSD/service.conf" texec sh -c "echo 'service [2345] kill:20 log service.sh -- Dyn serv' > $FINIT_RCSD/service.conf"
say 'Reload Finit' say 'Reload Finit'
texec sh -c "initctl reload" texec sh -c "initctl reload"
+1 -10
View File
@@ -3,7 +3,6 @@
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"
@@ -14,20 +13,12 @@ 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 /test_assets/service.sh -- Dyn service' > $FINIT_CONF" texec sh -c "echo 'service [2345] kill:20 log 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,4 +1,2 @@
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
View File
@@ -1 +0,0 @@
service [2345] kill:20 log /test_assets/service.sh
+3 -10
View File
@@ -5,6 +5,9 @@ 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"
@@ -12,13 +15,3 @@ 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/
+1 -4
View File
@@ -14,18 +14,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 '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 /test_assets/service.sh -- Test service' > $FINIT_CONF" texec sh -c "echo 'service [2345] kill:20 log 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
@@ -0,0 +1 @@
test
@@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# SysV style start script for service.sh # SysV style start script for service.sh
DAEMON="/test_assets/service.sh" DAEMON="/sbin/service.sh"
PIDFILE="/var/run/service.pid" PIDFILE="/var/run/service.pid"
start() start()
+4
View File
@@ -0,0 +1,4 @@
#!/bin/sh
echo "Shutting down ..."
exit 0
+5
View File
@@ -0,0 +1,5 @@
#!/bin/sh
echo "Starting up ..."
poweroff -d 2
+40
View File
@@ -0,0 +1,40 @@
# /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
@@ -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,11 +23,14 @@
# 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
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
+2 -6
View File
@@ -15,17 +15,13 @@ 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 /test_assets/service.sh -- Test service' > $FINIT_CONF" texec sh -c "echo 'service [2345] respawn log service.sh -- Test service' > $FINIT_CONF"
say 'Reload Finit' say 'Reload Finit'
texec sh -c "initctl reload" texec sh -c "initctl reload"
@@ -40,7 +36,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 "/test_assets/slay.sh service.sh" texec sh -c "slay service.sh"
done done
retry 'assert_new_pid service.sh /run/service.pid' retry 'assert_new_pid service.sh /run/service.pid'
+6 -7
View File
@@ -6,7 +6,6 @@ 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()
@@ -15,7 +14,6 @@ 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()
@@ -57,11 +55,12 @@ 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 /test_assets/serv -- Forking service" test_one "/run/serv.pid" "service pid:!/run/serv.pid serv -- Forking service, type 1"
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 /test_assets/serv -p -- Forking service w/o PID file" #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 -n -- Foreground 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 /test_assets/serv -n -p -- Foreground service w/ PID file" test_one "/run/serv.pid" "service serv -n -p -- Foreground service w/ 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" test_one "/run/servy.pid" "service pid:/run/servy.pid 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 /test_assets/service.sh -- Subserv' > $FINIT_RCSD/service.conf" texec sh -c "echo 'service [2345] kill:20 log 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'
+1 -4
View File
@@ -13,15 +13,12 @@ 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 /test_assets/service.sh -- Test service' > $FINIT_CONF" texec sh -c "echo 'service [2345] kill:20 log service.sh -- Test service' > $FINIT_CONF"
say 'Reload Finit' say 'Reload Finit'
texec sh -c "initctl reload" texec sh -c "initctl reload"
+1 -6
View File
@@ -12,17 +12,12 @@ 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 /test_assets/S01-service.sh -- SysV test service' > $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"
say 'Reload Finit' say 'Reload Finit'
texec sh -c "initctl reload" texec sh -c "initctl reload"
+1 -2
View File
@@ -1,2 +1 @@
EXTRA_DIST = lib.sh exec.sh start.sh root.mk busybox-x86_64.md5 EXTRA_DIST = lib.sh exec.sh start.sh root.mk
EXTRA_DIST += chrootsetup.sh
+3 -5
View File
@@ -154,13 +154,12 @@ 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:-} finit.debug=on & "$TEST_DIR/tenv/start.sh" finit ${FINIT_ARGS:-} &
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' '' log "$color_reset" 'Setup of test environment done, waiting for Finit to start up ...' ''
finit_pid=$(retry "pgrep -P $finit_ppid") finit_pid=$(retry "pgrep -P $finit_ppid")
@@ -170,5 +169,4 @@ 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 5 #sleep 1
+17 -57
View File
@@ -20,8 +20,9 @@
# 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.
DEST ?= ../tenv-root
srcdir ?= ../ srcdir ?= ../
SKEL ?= $(srcdir)/skel
DEST ?= ../tenv-root
CACHE ?= ~/.cache CACHE ?= ~/.cache
ARCH ?= x86_64 ARCH ?= x86_64
@@ -30,60 +31,27 @@ FINITBIN ?= ./sbin/finit
BBVER ?= 1.31.0 BBVER ?= 1.31.0
BBBIN = busybox-$(ARCH) BBBIN = busybox-$(ARCH)
BBURL ?= https://www.busybox.net/downloads/binaries/$(BBVER)-defconfig-multiarch-musl/$(BBBIN) BBHOME ?= https://www.busybox.net/downloads/binaries
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: $(dirs) $(binaries) $(libs) $(DEST)/bin/chrootsetup.sh all: $(libs) $(DEST)/bin/$(BBBIN)
touch $(DEST)/etc/fstab @(cd $(DEST); \
for prg in `./bin/$(BBBIN) --list-full`; do \
$(dirs): ln -sf /bin/$(BBBIN) $$prg; \
mkdir -p $@ done)
$(DEST)/bin/$(BBBIN).md5: $(DEST)/bin/$(BBBIN).md5:
cp $(srcdir)/tenv/$(notdir $@) $@ @mkdir -p $(DEST)
@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); \
@@ -101,17 +69,9 @@ $(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 $@
$(DEST)/bin/chrootsetup.sh: $(libs): $(DEST)/bin/$(BBBIN).md5
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" /bin/chrootsetup.sh "$@" "$chroot" "$TENV_ROOT" /sbin/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:"@bindir@":"@sbindir@" export TESTENV_PATH=/bin:/sbin:/usr/bin:/usr/sbin:"@bindir@":"@sbindir@"
export FINIT_CONF="@FINIT_CONF@" export FINIT_CONF="@FINIT_CONF@"
export FINIT_RCSD="@FINIT_RCSD@" export FINIT_RCSD="@FINIT_RCSD@"