1 #!/usr/bin/ksh 2 # CDDL HEADER START 3 # 4 # The contents of this file are subject to the terms of the 5 # Common Development and Distribution License (the "License"). 6 # You may not use this file except in compliance with the License. 7 # 8 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 # or http://www.opensolaris.org/os/licensing. 10 # See the License for the specific language governing permissions 11 # and limitations under the License. 12 # 13 # When distributing Covered Code, include this CDDL HEADER in each 14 # file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 # If applicable, add the following below this CDDL HEADER, with the 16 # fields enclosed by brackets "[]" replaced with your own identifying 17 # information: Portions Copyright [yyyy] [name of copyright owner] 18 # 19 # CDDL HEADER END 20 # 21 # 22 # Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23 # Use is subject to license terms. 24 # 25 26 typeset -r PROG=$(basename $0) 27 typeset -r CTAG_NULL="-" 28 29 # 30 # help message 31 # 32 help() 33 { 34 $xopt 35 36 cluster_configured 37 CLUSTER_CONFIGURED=$? 38 39 echo "\ 40 usage: 41 $PROG 42 $PROG -i 43 $PROG -e [-r][-p] 44 $PROG -d [-r]" >&2 45 if [ $CLUSTER_CONFIGURED -eq 1 ]; then 46 echo "\ 47 $PROG -s" >&2 48 fi 49 50 echo "\ 51 -i : display information on the Availability Suite services 52 -e : enable Availability Suite services (all, by default) 53 -d : disable Availability Suite services (all, by default) 54 -r : enable/disable Remote Mirror 55 -p : enable Point in Time Copy" >&2 56 if [ $CLUSTER_CONFIGURED -eq 1 ]; then 57 echo "\ 58 -s : set the location of the cluster configuration database" >&2 59 fi 60 echo "\ 61 -x : turn on script debugging (may be used with any valid option) 62 63 When executed with no options or with nothing but -x, $PROG runs in 64 interactive fashion, allowing the user to initialize the local (and 65 if applicable, the cluster) configuration database, and to start the 66 Availability Suite services." >&2 67 68 exit 2 69 } 70 71 ########################## SET GLOBAL VARIABLES ###################### 72 73 # root directory 74 PKG_INSTALL_ROOT="" 75 export PKG_INSTALL_ROOT 76 77 # set lib path 78 LD_LIBRARY_PATH=/usr/lib:/usr/lib 79 export LD_LIBRARY_PATH 80 81 # set dscfg 82 DSCFG="/usr/sbin/dscfg" 83 export DSCFG 84 85 # set parser config location 86 PCONFIG="/etc/dscfg_format" 87 export PCONFIG 88 89 # set local dscfg location 90 export LOCAL_DSCFG="/etc/dscfg_local" 91 92 # set cluster dscfg reference file 93 export CLUSTER_REF="/etc/dscfg_cluster" 94 95 # a service that has a dependency on us 96 FS_LOCAL_SVC="svc:/system/filesystem/local" 97 98 NODELIST="/tmp/nodelist" 99 DSCFGLOCKDCF="/etc/dscfg_lockdb" 100 DSCFG_DEPEND_NOCHK="/tmp/.dscfgadm_pid" 101 102 # SMF defines 103 MANIFEST_PATH=/lib/svc/manifest/system 104 105 # SMF services (enable and disable) 106 SMF_ENABLE="nws_scm nws_sv nws_ii nws_rdc nws_rdcsyncd" 107 SMF_DISABLE="nws_rdcsyncd nws_rdc nws_ii nws_sv nws_scm" 108 109 # state of each service 110 nws_scm_enabled=0 111 nws_sv_enabled=0 112 nws_ii_enabled=0 113 nws_rdc_enabled=0 114 nws_rdcsyncd_enabled=0 115 116 # set path 117 PATH=/usr/bin:/usr/sbin:/sbin/sh 118 export PATH 119 120 # set architecture 121 ARCH=`uname -p` 122 export ARCH 123 OS_MINOR=`uname -r | cut -d '.' -f2` 124 125 # number of sectors required for database 126 # 1024*1024*5.5/512 127 REQUIRED=11264 128 129 # must set here, else seen as null in MAIN 130 VALID_DB_ENTERED=0 131 132 NO_ARGS=0 133 134 # for debugging 135 xopt= 136 137 # set lengthy message here 138 CLUST_LOC_MESS="The current location is invalid for a Sun StorageTek \ 139 Data Services configuration database. Once a valid location is \ 140 entered (raw slice on \"did\" device), you may upgrade the existing \ 141 database to this new location - following the procedure outlined \ 142 in the Installation and Configuration Guide." 143 144 ########################## SET GLOBAL VARIABLES ###################### 145 146 147 ########################## ERROR #################################### 148 149 # called with optional error msg $1 150 # prints basic guidelines for configuration of the database location 151 error() 152 { 153 $xopt 154 155 echo >&2 156 echo "INSTALLATION ERROR" >&2 157 echo "Error: $1" >&2 158 echo >&2 159 in_cluster 160 161 if [ $? -eq 1 ]; then 162 echo "GENERAL INSTALLATION RULES:" >&2 163 echo "\tBecause you are installing on a cluster," >&2 164 echo "\tthe database must be located on a raw slice of a did device.">&2 165 echo "\t e.g. /dev/did/rdsk/d17s1" >&2 166 fi 167 # let? 168 MB=`expr $REQUIRED / 2 / 1024` 169 echo "\t$REQUIRED sectors ($MB MBs) are required for the database." >&2 170 } 171 172 ########################## ERROR #################################### 173 174 ########################## ALL LOCATION TESTS ######################## 175 176 # sets numerous environment variables describing the state of the system 177 get_system_state() 178 { 179 $xopt 180 181 valid_local_dscfg_exists 182 VALID_LOCAL_DB=$? 183 OLD_VALID_LOCAL_DB=$VALID_LOCAL_DB 184 185 in_cluster 186 IN_CLUSTER=$? 187 188 cluster_configured 189 CLUSTER_CONFIGURED=$? 190 191 if [ $IN_CLUSTER = 1 ]; then 192 valid_cluster_dscfg_exists 193 VALID_CLUSTER_DB=$? 194 OLD_VALID_CLUSTER_DB=$VALID_CLUSTER_DB 195 else 196 VALID_CLUSTER_DB=0 197 fi 198 } 199 200 # Checks if in cluster 201 # returns 1 if in cluster, else 0 202 # 203 in_cluster() 204 { 205 $xopt 206 207 if [ -x /usr/sbin/clinfo ]; then 208 clinfo 209 if [ $? -eq 0 ]; then 210 return 1 211 else 212 return 0 213 fi 214 else 215 return 0 216 fi 217 } 218 219 # checks if a system is configured as a cluster 220 # returns 1 if configured as a cluster, 0 if not 221 # 222 cluster_configured() 223 { 224 $xopt 225 226 if [ -f /etc/cluster/nodeid ]; then 227 return 1 228 else 229 return 0 230 fi 231 } 232 233 # Check the list of Sun Cluster device groups known in the dscfg, determing 234 # if they are currently enabled on this Sun Cluster node. If so, fail allowing 235 # the system administator to scswitch them elsewhere. 236 # 237 check_device_groups() 238 { 239 $xopt 240 241 if [ $VALID_CLUSTER_DB == 1 ]; then 242 DEVICE_GROUPS=`$DSCFG -s $FILE_LOC -l 2>/dev/null | \ 243 grep "^dsvol:" | cut -d' ' -f3 | sort | uniq | xargs` 244 for x in $DEVICE_GROUPS 245 do 246 $DSCFG -D $x 2>/dev/null 247 if [ $? -eq 1 ] 248 then 249 IN_USE="$IN_USE $x" 250 fi 251 done 252 253 if [ -n "$IN_USE" ] 254 then 255 print "The following Sun Cluster device groups are in use " 256 print "by Availability Suite on this node." 257 print "" 258 print "$IN_USE" 259 print "" 260 print "'scswitch' them to another Sun Cluster node before " 261 print "attempting to disable any data services." 262 return 1 263 else 264 return 0 265 fi 266 fi 267 268 return 0 269 } 270 271 # checks to see if this is a char device in the 272 # /dev/did/rdsk directory returns 1 if so. 273 # 274 is_did_device() 275 { 276 $xopt 277 278 DID=`echo $1 | awk -F/ '{print $3}'` 279 RDSK=`echo $1 | awk -F/ '{print $4}'` 280 281 if [ "did" = $DID -a "rdsk" = $RDSK -a -c $1 ]; then 282 return 1 283 else 284 return 0 285 fi 286 } 287 288 # 289 # checks size of area for db location 290 # 291 check_size() 292 { 293 $xopt 294 295 # if in cluster look for d*s* 296 SLICE=`echo $1 | sed -n 's/.*d.*s\(.*\)/\1/p'` 297 298 SECTORS=`prtvtoc $1 | tr -s ' '| grep "^ $SLICE " | awk '{print $5}'` 299 300 if [ -z "$SECTORS" ]; then 301 echo "SLICE at $1 not found on this device" 302 return 0 303 fi 304 305 # if required size is greater than space available, then fail 306 if [ $REQUIRED -gt $SECTORS ]; then 307 return 0 308 else 309 return 1 310 fi 311 } 312 313 # looks in dscfg_cluster reference file. if a location is configured, 314 # tests to see if it is a valid database. if so, returns 1 315 # 316 valid_cluster_dscfg_exists() 317 { 318 $xopt 319 320 if [ -s $CLUSTER_REF ]; then 321 FILE_LOC=`head -1 $CLUSTER_REF` 322 contains_data $FILE_LOC 323 return $? 324 else 325 return 0 326 fi 327 } 328 329 330 # checks for the existence of dscfg_local database, and if it exists, 331 # tests to see if it is a valid database. if so, returns 1 332 # 333 valid_local_dscfg_exists() 334 { 335 $xopt 336 337 if [ -s $LOCAL_DSCFG ]; then 338 contains_data $LOCAL_DSCFG 339 return $? 340 else 341 return 0 342 fi 343 } 344 345 # used to test if a valid DS config database exists on machine already 346 # MAGIC_STRING is the top line in the config used in v3.1 & v3.2 347 # 348 contains_data() 349 { 350 $xopt 351 352 # dscfg distinct strings, varies on the architecture 353 if [ $ARCH = "sparc" ] 354 then 355 MAGIC_STRING="MAGI" 356 elif [ $ARCH = "i386" ] 357 then 358 MAGIC_STRING="IGAM" 359 fi 360 361 # Create a PID unique temporary file 362 TMP_FILE=/tmp/$$ 363 364 # Write the first or 16th block (skipping over VTOC) to 365 # the TMP_FILE, then scan for the presence of the "MAGI" 366 # 367 for offset in 0 16 368 do 369 if [ ! -z "$1" ]; then 370 dd if=$1 of=$TMP_FILE count=1 iseek=$offset 2>/dev/null 371 FILECONTENTS=`strings $TMP_FILE | head -1 2>/dev/null` 372 if [ `echo $FILECONTENTS | grep -c "$MAGIC_STRING"` -gt 0 ]; then 373 rm $TMP_FILE 374 return 1 375 fi 376 fi 377 done 378 379 rm $TMP_FILE 380 return 0 381 } 382 383 ########################## ALL LOCATION TESTS ######################## 384 385 386 ########################## MAIN FUNCTIONS ############################ 387 388 # since location already has been set, asks what to do now? keeping 389 # it still checks the size (since an upgrade from 3.0 may still be 390 # occuring) and also checks if was an old cluster config on disallowed 391 # /dev/did/dsk directory 392 # 393 # returns: 394 # 0 if cluster location is invalid or the user does not want to keep it 395 # 1 if the location is valid and the user wants to keep it. 396 # 397 keep_it() 398 { 399 $xopt 400 401 NOTE="\nThe Sun StorageTek Data Services database configuration" 402 NOTE="$NOTE location has already been set." 403 echo $NOTE 404 405 echo "\nCurrent location: $PKG_INSTALL_ROOT$FILE_LOC" 406 407 QUEST="Would you like to preserve the existing configuration" 408 QUEST="$QUEST information at its current location? " 409 410 ANS=`ckyorn -Qd n -p "$QUEST"` 411 412 case $ANS in 413 y|Y|yes|YES|Yes) 414 #Since the user has said "yes I want to keep this current one" 415 #it may actually be a 3.x database, which only required 4.5mb 416 #space, so now will check that there is room to grow another 1mb" 417 check_location $FILE_LOC 418 if [ $? = 0 ]; then 419 error "$CLUST_LOC_MESS" 420 return 0 421 else 422 OLD_FILE_LOC=$FILE_LOC 423 FILE_LOC=$NULL 424 return 1 425 fi 426 ;; 427 *) 428 return 0 429 ;; 430 esac 431 } 432 433 # 434 # asks if user wants to keep existing db information, overwrite with 435 # a new db, or view the contents, and be asked again... 436 # returns: 437 # 0 if old location is bad 438 # 1 if old location is good 439 # 440 preserve_overwrite_maybe() 441 { 442 $xopt 443 444 echo "\nIt appears a valid database configuration exists here already." 445 446 while true 447 do 448 SAFE_LOC=$FILE_LOC 449 450 echo "\nWould you like to preserve this information and continue?" 451 echo "\ty - preserve current configuration" 452 echo "\tn - overwrite with new configuration" 453 echo "\tmaybe - view contents of current configuration" 454 455 ANS=`ckkeywd -Q y n maybe` 456 case $ANS in 457 y) 458 check_location $FILE_LOC 459 if [ $? = 0 ]; then 460 error "$CLUST_LOC_MESS" 461 return 0 462 else 463 $DSCFG -s "$FILE_LOC" -C $CTAG_NULL >/dev/null 2>&1 464 OLD_FILE_LOC=$FILE_LOC 465 FILE_LOC=$NULL 466 return 1 467 fi 468 ;; 469 n) 470 check_location $FILE_LOC 471 if [ $? = 0 ]; then 472 error "$CLUST_LOC_MESS" 473 return 0 474 else 475 return 1 476 fi 477 ;; 478 479 maybe) 480 # print contents of this db config. 481 echo "\nContents of database configuration found at $SAFE_LOC are:" 482 $DSCFG -l -s "$FILE_LOC" | more 483 FILE_LOC=$SAFE_LOC 484 continue 485 ;; 486 esac 487 done 488 } 489 490 # gets location from user 491 # 492 get_location() 493 { 494 $xopt 495 496 #Checks for absolute path name, and if file name and file doesn't 497 #exist, creates it. 498 echo "\n\n----------ENTER DATABASE CONFIGURATION LOCATION-----------------" 499 echo "Note: Please ensure this location meets all requirements specified" 500 echo "in the Availability Suite Installation Guide." 501 502 FILE_LOC=`ckpath -artwQ -p "Enter location:"` 503 if [ $? = 1 ] 504 then 505 exit 1 506 fi 507 508 # allow non-root user to access for least privileges 509 chmod 666 $FILE_LOC 510 } 511 512 513 # 514 # tests for proper config 515 # 516 # returns: 517 # 0 if bad location 518 # 1 if good location 519 # 520 check_location() 521 { 522 $xopt 523 524 # set to FILE_LOC 525 LOCATION=$1 526 527 did_clust_msg="You are in cluster and $LOCATION is not valid DID device" 528 529 # Set "actual file location" variable here to equal file location 530 # entered by user because getting here means contains_data was already 531 # successfully called before and now the two can equal each other for 532 # future testing. 533 534 SAFE_LOC=$FILE_LOC 535 536 if [ $IN_CLUSTER = 1 -o $CLUSTER_CONFIGURED = 1 ]; then 537 if [ -b "$LOCATION" ] || [ -c "$LOCATION" ]; then 538 is_did_device $LOCATION 539 if [ $? = 0 ]; then 540 error "$did_clust_msg" 541 return 0 542 fi 543 else 544 error "$did_clust_msg" 545 return 0 546 fi 547 else 548 echo "Location may not be changed in a non Sun Cluster OE." 2>&1 549 return 0 550 fi 551 552 check_size $LOCATION 553 554 if [ $? != 1 ]; then 555 error "$LOCATION does not meet minimum space requirement." 556 return 0 557 else 558 return 1 559 fi 560 } 561 562 # 563 # Notifies the user that the SMF services are online, 564 # and gives him the option to disable the services before proceeding. If 565 # the services are not disabled, the program cannot proceed with setting 566 # a new dscfg location. 567 # 568 ask_to_disable() 569 { 570 $xopt 571 572 echo "\ 573 \nYour services must be disabled before a new configuration location is set.\n" 574 575 QUEST="Would you like to disable the services now and continue with the" 576 QUEST="$QUEST Availability Suite setup? " 577 578 ANS=`ckyorn -Qd n -p "$QUEST"` 579 580 case $ANS 581 in y|Y|yes|YES|Yes) 582 return 1 583 ;; 584 *) 585 return 0 586 ;; 587 esac 588 } 589 590 # 591 # Asks the user if he would like to enable the services now. If so, 592 # import them (if necessary) and enable them. 593 # 594 ask_to_enable() 595 { 596 $xopt 597 598 echo "\ 599 \nIf you would like to start using the Availability Suite immediately, you may 600 start the SMF services now. You may also choose to start the services later 601 using the $PROG -e command." 602 603 QUEST="Would you like to start the services now? " 604 605 ANS=`ckyorn -Qd n -p "$QUEST"` 606 607 case $ANS 608 in y|Y|yes|YES|Yes) 609 return 1 610 ;; 611 *) 612 return 0 613 ;; 614 esac 615 } 616 617 # 618 # display information about the system 619 # 620 display_info() 621 { 622 $xopt 623 624 typeset grp_error_flg=0 625 typeset -L15 svc state en SVC="SERVICE" STATE="STATE" EN="ENABLED" 626 echo "$SVC\t$STATE\t$EN" 627 628 for i in $SMF_ENABLE 629 do 630 is_imported $i 631 if [ $? = 1 ] 632 then 633 state=`svcprop -c -p restarter/state \ 634 svc:/system/${i}:default` 635 en=`svcprop -c -p general/enabled \ 636 svc:/system/${i}:default` 637 check_fs_local_grouping $i 638 if [ $? -ne 0 ] 639 then 640 svc="${i}***" 641 grp_error_flg=$((grp_error_flg + 1)) 642 else 643 svc=$i 644 fi 645 646 echo "$svc\t$state\t$en" 647 fi 648 done 649 650 print "\nAvailability Suite Configuration:" 651 printf "Local configuration database: " 652 if [ $VALID_LOCAL_DB = 1 ] 653 then 654 print "valid" 655 else 656 print "invalid" 657 fi 658 659 if [ $CLUSTER_CONFIGURED = 1 ] 660 then 661 printf "cluster configuration database: " 662 if [ $VALID_CLUSTER_DB = 1 ] 663 then 664 print "valid" 665 print "cluster configuration location: ${FILE_LOC}" 666 else 667 print "invalid" 668 fi 669 fi 670 671 if [ $grp_error_flg -gt 0 ] 672 then 673 typeset p 674 typeset p_has 675 if [ $grp_error_flg -gt 1 ] 676 then 677 p="s" 678 p_has="have" 679 else 680 p="" 681 p_has="has" 682 fi 683 684 printf "\n*** Warning: The service$p above $p_has an incorrect " 685 printf "dependency. To repair the\n" 686 printf "problem, run \"dscfgadm\".\n" 687 fi 688 } 689 690 # 691 # initialize the local configuration database (only called if none exists) 692 # returns 0 if successful, 1 if failed 693 # 694 initialize_local_db() 695 { 696 $xopt 697 698 echo "Could not find a valid local configuration database." 699 echo "Initializing local configuration database..." 700 echo y | ${DSCFG} -i > /dev/null 2>&1 701 ${DSCFG} -i -p ${PCONFIG} > /dev/null 2>&1 702 703 # Make sure the new location is initialized properly 704 valid_local_dscfg_exists 705 VALID_LOCAL_DB=$? 706 if [ $VALID_LOCAL_DB != 1 ] 707 then 708 echo "Unable to initialize local configuration database" >&2 709 return 1 710 else 711 echo "Successfully initialized local configuration database" 712 fi 713 714 return 0 715 } 716 717 # 718 # initialize the cluster configuration database, if necessary 719 # returns 0 if successful, 1 if failed 720 # 721 initialize_cluster_db() 722 { 723 $xopt 724 725 if [ ! -n "$FILE_LOC" ] 726 then 727 return 0 728 fi 729 730 echo "Initializing cluster configuration database..." 731 ${DSCFG} -s ${FILE_LOC} -C $CTAG_NULL > /dev/null 2>&1 732 echo y | ${DSCFG} -i -C $CTAG_NULL > /dev/null 2>&1 733 ${DSCFG} -i -p ${PCONFIG} -C $CTAG_NULL > /dev/null 2>&1 734 735 # make sure the cluster db is valid now 736 valid_cluster_dscfg_exists 737 VALID_CLUSTER_DB=$? 738 if [ $VALID_CLUSTER_DB != 1 ] 739 then 740 echo "Unable to initialize cluster configuration database" >&2 741 return 1 742 else 743 echo "Successfully initialized cluster configuration database" 744 fi 745 746 return 0 747 748 } 749 750 # 751 # prompt the user for a config location and set AVS to use that location 752 # 753 set_cluster_config() 754 { 755 756 $xopt 757 758 REPEAT=0 759 while [ $REPEAT -eq 0 ]; do 760 # See if user has entered location already, and it was an existing 761 # db. Retruns FILE_LOC value 762 if [ $VALID_DB_ENTERED = 1 ]; then 763 764 # reset 765 VALID_DB_ENTERED=0 766 preserve_overwrite_maybe 767 768 # if 1, location passes, and FILE_LOC being passed to end, else 769 # set VALID_CLUSTER_DB to 0 since the "valid one" isn't valid anymore 770 # (bad size, etc) thereby when looping go straight to get_location 771 if [ $? = 1 ]; then 772 REPEAT=1 773 continue 774 else 775 VALID_CLUSTER_DB=0 776 continue 777 fi 778 fi 779 780 # if 1, then valid db exists, now see what user wants to do 781 if [ $VALID_CLUSTER_DB = 1 ]; then 782 SAFE_LOC=$FILE_LOC 783 keep_it 784 785 # if 0, then user can't or won't keep location. set PROMPT 786 # so we will get new location from user. 787 if [ $? = 0 ]; then 788 PROMPT=0 789 else 790 PROMPT=1 791 fi 792 fi 793 794 # if either are 0, then user wants or needs new db as outlined in 795 # earlier comments 796 if [ $VALID_CLUSTER_DB = 0 ] || [ $PROMPT = 0 ]; then 797 # 798 # We cannot proceed if the services are running. Give the user 799 # a chance to stop the services. If he chooses not to, bail. 800 # 801 check_enabled 802 if [ $? = 1 ] 803 then 804 show_enabled 805 ask_to_disable 806 if [ $? = 0 ] 807 then 808 echo "A new configuration location was not set." 809 exit 1 810 else 811 disable_services 812 if [ $? != 0 ] 813 then 814 exit 1 815 fi 816 fi 817 818 fi 819 820 get_location 821 contains_data $FILE_LOC 822 823 # if 1, then user entered an existsing db location, loop 824 # back to ask what to do with it 825 if [ $? = 1 ]; then 826 VALID_DB_ENTERED=1 827 continue 828 else 829 check_location $FILE_LOC 830 831 # if 0, that means location has failed, loop and 832 # get_location again 833 if [ $? = 0 ]; then 834 VALID_CLUSTER_DB=0 835 continue 836 fi 837 # entered location passes tests 838 REPEAT=1 839 continue 840 fi 841 else 842 # user wants to leave location where and how it is 843 # FILE_LOC being passed all the way to end 844 REPEAT=1 845 continue 846 fi 847 done 848 849 } 850 851 ########################## MAIN FUNCTIONS ############################ 852 853 ######################## SMF HELPER FUNCTIONS ######################## 854 # 855 # check if any SMF service is online (enabled) 856 # 857 check_enabled() 858 { 859 $xopt 860 typeset ret=0 861 typeset svc 862 863 for svc in $SMF_ENABLE 864 do 865 is_enabled $svc 866 eval ${svc}_enabled=$? 867 ret=$((ret | ${svc}_enabled)) 868 done 869 870 return $ret 871 } 872 873 # 874 # Display which services are enabled. (Must be called after check_enabled) 875 # 876 show_enabled() 877 { 878 $xopt 879 typeset svc 880 881 echo "\nThe following Availability Suite services are enabled:" 882 883 for svc in $SMF_ENABLE 884 do 885 if (( ${svc}_enabled == 1 )) 886 then 887 printf "$svc " 888 fi 889 done 890 891 echo "" 892 } 893 894 895 # 896 # check if the given SMF service is online (enabled) 897 # 898 # $1: service name to check for 899 # 900 is_enabled() 901 { 902 $xopt 903 typeset en 904 905 is_imported $1 906 if [ $? = 1 ] 907 then 908 en=`svcprop -c -p general/enabled svc:/system/${1}:default` 909 if [ $en = "true" ] 910 then 911 return 1 912 fi 913 fi 914 915 return 0 916 917 } 918 919 # 920 # If necessary, flag no dependency check 921 # 922 no_depend_check() 923 { 924 $xopt 925 typeset pid 926 typeset msg=0 927 928 if [ $OS_MINOR -lt 11 ] 929 then 930 if [ -f $DSCFG_DEPEND_NOCHK ] 931 then 932 pid=`cat $DSCFG_DEPEND_NOCHK` 933 echo "Another dscfgadm disable is in progress." 934 echo "Waiting for pid: $pid to terminate..." 935 936 while [ -f $DSCFG_DEPEND_NOCHK ] 937 do 938 if (( msg && (msg % 6 == 0))) 939 then 940 printf "\nAnother dscfgadm disable " 941 printf "(pid: $pid) still appears to " 942 printf " be in progress.\n" 943 printf "If this is not the case, you " 944 printf "may remove " 945 printf "$DSCFG_DEPEND_NOCHK.\n" 946 fi 947 sleep 5 948 msg=$((msg + 1)) 949 done 950 fi 951 952 touch $DSCFG_DEPEND_NOCHK 953 echo $$ >> $DSCFG_DEPEND_NOCHK 954 fi 955 } 956 957 # 958 # If necessary, remove the no dependency check flag 959 # 960 rm_no_depend_check() 961 { 962 $xopt 963 if [ $OS_MINOR -lt 11 ] 964 then 965 rm -f $DSCFG_DEPEND_NOCHK 966 fi 967 } 968 969 # 970 # set the filesystem/local dependency type and refresh 971 # 972 # $1: service name 973 # $2: either "require_all" or "optional_all" 974 # 975 set_fs_local_grouping() 976 { 977 $xopt 978 typeset svc=$1 979 typeset dep_group=$2 980 981 # set proper dependency type for fs-local 982 if [ $svc != nws_rdcsyncd ]; then 983 svccfg -s $FS_LOCAL_SVC setprop \ 984 ${svc}-local-fs/grouping=$dep_group 985 if [ $? -ne 0 ] 986 then 987 printf "command failed: svccfg -s $FS_LOCAL_SVC " 988 printf "setprop ${svc}-local-fs/grouping=$dep_group " 989 printf ">&2\n" 990 return 1 991 fi 992 993 # we need local-fs to know about the new grouping attributes 994 svcadm refresh ${FS_LOCAL_SVC}:default 995 if [ $? -ne 0 ] 996 then 997 print "Failed to refresh ${FS_LOCAL_SVC} >&2" 998 return 1 999 fi 1000 fi 1001 1002 return 0 1003 } 1004 1005 # 1006 # check if the grouping dependency type for filesystem/local is correct 1007 # 1008 # input: 1009 # $1: service name 1010 # 1011 # returns: 1012 # 0 if the setting is correct 1013 # 1 if the setting is incorrect 1014 # outputs: sets CORRECT_GROUPING with the value of what the grouping should be. 1015 # 1016 check_fs_local_grouping() 1017 { 1018 $xopt 1019 typeset svc=$1 1020 typeset cur_grouping 1021 1022 if [ $svc = nws_rdcsyncd ] 1023 then 1024 return 0 1025 fi 1026 1027 # If it's not imported, we just return success, since we don't want 1028 # further processing 1029 is_imported $svc 1030 if [ $? = 0 ] 1031 then 1032 return 0 1033 fi 1034 1035 # get the current grouping value from the repository 1036 cur_grouping=`svcprop -c -p ${svc}-local-fs/grouping $FS_LOCAL_SVC` 1037 1038 # Figure out what the grouping should be (based on enabled status) 1039 is_enabled $svc 1040 if [ $? = 1 ] 1041 then 1042 CORRECT_GROUPING="require_all" 1043 else 1044 CORRECT_GROUPING="optional_all" 1045 fi 1046 1047 if [ "$cur_grouping" != "$CORRECT_GROUPING" ] 1048 then 1049 # grouping is incorrect 1050 return 1 1051 else 1052 # grouping is just fine 1053 return 0 1054 fi 1055 } 1056 1057 # 1058 # enable/disable the given SMF service. Also, update the filesystem-local 1059 # dependency, if appropriate. 1060 # 1061 # $1: service name to check for 1062 # $2: "enable" or "disable" 1063 # 1064 svc_operation() 1065 { 1066 $xopt 1067 typeset svc=$1 1068 typeset command=$2 1069 typeset enable_state 1070 typeset dep_group 1071 1072 # If disabling, then enable_state better be true, and we are 1073 # transitioning to "option_all" grouping 1074 if [ $command = "disable" ] 1075 then 1076 enable_state=1 1077 dep_group="optional_all" 1078 1079 # If enabling, then enable_state better be false, and we are 1080 # transitioning to "require_all" grouping 1081 elif [ $command = "enable" ] 1082 then 1083 enable_state=0 1084 dep_group="require_all" 1085 else 1086 echo "invalid command: $command" >&2 1087 fi 1088 1089 is_imported $svc 1090 if [ $? = 1 ] 1091 then 1092 is_enabled $svc 1093 if [ $? = $enable_state ] 1094 then 1095 if [ $enable_state -eq 1 ] 1096 then 1097 # we're doing a disable--remove hard dependency 1098 set_fs_local_grouping $svc $dep_group 1099 if [ $? -ne 0 ] 1100 then 1101 return 1 1102 fi 1103 fi 1104 1105 svcadm $command -s svc:/system/$svc 1106 if [ $? != 0 ] 1107 then 1108 echo "$svc failed to $command" >&2 1109 return 1 1110 fi 1111 1112 if [ $enable_state -eq 0 ] 1113 then 1114 # we just did an enable--create hard dependency 1115 set_fs_local_grouping $svc $dep_group 1116 if [ $? -ne 0 ] 1117 then 1118 return 1 1119 fi 1120 fi 1121 1122 else 1123 echo "$svc service already ${command}d... skipping" 1124 fi 1125 fi 1126 1127 return 0 1128 } 1129 1130 # 1131 # This chart summarizes the behavior of the -r and -p sub-options for the 1132 # -e and -d options. 1133 # There are 5 possible states, and 5 transitions out of each state. 1134 # 1135 # states: (vertical axis) 1136 # ------- 1137 # 0: no services enabled 1138 # C: one or both core services enabled (illegal state) 1139 # R: both core services and RM services enabled 1140 # P: both core services and PITC service enabled 1141 # A: all services enabled 1142 # 1143 # transitions: (horizontal axis) 1144 # ------------ 1145 # +/-a: enable/disable, respectively, with neither -r nor -p 1146 # +/-r: enable/disable, respectively, with -r flag 1147 # +p: enable with -p flag 1148 # 1149 # The result of the function is the next state after the action has been 1150 # successfully performed. 1151 # 1152 # +a | -a | +r | -r | +p | 1153 # ++----+----+----+----+----+ 1154 # ++----+----+----+----+----+ 1155 # 0 || A | 0* | R | 0* | P | 1156 # --++----+----+----+----+----+ 1157 # C || A* | 0* | R | 0 | P | 1158 # --++----+----+----+----+----+ 1159 # R || A* | 0* | R* | 0 | A | 1160 # --++----+----+----+----+----+ 1161 # P || A* | 0* | A* | P* | P* | 1162 # --++----+----+----+----+----+ 1163 # A || A* | 0 | A* | P | A* | 1164 # --++----+----+----+----+----+ 1165 # 1166 # *: warning message is displayed, stating that a service is already 1167 # enabled/disabled. 1168 # 1169 1170 # enable the SMF services needed for the Availability Suite 1171 # 1172 enable_services() 1173 { 1174 $xopt 1175 typeset svc 1176 1177 # first, import them if they have not yet been imported 1178 import_services 1179 1180 # if neither r_flag nor p_flag is set, enable all services 1181 if (( (r_flag | p_flag) == 0 )) 1182 then 1183 for svc in $SMF_ENABLE 1184 do 1185 if ! svc_operation $svc enable 1186 then 1187 return 1 1188 fi 1189 done 1190 else 1191 # figure out which services are enabled 1192 check_enabled 1193 1194 # First, make sure both core services are enabled 1195 for svc in nws_scm nws_sv 1196 do 1197 if (( ${svc}_enabled == 0 )) && \ 1198 ! svc_operation $svc enable 1199 then 1200 return 1 1201 fi 1202 done 1203 1204 if ((p_flag)) 1205 then 1206 if ! svc_operation nws_ii enable 1207 then 1208 return 1 1209 fi 1210 fi 1211 1212 if ((r_flag)) 1213 then 1214 for svc in nws_rdc nws_rdcsyncd 1215 do 1216 if ! svc_operation $svc enable 1217 then 1218 return 1 1219 fi 1220 done 1221 fi 1222 1223 fi 1224 1225 return 0 1226 } 1227 1228 # 1229 # disable the SMF services needed for the Availability Suite 1230 # 1231 disable_services() 1232 { 1233 $xopt 1234 typeset svc 1235 1236 check_device_groups 1237 if [ $? == 1 ] 1238 then 1239 return 1 1240 fi 1241 1242 # This flags the shutdown scripts to not check to make sure the 1243 # services' dependents have been disabled. The flag must be removed 1244 # before returning from this function. 1245 no_depend_check 1246 1247 # NB: p_flag is not allowed for disables. II should not be 1248 # disabled if sndr is enabled. If rdc is not enabled, disabling just 1249 # II is equivalent to disabling all the remaining services. 1250 1251 # If no flags passed in, just disable everything 1252 if (( r_flag == 0 )) 1253 then 1254 for svc in $SMF_DISABLE 1255 do 1256 if ! svc_operation $svc disable 1257 then 1258 rm_no_depend_check 1259 return 1 1260 fi 1261 done 1262 1263 # Now that we've disable the services, lets unload them 1264 # from the Solaris kernel 1265 # 1266 modinfo | grep '(nws:' | grep -v "kRPC Stub" | sort -r | cut -d' ' -f1 | xargs -l modunload -i 2>/dev/null 1267 modinfo | grep '(nws:' | grep -v "kRPC Stub" | sort -r | cut -d' ' -f1 | xargs -l modunload -i 2>/dev/null 1268 else 1269 # we're disabling just rdc. If II is not already enabled, 1270 # we disable core services, as well. 1271 1272 # figure out which services are enabled 1273 check_enabled 1274 1275 for svc in nws_rdcsyncd nws_rdc 1276 do 1277 if ! svc_operation $svc disable 1278 then 1279 rm_no_depend_check 1280 return 1 1281 fi 1282 done 1283 1284 if (( nws_ii_enabled == 0 )) 1285 then 1286 for svc in nws_sv nws_scm 1287 do 1288 if ((${svc}_enabled)) && \ 1289 ! svc_operation $svc disable 1290 then 1291 rm_no_depend_check 1292 return 1 1293 fi 1294 done 1295 fi 1296 fi 1297 1298 1299 rm_no_depend_check 1300 return 0 1301 } 1302 1303 # 1304 # check if a service has been imported into the repository 1305 # $1: service to check 1306 # returns 1 if it is imported, 0 if it is not 1307 # 1308 is_imported() 1309 { 1310 $xopt 1311 1312 typeset svc=$1 1313 1314 svcprop -q -p general/entity_stability svc:/system/${svc} 1315 if [ $? = 1 ] 1316 then 1317 return 0 1318 else 1319 return 1 1320 fi 1321 } 1322 1323 # 1324 # import the SMF services into the repository, if necessary 1325 # 1326 import_services() 1327 { 1328 $xopt 1329 typeset svc 1330 1331 for svc in $SMF_ENABLE 1332 do 1333 import_service $svc 1334 done 1335 } 1336 1337 # 1338 # check to see if an SMF service is in the repository. If it is not, 1339 # import it in. 1340 # $1: name of service to import 1341 # 1342 import_service() 1343 { 1344 $xopt 1345 typeset svc=$1 1346 1347 is_imported $svc 1348 if [ $? = 0 ] 1349 then 1350 if [ -f $PKG_INSTALL_ROOT/$MANIFEST_PATH/$svc.xml ] 1351 then 1352 svccfg import $PKG_INSTALL_ROOT/$MANIFEST_PATH/$svc.xml 1353 1354 if [ $OS_MINOR -lt 11 ] 1355 then 1356 # workaround for 6221374--let local-fs know 1357 # that it depends on us. 1358 svcadm refresh ${FS_LOCAL_SVC}:default 1359 fi 1360 fi 1361 fi 1362 } 1363 1364 1365 ########################## MAIN ###################################### 1366 1367 # getopt processing 1368 enable=0 1369 disable=0 1370 set_location=0 1371 get_info=0 1372 r_flag=0 1373 p_flag=0 1374 while getopts "xedsirp" opt 2>/dev/null 1375 do 1376 case $opt in 1377 \?) 1378 help 1379 ;; 1380 e) 1381 enable=1 1382 ;; 1383 d) 1384 disable=1 1385 ;; 1386 x) 1387 xopt="set -x" 1388 set -x 1389 ;; 1390 s) 1391 set_location=1 1392 ;; 1393 i) 1394 get_info=1 1395 ;; 1396 r) 1397 r_flag=1 1398 ;; 1399 p) 1400 p_flag=1 1401 ;; 1402 esac 1403 done 1404 1405 # at most one option (besides -x) may be specified at a time 1406 options_count=$((enable + disable + set_location + get_info)) 1407 if [ $options_count -gt 1 ] 1408 then 1409 help 1410 elif [ $options_count = 0 ] 1411 then 1412 NO_ARGS=1 1413 fi 1414 1415 if (( ((r_flag + p_flag) > 0) && ((enable | disable) == 0) )) 1416 then 1417 echo "-r and -p options may only be used with -d or -e options" >&2 1418 return 1 1419 elif (( p_flag && disable )) 1420 then 1421 echo "The -p option may not be used with the -d option" >&2 1422 return 1 1423 fi 1424 1425 1426 1427 # set all the system information variables 1428 get_system_state 1429 1430 # if we're enabling, we need to make sure we have a valid dscfg out there. 1431 if [ $enable = 1 -a $VALID_LOCAL_DB != 1 ] 1432 then 1433 echo "Cannot find a valid configuration database" >&2 1434 return 1 1435 fi 1436 1437 if [ $NO_ARGS = 1 ] 1438 then 1439 1440 # only initialize the database if necessary 1441 if [ $VALID_LOCAL_DB = 1 ]; then 1442 echo "Local configuration database is already initialized." 1443 else 1444 initialize_local_db 1445 if [ $? != 0 ]; then 1446 return 1 1447 fi 1448 fi 1449 1450 if [ $CLUSTER_CONFIGURED = 1 ] 1451 then 1452 if [ $VALID_CLUSTER_DB = 1 ]; then 1453 printf "Cluster configuration database is already " 1454 printf "initialized.\n" 1455 else 1456 # ask the user for a cluster database location 1457 set_cluster_config 1458 1459 # initialize the new db 1460 initialize_cluster_db 1461 if [ $? != 0 ]; then 1462 return 1 1463 fi 1464 fi 1465 1466 fi 1467 1468 # make sure that the local filesystem dependency type is correct 1469 for svc in $SMF_ENABLE 1470 do 1471 check_fs_local_grouping $svc 1472 if [ $? -ne 0 ] 1473 then 1474 # NOTE: check_fs_local_grouping sets CORRECT_GROUPING 1475 # To avoid this issue in the future, always administer 1476 # the services using dscfgadm. 1477 printf "Warning: Fixing dependency for $svc.\n" 1478 set_fs_local_grouping $svc $CORRECT_GROUPING 1479 if [ $? -ne 0 ] 1480 then 1481 return 1 1482 fi 1483 fi 1484 done 1485 1486 # give the user the chance to startup AVS services, if not started 1487 check_enabled 1488 if [ $? = 1 ]; then 1489 if [ $OLD_VALID_LOCAL_DB = 0 ]; then 1490 printf "WARNING: AVS services are running on a system " 1491 printf "which had no valid configuration\ndatabase\n" 1492 fi 1493 show_enabled 1494 else 1495 ask_to_enable 1496 if [ $? = 1 ]; then 1497 enable_services 1498 if [ $? != 0 ] 1499 then 1500 return 1 1501 fi 1502 fi 1503 fi 1504 1505 elif [ $enable = 1 ] 1506 then 1507 enable_services 1508 if [ $? != 0 ] 1509 then 1510 return 1 1511 fi 1512 1513 elif [ $disable = 1 ] 1514 then 1515 disable_services 1516 if [ $? != 0 ] 1517 then 1518 return 1 1519 fi 1520 1521 elif [ $get_info = 1 ] 1522 then 1523 display_info 1524 1525 elif [ $set_location = 1 ] 1526 then 1527 if [ $CLUSTER_CONFIGURED = 1 ] 1528 then 1529 # ask the user for a cluster database location 1530 set_cluster_config 1531 1532 # initialize the new db 1533 initialize_cluster_db 1534 if [ $? != 0 ]; then 1535 return 1 1536 fi 1537 else 1538 echo "$PROG -s is only available on Sun Cluster OE systems" >&2 1539 return 1 1540 fi 1541 fi 1542 1543 return 0 1544 1545 1546 ########################## MAIN ###################################### 1547