]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - installworld_oldk
This commit was generated by cvs2svn to compensate for changes in r131702,
[FreeBSD/FreeBSD.git] / installworld_oldk
1 #!/bin/sh
2 # -------+---------+---------+---------+---------+---------+---------+---------+
3 # Copyright (c) 2004  - Garance Alistair Drosehn <gad@FreeBSD.org>.
4 #
5 # All rights reserved.
6 #
7 #  Redistribution and use in source and binary forms, with or without
8 #  modification, are permitted provided that the following conditions
9 #  are met:
10 #  1. Redistributions of source code must retain the above copyright
11 #     notice, this list of conditions and the following disclaimer.
12 #  2. Redistributions in binary form must reproduce the above copyright
13 #     notice, this list of conditions and the following disclaimer in the
14 #     documentation and/or other materials provided with the distribution.
15 #
16 #  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 #  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 #  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 #  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 #  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 #  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 #  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 #  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 #  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 #  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 #  SUCH DAMAGE.
27 #
28 # -------+---------+---------+---------+---------+---------+---------+---------+
29 # $FreeBSD$
30 # -------+---------+---------+---------+---------+---------+---------+---------+
31 #
32 #   This script does a 'make installworld' using the *old* versions of all
33 # commands to do the work.  It expects that the new kernel has been installed,
34 # but that the system has not been rebooted (and is thus still running on the
35 # previous kernel).  This is useful when a major incompatible change is made,
36 # and you want to do an installworld that uses NFS-mounted directories for
37 # /usr/src and /usr/obj.  This script was written for the change to
38 # 64-bit time_t on FreeBSD/Sparc64, but it is not specific to that.
39 #
40 #   IMPORTANT: This script does require that you are NOT YET running on
41 # the new kernel that matches the 'world' that you want to install.
42 #
43 # -------+---------+---------+---------+---------+---------+---------+---------+
44
45 #   This script expects that it will be run from /usr/src, or an
46 #   equivalent (perhaps NFS-mounted) directory.
47 if [ -f MAINTAINERS -a -f UPDATING -a -f Makefile -a -f Makefile.inc1 ] ; then
48     SOURCE_BWDIR="`make -V .OBJDIR`"
49 else
50     echo "This script must be run from /usr/src!  (or equivalent)"
51     exit 1
52 fi
53
54 DOMAKE=
55 DOMINI=
56 SETMINPATH=
57 SYMLINKS=
58 VERBOSE=
59 BADOPT=
60 while test $# != 0
61 do
62     case "$1" in
63     -M)   SETMINPATH=yes ;;
64     -N)   DOMINI=no ;;
65     -S)   echo "-S (symlinks) is ignored in installworld_oldk." ;;
66     -Y)   DOMINI=yes ;;
67     -y)   DOMAKE=yes ;;
68     -n)   DOMAKE=no ;;
69     -v)   VERBOSE=yes ;;
70     *)    echo "Invalid option: $1" ; BADOPT=yes ;;
71     esac
72     shift 1
73 done
74 if [ -n "$BADOPT" ] ; then
75     exit 1
76 fi
77
78 echo "* + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - *"
79 echo "*  This script expects that a 'make installkernel' has already"
80 echo "*  been done, but that the system is still running the previous"
81 echo "*  kernel.  Ie, that you have not rebooted."
82 echo "*"
83 echo "*  Also note that this only does a PARTIAL installworld.  You"
84 echo "*  will still have to do a full installworld after rebooting."
85 echo "* + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - *"
86 echo ""
87
88 #   See if the user wants us to create a mini-/bin inside of the
89 #   newly-installed kernel.  These executables would only be used
90 #   *after* booting into the new kernel, so we want the new-world
91 #   versions of all files.
92 #   XXX - This is a idea which could be useful in many situations, but
93 #       it really should be implemented as an official make-target.
94 #       It would be particularly nice to make this a statically-linked
95 #       (and crunchgen-ed) collection of programs...
96 if [ -z "${DOMINI}" -a -z "${DOMAKE}" ] ; then
97     echo "Do you want a mini-/bin in that newly-installed /boot/kernel? "
98     read -p "(y/n) ? "  DOMINI remline
99     echo " "
100 elif [ -z "${DOMINI}" ] ; then
101     DOMINI="${DOMAKE}"
102 fi
103 if [ -n "`echo /y/yes/okay/ok/ | grep -i \"/${DOMINI}/\"`" ] ; then
104     KERNBINDIR=/boot/kernel/bin
105     if [ -e ${KERNBINDIR} ] ; then
106         rm -Rf ${KERNBINDIR}
107     fi
108     mkdir -p ${KERNBINDIR}
109     #   Much of this is done in a subshell, so values of DESTDIR, etc,
110     #   will only be in effect for this section of the script.
111     (
112     DESTDIR=${KERNBINDIR}
113     BINDIR=""
114     NOINFO=YES
115     NOMAN=YES
116     export BINDIR DESTDIR NOINFO NOMAN
117     MFLAG=
118     for wantdir in bin/chflags bin/chmod bin/cp bin/ls bin/mkdir bin/mv bin/sh \
119                    sbin/ifconfig sbin/mount sbin/mount_nfs sbin/reboot \
120                    usr.bin/find usr.bin/xargs ; do
121         if [ -n "$VERBOSE" ] ; then
122             echo ".. Installing ${wantdir} to mini-/bin"
123         fi
124         (cd ${wantdir} && make ${MFLAG} install >/dev/null )
125         if [ $? -ne 0 ] ; then
126             echo "** Error while in ${wantdir} doing 'make install'"
127             echo "**       for DESTDIR=${KERNBINDIR}" 
128             exit 1
129         fi
130     done
131     echo "Done building ${KERNBINDIR}"
132     echo
133     ) || exit 1
134 fi
135
136 #   Start out with no PATH at all.
137 PATH=
138
139 #   Where all the binaries should be coming from.
140 OW_BIN="/bin"
141 OW_SBIN="/sbin"
142 OW_UBIN="/usr/bin"
143 OW_USBIN="/usr/sbin"
144 OW_GUBIN="/usr/bin"
145
146 MKTEMPCMD=/usr/bin/mktemp
147
148 #   I intentionally prefer to have a shorter name here...  We just need a
149 #   unique name, we're not likely to be under attack during installworld!
150 TMPHOLD=`"${MKTEMPCMD}" -q -d ${TMPDIR:-/tmp}/install-oldk.XXX`
151 if [ $? -ne 0 ] ; then
152     echo "** Unable to create temp program-holding directory"
153     exit 1
154 fi
155
156 #   Set the most-restrictive value for PATH that the user is willing to
157 #   shoot for.  The more restrictive we are here, the more likely we
158 #   will catch all references to "unexpected" executables.
159 PATH=${TMPHOLD}:/sbin:/bin:/usr/sbin:/usr/bin
160 if [ -n "$SETMINPATH" ] ; then
161     PATH=${TMPHOLD}
162 fi
163
164 #   Find the most-appropriate version of key commands for this script.
165 #   XXX - It would be nice if we could reliably find the exact kernel that
166 #       we booted up with, and check for the optional mini-/bin in it.
167 COPYCMD=/missing/cp
168 for chkexec in "/rescue/cp" /bin/cp ; do
169     if [ -f "${chkexec}" ] ; then
170         COPYCMD="${chkexec} -p"
171         break
172     fi
173 done
174 LINKCMD=/missing/ln
175 for chkexec in "/rescue/ln" /bin/ln ; do
176     if [ -f "${chkexec}" ] ; then
177         LINKCMD="${chkexec}"
178         break
179     fi
180 done
181 COPYINFO="Copying"
182
183 copy_exec () {
184     srcdir="$1"
185     cmdname="$2"
186     alsoln="$3"
187     srcfile="${srcdir}/${cmdname}"
188     resfile="/rescue/${cmdname}"
189
190     if [ -f "${resfile}" -a -x "${resfile}" ] ; then
191         if [ -n "$VERBOSE" ] ; then
192             echo ".. Linking ${TMPHOLD}/RESCUE to ${cmdname}"
193         fi
194         ${LINKCMD} "${TMPHOLD}/RESCUE" "${TMPHOLD}/${cmdname}"
195         if [ $? -ne 0 ] ; then
196             echo "** Error Linking '${cmdname}'"
197             exit 1
198         fi
199     elif [ -f "${srcfile}" -a -x "${srcfile}" ] ; then
200         if [ -n "$VERBOSE" ] ; then
201             echo ".. ${COPYINFO} ${srcfile}"
202         fi
203         ${COPYCMD} "${srcfile}" "${TMPHOLD}"
204         if [ $? -ne 0 ] ; then
205             echo "** Error ${COPYINFO} '${srcfile}'"
206             exit 1
207         fi
208     else
209         echo "** Cannot find ${cmdname} in /rescue or ${srcdir}?"
210         exit 1
211     fi
212
213     if [ -n "${alsoln}" ] ; then
214         if [ -n "$VERBOSE" ] ; then
215             echo ".. Linking '${cmdname}' as '${alsoln}' "
216         fi
217         ${LINKCMD} "${TMPHOLD}/${cmdname}" "${TMPHOLD}/${alsoln}"
218         if [ $? -ne 0 ] ; then
219             echo "** Error Linking '${cmdname}'"
220             exit 1
221         fi
222     fi
223 }
224
225 # The programs listed in the following `do' loop are all the same programs
226 # that the standard 'installworld' target wants to make copies of, except
227 # that this has special-cases for `awk', `[', and `egrep'.  This script
228 # also adds the commands `cp', `install', `id' and `which', because those
229 # are also *used* by the standard `make installworld' target, although
230 # that target doesn't bother to make copies of those programs.  The `sleep'
231 # command is also added, but only because it is used in this script.  And
232 # `script' is included just because it can be useful when testing this script.
233 #
234 # Note that this means there will be two copies made of these files
235 # (because the 'make installworld' target is still going to copy them a
236 # second time).
237
238 #   Do the `cp' command first, because this script does so much with it.
239 #   This is done as a special case, because it's the initial program
240 #   from /rescue (if /rescue exists).
241 chkfile="/rescue/cp"
242 if [ -f "${chkfile}" -a -x "${chkfile}" ] ; then
243     if [ -n "$VERBOSE" ] ; then
244         echo ".. Copying ${chkfile} to 'RESCUE'"
245     fi
246     ${COPYCMD} "${chkfile}" "${TMPHOLD}/RESCUE"
247 fi
248 copy_exec "${OW_BIN}" cp
249
250 #   Do the `ln' command as the second one, for similar reasons.
251 copy_exec "${OW_BIN}" ln
252
253 #   Awk is also called 'nawk'
254 copy_exec "${OW_UBIN}" nawk awk
255
256 #   The `install' comand is not a special case in this script,
257 #   but it is in the installworld_newk script.
258 copy_exec "${OW_UBIN}" install
259
260 #   Worried about the extra disk space that this script uses up in /tmp?  Well,
261 #   just specify the -S option, and this script will create symlinks instead of
262 #   copying the files.  Note that the original files might be NFS-mounted, and
263 #   /tmp might be a memory-based file system, so the `installworld' might go
264 #   much faster when copies are done here instead of symlinks.
265 if [ -n "$SYMLINKS" ] ; then
266     echo "The -S (symlinks) option is ignored in installworld_oldk"
267     # COPYINFO="Linking to"
268     # COPYCMD="ln -s"
269     # LINKCMD="ln -s"
270 fi
271
272 for prog in cap_mkdb cat chflags chmod chown date \
273             echo       find grep    make mkdir mtree mv \
274             pwd_mkdb rm sed sh sysctl test true uname wc zic \
275             hostname id ls sleep script umount which xargs
276 do
277     gotmatch=
278     for chkdir in "${OW_BIN}" "${OW_SBIN}" "${OW_UBIN}" "${OW_USBIN}"
279     do
280         if [ -f "${chkdir}/${prog}" -a -x "${chkdir}/${prog}" ] ; then
281             gotmatch=yes
282             copy_exec "${chkdir}" "${prog}"
283             if [ $? -ne 0 ] ; then
284                 exit 1
285             fi
286             break
287         fi
288     done
289     if [ -z "$gotmatch" ] ; then
290         echo "** Did not find '${prog}' ?"
291     fi
292 done
293
294 #   Special case to handle '[', which we know is the same as 'test'
295 if [ -x ${TMPHOLD}/test ] ; then
296     if [ -n "$VERBOSE" ] ; then
297         echo ".. Linking 'test' as '[' "
298     fi
299     ${LINKCMD} ${TMPHOLD}/test ${TMPHOLD}/[
300 fi
301 #   Special case for 'egrep', which is the same as 'grep'
302 if [ -x ${TMPHOLD}/grep ] ; then
303     if [ -n "$VERBOSE" ] ; then
304         echo ".. Linking 'grep' as 'egrep' "
305     fi
306     ${LINKCMD} ${TMPHOLD}/grep ${TMPHOLD}/egrep
307 fi
308
309 #   Have to duplicate the standard makefile, to make a few changes.
310
311 #   First find the setting of PATH.  Insert a line in front of that
312 #   which uses the (undocumented) .SHELL feature to get 'make' to
313 #   use the newer version of /bin/sh that we just made a copy of.
314 #   Then alter the PATH setting so that all make targets check our
315 #   directory of copied files first.  If '-M' was given, then have
316 #   a PATH setting that looks ONLY at our copied files.
317 #    
318 #   XXX - the .SHELL feature did NOT seem to work the way that I
319 #       wanted it to, but that is not a problem for now.  It can
320 #       be looked into at some later date...
321 nawk '/^PATH=/ { \
322             print "#   Try to get the make cmd to use an alternate /bin/sh." ; \
323             print ".SHELL : name=sh path=" TDIR "/sh"  ; \
324             print "" ; \
325             if (WANTMIN == "yes") \
326                 sub(/^PATH *=[ \t]*.*/, "PATH=\t" TDIR ); \
327             else \
328                 sub(/^PATH *=[ \t]*/, "PATH=\t" TDIR ":"); \
329             } \
330       /-f Makefile.inc1/ { \
331             sub(/Makefile.inc1/, TDIR "/Makefile.inc1" ); \
332             } \
333       { print $0 }' \
334     "TDIR=${TMPHOLD}" "WANTMIN=${SETMINPATH}" Makefile > ${TMPHOLD}/Makefile
335
336 #   In the case of this script, we want the new libraries to be the
337 #   *last* things that are installed (since we will be running some
338 #   programs which expect the present libraries).  However, we do
339 #   still have the problem that 'make' explicitly uses /bin/sh, so
340 #   the install of 'bin' must be delayed to after those libraries.
341 #   [Someone recently committed a total restructuring of Makefile.inc1,
342 #   so the following  has to be setup such that it works with either
343 #   formats.  That's why it seems to be doing everything twice.]
344 nawk 'BEGIN { GOTSBIN = 0; } \
345       /^# Put initial settings/ { \
346             print "#   Try to get the make cmd to use an alternate /bin/sh." ; \
347             print ".SHELL : name=sh path=" TDIR "/sh"  ; \
348             print "" ; \
349             } \
350       /^SUBDIR=[\t ]*share\/info .*bin/ { \
351             print "#   Try to get the make cmd to use an alternate /bin/sh." ; \
352             print ".SHELL : name=sh path=" TDIR "/sh"  ; \
353             print "" ; \
354             } \
355       /exists\(.*\/sbin\)/ { \
356             if (GOTSBIN == 0) { \
357                 GOTSBIN = 1;
358                 print "" ; \
359                 print "#   For installworld_oldk processing, forget" ; \
360                 print "#   all the subdirectories before sbin..."; \
361                 print "SUBDIR=" ; \
362                 } \
363             } \
364       /^SUBDIR\+=sbin/ { \
365             if (GOTSBIN == 0) { \
366                 GOTSBIN = 1;
367                 print "" ; \
368                 print "#   For installworld_oldk processing, forget" ; \
369                 print "#   all the subdirectories before sbin..."; \
370                 print "SUBDIR=" ; \
371                 } \
372             } \
373       /^# These are last, since it is/ { \
374             print "#   These dirs are done last for installworld_oldk." ; \
375             print ".if exists(${.CURDIR}/lib)" ; \
376             print "SUBDIR+= lib" ; \
377             print ".endif" ; \
378             print ".if exists(${.CURDIR}/libexec)" ; \
379             print "SUBDIR+= libexec"; \
380             print ".endif"; \
381             print ".if exists(${.CURDIR}/bin)" ; \
382             print "SUBDIR+= bin"; \
383             print ".endif"; \
384             } \
385       /-f Makefile.inc1/ { \
386             sub(/Makefile.inc1/, TDIR "/Makefile.inc1" ); \
387             } \
388      { print $0 } \
389      END    { \
390             if (GOTSBIN == 0) { \
391                 print "ERROR: No \"sbin\" match in Makefile.inc1" > "/dev/stderr"; \
392                 } \
393             }' \
394     "TDIR=${TMPHOLD}" Makefile.inc1 > "${TMPHOLD}/Makefile.inc1"
395
396 echo ""
397 echo "The key programs needed by 'make installworld' have been copied."
398 if [ -n "$VERBOSE" ] ; then
399     ls -C ${TMPHOLD}
400     echo ""
401 fi
402
403 # XXX - Add some "do-nothing" settings so that we won't clobber any
404 #       more than we need to.  I wish we could avoid having to set
405 #       them as environment variables, particularly for the case
406 #       where the user chooses to type in all the commands.  The
407 #       more a user has to type, the more chances for a typo...
408 NO_FORTRAN=yes
409 NO_RESCUE=yes
410 NOGAMES=yes
411 NOINFO=yes
412 NOMAN=yes
413 NOSHARE=yes
414 export NO_FORTRAN NO_RESCUE NOGAMES NOINFO NOMAN NOSHARE
415
416 #   The sparc64_installcheck will want this in the environment.
417 NEWSPARC_TIMETYPE=__int64_t
418 export NEWSPARC_TIMETYPE
419
420 # See if the user wants us to go ahead with 'installworld',
421 #     or just tell them what steps they need to do.
422 if [ -z "${DOMAKE}" ] ; then
423     echo "Do you want to proceed with the abridged 'installworld'? "
424     read -p "(y/n) ? "  DOMAKE remline
425     echo " "
426 fi
427 if [ -n "`echo /y/yes/okay/ok/ | grep -i \"/${DOMAKE}/\"`" ] ; then
428     echo "Okay then, this script has set:"
429     echo "    NO_FORTRAN NO_RESCUE NOGAMES NOINFO NOMAN NOSHARE"
430     echo "and:"
431     echo "    NEWSPARC_TIMETYPE=__int64_t"
432     echo "    PATH=${PATH}"
433     echo "and will now execute the command:"
434     echo "    make -f ${TMPHOLD}/Makefile installworld"
435     sleep 4
436     make -f ${TMPHOLD}/Makefile installworld
437 else
438     echo "When you are ready to continue, enter the commands:"
439     echo "    NO_FORTRAN=yes"
440     echo "    NO_RESCUE=yes"
441     echo "    NOGAMES=yes"
442     echo "    NOINFO=yes"
443     echo "    NOMAN=yes"
444     echo "    NOSHARE=yes"
445     echo "    export NO_FORTRAN NO_RESCUE NOGAMES NOINFO NOMAN NOSHARE"
446     echo "    NEWSPARC_TIMETYPE=__int64_t"
447     echo "    export NEWSPARC_TIMETYPE"
448     echo "and:"
449     echo "    PATH=${PATH}"
450     echo "or:"
451     echo "    PATH=${TMPHOLD}:\${PATH}"
452     echo "and:"
453     echo "    make -f ${TMPHOLD}/Makefile installworld"
454 fi