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