init-functions 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. # Begin /lib/lsb/init-funtions
  2. # Provides initialization funtions as defined by the Linux Standard Base
  3. # specification, version 3.1.0
  4. # Source rc configuration if not inherited from the environment
  5. if [ "${RC_BASE}" = "" ]; then
  6. . /etc/sysconfig/rc
  7. fi
  8. # Source the distro functions file
  9. if [ "${DISTRO_MINI}" != "" ]; then
  10. . "${RC_BASE}/init.d/${DISTRO_MINI}-functions"
  11. fi
  12. ################################################################################
  13. # start_daemon() #
  14. # Usage: start_daemon [-f] [-n nicelevel] [-p pidfile] pathname [args...] #
  15. # #
  16. # Purpose: This runs the specified program as a daemon #
  17. # #
  18. # Inputs: -f: (force) run the program even if it is already running. #
  19. # -n nicelevel: specify a nice level. See 'man nice(1)'. #
  20. # -p pidfile: use the specified file to determine PIDs. #
  21. # pathname: the complete path to the specified program #
  22. # args: additional arguments passed to the program (pathname) #
  23. # #
  24. # Return values (as defined by LSB exit codes): #
  25. # 0 - program is running or service is OK #
  26. # 1 - generic or unspecified error #
  27. # 2 - invalid or excessive argument(s) #
  28. # 5 - program is not installed #
  29. ################################################################################
  30. start_daemon()
  31. {
  32. local force=""
  33. local nice="0"
  34. local pidfile=""
  35. local pidlist=""
  36. local retval=""
  37. # Process arguments
  38. while true
  39. do
  40. case "${1}" in
  41. -f)
  42. force="1"
  43. shift 1
  44. ;;
  45. -n)
  46. nice="${2}"
  47. shift 2
  48. ;;
  49. -p)
  50. pidfile="${2}"
  51. shift 2
  52. ;;
  53. -*)
  54. return 2
  55. ;;
  56. *)
  57. program="${1}"
  58. break
  59. ;;
  60. esac
  61. done
  62. # Check for a valid program
  63. if [ ! -e "${program}" ]
  64. then
  65. return 5
  66. fi
  67. # Execute
  68. if [ -z "${force}" ]
  69. then
  70. if [ -z "${pidfile}" ]
  71. then
  72. # determine the pid by discovery
  73. pidlist=`pidofproc "${1}"`
  74. retval="${?}"
  75. else
  76. # The PID file contains the needed PIDs
  77. # Note that by LSB requirement, the path must be given to pidofproc,
  78. # however, it is not used by the current implementation or standard.
  79. pidlist=`pidofproc -p "${pidfile}" "${1}"`
  80. retval="${?}"
  81. fi
  82. # return a value ONLY
  83. # It is the init script's (or distribution's functions) responsibilty
  84. # to log messages!
  85. case "${retval}" in
  86. 0)
  87. # program is already running correctly, this is a
  88. # succesful start.
  89. return 0
  90. ;;
  91. 1)
  92. # program is not running, but an invalid pid file exists
  93. # remove the pid file and continue
  94. rm -f "${pidfile}"
  95. ;;
  96. 3)
  97. # program is not running and no pidfile exists
  98. # do nothing here, let start_deamon continue.
  99. ;;
  100. *)
  101. # Others as returned by status values shall not be interpreted
  102. # and returned as an unspecified error.
  103. return 1
  104. ;;
  105. esac
  106. fi
  107. # do the start!
  108. nice -n "${nice}" "${@}"
  109. }
  110. ################################################################################
  111. # killproc() #
  112. # Usage: killproc [-p pidfile] pathname [signal] #
  113. # #
  114. # Purpose: Send control signals to running processes #
  115. # #
  116. # Inputs: -p pidfile, uses the specified pidfile #
  117. # pathname, pathname to the specified program #
  118. # signal, send this signal to pathname #
  119. # #
  120. # Return values (as defined by LSB exit codes): #
  121. # 0 - program (pathname) has stopped/is already stopped or a #
  122. # running program has been sent specified signal and stopped #
  123. # successfully #
  124. # 1 - generic or unspecified error #
  125. # 2 - invalid or excessive argument(s) #
  126. # 5 - program is not installed #
  127. # 7 - program is not running and a signal was supplied #
  128. ################################################################################
  129. killproc()
  130. {
  131. local pidfile
  132. local program
  133. local prefix
  134. local progname
  135. local signal="-TERM"
  136. local fallback="-KILL"
  137. local nosig
  138. local pidlist
  139. local retval
  140. local pid
  141. local delay="30"
  142. local piddead
  143. local dtime
  144. # Process arguments
  145. while true
  146. do
  147. case "${1}" in
  148. -p)
  149. pidfile="${2}"
  150. shift 2
  151. ;;
  152. *)
  153. program="${1}"
  154. if [ -n "${2}" ]
  155. then
  156. signal="${2}"
  157. fallback=""
  158. else
  159. nosig=1
  160. fi
  161. # error on additional arguments
  162. if [ -n "${3}" ]
  163. then
  164. return 2
  165. else
  166. break
  167. fi
  168. ;;
  169. esac
  170. done
  171. # Check for a valid program
  172. if [ ! -e "${program}" ]
  173. then
  174. return 5
  175. fi
  176. # Check for a valid signal
  177. check_signal "${signal}"
  178. if [ "${?}" != "0" ]
  179. then
  180. return 2
  181. fi
  182. # Get a list of pids
  183. if [ -z "${pidfile}" ]
  184. then
  185. # determine the pid by discovery
  186. pidlist=`pidofproc "${1}"`
  187. retval="${?}"
  188. else
  189. # The PID file contains the needed PIDs
  190. # Note that by LSB requirement, the path must be given to pidofproc,
  191. # however, it is not used by the current implementation or standard.
  192. pidlist=`pidofproc -p "${pidfile}" "${1}"`
  193. retval="${?}"
  194. fi
  195. # return a value ONLY
  196. # It is the init script's (or distribution's functions) responsibilty
  197. # to log messages!
  198. case "${retval}" in
  199. 0)
  200. # program is running correctly
  201. # do nothing here, let killproc continue.
  202. ;;
  203. 1)
  204. # program is not running, but an invalid pid file exists
  205. # remove the pid file.
  206. rm -f "${pidfile}"
  207. # this is only a success if no signal was passed.
  208. if [ -n "${nosig}" ]
  209. then
  210. return 0
  211. else
  212. return 7
  213. fi
  214. ;;
  215. 3)
  216. # program is not running and no pidfile exists
  217. # this is only a success if no signal was passed.
  218. if [ -n "${nosig}" ]
  219. then
  220. return 0
  221. else
  222. return 7
  223. fi
  224. ;;
  225. *)
  226. # Others as returned by status values shall not be interpreted
  227. # and returned as an unspecified error.
  228. return 1
  229. ;;
  230. esac
  231. # perform different actions for exit signals and control signals
  232. check_sig_type "${signal}"
  233. if [ "${?}" -eq "0" ] # signal is used to terminate the program
  234. then
  235. # account for empty pidlist (pid file still exists and nosignal was given)
  236. if [ "${pidlist}" != "" ]; then
  237. #kill the list of pids
  238. for pid in ${pidlist}
  239. do
  240. kill -0 "${pid}" 2> /dev/null
  241. if [ "${?}" -ne "0" ]; then
  242. # process is dead, continue to next and assume all is well
  243. continue
  244. else
  245. kill "${signal}" "${pid}" 2> /dev/null
  246. # Wait up to ${delay}/10 seconds to for "${pid}" to
  247. # terminate in 10ths of a second
  248. while [ "${delay}" != "0" ]
  249. do
  250. kill -0 "${pid}" 2> /dev/null || piddead="1"
  251. if [ "${piddead}" = "1" ]
  252. then
  253. break
  254. fi
  255. sleep 0.1
  256. delay="$(( ${delay} - 1 ))"
  257. done
  258. # If a fallback is set, and program is still running, then
  259. # use the fallback
  260. if [ -n "${fallback}" -a "${piddead}" != "1" ]
  261. then
  262. kill "${fallback}" "${pid}" 2> /dev/null
  263. sleep 1
  264. # Check again, and fail if still running
  265. kill -0 "${pid}" 2> /dev/null && return 1
  266. else
  267. # just check one last time and if still alive, fail
  268. sleep 1
  269. kill -0 "${pid}" 2> /dev/null && return 1
  270. fi
  271. fi
  272. done
  273. fi
  274. # Check for and remove stale PID files.
  275. if [ -z "${pidfile}" ]
  276. then
  277. #find the basename of $program
  278. prefix=`echo "${program}" | sed 's/[^/]*$//'`
  279. progname=`echo "${program}" | sed "s@${prefix}@@"`
  280. if [ -e "/var/run/${progname}.pid" ]
  281. then
  282. rm -f "/var/run/${progname}.pid" 2> /dev/null
  283. fi
  284. else
  285. if [ -e "${pidfile}" ]
  286. then
  287. rm -f "${pidfile}" 2> /dev/null
  288. fi
  289. fi
  290. # For signals that do not expect a program to exit, simply
  291. # let kill do it's job, and evaluate kills return for value
  292. else # check_sig_type - signal is not used to terminate program
  293. for pid in ${pidlist}
  294. do
  295. kill "${signal}" "${pid}"
  296. if [ "${?}" -ne "0" ]; then
  297. return 1
  298. fi
  299. done
  300. fi
  301. }
  302. ################################################################################
  303. # pidofproc() #
  304. # Usage: pidofproc [-p pidfile] pathname #
  305. # #
  306. # Purpose: This function returns one or more pid(s) for a particular daemon #
  307. # #
  308. # Inputs: -p pidfile, use the specified pidfile instead of pidof #
  309. # pathname, path to the specified program #
  310. # #
  311. # Return values (as defined by LSB status codes): #
  312. # 0 - Success (PIDs to stdout) #
  313. # 1 - Program is dead, PID file still exists (remaining PIDs output) #
  314. # 3 - Program is not running (no output) #
  315. ################################################################################
  316. pidofproc()
  317. {
  318. local pidfile
  319. local program
  320. local prefix
  321. local progname
  322. local pidlist
  323. local lpids
  324. local exitstatus="0"
  325. # Process arguments
  326. while true
  327. do
  328. case "${1}" in
  329. -p)
  330. pidfile="${2}"
  331. shift 2
  332. ;;
  333. *)
  334. program="${1}"
  335. if [ -n "${2}" ]
  336. then
  337. # Too many arguments
  338. # Since this is status, return unknown
  339. return 4
  340. else
  341. break
  342. fi
  343. ;;
  344. esac
  345. done
  346. # If a PID file is not specified, try and find one.
  347. if [ -z "${pidfile}" ]
  348. then
  349. # get the program's basename
  350. prefix=`echo "${program}" | sed 's/[^/]*$//'`
  351. progname=`echo "${program}" | sed "s@${prefix}@@"`
  352. # if a PID file exists with that name, assume that is it.
  353. if [ -e "/var/run/${progname}.pid" ]
  354. then
  355. pidfile="/var/run/${progname}.pid"
  356. fi
  357. fi
  358. # if a PID file is set and exists, use it.
  359. if [ -n "${pidfile}" -a -e "${pidfile}" ]
  360. then
  361. # use the value in the first line of the pidfile
  362. pidlist=`/bin/head -n1 "${pidfile}"`
  363. # This can optionally be written as 'sed 1q' to repalce 'head -n1'
  364. # should LFS move /bin/head to /usr/bin/head
  365. else
  366. # use pidof
  367. pidlist=`pidof "${program}"`
  368. fi
  369. # Figure out if all listed PIDs are running.
  370. for pid in ${pidlist}
  371. do
  372. kill -0 ${pid} 2> /dev/null
  373. if [ "${?}" = "0" ]; then
  374. lpids="${pids}${pid} "
  375. else
  376. exitstatus="1"
  377. fi
  378. done
  379. if [ -z "${lpids}" -a ! -f "${pidfile}" ]; then
  380. return 3
  381. else
  382. echo "${lpids}"
  383. return "${exitstatus}"
  384. fi
  385. }
  386. ################################################################################
  387. # log_success_msg() #
  388. # Usage: log_success_msg [$MESSAGE | "message"] #
  389. # #
  390. # Purpose: Print a successful status message to the screen and optionally #
  391. # a boot log file. #
  392. # #
  393. # Inputs: accepts one string value, either a quoted string or optionally #
  394. # the value of $MESSAGE if set in the running environment. #
  395. # #
  396. # Return values: Not used #
  397. ################################################################################
  398. log_success_msg()
  399. {
  400. echo -n -e "${PREFIX_SUCCESS}${@}"
  401. echo -e "${SET_COL}${BRACKET}[${SUCCESS} OK ${BRACKET}]${NORMAL}"
  402. if [ "${BOOTLOG_ENAB}" = "yes" ]; then
  403. if [ $( hostname ) = "(none)" ]; then
  404. BTTIMESPEC=""
  405. else
  406. BTTIMESPEC="$(echo `date -u +"%b %d %T"` `hostname`) "
  407. fi
  408. echo "${BTTIMESPEC}bootlog: ${@} Successful" >> "${TEMPFS_MOUNT}/.bootlog"
  409. fi
  410. return 0
  411. }
  412. ################################################################################
  413. # log_failure_msg() #
  414. # Usage: log_failure_msg [$MESSAGE | "message"] #
  415. # #
  416. # Purpose: Print a failure status message to the screen and optionally #
  417. # a boot log file. #
  418. # #
  419. # Inputs: accepts one string value, either a quoted string or optionally #
  420. # the value of $MESSAGE if set in the running environment. #
  421. # #
  422. # Return values: Not used #
  423. ################################################################################
  424. log_failure_msg()
  425. {
  426. echo -n -e "${PREFIX_FAILURE}${@}"
  427. echo -e "${SET_COL}${BRACKET}[${FAILURE} FAIL ${BRACKET}]${NORMAL}"
  428. if [ "${BOOTLOG_ENAB}" = "yes" ]; then
  429. if [ $( hostname ) = "(none)" ]; then
  430. BTTIMESPEC=""
  431. else
  432. BTTIMESPEC="$(echo `date -u +"%b %d %T"` `hostname`) "
  433. fi
  434. echo "${BTTIMESPEC}bootlog: ${@} Failed!" >> "${TEMPFS_MOUNT}/.bootlog"
  435. fi
  436. return 0
  437. }
  438. ################################################################################
  439. # log_warning_msg() #
  440. # Usage: log_warning_msg [$MESSAGE | "message"] #
  441. # #
  442. # Purpose: Print a warning status message to the screen and optionally #
  443. # a boot log file. #
  444. # #
  445. # Inputs: accepts one string value, either a quoted string or optionally #
  446. # the value of $MESSAGE if set in the running environment. #
  447. # #
  448. # Return values: Not used #
  449. ################################################################################
  450. log_warning_msg()
  451. {
  452. echo -n -e "${PREFIX_WARNING}${@}"
  453. echo -e "${SET_COL}${BRACKET}[${WARNING} WARN ${BRACKET}]${NORMAL}"
  454. if [ "${BOOTLOG_ENAB}" = "yes" ]; then
  455. if [ $( hostname ) = "(none)" ]; then
  456. BTTIMESPEC=""
  457. else
  458. BTTIMESPEC="$(echo `date -u +"%b %d %T"` `hostname`) "
  459. fi
  460. echo "${BTTIMESPEC}bootlog: ${@} Warning" >> "${TEMPFS_MOUNT}/.bootlog"
  461. fi
  462. return 0
  463. }
  464. ################################################################################
  465. # check_signal() #
  466. # Usage: check_signal [ -{signal} | {signal} ] #
  467. # #
  468. # Purpose: Check for a valid signal. This is not defined by any LSB draft, #
  469. # however, it is required to check the signals to determine if the #
  470. # signals chosen are invalid arguments to the other functions. #
  471. # #
  472. # Inputs: accepts a single string value in the form or -{signal} or {signal} #
  473. # #
  474. # Return values: #
  475. # 0 - Success (signal is valid #
  476. # 1 - Signal is not valid #
  477. ################################################################################
  478. check_signal()
  479. {
  480. local valsig
  481. # Add error handling for invalid signals
  482. valsig="-ALRM -HUP -INT -KILL -PIPE -POLL -PROF -TERM -USR1 -USR2"
  483. valsig="${valsig} -VTALRM -STKFLT -PWR -WINCH -CHLD -URG -TSTP -TTIN"
  484. valsig="${valsig} -TTOU -STOP -CONT -ABRT -FPE -ILL -QUIT -SEGV -TRAP"
  485. valsig="${valsig} -SYS -EMT -BUS -XCPU -XFSZ -0 -1 -2 -3 -4 -5 -6 -8 -9"
  486. valsig="${valsig} -11 -13 -14 -15"
  487. echo "${valsig}" | grep -- " ${1} " > /dev/null
  488. if [ "${?}" = "0" ]
  489. then
  490. return 0
  491. else
  492. return 1
  493. fi
  494. }
  495. ################################################################################
  496. # check_sig_type() #
  497. # Usage: check_signal [ -{signal} | {signal} ] #
  498. # #
  499. # Purpose: Check if signal is a program termination signal or a control signal #
  500. # This is not defined by any LSB draft, however, it is required to #
  501. # check the signals to determine if they are intended to end a #
  502. # program or simply to control it. #
  503. # #
  504. # Inputs: accepts a single string value in the form or -{signal} or {signal} #
  505. # #
  506. # Return values: #
  507. # 0 - Signal is used for program termination #
  508. # 1 - Signal is used for program control #
  509. ################################################################################
  510. check_sig_type()
  511. {
  512. local valsig
  513. # The list of termination signals (limited to generally used items)
  514. valsig="-ALRM -INT -KILL -TERM -PWR -STOP -ABRT -QUIT -2 -3 -6 -9 -14 -15"
  515. echo "${valsig}" | grep -- " ${1} " > /dev/null
  516. if [ "${?}" = "0" ]
  517. then
  518. return 0
  519. else
  520. return 1
  521. fi
  522. }
  523. # End /lib/lsb/init-functions