/*===========================================================================* * main * *===========================================================================*/ int main(int argc, char *argv[]) { message m_out; int r, ipc_status; size_t size; /* SEF local startup. */ env_setargs(argc, argv); sef_local_startup(); for (;;) { /* Wait for request. */ if(driver_receive(ANY, &m_in, &ipc_status) != OK) { panic("driver_receive failed"); } #if DEBUG2 printf("Filter: got request %d from %d\n", m_in.m_type, m_in.m_source); #endif if(m_in.m_source == DS_PROC_NR && is_ipc_notify(ipc_status)) { ds_event(); continue; } who_e = m_in.m_source; req_id = m_in.BDEV_ID; grant_id = m_in.BDEV_GRANT; size = 0; /* Forword the request message to the drivers. */ switch(m_in.m_type) { case BDEV_OPEN: /* open/close is a noop for filter. */ case BDEV_CLOSE: r = OK; break; case BDEV_READ: r = do_rdwt(FLT_READ); break; case BDEV_WRITE: r = do_rdwt(FLT_WRITE); break; case BDEV_GATHER: r = do_vrdwt(FLT_READ); break; case BDEV_SCATTER: r = do_vrdwt(FLT_WRITE); break; case BDEV_IOCTL: r = do_ioctl(&m_in); break; default: printf("Filter: ignoring unknown request %d from %d\n", m_in.m_type, m_in.m_source); continue; } #if DEBUG2 printf("Filter: replying with code %d\n", r); #endif /* Send back reply message. */ m_out.m_type = BDEV_REPLY; m_out.BDEV_ID = req_id; m_out.BDEV_STATUS = r; send(who_e, &m_out); } return 0; }
/*===========================================================================* * restart_driver * *===========================================================================*/ static void restart_driver(int which, int tell_rs) { /* Restart the given driver. Block until the new instance is up. */ message msg; int ipc_status; int r; if (tell_rs) { /* Tell RS to refresh or restart the driver */ msg.m_type = RS_REFRESH; msg.RS_CMD_ADDR = driver[which].label; msg.RS_CMD_LEN = strlen(driver[which].label); #if DEBUG printf("Filter: asking RS to refresh %s..\n", driver[which].label); #endif r = sendrec(RS_PROC_NR, &msg); if (r != OK || msg.m_type != OK) panic("RS request failed: %d", r); #if DEBUG printf("Filter: RS call succeeded\n"); #endif } /* Wait until the new driver instance is up, and get its endpoint. */ #if DEBUG printf("Filter: endpoint update driver %d; old endpoint %d\n", which, driver[which].endpt); #endif if(driver[which].up_event == UP_EXPECTED) { driver[which].up_event = UP_NONE; } while(driver[which].up_event != UP_PENDING) { r = driver_receive(DS_PROC_NR, &msg, &ipc_status); if(r != OK) panic("driver_receive returned error: %d", r); ds_event(); } }
int main(__unused int argc, __unused char ** argv) { sef_local_startup(); for(;;) { int err, ipc_status; message m; netif_poll_lo(); mq_process(); if ((err = sef_receive_status(ANY, &m, &ipc_status)) != OK) { printf("LWIP : sef_receive_status errr %d\n", err); continue; } if (m.m_source == VFS_PROC_NR) socket_request(&m, ipc_status); else if (is_ipc_notify(ipc_status)) { switch (m.m_source) { case CLOCK: expire_timers(m.m_notify.timestamp); break; case DS_PROC_NR: ds_event(); break; case PM_PROC_NR: panic("LWIP : unhandled event from PM"); break; default: printf("LWIP : unexpected notify from %d\n", m.m_source); continue; } } else /* all other request can be from drivers only */ driver_request(&m); } return 0; }
/*===========================================================================* * do_control_msgs * *===========================================================================*/ static void *do_control_msgs(void *arg) { struct job my_job; my_job = *((struct job *) arg); fp = my_job.j_fp; /* Check for special control messages. */ if (job_m_in.m_source == CLOCK) { /* Alarm timer expired. Used only for select(). Check it. */ expire_timers(job_m_in.NOTIFY_TIMESTAMP); } else if (job_m_in.m_source == DS_PROC_NR) { /* DS notifies us of an event. */ ds_event(); } else { /* Device notifies us of an event. */ dev_status(&job_m_in); } thread_cleanup(NULL); return(NULL); }
/*===========================================================================* * main * *===========================================================================*/ PUBLIC int main(void) { /* This is the main program of the file system. The main loop consists of * three major activities: getting new work, processing the work, and sending * the reply. This loop never terminates as long as the file system runs. */ int error; /* SEF local startup. */ sef_local_startup(); /* This is the main loop that gets work, processes it, and sends replies. */ while (TRUE) { SANITYCHECK; get_work(); /* sets who and call_nr */ if (call_nr == DEV_REVIVE) { endpoint_t endpt; endpt = m_in.REP_ENDPT; if(endpt == VFS_PROC_NR) { endpt = suspended_ep(m_in.m_source, m_in.REP_IO_GRANT); if(endpt == NONE) { printf("FS: proc with " "grant %d from %d not found (revive)\n", m_in.REP_IO_GRANT, m_in.m_source); continue; } } revive(endpt, m_in.REP_STATUS); continue; } if (call_nr == DEV_REOPEN_REPL) { reopen_reply(); continue; } if (call_nr == DEV_CLOSE_REPL) { close_reply(); continue; } if (call_nr == DEV_SEL_REPL1) { select_reply1(); continue; } if (call_nr == DEV_SEL_REPL2) { select_reply2(); continue; } /* Check for special control messages first. */ if (is_notify(call_nr)) { if (who_e == CLOCK) { /* Alarm timer expired. Used only for select(). * Check it. */ expire_timers(m_in.NOTIFY_TIMESTAMP); } else if(who_e == DS_PROC_NR) { /* DS notifies us of an event. */ ds_event(); } else { /* Device notifies us of an event. */ dev_status(&m_in); } SANITYCHECK; continue; } /* We only expect notify()s from tasks. */ if(who_p < 0) { printf("FS: ignoring message from %d (%d)\n", who_e, m_in.m_type); continue; } /* Now it's safe to set and check fp. */ fp = &fproc[who_p]; /* pointer to proc table struct */ super_user = (fp->fp_effuid == SU_UID ? TRUE : FALSE); /* su? */ #if DO_SANITYCHECKS if(fp_is_blocked(fp)) { printf("VFS: requester %d call %d: suspended\n", who_e, call_nr); panic("requester suspended"); } #endif /* Calls from PM. */ if (who_e == PM_PROC_NR) { service_pm(); continue; } SANITYCHECK; /* Other calls. */ switch(call_nr) { case MAPDRIVER: error= do_mapdriver(); if (error != SUSPEND) reply(who_e, error); break; default: /* Call the internal function that does the work. */ if (call_nr < 0 || call_nr >= NCALLS) { error = SUSPEND; /* Not supposed to happen. */ printf("VFS: illegal %d system call by %d\n", call_nr, who_e); } else if (fp->fp_pid == PID_FREE) { error = ENOSYS; printf( "FS, bad process, who = %d, call_nr = %d, endpt1 = %d\n", who_e, call_nr, m_in.endpt1); } else { #if ENABLE_SYSCALL_STATS calls_stats[call_nr]++; #endif SANITYCHECK; error = (*call_vec[call_nr])(); SANITYCHECK; } /* Copy the results back to the user and send reply. */ if (error != SUSPEND) { reply(who_e, error); } } SANITYCHECK; } return(OK); /* shouldn't come here */ }
/*===========================================================================* * flt_receive * *===========================================================================*/ static int flt_receive(message *mess, int which) { /* Receive a message from one or either driver, unless a timeout * occurs. Can only return OK or RET_REDO. */ int r; int ipc_status; for (;;) { r = driver_receive(ANY, mess, &ipc_status); if(r != OK) panic("driver_receive returned error: %d", r); if(mess->m_source == DS_PROC_NR && is_ipc_notify(ipc_status)) { ds_event(); continue; } if(mess->m_source == CLOCK && is_ipc_notify(ipc_status)) { if (mess->NOTIFY_TIMESTAMP < flt_alarm(-1)) { #if DEBUG printf("Filter: SKIPPING old alarm " "notification\n"); #endif continue; } #if DEBUG printf("Filter: timeout waiting for disk driver %d " "reply!\n", which); #endif /* If we're waiting for either driver, * both are at fault. */ if (which < 0) { bad_driver(DRIVER_MAIN, check_senda(DRIVER_MAIN), EFAULT); return bad_driver(DRIVER_BACKUP, check_senda(DRIVER_BACKUP), EFAULT); } /* Otherwise, just report the one not replying as dead. */ return bad_driver(which, check_senda(which), EFAULT); } if (mess->m_source != driver[DRIVER_MAIN].endpt && mess->m_source != driver[DRIVER_BACKUP].endpt) { #if DEBUG printf("Filter: got STRAY message %d from %d\n", mess->m_type, mess->m_source); #endif continue; } /* We are waiting for a reply from one specific driver. */ if (which >= 0) { /* If the message source is that driver, good. */ if (mess->m_source == driver[which].endpt) break; /* This should probably be treated as a real protocol * error. We do not abort any receives (not even paired * receives) except because of timeouts. Getting here * means a driver replied at least the timeout period * later than expected, which should be enough reason * to kill it really. The other explanation is that it * is actually violating the protocol and sending bogus * messages... */ #if DEBUG printf("Filter: got UNEXPECTED reply from %d\n", mess->m_source); #endif continue; } /* We got a message from one of the drivers, and we didn't * care which one we wanted to receive from. A-OK. */ break; } return OK; }
int main(int argc, char *argv[]) { mq_t *mq; int ipc_status; int r; endpoint_t source; int m_type; /* SEF local startup. */ sef_local_startup(); while (TRUE) { #ifdef BUF_CONSISTENCY_CHECK if (inet_buf_debug) { static int buf_debug_count= 0; if (++buf_debug_count >= inet_buf_debug) { buf_debug_count= 0; if (!bf_consistency_check()) break; } } #endif if (ev_head) { ev_process(); continue; } if (clck_call_expire) { clck_expire_timers(); continue; } mq= mq_get(); if (!mq) ip_panic(("out of messages")); r= sef_receive_status(ANY, &mq->mq_mess, &ipc_status); if (r<0) { ip_panic(("unable to receive: %d", r)); } reset_time(); source= mq->mq_mess.m_source; m_type= mq->mq_mess.m_type; if (source == VFS_PROC_NR) { sr_rec(mq); } else if (is_ipc_notify(ipc_status)) { if (source == CLOCK) { clck_tick(&mq->mq_mess); mq_free(mq); } else if (source == PM_PROC_NR) { /* signaled */ /* probably SIGTERM */ mq_free(mq); } else if (source == DS_PROC_NR) { /* DS notifies us of an event. */ ds_event(); mq_free(mq); } else { printf("inet: got unexpected notify from %d\n", mq->mq_mess.m_source); mq_free(mq); } } else if (m_type == DL_CONF_REPLY || m_type == DL_TASK_REPLY || m_type == DL_STAT_REPLY) { eth_rec(&mq->mq_mess); mq_free(mq); } else { printf("inet: got bad message type 0x%x from %d\n", mq->mq_mess.m_type, mq->mq_mess.m_source); mq_free(mq); } } ip_panic(("task is not allowed to terminate")); return 1; }