Compare commits

..

67 Commits

Author SHA1 Message Date
fbt
65466f0702 set cfg_early_fsck by default
Signed-off-by: fbt <fbt@fleshless.org>
2021-03-14 14:43:25 +03:00
fbt
db4eb9162b early fsck
Signed-off-by: fbt <fbt@fleshless.org>
2017-12-07 17:24:02 +03:00
fbt
431f7e145e wait what how
Signed-off-by: fbt <fbt@fleshless.org>
2017-07-15 16:56:06 +03:00
fbt
5b1dbee3ac Merge branch 'master' of builder:git/spark-rc 2017-01-03 22:45:28 +03:00
fbt
6535b2b0e3 add a rundir for root
Signed-off-by: fbt <fbt@fleshless.org>
2016-09-14 08:46:07 +03:00
fbt
987c655fcc Just use /proc to see if a process is running 2016-03-29 19:21:53 +03:00
fbt
69a1c39cbc default timeout in the config 2016-03-29 16:23:55 +03:00
fbt
c799ab796b we need to actually return 1 if no pids are alive. DUH 2016-03-29 16:03:44 +03:00
fbt
24d64da2ed stupid typo 2016-03-29 15:48:59 +03:00
fbt
b640a64e21 Merge branch 'master' of builder:git/spark-rc 2016-03-29 15:40:20 +03:00
fbt
fced4775b1 wait flag for killall5 2016-03-29 15:40:14 +03:00
fbt
58054382e2 null the type output
Signed-off-by: fbt <fbt@fleshless.org>
2016-03-26 18:13:47 +03:00
fbt
04ff160a7d better sysrq test
Signed-off-by: fbt <fbt@fleshless.org>
2016-03-26 17:52:27 +03:00
fbt
409f6f8cd2 Merge branch 'master' of builder:git/spark-rc 2016-03-25 12:31:32 +03:00
fbt
ff28e04a20 use halt if available 2016-03-25 12:31:12 +03:00
fbt
e2b068e45d vim modeline 2015-11-04 21:06:19 +03:00
fbt
0afbcc55f2 rc.mount rewrite 2015-10-27 18:43:56 +03:00
fbt
1d5e825201 a huge oops 2015-10-26 19:16:18 +03:00
fbt
15592c0daa this should be a decent default 2015-10-14 10:03:58 +03:00
fbt
e379e8efff set the locale in rc.conf 2015-10-13 11:23:10 +03:00
fbt
9363ea33f5 agettys 2015-09-07 23:01:14 +03:00
fbt
92b8205255 on a second thought, the default IFS sucks 2015-09-01 13:05:37 +03:00
fbt
5dad6a777e default IFS, add tmp 2015-09-01 13:02:18 +03:00
fbt
63eda033cc not a hashtable 2015-08-31 02:03:26 +03:00
fbt
2b32655365 Indexed arrays were only needed to override defaults. 2015-08-31 01:56:54 +03:00
fbt
ec2ff428f8 change defaluts, move mountpoints to rc.conf 2015-08-31 01:45:16 +03:00
fbt
358824da8f oops 2015-08-30 16:48:20 +03:00
fbt
c0364011e0 Use an indexed array for mount definitions 2015-08-26 14:44:08 +03:00
fbt
f93cfc9056 git you silly thing 2015-08-17 17:13:39 +03:00
fbt
e59c449b0e Merge branch 'master' of builder:git/spark-rc 2015-08-17 17:10:28 +03:00
fbt
90c8943782 create the default XDG_RUNTIME dirs 2015-08-17 17:10:19 +03:00
fbt
33cea83d1b sync 2015-08-08 19:38:56 +03:00
fbt
79bccd989e Merge branch 'master' of builder:git/spark-rc 2015-06-16 16:45:40 +03:00
fbt
6d2a516b64 sync disks before shutting down 2015-06-16 16:45:33 +03:00
Alad Wenter
87de61f78c support for owner/group permissions in tmpfiles 2015-03-03 10:28:07 +03:00
fbt
22bb388fdb more robust umount 2015-03-02 18:02:16 +03:00
fbt
8af7868947 even better: configurable tpdirs and tmpfiles creation 2015-03-02 18:00:23 +03:00
fbt
e4b9660bce Merge branch 'master' of builder:git/spark-rc 2015-03-02 17:40:16 +03:00
fbt
550fabfc8e tmpfiles 2015-03-02 17:40:09 +03:00
fbt
a607a63107 Code cleanup, thx to http://www.shellcheck.net 2015-01-17 16:37:15 +03:00
fbt
782b0a3fe8 Newline, bitch 2015-01-08 15:35:06 +03:00
fbt
440eada379 simplify the default rc.conf 2015-01-08 12:42:44 +03:00
fbt
1c91d74984 support for reading hostname from /etc/hostname 2015-01-08 11:13:47 +03:00
fbt
31f80cc8da avoid heredocs, they don't work on a fully readonly VFS 2015-01-05 22:32:29 +03:00
fbt
f3cc18fcc2 Merge branch 'master' of builder:git/spark-rc 2014-12-30 18:41:33 +03:00
fbt
c23f30e7ca tmpdirs 2014-12-30 18:41:24 +03:00
fbt
14e07dbedf motd 2014-12-27 18:28:34 +03:00
fbt
88f0fa6acb Merge branch 'master' of builder:git/spark-rc 2014-12-27 17:53:39 +03:00
fbt
1d0bc30bb2 fixed the default rc.conf a bit 2014-12-27 17:53:28 +03:00
fbt
158c5939fd useless function 2014-12-01 12:03:31 +03:00
fbt
9edb1380fb rc.conf example for the timezone 2014-11-07 00:09:34 +03:00
fbt
f65b360295 set the timezone from rc.conf 2014-11-07 00:08:55 +03:00
fbt
362571f19a halt action 2014-11-06 23:29:40 +03:00
fbt
1c52234809 this is not the watchman makefile 2014-10-18 17:57:36 +04:00
fbt
025d3e4a36 make install 2014-10-18 17:56:51 +04:00
fbt
834668bd87 killall5 2014-10-18 17:50:53 +04:00
fbt
8a36bb37ae license 2014-10-16 13:28:18 +04:00
fbt
93edc4ceb7 This works properly 2014-08-09 15:17:26 +04:00
fbt
51c7ec2471 Oops 2014-08-09 14:59:12 +04:00
fbt
a57c6bd7fb switching to a makefile build 2014-08-09 14:55:26 +04:00
fbt
b7fa48d5d8 duplicate 2014-07-28 09:32:57 +04:00
fbt
25b13d5ef0 Comments! 2014-07-28 09:14:06 +04:00
fbt
48d2d826fc agettys should also start in parallel 2014-07-28 09:13:53 +04:00
fbt
d36bf9bef1 miscfs and devfs were migrated into the rc script itself 2014-07-28 07:47:35 +04:00
fbt
e2c9da41a8 mounting these is the rc's job 2014-07-28 07:37:38 +04:00
fbt
0b8f15ee5e With watchman, miscfs should start first so that watchman doesn't get confused 2014-07-28 07:11:40 +04:00
fbt
9eaeb20880 ok I really need a makefile for this. killall5 in sysv and ubase are different 2014-07-23 23:59:24 +04:00
11 changed files with 470 additions and 177 deletions

