xref: /illumos-gate/usr/src/cmd/stmsboot/stmsboot.sh (revision 753a6d45)
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 ]; 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 > /dev/null 2>&1
354	echo "mpxio-disable=\"${propval}\";" >> $TMPDRVCONF
355	echo "disable-sata-mpxio=\"${propval}\";" >> $TMPDRVCONF
356
357}
358
359setcmd()
360{
361	if [ "x$cmd" = xnone ]; then
362		cmd=$1
363	else
364		echo "$USAGE" 1>&2
365		exit 2
366	fi
367}
368
369#
370# Need to update bootpath on x86 if boot system from FC disk
371# Only update bootpath here when mpxio is enabled
372# If mpxio is currently disabled, then we'll update bootpath in the
373# mpxio-upgrade service method on reboot.
374#
375
376get_newbootpath_for_stmsdev() {
377	if [ "x$cmd" = "xenable" ]; then
378		return 0
379	fi
380
381	cur_bootpath=`$STMSBOOTUTIL -b`
382	if [ $? != 0 ]; then
383		return 1
384	fi
385
386	# Since on x64 platforms the eeprom command doesn't update the
387	# kernel, the file /boot/solaris/bootenv.rc and the kernel's
388	# bootpath variable have a good chance of differing. We do some
389	# extra handwaving to get the correct bootpath variable setting.
390
391	ONDISKVER=`$AWK '/bootpath/ {print $3}' /boot/solaris/bootenv.rc|\
392		$SED -e"s,',,g"`
393	if [ "x$ONDISKVER" != "x$cur_bootpath" ]; then
394		cur_bootpath="$ONDISKVER"
395	fi
396
397	NEWBOOTPATH=""
398	for path in $cur_bootpath; do
399		mapped=`$STMSBOOTUTIL -p $path`
400		if [ "$mapped" != "NOT_MAPPED" ]; then
401			if [ "$mapped" != "$path" ]; then
402				NEWBOOTPATH=`echo "$path " | \
403				   $SED -e"s|$path|$mapped|"`" $NEWBOOTPATH"
404			else
405				NEWBOOTPATH="$NEWBOOTPATH $path"
406			fi
407		fi
408	done
409	# now strip off leading and trailing space chars
410	new_bootpath=`echo $NEWBOOTPATH`
411	return 0
412}
413
414#
415# Emit a warning message to the user that by default we
416# operate on all multipath-capable controllers that are
417# attached to the system, and that if they want to operate
418# on only a specific controller type (fp|mpt|....) then
419# they need to re-invoke stmsboot with "-D $driver" in
420# their argument list
421#
422
423emit_driver_warning_msg() {
424
425	# for each driver that we support, grab the list
426	# of controllers attached to the system.
427
428	echo ""
429	gettext "WARNING: stmsboot operates on each supported multipath-capable controller\n"
430	gettext "         detected in a host. In your system, these controllers are\n\n"
431
432	for WARNDRV in `echo $SUPPORTED_DRIVERS| $SED -e"s,|, ,g"`; do
433		$STMSBOOTUTIL -D $WARNDRV -n
434	done;
435
436	echo ""
437	gettext "If you do NOT wish to operate on these controllers, please quit stmsboot\n"
438	gettext "and re-invoke with -D { fp | mpt } to specify which controllers you wish\n"
439	gettext "to modify your multipathing configuration for.\n"
440
441	echo ""
442	gettext "Do you wish to continue? [y/n] (default: y) "
443	read response
444
445	if [ "x$response" != "x" -a "x$response" != "xY" -a \
446	    "x$response" != "xy" ]; then
447		exit
448	fi
449}
450
451
452#
453#
454# main starts here
455#
456
457cmd=none
458# process options
459while getopts D:geduLl: c
460do
461	case $c in
462	e)	setcmd enable;;
463	d)	setcmd disable;;
464	u)	setcmd update;;
465	L)	setcmd listall;;
466	l)	setcmd list
467		controller=$OPTARG;;
468	D)	DRV=$OPTARG;;
469	g)	GUID="-g";;
470	\?)	echo "$USAGE" 1>&2
471		exit 2;;
472	esac
473done
474
475if [ "x$cmd" = xnone ]; then
476	echo "$USAGE" 1>&2
477	exit 2
478fi
479
480if [ "x$DRV" = "x" ]; then
481	DRVLIST="fp mpt"
482else
483	DRVLIST=$DRV
484fi
485
486USERID=`id | $EGREP "uid=0"`
487if [ -z "$USERID" ]; then
488	gettext "You must be super-user to run this script.\n" 1>&2
489	exit 1
490fi
491
492# just a sanity check
493if [ ! -f $STMSBOOTUTIL -o ! -f $STMSMETHODSCRIPT ]; then
494	fmt=`gettext "Can't find %s and/or %s"`
495	printf "$fmt\n" "$STMSBOOTUTIL" "$STMSMETHODSCRIPT" 1>&2
496	exit 1
497fi
498
499# If the old sun4u-specific SMF method is found, remove it
500$SVCCFG -s "platform/sun4u/mpxio-upgrade:default" < /dev/null > /dev/null 2>&1
501if [ $? -eq 0 ]; then
502	$SVCCFG delete "platform/sun4u/mpxio-upgrade:default" > /dev/null 2>&1
503fi
504
505# now import the new service, if necessary
506$SVCPROP -q $STMSINSTANCE < /dev/null > /dev/null 2>&1
507if [ $? -ne 0 ]; then
508	if [ -f /var/svc/manifest/system/device/mpxio-upgrade.xml ]; then
509		$SVCCFG import /var/svc/manifest/system/device/mpxio-upgrade.xml
510		if [ $? -ne 0 ]; then
511			fmt=`gettext "Unable to import the %s service"`
512			printf "$fmt\n" "$STMSINSTANCE" 1>&2
513			exit 1
514		else
515			fmt=`gettext "Service %s imported successfully, continuing"`
516			printf "$fmt\n" "$STMSINSTANCE" 1>&2
517		fi
518	else
519		fmt=`gettext "Service %s does not exist on this host"`
520 		printf "$fmt\n" "$STMSINSTANCE" 1>&2
521		exit 1
522	fi
523fi
524
525
526# make sure we can stash our data somewhere private
527if [ ! -d $SAVEDIR ]; then
528	$MKDIR -p $SAVEDIR
529fi
530# prime the cache
531$STMSBOOTUTIL -i
532
533
534if [ "x$cmd" = xenable -o "x$cmd" = xdisable -o "x$cmd" = xupdate ]; then
535	#
536	# The bootup script doesn't work on cache-only-clients as the script
537	# is executed before the plumbing for cachefs mounting of root is done.
538	#
539	if $MOUNT -v | $EGREP -s " on / type (nfs|cachefs) "; then
540		gettext "This command option is not supported on systems with an nfs or cachefs mounted root filesystem.\n" 1>&2
541		exit 1
542	fi
543
544	# if the user has left the system with the mpxio-upgrade service
545	# in a temporarily disabled state (ie, service is armed for the next
546	# reboot), then let them know. We need to ensure that the system is
547	# is in a sane state before allowing any further invocations, so
548	# try to get the system admin to do so
549
550	ISARMED=`$SVCS -l $STMSINSTANCE|$GREP "enabled.*false.*temporary"`
551	if [ ! $? ]; then
552		echo ""
553		gettext "You need to reboot the system in order to complete\n"
554		gettext "the previous invocation of stmsboot.\n"
555		echo ""
556		gettext "Do you wish to reboot the system now? (y/n, default y) "
557		read response
558
559		if [ "x$response" = "x" -o "x$response" = "xY" -o \
560		    "x$response" = "xy" ]; then
561			$REBOOT
562		else
563			echo ""
564			gettext "Please reboot this system before continuing\n"
565			echo ""
566			exit 1
567		fi
568	fi
569
570	#
571	# keep a copy of the last saved files, useful for manual
572	# recovery in case of a problem.
573	#
574	for d in $DRVLIST; do
575		DRVCONF=$d.conf
576		KDRVCONF=/kernel/drv/$d.conf
577		TMPDRVCONF=/var/run/tmp.$d.conf.$$
578		TMPDRVCONF_MPXIO_ENTRY=/var/run/tmp.$d.conf.mpxioentry.$$;
579		if [ "x$MACH" = "xsparc" ]; then
580			backup_lastsaved $KDRVCONF $VFSTAB
581		else
582			backup_lastsaved $KDRVCONF $VFSTAB /boot/solaris/$BOOTENV_FILE
583		fi
584	done
585fi
586
587if [ "x$cmd" = xenable -o "x$cmd" = xdisable ]; then
588
589	msgneeded=`echo "$DRVLIST" |grep " "`
590	if [ -n "$msgneeded" ]; then
591		emit_driver_warning_msg
592	fi
593	for d in $DRVLIST; do
594		configure_mpxio $cmd $d
595	done
596
597	if [ $reboot_needed -ne 0 ]; then
598		# Need to update bootpath on x86 if our boot device is
599		# now accessed through mpxio.
600		# Only update bootpath before reboot when mpxio is enabled
601		# If mpxio is currently disabled, we will update bootpath
602		# on reboot in the mpxio-upgrade service
603
604		if [ "x$cmd" = "xdisable" ]; then
605			if [ "x$MACH" = "xi386" ]; then
606				get_newbootpath_for_stmsdev
607				if [ $? -ne 0 ]; then
608					$RM -f $TMPDRVCONF > /dev/null 2>&1
609					gettext "failed to update bootpath.\n" 1>&2
610					gettext "No changes were made to your STMS configuration.\n" 1>&2
611					return 1
612				fi
613			fi
614			# If we're not using ZFS root then we need
615			# to keep track of what / maps to in case
616			# it's an active-active device and we boot from
617			# the other path
618			ROOTSCSIVHCI=`$DF /|$AWK -F":" '{print $1}' | \
619			    $AWK -F"(" '{print $2}'| \
620			    $SED -e"s,dsk,rdsk," -e"s,s.),,"`
621			$STMSBOOTUTIL -L | $GREP $ROOTSCSIVHCI | \
622			    $AWK '{print $1}' | $SED -e"s,rdsk,dsk,g" \
623			    >$BOOTDEVICES
624		fi
625		update_sysfiles
626	else
627		echo "STMS is already ${cmd}d. No changes or reboots needed"
628	fi
629
630
631elif [ "x$cmd" = xupdate ]; then
632	if [ "x$MACH" = "xi386" ]; then
633	# In this case we always change the bootpath to phci-based
634	# path first. bootpath will later be modified in mpxio-upgrade
635	# to the vhci-based path if mpxio is enabled on root.
636		get_newbootpath_for_stmsdev
637		if [ $? -ne 0 ]; then
638			gettext "failed to update bootpath.\n" 1>&2
639			return 1
640		fi
641	fi
642	update_sysfiles
643
644elif [ "x$cmd" = xlist ]; then
645		$STMSBOOTUTIL $GUID -l $controller
646else
647		$STMSBOOTUTIL $GUID -L
648fi
649
650exit $?
651