#!/bin/ksh # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # bos720 src/bos/usr/lib/nim/methods/c_getlevel.sh 1.11.1.3 # # Licensed Materials - Property of IBM # # Restricted Materials of IBM # # COPYRIGHT International Business Machines Corp. 2011,2014 # 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 # @(#)72 1.11.1.3 src/bos/usr/lib/nim/methods/c_getlevel.sh, cmdnim, bos720, 1432A_720 7/29/14 11:39:52 # # COMPONENT_NAME: cmdnim # # FUNCTIONS: ck_mksysb # ck_source # prep_SPOT # prep_cd # prep_rte # prep_tape # # ORIGINS: 27 # # # (C) COPYRIGHT International Business Machines Corp. 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 -------------------------------- typeset -i FUDGE_FACTOR=5 TAR_CREATE="${TAR} -cdpf - -C" TAR_EXTRACT="${TAR} -xpf -" #---------------------------- module globals -------------------------------- REQUIRED_ATTRS="source type" OPTIONAL_ATTRS="" typeset -i version=0 typeset -i release=0 typeset -i mod=0 oslevel_r="" oslevel_s="" source="" src_access="" type="" #---------------------------- prep_tape -------------------------------- # # NAME: prep_tape # # FUNCTION: # prepares the specified tape device and gets the level of the # bos image on the tape. # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # 0 = success # # OUTPUT: #------------------------------------------------------------------------------- function prep_tape { # tape needs a "no-rewind-on-close" extension # was one provided? if [[ ${source} = /dev/rmt[0-9].* ]] then [[ ${source} != /dev/rmt[0-9].1 ]] && \ [[ ${source} != /dev/rmt[0-9].5 ]] && \ error ${ERR_SOURCE} ${source} src_access=${source} else # append the extension src_access="${source}.5" fi # rewind the tape ${TCTL} -f ${src_access} rewind 2>${ERR} || err_from_cmd tctl # position to 4th record ${TCTL} -f ${src_access} fsf 3 2>${ERR} || err_from_cmd tctl # need to validate the AIX release level of this image, so we need the # the LPP_NAME file - restore it now cd ${TMPDIR} 2>${ERR} || err_from_cmd cd ${RESTORE} -xqf ${src_access} ${LPP_NAME} >/dev/NULL 2>${ERR} # if the restore succeeded, then get the level from the extracted # lpp_name file. Otherwise, use the level from the currently # installed NIM client fileset. if [[ $? -eq 0 ]] then # validate the release level ck_rel_level ${TMPDIR}/${LPP_NAME} else get_fileset_level ${NIM_CLIENT_PACKAGE} fi # rewind the tape ${TCTL} -f ${src_access} rewind 2>${ERR} || err_from_cmd tctl } # end of prep_tape #---------------------------- prep_cd -------------------------------- # # NAME: prep_cd # # FUNCTION: # prepares a CDROM device and gets the level of the BOS image # on the CD. # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # 0 = success # # OUTPUT: #------------------------------------------------------------------------------- function prep_cd { # mount the CDROM nim_mount ${source} [[ ! -e "${access_pnt}/${BOS_PATH_ON_CDROM}" ]] && \ BOS_PATH_ON_CDROM=${BOS_PATH_ON_CDROM_OLD} src_access=${access_pnt}/${BOS_PATH_ON_CDROM} # need to validate the AIX release level of this image, so we need # the LPP_NAME file - restore it now cd ${TMPDIR} 2>${ERR} || err_from_cmd cd ${RESTORE} -xqf ${src_access} ${LPP_NAME} >/dev/null 2>${ERR} # if the restore succeeded, then get the level from the extracted # lpp_name file. Otherwise, use the level from the currently # installed NIM client fileset. if [[ $? -eq 0 ]] then # validate the release level ck_rel_level ${TMPDIR}/${LPP_NAME} else get_fileset_level ${NIM_CLIENT_PACKAGE} fi } # end of prep_cd #---------------------------- prep_SPOT -------------------------------- # # NAME: prep_SPOT # # FUNCTION: # prepares a SPOT and gets the level of BOS that is installed. # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # 0 = success # # OUTPUT: #------------------------------------------------------------------------------- function prep_SPOT { typeset old_LANG # make sure source pathname ends with "/usr" if [[ "${source##*/}" != usr ]] then source=${source}/usr fi # get product data from spots ODM database odm_fileset_level=`ODMDIR=${source}/lib/objrepos ${ODMGET} -q "lpp_name=bos.rte" product\ | ${AWK} '/state =|rel =|mod =|ver =|fix =|lpp_name =/ \ { if ($1 == "state") c_state=$3 if ($1 == "ver") vrmf[1]=$3 if ($1 == "rel") vrmf[2]=$3 if ($1 == "mod") vrmf[3]=$3 if ($1 == "fix") { vrmf[4]=$3 if (c_state == 3 || c_state == 5) { bigger=0 for ( ix=1; ix<=4; ix++ ) { if (vrmf[ix] < h_vrmf[ix]) break if (vrmf[ix] > h_vrmf[ix]) bigger++ } if (bigger > 0) for ( ix=1; ix <= 4; ix++ ) h_vrmf[ix] = vrmf[ix] } for ( ix=1; ix <= 4; ix++ ) vrmf[ix] = 9999; } } END { print h_vrmf[1] "." h_vrmf[2] "." h_vrmf[3] "." h_vrmf[4] }'` # parse off the vrmf data into variables. vrmf=${odm_fileset_level} version=`echo ${vrmf} | ${CUT} -d"." -f1` release=`echo ${vrmf} | ${CUT} -d"." -f2` mod=`echo ${vrmf} | ${CUT} -d"." -f3` fix=`echo ${vrmf} | ${CUT} -d"." -f4` # Now run "oslevel -rf; oslevel -s" in the SPOT. location=${source} setup_chroot_env ${SET_CHROOT_LIBPATH} old_LANG=${LANG} export LANG=C oslevel_r=$(${chroot} ${OSLEVEL} -rf 2>/dev/null) oslevel_s=$(${chroot} ${OSLEVEL} -s 2>/dev/null) export LANG=${old_LANG} # If oslevel_r is not the form of 5200-1, logical AND the value of # oslevel_r with 1100 or ${version}${release}00 to get its base value # and not the level of bos.rte. if [[ -z ${oslevel_r} ]] then oslevel_r=`echo $vrmf | ${SED} 's/\.//g'` let oslevel_r="$oslevel_r & ${version}${release}00" fi [[ -z ${oslevel_s} ]] && oslevel_s=$oslevel_r ${UNSET_CHROOT_LIBPATH} print "oslevel_r=${oslevel_r}" print "oslevel_s=${oslevel_s}" } # end of prep_SPOT #---------------------------- prep_rte -------------------------------- # # NAME: prep_rte # # FUNCTION: # prepares environment to check a bos image in a directory to # determine its level. # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # 0 = success # # OUTPUT: #------------------------------------------------------------------------------- function prep_rte { typeset dir=${source%/*} typeset filename=${source##*/} # directory where rte exists must be local to the server # ${C_STAT} -a location=${dir} 2>${ERR} || err_from_cmd ${C_STAT} # need to validate the AIX release level of this image, so we need the # the LPP_NAME file - restore it now cd ${TMPDIR} 2>${ERR} || err_from_cmd cd # If the $source file exists, then restore the lpp_name file from it # to get the code level. If it does not exist, then get the level of # the currently installed NIM client fileset. if [[ -a ${source} ]] then ${RESTORE} -xqf ${source} ${LPP_NAME} >/dev/null 2>${ERR} || \ err_from_cmd ${RESTORE} # validate the release level ck_rel_level ${TMPDIR}/${LPP_NAME} else get_fileset_level ${NIM_CLIENT_PACKAGE} fi } # end of prep_rte #---------------------------- ck_mksysb ------------------------------ # # NAME: ck_mksysb # # FUNCTION: # verifies that the specified mksysb has an acceptable version/release # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # Mksysbs created on 4.2 and later will contain a line in the form # "OSLEVEL= V.R.M.F" in the image.data file that holds the release # information. For mksysbs created on 4.1, the uname information # will continue to be used to retrieve the release information. # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # 0 = success # # OUTPUT: #------------------------------------------------------------------------------- function ck_mksysb { typeset -i ok_version=${1:-${DEFAULT_REQUIRED_VERSION}} typeset -i ok_release=${2:-${DEFAULT_REQUIRED_RELEASE}} typeset filename=${source##*/} typeset datafile=${TMPDIR}/${IMAGE_DATA} typeset uname_info="" typeset oslevel="" # mount remote source, if necessary nim_mount ${source} # filename containing mksysb must exist ${C_STAT} -a force=yes -a location=${access_pnt} -a mode=0100000 2>${ERR} \ || err_from_cmd ${C_STAT} # for mksysb images, the version/release info is in the image.data file # restore that file now cd ${TMPDIR} 2>${ERR} || err_from_cmd cd ${RESTORE} -xqf ${access_pnt} ${IMAGE_DATA} >/dev/null 2>${ERR} || \ err_from_cmd ${RESTORE} # IMAGE_DATA readable? [[ ! -r "${datafile}" ]] && error ${ERR_FILE_ACCESS} ${datafile} # OSLEVEL_R specified in IMAGE_DATA? oslevel_r=$( ${AWK} '$1=="OSLEVEL_R="{print}' ${datafile} 2>/dev/null ) if [[ -n "${oslevel_r}" ]] then # remove OSLEVEL_R= from the string oslevel_r=${oslevel_r##*=*( )} fi # OSLEVEL_S specified in IMAGE_DATA? oslevel_s=$( ${AWK} '$1=="OSLEVEL_S="{print}' ${datafile} 2>/dev/null ) if [[ -n "${oslevel_s}" ]] then # remove OSLEVEL_S= from the string oslevel_s=${oslevel_s##*=*( )} fi # OSLEVEL specified in IMAGE_DATA? # OSLEVEL should be in image.data file for 4.2+ releases # It's in the form "OSLEVEL= ...". oslevel=$( ${AWK} '$1=="OSLEVEL="{print}' ${datafile} 2>/dev/null ) if [[ -n "${oslevel}" ]] then # remove the OSLEVEL string oslevel=`echo ${oslevel} | ${CUT} -d"=" -f2` # get version level version=$( echo ${oslevel} | ${CUT} -d"." -f1 ) # get release level release=$( echo ${oslevel} | ${CUT} -d"." -f2 ) # get modification level mod=$( echo ${oslevel} | ${CUT} -d"." -f3 ) else # must be 4.1 mksysb - use UNAME_INFO to get version info # UNAME_INFO specified in IMAGE_DATA? uname_info=$(${AWK} '$1=="UNAME_INFO="{print}' ${datafile} 2>/dev/null) [[ -z "${uname_info}" ]] && \ error ${ERR_INCOMPLETE} \ "UNAME_INFO stanza missing from ${IMAGE_DATA} in ${source}" # what's the version/release? # expecting a string like "UNAME_INFO= AIX rel ver cpuid" set -- ${uname_info} [[ $# -lt 5 ]] && error ${ERR_VALUE} "${uname_info}" \ "UNAME_INFO stanza from the ${IMAGE_DATA} file in ${source}" version=${5} release=${4} # if 4.2+ OSLEVEL should have been in image.data file if (( (( (( ${version} == 4 )) && (( ${release} >= 2 )) )) || (( ${version} > 4 )) )) then error ${ERR_INCOMPLETE} \ "OSLEVEL stanza missing from ${IMAGE_DATA} in ${source}" fi fi # make sure they're numeric [[ "${version}" != +([0-9]) ]] && \ error ${ERR_RELEASE_LEVEL} "${version}" "${release}" "${source}" [[ "${release}" != +([0-9]) ]] && \ error ${ERR_RELEASE_LEVEL} "${version}" "${release}" "${source}" [[ "${mod}" != +([0-9]) ]] && \ error ${ERR_VER_REL_MOD} "${version}" "${release}" "${mod}" \ "${source}" # now check the values if (( ${version} < ${ok_version} )) then error ${ERR_RELEASE_LEVEL} ${version} ${release} "${source}" elif (( ${ok_release} > 0 )) then if (( ${release} < ${ok_release} )) then error ${ERR_RELEASE_LEVEL} ${version} ${release} "${source}" fi fi # If oslevel_r is not the form of 5200-1, logical AND the value of # oslevel_r with 1100 or ${version}${release}00 to get its base value # and not the level of bos.rte. if [[ -n $oslevel_r ]] then echo $oslevel_r | ${GREP} "-" >/dev/null 2>&1 if [[ $? -ne 0 ]] then let oslevel_r="$oslevel_r & ${version}${release}00" fi print "oslevel_r=${oslevel_r}" fi [[ -z ${oslevel_s} ]] && oslevel_s=$oslevel_r print "oslevel_s=${oslevel_s}" } # end of ck_mksysb #---------------------------- ck_source -------------------------------- # # NAME: ck_source # # FUNCTION: # prepares the specified source device for use # # EXECUTION ENVIRONMENT: # # NOTES: # calls error on failure # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # 0 = success # # OUTPUT: #------------------------------------------------------------------------------- function ck_source { # what kind of source? case ${type} in device) # tape or CDROM? if [[ ${source} = /dev/rmt[0-9]* ]] then prep_tape elif [[ ${source} = /dev/cd[0-9]* ]] then prep_cd else error ${ERR_SOURCE} ${source} fi ;; spot) # source is a SPOT prep_SPOT ;; rte) # source is a BOS rte (runtime) image prep_rte ;; mksysb|ios_mksysb) # source is a mksysb (system backup) image ck_mksysb ;; *) # unknown type error ${ERR_SYS} "unknown source type - \"${type}\"" ;; esac } # end of ck_source #---------------------------- c_getlevel -------------------------------- # # NAME: c_getlevel # # FUNCTION: # Examines the AIX version/release level for the specified # source. If the level can not be determined, then the level # of the currently installed NIM client fileset will be used. # # EXECUTION ENVIRONMENT: # # NOTES: # # RECOVERY OPERATION: # # DATA STRUCTURES: # parameters: # global: # # RETURNS: (int) # 0 = version/release ok # 1 = error encountered - message on stderr # # OUTPUT: #------------------------------------------------------------------------------- # signal processing trap cleanup 0 trap err_signal 1 2 11 15 # NIM initialization nim_init # initialize local variables location= source= # set parameters from command line while getopts :a:qv 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}\" ;; 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 # check the specified source ck_source # if we get this far, level is ok # return the version & release on stdout as attr assignments so the calling # method will pick them up print "version=${version}" print "release=${release}" # modification level is only on mksysb definitions # starting with 4.2 and later if (( (( (( ${version} == 4 )) && (( ${release} >= 2 )) )) || (( ${version} > 4 )) )) then print "mod=${mod}" fi # all done exit 0