13
LICENSE Normal file
View File

@ -0,0 +1,13 @@
Copyright (c) 2012-2014, Jack L. Frost <fbt@fleshless.org>
Permission to use, copy, modify, and/or distribute this software for any purpose with or without
fee is hereby granted, provided that the above copyright notice and this permission notice appear
in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
OF THIS SOFTWARE.

43
Makefile Normal file
View File

@ -0,0 +1,43 @@
# spark-rc makefile
# Please modify config.mk and not this
sinclude config.mk
.PHONY: clean install uninstall all tools
build: rc tools
all: build
tools:
make -C tools
rc: rc.in
sed -r \
-e 's%@ETC@%$(ETC)%' \
-e 's%@BASH_PATH@%$(BASH_PATH)%' \
rc.in > rc
chmod 750 $@
clean:
rm rc
make -C tools clean
install: build
install -dm755 $(BINDIR)
install -dm755 $(ETCDIR)
install -m750 rc $(BINDIR)/rc
install -m644 rc.conf $(ETCDIR)/rc.conf
install -m644 rc.motd $(ETCDIR)/rc.motd
install -m755 tools/killall5 $(BINDIR)/killall5
make -C tools install
uninstall:
rm $(BINDIR)/rc
make -C tools uninstall

View File

@ -1,4 +1,8 @@
spark-rc
========
# spark-rc
A simple rc script to kickstart your system.
## depends
* Enabled sysrq or halt from suckless.org's ubase.
* /proc support.

160
bin/rc
View File

