Print this page
8034 shutdown(1M) needs modernizing
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Peter Tribble <peter.tribble@gmail.com>

@@ -23,12 +23,14 @@
 #       Use is subject to license terms.
 #
 #       Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
 #         All Rights Reserved
 
+#
+# Copyright 2017, OmniTI Computer Consulting, Inc. All rights reserved.
+#
 
-
 #       Sequence performed to change the init state of a machine.  Only allows
 #       transitions to states 0,1,5,6,s,S (i.e.: down or administrative states).
 
 #       This procedure checks to see if you are permitted and allows an
 #       interactive shutdown.  The actual change of state, killing of

@@ -42,20 +44,13 @@
 
 notify() {
         /usr/sbin/wall -a <<-!
         $*
         !
-        if [ -x /usr/sbin/showmount -a -x /usr/sbin/rwall ]
-        then
-                remotes=`/usr/sbin/showmount`
-                if [ "X${remotes}" != "X" ]
-                then
-                        /usr/sbin/rwall -q ${remotes} <<-!
-                        $*
-                        !
-                fi
-        fi
+        # We used to do rwall here if showmounts had any output, but
+        # rwall is a potential security hole, and it could block this, so
+        # we don't bother with it anymore.
 }
 
 nologin=/etc/nologin
 
 # Set the PATH so that to guarentee behavior of shell built in commands

@@ -126,11 +121,11 @@
                 ;;
         \?)     usage
                 ;;
         esac
 done
-shift `expr $OPTIND - 1`
+shift $(($OPTIND - 1))
 
 echo '\nShutdown started.    \c'
 /usr/bin/date
 echo
 

@@ -143,13 +138,13 @@
 # If other users are on the system (and any grace period is given), warn them.
 
 for i in 7200 3600 1800 1200 600 300 120 60 30 10; do
         if [ ${grace} -gt $i ]
         then
-                hours=`/usr/bin/expr ${grace} / 3600`
-                minutes=`/usr/bin/expr ${grace} % 3600 / 60`
-                seconds=`/usr/bin/expr ${grace} % 60`
+                hours=$((${grace} / 3600))
+                minutes=$((${grace} % 3600 / 60))
+                seconds=$((${grace} % 60))
                 time=""
                 if [ ${hours} -gt 1 ]
                 then
                         time="${hours} hours "
                 elif [ ${hours} -eq 1 ]

@@ -173,23 +168,21 @@
                         fi
                 fi
 
                 (notify \
 "The system ${NODENAME} will be shut down in ${time}
-$*") &
+$*")
 
-pid1=$!
-
                 rm $nologin >/dev/null 2>&1
                 cat > $nologin <<-!
 
                         NO LOGINS: System going down in ${time}
                         $*
 
                 !
 
-                /usr/bin/sleep `/usr/bin/expr ${grace} - $i`
+                /usr/bin/sleep $((${grace} - $i))
                 grace=$i
         fi
 done
 
 # Confirm that we really want to shutdown.

@@ -210,14 +203,12 @@
 # Final shutdown message, and sleep away the final 10 seconds (or less).
 
 (notify \
 "THE SYSTEM ${NODENAME} IS BEING SHUT DOWN NOW ! ! !
 Log off now or risk your files being damaged
-$*") &
+$*")
 
-pid2=$!
-
 if [ ${grace} -gt 0 ]
 then
         /usr/bin/sleep ${grace}
 fi
 

@@ -224,11 +215,21 @@
 # Go to the requested initstate.
 
 
 echo "Changing to init state $initstate - please wait"
 
-if [ "$pid1" ] || [ "$pid2" ]
-then
-        /usr/bin/kill $pid1 $pid2 > /dev/null 2>&1
+# We might be racing with a system that's still booting.
+# Before starting init, check to see if smf(5) is running.  The easiest way
+# to do this is to check for the existence of the repository service door.
+
+i=0
+# Try three times, sleeping one second each time...
+while [ ! -e /etc/svc/volatile/repository_door -a $i -lt 3 ]; do
+        sleep 1
+        i=$(($i + 1))
+done
+
+if [ ! -e /etc/svc/volatile/repository_door ]; then
+        notify "Could not find repository door, init-state change may fail!"
 fi
 
 /sbin/init ${initstate}