49 Commits

Author SHA1 Message Date
Érico Rolim
c75de34303 ctrlaltdel: trigger a reboot properly.
/run/runit/{stopit,reboot} should have their perms set to 100 by
ctrlaltdel, before runit signals itself with SIGCONT, in order to
trigger a reboot. This script can be changed by a user to perform
different actions. The comments in it explain what each file is for.

Patch created for Void, imported to Artix.
2020-08-03 23:01:04 +07:00
Érico Rolim
6453301c3b 3: remove /run/runit/reboot handling.
runit uses the permissions in the /etc/runit/reboot file to determine
whether it's going to perform a halt or reboot action. This conditional
in 3 meant that touching the reboot file, even with 000 perms, would
lead to a reboot, which goes agains what is expected according to the
runit documentation.

Patch made for Void, imported to Artix.
2020-08-03 23:00:29 +07:00
Érico Rolim
454078d6a0 1: only create /run/runit directory.
The 100 permission in /run/runit/stopit made it so that signaling runit
with SIGCONT would shut the system down. To achieve the correct
behavior, we should create the stopit and reboot files with 000 perms,
and allow their permissions to be set correctly by calls to `init 0` or
`init 6` or by /etc/runit/ctrlaltdel.

Patch created for Void, imported to Artix.
2020-08-03 22:59:27 +07:00
05801e2283 don't install rc.local -- let users create their own 2020-01-08 15:58:01 +07:00
f84f50c4e9 fix deprecation message 2020-01-01 09:49:40 +07:00
10bdc1aa58 better message 2020-01-01 09:41:28 +07:00
2b66059dbf Move any local files from /etc/rc/rc.local to /etc/rc.local 2019-12-30 22:35:25 +07:00
8eec042261 Add rc.shutdown 2019-03-08 20:16:37 +07:00
8f195fc564 Actually run the sv exit command 2019-02-12 21:16:59 +07:00
6278014c67 Add back support for /etc/rc/rc.local 2018-07-29 23:03:57 +07:00
bdb730a244 README 2018-05-22 09:47:52 +07:00
udeved
427bb5a772 makefile: rm left over rc seds 2018-05-15 13:36:29 +00:00
udeved
f9bf9fb275 remove rc 2018-05-15 13:18:46 +00:00
artoo
4882f52aba Merge pull request #9 from artix-linux/cleanup
latest dev versions cleaned up
2018-05-14 14:47:37 +02:00
udeved
ef17862551 rc-sv: add root check for non list actions 2018-05-13 17:54:22 +00:00
udeved
e148344dfa latest dev versions cleaned up 2018-05-13 15:02:02 +00:00
e8ad706b7b Drop dmraid support since mdadm-over-initramfs should implement it 2018-05-09 21:54:50 +07:00
5d16b77bdb Decouple LVM2 stage1 scripts to its own package 2018-05-09 07:22:56 +07:00
cea6a58cba Decouple cryptsetup initscripts to its own package 2018-05-09 07:16:43 +07:00
d2ebd92f24 Further fix for binfmt
Skip if directory doesn't exist or directory is empty.
Previous implementation was actually successful, but it always returns
1, probably because the loop expects all directories to exist.
2018-05-07 20:58:31 +07:00
4908b26a2d Enable btrfs only if USEBTRFS=yes 2018-05-07 14:24:37 +07:00
fdb0488f1e Fix issues with listing binfmt files 2018-05-07 11:08:52 +07:00
1aeedd0019 Remove /forcefsck and others during cleanup 2018-05-07 10:36:52 +07:00
0db3224e90 Add binfmt support 2018-05-06 20:25:53 +07:00
9527ccc8d0 Only read /etc/vconsole.conf if file exists 2018-05-06 19:46:18 +07:00
fb122c1beb Read from /etc/vconsole.conf for console_setup 2018-05-06 18:31:26 +07:00
8b47e238b9 Enable btrfs support 2018-05-06 18:27:45 +07:00
c9126a652a Make cleanup.sh the very last script to run by stage1 2018-05-06 11:13:45 +07:00
udeved
89b99e475d tmpfiles --clean is not implemented in opentmpfiles; remove the call 2018-05-06 01:14:01 +00:00
udeved
9befe99ed5 merge master 2018-05-05 23:27:57 +00:00
udeved
d36f9e6952 make clean up a sysinit module
rm unused
2018-05-05 23:24:56 +00:00
7852ea0ee3 sysctl: use sysctl --system 2018-05-06 06:12:39 +07:00
cf1c3912e7 Remove /forcefsck and others after boot
After testing, this file wasn't removed after boot, so I had to remove
it manually.
2018-05-06 06:03:29 +07:00
udeved
9cd7ec066b 1: move cleanup in rc 2018-05-05 21:57:53 +00:00
udeved
0df2f865bb rc: don't attempt to remove /tmp, consider /tmp to be mounted tmpfs
give the boot log file a*.log file extension
2018-05-05 21:57:17 +00:00
b3c76e6a59 Mount efivarfs only if EFI is detected 2018-05-05 21:08:11 +07:00
8847aa38b4 Force processes to be killed anyway 2018-05-05 21:06:05 +07:00
161c96b8fa Add license 2018-05-05 20:04:03 +07:00
990661bfd9 Split up getty-runit to its own make 2018-05-05 17:55:05 +07:00
bf732c4905 Move stages to rc, remove HASSYSV flag 2018-05-05 17:38:23 +07:00
24306e68c1 log console messages with bootlogd 2018-05-05 17:23:30 +07:00
9ae595db4f Move sysctl to functions 2018-05-05 17:14:50 +07:00
1eaaac7428 Add sysctl init to stage1 initscript 2018-05-05 17:03:47 +07:00
c9e84492fb Make stage 2 init-agnostic 2018-05-05 17:02:59 +07:00
9e4fd67db6 Add cleanup sysinit to stage1 2018-05-05 17:01:43 +07:00
d47df45f50 Remount RO before deactivating cryptsetup and LVM2 2018-05-05 15:26:25 +07:00
0665f7630b Remove Void shutdown binaries (now handled by artix-sysvcompat) 2018-05-05 13:48:48 +07:00
9a9003b255 sync immediately after remount ro 2018-05-05 13:45:08 +07:00
udeved
a67af1e82b fix bootlogd 2018-05-05 03:49:12 +00:00
83 changed files with 224 additions and 1692 deletions

27
1.in
View File

