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.
This commit is contained in:
parent
895c4f4149
commit
0af7d5bc20
@ -1,6 +1,8 @@
|
||||
DIR= ${SYSCONFDIR}
|
||||
CONF= rc.conf
|
||||
|
||||
CLEANFILES+= rc.conf
|
||||
|
||||
MK= ../mk
|
||||
include ${MK}/os.mk
|
||||
include Makefile.${OS}
|
||||
|
5
init.d/.gitignore
vendored
5
init.d/.gitignore
vendored
@ -2,12 +2,15 @@ bootmisc
|
||||
devfs
|
||||
dmesg
|
||||
fsck
|
||||
halt.sh
|
||||
halt
|
||||
hostname
|
||||
killprocs
|
||||
local
|
||||
localmount
|
||||
netmount
|
||||
romount
|
||||
root
|
||||
savecache
|
||||
swap
|
||||
sysctl
|
||||
urandom
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
23
init.d/halt.in
Normal file
23
init.d/halt.in
Normal file
@ -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
|
||||
}
|
@ -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
|
15
init.d/killprocs.in
Normal file
15
init.d/killprocs.in
Normal file
@ -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
|
||||
}
|
43
init.d/romount.in
Normal file
43
init.d/romount.in
Normal file
@ -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 $?
|
||||
}
|
25
init.d/savecache.in
Normal file
25
init.d/savecache.in
Normal file
@ -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 $?
|
||||
}
|
4
man/rc.8
4
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
|
||||
|
@ -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::
|
||||
|
||||
|
@ -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
|
||||
|
@ -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}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
79
src/rc/rc.c
79
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;
|
||||
}
|
||||
|
@ -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;
|
||||
@ -1008,8 +1011,6 @@ svc_stop(bool deps)
|
||||
if (runlevel &&
|
||||
(strcmp(runlevel,
|
||||
RC_LEVEL_SHUTDOWN) == 0 ||
|
||||
strcmp(runlevel,
|
||||
RC_LEVEL_REBOOT) == 0 ||
|
||||
strcmp(runlevel,
|
||||
RC_LEVEL_SINGLE) == 0))
|
||||
continue;
|
||||
|
Loading…
x
Reference in New Issue
Block a user