commit d2856bbc7368a2ee753aa5a16674f85e1cd54c65
parent 782b7549365a9ab0c64add15165d8eb24a5b9ec4
Author: Gerrit Pape <pape@smarden.org>
Date: Thu, 26 Sep 2002 11:12:56 +0000
cleanup. doc.
Diffstat:
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><supervision@list.skarnet.org></tt>
+<i>runit</i> is discussed on the
+<a href="http://skarnet.org/lists/#supervision">
+<supervision@list.skarnet.org></a>
mailing list. To subscribe send an empty email to
<a href="mailto:supervision-subscribe@list.skarnet.org">
<supervision-subscribe@list.skarnet.org></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 >/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 <pape@smarden.org> <P>
<HR><P>
@@ -49,7 +53,8 @@ Gerrit Pape <pape@smarden.org> <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 <pape@smarden.org>
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;