@@ -1,27 +0,0 @@
#!/bin/bash
PATH=/usr/bin:/usr/sbin
. @RCDIR@/rc.conf
. @RCDIR@/functions
# Prints distro name and URL
print_welcome
# log all console messages
bootlogd_start
run_hook sysinit_start
for sysinit in @RCDIR@/sysinit.d/*; do
. $sysinit
done
# Remove leftover files
# remove_leftover
run_hook sysinit_end
install -m100 /dev/null @RUNDIR@/stopit
status "Initialization complete"

35
3.in
View File

@@ -1,35 +0,0 @@
#!/bin/bash
PATH=/usr/bin:/usr/sbin
. @RCDIR@/rc.conf
. @RCDIR@/functions
. @RCDIR@/rc.shutdown
status "Stop services ..." sv force-stop @RUNDIR@/service/*
status "Exit services ..." sv exit @RUNDIR@/service/*
if [ -e @RUNDIR@/reboot ]; then
chmod 100 @RUNDIR@/reboot
fi
# avoid staircase effect
stty onlcr
echo " "
printhl "Initiating shutdown..."
echo " "
run_hook shutdown_start
for shutdown in @RCDIR@/shutdown.d/*; do
. $shutdown
done
run_hook shutdown_poweroff
if [ -e @RUNDIR@/reboot ]; then
[[ -x $(type -P kexec) ]] && kexec -e &>/dev/null
fi
status "Stage 3 completed."

24
COPYING Normal file
View File

@@ -0,0 +1,24 @@
Copyright (C) 2018 Muhammad Herdiansyah
Copyright (C) 2018 Artix Linux Developers
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

209
Makefile
View File

@@ -3,23 +3,79 @@ PREFIX ?= /usr
BINDIR = $(PREFIX)/bin
MANDIR = $(PREFIX)/share/man
LIBDIR = $(PREFIX)/lib
TMPFILESDIR = $(LIBDIR)/tmpfiles.d
RCLIBDIR = $(LIBDIR)/rc
########### runit ###########
RCDIR = $(SYSCONFDIR)/rc
RUNITDIR = $(SYSCONFDIR)/runit
SVDIR = $(RUNITDIR)/sv
RUNSVDIR = $(RUNITDIR)/runsvdir
SERVICEDIR = /etc/service
RUNDIR = /run/runit
RCBINDIR = $(PREFIX)/lib/rc/bin
RCDIR = $(SYSCONFDIR)/rc
TMPFILESDIR = $(LIBDIR)/tmpfiles.d
TMPFILES = tmpfile.conf
BIN = zzz pause modules-load
TMPFILES = misc/tmpfile.conf
STAGES = 1 2 3 ctrlaltdel
BIN = script/zzz src/pause
RCBIN = rc/halt rc/shutdown
RC = rc/rc.local rc/rc.shutdown rc/functions rc/rc.conf
STAGES = \
script/1 \
script/2 \
script/3 \
script/ctrlaltdel
RCLOCAL = script/rc.local script/rc.shutdown
AGETTY_CONSOLE = $(wildcard sv/agetty-console/*)
AGETTY_CONSOLE_S = supervise.agetty-console
AGETTY_GENERIC = $(wildcard sv/agetty-generic/*)
AGETTY_SERIAL = $(wildcard sv/agetty-serial/*)
AGETTY_TTY1 = $(wildcard sv/agetty-tty1/*)
AGETTY_TTY1_S = supervise.agetty-tty1
AGETTY_TTY2 = $(wildcard sv/agetty-tty2/*)
AGETTY_TTY2_S = supervise.agetty-tty2
AGETTY_TTY3 = $(wildcard sv/agetty-tty3/*)
AGETTY_TTY3_S = supervise.agetty-tty3
AGETTY_TTY4 = $(wildcard sv/agetty-tty4/*)
AGETTY_TTY4_S = supervise.agetty-tty4
AGETTY_TTY5 = $(wildcard sv/agetty-tty5/*)
AGETTY_TTY5_S = supervise.agetty-tty5
AGETTY_TTY6 = $(wildcard sv/agetty-tty6/*)
AGETTY_TTY6_S = supervise.agetty-tty6
AGETTY_TTYAMA0 = $(wildcard sv/agetty-ttyAMA0/*)
AGETTY_TTYAMA0_S = supervise.agetty-ttyAMA0
AGETTY_TTYS0 = $(wildcard sv/agetty-ttyS0/*)
AGETTY_TTYS0_S = supervise.agetty-ttyS0
AGETTY_TTYUSB0 = $(wildcard sv/agetty-ttyUSB0/*)
AGETTY_TTYUSB0_S = supervise.agetty-ttyUSB0
AGETTY_SULOGIN = $(wildcard sv/sulogin/*)
AGETTY_SULOGIN_S = supervise.sulogin
AGETTY_SYMS = \
agetty-tty1 \
agetty-tty2 \
agetty-tty3 \
agetty-tty4 \
agetty-tty5 \
agetty-tty6
SULOGIN_SYM = sulogin
########### end ###########
LN = ln -sf
CP = cp -R --no-dereference --preserve=mode,links -v
@@ -29,15 +85,14 @@ M4 = m4 -P
CHMODAW = chmod a-w
CHMODX = chmod +x
HASRC = yes
HASSYSV = no
EDIT = sed \
-e "s|@RCDIR[@]|$(RCDIR)|g" \
-e "s|@RUNITDIR[@]|$(RUNITDIR)|g" \
-e "s|@SERVICEDIR[@]|$(SERVICEDIR)|g" \
-e "s|@RUNSVDIR[@]|$(RUNSVDIR)|g" \
-e "s|@RUNDIR[@]|$(RUNDIR)|g" \
-e "s|@RCDIR[@]|$(RCDIR)|g"
-e "s|@SYSCONFDIR[@]|$(SYSCONFDIR)|g" \
-e "s|@RCLIBDIR[@]|$(RCLIBDIR)|g"
%: %.in Makefile
@echo "GEN $@"
@@ -46,31 +101,25 @@ EDIT = sed \
@$(CHMODAW) "$@"
@$(CHMODX) "$@"
all: all-runit
ifeq ($(HASRC),yes)
all: all-rc
endif
all-runit: $(STAGES)
$(CC) $(CFLAGS) pause.c -o pause $(LDFLAGS)
all-rc: $(RC) rc/shutdown
$(CC) $(CFLAGS) rc/halt.c -o rc/halt $(LDFLAGS)
all-runit: $(STAGES) $(RCLOCAL)
$(CC) $(CFLAGS) src/pause.c -o src/pause $(LDFLAGS)
install-runit:
install -d $(DESTDIR)$(RUNITDIR)
install -m755 $(STAGES) $(DESTDIR)$(RUNITDIR)
install -d $(DESTDIR)$(RUNSVDIR)/single
install -d $(DESTDIR)$(RUNSVDIR)/default
$(LN) default $(DESTDIR)$(RUNSVDIR)/current
$(LN) $(RUNDIR)/reboot $(DESTDIR)$(RUNITDIR)/
$(LN) $(RUNDIR)/stopit $(DESTDIR)$(RUNITDIR)/
install -d $(DESTDIR)$(SVDIR)
$(CP) sv/* $(DESTDIR)$(SVDIR)/
install -d $(DESTDIR)$(RUNSVDIR)
$(CP) runsvdir/* $(DESTDIR)$(RUNSVDIR)/
install -d $(DESTDIR)$(RCDIR)
install -m755 $(RCLOCAL) $(DESTDIR)$(RCDIR)
install -d $(DESTDIR)$(BINDIR)
install -m755 $(BIN) $(DESTDIR)$(BINDIR)
@@ -78,61 +127,69 @@ install-runit:
install -d $(DESTDIR)$(TMPFILESDIR)
install -m755 $(TMPFILES) $(DESTDIR)$(TMPFILESDIR)/runit.conf
install -d $(DESTDIR)$(SVDIR)/agetty-console
install -Dm755 $(AGETTY_CONSOLE) $(DESTDIR)$(SVDIR)/agetty-console
$(LN) $(RUNDIR)/$(AGETTY_CONSOLE_S) $(DESTDIR)$(SVDIR)/agetty-console/supervise
install -d $(DESTDIR)$(SVDIR)/agetty-generic
install -Dm755 $(AGETTY_GENERIC) $(DESTDIR)$(SVDIR)/agetty-generic
install -d $(DESTDIR)$(SVDIR)/agetty-serial
install -Dm755 $(AGETTY_SERIAL) $(DESTDIR)$(SVDIR)/agetty-serial
install -d $(DESTDIR)$(SVDIR)/agetty-tty1
install -Dm755 $(AGETTY_TTY1) $(DESTDIR)$(SVDIR)/agetty-tty1
$(LN) $(RUNDIR)/$(AGETTY_TTY1_S) $(DESTDIR)$(SVDIR)/agetty-tty1/supervise
#
install -d $(DESTDIR)$(SVDIR)/agetty-tty2
install -Dm755 $(AGETTY_TTY2) $(DESTDIR)$(SVDIR)/agetty-tty2
$(LN) $(RUNDIR)/$(AGETTY_TTY2_S) $(DESTDIR)$(SVDIR)/agetty-tty2/supervise
install -d $(DESTDIR)$(SVDIR)/agetty-tty3
install -Dm755 $(AGETTY_TTY3) $(DESTDIR)$(SVDIR)/agetty-tty3
$(LN) $(RUNDIR)/$(AGETTY_TTY3_S) $(DESTDIR)$(SVDIR)/agetty-tty3/supervise
install -d $(DESTDIR)$(SVDIR)/agetty-tty4
install -Dm755 $(AGETTY_TTY4) $(DESTDIR)$(SVDIR)/agetty-tty4
$(LN) $(RUNDIR)/$(AGETTY_TTY4_S) $(DESTDIR)$(SVDIR)/agetty-tty4/supervise
install -d $(DESTDIR)$(SVDIR)/agetty-tty5
install -Dm755 $(AGETTY_TTY5) $(DESTDIR)$(SVDIR)/agetty-tty5
$(LN) $(RUNDIR)/$(AGETTY_TTY5_S) $(DESTDIR)$(SVDIR)/agetty-tty5/supervise
install -d $(DESTDIR)$(SVDIR)/agetty-tty6
install -Dm755 $(AGETTY_TTY6) $(DESTDIR)$(SVDIR)/agetty-tty6
$(LN) $(RUNDIR)/$(AGETTY_TTY6_S) $(DESTDIR)$(SVDIR)/agetty-tty6/supervise
install -d $(DESTDIR)$(SVDIR)/agetty-ttyAMA0
install -Dm755 $(AGETTY_TTYAMA0) $(DESTDIR)$(SVDIR)/agetty-ttyAMA0
$(LN) $(RUNDIR)/$(AGETTY_TTYAMA0_S) $(DESTDIR)$(SVDIR)/agetty-ttyAMA0/supervise
install -d $(DESTDIR)$(SVDIR)/agetty-ttyS0
install -Dm755 $(AGETTY_TTYS0) $(DESTDIR)$(SVDIR)/agetty-ttyS0
$(LN) $(RUNDIR)/$(AGETTY_TTYS0_S) $(DESTDIR)$(SVDIR)/agetty-ttyS0/supervise
install -d $(DESTDIR)$(SVDIR)/agetty-ttyUSB0
install -Dm755 $(AGETTY_TTYUSB0) $(DESTDIR)$(SVDIR)/agetty-ttyUSB0
$(LN) $(RUNDIR)/$(AGETTY_TTYUSB0_S) $(DESTDIR)$(SVDIR)/agetty-ttyUSB0/supervise
install -d $(DESTDIR)$(SVDIR)/sulogin
install -Dm755 $(AGETTY_SULOGIN) $(DESTDIR)$(SVDIR)/sulogin
$(LN) $(RUNDIR)/$(AGETTY_SULOGIN_S) $(DESTDIR)$(SVDIR)/sulogin/supervise
for g in $(AGETTY_SYMS); do $(LN) $(SVDIR)/$$g $(DESTDIR)$(RUNSVDIR)/default/$$g; done
for g in $(SULOGIN_SYM); do $(LN) $(SVDIR)/$$g $(DESTDIR)$(RUNSVDIR)/single/$$g; done
install -d $(DESTDIR)$(MANDIR)/man1
install -m644 pause.1 $(DESTDIR)$(MANDIR)/man1
install -m644 man/pause.1 $(DESTDIR)$(MANDIR)/man1
install -d $(DESTDIR)$(MANDIR)/man8
install -m644 zzz.8 $(DESTDIR)$(MANDIR)/man8/zzz.8
install -m644 modules-load.8 $(DESTDIR)$(MANDIR)/man8
install-rc:
install -d $(DESTDIR)$(RCDIR)
install -d $(DESTDIR)$(RCDIR)/sysinit.d
install -d $(DESTDIR)$(RCDIR)/shutdown.d
install -m755 $(RC) $(DESTDIR)$(RCDIR)
install -m644 rc/sysinit.d/* $(DESTDIR)$(RCDIR)/sysinit.d
install -m644 rc/shutdown.d/* $(DESTDIR)$(RCDIR)/shutdown.d
install -m644 rc/crypt.awk $(DESTDIR)$(RCDIR)
install -d $(DESTDIR)$(RCBINDIR)
install -m644 $(RCBIN) $(DESTDIR)$(RCBINDIR)
$(LN) halt $(DESTDIR)$(RCBINDIR)/poweroff
$(LN) halt $(DESTDIR)$(RCBINDIR)/reboot
install_sysv:
install -d $(DESTDIR)$(BINDIR)
$(LN) runit-init $(DESTDIR)$(BINDIR)/init
$(LN) $(RCBINDIR)/halt $(DESTDIR)$(BINDIR)/halt
$(LN) $(RCBINDIR)/shutdown $(DESTDIR)$(BINDIR)/shutdown
$(LN) halt $(DESTDIR)$(BINDIR)/poweroff
$(LN) halt $(DESTDIR)$(BINDIR)/reboot
install -d $(DESTDIR)$(MANDIR)/man8
install -m644 rc/shutdown.8 $(DESTDIR)$(MANDIR)/man8/shutdown.8
install -m644 rc/halt.8 $(DESTDIR)$(MANDIR)/man8/halt.8
$(LN) halt.8 $(DESTDIR)$(MANDIR)/man8/poweroff.8
$(LN) halt.8 $(DESTDIR)$(MANDIR)/man8/reboot.8
install -m644 man/zzz.8 $(DESTDIR)$(MANDIR)/man8/zzz.8
install: install-runit
ifeq ($(HASRC),yes)
install: install-rc
ifeq ($(HASSYSV),yes)
install: install_sysv
endif
endif
clean-runit:
-rm -f pause
-rm -f $(STAGES)
clean-rc:
-rm -f rc/halt
-rm -f rc/shutdown $(RC)
-$(RM) src/pause $(STAGES) $(RCLOCAL)
clean: clean-runit
ifeq ($(HASRC),yes)
clean: clean-rc
endif
clean:
.PHONY: all install clean install-runit install-rc clean-runit clean-rc all-runit all-rc install_sysv
.PHONY: all install clean install-runit clean-runit

View File

@@ -1,21 +1,11 @@
## Runit init scripts for Artix Linux
## Supplemental files for runit in Artix
This repository contains the runit init scripts for the Artix Linux
distribution.
This work is based on Void Linux's
[void-runit](https://github.com/voidlinux/void-runit). Patches to Void
Linux's repo will also be applied here.
These files are supplements for runit implementation in Artix Linux.
## Dependencies
- GNU coreutils
- A POSIX shell
- A POSIX awk
- procps-ng (needs pkill -s0,1)
- runit
- opentmpfiles
- opensysusers
- runit-rc (https://github.com/artix-linux/runit-rc)
### How to use it
@@ -43,9 +33,7 @@ Feel free to send patches and contribute with improvements!
## Copyright
runit-artix is in the public domain.
Some codes are based on void-runit, which is licensed under CC0-1.0
To the extent possible under law, the creator of this work has waived
all copyright and related or neighboring rights to this work.
http://creativecommons.org/publicdomain/zero/1.0/
The rest of runit-artix is licensed under the terms as described in the
COPYING file.

67
halt.8
View File

@@ -1,67 +0,0 @@
.Dd July 29, 2014
.Dt HALT 8
.Os Linux
.Sh NAME
.Nm halt ,
.Nm reboot ,
.Nm poweroff
.Nd stop the system
.Sh SYNOPSIS
.Nm halt
.Op Fl n
.Op Fl f
.Nm reboot
.Op Fl n
.Op Fl f
.Nm poweroff
.Op Fl n
.Op Fl f
.Sh DESCRIPTION
.Nm halt
/
.Nm reboot
/
.Nm poweroff
tells
.Xr init 8
to bring down, reboot, or power off the system.
Without
.Fl f ,
it is a shortcut for
.Nm init 0
/
.Nm init 6 .
.Bl -tag -width indent
.It Fl n
Don't sync before reboot or halt.
Note that the kernel and storage drivers may still sync.
.It Fl f
Force halt or reboot, don't call
.Xr init 8 .
This is
.Sy dangerous !
.El
.Sh UNSUPPORTED OPTIONS
This version of
.Nm
is based on
.Xr runit 8 ,
the following features are
.Sy not
supported and silently ignored:
.Bl -tag -width indent
.It Fl w
to just write the wtmp record.
.It Fl d
to not write the wtmp record.
.It Fl h
to put hard drives in standby mode.
.It Fl i
to shut down network interfaces.
.El
.Sh SEE ALSO
.Xr init 8 ,
.Xr shutdown 8
.Sh AUTHOR
.An Leah Neukirchen ,
.Mt leah@vuxu.org .

77
halt.c
View File

@@ -1,77 +0,0 @@
#include <errno.h>
#include <unistd.h>
#include <err.h>
#include <string.h>
#include <sys/reboot.h>
extern char *__progname;
typedef enum {NOOP, HALT, REBOOT, POWEROFF} action_type;
int main(int argc, char *argv[]) {
int do_sync = 1;
int do_force = 0;
int opt;
action_type action = NOOP;
if (strcmp(__progname, "halt") == 0)
action = HALT;
else if (strcmp(__progname, "reboot") == 0)
action = REBOOT;
else if (strcmp(__progname, "poweroff") == 0)
action = POWEROFF;
else
warnx("no default behavior, needs to be called as halt/reboot/poweroff.");
while ((opt = getopt(argc, argv, "dfhinw")) != -1)
switch (opt) {
case 'n':
do_sync = 0;
break;
case 'w':
action = NOOP;
do_sync = 0;
break;
case 'd':
case 'h':
case 'i':
/* silently ignored. */
break;
case 'f':
do_force = 1;
break;
default:
errx(1, "Usage: %s [-n] [-f]", __progname);
}
if (do_sync)
sync();
switch (action) {
case HALT:
if (do_force)
reboot(RB_HALT_SYSTEM);
else
execl("/bin/runit-init", "init", "0", (char*)0);
err(1, "halt failed");
break;
case POWEROFF:
if (do_force)
reboot(RB_POWER_OFF);
else
execl("/bin/runit-init", "init", "0", (char*)0);
err(1, "poweroff failed");
break;
case REBOOT:
if (do_force)
reboot(RB_AUTOBOOT);
else
execl("/bin/runit-init", "init", "6", (char*)0);
err(1, "reboot failed");
break;
case NOOP:
break;
}
return 0;
}

