mirror of
https://github.com/troglobit/finit.git
synced 2026-10-12 10:12:32 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b361864fa | ||
|
|
41b0dc41a6 | ||
|
|
cab339c857 | ||
|
|
dcb42602c9 | ||
|
|
9e446557b4 | ||
|
|
a3d76c58a4 | ||
|
|
e0e0581d10 | ||
|
|
ef75d5ec31 | ||
|
|
dfeabd8bae | ||
|
|
7aa687bad9 | ||
|
|
c2ea2c1193 | ||
|
|
291b22e987 | ||
|
|
a091b69dd6 | ||
|
|
887c84a0d1 | ||
|
|
5009d54ab8 | ||
|
|
840ade6da7 | ||
|
|
030aa70842 | ||
|
|
dea3ae857b | ||
|
|
9f5172b0d1 | ||
|
|
e0529a5597 | ||
|
|
425cd17e57 | ||
|
|
0669a9cb81 | ||
|
|
5e040449c4 | ||
|
|
074686b520 | ||
|
|
d40f52357e | ||
|
|
076f77a31b | ||
|
|
8f1c16a8a5 | ||
|
|
b149dbc73e |
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "libuev"]
|
||||||
|
path = libuev
|
||||||
|
url = https://github.com/troglobit/libuev.git
|
||||||
+2
-2
@@ -13,9 +13,9 @@ addons:
|
|||||||
coverity_scan:
|
coverity_scan:
|
||||||
project:
|
project:
|
||||||
name: "troglobit/finit"
|
name: "troglobit/finit"
|
||||||
description: "finit | Fast Init Replacement"
|
description: "finit | Fast & Extensible init for Linux"
|
||||||
notification_email: troglobit@gmail.com
|
notification_email: troglobit@gmail.com
|
||||||
build_command: "make"
|
build_command: "make"
|
||||||
branch_pattern: master
|
branch_pattern: dev
|
||||||
|
|
||||||
script: make
|
script: make
|
||||||
|
|||||||
+278
@@ -0,0 +1,278 @@
|
|||||||
|
Change Log
|
||||||
|
==========
|
||||||
|
|
||||||
|
All notable changes to the project are documented in this file.
|
||||||
|
|
||||||
|
|
||||||
|
[1.11] - 2015-01-24
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
The [libuEv] release.
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
* Now using the asynchronous libuEv library for handling all events:
|
||||||
|
signals, timers and listening to sockets or file descriptors.
|
||||||
|
* Rename NEWS.md --> CHANGELOG.md, with symlinks for `make install`
|
||||||
|
* Attempt to align with http://keepachangelog.com/ for this file.
|
||||||
|
* Travis CI now only invokes Coverity Scan from the 'dev' branch. This
|
||||||
|
means that all development, except documentation updates, must go into
|
||||||
|
that branch.
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* Fix bug with finit dying when no `tty` is defined in `finit.conf`, now
|
||||||
|
even the fallback shell has control over its TTY, see fix in GIT
|
||||||
|
commit [dea3ae8] for this.
|
||||||
|
|
||||||
|
|
||||||
|
[1.10] - 2014-11-27
|
||||||
|
-------------------
|
||||||
|
Major bug fix release.
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
* Project now relies on static code analysis from Coverity, so this
|
||||||
|
release contains many serious bug fixes.
|
||||||
|
* Convert to use Markdown for README, NEWS and TODO.
|
||||||
|
* Serious update to README and slight pruning of finished TODO items.
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
|
||||||
|
[1.9] - 2014-04-21
|
||||||
|
------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
* Add support for an include directive to `.conf` files
|
||||||
|
* Fallback to `/bin/sh` if user forgets tty setting
|
||||||
|
* Initial support for restarting lost services during `norespwan`
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* Bug fixes, code cleanup
|
||||||
|
* Handle `SIGHUP` from service callback properly when switching runlevel
|
||||||
|
* Misc. major (memleak) and minor fixes and additions to `libite/lite.h`
|
||||||
|
|
||||||
|
|
||||||
|
[1.8] - 2013-06-07
|
||||||
|
------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
* 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
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* Bugfixes to libite
|
||||||
|
|
||||||
|
|
||||||
|
[1.7] - 2012-10-08
|
||||||
|
------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
* 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.
|
||||||
|
* Only clear screen when in verbose mode. Maybe this should be removed
|
||||||
|
altogether?
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* Bugfix: Do not `free()` static string in `finit.conf` parser
|
||||||
|
|
||||||
|
|
||||||
|
[1.6] - 2012-10-06
|
||||||
|
------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
* Skip `.` and `..` in plugin loader and display error when failing to
|
||||||
|
load 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`
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* Minor fix to alsa-utils plugin to silence on non-existing cards
|
||||||
|
|
||||||
|
|
||||||
|
[1.5] - 2012-10-03
|
||||||
|
------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
* 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
|
||||||
|
------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
* 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.
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* Fix I/O plugin watcher and load plugins earlier for a new hook
|
||||||
|
|
||||||
|
|
||||||
|
[1.3] - 2012-09-28
|
||||||
|
------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
* 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
|
||||||
|
------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
* Update README with section on building and enviroment variables
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* Fix installation paths encoded in finit binary
|
||||||
|
|
||||||
|
|
||||||
|
[1.1] - 2012-09-27
|
||||||
|
------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
* Rename signal.[ch]-->sig.[ch] to avoid name clash w/ system headers
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* Build fixes for ARM eabi/uClibc
|
||||||
|
|
||||||
|
|
||||||
|
[1.0] - 2012-09-26
|
||||||
|
------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
* 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)
|
||||||
|
|
||||||
|
|
||||||
|
[0.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
|
||||||
|
|
||||||
|
[libuEv]: https://github.com/troglobit/libuev
|
||||||
|
[dea3ae8]: https://github.com/troglobit/finit/commit/dea3ae8
|
||||||
|
[1.11]: https://github.com/troglobit/finit/compare/1.10...HEAD
|
||||||
|
[1.10]: https://github.com/troglobit/finit/compare/1.9...1.10
|
||||||
|
[1.9]: https://github.com/troglobit/finit/compare/1.8...1.9
|
||||||
|
[1.8]: https://github.com/troglobit/finit/compare/1.7...1.8
|
||||||
|
[1.7]: https://github.com/troglobit/finit/compare/1.6...1.7
|
||||||
|
[1.6]: https://github.com/troglobit/finit/compare/1.5...1.6
|
||||||
|
[1.5]: https://github.com/troglobit/finit/compare/1.4...1.5
|
||||||
|
[1.4]: https://github.com/troglobit/finit/compare/1.3...1.4
|
||||||
|
[1.3]: https://github.com/troglobit/finit/compare/1.2...1.3
|
||||||
|
[1.2]: https://github.com/troglobit/finit/compare/1.1...1.2
|
||||||
|
[1.1]: https://github.com/troglobit/finit/compare/1.0...1.1
|
||||||
|
[1.0]: https://github.com/troglobit/finit/compare/0.9...1.0
|
||||||
|
[0.9]: https://github.com/troglobit/finit/compare/0.8...0.9
|
||||||
|
[0.8]: https://github.com/troglobit/finit/compare/0.7...0.8
|
||||||
|
[0.7]: https://github.com/troglobit/finit/compare/0.6...0.7
|
||||||
|
[0.6]: https://github.com/troglobit/finit/compare/0.5...0.6
|
||||||
|
[0.5]: https://github.com/troglobit/finit/compare/0.4...0.5
|
||||||
|
[0.4]: https://github.com/troglobit/finit/compare/0.3...0.4
|
||||||
|
[0.3]: https://github.com/troglobit/finit/compare/0.2...0.3
|
||||||
|
[0.2]: https://github.com/troglobit/finit/compare/0.1...0.2
|
||||||
|
|
||||||
@@ -26,14 +26,16 @@
|
|||||||
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.10
|
VERSION ?= 1.11
|
||||||
NAME = finit
|
NAME = finit
|
||||||
PKG = $(NAME)-$(VERSION)
|
PKG = $(NAME)-$(VERSION)
|
||||||
DEV = $(NAME)-dev
|
DEV = $(NAME)-dev
|
||||||
ARCHIVE = $(PKG).tar.xz
|
ARCHTOOL = `which git-archive-all`
|
||||||
|
ARCHIVE = $(PKG).tar
|
||||||
|
ARCHIVEZ = ../$(ARCHIVE).xz
|
||||||
EXEC = finit reboot
|
EXEC = finit reboot
|
||||||
HEADERS = plugin.h svc.h helpers.h queue.h
|
HEADERS = plugin.h svc.h helpers.h queue.h
|
||||||
DISTFILES = LICENSE README NEWS finit.conf services
|
DISTFILES = LICENSE README CHANGELOG finit.conf services
|
||||||
OBJS = finit.o conf.o helpers.o sig.o svc.o plugin.o tty.o
|
OBJS = finit.o conf.o helpers.o sig.o svc.o plugin.o tty.o
|
||||||
SRCS = $(OBJS:.o=.c)
|
SRCS = $(OBJS:.o=.c)
|
||||||
DEPS = $(addprefix .,$(SRCS:.c=.d))
|
DEPS = $(addprefix .,$(SRCS:.c=.d))
|
||||||
@@ -57,22 +59,24 @@ FINIT_RCSD ?= $(sysconfdir)/finit.d
|
|||||||
CFLAGS += -W -Wall -Werror -Os
|
CFLAGS += -W -Wall -Werror -Os
|
||||||
# Disable annoying gcc warning for "warn_unused_result", see GIT 37af997
|
# Disable annoying gcc warning for "warn_unused_result", see GIT 37af997
|
||||||
CPPFLAGS += -U_FORTIFY_SOURCE
|
CPPFLAGS += -U_FORTIFY_SOURCE
|
||||||
CPPFLAGS += -Ilibite -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_GNU_SOURCE
|
CPPFLAGS += -Ilibite -Ilibuev
|
||||||
|
CPPFLAGS += -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_GNU_SOURCE
|
||||||
CPPFLAGS += -DVERSION=\"$(VERSION)\" -DWHOAMI=\"`whoami`@`hostname`\"
|
CPPFLAGS += -DVERSION=\"$(VERSION)\" -DWHOAMI=\"`whoami`@`hostname`\"
|
||||||
CPPFLAGS += -DFINIT_FIFO=\"$(FINIT_FIFO)\" -DFINIT_CONF=\"$(FINIT_CONF)\"
|
CPPFLAGS += -DFINIT_FIFO=\"$(FINIT_FIFO)\" -DFINIT_CONF=\"$(FINIT_CONF)\"
|
||||||
CPPFLAGS += -DFINIT_RCSD=\"$(FINIT_RCSD)\" -DPLUGIN_PATH=\"$(plugindir)\"
|
CPPFLAGS += -DFINIT_RCSD=\"$(FINIT_RCSD)\" -DPLUGIN_PATH=\"$(plugindir)\"
|
||||||
LDFLAGS += -rdynamic -L$(TOPDIR)/libite
|
LDFLAGS += -rdynamic -L$(TOPDIR)/libite
|
||||||
DEPLIBS = libite/libite.so
|
DEPLIBS = libite/libite.so libuev/libuev.a
|
||||||
LDLIBS += -ldl -lite
|
LDLIBS += -ldl -lite
|
||||||
|
|
||||||
include common.mk
|
include common.mk
|
||||||
export libdir plugindir incdir ROOTDIR CPPFLAGS LDFLAGS LDLIBS
|
export libdir plugindir incdir ROOTDIR CPPFLAGS LDFLAGS LDLIBS
|
||||||
|
|
||||||
all: $(DEPLIBS) $(EXEC)
|
all: $(DEPLIBS) $(EXEC)
|
||||||
$(MAKE) -C plugins $@
|
+$(MAKE) -C plugins $@
|
||||||
|
|
||||||
$(DEPLIBS): Makefile
|
$(DEPLIBS): Makefile
|
||||||
$(MAKE) -C libite all
|
+$(MAKE) -C libite all
|
||||||
|
+$(MAKE) -C libuev all
|
||||||
|
|
||||||
$(OBJS): Makefile
|
$(OBJS): Makefile
|
||||||
|
|
||||||
@@ -133,21 +137,32 @@ uninstall: uninstall-exec uninstall-data uninstall-dev
|
|||||||
|
|
||||||
clean:
|
clean:
|
||||||
-@$(RM) $(OBJS) $(DEPS) $(EXEC)
|
-@$(RM) $(OBJS) $(DEPS) $(EXEC)
|
||||||
$(MAKE) -C libite $@
|
+$(MAKE) -C plugins $@
|
||||||
$(MAKE) -C plugins $@
|
+$(MAKE) -C libite $@
|
||||||
|
+$(MAKE) -C libuev $@
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
-@$(RM) $(JUNK) unittest *.o .*.d
|
-@$(RM) $(JUNK) unittest *.o .*.d
|
||||||
$(MAKE) -C libite $@
|
+$(MAKE) -C plugins $@
|
||||||
$(MAKE) -C plugins $@
|
+$(MAKE) -C libite $@
|
||||||
|
+$(MAKE) -C libuev $@
|
||||||
|
|
||||||
check:
|
check:
|
||||||
$(CHECK) *.c plugins/*.c libite/*.c
|
$(CHECK) *.c plugins/*.c libite/*.c
|
||||||
|
|
||||||
dist:
|
dist:
|
||||||
|
@if [ x"$(ARCHTOOL)" = x"" ]; then \
|
||||||
|
echo "Missing git-archive-all from https://github.com/Kentzo/git-archive-all"; \
|
||||||
|
exit 1; \
|
||||||
|
fi
|
||||||
|
@if [ -e $(ARCHIVEZ) ]; then \
|
||||||
|
echo "Distribution already exists."; \
|
||||||
|
exit 1; \
|
||||||
|
fi
|
||||||
@echo "Building xz tarball of $(PKG) in parent dir..."
|
@echo "Building xz tarball of $(PKG) in parent dir..."
|
||||||
git archive --format=tar --prefix=$(PKG)/ $(VERSION) | xz >../$(ARCHIVE)
|
@$(ARCHTOOL) ../$(ARCHIVE)
|
||||||
@(cd ..; md5sum $(ARCHIVE) | tee $(ARCHIVE).md5)
|
@xz ../$(ARCHIVE)
|
||||||
|
@md5sum $(ARCHIVEZ) | tee $(ARCHIVEZ).md5
|
||||||
|
|
||||||
dev: distclean
|
dev: distclean
|
||||||
@echo "Building unstable xz $(DEV) in parent dir..."
|
@echo "Building unstable xz $(DEV) in parent dir..."
|
||||||
|
|||||||
@@ -1,206 +0,0 @@
|
|||||||
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,36 +1,57 @@
|
|||||||
README
|
Finit | Fast & Extensible init for Linux
|
||||||
======
|
========================================
|
||||||
[](https://travis-ci.org/troglobit/finit)
|
[](https://travis-ci.org/troglobit/finit)
|
||||||
[](https://scan.coverity.com/projects/3545)
|
[](https://scan.coverity.com/projects/3545)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Table of Contents
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
* [Introduction](#introduction)
|
||||||
|
* [Features](#features)
|
||||||
|
* [/etc/finit.conf](#etcfinitconf)
|
||||||
|
* [/etc/finit.d](#etcfinitd)
|
||||||
|
* [Bootstrap](#bootstrap)
|
||||||
|
* [Runlevels](#runlevels)
|
||||||
|
* [Hooks, Callbacks & Plugins](#hooks-callbacks--plugins)
|
||||||
|
* [Rebooting and Halting](#rebooting-and-halting)
|
||||||
|
* [Building](#building)
|
||||||
|
* [Running](#running)
|
||||||
|
* [Debugging](#debugging)
|
||||||
|
* [Origin & References](#origin--references)
|
||||||
|
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
------------
|
||||||
|
|
||||||
Init is the first process to run once a UNIX kernel has booted, it
|
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
|
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
|
system. Finit is plugin-based with built in [process supervision][1]
|
||||||
[process supervision](https://en.wikipedia.org/wiki/Process_supervision)
|
similar to that of D.J. Bernstein's [daemontools][2] and Gerrit Pape's
|
||||||
similar to that of D.J. Bernstein's
|
[runit][3]. The main focus of Finit is on small and embedded GNU/Linux
|
||||||
[daemontools](http://cr.yp.to/daemontools.html) and Gerrit Pape's
|
systems, yet fully functional on standard server and desktop
|
||||||
[runit](http://smarden.org/runit/). Its focus is on small and embedded
|
installations as well.
|
||||||
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
|
Traditional [SysV init][4] style systems are scripted. For low-resource
|
||||||
parallel. Services are supervised and automatically restarted if they
|
embedded systems this can be quite resource intensive and cause longer
|
||||||
fail. Services can have callbacks that are called before a service is
|
boot times. Finit is optimized to reduce context switches and forking
|
||||||
(re)started. For instance, before attempting to start a heavily
|
of processes to provide a very basic bootstrap written entirely in C.
|
||||||
resource intensive service like IPsec or OpenVPN, a callback can check
|
Hence, there is no `/etc/init.d/rcS` script, or similar, but instead a
|
||||||
if the outbound interface is up and has an IP address, or just check if
|
human-readable `/etc/finit.conf`. This file details what kernel modules
|
||||||
the service is disabled -- much like what a SysV init start script
|
to load, programs to run and daemons to supervise.
|
||||||
usually does.
|
|
||||||
|
|
||||||
To extend finit with new functionality, hooks can be added at certain
|
The command line arguments given in `/etc/finit.conf` to each service
|
||||||
points in the boot process that execute in sequence, which is useful for
|
provide a default. Each service can register callbacks, using plugins,
|
||||||
certain satisfying preconditions or for synchronization purposes. One
|
to override and modify the behavior to suit the current runlevel and
|
||||||
can also create plugins to functionality to suit your own needs, the
|
system configuration. For instance, before starting a heavily resource
|
||||||
initctl compatibility plugin that comes with finit is one such plugin.
|
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.
|
||||||
|
|
||||||
Finit is not only fast, it's arguably one of the easiest to get started
|
See [TroglOS][9] for an example of how to boot a small embedded system
|
||||||
with. A complete system can be booted with one simple configuration
|
with Finit.
|
||||||
file, `/etc/finit.conf`, see below for syntax.
|
|
||||||
|
|
||||||
|
|
||||||
Features
|
Features
|
||||||
@@ -42,20 +63,27 @@ Start, monitor and restart services if they fail.
|
|||||||
|
|
||||||
**Runlevels**
|
**Runlevels**
|
||||||
|
|
||||||
Finit supports standard runlevels if you want, but you don't need them
|
Runlevels is optional in Finit, but support for [SysV runlevels][5] is
|
||||||
for simple installations.
|
available if needed. All services in runlevel S(1) are started first,
|
||||||
|
followed by the desired run-time runlevel. Runlevel S can be started in
|
||||||
|
sequence by using `run [S] cmd`. Changing runlevels at runtime is done
|
||||||
|
like any other init, e.g. <kbd>init 4</kbd>.
|
||||||
|
|
||||||
**Plugins**
|
**Plugins**
|
||||||
|
|
||||||
Extend and modify finit behavior. See examples in plugins/ directory.
|
Finit plugins can be either *boot hooks* into different stages of the
|
||||||
|
boot process or *service callbacks*, or both. A basic set of plugins
|
||||||
|
that extend and modify the basic behavior are bundled. See examples in
|
||||||
|
the `plugins/` directory.
|
||||||
|
|
||||||
Plugin capabilities:
|
Plugin capabilities:
|
||||||
|
|
||||||
* Service callbacks — modify service arguments, run/restart/stop
|
* Service callbacks -- modify service arguments, run/restart/stop
|
||||||
* Task/Run callbacks — a one-shot commands, executed in sequence
|
* Task/Run callbacks -- a one-shot commands, executed in sequence
|
||||||
* Hooks — hook into the boot at predefined points to extend finit
|
* Hooks -- hook into the boot at predefined points to extend finit
|
||||||
* I/O — listen to external events and control finit behavior/services
|
* I/O -- listen to external events and control finit behavior/services
|
||||||
|
|
||||||
Extensions and functionality not purely related to what an /sbin/init
|
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
|
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.
|
hook into the boot process or respond to various I/O.
|
||||||
|
|
||||||
@@ -63,77 +91,76 @@ hook into the boot process or respond to various I/O.
|
|||||||
/etc/finit.conf
|
/etc/finit.conf
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
Contrary to most other script based init alternatives
|
Contrary to most other script based init alternatives ([SysV init][4],
|
||||||
([SysV init](https://en.wikipedia.org/wiki/Init),
|
[upstart][6], [systemd][7], [OpenRC][8], etc.) Finit reads its entire
|
||||||
[upstart](http://upstart.ubuntu.com/),
|
configuration from `/etc/finit.conf`.
|
||||||
[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>`
|
Syntax:
|
||||||
|
|
||||||
Run fsck on a file system before mounting it
|
* `check <DEV>`
|
||||||
|
|
||||||
* `module <MODULE>`
|
Run fsck on a file system before mounting it
|
||||||
|
|
||||||
Load a kernel module, with optional arguments
|
* `module <MODULE>`
|
||||||
|
|
||||||
* `network <PATH>`
|
Load a kernel module, with optional arguments
|
||||||
|
|
||||||
Script or program to bring up networking, with optional arguments
|
* `network <PATH>`
|
||||||
|
|
||||||
* `runlevel <N>`
|
Script or program to bring up networking, with optional arguments
|
||||||
|
|
||||||
N is the runlevel number 1-9, where 6 is reserved for reboot.
|
* `runlevel <N>`
|
||||||
|
|
||||||
Default is 2.
|
N is the runlevel number 1-9, where 6 is reserved for reboot.
|
||||||
|
|
||||||
* `run [LVLS] /path/to/cmd ARGS -- Optional description`
|
Default is 2.
|
||||||
|
|
||||||
One-shot command to run in sequence when entering a runlevel, with
|
* `run [LVLS] /path/to/cmd ARGS -- Optional description`
|
||||||
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 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.
|
||||||
|
|
||||||
One-shot like 'run', but starts in parallel with the next command
|
* `task [LVLS] /path/to/cmd ARGS -- Optional description`
|
||||||
|
|
||||||
* `service [LVLS] /path/to/daemon ARGS -- Optional description`
|
One-shot like 'run', but starts in parallel with the next command
|
||||||
|
|
||||||
Service, or daemon, to be monitored and automatically restarted if
|
* `service [LVLS] /path/to/daemon ARGS -- Optional description`
|
||||||
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>`
|
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.
|
||||||
|
|
||||||
Call run-parts(8) on a directory other than default ``/etc/finit.d``
|
* `runparts <PATH>`
|
||||||
|
|
||||||
* `include <CONF>`
|
Call run-parts(8) on a directory other than default ``/etc/finit.d``
|
||||||
|
|
||||||
Include another configuration file, ``/etc/finit.d``, or runparts
|
* `include <CONF>`
|
||||||
path is prepended to file if the file is not found or an absolute
|
|
||||||
path is not given
|
|
||||||
|
|
||||||
* `tty [LVLS] <DEV | /bin/sh>`
|
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
|
||||||
|
|
||||||
Start a getty on the given TTY device, in the given runlevels. When
|
* `tty [LVLS] <DEV | /bin/sh>`
|
||||||
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
|
Start a getty on the given TTY device, in the given runlevels. When
|
||||||
default baud rate.
|
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>`
|
See `finit.h` for the `#define GETTY` that is called, along with the
|
||||||
|
default baud rate.
|
||||||
|
|
||||||
Some embedded systems have a dedicated console port. This command
|
* `console <DEV>`
|
||||||
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
|
Some embedded systems have a dedicated console port. This command
|
||||||
provided since the system requirements differ too much. Try out the
|
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 <kbd>make install</kbd> no default `/etc/finit.conf` will
|
||||||
|
be installed since system requirements differ too much. Try out the
|
||||||
Debian 6.0 example `/usr/share/doc/finit/finit.conf` configuration that
|
Debian 6.0 example `/usr/share/doc/finit/finit.conf` configuration that
|
||||||
is capable of service monitoring SSH, sysklogd, gdm and a console getty!
|
is capable of service monitoring SSH, sysklogd, gdm and a console getty!
|
||||||
|
|
||||||
@@ -142,13 +169,55 @@ is capable of service monitoring SSH, sysklogd, gdm and a console getty!
|
|||||||
------------
|
------------
|
||||||
|
|
||||||
At the end of the boot, when networking and all services are up, finit
|
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
|
calls its built-in run-parts(8) on the `/etc/finit.d/` directory, if it
|
||||||
it exists. Similar to how the `/ec/rc.local` file works in most other
|
exists. Similar to how the `/ec/rc.local` file works in most other init
|
||||||
init daemons, only finit runs a directory of scripts. This replaces the
|
daemons, only finit runs a directory of scripts. This replaces the
|
||||||
earlier support for a `/usr/sbin/services.sh` script in the original
|
earlier support for a `/usr/sbin/services.sh` script in the original
|
||||||
finit.
|
finit.
|
||||||
|
|
||||||
|
|
||||||
|
Bootstrap
|
||||||
|
---------
|
||||||
|
|
||||||
|
1. Setup `/dev`
|
||||||
|
2. Parse `/etc/finit.conf`
|
||||||
|
3. Load all `.so` plugins
|
||||||
|
4. Remount/Pivot `/` to get R+W
|
||||||
|
5. Call 1st level hooks, `HOOK_ROOTFS_UP`
|
||||||
|
6. Mount `/etc/fstab` and swap, if available
|
||||||
|
7. Cleanup stale files from `/tmp/*` et al
|
||||||
|
8. Enable SysV init signals
|
||||||
|
9. Call 2nd level hooks, `HOOK_BASEFS_UP`
|
||||||
|
10. Start all 'S' runlevel tasks and services
|
||||||
|
11. Setup `/etc/sysctl.conf`
|
||||||
|
12. Setup hostname and loopback
|
||||||
|
13. Call `network` script, if set in `/etc/finit.conf`
|
||||||
|
14. Call 3rd level hooks, `HOOK_NETWORK_UP`
|
||||||
|
15. Switch to active runlevel, as set in `/etc/finit.conf`, default 2.
|
||||||
|
Here is where the rest of all tasks and services are started.
|
||||||
|
16. Call 4th level hooks, `HOOK_SVC_UP`
|
||||||
|
17. Run-parts in `/etc/finit.d`, if any
|
||||||
|
18. Call 5th level (last) hooks, `HOOK_SYSTEM_UP`
|
||||||
|
19. Start TTYs defined in `/etc/finit.conf`, or rescue on `/dev/console`
|
||||||
|
20. Enter main monitor loop
|
||||||
|
|
||||||
|
In (10) and (15) tasks and services defined in `/etc/finit.conf` are
|
||||||
|
started. Remember, all `service` and `task` stanzas are started in
|
||||||
|
parallel and `run` in sequence, and in the order listed. Hence, to
|
||||||
|
emulate a SysV `/etc/init.d/rcS` one could write a long file with only
|
||||||
|
`run` statments.
|
||||||
|
|
||||||
|
Notice the five hook points that are called at various point in the
|
||||||
|
bootstrap process. This is where plugins can extend the boot in any way
|
||||||
|
they please.
|
||||||
|
|
||||||
|
For instance, at `HOOK_BASEFS_UP` a plugin could read an XML file from a
|
||||||
|
USB stick, convert/copy its contents to the system's `/etc/` directory,
|
||||||
|
well before all 'S' runlevel tasks are started. This could be used with
|
||||||
|
system images that are created read-only and all configuration is stored
|
||||||
|
on external media.
|
||||||
|
|
||||||
|
|
||||||
Runlevels
|
Runlevels
|
||||||
---------
|
---------
|
||||||
|
|
||||||
@@ -158,8 +227,9 @@ commands and TTYs listed without a set of runlevels get a default set
|
|||||||
`[234]` assigned. The default runlevel after boot is 2.
|
`[234]` assigned. The default runlevel after boot is 2.
|
||||||
|
|
||||||
To specify an allowed set of runlevels for a `service`, `run` command, `task`,
|
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:
|
or `tty`, add `[NNN]` to it in your `/etc/finit.conf`, like this:
|
||||||
|
|
||||||
|
service [S12345] /sbin/syslogd -n -x -- System log daemon
|
||||||
run [S] /etc/init.d/acpid start -- Starting ACPI Daemon
|
run [S] /etc/init.d/acpid start -- Starting ACPI Daemon
|
||||||
task [S] /etc/init.d/kbd start -- Preparing console
|
task [S] /etc/init.d/kbd start -- Preparing console
|
||||||
service [S12345] /sbin/klogd -n -x -- Kernel log daemon
|
service [S12345] /sbin/klogd -n -x -- Kernel log daemon
|
||||||
@@ -170,21 +240,19 @@ or `tty`, add `[NNN]` to it in your `finit.conf`, like this:
|
|||||||
tty [2] /dev/tty5
|
tty [2] /dev/tty5
|
||||||
tty [2] /dev/tty6
|
tty [2] /dev/tty6
|
||||||
|
|
||||||
In this example acpid is started once at bootstrap using a conventional
|
In this example syslogd is first started, in parallel, and then acpid is
|
||||||
SysV init script. Here the run command was used, meaning the following
|
called using a conventional SysV init script. It is called with the run
|
||||||
task command is not run until the init script has fully completed. Then
|
command, meaning the following task command to start the kbd script is
|
||||||
the keyboard setup script is called in parallel with spawning klogd as
|
not called until the acpid init script has fully completed. Then the
|
||||||
a monitored service.
|
keyboard setup script is called in parallel with klogd as a monitored
|
||||||
|
service.
|
||||||
|
|
||||||
Tasks and services are started in parallel, while run commands are run
|
Again, tasks and services are started in parallel, while run commands
|
||||||
in the order listed and subsequent commands are not started until a run
|
are called in the order listed and subsequent commands are not started
|
||||||
command has completed.
|
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
|
Switching between runlevels can be done by calling init with a single
|
||||||
argument, e.g., `init 5` switches to runlevel 5.
|
argument, e.g. <kbd>init 5</kbd> switches to runlevel 5.
|
||||||
|
|
||||||
|
|
||||||
Hooks, Callbacks & Plugins
|
Hooks, Callbacks & Plugins
|
||||||
@@ -196,27 +264,26 @@ however come with support for hooks, service callbacks and plugins that
|
|||||||
can used to extend finit with. For your convenience a set of *optional*
|
can used to extend finit with. For your convenience a set of *optional*
|
||||||
plugins are available:
|
plugins are available:
|
||||||
|
|
||||||
* *alsa-utils.so*: Restore and save ALSA sound settings on
|
* *alsa-utils.so*: Restore and save ALSA sound settings on
|
||||||
startup/shutdown.
|
startup/shutdown.
|
||||||
|
|
||||||
* *bootmisc.so*: Setup necessary files for UTMP, tracking logins
|
* *bootmisc.so*: Setup necessary files for UTMP, tracks logins at boot.
|
||||||
at boot.
|
|
||||||
|
|
||||||
* *dbus.so*: Setup and start system message bus, D-Bus, 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
|
* *hwclock.so*: Restore and save system clock from/to RTC on
|
||||||
startup/shutdown.
|
startup/shutdown.
|
||||||
|
|
||||||
* *initctl.so*: Extends finit with a traditional initctl functionality.
|
* *initctl.so*: Extends finit with a traditional initctl functionality.
|
||||||
|
|
||||||
* *resolvconf.so*: Setup necessary files for resolvconf at startup.
|
* *resolvconf.so*: Setup necessary files for resolvconf at startup.
|
||||||
|
|
||||||
* *tty.so*: Watches /dev, using inotify, for new device nodes (TTY's) to
|
* *tty.so*: Watches /dev, using inotify, for new device nodes (TTY's) to
|
||||||
start/stop getty consoles on them on demand.
|
start/stop getty consoles on them on demand.
|
||||||
|
|
||||||
* *urandom.so*: Setup random seed at startup.
|
* *urandom.so*: Setup random seed at startup.
|
||||||
|
|
||||||
* *x11-common.so*: Setup necessary files for X-Window.
|
* *x11-common.so*: Setup necessary files for X-Window.
|
||||||
|
|
||||||
Usually you want to hook into the boot process once, simple hook plugins
|
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
|
like `bootmisc.so` are great for that purpose. They are called at each
|
||||||
@@ -224,22 +291,22 @@ hook point in the boot process, useful to insert some pre-bootstrap
|
|||||||
mechanisms, like generating configuration files, restoring HW device
|
mechanisms, like generating configuration files, restoring HW device
|
||||||
state, etc. Available hook points are:
|
state, etc. Available hook points are:
|
||||||
|
|
||||||
* `HOOK_ROOTFS_UP`: When `finit.conf` has been read and `/` has is
|
* `HOOK_ROOTFS_UP`: When `finit.conf` has been read and `/` has is
|
||||||
mounted -- very early
|
mounted -- very early
|
||||||
|
|
||||||
* `HOOK_BASEFS_UP`: All of `/etc/fstab` is mounted, swap is available
|
* `HOOK_BASEFS_UP`: All of `/etc/fstab` is mounted, swap is available
|
||||||
and default init signals are setup
|
and default init signals are setup
|
||||||
|
|
||||||
* `HOOK_NETWORK_UP`: System bootstrap, runlevel S, has completed and
|
* `HOOK_NETWORK_UP`: System bootstrap, runlevel S, has completed and
|
||||||
networking is up (`lo` is up and the `network` script has run)
|
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_SVC_UP`: All services in the active runlevel has been launched
|
||||||
|
|
||||||
* `HOOK_SYSTEM_UP`: All services *and* everything in `/etc/finit.d`
|
* `HOOK_SYSTEM_UP`: All services *and* everything in `/etc/finit.d`
|
||||||
has been launched
|
has been launched
|
||||||
|
|
||||||
* `HOOK_SHUTDOWN`: Called at shutdown/reboot, right before all
|
* `HOOK_SHUTDOWN`: Called at shutdown/reboot, right before all
|
||||||
services are sent `SIGTERM`
|
services are sent `SIGTERM`
|
||||||
|
|
||||||
Plugins like `initctl.so` and `tty.so` extend finit by acting on events,
|
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
|
they are called I/O plugins and are called from the finit main loop when
|
||||||
@@ -275,56 +342,58 @@ alter the behavior of finit.
|
|||||||
The following environment variables are checked by the makefiles and control
|
The following environment variables are checked by the makefiles and control
|
||||||
what is built and where resulting binaries are installed.
|
what is built and where resulting binaries are installed.
|
||||||
|
|
||||||
* `ROOTDIR=`: Top directory for building complete system, used in pretty
|
* `ROOTDIR=`: Top directory for building complete system, used in pretty
|
||||||
printing.
|
printing.
|
||||||
|
|
||||||
* `VERSION=`: Defaults to the currently released version of finit,
|
* `VERSION=`: Defaults to the currently released version of finit,
|
||||||
e.g., 1.3 but can be overridden by packagers using this variable to
|
e.g., 1.3 but can be overridden by packagers using this variable to
|
||||||
add a suffix or completely alter the version.
|
add a suffix or completely alter the version.
|
||||||
|
|
||||||
* `CFLAGS=`: Default `CFLAGS` are inherited from the build environment.
|
* `CFLAGS=`: Default `CFLAGS` are inherited from the environment.
|
||||||
|
|
||||||
* `CPPFLAGS=`: Default `CPPFLAGS` are inherited from the build
|
* `CPPFLAGS=`: Default `CPPFLAGS` are inherited from the environment.
|
||||||
environment.
|
|
||||||
|
|
||||||
* `LDFLAGS=`: Default `LDFLAGS` are inherited from the build
|
* `LDFLAGS=`: Default `LDFLAGS` are inherited from the environment.
|
||||||
environment.
|
|
||||||
|
|
||||||
* `LDLIBS=`: Default `LIBLIBS` are inherited from the build environment.
|
* `LDLIBS=`: Default `LIBLIBS` are inherited from the environment.
|
||||||
|
|
||||||
* `prefix=`: Base prefix path for all files, except `sbinbdir` and
|
* `prefix=`: Base prefix path for all files, except `sbinbdir` and
|
||||||
`sysconfdir`. Used in concert with the `DESTDIR` variable.
|
`sysconfdir`. Used in concert with the `DESTDIR` variable.
|
||||||
|
|
||||||
Defaults to `/usr`.
|
Defaults to `/usr`.
|
||||||
|
|
||||||
* `sbindir=`: Path to where resulting binaries should install to. Used
|
* `sbindir=`: Path to where resulting binaries should install to. Used
|
||||||
in concert with the `DESTDIR` variable.
|
in concert with the `DESTDIR` variable.
|
||||||
|
|
||||||
Defaults to `/sbin`.
|
Defaults to `/sbin`.
|
||||||
|
|
||||||
* `sysconfdir=`: Path to where finit configuration files should install
|
* `sysconfdir=`: Path to where finit configuration files should install
|
||||||
to. Used in concert with the `DESTDIR` variable.
|
to. Used in concert with the `DESTDIR` variable.
|
||||||
|
|
||||||
Defaults to `/etc`, but is currently unused.
|
Defaults to `/etc`, but is currently unused.
|
||||||
|
|
||||||
* `PLUGINS=`: List of stock finit plugins to build and install.
|
* `PLUGINS=`: List of stock finit plugins to build and install.
|
||||||
|
|
||||||
* `plugindir=`: Absolute path to where finit should look for dynamically
|
* `plugindir=`: Absolute path to where finit should look for dynamically
|
||||||
loadable plugins at runtime. At installation prepended by `DESTDIR`
|
loadable plugins at runtime. At installation prepended by `DESTDIR`
|
||||||
and `prefix`.
|
and `prefix`.
|
||||||
|
|
||||||
Defaults to `/lib/finit/plugins`.
|
Defaults to `/lib/finit/plugins`.
|
||||||
|
|
||||||
* `DESTDIR=`: Used by packagers and distributions when building a
|
* `DESTDIR=`: Used by packagers and distributions when building a
|
||||||
relocatable bundle of files. Always prepended to the `prefix`
|
relocatable bundle of files. Always prepended to the `prefix`
|
||||||
destination directory.
|
destination directory.
|
||||||
|
|
||||||
**Example**
|
**Example**
|
||||||
|
|
||||||
$ tar xfJ finit-1.3.tar.xz
|
First, unpack the archive:
|
||||||
$ PLUGINS="initctl.so hwclock.so" DESTDIR=/tmp/finit/dst \
|
|
||||||
make -C finit-1.3/ clean install
|
<kbd>$ tar xfJ finit-1.3.tar.xz; cd finit-1.3/</kbd>
|
||||||
make: Entering directory `/home/troglobit/finit-1.3'
|
|
||||||
|
Then build and install:
|
||||||
|
|
||||||
|
<kbd>$ PLUGINS="initctl.so hwclock.so" DESTDIR=/tmp/finit make install</kbd>
|
||||||
|
|
||||||
CC finit.o
|
CC finit.o
|
||||||
CC conf.o
|
CC conf.o
|
||||||
CC helpers.o
|
CC helpers.o
|
||||||
@@ -337,17 +406,14 @@ what is built and where resulting binaries are installed.
|
|||||||
PLUGIN plugins/initctl.so
|
PLUGIN plugins/initctl.so
|
||||||
CC plugins/hwclock.o
|
CC plugins/hwclock.o
|
||||||
PLUGIN plugins/hwclock.so
|
PLUGIN plugins/hwclock.so
|
||||||
INSTALL /tmp/finit/dst/sbin/finit
|
INSTALL /tmp/finit/sbin/finit
|
||||||
INSTALL /tmp/finit/dst/lib/finit/plugins/initctl.so
|
INSTALL /tmp/finit/lib/finit/plugins/initctl.so
|
||||||
INSTALL /tmp/finit/dst/lib/finit/plugins/hwclock.so
|
INSTALL /tmp/finit/lib/finit/plugins/hwclock.so
|
||||||
make: Leaving directory `/home/troglobit/finit-1.3'
|
|
||||||
|
|
||||||
In this example the
|
In this example the [finit-1.3.tar.xz][10] archive is unpacked to the
|
||||||
[finit-1.3.tar.xz](ftp://troglobit.com/finit/finit-1.3.tar.xz)
|
user's home directory, built and installed to a temporary staging
|
||||||
archive is unpacked to the user's home directory, built and
|
directory. The environment variables `DESTDIR` and `PLUGINS` are
|
||||||
installed to a temporary staging directory. The environment
|
changed to suit this particular build.
|
||||||
variables `DESTDIR` and `PLUGINS` are changed to suit this
|
|
||||||
particular build.
|
|
||||||
|
|
||||||
|
|
||||||
Running
|
Running
|
||||||
@@ -363,6 +429,8 @@ give the kernel the following extra command line:
|
|||||||
|
|
||||||
init=/sbin/finit
|
init=/sbin/finit
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
Debugging
|
Debugging
|
||||||
---------
|
---------
|
||||||
@@ -374,8 +442,8 @@ enable trace messages. A console getty is always started, see the file
|
|||||||
init=/sbin/finit --debug
|
init=/sbin/finit --debug
|
||||||
|
|
||||||
|
|
||||||
Credits & Contact
|
Origin & References
|
||||||
-----------------
|
-------------------
|
||||||
|
|
||||||
This is the continuation of the [original finit](http://helllabs.org/finit/)
|
This is the continuation of the [original finit](http://helllabs.org/finit/)
|
||||||
by [Claudio Matsuoka](https://github.com/cmatsuoka), which in turn was
|
by [Claudio Matsuoka](https://github.com/cmatsuoka), which in turn was
|
||||||
@@ -388,3 +456,13 @@ Finit is currently being developed and maintained by
|
|||||||
[GitHub](http://github.com/troglobit/finit). Please file bug reports, clone it,
|
[GitHub](http://github.com/troglobit/finit). Please file bug reports, clone it,
|
||||||
or send pull requests for bug fixes and proposed extensions.
|
or send pull requests for bug fixes and proposed extensions.
|
||||||
|
|
||||||
|
[1]: https://en.wikipedia.org/wiki/Process_supervision
|
||||||
|
[2]: http://cr.yp.to/daemontools.html
|
||||||
|
[3]: http://smarden.org/runit/
|
||||||
|
[4]: http://en.wikipedia.org/wiki/Init
|
||||||
|
[5]: http://en.wikipedia.org/wiki/Runlevel
|
||||||
|
[6]: http://upstart.ubuntu.com/
|
||||||
|
[7]: http://www.freedesktop.org/wiki/Software/systemd/
|
||||||
|
[8]: http://www.gentoo.org/proj/en/base/openrc/
|
||||||
|
[9]: https://github.com/troglobit/troglos
|
||||||
|
[10]: ftp://troglobit.com/finit/finit-1.3.tar.xz
|
||||||
|
|||||||
@@ -1,98 +1,165 @@
|
|||||||
TODO
|
Goals of Finit
|
||||||
====
|
==============
|
||||||
|
|
||||||
Unsorted TODO list of features and points of investigation that could be
|
The intent of finit is to monitor not just processes, but to supervise
|
||||||
useful for improving finit. But what is an improvement to finit? Well,
|
an entire system and the behavior of certain processes that declare
|
||||||
similiar to launchd, the goal of finit is to be a FAST replacement for:
|
themselves to be finit compliant. Similar to launchd, the goal of
|
||||||
|
finit is to be a replacement for:
|
||||||
|
|
||||||
* init
|
* init
|
||||||
* inetd
|
* inetd
|
||||||
* crond
|
* crond
|
||||||
* watchdogd
|
* watchdogd
|
||||||
|
|
||||||
|
A small and simple replacement, primarily for embedded systems, with a
|
||||||
|
very low dependency on external packages.
|
||||||
|
|
||||||
|
General
|
||||||
|
-------
|
||||||
|
|
||||||
|
* 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`
|
||||||
|
* 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
|
||||||
|
* 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`.
|
||||||
|
|
||||||
|
|
||||||
|
Init
|
||||||
|
----
|
||||||
|
|
||||||
|
Finit in itself is not SysV Init compatible, it doesn't use `/etc/rc.d`
|
||||||
|
and `/etc/inet.d` scripts to boot the system. However, a plausible way
|
||||||
|
to achieve compatibility would be to add a plugin to finit which reads
|
||||||
|
`/etc/inittab` to be able to start standard Linux systems.
|
||||||
|
|
||||||
The main goal is to be FAST. Secondary goals are to be: small, simple
|
|
||||||
and with a very low dependency on external packages.
|
|
||||||
|
|
||||||
Inetd
|
Inetd
|
||||||
-----
|
-----
|
||||||
|
|
||||||
Simple way of running Internet services on demand, like the old inetd:
|
Simple way of running Internet services on demand, like the old inetd:
|
||||||
|
|
||||||
inetd SVC [RUNLVL] /path/to/daemon args -- description
|
inetd PROTO/SERVICE <wait|nowait> [@USER[:GROUP]] /path/to/daemon args
|
||||||
|
|
||||||
Example:
|
Examples:
|
||||||
|
|
||||||
# Inetd services, launched on demand
|
# Inetd services, launched on demand
|
||||||
inetd ssh [2345] /usr/sbin/sshd -i -- SSH Daemon
|
inetd tcp/ssh nowait [2345] @root:root /usr/sbin/sshd -i
|
||||||
|
|
||||||
In keeping with the finit tradition, an optional callback can be setup
|
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
|
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
|
callback with a `struct in_pktinfo` argument which the callback then can
|
||||||
allowed or deny.
|
allowed or deny.
|
||||||
|
|
||||||
|
Alternatively, borrowing from TCP wrappers by Wietse Venema, a set of
|
||||||
|
`allow` and `deny` directives can be added to `finit.conf` to control
|
||||||
|
inetd services. It could be what IP addreses, networks or interfaces
|
||||||
|
are allowed to connect to the given inetd services. To start with the
|
||||||
|
easiest (and what we need for WeOS at Westermo) is allow/deny per iface.
|
||||||
|
|
||||||
Priority
|
# Disable access to SSH
|
||||||
|
deny ssh all
|
||||||
|
# Allow SSH connections originating from eth0
|
||||||
|
allow ssh eth0
|
||||||
|
|
||||||
|
Another option, to further extend the Inetd capabilities, is a separate
|
||||||
|
`finetd.conf` to list services. This would be beneficial when running
|
||||||
|
an SSH service on different ports on different interfaces:
|
||||||
|
|
||||||
|
# Run SSH on port 22 on all interfaces except upstream
|
||||||
|
tcp ssh {
|
||||||
|
listen = *, !wan0
|
||||||
|
exec = dropbear -i
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run SSH on non-standard port 222 for upstream interface
|
||||||
|
tcp 222 {
|
||||||
|
listen = wan0
|
||||||
|
exec = dropbear -i
|
||||||
|
wait = yes
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run TFTP service on all interfaces except upstream interface
|
||||||
|
udp tftp {
|
||||||
|
listen = *, !wan0
|
||||||
|
exec = uftpd -i -t
|
||||||
|
user = root
|
||||||
|
}
|
||||||
|
|
||||||
|
Syntax very similar to [xinetd](http://en.wikipedia.org/wiki/Xinetd)
|
||||||
|
|
||||||
|
|
||||||
|
Crond
|
||||||
|
-----
|
||||||
|
|
||||||
|
Requirements are quite rudimentary, basic cron functionality, mainly
|
||||||
|
system-level timed periodic tasks:
|
||||||
|
|
||||||
|
* Periodically run a task, in a matching runlevel
|
||||||
|
* Optionally run as non-root (`crontab -e` as operator)
|
||||||
|
|
||||||
|
Proposed syntax:
|
||||||
|
|
||||||
|
# Crontab
|
||||||
|
cron @YY-mm-ddTHH:MM [LVLS] /path/to/cmd [ARGS] -- Optional descr
|
||||||
|
|
||||||
|
# One-shot 'at' command
|
||||||
|
at @YY-mm-ddTHH:MM [LVLS] /path/to/cmd [ARGS] -- Optional descr
|
||||||
|
|
||||||
|
Notice the ISO date in notation. The runlevels is extra filtering
|
||||||
|
sugar. E.g., if cron service is only allowed in runlevels two or three
|
||||||
|
it will not start if system currently is in runlevel four.
|
||||||
|
|
||||||
|
To run a command as another user the `.conf` file must have a that
|
||||||
|
owner. E.g., `/etc/finit.d/extra.conf` may be owned by operator and
|
||||||
|
only hold `cron ...` lines.
|
||||||
|
|
||||||
|
What would be extremely useful is if `initctl`, or a homegrown `at`,
|
||||||
|
could support the basic functionality of the `at` command directly from
|
||||||
|
the shell -- that way setting up one-time jobs would not entail
|
||||||
|
re-reading `/etc/finit.conf`
|
||||||
|
|
||||||
|
|
||||||
|
Watchdog
|
||||||
--------
|
--------
|
||||||
|
|
||||||
The intent of finit is to monitor not just processes, but also to
|
Support for monitoring the health of the system and its processes.
|
||||||
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
|
* Add support for a `/dev/watchdog` plugin to replace `watchdogd`
|
||||||
fd's, etc. Because "Event driven software improves concurrency" --
|
* Integrate system supervisor to optionally reboot the system when a
|
||||||
Dave Zarzycki, Apple.
|
process stops responding, or when a respawn limit has been reached,
|
||||||
|
as well as when system load gets too high.
|
||||||
See the [launchd video](http://www.youtube.com/watch?v=cD_s6Fjdri8)
|
* API for processes to register with the watchdog.
|
||||||
for more info!
|
- Deeper monitoring of a process main loop
|
||||||
|
- If a process is not heard from within its subscribed period time
|
||||||
* Add support for a /dev/watchdog plugin to replace watchdogd
|
reboot system or restart process.
|
||||||
|
* Separate `/etc/watchdog.conf` configuration file, or a perhaps
|
||||||
* Integrate watchdog plugin with process/system supervisor to optionally
|
support for `/etc/finit.d/PLUGIN.conf`?
|
||||||
reboot the system when a process stops responding, or when a respawn
|
* Support enable/disable watchdog features:
|
||||||
limit has been reached, as well as when system load gets too high.
|
- Supervise processes,
|
||||||
|
- CPU loadavg,
|
||||||
|
- Watch for file descriptor leaks,
|
||||||
Configuration
|
- etc.
|
||||||
-------------
|
|
||||||
|
|
||||||
* 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
|
Documentation
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
* Write man pages for finit and `finit.conf`, steal from the excellent
|
* Write man pages for finit and `finit.conf`, steal from the excellent
|
||||||
`pimd` man pages ...
|
`pimd` man pages ...
|
||||||
* Update Debian `finit.conf` example with runlevels, `tty/console` and
|
* Update Debian `finit.conf` example with runlevels, `tty/console` and
|
||||||
dependency handling
|
dependency handling for Debian 8 (the dreaded systemd release).
|
||||||
|
|
||||||
|
|
||||||
Investigation
|
Investigation
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
* [FHS changes](http://askubuntu.com/questions/57297/why-has-var-run-been-migrated-to-run)
|
* [FHS changes](http://askubuntu.com/questions/57297/why-has-var-run-been-migrated-to-run)
|
||||||
affecting runtime status, plugins, etc.
|
affecting runtime status, plugins, etc.
|
||||||
|
|
||||||
|
|||||||
@@ -131,27 +131,6 @@ static int client(int argc, char *argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int run_loop(void)
|
|
||||||
{
|
|
||||||
int delay = DELAY_TTY ?: 1;
|
|
||||||
|
|
||||||
_d("Entering main loop ...");
|
|
||||||
while (1) {
|
|
||||||
svc_monitor();
|
|
||||||
plugin_monitor();
|
|
||||||
|
|
||||||
/* Delayed start of TTYs to let the system stabilize
|
|
||||||
* after switching runlevels. */
|
|
||||||
if (delay) {
|
|
||||||
if (--delay == 0)
|
|
||||||
tty_runlevel(runlevel);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void banner(void)
|
static void banner(void)
|
||||||
{
|
{
|
||||||
delline();
|
delline();
|
||||||
@@ -160,6 +139,8 @@ static void banner(void)
|
|||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
uev_ctx_t ctx;
|
||||||
|
|
||||||
if (getpid() != 1)
|
if (getpid() != 1)
|
||||||
return client(argc, argv);
|
return client(argc, argv);
|
||||||
|
|
||||||
@@ -173,6 +154,11 @@ int main(int argc, char* argv[])
|
|||||||
*/
|
*/
|
||||||
sig_init();
|
sig_init();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initalize event context.
|
||||||
|
*/
|
||||||
|
uev_init(&ctx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mount base file system, kernel is assumed to run devtmpfs for /dev
|
* Mount base file system, kernel is assumed to run devtmpfs for /dev
|
||||||
*/
|
*/
|
||||||
@@ -208,7 +194,7 @@ int main(int argc, char* argv[])
|
|||||||
* hook on to.
|
* hook on to.
|
||||||
*/
|
*/
|
||||||
print_desc("Loading plugins", NULL);
|
print_desc("Loading plugins", NULL);
|
||||||
print_result(plugin_load_all(PLUGIN_PATH));
|
print_result(plugin_load_all(&ctx, PLUGIN_PATH));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mount filesystems
|
* Mount filesystems
|
||||||
@@ -232,7 +218,7 @@ int main(int argc, char* argv[])
|
|||||||
run_interactive("rm -rf /tmp/* /var/run/* /var/lock/*", "Cleanup temporary directories");
|
run_interactive("rm -rf /tmp/* /var/run/* /var/lock/*", "Cleanup temporary directories");
|
||||||
|
|
||||||
/* Base FS up, enable standard SysV init signals */
|
/* Base FS up, enable standard SysV init signals */
|
||||||
sig_setup();
|
sig_setup(&ctx);
|
||||||
|
|
||||||
_d("Base FS up, calling hooks ...");
|
_d("Base FS up, calling hooks ...");
|
||||||
plugin_run_hooks(HOOK_BASEFS_UP);
|
plugin_run_hooks(HOOK_BASEFS_UP);
|
||||||
@@ -279,10 +265,13 @@ int main(int argc, char* argv[])
|
|||||||
/* Hooks that should run at the very end */
|
/* Hooks that should run at the very end */
|
||||||
plugin_run_hooks(HOOK_SYSTEM_UP);
|
plugin_run_hooks(HOOK_SYSTEM_UP);
|
||||||
|
|
||||||
|
/* Start TTYs */
|
||||||
|
tty_runlevel(runlevel);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enter main loop to monior /dev/initctl and services
|
* Enter main loop to monior /dev/initctl and services
|
||||||
*/
|
*/
|
||||||
return run_loop();
|
return uev_run(&ctx, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -65,9 +65,6 @@
|
|||||||
# define DEFHOST "noname"
|
# define DEFHOST "noname"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Delay start of GETTY at boot. Must be > 0 */
|
|
||||||
#define DELAY_TTY 2
|
|
||||||
|
|
||||||
#define CMD_SIZE 256
|
#define CMD_SIZE 256
|
||||||
#define LINE_SIZE 1024
|
#define LINE_SIZE 1024
|
||||||
#define BUF_SIZE 4096
|
#define BUF_SIZE 4096
|
||||||
|
|||||||
@@ -446,7 +446,7 @@ int run(char *cmd)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pid = fork();
|
pid = vfork();
|
||||||
if (0 == pid) {
|
if (0 == pid) {
|
||||||
int i;
|
int i;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
@@ -466,7 +466,9 @@ int run(char *cmd)
|
|||||||
dup2(fd, STDERR_FILENO);
|
dup2(fd, STDERR_FILENO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sig_unblock();
|
||||||
execvp(args[0], args);
|
execvp(args[0], args);
|
||||||
|
|
||||||
_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]);
|
||||||
@@ -563,13 +565,11 @@ int run_interactive(char *cmd, char *fmt, ...)
|
|||||||
|
|
||||||
pid_t run_getty(char *cmd, char *args[], int console)
|
pid_t run_getty(char *cmd, char *args[], int console)
|
||||||
{
|
{
|
||||||
pid_t pid = fork();
|
pid_t pid = vfork();
|
||||||
|
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
int i, fd;
|
int fd;
|
||||||
char c;
|
char c;
|
||||||
sigset_t nmask;
|
|
||||||
struct sigaction sa;
|
|
||||||
|
|
||||||
if (console) {
|
if (console) {
|
||||||
/* Detach from initial controlling TTY */
|
/* Detach from initial controlling TTY */
|
||||||
@@ -590,13 +590,13 @@ pid_t run_getty(char *cmd, char *args[], int console)
|
|||||||
|
|
||||||
prctl(PR_SET_NAME, "console", 0, 0, 0);
|
prctl(PR_SET_NAME, "console", 0, 0, 0);
|
||||||
}
|
}
|
||||||
sigemptyset(&nmask);
|
|
||||||
sigaddset(&nmask, SIGCHLD);
|
|
||||||
sigprocmask(SIG_UNBLOCK, &nmask, NULL);
|
|
||||||
|
|
||||||
/* Reset signal handlers that were set by the parent process */
|
sig_unblock();
|
||||||
for (i = 1; i < NSIG; i++)
|
|
||||||
DFLSIG(sa, i, 0);
|
setsid();
|
||||||
|
|
||||||
|
if (ioctl(STDIN_FILENO, TIOCSCTTY, 1) < 0)
|
||||||
|
_pe("Failed TIOCSCTTY");
|
||||||
|
|
||||||
while (!fexist(SYNC_SHUTDOWN)) {
|
while (!fexist(SYNC_SHUTDOWN)) {
|
||||||
static const char msg[] = "\nPlease press Enter to activate this console.";
|
static const char msg[] = "\nPlease press Enter to activate this console.";
|
||||||
@@ -629,7 +629,7 @@ pid_t run_getty(char *cmd, char *args[], int console)
|
|||||||
int run_parts(char *dir, char *cmd)
|
int run_parts(char *dir, char *cmd)
|
||||||
{
|
{
|
||||||
struct dirent **e;
|
struct dirent **e;
|
||||||
int i, num;
|
volatile int i, num;
|
||||||
|
|
||||||
num = scandir(dir, &e, NULL, alphasort);
|
num = scandir(dir, &e, NULL, alphasort);
|
||||||
if (num < 0) {
|
if (num < 0) {
|
||||||
@@ -669,9 +669,10 @@ int run_parts(char *dir, char *cmd)
|
|||||||
}
|
}
|
||||||
args[j++] = NULL;
|
args[j++] = NULL;
|
||||||
|
|
||||||
pid = fork();
|
pid = vfork();
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
_d("Calling %s ...", path);
|
_d("Calling %s ...", path);
|
||||||
|
sig_unblock();
|
||||||
execv(path, args);
|
execv(path, args);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
Submodule
+1
Submodule libuev added at 5c7a6f1163
@@ -36,10 +36,8 @@
|
|||||||
|
|
||||||
#define is_io_plugin(p) ((p)->io.cb && (p)->io.fd >= 0)
|
#define is_io_plugin(p) ((p)->io.cb && (p)->io.fd >= 0)
|
||||||
|
|
||||||
static char *plugpath = NULL; /* Set by first load. */
|
static char *plugpath = NULL; /* Set by first load. */
|
||||||
static size_t num_fds = 0;
|
static TAILQ_HEAD(, plugin) plugins = TAILQ_HEAD_INITIALIZER(plugins);
|
||||||
static struct pollfd fds[MAX_NUM_FDS];
|
|
||||||
static TAILQ_HEAD(, plugin) plugins = TAILQ_HEAD_INITIALIZER(plugins);
|
|
||||||
|
|
||||||
static void check_plugin_depends(plugin_t *plugin);
|
static void check_plugin_depends(plugin_t *plugin);
|
||||||
|
|
||||||
@@ -69,15 +67,8 @@ int plugin_register(plugin_t *plugin)
|
|||||||
|
|
||||||
check_plugin_depends(plugin);
|
check_plugin_depends(plugin);
|
||||||
|
|
||||||
if (is_io_plugin(plugin)) {
|
if (is_io_plugin(plugin))
|
||||||
if (num_fds + 1 >= MAX_NUM_FDS) {
|
|
||||||
num_fds = MAX_NUM_SVC;
|
|
||||||
errno = ENOMEM;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
num_fds++;
|
|
||||||
inuse++;
|
inuse++;
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin->svc.cb) {
|
if (plugin->svc.cb) {
|
||||||
svc_t *svc = svc_find(plugin->name);
|
svc_t *svc = svc_find(plugin->name);
|
||||||
@@ -189,62 +180,29 @@ void plugin_run_hooks(hook_point_t no)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Generic libev I/O callback, looks up correct plugin and calls its callback */
|
/* Generic libev I/O callback, looks up correct plugin and calls its callback */
|
||||||
static void generic_io_cb(struct pollfd *io)
|
static void generic_io_cb(uev_ctx_t *UNUSED(ctx), uev_t *w, void *arg, int events)
|
||||||
{
|
{
|
||||||
plugin_t *p, *tmp;
|
plugin_t *p = (plugin_t *)arg;
|
||||||
|
|
||||||
/* Find matching plugin, pick first matching fd */
|
if (is_io_plugin(p) && p->io.fd == w->fd) {
|
||||||
PLUGIN_ITERATOR(p, tmp) {
|
_d("Calling I/O %s from runloop...", basename(p->name));
|
||||||
if (is_io_plugin(p) && p->io.fd == io->fd) {
|
p->io.cb(p->io.arg, w->fd, events);
|
||||||
_d("Calling I/O %s from runloop...", basename(p->name));
|
|
||||||
p->io.cb(p->io.arg, io->fd, io->events);
|
|
||||||
|
|
||||||
/* Update fd, may be changed by plugin callback, e.g., if FIFO */
|
/* Update fd, may be changed by plugin callback, e.g., if FIFO */
|
||||||
io->fd = p->io.fd;
|
if (p->io.fd != w->fd)
|
||||||
io->events = p->io.flags;
|
uev_io_set (w, p->io.fd, p->io.flags);
|
||||||
io->revents = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void plugin_monitor(void)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
while ((ret = poll(fds, num_fds, 500))) {
|
|
||||||
if (-1 == ret) {
|
|
||||||
if (EINTR == errno)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
_e("Failed polling I/O plugin descriptors, error %d: %s",
|
|
||||||
errno, strerror(errno));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Traverse all I/O fds and run callbacks */
|
|
||||||
for (i = 0; i < num_fds; i++) {
|
|
||||||
if (fds[i].revents)
|
|
||||||
generic_io_cb(&fds[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup any I/O callbacks for plugins that use them */
|
/* Setup any I/O callbacks for plugins that use them */
|
||||||
static void init_plugins(void)
|
static void init_plugins(uev_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
int i = 0;
|
|
||||||
plugin_t *p, *tmp;
|
plugin_t *p, *tmp;
|
||||||
|
|
||||||
PLUGIN_ITERATOR(p, tmp) {
|
PLUGIN_ITERATOR(p, tmp) {
|
||||||
if (is_io_plugin(p)) {
|
if (is_io_plugin(p)) {
|
||||||
_d("Initializing plugin %s for I/O", basename(p->name));
|
_d("Initializing plugin %s for I/O", basename(p->name));
|
||||||
fds[i].revents = 0;
|
uev_io_init(ctx, &p->watcher, generic_io_cb, p, p->io.fd, p->io.flags);
|
||||||
fds[i].events = p->io.flags;
|
|
||||||
fds[i++].fd = p->io.fd;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -318,7 +276,7 @@ static void check_plugin_depends(plugin_t *plugin)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int plugin_load_all(char *path)
|
int plugin_load_all(uev_ctx_t *ctx, char *path)
|
||||||
{
|
{
|
||||||
int fail = 0;
|
int fail = 0;
|
||||||
DIR *dp = opendir(path);
|
DIR *dp = opendir(path);
|
||||||
@@ -341,7 +299,7 @@ int plugin_load_all(char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
closedir(dp);
|
closedir(dp);
|
||||||
init_plugins();
|
init_plugins(ctx);
|
||||||
|
|
||||||
return fail;
|
return fail;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,13 +24,13 @@
|
|||||||
#ifndef FINIT_PLUGIN_H_
|
#ifndef FINIT_PLUGIN_H_
|
||||||
#define FINIT_PLUGIN_H_
|
#define FINIT_PLUGIN_H_
|
||||||
|
|
||||||
#include <poll.h>
|
|
||||||
#include "queue.h" /* BSD sys/queue.h API */
|
#include "queue.h" /* BSD sys/queue.h API */
|
||||||
#include "svc.h"
|
#include "svc.h"
|
||||||
|
#include "libuev/uev.h"
|
||||||
|
|
||||||
#define PLUGIN_DEP_MAX 10
|
#define PLUGIN_DEP_MAX 10
|
||||||
#define PLUGIN_IO_READ POLLIN
|
#define PLUGIN_IO_READ UEV_READ
|
||||||
#define PLUGIN_IO_WRITE POLLOUT
|
#define PLUGIN_IO_WRITE UEV_WRITE
|
||||||
|
|
||||||
#define PLUGIN_INIT(x) static void __attribute__ ((constructor)) x(void)
|
#define PLUGIN_INIT(x) static void __attribute__ ((constructor)) x(void)
|
||||||
#define PLUGIN_EXIT(x) static void __attribute__ ((destructor)) x(void)
|
#define PLUGIN_EXIT(x) static void __attribute__ ((destructor)) x(void)
|
||||||
@@ -79,6 +79,9 @@ typedef struct plugin {
|
|||||||
/* BSD sys/queue.h linked list node. */
|
/* BSD sys/queue.h linked list node. */
|
||||||
TAILQ_ENTRY(plugin) link;
|
TAILQ_ENTRY(plugin) link;
|
||||||
|
|
||||||
|
/* Event loop handler, used internally by Finit */
|
||||||
|
uev_t watcher;
|
||||||
|
|
||||||
/* Plugin name, defaults to basename of plugin path if unset.
|
/* Plugin name, defaults to basename of plugin path if unset.
|
||||||
* NOTE: Must be same as @cmd for service plugins! */
|
* NOTE: Must be same as @cmd for service plugins! */
|
||||||
char *name;
|
char *name;
|
||||||
|
|||||||
+3
-2
@@ -26,16 +26,17 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
|
#include "libite/lite.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
|
||||||
static void setup(void *UNUSED(arg))
|
static void setup(void *UNUSED(arg))
|
||||||
{
|
{
|
||||||
#ifdef RANDOMSEED
|
#ifdef RANDOMSEED
|
||||||
copyfile(RANDOMSEED, "/dev/urandom", 0);
|
copyfile(RANDOMSEED, "/dev/urandom", 0, 0);
|
||||||
unlink(RANDOMSEED);
|
unlink(RANDOMSEED);
|
||||||
umask(077);
|
umask(077);
|
||||||
copyfile("/dev/urandom", RANDOMSEED, 4096);
|
copyfile("/dev/urandom", RANDOMSEED, 4096, 0);
|
||||||
umask(0);
|
umask(0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,11 +29,10 @@
|
|||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
|
||||||
void svc_bootstrap (void);
|
void svc_bootstrap (void);
|
||||||
void svc_monitor (void);
|
void svc_monitor (pid_t lost);
|
||||||
|
|
||||||
void plugin_run_hooks (hook_point_t no);
|
void plugin_run_hooks (hook_point_t no);
|
||||||
int plugin_load_all (char *path);
|
int plugin_load_all (uev_ctx_t *ctx, char *path);
|
||||||
void plugin_monitor (void);
|
|
||||||
|
|
||||||
#endif /* FINIT_PRIVATE_H_ */
|
#endif /* FINIT_PRIVATE_H_ */
|
||||||
|
|
||||||
|
|||||||
@@ -47,9 +47,13 @@
|
|||||||
#include "private.h"
|
#include "private.h"
|
||||||
#include "sig.h"
|
#include "sig.h"
|
||||||
|
|
||||||
static int stopped = 0;
|
static int stopped = 0;
|
||||||
|
static uev_t sigint_watcher, sigpwr_watcher;
|
||||||
|
static uev_t sigchld_watcher;
|
||||||
|
static uev_t sigstop_watcher, sigtstp_watcher, sigcont_watcher;
|
||||||
|
|
||||||
void do_shutdown (int sig)
|
|
||||||
|
void do_shutdown(int sig)
|
||||||
{
|
{
|
||||||
touch(SYNC_SHUTDOWN);
|
touch(SYNC_SHUTDOWN);
|
||||||
|
|
||||||
@@ -84,38 +88,35 @@ void do_shutdown (int sig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Shut down on INT USR1 USR2
|
* Shut down on INT PWR
|
||||||
*/
|
*/
|
||||||
static void shutdown_handler(int sig, siginfo_t *info, void *UNUSED(ctx))
|
static void sigint_cb(uev_ctx_t *UNUSED(ctx), uev_t *w, void *UNUSED(arg), int UNUSED(events))
|
||||||
{
|
{
|
||||||
_d("Rebooting on signal %d from %s (PID %d)",
|
do_shutdown(w->signo);
|
||||||
sig, pid_get_name(info->si_pid, NULL, 0), info->si_pid);
|
|
||||||
|
|
||||||
do_shutdown(sig);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SIGCHLD: one of our children has died
|
* SIGCHLD: one of our children has died
|
||||||
*/
|
*/
|
||||||
static void chld_handler(int UNUSED(sig), siginfo_t *UNUSED(info), void *UNUSED(ctx))
|
static void sigchld_cb(uev_ctx_t *UNUSED(ctx), uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
|
||||||
{
|
{
|
||||||
/* Do nothing, the svc_monitor() is the designated child reaper. */
|
svc_monitor(waitpid(-1, NULL, WNOHANG));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SIGSTOP: Paused by user or netflash
|
* SIGSTOP/SIGTSTP: Paused by user or netflash
|
||||||
*/
|
*/
|
||||||
static void sigstop_handler(int sig, siginfo_t *info, void *UNUSED(ctx))
|
static void sigstop_cb(uev_ctx_t *UNUSED(ctx), uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
|
||||||
{
|
{
|
||||||
_d("Received SIGSTOP(%d) from %s (PID %d)",
|
|
||||||
sig, pid_get_name(info->si_pid, NULL, 0), info->si_pid);
|
|
||||||
touch(SYNC_STOPPED);
|
touch(SYNC_STOPPED);
|
||||||
stopped++;
|
stopped++;
|
||||||
}
|
}
|
||||||
static void sigcont_handler(int sig, siginfo_t *info, void *UNUSED(ctx))
|
|
||||||
|
/*
|
||||||
|
* SIGCONT: Restart service monitor
|
||||||
|
*/
|
||||||
|
static void sigcont_cb(uev_ctx_t *UNUSED(ctx), uev_t *UNUSED(w), void *UNUSED(arg), int UNUSED(events))
|
||||||
{
|
{
|
||||||
_d("Received SIGCONT(%d) from %s (PID %d)",
|
|
||||||
sig, pid_get_name(info->si_pid, NULL, 0), info->si_pid);
|
|
||||||
stopped = 0;
|
stopped = 0;
|
||||||
erase(SYNC_STOPPED);
|
erase(SYNC_STOPPED);
|
||||||
}
|
}
|
||||||
@@ -131,6 +132,11 @@ int sig_stopped(void)
|
|||||||
/*
|
/*
|
||||||
* Inital signal setup - ignore everything but SIGCHLD until we're capable of responding
|
* Inital signal setup - ignore everything but SIGCHLD until we're capable of responding
|
||||||
*/
|
*/
|
||||||
|
static void chld_handler(int UNUSED(sig), siginfo_t *UNUSED(info), void *UNUSED(ctx))
|
||||||
|
{
|
||||||
|
/* NOP */
|
||||||
|
}
|
||||||
|
|
||||||
void sig_init(void)
|
void sig_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -142,10 +148,33 @@ void sig_init(void)
|
|||||||
SETSIG(sa, SIGCHLD, chld_handler, SA_RESTART);
|
SETSIG(sa, SIGCHLD, chld_handler, SA_RESTART);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unblock all signals blocked by finit when starting children
|
||||||
|
*/
|
||||||
|
void sig_unblock(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
sigset_t nmask;
|
||||||
|
struct sigaction sa;
|
||||||
|
|
||||||
|
sigemptyset(&nmask);
|
||||||
|
sigaddset(&nmask, SIGCHLD);
|
||||||
|
sigaddset(&nmask, SIGINT);
|
||||||
|
sigaddset(&nmask, SIGPWR);
|
||||||
|
sigaddset(&nmask, SIGSTOP);
|
||||||
|
sigaddset(&nmask, SIGTSTP);
|
||||||
|
sigaddset(&nmask, SIGCONT);
|
||||||
|
sigprocmask(SIG_UNBLOCK, &nmask, NULL);
|
||||||
|
|
||||||
|
/* Reset signal handlers that were set by the parent process */
|
||||||
|
for (i = 1; i < NSIG; i++)
|
||||||
|
DFLSIG(sa, i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup limited set of SysV compatible signals to respond to
|
* Setup limited set of SysV compatible signals to respond to
|
||||||
*/
|
*/
|
||||||
void sig_setup(void)
|
void sig_setup(uev_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
|
|
||||||
@@ -156,12 +185,12 @@ void sig_setup(void)
|
|||||||
erase(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);
|
uev_signal_init(ctx, &sigint_watcher, sigint_cb, NULL, SIGINT);
|
||||||
SETSIG(sa, SIGPWR, shutdown_handler, 0);
|
uev_signal_init(ctx, &sigpwr_watcher, sigint_cb, NULL, SIGPWR);
|
||||||
|
|
||||||
/* Ignore SIGUSR1/2 for now, only BusyBox init implements them as reboot+halt. */
|
/* Ignore SIGUSR1/2 for now, only BusyBox init implements them as reboot+halt. */
|
||||||
// SETSIG2(sa, SIGUSR1, reopen_initctl, 0);
|
// uev_signal_init(&ctx, &sigusr1_watcher, reopen_initctl_cb, NULL, SIGUSR1);
|
||||||
// SETSIG2(sa, SIGUSR2, pwrdwn_handler, 0);
|
// uev_signal_init(&ctx, &sigusr2_watcher, pwrdwn_cb, NULL, SIGUSR2);
|
||||||
|
|
||||||
/* Init must ignore SIGTERM. May otherwise get false SIGTERM in forked children! */
|
/* Init must ignore SIGTERM. May otherwise get false SIGTERM in forked children! */
|
||||||
IGNSIG(sa, SIGTERM, 0);
|
IGNSIG(sa, SIGTERM, 0);
|
||||||
@@ -172,10 +201,13 @@ void sig_setup(void)
|
|||||||
/* We don't have any /etc/inittab yet, reread finit.conf? */
|
/* We don't have any /etc/inittab yet, reread finit.conf? */
|
||||||
IGNSIG(sa, SIGHUP, 0);
|
IGNSIG(sa, SIGHUP, 0);
|
||||||
|
|
||||||
|
/* After initial bootstrap of Finit we call the service monitor to reap children */
|
||||||
|
uev_signal_init(ctx, &sigchld_watcher, sigchld_cb, NULL, SIGCHLD);
|
||||||
|
|
||||||
/* Stopping init is a bit tricky. */
|
/* Stopping init is a bit tricky. */
|
||||||
SETSIG(sa, SIGSTOP, sigstop_handler, 0);
|
uev_signal_init(ctx, &sigstop_watcher, sigstop_cb, NULL, SIGSTOP);
|
||||||
SETSIG(sa, SIGTSTP, sigstop_handler, 0);
|
uev_signal_init(ctx, &sigtstp_watcher, sigstop_cb, NULL, SIGTSTP);
|
||||||
SETSIG(sa, SIGCONT, sigcont_handler, 0);
|
uev_signal_init(ctx, &sigcont_watcher, sigcont_cb, NULL, SIGCONT);
|
||||||
|
|
||||||
/* Disable CTRL-ALT-DELETE from kernel, we handle shutdown gracefully with SIGINT, above */
|
/* Disable CTRL-ALT-DELETE from kernel, we handle shutdown gracefully with SIGINT, above */
|
||||||
reboot(RB_DISABLE_CAD);
|
reboot(RB_DISABLE_CAD);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#define FINIT_SIG_H_
|
#define FINIT_SIG_H_
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include "libuev/uev.h"
|
||||||
|
|
||||||
#define SYNC_SHUTDOWN "/var/lock/finit.shutdown"
|
#define SYNC_SHUTDOWN "/var/lock/finit.shutdown"
|
||||||
#define SYNC_STOPPED "/var/lock/finit.stopped"
|
#define SYNC_STOPPED "/var/lock/finit.stopped"
|
||||||
@@ -57,7 +58,8 @@
|
|||||||
void do_shutdown (int sig);
|
void do_shutdown (int sig);
|
||||||
int sig_stopped (void);
|
int sig_stopped (void);
|
||||||
void sig_init (void);
|
void sig_init (void);
|
||||||
void sig_setup (void);
|
void sig_unblock (void);
|
||||||
|
void sig_setup (uev_ctx_t *ctx);
|
||||||
|
|
||||||
#endif /* FINIT_SIG_H_ */
|
#endif /* FINIT_SIG_H_ */
|
||||||
|
|
||||||
|
|||||||
@@ -362,9 +362,8 @@ static void restart_any_lost_procs(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void svc_monitor(void)
|
void svc_monitor(pid_t lost)
|
||||||
{
|
{
|
||||||
pid_t lost;
|
|
||||||
svc_t *svc;
|
svc_t *svc;
|
||||||
|
|
||||||
if (was_stopped && !is_norespawn()) {
|
if (was_stopped && !is_norespawn()) {
|
||||||
@@ -373,10 +372,6 @@ void svc_monitor(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lost = waitpid(-1, NULL, WNOHANG);
|
|
||||||
if (lost < 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (fexist(SYNC_SHUTDOWN) || lost <= 1)
|
if (fexist(SYNC_SHUTDOWN) || lost <= 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -458,7 +453,7 @@ int svc_start(svc_t *svc)
|
|||||||
sigaddset(&nmask, SIGCHLD);
|
sigaddset(&nmask, SIGCHLD);
|
||||||
sigprocmask(SIG_BLOCK, &nmask, &omask);
|
sigprocmask(SIG_BLOCK, &nmask, &omask);
|
||||||
|
|
||||||
pid = fork();
|
pid = vfork();
|
||||||
sigprocmask(SIG_SETMASK, &omask, NULL);
|
sigprocmask(SIG_SETMASK, &omask, NULL);
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ void tty_start(finit_tty_t *tty)
|
|||||||
#elif defined(GETTY_BUSYBOX)
|
#elif defined(GETTY_BUSYBOX)
|
||||||
snprintf(line, sizeof(line), "%s %d %s %s", GETTY, tty->baud, tty->name, tty->term ?: "");
|
snprintf(line, sizeof(line), "%s %d %s %s", GETTY, tty->baud, tty->name, tty->term ?: "");
|
||||||
#else
|
#else
|
||||||
strlcpy(line, FALLBACK_CONSOLE, sizeof(line));
|
strlcpy(line, FALLBACK_SHELL, sizeof(line));
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
strlcpy(line, tty->name, sizeof(line));
|
strlcpy(line, tty->name, sizeof(line));
|
||||||
@@ -179,7 +179,7 @@ int tty_enabled(finit_tty_t *tty, int runlevel)
|
|||||||
|
|
||||||
if (!ISSET(tty->runlevels, runlevel))
|
if (!ISSET(tty->runlevels, runlevel))
|
||||||
return 0;
|
return 0;
|
||||||
else if (fexist(tty->name))
|
if (fexist(tty->name))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user