#!/usr/bin/ksh # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # bos72V src/bos/sbin/rc.boot/rc.boot.sh 1.58.14.28 # # Licensed Materials - Property of IBM # # COPYRIGHT International Business Machines Corp. 1989,2019 # All Rights Reserved # # US Government Users Restricted Rights - Use, duplication or # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. # # IBM_PROLOG_END_TAG # @(#)62 1.58.14.28 src/bos/sbin/rc.boot/rc.boot.sh, bosboot, bos72V, v2019_39A1 9/12/19 12:21:01 # # COMPONENT_NAME: (BOSBOOT) Base Operating System Boot # # FUNCTIONS: rc.boot.sh # # ORIGINS: 27 # # (C) COPYRIGHT International Business Machines Corp. 1989, 1996 # All Rights Reserved # Licensed Materials - Property of IBM # # US Government Users Restricted Rights - Use, duplication or # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. # # local defines ODMSTRNG="attribute=keylock and value=service" # define local functions loopled () { ${SHOWLED} "$1" "$2" # show a LED code while : # loop forever do : done # End of loopled function. } native_netboot_cfg() { # # Function: configure system for native network boot # # Read IPL control block for network addresses ${NIM_DEBUG} eval $(bootinfo -c) # gather the network boot parameters # if VEND_GW is non-null, then it overrides BOOT_GATE_IP [ -n "$VEND_GW" ] && BOOT_GATE_IP=$VEND_GW if [ -n "$SUBMASK" ]; then OIFS="$IFS" IFS=. # separate the IP address octets for bitwise processing print $SUBMASK $BOOT_SERV_IP $CLIENT_IPADDR \ | IFS=" " read S1 S2 S3 S4 B1 B2 B3 B4 C1 C2 C3 C4 IFS="$OIFS" # unset BOOT_GATE_IP if bootp server (BOOT_SERV_IP) is on the same # subnet as bootp client (CLIENT_IPADDR) if [ $((${S1} & ${B1})).$((${S2} & ${B2})).$((${S3} \ & ${B3})).$((${S4} & ${B4})) = \ $((${S1} & ${C1})).$((${S2} & ${C2})).$((${S3} \ & ${C3})).$((${S4} & ${C4})) ]; then unset BOOT_GATE_IP fi SUBMASK="netmask $SUBMASK" fi [ "$BOOT_GATE_IP" = 0 -o "$BOOT_GATE_IP" = 0.0.0.0 ] && unset BOOT_GATE_IP # Get boot device PHY_BOOT_DEV=`bootinfo -b` # processing if VLAN is in use - VLAN_ID and VLAN_PCP come from bootinfo above if [ -n "$VLAN_ID" ]; then BASE_DEV=$PHY_BOOT_DEV PHY_BOOT_DEV=$(/usr/lib/methods/define -n -c adapter -s vlan -t eth) /usr/lib/methods/chgvlan -l $PHY_BOOT_DEV -a \ "base_adapter=$BASE_DEV vlan_tag_id=$VLAN_ID vlan_priority=$VLAN_PCP" /usr/lib/methods/cfgvlan -l $PHY_BOOT_DEV [ "$E802" -eq 1 ] && LDEV=et || LDEV=en LDEV=${LDEV}${PHY_BOOT_DEV##*([!0-9])} /usr/lib/methods/defif -c if -t en -s EN -w ${LDEV} fi # call the function to generate interface name pdev_to_ldev ${SHOWLED} 0x606 "IFCONFIG BOOTDEV" ifconfig lo0 inet 127.0.0.1 up # determine ipv6 or ipv4 and call ifconfig accordingly if [[ $CLIENT_IPADDR = *:* ]]; then # configure link-local (when a using global address) [[ $CLIENT_IPADDR != [Ff][Ee]80:* ]] && ifconfig $LDEV inet6 fe80:: eui64 up ifconfig $LDEV inet6 $CLIENT_IPADDR up || return 1 [ "$BOOT_GATE_IP" ] && route -v add -inet6 -host $BOOT_SERV_IP $BOOT_GATE_IP else ifconfig $LDEV inet $CLIENT_IPADDR up $SUBMASK || return 1 [ "$BOOT_GATE_IP" ] && route -v add $BOOT_SERV_IP $BOOT_GATE_IP fi # set up route tables [ -n "${ROUTES}" ] && { for route_args in $ROUTES do OIFS="$IFS"; IFS=':' set -- $route_args IFS="$OIFS" # verify that there are 3 arguments [ $# -ne 3 ] && continue route -v add -net $1 -netmask $2 $3 || return 2 done } # build file name with client IP address if bootfile name is null CLIENT_INFO_FILE=${BOOTFILE:-$CLIENT_IPADDR}.info } disknet_odm_init() { # # Function: initialize the ODM with basecust data # restbase # extract basecust data rc=$? [ $rc -ne 0 ] && loopled 0x605 "NET RESTBASE BAD" # fatal error # save ATM data and reset ODM odmget -q name=at0 CuAt > /tmp/odm_atm odmget -q name=at0 CuDv >> /tmp/odm_atm odmget -q "name=atm0 and attribute=uni_vers" CuAt >> /tmp/odm_atm odmget -q name=inet0 CuAt >> /tmp/odm_atm odmget -q name=inet0 CuDv >> /tmp/odm_atm odmget -q"resource=ddins and value3=;" CuDvDr > /tmp/odm odmdelete -o CuAt odmdelete -o CuDv odmdelete -o CuDvDr odmadd /tmp/odm } config_ATM() { # # Function: configure ATM network services # odmadd /tmp/odm_atm cd / $(lsdev -Clatm0 -FConfigure) -2 -l atm0 /usr/lib/methods/cfgif.at -l at0 ifconfig lo0 inet 127.0.0.1 mtu 16896 up ifconfig lo0 inet6 ::1 mtu 16896 up /usr/lib/methods/cfginet mkatmpvc atmsvcd muxatmd sleep 60 BOOT_SERV_IP=$(odmget -q "name=at0 and \ attribute=BSipaddr" CuAt | grep -w value | cut -d"\"" -f 2) odmdelete -q "name=at0 and attribute=BSipaddr" -o CuAt CLIENT_INFO_FILE=$(odmget -q "name=at0 and \ attribute=CIfilename" CuAt | grep -w value | cut -d"\"" -f 2) odmdelete -q "name=at0 and attribute=CIfilename" -o CuAt } pdev_to_ldev() { # # Function: generate interface name from physical device name and # increase ifsize if interface count exceeds the default of 8. # LDEV_NUM=${PHY_BOOT_DEV##*([!0-9])} case "$PHY_BOOT_DEV" in ent*) [ "$E802" -eq 1 ] && \ LDEV=et${LDEV_NUM} || \ LDEV=en${LDEV_NUM};; fddi*) LDEV=fi${LDEV_NUM};; hfi*) LDEV=hf${LDEV_NUM};; tok*) LDEV=tr${LDEV_NUM};; *) # unknown network boot device loopled 0x605 "UNKNOWN NET DEV";; esac if [ "${LDEV_NUM}" -gt 7 ]; then (( IF_COUNT = LDEV_NUM + 1 )) no -o ifsize=${IF_COUNT} fi } undolt() { # # Function: verify a few things that are susceptible to doltism. # these changes target problems found in the real world # # replace a couple of important symlinks if they're gone [[ -r /bin ]] || ln -s /usr/bin /bin [[ -r /lib ]] || ln -s /usr/lib /lib [[ -h /etc/init ]] || ln -fs /usr/sbin/init /etc/init # replace rc.boot if it has been removed [[ -s /sbin/rc.boot ]] || cp /../sbin/rc.boot /sbin # ensure that these files are executable chmod u+x /sbin/rc.boot /usr/sbin/init } ras_getattr() { # # Retrieve a value from the SWservAt base # # Argument: attribute name # # Return: attribute value # odmget -q attribute=$1 SWservAt | awk -F'"' '/value/ {print $2}' } sh_setup() { # # Setup for System Hang Detection # If the emergency login terminal is the console, then change the # console mode to be 'share' # if [ "`ras_getattr sh_pp`" = enable -a \ "`ras_getattr sh_pp_login`" = enable ] then login_term=`ras_getattr sh_pp_lterm` if [ "$login_term" = /dev/console -o "$login_term" = `lscons` ] then pshare /dev/console fi fi } cfg_iscsi_sw() { # configure tcp/ip and iSCSI SW protocol device and any iSCSI SW children set -x # loop for each ethernet interface lsdev -Cc if -s EN -F name | while read ifname; do # get this interface network address lsattr -El $ifname -a netaddr -F value | read addr if [ -n "$addr" ]; then # found an address # get subnetmask for this interface lsattr -El $ifname -a netmask -F value | read mask if [ -n "$mask" ]; then # found the subnetmask # extract mtu setting from ODM lsattr -El $ifname -a mtu -F value | read mtu # configure this interface ifconfig $ifname inet $addr arp netmask $mask mtu ${mtu:-1500} up print $? fi fi done # loop for each route that is associated with inet0 lsattr -Elinet0 -aroute -Fvalue | while read data; do # the next four lines replace commas with spaces OIFS=$IFS IFS=',' set -- $data IFS=$OIFS # store the resulting string in ROUTE_ARGS # and prepend it with a dash ROUTE_ARGS="-$@" route add $ROUTE_ARGS # run the route command done # configure the iSCSI SW protocol devices lsdev -Cc driver -s node -t iscsi -F name | while read iscsiname do if [ -n "$iscsiname" ]; then if [ "$PHASE" -eq 1 ]; then cfgmgr -fvl $iscsiname else cfgmgr -vl $iscsiname fi fi done } nim_mount() { # create new mount function for nfs client access -- NIM typeset object=${1} typeset access_pnt=${2} if [ -n "${NIM_NFS4_MOUNTS}" ]; then # start lite versions of portmap and nfsrgyd portmap.min nfsrgyd.min fi # run the mount command mount ${NIM_SPOT_MOUNT_OPTS} ${NIM_MOUNT_OPTS} \ ${object} ${access_pnt} || return 1 return 0 } # End of rc.boot functions. # Set environment HOME=/ LIBPATH=/usr/lib:/lib ODMDIR=/etc/objrepos PATH=/usr/sbin:/etc:/usr/bin SHOWLED=/usr/lib/methods/showled SYSCFG_PHASE=BOOT AIX_NO_SAVEBASE=1 CFGLOG=default export HOME LIBPATH ODMDIR PATH SHOWLED SYSCFG_PHASE AIX_NO_SAVEBASE CFGLOG umask 077 set -x # Get config boot phase argument PHASE=$1 PLATFORM=`bootinfo -p` # verify that the correct bootinfo module exists if [ ! -x "/usr/lib/boot/bin/bootinfo_${PLATFORM}" ]; then loopled 0xA10 "UNKNOWN PLATFORM" fi if [ "$PHASE" -eq 1 ]; then # save boot fs space by removing other platform modules for i in /usr/lib/boot/bin/!(*_${PLATFORM}); do init -c "unlink $i" done chramfs -t # expand RAMFS init -c "unlink /usr/sbin/chramfs" >/dev/null fi # Start the boot process for a particular device. BOOTYPE=`bootinfo -t` [ "$?" -ne 0 ] && loopled 0xA06 "UNKNOWN BOOTTYPE" [ -z "$BOOTYPE" ] && BOOTYPE=1 case "$BOOTYPE" in 1) # Disk boot unset pdev_to_ldev native_netboot_cfg unset disknet_odm_init config_ATM case "$PHASE" in 1) # Phase 1 boot - disk echo "\n\n_______________________________________"\ "_____________________________________" \ "\nrc.boot: starting disk boot process" \ >/tmp/boot_log # Also log an informational message to the cfg log echo "B1 Starting Disk Boot" > /tmp/cfg_log ln /usr/lib/lib* /lib # Call restore base echo "rc.boot: executing \"restbase\"" \ >>/tmp/boot_log restbase rc=$? [ $rc -eq 1 ] && ${SHOWLED} 0x548 "RESTBASE FAILED" #fatal error [ $rc -eq 2 ] && >/no_sbase #non-fatal error ${SHOWLED} 0x510 "DEV CFG 1 START" # Call config manager phase 1 echo "rc.boot: executing \"cfgmgr -f -v\"" \ >>/tmp/boot_log cfgmgr -f -v # if booted from iscsi, configure tcp and iscsi sw if [ "$(bootinfo -i)" -eq 1 ]; then cfg_iscsi_sw fi ${SHOWLED} 0x511 "DEV CFG 1 END" dvc=`bootinfo -b` if [ ! "${dvc}" ]; then if [ "$(bootinfo -U)" -eq 1 ]; then # VRM reserve failures were detected loopled 0x2702 "INSUFFICIENT ENTITLED MEMORY" fi loopled 0x554 "UNKNOWN BOOTDISK" fi echo "rc.boot: boot device is $dvc" \ >>/tmp/boot_log ln /dev/r$dvc /dev/ipldevice exit 0 ;; 2) # Phase 2 boot - disk ${SHOWLED} 0x551 "VARYON IPL DEV" # Bring up the root volume group echo "rc.boot: executing \"ipl_varyon -v\"" \ >>/tmp/boot_log ipl_varyon -v rc=$? case $rc in 0 ) ;; # do nothing 7 | 8 ) loopled 0x554 "BOOTDEV ACC FAIL";; 4 | 9 ) loopled 0x556 "LVM_QUERY ERROR";; * ) loopled 0x552 "IPLVARYON ERROR";; esac ln /usr/sbin/mount /etc/umount ${SHOWLED} 0x517 "MOUNT ROOT" echo "rc.boot: executing \"fsck -fp /\"" \ >>/tmp/boot_log { fsck -fp / 2>&1; print $? >/tmp/rc; } | \ tee -a /tmp/boot_log read rc >/tmp/boot_log { mount -f / 2>&1; print $? >/../tmp/rc; } | \ tee -a /../tmp/boot_log read rc &1 | \ /../usr/bin/tee -a /../tmp/boot_log # Mount /usr /../usr/lib/methods/showled 0x517 "MOUNT /USR" echo "rc.boot: executing \"fsck -fp /usr\"" \ >>/../tmp/boot_log /../usr/sbin/fsck -fp /usr 2>&1 | \ /../usr/bin/tee -a /../tmp/boot_log echo "rc.boot: executing \"mount /usr\"" \ >>/../tmp/boot_log { /../usr/sbin/mount /usr 2>&1; \ print $? >/../tmp/rc; } | \ /../usr/bin/tee -a /../tmp/boot_log read rc > /../tmp/boot_log \ 1> /../tmp/teboot_log fi echo "The \"date\" command is now available: " \ "`date`" >>/../tmp/boot_log if [ -f /etc/rc.B1 ]; then /etc/rc.B1 start fi # Mount /var for copycore ${SHOWLED} 0x517 "MOUNT /VAR" echo "rc.boot: executing \"fsck -fp /var\"" \ >>/../tmp/boot_log /usr/sbin/fsck -fp /var 2>&1 | \ tee -a /../tmp/boot_log echo "rc.boot: executing \"mount /var\"" \ >>/../tmp/boot_log { mount /var 2>&1; print $? >/../tmp/rc; } | \ tee -a /../tmp/boot_log read rc >/../tmp/boot_log copycore umount /var # Error Recovery if customized data is zero [ -f /../no_sbase ] && { echo "rc.boot: executing savebase recovery procedures" \ >>/../tmp/boot_log X=`ODMDIR=/etc/objrepos odmshow CuDv |\ fgrep population` count=`echo $X | cut -f2 -d' '` [ $count -ne 0 ] && { unset AIX_NO_SAVEBASE # allow savebase to run /usr/sbin/savebase [ $? -ne 0 ] && loopled 0x546 "SAVEBASE FAILED" mount /var # so that reboot can log echo "savebase recovery reboot" \ >>/../tmp/boot_log cat /../tmp/boot_log | alog -q -t boot reboot } } # Copy LVM information to the hardfile cp /../etc/vg/* /etc/vg 2>/dev/null # Copy ram filesystem ODM customized data to disk cp /../etc/objrepos/Cu* /etc/objrepos # Empty the CuAtSav ODM file. odmdelete -o CuAtSav >/dev/null 2>&1 # Start paging if no dump - find first auto paging dev lsps -t lv | while read lvname junk vgname junk junk \ junk autoflag junk; do if [ "$vgname" = "rootvg" -a \ "$autoflag" = "yes" ]; then break fi done # ensure that lvname is not null if [ -z "$lvname" ]; then lvname=hd6 fi # get size (in MB) of kernel startup pagespace # it is always a multiple of 32 MB PGSP_SZ=$(bootinfo -A) # get size (in MB) and count of default # paging logical volume partitions lslv -L $lvname | awk ' $4 == "PP" && $5 == "SIZE:" && $6 ~ /^[0-9]+$/ { PPSZ=$6 } $1 == "LPs:" && $2 ~ /^[0-9]+$/ { LPC=$2 } END { print PPSZ " " LPC } ' | read PART_SZ PART_CNT # compare startup pagespace size to # paging logical volume size. # non-null values are required for all fields. if [ "$PGSP_SZ" -a "$PART_SZ" -a "$PART_CNT" ]; then # logical volume size is the product # of partition size and count. if [ "$PGSP_SZ" -gt \ $(( "$PART_SZ" * "$PART_CNT" )) ]; then # how many more partitions required? # divide startup size by partition size, # then subtract existing count REQD_PARTS=$(("$PGSP_SZ" / "$PART_SZ" - "$PART_CNT")) if [ $((PGSP_SZ % PART_SZ)) -ne 0 ] then # handle case where bitmap size # modulo partition size != 0 (( REQD_PARTS +=1 )) fi echo "adding $REQD_PARTS partition(s) to $lvname" >>/../tmp/boot_log chps -s $REQD_PARTS $lvname rc=$? if [ $rc -ne 0 ]; then echo "chps failed with $rc" \ >>/../tmp/boot_log fi fi fi [ ! -f /needcopydump ] && swapon /dev/"$lvname" 2>&1 | \ tee -a /../tmp/boot_log ls32 -i /dev/ipl_blv 2>/dev/null | \ read PREV_BLV_INODE junk BOOTLV=/dev/r$(bootinfo -v) ls32 -i $BOOTLV 2>/dev/null | read CURR_BLV_INODE junk if [ "$CURR_BLV_INODE" -ne "$PREV_BLV_INODE" ]; then # update link ln -f "$BOOTLV" /dev/ipl_blv # determine if TCB is enabled odmget -q attribute=TCB_STATE \ PdAt 2>/dev/null | \ grep -q tcb_disabled 2>/dev/null TCB_ENABLED=$? # 1 indicates TCB is enabled if [ $TCB_ENABLED -eq 1 ]; then PREV_BLVPATH=$(find /dev -inum \ $PREV_BLV_INODE -print) tcbck -a $PREV_BLVPATH links= tcbck -a "$BOOTLV" links=/dev/ipl_blv fi fi sync; sync; sync # flush to disk # allow service if there is a dump or # need diag/maintenance KEYPOS=`odmget -q"$ODMSTRNG" CuAt` if [ -n "$KEYPOS" -o -f /needcopydump ] then echo "rc.boot: initiating service procedures" \ >>/../tmp/boot_log export KEYPOS mv /needcopydump /../ >/dev/null 2>&1 /usr/lib/boot/srvboot [ $? -ne 0 ] && { if [ `bootinfo -L` = "1" ]; then # yes, the box has LED display loopled 0x549 "SRVBOOT FAILED" fi # else there's no LED for us to # indicate that the dump image could # not be retrieved. # log it and move along echo "\nrc.boot: NOTICE: the dump image could not be saved." >>/../tmp/boot_log echo "Increase the size of the dump copy directory.\n" >>/../tmp/boot_log /usr/bin/sysdumpdev -z } fi # # If this is the first reboot since an update, # we need to move the new odm commands # and library into the proper place. # if [ -f /etc/rc.update ] then /etc/rc.update rm /etc/rc.update fi ${SHOWLED} 0x517 "MOUNT /VAR" echo "rc.boot: run time mount of /var" \ >>/../tmp/boot_log { mount /var 2>&1; print $? >/../tmp/rc; } | \ tee -a /../tmp/boot_log read rc /etc/filesystems ${SHOWLED} 0x517 "MOUNT ${boot_fs}" mount -rv ${boot_fs} ${bootdev} /SPOT [ "$?" -ne 0 ] && loopled 0x518 \ "MOUNT ${boot_fs} FAIL" ${SHOWLED} 0x512 "PREPARE RAM FS" # remove stuff from the boot RAM fs /SPOT/usr/bin/rm -r /etc/init /usr/bin /usr/lib/boot \ /usr/lib/drivers/* /usr/lib/methods/* /usr/sbin # recreate and populate RAM fs /usr/bin and /usr/sbin /SPOT/usr/bin/mkdir /usr/bin /usr/sbin /SPOT/usr/bin/ln -s /SPOT/usr/bin/* /usr/bin ln -s /SPOT/usr/sbin/* /usr/sbin cd /usr/bin rm ksh tee cat odmget copydumpmenu sh cd /SPOT/usr/bin cp ksh tee cat odmget copydumpmenu /usr/bin ln /usr/bin/ksh /usr/bin/sh cd /usr/sbin rm umount mount bootinfo lsdev mvdir cd /SPOT/usr/sbin cp mount bootinfo lsdev mvdir /usr/sbin ln /usr/sbin/mount /usr/sbin/umount # finish populating /usr in the boot RAM fs cd / mkdir -p /usr/ccs/bin /usr/lib/boot /usr/lib/nls \ /usr/lib/objrepos /usr/lpp /usr/share/lib ln -s /SPOT/usr/lib/instl /usr/lib cp -p /SPOT/usr/ccs/bin/* /usr/ccs/bin cp -Rp /SPOT/usr/lib/boot/* /usr/lib/boot rm /usr/lib/boot/bin/!(*_${PLATFORM}) cp -Rp /SPOT/usr/lib/nls/* /usr/lib/nls cp -p /SPOT/usr/lib/objrepos/* /usr/lib/objrepos cp -p /SPOT/usr/lib/* /usr/lib cp -Rp /SPOT/usr/lpp/* /usr/lpp cp -p /SPOT/* / # populate RAM fs directories with links that # point to the files in the optical filesystem ln -s /SPOT/usr/lib/drivers/* /usr/lib/drivers ln -s /SPOT/usr/lib/methods/* /usr/lib/methods ln -s /SPOT/usr/share/lib/* /usr/share/lib cp -p /SPOT/usr/lib/microcode/* /usr/lib/microcode ln -s /SPOT/usr/lib/boot/ssh /etc/init ln -s /usr/lib/objrepos/* /etc/objrepos # Enable device package name generation DEV_PKGNAME=ALL export DEV_PKGNAME strload -f /dev/null # Run config manager for remaining devices ${SHOWLED} 0x510 "DEV CFG 2 START" cfgmgr -p3 -v ${SHOWLED} 0x511 "DEV CFG 2 END" exit 0 ;; 2) # Phase 2 boot - CDROM rm -f /sbin/rc.boot unset loopled shift $# # copy diagnostic /etc/objrepos files to boot # RAM filesystem so that diags can write to them cp /SPOT/root/etc/objrepos/* /etc/objrepos ${SHOWLED} 0x513 "EXECUTE BI_MAIN" exec /usr/lpp/bosinst/bi_main exit 0 ;; *) exit 0 ;; esac ;; 4) # Tape boot unset pdev_to_ldev undolt native_netboot_cfg unset disknet_odm_init config_ATM case "$PHASE" in 1) # Phase 1 boot - tape ${SHOWLED} 0x510 "STRLOAD" strload -f /dev/null # Run config manager first phase cfgmgr -f -v # Enable device package name generation DEV_PKGNAME=ALL export DEV_PKGNAME ${SHOWLED} 0x510 "DEV CFG 2 START" # Run config manager second phase cfgmgr -p3 -v ${SHOWLED} 0x512 "PREPARE RAM FS" # Ensure that all tape drives are # configured to block size 512. lsdev -Cc tape -F name | while read tapename do `lsdev -Cl$tapename -FChange` -l $tapename \ -a block_size=512 done # Cleanup for i in /usr/lib/drivers/*/* /usr/lib/drivers/* \ /usr/lib/methods/cfglft \ /usr/lib/methods/startlft \ /usr/lib/methods/starttty \ /usr/lib/microcode/* \ /usr/lib/nls/loc/C.lftkeymap /usr/lpp/fonts/* \ /usr/sbin/strload do init -c "unlink $i" >/dev/null done exit 0 ;; 2) # Phase 2 boot - tape init -c "unlink /sbin/rc.boot" >/dev/null unset loopled shift $# ${SHOWLED} 0x513 "EXECUTE BI_MAIN" if [ -f /etc/rc.B1 ]; then /etc/rc.B1 install fi exec /usr/lpp/bosinst/bi_main exit 0 ;; *) exit 0 ;; esac ;; 5) # Network boot unset NIM_DEBUG # make sure this is null if not used # export NIM_DEBUG='set -x' case "$PHASE" in 1) # Phase 1 boot - network ${NIM_DEBUG} ${SHOWLED} 0x600 "NET BOOT START" if [ "$(bootinfo -b)" = "atm0" ]; then disknet_odm_init fi # configure the network boot device and parent devices ${SHOWLED} 0x600 "CONFIG NETBOOT" cfgmgr -fv # set up env variable for local name resolution export NSORDER=local # configure network - NOTE: we assume that the # "ROUTES" env variable is undefined at this # point. It may be defined for subsequent calls. if [ "$(bootinfo -b)" = "atm0" ]; then config_ATM [ $? -ne 0 ] && loopled 0x607 "IFCONFIG FAILED" else native_netboot_cfg [ $? -ne 0 ] && loopled 0x607 "IFCONFIG FAILED" fi # tftp read client miniroot mount point file ${SHOWLED} 0x608 "GET CLIENT FILE" until tftp -go /SPOT/niminfo \ $BOOT_SERV_IP $CLIENT_INFO_FILE image do ${SHOWLED} 0xfff ${SHOWLED} 0x608 "RETRY CLIENTFILE" done # dot execute the /SPOT/niminfo file to load variables if [ -s "/SPOT/niminfo" ] then . /SPOT/niminfo else loopled 0x609 "NIMINFO FAILED" fi # set nfso reserved port option for nfs client if [ "${NFS_RESERVED_PORT}" = "yes" ] then nfso -o nfs_use_reserved_ports=1 [ $? -ne 0 ] && loopled 0x2026 "NFSO FAILED" fi # create /etc/hosts for the RAM filesystem for host_lines in $NIM_HOSTS do OIFS="$IFS"; IFS=':' set -- $host_lines IFS="$OIFS" echo $* >> /etc/hosts done # IPv6 hosts entries need a different delimiter, # since the IPv6 address uses colons NEW_IPADDR= [ -n "${NIM_IPV6_HOSTS}" ] && { for host_lines in $NIM_IPV6_HOSTS do OIFS="$IFS"; IFS='|' set -- $host_lines IFS="$OIFS" echo $* >> /etc/hosts # save client's IP /etc/hosts address [[ $NIM_HOSTNAME = $2 ]] && NEW_IPADDR=$1 done # firmware might use link-local address to # boot, but we need the global address # ... convert hex digits to uppercase typeset -u NEW_IP_UPPER=$NEW_IPADDR typeset -u CLIENT_IP_UPPER=$CLIENT_IPADDR if [[ -n $NEW_IP_UPPER && $NEW_IP_UPPER != $CLIENT_IP_UPPER ]] then ifconfig $LDEV detach ifconfig $LDEV inet6 $NEW_IPADDR up fi } # set up route tables [ -n "${ROUTES}" ] && { if [ "$(bootinfo -b)" = "atm0" ]; then route -v flush fi for route_args in $ROUTES do OIFS="$IFS"; IFS=':' set -- $route_args IFS="$OIFS" # verify that there are 3 arguments [ $# -ne 3 ] && continue route -v add -net $1 -netmask $2 $3 || loopled 0x613 "ADD ROUTE FAILED" done } for route_args in $NIM_IPV6_ROUTES do OIFS="$IFS"; IFS='|' set -- $route_args IFS="$OIFS" # verify that there are 3 arguments [ $# -ne 3 ] && continue # if the install is link-local, don't set # anymore routes, the existing link route # is sufficient [[ $CLIENT_IPADDR = [Ff][Ee]80:* ]] && continue # ifconfig now creates routes that may # conflict with the new routes... delete # those routes first before proceeding if [[ "$2" = "0" ]] then route -v delete -inet6 -net $1 route -v add -inet6 -net $1 $3 || loopled 0x613 "ADD ROUTE FAILED" else route -v delete -inet6 -net $1 -netmask $2 route -v add -inet6 -net $1 -netmask $2 $3 || loopled 0x613 "ADD ROUTE FAILED" fi done > /etc/filesystems # Tell the NIM master that we are about to mount # the SPOT. nimclient -o change -a force=yes -a ignore_lock=yes \ -a info="LED 610: mount ${NIM_MOUNT_OPTS} -r $SPOT /SPOT/usr" # NFS mount the spot ${SHOWLED} 0x610 "MOUNT /SPOT/USR" nim_mount $SPOT /SPOT/usr if [[ "$?" -ne 0 ]] then nimclient -o change -a force=yes \ -a ignore_lock=yes \ -a info="LED 611: failure: mount -r $SPOT /SPOT/usr" loopled 0x611 "/SPOT MNT FAILED" fi # Clear out the info field on the client so it will # not look like the mount hung. nimclient -o change -a force=yes \ -a ignore_lock=yes -a info="" ${SHOWLED} 0x612 "CP RCCONF FILE" cp /SPOT/usr/lib/boot/network/$RC_CONFIG /etc RC_CONFIG=/etc/$RC_CONFIG . $RC_CONFIG exit 0 ;; 2) # Phase 2 boot - network ${NIM_DEBUG} export NSORDER=local PHY_BOOT_DEV=`bootinfo -b` . /SPOT/niminfo RC_CONFIG=/etc/$RC_CONFIG . $RC_CONFIG # Kill portmap.min and nfsrgyd.min if they're running. # This is done here because init cannot wait for # inherited processes. PIDS=`ps -A | awk '$NF == "portmap.min" || $NF == "nfsrgyd.min" { PIDS = PIDS $1 " " } END { print PIDS }'` if [ -n "$PIDS" ] then kill -s KILL $PIDS while ps -p "$PIDS" do sleep 1 done fi exit 0 # Exit to kernel newroot ;; 3) # Phase 3 inittab finish boot - network # Set the shell debugging if NIM asked. ${NIM_DEBUG} . /etc/niminfo # fall through to bottom - phase 3 common code ;; *) exit 0 ;; esac ;; *) loopled 0xA06 "UNKNOWN BOOTTYPE" ;; esac unset SYSCFG_PHASE echo "rc.boot: checking free space in /tmp" | alog -q -t boot # this removes enough files to create 1024 K free space in /tmp # if that much space is already free, it does nothing /usr/lib/boot/bootutil -d /tmp -s 1024 | alog -t boot # Load the streams modules echo "rc.boot: executing \"strload\"" | alog -t boot strload 2>&1 | alog -t boot # A thinserver having at least one NFS4-mounted FS must have # nfsrgyd and portmap running in order to resolve the string->id or # id->string for user/group id/names that are not cached. # So, start them with the srcmstr and then, kill the srcmstr because it # will be spawned by /etc/init later in the boot process. if [ $BOOTYPE -eq 5 -a -n "${NIM_NFS4_MOUNTS}" ] then /usr/sbin/portmap & /usr/sbin/nfsrgyd & fi # Don't configure the secondary dump device if it's a paging space # other than hd6. # Note: The primary should be hd6 if it's a paging space. # Get odm entry for the secondary dump device. dumpparm= dev=`odmget -q "attribute = 'tsecondary'" SWservAt |\ awk -F'"' '/value/ {print $2}'` # See if it's a paging space other than hd6 [[ -n "$dev" ]] && dev=`basename $dev` if [[ -n "$dev" && "$dev" != "hd6" ]] then # Check for paging space. lsps $dev >/dev/null 2>&1 if [[ $? = 0 ]] then # secondary is paging, don't set it now. dumpparm='-s /dev/sysdumpnull' fi fi # For the Remote Dump # Configure the iSCSI subsystem if the primary dump device is an iSCSI disk # get current primary dump device # must be called before current value is overwriten by permanent value primary=`odmget -q "attribute = 'primary'" SWservAt |\ awk -F'"' '/value/ {sub(/\/dev\//, ""); print $2}'` found=`lsdev -l $primary -c disk -s iscsi` if [ -n "$found" ] then #configure tcp and iscsi sw cfg_iscsi_sw # configure current primary dump device cfgmgr -l $primary | alog -t boot fi sysdumpdev -q $dumpparm # Allow 64-bit apps echo "rc.boot: allow 64-bit apps" | alog -t boot /usr/lib/methods/cfg64 | alog -t boot # Configure live dump echo "rc.boot: executing \"cfglivedump -c\"" | alog -t boot /usr/lib/methods/cfglivedump -c | alog -t boot # Taking firmware-assisted dump if there is one in progress /usr/sbin/copy_inmem_dump -f | alog -t boot # Run the configuration manager echo "rc.boot: executing \"cfgmgr\"" | alog -t boot /usr/bin/rm -f /.bootsequence /etc/locks/* >/dev/null 2>&1 set +x KEYPOS=`odmget -q"$ODMSTRNG" CuAt` if [ -n "$KEYPOS" ] then cfgmgr -p3 -v 2>&1 | alog -t boot # key is in service position /usr/lib/methods/cfgcon # this call to swcons disables controlling tty swcons -c else # This is for alt_disk_install, to define the console correctly if [ -s /etc/inst_info/alt_cons.add1 ]; then ODMDIR=/etc/objrepos odmdelete -q \ "name=sys0 and attribute = tmpcons" -o CuAt ODMDIR=/etc/objrepos odmdelete -q \ "name=sys0 and attribute = altcons" -o CuAt ODMDIR=/etc/objrepos odmadd /etc/inst_info/alt_cons.add2 rm -f /etc/inst_info/alt_cons.add2 fi cfgmgr -p2 -v 2>&1 | alog -t boot # key is in normal position if [ -s /etc/inst_info/alt_cons.add1 ]; then ODMDIR=/etc/objrepos odmdelete -q \ "name=sys0 and attribute = tmpcons" -o CuAt ODMDIR=/etc/objrepos odmdelete -q \ "name=sys0 and attribute = altcons" -o CuAt CONS=`grep value /etc/inst_info/alt_cons.add1 | cut -d"\"" -f2` chcons $CONS rm -f /etc/inst_info/alt_cons.add1 fi /usr/lib/methods/cfgcon # this call to swcons disables controlling tty swcons -c # Setup for System Hang Detection # If the emergency login terminal is the console, then change the # console mode to be 'share' sh_setup # # If desktop to be started in inittab, then start graphical boot # RLEVEL=`/usr/bin/cat /etc/.init.state 2>/dev/null` DTRUN=`/usr/bin/grep "^dt:" /etc/inittab | /usr/bin/cut -d: -f2` DTACT=`/usr/bin/grep "^dt:" /etc/inittab | /usr/bin/cut -d: -f3` if [ -n "$DTRUN" -a -s "/etc/rc.dt" -a -s "/usr/bin/X11/aixconsole" \ -a "$RLEVEL" != "S" -a "$DTACT" != "off" ] then RUNINFO=`/usr/bin/grep ":initdefault:" /etc/inittab \ | /usr/bin/cut -d: -f2` if [ "$DTRUN" = "$RUNINFO" ] ; then >/.bootsequence /etc/rc.dt boot | alog -t boot -q /usr/bin/sleep 8 fi fi # # End of Graphical Boot Startup # fi # Inform kernel of boot progress for VRM entitlement /usr/lib/boot/bootutil -p sysdumpdev -q $dumpparm # Save base customize # (this must be done AFTER system console setup) unset AIX_NO_SAVEBASE # Allow savebase to save data. echo "\nSaving Base Customize Data to boot disk" | alog -t boot # savebase for disk booted systems [ "$BOOTYPE" -eq 1 ] && savebase # savebase for net boot systems [ "$BOOTYPE" -eq 5 ] && savebase -d /etc/basecust # Remove unavailable ttys from inittab # also remove ttyx if it is serving as the console /usr/lib/methods/cleantty sync; sync if [ -f /etc/rc.B1 ]; then /etc/rc.B1 label fi echo "Starting the sync daemon" | alog -t boot nohup /usr/sbin/syncd 60 > /dev/null 2>&1 & # deleting error notification objects that should not survive reboot odmdelete -o errnotify -q "en_persistenceflg=0" >/dev/null 2>&1 # prepare diagnostics Service Event queue file for diagela # error notifications prior to starting the interface to SFP if [ -x /usr/lpp/diagnostics/bin/diagServiceEvent ] then touch /etc/lpp/diagnostics/data/diagSE_queue fi # Get the platform dump directory. dir=`odmget -q "attribute = 'fwdump_dir'" SWservAt |\ awk -F'"' '/value/ {print $2}'` if [[ -n "$dir" ]] then # See if FS is defined lsfs $dir >/dev/null 2>&1 if [[ $? = 0 ]] then # mount the fs echo "Mounting the platform dump file system, $dir" | alog -t boot mount $dir 2>&1 | alog -t boot fi fi if [ -x /usr/lib/errdemon ] then echo "Starting the error daemon" | alog -t boot /usr/bin/rm -f /tmp/errdemon.$$ /usr/lib/errdemon >/tmp/errdemon.$$ 2>&1 if [ $? -ne 0 ] then cat /tmp/errdemon.$$ | alog -t boot echo "Starting the errdemon with the system default" \ "log file, /var/adm/ras/errlog." | alog -t boot /usr/lib/errdemon -i /var/adm/ras/errlog fi /usr/bin/rm -f /tmp/errdemon.$$ fi #Update etrace kernel variables with ODM values if [ -x "/usr/bin/probevctrl" ] then /usr/bin/probevctrl -i | alog -t boot fi ${SHOWLED} 0xFFF # If shutdown did not end gracefully rm -f /etc/nologin # start the mirrod if it exists [ -x /usr/sbin/mirrord ] && /usr/sbin/mirrord mir_modem # Configuration check, if it exists [ -x /usr/lib/methods/cfgchk ] && /usr/lib/methods/cfgchk | alog -t boot # do diagnostic stuff if this particular machine supports it bootinfo -M > /dev/null rc=$? if [ $rc -eq 101 -o $rc -eq 103 ]; then diag_ok=1 # diagnostics are supported else diag_ok=0 # diagnostics are not supported fi if [ $diag_ok = 1 ]; then # Setup Service boot and display message for missing devices. if [ -n "$KEYPOS" ]; then # this call to swcons enables controlling tty swcons +c DIAGD=/usr/lpp/diagnostics/bin [ -s $DIAGD/diagsrv ] && \ $DIAGD/diagsrv -b /dev/console 2>&1 # diagnostics exits by doing a shutdown, so we should # never get back to this point fi fi # Complete end of boot tasks /usr/lib/boot/bootutil -e # Check for pending power events /etc/rc.powerfail -p & > /dev/console 2>&1 # Restoring secure NLSPATH value, if it exists nlspath=`ODMDIR=/usr/lib/objrepos /usr/bin/odmget -q \ attribute=SEC_NLSPATH PdAt | /usr/bin/awk -F '"' '/deflt/ {print $2}'` if [ -n "$nlspath" ] then /usr/sbin/chnlspath $nlspath fi # Suspend initialization until fw-assisted system dump has completed /usr/sbin/copy_inmem_dump -s sysdumpdev -q $dumpparm echo "System initialization completed." | alog -t boot echo "B1" `date -u +"%D %r %Z"` "rc.boot complete." | alog -qt cfg exit 0