@ -1,160 +0,0 @@
#!/bin/bash
# Functions
rc.rescue() { exec "${cfg_rc_rescue_shell:-"$SHELL"}"; }
rc.motd() {
[[ -f "/etc/rc.motd" ]] && {
while read; do
printf "$REPLY"
done < "/etc/rc.motd"
}
return 0
}
rc.mount() {
local fs
local fs_type
local mountpoint
local mount_options
fs="$1"
fs_type="$2"
mountpoint="$3"
mount_options="${4:-defaults}"
mount "$1" -n -t "$2" -o "$mount_options" "$3"
}
rc.mount_misc() {
mountpoint -q /proc || { rc.mount proc proc /proc; }
mountpoint -q /dev || { rc.mount dev devtmpfs /dev; }
}
rc.parse_cmdline() {
[[ -f "/proc/cmdline" ]] && {
boot_cmdline=( $(</proc/cmdline) )
}
for i in "${boot_cmdline[@]}"; do
case "$i" in
init.single) rc.rescue;;
esac
done
}
rc.services_start() {
local service_name start_mode
for i in "${cfg_services[@]}"; do
unset service_name
[[ "$i" =~ ^@ ]] && {
service_name="${i##*@}"
start_mode='bg'
}
[[ "$i" =~ ^% ]] && {
service_name="${i##*%}"
start_mode='watch'
}
service_name=${service_name:-$i}
start_mode="${start_mode:-start}"
case "$start_mode" in
bg) service "$service_name" start &;;
start) service "$service_name" start;;
*) echo "Mode $start_mode not supported";;
esac
done
}
rc.services_stop() {
echo "Stopping services..."
local service_name
for i in "${cfg_services[@]}"; do
service_name="${i##*@}"; service_name="${service_name##*%}"
service "$service_name" stop &>/dev/null &
done
wait
}
rc.stop_everything() {
echo "Politely asking all processes to shut down..."
killall5 -s 15; sleep 3
echo "Killing the remaning ones..."
killall5 -s 9
}
rc.unmount_everything() {
echo "Unmounting filesystems..."
umount -a
}
rc.remount_root() {
echo "Remounting / read-only..."
mount / -o remount,ro
}
rc.boot() {
rc.mount_misc
rc.hostname
rc.modules
rc.services_start
wait
rc.motd
}
rc.halt() {
case "$action" in
poweroff|shutdown) echo 'o' > /proc/sysrq-trigger;;
halt) :;;
reboot|*) echo 'b' > /proc/sysrq-trigger;;
esac
}
rc.shutdown() {
rc.services_stop
rc.stop_everything
rc.unmount_everything
rc.remount_root
echo "Halt complete."
rc.halt
}
rc.hostname() {
[[ "$cfg_hostname" ]] && { hostname "$cfg_hostname"; }
}
rc.modules() {
for i in "${cfg_modules[@]}"; do
modprobe "$i"
done
}
rc.main() {
source "/etc/rc.conf"
action="${1:-boot}"
case "$action" in
boot)
echo "Welcome to `uname -rs`"
rc.boot
;;
poweroff|reboot|shutdown)
rc.shutdown
rc.halt
;;
esac
}
# Main part
rc.main "$@"

10
config.mk Normal file
View File

@ -0,0 +1,10 @@
# Make config
USR ?= /usr/local
ETC ?= /etc
BIN ?= $(USR)/bin
BASH_PATH ?= /bin/bash
BINDIR = $(DESTDIR)$(PREFIX)$(BIN)
ETCDIR = $(DESTDIR)$(PREFIX)$(ETC)

View File

@ -1,15 +0,0 @@
# System-wide configuration
export PATH='/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin'
# Hostname
cfg_hostname='changeme'
# Services
cfg_services+=( 'fsck' 'mount' 'systemd-udevd' 'sysctl' 'rc.local' )
cfg_services+=( agetty-tty{2..6} ) # Comment this if your init starts something on the ttys itself
cfg_services+=( '@crond' '@network' '@dbus' '@alsa' ) # These start in parallel
cfg_modules=( ) # Add modules you want to be loaded at boot time here
# Make C-A-D perform a soft reset
ctrlaltdel soft

48
rc.conf Normal file
View File

