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


   8 #
   9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10 # or http://www.opensolaris.org/os/licensing.
  11 # See the License for the specific language governing permissions
  12 # and limitations under the License.
  13 #
  14 # When distributing Covered Code, include this CDDL HEADER in each
  15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16 # If applicable, add the following below this CDDL HEADER, with the
  17 # fields enclosed by brackets "[]" replaced with your own identifying
  18 # information: Portions Copyright [yyyy] [name of copyright owner]
  19 #
  20 # CDDL HEADER END
  21 #
  22 #       Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23 #       Use is subject to license terms.
  24 #
  25 #       Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
  26 #         All Rights Reserved
  27 



  28 
  29 
  30 #       Sequence performed to change the init state of a machine.  Only allows
  31 #       transitions to states 0,1,5,6,s,S (i.e.: down or administrative states).
  32 
  33 #       This procedure checks to see if you are permitted and allows an
  34 #       interactive shutdown.  The actual change of state, killing of
  35 #       processes and such are performed by the new init state, say 0,
  36 #       and its /sbin/rc0.
  37 
  38 usage() {
  39         echo "Usage: $0 [ -y ] [ -g<grace> ] [ -i<initstate> ] [ message ]"
  40         exit 1
  41 }
  42 
  43 notify() {
  44         /usr/sbin/wall -a <<-!
  45         $*
  46         !
  47         if [ -x /usr/sbin/showmount -a -x /usr/sbin/rwall ]
  48         then
  49                 remotes=`/usr/sbin/showmount`
  50                 if [ "X${remotes}" != "X" ]
  51                 then
  52                         /usr/sbin/rwall -q ${remotes} <<-!
  53                         $*
  54                         !
  55                 fi
  56         fi
  57 }
  58 
  59 nologin=/etc/nologin
  60 
  61 # Set the PATH so that to guarentee behavior of shell built in commands
  62 # (such as echo).
  63 
  64 PATH=/usr/sbin:/usr/bin:/sbin
  65 
  66 # Initial sanity checks:
  67 #       Make sure /usr is mounted
  68 #       Check the user id (only root can run shutdown)
  69 
  70 if [ ! -d /usr/bin ]
  71 then
  72         echo "$0:  /usr is not mounted.  Mount /usr or use init to shutdown."
  73         exit 1
  74 fi
  75 
  76 if [ -x /usr/bin/id ]


 111                 [Ss0156])
 112                         initstate=$OPTARG
 113                         ;;
 114                 [234abcqQ])
 115                         echo "$0: Initstate $OPTARG is not for system shutdown"
 116                         exit 1
 117                         ;;
 118                 *)
 119                         echo "$0: $OPTARG is not a valid initstate"
 120                         usage
 121                         ;;
 122                 esac
 123                 ;;
 124         y)
 125                 askconfirmation=
 126                 ;;
 127         \?)     usage
 128                 ;;
 129         esac
 130 done
 131 shift `expr $OPTIND - 1`
 132 
 133 echo '\nShutdown started.    \c'
 134 /usr/bin/date
 135 echo
 136 
 137 NODENAME=`uname -n`
 138 
 139 cd /
 140 
 141 trap "rm $nologin >/dev/null 2>&1 ;exit 1"  1 2 15
 142 
 143 # If other users are on the system (and any grace period is given), warn them.
 144 
 145 for i in 7200 3600 1800 1200 600 300 120 60 30 10; do
 146         if [ ${grace} -gt $i ]
 147         then
 148                 hours=`/usr/bin/expr ${grace} / 3600`
 149                 minutes=`/usr/bin/expr ${grace} % 3600 / 60`
 150                 seconds=`/usr/bin/expr ${grace} % 60`
 151                 time=""
 152                 if [ ${hours} -gt 1 ]
 153                 then
 154                         time="${hours} hours "
 155                 elif [ ${hours} -eq 1 ]
 156                 then
 157                         time="1 hour "
 158                 fi
 159                 if [ ${minutes} -gt 1 ]
 160                 then
 161                         time="${time}${minutes} minutes "
 162                 elif [ ${minutes} -eq 1 ]
 163                 then
 164                         time="${time}1 minute "
 165                 fi
 166                 if [ ${hours} -eq 0 -a ${seconds} -gt 0 ]
 167                 then
 168                         if [ ${seconds} -eq 1 ]
 169                         then
 170                                 time="${time}${seconds} second"
 171                         else
 172                                 time="${time}${seconds} seconds"
 173                         fi
 174                 fi
 175 
 176                 (notify \
 177 "The system ${NODENAME} will be shut down in ${time}
 178 $*") &
 179 
 180 pid1=$!
 181 
 182                 rm $nologin >/dev/null 2>&1
 183                 cat > $nologin <<-!
 184 
 185                         NO LOGINS: System going down in ${time}
 186                         $*
 187 
 188                 !
 189 
 190                 /usr/bin/sleep `/usr/bin/expr ${grace} - $i`
 191                 grace=$i
 192         fi
 193 done
 194 
 195 # Confirm that we really want to shutdown.
 196 
 197 if [ ${askconfirmation} ]
 198 then
 199         echo "Do you want to continue? (y or n):   \c"
 200         read b
 201         if [ "$b" != "y" ]
 202         then
 203                 notify "False Alarm:  The system ${NODENAME} will not be brought down."
 204                 echo 'Shutdown aborted.'
 205                 rm $nologin >/dev/null 2>&1
 206                 exit 1
 207         fi
 208 fi
 209 
 210 # Final shutdown message, and sleep away the final 10 seconds (or less).
 211 
 212 (notify \
 213 "THE SYSTEM ${NODENAME} IS BEING SHUT DOWN NOW ! ! !
 214 Log off now or risk your files being damaged
 215 $*") &
 216 
 217 pid2=$!
 218 
 219 if [ ${grace} -gt 0 ]
 220 then
 221         /usr/bin/sleep ${grace}
 222 fi
 223 
 224 # Go to the requested initstate.
 225 
 226 
 227 echo "Changing to init state $initstate - please wait"
 228 
 229 if [ "$pid1" ] || [ "$pid2" ]
 230 then
 231         /usr/bin/kill $pid1 $pid2 > /dev/null 2>&1










 232 fi
 233 
 234 /sbin/init ${initstate}


   8 #
   9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10 # or http://www.opensolaris.org/os/licensing.
  11 # See the License for the specific language governing permissions
  12 # and limitations under the License.
  13 #
  14 # When distributing Covered Code, include this CDDL HEADER in each
  15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16 # If applicable, add the following below this CDDL HEADER, with the
  17 # fields enclosed by brackets "[]" replaced with your own identifying
  18 # information: Portions Copyright [yyyy] [name of copyright owner]
  19 #
  20 # CDDL HEADER END
  21 #
  22 #       Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23 #       Use is subject to license terms.
  24 #
  25 #       Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
  26 #         All Rights Reserved
  27 
  28 #
  29 # Copyright 2017, OmniTI Computer Consulting, Inc. All rights reserved.
  30 #
  31 

  32 #       Sequence performed to change the init state of a machine.  Only allows
  33 #       transitions to states 0,1,5,6,s,S (i.e.: down or administrative states).
  34 
  35 #       This procedure checks to see if you are permitted and allows an
  36 #       interactive shutdown.  The actual change of state, killing of
  37 #       processes and such are performed by the new init state, say 0,
  38 #       and its /sbin/rc0.
  39 
  40 usage() {
  41         echo "Usage: $0 [ -y ] [ -g<grace> ] [ -i<initstate> ] [ message ]"
  42         exit 1
  43 }
  44 
  45 notify() {
  46         /usr/sbin/wall -a <<-!
  47         $*
  48         !
  49         # We used to do rwall here if showmounts had any output, but
  50         # rwall is a potential security hole, and it could block this, so
  51         # we don't bother with it anymore.







  52 }
  53 
  54 nologin=/etc/nologin
  55 
  56 # Set the PATH so that to guarentee behavior of shell built in commands
  57 # (such as echo).
  58 
  59 PATH=/usr/sbin:/usr/bin:/sbin
  60 
  61 # Initial sanity checks:
  62 #       Make sure /usr is mounted
  63 #       Check the user id (only root can run shutdown)
  64 
  65 if [ ! -d /usr/bin ]
  66 then
  67         echo "$0:  /usr is not mounted.  Mount /usr or use init to shutdown."
  68         exit 1
  69 fi
  70 
  71 if [ -x /usr/bin/id ]


 106                 [Ss0156])
 107                         initstate=$OPTARG
 108                         ;;
 109                 [234abcqQ])
 110                         echo "$0: Initstate $OPTARG is not for system shutdown"
 111                         exit 1
 112                         ;;
 113                 *)
 114                         echo "$0: $OPTARG is not a valid initstate"
 115                         usage
 116                         ;;
 117                 esac
 118                 ;;
 119         y)
 120                 askconfirmation=
 121                 ;;
 122         \?)     usage
 123                 ;;
 124         esac
 125 done
 126 shift $(($OPTIND - 1))
 127 
 128 echo '\nShutdown started.    \c'
 129 /usr/bin/date
 130 echo
 131 
 132 NODENAME=`uname -n`
 133 
 134 cd /
 135 
 136 trap "rm $nologin >/dev/null 2>&1 ;exit 1"  1 2 15
 137 
 138 # If other users are on the system (and any grace period is given), warn them.
 139 
 140 for i in 7200 3600 1800 1200 600 300 120 60 30 10; do
 141         if [ ${grace} -gt $i ]
 142         then
 143                 hours=$((${grace} / 3600))
 144                 minutes=$((${grace} % 3600 / 60))
 145                 seconds=$((${grace} % 60))
 146                 time=""
 147                 if [ ${hours} -gt 1 ]
 148                 then
 149                         time="${hours} hours "
 150                 elif [ ${hours} -eq 1 ]
 151                 then
 152                         time="1 hour "
 153                 fi
 154                 if [ ${minutes} -gt 1 ]
 155                 then
 156                         time="${time}${minutes} minutes "
 157                 elif [ ${minutes} -eq 1 ]
 158                 then
 159                         time="${time}1 minute "
 160                 fi
 161                 if [ ${hours} -eq 0 -a ${seconds} -gt 0 ]
 162                 then
 163                         if [ ${seconds} -eq 1 ]
 164                         then
 165                                 time="${time}${seconds} second"
 166                         else
 167                                 time="${time}${seconds} seconds"
 168                         fi
 169                 fi
 170 
 171                 (notify \
 172 "The system ${NODENAME} will be shut down in ${time}
 173 $*")
 174 


 175                 rm $nologin >/dev/null 2>&1
 176                 cat > $nologin <<-!
 177 
 178                         NO LOGINS: System going down in ${time}
 179                         $*
 180 
 181                 !
 182 
 183                 /usr/bin/sleep $((${grace} - $i))
 184                 grace=$i
 185         fi
 186 done
 187 
 188 # Confirm that we really want to shutdown.
 189 
 190 if [ ${askconfirmation} ]
 191 then
 192         echo "Do you want to continue? (y or n):   \c"
 193         read b
 194         if [ "$b" != "y" ]
 195         then
 196                 notify "False Alarm:  The system ${NODENAME} will not be brought down."
 197                 echo 'Shutdown aborted.'
 198                 rm $nologin >/dev/null 2>&1
 199                 exit 1
 200         fi
 201 fi
 202 
 203 # Final shutdown message, and sleep away the final 10 seconds (or less).
 204 
 205 (notify \
 206 "THE SYSTEM ${NODENAME} IS BEING SHUT DOWN NOW ! ! !
 207 Log off now or risk your files being damaged
 208 $*")
 209 


 210 if [ ${grace} -gt 0 ]
 211 then
 212         /usr/bin/sleep ${grace}
 213 fi
 214 
 215 # Go to the requested initstate.
 216 
 217 
 218 echo "Changing to init state $initstate - please wait"
 219 
 220 # We might be racing with a system that's still booting.
 221 # Before starting init, check to see if smf(5) is running.  The easiest way
 222 # to do this is to check for the existence of the repository service door.
 223 
 224 i=0
 225 # Try three times, sleeping one second each time...
 226 while [ ! -e /etc/svc/volatile/repository_door -a $i -lt 3 ]; do
 227         sleep 1
 228         i=$(($i + 1))
 229 done
 230 
 231 if [ ! -e /etc/svc/volatile/repository_door ]; then
 232         notify "Could not find repository door, init-state change may fail!"
 233 fi
 234 
 235 /sbin/init ${initstate}