runit

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit d2856bbc7368a2ee753aa5a16674f85e1cd54c65
parent 782b7549365a9ab0c64add15165d8eb24a5b9ec4
Author: Gerrit Pape <pape@smarden.org>
Date:   Thu, 26 Sep 2002 11:12:56 +0000

cleanup. doc.

Diffstat:
Mdebian/control | 8++++----
Mdoc/index.html | 10++++++----
Mdoc/runsv.8.html | 14++++++++------
Mdoc/runsvdir.8.html | 17+++++++++++------
Mdoc/svwaitdown.8.html | 49++++++++++++++++++++++++++++---------------------
Mdoc/svwaitup.8.html | 52++++++++++++++++++++++++++--------------------------
Mdoc/upgrade.html | 24+++++++++++++++++++-----
Mman/runsv.8 | 27++++++++++++++++-----------
Mman/runsvdir.8 | 6++++++
Mman/svwaitdown.8 | 31++++++++++++++++++++++++++++---
Mman/svwaitup.8 | 4+++-
Mpackage/CHANGES | 5+++++
Apackage/THANKS | 3+++
Msrc/runsv.c | 76++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Msrc/runsvdir.c | 11+++++++++++
Msrc/svwaitdown.c | 100+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Msrc/svwaitup.c | 4++++
17 files changed, 295 insertions(+), 146 deletions(-)

