mirror of
https://github.com/troglobit/finit.git
synced 2026-10-12 10:12:32 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f32e4d4b30 | ||
|
|
eff87b3dc5 | ||
|
|
ea4821fd18 | ||
|
|
6285668dcd | ||
|
|
449bc7d12b | ||
|
|
ee867e7f3b | ||
|
|
b4c7ae9c8c | ||
|
|
95995a45cf | ||
|
|
823bb82b8c | ||
|
|
9a5bb46f78 | ||
|
|
950ca953f5 | ||
|
|
495c8c9eac | ||
|
|
2887795586 | ||
|
|
6a893f50ae | ||
|
|
5d08353284 | ||
|
|
a37037ded4 | ||
|
|
d331b72dfd | ||
|
|
3b21d35f23 | ||
|
|
62a694b8b7 | ||
|
|
eeba2960f9 | ||
|
|
91550c926b | ||
|
|
184525687c | ||
|
|
cdede817fd | ||
|
|
df42c2f6fe | ||
|
|
b53f2f4a60 | ||
|
|
5ff27c4fe2 | ||
|
|
e5fff5117d | ||
|
|
615cd5aac3 | ||
|
|
621d95a89e | ||
|
|
cd383167f9 | ||
|
|
cb2969002c | ||
|
|
1cf204e23d | ||
|
|
393834b253 | ||
|
|
4ca8256e18 | ||
|
|
280d91b9bf | ||
|
|
980152fd53 | ||
|
|
d994420d4d | ||
|
|
38f3ecf01f | ||
|
|
5cd0d05b31 | ||
|
|
62519c3638 | ||
|
|
27bb2deb1a | ||
|
|
a2c8e71f14 | ||
|
|
d1f56e7c2e | ||
|
|
a9fd0cbf02 | ||
|
|
be8c89ec00 | ||
|
|
4f53752693 | ||
|
|
393673222d | ||
|
|
a88f4524d5 | ||
|
|
3a02066a66 | ||
|
|
7e3981d1a3 | ||
|
|
ec2900e4dd | ||
|
|
d718a27abf | ||
|
|
db8027911c | ||
|
|
aef3b4117d | ||
|
|
6728b77aca | ||
|
|
a7c0b42965 | ||
|
|
667b6ecbbd | ||
|
|
b852878a4a | ||
|
|
940f1f7486 | ||
|
|
49c705b5ad | ||
|
|
5163e8a433 | ||
|
|
71e9603e4e | ||
|
|
c71102f44e | ||
|
|
9b9158a765 | ||
|
|
595e2b4e81 | ||
|
|
ae8e205343 | ||
|
|
00b33fbd42 | ||
|
|
841b06df37 | ||
|
|
522a06f864 | ||
|
|
fa14ed1649 | ||
|
|
64e41e066b | ||
|
|
2a71f35005 | ||
|
|
961a337a5e | ||
|
|
f0622a692e | ||
|
|
ef7042dd9d | ||
|
|
046ecfa329 | ||
|
|
47fbe49861 | ||
|
|
2f34315634 |
@@ -0,0 +1,68 @@
|
|||||||
|
name: Bob the Builder
|
||||||
|
|
||||||
|
# Run on all branches, including all pull requests, except the 'dev'
|
||||||
|
# branch since that's where we run Coverity Scan (limited tokens/day)
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- '**'
|
||||||
|
- '!dev'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- '**'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
# Verify we can build on latest Ubuntu with both gcc and clang
|
||||||
|
name: ${{ matrix.compiler }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
compiler: [gcc, clang]
|
||||||
|
fail-fast: false
|
||||||
|
env:
|
||||||
|
MAKEFLAGS: -j3
|
||||||
|
CC: ${{ matrix.compiler }}
|
||||||
|
steps:
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get -y update
|
||||||
|
sudo apt-get -y install pkg-config
|
||||||
|
wget https://github.com/troglobit/libuev/releases/download/v2.3.2/libuev-2.3.2.tar.xz
|
||||||
|
wget https://github.com/troglobit/libite/releases/download/v2.3.1/libite-2.3.1.tar.gz
|
||||||
|
tar xf libuev-2.3.2.tar.xz
|
||||||
|
tar xf libite-2.3.1.tar.gz
|
||||||
|
(cd libuev-2.3.2 && ./configure --prefix=/usr && make && sudo make install-strip)
|
||||||
|
(cd libite-2.3.1 && ./configure --prefix=/usr && make && sudo make install-strip)
|
||||||
|
sudo ldconfig
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Static Finit
|
||||||
|
run: |
|
||||||
|
./autogen.sh
|
||||||
|
./configure --prefix= --enable-static
|
||||||
|
make V=1
|
||||||
|
- name: Regular Finit
|
||||||
|
run: |
|
||||||
|
./configure --prefix= --enable-x11-common-plugin --with-watchdog --with-keventd
|
||||||
|
make clean
|
||||||
|
make V=1
|
||||||
|
- name: Install to ~/tmp and Inspect
|
||||||
|
run: |
|
||||||
|
DESTDIR=/tmp make install-strip
|
||||||
|
tree /tmp
|
||||||
|
ldd /tmp/sbin/finit
|
||||||
|
size /tmp/sbin/finit
|
||||||
|
ldd /tmp/sbin/initctl
|
||||||
|
size /tmp/sbin/initctl
|
||||||
|
ldd /tmp/sbin/reboot
|
||||||
|
size /tmp/sbin/reboot
|
||||||
|
/tmp/sbin/finit -h
|
||||||
|
/tmp/sbin/initctl -h
|
||||||
|
- name: Run Unit Tests
|
||||||
|
run: |
|
||||||
|
make -j1 distcheck
|
||||||
|
- name: Upload Test Results
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: finit-test-${{ matrix.compiler }}
|
||||||
|
path: test/*
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
name: Coverity Scan
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'dev'
|
||||||
|
|
||||||
|
env:
|
||||||
|
PROJECT_NAME: finit
|
||||||
|
CONTACT_EMAIL: troglobit@gmail.com
|
||||||
|
COVERITY_NAME: troglobit-finit
|
||||||
|
COVERITY_PROJ: troglobit%2Ffinit
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
coverity:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/cache@v2
|
||||||
|
id: coverity-toolchain-cache
|
||||||
|
with:
|
||||||
|
path: cov-analysis-linux64
|
||||||
|
key: ${{ runner.os }}-coverity
|
||||||
|
- name: Download Coverity Scan
|
||||||
|
if: steps.coverity-toolchain-cache.outputs.cache-hit != 'true'
|
||||||
|
env:
|
||||||
|
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
||||||
|
run: |
|
||||||
|
wget -q https://scan.coverity.com/download/cxx/linux64 \
|
||||||
|
--post-data "token=$TOKEN&project=${COVERITY_PROJ}" \
|
||||||
|
-O cov-analysis-linux64.tar.gz
|
||||||
|
mkdir cov-analysis-linux64
|
||||||
|
tar xzf cov-analysis-linux64.tar.gz --strip 1 -C cov-analysis-linux64
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get -y update
|
||||||
|
sudo apt-get -y install pkg-config
|
||||||
|
wget https://github.com/troglobit/libuev/releases/download/v2.3.2/libuev-2.3.2.tar.xz
|
||||||
|
wget https://github.com/troglobit/libite/releases/download/v2.3.1/libite-2.3.1.tar.gz
|
||||||
|
tar xf libuev-2.3.2.tar.xz
|
||||||
|
tar xf libite-2.3.1.tar.gz
|
||||||
|
(cd libuev-2.3.2 && ./configure --prefix=/usr && make && sudo make install-strip)
|
||||||
|
(cd libite-2.3.1 && ./configure --prefix=/usr && make && sudo make install-strip)
|
||||||
|
sudo ldconfig
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
./autogen.sh
|
||||||
|
./configure --prefix= --enable-x11-common-plugin --with-watchdog --with-keventd
|
||||||
|
export PATH=`pwd`/cov-analysis-linux64/bin:$PATH
|
||||||
|
cov-build --dir cov-int make
|
||||||
|
- name: Submit result to Coverity Scan
|
||||||
|
env:
|
||||||
|
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
||||||
|
run: |
|
||||||
|
tar czvf ${PROJECT_NAME}.tgz cov-int
|
||||||
|
curl \
|
||||||
|
--form project=${COVERITY_NAME} \
|
||||||
|
--form token=$TOKEN \
|
||||||
|
--form email=${CONTACT_EMAIL} \
|
||||||
|
--form file=@${PROJECT_NAME}.tgz \
|
||||||
|
--form version=trunk \
|
||||||
|
--form description="${PROJECT_NAME} $(git rev-parse HEAD)" \
|
||||||
|
https://scan.coverity.com/builds?project=${COVERITY_PROJ}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
name: Release General
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '[0-9]+.[0-9]+'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
name: Create GitHub release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
|
outputs:
|
||||||
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
|
release_id: ${{ steps.create_release.outputs.id }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Extract ChangeLog entry ...
|
||||||
|
# Hack to extract latest entry for body_path below
|
||||||
|
run: |
|
||||||
|
awk '/-----*/{if (x == 1) exit; x=1;next}x' ChangeLog.md \
|
||||||
|
|head -n -1 > release.md
|
||||||
|
cat release.md
|
||||||
|
- name: Create release ...
|
||||||
|
id: create_release
|
||||||
|
uses: actions/create-release@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
tag_name: ${{ github.ref }}
|
||||||
|
release_name: Finit v${{ github.ref }}
|
||||||
|
body_path: release.md
|
||||||
|
draft: false
|
||||||
|
prerelease: false
|
||||||
|
tarball:
|
||||||
|
name: Build and upload release tarball
|
||||||
|
needs: release
|
||||||
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Installing dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get -y update
|
||||||
|
sudo apt-get -y install pkg-config
|
||||||
|
wget https://github.com/troglobit/libuev/releases/download/v2.3.2/libuev-2.3.2.tar.xz
|
||||||
|
wget https://github.com/troglobit/libite/releases/download/v2.3.1/libite-2.3.1.tar.gz
|
||||||
|
tar xf libuev-2.3.2.tar.xz
|
||||||
|
tar xf libite-2.3.1.tar.gz
|
||||||
|
(cd libuev-2.3.2 && ./configure --prefix=/usr && make && sudo make install-strip)
|
||||||
|
(cd libite-2.3.1 && ./configure --prefix=/usr && make && sudo make install-strip)
|
||||||
|
sudo ldconfig
|
||||||
|
- name: Creating Makefiles
|
||||||
|
run: |
|
||||||
|
./autogen.sh
|
||||||
|
./configure --prefix= --enable-x11-common-plugin --with-watchdog --with-keventd
|
||||||
|
- name: Building release
|
||||||
|
run: |
|
||||||
|
make release
|
||||||
|
ls -lF ../
|
||||||
|
mkdir -p artifacts/
|
||||||
|
mv ../*.tar.* artifacts/
|
||||||
|
- name: Uploading release artifacts
|
||||||
|
uses: skx/github-action-publish-binaries@release-0.15
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
releaseId: ${{ needs.release.outputs.release_id }}
|
||||||
|
args: artifacts/*
|
||||||
-62
@@ -1,62 +0,0 @@
|
|||||||
# Travis CI integration -- https://travis-ci.org/troglobit/finit
|
|
||||||
# Defaults to GNU GCC and autotools: ./configure && make && make test
|
|
||||||
language: c
|
|
||||||
|
|
||||||
# Use docker for quicker builds, it now allows https://docs.travis-ci.com/user/apt/
|
|
||||||
sudo: false
|
|
||||||
|
|
||||||
# Test build with both GCC and Clang (LLVM)
|
|
||||||
compiler:
|
|
||||||
- gcc
|
|
||||||
- clang
|
|
||||||
|
|
||||||
# The secure: declaration is the encrypted COVERITY_SCAN_TOKEN, created
|
|
||||||
# via the "travis encrypt" command using the project repo's public key
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- PKG_CONFIG_PATH=/tmp/lib/pkgconfig
|
|
||||||
- CFLAGS="-W -Wall -Wextra"
|
|
||||||
- secure: "eOiuHs02lG2Uv146K9dMqucGTWUJFEhpz1oAtwe+kPrRXsXWc20hYMO+DSpMgD05vSvNeQA6p7h7LdRFQ+/g/Obj27TsOE+RKkUvRAtdwzxnKVyii9C/nmML8cFw7rIA0VS8O9mAkVYeyDxNDupBp3e9DPCibhKPvqCvioTnyy4="
|
|
||||||
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- tree
|
|
||||||
coverity_scan:
|
|
||||||
project:
|
|
||||||
name: "troglobit/finit"
|
|
||||||
description: "finit | Fast & Extensible init for Linux"
|
|
||||||
notification_email: troglobit@gmail.com
|
|
||||||
build_command_prepend: "./autogen.sh && ./configure --prefix= --disable-doc --disable-contrib --with-watchdog"
|
|
||||||
build_command: "make"
|
|
||||||
branch_pattern: dev
|
|
||||||
|
|
||||||
install:
|
|
||||||
- wget https://github.com/troglobit/libuev/releases/download/v2.3.2/libuev-2.3.2.tar.xz
|
|
||||||
- wget https://github.com/troglobit/libite/releases/download/v2.3.1/libite-2.3.1.tar.gz
|
|
||||||
- tar xf libuev-2.3.2.tar.xz
|
|
||||||
- tar xf libite-2.3.1.tar.gz
|
|
||||||
- (cd libuev-2.3.2 && ./configure --prefix=/tmp && make && make install-strip)
|
|
||||||
- (cd libite-2.3.1 && ./configure --prefix=/tmp && make && make install-strip)
|
|
||||||
|
|
||||||
# Custom build script for the time being, no "make test" yet
|
|
||||||
script:
|
|
||||||
- ./autogen.sh
|
|
||||||
- ./configure --prefix= --enable-static
|
|
||||||
- make clean
|
|
||||||
- make V=1 -j5
|
|
||||||
- ./configure --prefix= --enable-x11-common-plugin --with-watchdog --with-keventd
|
|
||||||
- cat config.log
|
|
||||||
- make clean
|
|
||||||
- make V=1 -j5
|
|
||||||
- make install-strip DESTDIR=/tmp/finit
|
|
||||||
- tree /tmp/finit
|
|
||||||
- ldd /tmp/finit/sbin/finit
|
|
||||||
- size /tmp/finit/sbin/finit
|
|
||||||
- size /tmp/finit/sbin/initctl
|
|
||||||
- size /tmp/finit/sbin/reboot
|
|
||||||
- LD_LIBRARY_PATH=/tmp/lib /tmp/finit/sbin/initctl -h
|
|
||||||
- unshare -V
|
|
||||||
- nsenter -V
|
|
||||||
- chroot --version
|
|
||||||
- 'LD_LIBRARY_PATH=/tmp/lib make distcheck || (cat finit-4.0-beta1/_build/sub/test/test-suite.log; exit 1)'
|
|
||||||
+71
-7
@@ -4,6 +4,69 @@ Change Log
|
|||||||
All relevant changes are documented in this file.
|
All relevant changes are documented in this file.
|
||||||
|
|
||||||
|
|
||||||
|
[4.2][] - 2022-01-16
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
* Support for non-root users to use `initctl`, e.g. group wheel
|
||||||
|
* Support for new libite (-lite) header namespace
|
||||||
|
* RTC plugin now reset an invalid RTC time to the kernel default
|
||||||
|
time, 2000-01-01 00:00, prevents errors and is less crazy than
|
||||||
|
some systems coming with with <= Jan 1, 1970
|
||||||
|
* urandom plugin now use RNDADDENTROPY ioctl to seed kernel rng,
|
||||||
|
incrementing entropy count. Also, 32 kiB instead of 512 bytes are
|
||||||
|
now saved (and restored) on reboot. This should greatly improve
|
||||||
|
reliability of systems with none or poor HWRNG
|
||||||
|
* Kernel logging to console (loglevel >= 7, debug, when quiet mode is
|
||||||
|
not used) is now honored by Finit, regardless of the finit.debug
|
||||||
|
command line option
|
||||||
|
* Reduced default log level from `LOG_NOTICE` to `LOG_INFO`
|
||||||
|
* Wrapped all calls to mount(2) to add logging in case of failure
|
||||||
|
* New configure options to control fastboot (no fsck) and fsck fix
|
||||||
|
options, by Ming Liu, Atlas Copco
|
||||||
|
* Support for overriding default `/etc/nologin` file with an external
|
||||||
|
`#define`, by Ming Liu, Atlas Copco
|
||||||
|
* Support for overriding default `/var/run/dbus/pid` file with an
|
||||||
|
external `#define`, by Ming Liu, Atlas Copco
|
||||||
|
* Support for more service options to control respawn behavior of
|
||||||
|
crashing services, by Robert Andersson and Ming Liu, Atlas Copco
|
||||||
|
* Support for `initctl ident [NAME]` which lists all instances of
|
||||||
|
`NAME`, or all enabled system run/tasks and services
|
||||||
|
* Show number of total restarts and current respawn count for a
|
||||||
|
service in `initctl status foo`
|
||||||
|
* Crashing services no longer have the crash/restart counter reset as
|
||||||
|
soon as they have stabilized. Instead, a background timer will
|
||||||
|
slowly (every 300 sec) age (decrement) the counter. This will still
|
||||||
|
catch services that "rage quit", but also those that crash after a
|
||||||
|
longer period of activity
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* Fix #180: user managed (`manual:yes`) services accidentally started
|
||||||
|
by `initctl reload`, regression introduced in Finit v4.0
|
||||||
|
* Fix #181: lots of typos all over the tree, by David Yang, Debian
|
||||||
|
* Fix #187: fix typos, incl. small cleanup, in doc/bootstrap.md
|
||||||
|
* Fix #188: support running on kernels that do not have cgroups v2.
|
||||||
|
When this is detect, all functions related to cgroups support in
|
||||||
|
Finit are disabled, *except* the .conf file parser. Hence, you
|
||||||
|
may get parse error if you have invalid cgroup configuration in
|
||||||
|
your Finit .conf files
|
||||||
|
* Fix #197: `initctl status foo` now shows a focused overview of all
|
||||||
|
matching instances; foo:1, foo:2 -- if only one instance matches the
|
||||||
|
command line argument, or if onle one instance exists, the detailed
|
||||||
|
view is shown, as before
|
||||||
|
* Fix #198: a few typos found by Tim Gates
|
||||||
|
* Fix #199: avoid using C++ reserved keywords
|
||||||
|
* Fix #201: memory leak in usr condition plugin, by Ming Liu, Atlas Copco
|
||||||
|
* Fix #203: ensure all filesystems listed in /proc/mounts are properly
|
||||||
|
unumounted on shutdown/reboot, by Robert Andersson, Atlas Copco
|
||||||
|
* Fix #210: resizing terminal (smaller) after boot causes empty lines
|
||||||
|
to be inserted between boot progress
|
||||||
|
* Fix #211: drop hard-coded 32 character limit in getty, now reads
|
||||||
|
`_SC_LOGIN_NAME_MAX` from `sysconf(3)`
|
||||||
|
* Fix #212: service PID file lost after inictl reload, visible from
|
||||||
|
the output from `initctl status foo`
|
||||||
|
|
||||||
|
|
||||||
[4.1][] - 2021-06-06
|
[4.1][] - 2021-06-06
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
@@ -184,7 +247,7 @@ make sure to read the whole change log when upgrading.
|
|||||||
- As long as a stepped service changes state we queue another step all
|
- As long as a stepped service changes state we queue another step all
|
||||||
event, because services may depend on each other
|
event, because services may depend on each other
|
||||||
* Require new libuEv API: `uev_init1()` to reduce event cache so that
|
* Require new libuEv API: `uev_init1()` to reduce event cache so that
|
||||||
the kernel can invalidate deleted events before enqueing to userspace
|
the kernel can invalidate deleted events before enqueuing to userspace
|
||||||
* Rename `hwclock.so` plugin to `rtc.so` since it now is stand-alone
|
* Rename `hwclock.so` plugin to `rtc.so` since it now is stand-alone
|
||||||
from the `hwclock` tool. Note: the kernel can also be set to load
|
from the `hwclock` tool. Note: the kernel can also be set to load
|
||||||
and store RTC to/from system clock at boot/halt as well, issue #110
|
and store RTC to/from system clock at boot/halt as well, issue #110
|
||||||
@@ -506,7 +569,7 @@ Bug fix release.
|
|||||||
|
|
||||||
* Add support for status/show service by `name:id`
|
* Add support for status/show service by `name:id`
|
||||||
* Enforce terse mode after boot, if verbose mode is disabled
|
* Enforce terse mode after boot, if verbose mode is disabled
|
||||||
* Reenable verbose mode at reboot, if disabled at boot
|
* Re-enable verbose mode at reboot, if disabled at boot
|
||||||
* Update section mentioning BusyBox getty
|
* Update section mentioning BusyBox getty
|
||||||
* Update debugging documentation
|
* Update debugging documentation
|
||||||
* Allow debug to override terse mode
|
* Allow debug to override terse mode
|
||||||
@@ -561,7 +624,7 @@ handling and reconfiguration at runtime.
|
|||||||
* Clarify how to select different plugins with the configure script
|
* Clarify how to select different plugins with the configure script
|
||||||
* Improve urandom plugin for embedded systems w/o random seed
|
* Improve urandom plugin for embedded systems w/o random seed
|
||||||
* Add `--debug` flag to `initctl`
|
* Add `--debug` flag to `initctl`
|
||||||
* The runlevels listed for services in `initctl show` now hightlight the
|
* The runlevels listed for services in `initctl show` now highlight the
|
||||||
active runlevel.
|
active runlevel.
|
||||||
* Clarify in the README and in `initctl help` that the GW event to
|
* Clarify in the README and in `initctl help` that the GW event to
|
||||||
listen for in service declarations is `GW:UP`
|
listen for in service declarations is `GW:UP`
|
||||||
@@ -593,7 +656,7 @@ handling and reconfiguration at runtime.
|
|||||||
* Do not use `-Os` use `-O2` as default optimization level. Many cross
|
* Do not use `-Os` use `-O2` as default optimization level. Many cross
|
||||||
compiler toolchains are known to have problems with `-Os`
|
compiler toolchains are known to have problems with `-Os`
|
||||||
* Do not allow build VERSION to be overloaded by an environment variable
|
* Do not allow build VERSION to be overloaded by an environment variable
|
||||||
* Fix too small MAX arguments and too few argments in `svc_t` for
|
* Fix too small MAX arguments and too few arguments in `svc_t` for
|
||||||
reading currently running services with `initctl show`
|
reading currently running services with `initctl show`
|
||||||
* Unblock blocked signals after forking off a child
|
* Unblock blocked signals after forking off a child
|
||||||
|
|
||||||
@@ -711,7 +774,7 @@ The inetd release.
|
|||||||
turned out to not work so well after all. For instance, launching
|
turned out to not work so well after all. For instance, launching
|
||||||
TTYs in a background process completely blocked inetd services from
|
TTYs in a background process completely blocked inetd services from
|
||||||
even starting up listening sockets ... proper fork seems to work fine
|
even starting up listening sockets ... proper fork seems to work fine
|
||||||
though. This is the casue for *yanking* the [1.11] release, below.
|
though. This is the cause for *yanking* the [1.11] release, below.
|
||||||
* Trap segfaults caused by external plugins/callbacks in a sub-process.
|
* Trap segfaults caused by external plugins/callbacks in a sub-process.
|
||||||
This prevents a single programming mistake in by a 3rd party developer
|
This prevents a single programming mistake in by a 3rd party developer
|
||||||
from taking down the entire system.
|
from taking down the entire system.
|
||||||
@@ -807,7 +870,7 @@ Major bug fix release.
|
|||||||
|
|
||||||
### Changes
|
### Changes
|
||||||
* Show `__FILE__` in `_d()` debug messages, useful for plugins with
|
* Show `__FILE__` in `_d()` debug messages, useful for plugins with
|
||||||
similarily named callbacks. Also, only in debug mode anyway
|
similarly named callbacks. Also, only in debug mode anyway
|
||||||
* Make sure to cleanup recorded PID when a service is lost. Required by
|
* Make sure to cleanup recorded PID when a service is lost. Required by
|
||||||
service plugins for their callbacks to work.
|
service plugins for their callbacks to work.
|
||||||
* Only clear screen when in verbose mode. Maybe this should be removed
|
* Only clear screen when in verbose mode. Maybe this should be removed
|
||||||
@@ -975,7 +1038,8 @@ Major bug fix release.
|
|||||||
|
|
||||||
* Initial release
|
* Initial release
|
||||||
|
|
||||||
[UNRELEASED]: https://github.com/troglobit/finit/compare/4.0...HEAD
|
[UNRELEASED]: https://github.com/troglobit/finit/compare/4.2...HEAD
|
||||||
|
[4.2]: https://github.com/troglobit/finit/compare/4.1...4.2
|
||||||
[4.1]: https://github.com/troglobit/finit/compare/4.0...4.1
|
[4.1]: https://github.com/troglobit/finit/compare/4.0...4.1
|
||||||
[4.0]: https://github.com/troglobit/finit/compare/3.1...4.0
|
[4.0]: https://github.com/troglobit/finit/compare/3.1...4.0
|
||||||
[3.1]: https://github.com/troglobit/finit/compare/3.0...3.1
|
[3.1]: https://github.com/troglobit/finit/compare/3.0...3.1
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
[![License Badge][]][License] [![Travis Status]][Travis] [![Coverity Status]][Coverity Scan]
|
[![License Badge][]][License] [![GitHub Status]][GitHub] [![Coverity Status]][Coverity Scan]
|
||||||
<img align="right" src="img/finit3.png" alt="Finit: Fast Init">
|
<img align="right" src="img/finit3.png" alt="Finit: Fast Init">
|
||||||
|
|
||||||
* [Introduction](#introduction)
|
* [Introduction](#introduction)
|
||||||
@@ -119,10 +119,10 @@ some of the most common components needed to start a UNIX daemon:
|
|||||||
|
|
||||||
```
|
```
|
||||||
service [LVLS] <COND> log env:[-]/etc/default/daemon daemon ARGS -- Daemon daemon
|
service [LVLS] <COND> log env:[-]/etc/default/daemon daemon ARGS -- Daemon daemon
|
||||||
^ ^ ^ ^ ^ ^ ^ ^
|
^ ^ ^ ^ ^ ^ ^ ^
|
||||||
| | | | | | | `-- Optional description
|
| | | | | | | `---------- Optional description
|
||||||
| | | | | | `----------- Daemon arguments
|
| | | | | | `------------------ Daemon arguments
|
||||||
| | | | | `-------------------------- Path to daemon
|
| | | | | `------------------------- Path to daemon
|
||||||
| | | | `---------------------------------------------------- Optional env. file
|
| | | | `---------------------------------------------------- Optional env. file
|
||||||
| | | `-------------------------------------------------------- Redirect output to log
|
| | | `-------------------------------------------------------- Redirect output to log
|
||||||
| | `--------------------------------------------------------------- Optional conditions
|
| | `--------------------------------------------------------------- Optional conditions
|
||||||
@@ -140,7 +140,7 @@ Dependencies are handled using [conditions](doc/conditions.md). One of
|
|||||||
the most common conditions is to wait for basic networking to become
|
the most common conditions is to wait for basic networking to become
|
||||||
available:
|
available:
|
||||||
|
|
||||||
service <net/route/default> nginx -- High performace HTTP server
|
service <net/route/default> nginx -- High performance HTTP server
|
||||||
|
|
||||||
Here is another example where we instruct Finit to not start BusyBox
|
Here is another example where we instruct Finit to not start BusyBox
|
||||||
`ntpd` until `syslogd` has started properly. Finit waits for `syslogd`
|
`ntpd` until `syslogd` has started properly. Finit waits for `syslogd`
|
||||||
@@ -571,34 +571,34 @@ This project is based on the [original finit][] by [Claudio Matsuoka][]
|
|||||||
which was reverse engineered from syscalls of the [EeePC fastinit][] —
|
which was reverse engineered from syscalls of the [EeePC fastinit][] —
|
||||||
"gaps filled with frog DNA …"
|
"gaps filled with frog DNA …"
|
||||||
|
|
||||||
Finit is developed and maintained by [Joachim Wiberg][] at [GitHub][].
|
Finit is developed and maintained by [Joachim Wiberg][] at [GitHub][6].
|
||||||
Please file bug reports, clone it, or send pull requests for bug fixes
|
Please file bug reports, clone it, or send pull requests for bug fixes
|
||||||
and proposed extensions.
|
and proposed extensions.
|
||||||
|
|
||||||
|
|
||||||
[1]: https://en.wikipedia.org/wiki/Process_supervision
|
[1]: https://en.wikipedia.org/wiki/Process_supervision
|
||||||
[2]: http://cr.yp.to/daemontools.html
|
[2]: https://cr.yp.to/daemontools.html
|
||||||
[3]: http://smarden.org/runit/
|
[3]: https://smarden.org/runit/
|
||||||
[4]: http://en.wikipedia.org/wiki/Init
|
[4]: https://en.wikipedia.org/wiki/Init
|
||||||
[5]: http://en.wikipedia.org/wiki/Runlevel
|
[5]: https://en.wikipedia.org/wiki/Runlevel
|
||||||
|
[6]: https://github.com/troglobit/finit
|
||||||
[RFC862]: https://tools.ietf.org/html/rfc862
|
[RFC862]: https://tools.ietf.org/html/rfc862
|
||||||
[RFC863]: https://tools.ietf.org/html/rfc863
|
[RFC863]: https://tools.ietf.org/html/rfc863
|
||||||
[RFC864]: https://tools.ietf.org/html/rfc864
|
[RFC864]: https://tools.ietf.org/html/rfc864
|
||||||
[RFC867]: https://tools.ietf.org/html/rfc867
|
[RFC867]: https://tools.ietf.org/html/rfc867
|
||||||
[RFC868]: https://tools.ietf.org/html/rfc868
|
[RFC868]: https://tools.ietf.org/html/rfc868
|
||||||
[init]: http://en.wikipedia.org/wiki/Init
|
[init]: https://en.wikipedia.org/wiki/Init
|
||||||
[upstart]: http://upstart.ubuntu.com/
|
[upstart]: https://upstart.ubuntu.com/
|
||||||
[systemd]: http://www.freedesktop.org/wiki/Software/systemd/
|
[systemd]: https://www.freedesktop.org/wiki/Software/systemd/
|
||||||
[openrc]: http://www.gentoo.org/proj/en/base/openrc/
|
[openrc]: https://www.gentoo.org/proj/en/base/openrc/
|
||||||
[run-parts(8)]: http://manpages.debian.org/cgi-bin/man.cgi?query=run-parts
|
[run-parts(8)]: https://manpages.debian.org/cgi-bin/man.cgi?query=run-parts
|
||||||
[original finit]: http://helllabs.org/finit/
|
[original finit]: http://helllabs.org/finit/
|
||||||
[EeePC fastinit]: https://web.archive.org/web/20071208212450/http://wiki.eeeuser.com/boot_process:the_boot_process
|
[EeePC fastinit]: https://web.archive.org/web/20071208212450/http://wiki.eeeuser.com/boot_process:the_boot_process
|
||||||
[Claudio Matsuoka]: https://github.com/cmatsuoka
|
[Claudio Matsuoka]: https://github.com/cmatsuoka
|
||||||
[Joachim Wiberg]: http://troglobit.com
|
[Joachim Wiberg]: https://troglobit.com
|
||||||
[GitHub]: https://github.com/troglobit/finit
|
|
||||||
[License]: https://en.wikipedia.org/wiki/MIT_License
|
[License]: https://en.wikipedia.org/wiki/MIT_License
|
||||||
[License Badge]: https://img.shields.io/badge/License-MIT-teal.svg
|
[License Badge]: https://img.shields.io/badge/License-MIT-teal.svg
|
||||||
[Travis]: https://travis-ci.org/troglobit/finit
|
[GitHub]: https://travis-ci.org/troglobit/finit
|
||||||
[Travis Status]: https://travis-ci.org/troglobit/finit.svg?branch=master
|
[GitHub Status]: https://travis-ci.org/troglobit/finit.svg?branch=master
|
||||||
[Coverity Scan]: https://scan.coverity.com/projects/3545
|
[Coverity Scan]: https://scan.coverity.com/projects/3545
|
||||||
[Coverity Status]: https://scan.coverity.com/projects/3545/badge.svg
|
[Coverity Status]: https://scan.coverity.com/projects/3545/badge.svg
|
||||||
|
|||||||
+27
-1
@@ -1,4 +1,4 @@
|
|||||||
AC_INIT(Finit, 4.1, https://github.com/troglobit/finit/issues, finit, https://troglobit.com/finit.html)
|
AC_INIT(Finit, 4.2, https://github.com/troglobit/finit/issues, finit, https://troglobit.com/finit.html)
|
||||||
AC_CONFIG_AUX_DIR(aux)
|
AC_CONFIG_AUX_DIR(aux)
|
||||||
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects])
|
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects])
|
||||||
AM_SILENT_RULES([yes])
|
AM_SILENT_RULES([yes])
|
||||||
@@ -57,6 +57,14 @@ AC_ARG_ENABLE(kernel_cmdline,
|
|||||||
AS_HELP_STRING([--enable-kernel-cmdline], [Parse init args from /proc/cmdline (don't use!)]),,[
|
AS_HELP_STRING([--enable-kernel-cmdline], [Parse init args from /proc/cmdline (don't use!)]),,[
|
||||||
enable_kernel_cmdline=no])
|
enable_kernel_cmdline=no])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(fastboot,
|
||||||
|
AS_HELP_STRING([--enable-fastboot], [Skip fsck check on filesystems listed in /etc/fstab]),,[
|
||||||
|
enable_fastboot=no])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(fsckfix,
|
||||||
|
AS_HELP_STRING([--enable-fsckfix], [Run fsck fix mode (options: -yf) on filesystems listed in /etc/fstab]),,[
|
||||||
|
enable_fsckfix=no])
|
||||||
|
|
||||||
AC_ARG_ENABLE(redirect,
|
AC_ARG_ENABLE(redirect,
|
||||||
AS_HELP_STRING([--disable-redirect], [Disable redirection of service output to /dev/null]),,[
|
AS_HELP_STRING([--disable-redirect], [Disable redirection of service output to /dev/null]),,[
|
||||||
enable_redirect=yes])
|
enable_redirect=yes])
|
||||||
@@ -106,6 +114,10 @@ AC_ARG_WITH(sysconfig,
|
|||||||
AS_HELP_STRING([--with-sysconfig=DIR], [System environment directory, sourced by .conf files, default /etc/default & /etc/conf.d]),
|
AS_HELP_STRING([--with-sysconfig=DIR], [System environment directory, sourced by .conf files, default /etc/default & /etc/conf.d]),
|
||||||
[sysconfig=$withval], [sysconfig=default])
|
[sysconfig=$withval], [sysconfig=default])
|
||||||
|
|
||||||
|
AC_ARG_WITH(group,
|
||||||
|
AS_HELP_STRING([--with-group=NAME], [Group for /run/finit/socket (initctl), default: root]),
|
||||||
|
[group=$withval], [group=root])
|
||||||
|
|
||||||
AC_ARG_WITH(hostname,
|
AC_ARG_WITH(hostname,
|
||||||
AS_HELP_STRING([--with-hostname=NAME], [If /etc/hostname is missing, default: noname]),
|
AS_HELP_STRING([--with-hostname=NAME], [If /etc/hostname is missing, default: noname]),
|
||||||
[hostname=$withval], [hostname=yes])
|
[hostname=$withval], [hostname=yes])
|
||||||
@@ -134,6 +146,12 @@ AS_IF([test "x$enable_auto_reload" = "xyes"], [
|
|||||||
AS_IF([test "x$enable_kernel_cmdline" = "xyes"], [
|
AS_IF([test "x$enable_kernel_cmdline" = "xyes"], [
|
||||||
AC_DEFINE(KERNEL_CMDLINE, 1, [Dumpster diving after init args from /proc/cmdline])])
|
AC_DEFINE(KERNEL_CMDLINE, 1, [Dumpster diving after init args from /proc/cmdline])])
|
||||||
|
|
||||||
|
AS_IF([test "x$enable_fastboot" = "xyes"], [
|
||||||
|
AC_DEFINE(FAST_BOOT, 1, [Skip fsck check on filesystems listed in /etc/fstab])])
|
||||||
|
|
||||||
|
AS_IF([test "x$enable_fsckfix" = "xyes"], [
|
||||||
|
AC_DEFINE(FSCK_FIX, 1, [Run fsck fix mode (options: -yf) on filesystems listed in /etc/fstab])])
|
||||||
|
|
||||||
AS_IF([test "x$enable_redirect" = "xyes"], [
|
AS_IF([test "x$enable_redirect" = "xyes"], [
|
||||||
AC_DEFINE(REDIRECT_OUTPUT, 1, [Enable redirection of service output to /dev/null])])
|
AC_DEFINE(REDIRECT_OUTPUT, 1, [Enable redirection of service output to /dev/null])])
|
||||||
|
|
||||||
@@ -174,6 +192,11 @@ AS_IF([test "x$with_heading" != "xno"], [
|
|||||||
AS_IF([test "x$heading" = "xyes"], [heading=""])
|
AS_IF([test "x$heading" = "xyes"], [heading=""])
|
||||||
AC_DEFINE_UNQUOTED(INIT_OSHEADING, "$heading", [Displayed by Finit at boot, defaults to /etc/os-release PRETTY_NAME])])
|
AC_DEFINE_UNQUOTED(INIT_OSHEADING, "$heading", [Displayed by Finit at boot, defaults to /etc/os-release PRETTY_NAME])])
|
||||||
|
|
||||||
|
AS_IF([test "x$with_group" != "xno"], [
|
||||||
|
AS_IF([test "x$group" = "xyes"], [
|
||||||
|
group=root])])
|
||||||
|
AC_DEFINE_UNQUOTED(DEFGROUP, "$group", [For /run/finit/socket])
|
||||||
|
|
||||||
AS_IF([test "x$with_hostname" != "xno"], [
|
AS_IF([test "x$with_hostname" != "xno"], [
|
||||||
AS_IF([test "x$hostname" = "xyes"], [
|
AS_IF([test "x$hostname" = "xyes"], [
|
||||||
hostname=noname])])
|
hostname=noname])])
|
||||||
@@ -255,8 +278,11 @@ Optional features:
|
|||||||
Built-in keventd......: $with_keventd
|
Built-in keventd......: $with_keventd
|
||||||
Built-in watchdogd....: $with_watchdog $watchdog
|
Built-in watchdogd....: $with_watchdog $watchdog
|
||||||
Built-in logrotate....: $enable_logrotate
|
Built-in logrotate....: $enable_logrotate
|
||||||
|
Skip fsck check.......: $enable_fastboot
|
||||||
|
Run fsck fix mode.....: $enable_fsckfix
|
||||||
Redirect output.......: $enable_redirect
|
Redirect output.......: $enable_redirect
|
||||||
Default hostname......: $hostname
|
Default hostname......: $hostname
|
||||||
|
Default group.........: $group
|
||||||
Default runlevel......: $runlevel
|
Default runlevel......: $runlevel
|
||||||
|
|
||||||
------------- Compiler version --------------
|
------------- Compiler version --------------
|
||||||
|
|||||||
@@ -4,5 +4,5 @@
|
|||||||
#
|
#
|
||||||
# Each line is run in sequence.
|
# Each line is run in sequence.
|
||||||
#
|
#
|
||||||
# NOTE: Remeber to set the executable bit!
|
# NOTE: Remember to set the executable bit!
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -4,4 +4,4 @@
|
|||||||
#
|
#
|
||||||
# Each line is run in sequence.
|
# Each line is run in sequence.
|
||||||
#
|
#
|
||||||
# NOTE: Remeber to set the executable bit!
|
# NOTE: Remember to set the executable bit!
|
||||||
|
|||||||
+9
-10
@@ -16,7 +16,9 @@ Bootstrap
|
|||||||
11. Load all `/etc/finit.d/*.conf` files and set hostname
|
11. Load all `/etc/finit.d/*.conf` files and set hostname
|
||||||
12. Remount `/` read-write if `/` is listed in `/etc/fstab` without `ro`
|
12. Remount `/` read-write if `/` is listed in `/etc/fstab` without `ro`
|
||||||
13. Call 1st level hooks, `HOOK_ROOTFS_UP`
|
13. Call 1st level hooks, `HOOK_ROOTFS_UP`
|
||||||
14. Mount all file systems listed in `/etc/fstab` and swap, if available
|
14. Mount all file systems listed in `/etc/fstab` and swap, if available.
|
||||||
|
On mount error `HOOK_MOUNT_ERROR` is called. After mount, regardless
|
||||||
|
of error, `HOOK_MOUNT_POST` is called
|
||||||
15. Enable SysV init signals
|
15. Enable SysV init signals
|
||||||
16. Call 2nd level hooks, `HOOK_BASEFS_UP`
|
16. Call 2nd level hooks, `HOOK_BASEFS_UP`
|
||||||
17. Cleanup stale files from `/tmp/*` et al, handled by `bootmisc` plugin
|
17. Cleanup stale files from `/tmp/*` et al, handled by `bootmisc` plugin
|
||||||
@@ -38,16 +40,13 @@ Bootstrap
|
|||||||
26. Call 5th level (last) hooks, `HOOK_SYSTEM_UP`
|
26. Call 5th level (last) hooks, `HOOK_SYSTEM_UP`
|
||||||
27. Start all configured TTYs
|
27. Start all configured TTYs
|
||||||
|
|
||||||
In (19) and (22) tasks and services defined in `/etc/finit.conf` and
|
In (19) and (23) tasks and services defined in `/etc/finit.conf` and
|
||||||
`/etc/sysctl.d/*.conf` are started. Remember, all `service` and `task`
|
`/etc/finit.d/*.conf` are started.
|
||||||
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 `finit.conf` with only `run` statements.
|
|
||||||
|
|
||||||
Notice the five hook points that are called at various point in the
|
Notice the seven hook points that are called at various point in the
|
||||||
bootstrap process. This is where plugins can extend the boot in any way
|
bootstrap process. This is where plugins can extend the boot in any
|
||||||
they please. There are other hook points, e.g. `HOOK_MOUNT_ERROR`, for
|
way they please. There are other hook points available, for more on
|
||||||
more on this see [plugins.md](plugins.md).
|
this, see [plugins.md](plugins.md).
|
||||||
|
|
||||||
For instance, at `HOOK_BASEFS_UP` a plugin could read an XML file from a
|
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,
|
USB stick, convert/copy its contents to the system's `/etc/` directory,
|
||||||
|
|||||||
+1
-1
@@ -27,7 +27,7 @@ optional plugins to enable. It depends on two external libraries:
|
|||||||
PKG_CONFIG_LIBDIR=/usr/local/lib/pkgconfig ./configure
|
PKG_CONFIG_LIBDIR=/usr/local/lib/pkgconfig ./configure
|
||||||
|
|
||||||
The configure script checks for all dependencies, including the correct
|
The configure script checks for all dependencies, including the correct
|
||||||
version of the above mentioned libraries. Currently requried versions:
|
version of the above mentioned libraries. Currently required versions:
|
||||||
|
|
||||||
- libite v2.2.0
|
- libite v2.2.0
|
||||||
- libuEv v2.2.0
|
- libuEv v2.2.0
|
||||||
|
|||||||
+1
-1
@@ -44,7 +44,7 @@ The `bool` setting is one of `on, off, true false, 1, 0`.
|
|||||||
`[1]` will be started, so a `tty [1] @console nologin` configuration
|
`[1]` will be started, so a `tty [1] @console nologin` configuration
|
||||||
presents you with a root console without login.
|
presents you with a root console without login.
|
||||||
|
|
||||||
For more on kernel boot paramaters, see the man page [bootparam(7)][].
|
For more on kernel boot parameters, see the man page [bootparam(7)][].
|
||||||
|
|
||||||
[config.md][]: config.md#rescue-mode
|
[config.md][]: config.md#rescue-mode
|
||||||
[bootparam(7)]: https://www.man7.org/linux/man-pages/man7/bootparam.7.html
|
[bootparam(7)]: https://www.man7.org/linux/man-pages/man7/bootparam.7.html
|
||||||
|
|||||||
+2
-2
@@ -90,7 +90,7 @@ Built-in Conditions
|
|||||||
Finit comes with a set of plugins for conditions: `pidfile`, `netlink`,
|
Finit comes with a set of plugins for conditions: `pidfile`, `netlink`,
|
||||||
`sys`, and `usr`. The `pidfile` plugin (recursively) watches `/run/`
|
`sys`, and `usr`. The `pidfile` plugin (recursively) watches `/run/`
|
||||||
(recursively) for PID files created by the monitored services, and sets
|
(recursively) for PID files created by the monitored services, and sets
|
||||||
a corresponding condition in the `pid/` namespace. Similarily, the
|
a corresponding condition in the `pid/` namespace. Similarly, the
|
||||||
`netlink` plugin provides basic conditions for when an interface is
|
`netlink` plugin provides basic conditions for when an interface is
|
||||||
brought up/down and when a default route (gateway) is set, in the `net/`
|
brought up/down and when a default route (gateway) is set, in the `net/`
|
||||||
namespace. The `sys` and `usr` plugins monitor are passive condition
|
namespace. The `sys` and `usr` plugins monitor are passive condition
|
||||||
@@ -180,7 +180,7 @@ PID IDENT STATUS CONDITION (+ ON, ~ FLUX, - OFF)
|
|||||||
|
|
||||||
Here we can see that `netd` is allowed to run since both its conditions
|
Here we can see that `netd` is allowed to run since both its conditions
|
||||||
are in the `on` state, as indicated by the `+`-prefix. `udhcpc` however
|
are in the `on` state, as indicated by the `+`-prefix. `udhcpc` however
|
||||||
is not allowed to run since `net/vlan1/exist` condition is not satsifed.
|
is not allowed to run since `net/vlan1/exist` condition is not satisfied.
|
||||||
As indicated by the `-`-prefix.
|
As indicated by the `-`-prefix.
|
||||||
|
|
||||||
To fake interface `vlan1` suddenly appearing, and test what happens to
|
To fake interface `vlan1` suddenly appearing, and test what happens to
|
||||||
|
|||||||
+21
-3
@@ -59,7 +59,7 @@ files for a package and let the user decide when to enable a service.
|
|||||||
On `initctl reload` the following is checked for all services:
|
On `initctl reload` the following is checked for all services:
|
||||||
|
|
||||||
- If a service's `.conf` file has been removed, or its conditions are no
|
- If a service's `.conf` file has been removed, or its conditions are no
|
||||||
longer satisifed, the service is stopped.
|
longer satisfied, the service is stopped.
|
||||||
- If the file is modified, or a service it depends on has been reloaded,
|
- If the file is modified, or a service it depends on has been reloaded,
|
||||||
the service is reloaded (stopped and started).
|
the service is reloaded (stopped and started).
|
||||||
- If a new service is added it is automatically started — respecting
|
- If a new service is added it is automatically started — respecting
|
||||||
@@ -332,8 +332,11 @@ by declaring the PID file to look for: `pid:!/path/to/pidfile.pid`.
|
|||||||
**Syntax:** `service [LVLS] <COND> /path/to/daemon ARGS -- Optional description`
|
**Syntax:** `service [LVLS] <COND> /path/to/daemon ARGS -- Optional description`
|
||||||
|
|
||||||
Service, or daemon, to be monitored and automatically restarted if it
|
Service, or daemon, to be monitored and automatically restarted if it
|
||||||
exits prematurely. Finit tries to restart services that die 10 times
|
exits prematurely. Finit tries to restart services that die, by
|
||||||
before giving up, then you have to `initctl restart NAME` it manually.
|
default 10 times before giving up and marking them as *crashed*.
|
||||||
|
After which they have to be manually restarted with `initctl restart
|
||||||
|
NAME`. The limits controling this are configurable, see the options
|
||||||
|
below.
|
||||||
|
|
||||||
For daemons that support it, we recommend appending `--foreground`,
|
For daemons that support it, we recommend appending `--foreground`,
|
||||||
`--no-background`, `-n`, `-F`, or similar command line argument to
|
`--no-background`, `-n`, `-F`, or similar command line argument to
|
||||||
@@ -390,6 +393,21 @@ optional `name` argument:
|
|||||||
|
|
||||||
name:<service-name>
|
name:<service-name>
|
||||||
|
|
||||||
|
As mentioned previously, services are automatically restarted, this is
|
||||||
|
configurable with the following options:
|
||||||
|
|
||||||
|
* `restart:NUM` -- number of times Finit tries to restart a crashing
|
||||||
|
service, default: 10. When this limit is reached the service is
|
||||||
|
marked *crashed* and must be restarted manually with `initctl`
|
||||||
|
* `restart_sec:SEC` -- number of seconds before Finit tries to restart
|
||||||
|
a crashing service, default: 2 seconds for the first five retries,
|
||||||
|
then back-off to 5 seconds. The maximum of this configured value
|
||||||
|
and the above (2 and 5) will be used
|
||||||
|
* `norestart` -- dont restart on failures, same as `restart:0`
|
||||||
|
* `oncrash:reboot` -- when all retries have failed, and the service
|
||||||
|
has *crashed*, if this option is set the system is rebooted.
|
||||||
|
Note, future releases may include other `oncrash:` actions
|
||||||
|
|
||||||
When stopping a service (run/task/sysv/service), either manually or
|
When stopping a service (run/task/sysv/service), either manually or
|
||||||
when moving to another runlevel, Finit starts by sending `SIGTERM`, to
|
when moving to another runlevel, Finit starts by sending `SIGTERM`, to
|
||||||
allow the process to shut down gracefully. If the process has not
|
allow the process to shut down gracefully. If the process has not
|
||||||
|
|||||||
+1
-1
@@ -107,7 +107,7 @@ Finit waits for the PID file of service A to be created/updated before
|
|||||||
it starts service B. Conversely, if service A is stopped and its PID
|
it starts service B. Conversely, if service A is stopped and its PID
|
||||||
file removed, service B is also stopped.
|
file removed, service B is also stopped.
|
||||||
.Pp
|
.Pp
|
||||||
The following condition families are availble today:
|
The following condition families are available today:
|
||||||
.Pp
|
.Pp
|
||||||
.Bl -tag -width pid -offset indent
|
.Bl -tag -width pid -offset indent
|
||||||
.It Cm net
|
.It Cm net
|
||||||
|
|||||||
+37
-4
@@ -174,9 +174,13 @@ the default behavior for the
|
|||||||
command modifier.
|
command modifier.
|
||||||
.It Cm service Oo LVLS Oc Ao COND Ac Ar /path/to/daemon ARGS Op -- Optional description
|
.It Cm service Oo LVLS Oc Ao COND Ac Ar /path/to/daemon ARGS Op -- Optional description
|
||||||
Service, or daemon, to be monitored and automatically restarted if it
|
Service, or daemon, to be monitored and automatically restarted if it
|
||||||
exits prematurely. Finit tries to restart services that die 10 times
|
exits prematurely. Finit tries to restart services that die, by
|
||||||
before giving up, then you have to restart it manually:
|
default 10 times, before giving up and marking them as
|
||||||
.Cm initctl restart NAME
|
.Em crashed .
|
||||||
|
After which they have to be restarted manually using
|
||||||
|
.Cm initctl restart NAME .
|
||||||
|
The number of restarts, the delay between each restart, and more is
|
||||||
|
configurable, see the options below.
|
||||||
.Pp
|
.Pp
|
||||||
For daemons that support it, we recommend appending
|
For daemons that support it, we recommend appending
|
||||||
.Cm --foreground , --no-background , -n , -F ,
|
.Cm --foreground , --no-background , -n , -F ,
|
||||||
@@ -200,6 +204,7 @@ flag (daemonize) to prevent it from forking to the background:
|
|||||||
.Bd -unfilled -offset indent
|
.Bd -unfilled -offset indent
|
||||||
service [2345] <pid/zebra> /sbin/ospfd -- OSPF daemon
|
service [2345] <pid/zebra> /sbin/ospfd -- OSPF daemon
|
||||||
.Ed
|
.Ed
|
||||||
|
.Pp
|
||||||
.Cm [2345]
|
.Cm [2345]
|
||||||
denote the runlevels
|
denote the runlevels
|
||||||
.Cm ospfd
|
.Cm ospfd
|
||||||
@@ -264,6 +269,34 @@ changed with the
|
|||||||
.Cm name:foo
|
.Cm name:foo
|
||||||
command modifier.
|
command modifier.
|
||||||
.Pp
|
.Pp
|
||||||
|
As mentioned previously, services are automatically restarted should
|
||||||
|
they crash, this is configurable with the following options:
|
||||||
|
.Bl -tag -width 1n
|
||||||
|
.It Cm restart:NUM
|
||||||
|
number of times Finit tries to restart a crashing
|
||||||
|
service, default: 10. When this limit is reached the service is
|
||||||
|
marked
|
||||||
|
.Em crashed
|
||||||
|
and must be restarted manually with
|
||||||
|
.Xr initctl 8 .
|
||||||
|
.It Cm restart_sec:SEC
|
||||||
|
number of seconds before Finit tries to restart
|
||||||
|
a crashing service, default: 2 seconds for the first five retries,
|
||||||
|
then back-off to 5 seconds. The maximum of this configured value
|
||||||
|
and the above (2 and 5) will be used
|
||||||
|
.It Cm norestart
|
||||||
|
dont restart on failures, same as
|
||||||
|
.Cm restart:0
|
||||||
|
.It Cm oncrash:reboot
|
||||||
|
when all retries have failed, and the service
|
||||||
|
has
|
||||||
|
.Em crashed ,
|
||||||
|
if this option is set the system is rebooted. Note, future releases
|
||||||
|
may include other
|
||||||
|
.Cm oncrash:
|
||||||
|
actions.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
When stopping a service (run/task/sysv/service), either manually or when
|
When stopping a service (run/task/sysv/service), either manually or when
|
||||||
moving to another runlevel, Finit starts by sending SIGTERM, to allow
|
moving to another runlevel, Finit starts by sending SIGTERM, to allow
|
||||||
the process to shut down gracefully. If the process has not been
|
the process to shut down gracefully. If the process has not been
|
||||||
@@ -301,7 +334,7 @@ services named
|
|||||||
may be
|
may be
|
||||||
.Cm foo:1 ,
|
.Cm foo:1 ,
|
||||||
or any unique identifier specified in the .conf file. The
|
or any unique identifier specified in the .conf file. The
|
||||||
.cm post:script
|
.Cm post:script
|
||||||
is called with an additional set of environment variables:
|
is called with an additional set of environment variables:
|
||||||
.Bl -tag -offset indent -width 1n
|
.Bl -tag -offset indent -width 1n
|
||||||
.It Cm EXIT_CODE=[exited,signal]
|
.It Cm EXIT_CODE=[exited,signal]
|
||||||
|
|||||||
+12
-1
@@ -118,6 +118,13 @@ Show condition status, default
|
|||||||
command.
|
command.
|
||||||
.It Nm Ar cond dump
|
.It Nm Ar cond dump
|
||||||
Dump all conditions and their status
|
Dump all conditions and their status
|
||||||
|
.It Nm Ar ident Op Cm NAME
|
||||||
|
Display indentities of all run/task/services, or only instances
|
||||||
|
matching
|
||||||
|
.Cm NAME .
|
||||||
|
A partial string, e.g.,
|
||||||
|
.Cm NAM ,
|
||||||
|
will not match anything
|
||||||
.It Nm Ar log Op Cm NAME
|
.It Nm Ar log Op Cm NAME
|
||||||
Show ten last Finit, or
|
Show ten last Finit, or
|
||||||
.Cm NAME ,
|
.Cm NAME ,
|
||||||
@@ -132,7 +139,11 @@ Reload service by name (SIGHUP or restart)
|
|||||||
.It Nm Ar restart Cm NAME[:ID]
|
.It Nm Ar restart Cm NAME[:ID]
|
||||||
Restart (stop/start) service by name
|
Restart (stop/start) service by name
|
||||||
.It Nm Ar status Cm NAME[:ID]
|
.It Nm Ar status Cm NAME[:ID]
|
||||||
Show service status, by name
|
Show service status, by name. If only
|
||||||
|
.Cm NAME
|
||||||
|
is given and multiple instances exits, a summary of all matching
|
||||||
|
instances are shown. Only an exact match displays the detailed status
|
||||||
|
for a particular instance
|
||||||
.It Nm Ar status
|
.It Nm Ar status
|
||||||
Show status of all services, default command
|
Show status of all services, default command
|
||||||
.It Nm Ar cgroup
|
.It Nm Ar cgroup
|
||||||
|
|||||||
@@ -21,7 +21,12 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
|||||||
+15
-5
@@ -24,7 +24,11 @@
|
|||||||
#include <ftw.h>
|
#include <ftw.h>
|
||||||
#include <mntent.h>
|
#include <mntent.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
@@ -100,6 +104,12 @@ static void clean(void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ln(const char *target, const char *linkpath, int ignerr)
|
||||||
|
{
|
||||||
|
if (symlink(target, linkpath) && !ignerr)
|
||||||
|
_pe("Failed creating %s -> %s symlink", target, linkpath);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup standard FHS 2.3 structure in /var, and write runlevel to UTMP
|
* Setup standard FHS 2.3 structure in /var, and write runlevel to UTMP
|
||||||
*/
|
*/
|
||||||
@@ -121,11 +131,11 @@ static void setup(void *arg)
|
|||||||
_d("System with new /run tmpfs ...");
|
_d("System with new /run tmpfs ...");
|
||||||
if (!fisdir("/run/lock"))
|
if (!fisdir("/run/lock"))
|
||||||
makedir("/run/lock", 1777);
|
makedir("/run/lock", 1777);
|
||||||
symlink("/run/lock", "/var/lock");
|
ln("/run/lock", "/var/lock", 0);
|
||||||
symlink("/dev/shm", "/run/shm");
|
ln("/dev/shm", "/run/shm", 0);
|
||||||
|
|
||||||
/* compat only, should really be set up by OS/dist */
|
/* compat only, should really be set up by OS/dist */
|
||||||
symlink("/run", "/var/run");
|
ln("/run", "/var/run", 1);
|
||||||
} else {
|
} else {
|
||||||
makedir("/var/lock", 1777);
|
makedir("/var/lock", 1777);
|
||||||
makedir("/var/run", 0755);
|
makedir("/var/run", 0755);
|
||||||
@@ -179,7 +189,7 @@ static void setup(void *arg)
|
|||||||
makedir("/var/run/sshd", 01755); /* OpenSSH */
|
makedir("/var/run/sshd", 01755); /* OpenSSH */
|
||||||
|
|
||||||
if (!fexist("/etc/mtab"))
|
if (!fexist("/etc/mtab"))
|
||||||
symlink("../proc/self/mounts", "/etc/mtab");
|
ln("../proc/self/mounts", "/etc/mtab", 1);
|
||||||
|
|
||||||
/* Void Linux has a uuidd that runs as uuid:uuid and needs /run/uuid */
|
/* Void Linux has a uuidd that runs as uuid:uuid and needs /run/uuid */
|
||||||
mksubsys("/var/run/uuidd", 0755, "uuidd", "uuidd");
|
mksubsys("/var/run/uuidd", 0755, "uuidd", "uuidd");
|
||||||
|
|||||||
+14
-4
@@ -22,7 +22,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@@ -35,7 +39,13 @@
|
|||||||
#define ARGS "--nofork --system --syslog-only"
|
#define ARGS "--nofork --system --syslog-only"
|
||||||
#define DESC "D-Bus message bus daemon"
|
#define DESC "D-Bus message bus daemon"
|
||||||
|
|
||||||
|
#ifndef DAEMONUSER
|
||||||
#define DAEMONUSER "messagebus"
|
#define DAEMONUSER "messagebus"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DAEMONPIDFILE
|
||||||
|
#define DAEMONPIDFILE "/var/run/dbus/pid"
|
||||||
|
#endif
|
||||||
|
|
||||||
static void setup(void *arg)
|
static void setup(void *arg)
|
||||||
{
|
{
|
||||||
@@ -61,11 +71,11 @@ static void setup(void *arg)
|
|||||||
run_interactive("dbus-uuidgen --ensure", "Creating machine UUID for D-Bus");
|
run_interactive("dbus-uuidgen --ensure", "Creating machine UUID for D-Bus");
|
||||||
|
|
||||||
/* Clean up from any previous pre-bootstrap run */
|
/* Clean up from any previous pre-bootstrap run */
|
||||||
remove("/var/run/dbus/pid");
|
remove(DAEMONPIDFILE);
|
||||||
|
|
||||||
/* Register service with Finit */
|
/* Register service with Finit */
|
||||||
snprintf(line, sizeof(line), "[S12345789] cgroup.system @%s:%s %s %s -- %s",
|
snprintf(line, sizeof(line), "[S12345789] cgroup.system pid:!%s @%s:%s %s %s -- %s",
|
||||||
DAEMONUSER, DAEMONUSER, cmd, ARGS, DESC);
|
DAEMONPIDFILE, DAEMONUSER, DAEMONUSER, cmd, ARGS, DESC);
|
||||||
if (service_register(SVC_TYPE_SERVICE, line, global_rlimit, NULL))
|
if (service_register(SVC_TYPE_SERVICE, line, global_rlimit, NULL))
|
||||||
_pe("Failed registering %s", DAEMON);
|
_pe("Failed registering %s", DAEMON);
|
||||||
free(cmd);
|
free(cmd);
|
||||||
|
|||||||
+6
-2
@@ -40,11 +40,15 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h> /* gettimeofday() */
|
#include <sys/time.h> /* gettimeofday() */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "helpers.h"
|
#include "util.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
|
||||||
struct module {
|
struct module {
|
||||||
|
|||||||
+23
-13
@@ -21,10 +21,14 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <lite/lite.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
@@ -40,36 +44,42 @@
|
|||||||
|
|
||||||
static void load(void *arg)
|
static void load(void *arg)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
struct dirent *d;
|
||||||
DIR *dirp;
|
|
||||||
struct dirent *direntp;
|
|
||||||
char line[256];
|
char line[256];
|
||||||
int index = 1;
|
int index = 1;
|
||||||
|
FILE *fp;
|
||||||
|
DIR *dir;
|
||||||
|
|
||||||
_d("Scanning " MODULES_LOAD_PATH " for config files ...");
|
_d("Scanning " MODULES_LOAD_PATH " for config files ...");
|
||||||
|
|
||||||
dirp = opendir(MODULES_LOAD_PATH);
|
dir = opendir(MODULES_LOAD_PATH);
|
||||||
if (!dirp) return;
|
if (!dir)
|
||||||
|
return;
|
||||||
|
|
||||||
while ((direntp = readdir(dirp)))
|
while ((d = readdir(dir))) {
|
||||||
{
|
|
||||||
char module_path[PATH_MAX];
|
char module_path[PATH_MAX];
|
||||||
|
|
||||||
strlcpy(module_path, MODULES_LOAD_PATH "/", sizeof(module_path));
|
strlcpy(module_path, MODULES_LOAD_PATH "/", sizeof(module_path));
|
||||||
strlcat(module_path, direntp->d_name, sizeof(module_path));
|
strlcat(module_path, d->d_name, sizeof(module_path));
|
||||||
|
|
||||||
fp = fopen(module_path, "r");
|
fp = fopen(module_path, "r");
|
||||||
if (!fp) continue;
|
if (!fp)
|
||||||
|
continue;
|
||||||
|
|
||||||
while (fgets(line, sizeof(line), fp)) {
|
while (fgets(line, sizeof(line), fp)) {
|
||||||
char cmd[CMD_SIZE], *mod, *args;
|
char cmd[CMD_SIZE], *mod, *args;
|
||||||
|
|
||||||
mod = strip_line(line);
|
mod = strip_line(line);
|
||||||
if (!*mod) continue;
|
if (!*mod)
|
||||||
|
continue;
|
||||||
|
|
||||||
mod = chomp(mod);
|
mod = chomp(mod);
|
||||||
if (!mod || !*mod) continue;
|
if (!mod || !*mod)
|
||||||
|
continue;
|
||||||
|
|
||||||
mod = strtok_r(mod, " ", &args);
|
mod = strtok_r(mod, " ", &args);
|
||||||
|
if (!mod)
|
||||||
|
continue;
|
||||||
|
|
||||||
snprintf(cmd, sizeof(cmd), SERVICE_LINE, index, mod, mod, args, mod);
|
snprintf(cmd, sizeof(cmd), SERVICE_LINE, index, mod, mod, args, mod);
|
||||||
service_register(SVC_TYPE_TASK, cmd, global_rlimit, NULL);
|
service_register(SVC_TYPE_TASK, cmd, global_rlimit, NULL);
|
||||||
@@ -80,7 +90,7 @@ static void load(void *arg)
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(dirp);
|
closedir(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static plugin_t plugin = {
|
static plugin_t plugin = {
|
||||||
|
|||||||
+1
-1
@@ -355,7 +355,7 @@ static void nl_resync(int all)
|
|||||||
|
|
||||||
if (all) {
|
if (all) {
|
||||||
_d("============================ RESYNC =================================");
|
_d("============================ RESYNC =================================");
|
||||||
/* this doesn't update condtions, and thus does not stop services */
|
/* this doesn't update conditions, and thus does not stop services */
|
||||||
cond_deassert("net/");
|
cond_deassert("net/");
|
||||||
|
|
||||||
nl_resync_ifaces(sd, seq++);
|
nl_resync_ifaces(sd, seq++);
|
||||||
|
|||||||
+3
-1
@@ -84,8 +84,10 @@ static void pidfile_update_conds(char *dir, char *name, uint32_t mask)
|
|||||||
mkcond(svc, cond, sizeof(cond));
|
mkcond(svc, cond, sizeof(cond));
|
||||||
if (mask & (IN_CLOSE_WRITE | IN_ATTRIB | IN_MODIFY | IN_MOVED_TO)) {
|
if (mask & (IN_CLOSE_WRITE | IN_ATTRIB | IN_MODIFY | IN_MOVED_TO)) {
|
||||||
svc_started(svc);
|
svc_started(svc);
|
||||||
if (!svc_has_pidfile(svc))
|
if (!svc_has_pidfile(svc)) {
|
||||||
|
_d("Setting %s PID file to %s", svc->name, fn);
|
||||||
pid_file_set(svc, fn, 1);
|
pid_file_set(svc, fn, 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (svc_is_forking(svc)) {
|
if (svc_is_forking(svc)) {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|||||||
+5
-1
@@ -22,7 +22,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
|||||||
@@ -21,7 +21,11 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
|||||||
+16
-2
@@ -24,7 +24,11 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <linux/rtc.h>
|
#include <linux/rtc.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
@@ -152,8 +156,18 @@ static void rtc_restore(void *arg)
|
|||||||
logit(LOG_ERR, "RTC has no previously saved (valid) time.");
|
logit(LOG_ERR, "RTC has no previously saved (valid) time.");
|
||||||
else
|
else
|
||||||
logit(LOG_ERR, "RTC error code %d: %s", errno, strerror(errno));
|
logit(LOG_ERR, "RTC error code %d: %s", errno, strerror(errno));
|
||||||
|
|
||||||
|
/* Been here already? */
|
||||||
|
if (rc)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Attempt to set RTC to a sane value ... */
|
||||||
|
tv.tv_sec = RTC_TIMESTAMP_BEGIN_2000;
|
||||||
|
if (!gmtime_r(&tv.tv_sec, &tm))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
logit(LOG_NOTICE, "Resetting RTC to kernel default, 2000-01-01 00:00.");
|
||||||
rc = 2;
|
rc = 2;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print_desc(NULL, "Restoring system clock (UTC) from RTC");
|
print_desc(NULL, "Restoring system clock (UTC) from RTC");
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* System condtion event monitor for the Finit condition engine
|
/* System condition event monitor for the Finit condition engine
|
||||||
*
|
*
|
||||||
* Copyright (c) 2021 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
|
|||||||
+5
-1
@@ -27,7 +27,11 @@
|
|||||||
#include <unistd.h> /* read() */
|
#include <unistd.h> /* read() */
|
||||||
#include <sys/inotify.h>
|
#include <sys/inotify.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
|||||||
+70
-3
@@ -22,19 +22,34 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h> /* gettimeofday() */
|
#include <sys/time.h> /* gettimeofday() */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
#include <linux/random.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
|
||||||
|
#ifndef RANDOM_BYTES
|
||||||
|
#define RANDOM_BYTES (32*1024)
|
||||||
|
#endif
|
||||||
|
|
||||||
static void setup(void *arg)
|
static void setup(void *arg)
|
||||||
{
|
{
|
||||||
#ifdef RANDOMSEED
|
#ifdef RANDOMSEED
|
||||||
|
struct rand_pool_info *rpi;
|
||||||
|
ssize_t len = 0;
|
||||||
|
int rc = -1;
|
||||||
|
int fd, err;
|
||||||
|
|
||||||
if (rescue) {
|
if (rescue) {
|
||||||
_d("Skipping %s plugin in rescue mode.", __FILE__);
|
_d("Skipping %s plugin in rescue mode.", __FILE__);
|
||||||
return;
|
return;
|
||||||
@@ -67,7 +82,59 @@ static void setup(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
print_desc("Initializing random number generator", NULL);
|
print_desc("Initializing random number generator", NULL);
|
||||||
print_result(512 != copyfile(RANDOMSEED, "/dev/urandom", 0, 0));
|
|
||||||
|
/*
|
||||||
|
* Simply copying our saved entropy to /dev/urandom doesn't
|
||||||
|
* increment the kernel "entropy count", instead we must use
|
||||||
|
* the ioctl below.
|
||||||
|
*/
|
||||||
|
fd = open(RANDOMSEED, O_RDONLY);
|
||||||
|
if (fd < 0)
|
||||||
|
goto fallback;
|
||||||
|
|
||||||
|
rpi = malloc(sizeof(*rpi) + RANDOM_BYTES);
|
||||||
|
if (!rpi) {
|
||||||
|
close(fd);
|
||||||
|
goto fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
ssize_t num;
|
||||||
|
|
||||||
|
num = read(fd, &rpi->buf[len], RANDOM_BYTES - len);
|
||||||
|
if (num <= 0) {
|
||||||
|
if (num == -1 && errno == EINTR)
|
||||||
|
continue;
|
||||||
|
if (len > 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
free(rpi);
|
||||||
|
goto fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
len += num;
|
||||||
|
} while (len < RANDOM_BYTES);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
fd = open("/dev/urandom", O_WRONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
free(rpi);
|
||||||
|
goto fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpi->buf_size = len;
|
||||||
|
rpi->entropy_count = len * 8;
|
||||||
|
rc = ioctl(fd, RNDADDENTROPY, rpi);
|
||||||
|
err = errno;
|
||||||
|
close(fd);
|
||||||
|
free(rpi);
|
||||||
|
if (rc < 0)
|
||||||
|
logit(LOG_ERR, "Failed adding entropy to kernel random pool: %s", strerror(err));
|
||||||
|
print_result(rc < 0);
|
||||||
|
return;
|
||||||
|
fallback:
|
||||||
|
print_result(512 > copyfile(RANDOMSEED, "/dev/urandom", 0, 0));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +151,7 @@ static void save(void *arg)
|
|||||||
prev = umask(077);
|
prev = umask(077);
|
||||||
|
|
||||||
print_desc("Saving random seed", NULL);
|
print_desc("Saving random seed", NULL);
|
||||||
print_result(512 != copyfile("/dev/urandom", RANDOMSEED, 512, 0));
|
print_result(RANDOM_BYTES != copyfile("/dev/urandom", RANDOMSEED, RANDOM_BYTES, 0));
|
||||||
|
|
||||||
umask(prev);
|
umask(prev);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+3
-1
@@ -1,4 +1,4 @@
|
|||||||
/* User-defined condtion event monitor for the Finit condition engine
|
/* User-defined condition event monitor for the Finit condition engine
|
||||||
*
|
*
|
||||||
* Copyright (c) 2021 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2021 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
@@ -97,6 +97,8 @@ static void usr_init(void *arg)
|
|||||||
|
|
||||||
if (iwatch_add(&iw_usr, path, IN_ONLYDIR))
|
if (iwatch_add(&iw_usr, path, IN_ONLYDIR))
|
||||||
iwatch_exit(&iw_usr);
|
iwatch_exit(&iw_usr);
|
||||||
|
|
||||||
|
free(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static plugin_t plugin = {
|
static plugin_t plugin = {
|
||||||
|
|||||||
@@ -24,7 +24,11 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
|||||||
@@ -29,7 +29,11 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
#include <uev/uev.h>
|
#include <uev/uev.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@@ -387,7 +391,7 @@ static void api_cb(uev_t *w, void *arg, int events)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_e("Request to hand-over wdog ... to PID %d", rq.runlevel);
|
_d("Request to hand-over wdog ... to PID %d", rq.runlevel);
|
||||||
svc = svc_find_by_pid(rq.runlevel);
|
svc = svc_find_by_pid(rq.runlevel);
|
||||||
if (!svc) {
|
if (!svc) {
|
||||||
logit(LOG_ERR, "Cannot find PID %d, not registered.", rq.runlevel);
|
logit(LOG_ERR, "Cannot find PID %d, not registered.", rq.runlevel);
|
||||||
@@ -413,7 +417,7 @@ static void api_cb(uev_t *w, void *arg, int events)
|
|||||||
case INIT_CMD_SVC_ITER:
|
case INIT_CMD_SVC_ITER:
|
||||||
// _d("svc iter, first: %d", rq.runlevel);
|
// _d("svc iter, first: %d", rq.runlevel);
|
||||||
/*
|
/*
|
||||||
* XXX: This severly limits the number of
|
* XXX: This severely limits the number of
|
||||||
* simultaneous client connections, but will
|
* simultaneous client connections, but will
|
||||||
* have to do for now.
|
* have to do for now.
|
||||||
*/
|
*/
|
||||||
@@ -466,12 +470,13 @@ error:
|
|||||||
|
|
||||||
int api_init(uev_ctx_t *ctx)
|
int api_init(uev_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
int sd;
|
|
||||||
mode_t oldmask;
|
|
||||||
struct sockaddr_un sun = {
|
struct sockaddr_un sun = {
|
||||||
.sun_family = AF_UNIX,
|
.sun_family = AF_UNIX,
|
||||||
.sun_path = INIT_SOCKET,
|
.sun_path = INIT_SOCKET,
|
||||||
};
|
};
|
||||||
|
mode_t oldmask;
|
||||||
|
int uid, gid;
|
||||||
|
int sd;
|
||||||
|
|
||||||
_d("Setting up external API socket ...");
|
_d("Setting up external API socket ...");
|
||||||
sd = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0);
|
sd = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0);
|
||||||
@@ -480,20 +485,26 @@ int api_init(uev_ctx_t *ctx)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uid = geteuid();
|
||||||
|
gid = getgroup(DEFGROUP);
|
||||||
|
|
||||||
erase(INIT_SOCKET);
|
erase(INIT_SOCKET);
|
||||||
oldmask = umask(0077);
|
oldmask = umask(0117);
|
||||||
if (-1 == bind(sd, (struct sockaddr*)&sun, sizeof(sun)))
|
if (-1 == bind(sd, (struct sockaddr*)&sun, sizeof(sun)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (-1 == listen(sd, 10))
|
if (-1 == listen(sd, 10))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (chown(INIT_SOCKET, uid, gid))
|
||||||
|
_pe("Failed setting group %s on %s", DEFGROUP, INIT_SOCKET);
|
||||||
|
|
||||||
umask(oldmask);
|
umask(oldmask);
|
||||||
if (!uev_io_init(ctx, &api_watcher, api_cb, NULL, sd, UEV_READ))
|
if (!uev_io_init(ctx, &api_watcher, api_cb, NULL, sd, UEV_READ))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
_pe("Failed intializing API socket");
|
_pe("Failed initializing API socket");
|
||||||
umask(oldmask);
|
umask(oldmask);
|
||||||
close(sd);
|
close(sd);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
+41
-7
@@ -24,8 +24,13 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
#include <lite/queue.h>
|
# include <libite/lite.h>
|
||||||
|
# include <libite/queue.h> /* BSD sys/queue.h API */
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
# include <lite/queue.h> /* BSD sys/queue.h API */
|
||||||
|
#endif
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/sysinfo.h> /* get_nprocs_conf() */
|
#include <sys/sysinfo.h> /* get_nprocs_conf() */
|
||||||
|
|
||||||
@@ -42,7 +47,7 @@ struct cg {
|
|||||||
char *cfg; /* kernel settings */
|
char *cfg; /* kernel settings */
|
||||||
|
|
||||||
int active; /* for mark & sweep */
|
int active; /* for mark & sweep */
|
||||||
int protected; /* for init/, user/, & system/ */
|
int is_protected; /* for init/, user/, & system/ */
|
||||||
};
|
};
|
||||||
|
|
||||||
static TAILQ_HEAD(, cg) cgroups = TAILQ_HEAD_INITIALIZER(cgroups);
|
static TAILQ_HEAD(, cg) cgroups = TAILQ_HEAD_INITIALIZER(cgroups);
|
||||||
@@ -51,6 +56,7 @@ static char controllers[256];
|
|||||||
|
|
||||||
static struct iwatch iw_cgroup;
|
static struct iwatch iw_cgroup;
|
||||||
static uev_t cgw;
|
static uev_t cgw;
|
||||||
|
static int avail;
|
||||||
|
|
||||||
|
|
||||||
static void cgset(const char *path, char *ctrl, char *prop)
|
static void cgset(const char *path, char *ctrl, char *prop)
|
||||||
@@ -159,6 +165,9 @@ static int cgroup_leaf_init(char *group, char *name, int pid, const char *cfg)
|
|||||||
|
|
||||||
int cgroup_user(char *name, int pid)
|
int cgroup_user(char *name, int pid)
|
||||||
{
|
{
|
||||||
|
if (!avail)
|
||||||
|
return 0;
|
||||||
|
|
||||||
return cgroup_leaf_init("user", name, pid, NULL);
|
return cgroup_leaf_init("user", name, pid, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,6 +175,9 @@ int cgroup_service(char *name, int pid, struct cgroup *cg)
|
|||||||
{
|
{
|
||||||
char *group = "system";
|
char *group = "system";
|
||||||
|
|
||||||
|
if (!avail)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (cg && cg->name[0]) {
|
if (cg && cg->name[0]) {
|
||||||
char path[256];
|
char path[256];
|
||||||
|
|
||||||
@@ -302,8 +314,11 @@ void cgroup_mark_all(void)
|
|||||||
{
|
{
|
||||||
struct cg *cg;
|
struct cg *cg;
|
||||||
|
|
||||||
|
if (!avail)
|
||||||
|
return;
|
||||||
|
|
||||||
TAILQ_FOREACH(cg, &cgroups, link) {
|
TAILQ_FOREACH(cg, &cgroups, link) {
|
||||||
if (cg->protected)
|
if (cg->is_protected)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cg->active = 0;
|
cg->active = 0;
|
||||||
@@ -318,6 +333,9 @@ void cgroup_cleanup(void)
|
|||||||
struct cg *cg, *tmp;
|
struct cg *cg, *tmp;
|
||||||
char path[256];
|
char path[256];
|
||||||
|
|
||||||
|
if (!avail)
|
||||||
|
return;
|
||||||
|
|
||||||
TAILQ_FOREACH_SAFE(cg, &cgroups, link, tmp) {
|
TAILQ_FOREACH_SAFE(cg, &cgroups, link, tmp) {
|
||||||
if (cg->active)
|
if (cg->active)
|
||||||
continue;
|
continue;
|
||||||
@@ -330,10 +348,13 @@ void cgroup_cleanup(void)
|
|||||||
/*
|
/*
|
||||||
* Add, or update, settings for top-level cgroup
|
* Add, or update, settings for top-level cgroup
|
||||||
*/
|
*/
|
||||||
int cgroup_add(char *name, char *cfg, int protected)
|
int cgroup_add(char *name, char *cfg, int is_protected)
|
||||||
{
|
{
|
||||||
struct cg *cg;
|
struct cg *cg;
|
||||||
|
|
||||||
|
if (!avail)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!name)
|
if (!name)
|
||||||
return -1;
|
return -1;
|
||||||
if (!cfg)
|
if (!cfg)
|
||||||
@@ -364,7 +385,7 @@ int cgroup_add(char *name, char *cfg, int protected)
|
|||||||
free(cg);
|
free(cg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cg->protected = protected;
|
cg->is_protected = is_protected;
|
||||||
cg->active = 1;
|
cg->active = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -378,6 +399,9 @@ int cgroup_del(char *dir)
|
|||||||
struct cg *cg;
|
struct cg *cg;
|
||||||
char path[256];
|
char path[256];
|
||||||
|
|
||||||
|
if (!avail)
|
||||||
|
return 0;
|
||||||
|
|
||||||
TAILQ_FOREACH(cg, &cgroups, link) {
|
TAILQ_FOREACH(cg, &cgroups, link) {
|
||||||
snprintf(path, sizeof(path), FINIT_CGPATH "/%s", cg->name);
|
snprintf(path, sizeof(path), FINIT_CGPATH "/%s", cg->name);
|
||||||
if (strcmp(path, dir))
|
if (strcmp(path, dir))
|
||||||
@@ -409,6 +433,9 @@ void cgroup_config(void)
|
|||||||
{
|
{
|
||||||
struct cg *cg;
|
struct cg *cg;
|
||||||
|
|
||||||
|
if (!avail)
|
||||||
|
return;
|
||||||
|
|
||||||
TAILQ_FOREACH(cg, &cgroups, link) {
|
TAILQ_FOREACH(cg, &cgroups, link) {
|
||||||
char path[256];
|
char path[256];
|
||||||
int leaf = 0;
|
int leaf = 0;
|
||||||
@@ -437,14 +464,21 @@ void cgroup_init(uev_ctx_t *ctx)
|
|||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (mount("none", FINIT_CGPATH, "cgroup2", opts, NULL)) {
|
if (mount("none", FINIT_CGPATH, "cgroup2", opts, NULL)) {
|
||||||
_pe("Failed mounting cgroup v2");
|
if (errno == ENOENT)
|
||||||
|
logit(LOG_NOTICE, "Kernel does not support cgroups v2, disabling.");
|
||||||
|
else
|
||||||
|
_pe("Failed mounting cgroup v2, disabling.");
|
||||||
|
avail = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
avail = 1;
|
||||||
|
|
||||||
/* Find available controllers */
|
/* Find available controllers */
|
||||||
fp = fopen(FINIT_CGPATH "/cgroup.controllers", "r");
|
fp = fopen(FINIT_CGPATH "/cgroup.controllers", "r");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
_pe("Failed opening %s", FINIT_CGPATH "/cgroup.controllers");
|
_pe("Failed opening %s", FINIT_CGPATH "/cgroup.controllers");
|
||||||
|
umount(FINIT_CGPATH);
|
||||||
|
avail = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@ struct cgroup {
|
|||||||
void cgroup_mark_all(void);
|
void cgroup_mark_all(void);
|
||||||
void cgroup_cleanup (void);
|
void cgroup_cleanup (void);
|
||||||
|
|
||||||
int cgroup_add (char *name, char *cfg, int protected);
|
int cgroup_add (char *name, char *cfg, int is_protected);
|
||||||
int cgroup_del (char *dir);
|
int cgroup_del (char *dir);
|
||||||
void cgroup_config (void);
|
void cgroup_config (void);
|
||||||
|
|
||||||
|
|||||||
+9
-1
@@ -30,7 +30,11 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <search.h>
|
#include <search.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
#include <sys/sysinfo.h> /* sysinfo() */
|
#include <sys/sysinfo.h> /* sysinfo() */
|
||||||
|
|
||||||
#include "cgutil.h"
|
#include "cgutil.h"
|
||||||
@@ -49,6 +53,10 @@ uint64_t total_ram; /* From sysinfo() */
|
|||||||
struct cg dummy; /* empty result "NULL" */
|
struct cg dummy; /* empty result "NULL" */
|
||||||
struct cg *list;
|
struct cg *list;
|
||||||
|
|
||||||
|
int cgroup_avail(void)
|
||||||
|
{
|
||||||
|
return fismnt(FINIT_CGPATH);
|
||||||
|
}
|
||||||
|
|
||||||
char *pid_cmdline(int pid, char *buf, size_t len)
|
char *pid_cmdline(int pid, char *buf, size_t len)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ struct cg {
|
|||||||
} cg_cpu;
|
} cg_cpu;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int cgroup_avail(void);
|
||||||
|
|
||||||
char *pid_cmdline (int pid, char *buf, size_t len);
|
char *pid_cmdline (int pid, char *buf, size_t len);
|
||||||
char *pid_comm (int pid, char *buf, size_t len);
|
char *pid_comm (int pid, char *buf, size_t len);
|
||||||
char *pid_cgroup (int pid, char *buf, size_t len);
|
char *pid_cgroup (int pid, char *buf, size_t len);
|
||||||
|
|||||||
+6
-2
@@ -23,8 +23,12 @@
|
|||||||
|
|
||||||
#include <ftw.h>
|
#include <ftw.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <lite/lite.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "cond.h"
|
#include "cond.h"
|
||||||
@@ -273,7 +277,7 @@ static int do_assert(const char *fpath, const struct stat *sb, int tflg, struct
|
|||||||
|
|
||||||
nm = strstr((char *)fpath, COND_BASE);
|
nm = strstr((char *)fpath, COND_BASE);
|
||||||
if (!nm) {
|
if (!nm) {
|
||||||
_e("Incorrect condtion path %s, cannot %sassert", fpath, set ? "re" : "de");
|
_e("Incorrect condition path %s, cannot %sassert", fpath, set ? "re" : "de");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -21,8 +21,12 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <lite/lite.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "cond.h"
|
#include "cond.h"
|
||||||
|
|||||||
+2
-1
@@ -2,7 +2,8 @@
|
|||||||
#define FINIT_COND_H_
|
#define FINIT_COND_H_
|
||||||
|
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
#include <svc.h>
|
|
||||||
|
#include "svc.h"
|
||||||
|
|
||||||
#define COND_BASE "finit/cond"
|
#define COND_BASE "finit/cond"
|
||||||
#define COND_PID "pid/"
|
#define COND_PID "pid/"
|
||||||
|
|||||||
+55
-6
@@ -28,14 +28,20 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/inotify.h>
|
#include <sys/inotify.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
#include <lite/queue.h> /* BSD sys/queue.h API */
|
# include <libite/lite.h>
|
||||||
|
# include <libite/queue.h> /* BSD sys/queue.h API */
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
# include <lite/queue.h> /* BSD sys/queue.h API */
|
||||||
|
#endif
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "cond.h"
|
#include "cond.h"
|
||||||
#include "iwatch.h"
|
#include "iwatch.h"
|
||||||
|
#include "private.h"
|
||||||
#include "service.h"
|
#include "service.h"
|
||||||
#include "tty.h"
|
#include "tty.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
@@ -82,6 +88,7 @@ fallback:
|
|||||||
/*
|
/*
|
||||||
* finit.debug = [on,off]
|
* finit.debug = [on,off]
|
||||||
* finit.show_status = [on,off]
|
* finit.show_status = [on,off]
|
||||||
|
* finit.status_style = [old,classic,modern]
|
||||||
*/
|
*/
|
||||||
static void parse_finit_opts(char *opt)
|
static void parse_finit_opts(char *opt)
|
||||||
{
|
{
|
||||||
@@ -165,19 +172,41 @@ static void parse_kernel_cmdline(void)
|
|||||||
#define parse_kernel_cmdline()
|
#define parse_kernel_cmdline()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void parse_kernel_loglevel(void)
|
||||||
|
{
|
||||||
|
char line[LINE_SIZE], *ptr;
|
||||||
|
FILE *fp;
|
||||||
|
int val;
|
||||||
|
|
||||||
|
fp = fopen("/proc/sys/kernel/printk", "r");
|
||||||
|
if (!fp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!fgets(line, sizeof(line), fp)) {
|
||||||
|
fclose(fp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
ptr = chomp(line);
|
||||||
|
_d("%s", ptr);
|
||||||
|
val = atoi(ptr);
|
||||||
|
if (val >= 7)
|
||||||
|
kerndebug = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Kernel gives us all non-kernel options on our cmdline
|
* Kernel gives us all non-kernel options on our cmdline
|
||||||
*/
|
*/
|
||||||
void conf_parse_cmdline(int argc, char *argv[])
|
void conf_parse_cmdline(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int dbg = 0;
|
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++)
|
for (int i = 1; i < argc; i++)
|
||||||
parse_arg(argv[i]);
|
parse_arg(argv[i]);
|
||||||
|
|
||||||
parse_kernel_cmdline();
|
parse_kernel_cmdline();
|
||||||
|
parse_kernel_loglevel();
|
||||||
|
|
||||||
log_init(dbg);
|
log_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kmod_exists(char *mod)
|
static int kmod_exists(char *mod)
|
||||||
@@ -544,6 +573,26 @@ static void parse_static(char *line, int is_rcsd)
|
|||||||
cfglevel = 2; /* Fallback */
|
cfglevel = 2; /* Fallback */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Periodic check and instability index leveler, seconds
|
||||||
|
*/
|
||||||
|
if (MATCH_CMD(line, "service-interval ", x)) {
|
||||||
|
char *token = strip_line(x);
|
||||||
|
const char *err = NULL;
|
||||||
|
int val;
|
||||||
|
|
||||||
|
/* 0 min to 1 day, should check at least daily */
|
||||||
|
val = strtonum(token, 0, 1440, &err);
|
||||||
|
if (!err) {
|
||||||
|
int disabled = !service_interval;
|
||||||
|
|
||||||
|
service_interval = val * 1000; /* to milliseconds */
|
||||||
|
if (disabled)
|
||||||
|
service_init();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_dynamic(char *line, struct rlimit rlimit[], char *file)
|
static void parse_dynamic(char *line, struct rlimit rlimit[], char *file)
|
||||||
@@ -580,7 +629,7 @@ static void parse_dynamic(char *line, struct rlimit rlimit[], char *file)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read contrl group limits */
|
/* Read control group limits */
|
||||||
if (MATCH_CMD(line, "cgroup ", x)) {
|
if (MATCH_CMD(line, "cgroup ", x)) {
|
||||||
conf_parse_cgroup(x);
|
conf_parse_cgroup(x);
|
||||||
return;
|
return;
|
||||||
|
|||||||
+7
-3
@@ -33,7 +33,11 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/ttydefaults.h> /* Not included by default in musl libc */
|
#include <sys/ttydefaults.h> /* Not included by default in musl libc */
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
#include <linux/vt.h>
|
#include <linux/vt.h>
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
@@ -282,7 +286,7 @@ static void prepare_tty(char *tty, speed_t speed, char *procname, struct rlimit
|
|||||||
static int activate_console(int noclear, int nowait)
|
static int activate_console(int noclear, int nowait)
|
||||||
{
|
{
|
||||||
static const char msg[] = "\nPlease press Enter to activate this console.";
|
static const char msg[] = "\nPlease press Enter to activate this console.";
|
||||||
static const char clr[] = "\r\e[2K";
|
static const char clr[] = "\r\e[K";
|
||||||
static const char cup[] = "\e[A";
|
static const char cup[] = "\e[A";
|
||||||
struct termios orig;
|
struct termios orig;
|
||||||
char c;
|
char c;
|
||||||
@@ -351,7 +355,7 @@ pid_t run_getty(char *tty, char *cmd, char *args[], int noclear, int nowait, str
|
|||||||
/* Dunno speed, tell stty() to not mess with it */
|
/* Dunno speed, tell stty() to not mess with it */
|
||||||
prepare_tty(tty, B0, "getty", rlimit);
|
prepare_tty(tty, B0, "getty", rlimit);
|
||||||
if (activate_console(noclear, nowait)) {
|
if (activate_console(noclear, nowait)) {
|
||||||
logit(LOG_INFO, "Starting external getty on %s", tty);
|
logit(LOG_INFO, "Starting getty on %s", tty);
|
||||||
rc = execv(cmd, args);
|
rc = execv(cmd, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+81
-29
@@ -36,7 +36,11 @@
|
|||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/stat.h> /* umask(), mkdir() */
|
#include <sys/stat.h> /* umask(), mkdir() */
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "cgroup.h"
|
#include "cgroup.h"
|
||||||
@@ -61,6 +65,7 @@ int debug = 0; /* debug mode from kernel cmdline */
|
|||||||
int rescue = 0; /* rescue mode from kernel cmdline */
|
int rescue = 0; /* rescue mode from kernel cmdline */
|
||||||
int single = 0; /* single user mode from kernel cmdline */
|
int single = 0; /* single user mode from kernel cmdline */
|
||||||
int bootstrap = 1; /* set while bootrapping (for TTYs) */
|
int bootstrap = 1; /* set while bootrapping (for TTYs) */
|
||||||
|
int kerndebug = 0; /* set if /proc/sys/kernel/printk > 7 */
|
||||||
char *sdown = NULL;
|
char *sdown = NULL;
|
||||||
char *network = NULL;
|
char *network = NULL;
|
||||||
char *hostname = NULL;
|
char *hostname = NULL;
|
||||||
@@ -82,7 +87,7 @@ static void banner(void)
|
|||||||
* similar enabled to start emptying /dev/kmsg, but for
|
* similar enabled to start emptying /dev/kmsg, but for
|
||||||
* our progress we want to own the console.
|
* our progress we want to own the console.
|
||||||
*/
|
*/
|
||||||
if (!debug)
|
if (!debug && !kerndebug)
|
||||||
klogctl(6, NULL, 0);
|
klogctl(6, NULL, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -117,6 +122,7 @@ static int fsck(int pass)
|
|||||||
while ((fs = getfsent())) {
|
while ((fs = getfsent())) {
|
||||||
char cmd[80];
|
char cmd[80];
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
int fsck_rc = 0;
|
||||||
|
|
||||||
if (fs->fs_passno != pass)
|
if (fs->fs_passno != pass)
|
||||||
continue;
|
continue;
|
||||||
@@ -134,8 +140,33 @@ static int fsck(int pass)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef FSCK_FIX
|
||||||
|
snprintf(cmd, sizeof(cmd), "fsck -yf %s", fs->fs_spec);
|
||||||
|
#else
|
||||||
snprintf(cmd, sizeof(cmd), "fsck -a %s", fs->fs_spec);
|
snprintf(cmd, sizeof(cmd), "fsck -a %s", fs->fs_spec);
|
||||||
rc += run_interactive(cmd, "Checking filesystem %.13s", fs->fs_spec);
|
#endif
|
||||||
|
fsck_rc = run_interactive(cmd, "Checking filesystem %.13s", fs->fs_spec);
|
||||||
|
/*
|
||||||
|
* "failure" is defined as exiting with a return code of
|
||||||
|
* 2 or larger. A return code of 1 indicates that filesystem
|
||||||
|
* errors were corrected but that the boot may proceed.
|
||||||
|
*/
|
||||||
|
if (fsck_rc > 1) {
|
||||||
|
char *sulogin[] = {
|
||||||
|
_PATH_SULOGIN,
|
||||||
|
"sulogin",
|
||||||
|
};
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < NELEMS(sulogin); i++) {
|
||||||
|
if (systemf(sulogin[i]))
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
do_shutdown(SHUT_REBOOT);
|
||||||
|
}
|
||||||
|
rc += fsck_rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
endfsent();
|
endfsent();
|
||||||
@@ -145,17 +176,31 @@ static int fsck(int pass)
|
|||||||
|
|
||||||
static int fsck_all(void)
|
static int fsck_all(void)
|
||||||
{
|
{
|
||||||
int pass, rc = 0;
|
int rc = 0;
|
||||||
|
#ifndef FAST_BOOT
|
||||||
|
int pass;
|
||||||
|
|
||||||
for (pass = 1; pass < 10; pass++) {
|
for (pass = 1; pass < 10; pass++) {
|
||||||
rc = fsck(pass);
|
rc = fsck(pass);
|
||||||
if (rc)
|
if (rc)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Wrapper for mount(2), logs any errors to stderr */
|
||||||
|
static void fs_mount(const char *src, const char *tgt, const char *fstype,
|
||||||
|
unsigned long flags, const void *data)
|
||||||
|
{
|
||||||
|
const char *msg = !fstype ? "MS_MOVE" : "mounting";
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = mount(src, tgt, fstype, flags, data);
|
||||||
|
if (rc && errno != EBUSY)
|
||||||
|
_pe("Failed %s %s on %s", msg, src, tgt);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef SYSROOT
|
#ifndef SYSROOT
|
||||||
/* If / is not listed in fstab, or listed as 'ro', leave it alone */
|
/* If / is not listed in fstab, or listed as 'ro', leave it alone */
|
||||||
static int fs_readonly_root(struct fstab *fs)
|
static int fs_readonly_root(struct fstab *fs)
|
||||||
@@ -207,8 +252,7 @@ static void fs_remount_root(int fsckerr)
|
|||||||
* XXX: Untested, in the initramfs age we should
|
* XXX: Untested, in the initramfs age we should
|
||||||
* probably use switch_root instead.
|
* probably use switch_root instead.
|
||||||
*/
|
*/
|
||||||
if (mount(SYSROOT, "/", NULL, MS_MOVE, NULL))
|
fs_mount(SYSROOT, "/", NULL, MS_MOVE, NULL);
|
||||||
_pe("Failed %s / MS_MOVE");
|
|
||||||
}
|
}
|
||||||
#endif /* SYSROOT */
|
#endif /* SYSROOT */
|
||||||
|
|
||||||
@@ -232,7 +276,7 @@ static void fs_finalize(void)
|
|||||||
*/
|
*/
|
||||||
if (!fismnt("/dev/shm")) {
|
if (!fismnt("/dev/shm")) {
|
||||||
makedir("/dev/shm", 0777);
|
makedir("/dev/shm", 0777);
|
||||||
mount("shm", "/dev/shm", "tmpfs", 0, "mode=0777");
|
fs_mount("shm", "/dev/shm", "tmpfs", 0, "mode=0777");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Modern systems use /dev/pts */
|
/* Modern systems use /dev/pts */
|
||||||
@@ -250,7 +294,7 @@ static void fs_finalize(void)
|
|||||||
snprintf(opts, sizeof(opts), "gid=%d,mode=%d,ptmxmode=0666", gid, mode);
|
snprintf(opts, sizeof(opts), "gid=%d,mode=%d,ptmxmode=0666", gid, mode);
|
||||||
|
|
||||||
makedir("/dev/pts", 0755);
|
makedir("/dev/pts", 0755);
|
||||||
mount("devpts", "/dev/pts", "devpts", MS_NOSUID | MS_NOEXEC, opts);
|
fs_mount("devpts", "/dev/pts", "devpts", MS_NOSUID | MS_NOEXEC, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -263,19 +307,19 @@ static void fs_finalize(void)
|
|||||||
* for /run (and optionally /run/lock).
|
* for /run (and optionally /run/lock).
|
||||||
*/
|
*/
|
||||||
if (fisdir("/run") && !fismnt("/run")) {
|
if (fisdir("/run") && !fismnt("/run")) {
|
||||||
mount("tmpfs", "/run", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME, "mode=0755,size=10%");
|
fs_mount("tmpfs", "/run", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME, "mode=0755,size=10%");
|
||||||
|
|
||||||
/* This prevents user DoS of /run by filling /run/lock at the expense of another tmpfs, max 5MiB */
|
/* This prevents user DoS of /run by filling /run/lock at the expense of another tmpfs, max 5MiB */
|
||||||
makedir("/run/lock", 1777);
|
makedir("/run/lock", 1777);
|
||||||
mount("tmpfs", "/run/lock", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME, "mode=0777,size=5252880");
|
fs_mount("tmpfs", "/run/lock", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME, "mode=0777,size=5252880");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Modern systems use tmpfs for /tmp */
|
/* Modern systems use tmpfs for /tmp */
|
||||||
if (!fismnt("/tmp"))
|
if (!fismnt("/tmp"))
|
||||||
mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_NODEV, "mode=1777");
|
fs_mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_NODEV, "mode=1777");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fs_mount(void)
|
static void fs_mount_all(void)
|
||||||
{
|
{
|
||||||
if (!rescue)
|
if (!rescue)
|
||||||
fs_remount_root(fsck_all());
|
fs_remount_root(fsck_all());
|
||||||
@@ -299,9 +343,9 @@ static void fs_mount(void)
|
|||||||
* We need /proc for rs_remount_root() and conf_parse_cmdline(), /dev
|
* We need /proc for rs_remount_root() and conf_parse_cmdline(), /dev
|
||||||
* for early multi-console, and /sys for the cgroups support. Any
|
* for early multi-console, and /sys for the cgroups support. Any
|
||||||
* occurrence of these file systems in /etc/fstab will replace these
|
* occurrence of these file systems in /etc/fstab will replace these
|
||||||
* mounts later in fs_mount()
|
* mounts later in fs_mount_all()
|
||||||
*
|
*
|
||||||
* Ignore any mount errors with EBUSY, kernel likely alread mounted
|
* Ignore any mount errors with EBUSY, kernel likely already mounted
|
||||||
* the filesystem for us automatically, e.g., CONFIG_DEVTMPFS_MOUNT.
|
* the filesystem for us automatically, e.g., CONFIG_DEVTMPFS_MOUNT.
|
||||||
*/
|
*/
|
||||||
static void fs_init(void)
|
static void fs_init(void)
|
||||||
@@ -319,8 +363,6 @@ static void fs_init(void)
|
|||||||
umask(022);
|
umask(022);
|
||||||
|
|
||||||
for (i = 0; i < NELEMS(fs); i++) {
|
for (i = 0; i < NELEMS(fs); i++) {
|
||||||
int rc;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if already mounted, we may be running in a
|
* Check if already mounted, we may be running in a
|
||||||
* container, or an initramfs ran before us. The
|
* container, or an initramfs ran before us. The
|
||||||
@@ -330,9 +372,7 @@ static void fs_init(void)
|
|||||||
if (fismnt(fs[i].file))
|
if (fismnt(fs[i].file))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
rc = mount(fs[i].spec, fs[i].file, fs[i].type, 0, NULL);
|
fs_mount(fs[i].spec, fs[i].file, fs[i].type, 0, NULL);
|
||||||
if (rc && errno != EBUSY)
|
|
||||||
_pe("Failed mounting %s on %s", fs[i].spec, fs[i].file);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,7 +422,7 @@ static void finalize(void *unused)
|
|||||||
static void crank_worker(void *unused)
|
static void crank_worker(void *unused)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Initalize state machine and start all bootstrap tasks
|
* Initialize state machine and start all bootstrap tasks
|
||||||
* NOTE: no network available!
|
* NOTE: no network available!
|
||||||
*/
|
*/
|
||||||
sm_init(&sm);
|
sm_init(&sm);
|
||||||
@@ -519,11 +559,11 @@ static int telinit(int argc, char *argv[])
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct wq crank = {
|
struct wq crank_work = {
|
||||||
.cb = crank_worker,
|
.cb = crank_worker,
|
||||||
.delay = 10
|
.delay = 10
|
||||||
};
|
};
|
||||||
struct wq bootstrap = {
|
struct wq bootstrap_work = {
|
||||||
.cb = bootstrap_worker,
|
.cb = bootstrap_worker,
|
||||||
.delay = 100
|
.delay = 100
|
||||||
};
|
};
|
||||||
@@ -550,7 +590,7 @@ int main(int argc, char *argv[])
|
|||||||
console_init();
|
console_init();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initalize event context.
|
* Initialize event context.
|
||||||
*/
|
*/
|
||||||
uev_init1(&loop, 1);
|
uev_init1(&loop, 1);
|
||||||
ctx = &loop;
|
ctx = &loop;
|
||||||
@@ -597,6 +637,11 @@ int main(int argc, char *argv[])
|
|||||||
enable_progress(1); /* Allow progress, if enabled */
|
enable_progress(1); /* Allow progress, if enabled */
|
||||||
banner();
|
banner();
|
||||||
|
|
||||||
|
if (osheading)
|
||||||
|
logit(LOG_CONSOLE | LOG_NOTICE, "%s, entering runlevel S", osheading);
|
||||||
|
else
|
||||||
|
logit(LOG_CONSOLE | LOG_NOTICE, "Entering runlevel S");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initial setup of signals, ignore all until we're up.
|
* Initial setup of signals, ignore all until we're up.
|
||||||
*/
|
*/
|
||||||
@@ -608,13 +653,15 @@ int main(int argc, char *argv[])
|
|||||||
cgroup_init(&loop);
|
cgroup_init(&loop);
|
||||||
|
|
||||||
/* Check and mount filesystems. */
|
/* Check and mount filesystems. */
|
||||||
fs_mount();
|
fs_mount_all();
|
||||||
|
|
||||||
/* Bootstrap conditions, needed for hooks */
|
/* Bootstrap conditions, needed for hooks */
|
||||||
cond_init();
|
cond_init();
|
||||||
|
|
||||||
/* Emit conditions for early hooks that ran before the
|
/*
|
||||||
* condition system was initialized in case anyone . */
|
* Emit conditions for early hooks that ran before the condition
|
||||||
|
* system was initialized in case anyone.
|
||||||
|
*/
|
||||||
cond_set_oneshot(plugin_hook_str(HOOK_BANNER));
|
cond_set_oneshot(plugin_hook_str(HOOK_BANNER));
|
||||||
cond_set_oneshot(plugin_hook_str(HOOK_ROOTFS_UP));
|
cond_set_oneshot(plugin_hook_str(HOOK_ROOTFS_UP));
|
||||||
|
|
||||||
@@ -653,10 +700,15 @@ int main(int argc, char *argv[])
|
|||||||
api_init(&loop);
|
api_init(&loop);
|
||||||
|
|
||||||
_d("Starting the big state machine ...");
|
_d("Starting the big state machine ...");
|
||||||
schedule_work(&crank);
|
schedule_work(&crank_work);
|
||||||
|
|
||||||
_d("Starting bootstrap finalize timer ...");
|
_d("Starting bootstrap finalize timer ...");
|
||||||
schedule_work(&bootstrap);
|
schedule_work(&bootstrap_work);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Background service tasks
|
||||||
|
*/
|
||||||
|
service_init();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enter main loop to monitor /dev/initctl and services
|
* Enter main loop to monitor /dev/initctl and services
|
||||||
|
|||||||
+6
-1
@@ -34,7 +34,11 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
#include <uev/uev.h>
|
#include <uev/uev.h>
|
||||||
|
|
||||||
/* just in case */
|
/* just in case */
|
||||||
@@ -110,6 +114,7 @@ extern int debug;
|
|||||||
extern int rescue;
|
extern int rescue;
|
||||||
extern int single;
|
extern int single;
|
||||||
extern int bootstrap;
|
extern int bootstrap;
|
||||||
|
extern int kerndebug;
|
||||||
extern char *rcsd;
|
extern char *rcsd;
|
||||||
extern char *sdown;
|
extern char *sdown;
|
||||||
extern char *network;
|
extern char *network;
|
||||||
|
|||||||
+16
-2
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <limits.h> /* LOGIN_NAME_MAX */
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -33,6 +34,7 @@
|
|||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
#include <sys/ttydefaults.h> /* Not included by default in musl libc */
|
#include <sys/ttydefaults.h> /* Not included by default in musl libc */
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
#include <unistd.h> /* sysconf() */
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
@@ -42,6 +44,12 @@
|
|||||||
#define _PATH_LOGIN "/bin/login"
|
#define _PATH_LOGIN "/bin/login"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef LOGIN_NAME_MIN
|
||||||
|
#define LOGIN_NAME_MIN 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static long logname_len = 32; /* useradd(1) limit at 32 chars */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read one character from stdin.
|
* Read one character from stdin.
|
||||||
*/
|
*/
|
||||||
@@ -196,8 +204,8 @@ static int do_login(char *name)
|
|||||||
|
|
||||||
static int getty(char *tty, speed_t speed, char *term, char *user)
|
static int getty(char *tty, speed_t speed, char *term, char *user)
|
||||||
{
|
{
|
||||||
const char cln[] = "\r\e[2K\n";
|
const char cln[] = "\r\e[K\n";
|
||||||
char name[33]; /* useradd(1) limit at 32 chars */
|
char name[logname_len + 1]; /* +1 for NUL termination */
|
||||||
pid_t sid;
|
pid_t sid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -263,6 +271,12 @@ int main(int argc, char *argv[])
|
|||||||
if (optind < argc)
|
if (optind < argc)
|
||||||
term = argv[optind++];
|
term = argv[optind++];
|
||||||
|
|
||||||
|
logname_len = sysconf(_SC_LOGIN_NAME_MAX);
|
||||||
|
if (logname_len == -1i)
|
||||||
|
logname_len = LOGIN_NAME_MAX;
|
||||||
|
if (logname_len < LOGIN_NAME_MIN)
|
||||||
|
logname_len = LOGIN_NAME_MIN;
|
||||||
|
|
||||||
return getty(tty, atoi(speed), term, NULL);
|
return getty(tty, atoi(speed), term, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-52
@@ -31,7 +31,11 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
@@ -223,7 +227,7 @@ void print_banner(const char *heading)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
strlcat(buf, "\r\e[2K", sizeof(buf));
|
strlcat(buf, "\r\e[K", sizeof(buf));
|
||||||
|
|
||||||
if (progress_style == PROGRESS_CLASSIC) {
|
if (progress_style == PROGRESS_CLASSIC) {
|
||||||
strlcat(buf, "\e[1m", sizeof(buf));
|
strlcat(buf, "\e[1m", sizeof(buf));
|
||||||
@@ -308,7 +312,7 @@ void printv(const char *fmt, va_list ap)
|
|||||||
if (progress_style == PROGRESS_CLASSIC)
|
if (progress_style == PROGRESS_CLASSIC)
|
||||||
cprintf("\r%s ", pad(buf, sizeof(buf), ".", sizeof(buf)));
|
cprintf("\r%s ", pad(buf, sizeof(buf), ".", sizeof(buf)));
|
||||||
else
|
else
|
||||||
cprintf("\r\e[2K%s%s", status(3), buf);
|
cprintf("\r\e[K%s%s", status(3), buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print(int rc, const char *fmt, ...)
|
void print(int rc, const char *fmt, ...)
|
||||||
@@ -560,55 +564,6 @@ void endfsent(void)
|
|||||||
}
|
}
|
||||||
#endif /* HAVE_GETFSENT */
|
#endif /* HAVE_GETFSENT */
|
||||||
|
|
||||||
static int hasopt(char *opts, char *opt)
|
|
||||||
{
|
|
||||||
char buf[strlen(opts) + 1];
|
|
||||||
char *ptr;
|
|
||||||
|
|
||||||
memcpy(buf, opts, sizeof(buf));
|
|
||||||
ptr = strtok(buf, ",");
|
|
||||||
while (ptr) {
|
|
||||||
if (!strcmp(ptr, opt))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
ptr = strtok(NULL, ",");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ismnt(char *file, char *dir, char *mode)
|
|
||||||
{
|
|
||||||
struct mntent *mnt;
|
|
||||||
int found = 0;
|
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
fp = setmntent(file, "r");
|
|
||||||
if (!fp)
|
|
||||||
return 0; /* Dunno, maybe not */
|
|
||||||
|
|
||||||
while ((mnt = getmntent(fp))) {
|
|
||||||
if (!strcmp(mnt->mnt_dir, dir)) {
|
|
||||||
if (mode) {
|
|
||||||
if (hasopt(mnt->mnt_opts, mode))
|
|
||||||
found = 1;
|
|
||||||
} else
|
|
||||||
found = 1;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
endmntent(fp);
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Requires /proc to be mounted */
|
|
||||||
int fismnt(char *dir)
|
|
||||||
{
|
|
||||||
return ismnt("/proc/mounts", dir, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* indent-tabs-mode: t
|
* indent-tabs-mode: t
|
||||||
|
|||||||
+5
-4
@@ -32,7 +32,11 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/ttydefaults.h> /* Not included by default in musl libc */
|
#include <sys/ttydefaults.h> /* Not included by default in musl libc */
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
#define PROGRESS_DEFAULT PROGRESS_MODERN
|
#define PROGRESS_DEFAULT PROGRESS_MODERN
|
||||||
@@ -126,9 +130,6 @@ static inline int dprint(int fd, const char *s, size_t len)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ismnt (char *file, char *dir, char *mode);
|
|
||||||
int fismnt (char *dir);
|
|
||||||
|
|
||||||
#endif /* FINIT_HELPERS_H_ */
|
#endif /* FINIT_HELPERS_H_ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+148
-84
@@ -33,7 +33,11 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <utmp.h>
|
#include <utmp.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "cond.h"
|
#include "cond.h"
|
||||||
@@ -47,6 +51,7 @@ struct cmd {
|
|||||||
char *cmd;
|
char *cmd;
|
||||||
struct cmd *ctx;
|
struct cmd *ctx;
|
||||||
int (*cb)(char *arg);
|
int (*cb)(char *arg);
|
||||||
|
int *cond;
|
||||||
};
|
};
|
||||||
|
|
||||||
int icreate = 0;
|
int icreate = 0;
|
||||||
@@ -58,6 +63,9 @@ int verbose = 0;
|
|||||||
int plain = 0;
|
int plain = 0;
|
||||||
int quiet = 0;
|
int quiet = 0;
|
||||||
int runlevel = 0;
|
int runlevel = 0;
|
||||||
|
int cgrp = 0;
|
||||||
|
int utmp = 0;
|
||||||
|
|
||||||
int iw, pw;
|
int iw, pw;
|
||||||
|
|
||||||
extern int reboot_main(int argc, char *argv[]);
|
extern int reboot_main(int argc, char *argv[]);
|
||||||
@@ -167,11 +175,11 @@ static int do_runlevel(char *arg)
|
|||||||
|
|
||||||
if (!arg) {
|
if (!arg) {
|
||||||
int prevlevel = 0;
|
int prevlevel = 0;
|
||||||
int runlevel;
|
int currlevel;
|
||||||
char prev;
|
char prev;
|
||||||
|
|
||||||
runlevel = runlevel_get(&prevlevel);
|
currlevel = runlevel_get(&prevlevel);
|
||||||
if (255 == runlevel) {
|
if (255 == currlevel) {
|
||||||
printf("unknown\n");
|
printf("unknown\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -180,7 +188,7 @@ static int do_runlevel(char *arg)
|
|||||||
if (prev <= '0' || prev > '9')
|
if (prev <= '0' || prev > '9')
|
||||||
prev = 'N';
|
prev = 'N';
|
||||||
|
|
||||||
printf("%c %d\n", prev , runlevel);
|
printf("%c %d\n", prev , currlevel);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,15 +476,12 @@ int do_suspend (char *arg) { return do_cmd(INIT_CMD_SUSPEND); }
|
|||||||
|
|
||||||
int utmp_show(char *file)
|
int utmp_show(char *file)
|
||||||
{
|
{
|
||||||
static int once = 0;
|
|
||||||
struct tm *sectm;
|
|
||||||
struct utmp *ut;
|
struct utmp *ut;
|
||||||
time_t sec;
|
time_t sec;
|
||||||
|
|
||||||
int pid;
|
|
||||||
char id[sizeof(ut->ut_id) + 1], user[sizeof(ut->ut_user) + 1], when[80];
|
|
||||||
|
|
||||||
if (heading) {
|
if (heading) {
|
||||||
|
static int once = 0;
|
||||||
|
|
||||||
print_header("%s%s ", once ? "\n" : "", file);
|
print_header("%s%s ", once ? "\n" : "", file);
|
||||||
once++;
|
once++;
|
||||||
}
|
}
|
||||||
@@ -484,7 +489,12 @@ int utmp_show(char *file)
|
|||||||
|
|
||||||
setutent();
|
setutent();
|
||||||
while ((ut = getutent())) {
|
while ((ut = getutent())) {
|
||||||
|
char user[sizeof(ut->ut_user) + 1];
|
||||||
|
char id[sizeof(ut->ut_id) + 1];
|
||||||
|
struct tm *sectm;
|
||||||
|
char when[80];
|
||||||
char addr[64];
|
char addr[64];
|
||||||
|
int pid;
|
||||||
|
|
||||||
strlcpy(id, ut->ut_id, sizeof(id));
|
strlcpy(id, ut->ut_id, sizeof(id));
|
||||||
strlcpy(user, ut->ut_user, sizeof(user));
|
strlcpy(user, ut->ut_user, sizeof(user));
|
||||||
@@ -509,7 +519,7 @@ int utmp_show(char *file)
|
|||||||
|
|
||||||
static int do_utmp(char *file)
|
static int do_utmp(char *file)
|
||||||
{
|
{
|
||||||
if (!has_utmp())
|
if (!utmp)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (fexist(file))
|
if (fexist(file))
|
||||||
@@ -538,7 +548,7 @@ static int show_version(char *arg)
|
|||||||
* Pointer to string on the form [2345], may be up to 12 chars long,
|
* Pointer to string on the form [2345], may be up to 12 chars long,
|
||||||
* plus escape sequences for highlighting current runlevel.
|
* plus escape sequences for highlighting current runlevel.
|
||||||
*/
|
*/
|
||||||
char *runlevel_string(int runlevel, int levels)
|
char *runlevel_string(int currlevel, int levels)
|
||||||
{
|
{
|
||||||
int i, pos = 1;
|
int i, pos = 1;
|
||||||
static char lvl[21];
|
static char lvl[21];
|
||||||
@@ -548,7 +558,7 @@ char *runlevel_string(int runlevel, int levels)
|
|||||||
|
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
if (ISSET(levels, i)) {
|
if (ISSET(levels, i)) {
|
||||||
if (!plain && runlevel == i)
|
if (!plain && currlevel == i)
|
||||||
pos = strlcat(lvl, "\e[1m", sizeof(lvl));
|
pos = strlcat(lvl, "\e[1m", sizeof(lvl));
|
||||||
|
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
@@ -556,7 +566,7 @@ char *runlevel_string(int runlevel, int levels)
|
|||||||
else
|
else
|
||||||
lvl[pos++] = '0' + i;
|
lvl[pos++] = '0' + i;
|
||||||
|
|
||||||
if (!plain && runlevel == i)
|
if (!plain && currlevel == i)
|
||||||
pos = strlcat(lvl, "\e[0m", sizeof(lvl));
|
pos = strlcat(lvl, "\e[0m", sizeof(lvl));
|
||||||
} else {
|
} else {
|
||||||
lvl[pos++] = '-';
|
lvl[pos++] = '-';
|
||||||
@@ -699,17 +709,27 @@ static int show_status(char *arg)
|
|||||||
{
|
{
|
||||||
char ident[MAX_IDENT_LEN];
|
char ident[MAX_IDENT_LEN];
|
||||||
char buf[512];
|
char buf[512];
|
||||||
|
int num = 0;
|
||||||
svc_t *svc;
|
svc_t *svc;
|
||||||
|
|
||||||
runlevel = runlevel_get(NULL);
|
runlevel = runlevel_get(NULL);
|
||||||
|
|
||||||
if (arg && arg[0]) {
|
while (arg && arg[0]) {
|
||||||
long now = jiffies();
|
long now = jiffies();
|
||||||
char uptm[42] = "N/A";
|
char uptm[42] = "N/A";
|
||||||
char grbuf[128];
|
char *pidfn = NULL;
|
||||||
char path[256];
|
int exact = 0;
|
||||||
struct cg *cg;
|
|
||||||
char *group;
|
for (svc = client_svc_iterator(1); svc; svc = client_svc_iterator(0)) {
|
||||||
|
svc_ident(svc, ident, sizeof(ident));
|
||||||
|
if (string_match(ident, arg))
|
||||||
|
num++;
|
||||||
|
if (string_case_compare(ident, arg))
|
||||||
|
exact++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num > 1 && !exact)
|
||||||
|
break;
|
||||||
|
|
||||||
svc = client_svc_find(arg);
|
svc = client_svc_find(arg);
|
||||||
if (!svc)
|
if (!svc)
|
||||||
@@ -718,9 +738,11 @@ static int show_status(char *arg)
|
|||||||
if (quiet)
|
if (quiet)
|
||||||
return svc->state != SVC_RUNNING_STATE;
|
return svc->state != SVC_RUNNING_STATE;
|
||||||
|
|
||||||
group = pid_cgroup(svc->pid, grbuf, sizeof(grbuf));
|
pidfn = svc->pidfile;
|
||||||
snprintf(path, sizeof(path), "%s/%s", FINIT_CGPATH, group);
|
if (pidfn[0] == '!')
|
||||||
cg = cg_conf(path);
|
pidfn++;
|
||||||
|
else if (pidfn[0] == 0)
|
||||||
|
pidfn = "none";
|
||||||
|
|
||||||
printf(" Status : %s\n", status(svc, 1));
|
printf(" Status : %s\n", status(svc, 1));
|
||||||
printf(" Identity : %s\n", svc_ident(svc, ident, sizeof(ident)));
|
printf(" Identity : %s\n", svc_ident(svc, ident, sizeof(ident)));
|
||||||
@@ -729,13 +751,23 @@ static int show_status(char *arg)
|
|||||||
printf("Environment : %s\n", svc_environ(svc, buf, sizeof(buf)));
|
printf("Environment : %s\n", svc_environ(svc, buf, sizeof(buf)));
|
||||||
printf("Condition(s): %s\n", svc_cond(svc, buf, sizeof(buf)));
|
printf("Condition(s): %s\n", svc_cond(svc, buf, sizeof(buf)));
|
||||||
printf(" Command : %s\n", svc_command(svc, buf, sizeof(buf)));
|
printf(" Command : %s\n", svc_command(svc, buf, sizeof(buf)));
|
||||||
printf(" PID file : %s\n", svc->pidfile);
|
printf(" PID file : %s\n", pidfn);
|
||||||
printf(" PID : %d\n", svc->pid);
|
printf(" PID : %d\n", svc->pid);
|
||||||
printf(" User : %s\n", svc->username);
|
printf(" User : %s\n", svc->username);
|
||||||
printf(" Group : %s\n", svc->group);
|
printf(" Group : %s\n", svc->group);
|
||||||
printf(" Uptime : %s\n", svc->pid ? uptime(now - svc->start_time, uptm, sizeof(uptm)) : uptm);
|
printf(" Uptime : %s\n", svc->pid ? uptime(now - svc->start_time, uptm, sizeof(uptm)) : uptm);
|
||||||
|
printf(" Restarts : %d (%d/%d)\n", svc->restart_tot, svc->restart_cnt, svc->restart_max);
|
||||||
printf(" Runlevels : %s\n", runlevel_string(runlevel, svc->runlevels));
|
printf(" Runlevels : %s\n", runlevel_string(runlevel, svc->runlevels));
|
||||||
if (svc->pid > 1) {
|
if (cgrp && svc->pid > 1) {
|
||||||
|
char grbuf[128];
|
||||||
|
char path[256];
|
||||||
|
struct cg *cg;
|
||||||
|
char *group;
|
||||||
|
|
||||||
|
group = pid_cgroup(svc->pid, grbuf, sizeof(grbuf));
|
||||||
|
snprintf(path, sizeof(path), "%s/%s", FINIT_CGPATH, group);
|
||||||
|
cg = cg_conf(path);
|
||||||
|
|
||||||
printf(" Memory : %s\n", memsz(cgroup_memory(group), uptm, sizeof(uptm)));
|
printf(" Memory : %s\n", memsz(cgroup_memory(group), uptm, sizeof(uptm)));
|
||||||
printf(" CGroup : %s cpu %s [%s, %s] mem [%s, %s]\n",
|
printf(" CGroup : %s cpu %s [%s, %s] mem [%s, %s]\n",
|
||||||
group, cg->cg_cpu.set, cg->cg_cpu.weight, cg->cg_cpu.max,
|
group, cg->cg_cpu.set, cg->cg_cpu.weight, cg->cg_cpu.max,
|
||||||
@@ -764,9 +796,11 @@ static int show_status(char *arg)
|
|||||||
for (svc = client_svc_iterator(1); svc; svc = client_svc_iterator(0)) {
|
for (svc = client_svc_iterator(1); svc; svc = client_svc_iterator(0)) {
|
||||||
char *lvls;
|
char *lvls;
|
||||||
|
|
||||||
printf("%-*d ", pw, svc->pid);
|
|
||||||
|
|
||||||
svc_ident(svc, ident, sizeof(ident));
|
svc_ident(svc, ident, sizeof(ident));
|
||||||
|
if (num && !string_match(ident, arg))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
printf("%-*d ", pw, svc->pid);
|
||||||
printf("%-*s %s ", iw, ident, status(svc, 0));
|
printf("%-*s %s ", iw, ident, status(svc, 0));
|
||||||
|
|
||||||
lvls = runlevel_string(runlevel, svc->runlevels);
|
lvls = runlevel_string(runlevel, svc->runlevels);
|
||||||
@@ -784,6 +818,30 @@ static int show_status(char *arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int show_ident(char *arg)
|
||||||
|
{
|
||||||
|
svc_t *svc;
|
||||||
|
|
||||||
|
for (svc = client_svc_iterator(1); svc; svc = client_svc_iterator(0)) {
|
||||||
|
char ident[MAX_IDENT_LEN];
|
||||||
|
size_t len;
|
||||||
|
char *pos;
|
||||||
|
|
||||||
|
svc_ident(svc, ident, sizeof(ident));
|
||||||
|
pos = strchr(ident, ':');
|
||||||
|
if (pos)
|
||||||
|
len = pos - ident;
|
||||||
|
else
|
||||||
|
len = strlen(ident);
|
||||||
|
if (arg && arg[0] && strncasecmp(ident, arg, len))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
puts(ident);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int transform(char *nm)
|
static int transform(char *nm)
|
||||||
{
|
{
|
||||||
char *names[] = {
|
char *names[] = {
|
||||||
@@ -880,12 +938,16 @@ static int usage(int rc)
|
|||||||
" stop <NAME>[:ID] Stop/Pause a running service by name\n"
|
" stop <NAME>[:ID] Stop/Pause a running service by name\n"
|
||||||
" reload <NAME>[:ID] Reload service by name (SIGHUP or restart)\n"
|
" reload <NAME>[:ID] Reload service by name (SIGHUP or restart)\n"
|
||||||
" restart <NAME>[:ID] Restart (stop/start) service by name\n"
|
" restart <NAME>[:ID] Restart (stop/start) service by name\n"
|
||||||
|
" ident [NAME] Show matching identities for NAME, or all\n"
|
||||||
" status <NAME>[:ID] Show service status, by name\n"
|
" status <NAME>[:ID] Show service status, by name\n"
|
||||||
" status Show status of services, default command\n"
|
" status Show status of services, default command\n");
|
||||||
"\n"
|
if (cgrp)
|
||||||
" cgroup List cgroup config overview\n"
|
fprintf(stderr,
|
||||||
" ps List processes based on cgroups\n"
|
"\n"
|
||||||
" top Show top-like listing based on cgroups\n"
|
" cgroup List cgroup config overview\n"
|
||||||
|
" ps List processes based on cgroups\n"
|
||||||
|
" top Show top-like listing based on cgroups\n");
|
||||||
|
fprintf(stderr,
|
||||||
"\n"
|
"\n"
|
||||||
" runlevel [0-9] Show or set runlevel: 0 halt, 6 reboot\n"
|
" runlevel [0-9] Show or set runlevel: 0 halt, 6 reboot\n"
|
||||||
" reboot Reboot system\n"
|
" reboot Reboot system\n"
|
||||||
@@ -893,13 +955,11 @@ static int usage(int rc)
|
|||||||
" poweroff Halt and power off system\n"
|
" poweroff Halt and power off system\n"
|
||||||
" suspend Suspend system\n");
|
" suspend Suspend system\n");
|
||||||
|
|
||||||
if (has_utmp())
|
if (utmp)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\n"
|
"\n"
|
||||||
" utmp show Raw dump of UTMP/WTMP db\n"
|
" utmp show Raw dump of UTMP/WTMP db\n");
|
||||||
"\n");
|
fprintf(stderr, "\n");
|
||||||
else
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -918,11 +978,22 @@ static int do_help(char *arg)
|
|||||||
return usage(0);
|
return usage(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cmd_cond(struct cmd *cmd)
|
||||||
|
{
|
||||||
|
if (!cmd || !cmd->cond)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return *cmd->cond;
|
||||||
|
}
|
||||||
|
|
||||||
static int cmd_parse(int argc, char *argv[], struct cmd *command)
|
static int cmd_parse(int argc, char *argv[], struct cmd *command)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
for (i = 0; argc > 0 && command[i].cmd; i++) {
|
for (i = 0; argc > 0 && command[i].cmd; i++) {
|
||||||
|
if (!cmd_cond(&command[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!string_match(command[i].cmd, argv[0]))
|
if (!string_match(command[i].cmd, argv[0]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -947,7 +1018,6 @@ static int cmd_parse(int argc, char *argv[], struct cmd *command)
|
|||||||
|
|
||||||
return command[0].cb(NULL); /* default cmd */
|
return command[0].cb(NULL); /* default cmd */
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct option long_options[] = {
|
struct option long_options[] = {
|
||||||
@@ -964,57 +1034,62 @@ int main(int argc, char *argv[])
|
|||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
};
|
};
|
||||||
struct cmd cond[] = {
|
struct cmd cond[] = {
|
||||||
{ "status", NULL, do_cond_show }, /* default cmd */
|
{ "status", NULL, do_cond_show, NULL }, /* default cmd */
|
||||||
{ "dump", NULL, do_cond_dump },
|
{ "dump", NULL, do_cond_dump, NULL },
|
||||||
{ "set", NULL, do_cond_set },
|
{ "set", NULL, do_cond_set, NULL },
|
||||||
{ "clr", NULL, do_cond_clr },
|
{ "clr", NULL, do_cond_clr, NULL },
|
||||||
{ "clear", NULL, do_cond_clr },
|
{ "clear", NULL, do_cond_clr, NULL },
|
||||||
{ NULL, NULL, NULL }
|
{ NULL, NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
struct cmd command[] = {
|
struct cmd command[] = {
|
||||||
{ "status", NULL, show_status }, /* default cmd */
|
{ "status", NULL, show_status, NULL }, /* default cmd */
|
||||||
|
{ "ident", NULL, show_ident, NULL },
|
||||||
|
|
||||||
{ "debug", NULL, toggle_debug },
|
{ "debug", NULL, toggle_debug, NULL },
|
||||||
{ "devel", NULL, do_devel },
|
{ "devel", NULL, do_devel, NULL },
|
||||||
{ "help", NULL, do_help },
|
{ "help", NULL, do_help, NULL },
|
||||||
{ "version", NULL, show_version },
|
{ "version", NULL, show_version, NULL },
|
||||||
|
|
||||||
{ "list", NULL, serv_list },
|
{ "list", NULL, serv_list, NULL },
|
||||||
{ "ls", NULL, serv_list },
|
{ "ls", NULL, serv_list, NULL },
|
||||||
{ "enable", NULL, serv_enable },
|
{ "enable", NULL, serv_enable, NULL },
|
||||||
{ "disable", NULL, serv_disable },
|
{ "disable", NULL, serv_disable, NULL },
|
||||||
{ "touch", NULL, serv_touch },
|
{ "touch", NULL, serv_touch, NULL },
|
||||||
{ "show", NULL, serv_show },
|
{ "show", NULL, serv_show, NULL },
|
||||||
{ "edit", NULL, serv_edit },
|
{ "edit", NULL, serv_edit, NULL },
|
||||||
{ "create", NULL, serv_creat },
|
{ "create", NULL, serv_creat, NULL },
|
||||||
{ "delete", NULL, serv_delete },
|
{ "delete", NULL, serv_delete, NULL },
|
||||||
{ "reload", NULL, do_reload },
|
{ "reload", NULL, do_reload, NULL },
|
||||||
|
|
||||||
{ "cond", cond, NULL },
|
{ "cond", cond, NULL, NULL },
|
||||||
|
|
||||||
{ "log", NULL, do_log },
|
{ "log", NULL, do_log, NULL },
|
||||||
{ "start", NULL, do_start },
|
{ "start", NULL, do_start, NULL },
|
||||||
{ "stop", NULL, do_stop },
|
{ "stop", NULL, do_stop, NULL },
|
||||||
{ "restart", NULL, do_restart },
|
{ "restart", NULL, do_restart, NULL },
|
||||||
|
|
||||||
{ "cgroup", NULL, show_cgroup },
|
{ "cgroup", NULL, show_cgroup, &cgrp },
|
||||||
{ "ps", NULL, show_cgps },
|
{ "ps", NULL, show_cgps, &cgrp },
|
||||||
{ "top", NULL, show_cgtop },
|
{ "top", NULL, show_cgtop, &cgrp },
|
||||||
|
|
||||||
{ "runlevel", NULL, do_runlevel },
|
{ "runlevel", NULL, do_runlevel, NULL },
|
||||||
{ "reboot", NULL, do_reboot },
|
{ "reboot", NULL, do_reboot, NULL },
|
||||||
{ "halt", NULL, do_halt },
|
{ "halt", NULL, do_halt, NULL },
|
||||||
{ "poweroff", NULL, do_poweroff },
|
{ "poweroff", NULL, do_poweroff, NULL },
|
||||||
{ "suspend", NULL, do_suspend },
|
{ "suspend", NULL, do_suspend, NULL },
|
||||||
|
|
||||||
{ "utmp", NULL, do_utmp },
|
{ "utmp", NULL, do_utmp, &utmp },
|
||||||
{ NULL, NULL, NULL }
|
{ NULL, NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
int interactive = 1, c;
|
int interactive = 1, c;
|
||||||
|
|
||||||
if (transform(progname(argv[0])))
|
if (transform(progname(argv[0])))
|
||||||
return reboot_main(argc, argv);
|
return reboot_main(argc, argv);
|
||||||
|
|
||||||
|
/* Enable functionality depending on system capabilities */
|
||||||
|
cgrp = cgroup_avail();
|
||||||
|
utmp = has_utmp();
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv, "1bcdfh?pqtv", long_options, NULL)) != EOF) {
|
while ((c = getopt_long(argc, argv, "1bcdfh?pqtv", long_options, NULL)) != EOF) {
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case '1':
|
case '1':
|
||||||
@@ -1062,17 +1137,6 @@ int main(int argc, char *argv[])
|
|||||||
if (interactive)
|
if (interactive)
|
||||||
ttinit();
|
ttinit();
|
||||||
|
|
||||||
if (!has_utmp()) {
|
|
||||||
/* system w/o utmp support, disable 'utmp' command */
|
|
||||||
for (c = 0; command[c].cmd; c++) {
|
|
||||||
if (!string_compare(command[c].cmd, "utmp"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
command[c].cb = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cmd_parse(argc - optind, &argv[optind], command);
|
return cmd_parse(argc - optind, &argv[optind], command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -26,7 +26,11 @@
|
|||||||
#define FINIT_IWATCH_H_
|
#define FINIT_IWATCH_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <lite/queue.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/queue.h> /* BSD sys/queue.h API */
|
||||||
|
#else
|
||||||
|
# include <lite/queue.h> /* BSD sys/queue.h API */
|
||||||
|
#endif
|
||||||
#include <sys/inotify.h>
|
#include <sys/inotify.h>
|
||||||
|
|
||||||
#ifndef IN_MASK_CREATE
|
#ifndef IN_MASK_CREATE
|
||||||
|
|||||||
+5
-1
@@ -37,7 +37,11 @@
|
|||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
|
|
||||||
#include "lite/lite.h"
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "cond.h"
|
#include "cond.h"
|
||||||
#include "pid.h"
|
#include "pid.h"
|
||||||
|
|||||||
@@ -24,7 +24,11 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
@@ -32,14 +36,14 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
static int up = 0;
|
static int up = 0;
|
||||||
static int loglevel = LOG_NOTICE;
|
static int loglevel = LOG_INFO;
|
||||||
|
|
||||||
void log_init(int dbg)
|
void log_init(void)
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
loglevel = LOG_DEBUG;
|
loglevel = LOG_DEBUG;
|
||||||
else
|
else
|
||||||
loglevel = LOG_NOTICE;
|
loglevel = LOG_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we enabled terse mode at boot, restore to previous setting at shutdown */
|
/* If we enabled terse mode at boot, restore to previous setting at shutdown */
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
#define _e(fmt, args...) logit(LOG_ERR, "%s():" fmt "\n", __func__, ##args)
|
#define _e(fmt, args...) logit(LOG_ERR, "%s():" fmt "\n", __func__, ##args)
|
||||||
#define _pe(fmt, args...) logit(LOG_ERR, "%s():" fmt ": %s\n", __func__, ##args, strerror(errno))
|
#define _pe(fmt, args...) logit(LOG_ERR, "%s():" fmt ": %s\n", __func__, ##args, strerror(errno))
|
||||||
|
|
||||||
void log_init (int dbg);
|
void log_init (void);
|
||||||
void log_exit (void);
|
void log_exit (void);
|
||||||
|
|
||||||
void log_debug (void);
|
void log_debug (void);
|
||||||
|
|||||||
+5
-1
@@ -30,7 +30,11 @@
|
|||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char version_info[] = PACKAGE_NAME " v" PACKAGE_VERSION;
|
static const char version_info[] = PACKAGE_NAME " v" PACKAGE_VERSION;
|
||||||
extern int logrotate(char *file, int num, off_t sz);
|
extern int logrotate(char *file, int num, off_t sz);
|
||||||
|
|||||||
+5
-1
@@ -20,12 +20,16 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <lite/lite.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
static int recreate(char *path, mode_t mode, uid_t uid, gid_t gid)
|
static int recreate(char *path, mode_t mode, uid_t uid, gid_t gid)
|
||||||
{
|
{
|
||||||
|
|||||||
+24
-18
@@ -28,7 +28,7 @@
|
|||||||
/*
|
/*
|
||||||
* SysV init on Debian/Ubuntu skips these protected mount points
|
* SysV init on Debian/Ubuntu skips these protected mount points
|
||||||
*
|
*
|
||||||
* It also skips anything below /proc, /sys and /run for good meausre so
|
* It also skips anything below /proc, /sys and /run for good measure so
|
||||||
* we do the same here. What we want is a list of non-protected tmpfs
|
* we do the same here. What we want is a list of non-protected tmpfs
|
||||||
* and regular filesystems that can be safely unmounted before we do
|
* and regular filesystems that can be safely unmounted before we do
|
||||||
* swapoff, and remount / as read-only, respectively.
|
* swapoff, and remount / as read-only, respectively.
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
static int is_protected(char *dir)
|
static int is_protected(char *dir)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
char *protected[] = {
|
char *protected_mnts[] = {
|
||||||
"/sys", "/proc",
|
"/sys", "/proc",
|
||||||
"/.dev", "/dev", "/dev/pts", "/dev/shm", "dev/.static/dev", "/dev/vcs",
|
"/.dev", "/dev", "/dev/pts", "/dev/shm", "dev/.static/dev", "/dev/vcs",
|
||||||
"/run", "/var/run",
|
"/run", "/var/run",
|
||||||
@@ -46,8 +46,8 @@ static int is_protected(char *dir)
|
|||||||
"/proc/", "/sys/", "/run/", NULL
|
"/proc/", "/sys/", "/run/", NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
for (i = 0; protected[i]; i++) {
|
for (i = 0; protected_mnts[i]; i++) {
|
||||||
if (!strcmp(dir, protected[i]))
|
if (!strcmp(dir, protected_mnts[i]))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,46 +59,52 @@ static int is_protected(char *dir)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mntent *iterator(char *fstab)
|
static void iterator_end(FILE **fp)
|
||||||
|
{
|
||||||
|
endmntent(*fp);
|
||||||
|
*fp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct mntent *iterator(char *fstab, FILE **fp)
|
||||||
{
|
{
|
||||||
static FILE *fp = NULL;
|
|
||||||
static struct mntent *mnt;
|
static struct mntent *mnt;
|
||||||
|
|
||||||
if (!fp && fstab) {
|
if (!*fp && fstab) {
|
||||||
fp = setmntent(fstab, "r");
|
*fp = setmntent(fstab, "r");
|
||||||
if (!fp)
|
if (!*fp)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((mnt = getmntent(fp))) {
|
while ((mnt = getmntent(*fp))) {
|
||||||
if (is_protected(mnt->mnt_dir))
|
if (is_protected(mnt->mnt_dir))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return mnt;
|
return mnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
endmntent(fp);
|
iterator_end(fp);
|
||||||
fp = NULL;
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unmount_tmpfs(void)
|
void unmount_tmpfs(void)
|
||||||
{
|
{
|
||||||
struct mntent *mnt;
|
struct mntent *mnt;
|
||||||
|
FILE *fp = NULL;
|
||||||
|
|
||||||
while ((mnt = iterator("/proc/mounts"))) {
|
while ((mnt = iterator("/proc/mounts", &fp))) {
|
||||||
if (!strcmp("tmpfs", mnt->mnt_fsname))
|
if (!strcmp("tmpfs", mnt->mnt_fsname) && !umount(mnt->mnt_dir))
|
||||||
umount(mnt->mnt_dir);
|
iterator_end(&fp); /* Restart iteration */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void unmount_regular(void)
|
void unmount_regular(void)
|
||||||
{
|
{
|
||||||
struct mntent *mnt;
|
struct mntent *mnt;
|
||||||
|
FILE *fp = NULL;
|
||||||
|
|
||||||
while ((mnt = iterator("/proc/mounts"))) {
|
while ((mnt = iterator("/proc/mounts", &fp))) {
|
||||||
umount(mnt->mnt_dir);
|
if (!umount(mnt->mnt_dir))
|
||||||
|
iterator_end(&fp); /* Restart iteration */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,11 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "pid.h"
|
#include "pid.h"
|
||||||
#include "svc.h"
|
#include "svc.h"
|
||||||
@@ -166,7 +170,7 @@ int pid_file_set(svc_t *svc, char *file, int not)
|
|||||||
* The logic is explained below. Please note that using the first form
|
* The logic is explained below. Please note that using the first form
|
||||||
* of the syntax not only creates and removes the PID file, but it also
|
* of the syntax not only creates and removes the PID file, but it also
|
||||||
* calls touch to update the mtime on service_restart(), only applicable
|
* calls touch to update the mtime on service_restart(), only applicable
|
||||||
* to processes that accept SIGHUP. This to ensure dependant services
|
* to processes that accept SIGHUP. This to ensure dependent services
|
||||||
* are sent SIGCONT properly on reload, otherwise their condition would
|
* are sent SIGCONT properly on reload, otherwise their condition would
|
||||||
* never be asserted again after `initctl reload`.
|
* never be asserted again after `initctl reload`.
|
||||||
*
|
*
|
||||||
|
|||||||
+8
-3
@@ -26,8 +26,13 @@
|
|||||||
#include <dirent.h> /* readdir() et al */
|
#include <dirent.h> /* readdir() et al */
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
#include <lite/queue.h> /* BSD sys/queue.h API */
|
# include <libite/lite.h>
|
||||||
|
# include <libite/queue.h> /* BSD sys/queue.h API */
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
# include <lite/queue.h> /* BSD sys/queue.h API */
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "cond.h"
|
#include "cond.h"
|
||||||
@@ -274,7 +279,7 @@ static int init_plugins(uev_ctx_t *ctx)
|
|||||||
* Loads a plugin from @path/@name[.so]. Note, if ".so" is missing from
|
* Loads a plugin from @path/@name[.so]. Note, if ".so" is missing from
|
||||||
* the plugin @name it is added before attempting to load.
|
* the plugin @name it is added before attempting to load.
|
||||||
*
|
*
|
||||||
* It is up to the plugin itself ot register itself as a "ctor" with the
|
* It is up to the plugin itself or register itself as a "ctor" with the
|
||||||
* %PLUGIN_INIT macro so that plugin_register() is called automatically.
|
* %PLUGIN_INIT macro so that plugin_register() is called automatically.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
|
|||||||
+5
-1
@@ -25,7 +25,11 @@
|
|||||||
#define FINIT_PLUGIN_H_
|
#define FINIT_PLUGIN_H_
|
||||||
|
|
||||||
#include <uev/uev.h>
|
#include <uev/uev.h>
|
||||||
#include <lite/queue.h> /* BSD sys/queue.h API */
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/queue.h> /* BSD sys/queue.h API */
|
||||||
|
#else
|
||||||
|
# include <lite/queue.h> /* BSD sys/queue.h API */
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "svc.h"
|
#include "svc.h"
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,9 @@
|
|||||||
#include "svc.h"
|
#include "svc.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
|
||||||
|
#define SERVICE_INTERVAL_DEFAULT 300000 /* 5 mins */
|
||||||
|
extern int service_interval;
|
||||||
|
|
||||||
int api_init (uev_ctx_t *ctx);
|
int api_init (uev_ctx_t *ctx);
|
||||||
int api_exit (void);
|
int api_exit (void);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@
|
|||||||
# runlevel. Finit does not restart them when they exit.
|
# runlevel. Finit does not restart them when they exit.
|
||||||
#
|
#
|
||||||
# - run : wait for completion before continuing with next stanza
|
# - run : wait for completion before continuing with next stanza
|
||||||
# - task : like run but started in background, parallell with other stanzas
|
# - task : like run but started in background, parallel with other stanzas
|
||||||
# - service : supervised daemon, run in foreground, restarted if it crashes
|
# - service : supervised daemon, run in foreground, restarted if it crashes
|
||||||
#
|
#
|
||||||
# The env: is an optional path to a file with environment variables to
|
# The env: is an optional path to a file with environment variables to
|
||||||
|
|||||||
+5
-1
@@ -28,7 +28,11 @@
|
|||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "initctl.h"
|
#include "initctl.h"
|
||||||
|
|
||||||
|
|||||||
+111
-13
@@ -26,11 +26,16 @@
|
|||||||
|
|
||||||
#include <ctype.h> /* isblank() */
|
#include <ctype.h> /* isblank() */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/reboot.h>
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
#include <wordexp.h>
|
#include <wordexp.h>
|
||||||
|
|
||||||
#include "cgroup.h"
|
#include "cgroup.h"
|
||||||
@@ -51,6 +56,7 @@
|
|||||||
static struct wq work = {
|
static struct wq work = {
|
||||||
.cb = service_worker,
|
.cb = service_worker,
|
||||||
};
|
};
|
||||||
|
int service_interval = SERVICE_INTERVAL_DEFAULT;
|
||||||
|
|
||||||
static void svc_set_state(svc_t *svc, svc_state_t new);
|
static void svc_set_state(svc_t *svc, svc_state_t new);
|
||||||
|
|
||||||
@@ -491,6 +497,12 @@ static int service_start(svc_t *svc)
|
|||||||
/* Declare we're waiting for svc to create its pidfile */
|
/* Declare we're waiting for svc to create its pidfile */
|
||||||
svc_starting(svc);
|
svc_starting(svc);
|
||||||
|
|
||||||
|
/* Increment total restarts, unless first time or non-service */
|
||||||
|
if (svc_is_daemon(svc) || svc_is_sysv(svc)) {
|
||||||
|
if (svc->restart_cnt || svc->restart_tot)
|
||||||
|
svc->restart_tot++;
|
||||||
|
}
|
||||||
|
|
||||||
/* Block SIGCHLD while forking. */
|
/* Block SIGCHLD while forking. */
|
||||||
sigemptyset(&nmask);
|
sigemptyset(&nmask);
|
||||||
sigaddset(&nmask, SIGCHLD);
|
sigaddset(&nmask, SIGCHLD);
|
||||||
@@ -843,7 +855,7 @@ static int service_restart(svc_t *svc)
|
|||||||
/**
|
/**
|
||||||
* service_reload_dynamic - Called on SIGHUP, 'init q' or 'initctl reload'
|
* service_reload_dynamic - Called on SIGHUP, 'init q' or 'initctl reload'
|
||||||
*
|
*
|
||||||
* This function is called when Finit has recieved SIGHUP to reload
|
* This function is called when Finit has received SIGHUP to reload
|
||||||
* .conf files in /etc/finit.d. It is responsible for starting,
|
* .conf files in /etc/finit.d. It is responsible for starting,
|
||||||
* stopping and reloading (forwarding SIGHUP) to processes affected.
|
* stopping and reloading (forwarding SIGHUP) to processes affected.
|
||||||
*/
|
*/
|
||||||
@@ -1079,7 +1091,7 @@ static void parse_cmdline_args(svc_t *svc, char *cmd)
|
|||||||
* This function is used to register commands to be run on different
|
* This function is used to register commands to be run on different
|
||||||
* system runlevels with optional username. The @type argument details
|
* system runlevels with optional username. The @type argument details
|
||||||
* if it's service to bo monitored/respawned (daemon), a one-shot task
|
* if it's service to bo monitored/respawned (daemon), a one-shot task
|
||||||
* or a command that must run in sequence and not in parallell, like
|
* or a command that must run in sequence and not in parallel, like
|
||||||
* service and task commands do.
|
* service and task commands do.
|
||||||
*
|
*
|
||||||
* The @line can optionally start with a username, denoted by an @
|
* The @line can optionally start with a username, denoted by an @
|
||||||
@@ -1119,7 +1131,7 @@ static void parse_cmdline_args(svc_t *svc, char *cmd)
|
|||||||
*
|
*
|
||||||
* Without the :ID syntax, Finit replaces the first service line with
|
* Without the :ID syntax, Finit replaces the first service line with
|
||||||
* the contents of the second. The :ID can be any string value and
|
* the contents of the second. The :ID can be any string value and
|
||||||
* defaults to "" (emtpy string).
|
* defaults to "" (empty string).
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* POSIX OK(0) on success, or non-zero errno exit status on failure.
|
* POSIX OK(0) on success, or non-zero errno exit status on failure.
|
||||||
@@ -1136,6 +1148,9 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
int respawn = 0;
|
int respawn = 0;
|
||||||
int levels = 0;
|
int levels = 0;
|
||||||
int manual = 0;
|
int manual = 0;
|
||||||
|
int restart_max = SVC_RESPAWN_MAX;
|
||||||
|
int restart_tmo = 0;
|
||||||
|
unsigned oncrash_action = SVC_ONCRASH_IGNORE;
|
||||||
char *line;
|
char *line;
|
||||||
svc_t *svc;
|
svc_t *svc;
|
||||||
|
|
||||||
@@ -1193,6 +1208,18 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
name = cmd;
|
name = cmd;
|
||||||
else if (!strncasecmp(cmd, "manual:yes", 10))
|
else if (!strncasecmp(cmd, "manual:yes", 10))
|
||||||
manual = 1;
|
manual = 1;
|
||||||
|
else if (!strncasecmp(cmd, "restart:", 8))
|
||||||
|
restart_max = atoi(&cmd[8]);
|
||||||
|
else if (!strncasecmp(cmd, "restarttmo:", 11)) /* compat alias */
|
||||||
|
restart_tmo = atoi(&cmd[11]) * 1000;
|
||||||
|
else if (!strncasecmp(cmd, "restart_sec:", 12))
|
||||||
|
restart_tmo = atoi(&cmd[12]) * 1000;
|
||||||
|
else if (!strncasecmp(cmd, "norestart", 9))
|
||||||
|
restart_max = 0;
|
||||||
|
else if (!strncasecmp(cmd, "oncrash:", 8)) {
|
||||||
|
if (!strncasecmp(&cmd[8], "reboot", 6))
|
||||||
|
oncrash_action = SVC_ONCRASH_REBOOT;
|
||||||
|
}
|
||||||
else if (!strncasecmp(cmd, "respawn", 7))
|
else if (!strncasecmp(cmd, "respawn", 7))
|
||||||
respawn = 1;
|
respawn = 1;
|
||||||
else if (!strncasecmp(cmd, "halt:", 5))
|
else if (!strncasecmp(cmd, "halt:", 5))
|
||||||
@@ -1277,16 +1304,19 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
|
|
||||||
if (type == SVC_TYPE_SERVICE && manual)
|
if (type == SVC_TYPE_SERVICE && manual)
|
||||||
svc_stop(svc);
|
svc_stop(svc);
|
||||||
|
|
||||||
|
svc->restart_max = restart_max;
|
||||||
|
svc->restart_tmo = restart_tmo;
|
||||||
|
svc->oncrash_action = oncrash_action;
|
||||||
} else {
|
} else {
|
||||||
/* update type, may have changed from service -> task */
|
/* update type, may have changed from service -> task */
|
||||||
svc->type = type;
|
svc->type = type;
|
||||||
|
|
||||||
/* e.g., if missing cmd or env before */
|
/* e.g., if missing cmd or env before */
|
||||||
svc_unblock(svc);
|
if (!manual)
|
||||||
|
svc_unblock(svc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Always clear svc PID file, for now. See TODO */
|
|
||||||
svc->pidfile[0] = 0;
|
|
||||||
/* Decode any optional pid:/optional/path/to/file.pid */
|
/* Decode any optional pid:/optional/path/to/file.pid */
|
||||||
if (pid && svc_is_daemon(svc) && pid_file_parse(svc, pid))
|
if (pid && svc_is_daemon(svc) && pid_file_parse(svc, pid))
|
||||||
_e("Invalid 'pid' argument to service: %s", pid);
|
_e("Invalid 'pid' argument to service: %s", pid);
|
||||||
@@ -1327,7 +1357,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
/* TTYs cannot be redirected */
|
/* TTYs cannot be redirected */
|
||||||
log = NULL;
|
log = NULL;
|
||||||
|
|
||||||
/* Create name:id tuple for identiy, e.g., tty:S0 */
|
/* Create name:id tuple for identity, e.g., tty:S0 */
|
||||||
ptr = strrchr(svc->dev, '/');
|
ptr = strrchr(svc->dev, '/');
|
||||||
if (ptr)
|
if (ptr)
|
||||||
ptr++;
|
ptr++;
|
||||||
@@ -1586,8 +1616,8 @@ static void service_post_script(svc_t *svc)
|
|||||||
|
|
||||||
static void service_retry(svc_t *svc)
|
static void service_retry(svc_t *svc)
|
||||||
{
|
{
|
||||||
int timeout;
|
|
||||||
char *restart_cnt = (char *)&svc->restart_cnt;
|
char *restart_cnt = (char *)&svc->restart_cnt;
|
||||||
|
int timeout;
|
||||||
|
|
||||||
service_timeout_cancel(svc);
|
service_timeout_cancel(svc);
|
||||||
if (svc->respawn) {
|
if (svc->respawn) {
|
||||||
@@ -1599,15 +1629,22 @@ static void service_retry(svc_t *svc)
|
|||||||
|
|
||||||
if (svc->state != SVC_HALTED_STATE ||
|
if (svc->state != SVC_HALTED_STATE ||
|
||||||
svc->block != SVC_BLOCK_RESTARTING) {
|
svc->block != SVC_BLOCK_RESTARTING) {
|
||||||
*restart_cnt = 0;
|
logit(LOG_CONSOLE | LOG_NOTICE, "Successfully restarted crashing service %s.",
|
||||||
|
svc_ident(svc, NULL, 0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*restart_cnt >= SVC_RESPAWN_MAX) {
|
/* Peak instability index */
|
||||||
|
if (*restart_cnt >= svc->restart_max) {
|
||||||
logit(LOG_CONSOLE | LOG_WARNING, "Service %s keeps crashing, not restarting.",
|
logit(LOG_CONSOLE | LOG_WARNING, "Service %s keeps crashing, not restarting.",
|
||||||
svc_ident(svc, NULL, 0));
|
svc_ident(svc, NULL, 0));
|
||||||
svc_crashing(svc);
|
svc_crashing(svc);
|
||||||
*restart_cnt = 0;
|
*restart_cnt = 0;
|
||||||
|
if (svc->oncrash_action == SVC_ONCRASH_REBOOT) {
|
||||||
|
logit(LOG_ERR, "%s issuing reboot", svc->cmd);
|
||||||
|
sync();
|
||||||
|
kill(1, SIGTERM);
|
||||||
|
}
|
||||||
service_step(svc);
|
service_step(svc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1616,12 +1653,14 @@ static void service_retry(svc_t *svc)
|
|||||||
|
|
||||||
_d("%s crashed, trying to start it again, attempt %d", svc->cmd, *restart_cnt);
|
_d("%s crashed, trying to start it again, attempt %d", svc->cmd, *restart_cnt);
|
||||||
logit(LOG_CONSOLE | LOG_WARNING, "Service %s[%d] died, restarting (%d/%d)",
|
logit(LOG_CONSOLE | LOG_WARNING, "Service %s[%d] died, restarting (%d/%d)",
|
||||||
svc_ident(svc, NULL, 0), svc->oldpid, *restart_cnt, SVC_RESPAWN_MAX);
|
svc_ident(svc, NULL, 0), svc->oldpid, *restart_cnt, svc->restart_max);
|
||||||
svc_unblock(svc);
|
svc_unblock(svc);
|
||||||
service_step(svc);
|
service_step(svc);
|
||||||
|
|
||||||
/* Wait 2s for the first 5 respawns, then back off to 5s */
|
/* Wait 2s for the first 5 respawns, then back off to 5s */
|
||||||
timeout = ((*restart_cnt) <= (SVC_RESPAWN_MAX / 2)) ? 2000 : 5000;
|
timeout = ((*restart_cnt) <= (svc->restart_max / 2)) ? 2000 : 5000;
|
||||||
|
/* If a longer timeout was specified in the conf, use that instead. */
|
||||||
|
timeout = max(svc->restart_tmo, timeout);
|
||||||
service_timeout_after(svc, timeout, service_retry);
|
service_timeout_after(svc, timeout, service_retry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1932,6 +1971,65 @@ int service_completed(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Every five¹ minutes we sweep over all services, skipping crashed or
|
||||||
|
* otherwise no longer running ones. Decrement non-zero crash counters
|
||||||
|
* to allow services that have started after an initial crash to slowly
|
||||||
|
* prove themselves again as stable services. Previously this counter
|
||||||
|
* was reset as soon as such services had stopped crashing at least once
|
||||||
|
* per second. This new scheme allows us to catch those that rage-quit
|
||||||
|
* immediately when we try to start them, but now also those that are
|
||||||
|
* only slightly buggy -- when they reach their restart_max, they too
|
||||||
|
* are marked 'crashed'.
|
||||||
|
*
|
||||||
|
* This does not affect the restart_tot counter, which you can see in
|
||||||
|
* the output from 'initctl status foo', along with this instability
|
||||||
|
* "index" in parethesis: total (cnt/max)
|
||||||
|
*/
|
||||||
|
static void service_interval_cb(uev_t *w, void *arg, int events)
|
||||||
|
{
|
||||||
|
svc_t *svc, *iter = NULL;
|
||||||
|
|
||||||
|
(void)arg;
|
||||||
|
if (UEV_ERROR == events) {
|
||||||
|
uev_timer_start(w);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
||||||
|
if (svc_is_daemon(svc) || svc_is_sysv(svc)) {
|
||||||
|
char *restart_cnt = (char *)&svc->restart_cnt;
|
||||||
|
|
||||||
|
if (!svc_is_running(svc))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (*restart_cnt > 0) {
|
||||||
|
logit(LOG_CONSOLE | LOG_DEBUG, "Aging %s instability index (%d/%d)",
|
||||||
|
svc_ident(svc, NULL, 0), svc->restart_cnt, svc->restart_max);
|
||||||
|
(*restart_cnt)--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
service_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The service_interval may change (conf) between invocations, so we
|
||||||
|
* periodically reset the one-shot timer instead of using a periodic.
|
||||||
|
*/
|
||||||
|
void service_init(void)
|
||||||
|
{
|
||||||
|
static int initialized = 0;
|
||||||
|
static uev_t watcher;
|
||||||
|
|
||||||
|
if (!initialized) {
|
||||||
|
uev_timer_init(ctx, &watcher, service_interval_cb, NULL, service_interval, 0);
|
||||||
|
initialized = 1;
|
||||||
|
} else
|
||||||
|
uev_timer_set(&watcher, service_interval, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* indent-tabs-mode: t
|
* indent-tabs-mode: t
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ void service_worker (void *unused);
|
|||||||
|
|
||||||
int service_completed (void);
|
int service_completed (void);
|
||||||
|
|
||||||
|
void service_init (void);
|
||||||
|
|
||||||
#endif /* FINIT_SERVICE_H_ */
|
#endif /* FINIT_SERVICE_H_ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -73,7 +73,11 @@
|
|||||||
#include <string.h> /* strerror() */
|
#include <string.h> /* strerror() */
|
||||||
#include <sys/reboot.h>
|
#include <sys/reboot.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "cond.h"
|
#include "cond.h"
|
||||||
@@ -445,7 +449,7 @@ const char *sig_name(int signo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inital signal setup - ignore everything but SIGCHLD until we're capable of responding
|
* Initial signal setup - ignore everything but SIGCHLD until we're capable of responding
|
||||||
*/
|
*/
|
||||||
static void chld_handler(int sig, siginfo_t *info, void *ctx)
|
static void chld_handler(int sig, siginfo_t *info, void *ctx)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "config.h" /* Generated by configure script */
|
#include "config.h" /* Generated by configure script */
|
||||||
|
|
||||||
|
#include <paths.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
@@ -38,6 +39,10 @@
|
|||||||
|
|
||||||
sm_t sm;
|
sm_t sm;
|
||||||
|
|
||||||
|
#ifndef FINIT_NOLOGIN_PATH
|
||||||
|
#define FINIT_NOLOGIN_PATH _PATH_NOLOGIN /* Stop user logging in. */
|
||||||
|
#endif
|
||||||
|
|
||||||
void sm_init(sm_t *sm)
|
void sm_init(sm_t *sm)
|
||||||
{
|
{
|
||||||
sm->state = SM_BOOTSTRAP_STATE;
|
sm->state = SM_BOOTSTRAP_STATE;
|
||||||
@@ -76,16 +81,16 @@ static char *sm_status(sm_state_t state)
|
|||||||
* Disable login in single user mode and shutdown/reboot
|
* Disable login in single user mode and shutdown/reboot
|
||||||
*
|
*
|
||||||
* Re-enable only when going from these runlevels, this way a user can
|
* Re-enable only when going from these runlevels, this way a user can
|
||||||
* manage /etc/nologin manually within the other runlevels without us
|
* manage FINIT_NOLOGIN_PATH manually within the other runlevels without
|
||||||
* pulling the rug from under their feet.
|
* us pulling the rug from under their feet.
|
||||||
*/
|
*/
|
||||||
static void nologin(void)
|
static void nologin(void)
|
||||||
{
|
{
|
||||||
if (runlevel == 1 || runlevel == 0 || runlevel == 6)
|
if (runlevel == 1 || runlevel == 0 || runlevel == 6)
|
||||||
touch("/etc/nologin");
|
touch(FINIT_NOLOGIN_PATH);
|
||||||
|
|
||||||
if (prevlevel == 1 || prevlevel == 0 || prevlevel == 6)
|
if (prevlevel == 1 || prevlevel == 0 || prevlevel == 6)
|
||||||
erase("/etc/nologin");
|
erase(FINIT_NOLOGIN_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sm_set_runlevel(sm_t *sm, int newlevel)
|
void sm_set_runlevel(sm_t *sm, int newlevel)
|
||||||
@@ -187,7 +192,7 @@ restart:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Prev runlevel services stopped, call hooks before starting new runlevel ... */
|
/* Prev runlevel services stopped, call hooks before starting new runlevel ... */
|
||||||
_d("All services have been stoppped, calling runlevel change hooks ...");
|
_d("All services have been stopped, calling runlevel change hooks ...");
|
||||||
plugin_run_hooks(HOOK_RUNLEVEL_CHANGE); /* Reconfigure HW/VLANs/etc here */
|
plugin_run_hooks(HOOK_RUNLEVEL_CHANGE); /* Reconfigure HW/VLANs/etc here */
|
||||||
|
|
||||||
_d("Starting services new to this runlevel ...");
|
_d("Starting services new to this runlevel ...");
|
||||||
|
|||||||
@@ -27,9 +27,9 @@
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
SM_BOOTSTRAP_STATE = 0, /* Init state, bootstrap services */
|
SM_BOOTSTRAP_STATE = 0, /* Init state, bootstrap services */
|
||||||
SM_RUNNING_STATE, /* Normal state, services running */
|
SM_RUNNING_STATE, /* Normal state, services running */
|
||||||
SM_RUNLEVEL_CHANGE_STATE, /* A runlevel change has occured */
|
SM_RUNLEVEL_CHANGE_STATE, /* A runlevel change has occurred */
|
||||||
SM_RUNLEVEL_WAIT_STATE, /* Waiting for all stopped runlevel processes to be halted */
|
SM_RUNLEVEL_WAIT_STATE, /* Waiting for all stopped runlevel processes to be halted */
|
||||||
SM_RELOAD_CHANGE_STATE, /* A reload event has occured */
|
SM_RELOAD_CHANGE_STATE, /* A reload event has occurred */
|
||||||
SM_RELOAD_WAIT_STATE, /* Waiting for all stopped reload processes to be halted */
|
SM_RELOAD_WAIT_STATE, /* Waiting for all stopped reload processes to be halted */
|
||||||
} sm_state_t;
|
} sm_state_t;
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,11 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <lite/queue.h> /* BSD sys/queue.h API */
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/queue.h> /* BSD sys/queue.h API */
|
||||||
|
#else
|
||||||
|
# include <lite/queue.h> /* BSD sys/queue.h API */
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "svc.h"
|
#include "svc.h"
|
||||||
@@ -613,27 +617,6 @@ int svc_enabled(svc_t *svc)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int svc_is_unique(svc_t *svc)
|
|
||||||
{
|
|
||||||
svc_t *s, *iter = NULL;
|
|
||||||
int unique = 1;
|
|
||||||
|
|
||||||
for (s = svc_iterator(&iter, 1); s; s = svc_iterator(&iter, 0)) {
|
|
||||||
if (svc->type == SVC_TYPE_FREE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (s == svc)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (s->job == svc->job) {
|
|
||||||
unique = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return unique;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* break up "job:id job:id job:id ..." into several "job:id" tokens */
|
/* break up "job:id job:id job:id ..." into several "job:id" tokens */
|
||||||
static char *tokstr(char *str, size_t len)
|
static char *tokstr(char *str, size_t len)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,8 +28,13 @@
|
|||||||
#include <sys/ipc.h> /* IPC_CREAT */
|
#include <sys/ipc.h> /* IPC_CREAT */
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <sys/types.h> /* pid_t */
|
#include <sys/types.h> /* pid_t */
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
#include <lite/queue.h> /* BSD sys/queue.h API */
|
# include <libite/lite.h>
|
||||||
|
# include <libite/queue.h> /* BSD sys/queue.h API */
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
# include <lite/queue.h> /* BSD sys/queue.h API */
|
||||||
|
#endif
|
||||||
#include <uev/uev.h>
|
#include <uev/uev.h>
|
||||||
|
|
||||||
#include "cgroup.h"
|
#include "cgroup.h"
|
||||||
@@ -40,7 +45,7 @@ typedef int svc_cmd_t;
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
SVC_TYPE_FREE = 0, /* Free to allocate */
|
SVC_TYPE_FREE = 0, /* Free to allocate */
|
||||||
SVC_TYPE_SERVICE = 1, /* Monitored, will be respawned */
|
SVC_TYPE_SERVICE = 1, /* Monitored, will be respawned */
|
||||||
SVC_TYPE_TASK = 2, /* One-shot, runs in parallell */
|
SVC_TYPE_TASK = 2, /* One-shot, runs in parallel */
|
||||||
SVC_TYPE_RUN = 4, /* Like task, but wait for completion */
|
SVC_TYPE_RUN = 4, /* Like task, but wait for completion */
|
||||||
SVC_TYPE_TTY = 8, /* Like service, but dedicated to TTYs */
|
SVC_TYPE_TTY = 8, /* Like service, but dedicated to TTYs */
|
||||||
SVC_TYPE_SYSV = 32, /* SysV style init.d script w/ start/stop */
|
SVC_TYPE_SYSV = 32, /* SysV style init.d script w/ start/stop */
|
||||||
@@ -70,6 +75,11 @@ typedef enum {
|
|||||||
SVC_BLOCK_RESTARTING,
|
SVC_BLOCK_RESTARTING,
|
||||||
} svc_block_t;
|
} svc_block_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SVC_ONCRASH_IGNORE = 0,
|
||||||
|
SVC_ONCRASH_REBOOT = 1,
|
||||||
|
} svc_oncrash_action_t;
|
||||||
|
|
||||||
#define MAX_ID_LEN 16
|
#define MAX_ID_LEN 16
|
||||||
#define MAX_ARG_LEN 64
|
#define MAX_ARG_LEN 64
|
||||||
#define MAX_IDENT_LEN (MAX_ARG_LEN + MAX_ID_LEN + 1)
|
#define MAX_IDENT_LEN (MAX_ARG_LEN + MAX_ID_LEN + 1)
|
||||||
@@ -102,7 +112,7 @@ typedef struct svc {
|
|||||||
struct cgroup cgroup;
|
struct cgroup cgroup;
|
||||||
|
|
||||||
/* Service details */
|
/* Service details */
|
||||||
int sighalt; /* Signal to stop prorcess, default: SIGTERM */
|
int sighalt; /* Signal to stop process, default: SIGTERM */
|
||||||
int killdelay; /* Delay in msec before sending SIGKILL */
|
int killdelay; /* Delay in msec before sending SIGKILL */
|
||||||
pid_t oldpid, pid;
|
pid_t oldpid, pid;
|
||||||
char pidfile[256];
|
char pidfile[256];
|
||||||
@@ -127,6 +137,10 @@ typedef struct svc {
|
|||||||
|
|
||||||
/* Counters */
|
/* Counters */
|
||||||
char once; /* run/task, (at least) once per runlevel */
|
char once; /* run/task, (at least) once per runlevel */
|
||||||
|
unsigned int restart_tot; /* Total restarts ever, summarized, including `initctl restart` */
|
||||||
|
unsigned char restart_max; /* Maximum number of restarts allowed */
|
||||||
|
int restart_tmo; /* Time required for the service to start. */
|
||||||
|
unsigned char oncrash_action; /* Action to perform in crashed state. */
|
||||||
char respawn; /* ttys, or services with `respawn`, never increment restart_cnt */
|
char respawn; /* ttys, or services with `respawn`, never increment restart_cnt */
|
||||||
const char restart_cnt; /* Incremented for each restart by service monitor. */
|
const char restart_cnt; /* Incremented for each restart by service monitor. */
|
||||||
|
|
||||||
@@ -207,7 +221,6 @@ void svc_prune_bootstrap (void);
|
|||||||
|
|
||||||
void svc_enable (svc_t *svc);
|
void svc_enable (svc_t *svc);
|
||||||
int svc_enabled (svc_t *svc);
|
int svc_enabled (svc_t *svc);
|
||||||
int svc_is_unique (svc_t *svc);
|
|
||||||
|
|
||||||
int svc_parse_jobstr (char *str, size_t len, int (*found)(svc_t *), int (not_found)(char *, char *));
|
int svc_parse_jobstr (char *str, size_t len, int (*found)(svc_t *), int (not_found)(char *, char *));
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,11 @@
|
|||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "config.h" /* Generated by configure script */
|
#include "config.h" /* Generated by configure script */
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
|
|||||||
+58
-3
@@ -24,6 +24,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <ctype.h> /* isprint() */
|
#include <ctype.h> /* isprint() */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <mntent.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -37,7 +38,11 @@
|
|||||||
# include <sys/ioctl.h>
|
# include <sys/ioctl.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sys/sysinfo.h> /* sysinfo() */
|
#include <sys/sysinfo.h> /* sysinfo() */
|
||||||
#include <lite/lite.h> /* strlcat() */
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#ifdef HAVE_TERMIOS_H
|
#ifdef HAVE_TERMIOS_H
|
||||||
@@ -177,7 +182,8 @@ int fnread(char *buf, size_t len, char *fmt, ...)
|
|||||||
if (!fp)
|
if (!fp)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
len = fread(buf, sizeof(char), len, fp);
|
len = fread(buf, sizeof(char), len - 1, fp);
|
||||||
|
buf[len] = 0;
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
return (int)len;
|
return (int)len;
|
||||||
@@ -216,7 +222,7 @@ int fnwrite(char *value, char *fmt, ...)
|
|||||||
|
|
||||||
int fngetint(char *path, int *val)
|
int fngetint(char *path, int *val)
|
||||||
{
|
{
|
||||||
char buf[10];
|
char buf[64];
|
||||||
|
|
||||||
if (fnread(buf, sizeof(buf), path) <= 0)
|
if (fnread(buf, sizeof(buf), path) <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -393,6 +399,55 @@ char *sanitize(char *arg, size_t len)
|
|||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hasopt(char *opts, char *opt)
|
||||||
|
{
|
||||||
|
char buf[strlen(opts) + 1];
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
memcpy(buf, opts, sizeof(buf));
|
||||||
|
ptr = strtok(buf, ",");
|
||||||
|
while (ptr) {
|
||||||
|
if (!strcmp(ptr, opt))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ptr = strtok(NULL, ",");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ismnt(char *file, char *dir, char *mode)
|
||||||
|
{
|
||||||
|
struct mntent *mnt;
|
||||||
|
int found = 0;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
fp = setmntent(file, "r");
|
||||||
|
if (!fp)
|
||||||
|
return 0; /* Dunno, maybe not */
|
||||||
|
|
||||||
|
while ((mnt = getmntent(fp))) {
|
||||||
|
if (!strcmp(mnt->mnt_dir, dir)) {
|
||||||
|
if (mode) {
|
||||||
|
if (hasopt(mnt->mnt_opts, mode))
|
||||||
|
found = 1;
|
||||||
|
} else
|
||||||
|
found = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endmntent(fp);
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Requires /proc to be mounted */
|
||||||
|
int fismnt(char *dir)
|
||||||
|
{
|
||||||
|
return ismnt("/proc/mounts", dir, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_TERMIOS_H
|
#ifdef HAVE_TERMIOS_H
|
||||||
/*
|
/*
|
||||||
* Called by initctl, and by finit at boot and shutdown, to
|
* Called by initctl, and by finit at boot and shutdown, to
|
||||||
|
|||||||
+10
-2
@@ -32,7 +32,6 @@
|
|||||||
#include <sys/reboot.h>
|
#include <sys/reboot.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#endif
|
#endif
|
||||||
#include <lite/lite.h>
|
|
||||||
|
|
||||||
#ifndef RB_SW_SUSPEND /* Since Linux 2.5.18, but not in GLIBC until 2.19 */
|
#ifndef RB_SW_SUSPEND /* Since Linux 2.5.18, but not in GLIBC until 2.19 */
|
||||||
#define RB_SW_SUSPEND 0xd000fce2
|
#define RB_SW_SUSPEND 0xd000fce2
|
||||||
@@ -45,7 +44,13 @@ extern char *prognm;
|
|||||||
|
|
||||||
/* Define for printheader() from conio.h, used in initctl */
|
/* Define for printheader() from conio.h, used in initctl */
|
||||||
#define SCREEN_WIDTH ttcols
|
#define SCREEN_WIDTH ttcols
|
||||||
#include <lite/conio.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/conio.h>
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/conio.h>
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
char *progname (char *arg0);
|
char *progname (char *arg0);
|
||||||
|
|
||||||
@@ -65,6 +70,9 @@ char *memsz (uint64_t sz, char *buf, size_t len);
|
|||||||
|
|
||||||
char *sanitize (char *arg, size_t len);
|
char *sanitize (char *arg, size_t len);
|
||||||
|
|
||||||
|
int ismnt (char *file, char *dir, char *mode);
|
||||||
|
int fismnt (char *dir);
|
||||||
|
|
||||||
#ifdef HAVE_TERMIOS_H
|
#ifdef HAVE_TERMIOS_H
|
||||||
int ttinit (void);
|
int ttinit (void);
|
||||||
int ttraw (void);
|
int ttraw (void);
|
||||||
|
|||||||
+5
-1
@@ -26,7 +26,11 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
#include <lite/lite.h>
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Execute a given command from withing the test environment.
|
# Execute a given command from within the test environment.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2021 Jacques de Laval <jacques@de-laval.se>
|
# Copyright (c) 2021 Jacques de Laval <jacques@de-laval.se>
|
||||||
#
|
#
|
||||||
|
|||||||
Reference in New Issue
Block a user