View File

View File

@@ -1,19 +0,0 @@
#!/bin/sh
# modules-load [-n] [-v] - modules-load.d(5) compatible kernel module loader
export PATH=/bin:/sbin
{
# Parameters passed as modules-load= or rd.modules-load= in kernel command line.
sed -nr 's/,/\n/;s/(.* |^)(rd\.)?modules-load=([^ ]*).*/\3/p' /proc/cmdline
# Find files /{etc,run,usr/lib}/modules-load.d/*.conf in that order.
find -L /etc/modules-load.d /run/modules-load.d /usr/lib/modules-load.d \
-maxdepth 1 -name '*.conf' -printf '%p %P\n' 2>/dev/null |
# Load each basename only once.
sort -k2 -s | uniq -f1 | cut -d' ' -f1 |
# Read the files, output all non-empty, non-comment lines.
tr '\012' '\0' | xargs -0 -r grep -h -v -e '^[#;]' -e '^$'
} |
# Call modprobe on the list of modules
tr '\012' '\0' | xargs -0 -r modprobe -ab "$@"

View File

@@ -1,52 +0,0 @@
.Dd June 1, 2016
.Dt MODULES-LOAD 8
.Os Linux
.Sh NAME
.Nm modules-load
.Nd Configure kernel modules to load at boot
.Sh SYNOPSIS
.Nm modules-load
.Op Fl nv
.Sh DESCRIPTION
.Nm
reads files which contain kernel modules to load during boot from the list of
locations below.
.Bl -tag -width indent
.It Fl n
dry-run mode.
This option does everything but actually insert or delete the modules.
.It Fl v
verbose mode.
Print messages about what the program is doing.
.El
.Sh FILES
Configuration files are read from the following locations:
.Bl -tag -width indent
.It /etc/modules-load.d/*.conf
.It /run/modules-load.d/*.conf
.It /usr/lib/modules-load.d/*.conf
.El
.Pp
The configuration files should simply contain a list of kernel module names
to load, separated by newlines.
Empty lines and lines whose first non-whitespace character is # or ; are
ignored.
.Sh EXAMPLES
.Pa /etc/modules-load.d/virtio-net.conf :
.Bd -literal -offset indent
# Load virtio-net.ko at boot
virtio-net
.Ed
.Sh SEE ALSO
.Xr modprobe 8
.Sh HISTORY
This program is a replacement for the
.Nm modules-load
utility provided by
.Nm systemd .
.Sh AUTHOR
.An Leah Neukirchen ,
.Mt leah@vuxu.org .
.Sh LICENSE
.Nm
is in the public domain.

View File

@@ -1,4 +0,0 @@
# Default rc.local; add your custom commands here.
#
# This is run by runit in stage 2 before the services are executed
# (see /etc/runit/2).

View File

@@ -1,103 +0,0 @@
/^#/ || /^$/ { next }
NF>4 { print "a valid crypttab has max 4 cols not " NF >"/dev/stderr"; next }
{
# decode the src variants
split($2, o_src, "=")
if (o_src[1] == "UUID") ("blkid -l -o device -t " $2) | getline src;
else src=o_src[1];
# no password or none is given, ask fo it
if ( NF == 2 ) {
ccmd="cryptsetup luksOpen " src " " $1;
system(ccmd);
ccmd="";
}
else if (NF == 3 ) {
dest=$1
key=$3
split($3, po, "=");
if ( po[1] == "none") ccmd="cryptsetup luksOpen " src " " dest;
else ccmd="cryptsetup luksOpen -d " key " " src" " dest;
system(ccmd);
ccmd="";
}
else {
# the option field is not empty parse the options
dest=$1
key=$3
split($4, opts, ",");
commonopts="";
swapopts="";
luksopts="";
for(i in opts) {
split(opts[i], para, "=");
par=para[1];
val=para[2];
if ( par == "readonly" || par == "read-only") commonopts=commonopts "-r ";
else if ( par == "discard" ) commonopts=commonopts "--allow-discards ";
else if ( par == "tries" ) commonopts=commonopts "-T " val " ";
else if ( par == "swap" ) makeswap="y";
else if ( par == "cipher" ) swapopts=swapopts "-c " val " ";
else if ( par == "size" ) swapopts=swapopts "-s " val " ";
else if ( par == "hash" ) swapopts=swapopts "-h " val " ";
else if ( par == "offset" ) swapopts=swapopts "-o " val " ";
else if ( par == "skip" ) swapopts=swapopts "-p " val " ";
else if ( par == "verify" ) swapopts=swapopts "-y ";
#else if ( par == "noauto" )
#else if ( par == "nofail" )
#else if ( par == "plain" )
#else if ( par == "timeout" )
#else if ( par == "tmp" )
else if ( par == "luks" ) use_luks="y";
else if ( par == "keyscript" ) {use_keyscript="y"; keyscript=val;}
else if ( par == "keyslot" || par == "key-slot" ) luksopts=luksopts "-S " val " ";
else if ( par == "keyfile-size" ) luksopts=luksopts "-l " val " ";
else if ( par == "keyfile-offset" ) luksopts=luksopts "-keyfile-offset=" val " ";
else if ( par == "header" ) luksopts=luksopts "--header=" val " ";
else {
print "option: " par " not supported " >"/dev/stderr";
makeswap="";
use_luks="";
use_keyscript="";
next;
}
}
if ( makeswap == "y" && use_luks != "y" ) {
ccmd="cryptsetup " swapopts commonopts "-d " key " create " dest " " src;
ccmd_2="mkswap /dev/mapper/" dest;
makeswap="";
use_luks="";
use_keyscript="";
system(ccmd);
system(ccmd_2);
ccmd="";
ccmd_2="";
next;
}
if ( use_luks == "y" && makeswap != "y" ){
if ( use_keyscript == "y") {
ccmd=keyscript " | cryptsetup " luksopts commonopts "luksOpen -d - " src " " dest;
use_keyscript="";
}
else {
if ( key == "none" ){
ccmd="cryptsetup " luksopts commonopts "luksOpen " src " " dest;
}
else {
ccmd="cryptsetup " luksopts commonopts "luksOpen -d " key " " src " " dest;
}
}
}
else {
print "use swap OR luks as option" >"/dev/stderr";
ccmd="";
}
makeswap="";
use_luks="";
use_keyscript="";
if ( ccmd != ""){
system(ccmd);
ccmd=""
}
}
}

View File

@@ -1,538 +0,0 @@
#!/bin/bash
# rc functions
#
# sanitize PATH (will be overridden later when /etc/profile is sourced but is useful for udev)
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# clear the TZ envvar, so daemons always respect /etc/localtime
# unset TZ
. /etc/profile.d/locale.sh
# width:
calc_columns () {
STAT_COL=80
if [[ ! -t 1 ]]; then
USECOLOR=""
elif [[ -t 0 ]]; then
# stty will fail when stdin isn't a terminal
STAT_COL=$(stty size)
# stty gives "rows cols"; strip the rows number, we just want columns
STAT_COL=${STAT_COL##* }
elif tput cols &>/dev/null; then
# is /usr/share/terminfo already mounted, and TERM recognized?
STAT_COL=$(tput cols)
fi
if (( STAT_COL == 0 )); then
# if output was 0 (serial console), set default width to 80
STAT_COL=80
USECOLOR=""
fi
# we use 13 characters for our own stuff
STAT_COL=$(( STAT_COL - 13 ))
if [[ -t 1 ]]; then
SAVE_POSITION="\e[s"
RESTORE_POSITION="\e[u"
DEL_TEXT="\e[$(( STAT_COL + 4 ))G"
else
SAVE_POSITION=""
RESTORE_POSITION=""
DEL_TEXT=""
fi
}
calc_columns
# disable colors on broken terminals
TERM_COLORS=$(tput colors 2>/dev/null)
if (( $? != 3 )); then
case $TERM_COLORS in
*[!0-9]*) USECOLOR="";;
[0-7]) USECOLOR="";;
'') USECOLOR="";;
esac
fi
unset TERM_COLORS
unquote() {
local -r quotes=$'[\'"]'
if [[ ${1:0:1} = $quotes && ${1:(-1)} = "${1:0:1}" ]]; then
printf '%s' "${1:1:(-1)}"
else
printf '%s' "$1"
fi
}
# functions:
deltext() {
printf "${DEL_TEXT}"
}
printhl() {
printf "${C_OTHER}${PREFIX_HL} ${C_H1}${1}${C_CLEAR} \n"
}
printsep() {
printf "\n${C_SEPARATOR} ------------------------------\n"
}
stat_busy() {
printf "${C_OTHER}${PREFIX_REG} ${C_MAIN}${1}${C_CLEAR} "
printf "${SAVE_POSITION}"
deltext
printf " ${C_OTHER}[${C_BUSY}BUSY${C_OTHER}]${C_CLEAR} "
}
stat_done() {
deltext
printf " ${C_OTHER}[${C_DONE}DONE${C_OTHER}]${C_CLEAR} \n"
}
stat_fail() {
deltext
printf " ${C_OTHER}[${C_FAIL}FAIL${C_OTHER}]${C_CLEAR} \n"
}
status() {
local quiet
case $1 in
-q)
quiet=1
;;&
-v)
# NOOP: supported for backwards compat
shift
;;
esac
stat_busy "$1"
shift
if (( quiet )); then
"$@" &>/dev/null
else
"$@"
fi
local ret=$?
(( ret == 0 )) && stat_done || stat_fail
return $ret
}
# usage : in_array( $needle, $haystack )
# return : 0 - found
# 1 - not found
in_array() {
local needle=$1; shift
local item
for item; do
[[ $item = "${needle}" ]] && return 0
done
return 1 # Not Found
}
kill_all() {
stat_busy "Sending TERM signal to processes"
pkill --inverse -s0,1 -TERM
if (( $? == 0 )); then
stat_done
else
stat_fail
sleep 1
status "Sending KILL signal to processes" pkill --inverse -s0,1 -KILL
fi
}
print_welcome() {
# see os-release(5)
. /etc/os-release
echo " "
printhl "${PRETTY_NAME}\n"
printhl "${C_H2}${HOME_URL}"
printsep
}
load_modules() {
local rc=0
/usr/bin/modules-load
(( rc+=$? ))
return $rc
}
# Start/trigger udev, load MODULES, and settle udev
udevd_modprobe() {
# $1 = where we are being called from.
# This is used to determine which hooks to run.
status "Starting udev daemon" udevd --daemon
run_hook "$1_udevlaunched"
stat_busy "Triggering udev uevents"
udevadm trigger --action=add --type=subsystems
udevadm trigger --action=add --type=devices
stat_done
# Load modules from the MODULES array and modules-load.d
status "Loading user-specified modules" load_modules
status "Waiting for udev uevents to be processed" \
udevadm settle
run_hook "$1_udevsettled"
# in case loading a module changed the display mode
calc_columns
}
activate_vgs() {
[[ $USELVM = [yY][eE][sS] && -x $(type -P lvm) && -d /sys/block ]] || return 0
stat_busy "Activating LVM2 groups"
vgchange --sysinit -a y >/dev/null
(( $? == 0 )) && stat_done || stat_fail
}
do_unlock_legacy() {
# $1 = requested name
# $2 = source device
# $3 = password
# $4 = options
local open=create a=$1 b=$2 failed=0
# Ordering of options is different if you are using LUKS vs. not.
# Use ugly swizzling to deal with it.
# isLuks only gives an exit code but no output to stdout or stderr.
if cryptsetup isLuks "$2" 2>/dev/null; then
open=luksOpen
a=$2
b=$1
fi
case $3 in
SWAP)
local _overwriteokay=0
if [[ -b $2 && -r $2 ]]; then
# This is DANGEROUS! If there is any known file system,
# partition table, RAID, or LVM volume on the device,
# we don't overwrite it.
#
# 'blkid' returns 2 if no valid signature has been found.
# Only in this case should we allow overwriting the device.
#
# This sanity check _should_ be sufficient, but it might not.
# This may cause data loss if it is not used carefully.
blkid -p "$2" &>/dev/null
(( $? == 2 )) && _overwriteokay=1
fi
if (( _overwriteokay == 0 )); then
false
elif cryptsetup -d /dev/urandom $4 $open "$a" "$b" >/dev/null; then
printf "creating swapspace..\n"
mkswap -f -L $1 /dev/mapper/$1 >/dev/null
fi;;
ASK)
printf "\nOpening '$1' volume:\n"
cryptsetup $4 $open "$a" "$b" < /dev/console;;
/dev*)
local ckdev=${3%%:*}
local cka=${3#*:}
local ckb=${cka#*:}
local cka=${cka%:*}
local ckfile=/dev/ckfile
local ckdir=/dev/ckdir
case ${cka} in
*[!0-9]*)
# Use a file on the device
# cka is not numeric: cka=filesystem, ckb=path
mkdir ${ckdir}
mount -r -t ${cka} ${ckdev} ${ckdir}
dd if=${ckdir}/${ckb} of=${ckfile} >/dev/null 2>&1
umount ${ckdir}
rmdir ${ckdir};;
*)
# Read raw data from the block device
# cka is numeric: cka=offset, ckb=length
dd if=${ckdev} of=${ckfile} bs=1 skip=${cka} count=${ckb} >/dev/null 2>&1;;
esac
cryptsetup -d ${ckfile} $4 $open "$a" "$b" >/dev/null
dd if=/dev/urandom of=${ckfile} bs=1 count=$(stat -c %s ${ckfile}) conv=notrunc >/dev/null 2>&1
rm ${ckfile};;
/*)
cryptsetup -d "$3" $4 $open "$a" "$b" >/dev/null;;
*)
echo "$3" | cryptsetup $4 $open "$a" "$b" >/dev/null;;
esac
return $?
}
do_unlock() {
local name=$1 device=$2 password=$3 options=$4
printf "${C_MAIN}Unlocking $1${C_CLEAR}\n"
if [[ ${options:0:2} =~ -. ]]; then
do_unlock_legacy "$name" "$device" "$password" "$options"
return $?
fi
case $password in
ASK|SWAP)
do_unlock_legacy "$name" "$device" "$password" "$options"
;;
*)
do_unlock_legacy "$name" "$device" "$password" "$options"
;;
esac
failed=$?
if (( $failed )); then
printf "${C_FAIL}Unlocking of $1 failed.${C_CLEAR}\n"
fi
return $?
}
deactivate_crypt() {
if [[ -x /usr/bin/dmsetup ]]; then
for v in $(dmsetup ls --target crypt --exec "dmsetup info -c --noheadings -o open,name"); do
[[ ${v%%:*} == "0" ]] && cryptsetup close ${v##*:}
done
fi
}
set_timezone() {
local tz=$1 zonefile=/usr/share/zoneinfo/$1
[[ $tz ]] || return 1
if [[ ! -e $zonefile ]]; then
printf "error: \`%s' is not a valid time zone\n" "$tz"
return 1
fi
if [[ -L /etc/localtime && /etc/localtime -ef $zonefile ]]; then
return 0
else
ln -sf "/usr/share/zoneinfo/$tz" /etc/localtime
fi
}
# Filesystem functions
# These can be overridden/reused for customizations like shutdown/loop-fsck.
NETFS="nfs,nfs4,smbfs,cifs,codafs,ncpfs,shfs,fuse,fuseblk,glusterfs,davfs,fuse.glusterfs"
# Check local filesystems
fsck_all() {
if [[ -f /forcefsck ]] || in_array forcefsck $(< /proc/cmdline); then
FORCEFSCK="-f"
elif [[ -f /fastboot ]] || in_array fastboot $(< /proc/cmdline); then
return 0
elif [[ -e /run/initramfs/root-fsck ]]; then
IGNORE_MOUNTED="-M"
fi
fsck -A -T -C${FSCK_FD} -a -t no${NETFS//,/,no},noopts=_netdev ${IGNORE_MOUNTED} -- ${FORCEFSCK}
}
# Single-user login and/or automatic reboot after fsck (if needed)
fsck_reboot() {
# $1 = exit code returned by fsck
# Ignore conditions 'FS errors corrected' and 'Cancelled by the user'
(( ($1 | 33) == 33 )) && return 0
if (( $1 & 2 )); then
echo
echo "********************** REBOOT REQUIRED *********************"
echo "* *"
echo "* The system will be rebooted automatically in 15 seconds. *"
echo "* *"
echo "************************************************************"
echo
sleep 15
else
echo
echo "***************** FILESYSTEM CHECK FAILED ****************"
echo "* *"
echo "* Please repair manually and reboot. Note that the root *"
echo "* file system is currently mounted read-only. To remount *"
echo "* it read-write, type: mount -o remount,rw / *"
echo "* When you exit the maintenance shell, the system will *"
echo "* reboot automatically. *"
echo "* *"
echo "************************************************************"
echo
sulogin -p
fi
echo "Automatic reboot in progress..."
umount -a
mount -o remount,ro /
reboot -f
exit 0
}
mount_all() {
mount -a -t "no${NETFS//,/,no}" -O no_netdev
}
remove_leftover() {
status 'Removing leftover files' tmpfiles --create --remove --clean
}
bootlogd_stop() {
[[ -f /run/bootlogd.pid ]] || return 0
touch /var/log/boot
kill $(< /run/bootlogd.pid)
rm -f /run/bootlogd.pid
}
bootlogd_start(){
[[ ! -f /var/log/boot ]] && touch /var/log/boot
bootlogd -p /run/bootlogd.pid
}
console_setup(){
TTYS=${TTYS:-6}
if [ -n "$FONT" ]; then
_index=0
while [ ${_index} -le $TTYS ]; do
setfont ${FONT_MAP:+-m $FONT_MAP} ${FONT_UNIMAP:+-u $FONT_UNIMAP} \
$FONT -C "/dev/tty${_index}"
_index=$((_index + 1))
done
fi
if [ -n "$KEYMAP" ]; then
loadkeys -q -u ${KEYMAP}
fi
}
init_random_seed(){
cp /var/lib/random-seed /dev/urandom >/dev/null 2>&1 || true
( umask 077; bytes=$(cat /proc/sys/kernel/random/poolsize) || bytes=512; dd if=/dev/urandom of=/var/lib/random-seed count=1 bs=$bytes >/dev/null 2>&1 )
}
save_random_seed(){
( umask 077; bytes=$(cat /proc/sys/kernel/random/poolsize) || bytes=512; dd if=/dev/urandom of=/var/lib/random-seed count=1 bs=$bytes >/dev/null 2>&1 )
}
mk_kmod_static_nodes(){
[[ -d /run/tmpfiles.d ]] || mkdir /run/tmpfiles.d
kmod static-nodes --format=tmpfiles --output=/run/tmpfiles.d/kmod.conf
}
mk_tmpfiles_dev(){
if [ -x /usr/bin/tmpfiles ]; then
tmpfiles --prefix=/dev --create --boot
fi
}
mk_tmpfiles_setup(){
if [ -x /usr/bin/tmpfiles ]; then
tmpfiles --exclude-prefix=/dev --create --remove --boot
fi
}
mk_sysusers(){
if [ -x /usr/bin/sysusers ]; then
sysusers
fi
}
cleanup_1(){
install -m0664 -o root -g utmp /dev/null /run/utmp
if [ ! -e /var/log/wtmp ]; then
install -m0664 -o root -g utmp /dev/null /var/log/wtmp
fi
if [ ! -e /var/log/btmp ]; then
install -m0600 -o root -g utmp /dev/null /var/log/btmp
fi
rm -rf /tmp
install -dm1777 /tmp /tmp/.X11-unix /tmp/.ICE-unix
rm -f /etc/nologin #/forcefsck /forcequotacheck /fastboot
}
###############################
# Custom hooks in initscripts #
###############################
# Hooks can be used to include custom code in various places in the rc.* scripts
#
# Define a hook function in a functions.d file using:
# function_name() {
# ...
# }
# add_hook hook_name function_name
# It is allowed to register several hook functions for the same hook
# Is is also allowed to register the same hook function for several hooks
#
# Currently, the following hooks exist:
# sysinit_start: at the beginning of rc.sysinit
# shutdown_start: at the beginning of rc.shutdown
# sysinit_end: at the end of rc.sysinit
# sysinit_udevlaunched: after udev has been launched in rc.sysinit
# sysinit_udevsettled: after uevents have settled in rc.sysinit
# sysinit_premount: before local filesystems are mounted, but after root is mounted read-write in rc.sysinit
# sysinit_postmount: after local filesystems are mounted
# shutdown_prekillall: before all processes are being killed in rc.shutdown
# shutdown_postkillall: after all processes have been killed in rc.shutdown
# shutdown_preumount: after last filesystem write, but before filesystems are unmounted
# shutdown_postumount: after filesystems are unmounted
# shutdown_poweroff: directly before powering off in rc.shutdown
#
# Declare add_hook and run_hook as read-only to prevent overwriting them.
# Too bad we cannot do the same thing with hook_funcs
if (( RC_FUNCTIONS_HOOK_FUNCS_DEFINED != 1 )); then
declare -A hook_funcs
add_hook() {
[[ $1 && $2 ]] || return 1
hook_funcs[$1]+=" $2"
}
run_hook() {
[[ $1 ]] || return 1
local func
for func in ${hook_funcs["$1"]}; do
"${func}"
done
}
declare -fr add_hook run_hook
declare -r RC_FUNCTIONS_HOOK_FUNCS_DEFINED=1
fi
# set colors
if [[ $USECOLOR != [nN][oO] ]]; then
if tput setaf 0 &>/dev/null; then
C_CLEAR=$(tput sgr0) # clear text
C_MAIN=${C_CLEAR}$(tput bold) # main text
C_OTHER=${C_MAIN}$(tput setaf 4) # prefix & brackets
C_SEPARATOR=${C_MAIN}$(tput setaf 0) # separator
C_BUSY=${C_CLEAR}$(tput setaf 6) # busy
C_FAIL=${C_MAIN}$(tput setaf 1) # failed
C_DONE=${C_MAIN} # completed
C_BKGD=${C_MAIN}$(tput setaf 5) # backgrounded
C_H1=${C_MAIN} # highlight text 1
C_H2=${C_MAIN}$(tput setaf 6) # highlight text 2
else
C_CLEAR="\e[m" # clear text
C_MAIN="\e[;1m" # main text
C_OTHER="\e[1;34m" # prefix & brackets
C_SEPARATOR="\e[1;30m" # separator
C_BUSY="\e[;36m" # busy
C_FAIL="\e[1;31m" # failed
C_DONE=${C_MAIN} # completed
C_BKGD="\e[1;35m" # backgrounded
C_H1=${C_MAIN} # highlight text 1
C_H2="\e[1;36m" # highlight text 2
fi
fi
# prefixes:
PREFIX_REG="::"
PREFIX_HL=" >"
# Source additional functions at the end to allow overrides
# for f in @RCDIR@/functions.d/*; do
# [[ -e $f ]] && . "$f"
# done

View File

@@ -1,67 +0,0 @@
.Dd July 29, 2014
.Dt HALT 8
.Os Linux
.Sh NAME
.Nm halt ,
.Nm reboot ,
.Nm poweroff
.Nd stop the system
.Sh SYNOPSIS
.Nm halt
.Op Fl n
.Op Fl f
.Nm reboot
.Op Fl n
.Op Fl f
.Nm poweroff
.Op Fl n
.Op Fl f
.Sh DESCRIPTION
.Nm halt
/
.Nm reboot
/
.Nm poweroff
tells
.Xr init 8
to bring down, reboot, or power off the system.
Without
.Fl f ,
it is a shortcut for
.Nm init 0
/
.Nm init 6 .
.Bl -tag -width indent
.It Fl n
Don't sync before reboot or halt.
Note that the kernel and storage drivers may still sync.
.It Fl f
Force halt or reboot, don't call
.Xr init 8 .
This is
.Sy dangerous !
.El
.Sh UNSUPPORTED OPTIONS
This version of
.Nm
is based on
.Xr runit 8 ,
the following features are
.Sy not
supported and silently ignored:
.Bl -tag -width indent
.It Fl w
to just write the wtmp record.
.It Fl d
to not write the wtmp record.
.It Fl h
to put hard drives in standby mode.
.It Fl i
to shut down network interfaces.
.El
.Sh SEE ALSO
.Xr init 8 ,
.Xr shutdown 8
.Sh AUTHOR
.An Leah Neukirchen ,
.Mt leah@vuxu.org .

View File

@@ -1,77 +0,0 @@
#include <errno.h>
#include <unistd.h>
#include <err.h>
#include <string.h>
#include <sys/reboot.h>
extern char *__progname;
typedef enum {NOOP, HALT, REBOOT, POWEROFF} action_type;
int main(int argc, char *argv[]) {
int do_sync = 1;
int do_force = 0;
int opt;
action_type action = NOOP;
if (strcmp(__progname, "halt") == 0)
action = HALT;
else if (strcmp(__progname, "reboot") == 0)
action = REBOOT;
else if (strcmp(__progname, "poweroff") == 0)
action = POWEROFF;
else
warnx("no default behavior, needs to be called as halt/reboot/poweroff.");
while ((opt = getopt(argc, argv, "dfhinw")) != -1)
switch (opt) {
case 'n':
do_sync = 0;
break;
case 'w':
action = NOOP;
do_sync = 0;
break;
case 'd':
case 'h':
case 'i':
/* silently ignored. */
break;
case 'f':
do_force = 1;
break;
default:
errx(1, "Usage: %s [-n] [-f]", __progname);
}
if (do_sync)
sync();
switch (action) {
case HALT:
if (do_force)
reboot(RB_HALT_SYSTEM);
else
execl("/bin/runit-init", "init", "0", (char*)0);
err(1, "halt failed");
break;
case POWEROFF:
if (do_force)
reboot(RB_POWER_OFF);
else
execl("/bin/runit-init", "init", "0", (char*)0);
err(1, "poweroff failed");
break;
case REBOOT:
if (do_force)
reboot(RB_AUTOBOOT);
else
execl("/bin/runit-init", "init", "6", (char*)0);
err(1, "reboot failed");
break;
case NOOP:
break;
}
return 0;
}

