bool http_client::handle(void) { const char* cmd = http_hdr_req_param(hdr_req_, "cmd"); if (cmd == NULL || *cmd == 0) { //logger_error("cmd null"); acl::string dummy; do_reply(400, "none", dummy, false); if (hdr_req_->hdr.keep_alive) wait(); else acl_aio_iocp_close(conn_); return true; } #define EQ !strcasecmp int i; for (i = 0; handlers[i].cmd != NULL; i++) { if (EQ(cmd, handlers[i].cmd)) break; } if (handlers[i].handler == NULL) { logger_warn("invalid cmd=%s", cmd); acl::string dummy; do_reply(400, "unknown", dummy, false); if (hdr_req_->hdr.keep_alive) wait(); else acl_aio_iocp_close(conn_); return true; } if ((this->*handlers[i].handler)()) return true; acl_aio_iocp_close(conn_); return false; }
/*===========================================================================* * main * *===========================================================================*/ int main(int argc, char *argv[]) { dpeth_t *dep; message m; int ipc_status; int r; /* SEF local startup. */ env_setargs(argc, argv); sef_local_startup(); while (TRUE) { if ((r= netdriver_receive(ANY, &m, &ipc_status)) != OK) panic("netdriver_receive failed: %d", r); if(is_ipc_notify(ipc_status)) { switch(_ENDPOINT_P(m.m_source)) { case CLOCK: do_watchdog(&m); break; case HARDWARE: dep = &de_state; if (dep->de_mode == DEM_ENABLED) { do_interrupt(dep); if (dep->de_flags & (DEF_ACK_SEND | DEF_ACK_RECV)) do_reply(dep); sys_irqenable(&dep->de_hook); } break; default: printf("ignoring notify from %d\n", m.m_source); break; } continue; } switch (m.m_type) { case DL_WRITEV_S: do_vwrite_s(&m, FALSE); break; case DL_READV_S: do_vread_s(&m, FALSE); break; case DL_CONF: do_conf(&m); break; case DL_GETSTAT_S: do_get_stat_s(&m); break; default: printf("message 0x%x; %d from %d\n", m.m_type, m.m_type-DL_RQ_BASE, m.m_source); panic("illegal message: %d", m.m_type); } } }
// // process monitor message. // // if shutdown, set done // void do_mon_msg(BMS_SRE *sre, bool *done) { int ferr; MS_Mon_Msg mon_msg; ferr = BMSG_READDATA_(sre->sre_msgId, // msgid (char *) &mon_msg, // reqdata (int) sizeof(mon_msg)); // bytecount assert(ferr == XZFIL_ERR_OK); if (mon_msg.type == MS_MsgType_Shutdown) *done = true; if (verbose) printf("srv: received mon message\n"); do_reply(sre, NULL, 0, 0); }
// // process monitor message. // // if shutdown, set done // void do_mon_msg(BMS_SRE *pp_sre, bool *pp_done) { int lv_ferr; MS_Mon_Msg lv_mon_msg; lv_ferr = BMSG_READDATA_(pp_sre->sre_msgId, // msgid (char *) &lv_mon_msg, // reqdata (int) sizeof(lv_mon_msg)); // bytecount assert(lv_ferr == XZFIL_ERR_OK); if (lv_mon_msg.type == MS_MsgType_Shutdown) { printf("%s: received shutdown message\n", ga_name); *pp_done = true; } if (gv_verbose) printf("srv: received mon message\n"); do_reply(pp_sre, NULL, 0, 0); }
// // process non-mon message // void do_req(BMS_SRE *pp_sre) { const char *lp_req_type; short lv_ec; int lv_ferr; int lv_len; GID_Rep lv_rep; GID_Req lv_req; long lv_req_id; struct timeval lv_tv; struct timespec lv_orig_ts; unsigned long lv_converted_tm_id; lv_ec = XZFIL_ERR_OK; lv_len = 0; if (gv_verbose) printf("srv: received NON-mon message\n"); if (pp_sre->sre_reqDataSize < (int) sizeof(lv_req)) { if (gv_verbose) printf("srv: received short data - sre_reqDataSize=%d, expecting len=%d, setting BADCOUNT\n", pp_sre->sre_reqDataSize, (int) sizeof(lv_req)); lv_ec = XZFIL_ERR_BADCOUNT; } else { lv_ferr = BMSG_READDATA_(pp_sre->sre_msgId, // msgid (char *) &lv_req, // reqdata (int) sizeof(lv_req)); // bytecount if (lv_ferr != XZFIL_ERR_OK){ printf("srv: received lv_ferr %d in do_req \n", lv_ferr); if((lv_ferr = XMSG_ISCANCELED_(pp_sre->sre_msgId))){ printf("srv: XMSG_ISCANCELED_ returned %d in do_req. Most likely the client timeout was exceeded \n", lv_ferr); return; } else{ printf("srv: XMSG_ISCANCELED_ returned %d in do_req after FEEOF on BMSG_READDATA_. ABORTING \n", lv_ferr); abort(); } } if (gv_verbose) { switch (lv_req.iv_req_type) { case GID_REQ_PING: lp_req_type = "ping"; break; case GID_REQ_ID: lp_req_type = "id"; break; case GID_REQ_ID_TO_STRING: lp_req_type = "id_to_string"; break; case GID_REQ_STRING_TO_ID: lp_req_type = "string_to_id"; break; default: lp_req_type = "unknown"; break; } if (gv_verbose) printf("srv: received msg. req-type=%d(%s), tag=%ld, len=%d\n", lv_req.iv_req_type, lp_req_type, lv_req.iv_req_tag, lv_req.iv_req_len); } switch (lv_req.iv_req_type) { case GID_REQ_PING: if (lv_req.iv_req_len == (int) sizeof(lv_req.u.iv_ping)) { if (gv_verbose) printf("srv: received ping request\n"); lv_rep.iv_rep_type = GID_REP_PING; lv_rep.iv_rep_tag = lv_req.iv_req_tag; lv_rep.iv_rep_len = (int) sizeof(lv_rep.u.iv_ping); lv_rep.u.iv_ping.iv_com.iv_error = GID_ERR_OK; gettimeofday(&lv_tv, NULL); lv_rep.u.iv_ping.iv_ts_sec = lv_tv.tv_sec; lv_rep.u.iv_ping.iv_ts_us = lv_tv.tv_usec; } else { if (gv_verbose) printf("srv: received ping, req-len=%d, expecting len=%d, setting BADCOUNT\n", lv_req.iv_req_len, (int) sizeof(lv_req.u.iv_ping)); lv_ec = XZFIL_ERR_BADCOUNT; } break; case GID_REQ_ID: if (lv_req.iv_req_len == (int) sizeof(lv_req.u.iv_id)) { if (gv_verbose) printf("srv: received id request\n"); lv_rep.iv_rep_type = GID_REP_ID; lv_rep.iv_rep_tag = lv_req.iv_req_tag; lv_rep.iv_rep_len = (int) sizeof(lv_rep.u.iv_id); lv_rep.u.iv_id.iv_com.iv_error = GID_ERR_OK; lv_rep.u.iv_id.iv_id = __sync_add_and_fetch_8(gp_shm, 1); } else { if (gv_verbose) printf("srv: received id, req-len=%d, expecting len=%d, setting BADCOUNT\n", lv_req.iv_req_len, (int) sizeof(lv_req.u.iv_id)); lv_ec = XZFIL_ERR_BADCOUNT; } break; case GID_REQ_ID_TO_STRING: if (lv_req.iv_req_len == (int) sizeof(lv_req.u.iv_id_to_string)) { lv_rep.iv_rep_type = GID_REP_ID_TO_STRING; lv_rep.iv_rep_tag = lv_req.iv_req_tag; lv_req_id = lv_req.u.iv_id_to_string.iv_req_id_to_string; if (gv_verbose) printf("srv: received id_to_string request for id:Ox%lx\n", lv_req_id); lv_orig_ts = long_to_timespec(lv_req_id); lv_ferr = timespec_to_str(lv_rep.u.iv_id_to_string.iv_id_to_string, sizeof(lv_rep.u.iv_id_to_string.iv_id_to_string) , &lv_orig_ts); lv_rep.iv_rep_len = sizeof(lv_rep.u.iv_id_to_string); lv_rep.u.iv_id_to_string.iv_com.iv_error = (GID_Err_Type) lv_ferr; if (gv_verbose){ printf("srv: replying to id_to_string request with err=%d, reply-size %d, string %s, and len%d\n", lv_rep.u.iv_id_to_string.iv_com.iv_error, lv_rep.iv_rep_len, lv_rep.u.iv_id_to_string.iv_id_to_string, (int) strlen(lv_rep.u.iv_id_to_string.iv_id_to_string)); } } else { if (gv_verbose) printf("srv: received id_to_string, req-len=%d, expecting len=%d, setting BADCOUNT\n", lv_req.iv_req_len, (int) sizeof(lv_req.u.iv_id_to_string)); lv_ec = XZFIL_ERR_BADCOUNT; } break; case GID_REQ_STRING_TO_ID: if (lv_req.iv_req_len == (int) sizeof(lv_req.u.iv_string_to_id)) { if (gv_verbose) printf("srv: received string_to_id request, string: %s\n", lv_req.u.iv_string_to_id.iv_string_to_id); lv_rep.iv_rep_type = GID_REP_STRING_TO_ID; lv_rep.iv_rep_tag = lv_req.iv_req_tag; lv_ferr = str_to_tm_id(lv_req.u.iv_string_to_id.iv_string_to_id, &lv_converted_tm_id); lv_rep.u.iv_string_to_id.iv_string_to_id = lv_converted_tm_id; lv_rep.iv_rep_len = sizeof(lv_rep.u.iv_string_to_id); lv_rep.u.iv_string_to_id.iv_com.iv_error = (GID_Err_Type) lv_ferr; if (lv_ferr != XZFIL_ERR_OK) lv_ec = lv_ferr; if (gv_verbose) printf("srv: replying to string_to_id request with err=%d, size %d, and id %ld\n", lv_ferr, lv_rep.iv_rep_len, lv_converted_tm_id); } else { if (gv_verbose) printf("srv: received string_to_id, req-len=%d, expecting len=%d, setting BADCOUNT\n", lv_req.iv_req_len, (int) sizeof(lv_req.u.iv_string_to_id)); lv_ec = XZFIL_ERR_BADCOUNT; } break; default: if (gv_verbose) printf("srv: received unknown req-type=%d, setting INVALOP\n", lv_req.iv_req_type); lv_ec = XZFIL_ERR_INVALOP; break; } } if (gv_verbose){ if(lv_rep.iv_rep_type == GID_REP_ID_TO_STRING){ printf("srv: reply, rep-type=%d, tag=%ld, id_to_string=%s, len=%d\n", lv_rep.iv_rep_type, lv_rep.iv_rep_tag, lv_rep.u.iv_id_to_string.iv_id_to_string, lv_rep.iv_rep_len); } else { printf("srv: reply, rep-type=%d, tag=%ld, id=%ld, len=%d\n", lv_rep.iv_rep_type, lv_rep.iv_rep_tag, lv_rep.u.iv_id.iv_id, lv_rep.iv_rep_len); } } lv_len = (int) sizeof(lv_rep); do_reply(pp_sre, (char *) &lv_rep, lv_len, lv_ec); }
// // process non-mon message // void do_req(BMS_SRE *sre) { short ec; int ferr; int len; GID_Rep rep; GID_Req req; const char *req_type; struct timeval tv; ec = XZFIL_ERR_OK; len = 0; if (verbose) printf("srv: received NON-mon message\n"); if (sre->sre_reqDataSize < (int) sizeof(req)) { if (verbose) printf("srv: received short data - sre_reqDataSize=%d, expecting len=%d, setting BADCOUNT\n", sre->sre_reqDataSize, (int) sizeof(req)); ec = XZFIL_ERR_BADCOUNT; } else { ferr = BMSG_READDATA_(sre->sre_msgId, // msgid (char *) &req, // reqdata (int) sizeof(req)); // bytecount assert(ferr == XZFIL_ERR_OK); if (verbose) { switch (req.req_type) { case GID_REQ_PING: req_type = "ping"; break; case GID_REQ_ID: req_type = "id"; break; default: req_type = "unknown"; break; } if (verbose) printf("srv: received msg. req-type=%d(%s), tag=%ld, len=%d\n", req.req_type, req_type, req.req_tag, req.req_len); } switch (req.req_type) { case GID_REQ_PING: if (req.req_len == (int) sizeof(req.u.ping)) { if (verbose) printf("srv: received ping request\n"); rep.rep_type = GID_REP_PING; rep.rep_tag = req.req_tag; rep.rep_len = (int) sizeof(rep.u.ping); rep.u.ping.com.error = GID_ERR_OK; gettimeofday(&tv, NULL); rep.u.ping.ts_sec = tv.tv_sec; rep.u.ping.ts_us = tv.tv_usec; } else { if (verbose) printf("srv: received ping, req-len=%d, expecting len=%d, setting BADCOUNT\n", req.req_len, (int) sizeof(req.u.ping)); ec = XZFIL_ERR_BADCOUNT; } break; case GID_REQ_ID: if (req.req_len == (int) sizeof(req.u.id)) { if (verbose) printf("srv: received id request\n"); rep.rep_type = GID_REP_ID; rep.rep_tag = req.req_tag; rep.rep_len = (int) sizeof(rep.u.id); rep.u.id.com.error = GID_ERR_OK; rep.u.id.id = __sync_add_and_fetch_8(shm, 1); } else { if (verbose) printf("srv: received id, req-len=%d, expecting len=%d, setting BADCOUNT\n", req.req_len, (int) sizeof(req.u.id)); ec = XZFIL_ERR_BADCOUNT; } break; default: if (verbose) printf("srv: received unknown req-type=%d, setting INVALOP\n", req.req_type); ec = XZFIL_ERR_INVALOP; break; } } if (ec == XZFIL_ERR_OK) { if (verbose) printf("srv: reply, rep-type=%d, tag=%ld, len=%d\n", rep.rep_type, rep.rep_tag, rep.rep_len); len = (int) sizeof(rep); } else { len = 0; } do_reply(sre, (char *) &rep, len, ec); }
// // process non-mon message // void do_req(BMS_SRE *pp_sre) { const char *lp_req_type; short lv_ec; int lv_ferr; int lv_len; GID_Rep lv_rep; GID_Req lv_req; struct timeval lv_tv; lv_ec = XZFIL_ERR_OK; lv_len = 0; if (gv_verbose) printf("srv: received NON-mon message\n"); if (pp_sre->sre_reqDataSize < (int) sizeof(lv_req)) { if (gv_verbose) printf("srv: received short data - sre_reqDataSize=%d, expecting len=%d, setting BADCOUNT\n", pp_sre->sre_reqDataSize, (int) sizeof(lv_req)); lv_ec = XZFIL_ERR_BADCOUNT; } else { lv_ferr = BMSG_READDATA_(pp_sre->sre_msgId, // msgid (char *) &lv_req, // reqdata (int) sizeof(lv_req)); // bytecount assert(lv_ferr == XZFIL_ERR_OK); if (gv_verbose) { switch (lv_req.iv_req_type) { case GID_REQ_PING: lp_req_type = "ping"; break; case GID_REQ_ID: lp_req_type = "id"; break; default: lp_req_type = "unknown"; break; } if (gv_verbose) printf("srv: received msg. req-type=%d(%s), tag=%ld, len=%d\n", lv_req.iv_req_type, lp_req_type, lv_req.iv_req_tag, lv_req.iv_req_len); } switch (lv_req.iv_req_type) { case GID_REQ_PING: if (lv_req.iv_req_len == (int) sizeof(lv_req.u.iv_ping)) { if (gv_verbose) printf("srv: received ping request\n"); lv_rep.iv_rep_type = GID_REP_PING; lv_rep.iv_rep_tag = lv_req.iv_req_tag; lv_rep.iv_rep_len = (int) sizeof(lv_rep.u.iv_ping); lv_rep.u.iv_ping.iv_com.iv_error = GID_ERR_OK; gettimeofday(&lv_tv, NULL); lv_rep.u.iv_ping.iv_ts_sec = lv_tv.tv_sec; lv_rep.u.iv_ping.iv_ts_us = lv_tv.tv_usec; } else { if (gv_verbose) printf("srv: received ping, req-len=%d, expecting len=%d, setting BADCOUNT\n", lv_req.iv_req_len, (int) sizeof(lv_req.u.iv_ping)); lv_ec = XZFIL_ERR_BADCOUNT; } break; case GID_REQ_ID: if (lv_req.iv_req_len == (int) sizeof(lv_req.u.iv_id)) { if (gv_verbose) printf("srv: received id request\n"); lv_rep.iv_rep_type = GID_REP_ID; lv_rep.iv_rep_tag = lv_req.iv_req_tag; lv_rep.iv_rep_len = (int) sizeof(lv_rep.u.iv_id); lv_rep.u.iv_id.iv_com.iv_error = GID_ERR_OK; lv_rep.u.iv_id.iv_id = __sync_add_and_fetch_8(gp_shm, 1); } else { if (gv_verbose) printf("srv: received id, req-len=%d, expecting len=%d, setting BADCOUNT\n", lv_req.iv_req_len, (int) sizeof(lv_req.u.iv_id)); lv_ec = XZFIL_ERR_BADCOUNT; } break; default: if (gv_verbose) printf("srv: received unknown req-type=%d, setting INVALOP\n", lv_req.iv_req_type); lv_ec = XZFIL_ERR_INVALOP; break; } } if (lv_ec == XZFIL_ERR_OK) { if (gv_verbose) printf("srv: reply, rep-type=%d, tag=%ld, len=%d\n", lv_rep.iv_rep_type, lv_rep.iv_rep_tag, lv_rep.iv_rep_len); lv_len = (int) sizeof(lv_rep); } else { lv_len = 0; } do_reply(pp_sre, (char *) &lv_rep, lv_len, lv_ec); }
/*===========================================================================* * main * *===========================================================================*/ 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 transid; struct worker_thread *wp; /* SEF local startup. */ sef_local_startup(); printf("Started VFS: %d worker thread(s)\n", NR_WTHREADS); /* This is the main loop that gets work, processes it, and sends replies. */ while (TRUE) { worker_yield(); /* let other threads run */ send_work(); /* The get_work() function returns TRUE if we have a new message to * process. It returns FALSE if it spawned other thread activities. */ if (!get_work()) continue; transid = TRNS_GET_ID(m_in.m_type); if (IS_VFS_FS_TRANSID(transid)) { wp = worker_get((thread_t) transid - VFS_TRANSID); if (wp == NULL || wp->w_fp == NULL) { printf("VFS: spurious message %d from endpoint %d\n", m_in.m_type, m_in.m_source); continue; } m_in.m_type = TRNS_DEL_ID(m_in.m_type); do_reply(wp); continue; } else if (who_e == PM_PROC_NR) { /* Calls from PM */ /* Special control messages from PM */ service_pm(); continue; } else if (is_notify(call_nr)) { /* A task ipc_notify()ed us */ switch (who_e) { case DS_PROC_NR: /* Start a thread to handle DS events, if no thread * is pending or active for it already. DS is not * supposed to issue calls to VFS or be the subject of * postponed PM requests, so this should be no problem. */ if (worker_can_start(fp)) handle_work(ds_event); break; case KERNEL: mthread_stacktraces(); break; case CLOCK: /* Timer expired. Used only for select(). Check it. */ expire_timers(m_in.m_notify.timestamp); break; default: printf("VFS: ignoring notification from %d\n", who_e); } continue; } else if (who_p < 0) { /* i.e., message comes from a task */ /* We're going to ignore this message. Tasks should * send ipc_notify()s only. */ printf("VFS: ignoring message from %d (%d)\n", who_e, call_nr); continue; } if (IS_BDEV_RS(call_nr)) { /* We've got results for a block device request. */ bdev_reply(); } else if (IS_CDEV_RS(call_nr)) { /* We've got results for a character device request. */ cdev_reply(); } else { /* Normal syscall. This spawns a new thread. */ handle_work(do_work); } } return(OK); /* shouldn't come here */ }