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