Well, since I am not sure my Solaris 10 variant of the patch works properly 
with recent Solarises (last patch revision was 5 years ago), here's the patched 
script back from Solaris 8 (yes, we have such boxes too). The two blocks of 
added lines are prefixes with exclamations, as asked:

===
[root@sol8 /]# cat /etc/rc0
#!/sbin/sh
#
# Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T.
# All rights reserved.
#
# THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
# The copyright notice above does not evidence any
# actual or intended publication of such source code.
#
# Copyright (c) 1997-1999 by Sun Microsystems, Inc.
# All rights reserved.
#
#ident  "@(#)rc0.sh     1.21    99/04/09 SMI"

# "Run Commands" for init states 0, 5 and 6.

PATH=/usr/sbin:/usr/bin

!# File used by NUT if shutting down because of UPS event
!UPSFLAG=/etc/ups/killpower
!# How long we wait after halt before reboot
!UPSWAIT=600
!# Flag used by us to trigger waiting
!_UPSPOWERDOWN=0

echo 'The system is coming down.  Please wait.'
![ -f "$UPSFLAG" ] && _UPSPOWERDOWN=1
![ x"$_UPSPOWERDOWN" = x1 ] && echo "UPS powering off, will wait and reboot in 
the end"

# Make sure /usr is mounted before proceeding since init scripts
# and this shell depend on things on /usr file system

/sbin/mount /usr >/dev/null 2>&1

# Export boot parameters to rc scripts

set -- `/usr/bin/who -r`

_INIT_RUN_LEVEL="$7"    # Current run-level
_INIT_RUN_NPREV="$8"    # Number of times previously at current run-level
_INIT_PREV_LEVEL="$9"   # Previous run-level

set -- `/usr/bin/uname -a`

_INIT_UTS_SYSNAME="$1"  # Operating system name (uname -s)
_INIT_UTS_NODENAME="$2" # Node name (uname -n)
_INIT_UTS_RELEASE="$3"  # Operating system release (uname -r)
_INIT_UTS_VERSION="$4"  # Operating system version (uname -v)
_INIT_UTS_MACHINE="$5"  # Machine class (uname -m)
_INIT_UTS_ISA="$6"      # Instruction set architecture (uname -p)
_INIT_UTS_PLATFORM="$7" # Platform string (uname -i)

export _INIT_RUN_LEVEL _INIT_RUN_NPREV _INIT_PREV_LEVEL \
    _INIT_UTS_SYSNAME _INIT_UTS_NODENAME _INIT_UTS_RELEASE _INIT_UTS_VERSION \
    _INIT_UTS_MACHINE _INIT_UTS_ISA _INIT_UTS_PLATFORM

# The following segment is for historical purposes.
# There should be nothing in /etc/shutdown.d.

if [ -d /etc/shutdown.d ]; then
        for f in /etc/shutdown.d/*; do
                [ -s $f ] && /sbin/sh $f
        done
fi

# End of historical section

if [ -d /etc/rc0.d ]; then
        for f in /etc/rc0.d/K*; do
                if [ -s $f ]; then
                        case $f in
                                *.sh)   .        $f ;;
                                *)      /sbin/sh $f stop ;;
                        esac
                fi
        done

        # System cleanup functions ONLY (things that end fast!) 

        for f in /etc/rc0.d/S*; do
                if [ -s $f ]; then
                        case $f in
                                *.sh)   .        $f ;;
                                *)      /sbin/sh $f start ;;
                        esac
                fi
        done
fi

[ -f /etc/.dynamic_routing ] && /usr/bin/rm -f /etc/.dynamic_routing

trap "" 15

# Kill all processes, first gently, then with prejudice.

/usr/sbin/killall
/usr/bin/sleep 5
/usr/sbin/killall 9
/usr/bin/sleep 10
[ -x /usr/lib/acct/closewtmp ] && /usr/lib/acct/closewtmp
/sbin/sync; /sbin/sync; /sbin/sync

# Unmount file systems. /usr, /var, /var/adm, /var/run are not unmounted by
# umountall because they are mounted by rcS (for single user mode) rather than
# mountall. If this is changed, mountall, umountall and rcS should also change.

/sbin/umountall
/sbin/umount /var/adm >/dev/null 2>&1
/sbin/umount /var/run >/dev/null 2>&1
/sbin/umount /var >/dev/null 2>&1
/sbin/umount /usr >/dev/null 2>&1

echo 'The system is down.'
!
!if [ x"$_UPSPOWERDOWN" = x1 -a -x /etc/ups/reboot ]; then
!        echo "Counting down to restart in case UPS line power is back: waiting 
$UPSWAIT sec"
!        sleep "$UPSWAIT"
!        ( echo "Syncing disks..."; /sbin/sync ) &
!        sleep 3
!        echo "Rebooting system now"
!        /etc/ups/reboot -lq
!fi
!
===

In this specific case the script could afford (and intended) to effectively 
delay the actual system shutdown. Rationale: the system goes down due to UPS 
being on battery too long, so it sent a low-battery event. Bad variants for the 
next few minutes:
* If the system reboots, power may be cut during next startup (when UPS runs 
out of juice and shuts down).
* If the system powers off, but the UPS remains on, and the line power returns 
at this moment, the system stays off. This is a shared UPS for like 20 boxes, 
so it's not practical to issue UPS-power-off command even if it's supported by 
UPS hardware, but that's a good way to ensure power-off for a single box.

So we effectively halt the system while keeping it powered on, and if the UPS 
runs out of power - systems are safely prepared to power off. If the power 
returns and the UPS doesn't shut down, in a few minutes the servers which are 
still alive just do a reboot and start back up.

In bad-luck practice that's when a second brown-out comes while electricians 
test that they've fixed the power lines, and the UPS shuts down ;) So we have 
to make it a rather long sleep - 10-15 minutes usually being enough.

In Solaris10/OpenSolaris the /etc/rc0 script ends at the sync lines, so umounts 
are done elsewhere, and killall lines are gone (as seen in your link for 
"rc0.sh"). My patch as shown in the original post does delay the system 
shutdown/reboot, and reboots it after the timeout if UPS is still alive, but at 
the expense of not having filesystems properly unmounted when/if the UPS dies. 
Possibly (given enough UPS lifetime) SMF can timeout the /etc/rc0 script thus 
killing my sleeper watchdog (and killalling other processes as well) and 
unmounting the FSes and pools.

In my second project - rebooting if umounts hang on some hardware or other 
timeouts (but the CPU is still available) - I wanted to add a similar watchdog 
running in the background (with "&") that would sleep and then issue "uadmin 1 
1" which, as I recently learned, is the ungraceful syscall behind reboot. I 
just need this watchdog not getting killed.

Anyway, thanks for the links. I hope there is some way more proper than 
recompiling lsvcrun or svc.startd for each of my desires, and each OS revision 
used around me ;)

Thanks,
//Jim Klimov
-- 
This message posted from opensolaris.org
_______________________________________________
sysadmin-discuss mailing list
sysadmin-discuss@opensolaris.org
http://mail.opensolaris.org/mailman/listinfo/sysadmin-discuss

Reply via email to