X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/blobdiff_plain/5dbd09a0a1da6890396c5cdc73290d05d853ab82..beebc37948c4baf100fd1fc11c2310d6094403be:/server/mr_main.c diff --git a/server/mr_main.c b/server/mr_main.c index 19cc64a5..9e61f243 100644 --- a/server/mr_main.c +++ b/server/mr_main.c @@ -4,7 +4,8 @@ * $Header$ * * Copyright (C) 1987 by the Massachusetts Institute of Technology - * + * For copying and distribution information, please see the file + * . * * SMS server process. * @@ -13,30 +14,15 @@ * You are in a maze of twisty little finite automata, all different. * Let the reader beware. * - * $Log$ - * Revision 1.5 1987-06-03 16:07:17 wesommer - * Fixes for lint. - * - * Revision 1.4 87/06/02 20:05:11 wesommer - * Bug fixes on memory allocation. - * - * Revision 1.3 87/06/01 04:34:27 wesommer - * Changed returned error code. - * - * Revision 1.2 87/06/01 03:34:53 wesommer - * Added shutdown, logging. - * - * Revision 1.1 87/05/31 22:06:56 wesommer - * Initial revision - * */ static char *rcsid_sms_main_c = "$Header$"; +#include #include #include #include -#include "sms_private.h" +#include #include "sms_server.h" extern CONNECTION newconn, listencon; @@ -55,9 +41,11 @@ extern char *whoami; extern char buf1[BUFSIZ]; extern char *takedown; extern int errno; - +extern FILE *journal; +#define JOURNAL "/u1/sms/journal" extern char *malloc(); +extern int free(); extern char *inet_ntoa(); extern void sms_com_err(); extern void do_client(); @@ -65,7 +53,9 @@ extern void do_client(); extern int sigshut(); void clist_append(); void oplist_append(); -extern u_short ntohs(); +void reapchild(); + +extern time_t now; /* * Main SMS server loop. @@ -81,6 +71,7 @@ main(argc, argv) char **argv; { int status; + time_t tardy; whoami = argv[0]; /* @@ -89,11 +80,18 @@ main(argc, argv) init_sms_err_tbl(); init_krb_err_tbl(); set_com_err_hook(sms_com_err); - + setlinebuf(stderr); + if (argc != 1) { com_err(whoami, 0, "Usage: smsd"); exit(1); } + + /* Profiling implies that getting rid of one level of call + * indirection here wins us maybe 1% on the VAX. + */ + gdb_amv = malloc; + gdb_fmv = free; /* * GDB initialization. @@ -102,6 +100,22 @@ main(argc, argv) com_err(whoami, 0, "GDB initialization failed."); exit(1); } + gdb_debug(0); /* this can be patched, if necessary, to enable */ + /* GDB level debugging .. */ + krb_realm = malloc(REALM_SZ); + get_krbrlm(krb_realm, 1); + + /* + * Database initialization. + */ + + if ((status = sms_open_database()) != 0) { + com_err(whoami, status, " when trying to open database."); + exit(1); + } + + sanity_check_queries(); + sanity_check_database(); /* * Set up client array handler. @@ -111,28 +125,36 @@ main(argc, argv) /* * Signal handlers + * There should probably be a few more of these. */ if ((((int)signal (SIGTERM, sigshut)) < 0) || + (((int)signal (SIGCHLD, reapchild)) < 0) || (((int)signal (SIGHUP, sigshut)) < 0)) { - com_err(whoami, errno, "Unable to establish signal handler."); + com_err(whoami, errno, " Unable to establish signal handler."); exit(1); } + journal = fopen(JOURNAL, "a"); + if (journal == NULL) { + com_err(whoami, errno, " while opening journal file"); + exit(1); + } + /* * Establish template connection. */ if ((status = do_listen()) != 0) { com_err(whoami, status, - "while trying to create listening connection"); + " while trying to create listening connection"); exit(1); } op_list = create_list_of_operations(1, listenop); - (void) sprintf(buf1, "started (pid %d)", getpid()); - com_err(whoami, 0, buf1); + com_err(whoami, 0, "started (pid %d)", getpid()); com_err(whoami, 0, rcsid_sms_main_c); + send_zgram("SMS", "server started"); /* * Run until shut down. @@ -151,41 +173,59 @@ main(argc, argv) (fd_set *)NULL, (struct timeval *)NULL); if (status == -1) { - com_err(whoami, errno, "error from op_select"); + com_err(whoami, errno, " error from op_select"); continue; } else if (status != -2) { - com_err(whoami, 0, "wrong return from op_select_any"); + com_err(whoami, 0, " wrong return from op_select_any"); continue; } if (takedown) break; + time(&now); #ifdef notdef fprintf(stderr, " tick\n"); #endif notdef /* - * Handle any existing connections. - */ - for (i=0; ipending_op)) { - cur_client = clients[i]; - do_client(cur_client); - cur_client = NULL; - if (takedown) break; - } - } - /* - * Handle any new connections. + * Handle any new connections; this comes first so + * errno isn't tromped on. */ if (OP_DONE(listenop)) { - if ((status = new_connection()) != 0) { + if (OP_STATUS(listenop) == OP_CANCELLED) { + if (errno == EWOULDBLOCK) { + do_reset_listen(); + } else { + com_err(whoami, errno, + " error on listen"); + exit(1); + } + } else if ((status = new_connection()) != 0) { com_err(whoami, errno, - "Error on listening operation."); + " Error on listening operation."); /* * Sleep here to prevent hosing? */ } } + /* + * Handle any existing connections. + */ + tardy = now - 30*60; + + for (i=0; ipending_op)) { + cur_client->last_time_used = now; + do_client(cur_client); + } else if (clients[i]->last_time_used < tardy) { + com_err(whoami, 0, "Shutting down connection due to inactivity"); + shutdown(cur_client->con->in.fd, 0); + } + cur_client = NULL; + if (takedown) break; + } } - com_err(whoami, 0, takedown); + com_err(whoami, 0, "%s", takedown); + sms_close_database(); + send_zgram("SMS", takedown); return 0; } @@ -212,6 +252,15 @@ do_listen() return 0; } + +do_reset_listen() +{ + client_addrlen = sizeof(client_addr); + start_accepting_client(listencon, listenop, &newconn, + (char *)&client_addr, + &client_addrlen, &client_tuple); +} + /* * This routine is called when a new connection comes in. * @@ -220,32 +269,34 @@ do_listen() int new_connection() { - register client *cp = (client *)malloc(sizeof *cp); + register client *cp; static counter = 0; /* * Make sure there's been no error */ - if(OP_STATUS(listenop) != OP_COMPLETE || - newconn == NULL) { + if(OP_STATUS(listenop) != OP_COMPLETE) { return errno; -#ifdef notdef - exit(8); /* XXX */ -#endif notdef + } + + if (newconn == NULL) { + return SMS_NOT_CONNECTED; } /* * Set up the new connection and reply to the client */ - - cp->state = CL_STARTING; + cp = (client *)malloc(sizeof *cp); + bzero(cp, sizeof(*cp)); cp->action = CL_ACCEPT; cp->con = newconn; cp->id = counter++; cp->args = NULL; cp->clname = NULL; cp->reply.sms_argv = NULL; - + cp->first = NULL; + cp->last = NULL; + cp->last_time_used = now; newconn = NULL; cp->pending_op = create_operation(); @@ -270,13 +321,11 @@ new_connection() * Log new connection. */ - (void) sprintf(buf1, - "New connection from %s port %d (now %d client%s)", - inet_ntoa(cp->haddr.sin_addr), - (int)ntohs(cp->haddr.sin_port), - nclients, - nclients!=1?"s":""); - com_err(whoami, 0, buf1); + com_err(whoami, 0, "New connection from %s port %d (now %d client%s)", + inet_ntoa(cp->haddr.sin_addr), + (int)ntohs(cp->haddr.sin_port), + nclients, + nclients!=1?"s":""); /* * Get ready to accept the next connection. @@ -334,9 +383,10 @@ clist_delete(cp) free((char *)clients); clients = clients_n; clients_n = NULL; - + oplist_delete(op_list, cp->pending_op); reset_operation(cp->pending_op); delete_operation(cp->pending_op); + sever_connection(cp->con); free((char *)cp); } @@ -359,7 +409,45 @@ oplist_append(oplp, op) size_of_list_of_operations((*oplp)->count)); newlist->count++; newlist->op[count-1] = op; - db_free((*oplp), size_of_list_of_operations(count-1)); + db_free((char *)(*oplp), size_of_list_of_operations(count-1)); (*oplp) = newlist; } + +oplist_delete(oplp, op) + LIST_OF_OPERATIONS oplp; + register OPERATION op; +{ + register OPERATION *s; + register int c; + + for (s = oplp->op, c=oplp->count; c; --c, ++s) { + if (*s == op) { + while (c > 0) { + *s = *(s+1); + ++s; + --c; + } + oplp->count--; + return; + } + } + abort(); +} + + +void reapchild() +{ + union wait status; + int pid; + + if (takedown) + return; + while ((pid = wait3(&status, WNOHANG, (struct rusage *)0)) > 0) { + if (status.w_termsig == 0 && status.w_retcode == 0) + com_err(whoami, 0, "dcm started successfully"); + else + com_err(whoami, 0, "%d: startdcm exits with signal %d status %d", + pid, status.w_termsig, status.w_retcode); + } +}