Print this page
8034 shutdown(1M) needs modernizing
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Peter Tribble <peter.tribble@gmail.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/initpkg/shutdown.sh
+++ new/usr/src/cmd/initpkg/shutdown.sh
1 1 #!/sbin/sh
2 2 #
3 3 # CDDL HEADER START
4 4 #
5 5 # The contents of this file are subject to the terms of the
6 6 # Common Development and Distribution License (the "License").
7 7 # You may not use this file except in compliance with the License.
8 8 #
9 9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 # or http://www.opensolaris.org/os/licensing.
11 11 # See the License for the specific language governing permissions
12 12 # and limitations under the License.
13 13 #
14 14 # When distributing Covered Code, include this CDDL HEADER in each
15 15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 # If applicable, add the following below this CDDL HEADER, with the
17 17 # fields enclosed by brackets "[]" replaced with your own identifying
|
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
18 18 # information: Portions Copyright [yyyy] [name of copyright owner]
19 19 #
20 20 # CDDL HEADER END
21 21 #
22 22 # Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 # Use is subject to license terms.
24 24 #
25 25 # Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
26 26 # All Rights Reserved
27 27
28 +#
29 +# Copyright 2017, OmniTI Computer Consulting, Inc. All rights reserved.
30 +#
28 31
29 -
30 32 # Sequence performed to change the init state of a machine. Only allows
31 33 # transitions to states 0,1,5,6,s,S (i.e.: down or administrative states).
32 34
33 35 # This procedure checks to see if you are permitted and allows an
34 36 # interactive shutdown. The actual change of state, killing of
35 37 # processes and such are performed by the new init state, say 0,
36 38 # and its /sbin/rc0.
37 39
38 40 usage() {
39 41 echo "Usage: $0 [ -y ] [ -g<grace> ] [ -i<initstate> ] [ message ]"
40 42 exit 1
41 43 }
42 44
43 45 notify() {
44 46 /usr/sbin/wall -a <<-!
45 47 $*
46 48 !
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
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.
57 52 }
58 53
59 54 nologin=/etc/nologin
60 55
61 56 # Set the PATH so that to guarentee behavior of shell built in commands
62 57 # (such as echo).
63 58
64 59 PATH=/usr/sbin:/usr/bin:/sbin
65 60
66 61 # Initial sanity checks:
67 62 # Make sure /usr is mounted
68 63 # Check the user id (only root can run shutdown)
69 64
70 65 if [ ! -d /usr/bin ]
71 66 then
72 67 echo "$0: /usr is not mounted. Mount /usr or use init to shutdown."
73 68 exit 1
74 69 fi
75 70
76 71 if [ -x /usr/bin/id ]
77 72 then
78 73 eval `/usr/bin/id | /usr/bin/sed 's/[^a-z0-9=].*//'`
79 74 if [ "${uid:=0}" -ne 0 ]
80 75 then
81 76 echo "$0: Only root can run $0"
82 77 exit 2
83 78 fi
84 79 else
85 80 echo "$0: can't check user id."
86 81 exit 2
87 82 fi
88 83
89 84 # Get options (defaults immediately below):
90 85
91 86 grace=60
92 87 askconfirmation=yes
93 88 initstate=s
94 89
95 90 while getopts g:i:y? c
96 91 do
97 92 case $c in
98 93 g)
99 94 case $OPTARG in
100 95 *[!0-9]* )
101 96 echo "$0: -g requires a numeric option"
102 97 usage
103 98 ;;
104 99 [0-9]* )
105 100 grace=$OPTARG
106 101 ;;
107 102 esac
108 103 ;;
109 104 i)
110 105 case $OPTARG in
111 106 [Ss0156])
112 107 initstate=$OPTARG
113 108 ;;
114 109 [234abcqQ])
115 110 echo "$0: Initstate $OPTARG is not for system shutdown"
116 111 exit 1
117 112 ;;
118 113 *)
119 114 echo "$0: $OPTARG is not a valid initstate"
120 115 usage
|
↓ open down ↓ |
54 lines elided |
↑ open up ↑ |
121 116 ;;
122 117 esac
123 118 ;;
124 119 y)
125 120 askconfirmation=
126 121 ;;
127 122 \?) usage
128 123 ;;
129 124 esac
130 125 done
131 -shift `expr $OPTIND - 1`
126 +shift $(($OPTIND - 1))
132 127
133 128 echo '\nShutdown started. \c'
134 129 /usr/bin/date
135 130 echo
136 131
137 132 NODENAME=`uname -n`
138 133
139 134 cd /
140 135
141 136 trap "rm $nologin >/dev/null 2>&1 ;exit 1" 1 2 15
142 137
143 138 # If other users are on the system (and any grace period is given), warn them.
144 139
145 140 for i in 7200 3600 1800 1200 600 300 120 60 30 10; do
146 141 if [ ${grace} -gt $i ]
147 142 then
148 - hours=`/usr/bin/expr ${grace} / 3600`
149 - minutes=`/usr/bin/expr ${grace} % 3600 / 60`
150 - seconds=`/usr/bin/expr ${grace} % 60`
143 + hours=$((${grace} / 3600))
144 + minutes=$((${grace} % 3600 / 60))
145 + seconds=$((${grace} % 60))
151 146 time=""
152 147 if [ ${hours} -gt 1 ]
153 148 then
154 149 time="${hours} hours "
155 150 elif [ ${hours} -eq 1 ]
156 151 then
157 152 time="1 hour "
158 153 fi
159 154 if [ ${minutes} -gt 1 ]
160 155 then
161 156 time="${time}${minutes} minutes "
162 157 elif [ ${minutes} -eq 1 ]
163 158 then
164 159 time="${time}1 minute "
165 160 fi
166 161 if [ ${hours} -eq 0 -a ${seconds} -gt 0 ]
167 162 then
|
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
168 163 if [ ${seconds} -eq 1 ]
169 164 then
170 165 time="${time}${seconds} second"
171 166 else
172 167 time="${time}${seconds} seconds"
173 168 fi
174 169 fi
175 170
176 171 (notify \
177 172 "The system ${NODENAME} will be shut down in ${time}
178 -$*") &
173 +$*")
179 174
180 -pid1=$!
181 -
182 175 rm $nologin >/dev/null 2>&1
183 176 cat > $nologin <<-!
184 177
185 178 NO LOGINS: System going down in ${time}
186 179 $*
187 180
188 181 !
189 182
190 - /usr/bin/sleep `/usr/bin/expr ${grace} - $i`
183 + /usr/bin/sleep $((${grace} - $i))
191 184 grace=$i
192 185 fi
193 186 done
194 187
195 188 # Confirm that we really want to shutdown.
196 189
197 190 if [ ${askconfirmation} ]
198 191 then
199 192 echo "Do you want to continue? (y or n): \c"
200 193 read b
201 194 if [ "$b" != "y" ]
202 195 then
203 196 notify "False Alarm: The system ${NODENAME} will not be brought down."
204 197 echo 'Shutdown aborted.'
|
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
205 198 rm $nologin >/dev/null 2>&1
206 199 exit 1
207 200 fi
208 201 fi
209 202
210 203 # Final shutdown message, and sleep away the final 10 seconds (or less).
211 204
212 205 (notify \
213 206 "THE SYSTEM ${NODENAME} IS BEING SHUT DOWN NOW ! ! !
214 207 Log off now or risk your files being damaged
215 -$*") &
208 +$*")
216 209
217 -pid2=$!
218 -
219 210 if [ ${grace} -gt 0 ]
220 211 then
221 212 /usr/bin/sleep ${grace}
222 213 fi
223 214
224 215 # Go to the requested initstate.
225 216
226 217
227 218 echo "Changing to init state $initstate - please wait"
228 219
229 -if [ "$pid1" ] || [ "$pid2" ]
230 -then
231 - /usr/bin/kill $pid1 $pid2 > /dev/null 2>&1
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!"
232 233 fi
233 234
234 235 /sbin/init ${initstate}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX