diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2004-09-29 00:05:15 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2004-09-29 00:05:15 +0000 |
commit | d6cde081015c12bf3797778c1d463324e19ca0b8 (patch) | |
tree | abff4fc77b604a35bedf78c337127e3136939e89 | |
parent | de87dea47187ff2ab1b88446ddfdf84835bad30f (diff) |
Code cleanup and shrinkage (~2K).
Factor out drive/partition handling for CD and disk installs. Should
only affect installs/upgrades from non-ISO CDs and unmounted disk partitions.
Tested by Otto@.
'It is that high risk time' deraadt@.
-rw-r--r-- | distrib/miniroot/install.sub | 270 |
1 files changed, 79 insertions, 191 deletions
diff --git a/distrib/miniroot/install.sub b/distrib/miniroot/install.sub index 255a65bf060..a7e94c1f7fe 100644 --- a/distrib/miniroot/install.sub +++ b/distrib/miniroot/install.sub @@ -1,4 +1,4 @@ -# $OpenBSD: install.sub,v 1.352 2004/09/16 22:23:44 mcbride Exp $ +# $OpenBSD: install.sub,v 1.353 2004/09/29 00:05:14 krw Exp $ # $NetBSD: install.sub,v 1.5.2.8 1996/09/02 23:25:02 pk Exp $ # # Copyright (c) 1997-2004 Todd Miller, Theo de Raadt, Ken Westerback @@ -187,6 +187,43 @@ get_serialdev() { echo "${_bd}${1} ${_td}${1}" } +get_drive() { + ask_which "$1" "contains the $MODE media" "$2" + [[ $resp == done ]] && return 1 + makedev $resp || return 1 + return 0 +} + +get_partition() { + local _drive=$1 _fstypes=$2 _part _fst + + # Create file /tmp/parts.$_drive where each line is of the + # form "<partition letter> <fs type>". + disklabel $_drive 2>/dev/null \ + | grep '^ [a-p]: ' \ + | egrep -v "swap|unused" \ + | sed -e 's/^ \(.\): *[^ ]* *[^ ]* *\([^ ]*\) .*/\1 \2/' \ + >/tmp/parts.$_drive + + disklabel $_drive 2>/dev/null | grep '^ .:' + + ask_which "$_drive partition" "has the $MODE sets" \ + "$(sed -e 's/^\(.\).*/\1/' /tmp/parts.$_drive)" + [[ $resp == done ]] && return 1 + + _part=$resp + _fst=$(sed -ne "/^$_part /s///p" /tmp/parts.$_drive) + + ask_which "filesystem type" "should be used to mount $_drive$_part" "$_fst $_fstypes ffs" + case $resp in + done) return 1 ;; + $_fst) resp="$_part" ;; + *) resp="$_part $resp" ;; + esac + + return 0 +} + # Ask for a password, saving the input in $resp. # Display $1 as the prompt. # *Don't* allow the '!' options that ask does. @@ -264,44 +301,39 @@ ask_yn() { done } -# Ask for the user to select a device from a list generated by scanning -# /var/run/dmesg.boot, and make the device if it doesn't exist. +# Ask for the user to select one value from a list, or 'done'. # -# $1 = device name (disk, cd, etc.) +# $1 = name of the list items (disk, cd, etc.) # $2 = question to ask -# $3 = list of devices from /var/run/dmesg.boot scan -# $4 = default device. If it is not specified, use the first device in $3 -# $5 = error message if no devices in $3, defaults to 'No $1s found.' +# $3 = list of valid choices +# $4 = default choice, if it is not specified use the first item in $3 +# $5 = error message if no items in $3, defaults to 'No $1s found.' # -# $resp holds device selected at exit, or 'done' +# At exit $resp holds selected item, or 'done' ask_which() { - local _name=$1 _query=$2 _devs=$3 _defdev=$4 _err=$5 + local _name=$1 _query=$2 _list=$3 _def=$4 _err=$5 - set -- $_devs - if [[ $# -lt 1 ]]; then + set -- $_list + if (( $# < 1 )); then echo "${_err:=No ${_name}s found}." resp=done return fi - : ${_defdev:=$1} + : ${_def:=$1} - # Eliminate extraneous (especially trailing) whitespace in _devs. - _devs="$*" + # Eliminate extraneous (especially trailing) whitespace in _list. + _list="$*" - while : ; do + while :; do # Put both lines in ask prompt, rather than use a # separate 'echo' to ensure the entire question is # re-ask'ed after a '!' or '!foo' shell escape. - ask "Available ${_name}s are: ${_devs}.\nWhich one ${_query}? (or 'done')" "$_defdev" - [[ $resp == done ]] && break + ask "Available ${_name}s are: $_list.\nWhich one $_query? (or 'done')" "$_def" # Quote $resp to prevent user from confusing isin() by # entering something like 'a a'. - if isin "$resp" $_devs; then - makedev $resp && break - else - echo "'$resp' is not a valid choice." - fi + isin "$resp" $_list done && break + echo "'$resp' is not a valid choice." done } @@ -413,12 +445,8 @@ __EOT makedev() { local _dev=$1 _node=/dev/r${1}c - # Don't need to make network interface device nodes. If the device is - # just a number then ignore it. This is used when selecting a serial - # console speed. If the device node exists, don't need to create it. - if isin $_dev $IFDEVS || [[ -c $_node || -z ${_dev##+([0-9])} ]] ; then - return 0 - fi + # If the device node exists, don't need to create it. + [[ -c $_node ]] && return 0 if [[ ! -r /dev/MAKEDEV ]] ; then echo "No /dev/MAKEDEV. Can't create device nodes for ${_dev}." @@ -1059,185 +1087,44 @@ install_mounted_fs() { esac done - install_files "file://$_dir" "`ls -l $_dir`" + install_files "file://$_dir" "$(ls -l $_dir)" } install_cdrom() { - local _drive _part _fstype _directory _n - - ask_which "CD-ROM" "contains the ${MODE} media" "$CDDEVS" - [[ $resp == done ]] && return + local _drive _part=c _fstype="-t cd9660" + get_drive "CD-ROM" "$CDDEVS" || return _drive=$resp - # If it is an ISO9660 CD-ROM, we don't need to ask any other questions - _n=0 - until disklabel $_drive >/tmp/label.$_drive 2>&1; do - # Try up to 6 times to access the CD - if egrep -q '(Input/output error)|(sector size 0)' /tmp/label.$_drive; then - _n=$(( $_n + 1 )) - if [ _n -le 5 ]; then - echo "I/O error accessing $_drive; retrying" - sleep 10 - else - echo "Cannot access $_drive." - return - fi - else - break - fi - done - - echo - if grep -q '^ *c: .*ISO9660' /tmp/label.$_drive; then - _fstype=cd9660 - _part=c - else - # Get partition from user - resp= - while [ -z "$resp" ] ; do - ask "CD-ROM partition to mount? (normally 'c')" c - case $resp in - [a-p]) - _part=$resp - ;; - *) echo "Invalid response: $resp" - # force loop to repeat - resp= - ;; - esac - done - - # Ask for filesystem type - cat << __EOT - -Two CD-ROM filesystem types are currently supported by this program: -cd9660 ISO-9660 -ffs Berkeley Fast Filesystem - -__EOT - resp= - while [ -z "$resp" ] ; do - ask "Which filesystem type?" cd9660 - case $resp in - cd9660|ffs) - _fstype=$resp - ;; - *) echo "Invalid response: '$resp'" - # force loop to repeat - resp= - ;; - esac - done - fi - - rm -f /tmp/label.$_drive - - # Mount the CD-ROM - if ! mount -t ${_fstype} -o ro /dev/${_drive}${_part} /mnt2 ; then - echo "Cannot mount CD-ROM drive." - return + # Only ask detail questions for non-ISO9660 CD-ROMs. + if [[ -z $(disklabel $_drive 2>&1 | grep '^ *c: .*ISO9660') ]]; then + unset _fstype + get_partition $_drive "cd9660" || return + set -- $resp + _part=$1 + [[ -n $2 ]] && _fstype="-t $2" fi + mount $_fstype -o ro /dev/$_drive$_part /mnt2 || return install_mounted_fs /mnt2 "$SETDIR" umount -f /mnt2 > /dev/null 2>&1 } -# Mount a disk on /mnt2. The set of disk devices to choose from -# is $DKDEVS. -# returns 0 on success, 1 on failure -mount_a_disk() { - local _drive _def_partition _partition_range _partition - local _fstype _fsopts - - ask_which "disk" "contains the ${MODE} sets" "$DKDEVS" - [[ $resp == done ]] && return 1 +install_disk() { + local _drive _part _fstype _fsopts + get_drive "disk" "$DKDEVS" || return _drive=$resp - # Get partition - cat << __EOT - -The following partitions have been found on $_drive: - -__EOT - disklabel $_drive 2>/dev/null | grep '^ .:' - echo - _likely_partition_range=`disklabel $_drive 2>/dev/null | \ - sed -n -e '/swap/s/.*//' -e '/unused/s/.*//' \ - -e '/^ .:/{s/^ \(.\).*/\1/;H;}' \ - -e '${g;s/\n//g;s/^/[/;s/$/]/p;}'` - _partition_range=`disklabel $_drive 2>/dev/null | \ - sed -n -e '/^ .:/{s/^ \(.\).*/\1/;H;}' \ - -e '${g;s/\n//g;s/^/[/;s/$/]/p;}'` - _def_partition=`echo $_likely_partition_range | \ - sed -n 's/^\[\(.\).*\]/\1/p'` - if [ -z "$_def_partition" ]; then - _def_partition=`echo $_partition_range | \ - sed -n 's/^\[\(.\).*\]/\1/p'` - if [ -z "$_def_partition" ]; then - echo "There are no usable partitions on that disk" - return 1 - fi - fi - - resp= - while [ -z "$resp" ]; do - ask "Partition?" "$_def_partition" - case $resp in - $_partition_range) - _partition=$resp - ;; - *) echo "Invalid response: $resp" - # force loop to repeat - resp= - ;; - esac - done - - # Ask for filesystem type - cat << __EOT - -The following filesystem types are supported: -default (deduced from the disklabel) -ffs -$MDFSTYPE -__EOT + get_partition $_drive "$MDFSTYPE" || return + set -- $resp + _part=$1 + [[ -n $2 ]] && _fstype="-t $2" + [[ $2 == $MDFSTYPE ]] && _fsopts=$MDFSOPTS - resp= - while [ -z "$resp" ]; do - ask "Which filesystem type?" default - case $resp in - default) - ;; - ffs) _fstype="-t ffs" - _fsopts=async - ;; - $MDFSTYPE) - _fstype="-t $resp" - _fsopts=$MDFSOPTS - ;; - *) echo "Invalid response: $resp" - # force loop to repeat - resp= - ;; - esac - done - - # Mount the disk read-only - if ! mount $_fstype -o ro,$_fsopts /dev/${_drive}${_partition} /mnt2; then - echo "Cannot mount disk." - return 1 - fi - - return 0 -} - -install_disk() { - if mount_a_disk; then - install_mounted_fs /mnt2 - umount -f /mnt2 > /dev/null 2>&1 - fi + mount $_fstype -o ro,$_fsopts /dev/$_drive$_part /mnt2 || return + install_mounted_fs /mnt2 + umount -f /mnt2 > /dev/null 2>&1 } install_nfs() { @@ -1800,6 +1687,7 @@ set -- $DKDEVS ask_which "disk" "is the root disk" "$DKDEVS" "$_defdsk" [[ $resp == done ]] && exit +makedev $resp || exit ROOTDISK=$resp ROOTDEV=${ROOTDISK}a |