New functions_static.ksh
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 "%Z%%M% %I% %E% 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 }