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