1#!/bin/sh 2# $NetBSD: install.sh,v 1.22 2000/04/11 08:26:34 pk Exp $ 3# 4# Copyright (c) 1996 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# 3. All advertising materials mentioning features or use of this software 19# must display the following acknowledgement: 20# This product includes software developed by the NetBSD 21# Foundation, Inc. and its contributors. 22# 4. Neither the name of The NetBSD Foundation nor the names of its 23# contributors may be used to endorse or promote products derived 24# from this software without specific prior written permission. 25# 26# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36# POSSIBILITY OF SUCH DAMAGE. 37# 38 39# NetBSD installation script. 40# In a perfect world, this would be a nice C program, with a reasonable 41# user interface. 42 43FILESYSTEMS="/tmp/filesystems" # used thoughout 44FQDN="" # domain name 45 46trap "umount /tmp > /dev/null 2>&1" 0 47 48MODE="install" 49 50# include machine-dependent functions 51# The following functions must be provided: 52# md_copy_kernel() - copy a kernel to the installed disk 53# md_get_diskdevs() - return available disk devices 54# md_get_cddevs() - return available CD-ROM devices 55# md_get_ifdevs() - return available network interfaces 56# md_get_partition_range() - return range of valid partition letters 57# md_installboot() - install boot-blocks on disk 58# md_labeldisk() - put label on a disk 59# md_prep_disklabel() - label the root disk 60# md_welcome_banner() - display friendly message 61# md_not_going_to_install() - display friendly message 62# md_congrats() - display friendly message 63# md_native_fstype() - native filesystem type for disk installs 64# md_native_fsopts() - native filesystem options for disk installs 65# md_makerootwritable() - make root writable (at least /tmp) 66 67# we need to make sure .'s below work if this directory is not in $PATH 68# dirname may not be available but expr is 69Mydir=`expr $0 : '^\(.*\)/[^/]*$'` 70Mydir=`cd ${Mydir:-.}; pwd` 71 72# this is the most likely place to find the binary sets 73# so save them having to type it in 74Default_sets_dir=$Mydir/../../binary/sets 75 76# include machine dependent subroutines 77. $Mydir/install.md 78 79# include common subroutines 80. $Mydir/install.sub 81 82# which sets? 83THESETS="$ALLSETS $MDSETS" 84 85# Good {morning,afternoon,evening,night}. 86md_welcome_banner 87echo -n "Proceed with installation? [n] " 88getresp "n" 89case "$resp" in 90 y*|Y*) 91 echo "Cool! Let's get to it..." 92 ;; 93 *) 94 md_not_going_to_install 95 exit 96 ;; 97esac 98 99# XXX Work around vnode aliasing bug (thanks for the tip, Chris...) 100ls -l /dev > /dev/null 2>&1 101 102# Deal with terminal issues 103md_set_term 104 105# Get timezone info 106get_timezone 107 108# Make sure we can write files (at least in /tmp) 109# This might make an MFS mount on /tmp, or it may 110# just re-mount the root with read-write enabled. 111md_makerootwritable 112 113# Install the shadowed disktab file; lets us write to it for temporary 114# purposes without mounting the miniroot read-write. 115cp /etc/disktab.shadow /tmp/disktab.shadow 116 117while [ "X${ROOTDISK}" = "X" ]; do 118 getrootdisk 119done 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. 124md_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. 129cat << \__get_filesystems_1 130 131You will now have the opportunity to enter filesystem information. 132You will be prompted for device name and mount point (full path, 133including the prepending '/' character). 134 135Note that these do not have to be in any particular order. You will 136be given the opportunity to edit the resulting 'fstab' file before 137any of the filesystems are mounted. At that time you will be able 138to resolve any filesystem order dependencies. 139 140__get_filesystems_1 141 142echo "The following will be used for the root filesystem:" 143echo " ${ROOTDISK}a /" 144 145echo "${ROOTDISK}a /" > ${FILESYSTEMS} 146 147resp="X" # force at least one iteration 148while [ "X$resp" != X"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 [ "X${_first_char}" != X"/" ]; do 162 echo -n "Mount point? " 163 getresp "" 164 _mount_point=$resp 165 if [ "X${_mount_point}" = X"/" ]; 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 176done 177 178# configure swap 179resp="" # force at least one iteration 180while [ "X${resp}" = X"" ]; 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 191done 192 193 194echo "" 195echo "You have configured the following devices and mount points:" 196echo "" 197cat ${FILESYSTEMS} 198echo "" 199echo "Filesystems will now be created on these devices. If you made any" 200echo -n "mistakes, you may edit this now. Edit? [n] " 201getresp "n" 202case "$resp" in 203 y*|Y*) 204 ${EDITOR} ${FILESYSTEMS} 205 ;; 206 *) 207 ;; 208esac 209 210# Loop though the file, place filesystems on each device. 211echo "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. 223cat << \__network_config_1 224You will now be given the opportunity to configure the network. This will 225be useful if you need to transfer the installation sets via FTP or NFS. 226Even if you choose not to transfer installation sets that way, this 227information will be preserved and copied into the new root filesystem. 228 229Note, enter all symbolic host names WITHOUT the domain name appended. 230I.e. use 'hostname' NOT 'hostname.domain.name'. 231 232__network_config_1 233echo -n "Configure the network? [y] " 234getresp "y" 235case "$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 [ "X${resp}" = X"" ]; 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 [ "X${resp}" != X"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 [ "X${resp}" != X"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 [ X${FQDN} != X ]; then 267 echo -n "Enter IP address of primary nameserver: [none] " 268 getresp "none" 269 fi 270 if [ "X${resp}" != X"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 308You will now be given the opportunity to escape to the command shell to 309do any additional network configuration you may need. This may include 310adding additional routes, if needed. In addition, you might take this 311opportunity to redo the default route in the event that it failed above. 312If you do change the default route, and wish for that change to carry over 313to the installed system, execute the following command at the shell 314prompt: 315 316 echo <ip_address_of_gateway> > /tmp/mygate 317 318where <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 ;; 335esac 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) < ${FILESYSTEMS} > /tmp/fstab 350 351echo "The fstab is configured as follows:" 352echo "" 353cat /tmp/fstab 354cat << \__fstab_config_1 355 356You may wish to edit the fstab. For example, you may need to resolve 357dependencies in the order which the filesystems are mounted. You may 358also wish to take this opportunity to place NFS mounts in the fstab. 359This would be especially useful if you plan to keep '/usr' on an NFS 360server. 361 362__fstab_config_1 363echo -n "Edit the fstab? [n] " 364getresp "n" 365case "$resp" in 366 y*|Y*) 367 ${EDITOR} /tmp/fstab 368 ;; 369 370 *) 371 ;; 372esac 373 374echo "" 375munge_fstab /tmp/fstab /tmp/fstab.shadow 376mount_fs /tmp/fstab.shadow 377 378mount | while read line; do 379 set -- $line 380 if [ "$2" = "/" -a "$3" = "nfs" ]; then 381 echo "You appear to be running diskless." 382 echo -n "Are the install sets on one of your currently mounted filesystems? [n] " 383 getresp "n" 384 case "$resp" in 385 y*|Y*) 386 get_localdir 387 ;; 388 *) 389 ;; 390 esac 391 fi 392done 393 394install_sets 395 396# Copy in configuration information and make devices in target root. 397( 398 cd /tmp 399 for file in fstab ifconfig.* hosts myname mygate resolv.conf; do 400 if [ -f $file ]; then 401 echo -n "Copying $file..." 402 cp $file /mnt/etc/$file 403 echo "done." 404 fi 405 done 406 407 # Enable rc.conf 408 if [ -e /mnt/etc/rc.conf ]; then 409 cp /mnt/etc/rc.conf /tmp 410 sed 's/^rc_configured=NO/rc_configured=YES/' /tmp/rc.conf \ 411 > /mnt/etc/rc.conf 412 fi 413 414 # If no zoneinfo on the installfs, give them a second chance 415 if [ ! -e /usr/share/zoneinfo ]; then 416 get_timezone 417 fi 418 if [ ! -e /mnt/usr/share/zoneinfo ]; then 419 echo "Cannot install timezone link..." 420 else 421 echo -n "Installing timezone link..." 422 rm -f /mnt/etc/localtime 423 ln -s /usr/share/zoneinfo/$TZ /mnt/etc/localtime 424 echo "done." 425 fi 426 if [ ! -x /mnt/dev/MAKEDEV ]; then 427 echo "No /dev/MAKEDEV installed, something is wrong here..." 428 else 429 echo -n "Making devices..." 430 pid=`twiddle` 431 cd /mnt/dev 432 sh MAKEDEV all 433 kill $pid 434 echo "done." 435 fi 436 md_copy_kernel 437 438 md_installboot ${ROOTDISK} 439) 440 441unmount_fs /tmp/fstab.shadow 442 443# Pat on the back. 444md_congrats 445 446# ALL DONE! 447exit 0 448