Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1716ef9ef | ||
|
|
fe5567bb04 | ||
|
|
88e9954828 | ||
|
|
a4b9c97282 | ||
|
|
d47288d838 | ||
|
|
1cf0c98514 | ||
|
|
0cded681e8 | ||
|
|
03e61ccd30 | ||
|
|
7067f7670e | ||
|
|
3c198185b2 | ||
|
|
e84366fd23 | ||
|
|
caacedc0a8 | ||
|
|
84d140a1f6 | ||
|
|
ee886c4482 | ||
|
|
1801561c2d | ||
|
|
7689106aa1 | ||
|
|
1564e155b7 | ||
|
|
44bac3c379 | ||
|
|
0ddee9b7d2 | ||
|
|
688566c535 | ||
|
|
7185e242ff | ||
|
|
ec27299f4b | ||
|
|
1ece16bfcd | ||
|
|
0cfd0dd9ef | ||
|
|
a77ee2e941 | ||
|
|
49b8a573a1 | ||
|
|
a2055af900 | ||
|
|
cbf96967f1 | ||
|
|
f1013037b4 |
263
ChangeLog
263
ChangeLog
@@ -1,7 +1,189 @@
|
|||||||
commit 809c205c356992145b8781ae07a5d3c98b79a8c9
|
commit fe5567bb04b3bacfb473d707e3eb936571c06661
|
||||||
Author: Sergei Trofimovich <slyfox@inbox.ru>
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
fix argument parsing for the sysvinit shutdown wrapper
|
||||||
|
|
||||||
|
This fixes #140.
|
||||||
|
|
||||||
|
commit 88e995482855356b79dc670420d31642162aaddb
|
||||||
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
scripts/shutdown: fix arguments to be sysvinit shutdown compatible
|
||||||
|
|
||||||
|
This fixes #140.
|
||||||
|
|
||||||
|
commit a4b9c972828089dccea16aa92371ccda02717fab
|
||||||
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
Fix link to shutdown for MKSYSVINIT=yes
|
||||||
|
|
||||||
|
commit d47288d838a45b89abf944f7ddf969372b54a8e1
|
||||||
|
Author: udeved <artoo@manjaro.org>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
scripts/Makefile: make symlinks absolute instead of relative
|
||||||
|
|
||||||
|
This closes #142.
|
||||||
|
|
||||||
|
commit 1cf0c98514c6b08dd56c363e89007e791dbc0589
|
||||||
|
Author: udeved <artoo@manjaro.org>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
scripts/Makefile: respect SBINDIR with MKSYSVINIT
|
||||||
|
|
||||||
|
This is for #142.
|
||||||
|
|
||||||
|
commit 0cded681e8759f05a22a60095353bf8b2196906f
|
||||||
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
version 0.27.2
|
||||||
|
|
||||||
|
commit 03e61ccd30122cb2be169335cb02c412ea56625f
|
||||||
|
Author: Jory A. Pratt <anarchy@gentoo.org>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
kill_all: include limits.h for PATH_MAX
|
||||||
|
|
||||||
|
commit 7067f7670e96363530ce362974e1f1e31f66ef6e
|
||||||
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
fix compile issue for musl
|
||||||
|
|
||||||
|
commit 3c198185b25d1cb4528461f34a8f8b552f23331c
|
||||||
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
version 0.27.1
|
||||||
|
|
||||||
|
commit e84366fd232a41c3ba79ed351e93c74cef8d7c8d
|
||||||
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
Update ChangeLog
|
||||||
|
|
||||||
|
commit caacedc0a82285fb2d25c6d3473f154044c7ad66
|
||||||
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
man: update openrc-shutdown man page
|
||||||
|
|
||||||
|
Add the new wtmp options and fix some cross references.
|
||||||
|
|
||||||
|
commit 84d140a1f6abf95a4170d13527152d3ab14e6613
|
||||||
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
scripts/shutdown: pass --single to openrc-shutdown
|
||||||
|
|
||||||
|
Sysvinit shutdown has a default of single user mode, but openrc-shutdown
|
||||||
|
makes you choose a default action. Because of this, the shutdown wrapper
|
||||||
|
needs to pass --single to openrc-shutdown.
|
||||||
|
|
||||||
|
commit ee886c44824b1dd892eaff2c6da666286e61bc73
|
||||||
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
openrc-shutdown: add --single option and clean up option processing
|
||||||
|
|
||||||
|
commit 1801561c2d36c330df7fd02c7508f503a61ff5ba
|
||||||
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
init.d/bootmisc: use openrc-shutdown instead of halt to write halt record
|
||||||
|
|
||||||
|
This fixes #139 and fixes #128.
|
||||||
|
and fixes #124.
|
||||||
|
|
||||||
|
commit 7689106aa10f7852b707b4c21ec080ccb2767280
|
||||||
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
add support for writing reboot and shutdown records to wtmp
|
||||||
|
|
||||||
|
commit 1564e155b726308200ecd5df315c002bd8b16952
|
||||||
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
openrc-init: add optional sysvinit compatibility
|
||||||
|
|
||||||
|
commit 44bac3c3798f7eb9186c3ea8774552aa191bfae7
|
||||||
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
Change killprocs to use kill_all instead of killall5
|
||||||
|
|
||||||
|
X-Gentoo-Bug:376977
|
||||||
|
X-Gentoo-Bug-URL:https://bugs.gentoo.org/show_bug.cgi?id=376977
|
||||||
|
|
||||||
|
commit 0ddee9b7d2b8dea810e252ca6a95c457876df120
|
||||||
|
Author: Sergei Trofimovich <slyfox@gentoo.org>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
openrc-init: fix buffer overflow in init.ctl
|
||||||
|
|
||||||
|
How to reproduce 1-byte overflow:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ FEATURES=-test CFLAGS="-fsanitize=address -O0 -ggdb3" emerge -1 openrc
|
||||||
|
|
||||||
|
=================================================================
|
||||||
|
==1==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff0efd8710
|
||||||
|
at pc 0x000000402076 bp 0x7fff0efd7d50 sp 0x7fff0efd7d40
|
||||||
|
WRITE of size 1 at 0x7fff0efd8710 thread T0
|
||||||
|
#0 0x402075 (/sbin/openrc-init+0x402075)
|
||||||
|
#1 0x3cf6e2070f in __libc_start_main (/lib64/libc.so.6+0x3cf6e2070f)
|
||||||
|
#2 0x4013b8 (/sbin/openrc-init+0x4013b8)
|
||||||
|
|
||||||
|
Address 0x7fff0efd8710 is located in stack of thread T0 at offset 2432 in frame
|
||||||
|
#0 0x401cfb (/sbin/openrc-init+0x401cfb)
|
||||||
|
|
||||||
|
This frame has 3 object(s):
|
||||||
|
[32, 160) 'signals'
|
||||||
|
[192, 344) 'sa'
|
||||||
|
[384, 2432) 'buf' <== Memory access at offset 2432 overflows this variable
|
||||||
|
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
|
||||||
|
(longjmp and C++ exceptions *are* supported)
|
||||||
|
SUMMARY: AddressSanitizer: stack-buffer-overflow ??:0 ??
|
||||||
|
```
|
||||||
|
|
||||||
|
The problem here is in the code handling reads from 'init.ctl':
|
||||||
|
|
||||||
|
```
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
...
|
||||||
|
char buf[2048];
|
||||||
|
for (;;) {
|
||||||
|
/* This will block until a command is sent down the pipe... */
|
||||||
|
fifo = fopen(RC_INIT_FIFO, "r");
|
||||||
|
count = fread(buf, 1, 2048, fifo);
|
||||||
|
buf[count] = 0;
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`buf[count] = 0;` writes outside the buffer when `fread()` returns non-truncated read.
|
||||||
|
|
||||||
|
This fixes #138.
|
||||||
|
|
||||||
|
commit 688566c535111a141f77caf88db12a4338544f7b
|
||||||
|
Author: Sergei Trofimovich <slyfox@inbox.ru>
|
||||||
|
Commit: Doug Freed <dwfreed@mtu.edu>
|
||||||
|
|
||||||
|
mk/cc.mk: make implicit function declarations fatal (#136)
|
||||||
|
|
||||||
|
Avoids issues with missing prototypes causing truncation of pointers.
|
||||||
|
|
||||||
|
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
|
||||||
|
|
||||||
|
commit 7185e242ffaa8cd1b672fe4726502a196fd779c2
|
||||||
|
Author: Sergei Trofimovich <slyfox@inbox.ru>
|
||||||
|
Commit: Doug Freed <dwfreed@mtu.edu>
|
||||||
|
|
||||||
rc-logger.c: fix crash on fclose(NULL) (#137)
|
rc-logger.c: fix crash on fclose(NULL) (#137)
|
||||||
|
|
||||||
Only close the log if we successfully opened it.
|
Only close the log if we successfully opened it.
|
||||||
@@ -10,47 +192,64 @@ Commit: William Hubbs <w.d.hubbs@gmail.com>
|
|||||||
Tested-by: Brian Evans <grknight@gentoo.org>
|
Tested-by: Brian Evans <grknight@gentoo.org>
|
||||||
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
|
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
|
||||||
|
|
||||||
commit 238bffca9bbec8ed723b9e46fbc04407e5daddeb
|
commit ec27299f4b88daa80261298fafea76ae634744d9
|
||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
version 0.26.3
|
typo fix
|
||||||
|
|
||||||
|
X-Gentoo-Bug: 618888
|
||||||
|
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=618888
|
||||||
|
|
||||||
commit da0ddd521ad15d030308fbf2017577acc422f1d6
|
commit 1ece16bfcd0ab71d2f9fe17a75ee6184e0fa4828
|
||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
update ChangeLog
|
openrc-shutdown: add dry-run option
|
||||||
|
|
||||||
commit 1967cd402caf6e229263f15aef40c6c4d8f60ce3
|
commit 0cfd0dd9ef580ed9dc563ccc164d70efe8f299db
|
||||||
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
openrc-shutdown: move to single user mode by default
|
||||||
|
|
||||||
|
To be more compatible with sysvinit, move to single user mode if no
|
||||||
|
options are specified on the command line.
|
||||||
|
|
||||||
|
commit a77ee2e94191ba1a286b8a6835f76556481566ba
|
||||||
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
init: add ability to switch to single user mode
|
||||||
|
|
||||||
|
commit 49b8a573a195f4b2cee992cd10678694da0a6f4f
|
||||||
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
|
add kill_all helper
|
||||||
|
|
||||||
|
This is similar to the sysvinit killall5 utility. It should only be used
|
||||||
|
in service scripts, so it will not be installed in the path.
|
||||||
|
|
||||||
|
This closes #129.
|
||||||
|
|
||||||
|
commit a2055af90054f5125cc07d4851b1dc9d16815e7c
|
||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
rc_status: calculate time differences in time_t and display seconds in uptime
|
rc_status: calculate time differences in time_t and display seconds in uptime
|
||||||
|
|
||||||
commit a7f3eb466c750eee160c49ab728ad1f8cd3380ee
|
commit cbf96967f1b6dc72ae16203dfbbb844bd08e8b6b
|
||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
|
|
||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
|
||||||
|
|
||||||
version 0.26.2
|
|
||||||
|
|
||||||
commit ae7490929d35322e1ce19daaa9f1edadbfe8dfd6
|
|
||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
|
|
||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
|
||||||
|
|
||||||
update ChangeLog
|
|
||||||
|
|
||||||
commit ddbd1caa35986b9f1be0070dad1cedfc427a1bf1
|
|
||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
supervise-daemon: save start time and respawn count before dropping privs
|
supervise-daemon: save start time and respawn count before dropping privs
|
||||||
|
|
||||||
commit a24965121834b64cc5e62c52c67b88886e5c5f5c
|
commit f1013037b47cdd6344f1b3ed92b7f84d7fcca01f
|
||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
|
|
||||||
version 0.26.1
|
version 0.27
|
||||||
|
|
||||||
commit e4bfb4530a86a4ccdff312c857df37fa0da36fd6
|
commit e4bfb4530a86a4ccdff312c857df37fa0da36fd6
|
||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
|
Author: William Hubbs <w.d.hubbs@gmail.com>
|
||||||
@@ -1433,23 +1632,3 @@ Commit: William Hubbs <w.d.hubbs@gmail.com>
|
|||||||
|
|
||||||
X-Gentoo-Bug:583634
|
X-Gentoo-Bug:583634
|
||||||
X-Gentoo-Bug-URL:https://bugs.gentoo.org/show_bug.cgi?id=583634
|
X-Gentoo-Bug-URL:https://bugs.gentoo.org/show_bug.cgi?id=583634
|
||||||
|
|
||||||
commit b2c92b88cc6ce6d81444667efbc6d44542db1788
|
|
||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
|
|
||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
|
||||||
|
|
||||||
fstabinfo/mountinfo: ensure /etc/fstab exists before calling setmntent
|
|
||||||
|
|
||||||
This is based on a patch by A. Wilcox <awilfox.gentoo@foxkit.us>.
|
|
||||||
|
|
||||||
X-Gentoo-Bug: 478226
|
|
||||||
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=478226
|
|
||||||
|
|
||||||
X-Gentoo-Bug: 478226
|
|
||||||
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=478226
|
|
||||||
|
|
||||||
commit 1b32af17225a4b18ced7f4326727cbe8265e7fd2
|
|
||||||
Author: William Hubbs <w.d.hubbs@gmail.com>
|
|
||||||
Commit: William Hubbs <w.d.hubbs@gmail.com>
|
|
||||||
|
|
||||||
increment version to 0.22
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
NAME= openrc
|
NAME= openrc
|
||||||
VERSION= 0.26.3
|
VERSION= 0.27.2
|
||||||
PKG= ${NAME}-${VERSION}
|
PKG= ${NAME}-${VERSION}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ MKPREFIX=yes
|
|||||||
MKPKGCONFIG=no
|
MKPKGCONFIG=no
|
||||||
MKSELINUX=yes
|
MKSELINUX=yes
|
||||||
MKSTATICLIBS=no
|
MKSTATICLIBS=no
|
||||||
|
MKSYSVINIT=yes
|
||||||
MKTERMCAP=ncurses
|
MKTERMCAP=ncurses
|
||||||
MKTERMCAP=termcap
|
MKTERMCAP=termcap
|
||||||
PKG_PREFIX=/usr/pkg
|
PKG_PREFIX=/usr/pkg
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#baud=""
|
#baud=""
|
||||||
|
|
||||||
# set the terminal type
|
# set the terminal type
|
||||||
#termtype="linux"
|
#term_type="linux"
|
||||||
|
|
||||||
# extra options to pass to agetty for this port
|
# extra options to pass to agetty for this port
|
||||||
#agetty_options=""
|
#agetty_options=""
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
# If you wish to pass any options to killall5 during shutdown,
|
# If you wish to pass any options to kill_all during shutdown,
|
||||||
# you should do so here.
|
# you should do so here.
|
||||||
|
#
|
||||||
|
# The setting is called killall5_opts because the options here are meant
|
||||||
|
# to be identical to those you could pass to killall5.
|
||||||
killall5_opts=""
|
killall5_opts=""
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ supervisor=supervise-daemon
|
|||||||
port="${RC_SVCNAME#*.}"
|
port="${RC_SVCNAME#*.}"
|
||||||
term_type="${term_type:-linux}"
|
term_type="${term_type:-linux}"
|
||||||
command=/sbin/agetty
|
command=/sbin/agetty
|
||||||
command_args_foreground="${agetty_options} ${port} ${baud} ${termtype}"
|
command_args_foreground="${agetty_options} ${port} ${baud} ${term_type}"
|
||||||
pidfile="/run/${RC_SVCNAME}.pid"
|
pidfile="/run/${RC_SVCNAME}.pid"
|
||||||
|
|
||||||
depend() {
|
depend() {
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ stop()
|
|||||||
{
|
{
|
||||||
# Write a halt record if we're shutting down
|
# Write a halt record if we're shutting down
|
||||||
if [ "$RC_RUNLEVEL" = shutdown ]; then
|
if [ "$RC_RUNLEVEL" = shutdown ]; then
|
||||||
[ "$RC_UNAME" = Linux ] && halt -w
|
[ "$RC_UNAME" = Linux ] && openrc-shutdown -w
|
||||||
if [ "$RC_SYS" = OPENVZ ]; then
|
if [ "$RC_SYS" = OPENVZ ]; then
|
||||||
yesno $RC_REBOOT && printf "" >/reboot
|
yesno $RC_REBOOT && printf "" >/reboot
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ depend()
|
|||||||
start()
|
start()
|
||||||
{
|
{
|
||||||
ebegin "Terminating remaining processes"
|
ebegin "Terminating remaining processes"
|
||||||
killall5 -15 ${killall5_opts}
|
kill_all 15 ${killall5_opts}
|
||||||
eend 0
|
eend 0
|
||||||
ebegin "Killing remaining processes"
|
ebegin "Killing remaining processes"
|
||||||
killall5 -9 ${killall5_opts}
|
kill_all 9 ${killall5_opts}
|
||||||
eend 0
|
eend 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
.\" This file may not be copied, modified, propagated, or distributed
|
.\" This file may not be copied, modified, propagated, or distributed
|
||||||
.\" except according to the terms contained in the LICENSE file.
|
.\" except according to the terms contained in the LICENSE file.
|
||||||
.\"
|
.\"
|
||||||
.Dd April 6, 2017
|
.Dd May 22, 2017
|
||||||
.Dt openrc-shutdown 8 SMM
|
.Dt openrc-shutdown 8 SMM
|
||||||
.Os OpenRC
|
.Os OpenRC
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@@ -16,22 +16,33 @@
|
|||||||
.Nd bring the system down
|
.Nd bring the system down
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
|
.Op Fl d , -no-write
|
||||||
|
.Op Fl D , -dry-run
|
||||||
.Op Fl H , -halt
|
.Op Fl H , -halt
|
||||||
.Op Fl k , -kexec
|
.Op Fl k , -kexec
|
||||||
.Op Fl p , -poweroff
|
.Op Fl p , -poweroff
|
||||||
.Op Fl R , -reexec
|
.Op Fl R , -reexec
|
||||||
.Op Fl r , -reboot
|
.Op Fl r , -reboot
|
||||||
|
.Op Fl s , -single
|
||||||
|
.Op Fl w , -write-only
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
.Nm
|
.Nm
|
||||||
is the utility that communicates with openrc-init(8) to bring down the
|
is the utility that communicates with
|
||||||
system or instruct openrc-init to re-execute itself. It supports the
|
.Xr openrc-init 8
|
||||||
following options:
|
to bring down the system or instruct openrc-init to re-execute itself.
|
||||||
|
It supports the following options:
|
||||||
.Bl -tag -width "poweroff"
|
.Bl -tag -width "poweroff"
|
||||||
|
.It Fl d , -no-write
|
||||||
|
Do not write the wtmp boot record.
|
||||||
|
.It Fl D , -dry-run
|
||||||
|
Print the action that would be taken without executing it. This is to
|
||||||
|
allow testing.
|
||||||
.It Fl H , -halt
|
.It Fl H , -halt
|
||||||
Stop all services, kill all remaining processes and halt the system.
|
Stop all services, kill all remaining processes and halt the system.
|
||||||
.It Fl k , -kexec
|
.It Fl k , -kexec
|
||||||
Stop all services, kill all processes and boot directly into a new
|
Stop all services, kill all processes and boot directly into a new
|
||||||
kernel loaded via kexec(8).
|
kernel loaded via
|
||||||
|
.Xr kexec 8 .
|
||||||
.It Fl p , -poweroff
|
.It Fl p , -poweroff
|
||||||
Stop all services, kill all processes and power off the system.
|
Stop all services, kill all processes and power off the system.
|
||||||
.It Fl R , -reexec
|
.It Fl R , -reexec
|
||||||
@@ -39,6 +50,10 @@ instruct openrc-init to re-exec itself. This should be used after an
|
|||||||
upgrade of OpenRC if you are using openrc-init as your init process.
|
upgrade of OpenRC if you are using openrc-init as your init process.
|
||||||
.It Fl r , -reboot
|
.It Fl r , -reboot
|
||||||
Stop all services, kill all processes and reboot the system.
|
Stop all services, kill all processes and reboot the system.
|
||||||
|
.It Fl s , -single
|
||||||
|
Stop all services, kill all processes and move to single user mode.
|
||||||
|
.It Fl w , -write-only
|
||||||
|
Stop all services, kill all processes and move to single user mode.
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr openrc-init 8 ,
|
.Xr openrc-init 8 ,
|
||||||
|
|||||||
3
mk/cc.mk
3
mk/cc.mk
@@ -26,7 +26,8 @@ _CCFLAGS= -Wall -Wextra -Wimplicit -Wshadow -Wformat=2 \
|
|||||||
-Wnested-externs \
|
-Wnested-externs \
|
||||||
-Winline -Wwrite-strings -Wcast-align -Wcast-qual \
|
-Winline -Wwrite-strings -Wcast-align -Wcast-qual \
|
||||||
-Wpointer-arith \
|
-Wpointer-arith \
|
||||||
-Wdeclaration-after-statement -Wsequence-point
|
-Wdeclaration-after-statement -Wsequence-point \
|
||||||
|
-Werror=implicit-function-declaration
|
||||||
|
|
||||||
# We should be using -Wredundant-decls, but our library hidden proto stuff
|
# We should be using -Wredundant-decls, but our library hidden proto stuff
|
||||||
# gives loads of warnings. I don't fully understand it (the hidden proto,
|
# gives loads of warnings. I don't fully understand it (the hidden proto,
|
||||||
|
|||||||
4
scripts/.gitignore
vendored
4
scripts/.gitignore
vendored
@@ -1 +1,5 @@
|
|||||||
|
halt
|
||||||
|
poweroff
|
||||||
rc-sstat
|
rc-sstat
|
||||||
|
reboot
|
||||||
|
shutdown
|
||||||
|
|||||||
@@ -8,12 +8,23 @@ INSTALLAFTER = _installafter
|
|||||||
ifeq (${OS},Linux)
|
ifeq (${OS},Linux)
|
||||||
SRCS+= rc-sstat.in
|
SRCS+= rc-sstat.in
|
||||||
BIN+= rc-sstat
|
BIN+= rc-sstat
|
||||||
|
ifeq (${MKSYSVINIT},yes)
|
||||||
|
SRCS+= halt.in poweroff.in reboot.in shutdown.in
|
||||||
|
BIN+= halt poweroff reboot shutdown
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
_installafter:
|
_installafter:
|
||||||
ifeq (${OS},Linux)
|
ifeq (${OS},Linux)
|
||||||
${INSTALL} -d ${DESTDIR}${SBINDIR}
|
${INSTALL} -d ${DESTDIR}${SBINDIR}
|
||||||
ln -sf ${DIR}/rc-sstat ${DESTDIR}/${SBINDIR}/rc-sstat
|
ln -sf ${DIR}/rc-sstat ${DESTDIR}/${SBINDIR}/rc-sstat
|
||||||
|
ifeq (${MKSYSVINIT},yes)
|
||||||
|
ln -sf ${DIR}/halt ${DESTDIR}/${SBINDIR}/halt
|
||||||
|
ln -sf ${DIR}/poweroff ${DESTDIR}/${SBINDIR}/poweroff
|
||||||
|
ln -sf ${DIR}/reboot ${DESTDIR}/${SBINDIR}/reboot
|
||||||
|
ln -sf ${DIR}/shutdown ${DESTDIR}/${SBINDIR}/shutdown
|
||||||
|
ln -sf openrc-init ${DESTDIR}/${SBINDIR}/init
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
include ${MK}/scripts.mk
|
include ${MK}/scripts.mk
|
||||||
|
|||||||
3
scripts/halt.in
Normal file
3
scripts/halt.in
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#!@SHELL@
|
||||||
|
|
||||||
|
exec @SBINDIR@/openrc-shutdown --halt "$@"
|
||||||
3
scripts/poweroff.in
Normal file
3
scripts/poweroff.in
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#!@SHELL@
|
||||||
|
|
||||||
|
exec @SBINDIR@/openrc-shutdown --poweroff "$@"
|
||||||
3
scripts/reboot.in
Normal file
3
scripts/reboot.in
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#!@SHELL@
|
||||||
|
|
||||||
|
exec @SBINDIR@/openrc-shutdown --reboot "$@"
|
||||||
21
scripts/shutdown.in
Normal file
21
scripts/shutdown.in
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#!@SHELL@
|
||||||
|
|
||||||
|
poweroff_arg=
|
||||||
|
while getopts :HhPr opt; do
|
||||||
|
case "$opt" in
|
||||||
|
h|P) poweroff_arg=--poweroff ;;
|
||||||
|
H) poweroff_arg=--halt ;;
|
||||||
|
r) poweroff_arg=--reboot ;;
|
||||||
|
\?) printf "${0##*/}: invalid option ${optarg}\n" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND-1))
|
||||||
|
|
||||||
|
if [ -z "${poweroff_arg}" ]; then
|
||||||
|
poweroff_arg=--single
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo @SBINDIR@/openrc-shutdown ${poweroff_arg} ${@}
|
||||||
|
exec @SBINDIR@/openrc-shutdown ${poweroff_arg} ${@}
|
||||||
26
src/includes/rc-wtmp.h
Normal file
26
src/includes/rc-wtmp.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* rc-wtmp.h
|
||||||
|
* This is private to us and not for user consumption
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017 The OpenRC Authors.
|
||||||
|
* See the Authors file at the top-level directory of this distribution and
|
||||||
|
* https://github.com/OpenRC/openrc/blob/master/AUTHORS
|
||||||
|
*
|
||||||
|
* This file is part of OpenRC. It is subject to the license terms in
|
||||||
|
* the LICENSE file found in the top-level directory of this
|
||||||
|
* distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
|
||||||
|
* This file may not be copied, modified, propagated, or distributed
|
||||||
|
* except according to the terms contained in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RC_WTMP_H__
|
||||||
|
#define __RC_WTMP_H__
|
||||||
|
|
||||||
|
#include <utmp.h>
|
||||||
|
|
||||||
|
void log_wtmp(const char *user, const char *id, pid_t pid, int type,
|
||||||
|
const char *line);
|
||||||
|
|
||||||
|
#endif
|
||||||
1
src/rc/.gitignore
vendored
1
src/rc/.gitignore
vendored
@@ -62,3 +62,4 @@ openrc
|
|||||||
openrc-init
|
openrc-init
|
||||||
openrc-run
|
openrc-run
|
||||||
openrc-shutdown
|
openrc-shutdown
|
||||||
|
kill_all
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ SRCS+= rc-selinux.c
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq (${OS},Linux)
|
ifeq (${OS},Linux)
|
||||||
SRCS+= openrc-init.c openrc-shutdown.c
|
SRCS+= kill_all.c openrc-init.c openrc-shutdown.c rc-wtmp.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CLEANFILES= version.h rc-selinux.o
|
CLEANFILES= version.h rc-selinux.o
|
||||||
@@ -44,6 +44,7 @@ RC_SBINPROGS= mark_service_starting mark_service_started \
|
|||||||
rc-abort swclock
|
rc-abort swclock
|
||||||
|
|
||||||
ifeq (${OS},Linux)
|
ifeq (${OS},Linux)
|
||||||
|
RC_BINPROGS+= kill_all
|
||||||
SBINPROGS+= openrc-init openrc-shutdown
|
SBINPROGS+= openrc-init openrc-shutdown
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -99,6 +100,9 @@ checkpath: rc-selinux.o
|
|||||||
endif
|
endif
|
||||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||||
|
|
||||||
|
kill_all: kill_all.o _usage.o
|
||||||
|
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||||
|
|
||||||
einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
|
einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
|
||||||
eindent eoutdent esyslog eval_ecolors ewaitfile \
|
eindent eoutdent esyslog eval_ecolors ewaitfile \
|
||||||
veinfo vewarn vebegin veend vewend veindent veoutdent: do_e.o rc-misc.o
|
veinfo vewarn vebegin veend vewend veindent veoutdent: do_e.o rc-misc.o
|
||||||
@@ -107,7 +111,7 @@ veinfo vewarn vebegin veend vewend veindent veoutdent: do_e.o rc-misc.o
|
|||||||
fstabinfo: fstabinfo.o _usage.o rc-misc.o
|
fstabinfo: fstabinfo.o _usage.o rc-misc.o
|
||||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||||
|
|
||||||
openrc-init: openrc-init.o
|
openrc-init: openrc-init.o rc-wtmp.o
|
||||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||||
|
|
||||||
is_newer_than: is_newer_than.o rc-misc.o
|
is_newer_than: is_newer_than.o rc-misc.o
|
||||||
@@ -128,7 +132,7 @@ mountinfo: mountinfo.o _usage.o rc-misc.o
|
|||||||
openrc rc: rc.o rc-logger.o rc-misc.o rc-plugin.o _usage.o
|
openrc rc: rc.o rc-logger.o rc-misc.o rc-plugin.o _usage.o
|
||||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||||
|
|
||||||
openrc-shutdown: openrc-shutdown.o _usage.o
|
openrc-shutdown: openrc-shutdown.o _usage.o rc-wtmp.o
|
||||||
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
|
||||||
|
|
||||||
openrc-run runscript: openrc-run.o _usage.o rc-misc.o rc-plugin.o
|
openrc-run runscript: openrc-run.o _usage.o rc-misc.o rc-plugin.o
|
||||||
|
|||||||
251
src/rc/kill_all.c
Normal file
251
src/rc/kill_all.c
Normal file
@@ -0,0 +1,251 @@
|
|||||||
|
/*
|
||||||
|
* kill_all.c
|
||||||
|
* Sends a signal to all processes on the system.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017 The OpenRC Authors.
|
||||||
|
* See the Authors file at the top-level directory of this distribution and
|
||||||
|
* https://github.com/OpenRC/openrc/blob/master/AUTHORS
|
||||||
|
*
|
||||||
|
* This file is part of OpenRC. It is subject to the license terms in
|
||||||
|
* the LICENSE file found in the top-level directory of this
|
||||||
|
* distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
|
||||||
|
* This file may not be copied, modified, propagated, or distributed
|
||||||
|
* except according to the terms contained in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
#include "einfo.h"
|
||||||
|
#include "rc.h"
|
||||||
|
#include "rc-misc.h"
|
||||||
|
#include "_usage.h"
|
||||||
|
|
||||||
|
const char *applet = NULL;
|
||||||
|
const char *extraopts = "[signal number]";
|
||||||
|
const char *getoptstring = "do:" getoptstring_COMMON;
|
||||||
|
const struct option longopts[] = {
|
||||||
|
{ "dry-run", 0, NULL, 'd' },
|
||||||
|
{ "omit", 1, NULL, 'o' },
|
||||||
|
longopts_COMMON
|
||||||
|
};
|
||||||
|
const char * const longopts_help[] = {
|
||||||
|
"print what would be done",
|
||||||
|
"omit this pid (can be repeated)",
|
||||||
|
longopts_help_COMMON
|
||||||
|
};
|
||||||
|
const char *usagestring = NULL;
|
||||||
|
|
||||||
|
static int mount_proc(void)
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
pid_t rc;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (exists("/proc/version"))
|
||||||
|
return 0;
|
||||||
|
pid = fork();
|
||||||
|
switch(pid) {
|
||||||
|
case -1:
|
||||||
|
syslog(LOG_ERR, "Unable to fork");
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
/* attempt to mount /proc */
|
||||||
|
execl("mount", "mount", "-t", "proc", "proc", "/proc", NULL);
|
||||||
|
syslog(LOG_ERR, "Unable to execute mount");
|
||||||
|
exit(1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* wait for child process */
|
||||||
|
while ((rc = wait(&status)) != pid)
|
||||||
|
if (rc < 0 && errno == ECHILD)
|
||||||
|
break;
|
||||||
|
if (rc != pid || WEXITSTATUS(status) != 0)
|
||||||
|
syslog(LOG_ERR, "mount returned non-zero exit status");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (! exists("/proc/version")) {
|
||||||
|
syslog(LOG_ERR, "Could not mount /proc");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_user_process(pid_t pid)
|
||||||
|
{
|
||||||
|
char buf[PATH_MAX+1];
|
||||||
|
FILE *fp;
|
||||||
|
char path[PATH_MAX+1];
|
||||||
|
pid_t temp_pid;
|
||||||
|
bool user_process = true;
|
||||||
|
|
||||||
|
while (pid >0 && user_process) {
|
||||||
|
if (pid == 2) {
|
||||||
|
user_process = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
snprintf(path, sizeof(path), "/proc/%d/status", pid);
|
||||||
|
fp = fopen(path, "r");
|
||||||
|
/*
|
||||||
|
* if we could not open the file, the process disappeared, which
|
||||||
|
* leaves us no way to determine for sure whether it was a user
|
||||||
|
* process or kernel thread, so we say it is a kernel thread to
|
||||||
|
* avoid accidentally killing it.
|
||||||
|
*/
|
||||||
|
if (!fp) {
|
||||||
|
user_process = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
temp_pid = -1;
|
||||||
|
while (! feof(fp)) {
|
||||||
|
buf[0] = 0;
|
||||||
|
if (fgets(buf, sizeof(buf), fp))
|
||||||
|
sscanf(buf, "PPid: %d", &temp_pid);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
if (temp_pid == -1) {
|
||||||
|
syslog(LOG_ERR, "Unable to read pid from /proc/%d/status", pid);
|
||||||
|
user_process = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pid = temp_pid;
|
||||||
|
}
|
||||||
|
return user_process;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int signal_processes(int sig, RC_STRINGLIST *omits, bool dryrun)
|
||||||
|
{
|
||||||
|
sigset_t signals;
|
||||||
|
sigset_t oldsigs;
|
||||||
|
DIR *dir;
|
||||||
|
struct dirent *d;
|
||||||
|
char buf[PATH_MAX+1];
|
||||||
|
pid_t pid;
|
||||||
|
int sendcount = 0;
|
||||||
|
|
||||||
|
kill(-1, SIGSTOP);
|
||||||
|
sigfillset(&signals);
|
||||||
|
sigemptyset(&oldsigs);
|
||||||
|
sigprocmask(SIG_SETMASK, &signals, &oldsigs);
|
||||||
|
/*
|
||||||
|
* Open the /proc directory.
|
||||||
|
* CWD must be /proc to avoid problems if / is affected by the killing
|
||||||
|
* (i.e. depends on fuse).
|
||||||
|
*/
|
||||||
|
if (chdir("/proc") == -1) {
|
||||||
|
syslog(LOG_ERR, "chdir /proc failed");
|
||||||
|
sigprocmask(SIG_SETMASK, &oldsigs, NULL);
|
||||||
|
kill(-1, SIGCONT);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
dir = opendir(".");
|
||||||
|
if (!dir) {
|
||||||
|
syslog(LOG_ERR, "cannot opendir(/proc)");
|
||||||
|
sigprocmask(SIG_SETMASK, &oldsigs, NULL);
|
||||||
|
kill(-1, SIGCONT);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Walk through the directory. */
|
||||||
|
while ((d = readdir(dir)) != NULL) {
|
||||||
|
/* Is this a process? */
|
||||||
|
pid = (pid_t) atoi(d->d_name);
|
||||||
|
if (pid == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Is this a process we have been requested to omit? */
|
||||||
|
sprintf(buf, "%d", pid);
|
||||||
|
if (rc_stringlist_find(omits, buf))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Is this process in our session? */
|
||||||
|
if (getsid(getpid()) == getsid(pid))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Is this a kernel thread? */
|
||||||
|
if (!is_user_process(pid))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (dryrun)
|
||||||
|
einfo("Would send signal %d to process %d", sig, pid);
|
||||||
|
else if (kill(pid, sig) == 0)
|
||||||
|
sendcount++;
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
sigprocmask(SIG_SETMASK, &oldsigs, NULL);
|
||||||
|
kill(-1, SIGCONT);
|
||||||
|
return sendcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char *arg = NULL;
|
||||||
|
int opt;
|
||||||
|
bool dryrun = false;
|
||||||
|
RC_STRINGLIST *omits = rc_stringlist_new();
|
||||||
|
int sig = SIGKILL;
|
||||||
|
char *here;
|
||||||
|
char *token;
|
||||||
|
|
||||||
|
/* Ensure that we are only quiet when explicitly told to be */
|
||||||
|
unsetenv("EINFO_QUIET");
|
||||||
|
|
||||||
|
applet = basename_c(argv[0]);
|
||||||
|
rc_stringlist_addu(omits, "1");
|
||||||
|
while ((opt = getopt_long(argc, argv, getoptstring,
|
||||||
|
longopts, (int *) 0)) != -1)
|
||||||
|
{
|
||||||
|
switch (opt) {
|
||||||
|
case 'd':
|
||||||
|
dryrun = true;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
here = optarg;
|
||||||
|
while ((token = strsep(&here, ",;:"))) {
|
||||||
|
if ((pid_t) atoi(token) > 0)
|
||||||
|
rc_stringlist_addu(omits, token);
|
||||||
|
else {
|
||||||
|
eerror("Invalid omit pid value %s", token);
|
||||||
|
usage(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case_RC_COMMON_GETOPT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc > optind) {
|
||||||
|
arg = argv[optind];
|
||||||
|
sig = atoi(arg);
|
||||||
|
if (sig <= 0 || sig > 31) {
|
||||||
|
rc_stringlist_free(omits);
|
||||||
|
eerror("Invalid signal %s", arg);
|
||||||
|
usage(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
openlog(applet, LOG_CONS|LOG_PID, LOG_DAEMON);
|
||||||
|
if (mount_proc() != 0) {
|
||||||
|
rc_stringlist_free(omits);
|
||||||
|
eerrorx("Unable to mount /proc file system");
|
||||||
|
}
|
||||||
|
signal_processes(sig, omits, dryrun);
|
||||||
|
rc_stringlist_free(omits);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "rc.h"
|
#include "rc.h"
|
||||||
|
#include "rc-wtmp.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
static const char *rc_default_runlevel = "default";
|
static const char *rc_default_runlevel = "default";
|
||||||
@@ -82,6 +83,7 @@ static void init(const char *default_runlevel)
|
|||||||
}
|
}
|
||||||
pid = do_openrc(runlevel);
|
pid = do_openrc(runlevel);
|
||||||
waitpid(pid, NULL, 0);
|
waitpid(pid, NULL, 0);
|
||||||
|
log_wtmp("reboot", "~~", 0, RUN_LVL, "~~");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_reexec(char *my_name)
|
static void handle_reexec(char *my_name)
|
||||||
@@ -105,6 +107,14 @@ static void handle_shutdown(const char *runlevel, int cmd)
|
|||||||
reboot(cmd);
|
reboot(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_single(void)
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
pid = do_openrc("single");
|
||||||
|
while (waitpid(pid, NULL, 0) != pid);
|
||||||
|
}
|
||||||
|
|
||||||
static void reap_zombies(void)
|
static void reap_zombies(void)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
@@ -187,7 +197,7 @@ int main(int argc, char **argv)
|
|||||||
perror("fopen");
|
perror("fopen");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
count = fread(buf, 1, 2048, fifo);
|
count = fread(buf, 1, sizeof(buf) - 1, fifo);
|
||||||
buf[count] = 0;
|
buf[count] = 0;
|
||||||
fclose(fifo);
|
fclose(fifo);
|
||||||
printf("PID1: Received \"%s\" from FIFO...\n", buf);
|
printf("PID1: Received \"%s\" from FIFO...\n", buf);
|
||||||
@@ -201,6 +211,8 @@ int main(int argc, char **argv)
|
|||||||
handle_shutdown("reboot", RB_AUTOBOOT);
|
handle_shutdown("reboot", RB_AUTOBOOT);
|
||||||
else if (strcmp(buf, "reexec") == 0)
|
else if (strcmp(buf, "reexec") == 0)
|
||||||
handle_reexec(argv[0]);
|
handle_reexec(argv[0]);
|
||||||
|
else if (strcmp(buf, "single") == 0)
|
||||||
|
handle_single();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,42 +27,67 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
#include "einfo.h"
|
#include "einfo.h"
|
||||||
#include "rc.h"
|
#include "rc.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "_usage.h"
|
#include "_usage.h"
|
||||||
|
#include "rc-wtmp.h"
|
||||||
|
|
||||||
const char *applet = NULL;
|
const char *applet = NULL;
|
||||||
const char *extraopts = NULL;
|
const char *extraopts = NULL;
|
||||||
const char *getoptstring = "HkpRr" getoptstring_COMMON;
|
const char *getoptstring = "dDHKpRrsw" getoptstring_COMMON;
|
||||||
const struct option longopts[] = {
|
const struct option longopts[] = {
|
||||||
|
{ "no-write", no_argument, NULL, 'd'},
|
||||||
|
{ "dry-run", no_argument, NULL, 'D'},
|
||||||
{ "halt", no_argument, NULL, 'H'},
|
{ "halt", no_argument, NULL, 'H'},
|
||||||
{ "kexec", no_argument, NULL, 'k'},
|
{ "kexec", no_argument, NULL, 'K'},
|
||||||
{ "poweroff", no_argument, NULL, 'p'},
|
{ "poweroff", no_argument, NULL, 'p'},
|
||||||
{ "reexec", no_argument, NULL, 'R'},
|
{ "reexec", no_argument, NULL, 'R'},
|
||||||
{ "reboot", no_argument, NULL, 'r'},
|
{ "reboot", no_argument, NULL, 'r'},
|
||||||
|
{ "single", no_argument, NULL, 's'},
|
||||||
|
{ "write-only", no_argument, NULL, 'w'},
|
||||||
longopts_COMMON
|
longopts_COMMON
|
||||||
};
|
};
|
||||||
const char * const longopts_help[] = {
|
const char * const longopts_help[] = {
|
||||||
|
"do not write wtmp record",
|
||||||
|
"print actions instead of executing them",
|
||||||
"halt the system",
|
"halt the system",
|
||||||
"reboot the system using kexec",
|
"reboot the system using kexec",
|
||||||
"power off the system",
|
"power off the system",
|
||||||
"re-execute init (use after upgrading)",
|
"re-execute init (use after upgrading)",
|
||||||
"reboot the system",
|
"reboot the system",
|
||||||
|
"single user mode",
|
||||||
|
"write wtmp boot record and exit",
|
||||||
longopts_help_COMMON
|
longopts_help_COMMON
|
||||||
};
|
};
|
||||||
const char *usagestring = NULL;
|
const char *usagestring = NULL;
|
||||||
const char *exclusive = "Select one of "
|
const char *exclusive = "Select one of "
|
||||||
"--halt, --kexec, --poweroff, --reexec or --reboot";
|
"--halt, --kexec, --poweroff, --reexec, --reboot, --single or --write-only";
|
||||||
|
|
||||||
|
static bool do_dryrun = false;
|
||||||
|
static bool do_halt = false;
|
||||||
|
static bool do_kexec = false;
|
||||||
|
static bool do_poweroff = false;
|
||||||
|
static bool do_reboot = false;
|
||||||
|
static bool do_reexec = false;
|
||||||
|
static bool do_single = false;
|
||||||
|
static bool do_wtmp = true;
|
||||||
|
static bool do_wtmp_only = false;
|
||||||
|
|
||||||
static void send_cmd(const char *cmd)
|
static void send_cmd(const char *cmd)
|
||||||
{
|
{
|
||||||
FILE *fifo;
|
FILE *fifo;
|
||||||
size_t ignored;
|
size_t ignored;
|
||||||
|
|
||||||
|
if (do_dryrun) {
|
||||||
|
einfo("Would send %s to init", cmd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (do_wtmp && (do_halt || do_kexec || do_reboot || do_poweroff))
|
||||||
|
log_wtmp("shutdown", "~~", 0, RUN_LVL, "~~");
|
||||||
fifo = fopen(RC_INIT_FIFO, "w");
|
fifo = fopen(RC_INIT_FIFO, "w");
|
||||||
|
|
||||||
if (!fifo) {
|
if (!fifo) {
|
||||||
perror("fopen");
|
perror("fopen");
|
||||||
return;
|
return;
|
||||||
@@ -78,24 +103,23 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int opt;
|
int opt;
|
||||||
int cmd_count = 0;
|
int cmd_count = 0;
|
||||||
bool do_halt = false;
|
|
||||||
bool do_kexec = false;
|
|
||||||
bool do_poweroff = false;
|
|
||||||
bool do_reboot = false;
|
|
||||||
bool do_reexec = false;
|
|
||||||
|
|
||||||
applet = basename_c(argv[0]);
|
applet = basename_c(argv[0]);
|
||||||
if (geteuid() != 0)
|
|
||||||
eerrorx("%s: you must be root\n", applet);
|
|
||||||
while ((opt = getopt_long(argc, argv, getoptstring,
|
while ((opt = getopt_long(argc, argv, getoptstring,
|
||||||
longopts, (int *) 0)) != -1)
|
longopts, (int *) 0)) != -1)
|
||||||
{
|
{
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
case 'd':
|
||||||
|
do_wtmp = false;
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
do_dryrun = true;
|
||||||
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
do_halt = true;
|
do_halt = true;
|
||||||
cmd_count++;
|
cmd_count++;
|
||||||
break;
|
break;
|
||||||
case 'k':
|
case 'K':
|
||||||
do_kexec = true;
|
do_kexec = true;
|
||||||
cmd_count++;
|
cmd_count++;
|
||||||
break;
|
break;
|
||||||
@@ -111,9 +135,19 @@ if (geteuid() != 0)
|
|||||||
do_reboot = true;
|
do_reboot = true;
|
||||||
cmd_count++;
|
cmd_count++;
|
||||||
break;
|
break;
|
||||||
|
case 's':
|
||||||
|
do_single = true;
|
||||||
|
cmd_count++;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
do_wtmp_only = true;
|
||||||
|
cmd_count++;
|
||||||
|
break;
|
||||||
case_RC_COMMON_GETOPT
|
case_RC_COMMON_GETOPT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (geteuid() != 0 && ! do_dryrun)
|
||||||
|
eerrorx("%s: you must be root\n", applet);
|
||||||
if (cmd_count != 1) {
|
if (cmd_count != 1) {
|
||||||
eerror("%s: %s\n", applet, exclusive);
|
eerror("%s: %s\n", applet, exclusive);
|
||||||
usage(EXIT_FAILURE);
|
usage(EXIT_FAILURE);
|
||||||
@@ -128,5 +162,9 @@ if (geteuid() != 0)
|
|||||||
send_cmd("reboot");
|
send_cmd("reboot");
|
||||||
else if (do_reexec)
|
else if (do_reexec)
|
||||||
send_cmd("reexec");
|
send_cmd("reexec");
|
||||||
|
else if (do_wtmp_only)
|
||||||
|
log_wtmp("shutdown", "~~", 0, RUN_LVL, "~~");
|
||||||
|
else if (do_single)
|
||||||
|
send_cmd("single");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
51
src/rc/rc-wtmp.c
Normal file
51
src/rc/rc-wtmp.c
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* rc-wtmp.c
|
||||||
|
* This file contains routines to deal with the wtmp file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2017 The OpenRC Authors.
|
||||||
|
* See the Authors file at the top-level directory of this distribution and
|
||||||
|
* https://github.com/OpenRC/openrc/blob/master/AUTHORS
|
||||||
|
*
|
||||||
|
* This file is part of OpenRC. It is subject to the license terms in
|
||||||
|
* the LICENSE file found in the top-level directory of this
|
||||||
|
* distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
|
||||||
|
* This file may not be copied, modified, propagated, or distributed
|
||||||
|
* except according to the terms contained in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
|
#include "rc-wtmp.h"
|
||||||
|
|
||||||
|
void log_wtmp(const char *user, const char *id, pid_t pid, int type,
|
||||||
|
const char *line)
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
struct utmp utmp;
|
||||||
|
struct utsname uname_buf;
|
||||||
|
|
||||||
|
memset(&utmp, 0, sizeof(utmp));
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
utmp.ut_tv.tv_sec = tv.tv_sec;
|
||||||
|
utmp.ut_tv.tv_usec = tv.tv_usec;
|
||||||
|
utmp.ut_pid = pid;
|
||||||
|
utmp.ut_type = type;
|
||||||
|
strncpy(utmp.ut_name, user, sizeof(utmp.ut_name));
|
||||||
|
strncpy(utmp.ut_id , id , sizeof(utmp.ut_id ));
|
||||||
|
strncpy(utmp.ut_line, line, sizeof(utmp.ut_line));
|
||||||
|
|
||||||
|
/* Put the OS version in place of the hostname */
|
||||||
|
if (uname(&uname_buf) == 0)
|
||||||
|
strncpy(utmp.ut_host, uname_buf.release, sizeof(utmp.ut_host));
|
||||||
|
|
||||||
|
updwtmp(WTMP_FILE, &utmp);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user