View File

@@ -1,13 +0,0 @@
# @RCDIR@/rc.conf - system configuration
# Storage
#
# USEDMRAID="no"
# USELVM="no"
# Network
#
# interface=
# address=
# netmask=
# gateway=

View File

@@ -1,4 +0,0 @@
# Default rc.local; add your custom commands here.
#
# This is run by runit in stage 2 before the services are executed
# (see /etc/runit/2).

View File

@@ -1,4 +0,0 @@
# Default rc.shutdown; add your custom commands here.
#
# This is run by runit in stage 3 after the services are stopped
# (see /etc/runit/3).

View File

@@ -1,90 +0,0 @@
.Dd July 29, 2014
.Dt SHUTDOWN 8
.Os Linux
.Sh NAME
.Nm shutdown
.Nd bring down the system
.Sh SYNOPSIS
.Nm shutdown
.Op Fl rhP
.Op Fl fF
.Op Cm now | Cm + Ns Ar mins
.Op Ar message ...
.Sh DESCRIPTION
.Nm
brings the system down in a secure way.
All logged-in users
are notified that the system is going down, and
.Xr login 1
is blocked.
.Pp
By default,
.Nm
puts the system into single user mode.
Rebooting and halting the system can be done using the following options:
.Bl -tag -width indent
.It Fl c
Cancel an ongoing shutdown.
.It Fl f
Enable fast booting; skip
.Xr fsck 8
on next boot.
.It Fl F
Force run of
.Xr fsck 8
on next boot.
.It Fl h
Halt the system.
.It Fl k
Don't really shutdown; only send the warning messages to everybody.
.It Fl P
Poweroff the system.
.It Fl r
Reboot the system.
.It Cm now
Shutdown without further waiting.
.It Cm + Ns Ar mins
Wait
.Ar mins
minutes before shutting down.
.It Ar message
Message displayed to all users, defaults to "system is going down".
.El
.Sh UNSUPPORTED OPTIONS
This version of
.Nm
is based on
.Xr runit 8 ,
the following features are
.Sy not
supported:
.Bl -tag -width indent
.It Fl t Ar secs
to wait
.Ar secs
seconds between SIGKILL and SIGTERM on shutdown is silently ignored.
.It Fl a
Use
.Pa /etc/shutdown.allow .
.It Fl H
Drop into boot monitor.
.It Fl n
Don't call
.Xr init 8 .
.It Ar hh Ns : Ns Ar mm
Absolute time specification is not implemented.
.El
.Sh EXAMPLES
Turn off the system:
.Dl # shutdown -h now
.Sh SEE ALSO
.Xr fsck 8 ,
.Xr halt 8 ,
.Xr init 8 ,
.Xr poweroff 8 ,
.Xr reboot 8 ,
.Xr runit 8 ,
.Xr runsvchdir 8
.Sh AUTHOR
.An Leah Neukirchen ,
.Mt leah@vuxu.org .

