main.c

Go to the documentation of this file.
00001 /* Data Store Server. 
00002  * This service implements a little publish/subscribe data store that is 
00003  * crucial for the system's fault tolerance. Components that require state
00004  * can store it here, for later retrieval, e.g., after a crash and subsequent
00005  * restart by the reincarnation server. 
00006  * 
00007  * Created:
00008  *   Oct 19, 2005       by Jorrit N. Herder
00009  */
00010 
00011 #include "inc.h"        /* include master header file */
00012 
00013 /* Allocate space for the global variables. */
00014 int who_e;              /* caller's proc number */
00015 int callnr;             /* system call number */
00016 int sys_panic;          /* flag to indicate system-wide panic */
00017 
00018 extern int errno;       /* error number set by system library */
00019 
00020 /* Declare some local functions. */
00021 FORWARD _PROTOTYPE(void init_server, (int argc, char **argv)            );
00022 FORWARD _PROTOTYPE(void exit_server, (void)                             );
00023 FORWARD _PROTOTYPE(void sig_handler, (void)                             );
00024 FORWARD _PROTOTYPE(void get_work, (message *m_ptr)                      );
00025 FORWARD _PROTOTYPE(void reply, (int whom, message *m_ptr)               );
00026 
00027 /*===========================================================================*
00028  *                              main                                         *
00029  *===========================================================================*/
00030 PUBLIC int main(int argc, char **argv)
00031 {
00032 /* This is the main routine of this service. The main loop consists of 
00033  * three major activities: getting new work, processing the work, and
00034  * sending the reply. The loop never terminates, unless a panic occurs.
00035  */
00036   message m;
00037   int result;                 
00038   sigset_t sigset;
00039 
00040   /* Initialize the server, then go to work. */
00041   init_server(argc, argv);
00042 
00043   /* Main loop - get work and do it, forever. */         
00044   while (TRUE) {              
00045 
00046       /* Wait for incoming message, sets 'callnr' and 'who'. */
00047       get_work(&m);
00048 
00049       switch (callnr) {
00050       case PROC_EVENT:
00051           sig_handler();
00052           continue;
00053       case DS_PUBLISH:
00054           result = do_publish(&m);
00055           break;
00056       case DS_RETRIEVE:
00057           result = do_retrieve(&m);
00058           break;
00059       case DS_SUBSCRIBE:
00060           result = do_subscribe(&m);
00061           break;
00062       case GETSYSINFO:
00063           result = do_getsysinfo(&m);
00064           break;
00065       default: 
00066           report("DS","warning, got illegal request from:", m.m_source);
00067           result = EINVAL;
00068       }
00069 
00070       /* Finally send reply message, unless disabled. */
00071       if (result != EDONTREPLY) {
00072           m.m_type = result;            /* build reply message */
00073           reply(who_e, &m);             /* send it away */
00074       }
00075   }
00076   return(OK);                           /* shouldn't come here */
00077 }
00078 
00079 /*===========================================================================*
00080  *                               init_server                                 *
00081  *===========================================================================*/
00082 PRIVATE void init_server(int argc, char **argv)
00083 {
00084 /* Initialize the data store server. */
00085   int i, s;
00086   struct sigaction sigact;
00087 
00088   /* Install signal handler. Ask PM to transform signal into message. */
00089   sigact.sa_handler = SIG_MESS;
00090   sigact.sa_mask = ~0;                  /* block all other signals */
00091   sigact.sa_flags = 0;                  /* default behaviour */
00092   if (sigaction(SIGTERM, &sigact, NULL) < 0) 
00093       report("DS","warning, sigaction() failed", errno);
00094 }
00095 
00096 /*===========================================================================*
00097  *                               sig_handler                                 *
00098  *===========================================================================*/
00099 PRIVATE void sig_handler()
00100 {
00101 /* Signal handler. */
00102   sigset_t sigset;
00103   int sig;
00104 
00105   /* Try to obtain signal set from PM. */
00106   if (getsigset(&sigset) != 0) return;
00107 
00108   /* Check for known signals. */
00109   if (sigismember(&sigset, SIGTERM)) {
00110       exit_server();
00111   }
00112 }
00113 
00114 /*===========================================================================*
00115  *                              exit_server                                  *
00116  *===========================================================================*/
00117 PRIVATE void exit_server()
00118 {
00119 /* Shut down the information service. */
00120 
00121   /* Done. Now exit. */
00122   exit(0);
00123 }
00124 
00125 /*===========================================================================*
00126  *                              get_work                                     *
00127  *===========================================================================*/
00128 PRIVATE void get_work(m_ptr)
00129 message *m_ptr;                         /* message buffer */
00130 {
00131     int status = 0;
00132     status = receive(ANY, m_ptr);   /* this blocks until message arrives */
00133     if (OK != status)
00134         panic("DS","failed to receive message!", status);
00135     who_e = m_ptr->m_source;        /* message arrived! set sender */
00136     callnr = m_ptr->m_type;       /* set function call number */
00137 }
00138 
00139 /*===========================================================================*
00140  *                              reply                                        *
00141  *===========================================================================*/
00142 PRIVATE void reply(who_e, m_ptr)
00143 int who_e;                              /* destination */
00144 message *m_ptr;                         /* message buffer */
00145 {
00146     int s;
00147     s = send(who_e, m_ptr);    /* send the message */
00148     if (OK != s)
00149         panic("DS", "unable to send reply!", s);
00150 }
00151 

Generated on Fri Apr 14 22:56:40 2006 for minix by  doxygen 1.4.6