3 # Enable a newly installed package to run or enable an existing package
4 # to run after a kernal upgrade.
9 type -P gettext.sh > /dev/null 2>&1 && \
10 type -p gettext >/dev/null 2>&1
26 TEXTDOMAINDIR=$PPBASE/i18n/catalog
28 export RPM_INSTALL_PREFIX
44 ### DO NOT REMOVE THE FOLLOWING LINE
45 #####################################################################
46 ### Start of Global variable section.
47 #####################################################################
49 # Temp directory used by the %pre section. (Before $PP_I_DIR exists.)
53 # Default installation directory for emcpower
55 PP_I_DIR=/etc/opt/emcpower
57 # The file name of the device file used to control the power path drivers
59 # created by sysfs in 2.6.
60 #POWER_DEV=/dev/emcpower
62 # Installation log file
64 POWER_LOG=$PP_I_DIR/log
66 # Installation temporary file directory.
68 POWER_TMP_DIR=$PP_I_DIR/.tmp
70 # Backup archives used in case an installation is aborted in mid-stream
72 POWER_BACKUP_ARCHIVE=$PP_I_DIR/.archive.tar
73 POWER_BACKUP_ARCHIVE_NEW=$PP_I_DIR/.archive_NEW.tar
74 archive_dir=$RPM_INSTALL_PREFIX/etc/emc/archive
76 # Patch log file in case of patch errors
78 PATCH_LOG=$PP_I_DIR/patch.log
82 modprobe_file=/etc/modprobe.conf.pp
83 #####################################################################
84 ### End of Global variable section.
85 #####################################################################
88 #-----------------------------------------------------------------------
89 # Restore system to the state that existed before this script ran.
90 # First, execute the commands in the undo list in reverse order, then
91 # untar archived files.
92 #-----------------------------------------------------------------------
95 awk '{print NR,$0}' $POWER_TMP_DIR/undolist | \
97 cut -d' ' -f2- > $POWER_TMP_DIR/undo.sh
98 sh $POWER_TMP_DIR/undo.sh
100 tar -x --absolute-names --file $POWER_TMP_DIR/rollbackfiles.tar
103 #-----------------------------------------------------------------------
104 # Delete the files containing rollback information
105 #-----------------------------------------------------------------------
108 rm -f $POWER_TMP_DIR/rollbackfiles.tar
109 rm -f $POWER_TMP_DIR/undolist
110 rm -f $POWER_TMP_DIR/undo.sh
113 #-----------------------------------------------------------------------
114 # Save a directory and contained files in the rollback archive
115 #-----------------------------------------------------------------------
116 save_dirtree_for_rollback()
123 tar --append --preserve-permissions --absolute-names \
124 --file $POWER_TMP_DIR/rollbackfiles.tar $pathname
127 #-----------------------------------------------------------------------
128 # Save a file or directory in the rollback archive
129 #-----------------------------------------------------------------------
137 tar --append --preserve-permissions --absolute-names \
138 --no-recursion --file $POWER_TMP_DIR/rollbackfiles.tar $pathname
141 #-----------------------------------------------------------------------
142 # Add a shell command, for execution during rollback, to the undo list
143 #-----------------------------------------------------------------------
146 echo "cd `pwd`; $*" >> $POWER_TMP_DIR/undolist
149 #-----------------------------------------------------------------------
150 # Move a file in such a way that the original source and destination
151 # files are restored by rollback.
152 #-----------------------------------------------------------------------
158 dest=$2/`basename $1`
162 if [ -f "$dest" ]; then
163 save_for_rollback $dest
165 add_to_undolist rm -f "$dest"
170 #-----------------------------------------------------------------------
171 # Copy a new file over an old one,in such a way that the old file
172 # can be restored during rollback.
173 #-----------------------------------------------------------------------
178 dest=$2/`basename $1`
182 if [ -f "$dest" ]; then
183 save_for_rollback $dest
185 add_to_undolist rm -f "$dest"
190 #-----------------------------------------------------------------------
191 # Save a file in the rollback archive and then delete it.
192 #-----------------------------------------------------------------------
201 #-----------------------------------------------------------------------
202 # Save a directory and contained files in the rollback archive and then
204 #-----------------------------------------------------------------------
208 save_dirtree_for_rollback $1
213 #-----------------------------------------------------------------------
214 # Make a directory in such a way that it will be removed during rollback.
215 # All non-existent directories in the given path are created. If the
216 # directory already exists, do nothing.
217 #-----------------------------------------------------------------------
220 if [ ! -d "$1" ]; then
221 make_dir2 $1 && chmod 755 $1 && chown root:root $1
227 if test ! -d "$1" && make_dir2 `dirname $1`; then
228 add_to_undolist rmdir $1
233 #-----------------------------------------------------------------------
234 # Copy a kernel module and set file pwermissions, group and owner
235 #-----------------------------------------------------------------------
238 copy_file "$1" "$2" && chmod 644 "$2" && chown root:root "$2"
241 #-----------------------------------------------------------------------
242 # Compare the vermagic string of the pp base driver to the vermagic string
243 # of the scsi_mod driver.
244 # input: path to PowerPath base driver, in package area.
245 # return 0 for matching strings.
246 #-----------------------------------------------------------------------
248 verify_driver_vermagic()
252 local ref_mod_version
255 ref_driver=`lsmod | cut -d' ' -f1 | tail -1`
256 ref_mod_version=`modinfo $ref_driver | \
257 sed -n '/^vermagic:/s/^vermagic: *//p'`
258 pp_mod_version=`modinfo $pp_drv_path | \
259 sed -n '/^vermagic:/s/^vermagic: *//p'`
260 ref_mod_version=`echo $ref_mod_version | cut -d' ' -f2-`
261 pp_mod_version=`echo $pp_mod_version | cut -d' ' -f2-`
262 if [ "$pp_mod_version" = "$ref_mod_version" ]
270 #-----------------------------------------------------------------------
271 # Recursively load all modules on the command line, in the order given.
272 # If any module fails to load, all previously loaded modules are unloaded
273 # and a non-zero status is returned. After all modules are loaded, emcpioc
275 #-----------------------------------------------------------------------
279 local mod=`basename "$1" .ko`
284 if lsmod | grep emcpioc > /dev/null
299 report_error 'PowerPath could not load module $mod'
304 #-----------------------------------------------------------------------
305 # Run "preinstall" checks to make sure the running system is compatible
307 #-----------------------------------------------------------------------
308 validate_install_target()
310 ## Check - Require effective UID of root
312 if [ $EUID != 0 ]; then
313 report_error "You must be root to install PowerPath."
317 ## Check - Only install on a 2.6 kernel
319 expr `uname -r` : '2\.6' > /dev/null
320 if [ $? -ne 0 ]; then
321 report_error "This PowerPath package does not support this kernel."
327 if expr \( "$EXPECTED_VENDOR" : ".*$VENDOR" \) = 0 >/dev/null; then
328 report_error 'This package requires a $VENDOR_NAME Platform.'
334 check_vendor_rev $EXPECTED_OS_REV
336 report_error 'This package requires $VENDOR_NAME $VENDOR_OS_NAME.'
340 ## Check hardware platform
342 if [ "`uname -m`" != "$EXPECTED_ISA" ]; then
344 'This package requires the $VENDOR_NAME $EXPECTED_ISA kernel.'
348 ## Check - Make sure no devices are in use.
350 if [ "`/sbin/lsmod | grep -w emcp`" != "" ]; then
351 /sbin/powermt save > /dev/null 2>&1
352 /sbin/powermt remove dev=all > /dev/null 2>&1
353 if [ "`powermt display dev=all 2>&1 | grep "not found"`" = "" ]; then
355 "Unable to remove devices from the PowerPath configuration."
357 "Please make sure no PowerPath devices are in use and retry."
358 /sbin/powermt config > /dev/null 2>&1
359 /sbin/powermt load > /dev/null 2>&1
362 /sbin/powermt config > /dev/null 2>&1
363 /sbin/powermt load > /dev/null 2>&1
366 ## Do we have modules that work with this kernel?
368 TAG=`identify_platform \`uname -r\``
369 if [ -z "$TAG" ]; then
370 report_error "This PowerPath package does not support this kernel."
371 report_error '$PPBASE'
375 ## Check driver vermagic
377 verify_driver_vermagic $PPBASE/bin/driver/$TAG/emcp.ko
379 report_error 'PowerPath driver version magic mismatch'
384 #-----------------------------------------------------------------------
385 # Compare the version recorded in the saved powermt.custom file with the
386 # version in $1. If the two versions match, return true.
387 #-----------------------------------------------------------------------
388 matching_saved_config_version()
392 if [ -f $archive_dir/powermt.custom.saved ]; then
393 Mmp=`expr "$1" : '\([0-9]\.[0-9]\.[0-9]\)'`
394 saved=`head -1 $archive_dir/powermt.custom.saved | cut -d: -f3`
395 if [ "$saved" = "$Mmp" ]; then
405 #-----------------------------------------------------------------------
406 # Move files from the PowerPath archive directory to their normal
407 # installed locations.
408 #-----------------------------------------------------------------------
409 restore_configuration_files()
411 for file in /etc/emc/mpaa.lams \
412 /etc/emc/mpaa.excluded \
413 /etc/emcp_registration
415 if [ -f $archive_dir/`basename $file`.saved ]; then
416 move_file $archive_dir/`basename $file`.saved $file
420 if test "$PP_VERSION" || \
421 matching_saved_config_version $NEW_PP_VERSION; then
422 for file in /etc/powermt.custom \
423 /etc/emcp_devicesDB.dat \
424 /etc/emcp_devicesDB.idx
426 if [ -f $archive_dir/`basename $file`.saved ]; then
427 move_file $archive_dir/`basename $file`.saved $file
431 if [ -f $archive_dir/*.FCS ]; then
432 for file in $archive_dir/*.FCS
440 #-----------------------------------------------------------------------
441 # tps_managed_classes - Return a true status if third party software
442 # is installed to manage the array named in $1. Otherwise return a
444 #-----------------------------------------------------------------------
449 test -d /opt/DynamicLinkManager/bin
452 test -d /usr/src/Autopath
455 test -d /opt/IBMsdd/bin
458 test -d /etc/CPQswsp/modules
466 #-----------------------------------------------------------------------
467 # prev_unmanaged - Return a true status if the array named in $2
468 # is marked "unmanaged" in the mpaa.lams file named in $1
469 #-----------------------------------------------------------------------
472 grep -w $2 $1 2>/dev/null | grep -w unmanaged > /dev/null 2>&1
475 #-----------------------------------------------------------------------
476 # If no mpaa.lams file exists, create one. Otherwise create a temporary
477 # mpaa.lams file, compare it to the existing file and replace the
478 # existing file with the temporary one if the two files differ. Also,
479 # create an empty mpaa.excluded if one doesn't exist
480 #-----------------------------------------------------------------------
483 local lams_file="/etc/emc/mpaa.lams"
484 local lams_excluded_file="/etc/emc/mpaa.excluded"
487 if [ -f "$lams_file" ]; then
489 lams_new=${lams_file}.tmp
495 echo "global:version:$PP_VERSION" > $lams_new
496 for array in symm clariion hpxp hitachi hphsx ess invista
498 if tps_managed $array || prev_unmanaged $lam_ref $array
500 echo "unmanaged:$array" >> $lams_new
502 echo "managed:$array" >> $lams_new
506 if [ "$lams_new" = "${lams_file}.tmp" ]; then
507 if /usr/bin/diff -q $lams_file $lams_new >/dev/null 2>&1; then
510 mv -f $lams_new $lams_file
513 add_to_undolist rm -f $lams_file
516 if [ ! -f "$lams_excluded_file" ]; then
517 echo "global:version:$PP_VERSION" > $lams_excluded_file
518 add_to_undolist rm -f $lams_excluded_file
522 #-----------------------------------------------------------------------
523 # Add lines to /etc/modprobe.conf.pp to coordinate filter driver, hba
524 # driver and emcp loading
525 #-----------------------------------------------------------------------
526 modprobe_add_pp_lines()
528 local begin_tag='#begin-hba-'
529 local end_tag='#end-hba-'
533 modprobe_hba=' /sbin/modprobe pp_hba;'
537 install_hba="$install_hba /sbin/modprobe $hba;"
541 if grep "^${begin_tag}$1" $modprobe_file > /dev/null; then
542 return # Lines for this hba are already in place
544 # Lines indented with tab!!
545 cat <<-EOF >> $modprobe_file
547 install emcp /sbin/modprobe pp_hba; /sbin/modprobe emcp --ignore-install
548 install pp_hba ${install_hba}
554 #-----------------------------------------------------------------------
555 # Create dependencies between HBA drivers and power path drivers.
556 #-----------------------------------------------------------------------
557 create_hba_dependencies()
559 local added_dependency=FALSE
560 local searchDir=/lib/modules/`uname -r`
564 qlaHbaName=`find /proc/scsi -name qla2xxx | sed -e 's/\/proc\/scsi\///'`
565 emulexHbaName=`find /proc/scsi -name lpfc* | sed -e 's/\/proc\/scsi\///'`
566 if [ "$qlaHbaName" ]; then
567 qla_hbas=`lsmod | cut -d' ' -f1 | grep qla | grep -v qla2xxx`
568 modprobe_add_pp_lines $qla_hbas
569 added_dependency=TRUE
572 # We no longer support mixed vendor types, so we will not add the
573 # emulex driver if the qla driver exists.
575 if [ "$emulexHbaName" != "" -a "$added_dependency" = FALSE ]; then
577 modloc=`find $searchDir -name ${emulexHbaName}.ko -print`
578 if [ "$modloc" != "" ]; then
579 modprobe_add_pp_lines $emulexHbaName
584 #-----------------------------------------------------------------------
585 # Add PowerPath parameters to modprobe.conf.pp file
586 #-----------------------------------------------------------------------
587 update_driver_parameters()
589 local lams_file="/etc/emc/mpaa.lams"
590 local lams_excluded_file="/etc/emc/mpaa.excluded"
592 ## Attach the PP file to modprobe.conf
594 grep '^##*BEGINPP' /etc/modprobe.conf >/dev/null 2>&1
595 if [ $? -ne 0 ]; then
596 save_for_rollback /etc/modprobe.conf
597 cat <<-EOF >> /etc/modprobe.conf ## Lines indented with tabs!!!
599 include /etc/modprobe.conf.pp
604 copy_file $PPBASE/modprobe.conf.pp $modprobe_file
606 ## Update the managedclass parameter line
608 mng_class=`awk -F: '$1 ~ /^managed$/ {print $2}' $lams_file | \
611 -e 's/^/options emcp managedclass=/'`
613 grep "options emcp managedclass" $modprobe_file > /dev/null 2>&1
614 if test $? -ne 0 ; then
615 echo "$mng_class" >> $modprobe_file
617 sed -i "s/^options emcp managedclass=.*/${mng_class}/" \
621 ## Update the excludedvolumes parameter line.
623 if [ `wc -l $lams_excluded_file | awk '{print $1}'` -gt 1 ] ; then
624 excluded=`awk -F: '{print $2","}' $lams_excluded_file |\
628 if [ "$excluded" ] ; then
629 if grep "options emcp excludedvolumes" \
630 $modprobe_file > /dev/null 2>&1 ; then
631 sed -i "/excludedvolumes/c\
632 options emcp excludedvolumes=$excluded" $modprobe_file
634 echo "options emcp excludedvolumes=$excluded" >> $modprobe_file
640 ## Link hba drivers and powerpath drivers
642 create_hba_dependencies
645 #-----------------------------------------------------------------------
646 # update_boot_logic - Tie PowerPath start into system startup logic.
647 #-----------------------------------------------------------------------
652 MDFILE=/etc/init.d/boot.md
653 grep boot.powerpath $MDFILE >> /dev/null 2>>/dev/null
654 if [ $? -eq 1 ]; then
655 save_for_rollback $MDFILE
656 string=`grep "# Required-Start:" $MDFILE`
657 sed --in-place -e "s/$string/$string boot.powerpath/" $MDFILE
658 if [ -x /sbin/insserv ]; then
664 ETCFILE=/etc/rc.d/rc.sysinit
665 grep BEGINPP $ETCFILE >> /dev/null 2>>/dev/null
666 if [ $? -eq 1 ]; then
667 save_for_rollback $ETCFILE
668 sed --in-place -e '/remount,rw \//a \
670 # Configure and initialize PowerPath.\
671 if [ -f /etc/init.d/PowerPath ]; then\
672 /etc/init.d/PowerPath start\
680 #-----------------------------------------------------------------------
681 # Delete old modules in all /lib/modules subdirectories, then install
683 #-----------------------------------------------------------------------
684 install_driver_modules()
686 for os in /lib/modules/*
689 /lib/modules/`uname -r`)
690 for modpath in $os/powerpath/*
696 remove_dirtree $os/powerpath
699 for modpath in $os/extra/emcp*
705 ## Install new modules.
707 MODULE_BASE=/lib/modules/`uname -r`
709 test -d $MODULE_BASE/powerpath || make_dir $MODULE_BASE/powerpath
711 for mod in `ls $PPBASE/bin/driver/$TAG`
713 copy_mod $PPBASE/bin/driver/$TAG/$mod $MODULE_BASE/powerpath/$mod
719 ##-------------------------------- Main ------------------------------##
721 PATH=/sbin:/usr/sbin:/bin:/usr/bin; export PATH
723 cmd_path=`dirname $0`
724 PPBASE=`(cd $cmd_path;pwd)`
726 test -f $PP_I_DIR/.pp_version && PP_VERSION=`cat $PP_I_DIR/.pp_version`
727 test -f $PP_I_DIR/.new_pp_version && \
728 NEW_PP_VERSION=`cat $PP_I_DIR/.new_pp_version`
729 test -f $PP_I_DIR/.os_version && OS_VERSION=`cat $PP_I_DIR/.os_version`
731 VENDOR=`rpm --showrc | awk '$2 == "_vendor" {print $3}'`
734 ### DO NOT REMOVE THE FOLLOWING LINE
735 # SuSE x86_64 specific:
740 VENDOR_OS_NAME=SLES10SP1
742 EXPECTED_OS_REV=10sp1
743 MIN_UPGRADE_REV=5.0.0
747 if [ "`cat /etc/SuSE-release | awk '$1 == "PATCHLEVEL" {print $3}'`" == "1" ]
749 sles_version=$EXPECTED_OS_REV
753 test "$1" = "$sles_version"
756 #-----------------------------------------------------------------------
757 # identify_platform -
758 # Determine the set of drivers files compatible with the /lib/modules
759 # subdirectory passed as an argument and echo the tag for that set of
761 #-----------------------------------------------------------------------
768 *-smp) platform=sles${EXPECTED_OS_REV}smp_x8664 ;;
769 *-xen) platform=sles${EXPECTED_OS_REV}xensmp_x8664 ;;
771 if [ "$1" = `uname -r` ]
773 pre_error "This PowerPath package only supports the SuSE SLES x86_64 smp kernel"
779 test "$platform" && echo $platform
787 validate_install_target
789 make_dir /etc/emc/ppme
791 test "$NEW_PP_VERSION" && restore_configuration_files
795 update_driver_parameters
797 install_driver_modules
799 ## Load new modules. Emcplib and emcp first, emcpdm and emcpioc last
800 ## with everything else in between.
802 load_all_modules `ls $PPBASE/bin/driver/$TAG | \
803 awk '/^emcplib.ko$/ {order[$1]=1; next}
804 /^emcp.ko$/ {order[$1]=2; next}
805 /^emcpdm.ko$/ {order[$1]=4; next}
806 /^emcpioc.ko$/ {order[$1]=5; next}
807 /^emcp/ {order[$1]=3; next}
808 END { for (mod in order) print order[mod],mod;}' |\
812 ## If error loading modules, roll back everything done to this point and
813 ## return an error status.
817 report_error "Error loading PowerPath kernel modules"
824 ## If kernel has changed make sure PowerPath will still start at boot time
826 if [ "$OS_VERSION" != `uname -r` ]; then
832 report_error "Error installing PowerPath"
838 ## Update state info in /etc/opt/emcpower
840 rm -f $PP_I_DIR/.os_version
841 uname -r > $PP_I_DIR/.os_version
842 rm -f $PP_I_DIR/.prev_pp_version
843 if [ -f $PP_I_DIR/.new_pp_version ]
845 test -f $PP_I_DIR/.pp_version && \
846 mv -f $PP_I_DIR/.pp_version $PP_I_DIR/.prev_pp_version
847 mv $PP_I_DIR/.new_pp_version $PP_I_DIR/.pp_version