aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2008-11-03 15:31:01 +0000
committerRoy Marples <roy@marples.name>2008-11-03 15:31:01 +0000
commit0af7d5bc204cd6b7d03f22aacf4072c5f526c0ee (patch)
treeaa819c4140f8c34bd3814ae5894a8b6214fff914
parent895c4f41492199d6aee75bb6c5a935134d67c29e (diff)
Add a new shutdown runlevel, Gentoo #224537.
Split halt.sh into halt, killprocs, romount and savecache services. The reboot runlevel is removed but mapped to shutdown. The halt script should be moved to the sysvinit package.
-rw-r--r--etc/Makefile2
-rw-r--r--init.d/.gitignore5
-rw-r--r--init.d/Makefile4
-rw-r--r--init.d/Makefile.Linux8
-rw-r--r--init.d/halt.in23
-rw-r--r--init.d/halt.sh.in112
-rw-r--r--init.d/killprocs.in15
-rw-r--r--init.d/romount.in43
-rw-r--r--init.d/savecache.in25
-rw-r--r--man/rc.84
-rw-r--r--runlevels/Makefile10
-rw-r--r--runlevels/Makefile.Linux4
-rw-r--r--sh/init-common-post.sh.in12
-rw-r--r--sh/init.sh.BSD.in21
-rw-r--r--sh/init.sh.Linux.in30
-rw-r--r--src/librc/librc-depend.c6
-rw-r--r--src/librc/rc.h.in1
-rw-r--r--src/rc/rc.c79
-rw-r--r--src/rc/runscript.c5
19 files changed, 199 insertions, 210 deletions
diff --git a/etc/Makefile b/etc/Makefile
index 8b43544c..ee1642e8 100644
--- a/etc/Makefile
+++ b/etc/Makefile
@@ -1,6 +1,8 @@
DIR= ${SYSCONFDIR}
CONF= rc.conf
+CLEANFILES+= rc.conf
+
MK= ../mk
include ${MK}/os.mk
include Makefile.${OS}
diff --git a/init.d/.gitignore b/init.d/.gitignore
index d7322d68..dace4de5 100644
--- a/init.d/.gitignore
+++ b/init.d/.gitignore
@@ -2,12 +2,15 @@ bootmisc
devfs
dmesg
fsck
-halt.sh
+halt
hostname
+killprocs
local
localmount
netmount
+romount
root
+savecache
swap
sysctl
urandom
diff --git a/init.d/Makefile b/init.d/Makefile
index 07d41a10..fd2c87d1 100644
--- a/init.d/Makefile
+++ b/init.d/Makefile
@@ -1,6 +1,6 @@
DIR= ${INITDIR}
-SRCS= bootmisc.in fsck.in halt.sh.in hostname.in local.in localmount.in \
- netmount.in root.in swap.in sysctl.in urandom.in
+SRCS= bootmisc.in fsck.in hostname.in local.in localmount.in \
+ netmount.in root.in savecache.in swap.in sysctl.in urandom.in
BIN= ${OBJS}
INSTALLAFTER= _installafter
diff --git a/init.d/Makefile.Linux b/init.d/Makefile.Linux
index be519c80..1bf3fe70 100644
--- a/init.d/Makefile.Linux
+++ b/init.d/Makefile.Linux
@@ -1,7 +1,11 @@
NET_LO= net.lo
-SRCS+= devfs.in dmesg.in hwclock.in consolefont.in keymaps.in modules.in \
- mtab.in numlock.in procfs.in sysfs.in termencoding.in
+SRCS+= devfs.in dmesg.in hwclock.in consolefont.in keymaps.in killprocs.in \
+ modules.in mtab.in numlock.in procfs.in romount.in sysfs.in \
+ termencoding.in
+
+# This really belongs with sysvinit
+SRCS+= halt.in
.SUFFIXES: .Linux.in
.Linux.in:
diff --git a/init.d/halt.in b/init.d/halt.in
new file mode 100644
index 00000000..b8f9ed90
--- /dev/null
+++ b/init.d/halt.in
@@ -0,0 +1,23 @@
+#!@PREFIX@/sbin/runscript
+# Copyright 2007-2008 Roy Marples <roy@marples.name>
+# All rights reserved. Released under the 2-clause BSD license.
+
+# This script really belongs with the Linux sysvinit package
+
+depend()
+{
+ after *
+ use romount
+}
+
+start()
+{
+ case "${RUNLEVEL}" in
+ 0) runlevel=shutdown;;
+ 6) runlevel=reboot;;
+ *) eerror "Unknown runlevel ${RUNLEVEL}"; return 1
+ esac
+
+ . /etc/init.d/"${runlevel}".sh
+ return 0
+}
diff --git a/init.d/halt.sh.in b/init.d/halt.sh.in
deleted file mode 100644
index ab73d8df..00000000
--- a/init.d/halt.sh.in
+++ /dev/null
@@ -1,112 +0,0 @@
-#!@SHELL@
-# Copyright 2007-2008 Roy Marples <roy@marples.name>
-# All rights reserved. Released under the 2-clause BSD license.
-
-. @SYSCONFDIR@/init.d/functions.sh
-. "${RC_LIBDIR}"/sh/rc-functions.sh
-[ -r @SYSCONFDIR@/conf.d/localmount ] && . @SYSCONFDIR@/conf.d/localmount
-[ -r @SYSCONFDIR@/rc.conf ] && . @SYSCONFDIR@/rc.conf
-
-# Really kill things off before unmounting
-if [ -x /sbin/killall5 ]; then
- killall5 -15
- killall5 -9
-fi
-
-# Flush all pending disk writes now
-sync; sync
-
-# If we are in a VPS, we don't need anything below here, because
-# 1) we don't need (and by default can't) umount anything (VServer) or
-# 2) the host utils take care of all umounting stuff (OpenVZ)
-if [ "${RC_SYS}" = "VSERVER" -o "${RC_SYS}" = "OPENVZ" ]; then
- [ "${RC_SYS}" = "OPENVZ" -a "$1" = "reboot" ] && echo "" > /reboot
- if [ -e @SYSCONFDIR@/init.d/"$1".sh ]; then
- . @SYSCONFDIR@/init.d/"$1".sh
- else
- exit 0
- fi
-fi
-
-# If $svcdir is still mounted, preserve it if we can
-mnt=$(mountinfo --node "${RC_SVCDIR}")
-if [ -n "${mnt}" ] && \
- rm -rf "${RC_LIBDIR}/tmp.$$" && \
- mkdir -p "${RC_LIBDIR}/tmp.$$" 2>/dev/null \
-; then
- rmdir "${RC_LIBDIR}/tmp.$$"
- f_opts="-m -c"
- [ "${RC_UNAME}" = "Linux" ] && f_opts="-c"
- if type fuser >/dev/null 2>&1; then
- if [ -n "$(fuser ${f_opts} "${svcdir}" 2>/dev/null)" ]; then
- fuser -k ${f_opts} "${svcdir}" >/dev/null 2>&1
- sleep 2
- fi
- fi
- cp -p "${RC_SVCDIR}"/deptree "${RC_SVCDIR}"/depconfig \
- "${RC_SVCDIR}"/softlevel "${RC_SVCDIR}"/nettree \
- "${RC_SVCDIR}"/rc.log \
- "${RC_LIBDIR}" 2>/dev/null
- umount "${RC_SVCDIR}"
- rm -rf "${RC_SVCDIR}"/*
- # Pipe errors to /dev/null as we may have future timestamps
- cp -p "${RC_LIBDIR}"/deptree "${RC_LIBDIR}"/depconfig \
- "${RC_LIBDIR}"/softlevel "${RC_LIBDIR}"/nettree \
- "${RC_LIBDIR}"/rc.log \
- "${RC_SVCDIR}" 2>/dev/null
- rm -f "${RC_LIBDIR}"/deptree "${RC_LIBDIR}"/depconfig \
- "${RC_LIBDIR}"/softlevel "${RC_LIBDIR}"/nettree \
- "${RC_LIBDIR}"/rc.log
- # Release the memory disk if we used it
- case "${mnt}" in
- "/dev/md"[0-9]*) mdconfig -d -u "${mnt#/dev/md*}";;
- esac
-fi
-
-unmounted=0
-# Remount the remaining filesystems read-only
-# Most BSD's don't need this as the kernel handles it nicely
-if [ "${RC_UNAME}" = "Linux" ]; then
- ebegin "Remounting remaining filesystems read-only"
- # We need the do_unmount function
- . "${RC_LIBDIR}"/sh/rc-mount.sh
- eindent
- no_umounts_r="/dev|/dev/.*|${RC_SVCDIR}"
- # RC_NO_UMOUNTS is an env var that can be set by plugins
- OIFS=${IFS} SIFS=${IFS-y}
- IFS=$IFS:
- for x in ${no_umounts} ${RC_NO_UMOUNTS}; do
- no_umounts_r="${no_umounts_r}|${x}"
- done
- if [ "${SIFS}" = "y" ]; then
- IFS=$OIFS
- else
- unset IFS
- fi
- no_umounts_r="${no_umounts_r}|/proc|/proc/.*|/sys|/sys/.*"
- no_umounts_r="^(${no_umounts_r})$"
- fs=
- for x in ${net_fs_list}; do
- fs="${fs}${fs:+|}${x}"
- done
- [ -n "${fs}" ] && fs="^(${fs})$"
- do_unmount "mount -n -o remount,ro" \
- --skip-point-regex "${no_umounts_r}" \
- ${fs:+--skip-fstype-regex} ${fs} --nonetdev
- eoutdent
- eend $?
- unmounted=$?
-fi
-
-if [ ${unmounted} -ne 0 ]; then
- if [ -x /sbin/sulogin ]; then
- ewarn "$1 timeout in 30 seconds"
- sulogin -t 30 /dev/console
- fi
-fi
-
-# Load the final script - not needed on BSD so they should not exist
-[ -e @SYSCONFDIR@/init.d/"$1".sh ] && . @SYSCONFDIR@/init.d/"$1".sh
-
-# Always exit 0 here
-exit 0
diff --git a/init.d/killprocs.in b/init.d/killprocs.in
new file mode 100644
index 00000000..a969d52a
--- /dev/null
+++ b/init.d/killprocs.in
@@ -0,0 +1,15 @@
+#!@PREFIX@/sbin/runscript
+# Copyright 2007-2008 Roy Marples <roy@marples.name>
+# All rights reserved. Released under the 2-clause BSD license.
+
+start()
+{
+ ebegin "Terminating remaining processes"
+ killall5 -15
+ sleep 1
+ eend 0
+ ebegin "Killing remaining processes"
+ killall5 -9
+ sleep 1
+ eend 0
+}
diff --git a/init.d/romount.in b/init.d/romount.in
new file mode 100644
index 00000000..d1adaad2
--- /dev/null
+++ b/init.d/romount.in
@@ -0,0 +1,43 @@
+#!@PREFIX@/sbin/runscript
+# Copyright 2007-2008 Roy Marples <roy@marples.name>
+# All rights reserved. Released under the 2-clause BSD license.
+
+depend()
+{
+ need killprocs savecache
+ keywords noopenvz novserver
+}
+
+start()
+{
+ # Flush all pending disk writes now
+ sync; sync
+
+ ebegin "Remounting remaining filesystems read-only"
+ # We need the do_unmount function
+ . "${RC_LIBDIR}"/sh/rc-mount.sh
+ eindent
+ local m="/dev|/dev/.*|/proc|/proc.*|/sys|/sys/.*|${RC_SVCDIR}" x= fs=
+ # RC_NO_UMOUNTS is an env var that can be set by plugins
+ local OIFS=$IFS SIFS=${IFS-y} IFS=$IFS
+ IFS=$IFS:
+ for x in ${no_umounts} ${RC_NO_UMOUNTS}; do
+ m="${m}|${x}"
+ done
+ if [ "${SIFS}" = y ]; then
+ IFS=$OIFS
+ else
+ unset IFS
+ fi
+ m="^(${m})$"
+ fs=
+ for x in ${net_fs_list}; do
+ fs="${fs}${fs:+|}${x}"
+ done
+ [ -n "${fs}" ] && fs="^(${fs})$"
+ do_unmount "mount -n -o remount,ro" \
+ --skip-point-regex "${m}" \
+ ${fs:+--skip-fstype-regex} ${fs} --nonetdev
+ eoutdent
+ eend $?
+}
diff --git a/init.d/savecache.in b/init.d/savecache.in
new file mode 100644
index 00000000..57ed50ce
--- /dev/null
+++ b/init.d/savecache.in
@@ -0,0 +1,25 @@
+#!@PREFIX@/sbin/runscript
+# Copyright 2007-2008 Roy Marples <roy@marples.name>
+# All rights reserved. Released under the 2-clause BSD license.
+
+description="Saves the caches OpenRC uses to non volatile storage"
+
+start()
+{
+ ebegin "Saving dependency cache"
+ if [ ! -d "${RC_LIBDIR}"/cache ]; then
+ rm -rf "${RC_LIBDIR}"/cache
+ if ! mkdir "${RC_LIBDIR}"/cache; then
+ eend $?
+ return $?
+ fi
+ fi
+ local save=
+ for x in deptree depconfig softlevel nettree rc.log; do
+ [ -e "${RC_SVCDIR}/${x}" ] && save="${save} ${RC_SVCDIR}/${x}"
+ done
+ if [ -n "${save}" ]; then
+ cp -p ${save} "${RC_LIBDIR}"/cache 2>/devnull
+ fi
+ eend $?
+}
diff --git a/man/rc.8 b/man/rc.8
index e0e31987..d4609eee 100644
--- a/man/rc.8
+++ b/man/rc.8
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd October 27, 2008
+.Dd November 03, 2008
.Dt RC 8 SMM
.Os OpenRC
.Sh NAME
@@ -65,8 +65,6 @@ All services in the boot and sysinit runlevels are automatically included
in all other runlevels except for those listed here.
.It Ar single
Stops all services except for those in the sysinit runlevel.
-.It Ar reboot
-Changes to the single runlevel and then reboots the host.
.It Ar shutdown
Changes to the single runlevel and then halts the host.
.El
diff --git a/runlevels/Makefile b/runlevels/Makefile
index 9e3131a9..b8a830af 100644
--- a/runlevels/Makefile
+++ b/runlevels/Makefile
@@ -1,11 +1,13 @@
BOOT= bootmisc fsck hostname localmount \
root swap sysctl urandom
DEFAULT= local netmount
+SHUTDOWN= savecache
LEVELDIR= ${DESTDIR}/${SYSCONFDIR}/runlevels
SYSINITDIR= ${LEVELDIR}/sysinit
BOOTDIR= ${LEVELDIR}/boot
DEFAULTDIR= ${LEVELDIR}/default
+SHUTDOWNDIR= ${LEVELDIR}/shutdown
INITDIR= ../init.d
@@ -44,6 +46,14 @@ install:
fi; \
ln -snf ${PREFIX}/etc/init.d/"$$x" ${DEFAULTDIR}/"$$x" || exit $$?; done \
fi
+ if ! test -d "${SHUTDOWNDIR}"; then \
+ ${INSTALL} -d ${SHUTDOWNDIR} || exit $$?; \
+ for x in ${SHUTDOWN}; do \
+ if test -n "${PREFIX}"; then \
+ grep -q "keyword .*noprefix" ${INITDIR}/"$$x" && continue; \
+ fi; \
+ ln -snf ${PREFIX}/etc/init.d/"$$x" ${SHUTDOWNDIR}/"$$x" || exit $$?; done \
+ fi
check test::
diff --git a/runlevels/Makefile.Linux b/runlevels/Makefile.Linux
index c5649b20..8e086aaf 100644
--- a/runlevels/Makefile.Linux
+++ b/runlevels/Makefile.Linux
@@ -1,2 +1,6 @@
SYSINIT+= devfs dmesg
BOOT+= hwclock keymaps modules mtab net.lo procfs termencoding
+SHUTDOWN+= killprocs romount
+
+# This really belongs with sysvinit
+SHUTDOWN+= halt
diff --git a/sh/init-common-post.sh.in b/sh/init-common-post.sh.in
index 2b1641df..aa264aa3 100644
--- a/sh/init-common-post.sh.in
+++ b/sh/init-common-post.sh.in
@@ -9,17 +9,15 @@ retval=0
RC_SVCDIR=${RC_SVCDIR:-/@LIB@/rc/init.d}
if [ "${RC_SVCDIR}" != "/" ] && mkdir "${RC_SVCDIR}/.test.$$" 2>/dev/null; then
rmdir "${RC_SVCDIR}/.test.$$"
- for x in ${RC_SVCDIR}/*; do
- [ -e "${x}" ] || continue
- case ${x##*/} in
- depconfig|deptree|ksoftlevel|rc.log);;
- *) rm -rf "${x}";;
- esac
- done
+ rm -rf "${RC_SVCDIR}"/*
else
mount_svcdir
retval=$?
fi
+if [ -e "${RC_LIBDIR}"/cache/deptree ]; then
+ cp -p "${RC_LIBDIR}"/cache/* "${RC_SVCDIR}" 2>/dev/null
+fi
+
echo "sysinit" > "${RC_SVCDIR}/softlevel"
exit ${retval}
diff --git a/sh/init.sh.BSD.in b/sh/init.sh.BSD.in
index dbff7368..652a3de2 100644
--- a/sh/init.sh.BSD.in
+++ b/sh/init.sh.BSD.in
@@ -10,18 +10,6 @@
# FreeBSD-7 supports tmpfs now :)
mount_svcdir()
{
- local dotmp=false release=false retval=0
- if [ -e "${RC_SVCDIR}"/deptree ]; then
- dotmp=true
- if ! mount -t tmpfs none "${RC_LIBDIR}"/tmp 2>/dev/null; then
- mdconfig -a -t malloc -s 1m -u 1
- newfs /dev/md1
- mount /dev/md1 "${RC_LIBDIR}"/tmp
- release=true
- fi
- cp -p "${RC_SVCDIR}"/deptree "${RC_SVCDIR}"/depconfig \
- "${RC_SVCDIR}"/nettree "${RC_LIBDIR}"/tmp 2>/dev/null
- fi
if ! fstabinfo --mount "${RC_SVCDIR}"; then
if ! mount -t tmpfs -o rw,noexec,nosuid none "${RC_SVCDIR}" 2>/dev/null; then
mdconfig -a -t malloc -s "${rc_svcsize:-1024}"k -u 0
@@ -29,15 +17,6 @@ mount_svcdir()
mount -o rw,noexec,nosuid /dev/md0 "${RC_SVCDIR}"
fi
fi
- retval=$?
- if ${dotmp}; then
- cp -p "${RC_LIBDIR}"/tmp/deptree "${RC_LIBDIR}"/tmp/depconfig \
- "${RC_LIBDIR}"/tmp/nettree "${RC_SVCDIR}" 2>/dev/null
- umount "${RC_LIBDIR}"/tmp
- ${release} && mdconfig -d -u 1
- fi
-
- return ${retval}
}
. "${RC_LIBDIR}"/sh/functions.sh
diff --git a/sh/init.sh.Linux.in b/sh/init.sh.Linux.in
index 6d99d49e..f38fe4e0 100644
--- a/sh/init.sh.Linux.in
+++ b/sh/init.sh.Linux.in
@@ -3,14 +3,13 @@
# Copyright 2007-2008 Roy Marples <roy@marples.name>
# All rights reserved. Released under the 2-clause BSD license.
-# This basically mounts $RC_SVCDIR as a ramdisk, but preserving its content
-# which allows us to store service state and generate dependencies if needed.
+# This basically mounts $RC_SVCDIR as a ramdisk.
# The tricky part is finding something our kernel supports
# tmpfs and ramfs are easy, so force one or the other.
mount_svcdir()
{
local fs= fsopts="-o rw,noexec,nodev,nosuid"
- local devdir="rc-svcdir" devtmp="none" x=
+ local devdir="rc-svcdir" x=
local svcsize=${rc_svcsize:-1024}
if grep -Eq "[[:space:]]+tmpfs$" /proc/filesystems; then
@@ -19,41 +18,24 @@ mount_svcdir()
elif grep -Eq "[[:space:]]+ramfs$" /proc/filesystems; then
fs="ramfs"
# ramfs has no special options
- elif [ -e /dev/ram0 -a -e /dev/ram1 ] \
+ elif [ -e /dev/ram0 ] \
&& grep -Eq "[[:space:]]+ext2$" /proc/filesystems; then
devdir="/dev/ram0"
- devtmp="/dev/ram1"
fs="ext2"
- for x in ${devdir} ${devtmp}; do
- dd if=/dev/zero of="${x}" bs=1k count="${svcsize}"
- mkfs -t "${fs}" -i 1024 -vm0 "${x}" "${svcsize}"
- done
+ dd if=/dev/zero of="${devdir}" bs=1k count="${svcsize}"
+ mkfs -t "${fs}" -i 1024 -vm0 "${devdir}" "${svcsize}"
else
echo
- eerror "OpenRC requires tmpfs, ramfs or 2 ramdisks + ext2"
+ eerror "OpenRC requires tmpfs, ramfs or a ramdisk + ext2"
eerror "compiled into the kernel"
echo
return 1
fi
- local dotmp=false
- if [ -e "${RC_SVCDIR}"/deptree ]; then
- dotmp=true
- mount -n -t "${fs}" -o rw "${devtmp}" "${RC_LIBDIR}"/tmp
- cp -p "${RC_SVCDIR}"/deptree "${RC_SVCDIR}"/depconfig \
- "${RC_SVCDIR}"/nettree "${RC_LIBDIR}"/tmp 2>/dev/null
- fi
-
# If we have no entry in fstab for $RC_SVCDIR, provide our own
if ! fstabinfo --mount "${RC_SVCDIR}"; then
mount -n -t "${fs}" ${fsopts} "${devdir}" "${RC_SVCDIR}"
fi
-
- if ${dotmp}; then
- cp -p "${RC_LIBDIR}"/tmp/deptree "${RC_LIBDIR}"/tmp/depconfig \
- "${RC_LIBDIR}"/tmp/nettree "${RC_SVCDIR}" 2>/dev/null
- umount -n "${RC_LIBDIR}"/tmp
- fi
}
. /etc/init.d/functions.sh
diff --git a/src/librc/librc-depend.c b/src/librc/librc-depend.c
index 739e6fc1..2c05ea1e 100644
--- a/src/librc/librc-depend.c
+++ b/src/librc/librc-depend.c
@@ -189,7 +189,8 @@ valid_service(const char *runlevel, const char *service, const char *type)
if (rc_service_in_runlevel(service, runlevel))
return true;
- if (strcmp(runlevel, RC_LEVEL_SYSINIT) != 0 &&
+ if (strcmp(runlevel, RC_LEVEL_SHUTDOWN) != 0 &&
+ strcmp(runlevel, RC_LEVEL_SYSINIT) != 0 &&
strcmp(runlevel, bootlevel) != 0)
{
if (rc_service_in_runlevel(service, bootlevel))
@@ -499,8 +500,7 @@ rc_deptree_order(const RC_DEPTREE *deptree, const char *runlevel, int options)
/* When shutting down, list all running services */
if (strcmp(runlevel, RC_LEVEL_SINGLE) == 0 ||
- strcmp(runlevel, RC_LEVEL_SHUTDOWN) == 0 ||
- strcmp(runlevel, RC_LEVEL_REBOOT) == 0)
+ strcmp(runlevel, RC_LEVEL_SHUTDOWN) == 0)
{
list = rc_services_in_state(RC_SERVICE_STARTED);
list2 = rc_services_in_state(RC_SERVICE_INACTIVE);
diff --git a/src/librc/rc.h.in b/src/librc/rc.h.in
index 92fb19c7..6f7c64e0 100644
--- a/src/librc/rc.h.in
+++ b/src/librc/rc.h.in
@@ -70,7 +70,6 @@ typedef TAILQ_HEAD(rc_stringlist, rc_string) RC_STRINGLIST;
#define RC_LEVEL_SYSINIT "sysinit"
#define RC_LEVEL_SINGLE "single"
#define RC_LEVEL_SHUTDOWN "shutdown"
-#define RC_LEVEL_REBOOT "reboot"
/*! Return the current runlevel.
* @return the current runlevel */
diff --git a/src/rc/rc.c b/src/rc/rc.c
index a6cde112..995cc910 100644
--- a/src/rc/rc.c
+++ b/src/rc/rc.c
@@ -831,6 +831,11 @@ main(int argc, char **argv)
}
newlevel = argv[optind++];
+ /* For compat with old system */
+ if (newlevel) {
+ if (strcmp(newlevel, "reboot") == 0)
+ newlevel = UNCONST(RC_LEVEL_SHUTDOWN);
+ }
/* Enable logging */
setenv("EINFO_LOG", "rc", 1);
@@ -875,8 +880,7 @@ main(int argc, char **argv)
set_krunlevel(NULL);
if (newlevel &&
- (strcmp(newlevel, RC_LEVEL_REBOOT) == 0 ||
- strcmp(newlevel, RC_LEVEL_SHUTDOWN) == 0 ||
+ (strcmp(newlevel, RC_LEVEL_SHUTDOWN) == 0 ||
strcmp(newlevel, RC_LEVEL_SINGLE) == 0))
{
going_down = true;
@@ -887,9 +891,9 @@ main(int argc, char **argv)
#ifdef __FreeBSD__
/* FIXME: we shouldn't have todo this */
- /* For some reason, wait_for_services waits for the logger proccess
- * to finish as well, but only on FreeBSD. We cannot allow this so
- * we stop logging now. */
+ /* For some reason, wait_for_services waits for the logger
+ * proccess to finish as well, but only on FreeBSD.
+ * We cannot allow this so we stop logging now. */
rc_logger_close();
#endif
@@ -944,29 +948,30 @@ main(int argc, char **argv)
}
/* Load our list of hotplugged services */
- hotplugged_services = rc_services_in_state(RC_SERVICE_HOTPLUGGED);
- if (!going_down ||
- strcmp(newlevel ? newlevel : runlevel, RC_LEVEL_SINGLE) == 0)
- start_services = rc_services_in_runlevel(RC_LEVEL_SYSINIT);
- if (!going_down &&
+ start_services = rc_services_in_runlevel(newlevel ?
+ newlevel : runlevel);
+ if (strcmp(newlevel ? newlevel : runlevel, RC_LEVEL_SHUTDOWN) != 0 &&
strcmp(newlevel ? newlevel : runlevel, RC_LEVEL_SYSINIT) != 0)
{
- /* We need to include the boot runlevel services */
- tmplist = rc_services_in_runlevel(bootlevel);
+ tmplist = rc_services_in_runlevel(RC_LEVEL_SYSINIT);
TAILQ_CONCAT(start_services, tmplist, entries);
free(tmplist);
- if (strcmp (newlevel ? newlevel : runlevel, bootlevel) != 0) {
- tmplist = rc_services_in_runlevel(newlevel ?
- newlevel : runlevel);
- TAILQ_CONCAT(start_services, tmplist, entries);
- free(tmplist);
- }
-
- if (hotplugged_services) {
- if (!start_services)
- start_services = rc_stringlist_new();
- TAILQ_FOREACH(service, hotplugged_services, entries)
- rc_stringlist_addu(start_services, service->value);
+ if (strcmp(newlevel ? runlevel : runlevel,
+ RC_LEVEL_SINGLE) != 0)
+ {
+ if (strcmp(newlevel ? newlevel : runlevel,
+ bootlevel) != 0)
+ {
+ tmplist = rc_services_in_runlevel(bootlevel);
+ TAILQ_CONCAT(start_services, tmplist, entries);
+ free(tmplist);
+ }
+ if (hotplugged_services) {
+ TAILQ_FOREACH(service, hotplugged_services,
+ entries)
+ rc_stringlist_addu(start_services,
+ service->value);
+ }
}
}
@@ -994,15 +999,12 @@ main(int argc, char **argv)
setenv("RC_RUNLEVEL", runlevel, 1);
}
- /* Run the halt script if needed */
- if (strcmp(runlevel, RC_LEVEL_SHUTDOWN) == 0 ||
- strcmp(runlevel, RC_LEVEL_REBOOT) == 0)
- {
+#ifdef __linux__
+ /* We can't log beyond this point as the shutdown runlevel
+ * will mount / readonly. */
+ if (strcmp(runlevel, RC_LEVEL_SHUTDOWN) == 0)
rc_logger_close();
- execl(HALTSH, HALTSH, runlevel, (char *) NULL);
- eerrorx("%s: unable to exec `%s': %s",
- applet, HALTSH, strerror(errno));
- }
+#endif
mkdir(RC_STARTING, 0755);
rc_plugin_run(RC_HOOK_RUNLEVEL_START_IN, runlevel);
@@ -1064,5 +1066,18 @@ main(int argc, char **argv)
if (regen && strcmp(runlevel, bootlevel) == 0)
unlink(RC_DEPTREE_CACHE);
+#ifdef __linux__
+ /* Run our halt script if it exists
+ * We only do this for compat with Gentoo sysvinit which
+ * should run halt.sh itself. */
+ if (exists(HALTSH)) {
+ if (strcmp(runlevel, RC_LEVEL_SHUTDOWN) == 0) {
+ execl(HALTSH, HALTSH, (char *) NULL);
+ eerrorx("%s: unable to exec `%s': %s",
+ applet, HALTSH, strerror(errno));
+ }
+ }
+#endif
+
return EXIT_SUCCESS;
}
diff --git a/src/rc/runscript.c b/src/rc/runscript.c
index 4fc12bfe..d0557307 100644
--- a/src/rc/runscript.c
+++ b/src/rc/runscript.c
@@ -519,6 +519,9 @@ svc_exec(const char *arg1, const char *arg2)
}
execok = rc_waitpid(service_pid) == 0 ? true : false;
+ if (!execok && errno == ECHILD)
+ /* killall5 -9 could cause this */
+ execok = true;
service_pid = 0;
return execok;
@@ -1009,8 +1012,6 @@ svc_stop(bool deps)
(strcmp(runlevel,
RC_LEVEL_SHUTDOWN) == 0 ||
strcmp(runlevel,
- RC_LEVEL_REBOOT) == 0 ||
- strcmp(runlevel,
RC_LEVEL_SINGLE) == 0))
continue;
rc_service_mark(service, RC_SERVICE_FAILED);