@ -0,0 +1,48 @@
# A default PATH
export PATH='/usr/local/bin:/usr/local/sbin:/usr/bin'
# Locale
export LC_ALL='en_US.UTF-8'
# Hostname
cfg_hostname='spark'
# Timezone
# Uncomment and change this to yours
#cfg_timezone='Europe/Moscow'
# Early fsck, if you don't have such a step in your initrd
cfg_early_fsck=1
# Services that start with @ are executed in parallel
cfg_services+=(
'mount' 'sysctl' 'rsyslogd'
'@lo.iface' '@scron' @agetty-tty{2..6}
)
# Uncomment and add modules you want to be loaded at boot time here
#cfg_modules=( )
# Make C-A-D perform a soft reset
ctrlaltdel soft
# Virtual filesystems
cfg_mounts=(
'run:tmpfs:/run'
'tmp:tmpfs:/tmp'
'proc:proc:/proc:defaults,hidepid=2'
'sys:sysfs:/sys'
'dev:devtmpfs:/dev'
'pts:devpts:/dev/pts:noexec,nosuid,gid=5,mode=0620'
'mqueue:mqueue:/dev/mqueue:noexec,nosuid,nodev'
'shm:tmpfs:/dev/shm:defaults,mode=0777'
)
# Some temporary directories and files
cfg_tmpdirs+=( '/run/lock' '/run/lock/lvm' '/run/lvm' '/run/user' )
cfg_tmpfiles+=( '/run/utmp' )
# How long do we wait for all processes to die nicely?
cfg_killall5_timeout=30

222
rc.in Normal file
View File

@ -0,0 +1,222 @@
#!@BASH_PATH@
# vim: ft=zsh
# Functions
rc.rescue() { exec "${cfg_rc_rescue_shell:-"$SHELL"}"; }
rc.motd() {
[[ -f "/etc/rc.motd" ]] && {
while read; do
printf "%s\n" "$REPLY"
done < "/etc/rc.motd"
}
return 0
}
rc.tmpfiles() {
printf '%s\n' "${cfg_tmpdirs[@]}" | while IFS=':' read dir perm own grp; do
mkdir -pm "${perm:-755}" "$dir"
chown -c "${own:-root}:${grp:-root}" "$dir"
done
printf '%s\n' "${cfg_tmpfiles[@]}" | while IFS=':' read file perm own grp; do
> "$file"
chmod -c "${perm:-644}" "$file"
chown -c "${own:-root}:${grp:-root}" "$file"
done
}
rc.mount() {
for fs in "${cfg_mounts[@]}"; do
echo "$fs" | while IFS=':' read device fs_type mountpoint mount_options; do
if mountpoint -q "$mountpoint"; then
if [[ "$mount_options" ]]; then
mount -o "remount,$mount_options" "$mountpoint"
fi
else
if ! [[ -d "$mountpoint" ]]; then
mkdir -p "$mountpoint"
fi
if ! [[ "$mount_options" ]]; then
mount_options='defaults'
fi
mount "$device" -n -t "$fs_type" -o "$mount_options" "$mountpoint"
fi
done
done
}
rc.parse_cmdline() {
[[ -f "/proc/cmdline" ]] && {
boot_cmdline=( $(</proc/cmdline) )
}
for i in "${boot_cmdline[@]}"; do
case "$i" in
init.single) rc.rescue;;
esac
done
}
rc.services_start() {
local service_name start_mode
for i in "${cfg_services[@]}"; do
unset service_name
[[ "$i" =~ ^@ ]] && {
service_name="${i##*@}"
start_mode='bg'
}
[[ "$i" =~ ^% ]] && {
service_name="${i##*%}"
start_mode='watch'
}
service_name=${service_name:-$i}
start_mode="${start_mode:-start}"
case "$start_mode" in
bg) service "$service_name" start &;;
start) service "$service_name" start;;
*) echo "Mode $start_mode not supported";;
esac
done
}
rc.services_stop() {
echo "Stopping services..."
local service_name
for i in "${cfg_services[@]}"; do
service_name="${i##*@}"; service_name="${service_name##*%}"
service "$service_name" stop &>/dev/null &
done
wait
}
rc.stop_everything() {
echo "Politely asking all processes to shut down..."
killall5 -s 15 -w "$cfg_killall5_timeout"
echo "Killing the remaning ones..."
killall5 -s 9
}
rc.unmount_everything() {
echo "Unmounting filesystems..."
umount -r -a
}
rc.remount_root() {
echo "Remounting / read-only..."
mount / -o remount,ro
}
rc.boot() {
(( cfg_early_fsck )) && rc.fsck
rc.mount
rc.tmpfiles
rc.hostname
rc.timezone
rc.modules
rc.services_start
wait
rc.motd
}
rc.halt() {
if type -P halt &>/dev/null; then
function rc.halt_poweroff { halt -p; }
function rc.halt_reboot { halt -r; }
elif (( $(</proc/sys/kernel/sysrq) )); then
function rc.halt_poweroff { echo 'o' > /proc/sysrq-trigger; }
function rc.halt_reboot { echo 'b' > /proc/sysrq-trigger; }
else
printf 'Cannot halt, please install halt from suckless.org ubase or enable sysrq.\n'
return 1
fi
case "$action" in
halt) :;;
poweroff|shutdown) rc.halt_poweroff;;
reboot|*) rc.halt_reboot;;
esac
}
rc.sync() {
echo "Syncing disks."
sync
}
rc.shutdown() {
rc.services_stop
rc.stop_everything
rc.sync
rc.unmount_everything
rc.remount_root
echo "Halt complete."
rc.halt
}
rc.hostname() {
[[ -f '/etc/hostname' ]] && { hostname "$(</etc/hostname)"; }
[[ "$cfg_hostname" ]] && { hostname "$cfg_hostname"; }
}
rc.modules() {
for i in "${cfg_modules[@]}"; do
modprobe "$i"
done
}
rc.timezone() {
[[ "$cfg_timezone" ]] && {
ln -fs "/usr/share/zoneinfo/${cfg_timezone}" /etc/localtime
}
}
rc.fsck() {
declare root_rw=0
touch /rc-write-test && root_rw=1
(( root_rw )) && mount -o remount,ro /
fsck -A -C -p
(( root_rw )) && mount -o remount,rw /
}
rc.main() {
source "@ETC@/rc.conf"
# Default XDG_RUNTIME_DIR for all non-system users
# rtkit:x:133:133:RealtimeKit:/proc:/sbin/nologin
# Also add one for root
cfg_tmpdirs+=( "/run/user/0:700:0:0" )
while IFS=':' read -r _ _ uid gid _; do
if (( uid >= 1000 )); then
cfg_tmpdirs+=( "/run/user/$uid:700:$uid:$gid" )
fi
done < /etc/passwd
action="${1:-boot}"
case "$action" in
boot)
echo "Welcome to $(uname -rs)"
rc.boot
;;
poweroff|reboot|shutdown|halt)
rc.shutdown
;;
esac
}
# Main part
rc.main "$@"

