#!/bin/sh # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # # Set path # PATH="/usr/bin:/usr/sbin:${PATH}" export PATH # # Set variables # BASEDIR=${BASEDIR:=/} FAILURE=1 # the kernel modules we install and the order of dependencies MODULES="nskern ncall nsctl sdbc" OS_VER=`eval uname -r` PKG_INSTALL_ROOT=${PKG_INSTALL_ROOT:=/} DEVLINKTB=${PKG_INSTALL_ROOT}/etc/devlink.tab NAMEMAJOR=${PKG_INSTALL_ROOT}/etc/name_to_major TMP_DSCFG=/tmp/dscfg.${PKGINST}.$$ ARCH=`uname -p` HOST=`/usr/bin/hostname` DSCFG="/usr/sbin/dscfg -r $PKG_INSTALL_ROOT" PCONFIG="${PKG_INSTALL_ROOT}/etc/dscfg_format" DSCFG_REF="${PKG_INSTALL_ROOT}/etc/opt/SUNWesm/dscfg.cf" DSCFG_LOCAL="${PKG_INSTALL_ROOT}/etc/dscfg_local" # number of KB required for the dscfg database (1024 * 5.5) DSCFG_SIZE=5632 FS_LOCAL_SVC="svc:/system/filesystem/local" EXIT=0 MODBUSY=0 MODBUSYMSG=" #### NOTICE #####\n The previous version of this software cannot be unloaded (busy).\n To load the new modules you must reboot the system." # # Functions # message() { echo "" echo "$@" echo "" } add_devlink() { PATTERN="$1" LINK="$2" echo "$PATTERN\t$LINK" >>${DEVLINKTB} } valid_dscfg_exists() { if [ -s $DSCFG_REF ]; then DSCFG_LOC=`head -1 $DSCFG_REF` DSCFG_LOC=${PKG_INSTALL_ROOT}${DSCFG_LOC} DSCFG_LOC=`echo $DSCFG_LOC | tr -s '/'` contains_data $DSCFG_LOC return $? fi return 0 } # used to test if a valid DS config database exists on machine already # MAGIC_STRING is the top line in the config used in v3.1 & v3.2 # contains_data() { $xopt # dscfg distinct strings, varies on the architecture if [ $ARCH = "sparc" ] then MAGIC_STRING="MAGI" elif [ $ARCH = "i386" ] then MAGIC_STRING="IGAM" fi # Create a PID unique temporary file TMP_FILE=/tmp/$$ # Write the first or 16th block (skipping over VTOC) to # the TMP_FILE, then scan for the presence of the "MAGI" # for offset in 0 16 do if [ ! -z "$1" ]; then dd if=$1 of=$TMP_FILE count=1 iseek=$offset 2>/dev/null FILECONTENTS=`strings $TMP_FILE | head -1 2>/dev/null` if [ `echo $FILECONTENTS | grep -c "$MAGIC_STRING"` -gt 0 ]; then rm $TMP_FILE return 1 fi fi done rm $TMP_FILE return 0 } # returns 1 if the dscfg is a cluster db, 0 otherwise is_cluster_db() { # # Check to see if we're in a cluster. # It has to be a /dev/did/rdsk device and it must contain ctags. # DID=`echo ${DSCFG_LOC} | awk -F/ '{print $3}'` RDSK=`echo ${DSCFG_LOC} | awk -F/ '{print $4}'` if [ "did" = $DID -a "rdsk" = $RDSK -a -c ${DSCFG_LOC} ]; then # check if there are any cluster tags. Do this by verifying # that the output with no cluster tags is equivalent to the # complete output without scm tags cat ${TMP_DSCFG}.1 | grep -v "^scm: " | diff - ${TMP_DSCFG}.2 \ > /dev/null 2>&1 if [ $? != 0 ] then return 1 fi fi return 0 } # move the old dscfg to the new standard location convert_dscfg() { # # First, grab some info from the old db # # backup contents of the old dscfg database ${DSCFG} -s ${DSCFG_LOC} -l 2> /dev/null | grep -v "^#" > ${TMP_DSCFG}.1 # grab all entries without a ctag ${DSCFG} -s ${DSCFG_LOC} -l -C - 2> /dev/null | grep -v "^#" \ > ${TMP_DSCFG}.2 # are we in a cluster? is_cluster_db if [ $? = 0 ] then # we're in a non-cluster environment--just reinit the config # First, just make sure we don't overwrite an existing dscfg if [ "$DSCFG_LOC" != "$DSCFG_LOCAL" ] then echo y | ${DSCFG} -i > /dev/null 2>&1 ${DSCFG} -i -p ${PCONFIG} > /dev/null 2>&1 ${DSCFG} -a ${TMP_DSCFG}.1 > /dev/null 2>&1 fi else # # We're in a cluster. # reinitialize new database with the contents of the old # strip out all dscfg entries that have a cluster tag other than # l.<my_host_name> # # grab all entries with a ctag of l.<my_host_name> ${DSCFG} -s ${DSCFG_LOC} -l -C l.${HOST} 2> /dev/null | \ grep -v "^#" > ${TMP_DSCFG}.3 # replace "l.$HOST" with "-" in ${TMP_DSCFG}.3 sed "s/l.${HOST}/-/g" ${TMP_DSCFG}.3 > ${TMP_DSCFG}.4 # merge the two, removing duplicate entries cat ${TMP_DSCFG}.2 ${TMP_DSCFG}.4 | sort -u > ${TMP_DSCFG}.5 # reinit the local dscfg, with the ctag info stripped out # First, just make sure we don't overwrite an existing dscfg valid_dscfg_exists $DSCFG_LOCAL if [ $? = 0 ] then echo y | ${DSCFG} -i > /dev/null 2>&1 ${DSCFG} -i -p ${PCONFIG} > /dev/null 2>&1 ${DSCFG} -a ${TMP_DSCFG}.5 > /dev/null 2>&1 fi # init the cluster dscfg ${DSCFG} -s ${DSCFG_LOC} echo y | ${DSCFG} -i -C - > /dev/null 2>&1 ${DSCFG} -i -p ${PCONFIG} -C - > /dev/null 2>&1 ${DSCFG} -a ${TMP_DSCFG}.1 -C - > /dev/null 2>&1 fi # cleanup rm -f ${TMP_DSCFG}.1 rm -f ${TMP_DSCFG}.2 rm -f ${TMP_DSCFG}.3 rm -f ${TMP_DSCFG}.4 rm -f ${TMP_DSCFG}.5 } # # Setup the service to enable. This is necessary to deal # with upgrade situations. It also sets the proper dependency type for the # local filesystems service # $1: name of service to enable # enable_service_on_reboot() { # enable the service svcadm enable -s svc:/system/$1 if [ $? -ne 0 ] then message "Warning: Unable to enable $1 service" fi # workaround for 6221374--let local-fs know that it depends on us svcadm refresh ${FS_LOCAL_SVC}:default if [ $? -ne 0 ] then message "Warning: Unable to refresh $1 service" fi # make sure the local filesystems service waits for us svccfg -s $FS_LOCAL_SVC setprop ${1}-local-fs/grouping=require_all if [ $? -ne 0 ] then message "Warning: Unable to set dependency for $1 service" fi svcadm refresh ${FS_LOCAL_SVC}:default if [ $? -ne 0 ] then message "Warning: Unable to refresh $1 service" fi } # # Set specific command syntax (if needed) # release=`uname -r | sed -e "s/[0-9]*\.//" -e "s/\..*//"` case $release in 1[0-9] ) REM_DRV="rem_drv -b ${PKG_INSTALL_ROOT}" ADD_DRV="add_drv -P sys_devices,sys_config -b ${PKG_INSTALL_ROOT}" ;; * ) REM_DRV="rem_drv -b ${PKG_INSTALL_ROOT}" ADD_DRV="add_drv -b ${PKG_INSTALL_ROOT}" UPD_DRV_AFTER_REBOOT=0 cat >> $BASEDIR/etc/rc2.d/S99storage <<\_SCMU #!/sbin/sh -x MODULES="nskern ncall nsctl sdbc" for MODULE in ${MODULES} do ADDERR="ERROR: The installation cannot be completed due to an error updating the \ ${MODULE} loadable module. The file ${ERRLOG} contains the errors. Exiting...\ Please fix problem and re-run pkgadd." update_drv -a -P sys_devices,sys_config -m '* 0666 root sys' $MODULE 2>&1 [ $? -ne 0 ] && { message ${ADDERR} exit 1 } done _SCMU chmod a+x $BASEDIR/etc/rc2.d/S99storage ;; esac # # the preinstall should have removed the modules therefore, # if the lowest level module (nskern or sdsi) is loaded (busy) then we need to # notify the user after the install to reboot or remove the clients and # re-run pkgadd. #n=`modinfo |grep -w nskern |cut -d" " -f1` # # add and load modules # for MODULE in ${MODULES} do ERRLOG=/tmp/${MODULE}.postlog REMERR="ERROR: The installation cannot be completed due to an error removing \ the ${MODULE} loadable module. The file ${ERRLOG} contains the errors. Exiting...\ Please fix problem and re-run pkgadd." ADDERR="ERROR: The installation cannot be completed due to an error adding the \ ${MODULE} loadable module. The file ${ERRLOG} contains the errors. Exiting...\ Please fix problem and re-run pkgadd." DEVLINKERR="ERROR: The installation cannot be completed due to an error configuring \ the ${MODULE} loadable module. The file ${ERRLOG} contains the errors. Exiting...\ Please fix problem and re-run pkgadd." # if the main module is still loaded then it has refused to unload # and we have to force a reboot. # if [ "${PKG_INSTALL_ROOT:-/}" = "/" ]; then modinfo | grep -w ${MODULE} >/dev/null 2>&1 if [ $? -eq 0 ]; then # still loaded MODBUSY=1 NOPT="-b / " fi fi # # if module has been previously installed, remove it # grep -w ${MODULE} ${NAMEMAJOR} if [ $? -eq 0 ]; then ${REM_DRV} ${MODULE} > ${ERRLOG} 2>&1 [ $? -ne 0 ] && { message ${REMERR} exit ${FAILURE} } fi # # install module # add_devlink "type=ddi_pseudo;name=${MODULE}" '\D' case ${MODULE} in *) ${ADD_DRV} $NOPT -m '* 0666 root sys' ${MODULE} > ${ERRLOG} 2>&1 status=$? ;; esac [ $status -ne 0 ] && { message ${ADDERR} exit ${FAILURE} } done # # Test if we need next boot to start Availability Suite # # check if we have a valid configuration database valid_dscfg_exists # if so, copy the old database to new location, setup the service to be enabled if [ $? = 1 ] then convert_dscfg enable_service_on_reboot nws_scm mv -f $DSCFG_REF ${DSCFG_REF}.legacy rm -f ${DSCFG_REF}.upgrade touch ${DSCFG_REF}.upgrade echo "$PKGINST" >> ${DSCFG_REF}.upgrade fi if [ $MODBUSY = 1 ]; then message $MODBUSYMSG fi