374 lines
9.8 KiB
Bash
374 lines
9.8 KiB
Bash
#! /bin/sh
|
||
#
|
||
# @(#)install_small_kernel 1.1 94/10/31 SMI
|
||
#
|
||
# install_small_kernel
|
||
#
|
||
# Copyright (c) 1989 by Sun Microsystems, Inc.
|
||
#
|
||
# This shell script installs a small preconfigured kernel for
|
||
# hardware configurations typically equipped with SCSI devices.
|
||
# It can be invoked from the miniroot, and from both single and
|
||
# multi-user modes.
|
||
#
|
||
# The following host types are supported by this script:
|
||
# Standalone with SCSI disks only
|
||
# Server: If the server has non-SCSI disks, the small kernel
|
||
# can be installed on its clients having the supported
|
||
# configurations. Otherwise, the user has the
|
||
# option of installing the small kernel on the host
|
||
# and each of the clients.
|
||
#
|
||
# Dataless installs are supported only if this script is invoked
|
||
# in multi-user mode.
|
||
#
|
||
# The script normally processes only those clients which aren't
|
||
# flagged as having been installed with the small kernel.
|
||
# You can force small kernel installation on specific hosts or speed
|
||
# up the installation process by invoking the script and specifying
|
||
# hostnames on the command line.
|
||
#
|
||
|
||
PATH=/bin:/usr/bin:/etc:/usr/etc:/usr/etc/upgrade:/usr/ucb ; export PATH
|
||
files_dir=/etc/install; script='install_small_kernel'
|
||
PWD=`pwd`; tmp=/tmp
|
||
|
||
usage="USAGE: $script [hostname1] [hostname2] [hostname3]..."
|
||
[ $# = 0 ] && default=1 && do_host=1
|
||
|
||
if [ -f /.MINIROOT ]; then
|
||
top='/a' && mini=1
|
||
else
|
||
[ ! `whoami` = "root" ] && echo "Not superuser!" && exit 1
|
||
ps -ax > /tmp/$$
|
||
if egrep -s '[/ ]cron$' /tmp/$$ || egrep -s '[/ ]update$' /tmp/$$; then
|
||
multi=1
|
||
else
|
||
single=1
|
||
fi
|
||
fi
|
||
|
||
#
|
||
# Make sure files created by suninstall are available
|
||
#
|
||
for installfile in mount_list sys_info; do
|
||
[ -s $files_dir/${installfile} ] && continue
|
||
notfound="$notfound $installfile"
|
||
done
|
||
|
||
if [ "$notfound" ]; then
|
||
echo "This utility depends on these files generated by 'suninstall':"
|
||
echo " $notfound."
|
||
echo "They are not available on this system."; exit 1
|
||
fi
|
||
|
||
host_type=`awk -F= '$1 ~ /^sys_type$/ {print $2}' $files_dir/sys_info`
|
||
|
||
if [ "$mini" ] ; then
|
||
sys_name=`awk -F= '$1 ~ /^hostname/ {print $2}' $files_dir/sys_info|\
|
||
awk -F, '{print $1}'`
|
||
else
|
||
sys_name=`hostname`
|
||
fi
|
||
|
||
|
||
#
|
||
# Validate optional hostnames provided
|
||
#
|
||
for i in $*; do
|
||
case $i in
|
||
$sys_name ) do_host=1;;
|
||
* ) if [ -s $files_dir/client.${i} ]; then
|
||
clients="$clients $i"; continue
|
||
fi
|
||
notfound="$notfound $i";;
|
||
esac
|
||
done
|
||
|
||
[ "$notfound" ] && echo "Unknown host: $notfound" && echo $usage && exit 1
|
||
|
||
#
|
||
# Subroutine: Process yes/no responses
|
||
#
|
||
get_yn='(while read yn; do
|
||
case "$yn" in
|
||
[Yy]* ) exit 0;;
|
||
[Nn]* ) exit 1;;
|
||
* ) echo -n "Please answer y or n: ";;
|
||
esac
|
||
done)'
|
||
|
||
|
||
echo "
|
||
|
||
|
||
This utility installs a small pre-configured kernel for
|
||
systems which are either diskless, or equipped with
|
||
SCSI devices. The kernel supports about four users for
|
||
the following diskfull or diskless configurations:
|
||
|
||
Sun3/50 and Sun3/60 with up to 2 SCSI disks, 1 SCSI tape
|
||
Sun3/80 with up to 4 SCSI disks, 2 SCSI tapes
|
||
Sun4/110 with up to 4 SCSI disks, 2 SCSI tapes
|
||
SPARCsystem 330 with up to 4 SCSI disks, 2 SCSI tapes
|
||
SPARCstation 1, 1+, and 2 systems with up to 8 SCSI disks,
|
||
4 SCSI tapes, 2 CD-ROM drives, 1 Floppy Disk
|
||
|
||
If this system is a server that does not fit any of the above
|
||
configurations, this utility can be invoked to install the small
|
||
kernel on its clients listed above.
|
||
"
|
||
|
||
[ "$mini" ] && echo "Dataless systems are supported in multi-user mode only.
|
||
"
|
||
|
||
echo -n "Do you wish to continue? (y/n): "
|
||
eval "$get_yn" || exit 1
|
||
|
||
wrong_config=\
|
||
"This utility installs a smaller generic kernel on
|
||
systems having SCSI disks. It appears that this machine
|
||
does not have the valid configuration that can be supported
|
||
by this utility."
|
||
|
||
no_dataless=\
|
||
"This utility does not support dataless clients from the miniroot.
|
||
If you wish to install the small kernel, reboot your system and
|
||
invoke it in multi-user mode."
|
||
|
||
if [ "$host_type" = "dataless" -a "$mini" ]; then
|
||
echo "$no_dataless" && exit 1
|
||
fi
|
||
|
||
#
|
||
# Subroutine: Mount and unmount partitions; if operation fails,
|
||
# attempt error recovery
|
||
#
|
||
get_mtstat='( [ "$do_mt" = "0" ] && cmd="mount" || cmd="umount"
|
||
tried=""; fixit=""
|
||
while :
|
||
do
|
||
/etc/mount|grep -s "$mt_dir "
|
||
[ "$?" = "$do_mt" ] && exit 0
|
||
if [ "$tried" ]; then
|
||
if [ "$do_mt" = "0" -a ! "$fixit" ]; then
|
||
/etc/umount $mt_dev && tried="" && fixit=1 && continue
|
||
fi
|
||
echo -n "Unable to $cmd $mt_dir! Try again? (y/n) "
|
||
eval "$get_yn" && continue || exit 1
|
||
fi
|
||
if [ "$do_mt" = 0 ]; then
|
||
/etc/${cmd} $mt_dev $mt_dir && echo "$mt_dev $mt_dir" >> \
|
||
$tmp/mt_$$
|
||
else
|
||
/etc/${cmd} $mt_dev
|
||
fi
|
||
tried=1
|
||
done )'
|
||
|
||
#
|
||
# Subroutine: Copy and verify the small kernel installed.
|
||
# If copy operation fails, try one more time and restore original
|
||
# version, if unsuccessful.
|
||
#
|
||
do_copy='( if [ ! -s $from/vmunix_small ]; then
|
||
echo "Small Kernel not found in $from!"
|
||
exit 1
|
||
fi
|
||
if [ -f $to/vmunix ]; then
|
||
[ ! -s $to/vmunix.orig ] && mv $to/vmunix $to/vmunix.orig
|
||
fi
|
||
for i in 1 2; do
|
||
cp $from/vmunix_small $to/vmunix
|
||
sync; sync
|
||
sum1=`$top/usr/bin/sum $from/vmunix_small`
|
||
sum2=`$top/usr/bin/sum $to/vmunix`
|
||
[ "$sum1" = "$sum2" ] && exit 0
|
||
if [ "$i" = 2 ]; then
|
||
echo "Unable to install small kernel for $sys_name!"
|
||
[ ! -f $to/vmunix.orig ] && exit 1
|
||
echo "Restoring default generic kernel..."
|
||
mv $to/vmunix.orig $to/vmunix
|
||
sync; sync
|
||
exit 1
|
||
fi
|
||
done
|
||
)'
|
||
|
||
#
|
||
# Subroutine: Before exiting, restore original filesystem mount state
|
||
# and display appropriate completion message
|
||
#
|
||
cleanup='( [ ! "$multi" ] && /etc/umount -at 4.2 > /dev/null 2>&1
|
||
if [ -s $tmp/mt_$$ ] && [ ! "$mini" ] ; then
|
||
do_mt=1
|
||
cat $tmp/mt_$$ | while read mountlist; do
|
||
set $mountlist
|
||
mt_dev=$1; dir_nm=$2;
|
||
mt_dir=${top}$dir_nm
|
||
eval "$get_mtstat" || break
|
||
done
|
||
fi
|
||
rm -f $tmp/*_$$; cd $PWD
|
||
if [ "$kern_ok" ]; then
|
||
echo ""
|
||
echo "The small pre-configured kernel has been installed on:"
|
||
echo " $kern_ok"
|
||
[ "$mini" ] && echo "You may reboot your system now." || \
|
||
echo "You may reboot the system(s) now."
|
||
else
|
||
echo "The small pre-configured kernel has not been installed."
|
||
fi
|
||
exit 0 )'
|
||
|
||
#
|
||
# Mount and verify root partition
|
||
#
|
||
|
||
cd $files_dir
|
||
for i in `cat mount_list`; do
|
||
case $i in
|
||
partition* ) disk=$i;;
|
||
mount_pt=/ ) rootdisk=`echo $disk | sed 's/.*=//g'`; break;;
|
||
*) ;;
|
||
esac
|
||
done
|
||
|
||
do_mt=0; mt_dev=/dev/${rootdisk}; mt_dir=${top}
|
||
eval "$get_mtstat"
|
||
[ ! "$?" = 0 ] && eval "$cleanup" && exit 1
|
||
|
||
trap 'echo $script ABORTED!; eval "$cleanup"; exit 1' 1 2 3 15
|
||
|
||
if [ ! -s $top/sbin/init ] ; then
|
||
echo \
|
||
"${rootdisk} does not appear to be the correct root partition!"
|
||
eval "$cleanup" && exit 1
|
||
fi
|
||
|
||
#
|
||
# Check if host has non-SCSI disks
|
||
# If host=server with non-SCSI disks, install on clients only
|
||
#
|
||
disk_types=`awk '$1 ~ /^\/dev/ {print $1 }' ${top}/etc/fstab|\
|
||
sed 's/^\/dev\///'`
|
||
|
||
if [ "$do_host" ] ; then
|
||
for i in $disk_types; do
|
||
case $i in
|
||
sd*|fd* ) ;;
|
||
* ) do_host=
|
||
[ ! "$host_type" = "server" ] && err=1 && break
|
||
if [ "$default" ] || [ "$clients" ]; then
|
||
echo "Small kernel not installed on $sys_name."
|
||
echo "Non-SCSI disk ($i) found..."
|
||
else
|
||
err=1
|
||
fi
|
||
break;;
|
||
esac
|
||
|
||
done
|
||
fi
|
||
|
||
[ "$err" ] && echo "$wrong_config" && eval "$cleanup" && exit 1
|
||
|
||
#
|
||
# Mount all partitions
|
||
#
|
||
|
||
do_mt=0
|
||
awk ' $1 ~ /^\/dev/ { print $1 " " $2}' < ${top}/etc/fstab |\
|
||
while read mountlist; do
|
||
set $mountlist
|
||
mt_dev=$1; dir_nm=$2;
|
||
[ "$dir_nm" = "/" ] && continue
|
||
[ "$dir_nm" = "/pcfs" ] && continue
|
||
mt_dir=${top}$dir_nm
|
||
eval "$get_mtstat" && continue
|
||
eval "$cleanup" && exit 1
|
||
done
|
||
|
||
#
|
||
# Install small kernel to host and verify it.
|
||
# If kernel can't be installed on server, query for clients.
|
||
#
|
||
if [ "$do_host" ] ; then
|
||
echo -n "Install small kernel on $sys_name? (y/n) "
|
||
eval "$get_yn" || do_host=
|
||
fi
|
||
|
||
if [ "$do_host" ]; then
|
||
to=$top
|
||
from=${top}/usr/kvm/stand
|
||
trap '' 1 2 3 15
|
||
eval "$do_copy"; stat=$?
|
||
trap 'echo $script ABORTED!; eval "$cleanup"; exit 1' 1 2 3 15
|
||
case $stat in
|
||
0) kern_ok="$kern_ok $sys_name"
|
||
[ ! "$host_type" = "server" ] && eval "$cleanup" && exit 0 ;;
|
||
*) [ ! "$host_type" = "server" ] && eval "$cleanup"&& exit 1
|
||
echo -n "Install small kernel on clients? (y/n) "
|
||
eval "$get_yn"
|
||
[ ! "$?" = 0 ] && eval "$cleanup" && exit 1;;
|
||
esac
|
||
fi
|
||
|
||
#
|
||
# Get client info for server installations, using suninstall data files
|
||
#
|
||
install_flag='small_kernel='
|
||
|
||
if [ "$default" ]; then
|
||
ls client_list.* > $tmp/client_$$ 2>/dev/null
|
||
if [ ! -s $tmp/client_$$ ] ; then
|
||
echo "No clients have been set up for this server."
|
||
eval "$cleanup" && exit 1
|
||
fi
|
||
clnt=`cat client_list.sun*`
|
||
else
|
||
clnt=`echo $clients`
|
||
fi
|
||
|
||
[ ! "$clnt" ] && eval "$cleanup" && exit 0
|
||
skip='(small kernel previously installed).'
|
||
echo "Processing clients..."
|
||
last_clnt=`echo $clnt | awk '{print $NF}'`
|
||
|
||
for sys_name in $clnt; do
|
||
cl_info=${files_dir}/client.${sys_name}
|
||
if [ "$default" ]; then
|
||
if grep -s ${install_flag}yes $cl_info; then
|
||
echo \
|
||
"Not processed: $sys_name $skip"
|
||
continue
|
||
fi
|
||
fi
|
||
echo -n "Install small kernel on $sys_name? (y/n) "
|
||
eval "$get_yn" || continue
|
||
rpath=`awk -F= '$1 ~ /^root_path$/ {print $2}' $cl_info`
|
||
to=${top}${rpath}
|
||
kpath=`awk -F= '$1 ~ /^kvm_path$/ {print $2}' $cl_info`
|
||
from=${top}${kpath}/stand
|
||
if [ ! -d $to ]; then
|
||
echo "Directory $to does not exist." && continue
|
||
fi
|
||
trap '' 1 2 3 15
|
||
eval "$do_copy"; stat=$?
|
||
trap 'echo $script ABORTED!; eval "$cleanup"; exit 1' 1 2 3 15
|
||
case $stat in
|
||
0) sed "s/^\($install_flag\).*/\1yes/" $cl_info > \
|
||
$tmp/$cl_info_$$
|
||
kern_ok="$kern_ok $sys_name"
|
||
cp -p $tmp/$cl_info_$$ ${cl_info}
|
||
[ "$mini" ] && cp -p $tmp/$cl_info_$$ ${top}${cl_info};;
|
||
*) if [ ! "$sys_name" = "$last_clnt" ] ; then
|
||
echo -n "Continue with other clients? (y/n) "
|
||
eval "$get_yn" && continue || break
|
||
fi
|
||
eval "$cleanup" && exit 1
|
||
esac
|
||
done
|
||
|
||
eval "$cleanup" && exit 0
|