Home | History | Annotate | Line # | Download | only in miniroot
      1 #!/bin/sh
      2 #	$NetBSD: install.sh,v 1.29 2025/08/30 15:14:32 thorpej Exp $
      3 #
      4 # Copyright (c) 1996,1997,1999,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 
     36 FILESYSTEMS="/tmp/filesystems"		# used throughout
     37 FQDN=""					# domain name
     38 
     39 trap "umount /tmp > /dev/null 2>&1" 0
     40 
     41 MODE="install"
     42 
     43 # include machine-dependent functions
     44 # The following functions must be provided:
     45 #	md_copy_kernel()	- copy a kernel to the installed disk
     46 #	md_get_diskdevs()	- return available disk devices
     47 #	md_get_cddevs()		- return available CD-ROM devices
     48 #	md_get_ifdevs()		- return available network interfaces
     49 #	md_get_partition_range() - return range of valid partition letters
     50 #	md_installboot()	- install boot-blocks on disk
     51 #	md_labeldisk()		- put label on a disk
     52 #	md_prep_disklabel()	- label the root disk
     53 #	md_welcome_banner()	- display friendly message
     54 #	md_not_going_to_install() - display friendly message
     55 #	md_congrats()		- display friendly message
     56 #	md_native_fstype()	- native filesystem type for disk installs
     57 #	md_native_fsopts()	- native filesystem options for disk installs
     58 #	md_makerootwritable()	- make root writable (at least /tmp)
     59 
     60 # The following are optional:
     61 #	md_view_labels_possible	- variable: md_view_labels defined
     62 #	md_view_labels		- peek at preexisting disk labels, to 
     63 #				  better identify disks
     64 
     65 # we need to make sure .'s below work if this directory is not in $PATH
     66 # dirname may not be available but expr is
     67 Mydir=$(expr $0 : '^\(.*\)/[^/]*$')
     68 Mydir=$(cd ${Mydir:-.}; pwd)
     69 
     70 # this is the most likely place to find the binary sets
     71 # so save them having to type it in
     72 Default_sets_dir=$Mydir/../../binary/sets
     73 
     74 # include machine dependent subroutines
     75 . $Mydir/install.md
     76 
     77 # include common subroutines
     78 . $Mydir/install.sub
     79 
     80 # which sets?
     81 THESETS="$ALLSETS $MDSETS"
     82 
     83 # Good {morning,afternoon,evening,night}.
     84 md_welcome_banner
     85 echo -n "Proceed with installation? [n] "
     86 getresp "n"
     87 case "$resp" in
     88 	y*|Y*)
     89 		echo	"Cool!  Let's get to it..."
     90 		;;
     91 	*)
     92 		md_not_going_to_install
     93 		exit
     94 		;;
     95 esac
     96 
     97 # XXX Work around vnode aliasing bug (thanks for the tip, Chris...)
     98 ls -l /dev > /dev/null 2>&1
     99 
    100 # Deal with terminal issues
    101 md_set_term
    102 
    103 # Get timezone info
    104 get_timezone
    105 
    106 # Make sure we can write files (at least in /tmp)
    107 # This might make an MFS mount on /tmp, or it may
    108 # just re-mount the root with read-write enabled.
    109 md_makerootwritable
    110 
    111 # Create a disktab file; lets us write to it for temporary
    112 # purposes without mounting the miniroot read-write.
    113 echo "# disktab" > /tmp/disktab.shadow
    114 
    115 test "$md_view_labels_possible" && md_view_labels
    116 
    117 while [ -z "${ROOTDISK}" ]; do
    118 	getrootdisk
    119 done
    120 
    121 # Deal with disklabels, including editing the root disklabel
    122 # and labeling additional disks.  This is machine-dependent since
    123 # some platforms may not be able to provide this functionality.
    124 md_prep_disklabel ${ROOTDISK}
    125 
    126 # Assume partition 'a' of $ROOTDISK is for the root filesystem.  Loop and
    127 # get the rest.
    128 # XXX ASSUMES THAT THE USER DOESN'T PROVIDE BOGUS INPUT.
    129 cat << \__get_filesystems_1
    130 
    131 You will now have the opportunity to enter filesystem information.
    132 You will be prompted for device name and mount point (full path,
    133 including the prepending '/' character).
    134 
    135 Note that these do not have to be in any particular order.  You will
    136 be given the opportunity to edit the resulting 'fstab' file before
    137 any of the filesystems are mounted.  At that time you will be able
    138 to resolve any filesystem order dependencies.
    139 
    140 __get_filesystems_1
    141 
    142 echo	"The following will be used for the root filesystem:"
    143 echo	"	${ROOTDISK}a	/"
    144 
    145 echo	"${ROOTDISK}a	/" > ${FILESYSTEMS}
    146 
    147 resp="not-done"	# force at least one iteration
    148 while [ "$resp" != "done" ]; do
    149 	echo	""
    150 	echo -n	"Device name? [RETURN if you already entered all devices] "
    151 	getresp "done"
    152 	case "$resp" in
    153 	done)
    154 		;;
    155 
    156 	*)
    157 		_device_name=$(basename $resp)
    158 
    159 		# force at least one iteration
    160 		_first_char="X"
    161 		while [ "${_first_char}" != "/" ]; do
    162 			echo -n "Mount point? "
    163 			getresp ""
    164 			_mount_point=$resp
    165 			if [ "${_mount_point}" = "/" ]; then
    166 				# Invalid response; no multiple roots
    167 				_first_char="X"
    168 			else
    169 				_first_char=$(firstchar ${_mount_point})
    170 			fi
    171 		done
    172 		echo "${_device_name}	${_mount_point}" >> ${FILESYSTEMS}
    173 		resp="X"	# force loop to repeat
    174 		;;
    175 	esac
    176 done
    177 
    178 # configure swap
    179 resp=""		# force at least one iteration
    180 while [ -z "${resp}" ]; do
    181 	echo -n	"Ok to configure ${ROOTDISK}b as a swap device? [] "
    182 	getresp ""
    183 	case "$resp" in
    184 	y*|Y*)
    185 		echo "${ROOTDISK}b	swap" >> ${FILESYSTEMS}
    186 		;;
    187 	n*|N*)
    188 		;;
    189 	*)	;;
    190 	esac
    191 done
    192 
    193 
    194 echo	""
    195 echo	"You have configured the following devices and mount points:"
    196 echo	""
    197 cat ${FILESYSTEMS}
    198 echo	""
    199 echo	"Filesystems will now be created on these devices.  If you made any"
    200 echo -n	"mistakes, you may edit this now.  Edit? [n] "
    201 getresp "n"
    202 case "$resp" in
    203 	y*|Y*)
    204 		${EDITOR} ${FILESYSTEMS}
    205 		;;
    206 	*)
    207 		;;
    208 esac
    209 
    210 # Loop though the file, place filesystems on each device.
    211 echo	"Creating filesystems..."
    212 (
    213 	while read _device_name _mp; do
    214 		if [ "$_mp" != "swap" ]; then
    215 			newfs /dev/r${_device_name}
    216 			echo ""
    217 		fi
    218 	done
    219 ) < ${FILESYSTEMS}
    220 
    221 # Get network configuration information, and store it for placement in the
    222 # root filesystem later.
    223 cat << \__network_config_1
    224 You will now be given the opportunity to configure the network.  This will
    225 be useful if you need to transfer the installation sets via FTP or NFS.
    226 Even if you choose not to transfer installation sets that way, this
    227 information will be preserved and copied into the new root filesystem.
    228 
    229 Note, enter all symbolic host names WITHOUT the domain name appended.
    230 I.e. use 'hostname' NOT 'hostname.domain.name'.
    231 
    232 __network_config_1
    233 echo -n	"Configure the network? [y] "
    234 getresp "y"
    235 case "$resp" in
    236 	y*|Y*)
    237 		resp=""		# force at least one iteration
    238 		if [ -f /etc/myname ]; then
    239 			resp=$(cat /etc/myname)
    240 		fi
    241 		echo -n "Enter system hostname: [$resp] "
    242 		while [ -z "${resp}" ]; do
    243 			getresp "$resp"
    244 		done
    245 		hostname $resp
    246 		echo $resp > /tmp/myname
    247 
    248 		echo -n "Enter DNS domain name: "
    249 		getresp "none"
    250 		if [ "${resp:-none}" != "none" ]; then
    251 			FQDN=$resp
    252 		fi
    253 
    254 		configurenetwork
    255 
    256 		echo -n "Enter IP address of default route: [none] "
    257 		getresp "none"
    258 		if [ "${resp:-none}" != "none" ]; then
    259 			route delete default > /dev/null 2>&1
    260 			if route add default $resp > /dev/null ; then
    261 				echo $resp > /tmp/mygate
    262 			fi
    263 		fi
    264 
    265 		resp="none"
    266 		if [ -n "${FQDN}" ]; then
    267 			echo -n	"Enter IP address of primary nameserver: [none] "
    268 			getresp "none"
    269 		fi
    270 		if [ "${resp:-none}" != "none" ]; then
    271 			echo "domain $FQDN" > /tmp/resolv.conf
    272 			echo "nameserver $resp" >> /tmp/resolv.conf
    273 			echo "search $FQDN" >> /tmp/resolv.conf
    274 
    275 			echo -n "Would you like to use the nameserver now? [y] "
    276 			getresp "y"
    277 			case "$resp" in
    278 				y*|Y*)
    279 					cp /tmp/resolv.conf \
    280 					    /tmp/resolv.conf.shadow
    281 					;;
    282 
    283 				*)
    284 					;;
    285 			esac
    286 		fi
    287 
    288 		echo ""
    289 		echo "The host table is as follows:"
    290 		echo ""
    291 		cat /tmp/hosts
    292 		echo ""
    293 		echo "You may want to edit the host table in the event that"
    294 		echo "you need to mount an NFS server."
    295 		echo -n "Would you like to edit the host table? [n] "
    296 		getresp "n"
    297 		case "$resp" in
    298 			y*|Y*)
    299 				${EDITOR} /tmp/hosts
    300 				;;
    301 
    302 			*)
    303 				;;
    304 		esac
    305 
    306 		cat << \__network_config_2
    307 
    308 You will now be given the opportunity to escape to the command shell to
    309 do any additional network configuration you may need.  This may include
    310 adding additional routes, if needed.  In addition, you might take this
    311 opportunity to redo the default route in the event that it failed above.
    312 If you do change the default route, and wish for that change to carry over
    313 to the installed system, execute the following command at the shell
    314 prompt:
    315 
    316 	echo <ip_address_of_gateway> > /tmp/mygate
    317 
    318 where <ip_address_of_gateway> is the IP address of the default router.
    319 
    320 __network_config_2
    321 		echo -n "Escape to shell? [n] "
    322 		getresp "n"
    323 		case "$resp" in
    324 			y*|Y*)
    325 				echo "Type 'exit' to return to install."
    326 				sh
    327 				;;
    328 
    329 			*)
    330 				;;
    331 		esac
    332 		;;
    333 	*)
    334 		;;
    335 esac
    336 
    337 # Now that the network has been configured, it is safe to configure the
    338 # fstab.
    339 (
    340 	while read _dev _mp; do
    341 		if [ "$_mp" = "/" ]; then
    342 			echo /dev/$_dev $_mp ffs rw 1 1
    343 		elif [ "$_mp" = "swap" ]; then
    344 			echo /dev/$_dev none swap sw 0 0
    345 		else
    346 			echo /dev/$_dev $_mp ffs rw 1 2
    347 		fi
    348 	done
    349 	
    350 	#
    351 	# A PTYFS instance is required for programs that use
    352 	# pseudo-terminals (e.g. sshd).
    353 	#
    354 	echo ptyfs /dev/pts ptyfs rw 0 0
    355 ) < ${FILESYSTEMS} > /tmp/fstab
    356 
    357 echo	"The fstab is configured as follows:"
    358 echo	""
    359 cat /tmp/fstab
    360 cat << \__fstab_config_1
    361 
    362 You may wish to edit the fstab.  For example, you may need to resolve
    363 dependencies in the order which the filesystems are mounted.  You may
    364 also wish to take this opportunity to place NFS mounts in the fstab.
    365 This would be especially useful if you plan to keep '/usr' on an NFS
    366 server.
    367 
    368 __fstab_config_1
    369 echo -n	"Edit the fstab? [n] "
    370 getresp "n"
    371 case "$resp" in
    372 	y*|Y*)
    373 		${EDITOR} /tmp/fstab
    374 		;;
    375 
    376 	*)
    377 		;;
    378 esac
    379 
    380 echo ""
    381 munge_fstab /tmp/fstab /tmp/fstab.shadow
    382 mount_fs /tmp/fstab.shadow
    383 
    384 mount | while read line; do
    385 	set -- $line
    386 	if [ "$2" = "/" ] && [ "$3" = "nfs" ]; then
    387 		echo "You appear to be running diskless."
    388 		echo -n	"Are the install sets on one of your currently mounted filesystems? [n] "
    389 		getresp "n"
    390 		case "$resp" in
    391 			y*|Y*)
    392 				get_localdir
    393 				;;
    394 			*)
    395 				;;
    396 		esac
    397 	fi
    398 done
    399 
    400 install_sets
    401 
    402 # Copy in configuration information and make devices in target root.
    403 (
    404 	cd /tmp
    405 	for file in fstab ifconfig.* hosts myname mygate resolv.conf; do
    406 		if [ -f $file ]; then
    407 			echo -n "Copying $file..."
    408 			cp $file /mnt/etc/$file
    409 			echo "done."
    410 		fi
    411 	done
    412 
    413 	# Enable rc.conf
    414 	if [ -e /mnt/etc/rc.conf ]; then
    415 		cp /mnt/etc/rc.conf /tmp
    416 		sed 's/^rc_configured=NO/rc_configured=YES/' /tmp/rc.conf \
    417 			> /mnt/etc/rc.conf
    418 	fi
    419 
    420 	# If no zoneinfo on the installfs, give them a second chance
    421 	if [ ! -e /usr/share/zoneinfo ]; then
    422 		get_timezone
    423 	fi
    424 	if [ ! -e /mnt/usr/share/zoneinfo ]; then
    425 		echo "Cannot install timezone link..."
    426 	else
    427 		echo -n "Installing timezone link..."
    428 		rm -f /mnt/etc/localtime
    429 		ln -s /usr/share/zoneinfo/$TZ /mnt/etc/localtime
    430 		echo "done."
    431 	fi
    432 	if [ ! -x /mnt/dev/MAKEDEV ]; then
    433 		echo "No /dev/MAKEDEV installed, something is wrong here..."
    434 	else
    435 		echo -n "Making devices..."
    436 		pid=$(twiddle)
    437 		cd /mnt/dev
    438 		sh MAKEDEV all
    439 		kill $pid
    440 		echo "done."
    441 	fi
    442 	md_copy_kernel
    443 
    444 	md_installboot ${ROOTDISK}
    445 )
    446 
    447 unmount_fs /tmp/fstab.shadow
    448 
    449 # Pat on the back.
    450 md_congrats
    451 
    452 # ALL DONE!
    453 exit 0
    454