From 5bc690e69ccf091585b7973de215bba5ce7abdf1 Mon Sep 17 00:00:00 2001 From: Rick Myers Date: Fri, 5 Oct 2018 16:34:43 -0400 Subject: [PATCH 1/9] whitespace tidy --- envdir.c | 12 ++-- envini.c | 42 +++++------ installer.c | 24 +++---- multilog.c | 34 ++++----- pathexec_env.c | 14 ++-- readproctitle.c | 14 ++-- softlimit.c | 4 +- subgetopt.c | 2 +- supervise.c | 186 ++++++++++++++++++++++++------------------------ svc.c | 3 +- svpath.c | 2 +- svscan.c | 26 +++---- svstat.c | 4 +- svup.c | 6 +- 14 files changed, 186 insertions(+), 187 deletions(-) diff --git a/envdir.c b/envdir.c index f02e739..dddd3c9 100644 --- a/envdir.c +++ b/envdir.c @@ -71,14 +71,14 @@ int main(int argc,const char *const *argv) if (sa.len) { sa.len = byte_chr(sa.s,sa.len,'\n'); while (sa.len) { - if (sa.s[sa.len - 1] != ' ') - if (sa.s[sa.len - 1] != '\t') - break; - --sa.len; + if (sa.s[sa.len - 1] != ' ') + if (sa.s[sa.len - 1] != '\t') + break; + --sa.len; } for (i = 0;i < sa.len;++i) - if (!sa.s[i]) - sa.s[i] = '\n'; + if (!sa.s[i]) + sa.s[i] = '\n'; if (!stralloc_0(&sa)) nomem(); if (!pathexec_env(saname.s,sa.s)) nomem(); } diff --git a/envini.c b/envini.c index 3054e90..5d68c1f 100644 --- a/envini.c +++ b/envini.c @@ -47,28 +47,28 @@ static void parse(void) ++start; if (end > start) { if (sa.s[start] == '[' && sa.s[end-1] == ']') { - if (!stralloc_copyb(§ion,sa.s+start+1,end-start-2)) nomem(); - if (!stralloc_append(§ion,'_')) nomem(); + if (!stralloc_copyb(§ion,sa.s+start+1,end-start-2)) nomem(); + if (!stralloc_append(§ion,'_')) nomem(); } else if (sa.s[start] == ';') - ; + ; else { - i = start; - while (i < end && sa.s[i] != '=' && !is_space(sa.s[i])) - ++i; - if (!stralloc_copys(&name,prefix)) nomem(); - if (!stralloc_cat(&name,§ion)) nomem(); - if (!stralloc_catb(&name,sa.s+start,i-start)) nomem(); - if (!stralloc_0(&name)) nomem(); - while (i < end && is_space(sa.s[i])) - ++i; - if (i >= end || sa.s[i++] != '=') - continue; /* Ignore misformatted lines */ - while (i < end && is_space(sa.s[i])) - ++i; - if (!stralloc_copyb(&value,sa.s+i,end-i)) nomem(); - if (!stralloc_0(&value)) nomem(); - if (!pathexec_env(name.s,value.s)) nomem(); + i = start; + while (i < end && sa.s[i] != '=' && !is_space(sa.s[i])) + ++i; + if (!stralloc_copys(&name,prefix)) nomem(); + if (!stralloc_cat(&name,§ion)) nomem(); + if (!stralloc_catb(&name,sa.s+start,i-start)) nomem(); + if (!stralloc_0(&name)) nomem(); + while (i < end && is_space(sa.s[i])) + ++i; + if (i >= end || sa.s[i++] != '=') + continue; /* Ignore misformatted lines */ + while (i < end && is_space(sa.s[i])) + ++i; + if (!stralloc_copyb(&value,sa.s+i,end-i)) nomem(); + if (!stralloc_0(&value)) nomem(); + if (!pathexec_env(name.s,value.s)) nomem(); } } } @@ -81,8 +81,8 @@ int main(int argc,const char *const *argv) while ((opt = getopt(argc,argv,"p:")) != opteof) switch (opt) { - case 'p': prefix = optarg; break; - default: die_usage(); + case 'p': prefix = optarg; break; + default: die_usage(); } argv += optind; diff --git a/installer.c b/installer.c index e579cec..3de6f6a 100644 --- a/installer.c +++ b/installer.c @@ -94,36 +94,36 @@ void doit(stralloc *line) case 'd': if (mkdir(target.s,0700) == -1) if (errno != error_exist) - strerr_die3sys(111,FATAL,"unable to mkdir ",target.s); + strerr_die3sys(111,FATAL,"unable to mkdir ",target.s); break; case 'c': fdin = open_read(name); if (fdin == -1) { - if (opt) - return; - else - strerr_die3sys(111,FATAL,"unable to read ",name); + if (opt) + return; + else + strerr_die3sys(111,FATAL,"unable to read ",name); } buffer_init(&bufin,buffer_unixread,fdin,inbuf,sizeof(inbuf)); fdout = open_trunc(target.s); if (fdout == -1) - strerr_die3sys(111,FATAL,"unable to write ",target.s); + strerr_die3sys(111,FATAL,"unable to write ",target.s); buffer_init(&bufout,buffer_unixwrite,fdout,outbuf,sizeof(outbuf)); switch(buffer_copy(&bufout,&bufin)) { - case -2: - strerr_die3sys(111,FATAL,"unable to read ",name); - case -3: - strerr_die3sys(111,FATAL,"unable to write ",target.s); + case -2: + strerr_die3sys(111,FATAL,"unable to read ",name); + case -3: + strerr_die3sys(111,FATAL,"unable to write ",target.s); } close(fdin); if (buffer_flush(&bufout) == -1) - strerr_die3sys(111,FATAL,"unable to write ",target.s); + strerr_die3sys(111,FATAL,"unable to write ",target.s); if (fsync(fdout) == -1) - strerr_die3sys(111,FATAL,"unable to write ",target.s); + strerr_die3sys(111,FATAL,"unable to write ",target.s); close(fdout); break; diff --git a/multilog.c b/multilog.c index 464bb39..dca386e 100644 --- a/multilog.c +++ b/multilog.c @@ -136,8 +136,8 @@ int filesfit(struct cyclog *d) if (x->d_name[0] == '@') if (str_len(x->d_name) >= 25) if (str_start(x->d_name,fn.s)) { - unlink(x->d_name); - break; + unlink(x->d_name); + break; } } if (errno) { closedir(dir); return -1; } @@ -161,7 +161,7 @@ void finish(struct cyclog *d,const char *file,const char *code) fnlen = fmt_tai64nstamp(fn.s); fn.s[fnlen++] = '.'; do { - fn.s[fnlen++] = *code; + fn.s[fnlen++] = *code; } while (*code++ != 0); if (link(file,fn.s) == 0) break; @@ -419,7 +419,7 @@ void c_init(char **script) else if (script[i][0] == 'w') { code_finished = script[i] + 1; if (!stralloc_ready(&fn,str_len(code_finished)+TIMESTAMP+1)) - strerr_die2sys(111,FATAL,"unable to allocate memory"); + strerr_die2sys(111,FATAL,"unable to allocate memory"); } else if ((script[i][0] == '.') || (script[i][0] == '/')) { d->num = num; @@ -469,7 +469,7 @@ int flushread(int fd,char *buf,int len) if (flagforcerotate) { for (j = 0;j < cnum;++j) if (c[j].bytes > 0) - fullcurrent(&c[j]); + fullcurrent(&c[j]); flagforcerotate = 0; } @@ -524,8 +524,8 @@ void doit(char **script) return; if (flagtimestamp) { linelen = (flagtimestamp == 't') - ? fmt_tai64nstamp(line) - : fmt_accustamp(line); + ? fmt_tai64nstamp(line) + : fmt_accustamp(line); line[linelen++] = ' '; } if (buffer_gets(&ssin,line+linelen,MAXLINE-linelen,'\n',&linelen) < 0) @@ -538,11 +538,11 @@ void doit(char **script) for (i = 0;(action = script[i]) != 0;++i) switch(*action) { case 'F': - match = match_fnmatch; - break; + match = match_fnmatch; + break; case 'S': - match = match_simple; - break; + match = match_simple; + break; case '+': if (!flagselected) if (match(action + 1,line,linelen)) @@ -590,19 +590,19 @@ void doit(char **script) while (linelen == MAXLINE) { linelen = 0; if (buffer_gets(&ssin,line,MAXLINE,'\n',&linelen) < 0) { - flageof = 1; - break; + flageof = 1; + break; } if (linelen == 0) - break; + break; for (j = 0;j < cnum;++j) - if (c[j].flagselected) - buffer_put(&c[j].ss,line,linelen); + if (c[j].flagselected) + buffer_put(&c[j].ss,line,linelen); } for (j = 0;j < cnum;++j) if (c[j].flagselected) { - ch = '\n'; + ch = '\n'; buffer_PUTC(&c[j].ss,ch); } diff --git a/pathexec_env.c b/pathexec_env.c index 2cb101c..0779c75 100644 --- a/pathexec_env.c +++ b/pathexec_env.c @@ -52,14 +52,14 @@ void pathexec(const char *const *argv) if (!plus.s[i]) { split = str_chr(plus.s + j,'='); for (t = 0;t < elen;++t) - if (byte_equal(plus.s + j,split,e[t])) - if (e[t][split] == '=') { - --elen; - e[t] = e[elen]; - break; - } + if (byte_equal(plus.s + j,split,e[t])) + if (e[t][split] == '=') { + --elen; + e[t] = e[elen]; + break; + } if (plus.s[j + split]) - e[elen++] = plus.s + j; + e[elen++] = plus.s + j; j = i + 1; } e[elen] = 0; diff --git a/readproctitle.c b/readproctitle.c index 82fbffd..0203a6c 100644 --- a/readproctitle.c +++ b/readproctitle.c @@ -17,14 +17,14 @@ int main(int argc,char **argv) for (;;) switch(read(0,&ch,1)) { case 1: - if (ch) { - for (i = 4;i < len;++i) buf[i - 1] = buf[i]; - buf[len - 1] = ch; - } - break; + if (ch) { + for (i = 4;i < len;++i) buf[i - 1] = buf[i]; + buf[len - 1] = ch; + } + break; case 0: - _exit(0); + _exit(0); case -1: - if (errno != error_intr) _exit(111); + if (errno != error_intr) _exit(111); } } diff --git a/softlimit.c b/softlimit.c index ea4c5b0..2e17de7 100644 --- a/softlimit.c +++ b/softlimit.c @@ -99,7 +99,7 @@ int main(int argc,const char *const *argv,const char *const *envp) while ((opt = getopt(argc,argv,"a:c:d:f:l:m:o:p:r:s:t:")) != opteof) switch(opt) { case '?': - die_usage(); + die_usage(); case 'a': #ifdef RLIMIT_AS doit(RLIMIT_AS,optarg); @@ -144,7 +144,7 @@ int main(int argc,const char *const *argv,const char *const *envp) #ifdef RLIMIT_AS doit(RLIMIT_AS,optarg); #endif - break; + break; case 'o': #ifdef RLIMIT_NOFILE doit(RLIMIT_NOFILE,optarg); diff --git a/subgetopt.c b/subgetopt.c index 266e72a..85ace96 100644 --- a/subgetopt.c +++ b/subgetopt.c @@ -54,7 +54,7 @@ int sgopt(int argc,const char *const *argv,const char *opts) optproblem = c; return '?'; } - ++optind; + ++optind; } } return c; diff --git a/supervise.c b/supervise.c index 201ab09..485c618 100644 --- a/supervise.c +++ b/supervise.c @@ -121,11 +121,11 @@ static int forkexecve(struct svc *svc,const char *argv[],int fd) sig_uncatch(sig_ttystop); sig_uncatch(sig_cont); if (stat_exists("no-setsid") == 0) - setsid(); /* shouldn't fail; if it does, too bad */ + setsid(); /* shouldn't fail; if it does, too bad */ if (fd >= 0 && logpipe[0] >= 0) { - dup2(logpipe[fd],fd); - close(logpipe[0]); - close(logpipe[1]); + dup2(logpipe[fd],fd); + close(logpipe[0]); + close(logpipe[1]); } execve(argv[0],(char*const*)argv,environ); strerr_die4sys(111,FATAL,"unable to start ",dir,argv[0]+1); @@ -301,32 +301,32 @@ void doit(void) if (!r) break; if ((r == -1) && (errno != error_intr)) break; if (r == svcmain.pid) - svc = &svcmain; + svc = &svcmain; else if (r == svclog.pid) - svc = &svclog; + svc = &svclog; else - continue; + continue; killpid = svc->pid; svc->pid = 0; if (((svc == &svcmain && svc->flagstatus == svstatus_starting) && (wait_crashed(wstat) || wait_exitcode(wstat) != 0)) - || (!wait_crashed(wstat) && wait_exitcode(wstat) == 100)) { - svc->flagwantup = 0; - svc->flagstatus = svstatus_failed; + || (!wait_crashed(wstat) && wait_exitcode(wstat) == 100)) { + svc->flagwantup = 0; + svc->flagstatus = svstatus_failed; } else if (svc == &svcmain && svc->flagstatus == svstatus_starting) { } else if (!svc->flagwant || !svc->flagwantup) - svc->flagstatus = svstatus_stopped; + svc->flagstatus = svstatus_stopped; pidchange(svc, wait_crashed(wstat) ? "killed" : "exit", - wait_crashed(wstat) ? wait_stopsig(wstat) : wait_exitcode(wstat), - killpid); + wait_crashed(wstat) ? wait_stopsig(wstat) : wait_exitcode(wstat), + killpid); firstrun = 0; if ((svc->flagwant && svc->flagwantup) || (svc == &svcmain && svc->flagstatus == svstatus_starting)) { - if (!flagexit) - trystart(svc); + if (!flagexit) + trystart(svc); } else if (svc->flagstatus != svstatus_failed) - trystop(svc); + trystop(svc); break; } @@ -335,89 +335,89 @@ void doit(void) while (read(fdcontrol,&ch,1) == 1) switch(ch) { case '+': - if (killpid > 0) killpid = -killpid; - break; + if (killpid > 0) killpid = -killpid; + break; case '=': - if (killpid < 0) killpid = -killpid; - break; + if (killpid < 0) killpid = -killpid; + break; case 'L': - svc = &svclog; - killpid = svc->pid; - break; + svc = &svclog; + killpid = svc->pid; + break; case 'l': - svc = &svcmain; - killpid = svc->pid; - break; - case 'd': - svc->flagwant = 1; - svc->flagwantup = 0; - if (killpid) - stopsvc(killpid,svc); - else - trystop(svc); - announce(); - break; - case 'u': - if (svc == &svcmain) - firstrun = !svcmain.flagwantup; - svc->flagwant = 1; - svc->flagwantup = 1; - if (!svc->pid) - svc->flagstatus = svstatus_starting; - announce(); - if (!svc->pid) trystart(svc); - break; - case 'o': - svc->flagwant = 0; - announce(); - if (!svc->pid) trystart(svc); - break; - case 'a': - if (killpid) kill(killpid,SIGALRM); - break; - case 'h': - if (killpid) kill(killpid,SIGHUP); - break; - case 'k': - if (killpid) kill(killpid,SIGKILL); - break; - case 't': - if (killpid) kill(killpid,SIGTERM); - break; - case 'i': - if (killpid) kill(killpid,SIGINT); - break; - case 'q': - if (killpid) kill(killpid,SIGQUIT); - break; - case '1': - if (killpid) kill(killpid,SIGUSR1); - break; - case '2': - if (killpid) kill(killpid,SIGUSR2); - break; - case 'w': - if (killpid) kill(killpid,SIGWINCH); - break; - case 'p': - svc->flagpaused = 1; - announce(); - if (killpid) kill(killpid,SIGSTOP); - break; - case 'c': - svc->flagpaused = 0; - announce(); - if (killpid) kill(killpid,SIGCONT); - break; - case 'x': - flagexit = 1; - announce(); - break; + svc = &svcmain; + killpid = svc->pid; + break; + case 'd': + svc->flagwant = 1; + svc->flagwantup = 0; + if (killpid) + stopsvc(killpid,svc); + else + trystop(svc); + announce(); + break; + case 'u': + if (svc == &svcmain) + firstrun = !svcmain.flagwantup; + svc->flagwant = 1; + svc->flagwantup = 1; + if (!svc->pid) + svc->flagstatus = svstatus_starting; + announce(); + if (!svc->pid) trystart(svc); + break; + case 'o': + svc->flagwant = 0; + announce(); + if (!svc->pid) trystart(svc); + break; + case 'a': + if (killpid) kill(killpid,SIGALRM); + break; + case 'h': + if (killpid) kill(killpid,SIGHUP); + break; + case 'k': + if (killpid) kill(killpid,SIGKILL); + break; + case 't': + if (killpid) kill(killpid,SIGTERM); + break; + case 'i': + if (killpid) kill(killpid,SIGINT); + break; + case 'q': + if (killpid) kill(killpid,SIGQUIT); + break; + case '1': + if (killpid) kill(killpid,SIGUSR1); + break; + case '2': + if (killpid) kill(killpid,SIGUSR2); + break; + case 'w': + if (killpid) kill(killpid,SIGWINCH); + break; + case 'p': + svc->flagpaused = 1; + announce(); + if (killpid) kill(killpid,SIGSTOP); + break; + case 'c': + svc->flagpaused = 0; + announce(); + if (killpid) kill(killpid,SIGCONT); + break; + case 'x': + flagexit = 1; + announce(); + break; } if (flagexit - && svcmain.flagstatus == svstatus_stopped - && (svclog.flagstatus == svstatus_running || svclog.flagstatus == svstatus_started)) + && svcmain.flagstatus == svstatus_stopped + && (svclog.flagstatus == svstatus_running || svclog.flagstatus == svstatus_started)) stopsvc(svclog.pid,&svclog); } } diff --git a/svc.c b/svc.c index 79e9397..0063f4e 100644 --- a/svc.c +++ b/svc.c @@ -50,8 +50,7 @@ int main(int argc,const char *const *argv) while ((dir = *argv++) != 0) { if (chdir(dir) == -1) strerr_warn4sys(WARNING,"unable to chdir to ",dir,""); - else if (!svpath_init() - || (fncontrol = svpath_make("/control")) == 0) + else if (!svpath_init() || (fncontrol = svpath_make("/control")) == 0) strerr_warn4sys(WARNING,"unable to setup control path for ",dir,""); else { fd = open_write(fncontrol); diff --git a/svpath.c b/svpath.c index 114d935..631b508 100644 --- a/svpath.c +++ b/svpath.c @@ -19,7 +19,7 @@ int svpath_init(void) return 0; for (ptr = cwd+1; *ptr != 0; ++ptr) if (*ptr == '/') - *ptr = ':'; + *ptr = ':'; if (!stralloc_cats(&svdir, cwd)) return 0; } diff --git a/svscan.c b/svscan.c index edcc46b..70f99b4 100644 --- a/svscan.c +++ b/svscan.c @@ -65,7 +65,7 @@ void start(const char *fn) for (i = 0;i < numx;++i) if (x[i].ino == st.st_ino) if (x[i].dev == st.st_dev) - break; + break; if (i == numx) { if (numx >= SERVICES) { @@ -83,12 +83,12 @@ void start(const char *fn) byte_copy(fnlog,fnlen,fn); byte_copy(fnlog + fnlen,5,"/log"); if (stat(fnlog,&st) == 0) - x[i].flaglog = S_ISDIR(st.st_mode); + x[i].flaglog = S_ISDIR(st.st_mode); else - if (errno != error_noent) { + if (errno != error_noent) { strerr_warn4sys(WARNING,"unable to stat ",fn,"/log"); return; - } + } } if (x[i].flaglog) { @@ -111,18 +111,18 @@ void start(const char *fn) return; case 0: if (x[i].flaglog) - if (fd_move(1,x[i].pi[1]) == -1) + if (fd_move(1,x[i].pi[1]) == -1) + strerr_die3sys(111,WARNING,"unable to set up descriptors for ",fn); + if (i == logx) + if (fd_move(0,logpipe[0]) == -1) strerr_die3sys(111,WARNING,"unable to set up descriptors for ",fn); - if (i == logx) - if (fd_move(0,logpipe[0]) == -1) - strerr_die3sys(111,WARNING,"unable to set up descriptors for ",fn); args[0] = "supervise"; args[1] = fn; args[2] = 0; - pathexec_run(*args,args,(const char*const*)environ); + pathexec_run(*args,args,(const char*const*)environ); strerr_die3sys(111,WARNING,"unable to start supervise ",fn); default: - x[i].pid = child; + x[i].pid = child; all_stopped = 0; } else @@ -140,15 +140,15 @@ void start(const char *fn) case 0: if (fd_move(0,x[i].pi[0]) == -1) strerr_die4sys(111,WARNING,"unable to set up descriptors for ",fn,"/log"); - if (chdir(fn) == -1) + if (chdir(fn) == -1) strerr_die3sys(111,WARNING,"unable to switch to ",fn); args[0] = "supervise"; args[1] = "log"; args[2] = 0; - pathexec_run(*args,args,(const char*const*)environ); + pathexec_run(*args,args,(const char*const*)environ); strerr_die4sys(111,WARNING,"unable to start supervise ",fn,"/log"); default: - x[i].pidlog = child; + x[i].pidlog = child; all_stopped = 0; } else diff --git a/svstat.c b/svstat.c index c2a91b0..f010b7a 100644 --- a/svstat.c +++ b/svstat.c @@ -173,8 +173,8 @@ void doit(const char *dir) if (check_log != 0) { if (r >= 20+18) { if (check_log < 0) { - buffer_puts(&b,"\n"); - buffer_puts(&b,dir); + buffer_puts(&b,"\n"); + buffer_puts(&b,dir); } buffer_puts(&b," log: "); showstatus(status+20,r-20,normallyup); diff --git a/svup.c b/svup.c index 6a78b66..76de1eb 100644 --- a/svup.c +++ b/svup.c @@ -13,7 +13,7 @@ static int checkstatus(const char status[19], int r) /* Check for a PID */ return (status[12] || status[13] || status[14] || status[15]) /* Check for a PID */ || (r > 18 - && (status[18] == svstatus_started || status[18] == svstatus_running)); + && (status[18] == svstatus_started || status[18] == svstatus_running)); } static void die_usage(void) @@ -82,11 +82,11 @@ int main(int argc,const char *const *argv) if (check_log != 0) { if (rd < 20+18) { if (check_log > 0) - _exit(100); + _exit(100); } else if (!checkstatus(status+20,rd-20)) - _exit(100); + _exit(100); } _exit(0); } From f70bba5727d72ef4e8791ed97fdf8fae9077b61f Mon Sep 17 00:00:00 2001 From: Rick Myers Date: Sat, 29 Sep 2018 13:03:20 -0400 Subject: [PATCH 2/9] sleeper: handle out of order cont/term signals --- sleeper.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 92 insertions(+), 15 deletions(-) diff --git a/sleeper.c b/sleeper.c index 00fed2c..1a1cee7 100644 --- a/sleeper.c +++ b/sleeper.c @@ -1,39 +1,84 @@ +#include #include +#include "ndelay.h" +#include "strerr.h" +#include "error.h" #include "byte.h" #include "sig.h" #include "str.h" -#include + +static int selfpipe[2]; static void catch_sig(int sig) +{ + int ignored; + char c; + + c = (char)sig; + ignored = write(selfpipe[1],&c,1); + (void)ignored; +} + +static void show_sig(int sig) { char buf[7+14+2] = "Caught "; const char *name; int ignored; int i; + switch (sig) { - case SIGALRM: name = "ALRM"; break; - case SIGCONT: name = "CONT"; break; - case SIGHUP: name = "HUP"; break; - case SIGINT: name = "INT"; break; - case SIGQUIT: name = "QUIT"; break; - case SIGTERM: name = "TERM"; break; - case SIGUSR1: name = "USR1"; break; - case SIGUSR2: name = "USR2"; break; - case SIGWINCH: name = "WINCH"; break; - default: name = "unknown signal"; + case SIGALRM: name = "ALRM"; break; + case SIGCONT: name = "CONT"; break; + case SIGHUP: name = "HUP"; break; + case SIGINT: name = "INT"; break; + case SIGQUIT: name = "QUIT"; break; + case SIGTERM: name = "TERM"; break; + case SIGUSR1: name = "USR1"; break; + case SIGUSR2: name = "USR2"; break; + case SIGWINCH: name = "WINCH"; break; + default: name = "unknown signal"; } i = str_len(name); byte_copy(buf+7,i,name); i += 7; buf[i++] = '\n'; ignored = write(1,buf,i); - if (sig != SIGCONT) - _exit(1); (void)ignored; } +static void show_err() +{ + int ignored; + + ignored = write(1,"invalid signal\n",15); + return; + (void)ignored; +} + +static void show_one(int sig) +{ + show_sig(sig); + return; +} + +static void show_two(int sig1, int sig2) +{ + show_sig(sig1); + show_sig(sig2); + return; +} + int main(void) { + int r; + int nc, nt, oc, ot; + int new_sig, old_sig=0; + char buf; + + if (pipe(selfpipe) == -1) + strerr_die1sys(111,"sleeper: fatal: unable to create pipe"); + ndelay_on(selfpipe[1]); + sig_catch(SIGALRM,catch_sig); sig_catch(SIGCONT,catch_sig); sig_catch(SIGHUP,catch_sig); @@ -43,6 +88,38 @@ int main(void) sig_catch(SIGUSR1,catch_sig); sig_catch(SIGUSR2,catch_sig); sig_catch(SIGWINCH,catch_sig); - sleep(9999); - return 0; + + for (;;) { + r = read(selfpipe[0],&buf,1); + if (!r) break; + if (r == -1) { + if (errno == error_intr) continue; + break; + } + + new_sig = (int)buf; + + nc = new_sig == SIGCONT; + nt = new_sig == SIGTERM; + oc = old_sig == SIGCONT; + ot = old_sig == SIGTERM; + + if (!nc && !nt && !oc && !ot) {show_one(new_sig); break; } + if (!nc && !nt && !oc && ot) {show_two(SIGTERM, new_sig); break; } + if (!nc && !nt && oc && !ot) {show_two(SIGCONT, new_sig); break; } + if (!nc && !nt && oc && ot) {show_err(); break; } + if (!nc && nt && !oc && !ot) {old_sig = SIGTERM; continue;} + if (!nc && nt && !oc && ot) {show_one(SIGTERM); continue;} + if (!nc && nt && oc && !ot) {show_two(SIGCONT, SIGTERM); break; } + if (!nc && nt && oc && ot) {show_err(); break; } + if ( nc && !nt && !oc && !ot) {old_sig = SIGCONT; continue;} + if ( nc && !nt && !oc && ot) {show_two(SIGCONT, SIGTERM); break; } + if ( nc && !nt && oc && !ot) {show_one(SIGCONT); continue;} + if ( nc && !nt && oc && ot) {show_err(); break; } + if ( nc && nt && !oc && !ot) {show_err(); break; } + if ( nc && nt && !oc && ot) {show_err(); break; } + if ( nc && nt && oc && !ot) {show_err(); break; } + if ( nc && nt && oc && ot) {show_err(); break; } + } + _exit(0); } From 7eb4c460b0044f98c5338db55a89faa8ccc503c5 Mon Sep 17 00:00:00 2001 From: Rick Myers Date: Sat, 29 Sep 2018 14:30:23 -0400 Subject: [PATCH 3/9] svscan: add tests for sigterm --- rts.tests/svscan-sigterm.exp | 107 +++++++++++ rts.tests/svscan-sigterm.sh | 350 +++++++++++++++++++++++++++++++++++ 2 files changed, 457 insertions(+) create mode 100644 rts.tests/svscan-sigterm.exp create mode 100644 rts.tests/svscan-sigterm.sh diff --git a/rts.tests/svscan-sigterm.exp b/rts.tests/svscan-sigterm.exp new file mode 100644 index 0000000..d762cb9 --- /dev/null +++ b/rts.tests/svscan-sigterm.exp @@ -0,0 +1,107 @@ +--- svscan handles sigterm + +--- svscanboot started +ok + +--- svscan started +ok + +--- readproctitle started +ok + +--- svscanboot pid looks sane +ok + +--- svscan pid looks sane +ok + +--- readproctitle pid looks sane +ok + +--- svscanboot is running +ok + +--- svscan is running +ok + +--- readproctitle is running +ok + +--- supervise svc0 is running +ok + +--- supervise svc1 is running +ok + +--- supervise svc1/log is running +ok + +--- supervise svc2 is running +ok + +--- svc0.log readable +ok + +--- svc1-main.log readable +ok + +--- svc1-log.log readable +ok + +--- svc2-main.log readable +ok + +--- svc2-log.log readable +ok + +--- sigterm sent +ok + +--- svscan is stopped +ok + +--- readproctitle is stopped +ok + +--- svscanboot is stopped +ok + +--- supervise svc0 is down +ok + +--- supervise svc1 is down +ok + +--- supervise svc1/log is down +ok + +--- supervise svc2 is down +ok + +--- svscanboot log + +--- svc0 log +svc0 ran +Caught CONT +Caught TERM + +--- svc1 main log +svc1-main ran +Caught CONT +Caught TERM + +--- svc1 log log +svc1-log ran +Caught CONT +Caught TERM + +--- svc2 main log +svc2-main ran +Caught CONT +Caught TERM + +--- svc2 log log +svc2-log ran +Caught CONT +Caught TERM + diff --git a/rts.tests/svscan-sigterm.sh b/rts.tests/svscan-sigterm.sh new file mode 100644 index 0000000..4f6e68b --- /dev/null +++ b/rts.tests/svscan-sigterm.sh @@ -0,0 +1,350 @@ +# TODO: +# * how do we know logs stop *after* main? +# +# * if logging with multilog (which exits at end of stdin), will a new +# multilog be created after the main supervise exits, but before the +# log supervise is signaled? if so, can we avoid it? +# + +# svc0 - no log +# svc1 - svscan-managed log +# svc2 - supervise-managed log + +echo '--- svscan handles sigterm' +echo + +rm -rf test.boot +mkdir test.boot || die "Could not create test.boot" +mkdir test.boot/service || die "Could not create test.boot/service" +mkdir test.boot/svc0 || die "Could not create test.boot/svc0" +mkdir test.boot/svc1 || die "Could not create test.boot/svc1" +mkdir test.boot/svc1/log || die "Could not create test.boot/svc1/log" +mkdir test.boot/svc2 || die "Could not create test.boot/svc2" + +cd test.boot || die "Could not change to test.boot" + +ln -s ../svc0 service || die "Could not link svc0" +ln -s ../svc1 service || die "Could not link svc1" +ln -s ../svc2 service || die "Could not link svc2" + + +catexe svscan <<'EOF' || die "Could not create svscan wrapper" +#!/bin/sh +PATH=`echo $PATH | cut -d':' -f2-` +exec env - PATH=$PATH svscan $@ & +echo $! > svscan.pid +EOF + +## this doesnt work. get the pid in svscanboot instead. +#catexe readproctitle <<'EOF' || die "Could not create readproctitle wrapper" +##!/bin/sh +#exec >readproctitle.log +#exec 2>&1 +#PATH=`echo $PATH | cut -d':' -f2-` +#exec env - PATH=$PATH readproctitle $@ & +#echo $! > test.boot/readproctitle.pid +#EOF + +test -x ../../svscanboot || die "Could not find svscanboot source" +sed -r \ + -e 's,PATH=/,PATH=.:..:../..:../../..:/,' \ + -e 's,^exec 2?>.+,,' \ + -e 's,/command/svc -dx .+,,g' \ + -e 's,/?service,service,g' \ + -e 's,readproctitle..*,& \& \ +,' \ + -e '$a\ +echo $! > readproctitle.pid' \ + -e '$a\ +wait' \ +< ../../svscanboot \ +| catexe svscanboot +test -x svscanboot || die "Could not create svscanboot stub" + +catexe svc0/run <<'EOF' || die "Could not create svc0/run script" +#!/bin/sh +echo svc0 ran >> ../svc0.log +exec ../../../sleeper >> ../svc0.log +EOF + +catexe svc1/run <<'EOF' || die "Could not create svc1/run script" +#!/bin/sh +echo svc1-main ran >> ../svc1-main.log +exec ../../../sleeper >> ../svc1-main.log +EOF + +catexe svc1/log/run <<'EOF' || die "Could not create svc1/log/run script" +#!/bin/sh +echo svc1-log ran >> ../../svc1-log.log +exec ../../../../sleeper >> ../../svc1-log.log +EOF + +catexe svc2/run <<'EOF' || die "Could not create svc2/run script" +#!/bin/sh +echo svc2-main ran >> ../svc2-main.log +exec ../../../sleeper >> ../svc2-main.log +EOF + +catexe svc2/log <<'EOF' || die "Could not create svc2/log script" +#!/bin/sh +echo svc2-log ran >> ../svc2-log.log +exec ../../../sleeper >> ../svc2-log.log +EOF + + +timed_read() { + for i in 10 9 8 7 6 5 4 3 2 1 0; do + if [ -f $1 ]; then + head -n 1 $1 + break + fi + if [ $i -eq 0 ]; then + echo 0 + break + fi + sleep 1 + done +} + +echo '--- svscanboot started' +./svscanboot service > svscanboot.log 2>&1 & +svscanbootpid=$! +if [ "$svscanbootpid" != "0" ]; then + echo ok +fi +echo + +echo '--- svscan started' +svscanpid=`timed_read svscan.pid` +if [ "$svscanpid" != "0" ]; then + echo ok +fi +echo + +echo '--- readproctitle started' +readproctitlepid=`timed_read readproctitle.pid` +if [ "$readproctitlepid" != "0" ]; then + echo ok +fi +echo + + +check_pid_sanity() { + if [ `echo $1 | grep -E '^[1-9][0-9]{0,4}$' | wc -l` != "1" ] \ + || [ $1 -le 1 ] \ + || [ $1 -ge 99999 ] + then + echo 0 + else + echo $1 + fi +} + +echo '--- svscanboot pid looks sane' +svscanbootpid=`check_pid_sanity $svscanbootpid` +if [ "$svscanbootpid" != "0" ]; then + echo ok +fi +echo + +echo '--- svscan pid looks sane' +svscanpid=`check_pid_sanity $svscanpid` +if [ "$svscanpid" != "0" ]; then + echo ok +fi +echo + +echo '--- readproctitle pid looks sane' +readproctitlepid=`check_pid_sanity $readproctitlepid` +if [ "$readproctitlepid" != "0" ]; then + echo ok +fi +echo + + +echo '--- svscanboot is running' +if kill -0 $svscanbootpid; then + echo ok +else + svscanbootpid=0 +fi +echo + +echo '--- svscan is running' +if kill -0 $svscanpid; then + echo ok +else + svscanpid=0 +fi +echo + +echo '--- readproctitle is running' +if kill -0 $readproctitlepid; then + echo ok +else + readproctitlepid=0 +fi +echo + +echo '--- supervise svc0 is running' +svok svc0 && echo ok +echo + +echo '--- supervise svc1 is running' +svok svc1 && echo ok +echo + +echo '--- supervise svc1/log is running' +svok svc1/log && echo ok +echo + +echo '--- supervise svc2 is running' +svok svc2 && echo ok +echo + + +# be sure shells are running, otherwise signal can come before +# sleeper execs, maybe even while shell is still starting. +# would be better if sleeper could tell us when ready. +# maybe sleeper could open/write a named pipe one time just +# before main loop? +# sleeper -w wait.fifo +# then here, +# cat wait.fifo > /dev/null +# both sleeper and test would be forced to wait at their +# respective read/write points until the other caught up. +# +# here signal can arrive while sleeper is starting. :( +timed_readable() { + for i in 10 9 8 7 6 5 4 3 2 1 0; do + if [ -r $1 ]; then + echo ok + break + fi + if [ $i -eq 0 ]; then + break + fi + sleep 1 + done +} + +echo '--- svc0.log readable' +timed_readable svc0.log +echo + +echo '--- svc1-main.log readable' +timed_readable svc1-main.log +echo + +echo '--- svc1-log.log readable' +timed_readable svc1-log.log +echo + +echo '--- svc2-main.log readable' +timed_readable svc2-main.log +echo + +echo '--- svc2-log.log readable' +timed_readable svc2-log.log +echo + + +echo '--- sigterm sent' +if [ "$svscanpid" != "0" ] && kill -TERM $svscanpid; then + echo ok +fi +echo + + +timed_stop() { + if [ $1 -ne 0 ]; then + for i in 10 9 8 7 6 5 4 3 2 1 0; do + if kill -0 $1 2>/dev/null; then + if [ $i -eq 0 ]; then + kill -HUP $1 + break + fi + sleep 1 + else + echo ok + break + fi + done + fi +} + +echo '--- svscan is stopped' +timed_stop $svscanpid +echo + +echo '--- readproctitle is stopped' +timed_stop $readproctitlepid +echo + +echo '--- svscanboot is stopped' +timed_stop $svscanbootpid +echo + + +timed_down() { + for i in 10 9 8 7 6 5 4 3 2 1 0; do + if svok $1; then + svc -dx $1 + if [ $i -eq 0 ]; then + break + fi + sleep 1 + else + echo ok + break + fi + done +} + +echo '--- supervise svc0 is down' +timed_down svc0 +echo + +echo '--- supervise svc1 is down' +timed_down svc1 +echo + +echo '--- supervise svc1/log is down' +timed_down svc1/log +echo + +echo '--- supervise svc2 is down' +timed_down svc2 +echo + + +echo '--- svscanboot log' +cat svscanboot.log +echo + +echo '--- svc0 log' +cat svc0.log +echo + +echo '--- svc1 main log' +cat svc1-main.log +echo + +echo '--- svc1 log log' +cat svc1-log.log +echo + +echo '--- svc2 main log' +cat svc2-main.log | uniq +echo + +echo '--- svc2 log log' +cat svc2-log.log +echo + + +# just in case +svc -dx svc0 svc1 svc1/log svc2 2>/dev/null + +cd $TOP + From 8bb9db78f768d6f9940f97f9b3c11890bd3d8807 Mon Sep 17 00:00:00 2001 From: Rick Myers Date: Fri, 5 Oct 2018 15:22:17 -0400 Subject: [PATCH 4/9] supervise-start.sh: portability fix for Solaris per CHANGES.djb --- rts.tests/supervise-start.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rts.tests/supervise-start.sh b/rts.tests/supervise-start.sh index 83a7766..9398c2b 100644 --- a/rts.tests/supervise-start.sh +++ b/rts.tests/supervise-start.sh @@ -18,13 +18,13 @@ done svc -o test.sv for c in 1 2 3 4 5 6 7 8 do - if [ -e test.sv/out ] + if [ -r test.sv/out ] then break fi sleep 1 done -if [ -e test.sv/out ] +if [ -r test.sv/out ] then cat test.sv/out else From cb3cc5121d8362ad7efb7992e744f9a63d11fba1 Mon Sep 17 00:00:00 2001 From: Rick Myers Date: Sun, 7 Oct 2018 07:57:00 -0400 Subject: [PATCH 5/9] add makefifo program for rts --- .gitignore | 1 + makefifo.c | 35 +++++++++++++++++++++++++++++++++++ makefifo=x | 2 ++ programs.do | 7 ++++--- rts.tests/10-makefifo.exp | 35 +++++++++++++++++++++++++++++++++++ rts.tests/10-makefifo.sh | 35 +++++++++++++++++++++++++++++++++++ 6 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 makefifo.c create mode 100644 makefifo=x create mode 100644 rts.tests/10-makefifo.exp create mode 100644 rts.tests/10-makefifo.sh diff --git a/.gitignore b/.gitignore index ded7be7..3871e64 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ haswaitp.h installer iopause.h load +makefifo makelib matchtest multilog diff --git a/makefifo.c b/makefifo.c new file mode 100644 index 0000000..9b689d5 --- /dev/null +++ b/makefifo.c @@ -0,0 +1,35 @@ +#include "alloc.h" +#include "fifo.h" +#include "stralloc.h" +#include "strerr.h" + +#define FATAL "makefifo: fatal: " +#define WARNING "makefifo: warning: " + +static void die_usage(void) +{ + strerr_die1x(100,"makefifo: usage: makefifo fifo1 [fifo2 ...]"); +} + +static void die_nomem(void) +{ + strerr_die2sys(100,FATAL,"out of memory"); +} + +int main(int argc, char **argv) +{ + stralloc fn = {0,0,0}; + int i; + + if (argc < 2) die_usage(); + + for (i = 1;i < argc; ++i) { + if (!stralloc_copys(&fn,argv[i])) die_nomem(); + if (!stralloc_0(&fn)) die_nomem(); + if (fifo_make(fn.s,0600)) + strerr_warn3sys(WARNING,"can't make fifo ",fn.s); + } + + alloc_free(fn.s); + return 0; +} diff --git a/makefifo=x b/makefifo=x new file mode 100644 index 0000000..09db56a --- /dev/null +++ b/makefifo=x @@ -0,0 +1,2 @@ +unix.a +byte.a diff --git a/programs.do b/programs.do index f635648..0a6bbd4 100644 --- a/programs.do +++ b/programs.do @@ -1,3 +1,4 @@ -dependon envdir envini envuidgid fghack installer matchtest multilog pgrphack \ - readproctitle setlock setuidgid setuser sleeper softlimit supervise svc \ - svok svscan svscanboot svstat svup tai64n tai64nlocal +dependon envdir envini envuidgid fghack installer makefifo matchtest \ + multilog pgrphack readproctitle setlock setuidgid setuser \ + sleeper softlimit supervise svc svok svscan svscanboot svstat \ + svup tai64n tai64nlocal diff --git a/rts.tests/10-makefifo.exp b/rts.tests/10-makefifo.exp new file mode 100644 index 0000000..bb0a528 --- /dev/null +++ b/rts.tests/10-makefifo.exp @@ -0,0 +1,35 @@ +--- makefifo works +makefifo: warning: can't make fifo fifo0: file already exists +makefifo: warning: can't make fifo fifo1: file already exists +makefifo: warning: can't make fifo fifo2: file already exists +makefifo: warning: can't make fifo fifo3: file already exists +makefifo: warning: can't make fifo fifo4: file already exists +makefifo: warning: can't make fifo fifo5: file already exists +makefifo: warning: can't make fifo fifo6: file already exists +makefifo: warning: can't make fifo fifo7: file already exists +makefifo: warning: can't make fifo fifo8: file already exists +makefifo: warning: can't make fifo fifo9: file already exists +makefifo: warning: can't make fifo fifoA: file already exists +makefifo: warning: can't make fifo fifoB: file already exists +makefifo: warning: can't make fifo fifoC: file already exists +makefifo: warning: can't make fifo fifoD: file already exists +makefifo: warning: can't make fifo fifoE: file already exists +makefifo: warning: can't make fifo fifoF: file already exists +makefifo: warning: can't make fifo fifo0: file already exists +makefifo: usage: makefifo fifo1 [fifo2 ...] +ok 0 +ok 1 +ok 2 +ok 3 +ok 4 +ok 5 +ok 6 +ok 7 +ok 8 +ok 9 +ok A +ok B +ok C +ok D +ok E +ok F diff --git a/rts.tests/10-makefifo.sh b/rts.tests/10-makefifo.sh new file mode 100644 index 0000000..7f6380b --- /dev/null +++ b/rts.tests/10-makefifo.sh @@ -0,0 +1,35 @@ +echo '--- makefifo works' +rm -rf makefifo +mkdir makefifo +cd makefifo +makefifo fifo0 fifo1 fifo2 +makefifo fifo3 fifo4 fifo0 +makefifo fifo5 fifo6 +makefifo fifo7 fifo1 fifo8 +makefifo fifo9 fifo2 fifo3 +makefifo fifoA fifo4 +makefifo fifo5 fifoB fifoC +makefifo fifo6 fifoD fifo7 +makefifo fifo8 fifoE +makefifo fifo9 fifoA fifoF +makefifo fifoB fifoC fifoD +makefifo fifoE fifoF +makefifo fifo0 +makefifo +if [ -p fifo0 ]; then echo ok 0; fi +if [ -p fifo1 ]; then echo ok 1; fi +if [ -p fifo2 ]; then echo ok 2; fi +if [ -p fifo3 ]; then echo ok 3; fi +if [ -p fifo4 ]; then echo ok 4; fi +if [ -p fifo5 ]; then echo ok 5; fi +if [ -p fifo6 ]; then echo ok 6; fi +if [ -p fifo7 ]; then echo ok 7; fi +if [ -p fifo8 ]; then echo ok 8; fi +if [ -p fifo9 ]; then echo ok 9; fi +if [ -p fifoA ]; then echo ok A; fi +if [ -p fifoB ]; then echo ok B; fi +if [ -p fifoC ]; then echo ok C; fi +if [ -p fifoD ]; then echo ok D; fi +if [ -p fifoE ]; then echo ok E; fi +if [ -p fifoF ]; then echo ok F; fi +cd $TOP From 9767c04b192a82d726ea8bca69628013790ee942 Mon Sep 17 00:00:00 2001 From: Rick Myers Date: Sun, 7 Oct 2018 08:13:15 -0400 Subject: [PATCH 6/9] sleeper: add switches for rts --- rts.tests/20-sleeper.exp | 35 ++++++ rts.tests/20-sleeper.sh | 63 ++++++++++ rts.tests/svc.exp | 1 + rts.tests/svc.sh | 28 +++-- rts.tests/svscan-sigterm.sh | 60 +++------ sleeper.c | 236 +++++++++++++++++++++++++++++------- sleeper=x | 1 + 7 files changed, 330 insertions(+), 94 deletions(-) create mode 100644 rts.tests/20-sleeper.exp create mode 100644 rts.tests/20-sleeper.sh diff --git a/rts.tests/20-sleeper.exp b/rts.tests/20-sleeper.exp new file mode 100644 index 0000000..90c3f17 --- /dev/null +++ b/rts.tests/20-sleeper.exp @@ -0,0 +1,35 @@ +--- sleeper -w works +sleeper: warning: -w missing argument +sleeper: usage: sleeper [-d delay] [-p pfifo] [-w wfifo] [-x code] +sleeper: fatal: unable to stat foo: file does not exist +ok +Caught CONT +Caught TERM + +--- sleeper -d works +sleeper: warning: -d missing argument +sleeper: usage: sleeper [-d delay] [-p pfifo] [-w wfifo] [-x code] +sleeper: warning: -d invalid argument +sleeper: usage: sleeper [-d delay] [-p pfifo] [-w wfifo] [-x code] +ok +Caught CONT +Caught TERM + +--- sleeper -p works +sleeper: warning: -p missing argument +sleeper: usage: sleeper [-d delay] [-p pfifo] [-w wfifo] [-x code] +sleeper: fatal: unable to stat foo: file does not exist +ok +Caught ALRM +Caught HUP +Caught CONT +Caught TERM + +--- sleeper -x works +sleeper: warning: -x missing argument +sleeper: usage: sleeper [-d delay] [-p pfifo] [-w wfifo] [-x code] +sleeper: warning: -x invalid argument +sleeper: usage: sleeper [-d delay] [-p pfifo] [-w wfifo] [-x code] +ok +Caught CONT +Caught TERM diff --git a/rts.tests/20-sleeper.sh b/rts.tests/20-sleeper.sh new file mode 100644 index 0000000..76c821f --- /dev/null +++ b/rts.tests/20-sleeper.sh @@ -0,0 +1,63 @@ +echo '--- sleeper -w works' +sleeper -w +sleeper -w foo +makefifo sleeper.wait +catexe test.sv/run < test.sv/run -chmod 755 test.sv/run +makefifo fifo.out fifo.wait +catexe test.sv/run <> ../svc0.log -exec ../../../sleeper >> ../svc0.log +echo svc0 ran >> ../svc0.log +exec ../../../sleeper -w ../svc0.ready >> ../svc0.log EOF +makefifo svc1-main.ready catexe svc1/run <<'EOF' || die "Could not create svc1/run script" #!/bin/sh -echo svc1-main ran >> ../svc1-main.log -exec ../../../sleeper >> ../svc1-main.log +echo svc1-main ran >> ../svc1-main.log +exec ../../../sleeper -w ../svc1-main.ready >> ../svc1-main.log EOF +makefifo svc1-log.ready catexe svc1/log/run <<'EOF' || die "Could not create svc1/log/run script" #!/bin/sh -echo svc1-log ran >> ../../svc1-log.log -exec ../../../../sleeper >> ../../svc1-log.log +echo svc1-log ran >> ../../svc1-log.log +exec ../../../../sleeper -w ../../svc1-log.ready >> ../../svc1-log.log EOF +makefifo svc2-main.ready catexe svc2/run <<'EOF' || die "Could not create svc2/run script" #!/bin/sh -echo svc2-main ran >> ../svc2-main.log -exec ../../../sleeper >> ../svc2-main.log +echo svc2-main ran >> ../svc2-main.log +exec ../../../sleeper -w ../svc2-main.ready >> ../svc2-main.log EOF +makefifo svc2-log.ready catexe svc2/log <<'EOF' || die "Could not create svc2/log script" #!/bin/sh -echo svc2-log ran >> ../svc2-log.log -exec ../../../sleeper >> ../svc2-log.log +echo svc2-log ran >> ../svc2-log.log +exec ../../../sleeper -w ../svc2-log.ready >> ../svc2-log.log EOF @@ -203,49 +208,24 @@ svok svc2 && echo ok echo -# be sure shells are running, otherwise signal can come before -# sleeper execs, maybe even while shell is still starting. -# would be better if sleeper could tell us when ready. -# maybe sleeper could open/write a named pipe one time just -# before main loop? -# sleeper -w wait.fifo -# then here, -# cat wait.fifo > /dev/null -# both sleeper and test would be forced to wait at their -# respective read/write points until the other caught up. -# -# here signal can arrive while sleeper is starting. :( -timed_readable() { - for i in 10 9 8 7 6 5 4 3 2 1 0; do - if [ -r $1 ]; then - echo ok - break - fi - if [ $i -eq 0 ]; then - break - fi - sleep 1 - done -} - echo '--- svc0.log readable' -timed_readable svc0.log +cat svc0.ready echo echo '--- svc1-main.log readable' -timed_readable svc1-main.log +cat svc1-main.ready echo echo '--- svc1-log.log readable' -timed_readable svc1-log.log +cat svc1-log.ready echo echo '--- svc2-main.log readable' -timed_readable svc2-main.log +cat svc2-main.ready echo echo '--- svc2-log.log readable' -timed_readable svc2-log.log +cat svc2-log.ready echo diff --git a/sleeper.c b/sleeper.c index 1a1cee7..a72d85b 100644 --- a/sleeper.c +++ b/sleeper.c @@ -1,13 +1,47 @@ +/* Options: + -d delay + waits delay nanoseconds before exiting. + -p fifo + sends output through fifo instead of stdout. opens, writes, and + closes fifo for each message sent. for signals that require + delay (CONT and TERM), the fifo is only opened once. also does + not exit after every signal unless a CONT/TERM pair. + -w fifo + opens fifo for write after signal handler set but before + entering main loop and sends "ok\n". + -x code + exits with supplied code. +*/ #include +#include +#include +#include #include -#include "ndelay.h" -#include "strerr.h" -#include "error.h" #include "byte.h" +#include "error.h" +#include "iopause.h" +#include "ndelay.h" +#include "scan.h" #include "sig.h" #include "str.h" +#include "stralloc.h" +#include "strerr.h" +#include "subgetopt.h" + +#define WARNING "sleeper: warning: " +#define FATAL "sleeper: fatal: " +#define USAGE "sleeper: usage: sleeper " static int selfpipe[2]; +static stralloc opt_p = {0,0,0}; +static stralloc opt_w = {0,0,0}; +static int opt_d = -1; +static int opt_x = 0; + +static void die_usage(void) +{ + strerr_die2x(100,USAGE,"[-d delay] [-p pfifo] [-w wfifo] [-x code]"); +} static void catch_sig(int sig) { @@ -19,7 +53,7 @@ static void catch_sig(int sig) (void)ignored; } -static void show_sig(int sig) +static void show_sig(int sig, int fd) { char buf[7+14+2] = "Caught "; const char *name; @@ -42,11 +76,34 @@ static void show_sig(int sig) byte_copy(buf+7,i,name); i += 7; buf[i++] = '\n'; - ignored = write(1,buf,i); + ignored = write(fd,buf,i); (void)ignored; } -static void show_err() +static int openp(void) +{ + struct stat st; + int fd; + if (opt_p.len) { + if (stat(opt_p.s,&st) == -1) + strerr_die4sys(111,FATAL,"unable to stat ",opt_p.s,""); + if ((st.st_mode & S_IFMT) != S_IFIFO) + strerr_die3x(111,FATAL,"not a fifo: ",opt_p.s); + while ((fd = open(opt_p.s,O_WRONLY|O_APPEND)) == -1) { + if (errno == error_intr) continue; + strerr_die4sys(111,FATAL,"open: ",opt_p.s,""); + } + } + else fd = 1; + return fd; +} + +static void closep(int fd) +{ + if (opt_p.len) close(fd); +} + +static void show_err(void) { int ignored; @@ -57,23 +114,41 @@ static void show_err() static void show_one(int sig) { - show_sig(sig); + int fd; + fd = openp(); + show_sig(sig,fd); + closep(fd); return; } static void show_two(int sig1, int sig2) { - show_sig(sig1); - show_sig(sig2); + int fd; + fd = openp(); + show_sig(sig1,fd); + show_sig(sig2,fd); + closep(fd); return; } -int main(void) +int main(int argc, const char *const *argv) { + struct stat st; + struct taia deadline; + struct taia stamp; + iopause_fd pausefd; + unsigned long tmp; int r; - int nc, nt, oc, ot; - int new_sig, old_sig=0; + int opt; + int nc = 0; + int nt = 0; + int oc = 0; + int ot = 0; + int new_sig = 0; + int old_sig = 0; + int ignored; char buf; + char p[2]; if (pipe(selfpipe) == -1) strerr_die1sys(111,"sleeper: fatal: unable to create pipe"); @@ -89,37 +164,116 @@ int main(void) sig_catch(SIGUSR2,catch_sig); sig_catch(SIGWINCH,catch_sig); - for (;;) { - r = read(selfpipe[0],&buf,1); - if (!r) break; - if (r == -1) { + while ((opt = sgopt(argc,argv,"d:p:w:x:")) != sgoptdone) + switch (opt) { + case 'd': + if (scan_ulong(sgoptarg,&tmp)) { + if (tmp >= 0) { + opt_d = (int)tmp; + continue; + } + } + strerr_warn2(WARNING,"-d invalid argument",0); + die_usage(); + case 'p': + stralloc_copys(&opt_p,sgoptarg); + stralloc_0(&opt_p); + continue; + case 'w': + stralloc_copys(&opt_w,sgoptarg); + stralloc_0(&opt_w); + continue; + case 'x': + if (scan_ulong(sgoptarg,&tmp)) { + if (tmp >= 0) { + opt_x = (int)tmp; + continue; + } + } + strerr_warn2(WARNING,"-x invalid argument",0); + die_usage(); + default: + p[0] = (char)sgoptproblem; + p[1] = '\0'; + if (argv[sgoptind] && (sgoptind < argc)) + strerr_warn3(WARNING,"illegal option -",p,0); + else + strerr_warn4(WARNING,"-",p," missing argument",0); + die_usage(); + } + argv += sgoptind; + + if (opt_p.len) { + if (stat(opt_p.s,&st) == -1) + strerr_die4sys(111,FATAL,"unable to stat ",opt_p.s,""); + if ((st.st_mode & S_IFMT) != S_IFIFO) + strerr_die3x(111,FATAL,"not a fifo: ",opt_p.s); + } + + if (opt_w.len) { + int fifofd; + if (stat(opt_w.s,&st) == -1) + strerr_die4sys(111,FATAL,"unable to stat ",opt_w.s,""); + if ((st.st_mode & S_IFMT) != S_IFIFO) + strerr_die3x(111,FATAL,"not a fifo: ",opt_w.s); + while ((fifofd = open(opt_w.s,O_WRONLY)) == -1) { if (errno == error_intr) continue; - break; + strerr_die4sys(111,FATAL,"open: ",opt_w.s,""); + } + ignored = write(fifofd,"ok\n",3); + close(fifofd); + } + + do { + for (;;) { + r = read(selfpipe[0],&buf,1); + if (!r) break; + if (r == -1) { + if (errno == error_intr) continue; + break; + } + + new_sig = (int)buf; + + nc = new_sig == SIGCONT; + nt = new_sig == SIGTERM; + oc = old_sig == SIGCONT; + ot = old_sig == SIGTERM; + + if (!nc && !nt && !oc && !ot) {show_one(new_sig); break; } + if (!nc && !nt && !oc && ot) {show_two(SIGTERM, new_sig); break; } + if (!nc && !nt && oc && !ot) {show_two(SIGCONT, new_sig); break; } + if (!nc && !nt && oc && ot) {show_err(); break; } + if (!nc && nt && !oc && !ot) {old_sig = SIGTERM; continue;} + if (!nc && nt && !oc && ot) {show_one(SIGTERM); continue;} + if (!nc && nt && oc && !ot) {show_two(SIGCONT, SIGTERM); break; } + if (!nc && nt && oc && ot) {show_err(); break; } + if ( nc && !nt && !oc && !ot) {old_sig = SIGCONT; continue;} + if ( nc && !nt && !oc && ot) {show_two(SIGCONT, SIGTERM); break; } + if ( nc && !nt && oc && !ot) {show_one(SIGCONT); continue;} + if ( nc && !nt && oc && ot) {show_err(); break; } + if ( nc && nt && !oc && !ot) {show_err(); break; } + if ( nc && nt && !oc && ot) {show_err(); break; } + if ( nc && nt && oc && !ot) {show_err(); break; } + if ( nc && nt && oc && ot) {show_err(); break; } } + old_sig = 0; + if ((oc && nt) || (ot && nc)) break; + } while (opt_p.len); - new_sig = (int)buf; - - nc = new_sig == SIGCONT; - nt = new_sig == SIGTERM; - oc = old_sig == SIGCONT; - ot = old_sig == SIGTERM; - - if (!nc && !nt && !oc && !ot) {show_one(new_sig); break; } - if (!nc && !nt && !oc && ot) {show_two(SIGTERM, new_sig); break; } - if (!nc && !nt && oc && !ot) {show_two(SIGCONT, new_sig); break; } - if (!nc && !nt && oc && ot) {show_err(); break; } - if (!nc && nt && !oc && !ot) {old_sig = SIGTERM; continue;} - if (!nc && nt && !oc && ot) {show_one(SIGTERM); continue;} - if (!nc && nt && oc && !ot) {show_two(SIGCONT, SIGTERM); break; } - if (!nc && nt && oc && ot) {show_err(); break; } - if ( nc && !nt && !oc && !ot) {old_sig = SIGCONT; continue;} - if ( nc && !nt && !oc && ot) {show_two(SIGCONT, SIGTERM); break; } - if ( nc && !nt && oc && !ot) {show_one(SIGCONT); continue;} - if ( nc && !nt && oc && ot) {show_err(); break; } - if ( nc && nt && !oc && !ot) {show_err(); break; } - if ( nc && nt && !oc && ot) {show_err(); break; } - if ( nc && nt && oc && !ot) {show_err(); break; } - if ( nc && nt && oc && ot) {show_err(); break; } + if (opt_d >= 0) { + deadline.sec.x = 0; + deadline.nano = opt_d; + deadline.atto = 0; + taia_now(&stamp); + taia_add(&deadline,&deadline,&stamp); + for (;;) { + taia_now(&stamp); + if (taia_less(&deadline,&stamp)) break; + iopause(&pausefd,0,&deadline,&stamp); + } } - _exit(0); + + _exit(opt_x); + (void)ignored; } diff --git a/sleeper=x b/sleeper=x index 4455370..5be7a03 100644 --- a/sleeper=x +++ b/sleeper=x @@ -1,2 +1,3 @@ +time.a byte.a unix.a From 867c7015328055bd478d818410165389167e8c94 Mon Sep 17 00:00:00 2001 From: Rick Myers Date: Sun, 7 Oct 2018 07:54:39 -0400 Subject: [PATCH 7/9] supervise: restart with svc -du when exit 100 --- rts.tests/nonexistent.sh | 1 + rts.tests/svc-du.exp | 15 ++++++++ rts.tests/svc-du.sh | 75 ++++++++++++++++++++++++++++++++++++++++ supervise.c | 14 ++++++-- 4 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 rts.tests/svc-du.exp create mode 100644 rts.tests/svc-du.sh diff --git a/rts.tests/nonexistent.sh b/rts.tests/nonexistent.sh index 92df66f..e6199d9 100644 --- a/rts.tests/nonexistent.sh +++ b/rts.tests/nonexistent.sh @@ -1,4 +1,5 @@ echo '--- svstat handles new and nonexistent directories' +rm -rf test.sv/supervise ( echo '#!/bin/sh'; echo echo hi ) > test.sv/run chmod 755 test.sv/run touch test.sv/down diff --git a/rts.tests/svc-du.exp b/rts.tests/svc-du.exp new file mode 100644 index 0000000..40a4eff --- /dev/null +++ b/rts.tests/svc-du.exp @@ -0,0 +1,15 @@ +--- svc -du works, service exits 0 +Caught CONT +Caught TERM +ok + +--- svc -du works, service exits 1 +Caught CONT +Caught TERM +ok + +--- svc -du works, service exits 100 +Caught CONT +Caught TERM +ok + diff --git a/rts.tests/svc-du.sh b/rts.tests/svc-du.sh new file mode 100644 index 0000000..93798d1 --- /dev/null +++ b/rts.tests/svc-du.sh @@ -0,0 +1,75 @@ +svpid() { + svstat test.sv | perl -ple 's/.+pid ([0-9]+).+/$1/ || s/.+/0/' +} + +echo '--- svc -du works, service exits 0' +catexe test.sv/run <pid; svc->pid = 0; - if (((svc == &svcmain && svc->flagstatus == svstatus_starting) && (wait_crashed(wstat) || wait_exitcode(wstat) != 0)) - || (!wait_crashed(wstat) && wait_exitcode(wstat) == 100)) { + if ((svc == &svcmain && svc->flagstatus == svstatus_starting) && (wait_crashed(wstat) || wait_exitcode(wstat) != 0)) { svc->flagwantup = 0; svc->flagstatus = svstatus_failed; } + else if (!wait_crashed(wstat) && wait_exitcode(wstat) == 100) { + if (svc->flagwantup) { + svc->flagstatus = svstatus_starting; + } + else { + svc->flagstatus = svstatus_failed; + } + } else if (svc == &svcmain && svc->flagstatus == svstatus_starting) { } - else if (!svc->flagwant || !svc->flagwantup) + else if (!svc->flagwant || !svc->flagwantup) { svc->flagstatus = svstatus_stopped; + } pidchange(svc, wait_crashed(wstat) ? "killed" : "exit", wait_crashed(wstat) ? wait_stopsig(wstat) : wait_exitcode(wstat), killpid); From 8900f1419e7d15d75e8fc1997575abdd97f00afc Mon Sep 17 00:00:00 2001 From: Rick Myers Date: Sun, 7 Oct 2018 07:45:24 -0400 Subject: [PATCH 8/9] supervise: use iopause instead of deepsleep for throttling --- supervise.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/supervise.c b/supervise.c index ba080ba..be57eef 100644 --- a/supervise.c +++ b/supervise.c @@ -33,6 +33,8 @@ struct svc int flagpaused; struct taia when; int ranstop; + struct taia after; + struct taia stopafter; }; const char *dir; @@ -50,6 +52,7 @@ const char *runscript = 0; int logpipe[2] = {-1,-1}; struct svc svcmain = {0,svstatus_stopped,1,1}; struct svc svclog = {0,svstatus_stopped,1,0}; +struct taia half; static int stat_isexec(const char *path) { @@ -209,6 +212,7 @@ void trystart(struct svc *svc) const char *argv[] = { 0,0 }; int f; int fd; + struct taia now; if (svc == &svclog) { argv[0] = "./log"; @@ -228,16 +232,22 @@ void trystart(struct svc *svc) svcmain.flagstatus = firstrun ? svstatus_starting : svstatus_running; fd = 1; } + taia_now(&now); + iopause(0,0,&svc->after,&now); if ((f = forkexecve(svc,argv,fd)) < 0) return; pidchange(svc,"start",0,f); - deepsleep(1); + taia_now(&now); + taia_add(&svc->after,&half,&now); + if (svc == &svclog) + svcmain.after = svclog.after; } void trystop(struct svc *svc) { const char *argv[] = { "./stop",0 }; int f; + struct taia now; if (svc->ranstop || svc != &svcmain @@ -247,21 +257,34 @@ void trystop(struct svc *svc) announce(); return; } + taia_now(&now); + iopause(0,0,&svc->stopafter,&now); runscript = argv[0]; if ((f = forkexecve(svc,argv,1)) < 0) return; svc->ranstop = 1; pidchange(svc,"start",0,f); - deepsleep(1); + taia_now(&now); + taia_add(&svc->stopafter,&half,&now); + if (svc == &svclog) + svcmain.stopafter = svclog.stopafter; } static void stopsvc(int killpid,struct svc *svc) { + struct taia now; + + taia_now(&now); + iopause(0,0,&svc->stopafter,&now); kill(killpid,SIGTERM); kill(killpid,SIGCONT); svc->flagpaused = 0; svc->flagstatus = svstatus_stopping; svc->ranstop = 0; + taia_now(&now); + taia_add(&svc->stopafter,&half,&now); + if (svc == &svclog) + svcmain.stopafter = svclog.stopafter; } void doit(void) @@ -315,6 +338,7 @@ void doit(void) else if (!wait_crashed(wstat) && wait_exitcode(wstat) == 100) { if (svc->flagwantup) { svc->flagstatus = svstatus_starting; + taia_now(&svc->after); } else { svc->flagstatus = svstatus_failed; @@ -340,7 +364,7 @@ void doit(void) svc = &svcmain; killpid = svc->pid; - while (read(fdcontrol,&ch,1) == 1) + while (read(fdcontrol,&ch,1) == 1) { switch(ch) { case '+': if (killpid > 0) killpid = -killpid; @@ -422,6 +446,7 @@ void doit(void) announce(); break; } + } if (flagexit && svcmain.flagstatus == svstatus_stopped @@ -509,6 +534,15 @@ int main(int argc,char **argv) strerr_die3sys(111,FATAL,"unable to read ",fntemp); closeonexec(fdok); + taia_now(&svclog.after); + svcmain.after = svclog.after; + svclog.stopafter = svclog.after; + svcmain.stopafter = svclog.stopafter; + + half.sec.x = 0; + half.nano = 500000000; + half.atto = 0; + if (!svclog.flagwant || svclog.flagwantup) trystart(&svclog); if (!svcmain.flagwant || svcmain.flagwantup) trystart(&svcmain); From 9131d96e812c56887c242b14dbb3c1618f7a523c Mon Sep 17 00:00:00 2001 From: Rick Myers Date: Mon, 8 Oct 2018 00:40:52 -0400 Subject: [PATCH 9/9] rts: various speedups --- rts.tests/supervise-base.sh | 21 +++++--- rts.tests/supervise-downtime.sh | 2 +- rts.tests/supervise-lock.sh | 2 +- rts.tests/supervise-start.sh | 21 ++------ rts.tests/supervise-stop.sh | 4 +- rts.tests/svc-du.exp | 6 +++ rts.tests/svc-du.sh | 42 +++++++++++---- rts.tests/svc.exp | 1 + rts.tests/svc.sh | 1 + rts.tests/svscan-sigterm.exp | 23 ++------ rts.tests/svscan-sigterm.sh | 96 ++++++++++++--------------------- rts.tests/svscan.exp | 5 ++ rts.tests/svscan.sh | 26 ++++++--- 13 files changed, 122 insertions(+), 128 deletions(-) diff --git a/rts.tests/supervise-base.sh b/rts.tests/supervise-base.sh index d7b55a1..c720aae 100644 --- a/rts.tests/supervise-base.sh +++ b/rts.tests/supervise-base.sh @@ -5,10 +5,17 @@ # svscanboot echo '--- supervise starts, svok works, svup works, svstat works, svc -x works' +rm -rf test.sv +mkdir test.sv +catexe test.sv/run < test.sv/run chmod 755 test.sv/run -( echo '#!/bin/sh'; echo echo second; echo svc -x . ) > test.sv/run2 +( echo '#!/bin/sh'; echo echo second; echo svc -x .; echo exit 100 ) > test.sv/run2 chmod 755 test.sv/run2 supervise test.sv & until svok test.sv do - sleep 1 + sleep 0 done svc -u test.sv wait diff --git a/rts.tests/supervise-downtime.sh b/rts.tests/supervise-downtime.sh index 8ca1695..2a04498 100644 --- a/rts.tests/supervise-downtime.sh +++ b/rts.tests/supervise-downtime.sh @@ -19,7 +19,7 @@ svpid=$! until svok test.sv do - sleep 1 + sleep 0 done svstat test.sv \ diff --git a/rts.tests/supervise-lock.sh b/rts.tests/supervise-lock.sh index c3d8bfc..f031d11 100644 --- a/rts.tests/supervise-lock.sh +++ b/rts.tests/supervise-lock.sh @@ -2,7 +2,7 @@ echo '--- supervise leaves locked service intact' supervise test.sv & until svok test.sv do - sleep 1 + sleep 0 done ( cd test.sv/supervise && ls -dl * | awk '{ print $1, $5, $9 }' ) supervise test.sv; echo $? diff --git a/rts.tests/supervise-start.sh b/rts.tests/supervise-start.sh index 9398c2b..b15ebf3 100644 --- a/rts.tests/supervise-start.sh +++ b/rts.tests/supervise-start.sh @@ -1,7 +1,7 @@ echo '--- svc -o works first time with start' catexe test.sv/run < out +echo ok svc -dx . EOF catexe test.sv/start <test.sv/run -( echo '#!/bin/sh'; echo echo in stop ) >test.sv/stop +( echo '#!/bin/sh'; echo echo in stop; echo exit 100 ) >test.sv/stop rm -f test.sv/down chmod +x test.sv/run test.sv/stop supervise test.sv & @@ -11,7 +11,7 @@ echo echo '--- supervise stops log after main' ( echo '#!/bin/sh'; echo 'exec ../../sleeper' ) >test.sv/log chmod +x test.sv/log -supervise test.sv +supervise test.sv & wait rm -f test.sv/log echo diff --git a/rts.tests/svc-du.exp b/rts.tests/svc-du.exp index 40a4eff..21e5620 100644 --- a/rts.tests/svc-du.exp +++ b/rts.tests/svc-du.exp @@ -1,15 +1,21 @@ --- svc -du works, service exits 0 +ok Caught CONT Caught TERM ok +ok --- svc -du works, service exits 1 +ok Caught CONT Caught TERM ok +ok --- svc -du works, service exits 100 +ok Caught CONT Caught TERM ok +ok diff --git a/rts.tests/svc-du.sh b/rts.tests/svc-du.sh index 93798d1..9af61a0 100644 --- a/rts.tests/svc-du.sh +++ b/rts.tests/svc-du.sh @@ -1,17 +1,24 @@ svpid() { - svstat test.sv | perl -ple 's/.+pid ([0-9]+).+/$1/ || s/.+/0/' + svstat test.sv \ + | sed -E -n 's/.+pid ([0-9][0-9]*).+/Z\1/; s/^[^Z].+/Z0/; s/Z//p' } echo '--- svc -du works, service exits 0' +makefifo sv.wait1 sv.wait2 catexe test.sv/run < svscan.pid +wait EOF ## this doesnt work. get the pid in svscanboot instead. @@ -45,7 +43,6 @@ EOF #echo $! > test.boot/readproctitle.pid #EOF -test -x ../../svscanboot || die "Could not find svscanboot source" sed -r \ -e 's,PATH=/,PATH=.:..:../..:../../..:/,' \ -e 's,^exec 2?>.+,,' \ @@ -59,60 +56,45 @@ echo $! > readproctitle.pid' \ wait' \ < ../../svscanboot \ | catexe svscanboot -test -x svscanboot || die "Could not create svscanboot stub" makefifo svc0.ready -catexe svc0/run <<'EOF' || die "Could not create svc0/run script" +catexe svc0/run <<'EOF' #!/bin/sh echo svc0 ran >> ../svc0.log exec ../../../sleeper -w ../svc0.ready >> ../svc0.log EOF makefifo svc1-main.ready -catexe svc1/run <<'EOF' || die "Could not create svc1/run script" +catexe svc1/run <<'EOF' #!/bin/sh echo svc1-main ran >> ../svc1-main.log exec ../../../sleeper -w ../svc1-main.ready >> ../svc1-main.log EOF makefifo svc1-log.ready -catexe svc1/log/run <<'EOF' || die "Could not create svc1/log/run script" +catexe svc1/log/run <<'EOF' #!/bin/sh echo svc1-log ran >> ../../svc1-log.log exec ../../../../sleeper -w ../../svc1-log.ready >> ../../svc1-log.log EOF makefifo svc2-main.ready -catexe svc2/run <<'EOF' || die "Could not create svc2/run script" +catexe svc2/run <<'EOF' #!/bin/sh echo svc2-main ran >> ../svc2-main.log exec ../../../sleeper -w ../svc2-main.ready >> ../svc2-main.log EOF makefifo svc2-log.ready -catexe svc2/log <<'EOF' || die "Could not create svc2/log script" +catexe svc2/log <<'EOF' #!/bin/sh echo svc2-log ran >> ../svc2-log.log exec ../../../sleeper -w ../svc2-log.ready >> ../svc2-log.log EOF -timed_read() { - for i in 10 9 8 7 6 5 4 3 2 1 0; do - if [ -f $1 ]; then - head -n 1 $1 - break - fi - if [ $i -eq 0 ]; then - echo 0 - break - fi - sleep 1 - done -} - echo '--- svscanboot started' -./svscanboot service > svscanboot.log 2>&1 & +./svscanboot > svscanboot.log 2>&1 & svscanbootpid=$! if [ "$svscanbootpid" != "0" ]; then echo ok @@ -120,14 +102,14 @@ fi echo echo '--- svscan started' -svscanpid=`timed_read svscan.pid` +svscanpid=`head -n 1 svscan.pid` if [ "$svscanpid" != "0" ]; then echo ok fi echo echo '--- readproctitle started' -readproctitlepid=`timed_read readproctitle.pid` +readproctitlepid=`head -n 1 readproctitle.pid` if [ "$readproctitlepid" != "0" ]; then echo ok fi @@ -139,6 +121,7 @@ check_pid_sanity() { || [ $1 -le 1 ] \ || [ $1 -ge 99999 ] then + echo pid = $1 >&2 echo 0 else echo $1 @@ -149,6 +132,8 @@ echo '--- svscanboot pid looks sane' svscanbootpid=`check_pid_sanity $svscanbootpid` if [ "$svscanbootpid" != "0" ]; then echo ok +else + echo pid = $svscanbootpid fi echo @@ -156,6 +141,8 @@ echo '--- svscan pid looks sane' svscanpid=`check_pid_sanity $svscanpid` if [ "$svscanpid" != "0" ]; then echo ok +else + echo pid = $svscanpid fi echo @@ -163,6 +150,8 @@ echo '--- readproctitle pid looks sane' readproctitlepid=`check_pid_sanity $readproctitlepid` if [ "$readproctitlepid" != "0" ]; then echo ok +else + echo pid = $readprocpid fi echo @@ -191,40 +180,24 @@ else fi echo -echo '--- supervise svc0 is running' -svok svc0 && echo ok -echo - -echo '--- supervise svc1 is running' -svok svc1 && echo ok -echo - -echo '--- supervise svc1/log is running' -svok svc1/log && echo ok -echo - -echo '--- supervise svc2 is running' -svok svc2 && echo ok -echo - -echo '--- svc0.log readable' +echo '--- svc0.log ready' cat svc0.ready echo -echo '--- svc1-main.log readable' +echo '--- svc1-main.log ready' cat svc1-main.ready echo -echo '--- svc1-log.log readable' +echo '--- svc1-log.log ready' cat svc1-log.ready echo -echo '--- svc2-main.log readable' +echo '--- svc2-main.log ready' cat svc2-main.ready echo -echo '--- svc2-log.log readable' +echo '--- svc2-log.log ready' cat svc2-log.ready echo @@ -244,7 +217,7 @@ timed_stop() { kill -HUP $1 break fi - sleep 1 + sleep $2 else echo ok break @@ -254,15 +227,15 @@ timed_stop() { } echo '--- svscan is stopped' -timed_stop $svscanpid +timed_stop $svscanpid 1 echo echo '--- readproctitle is stopped' -timed_stop $readproctitlepid +timed_stop $readproctitlepid 0 echo echo '--- svscanboot is stopped' -timed_stop $svscanbootpid +timed_stop $svscanbootpid 0 echo @@ -320,7 +293,6 @@ echo echo '--- svc2 log log' cat svc2-log.log -echo # just in case diff --git a/rts.tests/svscan.exp b/rts.tests/svscan.exp index 7a0b6c3..8a16481 100644 --- a/rts.tests/svscan.exp +++ b/rts.tests/svscan.exp @@ -1,5 +1,10 @@ --- svscan setup --- svscan start +go1log +go2log +go0 +go1 +go2 --- svscan out ==> svc0/output <== svc0 ran diff --git a/rts.tests/svscan.sh b/rts.tests/svscan.sh index 95eae95..5b39176 100644 --- a/rts.tests/svscan.sh +++ b/rts.tests/svscan.sh @@ -1,29 +1,37 @@ echo '--- svscan setup' -# set up services mkdir service svc0 svc1 svc2 svc2/log +makefifo svc0.wait svc1.wait svc1log.wait svc2.wait svc2log.wait catexe svc0/run <> output +echo go0 > ../svc0.wait +exit 100 EOF catexe svc1/run < ../svc1.wait +exit 100 EOF catexe svc1/log < output +echo go1log > ../svc1log.wait +exec cat >> output EOF catexe svc2/run < ../svc2.wait +exit 100 EOF catexe svc2/log/run < ../../svc2log.wait exec cat > ../output EOF @@ -33,21 +41,23 @@ echo '--- svscan start' svscan `pwd`/service >svscan.log 2>&1 & svscanpid=$! -until svok svc0 && svok svc1 && svok svc2 && svok svc2/log -do - sleep 1 -done +cat svc1log.wait +cat svc2log.wait +cat svc0.wait +cat svc1.wait +cat svc2.wait -# stop svscan and clean up kill $svscanpid wait >/dev/null 2>&1 while svok svc0 || svok svc1 || svok svc2 || svok svc2/log do - sleep 1 + sleep 0 done + echo '--- svscan out' head -n 1 svc[0-9]/output cat svscan.log rm -r svc0 svc1 svc2 service +rm -f svc0.wait svc1.wait svc1log.wait svc2.wait svc2log.wait