xref: /titanic_51/usr/src/cmd/stmsboot/stmsboot.sh (revision c3c82186300a3bf11cfdda43b1cca3cd6b333629)
1#!/sbin/sh -p
2#
3# CDDL HEADER START
4#
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.
8#
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.
13#
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]
19#
20# CDDL HEADER END
21#
22#
23# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24# Use is subject to license terms.
25#
26#
27PATH=/usr/bin:/usr/sbin:$PATH; export PATH
28STMSBOOTUTIL=/lib/mpxio/stmsboot_util
29STMSMETHODSCRIPT=/lib/svc/method/mpxio-upgrade
30KDRVCONF=
31DRVCONF=
32TMPDRVCONF=
33TMPDRVCONF_MPXIO_ENTRY=
34TMPDRVCONF_SATA_ENTRY=
35DRVLIST=
36GUID=
37VFSTAB=/etc/vfstab
38SAVEDIR=/etc/mpxio
39BOOTDEVICES=$SAVEDIR/boot-devices
40RECOVERFILE=$SAVEDIR/recover_instructions
41SVCCFG_RECOVERY=$SAVEDIR/svccfg_recover
42SUPPORTED_DRIVERS="fp|mpt"
43USAGE=`gettext "Usage: stmsboot [-D $SUPPORTED_DRIVERS] -e | -d | -u | -L | -l controller_number"`
44TEXTDOMAIN=SUNW_OST_OSCMD
45export TEXTDOMAIN
46STMSINSTANCE=svc:system/device/mpxio-upgrade:default
47STMSBOOT=/usr/sbin/stmsboot
48BOOTADM=/sbin/bootadm
49MOUNT=/usr/sbin/mount
50EEPROM=/usr/sbin/eeprom
51EGREP=/usr/bin/egrep
52GREP=/usr/bin/grep
53AWK=/usr/bin/awk
54CP=/usr/bin/cp
55DF=/usr/bin/df
56LS=/usr/bin/ls
57MV=/usr/bin/mv
58RM=/usr/bin/rm
59SORT=/usr/bin/sort
60UNIQ=/usr/bin/uniq
61EXPR=/usr/bin/expr
62MKDIR=/usr/bin/mkdir
63REBOOT=/usr/sbin/reboot
64SED=/usr/bin/sed
65SVCPROP=/usr/bin/svcprop
66SVCCFG=/usr/sbin/svccfg
67SVCS=/usr/bin/svcs
68SVCADM=/usr/sbin/svcadm
69
70NOW=`/usr/bin/date +%G%m%d_%H%M`
71MACH=`/usr/bin/uname -p`
72BOOTENV_FILE=bootenv.rc
73reboot_needed=0
74new_bootpath=""
75CLIENT_TYPE_PHCI=""
76CLIENT_TYPE_VHCI="/scsi_vhci"
77
78#
79# Copy all entries (including comments) from source driver.conf
80# to destination driver.conf except those entries which contain
81# the mpxio-disable property.
82# Take into consideration entries that spawn more than one line.
83#
84# $1	source driver.conf file
85# $2	destination driver.conf file
86#
87# Returns 0 on success, non zero on failure.
88#
89delete_mpxio_disable_entries()
90{
91	# be careful here, we've got embedded \t characters
92	# in sed's pattern space.
93	$SED '
94		/^[ 	]*#/{ p
95			      d
96			    }
97		s/[ 	]*$//
98		/^$/{ p
99		      d
100		    }
101		/mpxio-disable[ 	]*=.*;$/{ w '$3'
102						  d
103						}
104		/disable-sata-mpxio[ 	]*=.*;$/{ w '$4'
105						  d
106						}
107		/;$/{ p
108		      d
109		    }
110		:rdnext
111		N
112		s/[ 	]*$//
113		/[^;]$/b rdnext
114		/mpxio-disable[ 	]*=/{ s/\n/ /g
115					      w '$3'
116					      d
117					    }
118		' $1 > $2
119
120	return $?
121}
122
123#
124# backup the last saved copy of the specified files.
125# $*	files to backup
126#
127backup_lastsaved()
128{
129	for file in $*
130	do
131		newfile=`basename $file`
132		$CP $file $SAVEDIR/$newfile.$cmd.$NOW
133	done
134}
135
136#
137# build recover instructions
138#
139# $1	1 to include boot script in the instructions
140#	0 otherwise
141#
142build_recover()
143{
144	gettext "Instructions to recover your previous STMS configuration (if in case the system does not boot):\n\n" > $RECOVERFILE
145	echo "\tboot net \c"  >> $RECOVERFILE
146	gettext "(or from a cd/dvd/another disk)\n" >> $RECOVERFILE
147	echo "\tfsck <your-root-device>" >> $RECOVERFILE
148	echo "\tmount <your-root-device> /mnt" >> $RECOVERFILE
149
150	if [ "x$cmd" = xupdate ]; then
151		gettext "\tUndo the modifications you made to STMS configuration.\n\tFor example undo any changes you made to " >> $RECOVERFILE
152		echo "/mnt$KDRVCONF." >> $RECOVERFILE
153	else
154		echo "\tcp /mnt${SAVEDIR}/$DRVCONF.$cmd.$NOW /mnt$KDRVCONF" >> $RECOVERFILE
155	fi
156
157	if [ $1 -eq 1 ]; then
158		echo "\tcp /mnt${SAVEDIR}/vfstab.$cmd.$NOW /mnt$VFSTAB" >> $RECOVERFILE
159
160		echo "repository /mnt/etc/svc/repository.db" > $SVCCFG_RECOVERY
161		echo "select $STMSINSTANCE" >> $SVCCFG_RECOVERY
162		echo "setprop general/enabled=false" >> $SVCCFG_RECOVERY
163		echo "exit" >> $SVCCFG_RECOVERY
164
165		echo "\t$SVCCFG -f /mnt$SVCCFG_RECOVERY" >> $RECOVERFILE
166
167		if [ "x$MACH" = "xi386" -a "x$new_bootpath" != "x" ]; then
168			echo "\tcp /mnt${SAVEDIR}/bootenv.rc.$cmd.$NOW /mnt/boot/solaris/$BOOTENV_FILE" >> $RECOVERFILE
169		fi
170	fi
171
172	rootdisk=`$MOUNT | $GREP "/ on " | cut -f 3 -d " "`
173	echo "\tumount /mnt\n\treboot\n\n${rootdisk} \c" >> $RECOVERFILE
174	gettext "was your root device,\nbut it could be named differently after you boot net.\n" >> $RECOVERFILE
175}
176
177
178#
179# Arrange for /etc/vfstab and dump configuration to be updated
180# during the next reboot. If the cmd is "enable" or "disable", copy
181# $TMPDRVCONF to $KDRVCONF.
182#
183# Returns 0 on success, 1 on failure.
184#
185update_sysfiles()
186{
187
188	gettext "WARNING: This operation will require a reboot.\n"
189	gettext "Do you want to continue ? [y/n] (default: y) "
190	read response
191
192	if [ "x$response" != x -a "x$response" != xy -a \
193	    "x$response" != xY ]; then
194		for d in $DRVLIST; do
195			TMPDRVCONF=/var/run/tmp.$d.conf.$$
196			$RM -f $TMPDRVCONF > /dev/null 2>&1
197		done;
198		return 0;
199	fi
200
201	# set need_bootscript to the number of drivers that
202	# we support.
203	need_bootscript=`echo $SUPPORTED_DRIVERS|$AWK -F"|" '{print NF}'`
204
205	if [ "x$cmd" = xenable -o "x$cmd" = xdisable ]; then
206
207		for d in $DRVLIST; do
208			DRVCONF=$d.conf
209			KDRVCONF=/kernel/drv/$d.conf
210			TMPDRVCONF=/var/run/tmp.$d.conf.$$
211
212			$CP $KDRVCONF $SAVEDIR/`basename $KDRVCONF`.$cmd.$NOW
213			if [ -f $TMPDRVCONF ]; then
214				$CP $TMPDRVCONF $KDRVCONF
215				$RM -f $TMPDRVCONF
216			else
217				# if $TMPDRVCONF doesn't exist, then we
218				# haven't made any changes to it
219				continue;
220			fi
221
222			#
223			# there is no need to update the system files in the following
224			# cases:
225			# - we are enabling mpxio and the system has no configured
226			#   disks accessible by phci paths.
227			# - we are disabling mpxio and the system has no configured
228			#   disks accessible by vhci paths.
229			#
230
231			# Function to setup the CLIENT_TYPE_PHCI string based on
232			# the list of drivers that we're operating on. The variable
233			# depends upon the pathname of the parent node in the
234			# device tree, which can be different on x86/x64 and sparc.
235
236			CLIENT_TYPE_PHCI=`$STMSBOOTUTIL -D $d -N`;
237
238			if [ "x$CLIENT_TYPE_PHCI" = "x" ]; then
239				continue;
240			fi
241
242			if [ "x$cmd" = "xenable" ]; then
243				$LS -l /dev/dsk/*s2 2> /dev/null | \
244				    $EGREP -s "$CLIENT_TYPE_PHCI"
245			else
246				$LS -l /dev/dsk/*s2 2> /dev/null | \
247				    $EGREP -s "$CLIENT_TYPE_VHCI"
248			fi
249
250			if [ $? -ne 0 ]; then
251				need_bootscript=`$EXPR $need_bootscript - 1`
252			fi
253		done
254	fi
255
256	if [ $need_bootscript -gt 0 ]; then
257		need_bootscript=1
258		if [ "x$MACH" = "xi386" -a "x$new_bootpath" != "x" ]; then
259			#only update bootpath for x86.
260			$CP /boot/solaris/$BOOTENV_FILE $SAVEDIR/$BOOTENV_FILE.$cmd.$NOW
261			$EEPROM bootpath="$new_bootpath"
262		fi
263		# Enable the mpxio-upgrade service for the reboot
264		$SVCADM disable -t $STMSINSTANCE
265		$SVCCFG -s $STMSINSTANCE "setprop general/enabled=true"
266	else
267		need_bootscript=0
268	fi
269
270	build_recover $need_bootscript
271
272	if [ "x$MACH" = "xi386" ]; then
273		$BOOTADM update-archive
274	fi
275
276	gettext "The changes will come into effect after rebooting the system.\nReboot the system now ? [y/n] (default: y) "
277	read response
278
279	if [ "x$response" = x -o "x$response" = xy -o \
280	    "x$response" = xY ]; then
281		$REBOOT
282	fi
283
284	return 0
285}
286
287
288#
289# Enable or disable mpxio as specified by the cmd.
290# Returns 0 on success, 1 on failure.
291#
292# Args: $cmd = {enable | disable}
293#	$d = {fp | mpt}
294#
295# the global variable $DRVLIST is used
296#
297configure_mpxio()
298{
299	# be careful here, we've got embedded \t characters
300	# in sed's pattern space.
301	mpxiodisableno='mpxio-disable[ 	]*=[ 	]*"no"[ 	]*;'
302	mpxiodisableyes='mpxio-disable[ 	]*=[ 	]*"yes"[ 	]*;'
303	satadisableno='disable-sata-mpxio[ 	]*=[ 	]*"no"[ 	]*;'
304	satadisableyes='disable-sata-mpxio[ 	]*=[ 	]*"yes"[ 	]*;'
305
306	if [ "x$cmd" = xenable ]; then
307		mpxiodisable_cur_entry=$mpxiodisableyes
308		satadisable_cur_entry=$satadisableyes
309		propval=no
310		msg=`gettext "STMS already enabled"`
311	else
312		mpxiodisable_cur_entry=$mpxiodisableno
313		satadisable_cur_entry=$satadisableno
314		propval=yes
315		msg=`gettext "STMS already disabled"`
316	fi
317
318	DRVCONF=$d.conf
319	KDRVCONF=/kernel/drv/$d.conf
320	TMPDRVCONF=/var/run/tmp.$d.conf.$$
321	TMPDRVCONF_MPXIO_ENTRY=/var/run/tmp.$d.conf.mpxioentry.$$;
322	TMPDRVCONF_SATA_ENTRY=/var/run/tmp.$d.conf.sataentry.$$;
323
324	if delete_mpxio_disable_entries $KDRVCONF $TMPDRVCONF $TMPDRVCONF_MPXIO_ENTRY $TMPDRVCONF_SATA_ENTRY; then
325
326		if [ -s $TMPDRVCONF_MPXIO_ENTRY ]; then
327			# $DRVCONF does have mpxiodisable entries
328			$EGREP -s "$mpxiodisable_cur_entry" $TMPDRVCONF_MPXIO_ENTRY
329			if [ $? -eq 0 ]; then
330				reboot_needed=`$EXPR $reboot_needed + 1`
331			else
332				# if all mpxiodisable entries are no/yes for
333				# enable/disable mpxio, notify the user
334				$EGREP -s "$satadisable_cur_entry" $TMPDRVCONF_SATA_ENTRY
335				if [ $? -eq 0 -a "$d" = mpt ]; then
336					reboot_needed=`$EXPR $reboot_needed + 1`
337				else
338					$RM -f $TMPDRVCONF $TMPDRVCONF_MPXIO_ENTRY $TMPDRVCONF_SATA_ENTRY > /dev/null 2>&1
339					continue;
340				fi
341			fi
342
343			# If mpxiodisable entries do not exist, always continue update
344		fi
345	else
346		$RM -f $TMPDRVCONF $TMPDRVCONF_MPXIO_ENTRY $TMPDRVCONF_SATA_ENTRY > /dev/null 2>&1
347		gettext "failed to update " 1>&2
348		echo "$KDRVCONF." 1>&2
349		gettext "No changes were made to your STMS configuration.\n" 1>&2
350		return 1
351	fi
352
353	rm $TMPDRVCONF_MPXIO_ENTRY $TMPDRVCONF_SATA_ENTRY > /dev/null 2>&1
354	echo "mpxio-disable=\"${propval}\";" >> $TMPDRVCONF
355	if [ "$d" = mpt ]; then
356		echo "disable-sata-mpxio=\"${propval}\";" >> $TMPDRVCONF
357	fi
358
359}
360
361setcmd()
362{
363	if [ "x$cmd" = xnone ]; then
364		cmd=$1
365	else
366		echo "$USAGE" 1>&2
367		exit 2
368	fi
369}
370
371#
372# Need to update bootpath on x86 if boot system from FC disk
373# Only update bootpath here when mpxio is enabled
374# If mpxio is currently disabled, then we'll update bootpath in the
375# mpxio-upgrade service method on reboot.
376#
377
378get_newbootpath_for_stmsdev() {
379	if [ "x$cmd" = "xenable" ]; then
380		return 0
381	fi
382
383	cur_bootpath=`$STMSBOOTUTIL -b`
384	if [ $? != 0 ]; then
385		return 1
386	fi
387
388	# Since on x64 platforms the eeprom command doesn't update the
389	# kernel, the file /boot/solaris/bootenv.rc and the kernel's
390	# bootpath variable have a good chance of differing. We do some
391	# extra handwaving to get the correct bootpath variable setting.
392
393	ONDISKVER=`$AWK '/bootpath/ {print $3}' /boot/solaris/bootenv.rc|\
394		$SED -e"s,',,g"`
395	if [ "x$ONDISKVER" != "x$cur_bootpath" ]; then
396		cur_bootpath="$ONDISKVER"
397	fi
398
399	NEWBOOTPATH=""
400	for path in $cur_bootpath; do
401		mapped=`$STMSBOOTUTIL -p $path`
402		if [ "$mapped" != "NOT_MAPPED" ]; then
403			if [ "$mapped" != "$path" ]; then
404				NEWBOOTPATH=`echo "$path " | \
405				   $SED -e"s|$path|$mapped|"`" $NEWBOOTPATH"
406			else
407				NEWBOOTPATH="$NEWBOOTPATH $path"
408			fi
409		fi
410	done
411	# now strip off leading and trailing space chars
412	new_bootpath=`echo $NEWBOOTPATH`
413	return 0
414}
415
416#
417# Emit a warning message to the user that by default we
418# operate on all multipath-capable controllers that are
419# attached to the system, and that if they want to operate
420# on only a specific controller type (fp|mpt|....) then
421# they need to re-invoke stmsboot with "-D $driver" in
422# their argument list
423#
424
425emit_driver_warning_msg() {
426
427	# for each driver that we support, grab the list
428	# of controllers attached to the system.
429
430	echo ""
431	gettext "WARNING: stmsboot operates on each supported multipath-capable controller\n"
432	gettext "         detected in a host. In your system, these controllers are\n\n"
433
434	for WARNDRV in `echo $SUPPORTED_DRIVERS| $SED -e"s,|, ,g"`; do
435		$STMSBOOTUTIL -D $WARNDRV -n
436	done;
437
438	echo ""
439	gettext "If you do NOT wish to operate on these controllers, please quit stmsboot\n"
440	gettext "and re-invoke with -D { fp | mpt } to specify which controllers you wish\n"
441	gettext "to modify your multipathing configuration for.\n"
442
443	echo ""
444	gettext "Do you wish to continue? [y/n] (default: y) "
445	read response
446
447	if [ "x$response" != "x" -a "x$response" != "xY" -a \
448	    "x$response" != "xy" ]; then
449		exit
450	fi
451}
452
453
454#
455#
456# main starts here
457#
458
459cmd=none
460# process options
461while getopts D:geduLl: c
462do
463	case $c in
464	e)	setcmd enable;;
465	d)	setcmd disable;;
466	u)	setcmd update;;
467	L)	setcmd listall;;
468	l)	setcmd list
469		controller=$OPTARG;;
470	D)	DRV=$OPTARG;;
471	g)	GUID="-g";;
472	\?)	echo "$USAGE" 1>&2
473		exit 2;;
474	esac
475done
476
477if [ "x$cmd" = xnone ]; then
478	echo "$USAGE" 1>&2
479	exit 2
480fi
481
482if [ "x$DRV" = "x" ]; then
483	DRVLIST="fp mpt"
484else
485	DRVLIST=$DRV
486fi
487
488USERID=`id | $EGREP "uid=0"`
489if [ -z "$USERID" ]; then
490	gettext "You must be super-user to run this script.\n" 1>&2
491	exit 1
492fi
493
494# just a sanity check
495if [ ! -f $STMSBOOTUTIL -o ! -f $STMSMETHODSCRIPT ]; then
496	fmt=`gettext "Can't find %s and/or %s"`
497	printf "$fmt\n" "$STMSBOOTUTIL" "$STMSMETHODSCRIPT" 1>&2
498	exit 1
499fi
500
501# If the old sun4u-specific SMF method is found, remove it
502$SVCCFG -s "platform/sun4u/mpxio-upgrade:default" < /dev/null > /dev/null 2>&1
503if [ $? -eq 0 ]; then
504	$SVCCFG delete "platform/sun4u/mpxio-upgrade:default" > /dev/null 2>&1
505fi
506
507# now import the new service, if necessary
508$SVCPROP -q $STMSINSTANCE < /dev/null > /dev/null 2>&1
509if [ $? -ne 0 ]; then
510	if [ -f /var/svc/manifest/system/device/mpxio-upgrade.xml ]; then
511		$SVCCFG import /var/svc/manifest/system/device/mpxio-upgrade.xml
512		if [ $? -ne 0 ]; then
513			fmt=`gettext "Unable to import the %s service"`
514			printf "$fmt\n" "$STMSINSTANCE" 1>&2
515			exit 1
516		else
517			fmt=`gettext "Service %s imported successfully, continuing"`
518			printf "$fmt\n" "$STMSINSTANCE" 1>&2
519		fi
520	else
521		fmt=`gettext "Service %s does not exist on this host"`
522 		printf "$fmt\n" "$STMSINSTANCE" 1>&2
523		exit 1
524	fi
525fi
526
527
528# make sure we can stash our data somewhere private
529if [ ! -d $SAVEDIR ]; then
530	$MKDIR -p $SAVEDIR
531fi
532# prime the cache
533$STMSBOOTUTIL -i
534
535
536if [ "x$cmd" = xenable -o "x$cmd" = xdisable -o "x$cmd" = xupdate ]; then
537	#
538	# The bootup script doesn't work on cache-only-clients as the script
539	# is executed before the plumbing for cachefs mounting of root is done.
540	#
541	if $MOUNT -v | $EGREP -s " on / type (nfs|cachefs) "; then
542		gettext "This command option is not supported on systems with an nfs or cachefs mounted root filesystem.\n" 1>&2
543		exit 1
544	fi
545
546	# if the user has left the system with the mpxio-upgrade service
547	# in a temporarily disabled state (ie, service is armed for the next
548	# reboot), then let them know. We need to ensure that the system is
549	# is in a sane state before allowing any further invocations, so
550	# try to get the system admin to do so
551
552	ISARMED=`$SVCS -l $STMSINSTANCE|$GREP "enabled.*false.*temporary"`
553	if [ ! $? ]; then
554		echo ""
555		gettext "You need to reboot the system in order to complete\n"
556		gettext "the previous invocation of stmsboot.\n"
557		echo ""
558		gettext "Do you wish to reboot the system now? (y/n, default y) "
559		read response
560
561		if [ "x$response" = "x" -o "x$response" = "xY" -o \
562		    "x$response" = "xy" ]; then
563			$REBOOT
564		else
565			echo ""
566			gettext "Please reboot this system before continuing\n"
567			echo ""
568			exit 1
569		fi
570	fi
571
572	#
573	# keep a copy of the last saved files, useful for manual
574	# recovery in case of a problem.
575	#
576	for d in $DRVLIST; do
577		DRVCONF=$d.conf
578		KDRVCONF=/kernel/drv/$d.conf
579		TMPDRVCONF=/var/run/tmp.$d.conf.$$
580		TMPDRVCONF_MPXIO_ENTRY=/var/run/tmp.$d.conf.mpxioentry.$$;
581		if [ "x$MACH" = "xsparc" ]; then
582			backup_lastsaved $KDRVCONF $VFSTAB
583		else
584			backup_lastsaved $KDRVCONF $VFSTAB /boot/solaris/$BOOTENV_FILE
585		fi
586	done
587fi
588
589if [ "x$cmd" = xenable -o "x$cmd" = xdisable ]; then
590
591	msgneeded=`echo "$DRVLIST" |grep " "`
592	if [ -n "$msgneeded" ]; then
593		emit_driver_warning_msg
594	fi
595	for d in $DRVLIST; do
596		configure_mpxio $cmd $d
597	done
598
599	if [ $reboot_needed -ne 0 ]; then
600		# Need to update bootpath on x86 if our boot device is
601		# now accessed through mpxio.
602		# Only update bootpath before reboot when mpxio is enabled
603		# If mpxio is currently disabled, we will update bootpath
604		# on reboot in the mpxio-upgrade service
605
606		if [ "x$cmd" = "xdisable" ]; then
607			if [ "x$MACH" = "xi386" ]; then
608				get_newbootpath_for_stmsdev
609				if [ $? -ne 0 ]; then
610					$RM -f $TMPDRVCONF > /dev/null 2>&1
611					gettext "failed to update bootpath.\n" 1>&2
612					gettext "No changes were made to your STMS configuration.\n" 1>&2
613					return 1
614				fi
615			fi
616			# If we're not using ZFS root then we need
617			# to keep track of what / maps to in case
618			# it's an active-active device and we boot from
619			# the other path
620			ROOTSCSIVHCI=`$DF /|$AWK -F":" '{print $1}' | \
621			    $AWK -F"(" '{print $2}'| \
622			    $SED -e"s,dsk,rdsk," -e"s,s.[ ]*),,"`
623			$STMSBOOTUTIL -L | $GREP $ROOTSCSIVHCI | \
624			    $AWK '{print $1}' | $SED -e"s,rdsk,dsk,g" \
625			    >$BOOTDEVICES
626		fi
627		update_sysfiles
628	else
629		echo "STMS is already ${cmd}d. No changes or reboots needed"
630	fi
631
632
633elif [ "x$cmd" = xupdate ]; then
634	if [ "x$MACH" = "xi386" ]; then
635	# In this case we always change the bootpath to phci-based
636	# path first. bootpath will later be modified in mpxio-upgrade
637	# to the vhci-based path if mpxio is enabled on root.
638		get_newbootpath_for_stmsdev
639		if [ $? -ne 0 ]; then
640			gettext "failed to update bootpath.\n" 1>&2
641			return 1
642		fi
643	fi
644	update_sysfiles
645
646elif [ "x$cmd" = xlist ]; then
647		$STMSBOOTUTIL $GUID -l $controller
648else
649		$STMSBOOTUTIL $GUID -L
650fi
651
652exit $?
653