logo

oasis-root

Compiled tree of Oasis Linux based on own branch at <https://hacktivis.me/git/oasis/> git clone https://anongit.hacktivis.me/git/oasis-root.git

perpetrate.5 (10979B)


  1. .\" perpetrate.5
  2. .\" wcm, 2009.12.02 - 2013.01.09
  3. .\" ===
  4. .TH perpetrate 5 "January 2013" "perp-2.07" "persistent process supervision"
  5. .SH NAME
  6. perpetrate \- conventions for runscripts
  7. .SH DESCRIPTION
  8. .BR perpd (8)
  9. operates on a pair of ``runscripts'' that are executed to start and reset
  10. a service and an optional logger.
  11. .PP
  12. The runscripts recognized by
  13. .BR perpd (8)
  14. are:
  15. .PP
  16. .I rc.log
  17. .RS
  18. Optional. Controls the logger for the main service.
  19. .RE
  20. .PP
  21. .I rc.main
  22. .RS
  23. Required. Controls the main service.
  24. .RE
  25. .PP
  26. The arguments, structure, and conventions for
  27. .I rc.log
  28. and
  29. .I rc.main
  30. are identical.
  31. The illustrations below will usually be shown with
  32. .IR rc.main ,
  33. but are equally applicable to
  34. .I rc.log
  35. unless noted otherwise.
  36. .PP
  37. .BR perpd (8)
  38. will invoke service runscripts from within the service definition directory.
  39. For example,
  40. given some service definition directory
  41. .PP
  42. .RS
  43. .I /etc/perp/foo
  44. .RE
  45. .PP
  46. .BR perpd (8)
  47. will switch into
  48. .I foo
  49. before invoking a runscript.
  50. This means that
  51. .I foo
  52. will be the current working directory within the runscript environment.
  53. .PP
  54. Runscripts are normally implemented as executable shell scripts,
  55. prepared and installed by the system administrator.
  56. A runscript will be executed at least twice during the life cycle of a service:
  57. .RS
  58. .IP \(bu 4
  59. to start the service
  60. .IP \(bu 4
  61. after the service exits
  62. .RE
  63. .PP
  64. A runscript will accordingly be structured to handle either of these events.
  65. .PP
  66. Runscripts are invoked in the general form:
  67. .PP
  68. .RS
  69. .B ./rc.main
  70. .I target svname
  71. .B [
  72. .I args...
  73. .B ]
  74. .RE
  75. .PP
  76. The argument
  77. .I target
  78. will be set to one of two literal strings,
  79. either ``start'' or ``reset'',
  80. depending on whether
  81. .BR perpd (8)
  82. is starting or resetting the service.
  83. The
  84. .I svname
  85. argument will be set to the basename of the service definition directory,
  86. such as ``foo'' for the service directory
  87. .IR foo .
  88. Any additional arguments depend on the
  89. .IR target .
  90. .PP
  91. When using a ``start'' target,
  92. .BR perpd (8)
  93. will invoke the runscript like this:
  94. .PP
  95. .RS
  96. .B ./rc.main start
  97. .I svname
  98. .RE
  99. .PP
  100. This follows the general form with no additional arguments.
  101. Given a ``start'' target,
  102. a runscript process should perform any initializations the service requires,
  103. and then proceed to replace itself (its process ID)
  104. with the desired service running in the foreground.
  105. A Bourne-compatible script such as
  106. .BR sh (1)
  107. will replace itself by using the
  108. .B exec
  109. command to start the service.
  110. This provides
  111. .BR perpd (8)
  112. with the process ID it needs for the actual running service,
  113. so that the service may be properly monitored and controlled.
  114. .PP
  115. Normally the ``start'' target will result in a persistent process,
  116. a long-running program that starts at system boot and continues until system shutdown.
  117. A runscript called with a ``start'' target should generally not return or exit,
  118. unless some error is encountered in initializing or starting the service.
  119. .PP
  120. As long-running as a service may be,
  121. whenever it does exit,
  122. for any reason,
  123. .BR perpd (8)
  124. will call the runscript again with a ``reset'' target.
  125. A ``reset'' target
  126. will invoke the runscript with additional arguments in either one of two forms,
  127. depending on whether the service exited normally,
  128. or was terminated by a signal:
  129. .PP
  130. .RS
  131. .B ./rc.main reset
  132. .I svname
  133. .B exit
  134. .I exitcode
  135. .RE
  136. or
  137. .RS
  138. .B ./rc.main reset
  139. .I svname
  140. .B signal
  141. .I signum signame
  142. .RE
  143. .PP
  144. In the first case,
  145. where a service has terminated normally,
  146. the additional arguments include the literal string ``exit'',
  147. followed by a string representation of the numeric exit code returned by the process.
  148. .PP
  149. In the second case,
  150. where a service was terminated by a signal,
  151. the additional arguments include the literal string ``signal'',
  152. followed by a string representation of the signal number that killed the process,
  153. followed by the symbolic name for the signal, such as SIGTERM,
  154. and as may be found listed in
  155. .BR signal (7).
  156. .PP
  157. When called with a ``reset'' target,
  158. a runscript may be used for any number of purposes:
  159. .RS
  160. .IP \(bu 4
  161. post-service logging and cleanup
  162. .IP \(bu 4
  163. sysadmin notification
  164. .IP \(bu 4
  165. shutdown of dependent services
  166. .RE
  167. .PP
  168. On the other hand,
  169. a runscript doesn't have to do anything with a ``reset'' target at all.
  170. There are no particular conditions or requirements for a resetting service,
  171. except that the runscript should normally return/exit as promptly as possible.
  172. A resetting runscript will usually do its job quickly so that
  173. .BR perpd (8)
  174. may start the service again as soon as possible.
  175. .SH EXAMPLES
  176. Assume that
  177. .BR perpd (8)
  178. is supervising some service defined in the subdirectory
  179. .IR foo .
  180. The simplest barebones
  181. .I rc.main
  182. runscript will act only on the ``start'' target
  183. to exec into the foo service:
  184. .PP
  185. .RS
  186. .nf
  187. #!/bin/sh
  188. if test ${1} = 'start' ; then
  189. exec /usr/bin/foo -f
  190. fi
  191. exit 0
  192. .fi
  193. .RE
  194. .PP
  195. This example performs no initializations,
  196. does not prepare for logging,
  197. and responds only to a ``start'' target.
  198. It simply
  199. .BR exec s
  200. into the
  201. .I /usr/bin/foo
  202. program,
  203. here called with an
  204. .B \-f
  205. argument,
  206. presumably required to run foo in the foreground.
  207. On any other target other than ``start'',
  208. this runscript will exit 0.
  209. .PP
  210. Here is another example of a simple foo service,
  211. this time with a bit of logging added:
  212. .PP
  213. .RS
  214. .nf
  215. #!/bin/sh
  216. exec 2>&1
  217. if test ${1} = 'start' ; then
  218. echo "starting ${2}..."
  219. exec /usr/bin/foo -f
  220. fi
  221. exit 0
  222. .fi
  223. .RE
  224. .PP
  225. This runscript starts by redirecting stderr to stdout,
  226. so that all output will be captured by the associated logging service.
  227. The runscript also emits a startup message that will be picked up by the logger,
  228. showing the use of the
  229. .I svname
  230. argument given as the second parameter to the runscript.
  231. .PP
  232. A simple
  233. .I rc.log
  234. runscript for this service might look like this:
  235. .PP
  236. .RS
  237. .nf
  238. #!/bin/sh
  239. if test ${1} = 'start' ; then
  240. exec tinylog -k 5 -t /var/log/${2}
  241. fi
  242. exit 0
  243. .fi
  244. .RE
  245. .PP
  246. As with the
  247. .I rc.main
  248. runscript example,
  249. this runscript only responds to a ``start'' target.
  250. It execs
  251. .BR tinylog(8)
  252. to maintain a set of up to 5 rotated and timestamped log files
  253. in the directory
  254. .IR /var/log/foo ,
  255. supplying the final path element to the logging directory
  256. from the
  257. .I svname
  258. given as the second parameter to the runscript.
  259. .PP
  260. With a logger setup for the foo service,
  261. some post-service logging may now be added for a ``reset'' target in
  262. .IR rc.main :
  263. .PP
  264. .RS
  265. .nf
  266. #!/bin/sh
  267. exec 2>&1
  268. if test ${1} = 'start' ; then
  269. echo "starting ${2}..."
  270. exec /usr/bin/foo -f
  271. fi
  272. if test ${1} = 'reset' ; then
  273. case ${3} in
  274. 'exit') echo "service ${2} exited with exitcode ${4}" ;;
  275. 'signal') echo "service ${2} terminated on signal ${5}" ;;
  276. esac
  277. fi
  278. exit 0
  279. .fi
  280. .RE
  281. .PP
  282. Now whenever this service exits,
  283. and the runscript is run with a ``reset'' target,
  284. the logger will pick up a timestamped record of the event
  285. as well as the cause/type of termination.
  286. .PP
  287. Runscripts may use whatever branching idioms are provided by the script interpreter.
  288. A couple of obvious possibilities in
  289. .BR sh (1)
  290. include the
  291. .B case
  292. and
  293. .B eval
  294. statements.
  295. Here is an example runscript using
  296. .BR eval :
  297. .PP
  298. .RS
  299. .nf
  300. #!/bin/sh
  301. exec 2>&1
  302. TARGET=${1}
  303. SVNAME=${2}
  304. start() {
  305. echo "starting ${SVNAME}..."
  306. exec /usr/bin/foo -f
  307. }
  308. reset() {
  309. echo "resetting ${SVNAME}..."
  310. exit 0
  311. }
  312. eval ${TARGET} "$@"
  313. .fi
  314. .RE
  315. .PP
  316. The runscripts shown above are admittedly simplistic.
  317. Runscripts may be, and often are,
  318. embellished considerably beyond the simple examples shown here.
  319. In particular,
  320. .BR runtools (8)
  321. are often used in the
  322. .B exec
  323. command of a runscript ``start'' target to implement resource control,
  324. privilege drops,
  325. and other manipulations of the service process environment.
  326. .PP
  327. Nevertheless,
  328. it is generally preferable to keep runscripts as simple as possible,
  329. while still starting the service safely and reliably.
  330. Simpler runscripts run faster,
  331. are easier to maintain and diagnose,
  332. have fewer unexpected side effects,
  333. and are generally more portable among different host installations.
  334. .SH ENVIRONMENT
  335. In addition to the positional arguments supplied to the runscript,
  336. certain other variables are also defined within the runscript environment.
  337. .PP
  338. The PERP_BASE variable is defined for both ``start'' and ``reset'' targets.
  339. This variable provides the base directory of the service installation,
  340. normally
  341. .IR /etc/perp ,
  342. and as described in
  343. .BR perpd (8).
  344. The definition of PERP_BASE permits the use of such
  345. .B perp
  346. utilities
  347. as
  348. .BR perpok (8)
  349. and
  350. .BR perpctl (8)
  351. directly within runscripts,
  352. where they may then easily reference any other service definitions as necessary.
  353. .PP
  354. The PERP_SVPID variable is defined for both ``start'' and ``reset'' targets.
  355. For the ``start'' target,
  356. PERP_SVPID gives the process ID of the service that will be started.
  357. For the ``reset'' target,
  358. PERP_SVPID gives the process ID of the service that has just terminated.
  359. Runscripts may choose to use the PERP_SVPID variable to generate output that
  360. cleanly brackets the complete life\-cycle of a service within service logs,
  361. or for any other purpose of reporting and notification.
  362. .PP
  363. The PERP_SVSECS variable is defined only for the ``reset'' target.
  364. It gives the total wallclock uptime, in seconds,
  365. of the service that has just terminated.
  366. Runscripts running ``reset'' may choose to use PERP_SVSECS
  367. for logging the uptime of a service,
  368. or for any other purpose of reporting and notification.
  369. .SH COMPATIBILITY
  370. For users familiar with the daemontools package,
  371. the runscript conventions described here
  372. are not directly interchangeable with those of
  373. .BR supervise (8).
  374. The main difference is that the
  375. .I run
  376. scripts of daemontools
  377. are designed to perform only on startup of a service,
  378. and will have no facility for properly handling a ``reset'' argument.
  379. .PP
  380. Nevertheless,
  381. it is trivial to provide compatibility to
  382. .BR perpd (8)
  383. for any pre-existing daemontools
  384. .I run
  385. scripts.
  386. Just install copies of the following
  387. .I rc.main
  388. into any daemontools service definition directory:
  389. .PP
  390. .RS
  391. .nf
  392. #!/bin/sh
  393. if test ${1} = 'start' ; then
  394. exec ./run
  395. fi
  396. .fi
  397. .RE
  398. .PP
  399. Likewise,
  400. this
  401. .IR rc.log :
  402. .PP
  403. .RS
  404. .nf
  405. #!/bin/sh
  406. if test ${1} = 'start' ; then
  407. cd ./log && exec ./run
  408. fi
  409. .fi
  410. .RE
  411. .SH HISTORY
  412. The
  413. .BR perpd (8)
  414. daemon formerly used multiple instances of a
  415. .BR perpetrate (8)
  416. executable,
  417. running one instance for each service under supervision.
  418. Under that architecture,
  419. the
  420. .BR perpetrate (8)
  421. executable performed all the supervisory operations on the service definition
  422. as described in this manual.
  423. .PP
  424. Beginning with version 2.0,
  425. the operations of the
  426. .BR perpetrate (8)
  427. executable were internally coalesced with
  428. .BR perpd (8)
  429. itself, and the need for
  430. .BR perpetrate (8)
  431. was eliminated.
  432. Meanwhile, all the runscript conventions have otherwise remained the same,
  433. and the name of this manual page has been retained to describe them.
  434. .SH AUTHOR
  435. Wayne Marshall, http://b0llix.net/perp/
  436. .SH SEE ALSO
  437. .nh
  438. .BR perp_intro (8),
  439. .BR perpboot (8),
  440. .BR perpctl (8),
  441. .BR perpd (8),
  442. .BR perphup (8),
  443. .BR perpls (8),
  444. .BR perpok (8),
  445. .BR perpstat (8),
  446. .BR sissylog (8),
  447. .BR tinylog (8)
  448. .\" eof: perpetrate.5