mirror of
https://github.com/troglobit/finit.git
synced 2026-10-12 10:12:32 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa8d6a7294 | ||
|
|
a94dde403f | ||
|
|
9bb7e7b014 | ||
|
|
02a97e8d7d | ||
|
|
def759fe41 | ||
|
|
939cfc2476 | ||
|
|
7f2c73468f | ||
|
|
81a368f710 | ||
|
|
4e975e4974 | ||
|
|
a296c2dd00 | ||
|
|
5ff7994852 | ||
|
|
1bdcef9a2c | ||
|
|
f621117eb9 | ||
|
|
83cec7129a | ||
|
|
06b33c58fd | ||
|
|
8ce39f592c | ||
|
|
d37c451e81 | ||
|
|
a7ff1a61d5 | ||
|
|
8349909f60 | ||
|
|
3a2cf30f47 | ||
|
|
9a3cab3645 | ||
|
|
7dbc02f879 | ||
|
|
a39f75744c | ||
|
|
5742c6591a | ||
|
|
588901ee4c | ||
|
|
e30d2aae19 | ||
|
|
463e4f12f8 | ||
|
|
01c2817005 | ||
|
|
1a16aab970 | ||
|
|
8247344f0d | ||
|
|
2fdd64a2d8 | ||
|
|
22ed4e7f73 | ||
|
|
327ac9f931 | ||
|
|
5ad0c38fe8 |
+16
-1
@@ -1,6 +1,21 @@
|
|||||||
# Travis CI integration
|
# Travis CI integration -- https://travis-ci.org/troglobit/finit
|
||||||
language: c
|
language: c
|
||||||
compiler:
|
compiler:
|
||||||
- gcc
|
- gcc
|
||||||
|
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
|
||||||
|
# via the "travis encrypt" command using the project repo's public key
|
||||||
|
- secure: "eOiuHs02lG2Uv146K9dMqucGTWUJFEhpz1oAtwe+kPrRXsXWc20hYMO+DSpMgD05vSvNeQA6p7h7LdRFQ+/g/Obj27TsOE+RKkUvRAtdwzxnKVyii9C/nmML8cFw7rIA0VS8O9mAkVYeyDxNDupBp3e9DPCibhKPvqCvioTnyy4="
|
||||||
|
|
||||||
|
addons:
|
||||||
|
coverity_scan:
|
||||||
|
project:
|
||||||
|
name: "troglobit/finit"
|
||||||
|
description: "finit | Fast Init Replacement"
|
||||||
|
notification_email: troglobit@gmail.com
|
||||||
|
build_command: "make"
|
||||||
|
branch_pattern: master
|
||||||
|
|
||||||
script: make
|
script: make
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
uninstall-exec uninstall-data uninstall-dev
|
uninstall-exec uninstall-data uninstall-dev
|
||||||
|
|
||||||
#VERSION ?= $(shell git tag -l | tail -1)
|
#VERSION ?= $(shell git tag -l | tail -1)
|
||||||
VERSION ?= 1.9
|
VERSION ?= 1.10
|
||||||
NAME = finit
|
NAME = finit
|
||||||
PKG = $(NAME)-$(VERSION)
|
PKG = $(NAME)-$(VERSION)
|
||||||
DEV = $(NAME)-dev
|
DEV = $(NAME)-dev
|
||||||
|
|||||||
@@ -0,0 +1,206 @@
|
|||||||
|
NEWS
|
||||||
|
====
|
||||||
|
|
||||||
|
|
||||||
|
1.10 (2014-11-27)
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Major bug fix release.
|
||||||
|
|
||||||
|
* Project now relies on static code analysis from Coverity, so this
|
||||||
|
release contains many serious bug fixes.
|
||||||
|
* Fix serious file descriptor and memory leaks in the following
|
||||||
|
functions. In particular the leaks in `run_interactive()` are very
|
||||||
|
serious since that function is called every time a service is
|
||||||
|
started and/or restarted! For details, see the GIT log:
|
||||||
|
* `helpers.c:run()`
|
||||||
|
* `helpers.c:run_interactive()`
|
||||||
|
* `helpers.c:set_hostname()`
|
||||||
|
* `helpers.c:procname_kill()`
|
||||||
|
* `svc.c:svc_start()`: Fix swapped arguments to dup2() and add
|
||||||
|
close(fd) to prevent descriptor leak.
|
||||||
|
* `svc.c:svc_start()`: Fix out of bounds write to local stack
|
||||||
|
variable, wrote off-by-one outside array.
|
||||||
|
* Several added checks for return values to `mknod()`, `mkdir()`,
|
||||||
|
`remove()`, etc.
|
||||||
|
* Convert to use Markdown for README, NEWS and TODO.
|
||||||
|
* Serious update to README and slight pruning of finished TODO items.
|
||||||
|
|
||||||
|
|
||||||
|
1.9 (2014-04-21)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* Bug fixes, code cleanup
|
||||||
|
* Add support for an include directive to `.conf` files
|
||||||
|
* Fallback to `/bin/sh` if user forgets tty setting
|
||||||
|
* Handle `SIGHUP` from service callback properly when switching runlevel
|
||||||
|
* Initial support for restarting lost services during `norespwan`
|
||||||
|
* Misc. major (memleak) and minor fixes and additions to `libite/lite.h`
|
||||||
|
|
||||||
|
|
||||||
|
1.8 (2013-06-07)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* Support for runlevels, with a bootstrap runlevel 'S'
|
||||||
|
* Support for saving previous and current runlevel to UTMP
|
||||||
|
* Support for new `finit.conf` commands: run, task, and runlevel
|
||||||
|
* Support for tty and console commands in `finit.conf`, like services
|
||||||
|
but for launching multiple getty logins
|
||||||
|
* New tty plugin to monitor TTYs coming and going, like USB TTYs
|
||||||
|
* Bugfixes to libite
|
||||||
|
|
||||||
|
|
||||||
|
1.7 (2012-10-08)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* Show `__FILE__` in `_d()` debug messages, useful for plugins with
|
||||||
|
similarily named callbacks. Also, only in debug mode anyway
|
||||||
|
* Make sure to cleanup recorded PID when a service is lost. Required
|
||||||
|
by service plugins for their callbacks to work.
|
||||||
|
* Bugfix: Do not `free()` static string in `finit.conf` parser
|
||||||
|
* Only clear screen when in verbose mode. Maybe this should be removed
|
||||||
|
altogether?
|
||||||
|
|
||||||
|
|
||||||
|
1.6 (2012-10-06)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* Skip . and .. in plugin loader and display error on failed plugins
|
||||||
|
* Support for overriding `/etc/finit.d` with `runparts DIR` in
|
||||||
|
`finit.conf`
|
||||||
|
* Revoke support for starting services not starting with a slash.
|
||||||
|
* Prevent endless restart of non-existing services in `finit.conf`
|
||||||
|
* Support for sysvinit style startstop scripts in `/etc/finit.d`
|
||||||
|
* Minor fix to alsa-utils plugin to silence on non-existing cards
|
||||||
|
|
||||||
|
|
||||||
|
1.5 (2012-10-03)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* Use bootmisc plugin to setup standard FHS 2.3 structure in `/var`
|
||||||
|
* Added `FLOG_WARN()` syslog macro, for plugins
|
||||||
|
* Add plugin dependency resolver. Checks `plugin_t` for `.depends`
|
||||||
|
|
||||||
|
|
||||||
|
1.4 (2012-10-02)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* Fix I/O plugin watcher and load plugins earlier for a new hook
|
||||||
|
* Start refactoring helpers.c into a libite.so (-lite). This means
|
||||||
|
other user space applications/daemons can make use of the neat toolbox
|
||||||
|
available in finit
|
||||||
|
* Use short-form -s/-w -u to work with BusyBox hwclock as well
|
||||||
|
* Use RTLD_GLOBAL flag to tell dynamic loader to load dependent .so
|
||||||
|
files as well. Lets other plugins use global symbols.
|
||||||
|
* Greatly simplify svc hook for external plugins and cleanup plugin API.
|
||||||
|
* And more ... see the GIT log for more details.
|
||||||
|
|
||||||
|
|
||||||
|
1.3 (2012-09-28)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* Cleanup public plugin API a bit and add new pid/pidfile funcs
|
||||||
|
* Add plugin hook to end of service startup
|
||||||
|
* Remove finit.h from svc.h, plugins should not need this.
|
||||||
|
* Move utility macros etc. to helpers.h
|
||||||
|
* Make `finit.h` daemon internal, only
|
||||||
|
* Move defines of FIFO, conf and rcS.d to Makefile => correct paths
|
||||||
|
* Add support for installing required headers in system include dir
|
||||||
|
* Better support for distributions and packagers with install-exec,
|
||||||
|
install-data, and install-dev targets in Makefile. Useful if you want
|
||||||
|
to call targets with different `$DESTDIR`!
|
||||||
|
* Makefile fixes for installation, paths encoded wrong
|
||||||
|
* Strip binaries + .so files, support for `$(CROSS)` toolchain strip
|
||||||
|
* Default install is now to `/sbin/finit` and `/usr/`
|
||||||
|
* Note change in `$PLUGIN_DIR` environemnt variable to `$plugindir`
|
||||||
|
|
||||||
|
|
||||||
|
1.2 (2012-09-27)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* Fix installation paths encoded in finit binary
|
||||||
|
* Update README with section on building and enviroment variables
|
||||||
|
|
||||||
|
|
||||||
|
1.1 (2012-09-27)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* Build fixes for ARM eabi/uClibc
|
||||||
|
* Rename signal.[ch]-->sig.[ch] to avoid name clash w/ system headers
|
||||||
|
|
||||||
|
|
||||||
|
1.0 (2012-09-26)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* New plugin based system for all odd extensions
|
||||||
|
* New service monitor that restarts services if they die
|
||||||
|
* New maintainer at GitHub http://github.com/troglobit/finit
|
||||||
|
* Add standard LICENSE and AUTHORS files
|
||||||
|
* New focus: embedded systems and small headless servers
|
||||||
|
|
||||||
|
|
||||||
|
0.6 (2010-06-14)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* don't start consolekit manually, dbus starts it (rtp)
|
||||||
|
* unmount all filesystems before rebooting
|
||||||
|
* disable `USE_VAR_RUN_RESOLVCONF` for Mandriva
|
||||||
|
* unset terminal type in Mandriva before running X
|
||||||
|
* remove extra sleep in finit-alt before calling services.sh (caio)
|
||||||
|
|
||||||
|
|
||||||
|
0.5 (2008-08-21)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* add option to start dbus and consolekit before the X server
|
||||||
|
* finit-alt listens to `/dev/initctl` to work with `reboot(8)` (smurfy)
|
||||||
|
* write runlevel to utmp, needed by Printerdrake (Pascal Terjan)
|
||||||
|
* fix ownership of `/var/run/utmp` (reported by Pascal Terjan)
|
||||||
|
* remove obsolete code to load AGP drivers
|
||||||
|
* conditional build of `/etc/resolveconf/run` support
|
||||||
|
* add support to `/var/run/resolvconf` in Mandriva (blino)
|
||||||
|
|
||||||
|
|
||||||
|
O.4 (2008-05-16)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* default username for finit-alt configurable in Makefile
|
||||||
|
* create loopback device node in finit-alt (for squashfs)
|
||||||
|
* add option to use built-in run-parts instead of `/bin/run-parts`
|
||||||
|
* ignore signal instead of setting to an empty handler (Metalshark)
|
||||||
|
* handle pam_console permissions in finit-alt for Mandriva
|
||||||
|
* add services.sh example and nash-hotplug patch for Mandriva
|
||||||
|
* mount `/proc/bus/usb` in Mandriva
|
||||||
|
* add runtime debug to finit-alt if finit_debug parameter is specified
|
||||||
|
* read configuration from `/etc/finit.conf`
|
||||||
|
* run getty with openvt on the virtual terminal
|
||||||
|
|
||||||
|
|
||||||
|
0.3 (2008-02-23)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* Change poweroff method to `reboot(RB_POWER_OFF)` (Metalshark)
|
||||||
|
* Remove duplicate `unionctl()` reimplementation error
|
||||||
|
* Fix string termination in path creation
|
||||||
|
* Mount `/var/lock` and `/var/run` as tmpfs
|
||||||
|
|
||||||
|
|
||||||
|
0.2 (2008-02-19)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* replace` system("touch")` with `touch()` in finit-mod (Metalshark)
|
||||||
|
* disable `NO_HCTOSYS` by default to match stock Eeepc kernel
|
||||||
|
* drop `system("rm -f")` to clean `/tmp`, its a fresh mounted tmpfs
|
||||||
|
* write ACPI sleep state to `/sys/power/state` instead of
|
||||||
|
`/proc/acpi/sleep` (Metalshark)
|
||||||
|
* use direct calls to set loopback instead of `system("ifconfig")`
|
||||||
|
* replace `system("cat")` and `system("dd")` with C implementation
|
||||||
|
* moved finit-mod and finit-alt helpers to `helpers.c`
|
||||||
|
* replace `system("echo;cat")` to draw shutdown splash with C calls
|
||||||
|
|
||||||
|
|
||||||
|
0.1 (2008-02-14)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* initial release
|
||||||
|
|
||||||
@@ -1,169 +0,0 @@
|
|||||||
==============================================================================
|
|
||||||
NEWS
|
|
||||||
==============================================================================
|
|
||||||
|
|
||||||
1.9 (2014-04-21)
|
|
||||||
----------------
|
|
||||||
* Bug fixes, code cleanup
|
|
||||||
* Add support for an include directive to .conf files
|
|
||||||
* Fallback to ``/bin/sh`` if user forgets tty setting
|
|
||||||
* Handle ``SIGHUP`` from service callback properly when switching runlevel
|
|
||||||
* Initial support for restarting lost services during ``norespwan``
|
|
||||||
* Misc. major (memleak) and minor fixes and additions to libite/lite.h
|
|
||||||
|
|
||||||
|
|
||||||
1.8 (2013-06-07)
|
|
||||||
----------------
|
|
||||||
* Support for runlevels, with a bootstrap runlevel 'S'
|
|
||||||
* Support for saving previous and current runlevel to UTMP
|
|
||||||
* Support for new finit.conf commands: run, task, and runlevel
|
|
||||||
* Support for tty and console commands in finit.conf, like services but
|
|
||||||
for launching multiple getty logins
|
|
||||||
* New tty plugin to monitor TTYs coming and going, like USB TTYs
|
|
||||||
* Bugfixes to libite
|
|
||||||
|
|
||||||
|
|
||||||
1.7 (2012-10-08)
|
|
||||||
----------------
|
|
||||||
* Show __FILE__ in _d() debug messages, useful for plugins with
|
|
||||||
similarily named callbacks. Also, only in debug mode anyway
|
|
||||||
* Make sure to cleanup recorded PID when a service is lost. Required by
|
|
||||||
service plugins for their callbacks to work.
|
|
||||||
* Bugfix: Do not free() static string in finit.conf parser
|
|
||||||
* Only clear screen when in verbose mode. Maybe this should be removed
|
|
||||||
altogether?
|
|
||||||
|
|
||||||
|
|
||||||
1.6 (2012-10-06)
|
|
||||||
----------------
|
|
||||||
* Skip . and .. in plugin loader and display error on failed plugins
|
|
||||||
* Support for overriding /etc/finit.d with "runparts DIR" in finit.conf
|
|
||||||
* Revoke support for starting services not starting with a slash.
|
|
||||||
* Prevent endless restart of non-existing services in finit.conf
|
|
||||||
* Support for sysvinit style startstop scripts in /etc/finit.d
|
|
||||||
* Minor fix to alsa-utils plugin to silence on non-existing cards
|
|
||||||
|
|
||||||
|
|
||||||
1.5 (2012-10-03)
|
|
||||||
----------------
|
|
||||||
* Use bootmisc plugin to setup standard FHS 2.3 structure in /var
|
|
||||||
* Added FLOG_WARN() syslog macro, for plugins
|
|
||||||
* Add plugin dependency resolver. Checks plugin_t for .depends
|
|
||||||
|
|
||||||
|
|
||||||
1.4 (2012-10-02)
|
|
||||||
----------------
|
|
||||||
* Fix I/O plugin watcher and load plugins earlier for a new hook
|
|
||||||
* Start refactoring helpers.c into a libite.so (-lite). This means
|
|
||||||
other user space applications/daemons can make use of the neat toolbox
|
|
||||||
available in finit
|
|
||||||
* Use short-form -s/-w -u to work with BusyBox hwclock as well
|
|
||||||
* Use RTLD_GLOBAL flag to tell dynamic loader to load dependent .so
|
|
||||||
files as well. Lets other plugins use global symbols.
|
|
||||||
* Greatly simplify svc hook for external plugins and cleanup plugin API.
|
|
||||||
* And more... see the GIT log for more details.
|
|
||||||
|
|
||||||
|
|
||||||
1.3 (2012-09-28)
|
|
||||||
----------------
|
|
||||||
* Cleanup public plugin API a bit and add new pid/pidfile funcs
|
|
||||||
* Add plugin hook to end of service startup
|
|
||||||
* Remove finit.h from svc.h, plugins should not need this.
|
|
||||||
* Move utility macros etc. to helpers.h
|
|
||||||
* Make finit.h daemon internal, only
|
|
||||||
* Move defines of FIFO, conf and rcS.d to Makefile => correct paths
|
|
||||||
* Add support for installing required headers in system include dir
|
|
||||||
* Better support for distributions and packagers with install-exec,
|
|
||||||
install-data, and install-dev targets in Makefile. Useful if you want
|
|
||||||
to call targets with different $DESTDIR!
|
|
||||||
* Makefile fixes for installation, paths encoded wrong
|
|
||||||
* Strip binaries + .so files, support for $(CROSS) toolchain strip
|
|
||||||
* Default install is now to /sbin/finit and /usr/
|
|
||||||
* Note change in $PLUGIN_DIR environemnt variable to $plugindir
|
|
||||||
|
|
||||||
|
|
||||||
1.2 (2012-09-27)
|
|
||||||
----------------
|
|
||||||
* Fix installation paths encoded in finit binary
|
|
||||||
* Update README with section on building and enviroment variables
|
|
||||||
|
|
||||||
|
|
||||||
1.1 (2012-09-27)
|
|
||||||
----------------
|
|
||||||
* Build fixes for ARM eabi/uClibc
|
|
||||||
* Rename signal.[ch]-->sig.[ch] to avoid name clash w/ system headers
|
|
||||||
|
|
||||||
|
|
||||||
1.0 (2012-09-26)
|
|
||||||
----------------
|
|
||||||
* New plugin based system for all odd extensions
|
|
||||||
* New service monitor that restarts services if they die
|
|
||||||
* New maintainer at GitHub http://github.com/troglobit/finit
|
|
||||||
* Add standard LICENSE and AUTHORS files
|
|
||||||
* New focus: embedded systems and small headless servers
|
|
||||||
|
|
||||||
|
|
||||||
0.6 (2010-06-14)
|
|
||||||
----------------
|
|
||||||
* don't start consolekit manually, dbus starts it (rtp)
|
|
||||||
* unmount all filesystems before rebooting
|
|
||||||
* disable USE_VAR_RUN_RESOLVCONF for Mandriva
|
|
||||||
* unset terminal type in Mandriva before running X
|
|
||||||
* remove extra sleep in finit-alt before calling services.sh (caio)
|
|
||||||
|
|
||||||
|
|
||||||
0.5 (2008-08-21)
|
|
||||||
----------------
|
|
||||||
* add option to start dbus and consolekit before the X server
|
|
||||||
* finit-alt listens to /dev/initctl to work with reboot(8) (smurfy)
|
|
||||||
* write runlevel to utmp, needed by Printerdrake (Pascal Terjan)
|
|
||||||
* fix ownership of /var/run/utmp (reported by Pascal Terjan)
|
|
||||||
* remove obsolete code to load AGP drivers
|
|
||||||
* conditional build of /etc/resolveconf/run support
|
|
||||||
* add support to /var/run/resolvconf in Mandriva (blino)
|
|
||||||
|
|
||||||
|
|
||||||
O.4 (2008-05-16)
|
|
||||||
----------------
|
|
||||||
* default username for finit-alt configurable in Makefile
|
|
||||||
* create loopback device node in finit-alt (for squashfs)
|
|
||||||
* add option to use built-in run-parts instead of /bin/run-parts
|
|
||||||
* ignore signal instead of setting to an empty handler (Metalshark)
|
|
||||||
* handle pam_console permissions in finit-alt for Mandriva
|
|
||||||
* add services.sh example and nash-hotplug patch for Mandriva
|
|
||||||
* mount /proc/bus/usb in Mandriva
|
|
||||||
* add runtime debug to finit-alt if finit_debug parameter is specified
|
|
||||||
* read configuration from /etc/finit.conf
|
|
||||||
* run getty with openvt on the virtual terminal
|
|
||||||
|
|
||||||
|
|
||||||
0.3 (2008-02-23)
|
|
||||||
----------------
|
|
||||||
* Change poweroff method to reboot(RB_POWER_OFF) (Metalshark)
|
|
||||||
* Remove duplicate unionctl() reimplementation error
|
|
||||||
* Fix string termination in path creation
|
|
||||||
* Mount /var/lock and /var/run as tmpfs
|
|
||||||
|
|
||||||
|
|
||||||
0.2 (2008-02-19)
|
|
||||||
----------------
|
|
||||||
* replace system("touch") with touch() in finit-mod (Metalshark)
|
|
||||||
* disable NO_HCTOSYS by default to match stock Eeepc kernel
|
|
||||||
* drop system("rm -f") to clean /tmp, its a fresh mounted tmpfs
|
|
||||||
* write ACPI sleep state to /sys/power/state instead of /proc/acpi/sleep
|
|
||||||
(Metalshark)
|
|
||||||
* use direct calls to set loopback instead of system("ifconfig")
|
|
||||||
* replace system("cat") and system("dd") with C implementation
|
|
||||||
* moved finit-mod and finit-alt helpers to helpers.c
|
|
||||||
* replace system("echo;cat") to draw shutdown splash with C calls
|
|
||||||
|
|
||||||
|
|
||||||
0.1 (2008-02-14)
|
|
||||||
----------------
|
|
||||||
* initial release
|
|
||||||
|
|
||||||
|
|
||||||
.. Local Variables:
|
|
||||||
.. mode: rst
|
|
||||||
.. version-control: t
|
|
||||||
.. End:
|
|
||||||
@@ -0,0 +1,390 @@
|
|||||||
|
README
|
||||||
|
======
|
||||||
|
[](https://travis-ci.org/troglobit/finit)
|
||||||
|
[](https://scan.coverity.com/projects/3545)
|
||||||
|
|
||||||
|
Init is the first process to run once a UNIX kernel has booted, it
|
||||||
|
always has PID 1 and is responsible for starting up the rest of the
|
||||||
|
system. Finit is a very small plugin based init with built in
|
||||||
|
[process supervision](https://en.wikipedia.org/wiki/Process_supervision)
|
||||||
|
similar to that of D.J. Bernstein's
|
||||||
|
[daemontools](http://cr.yp.to/daemontools.html) and Gerrit Pape's
|
||||||
|
[runit](http://smarden.org/runit/). Its focus is on small and embedded
|
||||||
|
GNU/Linux systems, although fully functional on standard server and
|
||||||
|
desktop installations.
|
||||||
|
|
||||||
|
Finit is fast because it is "scripted" with C and starts services in
|
||||||
|
parallel. Services are supervised and automatically restarted if they
|
||||||
|
fail. Services can have callbacks that are called before a service is
|
||||||
|
(re)started. For instance, before attempting to start a heavily
|
||||||
|
resource intensive service like IPsec or OpenVPN, a callback can check
|
||||||
|
if the outbound interface is up and has an IP address, or just check if
|
||||||
|
the service is disabled -- much like what a SysV init start script
|
||||||
|
usually does.
|
||||||
|
|
||||||
|
To extend finit with new functionality, hooks can be added at certain
|
||||||
|
points in the boot process that execute in sequence, which is useful for
|
||||||
|
certain satisfying preconditions or for synchronization purposes. One
|
||||||
|
can also create plugins to functionality to suit your own needs, the
|
||||||
|
initctl compatibility plugin that comes with finit is one such plugin.
|
||||||
|
|
||||||
|
Finit is not only fast, it's arguably one of the easiest to get started
|
||||||
|
with. A complete system can be booted with one simple configuration
|
||||||
|
file, `/etc/finit.conf`, see below for syntax.
|
||||||
|
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
**Process Supervision**
|
||||||
|
|
||||||
|
Start, monitor and restart services if they fail.
|
||||||
|
|
||||||
|
**Runlevels**
|
||||||
|
|
||||||
|
Finit supports standard runlevels if you want, but you don't need them
|
||||||
|
for simple installations.
|
||||||
|
|
||||||
|
**Plugins**
|
||||||
|
|
||||||
|
Extend and modify finit behavior. See examples in plugins/ directory.
|
||||||
|
Plugin capabilities:
|
||||||
|
|
||||||
|
* Service callbacks — modify service arguments, run/restart/stop
|
||||||
|
* Task/Run callbacks — a one-shot commands, executed in sequence
|
||||||
|
* Hooks — hook into the boot at predefined points to extend finit
|
||||||
|
* I/O — listen to external events and control finit behavior/services
|
||||||
|
|
||||||
|
Extensions and functionality not purely related to what an /sbin/init
|
||||||
|
needs to start a system are available as a set of plugins that either
|
||||||
|
hook into the boot process or respond to various I/O.
|
||||||
|
|
||||||
|
|
||||||
|
/etc/finit.conf
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Contrary to most other script based init alternatives
|
||||||
|
([SysV init](https://en.wikipedia.org/wiki/Init),
|
||||||
|
[upstart](http://upstart.ubuntu.com/),
|
||||||
|
[systemd](http://www.freedesktop.org/wiki/Software/systemd/),
|
||||||
|
[OpenRC](http://www.gentoo.org/proj/en/base/openrc/) and the likes)
|
||||||
|
finit reads its configuration from `/etc/finit.conf`. Syntax:
|
||||||
|
|
||||||
|
* `check <DEV>`
|
||||||
|
|
||||||
|
Run fsck on a file system before mounting it
|
||||||
|
|
||||||
|
* `module <MODULE>`
|
||||||
|
|
||||||
|
Load a kernel module, with optional arguments
|
||||||
|
|
||||||
|
* `network <PATH>`
|
||||||
|
|
||||||
|
Script or program to bring up networking, with optional arguments
|
||||||
|
|
||||||
|
* `runlevel <N>`
|
||||||
|
|
||||||
|
N is the runlevel number 1-9, where 6 is reserved for reboot.
|
||||||
|
|
||||||
|
Default is 2.
|
||||||
|
|
||||||
|
* `run [LVLS] /path/to/cmd ARGS -- Optional description`
|
||||||
|
|
||||||
|
One-shot command to run in sequence when entering a runlevel, with
|
||||||
|
optional arguments and description. This command is guaranteed to
|
||||||
|
be completed before running the next command.
|
||||||
|
|
||||||
|
* `task LVLS] /path/to/cmd ARGS -- Optional description`
|
||||||
|
|
||||||
|
One-shot like 'run', but starts in parallel with the next command
|
||||||
|
|
||||||
|
* `service [LVLS] /path/to/daemon ARGS -- Optional description`
|
||||||
|
|
||||||
|
Service, or daemon, to be monitored and automatically restarted if
|
||||||
|
it exits prematurely. Please note that you often need to provide
|
||||||
|
a --foreground or --no-background argument to most daemons to
|
||||||
|
prevent them from forking off to the background.
|
||||||
|
|
||||||
|
* `runparts <PATH>`
|
||||||
|
|
||||||
|
Call run-parts(8) on a directory other than default ``/etc/finit.d``
|
||||||
|
|
||||||
|
* `include <CONF>`
|
||||||
|
|
||||||
|
Include another configuration file, ``/etc/finit.d``, or runparts
|
||||||
|
path is prepended to file if the file is not found or an absolute
|
||||||
|
path is not given
|
||||||
|
|
||||||
|
* `tty [LVLS] <DEV | /bin/sh>`
|
||||||
|
|
||||||
|
Start a getty on the given TTY device, in the given runlevels. When
|
||||||
|
no tty setting is given in `finit.conf`, or if `/bin/sh` is given as
|
||||||
|
argument instead of a device path, a single shell is started on the
|
||||||
|
default console. Useful for really bare-bones systems
|
||||||
|
|
||||||
|
See `finit.h` for the `#define GETTY` that is called, along with the
|
||||||
|
default baud rate.
|
||||||
|
|
||||||
|
* `console <DEV>`
|
||||||
|
|
||||||
|
Some embedded systems have a dedicated console port. This command
|
||||||
|
tells finit to not start getty, but instead print a friendly message
|
||||||
|
and wait for the user to activate the console with a key press before
|
||||||
|
starting getty.
|
||||||
|
|
||||||
|
When running `make install` no default `/etc/finit.conf` will be
|
||||||
|
provided since the system requirements differ too much. Try out the
|
||||||
|
Debian 6.0 example `/usr/share/doc/finit/finit.conf` configuration that
|
||||||
|
is capable of service monitoring SSH, sysklogd, gdm and a console getty!
|
||||||
|
|
||||||
|
|
||||||
|
/etc/finit.d
|
||||||
|
------------
|
||||||
|
|
||||||
|
At the end of the boot, when networking and all services are up, finit
|
||||||
|
calls its built-in run-parts(8) on the `/etc/finit.d/` directory, if
|
||||||
|
it exists. Similar to how the `/ec/rc.local` file works in most other
|
||||||
|
init daemons, only finit runs a directory of scripts. This replaces the
|
||||||
|
earlier support for a `/usr/sbin/services.sh` script in the original
|
||||||
|
finit.
|
||||||
|
|
||||||
|
|
||||||
|
Runlevels
|
||||||
|
---------
|
||||||
|
|
||||||
|
Basic support for [runlevels](http://en.wikipedia.org/wiki/Runlevel) is
|
||||||
|
included in Finit from v1.8. By default all services, tasks, run
|
||||||
|
commands and TTYs listed without a set of runlevels get a default set
|
||||||
|
`[234]` assigned. The default runlevel after boot is 2.
|
||||||
|
|
||||||
|
To specify an allowed set of runlevels for a `service`, `run` command, `task`,
|
||||||
|
or `tty`, add `[NNN]` to it in your `finit.conf`, like this:
|
||||||
|
|
||||||
|
run [S] /etc/init.d/acpid start -- Starting ACPI Daemon
|
||||||
|
task [S] /etc/init.d/kbd start -- Preparing console
|
||||||
|
service [S12345] /sbin/klogd -n -x -- Kernel log daemon
|
||||||
|
tty [12345] /dev/tty1
|
||||||
|
tty [2] /dev/tty2
|
||||||
|
tty [2] /dev/tty3
|
||||||
|
tty [2] /dev/tty4
|
||||||
|
tty [2] /dev/tty5
|
||||||
|
tty [2] /dev/tty6
|
||||||
|
|
||||||
|
In this example acpid is started once at bootstrap using a conventional
|
||||||
|
SysV init script. Here the run command was used, meaning the following
|
||||||
|
task command is not run until the init script has fully completed. Then
|
||||||
|
the keyboard setup script is called in parallel with spawning klogd as
|
||||||
|
a monitored service.
|
||||||
|
|
||||||
|
Tasks and services are started in parallel, while run commands are run
|
||||||
|
in the order listed and subsequent commands are not started until a run
|
||||||
|
command has completed.
|
||||||
|
|
||||||
|
Existing finit.conf files that lack runlevel setting will get a default
|
||||||
|
runlevel assigned, `[234]`.
|
||||||
|
|
||||||
|
Switching between runlevels can be done by calling init with a single
|
||||||
|
argument, e.g., `init 5` switches to runlevel 5.
|
||||||
|
|
||||||
|
|
||||||
|
Hooks, Callbacks & Plugins
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
Finit provides only the bare necessities for starting and supervising
|
||||||
|
processes, with an emphasis on *bare* -- for your convenience it does
|
||||||
|
however come with support for hooks, service callbacks and plugins that
|
||||||
|
can used to extend finit with. For your convenience a set of *optional*
|
||||||
|
plugins are available:
|
||||||
|
|
||||||
|
* *alsa-utils.so*: Restore and save ALSA sound settings on
|
||||||
|
startup/shutdown.
|
||||||
|
|
||||||
|
* *bootmisc.so*: Setup necessary files for UTMP, tracking logins
|
||||||
|
at boot.
|
||||||
|
|
||||||
|
* *dbus.so*: Setup and start system message bus, D-Bus, at boot.
|
||||||
|
|
||||||
|
* *hwclock.so*: Restore and save system clock from/to RTC on
|
||||||
|
startup/shutdown.
|
||||||
|
|
||||||
|
* *initctl.so*: Extends finit with a traditional initctl functionality.
|
||||||
|
|
||||||
|
* *resolvconf.so*: Setup necessary files for resolvconf at startup.
|
||||||
|
|
||||||
|
* *tty.so*: Watches /dev, using inotify, for new device nodes (TTY's) to
|
||||||
|
start/stop getty consoles on them on demand.
|
||||||
|
|
||||||
|
* *urandom.so*: Setup random seed at startup.
|
||||||
|
|
||||||
|
* *x11-common.so*: Setup necessary files for X-Window.
|
||||||
|
|
||||||
|
Usually you want to hook into the boot process once, simple hook plugins
|
||||||
|
like `bootmisc.so` are great for that purpose. They are called at each
|
||||||
|
hook point in the boot process, useful to insert some pre-bootstrap
|
||||||
|
mechanisms, like generating configuration files, restoring HW device
|
||||||
|
state, etc. Available hook points are:
|
||||||
|
|
||||||
|
* `HOOK_ROOTFS_UP`: When `finit.conf` has been read and `/` has is
|
||||||
|
mounted -- very early
|
||||||
|
|
||||||
|
* `HOOK_BASEFS_UP`: All of `/etc/fstab` is mounted, swap is available
|
||||||
|
and default init signals are setup
|
||||||
|
|
||||||
|
* `HOOK_NETWORK_UP`: System bootstrap, runlevel S, has completed and
|
||||||
|
networking is up (`lo` is up and the `network` script has run)
|
||||||
|
|
||||||
|
* `HOOK_SVC_UP`: All services in the active runlevel has been launched
|
||||||
|
|
||||||
|
* `HOOK_SYSTEM_UP`: All services *and* everything in `/etc/finit.d`
|
||||||
|
has been launched
|
||||||
|
|
||||||
|
* `HOOK_SHUTDOWN`: Called at shutdown/reboot, right before all
|
||||||
|
services are sent `SIGTERM`
|
||||||
|
|
||||||
|
Plugins like `initctl.so` and `tty.so` extend finit by acting on events,
|
||||||
|
they are called I/O plugins and are called from the finit main loop when
|
||||||
|
`poll()` detects an event. See the source code for `plugins/*.c` for
|
||||||
|
more help and ideas.
|
||||||
|
|
||||||
|
Callback plugins are called by finit them right before a process is
|
||||||
|
started, or restarted if it exits. The callback receive a pointer to
|
||||||
|
the `svc_t` (defined in `svc.h`) of the service, with all command line
|
||||||
|
parameters free to modify if needed. All the callback needs to do is
|
||||||
|
respond with one of: `SVC_STOP (0)` tells finit to *not* start the
|
||||||
|
service, `SVC_START (1)` to start the service, or `SVC_RELOAD (2)` to
|
||||||
|
have finit signal the process with `SIGHUP`.
|
||||||
|
|
||||||
|
|
||||||
|
Rebooting and Halting
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Finit handles `SIGUSR1` and `SIGUSR2` for reboot and halt, and listens
|
||||||
|
to `/dev/initctl` so system reboot and halt commands should also work.
|
||||||
|
This latter functionality is implemented in the optional `initctl.so`
|
||||||
|
plugin.
|
||||||
|
|
||||||
|
|
||||||
|
Building
|
||||||
|
--------
|
||||||
|
|
||||||
|
The finit build system does not employ the GNU Configure and Build System,
|
||||||
|
instead standard makefiles are used. The user is encouraged to make source
|
||||||
|
code changes, using defines and conditionally building plugins instead to
|
||||||
|
alter the behavior of finit.
|
||||||
|
|
||||||
|
The following environment variables are checked by the makefiles and control
|
||||||
|
what is built and where resulting binaries are installed.
|
||||||
|
|
||||||
|
* `ROOTDIR=`: Top directory for building complete system, used in pretty
|
||||||
|
printing.
|
||||||
|
|
||||||
|
* `VERSION=`: Defaults to the currently released version of finit,
|
||||||
|
e.g., 1.3 but can be overridden by packagers using this variable to
|
||||||
|
add a suffix or completely alter the version.
|
||||||
|
|
||||||
|
* `CFLAGS=`: Default `CFLAGS` are inherited from the build environment.
|
||||||
|
|
||||||
|
* `CPPFLAGS=`: Default `CPPFLAGS` are inherited from the build
|
||||||
|
environment.
|
||||||
|
|
||||||
|
* `LDFLAGS=`: Default `LDFLAGS` are inherited from the build
|
||||||
|
environment.
|
||||||
|
|
||||||
|
* `LDLIBS=`: Default `LIBLIBS` are inherited from the build environment.
|
||||||
|
|
||||||
|
* `prefix=`: Base prefix path for all files, except `sbinbdir` and
|
||||||
|
`sysconfdir`. Used in concert with the `DESTDIR` variable.
|
||||||
|
|
||||||
|
Defaults to `/usr`.
|
||||||
|
|
||||||
|
* `sbindir=`: Path to where resulting binaries should install to. Used
|
||||||
|
in concert with the `DESTDIR` variable.
|
||||||
|
|
||||||
|
Defaults to `/sbin`.
|
||||||
|
|
||||||
|
* `sysconfdir=`: Path to where finit configuration files should install
|
||||||
|
to. Used in concert with the `DESTDIR` variable.
|
||||||
|
|
||||||
|
Defaults to `/etc`, but is currently unused.
|
||||||
|
|
||||||
|
* `PLUGINS=`: List of stock finit plugins to build and install.
|
||||||
|
|
||||||
|
* `plugindir=`: Absolute path to where finit should look for dynamically
|
||||||
|
loadable plugins at runtime. At installation prepended by `DESTDIR`
|
||||||
|
and `prefix`.
|
||||||
|
|
||||||
|
Defaults to `/lib/finit/plugins`.
|
||||||
|
|
||||||
|
* `DESTDIR=`: Used by packagers and distributions when building a
|
||||||
|
relocatable bundle of files. Always prepended to the `prefix`
|
||||||
|
destination directory.
|
||||||
|
|
||||||
|
**Example**
|
||||||
|
|
||||||
|
$ tar xfJ finit-1.3.tar.xz
|
||||||
|
$ PLUGINS="initctl.so hwclock.so" DESTDIR=/tmp/finit/dst \
|
||||||
|
make -C finit-1.3/ clean install
|
||||||
|
make: Entering directory `/home/troglobit/finit-1.3'
|
||||||
|
CC finit.o
|
||||||
|
CC conf.o
|
||||||
|
CC helpers.o
|
||||||
|
CC sig.o
|
||||||
|
CC svc.o
|
||||||
|
CC plugin.o
|
||||||
|
CC strlcpy.o
|
||||||
|
LINK finit
|
||||||
|
CC plugins/initctl.o
|
||||||
|
PLUGIN plugins/initctl.so
|
||||||
|
CC plugins/hwclock.o
|
||||||
|
PLUGIN plugins/hwclock.so
|
||||||
|
INSTALL /tmp/finit/dst/sbin/finit
|
||||||
|
INSTALL /tmp/finit/dst/lib/finit/plugins/initctl.so
|
||||||
|
INSTALL /tmp/finit/dst/lib/finit/plugins/hwclock.so
|
||||||
|
make: Leaving directory `/home/troglobit/finit-1.3'
|
||||||
|
|
||||||
|
In this example the
|
||||||
|
[finit-1.3.tar.xz](ftp://troglobit.com/finit/finit-1.3.tar.xz)
|
||||||
|
archive is unpacked to the user's home directory, built and
|
||||||
|
installed to a temporary staging directory. The environment
|
||||||
|
variables `DESTDIR` and `PLUGINS` are changed to suit this
|
||||||
|
particular build.
|
||||||
|
|
||||||
|
|
||||||
|
Running
|
||||||
|
-------
|
||||||
|
|
||||||
|
The default install does not setup finit as the system default
|
||||||
|
`/sbin/init`, neither does it setup an initial `/etc/finit.conf`.
|
||||||
|
|
||||||
|
It is assumed that users of finit are competent enough to either setup
|
||||||
|
finit as their default `/sbin/init` or alter their respective Grub,
|
||||||
|
LOADLIN, LILO, U-Boot/Barebox or RedBoot boot loader configuration to
|
||||||
|
give the kernel the following extra command line:
|
||||||
|
|
||||||
|
init=/sbin/finit
|
||||||
|
|
||||||
|
|
||||||
|
Debugging
|
||||||
|
---------
|
||||||
|
|
||||||
|
Add `finit_debug`, or `--debug`, to the kernel command line to
|
||||||
|
enable trace messages. A console getty is always started, see the file
|
||||||
|
`finit.h` for more useful compile-time tweaks:
|
||||||
|
|
||||||
|
init=/sbin/finit --debug
|
||||||
|
|
||||||
|
|
||||||
|
Credits & Contact
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
This is the continuation of the [original finit](http://helllabs.org/finit/)
|
||||||
|
by [Claudio Matsuoka](https://github.com/cmatsuoka), which in turn was
|
||||||
|
reverse engineered from syscalls of the
|
||||||
|
[EeePC fastinit](http://wiki.eeeuser.com/boot_process:the_boot_process)
|
||||||
|
-- "gaps filled with frog DNA ...".
|
||||||
|
|
||||||
|
Finit is currently being developed and maintained by
|
||||||
|
[Joachim Nilsson](http://troglobit.com) at
|
||||||
|
[GitHub](http://github.com/troglobit/finit). Please file bug reports, clone it,
|
||||||
|
or send pull requests for bug fixes and proposed extensions.
|
||||||
|
|
||||||
-295
@@ -1,295 +0,0 @@
|
|||||||
==============================================================================
|
|
||||||
Finit | Fast Init Replacement
|
|
||||||
==============================================================================
|
|
||||||
|cistatus|
|
|
||||||
|
|
||||||
Finit is a small `SysV init`_ replacement with `process supervision`_
|
|
||||||
similar to that of `daemontools`_ and `runit`_. Its focus is on small
|
|
||||||
and embedded GNU/Linux systems, although fully functional on standard
|
|
||||||
server and desktop installations. It should also work on other UNIX
|
|
||||||
systems, but this has yet to be proven.
|
|
||||||
|
|
||||||
Finit is fast because it starts services in parallel, it then supervises
|
|
||||||
and automatically restarts them if they fail. This can be extended upon
|
|
||||||
with custom callbacks for all services, hooks into the boot process, or
|
|
||||||
plugins to extend the functionality and adapt Finit to your needs.
|
|
||||||
|
|
||||||
Finit is not only fast, it's arguably one of the easiest to get started
|
|
||||||
with. A complete system can be booted with one simple configuration
|
|
||||||
file, ``/etc/finit.conf``, see below for syntax.
|
|
||||||
|
|
||||||
|
|
||||||
Features
|
|
||||||
--------
|
|
||||||
|
|
||||||
**Process Supervision**
|
|
||||||
Start, monitor and restarting services if they fail.
|
|
||||||
|
|
||||||
**Runlevels**
|
|
||||||
Finit supports standard runlevels if you want, but you don't need them
|
|
||||||
for simple installations.
|
|
||||||
|
|
||||||
**Plugins**
|
|
||||||
Extend and modify finit behavior. See examples in plugins/ directory.
|
|
||||||
Plugin capabilities:
|
|
||||||
|
|
||||||
* Service callbacks — modify service arguments, run/restart/stop
|
|
||||||
* Task/Run callbacks — a one-shot commands, executed in sequence
|
|
||||||
* Hooks — hook into the boot at predefined points to extend finit
|
|
||||||
* I/O — listen to external events and control finit behavior/services
|
|
||||||
|
|
||||||
Extensions and functionality not purely related to what an /sbin/init
|
|
||||||
needs to start a system are available as a set of plugins that either
|
|
||||||
hook into the boot process or respond to various I/O.
|
|
||||||
|
|
||||||
|
|
||||||
/etc/finit.conf
|
|
||||||
---------------
|
|
||||||
|
|
||||||
Contrary to most script based init alternatives (`SysV init`_, upstart_,
|
|
||||||
systemd_, OpenRC_ and the likes) finit instead reads its configuration
|
|
||||||
from ``/etc/finit.conf``. Below is a brief list, see the source code
|
|
||||||
for the full list:
|
|
||||||
|
|
||||||
check <DEV>
|
|
||||||
Run fsck on a file system before mounting it
|
|
||||||
|
|
||||||
module <MODULE>
|
|
||||||
Load a kernel module, with optional arguments
|
|
||||||
|
|
||||||
network <PATH>
|
|
||||||
Script or program to bring up networking, with optional arguments
|
|
||||||
|
|
||||||
runlevel <N>
|
|
||||||
N is the runlevel number 1-9, where 6 is reserved for reboot
|
|
||||||
|
|
||||||
run [RUN_LVLS] /path/to/cmd ARGS -- Optional description
|
|
||||||
One-shot command to run in sequence when entering a runlevel, with
|
|
||||||
optional arguments and description. This command is guaranteed to
|
|
||||||
be completed before running the next command.
|
|
||||||
|
|
||||||
task [RUN_LVLS] /path/to/cmd ARGS -- Optional description
|
|
||||||
One-shot like 'run', but starts in parallel with the next command
|
|
||||||
|
|
||||||
service [RUN_LVLS] /path/to/daemon ARGS -- Optional description
|
|
||||||
Service, or daemon, to be monitored and automatically restarted if
|
|
||||||
it exits prematurely. Please note that you often need to provide
|
|
||||||
a --foreground or --no-background argument to most daemons to
|
|
||||||
prevent them from forking off to the background.
|
|
||||||
|
|
||||||
runparts <PATH>
|
|
||||||
Call run-parts(8) on a directory other than default ``/etc/finit.d``
|
|
||||||
|
|
||||||
include <CONF>
|
|
||||||
Include another configuration file, ``/etc/finit.d``, or runparts
|
|
||||||
path is prepended to file if the file is not found or an absolute
|
|
||||||
path is not given
|
|
||||||
|
|
||||||
tty [RUN_LVLS] <DEV | /bin/sh>
|
|
||||||
Start a getty on the given TTY device, in the given runlevels. When
|
|
||||||
no tty setting is given in ``finit.conf``, or if /bin/sh is given as
|
|
||||||
argument instead of a device path, a single shell is started on the
|
|
||||||
default console. Useful for really bare-bones systems
|
|
||||||
|
|
||||||
console <DEV>
|
|
||||||
Some embedded systems have a dedicated console port. This command
|
|
||||||
tells finit to not start getty, but instead print a friendly message
|
|
||||||
and wait for the user to activate the console with a key press before
|
|
||||||
starting getty.
|
|
||||||
|
|
||||||
When running ``make install`` no default ``/etc/finit.conf`` will be
|
|
||||||
provided since the system requirements differ too much. Try out the
|
|
||||||
Debian 6.0 example ``/usr/share/doc/finit/finit.conf`` configuration
|
|
||||||
that is capable of service monitoring SSH, sysklogd, gdm and a console
|
|
||||||
getty!
|
|
||||||
|
|
||||||
|
|
||||||
/etc/finit.d
|
|
||||||
------------
|
|
||||||
|
|
||||||
At the end of the boot, when networking and all services are up, finit
|
|
||||||
calls its built-in run-parts(8) on the ``/etc/finit.d/`` directory, if
|
|
||||||
it exists. Similar to how the ``/ec/rc.local`` file works in most other
|
|
||||||
init daemons, only finit runs a directory of scripts. This replaces the
|
|
||||||
earlier support for a ``/usr/sbin/services.sh`` script in the original
|
|
||||||
finit.
|
|
||||||
|
|
||||||
|
|
||||||
Runlevels
|
|
||||||
---------
|
|
||||||
|
|
||||||
Support for runlevels_ is included in Finit from v1.8. By default all
|
|
||||||
services, tasks, run commands and TTYs listed without a set of runlevels
|
|
||||||
get a default set [234] assigned. The default runlevel after boot is 2.
|
|
||||||
|
|
||||||
To specify an allowed set of runlevels for a service, run command, task,
|
|
||||||
or tty, add [NNN] to it in finit.conf, like this::
|
|
||||||
|
|
||||||
run [S] /etc/init.d/acpid start -- Starting ACPI Daemon
|
|
||||||
task [S] /etc/init.d/kbd start -- Preparing console
|
|
||||||
service [S12345] /sbin/klogd -n -x -- Kernel log daemon
|
|
||||||
tty [12345] /dev/tty1
|
|
||||||
tty [2] /dev/tty2
|
|
||||||
tty [2] /dev/tty3
|
|
||||||
tty [2] /dev/tty4
|
|
||||||
tty [2] /dev/tty5
|
|
||||||
tty [2] /dev/tty6
|
|
||||||
|
|
||||||
In this example acpid is started once at bootstrap using a conventional
|
|
||||||
SysV init script. Here the run command was used, meaning the following
|
|
||||||
task command is not run until the init script has fully completed.
|
|
||||||
|
|
||||||
Tasks and services are started in parallel, while run commands are run
|
|
||||||
in the order listed and subsequent commands are not started until a run
|
|
||||||
command has completed.
|
|
||||||
|
|
||||||
Existing finit.conf files that lack runlevel setting will get a default
|
|
||||||
runlevel assigned, [234].
|
|
||||||
|
|
||||||
Switching between runlevels can be done by calling init with a single
|
|
||||||
argument, e.g., 'init 5' switches to runlevel 5.
|
|
||||||
|
|
||||||
|
|
||||||
Rebooting and Halting
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
Finit handles SIGUSR1 and SIGUSR2 for reboot and halt, and listens to
|
|
||||||
``/dev/initctl`` so standard Linux reboot and halt commands should also
|
|
||||||
work.
|
|
||||||
|
|
||||||
|
|
||||||
Building
|
|
||||||
--------
|
|
||||||
|
|
||||||
The finit build system does not employ the GNU Configure and Build System,
|
|
||||||
instead standard makefiles are used. The user is encouraged to make source
|
|
||||||
code changes, using defines and conditionally building plugins instead to
|
|
||||||
alter the behavior of finit.
|
|
||||||
|
|
||||||
The following environment variables are checked by the makefiles and control
|
|
||||||
what is built and where resulting binaries are installed.
|
|
||||||
|
|
||||||
**ROOTDIR=**
|
|
||||||
Top directory for building complete system, used in pretty printing
|
|
||||||
|
|
||||||
**VERSION=**
|
|
||||||
Defaults to the currently released version of finit, e.g., 1.3 but can
|
|
||||||
be overridden by packages to add a suffix or completely alter the version.
|
|
||||||
|
|
||||||
**CFLAGS=**
|
|
||||||
Standard CFLAGS are inherited from the build environment.
|
|
||||||
|
|
||||||
**CPPFLAGS=**
|
|
||||||
Standard CPPFLAGS are inherited from the build environment.
|
|
||||||
|
|
||||||
**LDFLAGS=**
|
|
||||||
Standard LDFLAGS are inherited from the build environment.
|
|
||||||
|
|
||||||
**LDLIBS=**
|
|
||||||
Standard LIBLIBS are inherited from the build environment.
|
|
||||||
|
|
||||||
**prefix=**
|
|
||||||
Base prefix path for all files, except ``sbinbdir`` and ``sysconfdir``.
|
|
||||||
Used in concert with the ``DESTDIR`` variable. Defaults to ``/usr``
|
|
||||||
|
|
||||||
**sbindir=**
|
|
||||||
Path to where resulting binaries should install to. Used in concert
|
|
||||||
with the ``DESTDIR`` variable. Defaults to ``/sbin``
|
|
||||||
|
|
||||||
**sysconfdir=**
|
|
||||||
Path to where finit configuration files should install to. Used in
|
|
||||||
concert with the ``DESTDIR`` variable. Defaults to ``/etc``, but is
|
|
||||||
currently unused.
|
|
||||||
|
|
||||||
**PLUGINS=**
|
|
||||||
List of stock finit plugins to build and install.
|
|
||||||
|
|
||||||
**plugindir=**
|
|
||||||
Absolute path to where finit should look for dynamically loadable plugins
|
|
||||||
at runtime. At installation prepended by ``DESTDIR`` and ``prefix``.
|
|
||||||
Defaults to ``/lib/finit/plugins``
|
|
||||||
|
|
||||||
**DESTDIR=**
|
|
||||||
Used by packagers and distributions when building a relocatable
|
|
||||||
bundle of files. Always prepended to the ``prefix`` destination
|
|
||||||
directory.
|
|
||||||
|
|
||||||
**Example**::
|
|
||||||
|
|
||||||
$ tar xfJ finit-1.3.tar.xz
|
|
||||||
$ PLUGINS="initctl.so hwclock.so" DESTDIR=/tmp/finit/dst \
|
|
||||||
make -C finit-1.3/ clean install
|
|
||||||
make: Entering directory `/home/troglobit/finit-1.3'
|
|
||||||
CC finit.o
|
|
||||||
CC conf.o
|
|
||||||
CC helpers.o
|
|
||||||
CC sig.o
|
|
||||||
CC svc.o
|
|
||||||
CC plugin.o
|
|
||||||
CC strlcpy.o
|
|
||||||
LINK finit
|
|
||||||
CC plugins/initctl.o
|
|
||||||
PLUGIN plugins/initctl.so
|
|
||||||
CC plugins/hwclock.o
|
|
||||||
PLUGIN plugins/hwclock.so
|
|
||||||
INSTALL /tmp/finit/dst/sbin/finit
|
|
||||||
INSTALL /tmp/finit/dst/lib/finit/plugins/initctl.so
|
|
||||||
INSTALL /tmp/finit/dst/lib/finit/plugins/hwclock.so
|
|
||||||
make: Leaving directory `/home/troglobit/finit-1.3'
|
|
||||||
|
|
||||||
In this example the `finit-1.3.tar.xz`_ archive is unpacked to the
|
|
||||||
user's home directory, built and installed to a temporary staging
|
|
||||||
directory. The environment variables ``DESTDIR`` and ``PLUGINS`` are
|
|
||||||
changed to suit this particular build.
|
|
||||||
|
|
||||||
|
|
||||||
Running
|
|
||||||
-------
|
|
||||||
|
|
||||||
The default install does not setup finit as the system default
|
|
||||||
``/sbin/init``, neither does it setup an initial ``/etc/finit.conf``.
|
|
||||||
|
|
||||||
It is assumed that users of finit are competent enough to either setup
|
|
||||||
finit as their default ``/sbin/init`` or alter their respective Grub,
|
|
||||||
LOADLIN, LILO, U-Boot/Barebox or RedBoot boot loader configuration to
|
|
||||||
give the kernel the following extra command line::
|
|
||||||
|
|
||||||
init=/sbin/finit
|
|
||||||
|
|
||||||
|
|
||||||
Debugging
|
|
||||||
---------
|
|
||||||
|
|
||||||
Add ``finit_debug``, or ``--debug``, to the kernel command line to
|
|
||||||
enable trace messages. A console getty is always started, see the file
|
|
||||||
``finit.h`` for more useful compile-time tweaks::
|
|
||||||
|
|
||||||
init=/sbin/finit --debug
|
|
||||||
|
|
||||||
|
|
||||||
Contact
|
|
||||||
-------
|
|
||||||
|
|
||||||
This is the continuation of the `original finit`_ by Claudio Matsuoka,
|
|
||||||
which in turn was reverse engineered from syscalls of the `EeePC
|
|
||||||
fastinit`_ -- "gaps filled with frog DNA ...". It is currently being
|
|
||||||
developed and maintained by `Joachim Nilsson`_ at `GitHub`_. Please
|
|
||||||
file bug reports, clone it, or send pull requests for bug fixes and
|
|
||||||
proposed extensions.
|
|
||||||
|
|
||||||
.. _`SysV init`: https://en.wikipedia.org/wiki/Init
|
|
||||||
.. _`Joachim Nilsson`: http://troglobit.com
|
|
||||||
.. _GitHub: http://github.com/troglobit/finit
|
|
||||||
.. _`process supervision`: https://en.wikipedia.org/wiki/Process_supervision
|
|
||||||
.. _`daemontools`: http://cr.yp.to/daemontools.html
|
|
||||||
.. _`runit`: http://smarden.org/runit/
|
|
||||||
.. _`original finit`: http://helllabs.org/finit/
|
|
||||||
.. _`EeePC fastinit`: http://wiki.eeeuser.com/boot_process:the_boot_process
|
|
||||||
.. _upstart: http://upstart.ubuntu.com/
|
|
||||||
.. _runlevels: http://en.wikipedia.org/wiki/Runlevel
|
|
||||||
.. _systemd: http://www.freedesktop.org/wiki/Software/systemd/
|
|
||||||
.. _openrc: http://www.gentoo.org/proj/en/base/openrc/
|
|
||||||
.. _`finit-1.3.tar.xz`: ftp://troglobit.com/finit/finit-1.3.tar.xz
|
|
||||||
.. |cistatus| image:: https://travis-ci.org/troglobit/finit.png?branch=master
|
|
||||||
:target: https://travis-ci.org/troglobit/finit
|
|
||||||
|
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
TODO
|
||||||
|
====
|
||||||
|
|
||||||
|
Unsorted TODO list of features and points of investigation that could be
|
||||||
|
useful for improving finit. But what is an improvement to finit? Well,
|
||||||
|
similiar to launchd, the goal of finit is to be a FAST replacement for:
|
||||||
|
|
||||||
|
* init
|
||||||
|
* inetd
|
||||||
|
* crond
|
||||||
|
* watchdogd
|
||||||
|
|
||||||
|
The main goal is to be FAST. Secondary goals are to be: small, simple
|
||||||
|
and with a very low dependency on external packages.
|
||||||
|
|
||||||
|
Inetd
|
||||||
|
-----
|
||||||
|
|
||||||
|
Simple way of running Internet services on demand, like the old inetd:
|
||||||
|
|
||||||
|
inetd SVC [RUNLVL] /path/to/daemon args -- description
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
# Inetd services, launched on demand
|
||||||
|
inetd ssh [2345] /usr/sbin/sshd -i -- SSH Daemon
|
||||||
|
|
||||||
|
In keeping with the finit tradition, an optional callback can be setup
|
||||||
|
to each inetd service. When a client connects the finit will call the
|
||||||
|
callback with a `struct in_pktinfo` argument which the callback then can
|
||||||
|
allowed or deny.
|
||||||
|
|
||||||
|
|
||||||
|
Priority
|
||||||
|
--------
|
||||||
|
|
||||||
|
The intent of finit is to monitor not just processes, but also to
|
||||||
|
be able to supervise the entire system and the behavior of certain
|
||||||
|
processes that declare themselves to be finit compliant.
|
||||||
|
|
||||||
|
* Integrate the ingenious libev to handle all events: signals, polling
|
||||||
|
fd's, etc. Because "Event driven software improves concurrency" --
|
||||||
|
Dave Zarzycki, Apple.
|
||||||
|
|
||||||
|
See the [launchd video](http://www.youtube.com/watch?v=cD_s6Fjdri8)
|
||||||
|
for more info!
|
||||||
|
|
||||||
|
* Add support for a /dev/watchdog plugin to replace watchdogd
|
||||||
|
|
||||||
|
* Integrate watchdog plugin with process/system supervisor to optionally
|
||||||
|
reboot the system when a process stops responding, or when a respawn
|
||||||
|
limit has been reached, as well as when system load gets too high.
|
||||||
|
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
-------------
|
||||||
|
|
||||||
|
* Add support for `init <q | reload-configuration>` and `SIGHUP` to
|
||||||
|
have finit reload its `finit.conf`, but also
|
||||||
|
|
||||||
|
* Add support for inotify to automatically reload `finit.conf`
|
||||||
|
|
||||||
|
|
||||||
|
Runlevels
|
||||||
|
---------
|
||||||
|
|
||||||
|
* Implement `initctl stop|start|restart|reload|status <SVC>` and
|
||||||
|
`service <SVC> stop|start|restart|reload|status` on top
|
||||||
|
|
||||||
|
* Add PRE and POST hooks for when switching between runlevels
|
||||||
|
|
||||||
|
|
||||||
|
Miscellaneous
|
||||||
|
-------------
|
||||||
|
|
||||||
|
* Add support for `init -v,--version | version`
|
||||||
|
* Cleanup move sources from top-level directory to `src/` and `include/`
|
||||||
|
* Make sure to install `queue.h` to `$(PREFIX)/include/finit/queue.h`
|
||||||
|
* Move `finit.conf` "check" command to plugin which checks `/etc/fstab`
|
||||||
|
instead. This is the de-facto practice. But keep the check command
|
||||||
|
for really low-end systems w/o `/etc/fstab`.
|
||||||
|
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
-------------
|
||||||
|
|
||||||
|
* Write man pages for finit and `finit.conf`, steal from the excellent
|
||||||
|
`pimd` man pages ...
|
||||||
|
* Update Debian `finit.conf` example with runlevels, `tty/console` and
|
||||||
|
dependency handling
|
||||||
|
|
||||||
|
|
||||||
|
Investigation
|
||||||
|
-------------
|
||||||
|
|
||||||
|
* [FHS changes](http://askubuntu.com/questions/57297/why-has-var-run-been-migrated-to-run)
|
||||||
|
affecting runtime status, plugins, etc.
|
||||||
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
==============================================================================
|
|
||||||
TODO
|
|
||||||
==============================================================================
|
|
||||||
|
|
||||||
Unsorted TODO list of features and points of investigation that could be
|
|
||||||
useful for improving finit. But what is an improvement to finit? Well,
|
|
||||||
similiar to launchd, the goal of finit is to be a FAST replacement for:
|
|
||||||
|
|
||||||
* init
|
|
||||||
* inetd
|
|
||||||
* crond
|
|
||||||
* watchdogd
|
|
||||||
|
|
||||||
The main goal is to be FAST. Secondary goals are to be: small, simple
|
|
||||||
and with a very low dependency on external packages.
|
|
||||||
|
|
||||||
Inetd
|
|
||||||
-----
|
|
||||||
Simple way of running Internet services on demand, like the old inetd::
|
|
||||||
|
|
||||||
inetd SVC [RUNLVL] /path/to/daemon args -- description
|
|
||||||
|
|
||||||
Example::
|
|
||||||
|
|
||||||
# Inetd services, launched on demand
|
|
||||||
inetd ssh [2345] /usr/sbin/sshd -i -- SSH Daemon
|
|
||||||
|
|
||||||
In keeping with the finit tradition, an optional callback can be setup
|
|
||||||
to each inetd service. When a client connects the finit will call the
|
|
||||||
callback with a `struct in_pktinfo` argument which the callback then can
|
|
||||||
allowed or deny.
|
|
||||||
|
|
||||||
|
|
||||||
Priority
|
|
||||||
--------
|
|
||||||
The intent of finit is to monitor not just processes, but also to
|
|
||||||
be able to supervise the entire system and the behavior of certain
|
|
||||||
processes that declare themselves to be finit compliant.
|
|
||||||
|
|
||||||
* Integrate the ingenious libev to handle all events: signals, polling
|
|
||||||
fd's, etc. Because "Event driven software improves concurrency" --
|
|
||||||
Dave Zarzycki, Apple. See the `launchd video`_ for more info!
|
|
||||||
* Add support for a /dev/watchdog plugin to replace watchdogd
|
|
||||||
* Integrate watchdog plugin with process/system supervisor to optionally
|
|
||||||
reboot the system when a process stops responding, or when a respawn
|
|
||||||
limit has been reached, as well as when system load gets too high.
|
|
||||||
|
|
||||||
|
|
||||||
Configuration
|
|
||||||
-------------
|
|
||||||
* Add support for "init <q | reload-configuration>" and SIGHUP to
|
|
||||||
reload finit.conf, but also
|
|
||||||
* Add support for inotify to automatically reload finit.conf
|
|
||||||
|
|
||||||
|
|
||||||
Runlevels
|
|
||||||
---------
|
|
||||||
* Add support for "runlevel N" to finit.conf
|
|
||||||
* Improve support for runlevels: startup, running (services from
|
|
||||||
finit.conf), and shutdown as well as hooks when switching RL, startup
|
|
||||||
at RL 1 and a default run level.
|
|
||||||
* Implement initctl stop|start|restart|reload|status <SVC> and service
|
|
||||||
<SVC> stop|start|restart|reload|status on top
|
|
||||||
* Add PRE and POST hooks for when changing runlevels
|
|
||||||
* SysV init in Debian uses an rcS.d/ for scripts that should run once at
|
|
||||||
boot. These scripts are run before the actual runlevel, which is set
|
|
||||||
in inittab. We could use "task [S]" and "run [S]" (below) for this.
|
|
||||||
* Add support for a new runlevel 'S' that is started before all other
|
|
||||||
services in the selected runlevel.
|
|
||||||
|
|
||||||
|
|
||||||
Services and Tasks
|
|
||||||
------------------
|
|
||||||
Both the "task" and "boot" stanzas below are like "service", share the
|
|
||||||
same mechanism for registering callbacks. These callbacks can be used
|
|
||||||
to check a configuration db and return 1 (RUN), 2 (STOP), or 3 (RELOAD).
|
|
||||||
|
|
||||||
* Add support for "task [RUNLVL] ..." similar to services, but one-shot.
|
|
||||||
* Add support for "run [RUNLVL] ..." similar to task, but waits for
|
|
||||||
completion before continuing with the next task/service
|
|
||||||
* Add support for service/task/run dependencies
|
|
||||||
* Add support for "init list" to show running services
|
|
||||||
|
|
||||||
It is tempting to say that a task called at runlevel S would be a
|
|
||||||
blocking call, like run, but there are likely use-cases when you want to
|
|
||||||
call on-shot tasks in parallell with something else, even at boot. Hence
|
|
||||||
the differentiation between "task" and "run", which are essentially the
|
|
||||||
same, except for the "pause and wait for completion" that "run" has.
|
|
||||||
|
|
||||||
|
|
||||||
Miscellaneous
|
|
||||||
-------------
|
|
||||||
* Add support for "init -v,--version | version"
|
|
||||||
* Cleanup move sources from top-level directory to src/ and include/
|
|
||||||
* Make sure to install queue.h to $(PREFIX)/include/finit/queue.h
|
|
||||||
* Move finit.conf "check" command to plugin which checks /etc/fstab
|
|
||||||
instead. This is the de-facto practise. But keep the check command
|
|
||||||
for really low-end systems w/o /etc/fstab.
|
|
||||||
|
|
||||||
|
|
||||||
Documentation
|
|
||||||
-------------
|
|
||||||
* Write man pages for finit and finit.conf, steal from pimd man pages...
|
|
||||||
* Update Debian finit.conf example with runlevels, tty/console and
|
|
||||||
dependency handling
|
|
||||||
|
|
||||||
|
|
||||||
Investigation
|
|
||||||
-------------
|
|
||||||
* `FHS changes`_ affecting runtime status, plugins, etc.
|
|
||||||
|
|
||||||
.. _`launchd video`: http://www.youtube.com/watch?v=cD_s6Fjdri8
|
|
||||||
.. _`FHS changes`: http://askubuntu.com/questions/57297/why-has-var-run-been-migrated-to-run
|
|
||||||
..
|
|
||||||
.. Local Variables:
|
|
||||||
.. mode: rst
|
|
||||||
.. version-control: t
|
|
||||||
.. End:
|
|
||||||
@@ -181,8 +181,8 @@ int main(int argc, char* argv[])
|
|||||||
mount("none", "/proc", "proc", 0, NULL);
|
mount("none", "/proc", "proc", 0, NULL);
|
||||||
mount("none", "/proc/bus/usb", "usbfs", 0, NULL);
|
mount("none", "/proc/bus/usb", "usbfs", 0, NULL);
|
||||||
mount("none", "/sys", "sysfs", 0, NULL);
|
mount("none", "/sys", "sysfs", 0, NULL);
|
||||||
mkdir("/dev/pts", 0755);
|
makedir("/dev/pts", 0755);
|
||||||
mkdir("/dev/shm", 0755);
|
makedir("/dev/shm", 0755);
|
||||||
mount("none", "/dev/pts", "devpts", 0, "gid=5,mode=620");
|
mount("none", "/dev/pts", "devpts", 0, "gid=5,mode=620");
|
||||||
mount("none", "/dev/shm", "tmpfs", 0, NULL);
|
mount("none", "/dev/shm", "tmpfs", 0, NULL);
|
||||||
umask(022);
|
umask(022);
|
||||||
@@ -250,7 +250,7 @@ int main(int argc, char* argv[])
|
|||||||
run("/sbin/sysctl -e -p /etc/sysctl.conf >/dev/null");
|
run("/sbin/sysctl -e -p /etc/sysctl.conf >/dev/null");
|
||||||
|
|
||||||
/* Set initial hostname. */
|
/* Set initial hostname. */
|
||||||
set_hostname(hostname);
|
set_hostname(&hostname);
|
||||||
|
|
||||||
ifconfig("lo", "127.0.0.1", "255.0.0.0", 1);
|
ifconfig("lo", "127.0.0.1", "255.0.0.0", 1);
|
||||||
if (network)
|
if (network)
|
||||||
|
|||||||
@@ -131,31 +131,31 @@ void ifconfig(char *ifname, char *addr, char *mask, int up)
|
|||||||
*/
|
*/
|
||||||
pid_t pidfile_read(char *pidfile)
|
pid_t pidfile_read(char *pidfile)
|
||||||
{
|
{
|
||||||
pid_t pid = 0;
|
pid_t pid = 0;
|
||||||
char buf[16];
|
char buf[16];
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
if (!pidfile) {
|
if (!pidfile) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fexist(pidfile))
|
if (!fexist(pidfile))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
fp = fopen(pidfile, "r");
|
fp = fopen(pidfile, "r");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (fgets(buf, sizeof(buf), fp)) {
|
if (fgets(buf, sizeof(buf), fp)) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
pid = strtoul(buf, NULL, 0);
|
pid = (pid_t)strtol(buf, NULL, 10);
|
||||||
if (errno)
|
if (errno)
|
||||||
pid = 0; /* Failed conversion. */
|
pid = 0; /* Failed conversion. */
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -270,12 +270,15 @@ int procname_kill(char *name, int signo)
|
|||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
|
|
||||||
dir = opendir("/proc");
|
if (!name) {
|
||||||
if (!dir || !name) {
|
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dir = opendir("/proc");
|
||||||
|
if (!dir)
|
||||||
|
return 0;
|
||||||
|
|
||||||
while ((entry = readdir(dir)) != NULL) {
|
while ((entry = readdir(dir)) != NULL) {
|
||||||
/* Skip non-process entries in /proc */
|
/* Skip non-process entries in /proc */
|
||||||
if (!isdigit(*entry->d_name))
|
if (!isdigit(*entry->d_name))
|
||||||
@@ -404,7 +407,6 @@ int complete(char *cmd, int pid)
|
|||||||
int run(char *cmd)
|
int run(char *cmd)
|
||||||
{
|
{
|
||||||
int status, result, i = 0;
|
int status, result, i = 0;
|
||||||
FILE *fp;
|
|
||||||
char *args[NUM_ARGS + 1], *arg, *backup;
|
char *args[NUM_ARGS + 1], *arg, *backup;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
@@ -444,17 +446,18 @@ int run(char *cmd)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fp = fopen("/dev/null", "w");
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if (0 == pid) {
|
if (0 == pid) {
|
||||||
int i;
|
int i;
|
||||||
|
FILE *fp;
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
|
|
||||||
/* Reset signal handlers that were set by the parent process */
|
/* Reset signal handlers that were set by the parent process */
|
||||||
for (i = 1; i < NSIG; i++)
|
for (i = 1; i < NSIG; i++)
|
||||||
DFLSIG(sa, i, 0);
|
DFLSIG(sa, i, 0);
|
||||||
|
|
||||||
/* Redirect stdio if the caller requested so. */
|
/* Always redirect stdio for run() */
|
||||||
|
fp = fopen("/dev/null", "w");
|
||||||
if (fp) {
|
if (fp) {
|
||||||
int fd = fileno(fp);
|
int fd = fileno(fp);
|
||||||
|
|
||||||
@@ -467,14 +470,14 @@ int run(char *cmd)
|
|||||||
_exit(1); /* Only if execv() fails. */
|
_exit(1); /* Only if execv() fails. */
|
||||||
} else if (-1 == pid) {
|
} else if (-1 == pid) {
|
||||||
_pe("%s", args[0]);
|
_pe("%s", args[0]);
|
||||||
|
free(backup);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = complete(args[0], pid);
|
status = complete(args[0], pid);
|
||||||
if (-1 == status) {
|
if (-1 == status) {
|
||||||
if (fp) fclose(fp);
|
|
||||||
free(backup);
|
free(backup);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,7 +492,6 @@ int run(char *cmd)
|
|||||||
* change their return code accordingly. --Jocke */
|
* change their return code accordingly. --Jocke */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fp) fclose(fp);
|
|
||||||
free(backup);
|
free(backup);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -500,27 +502,49 @@ int run_interactive(char *cmd, char *fmt, ...)
|
|||||||
int status, oldout = 1, olderr = 2;
|
int status, oldout = 1, olderr = 2;
|
||||||
char line[LINE_SIZE];
|
char line[LINE_SIZE];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
FILE *fp = tmpfile();
|
FILE *fp;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
if (!cmd) {
|
||||||
vsnprintf(line, sizeof(line), fmt, ap);
|
errno = EINVAL;
|
||||||
va_end(ap);
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fmt) {
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vsnprintf(line, sizeof(line), fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
if (fmt)
|
|
||||||
print_desc("", line);
|
print_desc("", line);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Redirect output from cmd to a tempfile */
|
||||||
|
fp = tmpfile();
|
||||||
if (fp && !debug) {
|
if (fp && !debug) {
|
||||||
oldout = dup(STDOUT_FILENO);
|
oldout = dup(STDOUT_FILENO);
|
||||||
olderr = dup(STDERR_FILENO);
|
olderr = dup(STDERR_FILENO);
|
||||||
dup2(fileno(fp), STDOUT_FILENO);
|
dup2(fileno(fp), STDOUT_FILENO);
|
||||||
dup2(fileno(fp), STDERR_FILENO);
|
dup2(fileno(fp), STDERR_FILENO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Run cmd ... */
|
||||||
status = run(cmd);
|
status = run(cmd);
|
||||||
|
|
||||||
|
/* Restore stderr/stdout */
|
||||||
if (fp && !debug) {
|
if (fp && !debug) {
|
||||||
dup2(oldout, STDOUT_FILENO);
|
if (oldout >= 0) {
|
||||||
dup2(olderr, STDERR_FILENO);
|
dup2(oldout, STDOUT_FILENO);
|
||||||
|
close(oldout);
|
||||||
|
}
|
||||||
|
if (olderr >= 0) {
|
||||||
|
dup2(olderr, STDERR_FILENO);
|
||||||
|
close(olderr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fmt)
|
if (fmt)
|
||||||
print_result(status);
|
print_result(status);
|
||||||
|
|
||||||
|
/* Dump any results of cmd on stderr after we've printed [ OK ] or [FAIL] */
|
||||||
if (fp && !debug) {
|
if (fp && !debug) {
|
||||||
size_t len, written;
|
size_t len, written;
|
||||||
|
|
||||||
@@ -529,9 +553,11 @@ int run_interactive(char *cmd, char *fmt, ...)
|
|||||||
len = fread(line, 1, sizeof(line), fp);
|
len = fread(line, 1, sizeof(line), fp);
|
||||||
written = fwrite(line, len, sizeof(char), stderr);
|
written = fwrite(line, len, sizeof(char), stderr);
|
||||||
} while (len > 0 && written == len);
|
} while (len > 0 && written == len);
|
||||||
fclose(fp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fp)
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,7 +607,7 @@ pid_t run_getty(char *cmd, char *args[], int console)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (console) {
|
if (console) {
|
||||||
i = write(STDERR_FILENO, msg, sizeof(msg));
|
(void)write(STDERR_FILENO, msg, sizeof(msg));
|
||||||
while (read(STDIN_FILENO, &c, 1) == 1 && c != '\n')
|
while (read(STDIN_FILENO, &c, 1) == 1 && c != '\n')
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -698,26 +724,33 @@ void do_sleep(unsigned int sec)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_hostname(char *hostname)
|
void set_hostname(char **hostname)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
_d("Set hostname: %s", hostname);
|
_d("Set hostname: %s", *hostname);
|
||||||
if ((fp = fopen("/etc/hostname", "r")) != NULL) {
|
fp = fopen("/etc/hostname", "r");
|
||||||
|
if (fp) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
fstat(fileno(fp), &st);
|
if (fstat(fileno(fp), &st)) {
|
||||||
hostname = realloc(hostname, st.st_size);
|
fclose(fp);
|
||||||
if (!hostname)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fgets(hostname, st.st_size, fp);
|
*hostname = realloc(*hostname, st.st_size);
|
||||||
chomp(hostname);
|
if (!*hostname) {
|
||||||
|
fclose(fp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fgets(*hostname, st.st_size, fp);
|
||||||
|
chomp(*hostname);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hostname)
|
if (*hostname)
|
||||||
sethostname(hostname, strlen(hostname));
|
sethostname(*hostname, strlen(*hostname));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -42,7 +42,16 @@
|
|||||||
|
|
||||||
|
|
||||||
#ifndef touch
|
#ifndef touch
|
||||||
# define touch(x) mknod((x), S_IFREG|0644, 0)
|
# define touch(x) do { if (mknod((x), S_IFREG|0644, 0) && errno != EEXIST) _pe("Failed creating %s", x); } while (0)
|
||||||
|
#endif
|
||||||
|
#ifndef makedir
|
||||||
|
# define makedir(x, p) do { if (mkdir(x, p) && errno != EEXIST) _pe("Failed creating directory %s", x); } while (0)
|
||||||
|
#endif
|
||||||
|
#ifndef makefifo
|
||||||
|
# define makefifo(x, p) do { if (mkfifo(x, p) && errno != EEXIST) _pe("Failed creating FIFO %s", x); } while (0)
|
||||||
|
#endif
|
||||||
|
#ifndef erase
|
||||||
|
# define erase(x) do { if (remove(x) && errno != ENOENT) _pe("Failed removing %s", x); } while (0)
|
||||||
#endif
|
#endif
|
||||||
#ifndef chardev
|
#ifndef chardev
|
||||||
# define chardev(x,m,maj,min) mknod((x), S_IFCHR|(m), makedev((maj),(min)))
|
# define chardev(x,m,maj,min) mknod((x), S_IFCHR|(m), makedev((maj),(min)))
|
||||||
@@ -101,7 +110,7 @@ void chomp (char *str);
|
|||||||
void do_sleep (unsigned int sec);
|
void do_sleep (unsigned int sec);
|
||||||
int getuser (char *username);
|
int getuser (char *username);
|
||||||
int getgroup (char *group);
|
int getgroup (char *group);
|
||||||
void set_hostname (char *hostname);
|
void set_hostname (char **hostname);
|
||||||
|
|
||||||
int complete (char *cmd, int pid);
|
int complete (char *cmd, int pid);
|
||||||
int run (char *cmd);
|
int run (char *cmd);
|
||||||
|
|||||||
+2
-2
@@ -344,7 +344,7 @@ int main(void)
|
|||||||
if (fexist(files[i + 2]))
|
if (fexist(files[i + 2]))
|
||||||
fprintf(stderr, "OK => %s\n", files[i + 2]);
|
fprintf(stderr, "OK => %s\n", files[i + 2]);
|
||||||
|
|
||||||
remove(files[i + 2]);
|
erase(files[i + 2]);
|
||||||
i += 3;
|
i += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,7 +358,7 @@ int main(void)
|
|||||||
if (fexist(files[i + 2]))
|
if (fexist(files[i + 2]))
|
||||||
fprintf(stderr, "OK => %s\n", files[i + 2]);
|
fprintf(stderr, "OK => %s\n", files[i + 2]);
|
||||||
|
|
||||||
remove(files[i + 2]);
|
erase(files[i + 2]);
|
||||||
i += 3;
|
i += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -142,13 +142,13 @@ int simulate_files(int creat)
|
|||||||
if (creat)
|
if (creat)
|
||||||
touch(files[i]);
|
touch(files[i]);
|
||||||
else
|
else
|
||||||
remove(files[i]);
|
erase(files[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (creat)
|
if (creat)
|
||||||
symlink("config2.cfg", STARTUP_CONFIG);
|
symlink("config2.cfg", STARTUP_CONFIG);
|
||||||
else
|
else
|
||||||
remove(STARTUP_CONFIG);
|
erase(STARTUP_CONFIG);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-19
@@ -27,7 +27,8 @@
|
|||||||
#include "lite.h"
|
#include "lite.h"
|
||||||
#include "../helpers.h"
|
#include "../helpers.h"
|
||||||
|
|
||||||
static int makedir(char *buf, size_t buf_len, char *dir, char *name, mode_t mode);
|
static int copy(char *src, char *dst);
|
||||||
|
static int mdir(char *buf, size_t buf_len, char *dir, char *name, mode_t mode);
|
||||||
static int prune(char *dst, char **new_files, int new_num);
|
static int prune(char *dst, char **new_files, int new_num);
|
||||||
|
|
||||||
|
|
||||||
@@ -58,26 +59,16 @@ int rsync(char *src, char *dst, int delete, int (*filter) (const char *file))
|
|||||||
int i = 0, num = 0, result = 0;
|
int i = 0, num = 0, result = 0;
|
||||||
char **files; /* Array of file names. */
|
char **files; /* Array of file names. */
|
||||||
|
|
||||||
void copy(char *src, char *dst)
|
|
||||||
{
|
|
||||||
errno = 0;
|
|
||||||
copyfile(src, dst, 0, 1);
|
|
||||||
if (errno) {
|
|
||||||
if (errno == EEXIST)
|
|
||||||
errno = 0;
|
|
||||||
else
|
|
||||||
result++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fisdir(dst))
|
if (!fisdir(dst))
|
||||||
mkdir(dst, 0755);
|
makedir(dst, 0755);
|
||||||
|
|
||||||
if (!fisdir(src)) {
|
if (!fisdir(src)) {
|
||||||
if (!fexist(src))
|
if (!fexist(src))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
copy(src, dst);
|
if (copy(src, dst))
|
||||||
|
result++;
|
||||||
|
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +81,7 @@ int rsync(char *src, char *dst, int delete, int (*filter) (const char *file))
|
|||||||
else
|
else
|
||||||
ptr++;
|
ptr++;
|
||||||
|
|
||||||
if (makedir(dest, sizeof(dest), dst, ptr, fmode(src)))
|
if (mdir(dest, sizeof(dest), dst, ptr, fmode(src)))
|
||||||
return 1;
|
return 1;
|
||||||
dst = dest;
|
dst = dest;
|
||||||
}
|
}
|
||||||
@@ -103,7 +94,7 @@ int rsync(char *src, char *dst, int delete, int (*filter) (const char *file))
|
|||||||
char dst2[256];
|
char dst2[256];
|
||||||
|
|
||||||
strcat(source, "/");
|
strcat(source, "/");
|
||||||
if (makedir (dst2, sizeof(dst2), dst, files[i], fmode(source))) {
|
if (mdir (dst2, sizeof(dst2), dst, files[i], fmode(source))) {
|
||||||
result++;
|
result++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -111,7 +102,9 @@ int rsync(char *src, char *dst, int delete, int (*filter) (const char *file))
|
|||||||
rsync(source, dst2, delete, filter);
|
rsync(source, dst2, delete, filter);
|
||||||
continue; /* Next file/dir in @src to copy... */
|
continue; /* Next file/dir in @src to copy... */
|
||||||
}
|
}
|
||||||
copy(source, dst);
|
|
||||||
|
if (copy(source, dst))
|
||||||
|
result++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We ignore any errors from the pruning, that phase albeit useful is only
|
/* We ignore any errors from the pruning, that phase albeit useful is only
|
||||||
@@ -128,8 +121,23 @@ int rsync(char *src, char *dst, int delete, int (*filter) (const char *file))
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int copy(char *src, char *dst)
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
copyfile(src, dst, 0, 1);
|
||||||
|
if (errno) {
|
||||||
|
if (errno != EEXIST)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Creates dir/name @mode ... skipping / if dir already ends so. */
|
/* Creates dir/name @mode ... skipping / if dir already ends so. */
|
||||||
static int makedir(char *buf, size_t buf_len, char *dir, char *name, mode_t mode)
|
static int mdir(char *buf, size_t buf_len, char *dir, char *name, mode_t mode)
|
||||||
{
|
{
|
||||||
snprintf(buf, buf_len, "%s%s%s/", dir, fisslashdir(dir) ? "" : "/", name);
|
snprintf(buf, buf_len, "%s%s%s/", dir, fisslashdir(dir) ? "" : "/", name);
|
||||||
if (mkdir(buf, mode)) {
|
if (mkdir(buf, mode)) {
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ plugin_t *plugin_find(char *name)
|
|||||||
|
|
||||||
SEARCH_PLUGIN(name);
|
SEARCH_PLUGIN(name);
|
||||||
|
|
||||||
if (name[0] != '/') {
|
if (plugpath && name[0] != '/') {
|
||||||
int noext;
|
int noext;
|
||||||
char path[CMD_SIZE];
|
char path[CMD_SIZE];
|
||||||
|
|
||||||
@@ -280,6 +280,9 @@ static int load_one(char *path, char *name)
|
|||||||
snprintf(plugin, sizeof(plugin), "%s/%s%s", path, name, noext ? ".so" : "");
|
snprintf(plugin, sizeof(plugin), "%s/%s%s", path, name, noext ? ".so" : "");
|
||||||
|
|
||||||
_d("Loading plugin %s ...", basename(plugin));
|
_d("Loading plugin %s ...", basename(plugin));
|
||||||
|
/* Ignore leak, we do not support unloading of plugins atm.
|
||||||
|
* TODO: Add handle to list of loaded plugins, dlclose() on
|
||||||
|
* plugin_unregister() */
|
||||||
handle = dlopen(plugin, RTLD_LAZY | RTLD_GLOBAL);
|
handle = dlopen(plugin, RTLD_LAZY | RTLD_GLOBAL);
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
_e("Failed loading plugin %s: %s", plugin, dlerror());
|
_e("Failed loading plugin %s: %s", plugin, dlerror());
|
||||||
|
|||||||
+21
-22
@@ -39,25 +39,24 @@ static void setup(void *UNUSED(arg))
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
_d("Setting up FHS structure in /var ...");
|
_d("Setting up FHS structure in /var ...");
|
||||||
mkdir("/var/cache", 0755);
|
makedir("/var/cache", 0755);
|
||||||
mkdir("/var/games", 0755);
|
makedir("/var/games", 0755);
|
||||||
mkdir("/var/lib", 0755);
|
makedir("/var/lib", 0755);
|
||||||
mkdir("/var/lib/misc", 0755);
|
makedir("/var/lib/misc", 0755);
|
||||||
mkdir("/var/lib/alarm", 0755);
|
makedir("/var/lib/alarm", 0755);
|
||||||
mkdir("/var/lock", 0755);
|
makedir("/var/lock", 0755);
|
||||||
mkdir("/var/log", 0755);
|
makedir("/var/log", 0755);
|
||||||
mkdir("/var/mail", 0755);
|
makedir("/var/mail", 0755);
|
||||||
mkdir("/var/opt", 0755);
|
makedir("/var/opt", 0755);
|
||||||
mkdir("/var/run", 0755);
|
makedir("/var/run", 0755);
|
||||||
mkdir("/var/spool", 0755);
|
makedir("/var/spool", 0755);
|
||||||
mkdir("/var/spool/cron", 0755);
|
makedir("/var/spool/cron", 0755);
|
||||||
mkdir("/var/tmp", 0755);
|
makedir("/var/tmp", 0755);
|
||||||
mkdir("/var/empty", 0755);
|
makedir("/var/empty", 0755);
|
||||||
|
|
||||||
_d("Setting up necessary UTMP files ...");
|
_d("Setting up necessary UTMP files ...");
|
||||||
touch("/var/run/utmp");
|
touch("/var/run/utmp");
|
||||||
chown("/var/run/utmp", 0, getgroup("utmp"));
|
chown("/var/run/utmp", 0, getgroup("utmp"));
|
||||||
chmod("/var/run/utmp", 0664);
|
|
||||||
|
|
||||||
#ifdef RUNLEVEL
|
#ifdef RUNLEVEL
|
||||||
memset(&entry, 0, sizeof(struct utmp));
|
memset(&entry, 0, sizeof(struct utmp));
|
||||||
@@ -71,16 +70,16 @@ static void setup(void *UNUSED(arg))
|
|||||||
#ifdef TOUCH_ETC_NETWORK_RUN_IFSTATE
|
#ifdef TOUCH_ETC_NETWORK_RUN_IFSTATE
|
||||||
touch("/etc/network/run/ifstate");
|
touch("/etc/network/run/ifstate");
|
||||||
#else
|
#else
|
||||||
remove("/etc/network/run/ifstate");
|
erase("/etc/network/run/ifstate");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_d("Setting up misc files ...");
|
_d("Setting up misc files ...");
|
||||||
mkdir("/var/run/lldpd", 0755); /* Needed by lldpd */
|
makedir("/var/run/lldpd", 0755); /* Needed by lldpd */
|
||||||
mkdir("/var/run/pluto", 0755); /* Needed by Openswan */
|
makedir("/var/run/pluto", 0755); /* Needed by Openswan */
|
||||||
mkdir("/var/run/quagga", 0755); /* Needed by Quagga */
|
makedir("/var/run/quagga", 0755); /* Needed by Quagga */
|
||||||
mkdir("/var/log/quagga", 0755); /* Needed by Quagga */
|
makedir("/var/log/quagga", 0755); /* Needed by Quagga */
|
||||||
mkdir("/var/run/sshd", 01755); /* OpenSSH */
|
makedir("/var/run/sshd", 01755); /* OpenSSH */
|
||||||
mkfifo("/dev/xconsole", 0640); /* sysklogd */
|
makefifo("/dev/xconsole", 0640); /* sysklogd */
|
||||||
chown("/dev/xconsole", 0, getgroup("tty"));
|
chown("/dev/xconsole", 0, getgroup("tty"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -29,10 +29,10 @@ static void setup(void *UNUSED(arg))
|
|||||||
{
|
{
|
||||||
#ifdef HAVE_DBUS
|
#ifdef HAVE_DBUS
|
||||||
_d("Starting D-Bus ...");
|
_d("Starting D-Bus ...");
|
||||||
mkdir("/var/run/dbus", 0755);
|
makedir("/var/run/dbus", 0755);
|
||||||
mkdir("/var/lock/subsys/messagebus", 0755);
|
makedir("/var/lock/subsys/messagebus", 0755);
|
||||||
run("dbus-uuidgen --ensure");
|
run("dbus-uuidgen --ensure");
|
||||||
remove("/var/run/dbus/pid");
|
erase("/var/run/dbus/pid");
|
||||||
run_interactive("dbus-daemon --system", "Starting D-Bus");
|
run_interactive("dbus-daemon --system", "Starting D-Bus");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -124,7 +124,7 @@ static void parse(void *UNUSED(arg), int fd, int UNUSED(events))
|
|||||||
PLUGIN_INIT(plugin_init)
|
PLUGIN_INIT(plugin_init)
|
||||||
{
|
{
|
||||||
_d("Setting up %s", FINIT_FIFO);
|
_d("Setting up %s", FINIT_FIFO);
|
||||||
mkfifo(FINIT_FIFO, 0600);
|
makefifo(FINIT_FIFO, 0600);
|
||||||
|
|
||||||
fifo_open();
|
fifo_open();
|
||||||
plugin_register(&plugin);
|
plugin_register(&plugin);
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ static void setup(void *UNUSED(arg))
|
|||||||
#endif
|
#endif
|
||||||
char line[LINE_SIZE];
|
char line[LINE_SIZE];
|
||||||
|
|
||||||
makepath("/var/run/console");
|
makedir("/var/run/console", 01777);
|
||||||
snprintf(line, sizeof(line), "/var/run/console/%s", username);
|
snprintf(line, sizeof(line), "/var/run/console/%s", username);
|
||||||
touch(line);
|
touch(line);
|
||||||
|
|
||||||
@@ -48,8 +48,8 @@ static void setup(void *UNUSED(arg))
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mkdir("/tmp/.X11-unix", 01777);
|
makedir("/tmp/.X11-unix", 01777);
|
||||||
mkdir("/tmp/.ICE-unix", 01777);
|
makedir("/tmp/.ICE-unix", 01777);
|
||||||
}
|
}
|
||||||
|
|
||||||
static plugin_t plugin = {
|
static plugin_t plugin = {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: queue.h,v 1.36 2012/04/11 13:29:14 naddy Exp $ */
|
/* $OpenBSD: queue.h,v 1.38 2013/07/03 15:05:21 fgsch Exp $ */
|
||||||
/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
|
/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -316,6 +316,86 @@ struct { \
|
|||||||
(head)->sqh_last = &(elm)->field.sqe_next; \
|
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XOR Simple queue definitions.
|
||||||
|
*/
|
||||||
|
#define XSIMPLEQ_HEAD(name, type) \
|
||||||
|
struct name { \
|
||||||
|
struct type *sqx_first; /* first element */ \
|
||||||
|
struct type **sqx_last; /* addr of last next element */ \
|
||||||
|
unsigned long sqx_cookie; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define XSIMPLEQ_ENTRY(type) \
|
||||||
|
struct { \
|
||||||
|
struct type *sqx_next; /* next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XOR Simple queue access methods.
|
||||||
|
*/
|
||||||
|
#define XSIMPLEQ_XOR(head, ptr) ((__typeof(ptr))((head)->sqx_cookie ^ \
|
||||||
|
(unsigned long)(ptr)))
|
||||||
|
#define XSIMPLEQ_FIRST(head) XSIMPLEQ_XOR(head, ((head)->sqx_first))
|
||||||
|
#define XSIMPLEQ_END(head) NULL
|
||||||
|
#define XSIMPLEQ_EMPTY(head) (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head))
|
||||||
|
#define XSIMPLEQ_NEXT(head, elm, field) XSIMPLEQ_XOR(head, ((elm)->field.sqx_next))
|
||||||
|
|
||||||
|
|
||||||
|
#define XSIMPLEQ_FOREACH(var, head, field) \
|
||||||
|
for ((var) = XSIMPLEQ_FIRST(head); \
|
||||||
|
(var) != XSIMPLEQ_END(head); \
|
||||||
|
(var) = XSIMPLEQ_NEXT(head, var, field))
|
||||||
|
|
||||||
|
#define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
|
||||||
|
for ((var) = XSIMPLEQ_FIRST(head); \
|
||||||
|
(var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \
|
||||||
|
(var) = (tvar))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XOR Simple queue functions.
|
||||||
|
*/
|
||||||
|
#define XSIMPLEQ_INIT(head) do { \
|
||||||
|
arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \
|
||||||
|
(head)->sqx_first = XSIMPLEQ_XOR(head, NULL); \
|
||||||
|
(head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do { \
|
||||||
|
if (((elm)->field.sqx_next = (head)->sqx_first) == \
|
||||||
|
XSIMPLEQ_XOR(head, NULL)) \
|
||||||
|
(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
|
||||||
|
(head)->sqx_first = XSIMPLEQ_XOR(head, (elm)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do { \
|
||||||
|
(elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL); \
|
||||||
|
*(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \
|
||||||
|
(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||||
|
if (((elm)->field.sqx_next = (listelm)->field.sqx_next) == \
|
||||||
|
XSIMPLEQ_XOR(head, NULL)) \
|
||||||
|
(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
|
||||||
|
(listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define XSIMPLEQ_REMOVE_HEAD(head, field) do { \
|
||||||
|
if (((head)->sqx_first = XSIMPLEQ_XOR(head, \
|
||||||
|
(head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \
|
||||||
|
(head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
|
||||||
|
if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head, \
|
||||||
|
(elm)->field.sqx_next)->field.sqx_next) \
|
||||||
|
== XSIMPLEQ_XOR(head, NULL)) \
|
||||||
|
(head)->sqx_last = \
|
||||||
|
XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tail queue definitions.
|
* Tail queue definitions.
|
||||||
*/
|
*/
|
||||||
@@ -553,12 +633,12 @@ struct { \
|
|||||||
#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
|
#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
|
||||||
if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
|
if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
|
||||||
CIRCLEQ_END(head)) \
|
CIRCLEQ_END(head)) \
|
||||||
(head).cqh_last = (elm2); \
|
(head)->cqh_last = (elm2); \
|
||||||
else \
|
else \
|
||||||
(elm2)->field.cqe_next->field.cqe_prev = (elm2); \
|
(elm2)->field.cqe_next->field.cqe_prev = (elm2); \
|
||||||
if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
|
if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
|
||||||
CIRCLEQ_END(head)) \
|
CIRCLEQ_END(head)) \
|
||||||
(head).cqh_first = (elm2); \
|
(head)->cqh_first = (elm2); \
|
||||||
else \
|
else \
|
||||||
(elm2)->field.cqe_prev->field.cqe_next = (elm2); \
|
(elm2)->field.cqe_prev->field.cqe_next = (elm2); \
|
||||||
_Q_INVALIDATE((elm)->field.cqe_prev); \
|
_Q_INVALIDATE((elm)->field.cqe_prev); \
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ static void sigcont_handler(int sig, siginfo_t *info, void *UNUSED(ctx))
|
|||||||
_d("Received SIGCONT(%d) from %s (PID %d)",
|
_d("Received SIGCONT(%d) from %s (PID %d)",
|
||||||
sig, pid_get_name(info->si_pid, NULL, 0), info->si_pid);
|
sig, pid_get_name(info->si_pid, NULL, 0), info->si_pid);
|
||||||
stopped = 0;
|
stopped = 0;
|
||||||
remove(SYNC_STOPPED);
|
erase(SYNC_STOPPED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -152,8 +152,8 @@ void sig_setup(void)
|
|||||||
_d("Setup signals");
|
_d("Setup signals");
|
||||||
|
|
||||||
/* Cleanup any stale finit control files */
|
/* Cleanup any stale finit control files */
|
||||||
remove(SYNC_SHUTDOWN);
|
erase(SYNC_SHUTDOWN);
|
||||||
remove(SYNC_STOPPED);
|
erase(SYNC_STOPPED);
|
||||||
|
|
||||||
/* Standard SysV init calls ctrl-alt-delete handler */
|
/* Standard SysV init calls ctrl-alt-delete handler */
|
||||||
SETSIG(sa, SIGINT, shutdown_handler, 0);
|
SETSIG(sa, SIGINT, shutdown_handler, 0);
|
||||||
|
|||||||
@@ -143,16 +143,18 @@ void svc_bootstrap(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int encode(int lvl)
|
||||||
|
{
|
||||||
|
if (!lvl)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return lvl + '0';
|
||||||
|
}
|
||||||
|
|
||||||
static void utmp_save(int pre, int now)
|
static void utmp_save(int pre, int now)
|
||||||
{
|
{
|
||||||
struct utmp utent;
|
struct utmp utent;
|
||||||
|
|
||||||
int encode(int lvl)
|
|
||||||
{
|
|
||||||
if (!lvl) return 0;
|
|
||||||
return lvl + '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
utent.ut_type = RUN_LVL;
|
utent.ut_type = RUN_LVL;
|
||||||
utent.ut_pid = (encode(pre) << 8) | (encode(now) & 0xFF);
|
utent.ut_pid = (encode(pre) << 8) | (encode(now) & 0xFF);
|
||||||
strlcpy(utent.ut_user, "runlevel", sizeof(utent.ut_user));
|
strlcpy(utent.ut_user, "runlevel", sizeof(utent.ut_user));
|
||||||
@@ -209,7 +211,7 @@ void svc_runlevel(int newlevel)
|
|||||||
if (runlevel == 1)
|
if (runlevel == 1)
|
||||||
touch("/etc/nologin"); /* Disable login in single-user mode */
|
touch("/etc/nologin"); /* Disable login in single-user mode */
|
||||||
else
|
else
|
||||||
remove("/etc/nologin");
|
erase("/etc/nologin");
|
||||||
|
|
||||||
if (0 != prevlevel)
|
if (0 != prevlevel)
|
||||||
tty_runlevel(runlevel);
|
tty_runlevel(runlevel);
|
||||||
@@ -477,7 +479,7 @@ int svc_start(svc_t *svc)
|
|||||||
setuid(uid);
|
setuid(uid);
|
||||||
|
|
||||||
/* Serve copy of args to process in case it modifies them. */
|
/* Serve copy of args to process in case it modifies them. */
|
||||||
for (i = 0; i < MAX_NUM_SVC_ARGS && svc->args[i][0] != 0; i++)
|
for (i = 0; i < (MAX_NUM_SVC_ARGS - 1) && svc->args[i][0] != 0; i++)
|
||||||
args[i] = svc->args[i];
|
args[i] = svc->args[i];
|
||||||
args[i] = NULL;
|
args[i] = NULL;
|
||||||
|
|
||||||
@@ -487,8 +489,9 @@ int svc_start(svc_t *svc)
|
|||||||
|
|
||||||
fd = open(CONSOLE, O_WRONLY | O_APPEND);
|
fd = open(CONSOLE, O_WRONLY | O_APPEND);
|
||||||
if (-1 != fd) {
|
if (-1 != fd) {
|
||||||
dup2(STDOUT_FILENO, fd);
|
dup2(fd, STDOUT_FILENO);
|
||||||
dup2(STDERR_FILENO, fd);
|
dup2(fd, STDERR_FILENO);
|
||||||
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < MAX_NUM_SVC_ARGS && args[i]; i++) {
|
for (i = 0; i < MAX_NUM_SVC_ARGS && args[i]; i++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user