/*===========================================================================* * main * *===========================================================================*/ PUBLIC int main(int argc, char **argv) { /* 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; int result; sigset_t sigset; /* Initialize the server, then go to work. */ init_server(argc, argv); /* Main loop - get work and do it, forever. */ while (TRUE) { /* Wait for incoming message, sets 'callnr' and 'who'. */ get_work(&m); switch (callnr) { case PROC_EVENT: sig_handler(); continue; case DS_PUBLISH: result = do_publish(&m); break; case DS_RETRIEVE: result = do_retrieve(&m); break; case DS_SUBSCRIBE: result = do_subscribe(&m); break; case GETSYSINFO: result = do_getsysinfo(&m); break; default: report("DS","warning, got illegal request from:", m.m_source); result = EINVAL; } /* Finally send reply message, unless disabled. */ if (result != EDONTREPLY) { m.m_type = result; /* build reply message */ reply(who_e, &m); /* send it away */ } } return(OK); /* shouldn't come here */ }
/*===========================================================================* * main * *===========================================================================*/ PUBLIC int main(int argc, char **argv) { /* 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; int result; /* SEF local startup. */ env_setargs(argc, argv); sef_local_startup(); /* Main loop - get work and do it, forever. */ while (TRUE) { /* Wait for incoming message, sets 'callnr' and 'who'. */ get_work(&m); if (is_notify(callnr)) { printf("DS: warning, got illegal notify from: %d\n", m.m_source); result = EINVAL; goto send_reply; } switch (callnr) { case DS_PUBLISH: result = do_publish(&m); break; case DS_RETRIEVE: result = do_retrieve(&m); break; case DS_RETRIEVE_LABEL: result = do_retrieve_label(&m); break; case DS_DELETE: result = do_delete(&m); break; case DS_SUBSCRIBE: result = do_subscribe(&m); break; case DS_CHECK: result = do_check(&m); break; case DS_SNAPSHOT: result = do_snapshot(&m); break; case GETSYSINFO: result = do_getsysinfo(&m); break; default: printf("DS: warning, got illegal request from %d\n", m.m_source); result = EINVAL; } send_reply: /* Finally send reply message, unless disabled. */ if (result != EDONTREPLY) { m.m_type = result; /* build reply message */ reply(who_e, &m); /* send it away */ } } return(OK); /* shouldn't come here */ }
/*===========================================================================* * do_work * *===========================================================================*/ static void *do_work(void *arg) { int error; struct job my_job; my_job = *((struct job *) arg); fp = my_job.j_fp; lock_proc(fp, 0); /* This proc is busy */ if (job_call_nr == MAPDRIVER) { error = do_mapdriver(); } else if (job_call_nr == COMMON_GETSYSINFO) { error = do_getsysinfo(); } else if (IS_PFS_VFS_RQ(job_call_nr)) { if (who_e != PFS_PROC_NR) { printf("VFS: only PFS is allowed to make nested VFS calls\n"); error = ENOSYS; } else if (job_call_nr <= PFS_BASE || job_call_nr >= PFS_BASE + PFS_NREQS) { error = ENOSYS; } else { job_call_nr -= PFS_BASE; error = (*pfs_call_vec[job_call_nr])(); } } else { /* We're dealing with a POSIX system call from a normal * process. Call the internal function that does the work. */ if (job_call_nr < 0 || job_call_nr >= NCALLS) { error = ENOSYS; } else if (fp->fp_pid == PID_FREE) { /* Process vanished before we were able to handle request. * Replying has no use. Just drop it. */ error = SUSPEND; } else { #if ENABLE_SYSCALL_STATS calls_stats[job_call_nr]++; #endif error = (*call_vec[job_call_nr])(); } } /* Copy the results back to the user and send reply. */ if (error != SUSPEND) { if ((fp->fp_flags & FP_SYS_PROC)) { struct vmnt *vmp; if ((vmp = find_vmnt(fp->fp_endpoint)) != NULL) vmp->m_flags &= ~VMNT_CALLBACK; } if (deadlock_resolving) { if (fp->fp_wtid == dl_worker.w_tid) deadlock_resolving = 0; } reply(fp->fp_endpoint, error); } thread_cleanup(fp); return(NULL); }
/*===========================================================================* * 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); } } } }
/*===========================================================================* * 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 call_nr, who_e,who_p; /* call number and caller */ int result; /* result to return */ sigset_t sigset; /* system signal set */ int s; /* Initialize the server, then go to work. */ init_server(); /* Main loop - get work and do it, forever. */ while (TRUE) { /* Wait for request message. */ get_work(&m); who_e = m.m_source; who_p = _ENDPOINT_P(who_e); if(who_p < -NR_TASKS || who_p >= NR_PROCS) panic("RS","message from bogus source", who_e); call_nr = m.m_type; /* Now determine what to do. Three types of requests are expected: * - Heartbeat messages (notifications from registered system services) * - System notifications (POSIX signals or synchronous alarm) * - User requests (control messages to manage system services) */ /* Notification messages are control messages and do not need a reply. * These include heartbeat messages and system notifications. */ if (m.m_type & NOTIFY_MESSAGE) { switch (call_nr) { case SYN_ALARM: do_period(&m); /* check drivers status */ continue; case PROC_EVENT: sig_handler(); continue; default: /* heartbeat notification */ if (rproc_ptr[who_p] != NULL) /* mark heartbeat time */ rproc_ptr[who_p]->r_alive_tm = m.NOTIFY_TIMESTAMP; } } /* If this is not a notification message, it is a normal request. * Handle the request and send a reply to the caller. */ else { switch(call_nr) { 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_RESCUE: result = do_rescue(&m); break; case RS_SHUTDOWN: result = do_shutdown(&m); break; case GETSYSINFO: result = do_getsysinfo(&m); break; default: printf("Warning, RS got unexpected request %d from %d\n", m.m_type, m.m_source); result = EINVAL; } /* Finally send reply message, unless disabled. */ if (result != EDONTREPLY) { reply(who_e, result); } } } }
/*===========================================================================* * main * *===========================================================================*/ int main() { /* Main routine of the process manager. */ int result; /* SEF local startup. */ sef_local_startup(); // Initialization of the semarray (of pointers) to NULL register struct mproc *rmp; // rmp is the pointer to the struct of the process table for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) { for(int i=0; i<12; i++) // for all 12 semaphores { rmp->semarray[i]=NULL; } } // end of Initialization /* This is PM's main loop- get work and do it, forever and forever. */ while (TRUE) { int ipc_status; /* Wait for the next message and extract useful information from it. */ if (sef_receive_status(ANY, &m_in, &ipc_status) != OK) panic("PM sef_receive_status error"); who_e = m_in.m_source; /* who sent the message */ if(pm_isokendpt(who_e, &who_p) != OK) panic("PM got message from invalid endpoint: %d", who_e); call_nr = m_in.m_type; /* system call number */ /* Process slot of caller. Misuse PM's own process slot if the kernel is * calling. This can happen in case of synchronous alarms (CLOCK) or or * event like pending kernel signals (SYSTEM). */ mp = &mproc[who_p < 0 ? PM_PROC_NR : who_p]; if(who_p >= 0 && mp->mp_endpoint != who_e) { panic("PM endpoint number out of sync with source: %d", mp->mp_endpoint); } /* Drop delayed calls from exiting processes. */ if (mp->mp_flags & EXITING) continue; /* Check for system notifications first. Special cases. */ if (is_ipc_notify(ipc_status)) { if (who_p == CLOCK) { expire_timers(m_in.NOTIFY_TIMESTAMP); } /* done, send reply and continue */ sendreply(); continue; } switch(call_nr) { case PM_SETUID_REPLY: case PM_SETGID_REPLY: case PM_SETSID_REPLY: case PM_EXEC_REPLY: case PM_EXIT_REPLY: case PM_CORE_REPLY: case PM_FORK_REPLY: case PM_SRV_FORK_REPLY: case PM_UNPAUSE_REPLY: case PM_REBOOT_REPLY: case PM_SETGROUPS_REPLY: if (who_e == VFS_PROC_NR) { handle_vfs_reply(); result= SUSPEND; /* don't reply */ } else result= ENOSYS; break; case COMMON_GETSYSINFO: result = do_getsysinfo(); break; default: /* Else, if the system call number is valid, perform the * call. */ if ((unsigned) call_nr >= NCALLS) { result = ENOSYS; } else { #if ENABLE_SYSCALL_STATS calls_stats[call_nr]++; #endif result = (*call_vec[call_nr])(); } break; } /* Send reply. */ if (result != SUSPEND) setreply(who_p, result); sendreply(); } return(OK); }