From: Charles Duffy <cduffy@spamcop.net>
Subject: Re: new "sv status" flags and exit-tracking patch, yet again
Date: Wed, 21 Sep 2005 16:50:31 -0500 [thread overview]
Message-ID: <dgskj8$o4m$1@sea.gmane.org> (raw)
In-Reply-To: <dgn2ks$usn$1@sea.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 150 bytes --]
This version uses negative numbers for representing cases where exit was
on account of a signal being received, as per Gerrit's previous suggestion.
[-- Attachment #2: runit-1.3.1-newer.patch --]
[-- Type: text/x-patch, Size: 10130 bytes --]
diff -ru runit-1.3.1/src/runsv.c runit-1.3.1.new/src/runsv.c
--- runit-1.3.1/src/runsv.c 2005-08-24 15:14:39.680226345 -0500
+++ runit-1.3.1.new/src/runsv.c 2005-09-19 10:00:44.751145982 -0500
@@ -1,4 +1,5 @@
#include <sys/types.h>
+#include <sys/wait.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
@@ -39,6 +40,11 @@
#define W_UP 0
#define W_DOWN 1
#define W_EXIT 2
+/* exit type */
+#define ET_NOEXIT 0
+#define ET_NORMAL 1
+#define ET_SIGNAL 2
+#define ET_UNKNOWN 127
struct svdir {
int pid;
@@ -50,6 +56,10 @@
int fdcontrol;
int fdcontrolwrite;
int islog;
+ unsigned char runexit_type;
+ unsigned char runexit_val;
+ unsigned char finexit_type;
+ unsigned char finexit_val;
};
struct svdir svd[2];
@@ -86,7 +96,7 @@
void update_status(struct svdir *s) {
unsigned long l;
int fd;
- char status[20];
+ char status[24];
char bspace[64];
buffer b;
char spid[FMT_ULONG];
@@ -180,6 +190,10 @@
else
status[18] =0;
status[19] =s->state;
+ status[20] =s->runexit_type;
+ status[21] =s->runexit_val;
+ status[22] =s->finexit_type;
+ status[23] =s->finexit_val;
if ((fd =open_trunc("supervise/status.new")) == -1) {
warn("unable to open supervise/status.new");
return;
@@ -399,6 +413,10 @@
svd[0].ctrl =C_NOOP;
svd[0].want =W_UP;
svd[0].islog =0;
+ svd[0].runexit_type =0;
+ svd[0].runexit_val =0;
+ svd[0].finexit_type =0;
+ svd[0].finexit_val =0;
svd[1].pid =0;
taia_now(&svd[0].start);
if (stat("down", &s) != -1) svd[0].want =W_DOWN;
@@ -416,6 +434,10 @@
svd[1].ctrl =C_NOOP;
svd[1].want =W_UP;
svd[1].islog =1;
+ svd[1].runexit_type =0;
+ svd[1].runexit_val =0;
+ svd[1].finexit_type =0;
+ svd[1].finexit_val =0;
taia_now(&svd[1].start);
if (stat("log/down", &s) != -1)
svd[1].want =W_DOWN;
@@ -540,13 +562,39 @@
svd[0].pid =0;
pidchanged =1;
svd[0].ctrl &=~C_TERM;
- if (svd[0].state != S_FINISH)
+ if (svd[0].state != S_FINISH) {
+ if (WIFEXITED(wstat)) {
+ svd[0].runexit_type = ET_NORMAL;
+ svd[0].runexit_val = WEXITSTATUS(wstat);
+ } else if (WIFSIGNALED(wstat)) {
+ svd[0].runexit_type = ET_SIGNAL;
+ svd[0].runexit_val = WTERMSIG(wstat);
+ } else if(WIFSTOPPED(wstat)) {
+ /* do nothing */
+ } else {
+ svd[0].runexit_type = ET_UNKNOWN;
+ svd[0].runexit_val = 0;
+ }
if ((fd =open_read("finish")) != -1) {
close(fd);
svd[0].state =S_FINISH;
update_status(&svd[0]);
continue;
}
+ } else {
+ if (WIFEXITED(wstat)) {
+ svd[0].finexit_type = ET_NORMAL;
+ svd[0].finexit_val = WEXITSTATUS(wstat);
+ } else if (WIFSIGNALED(wstat)) {
+ svd[0].finexit_type = ET_SIGNAL;
+ svd[0].finexit_val = WTERMSIG(wstat);
+ } else if(WIFSTOPPED(wstat)) {
+ /* do nothing */
+ } else {
+ svd[0].finexit_type = ET_UNKNOWN;
+ svd[0].finexit_val = 0;
+ }
+ }
svd[0].state =S_DOWN;
taia_uint(&deadline, 1);
taia_add(&deadline, &svd[0].start, &deadline);
diff -ru runit-1.3.1/src/sv.c runit-1.3.1.new/src/sv.c
--- runit-1.3.1/src/sv.c 2005-08-24 15:14:39.801889117 -0500
+++ runit-1.3.1.new/src/sv.c 2005-09-21 16:42:48.347484541 -0500
@@ -1,5 +1,6 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include <string.h>
#include <unistd.h>
#include "str.h"
#include "strerr.h"
@@ -48,7 +49,7 @@
int (*cbk)(char*) =0;
int curdir, fd, r;
-char svstatus[20];
+char svstatus[24];
char sulong[FMT_ULONG];
void usage() {
@@ -63,6 +64,10 @@
strerr_warn4(FATAL, m1, m2, ": ", &strerr_sys);
done(lsb ? 151 : 100);
}
+void fatal2x(char *m1, char *m2) {
+ strerr_warn3(FATAL, m1, m2, 0);
+ done(lsb ? 151 : 100);
+}
void out(char *p, char *m1) {
buffer_puts(buffer_1, p);
buffer_puts(buffer_1, *service);
@@ -86,6 +91,114 @@
void outs2(const char *s) { buffer_puts(buffer_2, s); }
void flush2(const char *s) { outs2(s); buffer_flush(buffer_2); }
+typedef int (*flagprint_fn)();
+typedef struct statusflag {
+ char flagchar;
+ flagprint_fn printfunc;
+} statusflag_t;
+
+#define MAX_FLAGPRINTFUNCS 16
+flagprint_fn flagprintfuncs[MAX_FLAGPRINTFUNCS] = { 0, };
+int flagprintfunccount = 0; /* number of printfuncs currently requested */
+
+static inline int getPID() {
+ int pid =(unsigned char) svstatus[15];
+ pid <<=8; pid +=(unsigned char)svstatus[14];
+ pid <<=8; pid +=(unsigned char)svstatus[13];
+ pid <<=8; pid +=(unsigned char)svstatus[12];
+ return pid;
+}
+
+static int printULong(unsigned long ulong) {
+ char sulong[FMT_ULONG];
+ memset(sulong, 0, FMT_ULONG);
+ fmt_ulong(sulong, ulong);
+ outs(sulong);
+ return 1;
+}
+
+static inline int printExitData(int exit_type, int exit_val) {
+ if(exit_type != 1)
+ outs("-");
+ if(exit_type != 0)
+ printULong(exit_val);
+ return 1;
+}
+
+static int printRunExit() {
+ return printExitData(svstatus[20], svstatus[21]);
+}
+
+static int printFinExit() {
+ return printExitData(svstatus[22], svstatus[23]);
+}
+
+static int printPID() {
+ int pid = getPID(svstatus);
+ if(pid) printULong(pid);
+ else outs("-");
+ return 1;
+}
+
+static int printCurrentState() {
+ switch(svstatus[19]) {
+ case 0:
+ outs("down");
+ break;
+ case 1:
+ outs("run");
+ break;
+ case 2:
+ outs("finish");
+ break;
+ default:
+ outs("error");
+ return -1;
+ }
+ return 1;
+}
+
+static int printWantState() {
+ switch(svstatus[17]) {
+ case 'u':
+ outs("up");
+ break;
+ case 'd':
+ outs("down");
+ break;
+ case 'x':
+ outs("exit");
+ break;
+ default:
+ outs("error");
+ return -1;
+ }
+ return 1;
+}
+
+static int printUptime() {
+ struct tai svtai; /* from structure */
+ struct tai now; /* current time*/
+
+ tai_now(&now);
+ tai_unpack(svstatus, &svtai);
+ if (tai_less(&now,&svtai)) svtai = now;
+ tai_sub(&svtai,&now,&svtai);
+ printULong(tai_approx(&svtai));
+ return 1;
+}
+
+const statusflag_t statusflags[] = {
+ {'r', printRunExit},
+ {'f', printFinExit},
+ {'p', printPID},
+ {'s', printCurrentState},
+ {'w', printWantState},
+ {'u', printUptime},
+ {0, 0},
+};
+
+
int svstatus_get() {
if ((fd =open_write("supervise/ok")) == -1) {
if (errno == error_nodevice) {
@@ -100,10 +213,12 @@
warn("unable to open supervise/status");
return(-1);
}
- r =read(fd, svstatus, 20);
+ memset(svstatus, 0, 24);
+ r =read(fd, svstatus, 24);
close(fd);
switch(r) {
case 20: break;
+ case 24: break;
case -1: warn("unable to read supervise/status"); return(-1);
default: warnx("unable to read supervise/status: bad format"); return(-1);
}
@@ -122,10 +237,7 @@
}
normallyup =1;
}
- pid =(unsigned char) svstatus[15];
- pid <<=8; pid +=(unsigned char)svstatus[14];
- pid <<=8; pid +=(unsigned char)svstatus[13];
- pid <<=8; pid +=(unsigned char)svstatus[12];
+ pid =getPID();
tai_unpack(svstatus, &tstatus);
if (pid) {
switch (svstatus[19]) {
@@ -152,18 +264,28 @@
int status(char *unused) {
r =svstatus_get();
switch(r) { case -1: if (lsb) done(4); case 0: return(0); }
- r =svstatus_print(*service);
- if (chdir("log") == -1) {
- if (errno != error_noent) {
- outs("; log: "); outs(WARN);
- outs("unable to change to log service directory: ");
- outs(error_str(errno));
+
+ if(flagprintfunccount == 0) {
+ r =svstatus_print(*service);
+ if (chdir("log") == -1) {
+ if (errno != error_noent) {
+ outs("; log: "); outs(WARN);
+ outs("unable to change to log service directory: ");
+ outs(error_str(errno));
+ }
}
- }
- else
- if (svstatus_get()) {
- outs("; "); svstatus_print("log");
+ else
+ if (svstatus_get()) {
+ outs("; "); svstatus_print("log");
+ }
+ } else {
+ int i;
+ outs(*service);
+ for(i = 0; i < flagprintfunccount; i++) {
+ outs(" ");
+ flagprintfuncs[i]();
}
+ }
flush("\n");
if (lsb) switch(r) { case 1: done(0); case 2: done(3); case 0: done(4); }
return(r);
@@ -319,17 +441,42 @@
servicex =service;
for (i =0; i < services; ++i) {
- if ((**service != '/') && (**service != '.')) {
- if ((chdir(varservice) == -1) || (chdir(*service) == -1)) {
- fail("unable to change to service directory");
- *service =0;
+ if ((act == &status) && (**service == '-')) {
+ char *flag = (*service)+1;
+ while(*flag != 0) {
+ /* search for a function associated with this flag */
+ int fnidx, foundFlag = 0;
+ for(fnidx = 0; statusflags[fnidx].flagchar != 0; fnidx++) {
+ if(flagprintfunccount == MAX_FLAGPRINTFUNCS) {
+ fatal("Excessive number of flag-based parameters provided");
+ }
+ if(statusflags[fnidx].flagchar == *flag) {
+ flagprintfuncs[flagprintfunccount++] = statusflags[fnidx].printfunc;
+ foundFlag = 1;
+ break;
+ }
+ }
+ if(!foundFlag) {
+ char badFlag[3] = {'-', 'X', 0};
+ badFlag[1] = *flag;
+ fatal2x("Invalid status flag provided: ", badFlag);
+ }
+ flag++;
}
+ *service = 0;
}
else
- if (chdir(*service) == -1) {
- fail("unable to change to service directory");
- *service =0;
+ if ((**service != '/') && (**service != '.')) {
+ if ((chdir(varservice) == -1) || (chdir(*service) == -1)) {
+ fail("unable to change to service directory");
+ *service =0;
+ }
}
+ else
+ if (chdir(*service) == -1) {
+ fail("unable to change to service directory");
+ *service =0;
+ }
if (*service) if (act(acts) == -1) *service =0;
if (fchdir(curdir) == -1) fatal("unable to change to original directory");
service++;
next prev parent reply other threads:[~2005-09-21 21:50 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-09-17 4:46 new "sv status" flags and exit-tracking patch, and misc Charles Duffy
2005-09-17 5:17 ` Mike Bell
2005-09-19 8:35 ` Gerrit Pape
2005-09-17 8:53 ` Laurent Bercot
2005-09-19 8:31 ` Gerrit Pape
2005-09-19 16:04 ` Charles Duffy
2005-09-19 19:13 ` Charles Duffy
2005-09-21 21:50 ` Charles Duffy [this message]
2005-09-26 10:12 ` Gerrit Pape
2005-09-26 15:31 ` duplicate processes Jussi Ramo
2005-09-26 15:42 ` Charlie Brady
2005-12-08 11:08 ` new "sv status" flags and exit-tracking patch, and misc Gerrit Pape
2005-12-08 19:37 ` Charles Duffy
2005-12-09 14:29 ` Gerrit Pape
2005-12-09 14:50 ` Rafal Bisingier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='dgskj8$o4m$1@sea.gmane.org' \
--to=cduffy@spamcop.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).