5 # The contents of this file are subject to the terms of the
6 # Common Development and Distribution License (the "License").
7 # You may not use this file except in compliance with the License.
9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 # or http://www.opensolaris.org/os/licensing.
11 # See the License for the specific language governing permissions
12 # and limitations under the License.
14 # When distributing Covered Code, include this CDDL HEADER in each
15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 # If applicable, add the following below this CDDL HEADER, with the
17 # fields enclosed by brackets "[]" replaced with your own identifying
18 # information: Portions Copyright [yyyy] [name of copyright owner]
23 # Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24 # Copyright 2015 Nexenta Systems, Inc. All rights reserved.
27 PATH
=/usr
/bin
:/usr
/sbin
:$PATH; export PATH
28 STMSBOOTUTIL
=/lib
/mpxio
/stmsboot_util
29 STMSMETHODSCRIPT
=/lib
/svc
/method
/mpxio-upgrade
33 TMPDRVCONF_MPXIO_ENTRY
=
34 TMPDRVCONF_SATA_ENTRY
=
39 BOOTDEVICES
=$SAVEDIR/boot-devices
40 RECOVERFILE
=$SAVEDIR/recover_instructions
41 SVCCFG_RECOVERY
=$SAVEDIR/svccfg_recover
42 SUPPORTED_DRIVERS
="fp|mpt|mpt_sas|pmcs"
43 USAGE
=`gettext "Usage: stmsboot [-D $SUPPORTED_DRIVERS] -e | -d | -u | -L | -l controller_number"`
44 TEXTDOMAIN
=SUNW_OST_OSCMD
46 STMSINSTANCE
=svc
:system
/device
/mpxio-upgrade
:default
47 FASTBOOTINSTANCE
=svc
:system
/boot-config
:default
48 STMSBOOT
=/usr
/sbin
/stmsboot
51 EEPROM
=/usr
/sbin
/eeprom
64 REBOOT
=/usr
/sbin
/reboot
66 SVCPROP
=/usr
/bin
/svcprop
67 SVCCFG
=/usr
/sbin
/svccfg
69 SVCADM
=/usr
/sbin
/svcadm
71 NOW
=`/usr/bin/date +%G%m%d_%H%M`
72 MACH
=`/usr/bin/uname -p`
73 BOOTENV_FILE
=bootenv.rc
77 CLIENT_TYPE_VHCI
="/scsi_vhci"
80 # Copy all entries (including comments) from source driver.conf
81 # to destination driver.conf except those entries which contain
82 # the mpxio-disable property.
83 # Take into consideration entries that spawn more than one line.
85 # $1 source driver.conf file
86 # $2 destination driver.conf file
88 # Returns 0 on success, non zero on failure.
90 delete_mpxio_disable_entries
()
92 # be careful here, we've got embedded \t characters
93 # in sed's pattern space.
102 /mpxio-disable[ ]*=.*;$/{ w '$3'
105 /disable-sata-mpxio[ ]*=.*;$/{ w '$4'
115 /mpxio-disable[ ]*=/{ s/\n/ /g
125 # backup the last saved copy of the specified files.
132 newfile
=`basename $file`
133 $CP $file $SAVEDIR/$newfile.
$cmd.
$NOW
138 # build recover instructions
140 # $1 1 to include boot script in the instructions
145 gettext "Instructions to recover your previous STMS configuration (if in case the system does not boot):\n\n" > $RECOVERFILE
146 echo "\tboot net \c" >> $RECOVERFILE
147 gettext "(or from a cd/dvd/another disk)\n" >> $RECOVERFILE
148 echo "\tfsck <your-root-device>" >> $RECOVERFILE
149 echo "\tmount <your-root-device> /mnt" >> $RECOVERFILE
151 if [ "$cmd" = "update" ]; then
152 gettext "\tUndo the modifications you made to STMS configuration.\n\tFor example undo any changes you made to " >> $RECOVERFILE
153 echo "/mnt$KDRVCONF." >> $RECOVERFILE
155 echo "\tcp /mnt${SAVEDIR}/$DRVCONF.$cmd.$NOW /mnt$KDRVCONF" >> $RECOVERFILE
158 if [ $1 -eq 1 ]; then
159 echo "\tcp /mnt${SAVEDIR}/vfstab.$cmd.$NOW /mnt$VFSTAB" >> $RECOVERFILE
161 echo "repository /mnt/etc/svc/repository.db" > $SVCCFG_RECOVERY
162 echo "select $STMSINSTANCE" >> $SVCCFG_RECOVERY
163 echo "setprop general/enabled=false" >> $SVCCFG_RECOVERY
164 echo "exit" >> $SVCCFG_RECOVERY
166 echo "\t$SVCCFG -f /mnt$SVCCFG_RECOVERY" >> $RECOVERFILE
168 if [ -n "$new_bootpath" -a "$MACH" = "i386" ]; then
169 echo "\tcp /mnt${SAVEDIR}/bootenv.rc.$cmd.$NOW /mnt/boot/solaris/$BOOTENV_FILE" >> $RECOVERFILE
173 rootdisk
=`$MOUNT | $GREP "/ on " | cut -f 3 -d " "`
174 echo "\tumount /mnt\n\treboot\n\n${rootdisk} \c" >> $RECOVERFILE
175 gettext "was your root device,\nbut it could be named differently after you boot net.\n" >> $RECOVERFILE
180 # Arrange for /etc/vfstab and dump configuration to be updated
181 # during the next reboot. If the cmd is "enable" or "disable", copy
182 # $TMPDRVCONF to $KDRVCONF.
184 # Returns 0 on success, 1 on failure.
189 gettext "WARNING: This operation will require a reboot.\n"
190 gettext "Do you want to continue ? [y/n] (default: y) "
193 if [ -n "$response" -a "$response" != "y" -a \
194 "$response" != "Y" ]; then
195 for d
in $DRVLIST; do
196 TMPDRVCONF
=/var
/run
/tmp.
$d.conf.$$
197 $RM -f $TMPDRVCONF > /dev
/null
2>&1
202 # set need_bootscript to the number of drivers that
204 need_bootscript
=`echo $SUPPORTED_DRIVERS|$AWK -F"|" '{print NF}'`
206 if [ "$cmd" = "enable" -o "$cmd" = "disable" ]; then
208 for d
in $DRVLIST; do
210 KDRVCONF
=/kernel
/drv
/$d.conf
211 TMPDRVCONF
=/var
/run
/tmp.
$d.conf.$$
213 $CP $KDRVCONF $SAVEDIR/`basename $KDRVCONF`.
$cmd.
$NOW
214 if [ -f $TMPDRVCONF ]; then
215 $CP $TMPDRVCONF $KDRVCONF
218 # if $TMPDRVCONF doesn't exist, then we
219 # haven't made any changes to it
224 # there is no need to update the system files in the following
226 # - we are enabling mpxio and the system has no configured
227 # disks accessible by phci paths.
228 # - we are disabling mpxio and the system has no configured
229 # disks accessible by vhci paths.
232 # Function to setup the CLIENT_TYPE_PHCI string based on
233 # the list of drivers that we're operating on. The variable
234 # depends upon the pathname of the parent node in the
235 # device tree, which can be different on x86/x64 and sparc.
237 CLIENT_TYPE_PHCI
=`$STMSBOOTUTIL -D $d -N`;
239 if [ -z "$CLIENT_TYPE_PHCI" ]; then
243 if [ "$cmd" = "enable" ]; then
244 $LS -l /dev
/dsk
/*s2
2> /dev
/null | \
245 $EGREP -s "$CLIENT_TYPE_PHCI"
247 $LS -l /dev
/dsk
/*s2
2> /dev
/null | \
248 $EGREP -s "$CLIENT_TYPE_VHCI"
251 if [ $?
-ne 0 ]; then
252 need_bootscript
=`$EXPR $need_bootscript - 1`
257 if [ $need_bootscript -gt 0 ]; then
259 if [ -n "$new_bootpath" -a "$MACH" = "i386" ]; then
260 #only update bootpath for x86.
261 $CP /boot
/solaris
/$BOOTENV_FILE $SAVEDIR/$BOOTENV_FILE.
$cmd.
$NOW
262 $EEPROM bootpath
="$new_bootpath"
265 if [ "$MACH" = "i386" ]; then
266 # Disable Fast Reboot temporarily for the next reboot only.
267 HASZFSROOT
=`$DF -g / |$GREP zfs`
268 if [ -n "$HASZFSROOT" ]; then
269 $SVCCFG -s $FASTBOOTINSTANCE addpg config_ovr application P
> /dev
/null
2>&1
270 $SVCCFG -s $FASTBOOTINSTANCE \
271 setprop config_ovr
/fastreboot_default
=boolean
:\"false
\"
272 $SVCCFG -s $FASTBOOTINSTANCE \
273 setprop config_ovr
/fastreboot_onpanic
=boolean
:\"false
\"
274 $SVCADM refresh
$FASTBOOTINSTANCE
278 # Enable the mpxio-upgrade service for the reboot
279 $SVCADM disable
-t $STMSINSTANCE
280 $SVCCFG -s $STMSINSTANCE "setprop general/enabled=true"
285 build_recover
$need_bootscript
287 if [ "$MACH" = "i386" ]; then
288 $BOOTADM update-archive
291 gettext "The changes will come into effect after rebooting the system.\nReboot the system now ? [y/n] (default: y) "
294 if [ -z "$response" -o "$response" = "y" -o \
295 "$response" = "Y" ]; then
304 # Enable or disable mpxio as specified by the cmd.
305 # Returns 0 on success, 1 on failure.
307 # Args: $cmd = {enable | disable}
308 # $d = {fp | mpt | mpt_sas | pmcs}
310 # the global variable $DRVLIST is used
314 # be careful here, we've got embedded \t characters
315 # in sed's pattern space.
316 mpxiodisableno
='mpxio-disable[ ]*=[ ]*"no"[ ]*;'
317 mpxiodisableyes
='mpxio-disable[ ]*=[ ]*"yes"[ ]*;'
318 satadisableno
='disable-sata-mpxio[ ]*=[ ]*"no"[ ]*;'
319 satadisableyes
='disable-sata-mpxio[ ]*=[ ]*"yes"[ ]*;'
321 if [ "$cmd" = "enable" ]; then
322 mpxiodisable_cur_entry
=$mpxiodisableyes
323 satadisable_cur_entry
=$satadisableyes
325 msg
=`gettext "STMS already enabled"`
327 mpxiodisable_cur_entry
=$mpxiodisableno
328 satadisable_cur_entry
=$satadisableno
330 msg
=`gettext "STMS already disabled"`
334 KDRVCONF
=/kernel
/drv
/$d.conf
335 TMPDRVCONF
=/var
/run
/tmp.
$d.conf.$$
336 TMPDRVCONF_MPXIO_ENTRY
=/var
/run
/tmp.
$d.conf.mpxioentry.$$
;
337 TMPDRVCONF_SATA_ENTRY
=/var
/run
/tmp.
$d.conf.sataentry.$$
;
339 if delete_mpxio_disable_entries
$KDRVCONF $TMPDRVCONF $TMPDRVCONF_MPXIO_ENTRY $TMPDRVCONF_SATA_ENTRY; then
341 if [ -s $TMPDRVCONF_MPXIO_ENTRY ]; then
342 # $DRVCONF does have mpxiodisable entries
343 $EGREP -s "$mpxiodisable_cur_entry" $TMPDRVCONF_MPXIO_ENTRY
344 if [ $?
-eq 0 ]; then
345 reboot_needed
=`$EXPR $reboot_needed + 1`
347 # if all mpxiodisable entries are no/yes for
348 # enable/disable mpxio, notify the user
349 $EGREP -s "$satadisable_cur_entry" $TMPDRVCONF_SATA_ENTRY
350 if [ $?
-eq 0 -a "$d" = "mpt" ]; then
351 reboot_needed
=`$EXPR $reboot_needed + 1`
353 $RM -f $TMPDRVCONF $TMPDRVCONF_MPXIO_ENTRY $TMPDRVCONF_SATA_ENTRY > /dev
/null
2>&1
358 # If mpxiodisable entries do not exist, always continue update
361 $RM -f $TMPDRVCONF $TMPDRVCONF_MPXIO_ENTRY $TMPDRVCONF_SATA_ENTRY > /dev
/null
2>&1
362 gettext "failed to update " 1>&2
363 echo "$KDRVCONF." 1>&2
364 gettext "No changes were made to your STMS configuration.\n" 1>&2
368 rm $TMPDRVCONF_MPXIO_ENTRY $TMPDRVCONF_SATA_ENTRY > /dev
/null
2>&1
369 echo "mpxio-disable=\"${propval}\";" >> $TMPDRVCONF
370 if [ "$d" = "mpt" ]; then
371 echo "disable-sata-mpxio=\"${propval}\";" >> $TMPDRVCONF
378 if [ "$cmd" = "none" ]; then
387 # Need to update bootpath on x86 if boot system from FC disk
388 # Only update bootpath here when mpxio is enabled
389 # If mpxio is currently disabled, then we'll update bootpath in the
390 # mpxio-upgrade service method on reboot.
393 get_newbootpath_for_stmsdev
() {
394 if [ "$cmd" = "enable" ]; then
398 cur_bootpath
=`$STMSBOOTUTIL -b`
403 # Since on x64 platforms the eeprom command doesn't update the
404 # kernel, the file /boot/solaris/bootenv.rc and the kernel's
405 # bootpath variable have a good chance of differing. We do some
406 # extra handwaving to get the correct bootpath variable setting.
408 ONDISKVER
=`$AWK '/bootpath/ {print $3}' /boot/solaris/bootenv.rc|\
410 if [ "$ONDISKVER" != "$cur_bootpath" ]; then
411 cur_bootpath
="$ONDISKVER"
415 for path
in $cur_bootpath; do
416 mapped
=`$STMSBOOTUTIL -p $path`
417 if [ "$mapped" != "NOT_MAPPED" ]; then
418 if [ "$mapped" != "$path" ]; then
419 NEWBOOTPATH
=`echo "$path " | \
420 $SED -e"s|$path|$mapped|"`" $NEWBOOTPATH"
422 NEWBOOTPATH
="$NEWBOOTPATH $path"
426 # now strip off leading and trailing space chars
427 new_bootpath
=`echo $NEWBOOTPATH`
432 # Emit a warning message to the user that by default we
433 # operate on all multipath-capable controllers that are
434 # attached to the system, and that if they want to operate
435 # on only a specific controller type (fp|mpt|mpt_sas|pmcs|....) then
436 # they need to re-invoke stmsboot with "-D $driver" in
437 # their argument list
440 emit_driver_warning_msg
() {
442 # for each driver that we support, grab the list
443 # of controllers attached to the system.
446 gettext "WARNING: stmsboot operates on each supported multipath-capable controller\n"
447 gettext " detected in a host. In your system, these controllers are\n\n"
449 for WARNDRV
in `echo $SUPPORTED_DRIVERS| $SED -e"s,|, ,g"`; do
450 $STMSBOOTUTIL -D $WARNDRV -n
454 gettext "If you do NOT wish to operate on these controllers, please quit stmsboot\n"
455 gettext "and re-invoke with -D { fp | mpt | mpt_sas | pmcs} to specify which controllers you wish\n"
456 gettext "to modify your multipathing configuration for.\n"
459 gettext "Do you wish to continue? [y/n] (default: y) "
462 if [ -n "$response" -a "$response" != "Y" -a \
463 "$response" != "y" ]; then
476 while getopts D
:geduLl
: c
487 \?) echo "$USAGE" 1>&2
492 if [ "$cmd" = "none" ]; then
497 if [ -z "$DRV" ]; then
498 DRVLIST
="fp mpt mpt_sas pmcs"
503 USERID
=`id | $EGREP "uid=0"`
504 if [ -z "$USERID" ]; then
505 gettext "You must be super-user to run this script.\n" 1>&2
509 # just a sanity check
510 if [ ! -f $STMSBOOTUTIL -o ! -f $STMSMETHODSCRIPT ]; then
511 fmt=`gettext "Can't find %s and/or %s"`
512 printf "$fmt\n" "$STMSBOOTUTIL" "$STMSMETHODSCRIPT" 1>&2
516 # If the old sun4u-specific SMF method is found, remove it
517 $SVCCFG -s "platform/sun4u/mpxio-upgrade:default" < /dev
/null
> /dev
/null
2>&1
518 if [ $?
-eq 0 ]; then
519 $SVCCFG delete
"platform/sun4u/mpxio-upgrade:default" > /dev
/null
2>&1
522 # now import the new service, if necessary
523 $SVCPROP -q $STMSINSTANCE < /dev
/null
> /dev
/null
2>&1
524 if [ $?
-ne 0 ]; then
525 if [ -f /lib
/svc
/manifest
/system
/device
/mpxio-upgrade.xml
]; then
526 $SVCCFG import
/lib
/svc
/manifest
/system
/device
/mpxio-upgrade.xml
527 if [ $?
-ne 0 ]; then
529 fmt=`gettext "Unable to import the %s service"`
530 printf "$fmt\n" "$STMSINSTANCE" 1>&2
533 fmt=`gettext "Service %s imported successfully, continuing"`
534 printf "$fmt\n" "$STMSINSTANCE" 1>&2
537 fmt=`gettext "Service %s does not exist on this host"`
538 printf "$fmt\n" "$STMSINSTANCE" 1>&2
544 # make sure we can stash our data somewhere private
545 if [ ! -d $SAVEDIR ]; then
552 if [ "$cmd" = "enable" -o "$cmd" = "disable" -o "$cmd" = "update" ]; then
553 if $MOUNT -v |
$EGREP -s " on / type nfs "; then
554 gettext "This command option is not supported on systems with an nfs mounted root filesystem.\n" 1>&2
558 # if the user has left the system with the mpxio-upgrade service
559 # in a temporarily disabled state (ie, service is armed for the next
560 # reboot), then let them know. We need to ensure that the system is
561 # is in a sane state before allowing any further invocations, so
562 # try to get the system admin to do so
564 ISARMED
=`$SVCS -l $STMSINSTANCE|$GREP "enabled.*false.*temporary"`
567 gettext "You need to reboot the system in order to complete\n"
568 gettext "the previous invocation of stmsboot.\n"
570 gettext "Do you wish to reboot the system now? (y/n, default y) "
573 if [ -z "$response" -o "x$response" = "Y" -o \
574 "$response" = "y" ]; then
578 gettext "Please reboot this system before continuing\n"
585 # keep a copy of the last saved files, useful for manual
586 # recovery in case of a problem.
588 for d
in $DRVLIST; do
590 KDRVCONF
=/kernel
/drv
/$d.conf
591 TMPDRVCONF
=/var
/run
/tmp.
$d.conf.$$
592 TMPDRVCONF_MPXIO_ENTRY
=/var
/run
/tmp.
$d.conf.mpxioentry.$$
;
593 if [ "$MACH" = "sparc" ]; then
594 backup_lastsaved
$KDRVCONF $VFSTAB
596 backup_lastsaved
$KDRVCONF $VFSTAB /boot
/solaris
/$BOOTENV_FILE
601 if [ "$cmd" = "enable" -o "$cmd" = "disable" ]; then
603 msgneeded
=`echo "$DRVLIST" |$GREP " "`
604 if [ -n "$msgneeded" ]; then
605 emit_driver_warning_msg
607 for d
in $DRVLIST; do
608 configure_mpxio
$cmd $d
611 if [ $reboot_needed -ne 0 ]; then
612 # Need to update bootpath on x86 if our boot device is
613 # now accessed through mpxio.
614 # Only update bootpath before reboot when mpxio is enabled
615 # If mpxio is currently disabled, we will update bootpath
616 # on reboot in the mpxio-upgrade service
618 if [ "$cmd" = "disable" ]; then
619 if [ "$MACH" = "i386" ]; then
620 get_newbootpath_for_stmsdev
621 if [ $?
-ne 0 ]; then
622 $RM -f $TMPDRVCONF > /dev
/null
2>&1
623 gettext "failed to update bootpath.\n" 1>&2
624 gettext "No changes were made to your STMS configuration.\n" 1>&2
628 # If we're not using ZFS root then we need
629 # to keep track of what / maps to in case
630 # it's an active-active device and we boot from
632 HASZFSROOT
=`$DF -g / |$GREP zfs`
633 if [ -z "$HASZFSROOT" ]; then
634 ROOTSCSIVHCI
=`$DF /|$AWK -F":" '{print $1}' | \
635 $AWK -F"(" '{print $2}'| $SED -e"s,),,"`
636 TMPROOTDEV
=`$LS -l $ROOTSCSIVHCI |$AWK -F">" '{print $2}' | \
637 $SED -e"s, ../../devices,,"`
638 $STMSBOOTUTIL -q $TMPROOTDEV > $BOOTDEVICES
643 echo "STMS is already ${cmd}d. No changes or reboots needed"
647 elif [ "$cmd" = "update" ]; then
648 if [ "$MACH" = "i386" ]; then
649 # In this case we always change the bootpath to phci-based
650 # path first. bootpath will later be modified in mpxio-upgrade
651 # to the vhci-based path if mpxio is enabled on root.
652 get_newbootpath_for_stmsdev
653 if [ $?
-ne 0 ]; then
654 gettext "failed to update bootpath.\n" 1>&2
660 elif [ "$cmd" = "list" ]; then
661 $STMSBOOTUTIL $GUID -l $controller
663 $STMSBOOTUTIL $GUID -L