int main(int argc, char ** argv) { /* Create variables corresponding to the number of processes that have * been requested as well as this processes particular rank. */ int n_processes, rank; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &n_processes); MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* Split the tasks up according to whether they are the worker processes * or the master process. */ switch (rank) { case MASTER_PROCESS: master_process(); TERMINATE_ALL(); printf("Master process completed.\n"); break; case SCRIBE_PROCESS: scribe_process(); printf("Scribe process completed.\n"); break; default: worker_process(); printf("Worker process completed.\n"); break; } /* That's all folks! */ MPI_Finalize(); }
// Get and process messages forever or until interrupted void start_brokering() { while (!s_interrupted) { zmq::pollitem_t items [] = { { *m_socket, 0, ZMQ_POLLIN, 0 } }; zmq::poll (items, 1, HEARTBEAT_INTERVAL); // Process next input message, if any if (items [0].revents & ZMQ_POLLIN) { zmsg *msg = new zmsg(*m_socket); if (m_verbose) { s_console ("I: received message:"); msg->dump (); } std::string sender = std::string((char*)msg->pop_front ().c_str()); msg->pop_front (); //empty message std::string header = std::string((char*)msg->pop_front ().c_str()); // std::cout << "sbrok, sender: "<< sender << std::endl; // std::cout << "sbrok, header: "<< header << std::endl; // std::cout << "msg size: " << msg->parts() << std::endl; // msg->dump(); if (header.compare(MDPC_CLIENT) == 0) { client_process (sender, msg); } else if (header.compare(MDPW_WORKER) == 0) { worker_process (sender, msg); } else { s_console ("E: invalid message:"); msg->dump (); delete msg; } } // Disconnect and delete any expired workers // Send heartbeats to idle workers if needed if (s_clock () > m_heartbeat_at) { purge_workers (); for (std::vector<worker*>::iterator it = m_waiting.begin(); it != m_waiting.end() && (*it)!=0; it++) { worker_send (*it, (char*)MDPW_HEARTBEAT, "", NULL); } m_heartbeat_at = s_clock () + HEARTBEAT_INTERVAL; } } }
/** * Start the CDiameterPeer operations. * It forks all the processes required. * @param blocking - if this is set, use the calling processes for the timer and never * return; else fork a new one for the timer and return * @returns 1 on success, 0 on error, never if blocking */ int diameter_peer_start(int blocking) { int pid; int k=0; peer *p; /* fork workers */ for(k=0;k<config->workers;k++){ pid = fork_process(1001+k,"cdp_worker",1); if (pid==-1){ LM_CRIT("init_diameter_peer(): Error on fork() for worker!\n"); return 0; } if (pid==0) { srandom(time(0)*k); snprintf(pt[process_no].desc, MAX_PT_DESC,"cdp worker child=%d", k ); if (cfg_child_init()) return 0; worker_process(k); LM_CRIT("init_diameter_peer(): worker_process finished without exit!\n"); exit(-1); }else{ dp_add_pid(pid); } } /* init the fd_exchange pipes */ receiver_init(NULL); for(p = peer_list->head,k=0;p;p=p->next,k++) receiver_init(p); /* fork receiver for unknown peers */ pid = fork_process(1001+k,"cdp_receiver_peer_unkown",1); if (pid==-1){ LM_CRIT("init_diameter_peer(): Error on fork() for unknown peer receiver!\n"); return 0; } if (pid==0) { srandom(time(0)*k); snprintf(pt[process_no].desc, MAX_PT_DESC, "cdp receiver peer unknown"); if (cfg_child_init()) return 0; receiver_process(NULL); LM_CRIT("init_diameter_peer(): receiver_process finished without exit!\n"); exit(-1); }else{ dp_add_pid(pid); } /* fork receivers for each pre-configured peers */ lock_get(peer_list_lock); for(p = peer_list->head,k=-1;p;p = p->next,k--){ pid = fork_process(1001+k,"cdp_receiver_peer",1); if (pid==-1){ LM_CRIT("init_diameter_peer(): Error on fork() for peer receiver!\n"); return 0; } if (pid==0) { srandom(time(0)*k); snprintf(pt[process_no].desc, MAX_PT_DESC, "cdp_receiver_peer=%.*s", p->fqdn.len,p->fqdn.s ); if (cfg_child_init()) return 0; receiver_process(p); LM_CRIT("init_diameter_peer(): receiver_process finished without exit!\n"); exit(-1); }else{ dp_add_pid(pid); } } lock_release(peer_list_lock); /* Fork the acceptor process (after receivers, so it inherits all the right sockets) */ pid = fork_process(1000,"cdp_acceptor",1); if (pid==-1){ LM_CRIT("init_diameter_peer(): Error on fork() for acceptor!\n"); return 0; } if (pid==0) { if (cfg_child_init()) return 0; acceptor_process(config); LM_CRIT("init_diameter_peer(): acceptor_process finished without exit!\n"); exit(-1); }else{ dp_add_pid(pid); } /* fork/become timer */ if (blocking) { dp_add_pid(getpid()); if (cfg_child_init()) return 0; timer_process(1); } else{ pid = fork_process(1001,"cdp_timer",1); if (pid==-1){ LM_CRIT("init_diameter_peer(): Error on fork() for timer!\n"); return 0; } if (pid==0) { if (cfg_child_init()) return 0; timer_process(0); LM_CRIT("init_diameter_peer(): timer_process finished without exit!\n"); exit(-1); }else{ dp_add_pid(pid); } } return 1; }
static void monitor_worker_process(int child_pid, const debugger_request_t& request) { struct timespec timeout = {.tv_sec = 10, .tv_nsec = 0 }; if (should_attach_gdb(request)) { // If wait_for_gdb is enabled, set the timeout to something large. timeout.tv_sec = INT_MAX; } sigset_t signal_set; sigemptyset(&signal_set); sigaddset(&signal_set, SIGCHLD); bool kill_worker = false; bool kill_target = false; bool kill_self = false; int status; siginfo_t siginfo; int signal = TEMP_FAILURE_RETRY(sigtimedwait(&signal_set, &siginfo, &timeout)); if (signal == SIGCHLD) { pid_t rc = waitpid(-1, &status, WNOHANG | WUNTRACED); if (rc != child_pid) { ALOGE("debuggerd: waitpid returned unexpected pid (%d), committing murder-suicide", rc); if (WIFEXITED(status)) { ALOGW("debuggerd: pid %d exited with status %d", rc, WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { ALOGW("debuggerd: pid %d received signal %d", rc, WTERMSIG(status)); } else if (WIFSTOPPED(status)) { ALOGW("debuggerd: pid %d stopped by signal %d", rc, WSTOPSIG(status)); } else if (WIFCONTINUED(status)) { ALOGW("debuggerd: pid %d continued", rc); } kill_worker = true; kill_target = true; kill_self = true; } else if (WIFSIGNALED(status)) { ALOGE("debuggerd: worker process %d terminated due to signal %d", child_pid, WTERMSIG(status)); kill_worker = false; kill_target = true; } else if (WIFSTOPPED(status)) { ALOGE("debuggerd: worker process %d stopped due to signal %d", child_pid, WSTOPSIG(status)); kill_worker = true; kill_target = true; } } else { ALOGE("debuggerd: worker process %d timed out", child_pid); kill_worker = true; kill_target = true; } if (kill_worker) { // Something bad happened, kill the worker. if (kill(child_pid, SIGKILL) != 0) { ALOGE("debuggerd: failed to kill worker process %d: %s", child_pid, strerror(errno)); } else { waitpid(child_pid, &status, 0); } } int exit_signal = SIGCONT; if (kill_target && request.action == DEBUGGER_ACTION_CRASH) { ALOGE("debuggerd: killing target %d", request.pid); exit_signal = SIGKILL; } else { ALOGW("debuggerd: resuming target %d", request.pid); } if (kill(request.pid, exit_signal) != 0) { ALOGE("debuggerd: failed to send signal %d to target: %s", exit_signal, strerror(errno)); } if (kill_self) { stop_signal_sender(); _exit(1); } } static void handle_request(int fd) { ALOGV("handle_request(%d)\n", fd); android::base::unique_fd closer(fd); debugger_request_t request; memset(&request, 0, sizeof(request)); int status = read_request(fd, &request); if (status != 0) { return; } ALOGW("debuggerd: handling request: pid=%d uid=%d gid=%d tid=%d\n", request.pid, request.uid, request.gid, request.tid); #if defined(__LP64__) // On 64 bit systems, requests to dump 32 bit and 64 bit tids come // to the 64 bit debuggerd. If the process is a 32 bit executable, // redirect the request to the 32 bit debuggerd. if (is32bit(request.tid)) { // Only dump backtrace and dump tombstone requests can be redirected. if (request.action == DEBUGGER_ACTION_DUMP_BACKTRACE || request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) { redirect_to_32(fd, &request); } else { ALOGE("debuggerd: Not allowed to redirect action %d to 32 bit debuggerd\n", request.action); } return; } #endif // Fork a child to handle the rest of the request. pid_t fork_pid = fork(); if (fork_pid == -1) { ALOGE("debuggerd: failed to fork: %s\n", strerror(errno)); } else if (fork_pid == 0) { worker_process(fd, request); } else { monitor_worker_process(fork_pid, request); } }
int network_be_read(se_ptr_t *ptr) { epdata_t *epd = ptr->data; if(!epd) { return 0; } int n = 0; update_timeout(epd->timeout_ptr, STEP_READ_TIMEOUT); if(epd->headers == NULL) { epd->headers = malloc(4096); epd->buf_size = 4096; } else if(epd->data_len == epd->buf_size) { { char *_t = (char *) realloc(epd->headers, epd->buf_size + 4096); if(_t != NULL) { epd->headers = _t; } else { epd->iov[0].iov_base = NULL; epd->iov[0].iov_len = 0; epd->iov[1].iov_base = NULL; epd->iov[1].iov_len = 0; network_send_error(epd, 503, "memory error!"); return 0; } epd->buf_size += 4096; } } while((n = recv(epd->fd, epd->headers + epd->data_len, epd->buf_size - epd->data_len, 0)) >= 0) { if(n == 0) { close_client(epd); epd = NULL; break; } if(epd->data_len + n >= epd->buf_size) { char *_t = (char *) realloc(epd->headers, epd->buf_size + 4096); if(_t != NULL) { epd->headers = _t; } else { epd->iov[0].iov_base = NULL; epd->iov[0].iov_len = 0; epd->iov[1].iov_base = NULL; epd->iov[1].iov_len = 0; network_send_error(epd, 503, "memory error!"); return 0; } epd->buf_size += 4096; } if(epd->status != STEP_READ) { serv_status.reading_counts++; epd->status = STEP_READ; epd->data_len = n; } else { epd->data_len += n; } if(epd->_header_length < 1 && epd->data_len >= 4 && epd->headers) { int _get_content_length = 0; if(epd->headers[epd->data_len - 1] == '\n' && (epd->headers[epd->data_len - 2] == '\n' || (epd->headers[epd->data_len - 4] == '\r' && epd->headers[epd->data_len - 2] == '\r'))) { epd->_header_length = epd->data_len; } else { _get_content_length = 1; unsigned char *fp2 = (unsigned char *)stristr(epd->headers, "\r\n\r\n", epd->data_len); if(fp2) { epd->_header_length = (fp2 - epd->headers) + 4; } else { fp2 = (unsigned char *)stristr(epd->headers, "\n\n", epd->data_len); if(fp2) { epd->_header_length = (fp2 - epd->headers) + 2; } } } /// check request header length if(max_request_header > 0 && (epd->_header_length > max_request_header || (epd->_header_length < 1 && epd->data_len > max_request_header))) { network_send_error(epd, 413, "Request Header Too Large"); return 0; } if(epd->_header_length > 0 && epd->content_length < 0) { /// not POST or PUT request if(_get_content_length == 0 && epd->headers[0] != 'P' && epd->headers[0] != 'p') { epd->content_length = 0; } else { int flag = 0; unsigned char *fp = (unsigned char *)stristr(epd->headers, "\ncontent-length:", epd->data_len); if(fp) { int fp_at = fp - epd->headers + 16; int i = 0, _oc; for(i = fp_at; i < epd->data_len; i++) { if(epd->headers[i] == '\r' || epd->headers[i] == '\n') { flag = 1; fp = epd->headers + fp_at; _oc = epd->headers[i]; epd->headers[i] = '\0'; break; } } if(flag) { epd->content_length = atoi(fp); epd->headers[i] = _oc; /// check request body length if(max_request_body > 0 && epd->content_length > max_request_body) { network_send_error(epd, 413, "Request Entity Too Large"); return 0; } } if(stristr(epd->headers + (epd->_header_length - 60), "100-continue", epd->_header_length)) { network_raw_send(epd->fd, "HTTP/1.1 100 Continue\r\n\r\n", 25); } } } } if(epd->_header_length > 0 && epd->_header_length < epd->data_len && epd->content_length < 1) { epd->iov[0].iov_base = NULL; epd->iov[0].iov_len = 0; epd->iov[1].iov_base = NULL; epd->iov[1].iov_len = 0; network_send_error(epd, 411, ""); break; } } if(epd->_header_length > 0 && (epd->content_length < 1 || epd->content_length <= epd->data_len - epd->_header_length)) { /// start job epd->header_len = epd->_header_length; epd->headers[epd->data_len] = '\0'; epd->header_len -= 1; epd->headers[epd->header_len] = '\0'; if(epd->header_len + 1 < epd->data_len) { epd->contents = epd->headers + epd->header_len + 1; } else { epd->content_length = 0; } if(USE_KEEPALIVE == 1 && (epd->keepalive == 1 || (stristr(epd->headers, "keep-alive", epd->header_len)))) { epd->keepalive = 1; } epd->response_header_length = 0; epd->iov_buf_count = 0; epd->response_content_length = 0; epd->response_sendfile_fd = -1; /// output server status !!!!!!!!!! { int i, len; char *uri = NULL; uri = epd->headers; for(i = 0; i < epd->header_len; i++) if(uri[i] == ' ') { break; } for(; i < epd->header_len; i++) if(uri[i] != ' ') { break; } uri = epd->headers + i; len = strlen(uri); for(i = 0; i < len; i++) { if(uri[i] == '\r' || uri[i] == '\n' || uri[i] == ' ') { break; } } if(i > 11 && strncmp("/serv-status", uri, i) == 0) { epd->process_timeout = 0; epd->iov[0].iov_base = NULL; epd->iov[0].iov_len = 0; epd->iov[1].iov_base = NULL; epd->iov[1].iov_len = 0; network_send_status(epd); serv_status.reading_counts--; break; } } /// end. se_be_pri(epd->se_ptr, NULL); // be wait if(epd->status == STEP_READ) { serv_status.reading_counts--; epd->status = STEP_PROCESS; serv_status.sec_process_counts[(now) % 5]++; serv_status.process_counts++; epd->method = NULL; epd->uri = NULL; epd->host = NULL; epd->query = NULL; epd->http_ver = NULL; epd->referer = NULL; epd->user_agent = NULL; if(worker_process(epd, 0) != 0) { close_client(epd); epd = NULL; } } break; } } if(epd && n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { LOGF(ERR, "error fd %d (%d) %s", epd->fd, errno, strerror(errno)); close_client(epd); epd = NULL; return 0; } return 1; }
/** * Start the CDiameterPeer operations. * It forks all the processes required. * @param blocking - if this is set, use the calling processes for the timer and never * return; else fork a new one for the timer and return * @returns 1 on success, 0 on error, never if blocking */ int diameter_peer_start(int blocking) { int pid; int k=0; /* Fork the acceptor process */ #ifdef CDP_FOR_SER pid = fork_process(1000,"cdp_acceptor",1); #else pid = fork(); #endif if (pid==-1){ LOG(L_CRIT,"ERROR:init_diameter_peer(): Error on fork() for acceptor!\n"); return 0; } if (pid==0) { acceptor_process(config); LOG(L_CRIT,"ERROR:init_diameter_peer(): acceptor_process finished without exit!\n"); exit(-1); }else{ dp_add_pid(pid); } /* fork workers */ for(k=0;k<config->workers;k++){ #ifdef CDP_FOR_SER pid = fork_process(1001+k,"cdp_worker",1); #else pid = fork(); #endif if (pid==-1){ LOG(L_CRIT,"ERROR:init_diameter_peer(): Error on fork() for worker!\n"); return 0; } if (pid==0) { srandom(time(0)*k); #ifdef CDP_FOR_SER snprintf(pt[process_no].desc, MAX_PT_DESC, "cdp worker child=%d", k ); #endif worker_process(k); LOG(L_CRIT,"ERROR:init_diameter_peer(): worker_process finished without exit!\n"); exit(-1); }else{ dp_add_pid(pid); } } /* fork/become timer */ if (blocking) { dp_add_pid(getpid()); timer_process(1); } else{ #ifdef CDP_FOR_SER pid = fork_process(1001,"cdp_timer",1); #else pid = fork(); #endif if (pid==-1){ LOG(L_CRIT,"ERROR:init_diameter_peer(): Error on fork() for timer!\n"); return 0; } if (pid==0) { timer_process(0); LOG(L_CRIT,"ERROR:init_diameter_peer(): timer_process finished without exit!\n"); exit(-1); }else{ dp_add_pid(pid); } } return 1; }