systemtap 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. #!/bin/bash
  2. #
  3. # systemtap Startup script for SystemTap scripts
  4. #
  5. # chkconfig: - 00 99
  6. # description: SystemTap is a programmable kernel/application tracing tool.
  7. # config: /etc/systemtap/config
  8. # config: /etc/systemtap/conf.d
  9. ### BEGIN INIT INFO
  10. # Provides: SystemTap scripts startup
  11. # Required-Start: $local_fs
  12. # Required-Stop: $local_fs
  13. # Short-Description: Start and stop SystemTap scripts
  14. # Description: SystemTap is a programmable kernel/application tracing tool.
  15. ### END INIT INFO
  16. # Source function library.
  17. if [ -f /etc/rc.d/init.d/functions ]; then
  18. # Red Hat init functions
  19. . /etc/rc.d/init.d/functions
  20. else
  21. # Default init functions
  22. success () {
  23. echo -n "OK"
  24. }
  25. failure () {
  26. echo -n "FAILED"
  27. }
  28. fi
  29. prog=systemtap
  30. # Commands
  31. STAP=${exec_prefix}/bin/stap
  32. STAPRUN=${exec_prefix}/bin/staprun
  33. UNAME=/bin/uname
  34. LSMOD=/sbin/lsmod
  35. # Path setup
  36. SCRIPT_PATH=/etc/systemtap/script.d
  37. CONFIG_PATH=/etc/systemtap/conf.d
  38. CACHE_PATH=/var/cache/systemtap
  39. STAT_PATH=/run/systemtap
  40. TEMP_PATH=/tmp
  41. LOG_FILE=/var/log/systemtap.log
  42. # FAIL unless all scripts succeeded to run
  43. PASSALL=yes
  44. # Always follows script dependencies
  45. RECURSIVE=no
  46. # Automatically recompile scripts if caches are old or do not exist.
  47. AUTOCOMPILE=yes
  48. # Start these scripts by default. If omitted, all scripts are started.
  49. DEFAULT_START=
  50. # Allow cache only scripts
  51. ALLOW_CACHEONLY=no
  52. # Optional settings
  53. CONFIG=/etc/systemtap/config
  54. SCRIPTS=
  55. KRELEASE=`uname -r`
  56. OPT_RECURSIVE=
  57. OPT_SCRIPTS=
  58. OPTS=
  59. OPT_ASSUMEYES=
  60. echo_usage () {
  61. echo $"Usage: $prog {start|stop|status|restart|compile|cleanup|condrestart|try-restart|reload|force-reload} [option]"
  62. echo $"Options:"
  63. echo $" -c configfile : specify config file"
  64. echo $" -r kernelrelease: specify kernel release version"
  65. echo $" -R : recursively dependency checking"
  66. echo $" -y : answer yes for all questions."
  67. echo $" script(s) : specify systemtap scripts"
  68. }
  69. #-----------------------------------------------------------------
  70. # Helper functions
  71. #-----------------------------------------------------------------
  72. log () { # message
  73. echo `LC_ALL=en date +"%b %e %T"`": $1" >> "$LOG_FILE"
  74. }
  75. clog () { # message [-n]
  76. echo $2 "$1"
  77. log "$1"
  78. }
  79. slog () { # message
  80. logger "$1" # if syslogd is running, this message will be sent to syslog.
  81. log "$1"
  82. }
  83. logex () { # command
  84. eval log \"Exec: $@\"
  85. "$@" >> "$LOG_FILE" 2>&1
  86. return $?
  87. }
  88. do_warning () { # message
  89. slog "Warning: $1"
  90. warning "$1"
  91. }
  92. do_failure () { # message
  93. slog "Error: $1"
  94. failure "$1"
  95. }
  96. do_success () { # message
  97. log "Pass: $1"
  98. success "$1"
  99. }
  100. # Normalize options
  101. check_bool () { # value
  102. case $1 in
  103. n|N|no|No|NO|0)
  104. return 0;;
  105. y|Y|yes|Yes|YES|1)
  106. return 1;;
  107. *)
  108. return 2;;
  109. esac
  110. }
  111. ask_yesno () { # message
  112. local yn ret=2
  113. [ "$OPT_ASSUMEYES" ] && return 1
  114. while [ $ret -eq 2 ]; do
  115. echo -n "$1 [y/N]: "
  116. read yn
  117. [ -z "$yn" ] && return 0
  118. check_bool $yn
  119. ret=$?
  120. done
  121. return $ret
  122. }
  123. #------------------------------------------------------------------
  124. # Parameter parsing and setup options
  125. #------------------------------------------------------------------
  126. parse_args () { # arguments
  127. while [ -n "$1" ]; do
  128. case "$1" in
  129. -c)
  130. CONFIG=$2
  131. shift 1
  132. ;;
  133. -r)
  134. KRELEASE=$2
  135. shift 1
  136. ;;
  137. -R)
  138. OPT_RECURSIVE=1
  139. ;;
  140. -y)
  141. OPT_ASSUMEYES=1
  142. ;;
  143. --)
  144. ;;
  145. *)
  146. OPT_SCRIPTS=$OPT_SCRIPTS\ $1
  147. ;;
  148. esac
  149. shift 1
  150. done
  151. }
  152. CMD=$1
  153. shift 1
  154. OPTS=`getopt -s bash -u -o 'r:c:Ry' -- $@`
  155. if [ $? -ne 0 ]; then
  156. slog "Error: Argument parse error: $@"
  157. failure $"parse error"
  158. echo_usage
  159. exit 3
  160. fi
  161. parse_args $OPTS
  162. # Include configs
  163. . "$CONFIG"
  164. for f in "$CONFIG_PATH"/*.conf; do
  165. if [ -f "$f" ]; then
  166. . "$f"
  167. fi
  168. done
  169. check_bool $PASSALL
  170. PASSALL=$?
  171. check_bool $RECURSIVE
  172. RECURSIVE=$?
  173. if [ "$OPT_RECURSIVE" ]; then # -r option overrides RECURSIVE.
  174. RECURSIVE=1
  175. fi
  176. check_bool $AUTOCOMPILE
  177. AUTOCOMPILE=$?
  178. CACHE_PATH="$CACHE_PATH/$KRELEASE"
  179. check_bool $ALLOW_CACHEONLY
  180. ALLOW_CACHEONLY=$?
  181. __get_all_scripts () {
  182. local s
  183. if [ $ALLOW_CACHEONLY -eq 1 ]; then
  184. for s in "$CACHE_PATH"/*.ko; do
  185. if [ -f "$s" ]; then
  186. basename "$s" | sed s/\.ko$//g
  187. fi
  188. done
  189. fi
  190. for s in "$SCRIPT_PATH"/*.stp; do
  191. if [ -f "$s" ]; then
  192. basename "$s" | sed s/\.stp$//g
  193. fi
  194. done
  195. }
  196. get_all_scripts() {
  197. __get_all_scripts | sort | uniq
  198. }
  199. if [ -z "$OPT_SCRIPTS" ]; then
  200. SCRIPTS=`get_all_scripts | xargs`
  201. RECURSIVE=1
  202. else
  203. SCRIPTS="$OPT_SCRIPTS"
  204. fi
  205. #------------------------------------------------------------------
  206. # Main routine
  207. #------------------------------------------------------------------
  208. NR_FAILS=0
  209. might_fail () { # message exitcode
  210. if [ $PASSALL -eq 1 ]; then
  211. do_failure "$1"
  212. echo
  213. [ -z "$2" ] && exit 1
  214. exit $2
  215. else
  216. log "Warning: "$1
  217. NR_FAILS=$((NR_FAILS+1))
  218. return 0
  219. fi
  220. }
  221. might_success () { # message
  222. if [ $NR_FAILS -ne 0 ]; then
  223. log "Warning: $NR_FAILS failure occurred."
  224. do_warning "$1"
  225. else
  226. do_success "$1"
  227. fi
  228. return 0
  229. }
  230. get_all_runnings () {
  231. local f
  232. for f in "$STAT_PATH"/*; do
  233. if [ -f "$f" ]; then
  234. basename "$f"
  235. fi
  236. done
  237. }
  238. get_daemon_pid () { # script
  239. cat "$STAT_PATH/$1"
  240. }
  241. # Check whether a script is running. Returns:
  242. # 0: running
  243. # 4: running, but no pidfile
  244. # 3: not running
  245. # 1: not running, but pidfile remains
  246. check_running () { # script
  247. local m f
  248. f="$STAT_PATH/$1"
  249. m=`$LSMOD | grep "^$1 "`
  250. if [ -n "$m" ]; then
  251. [ -f "$f" ] && return 0 # running
  252. return 4 # another script is running
  253. else
  254. [ -f "$f" ] && return 1 # dead, but pidfile remains
  255. return 3 # dead
  256. fi
  257. }
  258. # check whether a script cache need to be updated.
  259. check_cache () { # script opts
  260. local s tmp tmp2
  261. s=$1; shift 1
  262. [ ! -f "$CACHE_PATH/$s.ko" -o ! -f "$CACHE_PATH/$s.opts" ] && return 1
  263. if [ $ALLOW_CACHEONLY -ne 1 -o -f "$SCRIPT_PATH/$s.stp" ]; then
  264. [ "$SCRIPT_PATH/$s.stp" -nt "$CACHE_PATH/$s.ko" ] && return 2
  265. fi
  266. tmp=`head -n 1 "$CACHE_PATH/$s.opts"`
  267. tmp2=`$UNAME -a`
  268. [ "$tmp" != "$tmp2" ] && return 3
  269. tmp=`tail -n 1 "$CACHE_PATH/$s.opts"`
  270. tmp2="$*"
  271. [ "$tmp" != "$tmp2" ] && return 4
  272. return 0
  273. }
  274. stap_getopt () { # opts
  275. local ret
  276. # TODO: support quoted options
  277. getopt -s bash -u \
  278. -l 'kelf,kmap::,ignore-vmlinux,ignore-dwarf,vp:' \
  279. -o 'hVvtp:I:e:o:R:r:m:kgPc:x:D:bs:uqwl:d:L:FS:' -- $@
  280. ret=$?
  281. [ $ret -ne 0 ] && slog "Failed to parse parameters. ($@)"
  282. return $ret
  283. }
  284. get_compile_opts () { # opts
  285. local opts o skip
  286. opts=`stap_getopt $*`
  287. [ $? -ne 0 ] && return 1
  288. skip=0
  289. for o in $opts; do
  290. if [ $skip -ne 0 ]; then skip=0; continue; fi
  291. case $o in
  292. -p|-m|-r|-c|-x|-e|-s|-o|-S)
  293. skip=1 ;;
  294. -h|-V|-k|-F)
  295. ;;
  296. *)
  297. echo -n $o" " ;;
  298. esac
  299. done
  300. }
  301. get_run_opts () { # normalized_opts
  302. local opts o show mode
  303. opts=`stap_getopt $*`
  304. [ $? -ne 0 ] && return 1
  305. mode='-L'
  306. show=0
  307. for o in $opts; do
  308. case $o in
  309. -c|-x|-s|-o|-S)
  310. [ $o == '-s' ] && o='-b'
  311. [ $o == '-o' ] && mode='-D'
  312. echo -n $o" "
  313. show=1
  314. ;;
  315. *)
  316. if [ $show -ne 0 ]; then
  317. echo -n $o" "
  318. show=0
  319. fi
  320. ;;
  321. esac
  322. done
  323. echo -n $mode
  324. }
  325. prepare_cache_dir () {
  326. if [ ! -d "$CACHE_PATH" ]; then
  327. logex mkdir -p "$CACHE_PATH"
  328. [ $? -ne 0 ] && return 1
  329. fi
  330. return 0
  331. }
  332. prepare_stat_dir () {
  333. if [ ! -d "$STAT_PATH" ]; then
  334. logex mkdir -p "$STAT_PATH"
  335. [ $? -ne 0 ] && return 1
  336. fi
  337. return 0
  338. }
  339. compile_script () { # script checkcache
  340. local opts f tmpdir ret
  341. eval f="$SCRIPT_PATH/$1.stp"
  342. if [ ! -f "$f" ]; then
  343. if [ $ALLOW_CACHEONLY -eq 1 ]; then
  344. clog "Warning: no script file($f). Use compiled cache."
  345. return 0
  346. else
  347. clog "Error: no script file($f)."
  348. return 1
  349. fi
  350. fi
  351. eval opts=\$$1_OPT
  352. opts=`get_compile_opts $opts`
  353. [ $? -ne 0 ] && return 2
  354. if [ "$2" = "check" ]; then
  355. check_cache $1 $opts
  356. [ $? -eq 0 ] && return 0 # already compiled
  357. if [ $AUTOCOMPILE -eq 0 ]; then
  358. slog "No valid cache for $1"
  359. return 1
  360. fi
  361. fi
  362. clog " Compiling $1 ... " -n
  363. tmpdir=`mktemp -d -p "$TEMP_PATH" cache.XXXXXXXX`
  364. if [ $? -ne 0 ]; then
  365. clog "Failed to create temporary directory."
  366. return 1
  367. fi
  368. pushd "$tmpdir" &> /dev/null
  369. logex $STAP -m "$1" -p4 -r $KRELEASE $opts "$f"
  370. ret=$?
  371. if [ $ret -eq 0 ]; then
  372. $UNAME -a > "$1.opts"
  373. echo $opts >> "$1.opts"
  374. logex mv "$1.ko" "$1.opts" "$CACHE_PATH/"
  375. ret=$?
  376. else
  377. slog "Failed to compile script($1)."
  378. fi
  379. popd &> /dev/null
  380. rm -rf $tmpdir
  381. [ $ret -eq 0 ] && clog "done" || clog "error"
  382. return $ret
  383. }
  384. # dependency resolver
  385. __SORTED=
  386. __follow_dependency () { # script requesters
  387. local opts r reqs s ret
  388. s=$1
  389. shift 1
  390. r=`echo \ $*\ | grep \ $s\ `
  391. if [ -n "$r" ]; then
  392. might_fail $"Dependency loop detected on $s"
  393. return 1
  394. fi
  395. r=`echo \ $__SORTED\ | grep \ $s\ `
  396. [ -n "$r" ] && return 0 # already listed up
  397. eval reqs=\$${s}_REQ
  398. if [ -n "$reqs" ]; then
  399. for r in $reqs; do
  400. __follow_dependency $r $s $*
  401. ret=$?
  402. if [ $ret -ne 0 ]; then
  403. return $ret # if one of requires failed, we can't run this script.
  404. fi
  405. done
  406. fi
  407. echo -n "$s "
  408. return 0
  409. }
  410. sort_dependency () { # scripts
  411. local s r=0
  412. __SORTED=
  413. for s in $*; do
  414. __SORTED="$__SORTED "`__follow_dependency $s`
  415. [ $? -ne 0 ] && return 1
  416. done
  417. echo $__SORTED
  418. return 0
  419. }
  420. start_script () { # script
  421. local tmpdir s=$1 ret count=0
  422. check_running $s
  423. ret=$?
  424. [ $ret -eq 0 ] && return 0 # already running
  425. if [ $ret -eq 4 ]; then
  426. clog "$s is dead, but another script is running."
  427. return 4
  428. fi
  429. compile_script $s check
  430. ret=$?
  431. [ $ret -ne 0 ] && return $ret
  432. eval opts=\$${s}_OPT
  433. opts=`get_run_opts $opts`
  434. [ $? -ne 0 ] && return 2
  435. clog " Starting $1 ... " -n
  436. tmpdir=`mktemp -d -p "$TEMP_PATH" cache.XXXXXXXX` # bz7097
  437. if [ $? -ne 0 ]; then
  438. clog "Failed to create temporary directory."
  439. return 1
  440. fi
  441. pushd "$tmpdir" &> /dev/null
  442. eval log \"Exec: $STAPRUN $opts $CACHE_PATH/$s.ko\"
  443. $STAPRUN $opts "$CACHE_PATH/$s.ko" 2>> "$LOG_FILE" > ./pid
  444. ret=$?
  445. # When the staprun '-D' option (run in background as a daemon) is
  446. # used, staprun detaches from the terminal and *then* prints the new
  447. # pid. So, it is possible to check the ./pid file before it has
  448. # been written. To avoid this, wait a bit (if necessary).
  449. while [ $count -lt 10 ]; do
  450. # when the file exists and has a size > 0, quit
  451. [ -s ./pid ] && break
  452. sleep 1
  453. count=`expr $count + 1`
  454. done
  455. [ x`cat ./pid` = x ] && echo 0 > ./pid
  456. if [ $ret -eq 0 ]; then
  457. logex cp -f ./pid "$STAT_PATH/$s"
  458. fi
  459. popd &> /dev/null
  460. rm -rf "$tmpdir"
  461. [ $ret -eq 0 ] && clog "done" || clog "error"
  462. return $ret
  463. }
  464. start () {
  465. local start_scripts s ret
  466. clog $"Starting $prog: " -n
  467. start_scripts=$SCRIPTS
  468. if [ -n "$DEFAULT_START" -a -z "$OPT_SCRIPTS" ]; then
  469. start_scripts="$DEFAULT_START"
  470. fi
  471. if [ -z "$start_scripts" ]; then
  472. do_warning $"No scripts exist."
  473. return 5 # program is not installed
  474. fi
  475. prepare_stat_dir
  476. if [ $? -ne 0 ]; then
  477. do_failure $"Failed to make stat directory ($STAT_PATH)"
  478. return 1
  479. fi
  480. prepare_cache_dir
  481. if [ $? -ne 0 ]; then
  482. do_failure $"Failed to make cache directory ($CACHE_PATH)"
  483. return 1
  484. fi
  485. if [ $RECURSIVE -eq 1 ]; then
  486. start_scripts=`sort_dependency $start_scripts`
  487. if [ $? -ne 0 ]; then
  488. do_failure $"Failed to sort dependency"
  489. return 6 # program is not configured
  490. fi
  491. fi
  492. for s in $start_scripts; do
  493. start_script "$s"
  494. ret=$?
  495. if [ $ret -ne 0 ]; then
  496. might_fail $"Failed to run \"$s\". ($ret)"
  497. fi
  498. done
  499. might_success $"$prog startup"
  500. return 0
  501. }
  502. stop_script () { # script
  503. local p f count=0
  504. f="$STAT_PATH/$1"
  505. while [ $count -lt 10 ]; do
  506. check_running "$1"
  507. ret=$?
  508. # If the module is isn't running, we're done.
  509. [ $ret -eq 3 ] && return 0
  510. # If the module isn't loaded but the pidfile remains, remove the
  511. # old pidfile and return.
  512. if [ $ret -eq 1 ]; then
  513. rm -f $f
  514. return 0
  515. fi
  516. # Try to either kill the stap process that is handling the
  517. # module (which will cause the module to be unloaded) or use
  518. # staprun to delete the module. (Note that staprun will only
  519. # delete systemtap modules.)
  520. p=`get_daemon_pid $1`
  521. if [ $p -ne 0 ]; then
  522. logex kill -TERM $p
  523. else
  524. logex $STAPRUN -d "$1"
  525. fi
  526. [ $? -ne 0 ] && return 1
  527. # At this point the module should be unloaded, but the pidfile
  528. # will still be present. If so, remove the pidfile and return.
  529. # Otherwise, wait a bit for the module to unload and try again.
  530. check_running "$1"
  531. ret=$?
  532. [ $ret -eq 3 ] && return 0
  533. if [ $ret -eq 1 ]; then
  534. rm -f $f
  535. return 0
  536. fi
  537. sleep 1
  538. count=`expr $count + 1`
  539. done
  540. do_failure $"Failed to stop script \"$1\" after $count attempts"
  541. return 1
  542. }
  543. stop () {
  544. local stop_scripts s sl=
  545. clog $"Stopping $prog: " -n
  546. stop_scripts=$SCRIPTS
  547. [ -z "$OPT_SCRIPTS" ] && stop_scripts=`get_all_runnings`
  548. if [ $RECURSIVE -eq 1 ]; then
  549. stop_scripts=`sort_dependency $stop_scripts`
  550. if [ $? -ne 0 ]; then
  551. do_failure $"Failed to sort dependency"
  552. return 6 # program is not configured
  553. fi
  554. fi
  555. for s in $stop_scripts; do
  556. sl="$s $sl"
  557. done
  558. for s in $sl; do
  559. stop_script $s
  560. [ $? -ne 0 ] && might_fail $"Failed to stop \"$s\". "
  561. done
  562. might_success $"$prog stopping "
  563. return 0
  564. }
  565. rh_status () {
  566. local status_scripts s pid ret r
  567. status_scripts=$SCRIPTS
  568. [ -z "$status_scripts" ] && status_scripts=`get_all_runnings`
  569. ret=3
  570. if [ -z "$status_scripts" ] ; then
  571. echo "No systemtap scripts are present"
  572. return $ret
  573. fi
  574. for s in $status_scripts; do
  575. check_running $s
  576. r=$?
  577. [ $ret -ne 0 ] && ret=$r
  578. case $r in
  579. 0)
  580. pid=`get_daemon_pid $s`
  581. [ $pid -ne 0 ] && pid="($pid)" || pid=
  582. echo $"$s$pid is running..." ;;
  583. 1|3) echo $"$s is stopped" ;;
  584. 4) echo $"$s is dead, but another script is running.";;
  585. esac
  586. done
  587. return $ret
  588. }
  589. rh_status_q () {
  590. rh_status >/dev/null 2>&1
  591. return $?
  592. }
  593. compile () {
  594. local s ss
  595. clog $"Compiling systemtap scripts: " -n
  596. prepare_cache_dir
  597. if [ $? -ne 0 ]; then
  598. do_failure $"Failed to make cache directory ($CACHE_PATH)"
  599. return 1
  600. fi
  601. for s in $SCRIPTS; do
  602. ss="$ss "`ls "$CACHE_PATH/$s.ko" "$CACHE_PATH/$s.opts" 2> /dev/null`
  603. done
  604. ss=`echo -n $ss`
  605. if [ "$ss" ]; then
  606. clog "Updating caches: $ss"
  607. ask_yesno "Do you really want to update above caches"
  608. [ $? -eq 0 ] && return 0
  609. fi
  610. for s in $SCRIPTS; do
  611. compile_script $s nocheck
  612. [ $? -ne 0 ] && might_fail $"$s compilation failed "
  613. done
  614. might_success $"$prog compiled "
  615. return 0
  616. }
  617. # Cleanup caches
  618. cleanup () {
  619. local s ss ret
  620. clog $"Cleaning up systemtap scripts: " -n
  621. if [ ! -d "$CACHE_PATH" ]; then
  622. do_success "no cache"
  623. return 0
  624. fi
  625. for s in $SCRIPTS; do
  626. ss="$ss "`ls "$CACHE_PATH/$s.ko" "$CACHE_PATH/$s.opts" 2> /dev/null`
  627. done
  628. ss=`echo -n $ss`
  629. if [ "$ss" ]; then
  630. echo "Removing caches: $ss"
  631. ask_yesno "Do you really want to remove above caches"
  632. [ $? -eq 0 ] && return 0
  633. for s in $SCRIPTS; do
  634. logex rm -f "$CACHE_PATH/$s.ko" "$CACHE_PATH/$s.opts"
  635. [ $? -ne 0 ] && might_fail $"failed to clean cache $s.ko"
  636. done
  637. might_success "done"
  638. return 0
  639. fi
  640. }
  641. # Restart scripts
  642. function restart () {
  643. stop
  644. echo # we need a newline
  645. start
  646. return $?
  647. }
  648. RETVAL=0
  649. case $CMD in
  650. start)
  651. start
  652. RETVAL=$?
  653. ;;
  654. stop)
  655. stop
  656. RETVAL=$?
  657. ;;
  658. restart|force-reload|reload)
  659. restart
  660. RETVAL=$?
  661. ;;
  662. status)
  663. rh_status
  664. exit $?
  665. ;;
  666. compile)
  667. compile
  668. RETVAL=$?
  669. ;;
  670. cleanup)
  671. cleanup
  672. RETVAL=$?
  673. ;;
  674. condrestart|try-restart)
  675. rh_status_q || exit 0
  676. restart
  677. RETVAL=$?
  678. ;;
  679. *)
  680. echo_usage
  681. RETVAL=3
  682. ;;
  683. esac
  684. echo
  685. exit $RETVAL