FreeBSD/Linux Kernel Cross Reference
sys/servers/ds/main.c
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. */
14 int who; /* caller's proc number */
15 int callnr; /* system call number */
16 int sys_panic; /* flag to indicate system-wide panic */
17
18 extern int errno; /* error number set by system library */
19
20 /* Declare some local functions. */
21 FORWARD _PROTOTYPE(void init_server, (int argc, char **argv) );
22 FORWARD _PROTOTYPE(void exit_server, (void) );
23 FORWARD _PROTOTYPE(void get_work, (message *m_ptr) );
24 FORWARD _PROTOTYPE(void reply, (int whom, message *m_ptr) );
25
26 /*===========================================================================*
27 * main *
28 *===========================================================================*/
29 PUBLIC int main(int argc, char **argv)
30 {
31 /* This is the main routine of this service. The main loop consists of
32 * three major activities: getting new work, processing the work, and
33 * sending the reply. The loop never terminates, unless a panic occurs.
34 */
35 message m;
36 int result;
37 sigset_t sigset;
38
39 /* Initialize the server, then go to work. */
40 init_server(argc, argv);
41
42 /* Main loop - get work and do it, forever. */
43 while (TRUE) {
44
45 /* Wait for incoming message, sets 'callnr' and 'who'. */
46 get_work(&m);
47
48 switch (callnr) {
49 case SYS_SIG:
50 sigset = (sigset_t) m.NOTIFY_ARG;
51 if (sigismember(&sigset,SIGTERM) || sigismember(&sigset,SIGKSTOP)) {
52 exit_server();
53 }
54 continue;
55 case DS_PUBLISH:
56 result = do_publish(&m);
57 break;
58 case DS_RETRIEVE:
59 result = do_retrieve(&m);
60 break;
61 case DS_SUBSCRIBE:
62 result = do_subscribe(&m);
63 break;
64 case GETSYSINFO:
65 result = do_getsysinfo(&m);
66 break;
67 default:
68 report("DS","warning, got illegal request from:", m.m_source);
69 result = EINVAL;
70 }
71
72 /* Finally send reply message, unless disabled. */
73 if (result != EDONTREPLY) {
74 m.m_type = result; /* build reply message */
75 reply(who, &m); /* send it away */
76 }
77 }
78 return(OK); /* shouldn't come here */
79 }
80
81 /*===========================================================================*
82 * init_server *
83 *===========================================================================*/
84 PRIVATE void init_server(int argc, char **argv)
85 {
86 /* Initialize the data store server. */
87 int i, s;
88 struct sigaction sigact;
89
90 /* Install signal handler. Ask PM to transform signal into message. */
91 sigact.sa_handler = SIG_MESS;
92 sigact.sa_mask = ~0; /* block all other signals */
93 sigact.sa_flags = 0; /* default behaviour */
94 if (sigaction(SIGTERM, &sigact, NULL) < 0)
95 report("DS","warning, sigaction() failed", errno);
96 }
97
98 /*===========================================================================*
99 * exit_server *
100 *===========================================================================*/
101 PRIVATE void exit_server()
102 {
103 /* Shut down the information service. */
104
105 /* Done. Now exit. */
106 exit(0);
107 }
108
109 /*===========================================================================*
110 * get_work *
111 *===========================================================================*/
112 PRIVATE void get_work(m_ptr)
113 message *m_ptr; /* message buffer */
114 {
115 int status = 0;
116 status = receive(ANY, m_ptr); /* this blocks until message arrives */
117 if (OK != status)
118 panic("DS","failed to receive message!", status);
119 who = m_ptr->m_source; /* message arrived! set sender */
120 callnr = m_ptr->m_type; /* set function call number */
121 }
122
123 /*===========================================================================*
124 * reply *
125 *===========================================================================*/
126 PRIVATE void reply(who, m_ptr)
127 int who; /* destination */
128 message *m_ptr; /* message buffer */
129 {
130 int s;
131 s = send(who, m_ptr); /* send the message */
132 if (OK != s)
133 panic("DS", "unable to send reply!", s);
134 }
135
Cache object: 99ff10ee4b090a6c7606d811855af2e2
|