1 # 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/CDDL.txt 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/CDDL.txt. 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 # 23 # Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 # Use is subject to license terms. 25 # 26 27 # ident "@(#)functions.ksh 1.13 08/05/15 SMI" 28 29 PKG=SUNWscPostgreSQL 30 METHOD=`basename $0` 31 TASK_COMMAND="" 32 33 ZONENAME=/usr/bin/zonename 34 DIRNAME=/usr/bin/dirname 35 36 SCLOGGER=/usr/cluster/lib/sc/scds_syslog 37 PMFADM=/usr/cluster/bin/pmfadm 38 GETENT=/usr/bin/getent 39 AWK=/usr/bin/awk 40 NAWK=/usr/bin/nawk 41 CAT=/usr/bin/cat 42 EGREP=/usr/bin/egrep 43 GREP=/usr/bin/grep 44 ENV=/usr/bin/env 45 HEAD=/usr/bin/head 46 PS=/usr/bin/ps 47 PGREP=/usr/bin/pgrep 48 KILL=/usr/bin/kill 49 IPCS=/usr/bin/ipcs 50 IPCRM=/usr/bin/ipcrm 51 ECHO=/usr/bin/echo 52 TR=/usr/bin/tr 53 SU=/usr/bin/su 54 RM=/usr/bin/rm 55 ZLOGIN=/usr/sbin/zlogin 56 TEST=/usr/bin/test 57 PING=/usr/sbin/ping 58 SED=/usr/bin/sed 59 IFCONFIG=/usr/sbin/ifconfig 60 SSH=/usr/bin/ssh 61 SSH_AGENT=/usr/bin/ssh-agent 62 PKILL=/usr/bin/pkill 63 WC=/usr/bin/wc 64 SLEEP=/usr/bin/sleep 65 TOUCH=/usr/bin/touch 66 CHOWN=/usr/bin/chown 67 CP=/usr/bin/cp 68 69 get_fmri_parameters () 70 { 71 72 # extract the smf properties, you need to call your agent commands 73 74 debug_message "Function: get_fmri_parameters - Begin " 75 ${SET_DEBUG} 76 77 # Resource name 78 79 RESOURCE=`/usr/bin/svcprop -p parameters/Resource ${SMF_FMRI}` 80 81 # Resource Group 82 83 RESOURCEGROUP=`/usr/bin/svcprop -p parameters/Resource_group ${SMF_FMRI}` 84 85 # Start Project 86 87 Project=:default 88 if /usr/bin/svcprop ${SMF_FMRI}|grep start/project >/dev/null 89 then 90 Project=`/usr/bin/svcprop -p start/project ${SMF_FMRI}` 91 if [ "${Project}" != ":default" ] 92 then 93 PROJ_OPT=" -P ${Project}" 94 ZONE_PROJECT=${Project} 95 fi 96 fi 97 98 # Parameter file 99 100 PARFILE=`/usr/bin/svcprop -p parameters/Parameter_File ${SMF_FMRI}` 101 102 debug_message "Function: get_fmri_parameters - End " 103 } 104 105 set_shell_specifics() 106 { 107 108 # Set variables to construct sourcing and output redirection depending 109 # on the login shell of the user 110 111 debug_message "Function: set_shell_specifics - Begin" 112 ${SET_DEBUG} 113 114 ENVSC= 115 116 if /usr/bin/getent passwd ${USER} | /usr/bin/awk -F: '{print $7}' | /usr/bin/grep csh > /dev/null 117 then 118 119 # C shell specifics 120 121 # sourcing 122 123 if [ -n "${ENVSCRIPT}" ] 124 then 125 ENVSC="source ${ENVSCRIPT};" 126 fi 127 128 # brackets for subshells 129 130 OPEN_BRACKET="(" 131 CLOSE_BRACKET=")" 132 133 # redirection 134 135 OUTPUT_APP=">>& ${LOGFILE}" 136 OUTPUT=">& ${LOGFILE}" 137 CAT_OUTPUT="> /tmp/${RESOURCE}-${USER}-cat-out" 138 CAT_ERRPUT=">& /tmp/${RESOURCE}-${USER}-cat-err" 139 TBL_OUTPUT="> /tmp/${RESOURCE}-${USER}-tbl-out" 140 TBL_ERRPUT=">& /tmp/${RESOURCE}-${USER}-tbl-err" 141 else 142 143 # Korn shell specifics 144 145 # sourcing 146 147 if [ -n "${ENVSCRIPT}" ] 148 then 149 ENVSC=". ${ENVSCRIPT};" 150 fi 151 152 # no subshell needed in a ksh 153 154 OPEN_BRACKET= 155 CLOSE_BRACKET= 156 157 # redirection 158 159 OUTPUT_APP=">> ${LOGFILE} 2>&1" 160 OUTPUT="> ${LOGFILE} 2>&1" 161 CAT_OUTPUT="> /tmp/${RESOURCE}-${USER}-cat-out" 162 CAT_ERRPUT="2> /tmp/${RESOURCE}-${USER}-cat-err" 163 TBL_OUTPUT="> /tmp/${RESOURCE}-${USER}-tbl-out" 164 TBL_ERRPUT="2> /tmp/${RESOURCE}-${USER}-tbl-err" 165 fi 166 167 168 debug_message "Function: set_shell_specifics - End" 169 } 170 171 create_pfile() 172 { 173 174 # Creation of the parameter file. This function is used at registration 175 # time only. 176 177 debug_message "Function: create_pfile - Begin " 178 ${SET_DEBUG} 179 180 if [ -z "${PFILE}" ] 181 then 182 ${ECHO} "ERROR: set the variable parameter file" 183 return 1 184 fi 185 186 # determine wether the parameter file needs to be created in a zone or not 187 188 zonecmd= 189 190 pfile_tmp="/tmp/pgspfile.${RS}" 191 192 # get the zonename of the resource group 193 194 target_zone=$(rgs_zonename) 195 if [ -n "${target_zone}" ] 196 then 197 zonecmd="${ZLOGIN} ${target_zone}" 198 fi 199 200 # check the directory of the parameter file 201 202 pdir=`${zonecmd} ${DIRNAME} ${PFILE}` 203 204 # test for the existance of the parameter files directory either in the local or 205 # the global zone according to the zone entry in the nodelist 206 207 if ! ${zonecmd} ${TEST} -d ${pdir} 208 then 209 ${ECHO} "ERROR: set the variable parameter file in an existing directory" 210 return 1 211 fi 212 213 # create the parameter file 214 215 ${ECHO} "Prepare the parameter file ${PFILE}" 216 217 ${CAT} <<EOF > ${pfile_tmp} 218 219 # 220 # Content for the parameter file 221 # 222 # USER - The Solaris user, which owns the PostgreSQL database 223 # PGROOT - Contains the path to the PostgreSQL directory. Below this 224 # directory the postgres binaries are located in the ./bin 225 # directory. 226 # PGDATA - Contains the path to the databases of this specific PostgreSQL 227 # instance. The pg_hba.conf needs to be here. 228 # PGPORT - Port where the postmaster process will be listening to. 229 # PGHOST - Hostname where the postmaster process is listening to, or a directory where the 230 # Unix socket file is stored. 231 # If set to a valid hostname, the PGHOST variable forces the probe to 232 # traverse the TCP/IP stack. If the PGHOST variable is empty or starts with a "/", 233 # the probe will use a socket. If the PGHOST variable starts with a "/", the entry must 234 # be the directory which contains the socket file. 235 # PGLOGFILE - Logfile where the log messages of the postmaster will be stored. 236 # LD_LIBRARY_PATH - This path contains all the necessary libraries for this PostgreSQL 237 # installation. 238 # Optional 239 # ENVSCRIPT - Script to contain PostgreSQL specific runtime variables. 240 # Optional 241 # SCDB - This specific PostgreSQL database will be monitored. 242 # SCUSER - PostgresSQL user to connect to the $SCDB database. 243 # SCTABLE - Table name in the $SCDB database. This table name will be manipulated 244 # to check if PostgreSQL is alive. This table will be generated at database 245 # preparation time. 246 # SCPASS - Password of the SCUSER. If no password is provided the authentication method 247 # for the SCDB database needs to be trusted for requests from the localhost. 248 # Optional 249 # NOCONRET - Return code for connection errors. This return code has to follow the rules 250 # for the generic data service. The value has to be between 1 and 100. 251 # 100/NOCONRET defines the number of consecutive probes to ignore for failed 252 # connections. A restart or failover will occur, if the number is exeeded within 253 # the retry interval. 254 255 256 USER=${USER} 257 PGROOT=${PGROOT} 258 PGDATA=${PGDATA} 259 PGPORT=${PGPORT} 260 PGHOST=${PGHOST} 261 PGLOGFILE=${PGLOGFILE} 262 LD_LIBRARY_PATH=${LD_LIBRARY_PATH} 263 ENVSCRIPT=${ENVSCRIPT} 264 SCDB=${SCDB} 265 SCUSER=${SCUSER} 266 SCTABLE=${SCTABLE} 267 SCPASS=${SCPASS} 268 NOCONRET=${NOCONRET} 269 270 # The following parameters need to be configured only if logfile shipping is configured to ship 271 # the PosgreSQL WAL logs between a designated primary and a designated standby resource. 272 # They need to be configured only on the primary. 273 274 # STDBY_RS The resource name of the PostgreSQL standby resource. 275 # STDBY_RG The resource group name of the PostgreSQL standby resource group. 276 # STDBY_USER User which is the owner of the standby postgres database. 277 # STDBY_HOST Resolvable name of the standby host or the standby zone, 278 # this name has to be reachable via ssh. 279 # STDBY_PARFILE The standbys postgres parameter file to get the rest of the necessary parameters. 280 # STDBY_PING The number of packets the primary uses to ping the standby host. If this variable is 281 # empty, it will be set to 5 packets. 282 # ROLECHG_RS The rolechangers resource name. 283 # SSH_PASSDIR A directory where the ssh passphrase is stored in a the file <resourcename>-phrase. 284 # This parameter is needed only if you configured WAL file shipping and secured your 285 # ssh key with a passphrase. 286 # Leave it undefined if the passprase is empty. 287 # 288 # If you configure the logfile shipping in a shared nothing topology, do not set the LH parameter. 289 # 290 # Configure the following paramters on the primary host. 291 292 STDBY_RS=${STDBY_RS} 293 STDBY_RG=${STDBY_RG} 294 STDBY_USER=${STDBY_USER} 295 STDBY_HOST=${STDBY_HOST} 296 STDBY_PARFILE=${STDBY_PARFILE} 297 STDBY_PING=${STDBY_PING} 298 # 299 # Configure the following paramter on the standby host. 300 # 301 ROLECHG_RS=${ROLECHG_RS} 302 # 303 # Configure the following parameter on both hosts. 304 # 305 SSH_PASSDIR=${SSH_PASSDIR} 306 307 EOF 308 if [ $? -ne 0 ] 309 then 310 ${ECHO} "ERROR: could not create the temporary parameter file ${pfile_tmp}" 311 return 1 312 fi 313 314 # create the parameter file either in the global or in the prepared target zone 315 316 if [ -n "${target_zone}" ] 317 then 318 ${CAT} ${pfile_tmp} | ${zonecmd} ${CAT} - \>${PFILE} 319 if [ $? -ne 0 ] 320 then 321 ${ECHO} "ERROR: could not create the parameter file ${PFILE}" 322 return 1 323 fi 324 else 325 ${CAT} ${pfile_tmp} > ${PFILE} 326 if [ $? -ne 0 ] 327 then 328 ${ECHO} "ERROR: could not create the parameter file ${PFILE}" 329 return 1 330 fi 331 fi 332 333 debug_message "Function: create_pfile - End " 334 return 0 335 } 336 337 validate_options() 338 { 339 debug_message "Function: validate_options - Begin" 340 ${SET_DEBUG} 341 342 # 343 # Ensure all mandatory options are set 344 # 345 346 for i in RESOURCE RESOURCEGROUP PARFILE 347 do 348 case ${i} in 349 RESOURCE) 350 if [ -z "${RESOURCE}" ]; then 351 # SCMSGS 352 # @explanation 353 # The start, stop or probe command requires an 354 # option which is not set. 355 # @user_action 356 # Fix the start, stop or probe command in the 357 # SUNW.gds resource. 358 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 359 "Function: validate_options: %s Option %s not set" \ 360 "${METHOD}" "-R" 361 return 1 362 fi;; 363 364 RESOURCEGROUP) 365 if [ -z "${RESOURCEGROUP}" ]; then 366 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 367 "Function: validate_options: %s Option %s not set" \ 368 "${METHOD}" "-G" 369 return 1 370 fi;; 371 372 PARFILE) 373 if [ -z "${PARFILE}" ]; then 374 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 375 "Function: validate_options: %s Option %s not set" \ 376 "${METHOD}" "-P" 377 return 1 378 fi;; 379 esac 380 done 381 382 debug_message "Function: validate_options - End" 383 } 384 385 validate() 386 { 387 # 388 # Validate 389 # 390 391 debug_message "Function: validate - Begin" 392 ${SET_DEBUG} 393 394 rc_validate=0 395 396 if ! val_parfile ${PARFILE} "USER PGROOT PGDATA PGPORT PGLOGFILE SCDB SCUSER SCTABLE NOCONRET" 397 then 398 debug_message "Function: validate - End" 399 rc_validate=1 400 return ${rc_validate} 401 fi 402 403 . ${PARFILE} 404 405 for i in `${CAT} ${PARFILE} |grep -v "^#"|grep -v "^ "|nawk -F= '{print $1}'` 406 do 407 case $i in 408 USER) 409 410 # Test the PostgresSQL OS user 411 412 if [ -z "${USER}" ]; then 413 # SCMSGS 414 # @explanation 415 # A mandatory variable is unset in the 416 # parameter file. 417 # @user_action 418 # Fix the parameter file and provide a value 419 # for the variable in the parameter file 420 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 421 "Function: validate: The %s variable is not set, but it is required" \ 422 "USER" 423 rc_validate=1 424 else 425 id ${USER} >/dev/null 2>&1 426 if [ $? -ne 0 ]; then 427 # SCMSGS 428 # @explanation 429 # The user mentioned in the parameter 430 # file is not defined in the OS. 431 # @user_action 432 # Fix the parameter file and provide 433 # an existing user for the variable 434 # USER. 435 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 436 "Function: validate: User %s does not exist, an existing user is required" \ 437 "${USER}" 438 rc_validate=1 439 else 440 debug_message "Function: validate - USER OK" 441 fi 442 fi;; 443 444 PGROOT) 445 446 # Test the PG Root variable 447 448 if [ -z "${PGROOT}" ]; then 449 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 450 "Function: validate: The %s variable is not set, but it is required" \ 451 "PGROOT" 452 rc_validate=1 453 else 454 if [ ! -d ${PGROOT} ]; then 455 # SCMSGS 456 # @explanation 457 # The directory mentioned in the 458 # parameter file for the PGROOT or 459 # PGDATA variable does not exist. 460 # @user_action 461 # Fix the parameter file and provide 462 # an existing directoy for the 463 # variable PGROOT or PGDATA. 464 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 465 "Function: validate: Directory %s does not exist, an existing directory is required" \ 466 "${PGROOT}" 467 rc_validate=1 468 fi 469 470 # test if it is a postgres installation 471 472 if [ ! -f ${PGROOT}/bin/pg_ctl ] 473 then 474 # SCMSGS 475 # @explanation 476 # The directory mentioned in the 477 # PGROOT variable does not contain the 478 # PostgreSQL binaries in its bin 479 # directory. 480 # @user_action 481 # Provide the directory which does 482 # contain at least the PostgreSQL 483 # binaries in the path ./bin. 484 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 485 "Function: validate: Directory %s does not contain the PostgreSQL binaries" \ 486 "${PGROOT}" 487 rc_validate=1 488 else 489 debug_message "Function: validate - PGROOT OK" 490 fi 491 fi;; 492 493 PGDATA) 494 495 # Test the PG Data variable 496 497 if [ -z "${PGDATA}" ]; then 498 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 499 "Function: validate: The %s variable is not set, but it is required" \ 500 "PGDATA" 501 rc_validate=1 502 else 503 if [ ! -d ${PGDATA} ]; then 504 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 505 "Function: validate: Directory %s does not exist, an existing directory is required" \ 506 "${PGDATA}" 507 rc_validate=1 508 fi 509 510 # test if it is a postgres database cluster 511 512 if [ ! -f ${PGDATA}/postgresql.conf ] 513 then 514 # SCMSGS 515 # @explanation 516 # A directory is specified in the 517 # PGDATA variable which does not 518 # contain a postgresql.conf file. 519 # @user_action 520 # Specify a directory in the PGDATA 521 # variable in the parmeter file, which 522 # contains the postgresql.conf file. 523 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 524 "Function: validate: Directory %s does not contain the PostgreSQL configuration files" \ 525 "${PGDATA}" 526 rc_validate=1 527 else 528 debug_message "Function: validate - PGDATA OK" 529 fi 530 fi;; 531 532 PGPORT) 533 534 # Test the PG Port variable 535 536 if [ -z "${PGPORT}" ]; then 537 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 538 "Function: validate: The %s variable is not set, but it is required" \ 539 "PGPORT" 540 rc_validate=1 541 else 542 543 # test if the port is numeric 544 545 if ! let x=${PGPORT} >/dev/null 2>&1 546 then 547 # SCMSGS 548 # @explanation 549 # In the parameter file, there is a 550 # non numeric character in the value 551 # for the PGPORT variable. 552 # @user_action 553 # Fix the PGPORT variable in the 554 # parameter file. 555 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 556 "Function: validate: Port %s is not numeric" \ 557 "${PGPORT}" 558 rc_validate=1 559 else 560 debug_message "Function: validate - PGPORT OK" 561 fi 562 fi;; 563 564 PGHOST) 565 566 # test the PGHOST variable ony if it is defined 567 568 if [ -n "${PGHOST}" ] 569 then 570 571 # strip of leading spaces 572 573 PGHOST=`print ${PGHOST}|${SED} 's/^ *//'` 574 575 if ${ECHO} ${PGHOST} | ${GREP} "^/" >/dev/null 2>&1 576 then 577 578 if [ ! -d "${PGHOST}" ] 579 then 580 581 # SCMSGS 582 # @explanation 583 # The directory specified in the PGHOST variable does not 584 # exist. 585 # @user_action 586 # Create the directory. None if it was a lost mount. 587 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 588 "Function: validate - Directory for the socket file %s does not exist" \ 589 "${PGHOST}" 590 rc_validate=1 591 592 else 593 debug_message "Function: validate - PGHOST OK" 594 fi 595 596 else 597 if ! ${GETENT} hosts ${PGHOST} >/dev/null 2>&1 598 then 599 600 # SCMSGS 601 # @explanation 602 # The host specified in the PGHOST variable is not 603 # resolvable. 604 # @user_action 605 # Create the the host entry in /etc/hosts. 606 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 607 "Function: validate - The host %s is not resolvable" \ 608 "${PGHOST}" 609 rc_validate=1 610 611 else 612 debug_message "Function: validate - PGHOST resolvable" 613 fi 614 615 # Validate if the address of the PGHOST variable is configured UP 616 # on a adapter of the host. This validation works in 617 # global zones, local zones and in failover zones. 618 # This method was preferred over checking the dependency tree, 619 # because it works in failover zones, even if there is no logical 620 # host configured. 621 622 # Set the laguage to C to avoid localisation problems with ifconfig 623 624 LANG=C 625 626 addr=`${GETENT} hosts ${PGHOST}| ${AWK} '{print $1}'` 627 628 # Check if the address is configured up on the node 629 630 adapter_success=1 631 for i in `${IFCONFIG} -a |${GREP} UP|${AWK} '{print $1}' |${EGREP} -v "zone|inet"|${GREP} ":$"|${SED} s/:$//` 632 do 633 634 ${IFCONFIG} ${i}|${GREP} ${addr} >/dev/null 2>&1 635 if [ ${?} -eq 0 ] 636 then 637 adapter_success=0 638 fi 639 640 done 641 642 if [ ${adapter_success} -ne 0 ] 643 then 644 645 # SCMSGS 646 # @explanation 647 # The host specified in the PGHOST variable is not 648 # configured up on the hosts adapters. 649 # @user_action 650 # Fix either the network configuration or the PGHOST variable 651 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 652 "Function: validate - The host %s is not configured UP on the hosts adapters" \ 653 "${PGHOST}" 654 rc_validate=1 655 else 656 debug_message "Function: validate - PGHOST is configured on the nodes adapters" 657 fi 658 fi 659 fi;; 660 661 PGLOGFILE) 662 663 # Test the Logfile variable 664 665 if [ -z "${PGLOGFILE}" ]; then 666 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 667 "Function: validate: The %s variable is not set, but it is required" \ 668 "PGLOGFILE" 669 rc_validate=1 670 else 671 672 # test if the directory for Logfile exists 673 674 Logdir=`/usr/bin/dirname ${PGLOGFILE}` 675 if [ ! -d ${Logdir} ]; then 676 # SCMSGS 677 # @explanation 678 # The path to the filename variable 679 # PGLOGFILE does not exist. 680 # @user_action 681 # Qualify the filename of the parameter 682 # files PGLOGFILE variable in an 683 # existing directory. 684 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 685 "Function: validate: Directory for logfile %s does not exist, an existing directory is required" \ 686 "${PGLOGFILE}" 687 rc_validate=1 688 else 689 debug_message "Function: validate - PGLOGFILE OK" 690 fi 691 fi;; 692 693 LD_LIBRARY_PATH) 694 695 # test LD_LIBRARY_PATH if it is set 696 697 if [ -n "${LD_LIBRARY_PATH}" ] 698 then 699 export LD_LIBRARY_PATH 700 if ! ${PGROOT}/bin/psql --help >/dev/null 2>&1 701 then 702 # SCMSGS 703 # @explanation 704 # The LD_LIBRARY_PATH is not valid to 705 # call the postgres binary. 706 # @user_action 707 # Qualify the LD_LIBRARY_PATH in the 708 # parameter file until it is 709 # sufficient for the psql binary. 710 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 711 "Function: validate: The LD_LIBRARY_PATH %s is not valid for this PostgreSQL installation" \ 712 "${LD_LIBRARY_PATH}" 713 rc_validate=1 714 else 715 debug_message "Function: validate - LD_LIBRARY_PATH OK" 716 fi 717 fi;; 718 719 ENVSCRIPT) 720 721 # test if the environment script is a syntactically valid script 722 # In the smf context it needs to be a ksh script. 723 # In the GDS context the script type ksh/csh is dependent from the login shell of the user. 724 725 if [ -n "${ENVSCRIPT}" ] 726 then 727 if [ -f ${ENVSCRIPT} ] 728 then 729 if ${GETENT} passwd ${USER} | ${AWK} -F: '{print $7}' | ${GREP} "csh" > /dev/null && [ -z "${SMF_FMRI}" ] 730 then 731 if ! /usr/bin/csh -n ${ENVSCRIPT} > /dev/null 2>&1 732 then 733 # SCMSGS 734 # @explanation 735 # The environment 736 # script specified in 737 # the parameter file 738 # needs to be a valid 739 # c shell script, 740 # because the login 741 # shell of the 742 # PostgreSQL user is c 743 # shell compliant. 744 # @user_action 745 # Fix the environment 746 # script until it 747 # passes csh -n 748 # scriptname. 749 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 750 "Function: validate: The Environment script %s is not a valid c shell script" \ 751 "${ENVSCRIPT}" 752 rc_validate=1 753 else 754 debug_message "Function: validate - ENVSCRIPT OK" 755 fi 756 else 757 if ! /usr/bin/ksh -n ${ENVSCRIPT} >/dev/null 2>&1 758 then 759 # SCMSGS 760 # @explanation 761 # The environment 762 # script specified in 763 # the parameter file 764 # needs to be a valid 765 # korn shell script, 766 # because the login 767 # shell of the 768 # PostgreSQL user is 769 # korn shell 770 # compliant. 771 # @user_action 772 # Fix the environment 773 # script until it 774 # passes ksh -n 775 # scriptname. 776 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 777 "Function: validate: The Environment script %s is not a valid korn shell script" \ 778 "${ENVSCRIPT}" 779 rc_validate=1 780 else 781 debug_message "Function: validate - ENVSCRIPT OK" 782 fi 783 fi 784 else 785 # SCMSGS 786 # @explanation 787 # The filename specified in the 788 # parameter files ENVSCRIPT variable 789 # does not exist. 790 # @user_action 791 # Fix the parameter file and specify a 792 # valid Environment script. 793 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 794 "Function: validate: The Environment script %s does not exist" \ 795 "${ENVSCRIPT}" 796 rc_validate=1 797 798 fi 799 fi;; 800 801 SCDB) 802 803 # Test if the test database variable is defined 804 805 if [ -z "${SCDB}" ]; then 806 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 807 "Function: validate: The %s variable is not set, but it is required" \ 808 "SCDB" 809 rc_validate=1 810 else 811 debug_message "Function: validate - SCDB OK" 812 fi;; 813 814 SCUSER) 815 816 # Test if the database user variable is defined 817 818 if [ -z "${SCUSER}" ]; then 819 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 820 "Function: validate: The %s variable is not set, but it is required" \ 821 "SCUSER" 822 rc_validate=1 823 else 824 debug_message "Function: validate - SCUSER OK" 825 fi;; 826 827 SCTABLE) 828 829 # Test if the database table variable is defined 830 831 if [ -z "${SCTABLE}" ]; then 832 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 833 "Function: validate: The %s variable is not set, but it is required" \ 834 "SCTABLE" 835 rc_validate=1 836 else 837 debug_message "Function: validate - SCTABLE OK" 838 fi;; 839 840 NOCONRET) 841 842 # Test the No Connection return code variable 843 844 if [ -z "${NOCONRET}" ]; then 845 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 846 "Function: validate: The %s variable is not set, but it is required" \ 847 "NOCONRET" 848 rc_validate=1 849 else 850 851 # test if the NOCONRET is numeric 852 853 if ! let x=${NOCONRET} >/dev/null 2>&1 854 then 855 # SCMSGS 856 # @explanation 857 # The value for the NOCONRET variable 858 # contains a non numeric character. 859 # @user_action 860 # Fix the NOCONRET variable in the 861 # parameter file. 862 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 863 "Function: validate: Return code for failed connections %s is not numeric" \ 864 "${NOCONRET}" 865 rc_validate=1 866 else 867 if [ ${NOCONRET} -gt 100 ]; then 868 # SCMSGS 869 # @explanation 870 # The value of the NOCONRET 871 # variable in the parameter 872 # file exeeds 100. 873 # @user_action 874 # Fix the parameter file with 875 # a value below 100. 876 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 877 "Function: validate: Return code for failed connections %s is greater 100" \ 878 "${NOCONRET}" 879 rc_validate=1 880 else 881 debug_message "Function: validate - NOCONRET OK" 882 fi 883 fi 884 fi;; 885 886 STDBY_HOST) 887 888 # Test the standby host variable and the neccessary other variables if the standby 889 # host variable is not set. 890 891 if [ -n "${STDBY_HOST}" ]; then 892 if ! ${GETENT} hosts ${STDBY_HOST} >/dev/null 2>&1 893 then 894 895 # SCMSGS 896 # @explanation 897 # The host specified in the STDBY_HOST variable is not 898 # resolvable. 899 # @user_action 900 # Add the host to one of your configured name services, 901 # so it can get listed with getent. 902 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 903 "Function: validate - The standby host %s is not resolvable" \ 904 "${STDBY_HOST}" 905 rc_validate=1 906 907 else 908 debug_message "Function: validate - STDBY_HOST resolvable" 909 fi 910 911 # Test if all the other standby related variables are set. 912 # There will be no other validation, because it may be that the necessary 913 # resources are not up right now, and then the validation will fail without 914 # a valid reason which is related to the parameter configuration. 915 916 if [ -z "${STDBY_RS}" ] 917 then 918 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 919 "Function: validate: The %s variable is not set, but it is required" \ 920 "STDBY_RS" 921 rc_validate=1 922 else 923 debug_message "Function: validate - STDBY_RS OK" 924 fi 925 926 if [ -z "${STDBY_RG}" ] 927 then 928 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 929 "Function: validate: The %s variable is not set, but it is required" \ 930 "STDBY_RG" 931 rc_validate=1 932 else 933 debug_message "Function: validate - STDBY_RG OK" 934 fi 935 936 if [ -z "${STDBY_USER}" ] 937 then 938 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 939 "Function: validate: The %s variable is not set, but it is required" \ 940 "STDBY_USER" 941 rc_validate=1 942 else 943 debug_message "Function: validate - STDBY_USER OK" 944 fi 945 946 if [ -z "${STDBY_PARFILE}" ] 947 then 948 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 949 "Function: validate: The %s variable is not set, but it is required" \ 950 "STDBY_PARFILE" 951 rc_validate=1 952 else 953 debug_message "Function: validate - STDBY_PARFILE OK" 954 fi 955 956 if [ -n "${STDBY_PING}" ] 957 then 958 if ! let x=${STDBY_PING} >/dev/null 2>&1 959 then 960 # SCMSGS 961 # @explanation 962 # In the parameter file, there is a 963 # non numeric character in the value 964 # for the STDBY_PING variable. 965 # @user_action 966 # Fix the STDBY_PING variable in the 967 # parameter file. 968 969 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 970 "Function: validate: The STDBY_PING value of %s is not numeric" \ 971 "${STDBY_PING}" 972 rc_validate=1 973 else 974 debug_message "Function: validate - STDBY_PING OK" 975 fi 976 else 977 # set a default of 5 packets 978 STDBY_PING=5 979 debug_message "Function: validate - STDBY_PING OK, it was set to 5 packets" 980 fi 981 982 fi;; 983 esac 984 done 985 986 debug_message "Function: validate - End" 987 return ${rc_validate} 988 } 989 990 validate_probe() 991 { 992 # Validate ony for non existant files or lost directories 993 994 debug_message "Function: validate_probe - Begin" 995 ${SET_DEBUG} 996 997 rc_val_probe=0 998 999 # If the parameter file does not pass the short validation, try a failover 1000 # A failover is the appropriate action, because the directory existed 1001 # at startup of the resource. 1002 1003 if ! val_parfile ${PARFILE} 1004 then 1005 1006 1007 # SCMSGS 1008 # @explanation 1009 # The file specified in the PARFILE variable does not 1010 # exist any more. 1011 # @user_action 1012 # Create the directory and restore the parameter file. None if it was a lost mount. 1013 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 1014 "Function: validate_probe - Directory for the parameter file %s does not exist any more, a faiover will occur" \ 1015 "${PARFILE}" 1016 1017 rc_val_probe=201 1018 fi 1019 1020 # source the parameter file 1021 1022 . ${PARFILE} 1023 1024 # Check the PGHOST variable. 1025 # If the PGHOST variable starts with a / then it should be a directory which contains the socket file. 1026 # If this directory is not available, a failover will be initiated. 1027 # If it does not contain a / then it has to be a hostname or an address, in this case the hostname 1028 # has to respond to ping. 1029 1030 if [ -n "${PGHOST}" ] 1031 then 1032 1033 # strip of leading spaces 1034 1035 PGHOST=`print ${PGHOST}|${SED} 's/^ *//'` 1036 1037 if ${ECHO} ${PGHOST} | ${GREP} "^/" >/dev/null 2>&1 1038 then 1039 1040 if [ ! -d "${PGHOST}" ] 1041 then 1042 1043 # SCMSGS 1044 # @explanation 1045 # The directory specified in the PGHOST variable does not 1046 # exist any more. 1047 # @user_action 1048 # Create the directory. None if it was a lost mount. 1049 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 1050 "Function: validate_probe - Directory for the socket file %s does not exist any more, a faiover will occur" \ 1051 "${PGHOST}" 1052 rc_val_probe=201 1053 else 1054 debug_message "Function: validate_probe - the directory in PGHOST exists" 1055 fi 1056 1057 else 1058 1059 # If an address is specified, test it with ping. Initiate a failover if the address 1060 # is unavailable. 1061 # This needs to be done, because an unpingable address will cause the psql commands to hang 1062 # The test will detect accidentally unconfigured interfaces, just a failover or restart of 1063 # the resource group can cure this problem. 1064 1065 # This ping test is here to prevent a predictable timeout, it is needed as long as 1066 # SUNW.LogicalHost does not probe the ipaddresses. As soon as this changes the 1067 # ping test should be removed. 1068 1069 if ! ${PING} ${PGHOST} 1 >/dev/null 2>&1 1070 then 1071 # SCMSGS 1072 # @explanation 1073 # The address specified in the PGHOST variable 1074 # is unavailable. 1075 # @user_action 1076 # None, a failover will occur 1077 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 1078 "check_pgs: The host %s is not accessible, a failover will occur" \ 1079 "${PGHOST}" 1080 1081 rc_val_probe=201 1082 else 1083 debug_message "Function: validate_probe - the host in PGHOST is pingable" 1084 fi 1085 fi 1086 fi 1087 1088 debug_message "Function: validate_probe - End" 1089 return $rc_val_probe 1090 } 1091 1092 val_parfile() 1093 { 1094 # Common valdation for parameter file 1095 # 1096 # If the parameter is in $2, there will be an intensive validation. 1097 # If $2 is empty, the validation will just check for the existance of the file. 1098 1099 debug_message "Function: val_parfile - Begin" 1100 ${SET_DEBUG} 1101 1102 rc_val_parfile=0 1103 1104 # Validate that parameter file exists 1105 1106 PARFILE=${1} 1107 PARLIST=${2} 1108 1109 if [ ! -f "${PARFILE}" ]; then 1110 # SCMSGS 1111 # @explanation 1112 # The parameter file does not exist in the parameter file 1113 # directory. 1114 # @user_action 1115 # Restore the parameter file or re-register the resource. 1116 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 1117 "Function: val_parfile - File %s does not exist" \ 1118 "${PARFILE}" 1119 rc_val_parfile=1 1120 else 1121 debug_message "Function: val_parfile - ${PARFILE} exists" 1122 fi 1123 1124 # Test the semantics only, if the parameter list is specified. 1125 # This should not be done when called from validate_probe. 1126 1127 if [ -n "${2}" ] 1128 then 1129 1130 # Test if the parameter file is a valid ksh script