#!/bin/ksh ## Copyright 2005 Sun Microsystems, Inc. All rights reserved. ## Use is subject to license terms. ## Is it safe to proceed. ARCH=`uname -p` if [ $ARCH != i386 ]; then exit 0 fi PATH="/usr/bin:/usr/sbin:${PATH}"; export PATH ZDIR=/etc/zones PKGCOND=/usr/bin/pkgcond PKGINFO=/usr/bin/pkginfo patchdir="${PWD}" typeset -r ku_base_pid=118844-21 DONT_NEED_NEWBOOT_FILE="${ROOTDIR}/tmp/.we_dont_need_newboot" patch=118844-19 uname=$(uname -v) uname=${uname##*_} # remove text before underscore... if [ "$ROOTDIR" = "/" ] ; then if [[ $uname == "Generic" ]] || \ [[ ${uname%-*} == ${patch%-*} && ${uname#*-} -lt ${patch#*-} ]]; then print -u2 "\ In order to apply this patch, the Kernel patch ${patch}, must be installed and the system rebooted prior to installing this patch. \ " exit 1 fi fi last_patch() { ## returns the number of patches installed at or above this rev. ## if this is the first rev of the patch ## prepatch will return 0 ## postpatch, prebackout, and postbackout will return 1 root_dir=${ROOTDIR:-/} ## parse id and rev pid=`echo $1 | cut -d\- -f1` prev=`echo $1 | cut -d\- -f2` patch_cnt=0 ## get all installed refernces to the installed patch base id installed_patches=`patchadd -p -R $root_dir -p | sed -n -e 's/Req.*//' -e 's/[a-zA-Z]*://g' -e 's/,//g' -e "/$pid/p"` for x in $installed_patches ; do base=`echo $x | cut -d\- -f1` rev=`echo $x | cut -d\- -f2` if [ $pid -eq $base ] && [ $rev -ge $prev ] ; then ## count all installed patches includeing this patch patch_cnt=$(($patch_cnt + 1)) fi done return $patch_cnt } is_new_boot_installed() { #Check if NewBoot has been applied on the system rm -f "${DONT_NEED_NEWBOOT_FILE}" last_patch $ku_base_pid if [ "$?" -gt "0" ] ; then touch "${DONT_NEED_NEWBOOT_FILE}" fi } update_logindevperm() { cp $ROOTDIR/etc/logindevperm $ROOTDIR/etc/logindevperm.before-$PatchNum } function CheckForRequiredFiles { # # Look for required files; if any are missing, bail out with an error. # if [ ! -x $patchdir/zfs_cache ]; then echo ERROR: Missing zfs_cache command. exit 1; fi if [ ! -f $patchdir/fbtmplmeth.ksh ]; then echo ERROR: Missing reboot service method template exit 1; fi if [ ! -f $patchdir/fbtmplsvc.xml ]; then echo ERROR: Missing reboot service XML manifest exit 1; fi return 0 } load_mods() { ## load modules during patch installation per 6349240 ## to prevent warnings from displaying on the console ## before the system is rebooted. ## find all kernel driver modules in patch PLATFORM=`uname -i` CLASS=`uname -m` ISA_INFO=`/usr/bin/isainfo -b` cd ${patchdir:-$PWD} for i in * do pkginfo `echo $i | cut -f 1 -d '.'` > /dev/null 2>&1 if [ $? -eq 0 ]; then grep " kernel\>" $i/pkgmap | grep -v mpxio | grep -v kmdb grep "/kernel\>" $i/pkgmap | grep "${PLATFORM}/" | grep -v "cpu" | grep -v kmdb grep "/kernel\>" $i/pkgmap | grep "$CLASS/" | grep -v "cpu" | grep -v "kmdb/" fi done 2>/dev/null | nawk '/^1 f/ && ! /\.conf|\/unix|\/genunix/ {print $4}' >/tmp/modules.$$ if [ "$ROOTDIR" = "/" ] ; then ## ## Disable kernel module unloading ## print "Disabling kernel module unloading ... \n" if [ -x /usr/bin/mdb ]; then if [ $ISA_INFO = 64 ]; then SAVED_ADDR=`echo '_kobj_printf/J' | mdb -k | cut -f2 -d ':'` echo '_kobj_printf/Z systrace_stub' | mdb -kw > /dev/null 2>&1 else SAVED_ADDR=`echo '_kobj_printf/X' | mdb -k | cut -f2 -d ':'` echo '_kobj_printf/W systrace_stub' | mdb -kw > /dev/null 2>&1 fi echo "moddebug/W20000" | adb -kw /dev/ksyms /dev/mem | grep moddebug > /dev/null 2>&1 else echo "mdb not found: patchadd not safe." fi while read line; do ## preload each module [ -f /$line ] && { ## echo "loading module $line" modload /$line > /dev/null 2>&1 } done < /tmp/modules.$$ fi if [ $ISA_INFO = 64 ]; then echo '_kobj_printf/Z '$SAVED_ADDR | mdb -kw > /dev/null 2>&1 else echo '_kobj_printf/W '$SAVED_ADDR | mdb -kw > /dev/null 2>&1 fi mv /tmp/modules.$$ /tmp/backoutmods.$PatchNum } CheckZones() { if [ "$ROOTDIR" = "/" -a -x /usr/bin/zonename ]; then ZONENAME=`/usr/bin/zonename` if [ ${ZONENAME} = "global" ]; then GLOBAL_ZONE=true else GLOBAL_ZONE=false fi else # Unable to determine zone GLOBAL_ZONE=true fi } fix_cputrak() { ################################################################################ # Removal of cputrack object is to circumvent the stringent check ( attribute # checking ) in the local zone environment. # ERROR: attribute verification of failed. ################################################################################ Quiet() { typeset -r cmd_n_args=$* eval "$cmd_n_args" > /dev/null 2>&1 } typeset -r cpu_dir=$ROOTDIR/usr/bin typeset -r cpu_track=$cpu_dir/cputrack typeset -r cpu_pkg=SUNWcpcu Quiet removef -R $ROOTDIR $cpu_pkg $cpu_track Quiet removef -R $ROOTDIR -f $cpu_pkg # Destroy the hardlink regardless of the zone type (global/local(sparse, blank)) /usr/bin/rm -f $cpu_track ################################################################################ } ## ## Move kbtrans to the correct pkg if needed. ## fix_kbtrans() { rmpkg=SUNWusb addpkg=SUNWckr kbtrans=/kernel/misc/amd64/kbtrans relocate_kbtrans() { if [ ! -f $ROOTDIR/$kbtrans ] ; then return fi ## This patch will add kbtrans to SUNWckr. Manually remove it from SUNWusb ## if it exists ## Pgk=`pkgchk -R $ROOTDIR -l -p $kbtrans | grep $rmpkg` if [ "$?" = "0" ] ; then removef -R $ROOTDIR $rmpkg $ROOTDIR/$kbtrans 1>/dev/null 2>&1 removef -R $ROOTDIR -f $rmpkg installf -R $ROOTDIR $addpkg $ROOTDIR/$kbtrans installf -R $ROOTDIR -f $addpkg save_kbtrans_pkgmap fi } relocate_kbtrans return 0 } ## ## Save kbtrans entry ## ## Address 6343544 by using workaround 6312956 - removef doesn't update zones ## saved pkgmap files. We'll use cp -p to preserve permissions on the pkgmap ## file. Even though kbtrans may have moved from SUNWusb to SUNWckr, the ## pkgmap still needs to be cleaned up after the package switch is complete. ## save_kbtrans_pkgmap () { rmpkg=SUNWusb kbtrans_entry=kernel/misc/amd64/kbtrans mypatchid=${PatchNum} if [ ! -d $ROOTDIR/var/sadm/pkg/$rmpkg/save/pspool/$rmpkg ]; then return fi cd $ROOTDIR/var/sadm/pkg/$rmpkg/save/pspool/$rmpkg ## Until removef/installf is fixed, we'll check if the entry is ## still in the origin package's pkgmap if grep "$kbtrans_entry" pkgmap >/dev/null then ## Save kbtrans entry in backoutpkgmap for postbackout restore backoutpkgmap=/tmp/$rmpkg.pkgmap.$mypatchid mkdir -p "`dirname $backoutpkgmap`" cp -p pkgmap $backoutpkgmap grep "$kbtrans_entry" pkgmap > $backoutpkgmap ## Remove kbtrans entry in present SUNWusb pkgmap to clean up cp -p pkgmap pkgmap.tmp grep -v "$kbtrans_entry" pkgmap > pkgmap.tmp mv pkgmap.tmp pkgmap fi } ## ## newboot support ## newboot () { BASEDIR=$ROOTDIR MEMSIZE_MIN=250 MDPATCH=117435-02 if [ -f "$BASEDIR/platform/i86pc/multiboot" ]; then return 0 fi # # Check for sufficient system memory # memsize=`prtconf | grep "Memory size:" | cut -d' ' -f3` if [ "$memsize" -lt "$MEMSIZE_MIN" ]; then echo "Not enough memory for GRUB based boot process." exit 1 fi # # Check for biosdev and make sure it works # if [ -x /sbin/biosdev ]; then /sbin/biosdev 2> /dev/null | grep "^0x80" > /dev/null if [ $? = 0 ]; then return 0 fi fi # # biosdev failed. We can still apply the patch if the rootdisk # is the same as the bootdisk # bootdev=`prtconf -v /devices | sed -n '/boot-device/{n;p;}' | grep pci | cut -f 2 -d \'` rootdev=`df -k ${BASEDIR:-/} | nawk 'NR > 1 { print $1 }'` if [ -n "$bootdev" ] ; then ls -l $rootdev | grep $bootdev > /dev/null if [ $? = 0 ]; then return 0 fi fi # echo "" echo "ERROR: One of the following may need to be corrected prior to installing this patch." echo "ERROR:" echo "ERROR: The boot device may be different from the root device on `hostname`." echo "ERROR: If you have booted from a floppy disk, eject the disk and reboot `hostname` prior" echo "ERROR: to installing this patch." echo "" echo "ERROR: You may have forgotten to reboot `hostname` AFTER installing $MDPATCH." echo "ERROR: This configuration requires that $MDPATCH be installed first and the" echo "ERROR: system must then be rebooted prior to installing this patch." echo "" exit 1 } ExecuteALLCmds () { newboot fix_kbtrans CheckForRequiredFiles load_mods update_logindevperm is_new_boot_installed return 0 } LocalZones () { # commands specific to non-gloabl zones return 0 } ExecuteInProperEnvironment () { ## $PKGCOND is_path_writable $ROOTDIR/usr/bin && fix_cputrak /usr/bin/touch ${ROOTDIR}/usr/bin/.test.$$ > /dev/null 2>&1 && { fix_cputrak /usr/bin/rm /usr/bin/.test.$$ > /dev/null 2>&1 } if $PKGCOND is_whole_root_nonglobal_zone > /dev/null 2>&1 ; then # Execute non-global whole root zone commands. # Should be same action as the default action. update_logindevperm return 0 fi if $PKGCOND is_nonglobal_zone > /dev/null 2>&1 ; then # Execute non-global zone commands. Should be no action here update_logindevperm return 0 fi if $PKGCOND is_netinstall_image > /dev/null 2>&1 ; then # Execute commands applicable to patching the mini-root. # There are usually no actions to take here since your patching # the mini-root on an install server. update_logindevperm ExecuteALLCmds return 0 fi if $PKGCOND is_mounted_miniroot > /dev/null 2>&1 ; then # Execute commands specific to the mini-root fix_kbtrans update_logindevperm return 0 fi if $PKGCOND is_diskless_client > /dev/null 2>&1 ; then # Execute commands specific to diskless client fix_kbtrans update_logindevperm return 0 fi if $PKGCOND is_alternative_root > /dev/null 2>&1 ; then # Execute commands specific to an alternate root ExecuteALLCmds return 0 fi if $PKGCOND is_global_zone > /dev/null 2>&1 ; then # In a global zone and system is mounted on /. # Execute all commands. ExecuteALLCmds return 0 fi return 1 } AlternateRoot() # returns 0 if $PKG_INSTALL_ROOT - { if [ -n "$ROOTDIR" ]; then if [ "/" = "`echo $ROOTDIR |nawk '{gsub(/\/+/,"/"); print}'`" ]; then return 1 else return 0 fi else return 1 fi } Check_miniroot() { if [ ! -z "$PKGDBARG" ]; then echo $PKGDBARG | grep "^\-C" > /dev/null 2>&1 if [ $? -eq 0 ] ; then if [ X"$PKG_NONABI_SYMLINKS" != X"true" ]; then return 1 fi fi fi return 0 } CheckLOFI() { LOFITESTF1=/tmp/.lofitestf1.$$.$PatchNum LOFITESTF2=/tmp/.lofitestf2.$$.$PatchNum mkdir -p /tmp echo "1" >$LOFITESTF1 echo "2" >$LOFITESTF2 if mount -F lofs $LOFITESTF1 $LOFITESTF2 >/dev/null 2>&1; then if [ X"`cat $LOFITESTF2`" = X"1" ]; then # well lofs mount does work _LOFI=0 else #It does not work :( _LOFI=1 fi else _LOFI=1 fi umount $LOFITESTF2 >/dev/null 2>&1 rm -f $LOFITESTF2 $LOFITESTF1 return $_LOFI } zfs_zones_check() { if [ ! -x "/usr/sbin/zoneadm" ]; then # zoneadm does not exist, so we have no problem here return 0 fi zone_list="" # # Look at all zones for the "dataset" keyword. # We look at all installed zones. # for zone in $(zoneadm -R ${ROOTDIR:-/} list -i) do if [[ ${zone} == "global" ]]; then continue fi grep " /dev/null 2>&1 || pkgparam -R $ROOTDIR SUNWsndmr > /dev/null 2>&1; } \ && { pkgparam -R $ROOTDIR SUNWopenssl-libraries > /dev/null 2>&1 \ || { cat <