1
rc.motd Normal file
View File

@ -0,0 +1 @@
Boot finished. Switch to tty2 to login.

29
tools/Makefile Normal file
View File

@ -0,0 +1,29 @@
# spark-rc tools makefile
# Please modify config.mk and not this
sinclude ../config.mk
.PHONY: clean install uninstall all
build: killall5
all: build
killall5: killall5.in
sed -r \
-e 's%@BASH_PATH@%$(BASH_PATH)%' \
killall5.in > killall5
chmod 750 $@
clean:
rm killall5
install: build
install -dm755 $(BINDIR)
install -dm755 $(ETCDIR)
install -m750 killall5 $(BINDIR)/killall5
uninstall:
rm $(BINDIR)/killall5

98
tools/killall5.in Normal file
View File

@ -0,0 +1,98 @@
#!@BASH_PATH@
# A simple reimplementation of killall5 from sysvinit-tools
get_my_tree() {
local my_pid
read my_pid garbage < "/proc/self/stat"
child="$my_pid"
while [[ "$parent" != 1 ]]; do
read a b c parent d < "/proc/$child/stat";
child="$parent"
echo "$parent"
done
}
get_all_procs() {
local processlist
for i in /proc/*/exe; do
process_dir="${i%/*}"
process_pid="${process_dir##*/}"
readlink -e "$i" &>/dev/null && {
echo "$process_pid"
}
done
}
get_procs_to_kill() {
for i in "${all_procs[@]}"; do
unset skip
for p in "${my_tree[@]}"; do
[[ "$i" == "$p" ]] && { skip=1; }
done
[[ "$skip" ]] || { echo "$i"; }
done
}
pids_exist() {
for i in "$@"; do
if [[ -d "/proc/$i" ]]; then
return 0
fi
done
return 1
}
pid_wait() {
declare counter
while pids_exist "$@"; do
if (( counter == timeout )); then
return 1
fi
sleep 1
(( counter++ ))
done
}
main() {
timeout=30
signal=15
while (( $# )); do
case $1 in
-w)
flag_wait=1
timeout=$2
shift
;;
-s)
signal=$2
shift
;;
esac
shift
done
my_tree=( $(get_my_tree) self thread-self )
all_procs=( $(get_all_procs) )
procs_to_kill=( $(get_procs_to_kill) )
kill -n "$signal" "${procs_to_kill[@]}" 2>/dev/null
if (( flag_wait )); then
pid_wait "${procs_to_kill[@]}"
fi
return 0
}
main "$@"