X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=userv.git;a=blobdiff_plain;f=overlord.c;h=ae6fbfb972530cc8a599d1532014d73562f5da17;hp=dfb58a2f21ec497bc133f403450c07373b6a87dd;hb=26f06c01c4cb357d9e4fb6d0cd0386e70f7e6b6e;hpb=78032a78185e751a0bf0b77863f23d005359205f diff --git a/overlord.c b/overlord.c index dfb58a2..ae6fbfb 100644 --- a/overlord.c +++ b/overlord.c @@ -43,7 +43,7 @@ pid_t overlordpid; static pid_t checkpid= -1, detachpid= -1; -static sig_atomic_t needcheck= 1; +static sig_atomic_t needcheck= 1; /* 2 means we half-expect the server to be down */ static void checkstalepipes(void) { /* There is an unimportant race here. If there is a stale pipe but @@ -128,11 +128,14 @@ static void sighandler_chld(int x) { } else if (!WIFEXITED(status)) { syslog(LOG_ERR,"call pid %ld died due to unknown reason, code %d", (long)r,status); + } else if (WEXITSTATUS(status)==10) { + needcheck= 2; } else if (WEXITSTATUS(status)>12) { if (WEXITSTATUS(status)>24) syslog(LOG_ERR,"call pid %ld exited with status %d >24", (long)r,WEXITSTATUS(status)); checkstalepipes(); + needcheck= 1; } } } @@ -165,7 +168,7 @@ static void blocksignals(int how) { r= sigprocmask(how,&set,0); assert(!r); } -static void NONRETURNING docheck(void) { +static void NONRETURNING docheck(int needwanted) { #ifndef DEBUG /* This subprocess exits with status 0 if the parent should die, * 1 if it should not, and something else if it fails horribly. @@ -197,8 +200,11 @@ static void NONRETURNING docheck(void) { r= connect(sfd,(struct sockaddr*)&ssockname,sizeof(ssockname)); if (r) { - if (errno == ECONNREFUSED || errno == ENOENT) - { syslog(LOG_WARNING,"real uservd daemon is not running: %m"); exit(0); } + if (errno == ECONNREFUSED || errno == ENOENT) { + if (needwanted != 2) + syslog(LOG_WARNING,"real uservd daemon is not running: %m"); + exit(0); + } syslog(LOG_ERR,"unable to connect to uservd daemon: %m"); exit(1); } @@ -340,11 +346,10 @@ int main(int argc, char *const *argv) { for (;;) { if (needcheck) { - assert(checkpid==-1); - for (;;) { + while (checkpid==-1) { checkpid= fork(); if (checkpid!=-1) { - if (!checkpid) docheck(); + if (!checkpid) docheck(needcheck); break; } else if (errno==EAGAIN) { syslog(LOG_ERR,"fork for check - will wait and retry: %m");