/*===========================================================================* * sef_cb_signal_manager * *===========================================================================*/ static int sef_cb_signal_manager(endpoint_t target, int signo) { /* Process system signal on behalf of the kernel. */ int target_p; struct rproc *rp; message m; /* Lookup slot. */ if(rs_isokendpt(target, &target_p) != OK || rproc_ptr[target_p] == NULL) { if(rs_verbose) printf("RS: ignoring spurious signal %d for process %d\n", signo, target); return OK; /* clear the signal */ } rp = rproc_ptr[target_p]; /* Don't bother if a termination signal has already been processed. */ if((rp->r_flags & RS_TERMINATED) && !(rp->r_flags & RS_EXITING)) { return EDEADEPT; /* process is gone */ } /* Ignore external signals for inactive service instances. */ if( !(rp->r_flags & RS_ACTIVE) && !(rp->r_flags & RS_EXITING)) { if(rs_verbose) printf("RS: ignoring signal %d for inactive %s\n", signo, srv_to_string(rp)); return OK; /* clear the signal */ } if(rs_verbose) printf("RS: %s got %s signal %d\n", srv_to_string(rp), SIGS_IS_TERMINATION(signo) ? "termination" : "non-termination",signo); /* Print stacktrace if necessary. */ if(SIGS_IS_STACKTRACE(signo)) { sys_diagctl_stacktrace(target); } /* In case of termination signal handle the event. */ if(SIGS_IS_TERMINATION(signo)) { rp->r_flags |= RS_TERMINATED; terminate_service(rp); rs_idle_period(); return EDEADEPT; /* process is now gone */ } /* Never deliver signals to VM. */ if (rp->r_pub->endpoint == VM_PROC_NR) { return OK; } /* Translate every non-termination signal into a message. */ m.m_type = SIGS_SIGNAL_RECEIVED; m.m_pm_lsys_sigs_signal.num = signo; rs_asynsend(rp, &m, 1); return OK; /* signal has been delivered */ }
/*===========================================================================* * main * *===========================================================================*/ PUBLIC int main(void) { /* This is the main routine of this service. The main loop consists of * three major activities: getting new work, processing the work, and * sending the reply. The loop never terminates, unless a panic occurs. */ message m; /* request message */ int ipc_status; /* status code */ int call_nr, who_e,who_p; /* call number and caller */ int result; /* result to return */ int s; /* SEF local startup. */ sef_local_startup(); if (OK != (s=sys_getmachine(&machine))) panic("couldn't get machine info: %d", s); /* Main loop - get work and do it, forever. */ while (TRUE) { /* Wait for request message. */ get_work(&m, &ipc_status); who_e = m.m_source; if(rs_isokendpt(who_e, &who_p) != OK) { panic("message from bogus source: %d", who_e); } call_nr = m.m_type; /* Now determine what to do. Four types of requests are expected: * - Heartbeat messages (notifications from registered system services) * - System notifications (synchronous alarm) * - User requests (control messages to manage system services) * - Ready messages (reply messages from registered services) */ /* Notification messages are control messages and do not need a reply. * These include heartbeat messages and system notifications. */ if (is_ipc_notify(ipc_status)) { switch (who_p) { case CLOCK: do_period(&m); /* check services status */ continue; default: /* heartbeat notification */ if (rproc_ptr[who_p] != NULL) { /* mark heartbeat time */ rproc_ptr[who_p]->r_alive_tm = m.NOTIFY_TIMESTAMP; } else { printf("RS: warning: got unexpected notify message from %d\n", m.m_source); } } } /* If we get this far, this is a normal request. * Handle the request and send a reply to the caller. */ else { if (call_nr != COMMON_GETSYSINFO && (call_nr < RS_RQ_BASE || call_nr >= RS_RQ_BASE+0x100)) { /* Ignore invalid requests. Do not try to reply. */ printf("RS: warning: got invalid request %d from endpoint %d\n", call_nr, m.m_source); continue; } /* Handler functions are responsible for permission checking. */ switch(call_nr) { /* User requests. */ case RS_UP: result = do_up(&m); break; case RS_DOWN: result = do_down(&m); break; case RS_REFRESH: result = do_refresh(&m); break; case RS_RESTART: result = do_restart(&m); break; case RS_SHUTDOWN: result = do_shutdown(&m); break; case RS_UPDATE: result = do_update(&m); break; case RS_CLONE: result = do_clone(&m); break; case RS_EDIT: result = do_edit(&m); break; case COMMON_GETSYSINFO: result = do_getsysinfo(&m); break; case RS_LOOKUP: result = do_lookup(&m); break; /* Ready messages. */ case RS_INIT: result = do_init_ready(&m); break; case RS_LU_PREPARE: result = do_upd_ready(&m); break; default: printf("RS: warning: got unexpected request %d from %d\n", m.m_type, m.m_source); result = EINVAL; } /* Finally send reply message, unless disabled. */ if (result != EDONTREPLY) { m.m_type = result; reply(who_e, NULL, &m); } } } }