2 # -------+---------+---------+---------+---------+---------+---------+---------+
3 # Copyright (c) 2004 - Garance Alistair Drosehn <gad@FreeBSD.org>.
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
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.
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
28 # -------+---------+---------+---------+---------+---------+---------+---------+
30 # -------+---------+---------+---------+---------+---------+---------+---------+
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.
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.
43 # -------+---------+---------+---------+---------+---------+---------+---------+
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`"
50 echo "This script must be run from /usr/src! (or equivalent)"
65 -S) echo "-S (symlinks) is ignored in installworld_oldk." ;;
70 *) echo "Invalid option: $1" ; BADOPT=yes ;;
74 if [ -n "$BADOPT" ] ; then
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."
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 "* + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - *"
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
100 elif [ -z "${DOMINI}" ] ; then
103 if [ -n "`echo /y/yes/okay/ok/ | grep -i \"/${DOMINI}/\"`" ] ; then
104 KERNBINDIR=/boot/kernel/bin
105 if [ -e ${KERNBINDIR} ] ; then
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.
112 DESTDIR=${KERNBINDIR}
116 export BINDIR DESTDIR NOINFO NOMAN
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"
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}"
131 echo "Done building ${KERNBINDIR}"
136 # Start out with no PATH at all.
139 # Where all the binaries should be coming from.
146 MKTEMPCMD=/usr/bin/mktemp
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"
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
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.
168 for chkexec in "/rescue/cp" /bin/cp ; do
169 if [ -f "${chkexec}" ] ; then
170 COPYCMD="${chkexec} -p"
175 for chkexec in "/rescue/ln" /bin/ln ; do
176 if [ -f "${chkexec}" ] ; then
187 srcfile="${srcdir}/${cmdname}"
188 resfile="/rescue/${cmdname}"
190 if [ -f "${resfile}" -a -x "${resfile}" ] ; then
191 if [ -n "$VERBOSE" ] ; then
192 echo ".. Linking ${TMPHOLD}/RESCUE to ${cmdname}"
194 ${LINKCMD} "${TMPHOLD}/RESCUE" "${TMPHOLD}/${cmdname}"
195 if [ $? -ne 0 ] ; then
196 echo "** Error Linking '${cmdname}'"
199 elif [ -f "${srcfile}" -a -x "${srcfile}" ] ; then
200 if [ -n "$VERBOSE" ] ; then
201 echo ".. ${COPYINFO} ${srcfile}"
203 ${COPYCMD} "${srcfile}" "${TMPHOLD}"
204 if [ $? -ne 0 ] ; then
205 echo "** Error ${COPYINFO} '${srcfile}'"
209 echo "** Cannot find ${cmdname} in /rescue or ${srcdir}?"
213 if [ -n "${alsoln}" ] ; then
214 if [ -n "$VERBOSE" ] ; then
215 echo ".. Linking '${cmdname}' as '${alsoln}' "
217 ${LINKCMD} "${TMPHOLD}/${cmdname}" "${TMPHOLD}/${alsoln}"
218 if [ $? -ne 0 ] ; then
219 echo "** Error Linking '${cmdname}'"
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.
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
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).
242 if [ -f "${chkfile}" -a -x "${chkfile}" ] ; then
243 if [ -n "$VERBOSE" ] ; then
244 echo ".. Copying ${chkfile} to 'RESCUE'"
246 ${COPYCMD} "${chkfile}" "${TMPHOLD}/RESCUE"
248 copy_exec "${OW_BIN}" cp
250 # Do the `ln' command as the second one, for similar reasons.
251 copy_exec "${OW_BIN}" ln
253 # Awk is also called 'nawk'
254 copy_exec "${OW_UBIN}" nawk awk
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
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"
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
278 for chkdir in "${OW_BIN}" "${OW_SBIN}" "${OW_UBIN}" "${OW_USBIN}"
280 if [ -f "${chkdir}/${prog}" -a -x "${chkdir}/${prog}" ] ; then
282 copy_exec "${chkdir}" "${prog}"
283 if [ $? -ne 0 ] ; then
289 if [ -z "$gotmatch" ] ; then
290 echo "** Did not find '${prog}' ?"
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 '[' "
299 ${LINKCMD} ${TMPHOLD}/test ${TMPHOLD}/[
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' "
306 ${LINKCMD} ${TMPHOLD}/grep ${TMPHOLD}/egrep
309 # Have to duplicate the standard makefile, to make a few changes.
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.
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...
322 print "# Try to get the make cmd to use an alternate /bin/sh." ; \
323 print ".SHELL : name=sh path=" TDIR "/sh" ; \
325 if (WANTMIN == "yes") \
326 sub(/^PATH *=[ \t]*.*/, "PATH=\t" TDIR ); \
328 sub(/^PATH *=[ \t]*/, "PATH=\t" TDIR ":"); \
330 /-f Makefile.inc1/ { \
331 sub(/Makefile.inc1/, TDIR "/Makefile.inc1" ); \
334 "TDIR=${TMPHOLD}" "WANTMIN=${SETMINPATH}" Makefile > ${TMPHOLD}/Makefile
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" ; \
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" ; \
355 /exists\(.*\/sbin\)/ { \
356 if (GOTSBIN == 0) { \
359 print "# For installworld_oldk processing, forget" ; \
360 print "# all the subdirectories before sbin..."; \
365 if (GOTSBIN == 0) { \
368 print "# For installworld_oldk processing, forget" ; \
369 print "# all the subdirectories before sbin..."; \
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" ; \
378 print ".if exists(${.CURDIR}/libexec)" ; \
379 print "SUBDIR+= libexec"; \
381 print ".if exists(${.CURDIR}/bin)" ; \
382 print "SUBDIR+= bin"; \
385 /-f Makefile.inc1/ { \
386 sub(/Makefile.inc1/, TDIR "/Makefile.inc1" ); \
390 if (GOTSBIN == 0) { \
391 print "ERROR: No \"sbin\" match in Makefile.inc1" > "/dev/stderr"; \
394 "TDIR=${TMPHOLD}" Makefile.inc1 > "${TMPHOLD}/Makefile.inc1"
397 echo "The key programs needed by 'make installworld' have been copied."
398 if [ -n "$VERBOSE" ] ; then
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...
414 export NO_FORTRAN NO_RESCUE NOGAMES NOINFO NOMAN NOSHARE
416 # The sparc64_installcheck will want this in the environment.
417 NEWSPARC_TIMETYPE=__int64_t
418 export NEWSPARC_TIMETYPE
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
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"
431 echo " NEWSPARC_TIMETYPE=__int64_t"
433 echo "and will now execute the command:"
434 echo " make -f ${TMPHOLD}/Makefile installworld"
436 make -f ${TMPHOLD}/Makefile installworld
438 echo "When you are ready to continue, enter the commands:"
439 echo " NO_FORTRAN=yes"
440 echo " NO_RESCUE=yes"
445 echo " export NO_FORTRAN NO_RESCUE NOGAMES NOINFO NOMAN NOSHARE"
446 echo " NEWSPARC_TIMETYPE=__int64_t"
447 echo " export NEWSPARC_TIMETYPE"
451 echo " PATH=${TMPHOLD}:\${PATH}"
453 echo " make -f ${TMPHOLD}/Makefile installworld"