xref: /minix/minix/servers/ds/main.c (revision 0a6a1f1d)
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 #include <minix/endpoint.h>
13 
14 /* Allocate space for the global variables. */
15 static endpoint_t who_e;	/* caller's proc number */
16 static int callnr;		/* system call number */
17 
18 /* Declare some local functions. */
19 static void get_work(message *m_ptr);
20 static void reply(endpoint_t whom, message *m_ptr);
21 
22 /* SEF functions and variables. */
23 static void sef_local_startup(void);
24 
25 /*===========================================================================*
26  *				main                                         *
27  *===========================================================================*/
28 int main(int argc, char **argv)
29 {
30 /* This is the main routine of this service. The main loop consists of
31  * three major activities: getting new work, processing the work, and
32  * sending the reply. The loop never terminates, unless a panic occurs.
33  */
34   message m;
35   int result;
36 
37   /* SEF local startup. */
38   env_setargs(argc, argv);
39   sef_local_startup();
40 
41   /* Main loop - get work and do it, forever. */
42   while (TRUE) {
43 
44       /* Wait for incoming message, sets 'callnr' and 'who'. */
45       get_work(&m);
46 
47       if (is_notify(callnr)) {
48           printf("DS: warning, got illegal notify from: %d\n", m.m_source);
49           result = EINVAL;
50           goto send_reply;
51       }
52 
53       switch (callnr) {
54       case DS_PUBLISH:
55           result = do_publish(&m);
56           break;
57       case DS_RETRIEVE:
58 	  result = do_retrieve(&m);
59 	  break;
60       case DS_RETRIEVE_LABEL:
61 	  result = do_retrieve_label(&m);
62 	  break;
63       case DS_DELETE:
64 	  result = do_delete(&m);
65 	  break;
66       case DS_SUBSCRIBE:
67 	  result = do_subscribe(&m);
68 	  break;
69       case DS_CHECK:
70 	  result = do_check(&m);
71 	  break;
72       case DS_GETSYSINFO:
73 	  result = do_getsysinfo(&m);
74 	  break;
75       default:
76           printf("DS: warning, got illegal request from %d\n", m.m_source);
77           result = EINVAL;
78       }
79 
80 send_reply:
81       /* Finally send reply message, unless disabled. */
82       if (result != EDONTREPLY) {
83           m.m_type = result;  		/* build reply message */
84 	  reply(who_e, &m);		/* send it away */
85       }
86   }
87   return(OK);				/* shouldn't come here */
88 }
89 
90 /*===========================================================================*
91  *			       sef_local_startup			     *
92  *===========================================================================*/
93 static void sef_local_startup()
94 {
95   /* Register init callbacks. */
96   sef_setcb_init_fresh(sef_cb_init_fresh);
97   sef_setcb_init_restart(SEF_CB_INIT_RESTART_STATEFUL);
98 
99   /* Register state transfer callbacks. */
100   sef_llvm_ds_st_init();
101 
102   /* Let SEF perform startup. */
103   sef_startup();
104 }
105 
106 /*===========================================================================*
107  *				get_work                                     *
108  *===========================================================================*/
109 static void get_work(
110   message *m_ptr			/* message buffer */
111 )
112 {
113     int status = sef_receive(ANY, m_ptr);   /* blocks until message arrives */
114     if (OK != status)
115         panic("failed to receive message!: %d", status);
116     who_e = m_ptr->m_source;        /* message arrived! set sender */
117     callnr = m_ptr->m_type;       /* set function call number */
118 }
119 
120 /*===========================================================================*
121  *				reply					     *
122  *===========================================================================*/
123 static void reply(
124   endpoint_t who_e,			/* destination */
125   message *m_ptr			/* message buffer */
126 )
127 {
128     int s = ipc_send(who_e, m_ptr);    /* send the message */
129     if (OK != s)
130         printf("DS: unable to send reply to %d: %d\n", who_e, s);
131 }
132 
133