1 # 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/CDDL.txt 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/CDDL.txt. 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 #ident "@(#)functions_static.ksh 1.10 08/05/06 SMI" 29 30 TASK_COMMAND="" 31 32 ZONENAME=/usr/bin/zonename 33 34 SCLOGGER=/usr/cluster/lib/sc/scds_syslog 35 LOGGER=/usr/bin/logger 36 SCHA_RESOURCE_SETSTATUS=/usr/cluster/bin/scha_resource_setstatus 37 SCHA_RESOURCE_GET=/usr/cluster/bin/scha_resource_get 38 SCHA_RESOURCEGROUP_GET=/usr/cluster/bin/scha_resourcegroup_get 39 PMFADM=/usr/cluster/bin/pmfadm 40 UNAME=/usr/bin/uname 41 ECHO=/usr/bin/echo 42 AWK=/usr/bin/awk 43 EGREP=/usr/bin/egrep 44 GREP=/usr/bin/grep 45 PROJECTS=/usr/bin/projects 46 WC=/usr/bin/wc 47 CAT=/usr/bin/cat 48 ENV=/usr/bin/env 49 RM=/usr/bin/rm 50 SSH_AGENT=/usr/bin/ssh-agent 51 SSH_ADD=/usr/bin/ssh-add 52 CHMOD=/usr/bin/chmod 53 54 terminate() 55 { 56 57 debug_message "Function: terminate - Begin" 58 ${SET_DEBUG} 59 60 exiting_func=${1} 61 exit_code=${2} 62 63 # determine the right return code, it is either the return code from the functions or 64 # the appropriate smf return code 65 66 if in_cluster 67 then 68 69 # called in a clustered global zone 70 71 debug_message "Method: ${MYNAME} ${exiting_func} - End (${exit_code})" 72 exit ${exit_code} 73 74 else 75 if [ -n "${SMF_FMRI}" ] 76 then 77 if [ "${exit_code}" -ne 0 ] 78 then 79 80 # honour the gds specific probe values like 100 or 201 81 82 if [ "${exiting_func}" == "probe" -o "${exiting_func}" == "validate" ] 83 then 84 debug_message "Method: ${MYNAME} ${exiting_func} - End (${exit_code})" 85 exit ${exit_code} 86 else 87 debug_message "Method: ${MYNAME} ${exiting_func} - End (${SMF_EXIT_ERR_PERM})" 88 exit ${SMF_EXIT_ERR_PERM} 89 fi 90 fi 91 92 debug_message "Method: ${MYNAME} ${exiting_func} - End (${SMF_EXIT_OK})" 93 exit ${SMF_EXIT_OK} 94 else 95 debug_message "Method: ${MYNAME} ${exiting_func} - End (${exit_code})" 96 exit ${exit_code} 97 fi 98 fi 99 100 debug_message "Function: terminate - End" 101 102 } 103 syslog_tag() 104 { 105 # 106 # Data Service message format 107 # 108 109 ${SET_DEBUG} 110 111 print "SC[${PKG:-??}.${METHOD:-??}]:${RESOURCEGROUP:-??}:${RESOURCE:-??}" 112 } 113 114 scds_syslog() 115 { 116 117 # 118 # Log a message 119 # 120 121 ${SET_DEBUG} 122 123 if [ -f ${SCLOGGER} ] 124 then 125 ${SCLOGGER} "$@" & 126 else 127 128 # eliminate -m and honour -p and -t option 129 while getopts 'p:t:m' opt 130 do 131 case "${opt}" in 132 t) TAG=${OPTARG};; 133 p) PRI=${OPTARG};; 134 esac 135 done 136 137 shift $((${OPTIND} - 1)) 138 LOG_STRING=`/usr/bin/printf "$@"` 139 140 ${LOGGER} -p ${PRI} -t ${TAG} ${LOG_STRING} 141 fi 142 143 } 144 145 rgs_zonename() 146 { 147 148 # Determine wether the host specified by uname -n is combined with a zonename in the 149 # current resourcegroups nodelist. The seperator beween nodename and zonename is ":". 150 # 151 # This function assume the resource group name preset in the variable ${RESOURCEGROUP} and should be called 152 # 153 # $(rgs_zonename) 154 # 155 # It passes back a zonename or nothing. 156 # If there are more than one zones in the nodelist, it passes back either the zone where the resource group 157 # is online or first one in the list. 158 159 debug_message "Function: rg_zonename - Begin " 160 ${SET_DEBUG} 161 162 nodes_zone= 163 nodename=`${UNAME} -n` 164 node=`${SCHA_RESOURCEGROUP_GET} -G ${RESOURCEGROUP} -O NODELIST|${EGREP} "${nodename}$|${nodename}:"` 165 166 if ${ECHO} ${node} | ${GREP} : >/dev/null 2>&1 167 then 168 if [ `${ECHO} ${node}|${WC} -w` -gt 1 ] 169 then 170 online=0 171 for i in ${node} 172 do 173 if ${SCHA_RESOURCEGROUP_GET} -G ${RESOURCEGROUP} -O RG_state_node ${i}| ${GREP} -i online >/dev/null 2>&1 174 then 175 nodes_zone=`${ECHO} ${i} | ${AWK} -F: '{print $2}'` 176 online=1 177 fi 178 done 179 180 # check if we found a zone where the resource group is online, if not pick the first zone in the list 181 182 if [ ${online} -eq 0 ] 183 then 184 first_node=`${ECHO} ${node} | ${AWK} '{print $1}'` 185 nodes_zone=`${ECHO} ${first_node} | ${AWK} -F: '{print $2}'` 186 fi 187 else 188 nodes_zone=`${ECHO} ${node} | ${AWK} -F: '{print $2}'` 189 fi 190 191 fi 192 193 print ${nodes_zone} 194 195 debug_message "Function: rg_zonename - End " 196 } 197 198 debug_message() 199 { 200 # 201 # Output a debug message to syslog if required 202 # 203 204 if [ -n "${DEBUG}" ] 205 then 206 207 # determine if we should display a message and do it 208 209 if [ "${DEBUG}" = "ALL" ] 210 then 211 SET_DEBUG="set -x" 212 213 DEBUG_TEXT=${1} 214 215 scds_syslog -p daemon.debug -t $(syslog_tag) -m \ 216 "%s" "${DEBUG_TEXT}" 217 else 218 219 # check if the actual resource matches one of the list of resources 220 # if it matches, display a message 221 222 DEBUG=`echo ${DEBUG}|tr "," " "` 223 for i in ${DEBUG} 224 do 225 if [ "${i}" = "${RESOURCE}" ] 226 then 227 SET_DEBUG="set -x" 228 229 DEBUG_TEXT=${1} 230 231 scds_syslog -p daemon.debug -t $(syslog_tag) -m \ 232 "%s" "${DEBUG_TEXT}" 233 fi 234 done 235 fi 236 else 237 SET_DEBUG= 238 fi 239 } 240 241 log_message() 242 { 243 # 244 # Output a message to syslog as required 245 # 246 247 debug_message "Function: log_message - Begin" 248 ${SET_DEBUG} 249 250 if [ -s "${LOGFILE}" ] 251 then 252 PRIORITY=${1} 253 HEADER=${2} 254 255 # 256 # Ensure the while loop only reads a closed file 257 # 258 259 strings ${LOGFILE} > ${LOGFILE}.copy 260 while read MSG_TXT 261 do 262 scds_syslog -p daemon.${PRIORITY} -t $(syslog_tag) -m \ 263 "%s - %s" \ 264 "${HEADER}" "${MSG_TXT}" 265 done < ${LOGFILE}.copy 266 267 fi 268 269 debug_message "Function: log_message - End" 270 } 271 272 srm_function() 273 { 274 debug_message "Function: srm_function - Begin" 275 ${SET_DEBUG} 276 277 USER=${1} 278 279 # 280 # If Solaris 8 just return 281 # 282 283 if [ `/usr/bin/uname -r` = "5.8" ]; 284 then 285 return 0 286 fi 287 288 # 289 # Retrieve RESOURCE_PROJECT_NAME 290 # 291 292 if in_cluster 293 then 294 RESOURCE_PROJECT_NAME=`${SCHA_RESOURCE_GET} -R ${RESOURCE} -G ${RESOURCEGROUP} -O RESOURCE_PROJECT_NAME` 295 296 # 297 # Retrieve RG_PROJECT_NAME if RESOURCE_PROJECT_NAME is not set 298 # 299 300 if [ -z "${RESOURCE_PROJECT_NAME}" ] || [ "${RESOURCE_PROJECT_NAME}" = "default" ];then 301 302 RESOURCE_PROJECT_NAME=`${SCHA_RESOURCEGROUP_GET} -G ${RESOURCEGROUP} -O RG_PROJECT_NAME` 303 fi 304 else 305 RESOURCE_PROJECT_NAME=${ZONE_PROJECT} 306 fi 307 308 # 309 # Return if no projects are defined 310 # 311 312 if [ -z "${RESOURCE_PROJECT_NAME}" ] || [ "${RESOURCE_PROJECT_NAME}" = "default" ]; then 313 return 0 314 fi 315 316 # 317 # Validate that $USER belongs to the project defined by 318 # ${RESOURCE_PROJECT_NAME} 319 # 320 321 PROJ_MEMBER=`${PROJECTS} ${USER} | ${EGREP} "^${RESOURCE_PROJECT_NAME} | ${RESOURCE_PROJECT_NAME} | ${RESOURCE_PROJECT_NAME}$|^${RESOURCE_PROJECT_NAME}$"` 322 323 if [ -z "${PROJ_MEMBER}" ]; 324 then 325 # SCMSGS 326 # @explanation 327 # The specified user does not belong to the project defined by 328 # Resource_project_name or Rg_project_name. 329 # @user_action 330 # Add the user to the defined project in /etc/project. 331 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 332 "srm_function - The user %s does not belongs to project %s" \ 333 "${USER}" "${RESOURCE_PROJECT_NAME}" 334 return 1 335 else 336 debug_message "srm_function - User ${USER} belongs to project ${RESOURCE_PROJECT_NAME}" 337 fi 338 339 # 340 # Set TASK_COMMAND 341 # 342 343 TASK_COMMAND="/usr/bin/newtask -p ${RESOURCE_PROJECT_NAME}" 344 345 debug_message "Function: srm_function - End" 346 347 return 0 348 } 349 350 zone_function() 351 { 352 debug_message "Function: zone_function - Begin" 353 ${SET_DEBUG} 354 355 # 356 # Initialize PZONEOPT as empty 357 PZONEOPT="" 358 359 # 360 # If Solaris does not have /usr/bin/zonename just return 0 361 # else add "-z <zonename>" to PZONEOPT 362 # 363 364 if [ -x "${ZONENAME}" ]; 365 then 366 PZONEOPT="-z `${ZONENAME}`" 367 fi 368 369 debug_message "Function: zone_function - End" 370 return 0 371 } 372 373 in_cluster() 374 { 375 # 376 # determine if we are started in a clustered global zone 377 # 378 379 debug_message "Function: in_cluster - Begin" 380 ${SET_DEBUG} 381 382 in_cluster_val=0 383 384 if [ ! -d /etc/cluster ] 385 then 386 in_cluster_val=1 387 fi 388 389 debug_message "Function: in_cluster - End" 390 391 return ${in_cluster_val} 392 } 393 394 start_dependency() 395 { 396 debug_message "Function: start_dependency - Begin" 397 ${SET_DEBUG} 398 399 # RETRIEVE START_TIMEOUT 400 401 if [-z "${ZONE_START_TIMOUT}" ] 402 then 403 START_TIMEOUT=`standard_resource_get START_TIMEOUT` 404 else 405 START_TIMEOUT=${ZONE_START_TIMOUT} 406 fi 407 408 # 80 % OF THE START-TIMEOUT CAN BE SPENT ON WAITING 409 410 MAX_START_TIMEOUT=`expr ${START_TIMEOUT} \* 80 \/ 100` 411 412 # GET CURRENT TIME IN SEC ON 24H BASE 413 414 CUR_HOUR=`date '+%H'` 415 CUR_MIN=`date '+%M'` 416 CUR_SEC=`date '+%S'` 417 CUR_TIME=`expr ${CUR_HOUR} \* 3600 + ${CUR_MIN} \* 60 + ${CUR_SEC}` 418 419 # RUN A TEST LOOP UNTIL THE DEPENDENT RESOURCE IS UP OR 420 # A TIMEOUT HAS OCCURED 421 422 while [ 1 -eq 1 ] 423 do 424 425 # GET NEW CURRENT TIMEOUT 426 NEW_HOUR=`date '+%H'` 427 NEW_MIN=`date '+%M'` 428 NEW_SEC=`date '+%S'` 429 NEW_TIME=`expr ${NEW_HOUR} \* 3600 + ${NEW_MIN} \* 60 + ${NEW_SEC}` 430 431 # HAVE WE EXEEDED TIMEOUT 432 433 s1=`expr ${CUR_TIME} + ${MAX_START_TIMEOUT}` 434 435 if [ ${s1} -le ${NEW_TIME} ]; then 436 # SCMSGS 437 # @explanation 438 # The start of a dependent resource takes too long. 439 # @user_action 440 # None 441 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 442 "start_dependency: Exeeded ${MAX_START_TIMEOUT} seconds for waiting on dependent resource for resource ${RESOURCE} to come online" 443 444 St=1 445 break 446 fi 447 448 # CALL check_start_dependency 449 450 debug_message "Function: start_dependency - Call check_start_dependency function with argument "$* 451 452 check_start_dependency $* 453 St=$? 454 455 if [ ${St} -eq 0 ]; then 456 St=0 457 break 458 fi 459 460 # Wait 5 seconds 461 462 sleep 5 463 done 464 465 466 debug_message "Function: start_dependency - End" 467 468 return ${St} 469 } 470 471 restart_dependency() 472 { 473 debug_message "Function: restart_dependency - Begin" 474 ${SET_DEBUG} 475 476 477 # CALL check_restart_dependency 478 479 debug_message "Function: start_dependency - Call check_restart_dependency function with argument "$* 480 check_restart_dependency $* 481 St=$? 482 483 if [ ${St} -ne 0 ]; then 484 # SCMSGS 485 # @explanation 486 # The dependent resource was restarted, the resource is restarting 487 # now. 488 # @explanation-2 489 # A restart of the dependant resource has been noticed, 490 # it might be necessary to restart the resource depending on 491 # @explanation-3 492 # a restart of the dependant resource has been noticed, it might be 493 # necessary to restart the resource depending on 494 # @explanation-4 495 # a restart of the dependant resource has been noticed, it might be 496 # necessary to restart the resource depending on 497 # @user_action 498 # None 499 # @user_action-2 500 # check the validity of the service. there might be a dependency 501 # problem, a sub resource has been restarted, and functionality 502 # might have been impaired 503 # @user_action-3 504 # check the validity of the service. there might be a dependency 505 # problem, a sub resource has been restarted, and functionality 506 # might have been impaired 507 # @user_action-4 508 # check the validity of the service. there might be a dependency 509 # problem, a sub resource has been restarted, and functionality 510 # might have been impaired 511 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 512 "restart_dependency - Dependent resource to resource %s has been restarted, restart this resource %s" \ 513 "${RESOURCE}" "${RESOURCE}" 514 515 St=100 516 else 517 St=0 518 fi 519 520 debug_message "Function: restart_dependency - End" 521 522 return ${St} 523 } 524 525 start_ssh_agent() 526 { 527 # 528 # Start an ssh-agent and add the decrypted private key. 529 # Only when the ssh-agent contains the private key, a ssh login without a 530 # passphrase challenge is possible. 531 # 532 # This function stores the environment variables SSH_AUTH_SOCK and 533 # SSH_AGENT_PID in /tmp/${RESOURCE}-ssh in a ksh compatible format. 534 # 535 # The start_ssh_agent function is meant to be called in the target users 536 # environment. 537 # 538 # The only necessary parameter is the passphrase of the target users 539 # private ssh key. 540 # If you use this function you should kill the started ssh-agent in your 541 # stop function. 542 # 543 # To do this you have to export the SSH_AGENT_PID from tmp/${RESOURCE}-ssh 544 # in the users environment and call /usr/bin/ssh-agent -k. 545 # 546 # The returncode of the start_ssh_agent function is 0 for success, and 1 for error. 547 548 debug_message "Function: start_ssh_agent - Begin" 549 ${SET_DEBUG} 550 551 SSH_PASS=${1} 552 553 rc_start_ssh_agent=0 554 export DISPLAY="" 555 556 # remove the SSH_ASKPASS script and the temporary store of SSH_AUTH_SOCK 557 # and SSH_AGENT_PID to satisfy noclobber 558 559 ${RM} /tmp/${RESOURCE}-askpass 2>/dev/null 560 ${RM} /tmp/${RESOURCE}-ssh 2>/dev/null 561 562 # start the ssh-agent 563 564 eval `${SSH_AGENT} -s` >/dev/null 2>&1 565 if [ ${?} -eq 0 ] 566 then 567 debug_message "Function: start_ssh_agent - ssh-agent started" 568 569 ${ENV} | ${EGREP} "SSH_AUTH_SOCK|SSH_AGENT_PID">/tmp/${RESOURCE}-ssh 570 571 # create the SSH_ASKPASS script needed for a headless ssh-agent 572 573 export SSH_ASKPASS=/tmp/${RESOURCE}-askpass 574 ${CAT} > ${SSH_ASKPASS} <<EOF 575 #!/usr/bin/ksh 576 # reads a passphrase at the ssh-agent command 577 read x 578 ${ECHO} \${x} 579 EOF 580 ${CHMOD} +x ${SSH_ASKPASS} 581 582 # decrypt the private key and store it in memory 583 584 if print ${SSH_PASS}|${SSH_ADD} >/dev/null 2>&1 585 then 586 debug_message "Function: start_ssh_agent - ssh-add successful, private key decryped and stored" 587 else 588 # SCMSGS 589 # @explanation 590 # The ssh passphrase passed to the start_ssh_agent function is wrong 591 # @user_action 592 # Fix the ssh passphrase entry in your parameters 593 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 594 "start_ssh_agent: The passphrase %s is wrong" \ 595 "${SSH_PASS}" 596 rc_start_ssh_agent=1 597 fi 598 599 # remove the previously created askpass script 600 601 ${RM} ${SSH_ASKPASS} 602 else 603 # SCMSGS 604 # @explanation 605 # The ssh-agent is not startable for the given user 606 # @user_action 607 # Determine and fix the root cause by running the ssh-agent manually 608 # as the target user 609 scds_syslog -p daemon.err -t $(syslog_tag) -m \ 610 "start_ssh_agent: The start of the ssh-agent was unsuccessful" 611 rc_start_ssh_agent=1 612 613 fi 614 615 debug_message "Function: start_ssh_agent - End" 616 return ${rc_start_ssh_agent} 617 618 } 619