View File

@@ -1 +0,0 @@
status 'Saving random seed' save_random_seed

View File

@@ -1 +0,0 @@
[[ $TIMEZONE ]] && status "Configuring time zone" set_timezone "$TIMEZONE"

View File

@@ -1,2 +0,0 @@
# Write to wtmp file before unmounting
halt -w

View File

@@ -1,3 +0,0 @@
# stop monitoring of LVM2 groups before unmounting filesystems
[[ $USELVM = [Yy][Ee][Ss] && -x $(type -P lvm) ]] &&
status "Deactivating monitoring of LVM2 groups" vgchange --monitor n

View File

@@ -1,2 +0,0 @@
# any future uevents can and should be ignored
status "Shutting down udev" udevadm control --exit

View File

@@ -1,3 +0,0 @@
run_hook shutdown_prekillall
kill_all
run_hook shutdown_postkillall

View File

@@ -1,3 +0,0 @@
# almost everything is dead now, so the swap should hopefully be relatively
# empty, and quick to switch off
status "Deactivating swap" swapoff -a

View File

@@ -1,3 +0,0 @@
run_hook shutdown_preumount
status "Unmounting non-API filesystems" umount -r -a -t nosysfs,noproc,nodevtmpfs,notmpfs
run_hook shutdown_postumount

