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