xref: /netbsd/distrib/miniroot/upgrade.sh (revision 40de559a)
1#!/bin/sh
2#	$NetBSD: upgrade.sh,v 1.24 2019/04/04 20:51:35 christos Exp $
3#
4# Copyright (c) 1996-2000,2006 The NetBSD Foundation, Inc.
5# All rights reserved.
6#
7# This code is derived from software contributed to The NetBSD Foundation
8# by Jason R. Thorpe.
9#
10# Redistribution and use in source and binary forms, with or without
11# modification, are permitted provided that the following conditions
12# are met:
13# 1. Redistributions of source code must retain the above copyright
14#    notice, this list of conditions and the following disclaimer.
15# 2. Redistributions in binary form must reproduce the above copyright
16#    notice, this list of conditions and the following disclaimer in the
17#    documentation and/or other materials provided with the distribution.
18#
19# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29# POSSIBILITY OF SUCH DAMAGE.
30#
31
32#	NetBSD installation script.
33#	In a perfect world, this would be a nice C program, with a reasonable
34#	user interface.
35
36ROOTDISK=""				# filled in below
37
38trap "unmount_fs -fast /tmp/fstab.shadow > /dev/null 2>&1; rm -f /tmp/fstab.shadow" 0
39
40MODE="upgrade"
41
42# include machine-dependent functions
43# The following functions must be provided:
44#	md_copy_kernel()	- copy a kernel to the installed disk
45#	md_get_diskdevs()	- return available disk devices
46#	md_get_cddevs()		- return available CD-ROM devices
47#	md_get_ifdevs()		- return available network interfaces
48#	md_get_partition_range() - return range of valid partition letters
49#	md_installboot()	- install boot-blocks on disk
50#	md_labeldisk()		- put label on a disk
51#	md_welcome_banner()	- display friendly message
52#	md_not_going_to_install() - display friendly message
53#	md_congrats()		- display friendly message
54#	md_set_term		- set terminal type
55#	md_makerootwritable	- what it says
56# optional:
57#	md_upgrade_prep_needed	- variable: set if you md_prepare_upgrade()
58#	md_prepare_upgrade	- any machine dependent preparations
59#	md_view_labels_possible	- variable: md_view_labels defined
60#	md_view_labels		- peek at preexisting disk labels, to
61#				  better identify disks
62
63# we need to make sure .'s below work if this directory is not in $PATH
64# dirname may not be available but expr is
65Mydir=$(expr $0 : '^\(.*\)/[^/]*$')
66Mydir=$(cd ${Mydir:-.}; pwd)
67
68# this is the most likely place to find the binary sets
69# so save them having to type it in
70Default_sets_dir=$Mydir/../../binary/sets
71
72# include machine dependent subroutines
73. $Mydir/install.md
74
75# include common subroutines
76. $Mydir/install.sub
77
78# which sets?
79THESETS="$UPGRSETS $MDSETS"
80
81# Files that moved between 1.2 and 1.3
82RELOCATED_FILES_13="${RELOCATED_FILES_13} /sbin/dumpfs /usr/sbin/dumpfs"
83RELOCATED_FILES_13="${RELOCATED_FILES_13} /sbin/dumplfs /usr/sbin/dumplfs"
84RELOCATED_FILES_13="${RELOCATED_FILES_13} /sbin/nfsd /usr/sbin/nfsd"
85RELOCATED_FILES_13="${RELOCATED_FILES_13} /sbin/nfsiod /usr/sbin/nfsiod"
86RELOCATED_FILES_13="${RELOCATED_FILES_13} /sbin/mountd /usr/sbin/mountd"
87RELOCATED_FILES_13="${RELOCATED_FILES_13} /sbin/quotacheck /usr/sbin/quotacheck"
88RELOCATED_FILES_13="${RELOCATED_FILES_13} /sbin/rtquery /usr/sbin/rtquery"
89
90# Files that moved between 1.3 and 1.4
91RELOCATED_FILES_14="${RELOCATED_FILES_14} /sbin/newlfs /sbin/newfs_lfs"
92RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/games/chess /usr/games/chess"
93RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/games/hide/chess /usr/games/hide/chess"
94RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/share/games/gnuchess.book /usr/share/games/gnuchess.book"
95RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/share/games/atc/ATC_scores /usr/share/games/atc/ATC_scores"
96RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/share/games/atc/ATC_scores /usr/share/games/atc/ATC_scores"
97RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/lib/libamu.a /usr/lib/libamu.a"
98RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/lib/libamu_p.a /usr/lib/libamu_p.a"
99RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/lib/libamu_pic.a /usr/lib/libamu_pic.a"
100RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/lib/libbfd.a /usr/lib/libbfd.a"
101RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/lib/libbfd_pic.a /usr/lib/libbfd_pic.a"
102RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/lib/libg++.a /usr/lib/libg++.a"
103RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/lib/libg++_p.a /usr/lib/libg++_p.a"
104RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/lib/libg++_pic.a /usr/lib/libg++_pic.a"
105
106RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/sbin/gettable /usr/sbin/gettable"
107RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/sbin/dig /usr/bin/dig"
108RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/sbin/dnsquery /usr/bin/dnsquery"
109RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/sbin/htable /usr/bin/htable"
110RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/sbin/htable /usr/sbin/htable"
111RELOCATED_FILES_14="${RELOCATED_FILES_14} /usr/sbin/nslookup /usr/sbin/nslookup"
112
113rm_relocated_files()
114{
115	# ($n, $(n+1)): pairs of (old,new) locations of relocated files
116	while [ $# -ge 2 ]; do
117		if [ -f "$2" ]; then
118			echo Removing "$1";
119			rm -f "$1"
120		fi
121		shift 2
122	done
123}
124
125# Good {morning,afternoon,evening,night}.
126md_welcome_banner
127echo -n "Proceed with upgrade? [n] "
128getresp "n"
129case "$resp" in
130	y*|Y*)
131		echo	"Cool!  Let's get to it..."
132		;;
133	*)
134		md_not_going_to_install
135		exit
136		;;
137esac
138
139# Deal with terminal issues
140md_set_term
141
142# XXX Work around vnode aliasing bug (thanks for the tip, Chris...)
143ls -l /dev > /dev/null 2>&1
144
145# Make sure we can write files (at least in /tmp)
146# This might make an MFS mount on /tmp, or it may
147# just re-mount the root with read-write enabled.
148md_makerootwritable
149
150test "$md_view_labels_possible" && md_view_labels
151
152while [ -z "${ROOTDISK}" ]; do
153	getrootdisk
154done
155
156# Assume partition 'a' of $ROOTDISK is for the root filesystem.  Confirm
157# this with the user.  Check and mount the root filesystem.
158resp=""			# force one iteration
159while [ -z "${resp}" ]; do
160	echo -n	"Root filesystem? [${ROOTDISK}a] "
161	getresp "${ROOTDISK}a"
162	_root_filesystem="/dev/$(basename $resp)"
163	if [ ! -b ${_root_filesystem} ]; then
164		echo "Sorry, ${resp} is not a block device."
165		resp=""	# force loop to repeat
166	fi
167done
168
169echo	"Checking root filesystem..."
170if ! fsck -pf ${_root_filesystem}; then
171	echo	"ERROR: can't check root filesystem!"
172	exit 1
173fi
174
175echo	"Mounting root filesystem..."
176if ! mount -o ro ${_root_filesystem} /mnt; then
177	echo	"ERROR: can't mount root filesystem!"
178	exit 1
179fi
180
181# Grab the fstab so we can munge it for our own use.
182if [ ! -f /mnt/etc/fstab ]; then
183	echo	"ERROR: no /etc/fstab!"
184	exit 1
185fi
186
187# Grab the hosts table so we can use it.
188if [ ! -f /mnt/etc/hosts ]; then
189	echo	"ERROR: no /etc/hosts!"
190	exit 1
191fi
192cp /mnt/etc/hosts /tmp/hosts
193
194# Start up the network in same/similar configuration as the installed system
195# uses.
196cat << \__network_config_1
197
198The upgrade program would now like to enable the network.  It will use the
199configuration already stored on the root filesystem.  This is required
200if you wish to use the network installation capabilities of this program.
201
202__network_config_1
203echo -n	"Enable network? [y] "
204getresp "y"
205case "$resp" in
206	y*|Y*)
207		if ! enable_network; then
208			echo "ERROR: can't enable network!"
209			exit 1
210		fi
211
212		cat << \__network_config_2
213
214You will now be given the opportunity to escape to the command shell to
215do any additional network configuration you may need.  This may include
216adding additional routes, if needed.  In addition, you might take this
217opportunity to redo the default route in the event that it failed above.
218
219__network_config_2
220		echo -n "Escape to shell? [n] "
221		getresp "n"
222		case "$resp" in
223			y*|Y*)
224				echo "Type 'exit' to return to upgrade."
225				sh
226				;;
227
228			*)
229				;;
230		esac
231		;;
232	*)
233		;;
234esac
235
236# Now that the network has been configured, it is safe to configure the
237# fstab.  We remove all but ufs/ffs.
238(
239	> /tmp/fstab
240	while read _dev _mp _fstype _rest ; do
241		if [ "${_fstype}" = "ufs" ] ||
242		   [ "${_fstype}" = "ffs" ]; then
243			if [ "${_fstype}" = "ufs" ]; then
244				# Convert ufs to ffs.
245				_fstype=ffs
246			fi
247			echo "$_dev $_mp $_fstype $_rest" >> /tmp/fstab
248		fi
249	done
250) < /mnt/etc/fstab
251
252echo	"The fstab is configured as follows:"
253echo	""
254cat /tmp/fstab
255cat << \__fstab_config_1
256
257You may wish to edit the fstab.  For example, you may need to resolve
258dependencies in the order which the filesystems are mounted.  Note that
259this fstab is only for installation purposes, and will not be copied into
260the root filesystem.
261
262__fstab_config_1
263echo -n	"Edit the fstab? [n] "
264getresp "n"
265case "$resp" in
266	y*|Y*)
267		${EDITOR} /tmp/fstab
268		;;
269
270	*)
271		;;
272esac
273
274echo	""
275munge_fstab /tmp/fstab /tmp/fstab.shadow
276
277if ! umount /mnt; then
278	echo	"ERROR: can't unmount previously mounted root!"
279	exit 1
280fi
281
282# Check all of the filesystems.
283check_fs /tmp/fstab.shadow
284
285# Mount filesystems.
286mount_fs /tmp/fstab.shadow
287
288# Machine dependent preparation.
289test "$md_upgrade_prep_needed" && {
290	md_prepare_upgrade || {
291		cat << 'EOF'
292The preparations for upgrading your machine did not complete successfully.
293
294EOF
295		echo -n "Continue anyway? [n]"
296		getresp "n"
297		case "$resp" in
298			y*|Y*)
299				;;
300			*)
301				exit 1
302				;;
303		esac
304	}
305}
306
307
308echo -n	"Are the upgrade sets on one of your normally mounted (local) filesystems? [y] "
309getresp "y"
310case "$resp" in
311	y*|Y*)
312		get_localdir /mnt
313		;;
314	*)
315		;;
316esac
317
318# Install sets.
319install_sets
320
321# Remove files that have just been installed in a new location
322# from the old location
323rm_relocated_files $(eval echo \\$RELOCATED_FILES_${VERSION})
324
325# Get timezone info
326get_timezone
327
328# Fix up the fstab.
329echo -n	"Converting ufs to ffs in /etc/fstab..."
330(
331	> /tmp/fstab
332	while read _dev _mp _fstype _rest ; do
333		if [ "${_fstype}" = "ufs" ]; then
334			# Convert ufs to ffs.
335			_fstype=ffs
336		fi
337		echo "$_dev $_mp $_fstype $_rest" >> /tmp/fstab
338	done
339) < /mnt/etc/fstab
340echo	"done."
341echo -n	"Would you like to edit the resulting fstab? [y] "
342getresp "y"
343case "$resp" in
344	y*|Y*)
345		${EDITOR} /tmp/fstab
346		;;
347
348	*)
349		;;
350esac
351
352# Copy in configuration information and make devices in target root.
353(
354	cd /tmp
355	for file in fstab; do
356		if [ -f $file ]; then
357			echo -n "Copying $file..."
358			cp $file /mnt/etc/$file
359			echo "done."
360		fi
361	done
362
363	echo -n "Installing timezone link..."
364	rm -f /mnt/etc/localtime
365	ln -s /usr/share/zoneinfo/$TZ /mnt/etc/localtime
366	echo "done."
367
368	echo -n "Making devices..."
369	_pid=$(twiddle)
370	cd /mnt/dev
371	sh MAKEDEV all
372	kill $_pid
373	echo "done."
374
375	md_copy_kernel
376
377	md_installboot ${ROOTDISK}
378)
379
380unmount_fs /tmp/fstab.shadow
381
382# Pat on the back.
383md_congrats
384
385# ALL DONE!
386exit 0
387