#!/bin/ksh # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # bos72Q src/bos/usr/lib/nim/methods/c_mkbooti.sh 1.22.3.2 # # Licensed Materials - Property of IBM # # COPYRIGHT International Business Machines Corp. 1993,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 # @(#)45 1.22.3.2 src/bos/usr/lib/nim/methods/c_mkbooti.sh, cmdnim, bos72Q, q2019_26A2 6/21/19 14:05:01 # COMPONENT_NAME: CMDNIM # # FUNCTIONS: ./usr/lib/nim/methods/c_mkbooti.sh # # # ORIGINS: 27 # # # (C) COPYRIGHT International Business Machines Corp. 1993, 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. # include common NIM shell defines/functions NIMPATH=${0%/*} NIMPATH=${NIMPATH%/*} [[ ${NIMPATH} = ${0} ]] && NIMPATH=/usr/lpp/bos.sysmgt/nim NIM_METHODS="${NIMPATH}/methods" . ${NIM_METHODS}/c_sh_lib #---------------------------- local defines -------------------------------- IF_SUPPORTED="if_supported" NETDIR="lib/boot/network" KERNELDIR='lib/boot' PROTODIR='lib/boot/network' PROTO='lib/boot/network/*.proto' RS6K_PROTO='lib/boot/network/rs6k.*.proto' RS6KSMP_PROTO='lib/boot/network/rs6ksmp.*.proto' CHRP_PROTO='lib/boot/network/chrp.*.proto' CHRPSMP_PROTO='lib/boot/network/chrpsmp.*.proto' PROTOEXT='lib/boot/protoext' #---------------------------- module globals -------------------------------- REQUIRED_ATTRS="location name" OPTIONAL_ATTRS="platform debug if_defined if_remove" location="" name="" debug="" preview="" typeset proto_files="" typeset boot_image_created="" cmd="${BOSBOOT} -a" typeset -i tmp_needed=0 typeset -i tftpboot_needed=0 typeset -i num_booti=0 enter_dbg_mp="" enter_dbg_up="" enter_dbg_64="" typeset boot_kernel="" typeset boot_platform="" typeset boot_network="" #---------------------------- mkboot_images_41 -------------------------------- # # NAME: mkbooti_images_41 # # FUNCTION: # This function builds boot images for 4.1 SPOTs. # It creates a boot image for each file in # /usr/lib/boot/network/*.proto in the SPOT that # contains a valid platform type. The platform # type must be one of the valid platforms passed in # from C_CKSPOT. Boot images created by this routine # use the following naming convention: # .. # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # cmd # # RETURNS: (int) # 0 = success # # OUTPUT: # writes IF_SUPPORTED attr assignments to stdout # in the form: if_supported = #------------------------------------------------------------------------------- function mkboot_images_41 { typeset types="" typeset platform_type="" typeset print_platform="" typeset if_type="" typeset supported_platform="" typeset kernel="" typeset bi_name="" typeset pf="" typeset rs6k_proto_files="" typeset remove_rs6ksmp="" typeset remove_chrpsmp="" # the NIM master is at 4.1 -- so create 4.1 boot images # for this 4.2 SPOT -- build the rs6ksmp boot images if # rs6k platform is supported using the rs6k proto files # chrp proto files will also be used to build the chrpsmp # boot images. if (( (( (( ${spot_version} == 4 )) && (( ${spot_release} >= 2 )) )) || (( ${spot_version} > 4 )) )) then # get list of all rs6k proto files rs6k_proto_files="${location}/${RS6K_PROTO}" # get list of all chrp proto files chrp_proto_files="${location}/${CHRP_PROTO}" # link rs6k proto files to rs6ksmp proto files for pf in ${rs6k_proto_files} do if_type=`echo ${pf} | ${CUT} -d"." -f2` ${LN} -s ${pf} ${location}/${NETDIR}/rs6ksmp.${if_type}.proto done # link chrp proto files to chrpsmp proto files for pf in ${chrp_proto_files} do if_type=`echo ${pf} | ${CUT} -d"." -f2` ${LN} -s ${pf} ${location}/${NETDIR}/chrpsmp.${if_type}.proto done # get proto list again after changes proto_files="${location}/${PROTO}" # link rs6k proto config to rs6ksmp if [[ -s ${location}/${PROTOEXT}/rs6k.pcfg ]] then ${LN} -s ${location}/${PROTOEXT}/rs6k.pcfg \ ${location}/${PROTOEXT}/rs6ksmp.pcfg fi # link the rs6k mkboot to rs6ksmp if [[ -s ${location}/lib/boot/bin/mkboot_rs6k ]] then ${LN} -s ${location}/lib/boot/bin/mkboot_rs6k \ ${location}/lib/boot/bin/mkboot_rs6ksmp fi # remove rs6ksmp proto files when done remove_rs6ksmp=yes # remove chrpsmp proto files when done remove_chrpsmp=yes fi # # For each proto file in the SPOT... # for pf in ${proto_files} do # # Skip any bad proto files # [[ ! -s ${pf} ]] && continue # expecting proto files to be named like: # ..proto # ignore the parent directoy pathname & separate the proto filename # into these parts IFS='.' set -- ${pf##*/} IFS=${OLD_IFS} # how many fields in the proto filename? if [[ $# -eq 2 ]] then # assume the platform is rs6k platform_type=rs6k if_type=${1} elif [[ $# -eq 3 ]] then platform_type=${1} if_type=${2} else warning ${ERR_VALUE} ${pf} ".proto filename" continue fi # interface type must exist in predefined device database or bosboot # will barf [[ -z "$( ${ODMGET} -qprefix=${if_type} PdDv 2>/dev/null )" ]] && continue # platform must match one of the types specified in the platform attr # which was passed by the caller for types in ${platform} do supported_platform=${types%%=*} kernel=${location}/${KERNELDIR}/${types##*=} # does this proto file match a supported platform type? [[ ${platform_type} != ${supported_platform} ]] && continue # skip bad kernels [[ ! -s ${kernel} ]] && continue # construct a boot image pathname like this: # /tftpboot/.. bi_name="${TFTPBOOT}/${name}.${platform_type}.${if_type}" # Save the original platform type to print out # later as a supported platform for booting. # Do this in case the platform_type is changed for # chrpsmp. print_platform=${platform_type} # The chrpsmp type is really chrp with an mp kernel. # Change the parameters accordingly for the bosboot # command. if [[ ${platform_type} = "chrpsmp" ]] then platform_type="chrp" pf=`echo ${pf} | sed s/chrpsmp/chrp/` fi # create a network boot image if ${cmd} -b ${bi_name} \ -d /dev/${if_type} \ -T ${platform_type} \ -p ${pf} \ -k ${kernel} 2>${ERR} 1>&2 then # just previewing info? if [[ -n "${preview}" ]] then preview_data continue fi # print out the attr assignment so that m_instspot can add it to # the SPOTs definition so that NIM knows what kind of interfaces # this SPOT supports print "${IF_SUPPORTED}=${platform_type} ${if_type}" # flag that we've created a boot image for this platform type [[ "${boot_image_created}" != *\ ${platform_type}=+([! ])\ * ]] && eval boot_image_created=\"${boot_image_created} \ ${platform_type}=\$enter_dbg_${kernel##*_} \" else # cache the error messages from BOSBOOT ${CAT} ${ERR} >>${TMPDIR}/bosboot.errors 2>/dev/null fi done # for each platform type done # for each proto file # remove any rs6ksmp proto files that we created if [[ ${remove_rs6ksmp} = yes ]] then ${RM} ${location}/${RS6KSMP_PROTO} ${RM} ${location}/${PROTOEXT}/rs6ksmp.pcfg ${RM} ${location}/lib/boot/bin/mkboot_rs6ksmp fi # remove any chrpsmp proto files that we created if [[ ${remove_chrpsmp} = yes ]] then ${RM} ${location}/${CHRPSMP_PROTO} fi } # end mkboot_images_41 #---------------------------- mkboot_images_42 -------------------------------- # # NAME: mkbooti_images_42 # # FUNCTION: # This function rebuilds the boot images for SPOTs created # on 4.2 or later. It creates a UP and MP boot image for each # /usr/lib/boot/network/*.proto file located in the SPOT. # For 5.4 SPOTs and later, only 64bit boot images are created. # Boot images created by this routine will use the following # naming convention: # ... # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # cmd # # RETURNS: (int) # 0 = success # # OUTPUT: # writes IF_SUPPORTED attr assignments on stdout # in the form: if_supported = . #------------------------------------------------------------------------------- function mkboot_images_42 { typeset types="" typeset platform_type="" typeset if_type="" typeset supported_platform="" typeset kernel="" typeset bi_name="" typeset pf="" typeset duplicate_platform="no" # # For each proto file in the SPOT... # for pf in ${proto_files} do # # Skip any bad proto files # [[ ! -s ${pf} ]] && continue # expecting proto files to be named like: # ..proto # ignore the parent directoy pathname & separate the proto filename # into these parts IFS='.' set -- ${pf##*/} IFS=${OLD_IFS} # how many fields in the proto filename? if [[ $# -eq 2 ]] then # assume the platform is rs6k platform_type=rs6k if_type=${1} elif [[ $# -eq 3 ]] then platform_type=${1} if_type=${2} else warning ${ERR_VALUE} ${pf} ".proto filename" continue fi # interface type must exist in predefined device database or bosboot # will barf [[ -z "$( ${ODMGET} -qprefix=${if_type} PdDv 2>/dev/null )" ]] && continue if [[ -n "${boot_kernel}" ]] then KERNELS=${location}/${KERNELDIR}/unix_${boot_kernel} elif (( (( (( ${spot_version} == 5 )) && (( ${spot_release} >= 4 )) )) || (( ${spot_version} > 5 )) )) then KERNELS=${location}/${KERNELDIR}/unix_64 elif (( (( ${spot_version} == 5 )) && (( ${spot_release} = 3 )) )) then KERNELS=${location}/${KERNELDIR}/unix_@(mp|64) else KERNELS=${location}/${KERNELDIR}/unix_[um]p fi # build a MP and UP boot image for each proto file for kernel in ${KERNELS} do duplicate_platform=no [[ ! -s ${kernel} ]] && continue # construct a boot image pathname like this: # /tftpboot/... kernel_type=`${BASENAME} ${kernel} | ${CUT} -d"_" -f2` bi_name="${TFTPBOOT}/${name}.${platform_type}.${kernel_type}.${if_type}" # create a network boot image if ${cmd} -b ${bi_name} \ -d /dev/${if_type} \ -T ${platform_type} \ -p ${pf} \ -k ${kernel} 2>${ERR} 1>&2 then # just previewing info? if [[ -n "${preview}" ]] then preview_data continue fi # POC - Temporary code that will be removed with firmware limitations eventually get lifted. ${C_BOOTDISKHDR} -a spot=$name -a if_defined=${platform_type}.${kernel_type}.${if_type} # print out the attr assignment so that m_instspot can add it to # the SPOTs definition so that NIM knows what kind of interfaces # this SPOT supports print "${IF_SUPPORTED}=${platform_type}.${kernel_type} ${if_type}" # has this platform already been added? for types in ${boot_image_created} do if [[ ${types%%=*} = ${platform_type}.${kernel##*_} ]] then duplicate_platform=yes break fi done # flag that we've created a boot image for this platform if [[ ${duplicate_platform} = no ]] then [[ "${boot_image_created}" != *\ ${platform_type}=+([! ])\ * ]] && if [[ -n ${if_defined} ]] then eval boot_image_created=\"${boot_image_created} \ ${platform_type}.${kernel##*_}.${if_type}=\$enter_dbg_${kernel##*_} \" else eval boot_image_created=\"${boot_image_created} \ ${platform_type}.${kernel##*_}=\$enter_dbg_${kernel##*_} \" fi fi else # cache the error messages from BOSBOOT ${CAT} ${ERR} >>${TMPDIR}/bosboot.errors 2>/dev/null fi done # for each kernel done # for each proto file } # end mkbooti_images_42 #---------------------------- turn_debug_on -------------------------------- # # NAME: turn_debug_on # # FUNCTION: # makes the required changed to enable the kernel debugger in the network # boot images # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # cmd # # RETURNS: (int) # 0 = success # # OUTPUT: # writes enter_dbg symbol addresses to stdout #------------------------------------------------------------------------------- function turn_debug_on { typeset kernel="" typeset kernel_type="" typeset enter_dbg="" # we want a network boot image which has the kernel debugger enabled cmd="${cmd} -I" # turn on debugging in the rc.boot file if ${AWK} '$0 !~ /^[[:space:]]*export NIM_DEBUG=/{print};\ /[ ]*unset NIM_DEBUG/{print "export NIM_DEBUG=\"set -x\""}'\ ${RCBOOT} >${TMPDIR}/rc.boot 2>${ERR} then ${CAT} ${TMPDIR}/rc.boot >${RCBOOT} 2>${ERR} || err_from_cmd ${CAT} fi # return the enter_dbg info for kernel in ${location}/${KERNELDIR}/unix_@(mp|up|64) do # what type of kernel? kernel_type=${kernel##*_} enter_dbg="" enter_dbg=$( ${NM} -X32_64 -x ${kernel} | ${GREP} enter_dbg | \ ${AWK} 'NR==1{print $3}' 2>/dev/null ) # remember the enter_dbg address eval enter_dbg_${kernel_type}=${enter_dbg} done } # end of turn_debug_on #---------------------------- turn_debug_off -------------------------------- # # NAME: turn_debug_off # # FUNCTION: # changes the appropriate files to disable the kernel debugger for the # network boot images # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # cmd # # RETURNS: (int) # 0 = success # # OUTPUT: #------------------------------------------------------------------------------- function turn_debug_off { # we don't want the kernel debugger enabled cmd="${cmd}" # turn off debugging in the rc.boot file if ${AWK} '$0 !~ /^[[:space:]]*export NIM_DEBUG=/{print}' ${RCBOOT} \ >${TMPDIR}/rc.boot 2>${ERR} then ${CAT} ${TMPDIR}/rc.boot >${RCBOOT} 2>${ERR} || err_from_cmd ${CAT} fi } # end of turn_debug_off #---------------------------- preview_data -------------------------------- # # NAME: preview_data # # FUNCTION: # reads the "bosboot -q" information and writes the information to stdout # when parameter #1 is non-NULL # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # 1 = when non-NULL, write preview data # global: # # RETURNS: (int) # 0 = success # # OUTPUT: # writes preview data to stdout #------------------------------------------------------------------------------- function preview_data { typeset write_data=${1} typeset line="" typeset -i new_tmp=0 # write the preview data or read new info? if [[ -n "${write_data}" ]] then # write the data print "tmp_needed=${tmp_needed}" print "tftpboot_needed=${tftpboot_needed}" print "num_booti=${num_booti}" else # parse the "bosboot -q" output ${CAT} ${ERR} | \ while read line do set -- ${line} case ${1} in /tmp) (( ${2} > tmp_needed )) && let tmp_needed=${2} ;; /|/tftpboot|/*/tftpboot) (( ${2} > tftpboot_needed )) && let tftpboot_needed=${2} ;; esac done let num_booti+=1 fi } # end of preview_data #---------------------------- mkbooti -------------------------------- # # NAME: mkbooti # # FUNCTION: # Determines the level of the SPOT whose boot images are being # rebuilt, and calls either mkboot_41 or mkboot_42 to rebuild # the images. # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # cmd # # RETURNS: (int) # 0 = success; boot images created # # OUTPUT: #------------------------------------------------------------------------------- function mkbooti { typeset enter_dbg="" typeset types="" typeset -i spot_version=0 typeset -i spot_release=0 # generate list of proto files which reside in SPOTname/usr/lib/boot/network if [[ -n "${if_defined}" ]] then # expecting if_defined parameters to look like: # .kernel. IFS='.' set -- ${if_defined} IFS=${OLD_IFS} boot_platform=${1} boot_kernel=${2} boot_network=${3} proto_files="${location}/${PROTODIR}/${boot_platform}.${boot_network}.proto" else proto_files="${location}/${PROTO}" fi if [[ -z "${preview}" ]] && [[ -z "${if_remove}" || "${if_remove}" = "yes" ]] then # # We're committed to re-building the boot images, so # delete all existing boot images for this SPOT. # ${RM} ${TFTPBOOT}/${name}.* 2>${ERR} || err_from_cmd ${RM} # # # Gather the list of available platforms in the SPOT for use # by the platform listing routines if [[ -n "${if_remove}" ]] && [[ "${if_remove}" = "yes" ]] then ${LS} ${location}/${PROTO} 2>/dev/null | while read pf do pf=${pf##*/} # remove path if [[ -n "$pf" ]] then echo "plat_defined=\c" echo $pf | ${CUT} -d'.' -f1 fi done | ${SORT} -u fi fi if [[ -z "${preview}" ]] then # was debug specified? if [[ -n "${debug}" ]] then # we want a network boot image which has the kernel debugger enabled turn_debug_on else # we don't want the kernel debugger enabled turn_debug_off fi fi # get the version and release of the SPOT # whose boot images we are rebuilding ODMDIR=/usr/lib/objrepos ${ODMGET} -q "lpp_name='bos.rte' and update='0'" \ product >${TMPDIR}/spot.product 2>${ERR} || err_from_cmd ${ODMGET} let spot_version=$( ${AWK} '$1=="ver"{print $3}' ${TMPDIR}/spot.product \ 2>/dev/null ) let spot_release=$( ${AWK} '$1=="rel"{print $3}' ${TMPDIR}/spot.product \ 2>/dev/null ) # build the boot images if (( (( (( ${spot_version} == 4 )) && (( ${spot_release} >= 2 )) )) || (( ${spot_version} > 4 )) )) then # if 4.1 master building a 4.2 SPOT, the platform kernel # pairs will be passed in -- build 4.1 version boot images if [[ -n "${platform}" ]] then mkboot_images_41 else # if 4.2 master building a 4.2 SPOT or if 4.3 master building # all possible boot images, then boot image will be created for # every network proto combination. Otherwise, only the network # combination passed in as the nettype will be built. if [[ -z "${if_remove}" ]] || [[ -n "${if_defined}" ]] then mkboot_images_42 fi fi else mkboot_images_41 fi # replace ERR file with cached error messages ${CAT} ${TMPDIR}/bosboot.errors >${ERR} 2>/dev/null # preview or errors? if [[ -n "${preview}" ]] then # write the preview info preview_data "TRUE" elif [[ -z "${boot_image_created}" ]] && [[ -z "${if_remove}" ]] then # no network boot images could be created # print the "missing" attr so that it gets added so the SPOT's definition print "missing=\"${MSG_MISSING_BOOTI}\"" # display error message [[ -s ${ERR} ]] && err_from_cmd ${BOSBOOT} || error ${ERR_NO_BOOTI} elif [[ -s ${TMPDIR}/bosboot.errors ]] then warning_from_cmd ${BOSBOOT} fi if [[ -n "${debug}" ]] && [[ -n "${boot_image_created}" ]] then # print out the enter_dbg info for types in ${boot_image_created} do print "enter_dbg=\"${types%%=*} ${types##*=}\"" done fi } # end of mkbooti #---------------------------- c_mkbooti -------------------------------- # # NAME: c_mkbooti # # FUNCTION: # creates a network boot image for each interface which has a proto file # in the SPOTname/usr/lib/boot/network directory # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # 0 = boot images created; attr assignments on stdout # 1 = failure # # OUTPUT: # writes IF_SUPPORTED attr assignments on stdout #------------------------------------------------------------------------------- # signal processing trap cleanup 0 trap err_signal 1 2 11 15 export INUCLIENTS=yes # NIM initialization nim_init # initialize local variables typeset c="" # set parameters from command line while getopts :a:pqv c do case ${c} in a) # validate the attr ass parse_attr_ass "${OPTARG}" # include the assignment for use in this environment eval ${variable}=\"${value}\" ;; p) # preview bosboot size requirements preview=TRUE cmd="${cmd} -q" ;; q) # show attr info cmd_what exit 0 ;; v) # verbose mode (for debugging) set -x for i in $(typeset +f) do typeset -ft $i done ;; \?) # unknown option error ${ERR_BAD_OPT} ${OPTARG} ;; esac done # check for missing attrs ck_attrs # create the boot images mkbooti # all done exit 0