functions.xml 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. <sect1 id="ch07-functions">
  2. <title>Creating the functions script</title>
  3. <para>
  4. A new file <filename>/etc/init.d/functions</filename> is created containing
  5. the following:
  6. </para>
  7. <literallayout>
  8. <userinput>cat &gt; functions &lt;&lt; "EOF"</userinput>
  9. #!/bin/sh
  10. # Begin /etc/init.d/functions
  11. #
  12. # Set a few variables that influence the text that's printed on the
  13. # screen. The SET_COL variable starts the text in column number 70 (as
  14. # defined by the COL variable). NORMAL prints text in normal mode.
  15. # SUCCESS prints text in a green colour and FAILURE prints text in a red
  16. # colour
  17. #
  18. COL=70
  19. WCOL=50
  20. SET_COL="echo -en \\033[${COL}G"
  21. SET_WCOL="echo -en \\033[${WCOL}G"
  22. NORMAL="echo -en \\033[0;39m"
  23. SUCCESS="echo -en \\033[1;32m"
  24. WARNING="echo -en \\033[1;33m"
  25. FAILURE="echo -en \\033[1;31m"
  26. #
  27. # The evaluate_retval function evaluates the return value of the process
  28. # that was run just before this function was called. If the return value
  29. # was 0, indicating success, the print_status function is called with
  30. # the 'success' parameter. Otherwise the print_status function is called
  31. # with the failure parameter.
  32. #
  33. evaluate_retval()
  34. {
  35. if [ $? = 0 ]
  36. then
  37. print_status success
  38. else
  39. print_status failure
  40. fi
  41. }
  42. #
  43. # The print_status prints [ OK ] or [FAILED] to the screen. OK appears
  44. # in the colour defined by the SUCCESS variable and FAILED appears in
  45. # the colour defined by the FAILURE variable. Both are printed starting
  46. # in the column defined by the COL variable.
  47. #
  48. print_status()
  49. {
  50. #
  51. # If no parameters are given to the print_status function, print usage
  52. # information.
  53. #
  54. if [ $# = 0 ]
  55. then
  56. echo "Usage: print_status {success|failure}"
  57. return 1
  58. fi
  59. case "$1" in
  60. success)
  61. $SET_COL
  62. echo -n "[ "
  63. $SUCCESS
  64. echo -n "OK"
  65. $NORMAL
  66. echo " ]"
  67. ;;
  68. warning)
  69. $SET_COL
  70. echo -n "[ "
  71. $WARNING
  72. echo -n "ATTN"
  73. $NORMAL
  74. echo " ]"
  75. ;;
  76. failure)
  77. $SET_COL
  78. echo -n "["
  79. $FAILURE
  80. echo -n "FAILED"
  81. $NORMAL
  82. echo "]"
  83. ;;
  84. esac
  85. }
  86. #
  87. # The loadproc function starts a process (often a daemon) with
  88. # proper error checking
  89. #
  90. loadproc()
  91. {
  92. #
  93. # If no parameters are given to the print_status function, print usage
  94. # information.
  95. #
  96. if [ $# = 0 ]
  97. then
  98. echo "Usage: loadproc {program}"
  99. exit 1
  100. fi
  101. #
  102. # Find the basename of the first parameter (the daemon's name without
  103. # the path
  104. # that was provided so /usr/sbin/syslogd becomes plain 'syslogd' after
  105. # basename ran)
  106. #
  107. base=$(/usr/bin/basename $1)
  108. #
  109. # the pidlist variable will contains the output of the pidof command.
  110. # pidof will try to find the PID's that belong to a certain string;
  111. # $base in this case
  112. #
  113. pidlist=$(/bin/pidof -o $$ -o $PPID -o %PPID -x $base)
  114. pid=""
  115. for apid in $pidlist
  116. do
  117. if [ -d /proc/$apid ]
  118. then
  119. pid="$pid $apid"
  120. fi
  121. done
  122. #
  123. # If the $pid variable contains anything (from the previous for loop) it
  124. # means the daemon is already running
  125. #
  126. if [ ! -n "$pid" ]
  127. then
  128. #
  129. # Empty $pid variable means it's not running, so we run "$@" (all
  130. # parameters giving to this function from the script) and then check the
  131. # return value
  132. #
  133. "$@"
  134. evaluate_retval
  135. else
  136. #
  137. # The variable $pid was not empty, meaning it was already running. We'll
  138. # print [ ATTN ] now
  139. #
  140. $SET_WCOL
  141. echo -n "Already running"
  142. print_status warning
  143. fi
  144. }
  145. #
  146. # The killproc function kills a process with proper error checking
  147. #
  148. killproc()
  149. {
  150. #
  151. # If no parameters are given to the print_status function, print usage
  152. # information.
  153. #
  154. if [ $# = 0 ]
  155. then
  156. echo "Usage: killproc {program} [signal]"
  157. exit 1
  158. fi
  159. #
  160. # Find the basename of the first parameter (the daemon's name without
  161. # the path
  162. # that was provided so /usr/sbin/syslogd becomes plain 'syslogd' after
  163. # basename ran)
  164. #
  165. base=$(/usr/bin/basename $1)
  166. #
  167. # Check if we gave a signal to kill the process with (like -HUP, -TERM,
  168. # -KILL, etc) to this function (the second parameter). If no second
  169. # parameter was provided set the nolevel variable. Else set the
  170. # killlevel variable to the value of $2 (the second parameter)
  171. #
  172. if [ "$2" != "" ]
  173. then
  174. killlevel=-$2
  175. else
  176. nolevel=1
  177. fi
  178. #
  179. # the pidlist variable will contains the output of the pidof command.
  180. # pidof will try to find the PID's that belong to a certain string;
  181. # $base in this case
  182. #
  183. pidlist=$(/bin/pidof -o $$ -o $PPID -o %PPID -x $base)
  184. pid=""
  185. for apid in $pidlist
  186. do
  187. if [ -d /proc/$apid ]
  188. then
  189. pid="$pid $apid"
  190. fi
  191. done
  192. #
  193. # If $pid contains something from the previous for loop it means one or
  194. # more PID's were found that belongs to the processes to be killed
  195. #
  196. if [ -n "$pid" ]
  197. then
  198. #
  199. # If no kill level was specified we'll try -TERM first and then sleep
  200. # for 2 seconds to allow the kill to be completed
  201. #
  202. if [ "$nolevel" = 1 ]
  203. then
  204. /bin/kill -TERM $pid
  205. #
  206. # If after -TERM the PID still exists we'll wait 2 seconds before
  207. # trying to kill it with -KILL. If the PID still exist after that, wait
  208. # two more seconds. If the PIDs still exist by then it's safe to assume
  209. # that we cannot kill these PIDs.
  210. #
  211. if /bin/ps h $pid &gt;/dev/null 2&gt;&amp;1
  212. then
  213. /usr/bin/sleep 2
  214. if /bin/ps h $pid &gt; /dev/null 2&gt;&amp;1
  215. then
  216. /bin/kill -KILL $pid
  217. if /bin/ps h $pid &gt; /dev/null 2&gt;&amp;1
  218. then
  219. /usr/bin/sleep 2
  220. fi
  221. fi
  222. fi
  223. /bin/ps h $pid &gt;/dev/null 2&gt;&amp;1
  224. if [ $? = 0 ]
  225. then
  226. #
  227. # If after the -KILL it still exists it can't be killed for some reason
  228. # and we'll print [FAILED]
  229. #
  230. print_status failure
  231. else
  232. #
  233. # It was killed, remove possible stale PID file in /var/run and
  234. # print [ OK ]
  235. #
  236. /bin/rm -f /var/run/$base.pid
  237. print_status success
  238. fi
  239. else
  240. #
  241. # A kill level was provided. Kill with the provided kill level and wait
  242. # for 2 seconds to allow the kill to be completed
  243. #
  244. /bin/kill $killlevel $pid
  245. if /bin/ps h $pid &gt; /dev/null 2&gt;&amp;1
  246. then
  247. /usr/bin/sleep 2
  248. fi
  249. /bin/ps h $pid &gt;/dev/null 2&gt;&amp;1
  250. if [ $? = 0 ]
  251. then
  252. #
  253. # If ps' return value is 0 it means it ran ok which indicates that the
  254. # PID still exists. This means the process wasn't killed properly with
  255. # the signal provided. Print [FAILED]
  256. #
  257. print_status failure
  258. else
  259. #
  260. # If the return value was 1 or higher it means the PID didn't exist
  261. # anymore which means it was killed successfully. Remove possible stale
  262. # PID file and print [ OK ]
  263. #
  264. /bin/rm -f /var/run/$base.pid
  265. print_status success
  266. fi
  267. fi
  268. else
  269. #
  270. # The PID didn't exist so we can't attempt to kill it. Print [ ATTN ]
  271. #
  272. $SET_WCOL
  273. echo -n "Not running"
  274. print_status warning
  275. fi
  276. }
  277. #
  278. # The reloadproc functions sends a signal to a daemon telling it to
  279. # reload it's configuration file. This is almost identical to the
  280. # killproc function with the exception that it won't try to kill it with
  281. # a -KILL signal (aka -9)
  282. #
  283. reloadproc()
  284. {
  285. #
  286. # If no parameters are given to the print_status function, print usage
  287. # information.
  288. #
  289. if [ $# = 0 ]
  290. then
  291. echo "Usage: reloadproc {program} [signal]"
  292. exit 1
  293. fi
  294. #
  295. # Find the basename of the first parameter (the daemon's name without
  296. # the path that was provided so /usr/sbin/syslogd becomes plain 'syslogd'
  297. # after basename ran)
  298. #
  299. base=$(/usr/bin/basename $1)
  300. #
  301. # Check if we gave a signal to send to the process (like -HUP)
  302. # to this function (the second parameter). If no second
  303. # parameter was provided set the nolevel variable. Else set the
  304. # killlevel variable to the value of $2 (the second parameter)
  305. #
  306. if [ -n "$2" ]
  307. then
  308. killlevel=-$2
  309. else
  310. nolevel=1
  311. fi
  312. #
  313. # the pidlist variable will contains the output of the pidof command.
  314. # pidof will try to find the PID's that belong to a certain string;
  315. # $base in this case
  316. #
  317. pidlist=$(/bin/pidof -o $$ -o $PPID -o %PPID -x $base)
  318. pid=""
  319. for apid in $pidlist
  320. do
  321. if [ -d /proc/$apid ]
  322. then
  323. pid="$pid $apid"
  324. fi
  325. done
  326. #
  327. # If $pid contains something from the previous for loop it means one or
  328. # more PID's were found that belongs to the processes to be reloaded
  329. #
  330. if [ -n "$pid" ]
  331. then
  332. #
  333. # If nolevel was set we will use the default reload signal SIGHUP.
  334. #
  335. if [ "$nolevel" = 1 ]
  336. then
  337. /bin/kill -SIGHUP $pid
  338. evaluate_retval
  339. else
  340. #
  341. # Else we will use the provided signal
  342. #
  343. /bin/kill $killlevel $pid
  344. evaluate_retval
  345. fi
  346. else
  347. #
  348. # If $pid is empty no PID's have been found that belong to the process.
  349. # Print [ ATTN ]
  350. #
  351. $SET_WCOL
  352. echo -n "Not running"
  353. print_status warning
  354. fi
  355. }
  356. #
  357. # The statusproc function will try to find out if a process is running
  358. # or not
  359. #
  360. statusproc()
  361. {
  362. #
  363. # If no parameters are given to the print_status function, print usage
  364. # information.
  365. #
  366. if [ $# = 0 ]
  367. then
  368. echo "Usage: status {program}"
  369. return 1
  370. fi
  371. #
  372. # $pid will contain a list of PID's that belong to a process
  373. #
  374. pid=$(/bin/pidof -o $$ -o $PPID -o %PPID -x $1)
  375. if [ -n "$pid" ]
  376. then
  377. #
  378. # If $pid contains something, the process is running, print the contents
  379. # of the $pid variable
  380. #
  381. echo "$1 running with Process ID $pid"
  382. return 0
  383. fi
  384. #
  385. # If $pid doesn't contain it check if a PID file exists and inform the
  386. # user about this stale file.
  387. #
  388. if [ -f /var/run/$1.pid ]
  389. then
  390. pid=$(/usr/bin/head -1 /var/run/$1.pid)
  391. if [ -n "$pid" ]
  392. then
  393. echo "$1 not running but /var/run/$1.pid exists"
  394. return 1
  395. fi
  396. else
  397. echo "$1 is not running"
  398. fi
  399. }
  400. # End /etc/init.d/functions
  401. <userinput>EOF</userinput>
  402. </literallayout>
  403. </sect1>