X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/blobdiff_plain/e688520ab428651807bd8e604e694b8c91b776bc..991417e4b47af30da364d612fda7130433b56703:/server/mr_main.c diff --git a/server/mr_main.c b/server/mr_main.c index 13c85701..7337f455 100644 --- a/server/mr_main.c +++ b/server/mr_main.c @@ -29,11 +29,10 @@ #include #include +#include RCSID("$Header$"); -extern char *krb_get_lrealm(char *, int); - client *cur_client; char *whoami; @@ -44,12 +43,15 @@ time_t now; char *host; char krb_realm[REALM_SZ]; +krb5_context context = NULL; /* Client array and associated data. This needs to be global for _list_users */ client **clients; int nclients, clientssize; int dormant; +int child_exited_abnormally = 0; +int child_pid, child_signal, child_status; void reapchild(int x); void godormant(int x); @@ -106,6 +108,13 @@ int main(int argc, char **argv) krb_get_lrealm(krb_realm, 1); + status = krb5_init_context(&context); + if (status) + { + com_err(whoami, status, "Initializing krb5 context."); + exit(1); + } + /* * Database initialization. Only init if database should be open. */ @@ -162,9 +171,10 @@ int main(int argc, char **argv) /* * Establish template connection. */ - if (!(listener = mr_listen(port))) + listener = mr_listen(port); + if (listener == -1) { - com_err(whoami, status, "trying to create listening connection"); + com_err(whoami, MR_ABORTED, "trying to create listening connection"); exit(1); } FD_ZERO(&xreadfds); @@ -185,11 +195,12 @@ int main(int argc, char **argv) while (!takedown) { int i; - struct timeval timeout; + struct timeval timeout = {60, 0}; /* 1 minute */ /* If we're supposed to go down and we can, do it */ - if ((dormant == AWAKE) && (nclients == 0) && - (stat(MOIRA_MOTD_FILE, &stbuf) == 0)) + if (((dormant == AWAKE) && (nclients == 0) && + (stat(MOIRA_MOTD_FILE, &stbuf) == 0)) || + (dormant == SLEEPY)) { mr_close_database(); com_err(whoami, 0, "database closed"); @@ -201,8 +212,7 @@ int main(int argc, char **argv) /* Block until something happens. */ memcpy(&readfds, &xreadfds, sizeof(readfds)); memcpy(&writefds, &xwritefds, sizeof(writefds)); - /* XXX set timeout */ - if (select(nfds, &readfds, &writefds, NULL, NULL) == -1) + if (select(nfds, &readfds, &writefds, NULL, &timeout) == -1) { if (errno != EINTR) com_err(whoami, errno, "in select"); @@ -213,6 +223,14 @@ int main(int argc, char **argv) if (takedown) break; + + if (child_exited_abnormally) + { + critical_alert("moirad", "%d: child exits with signal %d status %d", + child_pid, child_signal, child_status); + child_exited_abnormally = 0; + } + time(&now); if (!inc_running || now - inc_started > INC_TIMEOUT) next_incremental(); @@ -232,11 +250,11 @@ int main(int argc, char **argv) /* Handle any new connections */ if (FD_ISSET(listener, &readfds)) { - int newconn; + int newconn, addrlen = sizeof(struct sockaddr_in); struct sockaddr_in addr; client *cp; - newconn = mr_accept(listener, &addr); + newconn = accept(listener, (struct sockaddr *)&addr, &addrlen); if (newconn == -1) com_err(whoami, errno, "accepting new connection"); else if (newconn > 0) @@ -262,6 +280,8 @@ int main(int argc, char **argv) cp->tuplessize = 1; cp->tuples = xmalloc(sizeof(mr_params)); memset(cp->tuples, 0, sizeof(mr_params)); + cp->state = CL_ACCEPTING; + cp->version = 2; cur_client = cp; com_err(whoami, 0, @@ -283,7 +303,6 @@ int main(int argc, char **argv) if (!clients[i]->ntuples) { FD_CLR(clients[i]->con, &xwritefds); - /* Now that we're done writing we can read again */ FD_SET(clients[i]->con, &xreadfds); } clients[i]->last_time_used = now; @@ -291,19 +310,44 @@ int main(int argc, char **argv) if (FD_ISSET(clients[i]->con, &readfds)) { - client_read(clients[i]); - if (clients[i]->ntuples) - FD_SET(clients[i]->con, &xwritefds); - clients[i]->last_time_used = now; + if (clients[i]->state == CL_ACCEPTING) + { + switch(mr_cont_accept(clients[i]->con, + &clients[i]->hsbuf, + &clients[i]->hslen)) + { + case -1: + break; + + case 0: + clients[i]->state = CL_CLOSING; + break; + + default: + clients[i]->state = CL_ACTIVE; + clients[i]->hsbuf = NULL; + break; + } + } + else + { + client_read(clients[i]); + if (clients[i]->ntuples) + { + FD_CLR(clients[i]->con, &xreadfds); + FD_SET(clients[i]->con, &xwritefds); + } + clients[i]->last_time_used = now; + } } if (clients[i]->last_time_used < tardy) { com_err(whoami, 0, "Shutting down connection due to inactivity"); - clients[i]->done = 1; + clients[i]->state = CL_CLOSING; } - if (clients[i]->done) + if (clients[i]->state == CL_CLOSING) { client *old; @@ -315,9 +359,9 @@ int main(int argc, char **argv) close(clients[i]->con); FD_CLR(clients[i]->con, &xreadfds); FD_CLR(clients[i]->con, &xwritefds); - for (; clients[i]->ntuples; clients[i]->ntuples--) - mr_destroy_reply(clients[i]->tuples[clients[i]->ntuples - 1]); + free_rtn_tuples(clients[i]); free(clients[i]->tuples); + free(clients[i]->hsbuf); old = clients[i]; clients[i] = clients[--nclients]; free(old); @@ -345,8 +389,12 @@ void reapchild(int x) if (pid == inc_pid) inc_running = 0; if (!takedown && (WTERMSIG(status) != 0 || WEXITSTATUS(status) != 0)) - com_err(whoami, 0, "%d: child exits with signal %d status %d", - pid, WTERMSIG(status), WEXITSTATUS(status)); + { + child_exited_abnormally = 1; + child_pid = pid; + child_signal = WTERMSIG(status); + child_status = WEXITSTATUS(status); + } } } @@ -419,6 +467,13 @@ void mr_setup_signals(void) exit(1); } + action.sa_handler = SIG_IGN; + if (sigaction(SIGPIPE, &action, NULL) < 0) + { + com_err(whoami, errno, "Unable to establish signal handlers."); + exit(1); + } + action.sa_handler = reapchild; sigaddset(&action.sa_mask, SIGCHLD); if (sigaction(SIGCHLD, &action, NULL) < 0)