source: trunk/minix/servers/ds/main.c@ 11

Last change on this file since 11 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 4.9 KB
Line 
1/* Data Store Server.
2 * This service implements a little publish/subscribe data store that is
3 * crucial for the system's fault tolerance. Components that require state
4 * can store it here, for later retrieval, e.g., after a crash and subsequent
5 * restart by the reincarnation server.
6 *
7 * Created:
8 * Oct 19, 2005 by Jorrit N. Herder
9 */
10
11#include "inc.h" /* include master header file */
12
13/* Allocate space for the global variables. */
14int who_e; /* caller's proc number */
15int callnr; /* system call number */
16int sys_panic; /* flag to indicate system-wide panic */
17
18extern int errno; /* error number set by system library */
19
20/* Declare some local functions. */
21FORWARD _PROTOTYPE(void init_server, (int argc, char **argv) );
22FORWARD _PROTOTYPE(void exit_server, (void) );
23FORWARD _PROTOTYPE(void sig_handler, (void) );
24FORWARD _PROTOTYPE(void get_work, (message *m_ptr) );
25FORWARD _PROTOTYPE(void reply, (int whom, message *m_ptr) );
26
27/*===========================================================================*
28 * main *
29 *===========================================================================*/
30PUBLIC int main(int argc, char **argv)
31{
32/* This is the main routine of this service. The main loop consists of
33 * three major activities: getting new work, processing the work, and
34 * sending the reply. The loop never terminates, unless a panic occurs.
35 */
36 message m;
37 int result;
38 sigset_t sigset;
39
40 /* Initialize the server, then go to work. */
41 init_server(argc, argv);
42
43 /* Main loop - get work and do it, forever. */
44 while (TRUE) {
45
46 /* Wait for incoming message, sets 'callnr' and 'who'. */
47 get_work(&m);
48
49 switch (callnr) {
50 case PROC_EVENT:
51 sig_handler();
52 continue;
53 case DS_PUBLISH:
54 result = do_publish(&m);
55 break;
56 case DS_RETRIEVE:
57 result = do_retrieve(&m);
58 break;
59 case DS_SUBSCRIBE:
60 result = do_subscribe(&m);
61 break;
62 case GETSYSINFO:
63 result = do_getsysinfo(&m);
64 break;
65 default:
66 report("DS","warning, got illegal request from:", m.m_source);
67 result = EINVAL;
68 }
69
70 /* Finally send reply message, unless disabled. */
71 if (result != EDONTREPLY) {
72 m.m_type = result; /* build reply message */
73 reply(who_e, &m); /* send it away */
74 }
75 }
76 return(OK); /* shouldn't come here */
77}
78
79/*===========================================================================*
80 * init_server *
81 *===========================================================================*/
82PRIVATE void init_server(int argc, char **argv)
83{
84/* Initialize the data store server. */
85 int i, s;
86 struct sigaction sigact;
87
88 /* Install signal handler. Ask PM to transform signal into message. */
89 sigact.sa_handler = SIG_MESS;
90 sigact.sa_mask = ~0; /* block all other signals */
91 sigact.sa_flags = 0; /* default behaviour */
92 if (sigaction(SIGTERM, &sigact, NULL) < 0)
93 report("DS","warning, sigaction() failed", errno);
94}
95
96/*===========================================================================*
97 * sig_handler *
98 *===========================================================================*/
99PRIVATE void sig_handler()
100{
101/* Signal handler. */
102 sigset_t sigset;
103 int sig;
104
105 /* Try to obtain signal set from PM. */
106 if (getsigset(&sigset) != 0) return;
107
108 /* Check for known signals. */
109 if (sigismember(&sigset, SIGTERM)) {
110 exit_server();
111 }
112}
113
114/*===========================================================================*
115 * exit_server *
116 *===========================================================================*/
117PRIVATE void exit_server()
118{
119/* Shut down the information service. */
120
121 /* Done. Now exit. */
122 exit(0);
123}
124
125/*===========================================================================*
126 * get_work *
127 *===========================================================================*/
128PRIVATE void get_work(m_ptr)
129message *m_ptr; /* message buffer */
130{
131 int status = 0;
132 status = receive(ANY, m_ptr); /* this blocks until message arrives */
133 if (OK != status)
134 panic("DS","failed to receive message!", status);
135 who_e = m_ptr->m_source; /* message arrived! set sender */
136 callnr = m_ptr->m_type; /* set function call number */
137}
138
139/*===========================================================================*
140 * reply *
141 *===========================================================================*/
142PRIVATE void reply(who_e, m_ptr)
143int who_e; /* destination */
144message *m_ptr; /* message buffer */
145{
146 int s;
147 s = send(who_e, m_ptr); /* send the message */
148 if (OK != s)
149 panic("DS", "unable to send reply!", s);
150}
151
Note: See TracBrowser for help on using the repository browser.