diff --git a/debian/control b/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.5.2 Package: runit Architecture: any -Depends: ${shlibs:Depends} +Suggests: daemontools Description: minimal replacement for sysvinit using daemontools - runit cooperates with djb's daemontools package to create a replacement for - sysvinit. runit currently runs on Debian GNU/Linux but may be easily adapted - to other unix operating systems using glibc. If runit runs for you on any + runit is a daemontools package alike replacement for sysvinit. runit + currently runs on Debian GNU/Linux, FreeBSD, OpenBSD, and may be easily + adapted to other unix operating systems. If runit runs for you on any other operating system or linux distribution, please let me know. . Warning: Replacing sysvinit can cause the system's boot to fail. Make sure diff --git a/doc/index.html b/doc/index.html @@ -25,9 +25,9 @@ Dependencies and runlevels</a> <a href="svwaitdown.8.html">The <tt>svwaitdown</tt> program</a><br> <a href="svwaitup.8.html">The <tt>svwaitup</tt> program</a> <hr> -<i>runit</i> cooperates with the -<a href="http://cr.yp.to/daemontools.html">daemontools</a> package to create -a replacement for +<i>runit</i> is a +<a href="http://cr.yp.to/daemontools.html">daemontools</a> alike +replacement for <a href="ftp://ftp.cistron.nl/pub/people/miquels/sysvinit/">sysvinit</a>. <i>runit</i> runs on <b>Debian GNU/Linux</b>, <b>OpenBSD 2.9</b>, <b>FreeBSD 4.4</b>. <i>runit</i> reportedly runs on <b>FreeBSD 4.3</b>, @@ -40,7 +40,9 @@ system's boot to fail. Make sure you are able to recover and repair your system, for example if you run a boot loader, it should be able to pass <tt>init=/bin/sh</tt> to the kernel. <hr> -<i>runit</i> is discussed on the <tt>&lt;supervision@list.skarnet.org&gt;</tt> +<i>runit</i> is discussed on the +<a href="http://skarnet.org/lists/#supervision"> +&lt;supervision@list.skarnet.org&gt;</a> mailing list. To subscribe send an empty email to <a href="mailto:supervision-subscribe@list.skarnet.org"> &lt;supervision-subscribe@list.skarnet.org&gt;</a>. diff --git a/doc/runsv.8.html b/doc/runsv.8.html @@ -31,12 +31,13 @@ and <I>service</I>/finish's standard output to the pipe, switches to the directo the <I>service</I> directory. The standard input of the log service a redirected to read from the pipe. <P> <B>runsv</B> maintains status information in a binary format -compatible to <B><I>supervise</B>(8)</I> in <I>service</I>/supervise/status ( and <I>service</I>/log/supervise/status), -and in a human readable format in <I>service</I>/supervise/stat ( and <I>service</I>/log/supervise/stat). - +compatible to <B><I>supervise</B>(8)</I> in <I>service</I>/supervise/status and <I>service</I>/log/supervise/status, +and in a human-readable format in <I>service</I>/supervise/stat, <I>service</I>/log/supervise/stat, +<I>service</I>/supervise/pid, <I>service</I>/log/supervise/pid. <H2><A NAME="sect3">Control</A></H2> -The named pipe <I>service</I>/supervise/control (and <I>service</I>/log/supervise/control) -is provided to give commands to <B>runsv</B>. You can use <B><I>svc</B>(8)</I> to control the +The named pipes +<I>service</I>/supervise/control, and (optionally) <I>service</I>/log/supervise/control +are provided to give commands to <B>runsv</B>. You can use <B><I>svc</B>(8)</I> to control the service or just write one of the following characters to the named pipe: <DL> @@ -97,7 +98,8 @@ example, to send a TERM signal to /service/socklog-unix, either do # svc # echo -n t &gt;/service/socklog-unix/supervise/control<BR> <P> If <B><I>echo</B>(1)</I> on your systems does not provide the -n option, leave it out, -<B>runsv</B> ignores unknown characters written to the control pipe. +<B>runsv</B> ignores unknown characters written to the control pipe. <B><I>echo</B>(1)</I> usally +blocks if no <B>runsv</B> process is running in the service directory. <H2><A NAME="sect4">Signals</A></H2> If <B>runsv</B> receives a TERM signal, it acts as if the character x was written diff --git a/doc/runsvdir.8.html b/doc/runsvdir.8.html @@ -34,13 +34,17 @@ a process-listing tool such as <B><I>ps</B>(1)</I>. <B>runsvdir</B> writes a dot log every 15 minutes so that old error messages expire. <P> Normally <B>runsvdir</B> is started by <B><I>runit</B>(8)</I> in stage 2. -<H2><A NAME="sect3">See Also</A></H2> -<I>runit(8)</I>, <I>runit-init(8)</I>, <I>runsv(8)</I>, -<I>readproctitle(8)</I>, <I>svscan(8)</I> <P> +<H2><A NAME="sect3">Signals</A></H2> +If <B>runsvdir</B> receives a TERM signal, +it sends a TERM signal to each <B><I>runsv</B>(8)</I> process it is monitoring and then +exits. +<H2><A NAME="sect4">See Also</A></H2> +<I>runit(8)</I>, <I>runit-init(8)</I>, <I>runsv(8)</I>, <I>readproctitle(8)</I>, <I>svscan(8)</I> +<P> <I>http://smarden.org/runit/</I><BR> <I>http://cr.yp.to/daemontools.html</I><BR> -<H2><A NAME="sect4">Author</A></H2> +<H2><A NAME="sect5">Author</A></H2> Gerrit Pape &lt;pape@smarden.org&gt; <P> <HR><P> @@ -49,7 +53,8 @@ Gerrit Pape &lt;pape@smarden.org&gt; <P> <LI><A NAME="toc0" HREF="#sect0">Name</A></LI> <LI><A NAME="toc1" HREF="#sect1">Synopsis</A></LI> <LI><A NAME="toc2" HREF="#sect2">Description</A></LI> -<LI><A NAME="toc3" HREF="#sect3">See Also</A></LI> -<LI><A NAME="toc4" HREF="#sect4">Author</A></LI> +<LI><A NAME="toc3" HREF="#sect3">Signals</A></LI> +<LI><A NAME="toc4" HREF="#sect4">See Also</A></LI> +<LI><A NAME="toc5" HREF="#sect5">Author</A></LI> </UL> </BODY></HTML> diff --git a/doc/svwaitdown.8.html b/doc/svwaitdown.8.html @@ -15,39 +15,46 @@ svwaitdown - waits for services controlled by <I>supervise(8)</I> to be down <B>svwaitdown</B> [ <B>-v</B> ] [ <B>-t</B> <I>sec</I> ] <I>services</I> <H2><A NAME="sect2">Description</A></H2> <I>services</I> consist -of one or more arguments. <P> -<B>svwaitdown</B> checks each <I>service</I> given at the command -line for being down. The <I>services</I> given at the command line must be controlled -by <B><I>supervise</B>(8)</I>. <P> -<B>svwaitdown</B> blocks, limited by a <I>timeout</I>, until all <I>services</I> -are down or reports errors. +of one or more arguments. Each <I>service</I> directory must start with a slash. +<P> +<B>svwaitdown</B> checks each <I>service</I> given at the command line for being down. +The <I>services</I> given at the command line must be controlled by <B><I>supervise</B>(8)</I>. +<P> +<B>svwaitdown</B> blocks, limited by a <I>timeout</I>, until all <I>services</I> are down or +reports errors. <H2><A NAME="sect3">Options</A></H2> <DL> <DT><B>-v</B> </DT> -<DD>verbose. Print verbose messages to stderr. -</DD> +<DD>verbose. Print verbose messages to stderr. </DD> -<DT><B>-t <I>sec</B> </I></DT> +<DT><B>-t <I>sec</B> +</I></DT> <DD>Set the timeout for waiting for <I>services</I> to become down to <I>sec</I> seconds. <I>sec</I> must be between 2 and 6000. Default is 600 (10 minutes). </DD> + +<DT><B>-x</B> </DT> +<DD>exit. Wait +for the corresponding <B><I>runsv</B>(8)</I> process to exit instead for the <I>service</I> +to be down. This option should only be used by <B><I>runit</B>(8)</I> in stage 3 when +<B><I>runsvdir</B>(8)</I> is already stopped. </DD> </DL> <H2><A NAME="sect4">Exit Codes</A></H2> -<B>svwaitdown</B> -returns 0 as soon as all <I>services</I> are down. <P> -If a <I>service</I> is usually controlled -by <B><I>supervise</B>(8)</I>, but no <B><I>supervise</B>(8)</I> process is currently running, <B>svwaitdown</B> -treats this <I>service</I> as if it would be down. <P> -For each <I>service</I> that causes -an error while checking, <B>svwaitdown</B> increases the exit code by one and -exits non zero. The maximum is 100. <P> -<B>svwaitdown</B> returns 111 if the timeout -<I>sec</I> was reached. +<B>svwaitdown</B> returns 0 as soon as +all <I>services</I> are down. <P> +If a <I>service</I> is usually controlled by <B><I>supervise</B>(8)</I>, +but no <B><I>supervise</B>(8)</I> process is currently running, <B>svwaitdown</B> treats this +<I>service</I> as if it would be down. <P> +For each <I>service</I> that causes an error while +checking, <B>svwaitdown</B> increases the exit code by one and exits non zero. +The maximum is 100. <P> +<B>svwaitdown</B> returns 111 if the timeout <I>sec</I> was reached. + <H2><A NAME="sect5">See Also</A></H2> -<I>svwaitup(8)</I>, <I>runit(8)</I>, <I>runit-init(8)</I>, <I>runsvdir(8)</I>, -<I>runsv(8)</I>, <I>supervise(8)</I>, <I>svscan(8)</I> <P> +<I>svwaitup(8)</I>, <I>runit(8)</I>, <I>runit-init(8)</I>, <I>runsvdir(8)</I>, <I>runsv(8)</I>, <I>supervise(8)</I>, +<I>svscan(8)</I> <P> <I>http://smarden.org/runit/</I><BR> <I>http://cr.yp.to/daemontools.html</I><BR> diff --git a/doc/svwaitup.8.html b/doc/svwaitup.8.html @@ -15,43 +15,43 @@ svwaitup - waits for services controlled by <I>supervise(8)</I> to be up [ <B>-v</B> ] [ <B>-s</B> <I>sec</I> ] <I>services</I> <H2><A NAME="sect2">Description</A></H2> <I>services</I> consist of one or more arguments. +Each <I>service</I> directory must start with a slash. <P> +<B>svwaitup</B> checks each <I>service</I> +given at the command line for being at least the specified number of seconds +<I>sec</I> up. The <I>services</I> given at the command line must be controlled by <B><I>supervise</B>(8)</I>. <P> -<B>svwaitup</B> checks each <I>service</I> given at the command line for being at least -the specified number of seconds <I>sec</I> up. The <I>services</I> given at the command -line must be controlled by <B><I>supervise</B>(8)</I>. <P> -<B>svwaitup</B> blocks until all <I>services</I> -were up and running at least <I>sec</I> seconds when <B>svwaitup</B> was checking or -reports errors. +<B>svwaitup</B> blocks until all <I>services</I> were up and running at least <I>sec</I> seconds +when <B>svwaitup</B> was checking or reports errors. <H2><A NAME="sect3">Options</A></H2> <DL> <DT><B>-v</B> </DT> -<DD>verbose. Print verbose messages to stderr. </DD> +<DD>verbose. Print verbose +messages to stderr. </DD> -<DT><B>-s <I>sec</B> -</I></DT> -<DD>Set the minimum number of seconds each <I>service</I> has to be up to <I>sec</I> seconds. -<I>sec</I> must be between 2 and 600. Default is 2. </DD> +<DT><B>-s <I>sec</B> </I></DT> +<DD>Set the minimum number of seconds each <I>service</I> +has to be up to <I>sec</I> seconds. <I>sec</I> must be between 2 and 600. Default is 2. +</DD> </DL> <H2><A NAME="sect4">Exit Codes</A></H2> -<B>svwaitup</B> returns 0 -as soon as all <I>services</I> were at least <I>sec</I> seconds up. <P> -<B>Note</B>: If <B>svwaitup</B> -exits 0, it does not guarantee that all <I>services</I> are actually running. A -<I>service</I> could have crashed immediatly after <B>svwaitup</B> was successfully checking -it to be up <I>sec</I> seconds. <I>services</I> should be designed not to rely on <B>svwaitup</B> -to resolve dependencies. <P> -For each <I>service</I> that is down and not requested -to become up, or that causes an error while checking (e.g. <B><I>supervise</B>(8)</I> is -not running), <B>svwaitup</B> increases the exit code by one and exits non zero. -The maximum is 100. <P> +<B>svwaitup</B> returns 0 as soon as all <I>services</I> were at least <I>sec</I> +seconds up. <P> +<B>Note</B>: If <B>svwaitup</B> exits 0, it does not guarantee that all <I>services</I> +are actually running. A <I>service</I> could have crashed immediatly after <B>svwaitup</B> +was successfully checking it to be up <I>sec</I> seconds. <I>services</I> should be designed +not to rely on <B>svwaitup</B> to resolve dependencies. <P> +For each <I>service</I> that is +down and not requested to become up, or that causes an error while checking +(e.g. <B><I>supervise</B>(8)</I> is not running), <B>svwaitup</B> increases the exit code by one +and exits non zero. The maximum is 100. <P> <B>svwaitup</B> returns 111 on error. -<H2><A NAME="sect5">See Also</A></H2> -<I>svwaitdown(8)</I>, -<I>runit(8)</I>, <I>runit-init(8)</I>, <I>runsvdir(8)</I>, <I>runsv(8)</I>, <I>supervise(8)</I>, <I>svscan(8)</I> -<P> +<H2><A NAME="sect5">See +Also</A></H2> +<I>svwaitdown(8)</I>, <I>runit(8)</I>, <I>runit-init(8)</I>, <I>runsvdir(8)</I>, <I>runsv(8)</I>, <I>supervise(8)</I>, +<I>svscan(8)</I> <P> <I>http://smarden.org/runit/</I><BR> <I>http://cr.yp.to/daemontools.html</I><BR> diff --git a/doc/upgrade.html b/doc/upgrade.html @@ -10,12 +10,26 @@ <h1>runit - upgrading from previous versions</h1> <hr> -<h3>0.4.1 to 0.5.0</h3> +<h3>0.5.0 to 0.6.0</h3> +There are two new programs, <a href="runsvdir.8.html">runsvdir</a> and +<a href="runsv.8.html">runsv</a>, which replace the +<tt>svscanboot</tt>/<tt>svscan</tt>/<tt>readproctitle</tt>/<tt>supervise</tt> +combination of daemontools. Please adapt <tt>runit</tt>'s stage 2 +(<tt>/etc/runit/2</tt>) to use <tt>runsvdir</tt> instead of +<tt>svscanboot</tt>; see the examples in <tt>/package/admin/runit/etc/</tt>. +The change takes effect on the next reboot or if you stop all services and +kill <tt>svscan</tt> and <tt>readproctitle</tt>. <tt>runit</tt> then +automatically restarts stage 2. <p> -There is a new program: <tt>utmpset</tt>. This program is used in the -getty run scripts to enable local login accounting. You might want to adapt -your getty run scripts <tt>/service/getty-*/run</tt>, see the examples in -<tt>/package/admin/runit/etc/</tt>. +The <a href="svwaitdown.8.html">svwaitdown</a> program has new options: -k +and -x. They are used in <tt>runit</tt>'s stage 3 (<tt>/etc/runit/3</tt>). +Please adapt your <tt>/etc/runit/3</tt> script, see the examples in +<tt>/package/admin/runit/etc/</tt>. +<h3>0.4.1 to 0.5.0</h3> +There is a new program: <a href="utmpset.8.html">utmpset</a>. This program +is used in the getty run scripts to enable local login accounting. You might +want to adapt your getty run scripts <tt>/service/getty-*/run</tt>, see the +examples in <tt>/package/admin/runit/etc/</tt>. <hr> <address><a href="mailto:pape@smarden.org"> Gerrit Pape &lt;pape@smarden.org&gt; diff --git a/man/runsv.8 b/man/runsv.8 @@ -50,18 +50,19 @@ maintains status information in a binary format compatible to .BR supervise (8) in .IR service /supervise/status -( and -.IR service /log/supervise/status), -and in a human readable format in -.IR service /supervise/stat -( and -.IR service /log/supervise/stat). +and +.IR service /log/supervise/status, +and in a human-readable format in +.IR service /supervise/stat, +.IR service /log/supervise/stat, +.IR service /supervise/pid, +.IR service /log/supervise/pid. .SH CONTROL -The named pipe -.IR service /supervise/control -(and -.IR service /log/supervise/control) -is provided to give commands to +The named pipes +.IR service /supervise/control, +and (optionally) +.IR service /log/supervise/control +are provided to give commands to .BR runsv . You can use .BR svc (8) @@ -128,6 +129,10 @@ If on your systems does not provide the -n option, leave it out, .B runsv ignores unknown characters written to the control pipe. +.BR echo (1) +usally blocks if no +.B runsv +process is running in the service directory. .SH SIGNALS If .B runsv diff --git a/man/runsvdir.8 b/man/runsvdir.8 @@ -70,6 +70,12 @@ Normally is started by .BR runit (8) in stage 2. +.SH SIGNALS +If +.B runsvdir +receives a TERM signal, it sends a TERM signal to each +.BR runsv (8) +process it is monitoring and then exits. .SH SEE ALSO runit(8), runit-init(8), diff --git a/man/svwaitdown.8 b/man/svwaitdown.8 @@ -5,15 +5,18 @@ svwaitdown \- waits for services controlled by supervise(8) to be down .B svwaitdown [ .B \-v -] -[ +] [ +.B \-k +] [ .B \-t .I sec ] .I services .SH DESCRIPTION .I services -consist of one or more arguments. +consist of one or more arguments. Each +.I service +directory must start with a slash. .P .B svwaitdown checks each @@ -43,6 +46,28 @@ to become down to seconds. .I sec must be between 2 and 6000. Default is 600 (10 minutes). +.TP +.B \-k +Kill. If the timeout is reached before all +.I services +are down, tell the +.BR supervise (8) +processes to send the +.I services +a KILL signal. +.TP +.B \-x +Exit. Wait for the corresponding +.BR runsv (8) +processes to exit instead for the +.I services +to be down. +This option should only be used by +.BR runit (8) +in stage 3 when +.BR runsvdir (8) +is already stopped. + .SH EXIT CODES .B svwaitdown returns 0 as soon as all diff --git a/man/svwaitup.8 b/man/svwaitup.8 @@ -13,7 +13,9 @@ svwaitup \- waits for services controlled by supervise(8) to be up .I services .SH DESCRIPTION .I services -consist of one or more arguments. +consist of one or more arguments. Each +.I service +directory must start with a slash. .P .B svwaitup checks each diff --git a/package/CHANGES b/package/CHANGES @@ -2,6 +2,11 @@ runit 0.5.4 Wed, 25 Sep 2002 12:13:46 +0200 * man/runsv.8, man/runsvdir.8: new. * doc: use runsvdir/runsv instead of svscanboot/supervise. + * svwaitdown.c, svwaitup.c, man/svwaitdown.8, man/svwaitup.8: services + must start with slash. + * svwaitdown: new option -x: wait for runsv to exit instead for the + service to be down; new option -k: SIGKILL still running services if + timeout is reached. runit 0.5.3 Tue, 24 Sep 2002 12:14:02 +0200 diff --git a/package/THANKS b/package/THANKS @@ -0,0 +1,3 @@ +Thanks to D. J. Bernstein for his daemontools package and for putting +daemontools' library code into the public domain, this package wouldn't +exist if Bernstein did not make the daemontools package available. diff --git a/src/runsv.c b/src/runsv.c @@ -53,6 +53,7 @@ struct svdir { struct svdir svd[2]; int haslog =0; +int pidchanged =1; int logpipe[2]; char *dir; @@ -90,17 +91,41 @@ void update_status(struct svdir *s) { char bspace[64]; buffer b; char spid[FMT_ULONG]; - - if (s->islog) { - if ((fd =open_trunc("log/supervise/stat")) == -1) - fatal("unable to open log/supervise/stat"); + + /* pid */ + if (pidchanged) { + if ((fd =open_trunc("supervise/pid.new")) == -1) { + warn("unable to open supervise/pid.new"); + return; + } + buffer_init(&b, buffer_unixwrite, fd, bspace, sizeof bspace); + spid[fmt_ulong(spid, (unsigned long)s->pid)] =0; + if (s->pid) { + buffer_puts(&b, spid); + buffer_putsflush(&b, "\n"); + } + close(fd); + if (s->islog) { + if (rename("supervise/pid.new", "log/supervise/pid") == -1) { + warn("unable to rename supervise/pid.new to log/supervise/pid"); + return; + } + } + else { + if (rename("supervise/pid.new", "supervise/pid") == -1) { + warn("unable to rename supervise/pid.new to supervise/pid"); + return; + } + } + pidchanged =0; } - else { - if ((fd =open_trunc("supervise/stat")) == -1) - fatal("unable to open supervise/stat"); + + /* stat */ + if ((fd =open_trunc("supervise/stat.new")) == -1) { + warn("unable to open supervise/stat.new"); + return; } buffer_init(&b, buffer_unixwrite, fd, bspace, sizeof bspace); - spid[fmt_ulong(spid, (unsigned long)s->pid)] =0; switch (s->state) { case S_DOWN: buffer_puts(&b, "down"); @@ -112,11 +137,6 @@ void update_status(struct svdir *s) { buffer_puts(&b, "finish"); break; } - if (s->pid) { - buffer_puts(&b, " (pid "); - buffer_puts(&b, spid); - buffer_puts(&b, ")"); - } if (s->ctrl & C_PAUSE) buffer_puts(&b, ", paused"); if (s->ctrl & C_TERM) @@ -131,6 +151,14 @@ void update_status(struct svdir *s) { } buffer_putsflush(&b, "\n"); close(fd); + if (s->islog) { + if (rename("supervise/stat.new", "log/supervise/stat") == -1) + warn("unable to rename supervise/stat.new to log/supervise/stat"); + } + else { + if (rename("supervise/stat.new", "supervise/stat") == -1) + warn("unable to rename supervise/stat.new to supervise/stat"); + } /* supervise compatibility */ taia_pack(status, &s->start); @@ -226,6 +254,7 @@ void startservice(struct svdir *s) { s->state =S_RUN; } s->pid =p; + pidchanged =1; s->ctrl =C_NOOP; update_status(s); sleep(1); @@ -340,27 +369,24 @@ int main(int argc, char **argv) { taia_now(&svd[1].start); if (stat("log/down", &s) != -1) svd[1].want =W_DOWN; + if (pipe(logpipe) == -1) + fatal("unable to create log pipe"); + coe(logpipe[0]); + coe(logpipe[1]); } } - if (haslog) { - if (pipe(logpipe) == -1) - fatal("unable to create log pipe"); - coe(logpipe[0]); - coe(logpipe[1]); - } - mkdir("supervise", 0700); if ((svd[0].fdlock =open_append("supervise/lock")) == -1) - fatal("unable to open lock."); + fatal("unable to open lock"); if (lock_exnb(svd[0].fdlock) == -1) - fatal("unable to lock."); + fatal("unable to lock"); if (haslog) { mkdir("log/supervise", 0700); if ((svd[1].fdlock =open_append("log/supervise/lock")) == -1) - fatal("unable to open log/lock."); + fatal("unable to open log/lock"); if (lock_ex(svd[1].fdlock) == -1) - fatal("unable to log/lock."); + fatal("unable to log/lock"); } fifo_make("supervise/control", 0600); @@ -430,6 +456,7 @@ int main(int argc, char **argv) { if ((child == -1) && (errno != error_intr)) break; if (child == svd[0].pid) { svd[0].pid =0; + pidchanged =1; if (open_read("finish") != -1) { svd[0].state =S_FINISH; startservice(&svd[0]); @@ -448,6 +475,7 @@ int main(int argc, char **argv) { if (haslog) { if (child == svd[1].pid) { svd[1].pid =0; + pidchanged =1; svd[1].state =S_DOWN; taia_now(&svd[1].start); update_status(&svd[1]); diff --git a/src/runsvdir.c b/src/runsvdir.c @@ -36,6 +36,7 @@ int loglen; int logpipe[2]; iopause_fd io[1]; struct taia stamplog; +int exitsoon =0; void usage () { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); @@ -49,6 +50,9 @@ void warn(char *m1, char *m2) { void warn3x(char *m1, char *m2, char *m3) { strerr_warn6("runsvdir ", svdir, ": warning: ", m1, m2, m3, 0); } +void s_term() { + exitsoon =1; +} void runsv(int no, char *name) { int pid; @@ -173,6 +177,7 @@ int main(int argc, char **argv) { progname =*argv++; if (! argv || ! *argv) usage(); + sig_catch(sig_term, s_term); svdir =*argv++; if (argv && *argv) { log =*argv; @@ -241,6 +246,12 @@ int main(int argc, char **argv) { } } } + if (exitsoon) { + for (i =0; i < svnum; i++) { + if (sv[i].pid) kill(sv[i].pid, SIGTERM); + } + exit(0); + } } /* not reached */ exit(0); diff --git a/src/svwaitdown.c b/src/svwaitdown.c @@ -1,11 +1,3 @@ -/* - in /package/admin/daemontools/compile/ : - gcc -Wall -c svwaitdown.c && \ - gcc -o svwaitdown svwaitdown.o unix.a byte.a time.a - - Gerrit Pape <pape@smarden.org> -*/ - #include <unistd.h> #include "strerr.h" #include "error.h" @@ -38,6 +30,8 @@ int main (int argc, const char * const *argv) { int opt; unsigned long sec =600; int verbose =0; + int doexit =0; + int dokill =0; int fd; char status[18]; int r; @@ -47,7 +41,7 @@ int main (int argc, const char * const *argv) { progname =*argv; - while ((opt =getopt(argc, argv, "t:vV")) != opteof) { + while ((opt =getopt(argc, argv, "t:xkvV")) != opteof) { switch(opt) { case 't': scan_ulong(optarg, &sec); @@ -55,6 +49,12 @@ int main (int argc, const char * const *argv) { usage(); } break; + case 'x': + doexit =1; + break; + case 'k': + dokill =1; + break; case 'v': verbose =1; break; @@ -71,8 +71,11 @@ int main (int argc, const char * const *argv) { dir =argv; tai_now(&start); - while (*dir) { + if (*dir[0] != '/') { + warn(*dir, ": service directory must start with a slash.", 0); + continue; + } if (chdir(*dir) == -1) { warn(*dir, ": unable to change directory: ", &strerr_sys); continue; @@ -90,37 +93,64 @@ int main (int argc, const char * const *argv) { } close(fd); - fd = open_read("supervise/status"); - if (fd == -1) { - warn(*dir, "unable to open supervise/status: ", &strerr_sys); - continue; - } - r = buffer_unixread(fd, status, sizeof status); - close(fd); - if (r < sizeof status) { - if (r == -1) - warn(*dir, "unable to read supervise/status: ", &strerr_sys); - else - warn(*dir, ": unable to read supervise/status: bad format.", 0); - continue; - } - - pid = (unsigned char) status[15]; - pid <<= 8; pid += (unsigned char) status[14]; - pid <<= 8; pid += (unsigned char) status[13]; - pid <<= 8; pid += (unsigned char) status[12]; - if (! pid) { - /* ok, service is down */ - if (verbose) strerr_warn3(INFO, *dir, ": down.", 0); - dir++; - continue; + if (! doexit) { + fd = open_read("supervise/status"); + if (fd == -1) { + warn(*dir, "unable to open supervise/status: ", &strerr_sys); + continue; + } + r = buffer_unixread(fd, status, sizeof status); + close(fd); + if (r < sizeof status) { + if (r == -1) + warn(*dir, "unable to read supervise/status: ", &strerr_sys); + else + warn(*dir, ": unable to read supervise/status: bad format.", 0); + continue; + } + pid = (unsigned char) status[15]; + pid <<= 8; pid += (unsigned char) status[14]; + pid <<= 8; pid += (unsigned char) status[13]; + pid <<= 8; pid += (unsigned char) status[12]; + if (! pid) { + /* ok, service is down */ + if (verbose) strerr_warn3(INFO, *dir, ": down.", 0); + dir++; + continue; + } } - tai_now(&now); tai_sub(&now, &now, &start); if (tai_approx(&now) >= sec) { /* timeout */ if (verbose) strerr_warn2(INFO, "timeout.", 0); + if (dokill) { + dir =argv; + while (*dir) { + if (chdir(*dir) == -1) { + warn(*dir, ": unable to change directory: ", &strerr_sys); + continue; + } + if ((fd =open_write("supervise/control")) == -1) { + if (errno == error_nodevice) { + if (verbose) + strerr_warn3(INFO, *dir, + ": supervise not running.", 0); + dir++; + } + else + warn(*argv, ": unable to open supervise/control: ", &strerr_sys); + continue; + } + if (write(fd, "k", 1) != 1) + warn(*argv, + ": unable to write to supervise/control: ", &strerr_sys); + else + strerr_warn3(INFO, *dir, ": killed.", 0); + close(fd); + dir++; + } + } exit(111); } diff --git a/src/svwaitup.c b/src/svwaitup.c @@ -65,6 +65,10 @@ int main (int argc, const char * const *argv) { dir =argv; while (*dir) { + if (*dir[0] != '/') { + warn(*dir, ": service directory must start with a slash.", 0); + continue; + } if (chdir(*dir) == -1) { warn(*dir, ": unable to change directory: ", &strerr_sys); continue;