4de2612967d06c4fdbf524a62556a1e8118a006fxs#!/sbin/sh
4de2612967d06c4fdbf524a62556a1e8118a006fxs#
4de2612967d06c4fdbf524a62556a1e8118a006fxs# CDDL HEADER START
4de2612967d06c4fdbf524a62556a1e8118a006fxs#
bb25c06cca41ca78e5fb87fbb8e81d55beb18c95jg# The contents of this file are subject to the terms of the
bb25c06cca41ca78e5fb87fbb8e81d55beb18c95jg# Common Development and Distribution License (the "License").
4de2612967d06c4fdbf524a62556a1e8118a006fxs# You may not use this file except in compliance with the License.
4de2612967d06c4fdbf524a62556a1e8118a006fxs#
4de2612967d06c4fdbf524a62556a1e8118a006fxs# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4de2612967d06c4fdbf524a62556a1e8118a006fxs# or http://www.opensolaris.org/os/licensing.
4de2612967d06c4fdbf524a62556a1e8118a006fxs# See the License for the specific language governing permissions
4de2612967d06c4fdbf524a62556a1e8118a006fxs# and limitations under the License.
4de2612967d06c4fdbf524a62556a1e8118a006fxs#
4de2612967d06c4fdbf524a62556a1e8118a006fxs# When distributing Covered Code, include this CDDL HEADER in each
4de2612967d06c4fdbf524a62556a1e8118a006fxs# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4de2612967d06c4fdbf524a62556a1e8118a006fxs# If applicable, add the following below this CDDL HEADER, with the
4de2612967d06c4fdbf524a62556a1e8118a006fxs# fields enclosed by brackets "[]" replaced with your own identifying
4de2612967d06c4fdbf524a62556a1e8118a006fxs# information: Portions Copyright [yyyy] [name of copyright owner]
4de2612967d06c4fdbf524a62556a1e8118a006fxs#
4de2612967d06c4fdbf524a62556a1e8118a006fxs# CDDL HEADER END
4de2612967d06c4fdbf524a62556a1e8118a006fxs#
4de2612967d06c4fdbf524a62556a1e8118a006fxs#
489b7c4ab76ae8df137fbfcc2214f7baa52883a0Raymond Chen# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
4de2612967d06c4fdbf524a62556a1e8118a006fxs# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
4de2612967d06c4fdbf524a62556a1e8118a006fxs#
e2c88f0c2610f16de7b639746b40dea5f3e2256eGarrett D'Amore
4de2612967d06c4fdbf524a62556a1e8118a006fxs. /lib/svc/share/fs_include.sh
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits. /lib/svc/share/net_include.sh
4de2612967d06c4fdbf524a62556a1e8118a006fxs
4de2612967d06c4fdbf524a62556a1e8118a006fxs# Make sure that the essential libraries can be found.
4de2612967d06c4fdbf524a62556a1e8118a006fxsLD_LIBRARY_PATH=/lib; export LD_LIBRARY_PATH
4de2612967d06c4fdbf524a62556a1e8118a006fxsSTMSBOOTUTIL=/lib/mpxio/stmsboot_util
4de2612967d06c4fdbf524a62556a1e8118a006fxsSAVEDIR=/etc/mpxio
4de2612967d06c4fdbf524a62556a1e8118a006fxsBOOTDEVICES=$SAVEDIR/boot-devices
4de2612967d06c4fdbf524a62556a1e8118a006fxsRECOVERFILE=$SAVEDIR/recover_instructions
4de2612967d06c4fdbf524a62556a1e8118a006fxsDEVFSADM=/usr/sbin/devfsadm
4de2612967d06c4fdbf524a62556a1e8118a006fxsDUMPADM=/usr/sbin/dumpadm
4de2612967d06c4fdbf524a62556a1e8118a006fxsMETADEVADM=/usr/sbin/metadevadm
4de2612967d06c4fdbf524a62556a1e8118a006fxsISROOTDEV=""
4de2612967d06c4fdbf524a62556a1e8118a006fxsISROOTDEVPATH=""
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997fritsusrmounted=0
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997fritsUNAME=/usr/bin/uname
4de2612967d06c4fdbf524a62556a1e8118a006fxsECHO=/usr/bin/echo
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997fritsCAT=/usr/bin/cat
4de2612967d06c4fdbf524a62556a1e8118a006fxsCP=/usr/bin/cp
4de2612967d06c4fdbf524a62556a1e8118a006fxsDF=/usr/bin/df
4de2612967d06c4fdbf524a62556a1e8118a006fxsLS=/usr/bin/ls
4de2612967d06c4fdbf524a62556a1e8118a006fxsRM=/usr/bin/rm
4de2612967d06c4fdbf524a62556a1e8118a006fxsEGREP=/usr/bin/egrep
4de2612967d06c4fdbf524a62556a1e8118a006fxsSED=/usr/bin/sed
7014882c6a3672fd0e5d60200af8643ae53c5928Richard LoweZPOOL=/usr/sbin/zpool
7014882c6a3672fd0e5d60200af8643ae53c5928Richard LoweAWK=/usr/bin/awk
4de2612967d06c4fdbf524a62556a1e8118a006fxsMOUNT=/sbin/mount
4de2612967d06c4fdbf524a62556a1e8118a006fxsUMOUNT=/sbin/mount
4de2612967d06c4fdbf524a62556a1e8118a006fxsEEPROM=/usr/sbin/eeprom
4de2612967d06c4fdbf524a62556a1e8118a006fxsBOOTADM=/usr/sbin/bootadm
4de2612967d06c4fdbf524a62556a1e8118a006fxsSVCADM=/usr/sbin/svcadm
4de2612967d06c4fdbf524a62556a1e8118a006fxsREBOOT=/usr/sbin/reboot
4de2612967d06c4fdbf524a62556a1e8118a006fxs
4de2612967d06c4fdbf524a62556a1e8118a006fxsmpxio_error()
4de2612967d06c4fdbf524a62556a1e8118a006fxs{
4de2612967d06c4fdbf524a62556a1e8118a006fxs cecho "\nERROR: stmsboot: $1"
4de2612967d06c4fdbf524a62556a1e8118a006fxs #
4de2612967d06c4fdbf524a62556a1e8118a006fxs # display recovery instructions - the first call logs to the service
4de2612967d06c4fdbf524a62556a1e8118a006fxs # log and the second call displays on the console.
4de2612967d06c4fdbf524a62556a1e8118a006fxs #
4de2612967d06c4fdbf524a62556a1e8118a006fxs shcat $RECOVERFILE
4de2612967d06c4fdbf524a62556a1e8118a006fxs shcat $RECOVERFILE >/dev/msglog 2>&1
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits cecho "These instructions were also logged to the file $RECOVERFILE\n"
4de2612967d06c4fdbf524a62556a1e8118a006fxs}
4de2612967d06c4fdbf524a62556a1e8118a006fxs
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits#
4de2612967d06c4fdbf524a62556a1e8118a006fxs# root ("/") is already mounted read only by the kernel.
4de2612967d06c4fdbf524a62556a1e8118a006fxs# Remount the root read-write.
4de2612967d06c4fdbf524a62556a1e8118a006fxs#
4de2612967d06c4fdbf524a62556a1e8118a006fxsmpxio_mount_root()
4de2612967d06c4fdbf524a62556a1e8118a006fxs{
4de2612967d06c4fdbf524a62556a1e8118a006fxs HASZFSROOT=`$DF -g / |grep zfs`
4de2612967d06c4fdbf524a62556a1e8118a006fxs RVAL=""
4de2612967d06c4fdbf524a62556a1e8118a006fxs
4de2612967d06c4fdbf524a62556a1e8118a006fxs # In single-user maintenance mode, we don't have a writable
4de2612967d06c4fdbf524a62556a1e8118a006fxs # root partition, so we _cannot_ use devlinks. Therefore we
4de2612967d06c4fdbf524a62556a1e8118a006fxs # have to do some dancing - first mount the physical path
4de2612967d06c4fdbf524a62556a1e8118a006fxs # read-write, then re-run $STMSBOOTUTIL to get the real
4de2612967d06c4fdbf524a62556a1e8118a006fxs # devlink mapping, and then re-mount the root slice. Of course,
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits # if we all used ZFS this wouldn't be such a pain!
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits exec < $vfstab; readvfstab /
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits # ZFS root environments should _not_ have an entry for /
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits # in their /etc/vfstab.
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits if [ -n "$special" ]; then
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits # sanity check for ZFSRoot _and_ / in /etc/vfstab
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits if [ -n "$HASZFSROOT" ]; then
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits # ERROR - this would cause a failure later
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits # so let root know about it now and provide
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits # a chance to handle it before filesystem/usr
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits cecho "stmsboot: System has ZFS Root *and* an entry for / in /etc/vfstab\nstmsboot: Please remove the / entry from /etc/vfstab and then run\n# svcadm clear mpxio-upgrade"
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits exit 1
bf56214c0556fa6864189c826d39dbe156bb22a0stevel fi
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits ISPHYS=`echo $special |$AWK '/^\/dev\/dsk/ {print}'`;
e2c88f0c2610f16de7b639746b40dea5f3e2256eGarrett D'Amore if [ -z "$ISPHYS" ]; then
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits # a metadevice, either /dev/md or /dev/vx
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits new_special=$special
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits $MOUNT -o remount,rw $new_special / >/dev/msglog 2>&1
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits else
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits new_special=`$STMSBOOTUTIL -m $special`
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits if [ "$new_special" = "NOT_MAPPED" ]; then
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits # this is a bad state to be in, exit
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits cecho "Error: Your root device is not mapped."
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits exit 1
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits fi
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits checkopt "llock" $mntopts
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits mntopts='remount'
bf56214c0556fa6864189c826d39dbe156bb22a0stevel [ -n "$otherops" ] && mntopts="${mntopts},${otherops}"
bf56214c0556fa6864189c826d39dbe156bb22a0stevel RVAL=`$MOUNT -m -F $fstype -o $mntopts $new_special \
bf56214c0556fa6864189c826d39dbe156bb22a0stevel $mountp >/dev/msglog 2>&1`
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits # if we've got active-active paths to our rootvp and
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits # the first path returned by $STMSBOOTUTIL is not the
bf56214c0556fa6864189c826d39dbe156bb22a0stevel # same as the one we booted from, then we need some
bf56214c0556fa6864189c826d39dbe156bb22a0stevel # handwaving due to restrictions in the ufs module
bf56214c0556fa6864189c826d39dbe156bb22a0stevel # (see the remountfs() function in
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits # $SRC/uts/common/fs/ufs/ufs_vfsops.c)
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits if [ $? -eq 0 ]; then
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits # now re-run $STMSBOOTUTIL to get the real
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits # mapping for this device
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits new_special=`$STMSBOOTUTIL -m $special`
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits # mount root for real
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits $MOUNT -o remount,rw $new_special / \
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits >/dev/msglog 2>&1
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits else
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits for device in `$CAT $BOOTDEVICES`; do
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits new_special="/devices${device}"
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits $MOUNT -m -F $fstype -o $mntopts \
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits $new_special $mountp >/dev/msglog 2>&1
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits if [ $? -eq 0 ]; then
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits # success, break out
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits ISROOTDEVPATH=`$ECHO $device | \
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits $AWK -F":" '{print $1}'`
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits break;
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits fi
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits done
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits if [ -n "$RVAL" ]; then
4ebb14b236958cfe1ef4ff3b7a50216d9e51f997frits cecho "Error: Unable to remount your root device"
exit 1;
fi
fi
fi
else
if [ -z "$HASZFSROOT" ]; then
cecho "stmsboot: Error: your root slice is invalid"
exit 1
else
cecho "stmsboot: Root is on ZFS"
fi
fi
}
#
# mount /usr read only
#
mpxio_mount_usr()
{
exec < $vfstab; readvfstab "/usr"
ret_val=0
if [ -n "$mountp" ]; then
case "$special" in
/dev/md/*)
new_special=$special
;;
/dev/vx/*)
new_special=$special
;;
*)
new_special=`$STMSBOOTUTIL -m $special`
;;
esac
#
# Must use -o largefiles here to ensure the read-only
# mount does not fail as a result of having a large
# file present on /usr.
#
if [ "$mntopts" = "-" ]; then
mntopts='ro,largefiles'
else
checkopt largefiles $mntopts
if [ "$option" != "largefiles" ]; then
mntopts="largefiles,$mntopts"
fi
checkopt ro $mntopts
if [ "$option" != "ro" ]; then
mntopts="ro,$mntopts"
fi
# Requesting logging on a read-only mount
# causes errors to be displayed, so remove
# "logging" from the list of options.
checkopt logging $mntopts
if [ "$option" = "logging" ]; then
mntopts="$otherops"
fi
fi
# In case of a manual restart of the service, mount
# will emit messages if /usr is already mounted.
# So redirect the output to /dev/null.
$MOUNT -m -F $fstype -o $mntopts $new_special /usr \
>/dev/null 2>&1
ret_val=$?
if [ $ret_val -eq 0 ]; then
usrmounted=1
fi
fi
return $ret_val
}
# update system dump configuration
update_dumpconf()
{
# Disable device-in-use checking (done in libdiskmgt).
# Without disabling this check, the configuration of dump device
# would fail as the device-in-use code incorrectly concludes that
# the device is in use and hence prevents configuration of the dump
# device.
NOINUSE_CHECK=1
export NOINUSE_CHECK
DUMPISZFS=`$AWK -F"=" '/DUMPADM_DEVICE/ {print $2}' /etc/dumpadm.conf|$EGREP zvol`
if [ -z "$DUMPISZFS" ]; then
set -- `$DUMPADM -u 2>&1 | $EGREP 'cannot use /dev.* as dump device'`
if [ -n "$4" ]; then
newname=`$STMSBOOTUTIL -m $4`
if [ $? -eq 0 ]; then
if $DUMPADM -d $newname > /dev/msglog 2> /dev/console; then
cecho "stmsboot: dump configuration \
has been updated."
else
mpxio_error "failed to configure \
the dump device.\nold \
dump device name: $4"
return 1
fi
fi
fi
else
# make sure we can get to it, force zfs to load fully
$LS $DUMPISZFS >>/dev/null 2>&1
cecho "stmsboot: dump on ZFS, no dumpadm update required"
fi
return 0
}
# Update bootpath for x86 here when we are enabling mpxio on root
update_bootpath()
{
cur_bootpath=`$STMSBOOTUTIL -b`
if [ $? -ne 0 ]; then
cecho "stmsboot: ERROR! Unable to retrieve bootpath property\n"
exit 1
fi
# Since on x64 platforms the eeprom command doesn't update the
# kernel, the file /boot/solaris/bootenv.rc and the kernel's
# bootpath variable have a good chance of differing. We do some
# extra handwaving to get the correct bootpath variable setting.
ONDISKVER=`$AWK '/bootpath/ {print $3}' /boot/solaris/bootenv.rc|\
$SED -e"s,',,g"`
if [ "$ONDISKVER" != "$cur_bootpath" ]; then
cur_bootpath="$ONDISKVER"
fi
NEWBOOTPATH=""
for path in $cur_bootpath; do
mapped=`$STMSBOOTUTIL -p $path`
if [ "$mapped" != "NOT_MAPPED" ]; then
if [ "$mapped" != "$path" ]; then
NEWBOOTPATH=`echo "$path " | \
$SED -e"s|$path|$mapped|"`" $NEWBOOTPATH"
else
NEWBOOTPATH="$NEWBOOTPATH $path"
fi
fi
done
# now strip off leading and trailing space chars
new_bootpath=`echo $NEWBOOTPATH`
$EEPROM bootpath="$new_bootpath"
cecho "stmsboot: bootpath has been updated"
cecho ""
}
# Now do the actual work
mpxio_main()
{
# NOTE: If the first attempt to run the service has failed due to an
# expected error, users should be able to manually rerun the service.
#
# First mount /usr read only. This must be done to run
# utilities such as fsck and devfsadm.
# In the case of a manual rerun of the service, mounting of /usr here
# fails if /usr already happens to be mounted. It is better that we
# do not mount /usr if already mounted, but there seems to be no
# apparent way to check whether /usr is mounted or not as we mount
# /usr without making an entry into /etc/mnttab. So instead of
# explicitly checking for mount failures, we just do a sanity check
# by looking for some file (in this case devfsadm) in /usr.
#
mpxio_mount_usr
if [ ! -s $DEVFSADM ]; then
mpxio_error "failed to mount the /usr filesystem."
return
fi
if mpxio_mount_root; then
# create /dev links
cecho "stmsboot: configuring devices"
$DEVFSADM
if [ -n "$ISROOTDEVPATH" ]; then
ISROOTDEV=`$STMSBOOTUTIL -o $ISROOTDEVPATH`
fi
# update /etc/vfstab to reflect device name changes
$STMSBOOTUTIL -u >/dev/msglog 2>&1
if [ $? -eq 0 ]; then
$CP /etc/vfstab /etc/vfstab.old
# handle active-active paths, where the probe order
# for the hba reports a different path to what the
# boot-device variable gives us
if [ -n "$ISROOTDEV" ]; then
ROOTDEVCHK=`grep $ISROOTDEV /etc/vfstab`
if [ $? -ne 0 ]; then
# we got a different path for root
exec < $SAVEDIR/vfstab.new; readvfstab /
FILEDEV=`$ECHO $special | \
$SED -e"s,/dev/dsk/,," -e"s,s[0-9]*,,"`
$SED -e"s,$FILEDEV,$ISROOTDEV,g" < \
$SAVEDIR/vfstab.new > /etc/vfstab
fi
else
$CP $SAVEDIR/vfstab.new /etc/vfstab
fi
$RM $SAVEDIR/vfstab.new
cecho ""
cecho "stmsboot: vfstab has been updated"
if update_dumpconf; then
# update svm configuration to reflect new names
if [ -s /kernel/drv/md.conf ] && \
[ -x $METADEVADM ]; then
$METADEVADM -r >/dev/msglog 2>&1
fi
fi
MACH=`$UNAME -p`
if [ "$MACH" = "i386" ]; then
# only update bootpath here for x86
update_bootpath
fi
cecho "stmsboot: now regenerating boot archive"
$BOOTADM update-archive
else
mpxio_error "failed to update /etc/vfstab."
fi
$SVCADM disable system/device/mpxio-upgrade
if [ $usrmounted -eq 1 ]; then
cecho "stmsboot: rebooting the system now."
$REBOOT
fi
else
mpxio_error "failed to mount the root filesystem."
fi
}
mpxio_main