init-functions 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. # /lib/lsb/init-functions for Debian -*- shell-script -*-
  2. #
  3. #Copyright (c) 2002-08 Chris Lawrence
  4. #All rights reserved.
  5. #
  6. #Redistribution and use in source and binary forms, with or without
  7. #modification, are permitted provided that the following conditions
  8. #are met:
  9. #1. Redistributions of source code must retain the above copyright
  10. # notice, this list of conditions and the following disclaimer.
  11. #2. Redistributions in binary form must reproduce the above copyright
  12. # notice, this list of conditions and the following disclaimer in the
  13. # documentation and/or other materials provided with the distribution.
  14. #3. Neither the name of the author nor the names of other contributors
  15. # may be used to endorse or promote products derived from this software
  16. # without specific prior written permission.
  17. #
  18. #THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  19. #IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. #WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. #ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
  22. #LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  23. #CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  24. #SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  25. #BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  26. #WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  27. #OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  28. #EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. start_daemon () {
  30. local force nice pidfile exec args OPTIND
  31. force=""
  32. nice=0
  33. pidfile=/dev/null
  34. OPTIND=1
  35. while getopts fn:p: opt ; do
  36. case "$opt" in
  37. f) force="force";;
  38. n) nice="$OPTARG";;
  39. p) pidfile="$OPTARG";;
  40. esac
  41. done
  42. shift $(($OPTIND - 1))
  43. if [ "$1" = '--' ]; then
  44. shift
  45. fi
  46. exec="$1"; shift
  47. args="--start --nicelevel $nice --quiet --oknodo"
  48. if [ "$force" ]; then
  49. /sbin/start-stop-daemon $args \
  50. --chdir "$PWD" --startas $exec --pidfile /dev/null -- "$@"
  51. elif [ $pidfile ]; then
  52. /sbin/start-stop-daemon $args \
  53. --chdir "$PWD" --exec $exec --oknodo --pidfile "$pidfile" -- "$@"
  54. else
  55. /sbin/start-stop-daemon $args --chdir "$PWD" --exec $exec -- "$@"
  56. fi
  57. }
  58. pidofproc () {
  59. local pidfile base status specified pid OPTIND
  60. pidfile=
  61. specified=
  62. OPTIND=1
  63. while getopts p: opt ; do
  64. case "$opt" in
  65. p) pidfile="$OPTARG"
  66. specified="specified"
  67. ;;
  68. esac
  69. done
  70. shift $(($OPTIND - 1))
  71. if [ $# -ne 1 ]; then
  72. echo "$0: invalid arguments" >&2
  73. return 4
  74. fi
  75. base=${1##*/}
  76. if [ ! "$specified" ]; then
  77. pidfile="/var/run/$base.pid"
  78. fi
  79. if [ -n "${pidfile:-}" ]; then
  80. if [ -e "$pidfile" ]; then
  81. if [ -r "$pidfile" ]; then
  82. read pid < "$pidfile"
  83. if [ -n "${pid:-}" ]; then
  84. if $(kill -0 "${pid:-}" 2> /dev/null); then
  85. echo "$pid" || true
  86. return 0
  87. elif ps "${pid:-}" >/dev/null 2>&1; then
  88. echo "$pid" || true
  89. return 0 # program is running, but not owned by this user
  90. else
  91. return 1 # program is dead and /var/run pid file exists
  92. fi
  93. fi
  94. else
  95. return 4 # pid file not readable, hence status is unknown.
  96. fi
  97. else
  98. # pid file doesn't exist, try to find the pid nevertheless
  99. if [ -x /bin/pidof ] && [ ! "$specified" ]; then
  100. status="0"
  101. /bin/pidof -c -o %PPID -x $1 || status="$?"
  102. if [ "$status" = 1 ]; then
  103. return 3 # program is not running
  104. fi
  105. return 0
  106. fi
  107. return 3 # specified pid file doesn't exist, program probably stopped
  108. fi
  109. fi
  110. if [ "$specified" ]; then
  111. return 3 # almost certain it's not running
  112. fi
  113. return 4 # Unable to determine status
  114. }
  115. # start-stop-daemon uses the same algorithm as "pidofproc" above.
  116. killproc () {
  117. local pidfile sig status base name_param is_term_sig OPTIND
  118. pidfile=
  119. name_param=
  120. is_term_sig=
  121. OPTIND=1
  122. while getopts p: opt ; do
  123. case "$opt" in
  124. p) pidfile="$OPTARG";;
  125. esac
  126. done
  127. shift $(($OPTIND - 1))
  128. base=${1##*/}
  129. if [ ! $pidfile ]; then
  130. name_param="--name $base --pidfile /var/run/$base.pid"
  131. else
  132. name_param="--name $base --pidfile $pidfile"
  133. fi
  134. sig=$(echo ${2:-} | sed -e 's/^-\(.*\)/\1/')
  135. sig=$(echo $sig | sed -e 's/^SIG\(.*\)/\1/')
  136. if [ "$sig" = 15 ] || [ "$sig" = TERM ]; then
  137. is_term_sig="terminate_signal"
  138. fi
  139. status=0
  140. if [ ! "$is_term_sig" ]; then
  141. if [ -n "$sig" ]; then
  142. /sbin/start-stop-daemon --stop --signal "$sig" \
  143. --quiet $name_param || status="$?"
  144. else
  145. /sbin/start-stop-daemon --stop \
  146. --retry 5 \
  147. --quiet $name_param || status="$?"
  148. fi
  149. else
  150. /sbin/start-stop-daemon --stop --quiet \
  151. --oknodo $name_param || status="$?"
  152. fi
  153. if [ "$status" = 1 ]; then
  154. if [ -z "$sig" ]; then
  155. return 0
  156. fi
  157. return 3 # program is not running
  158. fi
  159. if [ "$status" = 0 ] && [ "$is_term_sig" ] && [ "$pidfile" ]; then
  160. pidofproc -p "$pidfile" "$1" >/dev/null || rm -f "$pidfile"
  161. fi
  162. return 0
  163. }
  164. # Return LSB status
  165. status_of_proc () {
  166. local pidfile daemon name status OPTIND
  167. pidfile=
  168. OPTIND=1
  169. while getopts p: opt ; do
  170. case "$opt" in
  171. p) pidfile="$OPTARG";;
  172. esac
  173. done
  174. shift $(($OPTIND - 1))
  175. if [ -n "$pidfile" ]; then
  176. pidfile="-p $pidfile"
  177. fi
  178. daemon="$1"
  179. name="$2"
  180. status="0"
  181. pidofproc $pidfile $daemon >/dev/null || status="$?"
  182. if [ "$status" = 0 ]; then
  183. log_success_msg "$name is running"
  184. return 0
  185. elif [ "$status" = 4 ]; then
  186. log_failure_msg "could not access PID file for $name"
  187. return $status
  188. else
  189. log_failure_msg "$name is not running"
  190. return $status
  191. fi
  192. }
  193. log_use_fancy_output () {
  194. TPUT=/usr/bin/tput
  195. EXPR=/usr/bin/expr
  196. if [ -t 1 ] &&
  197. [ "x${TERM:-}" != "x" ] &&
  198. [ "x${TERM:-}" != "xdumb" ] &&
  199. [ -x $TPUT ] && [ -x $EXPR ] &&
  200. $TPUT hpa 60 >/dev/null 2>&1 &&
  201. $TPUT setaf 1 >/dev/null 2>&1
  202. then
  203. [ -z $FANCYTTY ] && FANCYTTY=1 || true
  204. else
  205. FANCYTTY=0
  206. fi
  207. case "$FANCYTTY" in
  208. 1|Y|yes|true) true;;
  209. *) false;;
  210. esac
  211. }
  212. log_success_msg () {
  213. if [ -n "${1:-}" ]; then
  214. log_begin_msg $@
  215. fi
  216. log_end_msg 0
  217. }
  218. log_failure_msg () {
  219. if [ -n "${1:-}" ]; then
  220. log_begin_msg $@ "..."
  221. fi
  222. log_end_msg 1 || true
  223. }
  224. log_warning_msg () {
  225. if [ -n "${1:-}" ]; then
  226. log_begin_msg $@ "..."
  227. fi
  228. log_end_msg 255 || true
  229. }
  230. #
  231. # NON-LSB HELPER FUNCTIONS
  232. #
  233. # int get_lsb_header_val (char *scriptpathname, char *key)
  234. get_lsb_header_val () {
  235. if [ ! -f "$1" ] || [ -z "${2:-}" ]; then
  236. return 1
  237. fi
  238. LSB_S="### BEGIN INIT INFO"
  239. LSB_E="### END INIT INFO"
  240. sed -n "/$LSB_S/,/$LSB_E/ s/# $2: \+\(.*\)/\1/p" "$1"
  241. }
  242. # If the currently running init daemon is upstart, return zero; if the
  243. # calling init script belongs to a package which also provides a native
  244. # upstart job, it should generally exit non-zero in this case.
  245. init_is_upstart()
  246. {
  247. if [ -x /sbin/initctl ] && /sbin/initctl version 2>/dev/null | /bin/grep -q upstart; then
  248. return 0
  249. fi
  250. return 1
  251. }
  252. # int log_begin_message (char *message)
  253. log_begin_msg () {
  254. log_begin_msg_pre "$@"
  255. if [ -z "${1:-}" ]; then
  256. return 1
  257. fi
  258. echo -n "$@" || true
  259. log_begin_msg_post "$@"
  260. }
  261. # Sample usage:
  262. # log_daemon_msg "Starting GNOME Login Manager" "gdm"
  263. #
  264. # On Debian, would output "Starting GNOME Login Manager: gdm"
  265. # On Ubuntu, would output " * Starting GNOME Login Manager..."
  266. #
  267. # If the second argument is omitted, logging suitable for use with
  268. # log_progress_msg() is used:
  269. #
  270. # log_daemon_msg "Starting remote filesystem services"
  271. #
  272. # On Debian, would output "Starting remote filesystem services:"
  273. # On Ubuntu, would output " * Starting remote filesystem services..."
  274. log_daemon_msg () {
  275. if [ -z "${1:-}" ]; then
  276. return 1
  277. fi
  278. log_daemon_msg_pre "$@"
  279. if [ -z "${2:-}" ]; then
  280. echo -n "$1:" || true
  281. return
  282. fi
  283. echo -n "$1: $2" || true
  284. log_daemon_msg_post "$@"
  285. }
  286. # #319739
  287. #
  288. # Per policy docs:
  289. #
  290. # log_daemon_msg "Starting remote file system services"
  291. # log_progress_msg "nfsd"; start-stop-daemon --start --quiet nfsd
  292. # log_progress_msg "mountd"; start-stop-daemon --start --quiet mountd
  293. # log_progress_msg "ugidd"; start-stop-daemon --start --quiet ugidd
  294. # log_end_msg 0
  295. #
  296. # You could also do something fancy with log_end_msg here based on the
  297. # return values of start-stop-daemon; this is left as an exercise for
  298. # the reader...
  299. #
  300. # On Ubuntu, one would expect log_progress_msg to be a no-op.
  301. log_progress_msg () {
  302. if [ -z "${1:-}" ]; then
  303. return 1
  304. fi
  305. echo -n " $@" || true
  306. }
  307. # int log_end_message (int exitstatus)
  308. log_end_msg () {
  309. # If no arguments were passed, return
  310. if [ -z "${1:-}" ]; then
  311. return 1
  312. fi
  313. local retval
  314. retval=$1
  315. log_end_msg_pre "$@"
  316. # Only do the fancy stuff if we have an appropriate terminal
  317. # and if /usr is already mounted
  318. if log_use_fancy_output; then
  319. RED=$( $TPUT setaf 1)
  320. YELLOW=$( $TPUT setaf 3)
  321. NORMAL=$( $TPUT op)
  322. else
  323. RED=''
  324. YELLOW=''
  325. NORMAL=''
  326. fi
  327. if [ $1 -eq 0 ]; then
  328. echo "." || true
  329. elif [ $1 -eq 255 ]; then
  330. /bin/echo -e " ${YELLOW}(warning).${NORMAL}" || true
  331. else
  332. /bin/echo -e " ${RED}failed!${NORMAL}" || true
  333. fi
  334. log_end_msg_post "$@"
  335. return $retval
  336. }
  337. log_action_msg () {
  338. log_action_msg_pre "$@"
  339. echo "$@." || true
  340. log_action_msg_post "$@"
  341. }
  342. log_action_begin_msg () {
  343. log_action_begin_msg_pre "$@"
  344. echo -n "$@..." || true
  345. log_action_begin_msg_post "$@"
  346. }
  347. log_action_cont_msg () {
  348. echo -n "$@..." || true
  349. }
  350. log_action_end_msg () {
  351. local end
  352. log_action_end_msg_pre "$@"
  353. if [ -z "${2:-}" ]; then
  354. end="."
  355. else
  356. end=" ($2)."
  357. fi
  358. if [ $1 -eq 0 ]; then
  359. echo "done${end}" || true
  360. else
  361. if log_use_fancy_output; then
  362. RED=$( $TPUT setaf 1)
  363. NORMAL=$( $TPUT op)
  364. /bin/echo -e "${RED}failed${end}${NORMAL}" || true
  365. else
  366. echo "failed${end}" || true
  367. fi
  368. fi
  369. log_action_end_msg_post "$@"
  370. }
  371. # Pre&Post empty function declaration, to be overriden from /lib/lsb/init-functions.d/*
  372. log_daemon_msg_pre () { :; }
  373. log_daemon_msg_post () { :; }
  374. log_begin_msg_pre () { :; }
  375. log_begin_msg_post () { :; }
  376. log_end_msg_pre () { :; }
  377. log_end_msg_post () { :; }
  378. log_action_msg_pre () { :; }
  379. log_action_msg_post () { :; }
  380. log_action_begin_msg_pre () { :; }
  381. log_action_begin_msg_post () { :; }
  382. log_action_end_msg_pre () { :; }
  383. log_action_end_msg_post () { :; }
  384. # Include hooks from other packages in /lib/lsb/init-functions.d
  385. for hook in $(run-parts --lsbsysinit --list /lib/lsb/init-functions.d 2>/dev/null); do
  386. [ -r $hook ] && . $hook || true
  387. done
  388. FANCYTTY=
  389. [ -e /etc/lsb-base-logging.sh ] && . /etc/lsb-base-logging.sh || true