1 #!/bin/ksh -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 # 
  24 # Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  25 # Use is subject to license terms.
  26 #
  27 
  28 #
  29 #This script is a tool which applies various service states to either
  30 #system services (or) test services according to usage.
  31 #
  32 
  33 bname=`basename $0`
  34 
  35 ###############################################################################
  36 #This section is configurable section. If you want you can add some more
  37 #validstates to variable "test_state". Also make sure you are going to add
  38 #matching 'output_state' for each test_state. Increase lib_wait_time
  39 #if default value is not sufficient.
  40 ###############################################################################
  41 
  42 lib_wait_time=${DEFAULT_WAIT_TIME:-30}
  43 test_state="enable disable refresh restart maintenance" # Add more valid states if needed
  44 output_state="online disabled online online maintenance" # Add more valid output states 
  45                                              # if needed
  46 
  47 ###############################################################################
  48 #       Initialize variables
  49 ###############################################################################
  50 
  51 
  52 typeset child_process="/var/tmp/child_script.$$"
  53 set -A rarray $output_state
  54 typeset pid=$$
  55 typeset ignore_not_online=0
  56 typeset continue_after_fails=0
  57 typeset filename=
  58 typeset time=
  59 typeset global_service_identifier=
  60 typeset bstime=                 # service STIME before restart
  61 typeset astime=                 # service STIME after restart
  62 typeset bppid=                  # process STIME before restart
  63 typeset appid=                  # process STIME after restart
  64 typeset fmri=
  65 
  66 ###############################################################################
  67 #       Usage of this script
  68 ###############################################################################
  69 
  70 function usage {
  71 
  72         cat >&2 << EOF
  73 Usage: $PROG [-M <instance_FMRI>] [-f <filename>] [-t <timeout_in_seconds>] [-i] [-n <num_of_iter>]
  74         [-c]
  75 
  76 Options:
  77         -M: Instance FMRI
  78         -f: filename contains list of online services
  79         -t: timeout in seconds to restrict runtime of this script.
  80         -i: to ignore services which are not online
  81         -n: to iterate the whole process given number of times
  82         -c: continue the transition even if some services fails
  83 EOF
  84 }
  85 
  86 ###############################################################################
  87 #       Generic cleanup; called when exit 0, 1, 2 and 15.
  88 ###############################################################################
  89 
  90 function cleanup {
  91         print "$bname: Bring back pending service state transition to online"
  92         rm -f $child_process
  93         bring_service_back_to_online $global_service_identifier
  94         if [ $? -ne 0 ]; then
  95                 return 1
  96         fi
  97 }
  98 
  99 ###############################################################################
 100 #       Cleanup_usr2 called when current process gets killed by signal
 101 #       "SIGUSR2". SIGUSR2 is sent after <time> seconds if <-t time> is set 
 102 #       when starting this script.
 103 ###############################################################################
 104 
 105 function cleanup_usr2 {
 106         print "$bname: This script ran for \"$time\" seconds; Now aborting due
 107                         to SIGUSR2 as per requirement"
 108         rm -f $child_process
 109         bring_service_back_to_online $global_service_identifier
 110         if [ $? -ne 0 ]; then
 111                 return 1
 112         fi
 113         exit 0
 114 }
 115 
 116 ###############################################################################
 117 #       Validate the given file
 118 #               - Check if file size > 0
 119 #               - Check if it is readable
 120 ###############################################################################
 121 
 122 function validate_file {
 123         typeset fname="$bname: function - validate_file:"
 124 
 125         [[ $# -ne 1 ]] && {
 126                 print -u2 "$fname: requires one argument - $# passed"
 127                 return 1
 128         }
 129         input_file="$1"
 130 
 131         if [[ ! -s $input_file || ! -r $input_file ]]; then
 132                 print -u2 "$fname: $input_file is not readable (or) zero size"
 133                 return 1
 134         fi
 135 
 136         return 0
 137 }
 138 
 139 ###############################################################################
 140 #       Validate each service
 141 #               - Verify that service state is "online"
 142 ###############################################################################
 143 
 144 function validate_eachservice {
 145         typeset fname="$bname: function - validate_eachservice:"
 146 
 147         [[ $# -ne 1 ]] && {
 148                 print -u2 "$fname: requires one argument - $# passed"
 149                 return 1
 150         }
 151 
 152         service=$1
 153         state=`svcprop -p restarter/state $service 2>/dev/null`
 154         if [ "$state" != "online" ]; then
 155                 return 1
 156         fi
 157         return 0
 158 }
 159 
 160 ###############################################################################
 161 #       Verify that given service exists in the system
 162 ###############################################################################
 163         
 164 function service_exists {
 165         typeset fname="$bname: function - service_exists:"
 166 
 167         [[ $# -ne 1 ]] && {
 168                 print "$fname : function requires one argument $# passed"
 169                 return 1
 170         }
 171         typeset service=$1
 172 
 173         /usr/sbin/svccfg select $service > /dev/null 2>&1
 174         ret=$?
 175         return $ret
 176 }
 177 
 178 ###############################################################################
 179 #       This function checks service state
 180 #               Two arguments : 1. Service name 2. Service state
 181 #       Return value:
 182 #               Return 1 if Service's state is not equal to expected state
 183 ###############################################################################
 184 
 185 
 186 function service_check_state {
 187         typeset fname="$bname: function - service_check_state:"
 188         typeset quiet=
 189 
 190 
 191         if [ -n "$1" -a "$1" = "-q" ]; then
 192                 quiet=1
 193                 shift
 194         fi
 195 
 196         [[ $# -ne 2 ]] && {
 197                 print -u2 "$fname: function requires two arguments - $# passed"
 198                 return 2
 199         }
 200 
 201         typeset service=$1
 202         typeset statetocheck=$2
 203 
 204         typeset state=
 205         typeset nstate=
 206 
 207         service_exists $service || {
 208                 print -u2 "$fname: entity $service does not exist"
 209                 return 2
 210         } 
 211 
 212         state=`svcprop -p restarter/state $service 2>/dev/null`
 213         [[ -z $state ]] && {
 214                 print -u2 "$fname: svcs did not return a state for service \
 215                         $state"
 216                 return 2
 217         }
 218 
 219         nstate=`svcprop -p restarter/state $service 2>/dev/null`
 220         [[ -z $nstate ]] && {
 221                 print -u2 "$fname: svcs did not return have nstate = -"
 222                 return 2
 223         }
 224 
 225         if [[ "$state" != "$statetocheck" || "$nstate" != "-" ]]; then
 226                 [ -z "$quiet" ] && \
 227                 print -u2 "$fname: service $service returned state $state, \
 228                         not $statetocheck"
 229 
 230                 return 1
 231         fi
 232         return 0
 233 }
 234 
 235 ###############################################################################
 236 #       This function waits until service gets transited to given state.
 237 #               Two arguments : 1. Service name 2. Service state
 238 #       Return value:
 239 #               Return 1 if Service's state didn't transit to given state in
 240 #                       wait_time
 241 ###############################################################################
 242 
 243 function service_wait_state {
 244         typeset fname="$bname: function - service_wait_state:"
 245 
 246         [[ $# -ne 2 && $# -ne 3 ]] && {
 247                 print -u2 "$fname: function requires two or three arguments - $# passed"
 248                 return 2
 249         }
 250 
 251 
 252         typeset service=$1
 253         typeset state=$2
 254         typeset wait_time=${3:-$lib_wait_time}
 255         typeset nsec=0
 256 
 257         while [ $nsec -le $wait_time ]; do
 258                 service_check_state -q $service $state
 259                 [[ $? -eq 0 ]] && {
 260                         print -u2 "$fname: $service transitioned to $state"
 261                         return 0
 262                 }
 263                 sleep 1
 264                 nsec=$((nsec + 1))
 265         done
 266 
 267 
 268         print -u2 "$fname: service did not transition to state $state within
 269                 $wait_time seconds"
 270         return 1
 271 }
 272 
 273 ###############################################################################
 274 #       Function name : stop_after_signaled
 275 #
 276 #       Description :   This function is called if this script invoked
 277 #                       with <-t time>. Basically, this function forks
 278 #                       one more process, which sleeps for given time
 279 #                       and sends SIGUSR2 to parent process. This is
 280 #                       to restrict the run time of script if user opts.
 281 #
 282 #       Argument : 2 arguments ; 1. Time (in seconds) 2. pid (pid of parent)
 283 ###############################################################################
 284                          
 285 
 286 function stop_after_signaled {
 287         typeset fname="$bname: function - stop_after_signaled:"
 288 
 289         [[ $# -ne 2 ]] && {
 290                 print -u2 "$fname: requires two argument - $# passed"
 291                 return 1
 292         }
 293 
 294         typeset wait_time="$1"
 295         typeset parent_pid="$2"
 296 
 297         typeset child_pid=
 298 
 299 cat > /var/tmp/child_script.$$ << EOF
 300         #!/bin/ksh -p
 301         sleep $wait_time
 302         ps -p $parent_pid >/dev/null 2>&1
 303         if [ $? -eq 0 ]; then
 304                 kill -17 $parent_pid >/dev/null 2>&1
 305         fi
 306         exit 0
 307 EOF
 308 
 309         chmod 755 /var/tmp/child_script.$$ >/dev/null 2>&1
 310         if [ $? -ne 0 ]; then
 311                 print -u2 "$fname: chmod 755 /var/tmp/child_script.$$ failed"
 312                 return 1
 313         fi
 314 
 315         # Call the script
 316 
 317         /var/tmp/child_script.$$ &
 318         child_pid=$!
 319         if [ -z $child_pid ]; then
 320                 print -u2 "$fname: Unable to run $childprocess"
 321                 return 1
 322         fi
 323         return 0
 324 }
 325 
 326 ###############################################################################
 327 #       Function name : transit_state
 328 #
 329 #       Description :   This function is called over each service to
 330 #                       apply various states and expect the transition
 331 #                       to happen.
 332 #
 333 #       Argument : 1 argument ; 1. Servicename
 334 ###############################################################################
 335 
 336 function transit_state {
 337         typeset fname="$bname: function - transit_state:"
 338         typeset atime=
 339         typeset btime=
 340 
 341         bstime=""
 342         astime=""
 343         bppid=""
 344         appid=""
 345 
 346         [[ $# -ne 1 ]] && {
 347                 print -u2 "$fname: requires one argument - $# passed"
 348                 return 1
 349         }
 350 
 351         typeset count=0
 352         typeset service=$1
 353         global_service_identifier=$service
 354 
 355         print "\n\nFMRI: $service"
 356 
 357         for eachstate in $test_state
 358         do
 359 
 360                 print "         Attempted command: $eachstate"
 361                 expected_state=${rarray[$count]}
 362                 print "         Expected state: $expected_state"
 363                 # If state = restart, then calculate stime of the
 364                 # service before restart
 365 
 366                 if [ "$eachstate" = "restart" ]; then
 367                         calculate_pid "before" $service
 368                         if [ $? -ne 0 ]; then
 369                                 return 1
 370                         fi
 371                 fi
 372 
 373                 # Could use 'svcadm enable -r' here, perhaps
 374                 if [ "$eachstate" = "enable" ]; then
 375                         /usr/sbin/svcadm enable $service > /dev/null 2>&1
 376                 elif [ "$eachstate" = "maintenance" ]; then
 377                         /usr/sbin/svcadm mark maintenance $service > /dev/null 2>&1
 378                 else
 379                         /usr/sbin/svcadm $eachstate $service >/dev/null 2>&1
 380                 fi
 381 
 382                 if [ $? -ne 0 ]; then
 383                         print -u2 "$fname: svcadm $eachstate $service failed"
 384                         return 1
 385                 fi
 386 
 387                 service_wait_state $service $expected_state >/dev/null 2>&1
 388                 if [ $? -ne 0 ]; then
 389                         tstate=`svcprop -p restarter/state $service 2>/dev/null`
 390                         print "         Actual state: $tstate"
 391                         print -u2 "$fname: Service transition to $expected_state failed"
 392                         return 1
 393                 fi
 394                 print "         Actual state: $expected_state"
 395                 print "         -----------------------------"
 396 
 397 
 398                 #Verify state transition of dependencies
 399                 check_for_dependencies $service $expected_state
 400                 if [ $? -ne 0 ]; then
 401                         return 1
 402                 fi
 403 
 404                 # If state = restart, then calculate stime of the
 405                 # service after restart
 406 
 407                 if [ "$eachstate" = "restart" ]; then
 408                         calculate_pid "after" $service
 409                         if [ $? -ne 0 ]; then
 410                                 return 1
 411                         fi
 412                 fi
 413 
 414 
 415                 if [ "$expected_state" = "maintenance" ]; then
 416                         print "         Attempted command: clear"
 417 
 418                         svcadm clear $service >/dev/null 2>&1
 419                         if [ $? -ne 0 ]; then
 420                                 print -u2 "$fname: svcadm clear $service failed"
 421                                 return 1
 422                         fi
 423                         print "         Expected state: online"
 424 
 425                         service_wait_state $service "online" >/dev/null 2>&1
 426                         if [ $? -ne 0 ]; then
 427                                 tstate=`svcprop -p restarter/state $service 2>/dev/null`
 428                                 print "         Actual state: $tstate"
 429                                 print -u2 "$fname: Service transition to online failed"
 430                                 return 1
 431                         fi
 432 
 433                         check_for_dependencies $service "online"
 434                         if [ $? -ne 0 ]; then
 435                                 return 1
 436                         fi
 437                         print "         Actual state: online"
 438                         print "         -----------------------------"
 439                 fi
 440 
 441                 #If following states attempted, bring service to
 442                 #online
 443 
 444 
 445                 if [[ $expected_state = "degraded" || \
 446                         $expected_state = "disabled" ]]
 447                 then
 448                         bring_service_back_to_online $service
 449                         if [ $? -ne 0 ]; then
 450                                 return 1
 451                         fi
 452                 fi
 453                 count=`expr $count + 1`
 454         done
 455         return 0
 456 }
 457 
 458 ###############################################################################
 459 #       Function name : bring_service_back_to_online
 460 #
 461 #       Description :   This function is called if the service state is
 462 #                               - disabled
 463 #                               - maintenance
 464 #                               - degraded
 465 #       Expected : To bring services back to online.
 466 #
 467 #       Argument : 1 argument : Servicename
 468 ###############################################################################
 469 
 470 function bring_service_back_to_online 
 471 {
 472         typeset fname="$bname: function - transit_state:"
 473         [[ $# -ne 1 ]] && {
 474                 print -u2 "$fname: requires one argument - $# passed"
 475                 return 1
 476         }
 477 
 478         typeset service="$1"
 479 
 480         tmp_state=`svcprop -p restarter/state $service 2>/dev/null`
 481         if [ "$tmp_state" = "maintenance" ]; then
 482                 /usr/sbin/svcadm clear $service >/dev/null 2>&1
 483                 if [ $? -ne 0 ]; then
 484                         print -u2 "$fname: svcadm clear $service failed"
 485                         return 1
 486                 fi
 487         else
 488                 /usr/sbin/svcadm enable $service >/dev/null 2>&1
 489                 if [ $? -ne 0 ]; then
 490                         print -u2 "$fname: svcadm enable $service failed"
 491                         return 1
 492                 fi
 493         fi
 494 
 495         service_wait_state $service "online" >/dev/null 2>&1
 496         if [ $? -ne 0 ]; then
 497                 print -u2 "$fname: service_wait_state to online failed"
 498                 return 1
 499         fi
 500 
 501         return 0
 502 }
 503 
 504 ###############################################################################
 505 #       Function name : calculate_pid
 506 #
 507 #       Description :   This function is called to verify the different
 508 #                       in stime of process and service before restart
 509 #                       and after restart
 510 #       Argument : 1 argument : mode and Servicename
 511 ###############################################################################
 512 
 513 
 514 function calculate_pid {
 515         typeset fname="$bname: function - calculate_pid:"
 516         typeset mode=$1
 517         typeset service=$2
 518         typeset stime=
 519         typeset ppid=
 520         typeset line_count=
 521 
 522         stime=`svcs -Ho STIME $service 2>/dev/null`
 523         if [[ $? -ne 0 || -z $stime ]]; then
 524                 print -u2 "$fname: Error in calculating \
 525                         STIME of $service"
 526                 return 1
 527         fi
 528         line_count=`svcs -Hp $service | wc -l 2>/dev/null`
 529         if [ $? -ne 0 ]; then
 530                 print -u2 "$fname: Error in calculating svcs -Hp $service"
 531                 return 1
 532         fi
 533 
 534         if [ $line_count -ge 2 ]; then
 535                 ppid=`svcs -Hp $service | grep -v $service | \
 536                         awk '{print $1}' 2>/dev/null`
 537                 if [[ $? -ne 0 || -z $ppid ]]; then
 538                         print -u2 "$fname: Error calculating \
 539                                 pid of $service's process"
 540                         return 1
 541                 fi
 542         fi
 543 
 544         if [ "$mode" = "before" ]; then
 545                 bstime=$stime
 546                 if [ ! -z $ppid ]; then
 547                         bppid=$ppid
 548                 fi
 549         fi
 550 
 551         if [ "$mode" = "after" ]; then
 552                 astime=$stime
 553                 if [ ! -z $ppid ]; then
 554                         appid=$ppid
 555                 fi
 556 
 557                 if [ $bstime = $astime ]; then
 558                         print -u2 "$fname: ERROR Service time unchanged upon \
 559                                         restart of $service $bstime $astime"
 560                         return 1
 561                 fi
 562 
 563                 if [[ ! -z $appid && ! -z $bppid ]]; then
 564                         set -A array $appid
 565                         typeset tcount=0
 566                         for eachbppid in $bppid
 567                         do
 568                                 if [ "$eachbppid" = "${array[$tcount]}" ]; then
 569                                         print -u2 "$fname: ERROR: Process id\
 570                                                 unchanged upon restart \
 571                                                 of service $service $appid $bppid"
 572                                         return 1
 573                                 fi
 574                                 tcount=`expr $tcount + 1`
 575                         done
 576                 fi
 577         fi
 578         return 0
 579 }
 580 
 581 
 582 # aditya: This function is incorrect, *dependent*
 583 # instances may be disabled by default in which case
 584 # they will never come online.
 585 ###############################################################################
 586 #       Function name : check_for_dependencies
 587 #
 588 #       Description :   This function verifies corresponding states for
 589 #                       dependencies also.
 590 #
 591 #       Argument : 2:  1. Servicename 2. State
 592 ###############################################################################
 593 
 594 function check_for_dependencies {
 595 
 596         return 0
 597 
 598         typeset service=$1
 599         typeset state=$2
 600         typeset fname="$bname: function - check_for_dependencies"
 601         typeset dependencies=
 602 
 603         dependencies=`svcs -HD -o FMRI $service 2>/dev/null`
 604         if [ $? -ne 0 ]; then
 605                 print -u2 "$fname: Error: Calculating dependencies for $service"
 606                 return 1
 607         fi
 608         if [ -z $dependencies ]; then
 609                 return 0
 610         fi
 611 
 612         if [[ "$state" = "disabled" || "$state" = "maintenance" ]]; then
 613                 state="offline"
 614         fi
 615 
 616         for eachdependencies in $dependencies
 617         do
 618                 service_wait_state $eachdependencies $state >/dev/null 2>&1
 619                 if [ $? -ne 0 ]; then
 620                         astate=`svcprop -p restarter/state $eachdependencies 2>/dev/null`
 621                         print -u2 "$fname: For dependency $eachdependencies"
 622                         print -u2 "Expected state : $state"
 623                         print -u2 "Actual state : $astate"
 624                         return 1
 625                 fi
 626         done
 627 
 628         return 0
 629 }
 630 
 631 
 632 ##############################################################################
 633 #main
 634 ##############################################################################
 635 
 636 # Make sure we run as root
 637 if ! /usr/bin/id | grep "uid=0(root)" > /dev/null 2>&1
 638 then
 639         print -u2 "$bname: This script must be run as root."
 640         exit $STF_UNRESOLVED
 641 fi
 642 
 643 # Make sure /usr/bin is first in our path
 644 export PATH=/usr/bin:$PATH
 645 
 646 typeset max=1
 647 while getopts :M:f:t:icn: opt
 648 do
 649         case $opt in
 650         M)
 651                 # Use supplied argument as instance FMRI.
 652                 fmri=$OPTARG
 653                 ;;
 654         f)
 655                 #Validate input filename
 656                 filename=$OPTARG
 657                 validate_file $filename
 658                 if [ $? -ne 0 ]; then
 659                         exit 1
 660                 fi
 661                 ;;
 662         t)
 663                 #Stop the process after time "t" with signal SIGUSR2
 664                 time=$OPTARG
 665                 stop_after_signaled $time $pid
 666                 if [ $? -ne 0 ]; then
 667                         exit 1
 668                 fi
 669                 ;;
 670         i)
 671                 # to ignore services which are not online
 672                 ignore_not_online=1
 673                 ;;
 674         c)
 675                 # to ignore services which are not online
 676                 continue_after_fails=1
 677                 ;;
 678         n)
 679                 #Number of iterations.
 680                 max=$OPTARG
 681                 ;;
 682         *)
 683                 usage
 684                 exit 2
 685                 ;;
 686         esac
 687 done
 688 
 689 # Handle signals
 690 trap cleanup_usr2 USR2
 691 trap cleanup 0 1 2 15
 692 
 693 typeset -i PASS=0
 694 typeset -i UNRESOLVED=1
 695 typeset -i FAIL=2
 696 
 697 typeset -i result=$PASS
 698 
 699 typeset iter=0
 700 
 701 while [ $iter -lt $max ]
 702 do
 703 
 704         # If filename is given then get services from file
 705         if [ ! -z $filename ]; then
 706                 for eachservice in `cat $filename`
 707                 do
 708                         validate_eachservice $eachservice
 709                         if [ $? -ne 0 ]; then
 710                                 if [ $ignore_not_online -eq 1 ]; then
 711                                         print -u2 "\n\n$bname: $eachservice is not online, continuing ..."
 712                                         result=$UNRESOLVED
 713                                         print -u2 "\nResult: UNRESOLVED\n"
 714                                         continue;
 715                                 else
 716                                         print -u2 "\n$bname: $eachservice is not online\n"
 717                                         bring_service_back_to_online $eachservice
 718                                         if [ $? -ne 0 ]; then
 719                                                 print -u2 "\n$bname: Couldnt bring $eachservice online, continuing on ...\n"
 720                                                 result=$FAIL
 721                                                 print -u2 "\nResult: FAIL\n"
 722                                                 if [ $continue_after_fails -eq 1 ]; then
 723                                                     continue
 724                                                 fi
 725                                                 exit 1
 726                                         fi
 727                                 fi
 728                         fi
 729 
 730                         transit_state $eachservice
 731                         if [ $? -ne 0 ]; then
 732                                 result=$FAIL
 733                                 print -u2 "\nResult: FAIL\n"
 734                                 if [ $continue_after_fails -eq 1 ]; then
 735                                         continue
 736                                 fi
 737                                 exit 1
 738                         fi
 739                         print -u2 "\nResult: PASS\n"
 740                 done
 741         elif [ ! -z $fmri ]
 742         then
 743                         validate_eachservice $fmri
 744                         if [ $? -ne 0 ]; then
 745                                 if [ $ignore_not_online -eq 1 ]; then
 746                                         print -u2 "\n\n$bname: $fmri is not online, continuing ..."
 747                                         result=$UNRESOLVED
 748                                         print -u2 "\nResult: UNRESOLVED\n"
 749                                         exit 1
 750                                 else
 751                                         print -u2 "\n$bname: $fmri is not online\n"
 752                                         bring_service_back_to_online $fmri
 753                                         if [ $? -ne 0 ]; then
 754                                                 print -u2 "\n$bname: Couldnt bring $fmri online, continuing on ...\n"
 755                                                 result=$FAIL
 756                                                 print -u2 "\nResult: FAIL\n"
 757                                                 exit 1
 758                                         fi
 759                                 fi
 760                         fi
 761 
 762                         transit_state $fmri
 763                         if [ $? -ne 0 ]; then
 764                                 result=$FAIL
 765                                 print -u2 "\nResult: FAIL\n"
 766                                 exit 1
 767                         fi
 768                         print -u2 "\nResult: PASS\n"
 769         else
 770                 # If filename is not given, then get system's online service
 771                 # and play with them
 772                 for eachservice in `svcs -Ho STATE,FMRI | grep online | awk '{print $2}'`
 773                 do
 774                         transit_state $eachservice
 775                         if [ $? -ne 0 ]; then
 776                                 result=$FAIL
 777                                 print -u2 "\nResult: FAIL\n"
 778                         else
 779                                 print -u2 "\nResult: PASS\n"
 780                                 continue;
 781                         fi
 782                         if [ $continue_after_fails -eq 1 ]; then
 783                                 continue;
 784                         else
 785                             exit 1
 786                         fi
 787                 done
 788         fi
 789 
 790         iter=`expr $iter + 1`
 791 done
 792 
 793 exit 0