View File

@@ -1,7 +0,0 @@
# Kill non-root encrypted partition mappings
if [[ -f /etc/crypttab ]] && type -p cryptsetup >/dev/null; then
# Maybe someone has LVM on an encrypted block device
# executing an extra vgchange is errorless
[[ $USELVM = [Yy][Ee][Ss] ]] && vgchange --sysinit -a n &>/dev/null
deactivate_crypt
fi

View File

@@ -1,2 +0,0 @@
[[ $USELVM = [Yy][Ee][Ss] && -x $(type -P lvm) ]] &&
status "Deactivating LVM2 groups" vgchange --sysinit -a n &>/dev/null

View File

@@ -1,2 +0,0 @@
status "Remounting root filesystem read-only" \
mount -o remount,ro /

View File

@@ -1,73 +0,0 @@
#!/bin/sh
# shutdown - shutdown(8) lookalike for runit
single() {
runsvchdir single
}
abort() {
printf '%s\n' "$1" >&2
exit 1
}
usage() {
abort "Usage: ${0##*/} [-fF] [-kchPr] time [warning message]"
}
action=single
while getopts akrhPHfFnct: opt; do
case "$opt" in
a|n|H) abort "'-$opt' is not implemented";;
t) ;;
f) touch /fastboot;;
F) touch /forcefsck;;
k) action=true;;
c) action=cancel;;
h|P) action=halt;;
r) action=reboot;;
[?]) usage;;
esac
done
shift $((OPTIND - 1))
[ $# -eq 0 ] && usage
time=$1; shift
message="${*:-system is going down}"
if [ "$action" = "cancel" ]; then
kill "$(cat @RUNDIR@/shutdown.pid)"
if [ -e /etc/nologin ] && ! [ -s /etc/nologin ]; then
rm /etc/nologin
fi
echo "${*:-shutdown cancelled}" | wall
exit
fi
touch @RUNDIR@/shutdown.pid 2>/dev/null || abort "Not enough permissions to execute ${0#*/}"
echo $$ >@RUNDIR@/shutdown.pid
case "$time" in
now) time=0;;
+*) time=${time#+};;
*:*) abort "absolute time is not implemented";;
*) abort "invalid time";;
esac
for break in 5 0; do
[ "$time" -gt "$break" ] || continue
[ "$break" = 0 ] && touch /etc/nologin
printf '%s in %s minutes\n' "$message" "$time" | wall
printf 'shutdown: sleeping for %s minutes... ' "$(( time - break ))"
sleep $(( (time - break) * 60 ))
time="$break"
printf '\n'
[ "$break" = 0 ] && rm /etc/nologin
done
printf '%s NOW\n' "$message" | wall
$action

