From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.io/gmane.comp.sysutils.supervision.general/885 Path: news.gmane.org!not-for-mail From: Charles Duffy Newsgroups: gmane.comp.sysutils.supervision.general Subject: Re: new "sv status" flags and exit-tracking patch, yet again Date: Wed, 21 Sep 2005 16:50:31 -0500 Message-ID: References: <20050919082620.21268.qmail@162d9f02f26a34.315fe32.mid.smarden.org> NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------010609080204040206040104" X-Trace: sea.gmane.org 1127339768 25665 80.91.229.2 (21 Sep 2005 21:56:08 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Wed, 21 Sep 2005 21:56:08 +0000 (UTC) Original-X-From: supervision-return-1121-gcsg-supervision=m.gmane.org@list.skarnet.org Wed Sep 21 23:56:06 2005 Return-path: Original-Received: from antah.skarnet.org ([212.85.147.14]) by ciao.gmane.org with smtp (Exim 4.43) id 1EICXq-0002cQ-Lg for gcsg-supervision@gmane.org; Wed, 21 Sep 2005 23:54:27 +0200 Original-Received: (qmail 12073 invoked by uid 76); 21 Sep 2005 21:54:46 -0000 Mailing-List: contact supervision-help@list.skarnet.org; run by ezmlm List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Archive: Original-Received: (qmail 12067 invoked from network); 21 Sep 2005 21:54:46 -0000 X-Injected-Via-Gmane: http://gmane.org/ Original-To: supervision@list.skarnet.org Original-Lines: 392 Original-X-Complaints-To: usenet@sea.gmane.org X-Gmane-NNTP-Posting-Host: fwext1-ext.isgenesis.com User-Agent: Mozilla Thunderbird 1.0.6 (X11/20050716) X-Accept-Language: en-us, en In-Reply-To: Original-Sender: news Xref: news.gmane.org gmane.comp.sysutils.supervision.general:885 Archived-At: This is a multi-part message in MIME format. --------------010609080204040206040104 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit This version uses negative numbers for representing cases where exit was on account of a signal being received, as per Gerrit's previous suggestion. --------------010609080204040206040104 Content-Type: text/x-patch; name="runit-1.3.1-newer.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="runit-1.3.1-newer.patch" 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 +#include #include #include #include @@ -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 #include +#include #include #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++; --------------010609080204040206040104--