1 | #!/bin/sh |
---|
2 | # $Id: update_ws.sh,v 1.61 2002-08-05 14:55:45 ghudson Exp $ |
---|
3 | |
---|
4 | # Copyright 1996 by the Massachusetts Institute of Technology. |
---|
5 | # |
---|
6 | # Permission to use, copy, modify, and distribute this |
---|
7 | # software and its documentation for any purpose and without |
---|
8 | # fee is hereby granted, provided that the above copyright |
---|
9 | # notice appear in all copies and that both that copyright |
---|
10 | # notice and this permission notice appear in supporting |
---|
11 | # documentation, and that the name of M.I.T. not be used in |
---|
12 | # advertising or publicity pertaining to distribution of the |
---|
13 | # software without specific, written prior permission. |
---|
14 | # M.I.T. makes no representations about the suitability of |
---|
15 | # this software for any purpose. It is provided "as is" |
---|
16 | # without express or implied warranty. |
---|
17 | |
---|
18 | # update_ws (also known as auto_update) |
---|
19 | # |
---|
20 | # Check that an update is needed, and make sure the conditions necessary |
---|
21 | # for a successful update are met. Then prepare the machine for update, |
---|
22 | # and run do-update. |
---|
23 | |
---|
24 | # "tee" doesn't work reliably across OS versions (since it's not local on |
---|
25 | # Solaris), so emulate it in the shell. |
---|
26 | shelltee() { |
---|
27 | exec 3>$1 |
---|
28 | while IFS="" read line; do |
---|
29 | echo "$line" |
---|
30 | echo "$line" 1>&3 |
---|
31 | done |
---|
32 | } |
---|
33 | |
---|
34 | trap "" 1 15 |
---|
35 | |
---|
36 | export CONFDIR LIBDIR PATH HOSTTYPE |
---|
37 | CONFDIR=/etc/athena |
---|
38 | LIBDIR=/srvd/usr/athena/lib/update |
---|
39 | PATH=/bin:/etc:/usr/bin:/usr/ucb:/usr/bsd:/os/bin:/os/etc:/etc/athena:/bin/athena:/os/usr/bin:/usr/athena/sbin:/os/usr/ucb:/os/usr/bsd:/usr/sbin:$LIBDIR |
---|
40 | HOSTTYPE=`/bin/athena/machtype` |
---|
41 | |
---|
42 | case $0 in |
---|
43 | *auto_update) |
---|
44 | method=Auto |
---|
45 | why=$1 |
---|
46 | ;; |
---|
47 | *) |
---|
48 | method=Manual |
---|
49 | ;; |
---|
50 | esac |
---|
51 | |
---|
52 | # The -a option specifies that the update is automatic (run by the |
---|
53 | # boot script or reactivate). The -r option specifies that the update |
---|
54 | # is remote and that we shouldn't give the user a shell after the |
---|
55 | # reboot. |
---|
56 | while getopts a:r opt; do |
---|
57 | case $opt in |
---|
58 | a) |
---|
59 | method=Auto |
---|
60 | why=$OPTARG |
---|
61 | ;; |
---|
62 | r) |
---|
63 | method=Remote |
---|
64 | ;; |
---|
65 | \?) |
---|
66 | echo "$0 [-r] [-a reactivate|rc]" 1>&2 |
---|
67 | exit 1 |
---|
68 | ;; |
---|
69 | esac |
---|
70 | done |
---|
71 | shift `expr $OPTIND - 1` |
---|
72 | |
---|
73 | case `id` in |
---|
74 | "uid=0("*) |
---|
75 | ;; |
---|
76 | *) |
---|
77 | echo "You are not root. This update script must be run as root." |
---|
78 | exit 1 |
---|
79 | ;; |
---|
80 | esac |
---|
81 | |
---|
82 | # If /srvd is not mounted, quit. |
---|
83 | if [ ! -d /srvd/bin ]; then |
---|
84 | exit 1 |
---|
85 | fi |
---|
86 | |
---|
87 | if [ ! -f "$CONFDIR/version" ]; then |
---|
88 | echo "Athena Update (???) Version 0.0A Mon Jan 1 00:00:00 EDT 0000" \ |
---|
89 | > "$CONFDIR/version" |
---|
90 | fi |
---|
91 | |
---|
92 | newvers=`awk '{a=$5}; END{print a}' /srvd/.rvdinfo` |
---|
93 | version=`awk '$0 != "" {a=$5}; END{print a}' "$CONFDIR/version"` |
---|
94 | |
---|
95 | if [ -f "$CONFDIR/rc.conf" ]; then |
---|
96 | . "$CONFDIR/rc.conf" |
---|
97 | else |
---|
98 | export PUBLIC AUTOUPDATE HOST |
---|
99 | PUBLIC=true |
---|
100 | AUTOUPDATE=true |
---|
101 | HOST=`hostname` |
---|
102 | fi |
---|
103 | |
---|
104 | # Make sure /var/athena exists (it was introduced in 8.1.0) so we have a |
---|
105 | # place to put the temporary clusterinfo file and the desync state file |
---|
106 | # and the update log. |
---|
107 | if [ ! -d /var/athena ]; then |
---|
108 | mkdir -m 755 /var/athena |
---|
109 | fi |
---|
110 | |
---|
111 | # Get and read cluster information, to set one or both of |
---|
112 | # NEW_TESTING_RELEASE and NEW_PRODUCTION_RELEASE if there are new |
---|
113 | # releases available. |
---|
114 | /etc/athena/save_cluster_info |
---|
115 | if [ -f /var/athena/clusterinfo.bsh ]; then |
---|
116 | . /var/athena/clusterinfo.bsh |
---|
117 | fi |
---|
118 | |
---|
119 | # Check if we're already in the middle of an update. |
---|
120 | case $version in |
---|
121 | [0-9]*) |
---|
122 | # If this field starts with a digit, we're running a proper |
---|
123 | # release. Otherwise... |
---|
124 | ;; |
---|
125 | *) |
---|
126 | if [ ! -f /var/tmp/update.check ]; then |
---|
127 | logger -t $HOST -p user.notice at revision $version |
---|
128 | touch /var/tmp/update.check |
---|
129 | fi |
---|
130 | |
---|
131 | echo "This system is in the middle of an update. Please contact" |
---|
132 | echo "Athena Cluster Services at x3-1410. Thank you. -Athena Operations" |
---|
133 | exit 1 |
---|
134 | ;; |
---|
135 | esac |
---|
136 | |
---|
137 | # Find out if the version in /srvd/.rvdinfo is newer than |
---|
138 | # /etc/athena/version. Distinguish between major, minor, and patch |
---|
139 | # releases so that we can desynchronize patch releases. |
---|
140 | packsnewer=`echo "$newvers $version" | awk '{ |
---|
141 | split($1, v1, "."); |
---|
142 | split($2, v2, "."); |
---|
143 | if (v1[1] + 0 > v2[1] + 0) |
---|
144 | print "major"; |
---|
145 | else if (v1[1] + 0 == v2[1] + 0 && v1[2] + 0 > v2[2] + 0) |
---|
146 | print "minor"; |
---|
147 | else if (v1[1] == v2[1] && v1[2] == v2[2] && v1[3] + 0 > v2[3] + 0) |
---|
148 | print "patch"; }'` |
---|
149 | |
---|
150 | # If the packs aren't any newer, print an appropriate message and exit. |
---|
151 | if [ -z "$packsnewer" ]; then |
---|
152 | if [ Auto != "$method" ]; then |
---|
153 | # User ran update_ws; display something appropriate. |
---|
154 | if [ -n "$NEW_PRODUCTION_RELEASE" -o \ |
---|
155 | -n "$NEW_TESTING_RELEASE" ]; then |
---|
156 | echo "Your workstation software already matches the version on the" |
---|
157 | echo "system packs. You must manually attach a newer version of the" |
---|
158 | echo "system packs to update beyond this point." |
---|
159 | else |
---|
160 | echo "It appears you already have this update." |
---|
161 | fi |
---|
162 | else |
---|
163 | # System ran auto_update; point out new releases if available. |
---|
164 | if [ -n "$NEW_PRODUCTION_RELEASE" ]; then |
---|
165 | ver=$NEW_PRODUCTION_RELEASE |
---|
166 | echo "A new Athena release ($ver) is available. Since it may be" |
---|
167 | echo "incompatible with your workstation software, your workstation is" |
---|
168 | echo "still using the old system packs. Please contact Athena Cluster" |
---|
169 | echo "Services (x3-1410) to have your workstation updated." |
---|
170 | fi |
---|
171 | if [ -n "$NEW_TESTING_RELEASE" ]; then |
---|
172 | ver=$NEW_TESTING_RELEASE |
---|
173 | echo "A new Athena release ($ver) is now in testing. You are" |
---|
174 | echo "theoretically interested in this phase of testing, but because" |
---|
175 | echo "there may be bugs which would inconvenience your work, you must" |
---|
176 | echo "update to this release manually. Please contact Athena Cluster" |
---|
177 | echo "Services (x3-1410) if you have not received instructions on how" |
---|
178 | echo "to do so." |
---|
179 | fi |
---|
180 | fi |
---|
181 | exit 0 |
---|
182 | fi |
---|
183 | |
---|
184 | # The packs are newer, but if we were run as auto_update, we don't want to do |
---|
185 | # an update unless the machine is autoupdate (or public). |
---|
186 | if [ Auto = "$method" -a true != "$AUTOUPDATE" -a true != "$PUBLIC" ]; then |
---|
187 | echo "A new version of Athena software is now available. Please contact" |
---|
188 | echo "Athena Cluster Services (x3-1410) to get more information on how to" |
---|
189 | echo "update your workstation yourself, or to schedule us to do it for you." |
---|
190 | echo "Thank you. -Athena Operations" |
---|
191 | if [ ! -f /var/tmp/update.check ]; then |
---|
192 | logger -t "$HOST" -p user.notice at revision $version |
---|
193 | cp /dev/null /var/tmp/update.check |
---|
194 | fi |
---|
195 | exit 1 |
---|
196 | fi |
---|
197 | |
---|
198 | if [ Auto = "$method" -a patch = "$packsnewer" ]; then |
---|
199 | # There is a patch release available and we want to take the update, |
---|
200 | # but not necessarily right now. Use desync to stagger the update |
---|
201 | # over a four-hour period. (Use the version from /srvd for now to |
---|
202 | # make sure the -t option works, since that option was not |
---|
203 | # introduced until 8.1.) Note that we only do desynchronization |
---|
204 | # here for patch releases. Desynchronization for major or minor |
---|
205 | # releases is handled in getcluster, since we don't want the |
---|
206 | # workstation to run with a new, possibly incompatible version of |
---|
207 | # the packs. |
---|
208 | |
---|
209 | /srvd/etc/athena/desync -t /var/athena/update.desync 14400 |
---|
210 | if [ $? -ne 0 ]; then |
---|
211 | exit 0 |
---|
212 | fi |
---|
213 | fi |
---|
214 | |
---|
215 | # Beyond this point, if the update fails, it's probably due to a full |
---|
216 | # release which we can't take for some reason. A machine with new |
---|
217 | # system packs attached won't function properly in this state, so we |
---|
218 | # should attempt to reattach the old system packs before exiting if |
---|
219 | # this was an automatic update attempt. This function takes care of |
---|
220 | # reattaching the old system packs and exiting with an error status. |
---|
221 | failupdate() { |
---|
222 | if [ Auto = "$method" ]; then |
---|
223 | echo "Attempting to reattach old system packs" |
---|
224 | detach "$SYSLIB" |
---|
225 | AUTOUPDATE=false getcluster -b -l /etc/athena/cluster.local \ |
---|
226 | "$HOST" "$version" > /var/athena/cluster.oldrel |
---|
227 | if [ -s /var/athena/cluster.oldrel ]; then |
---|
228 | . /var/athena/cluster.oldrel |
---|
229 | fi |
---|
230 | attach -O "$SYSLIB" |
---|
231 | fi |
---|
232 | exit 1 |
---|
233 | } |
---|
234 | |
---|
235 | # This check needs to be updated for each full release. It verifies |
---|
236 | # that people aren't updating across two full releases, which |
---|
237 | # generally doesn't work. |
---|
238 | case "$version" in |
---|
239 | 9.0.*|9.1.*) |
---|
240 | ;; |
---|
241 | *) |
---|
242 | echo "You must update by only one full release at a time." |
---|
243 | failupdate |
---|
244 | ;; |
---|
245 | esac |
---|
246 | |
---|
247 | case "$HOSTTYPE" in |
---|
248 | sun4) |
---|
249 | |
---|
250 | # Set required filesystem sizes 9.1 release, and required filesystem |
---|
251 | # space for the 9.1 update. Filesystem overhead consumes about 7% of |
---|
252 | # a partition, so we check for a filesystem size 10% less than the |
---|
253 | # partition size we want. We get some extra margin from minfree, |
---|
254 | # but we don't deliberately rely on that. |
---|
255 | |
---|
256 | # For the 9.1 release, the size of /usr with sys_rvd.big actually |
---|
257 | # decreased (due to the use of gnu ld), so there is no special check |
---|
258 | # for sys_rvd.big machines. |
---|
259 | reqrootsize=88473 # 96MB partition; measured use 66033K |
---|
260 | requsrsize=184320 # 200MB partition; measured use 153465K |
---|
261 | reqrootspace=10240 # 10MB; measured space increase 6837K |
---|
262 | requsrspace=61440 # 60MB; measured space increase 51909K |
---|
263 | |
---|
264 | # Check filesystem sizes. |
---|
265 | rootsize=`df -k / | awk '{ x = $2; } END { print x; }'` |
---|
266 | usrsize=`df -k /usr | awk '{ x = $2; } END { print x; }'` |
---|
267 | if [ "$reqrootsize" -gt "$rootsize" -o "$requsrsize" -gt "$usrsize" ]; then |
---|
268 | echo "Your / or /usr partition is not big enough for Athena release 9.1" |
---|
269 | echo "and higher. You must reinstall to take this update." |
---|
270 | logger -t "$HOST" -p user.notice / or /usr too small to take update |
---|
271 | failupdate |
---|
272 | fi |
---|
273 | |
---|
274 | # Check free space if this is a full update to 9.1. |
---|
275 | case $version in |
---|
276 | 8.*|9.0.*) |
---|
277 | rootspace=`df -k / | awk '{ x = $4; } END { print x; }'` |
---|
278 | usrspace=`df -k /usr | awk '{ x = $4; } END { print x; }'` |
---|
279 | if [ "$reqrootspace" -gt "$rootspace" \ |
---|
280 | -o "$requsrspace" -gt "$usrspace" ]; then |
---|
281 | echo "The / partition must have ${reqrootspace}K free and the /usr" |
---|
282 | echo "partition must have ${requsrspace}K free for this update. Please" |
---|
283 | echo "reinstall or clean local files off the / and /usr partitions." |
---|
284 | logger -t "$HOST" -p user.notice / or /usr too full to take update |
---|
285 | failupdate |
---|
286 | fi |
---|
287 | ;; |
---|
288 | esac |
---|
289 | |
---|
290 | # The 9.1.14 release adds about 200MB of files to /usr/athena on |
---|
291 | # sys_rvd.big machines. Make sure we have enough space for that |
---|
292 | # update if this is such a machine. No need to add in numbers for |
---|
293 | # the 9.0 to 9.1 update, since (as noted above) disk usage on |
---|
294 | # sys_rvd.big machines went down between 9.0 and 9.1.13. |
---|
295 | if [ ! -h /usr/athena ]; then |
---|
296 | case $version in |
---|
297 | 8.*|9.0.*|9.1.[0-9]|9.1.1[0-3]) |
---|
298 | rootspace=`df -k / | awk '{ x = $4; } END { print x; }'` |
---|
299 | if [ "$rootspace" -lt 204800 ]; then |
---|
300 | echo "The / partition must have 204800K free for this update." |
---|
301 | echo "Please clean local files." |
---|
302 | logger -t "$HOST" -p user.notice / too full to take 9.1.14 update |
---|
303 | failupdate |
---|
304 | fi |
---|
305 | ;; |
---|
306 | esac |
---|
307 | fi |
---|
308 | |
---|
309 | # Ultras with old enough OBP versions aren't able to boot the 64 bit |
---|
310 | # Solaris kernel without a firmware upgrade. They will fail the |
---|
311 | # update ungracefully, since the miniroot can only boot the 64 bit |
---|
312 | # kernel on Ultras. Check the version of OBP here so we can bomb out |
---|
313 | # gracefully. |
---|
314 | # |
---|
315 | # We must be running version 3.11.1 or greater in order to be able to |
---|
316 | # boot the 64 bit kernel. |
---|
317 | if [ sun4u = `uname -m` ]; then |
---|
318 | eval `prtconf -V | awk '{print $2}' \ |
---|
319 | | awk -F. '{print "obpmajor=" $1, "obpminor=" $2}'` |
---|
320 | if [ ! "$obpmajor" -gt 3 -a ! "$obpminor" -ge 11 ]; then |
---|
321 | echo "This machine requires a firmware upgrade for this update." |
---|
322 | logger -t "$HOST" -p user.notice firmware too old to take update |
---|
323 | failupdate |
---|
324 | fi |
---|
325 | fi |
---|
326 | |
---|
327 | # Athena 9.1 does not support sun4m hardware. |
---|
328 | if [ sun4m = `uname -m` ]; then |
---|
329 | echo "This machine is no longer supported and is too old for this update." |
---|
330 | logger -t "$HOST" -p user.notice sun4m hardware unable to take update |
---|
331 | failupdate |
---|
332 | fi |
---|
333 | ;; |
---|
334 | esac |
---|
335 | |
---|
336 | # Ensure that we have enough disk space on the IRIX root partition |
---|
337 | # for an upgrade to 9.1. |
---|
338 | # We also require a minimum of 64MB of memory on all SGI's. |
---|
339 | case $HOSTTYPE in |
---|
340 | sgi) |
---|
341 | case `uname -r` in |
---|
342 | 6.2) |
---|
343 | rootneeded=150 |
---|
344 | ;; |
---|
345 | 6.3) |
---|
346 | rootneeded=90 |
---|
347 | ;; |
---|
348 | 6.5) |
---|
349 | case "`uname -R | awk '{ print $2; }'`" in |
---|
350 | 6.5.3m) |
---|
351 | rootneeded=50 |
---|
352 | ;; |
---|
353 | *) |
---|
354 | case $version in |
---|
355 | 9.1.*) |
---|
356 | rootneeded=0 |
---|
357 | ;; |
---|
358 | *) |
---|
359 | rootneeded=20 |
---|
360 | ;; |
---|
361 | esac |
---|
362 | ;; |
---|
363 | esac |
---|
364 | ;; |
---|
365 | *) |
---|
366 | rootneeded=0 |
---|
367 | ;; |
---|
368 | esac |
---|
369 | |
---|
370 | rootfree=`df -k / | awk '$NF == "/" { print int($5 / 1024); }'` |
---|
371 | if [ "$rootfree" -lt "$rootneeded" ]; then |
---|
372 | echo "Root partition low on space (less than ${rootneeded}MB); not" |
---|
373 | echo "performing update. Please reinstall or clean local files off root" |
---|
374 | echo "partition." |
---|
375 | logger -t "$HOST" -p user.notice / too full to take update |
---|
376 | failupdate |
---|
377 | fi |
---|
378 | |
---|
379 | if [ 64 -gt "`hinv -t memory | awk '{ print $4; }'`" ]; then |
---|
380 | echo "Insufficient memory (less than 64MB); not performing update. Please" |
---|
381 | echo "add more memory or reinstall." |
---|
382 | logger -t "$HOST" -p user.notice insufficient memory to take update |
---|
383 | failupdate |
---|
384 | fi |
---|
385 | ;; |
---|
386 | esac |
---|
387 | |
---|
388 | # If this is a private workstation, make sure we can recreate the mkserv |
---|
389 | # state of the machine after the update. |
---|
390 | if [ -d /var/server ] ; then |
---|
391 | /srvd/usr/athena/bin/mkserv updatetest |
---|
392 | if [ $? -ne 0 ]; then |
---|
393 | echo "mkserv services cannot be found for all services. Update cannot be" |
---|
394 | echo "performed." |
---|
395 | logger -t "$HOST" -p user.notice missing mkserv services, unable to take update |
---|
396 | failupdate |
---|
397 | fi |
---|
398 | fi |
---|
399 | |
---|
400 | # Tell dm to shut down everything and sleep forever during the update. |
---|
401 | if [ Auto = "$method" -a reactivate = "$why" ]; then |
---|
402 | if [ -f /var/athena/dm.pid ]; then |
---|
403 | kill -FPE `cat /var/athena/dm.pid` |
---|
404 | fi |
---|
405 | # 8.0 and prior machines still have /etc/athena/dm.pid. |
---|
406 | if [ -f /etc/athena/dm.pid ]; then |
---|
407 | kill -FPE `cat /etc/athena/dm.pid` |
---|
408 | fi |
---|
409 | |
---|
410 | if [ -f /etc/init.d/axdm ]; then |
---|
411 | /etc/init.d/axdm stop |
---|
412 | fi |
---|
413 | |
---|
414 | sleep 2 |
---|
415 | if [ sgi = "$HOSTTYPE" ]; then |
---|
416 | exec 1>/dev/tport 2>&1 |
---|
417 | fi |
---|
418 | fi |
---|
419 | |
---|
420 | # Everything is all set; do the actual update. |
---|
421 | rm -f /var/athena/update.log |
---|
422 | if [ Auto = "$method" ]; then |
---|
423 | echo |
---|
424 | echo "THIS WORKSTATION IS ABOUT TO UNDERGO AN AUTOMATIC SOFTWARE UPDATE." |
---|
425 | echo "THIS PROCEDURE MAY TAKE SOME TIME." |
---|
426 | echo |
---|
427 | echo "PLEASE DO NOT DISTURB IT WHILE THIS IS IN PROGRESS." |
---|
428 | echo |
---|
429 | exec sh "$LIBDIR/do-update" "$method" "$version" "$newvers" \ |
---|
430 | < /dev/null 2>&1 | shelltee /var/athena/update.log |
---|
431 | else |
---|
432 | exec sh "$LIBDIR/do-update" "$method" "$version" "$newvers" \ |
---|
433 | 2>&1 | shelltee /var/athena/update.log |
---|
434 | fi |
---|