View File

@@ -1,16 +0,0 @@
# mount the API filesystems
# /proc, /sys, /run, /dev, /run/lock, /dev/pts, /dev/shm
mountpoint -q /proc || mount -t proc proc /proc -o nosuid,noexec,nodev
mountpoint -q /sys || mount -t sysfs sys /sys -o nosuid,noexec,nodev
mountpoint -q /run || mount -t tmpfs run /run -o mode=0755,nosuid,nodev
mountpoint -q /dev || mount -t devtmpfs dev /dev -o mode=0755,nosuid
mkdir -p /dev/{pts,shm}
mountpoint -q /dev/pts || mount -t devpts devpts /dev/pts -o mode=0620,gid=5,nosuid,noexec
mountpoint -q /dev/shm || mount -t tmpfs shm /dev/shm -o mode=1777,nosuid,nodev
mountpoint -q /sys/kernel/security || mount -n -t securityfs securityfs /sys/kernel/security
mountpoint -q /sys/firmware/efi/efivars || mount -n -t efivarfs -o ro efivarfs /sys/firmware/efi/efivars
mountpoint -q /sys/fs/cgroup || mount -o mode=0755 -t tmpfs cgroup /sys/fs/cgroup
mountpoint -q /sys/fs/cgroup/openrc || mkdir -p /sys/fs/cgroup/openrc && mount -t cgroup -o none,name=openrc cgroup /sys/fs/cgroup/openrc
awk '$4 == 1 { system("mountpoint -q /sys/fs/cgroup/" $1 " || { mkdir -p /sys/fs/cgroup/" $1 " && mount -t cgroup -o " $1 " cgroup /sys/fs/cgroup/" $1 " ;}" ) }' /proc/cgroups
findmnt / --options ro &>/dev/null || status "Mounting root read-only" mount -o remount,ro /

View File

@@ -1,10 +0,0 @@
unset HOSTNAME
if [[ -s /etc/hostname ]]; then
HOSTNAME=$(< /etc/hostname)
fi
if [[ $HOSTNAME ]]; then
stat_busy "Setting hostname: $HOSTNAME"
echo "$HOSTNAME" >| /proc/sys/kernel/hostname && stat_done || stat_fail
fi

View File

@@ -1,34 +0,0 @@
HWCLOCK_PARAMS="--systz"
if [[ $HARDWARECLOCK ]]; then
[[ -f /etc/adjtime ]] && { read ; read ; read ADJTIME; } < /etc/adjtime
if [[ $ADJTIME == 'LOCAL' ]]; then
if [[ $HARDWARECLOCK == 'UTC' ]]; then
printf "${C_FAIL}@RCDIR@/rc.conf says the RTC is in UTC, but /etc/adjtime says it is in localtime.\n${C_OTHER}."
fi
else
if [[ $HARDWARECLOCK == 'LOCALTIME' ]]; then
printf "${C_FAIL}@RCDIR@/rc.conf says the RTC is in localtime, but hwclock (/etc/adjtime) thinks it is in UTC.\n${C_OTHER}."
fi
fi
case $HARDWARECLOCK in
UTC) HWCLOCK_PARAMS+=" --utc --noadjfile";;
localtime) HWCLOCK_PARAMS+=" --localtime --noadjfile";;
*) HWCLOCK_PARAMS="";;
esac
fi
if [[ $HWCLOCK_PARAMS ]]; then
stat_busy "Adjusting system time and setting kernel time zone"
# Adjust the system time for time zone offset if rtc is not in UTC, as
# filesystem checks can depend on system time. This also sets the kernel
# time zone, used by e.g. vfat.
hwclock $HWCLOCK_PARAMS && stat_done || stat_fail
unset TZ
fi

View File

@@ -1 +0,0 @@
status "Creating list of required static device nodes" mk_kmod_static_nodes

View File

@@ -1 +0,0 @@
status "Setting up tmpfiles.d entries for /dev" mk_tmpfiles_dev

View File

@@ -1,2 +0,0 @@
# Start/trigger udev, load MODULES, and settle udev
udevd_modprobe sysinit

View File

@@ -1,2 +0,0 @@
# this must be done after udev has loaded the KMS modules
status 'Configuring virtual consoles' console_setup

View File

@@ -1,2 +0,0 @@
# bring up the loopback interface
[[ -d /sys/class/net/lo ]] && status "Bringing up loopback interface" ip link set up dev lo

View File

@@ -1,3 +0,0 @@
# FakeRAID devices detection
[[ $USEDMRAID = [Yy][Ee][Ss] && -x $(type -P dmraid) ]] &&
status "Activating FakeRAID arrays" dmraid -i -ay

View File

@@ -1,2 +0,0 @@
# Activate LVM2 groups, if any
activate_vgs

View File

@@ -1,6 +0,0 @@
# Set up non-root encrypted partition mappings
if [[ -f /etc/crypttab ]] && type -p cryptsetup >/dev/null; then
status "Activating encrypted devices" awk -f /etc/rc/crypt.awk /etc/crypttab
# Maybe someone has LVM on an encrypted block device
activate_vgs
fi

View File

@@ -1,13 +0,0 @@
run_hook sysinit_prefsck
if [[ -x $(type -P fsck) ]]; then
stat_busy "Checking filesystems"
fsck_all >|"${FSCK_OUT:-/dev/stdout}" 2>|"${FSCK_ERR:-/dev/stdout}"
declare -r fsckret=$?
(( fsckret <= 1 )) && stat_done || stat_fail
else
declare -r fsckret=0
fi
# Single-user login and/or automatic reboot if needed
run_hook sysinit_postfsck
fsck_reboot $fsckret

View File

@@ -1,2 +0,0 @@
status "Remounting root and API filesystems" \
mount -o remount,rw /

View File

@@ -1,4 +0,0 @@
run_hook sysinit_premount
status "Mounting local filesystems" \
mount_all
run_hook sysinit_postmount

View File

@@ -1,4 +0,0 @@
# Enable monitoring of LVM2 groups, now that the filesystems are mounted rw
[[ $USELVM = [Yy][Ee][Ss] && -x $(type -P lvm) && -d /sys/block ]] &&
status "Activating monitoring of LVM2 groups" \
vgchange --monitor y >/dev/null

View File

@@ -1 +0,0 @@
status "Activating swap" swapon -a

View File

@@ -1 +0,0 @@
[[ $TIMEZONE ]] && status "Configuring time zone" set_timezone "$TIMEZONE"

View File

@@ -1 +0,0 @@
status 'Initializing random seed' init_random_seed

View File

@@ -1 +0,0 @@
status "Setting up tmpfiles.d entries" mk_tmpfiles_setup

View File

@@ -1 +0,0 @@
status "Setting up sysusers.d entries" mk_sysusers

View File

@@ -1,8 +0,0 @@
stat_busy "Saving dmesg log"
if [[ -e /proc/sys/kernel/dmesg_restrict ]] &&
(( $(< /proc/sys/kernel/dmesg_restrict) == 1 )); then
install -Tm 0600 <( dmesg ) /var/log/dmesg.log
else
install -Tm 0644 <( dmesg ) /var/log/dmesg.log
fi
(( $? == 0 )) && stat_done || stat_fail

View File

@@ -1 +0,0 @@
default

View File

@@ -1 +0,0 @@
/etc/runit/sv/agetty-tty1

View File

@@ -1 +0,0 @@
/etc/runit/sv/agetty-tty2

View File

@@ -1 +0,0 @@
/etc/runit/sv/agetty-tty3

View File

@@ -1 +0,0 @@
/etc/runit/sv/agetty-tty4

View File

@@ -1 +0,0 @@
/etc/runit/sv/agetty-tty5

View File

@@ -1 +0,0 @@
/etc/runit/sv/agetty-tty6

View File

@@ -1 +0,0 @@
/etc/runit/sv/sulogin

12
script/1.in Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/bash
PATH=/usr/bin:/usr/sbin
. @RCLIBDIR@/functions
run_sysinit
install -m000 /dev/null @RUNDIR@/stopit
install -m000 /dev/null @RUNDIR@/reboot
status "Initialization complete"

View File

