#!/sbin/sh # #ident "@(#)rcS.sh 1.152 02/10/23 SMI" # # Copyright (c) 1992-1999 Sun Microsystems, Inc. All Rights Reserved. # # # the 2.X install "rcS" file # run by init(8) to create the environment for doing the installation # replaces normal rcS # #* init starts # * mount tmpfs onto /tmp # * copy any needed files into /tmp... # * device reconfigure # * figure out root and /cdrom # * mount /cdrom # # UberJS rcS Version 1.1-Server PLATFORM=`/sbin/uname -p` export PLATFORM I386="i386" SPARC="sparc" PPC="ppc" ROOT=/tmp/root LOGS=${ROOT}/var/sadm/system/logs Network="no" FJS_BOOT="no" DoDrvconfig="yes" SINGLE_USER=0 USING_DHCP=0 # # Functions # # # use shell to snarf the base device name so we can make slice 0's name # now we (only) do OBP style names # INPUT: $1 - the rootfs device name # OUTPUT: spits out on stdout the short device name of the cdrom device # basedevof() { D=$1 # Device T=$2 # Type # if we had expr on root, this is what we would simply do # U=`expr $D : '\(.*\):.*' # echo "${U}:a" # but we don't have expr and would like to live without it # so we use set to separate at all ":" IFS=":" set -- ${D} # get everything up till last ":" into U U=$1 shift ; while [ $# -gt 1 ] ; do U=${U}:$1 shift ; done # now we got everything except the stuff after the last ":", # which we assume was just a partition letter # x86 & ppc use p0 device for hsfs. sparc uses s0 device. # These map to :q and :a respectively under /devices/... if [ "${PLATFORM}" = "${SPARC}" ]; then echo "${U}:a" else if [ "${T}" = "ufs" ]; then echo "${U}:b" else echo "${U}:q" fi fi } # # Find and mount the CD image using DHCP # dhcp_find_and_mount_cdrom() { /sbin/dhcpagent -a # # Look for the root boot parameters; # For dhcpinfo: SrootNM returns the root file system server name # SrootPTH returns the root file system path # for non-NFS DHCP boots, force the use of the local media # if [ "${Network}" = "yes" ]; then if rs=`/sbin/dhcpinfo SrootNM` && rp=`/sbin/dhcpinfo SrootPTH` ; then Rootfs=$rs:$rp echo "${Rootfs} - / ${Roottype} - no ro" >> /etc/vfstab else echo "ERROR: dhcpagent unable to access network information" exec /sbin/sh fi else # # We are not booting off of an NFS root filesystem. # use pre-set Rootfs and Roottype. # echo "${Rootfs} - / ${Roottype} - no ro" >> /etc/vfstab fi # # Look for the install boot parameter; # For dhcpinfo: SinstNM returns the install file system server name # SinstPTH returns the install file system path # if [ "${Network}" = "yes" ]; then if is=`/sbin/dhcpinfo SinstNM` && ip=`/sbin/dhcpinfo SinstPTH` ; then Installfs=$is:$ip else echo "ERROR: dhcpinfo unable to access network install information" exec /sbin/sh fi else # we are booting off local media. Use it. echo "DHCP: using local media" fi # Get the server IP address so we can complain about it by name if need be DHCPServerAddr=`/sbin/dhcpinfo ServerID` # update the hosts file with the proper name to address translation for our # install server, if we are net DHCP booting if [ "${Network}" = "yes" ]; then echo "`/sbin/dhcpinfo SinstIP4` $is" >> /etc/inet/hosts fi /sbin/mount -F ${Installtype} -o ro ${Installfs} /cdrom >/dev/null 2>&1 if [ $? -ne 0 ]; then if [ "${Network}" = "yes" ]; then # Bad information was returned by this DHCP server # display what information is available and # exit to allow the user to correct the situation # echo "received from DHCP server at $DHCPServerAddr" echo "install info: server $is, path $ip" echo "root info: server $rs, path $rp" echo "ERROR: Unable to NFS mount ${Installfs}" echo " Exiting to shell." exec /sbin/sh else # not networked, and mount failed. echo "ERROR: ${Installfs} of type ${Installtype} does not exist, unable to mount /cdrom" exec /sbin/sh fi fi # make file for solaris install wizard(s) echo $Installfs > /tmp/.netmnt # Loopback mount the full version of /usr on the cdrom # if [ -d /cdrom/Solaris_*/Tools/Boot/usr -a "${Roottype}" != "nfs" ]; then /sbin/mount -F lofs /cdrom/Solaris_*/Tools/Boot/usr /usr mount_return_code=$? if [ $mount_return_code -ne 0 ]; then echo "Unable to mount /cdrom/Solaris_*/Tools/Boot/usr" exec /sbin/sh fi fi echo "${Installfs} - /cdrom ${Installtype} - no ro" >> /etc/vfstab } # # Find and mount the CD image using bootparams # bootparams_find_and_mount_cdrom() { # # net_device_list contains a ":" delimited list # of network devices # do an auto-revarp on each of them with the # exception of the loopback device # old_ifs=$IFS IFS=":" set -- $net_device_list for i do # # skip the auto-revarp for the loopback device # if [ "$i" = "lo0" ]; then continue fi /sbin/ifconfig $i auto-revarp -trailers >/tmp/dev.$$ 2>&1 ipaddr=`/sbin/ifconfig $i |grep inet |awk '{print $2;}'` if [ "X$ipaddr" != "X0.0.0.0" ] ; then # The interface configured itself correctly echo "Configured interface $i" /sbin/ifconfig $i up else echo "Skipping interface $i" fi done IFS=$old_ifs /sbin/hostconfig -p bootparams 2> /dev/null # # if not booting from the net add root entry to # /etc/vfstab # if [ "${Network}" != "yes" ]; then echo "${Rootfs} - / ${Roottype} - no ro" >> /etc/vfstab else # # Look for the root boot parameter; # bpgetfile returns $1 = server name, $2 = server IP addr, $3 = path # set -- "" set -- `/sbin/bpgetfile` SERVER_IPADDR=$2 if [ $2"x" != "x" ]; then Rootfs=$1:$3 echo "${Rootfs} - / ${Roottype} - no ro" >> /etc/vfstab else echo "ERROR: bpgetfile unable to access network information" exec /sbin/sh fi # get the server's netmask if [ -x /sbin/get_netmask ]; then netmask=`/sbin/get_netmask $SERVER_IPADDR 2>/dev/null` if [ -n "$netmask" ]; then /sbin/ifconfig -a netmask 0x${netmask} >/dev/null 2>&1 fi fi # # Look for the install boot parameter; # bpgetfile returns $1 = server name, $2 server IP addr, $3 = path # set -- "" set -- `/sbin/bpgetfile install` if [ $2"x" != "x" ]; then Installfs=$2:$3 else echo "ERROR: bpgetfile unable to access network install information" exec /sbin/sh fi fi /sbin/mount -F ${Installtype} -o ro ${Installfs} /cdrom >/dev/null 2>&1 if [ $? -ne 0 ]; then # if the .netmnt file exists at this point, then we # must have already booted once, and are booting again # (i.e. Solaris Install CD). In this case, we simply # ignore the error and return, because the rest of # this function tries to mount the Installfs, which is # not needed (and will fail) when booting a Solaris # Install CD "disk0" boot image from a cd0-based net # boot. if [ -f /tmp/.netmnt ] ; then return 0 fi if [ "${Installtype}" = "hsfs" ]; then # only used internally for testing echo "hsfs mount failed, trying ufs..." Installfs=`basedevof ${Rootfs} ufs` if [ -b ${Installfs} ] ; then /sbin/mount -F ufs -o ro ${Installfs} /cdrom else echo "ERROR: ${Installfs} does not exist, unable to mount /cdrom" fi else # there is a bad entry in the bootparams map # display what information is available and # exit to allow the user to correct the situation # echo "install entry: "`/sbin/bpgetfile install` echo "root entry: "`/sbin/bpgetfile` echo "ERROR: Unable to NFS mount ${Installfs}" echo " Exiting to shell." exec /sbin/sh fi fi # By touching this file, we avoid failure during a possible # disk0-based reboot (think Solaris Install CD) when mounting # a possibly non-existent hsfs Solaris Install image. See # above comment dealing with .netmnt for more info. echo $Installfs > /tmp/.netmnt # Loopback mount the full version of /usr on the cdrom # if [ -d /cdrom/Solaris_*/Tools/Boot/usr -a "${Roottype}" != "nfs" ]; then /sbin/mount -F lofs /cdrom/Solaris_*/Tools/Boot/usr /usr mount_return_code=$? if [ $mount_return_code -ne 0 ]; then echo "Unable to mount /cdrom/Solaris_*/Tools/Boot/usr" exec /sbin/sh fi fi echo "${Installfs} - /cdrom ${Installtype} - no ro" >> /etc/vfstab } # restores x86 boot partition if one was backed during a cd0 boot restore_x86boot() { if [ -f /tmp/.x86bootpart ];then if [ -f /tmp/.x86boot.dd.Z ];then uncompress /tmp/.x86boot.dd.Z >> /tmp/disk0_install.log 2>&1 fi # # if the compress failed in cd0_install, we should still have a dd # if [ -f /tmp/.x86boot.dd ];then dd if=/tmp/.x86boot.dd of=`cat /tmp/.x86bootpart` >> /tmp/disk0_install.log 2>&1 fi fi # now reset the active partition if needed. if [ -f /tmp/.originalfdfile ] && [ -f /tmp/.originaldev ];then bootdev=`cat /tmp/.originaldev` # prune out the irritating HBA message from fdisk fdisk -F /tmp/.originalfdfile $bootdev fi } ################################################### ################################################### # Main # # # Mount tmpfs and procfs # if [ ! -f /tmp/.rcSmnt ]; then # mount tmpfs, for now it can't swap so we can't fill it too full /sbin/mount -F tmpfs swap /tmp if [ $? -ne 0 ]; then echo "tmpfs mount failed." /sbin/sh fi # mount proc /sbin/mount -F proc proc /proc if [ $? -ne 0 ]; then echo "proc mount failed." /sbin/sh fi # mount mnttab # /usr/lib/fs/mntfs/mount mnttab /etc/mnttab cat < /dev/null > /tmp/.rcSmnt fi # Mount tftpboot # if [ ! -f /tftpboot/.rcSmnt ]; then # mount tftpboot /sbin/mount -F tmpfs swap /tftpboot if [ $? -ne 0 ]; then echo "tftpboot mount failed." /sbin/sh fi cat < /dev/null > /tmp/.rcSmnt fi # # Check for no reboot flag # if [ "${RB_NOBOOTRC}" = "YES" ]; then RB_NOBOOTRC="no" export RB_NOBOOTRC /sbin/sh fi if [ -f /tmp/.rcSrun ]; then exit 0 fi DownRevRoss=`echo "downrev_ross_detected/X" | adb /dev/ksyms /dev/kmem | \ ( read junk ; read junk ; read junk rev; echo $rev )` if [ "$DownRevRoss" = "1" ]; then echo " " echo "The ROSS 605 CPU modules installed in this system are not fully" echo "compatible with this version of Solaris. If this version of Solaris" echo "software is installed, this system will run only in uni-processor" echo "mode, which will affect performance." echo " " echo "Please upgrade your CPU module(s) in order to run in multi-processor" echo "mode." echo " " echo " Do you want to continue with the installation? If you choose" echo " not to continue, previous system software will be left intact." echo " Continue installation (y/n)?" read answer if [ "$answer" = "n" ]; then echo "Installation stopped. Previous system software has been left intact." echo "Please reboot." sync;sync /sbin/uadmin 2 0 # force it down fi echo "WARNING: System performance will be affected. Are you sure (y/n)?" read answer if [ "$answer" = "n" ]; then echo "Installation stopped. Previous system software has been left intact." echo "Please reboot." sync;sync /sbin/uadmin 2 0 # force it down fi fi # # Start the twirling dial # if [ -x /sbin/dial ]; then if [ -f /.tmp_proto/uberjs/disable_dial ]; then echo "Dial disabled" else dial & dial_pid=$! fi fi # # Unpack writeable initialized files into /tmp. # NOTE: send output to /tmp (not /dev/null) to avoid nfs bug on remote # ro mounted fs ( cd /.tmp_proto; find . -print -depth | cpio -pdm /tmp 2>/tmp/cpio.out ) # # Unpack writeable initialized files into /tftpboot. # NOTE: send output to /tmp (not /dev/null) to avoid nfs bug on remote # ro mounted fs ( cd /.tftpboot_proto; find . -print -depth | cpio -pdm /tftpboot 2>/tmp/cpio.out ) mkdir -p /tmp/root/var/sadm/system/logs # restore x86boot partition, if one existed from Solaris # Installation CD boot. if [ "`uname -m`" = "i86pc" ];then restore_x86boot fi MEMSIZE=`/sbin/mem` echo "Memory free after tmpfs initialization: ${MEMSIZE}" >> ${LOGS}/sysidtool.log if [ ${MEMSIZE} -lt 4000 ]; then echo "ERROR: ${MEMSIZE}KB is not enough free memory to install Solaris 2" /sbin/uadmin 2 0 # force it down fi ######## # Configured "/" writeable files may not be updated. # # create /etc/vfstab (/tmp/root/etc/vfstab) echo "swap - /tmp tmpfs - no -" >> /etc/vfstab # # add the procfs mount line # echo "/proc - /proc proc - no -" >> /etc/vfstab # configure devfs in /tmp/dev and /tmp/devices # using find | cpio to preserve the directory attributes find devices dev -depth -print | cpio -pdum /tmp >/dev/null 2>&1 # # Loopback mount the newly plumbed devices onto the main # file systems # /sbin/mount -F lofs /tmp/devices /devices /sbin/mount -F lofs /tmp/dev /dev _INIT_RECONFIG=set; export _INIT_RECONFIG mkdir -p /tmp/etc mkdir -p /tmp/etc/sysevent /usr/lib/sysevent/syseventd -r /tmp /usr/lib/devfsadm/devfsadmd -r /tmp -p /tmp/root/etc/path_to_inst # # Force bootdev module loading so that we don't hang on reboot. # This is the bugfix to bugID 4634913, which is a workaround to # bugID 4628607. Once 4628607 is fixed, this _should_ be # uneccessary # /usr/sbin/modload -p misc/bootdev # # PPC/Intel Unbundled Driver support - Sun private interface # Copy driver scripts and data files onto the system from # floppy, CD or netinstall image (if they exist). We are # looking for the rc.d directory in the top level of the floppy # or in /boot/rc.d on a CD or netinstall image. Floppy files # take precedence over CD or net files if the same file exists # in both places. # if [ "${PLATFORM}" = "${I386}" -o "${PLATFORM}" = "${PPC}" ]; then /sbin/mount -F pcfs -o ro,foldcase /dev/diskette /mnt >/dev/null 2>&1 status=$? if [ ${status} -ne 0 ]; then /sbin/mount -F ufs -o ro /dev/diskette /mnt >/dev/null 2>&1 status=$? fi if [ ${status} -eq 0 ]; then if [ -d /mnt/rc.d ]; then FILES=`/usr/bin/ls /mnt/rc.d` if [ ! -z "${FILES}" ]; then /usr/bin/mkdir /tmp/diskette_rc.d /usr/bin/cp -p -r /mnt/rc.d/* /tmp/diskette_rc.d fi fi if [ -d /mnt/kernel ]; then FILES=`/usr/bin/ls /mnt/kernel` if [ ! -z "${FILES}" ]; then /usr/bin/mkdir -p /tmp/kernel /usr/bin/cp -p -r /mnt/kernel/* /tmp/kernel fi fi /sbin/umount /dev/diskette fi if [ -d /boot/rc.d ]; then if [ ! -d /tmp/diskette_rc.d ]; then /usr/bin/mkdir /tmp/diskette_rc.d fi for FILE in `/usr/bin/ls /boot/rc.d`; do RCPATH=/boot/rc.d/$FILE if [ -f $RCPATH -a ! -f /tmp/diskette_rc.d/$FILE ]; then /usr/bin/cp -p $RCPATH /tmp/diskette_rc.d/$FILE fi done fi if [ -r /tmp/diskette_rc.d/rcs1.sh ]; then /sbin/sh /tmp/diskette_rc.d/rcs1.sh fi fi # # read bootargs for the boot device # if fails - ignore and assume regular install # if ok - see if preinstall bootargs set # and if possible, copy the /devices from the stub # read prom for default boot dev # looking for "FD=..." set -- "" set -- `/sbin/getbootargs 2>/dev/null` if [ $# -gt 0 ] ; then while [ $# -gt 0 ] ; do case $1 in # # Public flags # FD=*) # at end of script, save root dev in /tmp/.preinstall # this is an unambiguous indication of stub boot FJS_BOOT="yes" From=`(IFS="="; set -- $1; echo "$2 $3 $4 $5" )` break ;; install) INSTALL_BOOT="yes" cat < /dev/null > /tmp/.install_boot shift ;; dhcp) TRY_DHCP="yes" shift ;; tape*|*:/*) echo "cj_location $1" >> /tmp/.cjfiles_method # providing a URL implies you want to do an install boot, so do it. INSTALL_BOOT="yes" cat < /dev/null > /tmp/.install_boot shift ;; ask) cat < /dev/null > /tmp/.cjfiles_ask shift ;; nowin|w) cat < /dev/null > /tmp/.nowin shift ;; # # Private flags # wizard_debug) cat < /dev/null > /tmp/.wizard_debug shift ;; mansysid) cat < /dev/null > /tmp/.manual-sysid shift ;; *) shift ;; esac done fi # # figure out root file system information (ie local or remote) # eval `/sbin/get_root -t Roottype -b Rootfs /` case ${Roottype} in ufs|hsfs) # we are on a ufs or hsfs (local machine) # get the name of the device for the Solaris distribution Installfs=`basedevof ${Rootfs} ""` if [ -b ${Installfs} ] ; then echo $Installfs >> /tmp/.cdroot break else # "this never happens" :-) echo "ERROR: The Solaris Distribution, ${Installfs} does not exist" echo " Exiting to shell." /sbin/sh fi # the slice 0 is type hsfs Installtype=hsfs ;; nfs*) # we are over the network (nfs, nfs2, nfs3) Roottype=nfs Network="yes" # set Installfs=... from config file from server Installtype=nfs ;; *) # fatal error - unknown "/" filesystem # we cannot use it as-is - note all the fs specific changes /sbin/dial $dial_pid while : ; do echo "FATAL ERROR: "/" file system type \"${Roottype}\" is unknown" echo " Exiting to shell." /sbin/sh done ;; esac # # Configure network interfaces: # - software loopback interface # - hardware interfaces # Complete the network configuration # /sbin/ifconfig lo0 plumb /sbin/ifconfig lo0 127.0.0.1 up # # Configure all network interfaces # /sbin/ifconfig -a plumb > /dev/null 2>&1 if [ "X${Roottype}" = "Xufs" -o "X${Roottype}" = "Xhsfs" ] ; then # Try manually turning DHCP on if [ $USING_DHCP -ne 1 -a "X$TRY_DHCP" = "Xyes" ] ; then for i in `ifconfig -a |grep "^[a-z0-9]*:" |sed -e "s/: .*$//g"` ; do if [ $i = "lo0" ] ; then continue fi echo "Trying DHCP on $i" /sbin/ifconfig $i dhcp primary start wait 120 if [ $? -eq 0 ] ; then echo Success USING_DHCP=1 break else # No luck, give up on this interface /sbin/ifconfig $i dhcp drop fi done fi else # Export net boot configuration strategy. _INIT_NET_IF is set to the # interface name of the netbooted interface if this is a net boot. # _INIT_NET_STRATEGY is set to the network configuration strategy. set -- `/sbin/netstrategy` if [ $? -eq 0 ]; then if [ "$1" = "nfs" -o "$1" = "cachefs" ]; then _INIT_NET_IF="$2" fi _INIT_NET_STRATEGY="$3" export _INIT_NET_IF _INIT_NET_STRATEGY fi if [ "X${_INIT_NET_STRATEGY}" = "Xdhcp" ] ; then USING_DHCP=1 fi fi # # Get the complete list of network devices # so that we can ifconfig them individually # for i in `ifconfig -a |grep "^[a-z0-9]*:"` ; do echo $i |grep "^[a-z0-9]*:" >/dev/null 2>&1 if [ $? -eq 1 ]; then continue fi net_device_list="${i}${net_device_list}" done if [ -f /tmp/uberjs/uberjs-exec ]; then echo "Executing UberJS script: /tmp/uberjs/uberjs-server-exec" /sbin/sh /tmp/uberjs/uberjs-server-exec else if [ $USING_DHCP -eq 1 ] ; then echo "Using DHCP for network configuration information." dhcp_find_and_mount_cdrom else echo "Using RPC Bootparams for network configuration information." bootparams_find_and_mount_cdrom fi fi echo "fd - /dev/fd fd - no -" >> /etc/vfstab /sbin/mount -F fd /dev/fd ##### ### Intel/PPC private interface for unbundled device drivers ### Execute diskette shell script if [ ${PLATFORM} = ${PPC} -o ${PLATFORM} = ${I386} ]; then if [ -r /tmp/diskette_rc.d/rcs3.sh ]; then /sbin/sh /tmp/diskette_rc.d/rcs3.sh fi fi ########## # now we have /usr, we can load our keyboard mappings # (architecture specific mechanisms) # Included from init.d/keymap # # Systems with no hardware keyboard ID will provide an eeprom value. # if test -x /usr/lib/set_keyboard_layout then /usr/lib/set_keyboard_layout fi # Load the keymap for the attached keyboard. /usr/bin/loadkeys # Initialize the keyboard defaults [ -h /dev/kbd -a -x /usr/bin/kbd ] && /usr/bin/kbd -i >/dev/null 2>&1 # end of init.d/keymap code # save the name of the root device in /tmp/.preinstall if [ "${FJS_BOOT}" = "yes" -a "${From}" ]; then FromDisk=`echo ${From} | ( read d n junk ; echo $d )` if [ -b /devices/${FromDisk} ]; then lsline=`ls -l /dev/dsk | grep ${FromDisk}` if [ "${lsline}" ]; then shortname=`( set -- ${lsline} ; while [ $# -gt 3 ]; do shift; done if [ "$2" = "->" ]; then echo "$1"; else echo "" ; fi )` if [ -b /dev/dsk/${shortname} ]; then echo /dev/dsk/${shortname} > \ /tmp/.preinstall fi fi fi fi ########## # Intel config cleanup logic if [ -x /usr/sbin/install.d/atconfig ]; then /usr/sbin/install.d/atconfig fi ##### ### Intel/PPC - Sun private device driver update interface if [ ${PLATFORM} = ${PPC} -o ${PLATFORM} = ${I386} ]; then if [ -r /tmp/diskette_rc.d/rcs9.sh ]; then /sbin/sh /tmp/diskette_rc.d/rcs9.sh fi fi ######## # PowerPC Virtual OpenFirmware validation VOFCHECK=/usr/sbin/install.d/vofcheck if [ -x ${VOFCHECK} ]; then ${VOFCHECK} if [ $? != 0 ]; then if [ ! -z "${dial_pid}" ]; then kill $dial_pid >/dev/null 2>&1 fi echo echo "ERROR: The Solaris boot diskette must be inserted in the diskette" echo " drive to continue the Solaris installation program." echo echo " > Insert the Solaris diskette and press the Enter key." echo " The system will reboot." read a < /dev/console uadmin 2 0 fi fi ##### # Intel - Initialize boot properties if [ "`uname -m`" = "i86pc" ] && [ -x /usr/sbin/eeprom ]; then /usr/sbin/eeprom -I fi ########################################################################### # now we exit rcS, and the rc files bring the system further # on up (ie networking comes up...) ########################################################################### if [ ! -z "${dial_pid}" ]; then kill $dial_pid >/dev/null 2>&1 fi cat < /dev/null > /tmp/.rcSrun exit 0