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();
}
Beispiel #2
0
   //  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;
          }
      }
   }
Beispiel #3
0
/**
 * 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);
  }
}
Beispiel #5
0
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;
}