@@ -2,20 +2,23 @@
PATH=/usr/bin:/usr/sbin
. @RCDIR@/functions
status "Running stage 2"
runlevel=default
for arg in $(cat /proc/cmdline); do
if [ -d @RUNITDIR@/runsvdir/"$arg" ]; then
status "Runlevel detected: '$arg' (via kernel cmdline)"
echo "Runlevel detected: '$arg' (via kernel cmdline)"
runlevel="$arg"
fi
done
if [ -x @RCDIR@/rc.local ] && grep -qv '^#' @RCDIR@/rc.local; then
@RCDIR@/rc.local
echo "==> @RCDIR@/rc.local has been deprecated. Please move the contents"
echo " of the file to @SYSCONFDIR@/rc.local, since the next version of"
echo " runit-artix won't read @RCDIR@/rc.local anymore."
fi
[ -x @SYSCONFDIR@/rc.local ] && @SYSCONFDIR@/rc.local
runsvchdir "${runlevel}"
# mkdir -p @RUNDIR@/runsvdir
ln -s @RUNSVDIR@/current @SERVICEDIR@
exec env - PATH=$PATH \

28
script/3.in Executable file
View File

@@ -0,0 +1,28 @@
#!/bin/bash
PATH=/usr/bin:/usr/sbin
. @RCLIBDIR@/functions
stat_busy "Stop services ..."
sv force-stop @RUNDIR@/service/*
stat_done
stat_busy "Exit services ..."
sv exit @RUNDIR@/service/*
stat_done
if [ -x @RCDIR@/rc.shutdown ] && grep -qv '^#' @RCDIR@/rc.shutdown; then
@RCDIR@/rc.shutdown
echo "==> @RCDIR@/rc.shutdown has been depreacted. Please move the contents"
echo " of the file to @SYSCONFDIR@/rc.shutdown since the next version of"
echo " runit-artix won't read @RCDIR@/rc.shutdown anymore."
fi
[ -x @SYSCONFDIR@/rc.local ] && @SYSCONFDIR@/rc.local
run_shutdown
if [ -e @RUNDIR@/reboot ]; then
[[ -x $(type -P kexec) ]] && kexec -e &>/dev/null
fi
status "Stage 3 completed."

View File

@@ -3,8 +3,11 @@
PATH=/usr/bin:/usr/sbin
MSG="System is going down..."
# We check for this file after receiving a SIGCONT to move to stage3
chmod 100 @RUNDIR@/stopit
# We check for this file in stage3 to halt or reboot
touch @RUNDIR@/reboot
chmod 100 @RUNDIR@/reboot
# Proceed with shutdown process
echo "$MSG" | wall

4
script/rc.local.in Normal file
View File

@@ -0,0 +1,4 @@
# @SYSCONFDIR@/rc.local -- rc.local for Artix Linux
#
# Enter your custom commands here. It will be executed on stage 2
# before running services.

4
script/rc.shutdown.in Normal file
View File

@@ -0,0 +1,4 @@
# @SYSCONFDIR@/rc.shutdown -- rc.shutdown for Artix Linux
#
# Enter your custom commands here. It will be executed on stage 3
# after stopping services.

View File

View File

@@ -1,90 +0,0 @@
.Dd July 29, 2014
.Dt SHUTDOWN 8
.Os Linux
.Sh NAME
.Nm shutdown
.Nd bring down the system
.Sh SYNOPSIS
.Nm shutdown
.Op Fl rhP
.Op Fl fF
.Op Cm now | Cm + Ns Ar mins
.Op Ar message ...
.Sh DESCRIPTION
.Nm
brings the system down in a secure way.
All logged-in users
are notified that the system is going down, and
.Xr login 1
is blocked.
.Pp
By default,
.Nm
puts the system into single user mode.
Rebooting and halting the system can be done using the following options:
.Bl -tag -width indent
.It Fl c
Cancel an ongoing shutdown.
.It Fl f
Enable fast booting; skip
.Xr fsck 8
on next boot.
.It Fl F
Force run of
.Xr fsck 8
on next boot.
.It Fl h
Halt the system.
.It Fl k
Don't really shutdown; only send the warning messages to everybody.
.It Fl P
Poweroff the system.
.It Fl r
Reboot the system.
.It Cm now
Shutdown without further waiting.
.It Cm + Ns Ar mins
Wait
.Ar mins
minutes before shutting down.
.It Ar message
Message displayed to all users, defaults to "system is going down".
.El
.Sh UNSUPPORTED OPTIONS
This version of
.Nm
is based on
.Xr runit 8 ,
the following features are
.Sy not
supported:
.Bl -tag -width indent
.It Fl t Ar secs
to wait
.Ar secs
seconds between SIGKILL and SIGTERM on shutdown is silently ignored.
.It Fl a
Use
.Pa /etc/shutdown.allow .
.It Fl H
Drop into boot monitor.
.It Fl n
Don't call
.Xr init 8 .
.It Ar hh Ns : Ns Ar mm
Absolute time specification is not implemented.
.El
.Sh EXAMPLES
Turn off the system:
.Dl # shutdown -h now
.Sh SEE ALSO
.Xr fsck 8 ,
.Xr halt 8 ,
.Xr init 8 ,
.Xr poweroff 8 ,
.Xr reboot 8 ,
.Xr runit 8 ,
.Xr runsvchdir 8
.Sh AUTHOR
.An Leah Neukirchen ,
.Mt leah@vuxu.org .

View File

@@ -1 +0,0 @@
/run/runit/supervise.agetty-console

View File

@@ -1 +0,0 @@
/run/runit/supervise.agetty-tty1

View File

@@ -1 +0,0 @@
/run/runit/supervise.agetty-tty2

View File

@@ -1 +0,0 @@
/run/runit/supervise.agetty-tty3

View File

@@ -1 +0,0 @@
/run/runit/supervise.agetty-tty4

View File

@@ -1 +0,0 @@
/run/runit/supervise.agetty-tty5

View File

@@ -1 +0,0 @@
/run/runit/supervise.agetty-tty6

View File

@@ -1 +0,0 @@
/run/runit/supervise.agetty-ttyAMA0

View File

@@ -1 +0,0 @@
/run/runit/supervise.agetty-ttyS0

View File

@@ -1 +0,0 @@
/run/runit/supervise.agetty-ttyUSB0

View File

@@ -1 +0,0 @@
/run/runit/supervise.sulogin

View File

@@ -1,88 +0,0 @@
#!/bin/sh
set -e
servicedir=$SVDIR
test -n "$servicedir" || servicedir=@SERVICEDIR@
err() { >&2 printf '%s\n\n' "$*"; exit 1; }
fatal() { err "${0##*/}: fatal: $*"; }
warn() { err "${0##*/}: warning: $*"; }
usage() {
err "Usage: ${0##*/} --add|--remove <service-directory> [<service-name>]
${0##*/} --list|--check [<service-name>]"
}
opt=$1
svdir=${2%/}
sv=$3
test -z "${opt##-*}" || usage
case "$opt" in
-c|--check) exec >/dev/null; exec 2>/dev/null; opt=-l;;
esac
case "$opt" in
-l|--list)
test -n "$svdir" || exec ls -1 "$servicedir"
test -h "$servicedir"/"$svdir" || err "Service $svdir not registered."
printf '%s -> %s\n' "$svdir" "$(readlink "$servicedir"/"$svdir")"
exit 0
;;
esac
test -n "$svdir" || usage
test -d "$svdir" ||
fatal "$svdir does not exist, or is not a directory."
test -z "${svdir%%/*}" ||
fatal "The <service-directory> must start with a slash."
test -n "$sv" || sv=${svdir##*/}
test -n "${sv##.*}" ||
fatal "The <service-name> must not start with a dot."
test "$sv" = "${sv#*/}" ||
fatal "The <service-name> must not contain a slash."
case "$opt" in
-a|--add)
test "$(id -u)" = 0 || fatal "${0##*/} -a must be run by root."
if test -e "$servicedir"/"$sv"; then
test -h "$servicedir"/"$sv" ||
fatal "$servicedir/$sv exists, but is not a symbolic link."
test "$(readlink "$servicedir"/"$sv")" = "$svdir" ||
test "$(readlink "$servicedir"/"$sv")" = "$svdir"/ ||
fatal "$servicedir/$sv exists, but doesn't point to $svdir."
printf '%s\n' "Service $sv already added."
exit 0
fi
! sv stat "$svdir" >/dev/null 2>&1 ||
fatal "$svdir is currently controlled by a runsv(8) process."
if test "${svdir#/etc/}" != "$svdir"; then
if test ! -h "$svdir"/supervise; then
rm -rf "$svdir"/supervise
ln -s /var/lib/supervise/"$sv" "$svdir"/supervise
fi
if test -d "$svdir"/log && test ! -h "$svdir"/log/supervise; then
rm -rf "$svdir"/log/supervise
ln -s /var/lib/supervise/"$sv".log "$svdir"/log/supervise
fi
fi
ln -s "$svdir" "$servicedir"/"$sv"
printf '%s\n' "Service $sv added."
exit 0
;;
-r|--remove)
test "$(id -u)" = 0 || fatal "${0##*/} -r must be run by root."
test -e "$servicedir"/"$sv" ||
warn "$servicedir/$sv does not exist."
test -h "$servicedir"/"$sv" ||
fatal "$servicedir/$sv is not a symbolic link."
test "$svdir" = "$(readlink "$servicedir"/"$sv")" ||
test "$svdir"/ = "$(readlink "$servicedir"/"$sv")" ||
fatal "$servicedir/$sv does not point to $svdir."
rm -f "$servicedir"/"$sv"
printf '%s %s\n' \
"Service $sv removed," \
"the service daemon received the TERM and CONT signals."
exit 0
;;
*) usage
;;
esac