コード例 #1
0
ファイル: gsstunnel.c プロジェクト: frenche/gss-tunnel
static int tunnel(struct gt_service *svc, int fd, struct sockaddr *cliaddr)
{
    AUTOCLEAN(char *tmbuf, autofreestr) = NULL;
    AUTOCLEAN(struct addrinfo *addr, autofreeaddrinfo) = NULL;
    AUTOCLEAN(int sd, autofreesocket) = -1;
    AUTOCLEAN(int efd, autofreesocket) = -1;
    AUTOCLEAN(gss_name_t name, autofreegssname) = GSS_C_NO_NAME;
    AUTOCLEAN(gss_name_t srcname, autofreegssname) = GSS_C_NO_NAME;
    AUTOCLEAN(gss_cred_id_t cred, autofreegsscred) = GSS_C_NO_CREDENTIAL;
    AUTOCLEAN(gss_ctx_id_t ctx, autofreegssctx) = GSS_C_NO_CONTEXT;
    AUTOCLEAN(gss_buffer_desc output, autofreegssbuf) = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc input = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc  namebuf;
    OM_uint32 maj, min;
    OM_uint32 ignore;
    struct epoll_event events[MAX_EVENTS];
    size_t tmlen;
    int pfd; /* plain text fd */
    int cfd; /* cipher text fd */
    int ret;

    /* We allocate a 1 MiB buffer for messages, that's also the maximum msg
     * size */
    tmbuf = malloc(MAX_MSG_SIZE);
    if (!tmbuf) return ENOMEM;

    if (svc->exec) {
        fprintf(stderr, "[%s] EXEC option not supported yet, sorry!\n",
                        svc->name);
        return ENOTSUP;
    }

    ret = string_to_addrinfo(svc->connect, &addr);
    if (ret) return ret;

    errno = 0;
    sd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
    if (sd == -1) return errno;

    ret = connect(sd, addr->ai_addr, addr->ai_addrlen);
    if (ret != 0) {
        ret = errno;
        fprintf(stderr, "[%s] Failed to connect to server '%s': %s\n",
                        svc->name, svc->connect, strerror(ret));
        return ret;
    }

    if (svc->target_name) {
        namebuf.length = strlen(svc->target_name);
        namebuf.value = svc->target_name;
        maj = gss_import_name(&min, &namebuf,
                              GSS_C_NT_HOSTBASED_SERVICE, &name);
        if (maj != GSS_S_COMPLETE) {
            fprintf(stderr, "[%s] Failed to import name: '%s' (%d/%d)\n",
                            svc->name, svc->target_name,
                            (int)maj, (int)min);
            return EINVAL;
        }
    }

    if (svc->client) {
        pfd = fd;
        cfd = sd;

        do {
            maj = gss_init_sec_context(&min, cred, &ctx, name, GSS_C_NO_OID,
                                       GSS_C_MUTUAL_FLAG
                                        | GSS_C_REPLAY_FLAG
                                        | GSS_C_SEQUENCE_FLAG
                                        | GSS_C_CONF_FLAG
                                        | GSS_C_INTEG_FLAG, 0,
                                       GSS_C_NO_CHANNEL_BINDINGS,
                                       &input, NULL, &output, NULL, NULL);

            if (maj != GSS_S_COMPLETE && maj != GSS_S_CONTINUE_NEEDED) {
                gt_gss_error(svc->name, GSS_C_NO_OID, maj, min);
                return EBADE;
            }

            if (output.length > MAX_MSG_SIZE) return ENOSPC;
            if (output.length > 0) {
                memcpy(tmbuf, output.value, output.length);
                tmlen = output.length;
                (void)gss_release_buffer(&ignore, &output);

                ret = send_msg(cfd, tmbuf, tmlen, true);
                if (ret) return ret;
            }

            if (maj == GSS_S_CONTINUE_NEEDED) {
                tmlen = MAX_MSG_SIZE;
                ret = recv_msg(cfd, tmbuf, &tmlen, true);
                if (ret) return ret;

                input.value = tmbuf;
                input.length = tmlen;
            }

        } while (maj == GSS_S_CONTINUE_NEEDED);

    } else {
        pfd = sd;
        cfd = fd;

        if (name != GSS_C_NO_NAME) {
            maj = gss_acquire_cred(&min, name, GSS_C_INDEFINITE,
                                   GSS_C_NO_OID_SET, GSS_C_ACCEPT,
                                   &cred, NULL, NULL);
            if (maj != GSS_S_COMPLETE) {
                fprintf(stderr,
                        "[%s] Failed to acquire creds for '%s' (%d/%d)\n",
                        svc->name, svc->target_name?svc->target_name:"",
                        (int)maj, (int)min);
                return EIO;
            }
        }

        do {
            tmlen = MAX_MSG_SIZE;
            ret = recv_msg(cfd, tmbuf, &tmlen, true);
            if (ret) return ret;

            input.value = tmbuf;
            input.length = tmlen;

            maj = gss_accept_sec_context(&min, &ctx, cred, &input,
                                         GSS_C_NO_CHANNEL_BINDINGS, &srcname,
                                         NULL, &output, NULL, NULL, NULL);

            if (maj != GSS_S_COMPLETE && maj != GSS_S_CONTINUE_NEEDED) {
                gt_gss_error(svc->name, GSS_C_NO_OID, maj, min);
                return EBADE;
            }

            if (output.length > MAX_MSG_SIZE) return ENOSPC;
            if (output.length > 0) {
                memcpy(tmbuf, output.value, output.length);
                tmlen = output.length;
                (void)gss_release_buffer(&ignore, &output);

                ret = send_msg(cfd, tmbuf, tmlen, true);
                if (ret) return ret;
            }

        } while (maj == GSS_S_CONTINUE_NEEDED);
    }

    /* negotiation completed, now handle traffic */

    ret = init_epoll(cfd, pfd, &efd);
    if (ret) return ret;

    while (efd != -1) {
        struct epoll_event *ev;
        int n;
        n = epoll_wait(efd, events, MAX_EVENTS, -1);
        if (n == -1) {
            ret = errno;
            if (ret == EINTR) continue;
            return ret;
        }
        for (int i = 0; i < n; i++) {
            ev = &events[i];
            if (ev->events & (EPOLLERR|EPOLLHUP)) {
                /* one of the peers gave up */
                return ENOLINK;
            }

            /* RECEIVE */

            tmlen = MAX_MSG_SIZE;
            ret = recv_msg(ev->data.fd, tmbuf, &tmlen, (ev->data.fd == cfd));
            if (ret) return ret;

            if (ev->data.fd == cfd) {
                /* sender encrypts */
                input.value = tmbuf;
                input.length = tmlen;
                maj = gss_unwrap(&min, ctx, &input, &output, NULL, NULL);
                if (maj != GSS_S_COMPLETE) {
                    gt_gss_error(svc->name, GSS_C_NO_OID, maj, min);
                    return EIO;
                }
                if (output.length > MAX_MSG_SIZE) return ENOSPC;
                memcpy(tmbuf, output.value, output.length);
                tmlen = output.length;
                (void)gss_release_buffer(&ignore, &output);
            }

            /* RESEND */
            if (ev->data.fd == pfd) {
                /* receiver encrypts */
                input.value = tmbuf;
                input.length = tmlen;
                maj = gss_wrap(&min, ctx, 1, 0, &input, NULL, &output);
                if (maj != GSS_S_COMPLETE) {
                    gt_gss_error(svc->name, GSS_C_NO_OID, maj, min);
                    return EIO;
                }
                if (output.length > MAX_MSG_SIZE) return ENOSPC;
                memcpy(tmbuf, output.value, output.length);
                tmlen = output.length;
                (void)gss_release_buffer(&ignore, &output);
            }

            /* send to the other fd, add header only if we encrypted */
            ret = send_msg((ev->data.fd == pfd)?cfd:pfd,
                           tmbuf, tmlen, (ev->data.fd == pfd));
            if (ret) return ret;
        }
    }

    return 0;
}
コード例 #2
0
ファイル: server_hello.c プロジェクト: wangyq/mynet
int main(int argc, const char* argv[])
{
	struct sockaddr_in sAddr;
	struct epoll_event ev;
	struct epoll_event evlist[MAX_EVENTS];
	int ready, i;

	int listensock = 0;

	int result=0, val = 0;

	//init epoll
	if( init_epoll() ){
		exit(-1);
	}
	printf("epoll instance created success! \n");

	//create socket
	if ( -1 == (listensock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)))  {
		perror("create socket error!");
		exit(1);
	}
	
	val = 1;
	result = setsockopt(listensock, SOL_SOCKET, SO_REUSEADDR, &val,sizeof(val));
	if( result < 0 ){
		perror("set socket option error!");
		exit(1);
	}
	
	sAddr.sin_family = AF_INET;
	sAddr.sin_port = htons(g_server_port);
	sAddr.sin_addr.s_addr = INADDR_ANY;

	//now bind the address and port
	result = bind(listensock, (struct sockaddr*)&sAddr, sizeof(sAddr));
	if ( result < 0 ) {
		perror("bind error!");
		exit(1);
	}

	//print server ready info
	printf("Server get ready at port : %d \n", g_server_port);

	result = listen(listensock, 5);
	if( result < 0 ) {
		perror("listen error!");
		exit(1);
	}
	
	setnonblocking(listensock); //set nonblocking

	ev.events = EPOLLIN|EPOLLET; //edge-trigged
        ev.data.fd = listensock;
        if( epoll_ctl(epfd, EPOLL_CTL_ADD, listensock, &ev) == -1 ){
		perror("epoll_ctl add error!");
	        exit(-1);
	}

	//now we will epoll_wait the event
	//
	while(1) {
		//Fetch up to MAX_EVENTS items from the ready list
                //printf("About to epoll_wait() \n");
                ready = epoll_wait(epfd, evlist, MAX_EVENTS, -1);
		if( ready == -1 ){
			if( errno == EINTR ){
				printf("Get an intr signal!\n");
				continue;
			} else {
				perror("epoll_wait error!");
				exit(-1);
			}

		}

		for(i=0;i<ready;i++){
		/*	printf("fd=%d, events: %s%s%s%s \n",evlist[i].data.fd,
				(evlist[i].events & EPOLLIN)? "EPOLLIN ":"",
				(evlist[i].events & EPOLLOUT)? "EPOLLOUT ":"",
				(evlist[i].events & EPOLLHUP)? "EPOLLHUP ":"",
				(evlist[i].events & EPOLLERR)? "EPOLLERR ":"");
		*/
			//deal with events
			if( evlist[i].events & EPOLLIN ){
				if( evlist[i].data.fd == listensock ){
					handle_accept(evlist[i].data.fd);
				} else {
					handle_read(evlist[i].data.fd);
				}

			}
			else if( evlist[i].events & EPOLLOUT){
				handle_write(evlist[i].data.fd);
			}
			else if( evlist[i].events &(EPOLLHUP|EPOLLERR)){
				printf("Client on descriptor #%d disconnetcted. \n", evlist[i].data.fd);

				if( close( evlist[i].data.fd ) == -1 ){
					perror("close fd error!");
					exit(-1);
				}
			}
		}//end of for ready
	}//end of while

	return 0;

}
コード例 #3
0
void server_init (engine_t *E, server_functions_t *F, conn_type_t *listen_connection_type, void *listen_connection_extra) {
  if (F != NULL) {
    if (F->sighup) {
      sf.sighup = F->sighup;
    }
    if (F->sigusr1) {
      sf.sigusr1 = F->sigusr1;
    }
    if (F->save_index) {
      sf.save_index = F->save_index;
    }
    if (F->cron) {
      sf.cron = F->cron;
    }
  }
  
  init_epoll ();
  init_netbuffers ();
  if (udp_enabled) {
    init_msg_buffers (0);
  }
  
  if (daemonize) {
    setsid ();
    reopen_logs ();
  }

  if (!E->sfd) {
    E->sfd = server_socket (port, E->settings_addr, backlog, 0);
  }

  if (E->sfd < 0) {
    kprintf ("cannot open server socket at port %d: %m\n", port);
    exit (1);
  }

  if (change_user (username) < 0) {
    kprintf ("fatal: cannot change user to %s\n", username ? username : "******");
    exit (1);
  }

  if (binlogname && !binlog_disabled) {
    assert (append_to_binlog (Binlog) == log_readto_pos);
  }

  init_listening_connection (E->sfd, listen_connection_type, listen_connection_extra);
  if (udp_enabled) {
    add_udp_socket (port, 0);
  }
  
  if (binlog_disabled && binlog_fd >= 0) {
    epoll_pre_event = read_new_events;
  }

  struct sigaction sa;
  memset (&sa, 0, sizeof (sa));
  sa.sa_handler = sigint_handler;
  sigemptyset (&sa.sa_mask);
  sigaddset (&sa.sa_mask, SIGTERM); 
  sigaction (SIGINT, &sa, NULL);
  
  sa.sa_handler = sigterm_handler;
  sigemptyset (&sa.sa_mask);
  sigaddset (&sa.sa_mask, SIGINT);
  sigaction (SIGTERM, &sa, NULL);
  
  sa.sa_handler = SIG_IGN;
  sigaction (SIGPIPE, &sa, NULL);
  sigaction (SIGPOLL, &sa, NULL);
  
  if (daemonize) {
    sa.sa_handler = sighup_handler;
    sigemptyset (&sa.sa_mask);
    sigaction (SIGHUP, &sa, NULL);
  }
}
コード例 #4
0
int lib_main_loop(struct core_control *ctl_params)
{
	int sockfd[2];
	pid_t new_proc_pid;
	struct com_msg_open_session *recv_open_msg = NULL;
	struct com_msg_ta_created new_ta_info;
	int ret, event_count, i;
	sigset_t sig_empty_set, sig_block_set;
	struct epoll_event cur_events[MAX_CURR_EVENTS];
	struct ta_loop_arg ta_loop_args = {0};
	int shm_fds[4];
	int shm_fd_count;

	memset(&new_ta_info, 0, sizeof(struct com_msg_ta_created));

	child_stack = calloc(1, CHILD_STACK_SIZE);
	if (!child_stack) {
		OT_LOG(LOG_ERR, "Sigempty set failed");
		exit(EXIT_FAILURE);
	}

	if (sigemptyset(&sig_empty_set)) {
		OT_LOG(LOG_ERR, "Sigempty set failed");
		exit(EXIT_FAILURE);
	}

	if (sigfillset(&sig_block_set)) {
		OT_LOG(LOG_ERR, "Sigempty set failed");
		exit(EXIT_FAILURE);
	}

	if (init_epoll()) {
		OT_LOG(LOG_ERR, "Epoll init failure");
		exit(EXIT_FAILURE);
	}

	/* listen to inbound connections from the manager */
	if (epoll_reg_fd(ctl_params->comm_sock_fd, EPOLLIN)) {
		OT_LOG(LOG_ERR, "Failed reg manager socket");
		exit(EXIT_FAILURE);
	}

	if (epoll_reg_fd(ctl_params->self_pipe_fd, EPOLLIN)) {
		OT_LOG(LOG_ERR, "Failed reg self pipe socket");
		exit(EXIT_FAILURE);
	}

#ifdef GRACEFUL_TERMINATION
	/* Cleanup function if process need to be cleaned gracefully */
	ctl_params->fn_cleanup_launher = cleanup_launcher;
#endif

	OT_LOG(LOG_ERR, "Entering the launcher mainloop");

	for (;;) {
		if (pthread_sigmask(SIG_SETMASK, &sig_empty_set, NULL)) {
			OT_LOG(LOG_ERR, "Problem with signal mask setting");
			continue;
		}

		event_count = wrap_epoll_wait(cur_events, MAX_CURR_EVENTS);
		if (event_count == -1) {
			if (errno == EINTR) {
				check_signal_status(ctl_params);
				continue;
			}

			/* Log error and hope the error clears itself */
			OT_LOG(LOG_ERR, "Failed return from epoll_wait");
			continue;
		}

		if (pthread_sigmask(SIG_SETMASK, &sig_block_set, NULL)) {
			OT_LOG(LOG_ERR, "Problem with signal mask setting");
			continue;
		}

		/* Note: All signals are blocked */

		for (i = 0; i < event_count; i++) {

			if (cur_events[i].data.fd == ctl_params->self_pipe_fd) {

				if (cur_events[i].events & EPOLLERR) {
					OT_LOG(LOG_ERR, "Something wrong with self pipe");
					exit(EXIT_FAILURE);
				}

				check_signal_status(ctl_params);
				continue;
			}

			/* Launcher is monitoring only two socket and second one is manager fd */
			if (cur_events[i].events & EPOLLERR || cur_events[i].events & EPOLLHUP) {
				OT_LOG(LOG_ERR, "Manager socket error");
				exit(EXIT_FAILURE);
			}

			ret = com_recv_msg(ctl_params->comm_sock_fd, (void **)&recv_open_msg, NULL,
					   shm_fds, &shm_fd_count);

			if (ret == -1) {
				free(recv_open_msg);
				/* TODO: Figur out why -1, but for now lets
				 *  hope the error clears itself*/
				continue;

			} else if (ret > 0) {
				/* ignore message */
				free(recv_open_msg);
				continue;
			}

			recv_open_msg->msg_hdr.shareable_fd_count = 0;
			if (shm_fd_count > 0 && shm_fd_count <= 4) {
				recv_open_msg->msg_hdr.shareable_fd_count = shm_fd_count;
				memcpy(recv_open_msg->msg_hdr.shareable_fd, shm_fds,
				       sizeof(int)*shm_fd_count);
			}

			/* Extrac info from message */
			if (recv_open_msg->msg_hdr.msg_name != COM_MSG_NAME_OPEN_SESSION ||
			    recv_open_msg->msg_hdr.msg_type != COM_TYPE_QUERY) {
				OT_LOG(LOG_ERR, "Invalid message");
				goto close_fd;
			}

			/* Received correct mesage from manager. Prepare response message.
			 * PID is filled later */
			new_ta_info.msg_hdr.msg_name = COM_MSG_NAME_CREATED_TA;
			new_ta_info.msg_hdr.msg_type = COM_TYPE_RESPONSE;
			new_ta_info.msg_hdr.sess_id = recv_open_msg->msg_hdr.sess_id;

			/* create a socket pair so the manager and TA can communicate */
			if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) == -1) {
				OT_LOG(LOG_ERR, "failed to create a socket pair");
				send_err_msg_to_manager(ctl_params->comm_sock_fd, &new_ta_info);
				goto close_fd;
			}

			/*
			 * Clone now to create the TA subprocess
			 */

			/* Fill ta loop arguments */
			ta_loop_args.com_sock = sockfd[1];
			ta_loop_args.ctl_params = ctl_params;
			ta_loop_args.recv_open_msg = recv_open_msg;

			new_proc_pid = clone(ta_process_loop, child_stack + CHILD_STACK_SIZE,
					     SIGCHLD | CLONE_PARENT, &ta_loop_args);

			if (new_proc_pid == -1) {
				send_err_msg_to_manager(ctl_params->comm_sock_fd, &new_ta_info);
				goto close_pair;

			}

			new_ta_info.pid = new_proc_pid;

			ret = com_send_msg(ctl_params->comm_sock_fd, &new_ta_info,
					   sizeof(struct com_msg_ta_created), NULL, 0);

			if (ret == sizeof(struct com_msg_ta_created)) {

				if (send_fd(ctl_params->comm_sock_fd, &sockfd[0], 1, NULL, 0)
				    == -1) {
					OT_LOG(LOG_ERR, "Failed to send TA sock");
					kill(new_proc_pid, SIGKILL);
					/* TODO: Check what is causing error, but for now
						 * lets hope the error clears itself*/
				}

			} else {
				OT_LOG(LOG_ERR, "Failed to send response msg");
				kill(new_proc_pid, SIGKILL);
				/* TODO: Check what is causing error, but for now lets
					 *  hope the error clears itself*/
			}
close_pair:
			/* parent process will stay as the launcher */
			close(sockfd[0]);
			close(sockfd[1]);
close_fd:
			/* close possibly forwarded file descriptors */
			while (recv_open_msg->msg_hdr.shareable_fd_count > 0) {
				recv_open_msg->msg_hdr.shareable_fd_count--;
				close(recv_open_msg->msg_hdr.shareable_fd
						[recv_open_msg->msg_hdr.shareable_fd_count]);
			}
			free(recv_open_msg);

		}
	}
}
コード例 #5
0
ファイル: spike.c プロジェクト: softsprocket/sprockets
int run_watchdog (int pids[], int num_pids, char* port, char* email_address, char* mail_server) {
	signal (SIGPIPE, SIG_IGN);

	pid_t pid = fork();
	if (pid < 0) {
		PERR ("fork");
		exit (EXIT_FAILURE);
	}

	if (pid == 0) {

		umask(0);

		openlog ("SPROCKETS_WATCHDOG", LOG_CONS, LOG_DAEMON);

		pid_t sid = setsid();
		if (sid < 0) {
			PMSG ("Sprockets watchdog failed to setsid. Exiting now.\n");
			exit (EXIT_FAILURE);
		}

		if ((chdir("/")) < 0) {
			PMSG ("Sprockets watchdog failed to chdir. Exiting now.\n");
			exit (EXIT_FAILURE);
		}

		int sigs[] = { SIGINT, SIGQUIT, SIGHUP, SIGCHLD };
		int sfd = setup_sighandlers (sigs, 3);
		if (sfd == 0) {
			PMSG ("Sprockets watchdog failed to set sighandlers. Exiting now.\n");
			exit (EXIT_FAILURE);
		}

		int epfd = init_epoll (sfd);
		if (epfd == 0) {
			PMSG ("Sprockets watchdog failed to initialize epoll. Exiting now.\n");
			exit (EXIT_FAILURE);
		}

		int server_fd = NULL;
		if (port != NULL) {
			server_fd = sprocket_tcp_server (port, NULL);
			if (server_fd == 0) {
				PMSG ("Couldn't start watchdog server\n");
			       	exit (EXIT_FAILURE);	
			}

			if (add_fd_to_epoll (epfd, server_fd) == 0) {
				PERR ("Couldn't add watchdog server to epoll\n");
			       	exit (EXIT_FAILURE);	
			}
		}

		close(STDIN_FILENO);
		close(STDOUT_FILENO);
		close(STDERR_FILENO);

		syslog (LOG_NOTICE, "Sprockets watchdog successfully started\n");



				
		int paused_for_signal = 0;
		char* stats = NULL;
		auto_string* stat_buffer = NULL;
		pthread_mutex_t stats_mutex;
		pthread_mutex_init(&stats_mutex, NULL);

		auto_array* thread_array = auto_array_create (10);
		if (thread_array == NULL) {
			syslog (LOG_CRIT, "Unable to create thread array - out of memory");
			exit (EXIT_FAILURE);
		}


		while (1) {
			struct epoll_event events[MAX_EPOLL_EVENTS];
			int num_fd = epoll_wait(epfd, events, MAX_EPOLL_EVENTS, 500);

			if (num_fd == -1) {
				if (errno == EINTR) {
					syslog (LOG_NOTICE, "epoll_wait interrupted. Continuing\n");
					continue;
				}

				syslog (LOG_CRIT, "epoll_wait error: %s\n", strerror (errno)); 
				exit (EXIT_FAILURE);
			}

			if (num_fd != 0) { // no fds  timeout occurred
				for (int i = 0; i < num_fd; ++i) {
					if (events[i].data.fd == sfd) { // caught signal
						struct signalfd_siginfo fdsi;

 						int s = read (sfd, &fdsi, sizeof fdsi);
               					if (s != sizeof fdsi) {
							syslog (LOG_CRIT, "Read signal error: %s\n", strerror (errno));
							continue;
						}

						switch (fdsi.ssi_signo) {
							case SIGINT:
								syslog (LOG_NOTICE, "Caught SIGINT - pausing\n");
								paused_for_signal = 1;
								break;	
							case SIGQUIT:
								syslog (LOG_NOTICE, "Caught SIGQUIT - exiting\n");
								for (int ii = 0; ii < num_pids; ++ii) {
									if (pids[ii] != 0) { 
										kill (pids[ii], SIGTERM);
									}
								}

								for (int ii = 0; ii < thread_array->count; ++ii) {
									watchdog_thread* wt = auto_array_get (thread_array, ii);
									char ex[2] = "EX";
									write (wt->pipe_write, ex, 2);

								       	auto_array_delete (thread_array, free);	
								}

								exit (EXIT_SUCCESS);
							case SIGHUP:
								syslog (LOG_NOTICE, "Caught SIGHUP\n");
								paused_for_signal = 0;
								break;
							case SIGCHLD:
								syslog (LOG_NOTICE, "Caught SIGCHLD\n");
								break;
							default:
								syslog (LOG_NOTICE, "Caught unknown signal\n");
								break;
						}
	       				} else if (events[i].data.fd == server_fd) {
						struct sockaddr_in addr;
						socklen_t addr_sz = 0;
						int client_fd = accept (server_fd, (struct sockaddr*) &addr, &addr_sz);
						
						watchdog_thread_args* thread_args = malloc (sizeof thread_args);
						if (thread_args == NULL) {
							syslog (LOG_CRIT, "Malloc returned NULL: %s", strerror (errno));
							exit (EXIT_FAILURE);
						}

						watchdog_thread* dog_thread = malloc (sizeof dog_thread);
						if (dog_thread == NULL) {
							syslog (LOG_CRIT, "Malloc returned NULL: %s", strerror (errno));
							exit (EXIT_FAILURE);
						}

						int pipefd[2];
						if (pipe (pipefd) < 0) {
							syslog (LOG_CRIT, "watchdog pipe error: %s", strerror (errno));
							continue;
						}
						
						dog_thread->pipe_write = pipefd[1];

						thread_args->pipe_read = pipefd[0];
						thread_args->client_fd = client_fd;
						thread_args->stats = &stats;
						thread_args->stats_mutex = &stats_mutex;

						pthread_attr_t attr;
						int trv = 0;
						if ((trv = pthread_attr_init (&attr)) != 0) {
							syslog (LOG_CRIT, "pthread_attr_init: %s\n", strerror (trv));
						       	continue;	
						}

						if ((trv = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) != 0) {
							syslog (LOG_CRIT, "pthread_attr_setdetachstate: %s\n", strerror (trv));
						       	continue;	
						}

						if ((trv = pthread_create(&dog_thread->th_id, &attr, client_thread, thread_args)) != 0) {
							syslog (LOG_CRIT, "pthread_create: %s\n", strerror (trv));
						       	continue;	
						}

						auto_array_add (thread_array, dog_thread);

						pthread_attr_destroy(&attr);
					}
				}

			}

			if (paused_for_signal) {
				syslog (LOG_NOTICE, "Paused for signal\n");
			} else {
				auto_array* stat_files = auto_array_create (num_pids);
				for (int i = 0; i < num_pids; ++i) {
					if (pids[i] == 0) {
						continue;
					}

					char pid[32];
					sprintf (pid, "%d", pids[i]);
					
					FILE* p = get_stat_filep (pid);
					if (p == NULL) {
						syslog (LOG_CRIT, "Process with pid %s has halted", pid);
						if (email_address != NULL && mail_server != NULL) {
							char msg[2048];
							snprintf (msg, 2048, email_alert_msg_format, email_address, email_address, pid);
							send_email (mail_server, email_address, email_address, msg);
									
							pids[i] = 0; 
						}

						continue;
					}

					auto_array_add (stat_files, p);
				}

				pthread_mutex_lock(&stats_mutex);

				if (stat_buffer != NULL) {
					auto_string_delete (stat_buffer);
				}
				
				stat_buffer = auto_string_create (1024);
				if (stat_buffer == NULL) {
					syslog (LOG_CRIT, "Unable to create stat buffer - out of memory");
					exit (EXIT_FAILURE);
				}

				for (int i = 0; i < stat_files->count; ++i) {
					FILE* f = auto_array_get (stat_files, i);
					
					char* tmp = get_proc_string (f);
					
					if (tmp != NULL) {
						auto_string_append (stat_buffer, tmp);
						free (tmp);	
					}
				}

				stats = stat_buffer->buf;

				pthread_mutex_unlock (&stats_mutex);

				for (int i = 0; i < thread_array->count; ++i) {
					watchdog_thread* wt = auto_array_get (thread_array, i);
					char ok[2] = "OK";
					if (write (wt->pipe_write, ok, 2) <= 0) {
						syslog (LOG_CRIT, "watchdog write client thread: %s", strerror (errno));
						auto_array_remove (thread_array, i);
						close (wt->pipe_write);
						free (wt);
					}
				}
				
				auto_array_delete (stat_files, close_file);
			}	
		}

	}

	return pid;
}
コード例 #6
0
ファイル: ccatn.c プロジェクト: zuokaihuang/ccatn
int main(int argc, char *argv[])
{
	int c;
	int _argc = 0;
	unsigned long packet_cnt = 0;
	char *_argv[3];
	pid_t pid;
	static User_Linker *usrinfo = NULL;
	while ((c = getopt(argc, argv, "dDv:")) != -1) {
		switch (c) {
		case 'd':
			become_daemon = 0;
			break;
		case 'D':
			execed = 1;
			break;
		default:
			return -1;
		}
	}
	if (become_daemon) {
		if (!execed) {
			if ((pid = vfork()) < 0) {
				fprintf(stderr, "vfork failed\n");
				exit(1);
			} else if (pid != 0) {
				exit(0);	//parent progress exit
			}

			_argv[_argc++] = argv[0];
			_argv[_argc++] = "-D";
			_argv[_argc++] = NULL;
			execv(_argv[0], _argv);
			/* Not reached */
			fprintf(stderr, "Couldn't exec\n");
			_exit(1);

		} else {
			setsid();
			chdir("/");
			umask(0);
			close(0);
			close(1);
			close(2);
		}
		FILE *f = fopen("/var/run/lldpd.pid", "w");
		if (!f) {
			ERROR("can't open /var/run/lldpd.pid");
			return -1;
		}
	}
	INFO("lldp start");
	/*Create epoll*/
	TST(init_epoll()==0,-1);
	/*Initialize client control socket*/
	//TST(ctlserver_socket_init()==0,-1);
	TST(packet_socket_init(SVR_PORT_SD, &packet_handler_1, &usrinfo)==0, -1);
	TST(packet_socket_init(SVR_PORT_FT, &packet_handler_2, &usrinfo)==0, -1);
	epoll_main_loop(usrinfo, &packet_cnt);
	//ctlserver_socket_cleanup();
	packet_socket_cleanup(&packet_handler_1);
	packet_socket_cleanup(&packet_handler_2);
	free_user_link_linker(usrinfo);
	return 0;
}
コード例 #7
0
ファイル: ta_process.c プロジェクト: z08053520/TEE-Emu
int ta_process_loop(int man_sockfd, struct com_msg_open_session *open_msg)
{
	int ret;
	pthread_t ta_logic_thread;
	pthread_attr_t attr;
	struct epoll_event cur_events[MAX_CURR_EVENTS];
	int event_count, i;
	char proc_name[MAX_PR_NAME]; /* For now */
	sigset_t sig_empty_set;

	/* Set new ta process name */
	strncpy(proc_name, open_msg->ta_so_name, MAX_PR_NAME);
	prctl(PR_SET_NAME, (unsigned long)proc_name);
	strncpy(argv0, proc_name, argv0_len);

	/* Load TA to this process */
	ret = load_ta(open_msg->ta_so_name, &interface);
	if (ret != TEE_SUCCESS || interface == NULL) {
		OT_LOG(LOG_ERR, "Failed to load the TA");
		exit(EXIT_FAILURE);
	}

	/* Note: All signal are blocked. Prepare allow set when we can accept signals */
	if (sigemptyset(&sig_empty_set)) {
		OT_LOG(LOG_ERR, "Sigempty set failed: %s", strerror(errno))
		exit(EXIT_FAILURE);
	}

	/* create an eventfd, that will allow the writer to increment the count by 1
	 * for each new event, and the reader to decrement by 1 each time, this will allow the
	 * reader to be notified for each new event, as opposed to being notified just once that
	 * there are "event(s)" pending*/
	event_fd = eventfd(0, EFD_SEMAPHORE);
	if (event_fd == -1) {
		OT_LOG(LOG_ERR, "Failed to initialize eventfd");
		exit(EXIT_FAILURE);
	}

	/* Initializations of TODO and DONE queues*/
	INIT_LIST(&tasks_todo.list);
	INIT_LIST(&tasks_done.list);

	/* Init epoll and register FD/data */
	if (init_epoll())
		exit(EXIT_FAILURE);

	/* listen to inbound connections from the manager */
	if (epoll_reg_fd(man_sockfd, EPOLLIN))
		exit(EXIT_FAILURE);

	/* listen for communications from the TA thread process */
	if (epoll_reg_fd(event_fd, EPOLLIN))
		exit(EXIT_FAILURE);

	/* Signal handling */
	if (epoll_reg_fd(self_pipe_fd, EPOLLIN))
		exit(EXIT_FAILURE);

	/* Init worker thread */
	ret = pthread_attr_init(&attr);
	if (ret) {
		OT_LOG(LOG_ERR, "Failed to create attr for thread: %s", strerror(errno))
		exit(EXIT_FAILURE);
	}

	/* TODO: Should we reserver space for thread stack? */

	ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	if (ret) {
		OT_LOG(LOG_ERR, "Failed set DETACHED: %s", strerror(errno))
		exit(EXIT_FAILURE);
	}

	/* Known error: CA can not determ if TA is launched or not, because framework is calling
	 * create entry point and open session function. Those functions return values is mapped
	 * into one return value. */
	if (interface->create() != TEE_SUCCESS) {
		OT_LOG(LOG_ERR, "TA create entry point failed");
		exit(EXIT_SUCCESS);
	}

	/* Launch worker thread and pass open session message as a parameter */
	ret = pthread_create(&ta_logic_thread, &attr, ta_internal_thread, open_msg);
	if (ret) {
		OT_LOG(LOG_ERR, "Failed launch thread: %s", strerror(errno))
		interface->destroy();
		exit(EXIT_FAILURE);
	}

	pthread_attr_destroy(&attr); /* Not needed any more */

	/* Allow signal delivery */
	if (pthread_sigmask(SIG_SETMASK, &sig_empty_set, NULL)) {
		OT_LOG(LOG_ERR, "failed to allow signals: %s", strerror(errno))
		exit(EXIT_FAILURE);
	}

	/* Enter into the main part of this io_thread */
	for (;;) {
		event_count = wrap_epoll_wait(cur_events, MAX_CURR_EVENTS);
		if (event_count == -1) {
			if (errno == EINTR) {

				continue;
			}

			/* Log error and hope the error clears itself */
			OT_LOG(LOG_ERR, "Failed return from epoll_wait");
			continue;
		}

		for (i = 0; i < event_count; i++) {

			if (cur_events[i].data.fd == man_sockfd) {
				receive_from_manager(&cur_events[i], man_sockfd);

			} else if (cur_events[i].data.fd == event_fd) {
				reply_to_manager(&cur_events[i], man_sockfd);

			} else if (cur_events[i].data.fd == self_pipe_fd) {


			} else {
				OT_LOG(LOG_ERR, "unknown event source");
			}
		}
	}

	/* Should never reach here */
	exit(EXIT_FAILURE);
}
コード例 #8
0
ファイル: io_wait.c プロジェクト: BeIP/opensips
/*!
 * \brief initializes the static vars/arrays
 * \param  h - pointer to the io_wait_h that will be initialized
 * \param  max_fd - maximum allowed fd number
 * \param  poll_method - poll method (0 for automatic best fit)
 */
int init_io_wait(io_wait_h* h, char *name, int max_fd,
								enum poll_types poll_method, int max_prio)
{
	char * poll_err;

	memset(h, 0, sizeof(*h));
	h->name = name;
	h->max_prio = max_prio;
	h->max_fd_no=max_fd;
#ifdef HAVE_EPOLL
	h->epfd=-1;
#endif
#ifdef HAVE_KQUEUE
	h->kq_fd=-1;
#endif
#ifdef HAVE_DEVPOLL
	h->dpoll_fd=-1;
#endif
	poll_err=check_poll_method(poll_method);

	/* set an appropiate poll method */
	if (poll_err || (poll_method==0)){
		poll_method=choose_poll_method();
		if (poll_err){
			LM_ERR("%s, using %s instead\n",
					poll_err, poll_method_str[poll_method]);
		}else{
			LM_INFO("using %s as the io watch method"
					" (auto detected)\n", poll_method_str[poll_method]);
		}
	}

	h->poll_method=poll_method;

	/* common stuff, everybody has fd_hash */
	h->fd_hash=local_malloc(sizeof(*(h->fd_hash))*h->max_fd_no);
	if (h->fd_hash==0){
		LM_CRIT("could not alloc fd hashtable (%ld bytes)\n",
					(long)sizeof(*(h->fd_hash))*h->max_fd_no );
		goto error;
	}
	memset((void*)h->fd_hash, 0, sizeof(*(h->fd_hash))*h->max_fd_no);

	/* init the fd array as needed for priority ordering */
	h->fd_array=local_malloc(sizeof(*(h->fd_array))*h->max_fd_no);
	if (h->fd_array==0){
		LM_CRIT("could not alloc fd array (%ld bytes)\n",
					(long)sizeof(*(h->fd_hash))*h->max_fd_no);
		goto error;
	}
	memset((void*)h->fd_array, 0, sizeof(*(h->fd_array))*h->max_fd_no);
	/* array with indexes in fd_array where the priority changes */
	h->prio_idx=local_malloc(sizeof(*(h->prio_idx))*h->max_prio);
	if (h->prio_idx==0){
		LM_CRIT("could not alloc fd array (%ld bytes)\n",
					(long)sizeof(*(h->prio_idx))*h->max_prio);
		goto error;
	}
	memset((void*)h->prio_idx, 0, sizeof(*(h->prio_idx))*h->max_prio);

	switch(poll_method){
		case POLL_POLL:
			break;
#ifdef HAVE_SELECT
		case POLL_SELECT:
			if ((poll_method==POLL_SELECT) && (init_select(h)<0)){
				LM_CRIT("select init failed\n");
				goto error;
			}
			break;
#endif
#ifdef HAVE_DEVPOLL
		case POLL_DEVPOLL:
			if ((poll_method==POLL_DEVPOLL) && (init_devpoll(h)<0)){
				LM_CRIT("/dev/poll init failed\n");
				goto error;
			}
			h->dp_changes=local_malloc(sizeof(*(h->dp_changes))*h->max_fd_no);
			if (h->dp_changes==0){
				LM_CRIT("could not alloc db changes array (%ld bytes)\n",
							(long)sizeof(*(h->dp_changes))*h->max_fd_no);
				goto error;
			}
			memset((void*)h->dp_changes, 0,
				sizeof(*(h->dp_changes))*h->max_fd_no);
			break;
#endif
#ifdef HAVE_SIGIO_RT
		case POLL_SIGIO_RT:
			if ((poll_method==POLL_SIGIO_RT) && (init_sigio(h, 0)<0)){
				LM_CRIT("sigio init failed\n");
				goto error;
			}
			break;
#endif
#ifdef HAVE_EPOLL
		case POLL_EPOLL_LT:
		case POLL_EPOLL_ET:
			h->ep_array=local_malloc(sizeof(*(h->ep_array))*h->max_fd_no);
			if (h->ep_array==0){
				LM_CRIT("could not alloc epoll array\n");
				goto error;
			}
			memset((void*)h->ep_array, 0, sizeof(*(h->ep_array))*h->max_fd_no);
			if (init_epoll(h)<0){
				LM_CRIT("epoll init failed\n");
				goto error;
			}
			break;
#endif
#ifdef HAVE_KQUEUE
		case POLL_KQUEUE:
			h->kq_array=local_malloc(sizeof(*(h->kq_array))*h->max_fd_no);
			if (h->kq_array==0){
				LM_CRIT("could not alloc kqueue event array\n");
				goto error;
			}
			h->kq_changes_size=KQ_CHANGES_ARRAY_SIZE;
			h->kq_changes=local_malloc(sizeof(*(h->kq_changes))*
										h->kq_changes_size);
			if (h->kq_changes==0){
				LM_CRIT("could not alloc kqueue changes array\n");
				goto error;
			}
			h->kq_nchanges=0;
			memset((void*)h->kq_array, 0, sizeof(*(h->kq_array))*h->max_fd_no);
			memset((void*)h->kq_changes, 0,
						sizeof(*(h->kq_changes))* h->kq_changes_size);
			if (init_kqueue(h)<0){
				LM_CRIT("kqueue init failed\n");
				goto error;
			}
			break;
#endif
		default:
			LM_CRIT("unknown/unsupported poll method %s (%d)\n",
						poll_method_str[poll_method], poll_method);
			goto error;
	}
	return 0;
error:
	return -1;
}
コード例 #9
0
ファイル: mstpd.c プロジェクト: sevennothing/lros
static void mstpd_run(void * param)
{
	int i;
	struct stpDriver stpDrv = {
		.stp_set_state = do_set_stp_state,
		.stp_create_msti = do_create_stp_msti,
		.stp_delete_msti = do_delete_stp_msti,
		.stp_flush_all_fids = do_flush_all_fids_of_port,
		.alert_push = alert_push,
		.get_ifflags = do_get_flags,
		.if_shutdown = do_if_shutdown,
		.get_speed_duplex = do_get_speed_duplex,
		.get_hwaddr = do_get_hwaddr,
		.get_bridge_portno = do_get_bridge_portno,


#ifdef KERNEL_BRIDGE_TURN_ON
		.br_set_state = br_set_state,
		.br_set_ageing_time = br_set_ageing_time,
		.br_flush_port = br_flush_port,
#endif
		.if_index_to_name = do_if_index_to_name,
		.if_name_to_index = do_if_name_to_index,

	};

	init_stp_driver(&stpDrv);

	usleep(500000); /* wait for ubus stable*/
	if(init_epoll() != 0){
		goto run_mstp_faild;
	}


	if(packet_sock_init() != 0){
		goto run_mstp_faild;
	}


	/* 初始网络套接字,用于获取网络接口信息*/
	if(netsock_init() != 0){
		goto run_mstp_faild;
	}

#ifdef KERNEL_BRIDGE_TURN_ON
	/* 初始化桥操作入口,用于监视桥状态和相关操作 */
	if(init_bridge_ops() != 0){
		goto run_mstp_faild;
	}

#endif
	
	
	for(i=1; i< MAX_MSTID; i++)
		msti_new_flag[i] = 1;

#ifndef KERNEL_BRIDGE_TURN_ON   //内核开启Bridge 支持
	char ifname[10];
	for(i=1; i<6; i++){
		sprintf(ifname, "lan%d", i);
		ifname[4] = 0;
		set_if_to_promisc(ifname);
	}
#endif
	
	join_bridge_to_mstp();

	epoll_main_loop();
	goto over_mstpd;
	
run_mstp_faild:
	ERROR(GLOBAL_OUT_GROUP, "initination run MSTP faild.\n");

over_mstpd:
	pthread_exit(0);

}
コード例 #10
0
ファイル: io_wait.c プロジェクト: Distrotech/opensips
/*!
 * \brief initializes the static vars/arrays
 * \param  h - pointer to the io_wait_h that will be initialized
 * \param  max_fd - maximum allowed fd number
 * \param  poll_method - poll method (0 for automatic best fit)
 */
int init_io_wait(io_wait_h* h, char *name, int max_fd,
									enum poll_types poll_method, int async)
{
	char * poll_err;

	memset(h, 0, sizeof(*h));
	h->name = name;
	h->max_fd_no=max_fd;
#ifdef HAVE_EPOLL
	h->epfd=-1;
#endif
#ifdef HAVE_KQUEUE
	h->kq_fd=-1;
#endif
#ifdef HAVE_DEVPOLL
	h->dpoll_fd=-1;
#endif
	poll_err=check_poll_method(poll_method);

	/* set an appropiate poll method */
	if (poll_err || (poll_method==0)){
		poll_method=choose_poll_method();
		if (poll_err){
			LM_ERR("%s, using %s instead\n",
					poll_err, poll_method_str[poll_method]);
		}else{
			LM_INFO("using %s as the io watch method"
					" (auto detected)\n", poll_method_str[poll_method]);
		}
	}

	h->poll_method=poll_method;

	if (h->poll_method != POLL_POLL && h->poll_method != POLL_EPOLL_LT &&
		h->poll_method != POLL_EPOLL_ET) {
		if (async)
			LM_WARN("Tried to enable async polling but current poll method is %d."
				" Currently we only support POLL and EPOLL \n",h->poll_method);
		async=0;
	}

	/* common stuff, everybody has fd_hash */
	h->fd_hash=local_malloc(sizeof(*(h->fd_hash))*h->max_fd_no);
	if (h->fd_hash==0){
		LM_CRIT("could not alloc fd hashtable (%ld bytes)\n",
					(long)sizeof(*(h->fd_hash))*h->max_fd_no );
		goto error;
	}
	memset((void*)h->fd_hash, 0, sizeof(*(h->fd_hash))*h->max_fd_no);

	switch(poll_method){
		case POLL_POLL:
#ifdef HAVE_SELECT
		case POLL_SELECT:
#endif
#ifdef HAVE_SIGIO_RT
		case POLL_SIGIO_RT:
#endif
#ifdef HAVE_DEVPOLL
		case POLL_DEVPOLL:
#endif
			h->fd_array=local_malloc(sizeof(*(h->fd_array))*h->max_fd_no);
			if (h->fd_array==0){
				LM_CRIT("could not alloc fd array (%ld bytes)\n",
							(long)sizeof(*(h->fd_hash))*h->max_fd_no);
				goto error;
			}
			memset((void*)h->fd_array, 0, sizeof(*(h->fd_array))*h->max_fd_no);
#ifdef HAVE_SIGIO_RT
			if ((poll_method==POLL_SIGIO_RT) && (init_sigio(h, 0)<0)){
				LM_CRIT("sigio init failed\n");
				goto error;
			}
#endif
#ifdef HAVE_DEVPOLL
			if ((poll_method==POLL_DEVPOLL) && (init_devpoll(h)<0)){
				LM_CRIT("/dev/poll init failed\n");
				goto error;
			}
#endif
#ifdef HAVE_SELECT
			if ((poll_method==POLL_SELECT) && (init_select(h)<0)){
				LM_CRIT("select init failed\n");
				goto error;
			}
#endif

			break;
#ifdef HAVE_EPOLL
		case POLL_EPOLL_LT:
		case POLL_EPOLL_ET:
			h->ep_array=local_malloc(sizeof(*(h->ep_array))*h->max_fd_no);
			if (h->ep_array==0){
				LM_CRIT("could not alloc epoll array\n");
				goto error;
			}
			memset((void*)h->ep_array, 0, sizeof(*(h->ep_array))*h->max_fd_no);
			if (init_epoll(h)<0){
				LM_CRIT("epoll init failed\n");
				goto error;
			}
			break;
#endif
#ifdef HAVE_KQUEUE
		case POLL_KQUEUE:
			h->kq_array=local_malloc(sizeof(*(h->kq_array))*h->max_fd_no);
			if (h->kq_array==0){
				LM_CRIT("could not alloc kqueue event array\n");
				goto error;
			}
			h->kq_changes_size=KQ_CHANGES_ARRAY_SIZE;
			h->kq_changes=local_malloc(sizeof(*(h->kq_changes))*
										h->kq_changes_size);
			if (h->kq_changes==0){
				LM_CRIT("could not alloc kqueue changes array\n");
				goto error;
			}
			h->kq_nchanges=0;
			memset((void*)h->kq_array, 0, sizeof(*(h->kq_array))*h->max_fd_no);
			memset((void*)h->kq_changes, 0,
						sizeof(*(h->kq_changes))* h->kq_changes_size);
			if (init_kqueue(h)<0){
				LM_CRIT("kqueue init failed\n");
				goto error;
			}
			break;
#endif
		default:
			LM_CRIT("unknown/unsupported poll method %s (%d)\n",
						poll_method_str[poll_method], poll_method);
			goto error;
	}
	return 0;
error:
	return -1;
}
コード例 #11
0
ファイル: io_wait.c プロジェクト: Gaoithe/openimscore_ims
/* initializes the static vars/arrays
 * params:      h - pointer to the io_wait_h that will be initialized
 *         max_fd - maximum allowed fd number
 *         poll_m - poll method (0 for automatic best fit)
 */
int init_io_wait(io_wait_h* h, int max_fd, enum poll_types poll_method)
{
	char * poll_err;
	
	if (_os_ver==0) _os_ver=get_sys_version(0,0,0);
	memset(h, 0, sizeof(*h));
	h->max_fd_no=max_fd;
#ifdef HAVE_EPOLL
	h->epfd=-1;
#endif
#ifdef HAVE_KQUEUE
	h->kq_fd=-1;
#endif
#ifdef HAVE_DEVPOLL
	h->dpoll_fd=-1;
#endif
	poll_err=check_poll_method(poll_method);
	
	/* set an appropiate poll method */
	if (poll_err || (poll_method==0)){
		poll_method=choose_poll_method();
		if (poll_err){
			LOG(L_ERR, "ERROR: init_io_wait: %s, using %s instead\n",
					poll_err, poll_method_str[poll_method]);
		}else{
			LOG(L_INFO, "init_io_wait: using %s as the io watch method"
					" (auto detected)\n", poll_method_str[poll_method]);
		}
	}
	
	h->poll_method=poll_method;
	
	/* common stuff, everybody has fd_hash */
	h->fd_hash=local_malloc(sizeof(*(h->fd_hash))*h->max_fd_no);
	if (h->fd_hash==0){
		LOG(L_CRIT, "ERROR: init_io_wait: could not alloc"
					" fd hashtable (%ld bytes)\n",
					(long)sizeof(*(h->fd_hash))*h->max_fd_no );
		goto error;
	}
	memset((void*)h->fd_hash, 0, sizeof(*(h->fd_hash))*h->max_fd_no);
	
	switch(poll_method){
		case POLL_POLL:
#ifdef HAVE_SELECT
		case POLL_SELECT:
#endif
#ifdef HAVE_SIGIO_RT
		case POLL_SIGIO_RT:
#endif
#ifdef HAVE_DEVPOLL
		case POLL_DEVPOLL:
#endif
			h->fd_array=local_malloc(sizeof(*(h->fd_array))*h->max_fd_no);
			if (h->fd_array==0){
				LOG(L_CRIT, "ERROR: init_io_wait: could not"
							" alloc fd array (%ld bytes)\n",
							(long)sizeof(*(h->fd_hash))*h->max_fd_no);
				goto error;
			}
			memset((void*)h->fd_array, 0, sizeof(*(h->fd_array))*h->max_fd_no);
#ifdef HAVE_SIGIO_RT
			if ((poll_method==POLL_SIGIO_RT) && (init_sigio(h, 0)<0)){
				LOG(L_CRIT, "ERROR: init_io_wait: sigio init failed\n");
				goto error;
			}
#endif
#ifdef HAVE_DEVPOLL
			if ((poll_method==POLL_DEVPOLL) && (init_devpoll(h)<0)){
				LOG(L_CRIT, "ERROR: init_io_wait: /dev/poll init failed\n");
				goto error;
			}
#endif
#ifdef HAVE_SELECT
			if ((poll_method==POLL_SELECT) && (init_select(h)<0)){
				LOG(L_CRIT, "ERROR: init_io_wait: select init failed\n");
				goto error;
			}
#endif
			
			break;
#ifdef HAVE_EPOLL
		case POLL_EPOLL_LT:
		case POLL_EPOLL_ET:
			h->ep_array=local_malloc(sizeof(*(h->ep_array))*h->max_fd_no);
			if (h->ep_array==0){
				LOG(L_CRIT, "ERROR: init_io_wait: could not alloc"
							" epoll array\n");
				goto error;
			}
			memset((void*)h->ep_array, 0, sizeof(*(h->ep_array))*h->max_fd_no);
			if (init_epoll(h)<0){
				LOG(L_CRIT, "ERROR: init_io_wait: epoll init failed\n");
				goto error;
			}
			break;
#endif
#ifdef HAVE_KQUEUE
		case POLL_KQUEUE:
			h->kq_array=local_malloc(sizeof(*(h->kq_array))*h->max_fd_no);
			if (h->kq_array==0){
				LOG(L_CRIT, "ERROR: init_io_wait: could not alloc"
							" kqueue event array\n");
				goto error;
			}
			h->kq_changes_size=KQ_CHANGES_ARRAY_SIZE;
			h->kq_changes=local_malloc(sizeof(*(h->kq_changes))*
										h->kq_changes_size);
			if (h->kq_changes==0){
				LOG(L_CRIT, "ERROR: init_io_wait: could not alloc"
							" kqueue changes array\n");
				goto error;
			}
			h->kq_nchanges=0;
			memset((void*)h->kq_array, 0, sizeof(*(h->kq_array))*h->max_fd_no);
			memset((void*)h->kq_changes, 0,
						sizeof(*(h->kq_changes))* h->kq_changes_size);
			if (init_kqueue(h)<0){
				LOG(L_CRIT, "ERROR: init_io_wait: kqueue init failed\n");
				goto error;
			}
			break;
#endif
		default:
			LOG(L_CRIT, "BUG: init_io_wait: unknown/unsupported poll"
						" method %s (%d)\n",
						poll_method_str[poll_method], poll_method);
			goto error;
	}
	return 0;
error:
	return -1;
}
コード例 #12
0
void start_server (void) {
  char buf[64];
  int i, prev_time = 0;

  init_epoll ();
  init_netbuffers ();

  if (!sfd) {
    sfd = server_socket (port, settings_addr, backlog, 0);
  }

  if (sfd < 0) {
    kprintf ("cannot open server socket at port %d: %m\n", port);
    exit (3);
  }

  vkprintf (1, "created listening socket at %s:%d, fd=%d\n", conv_addr (settings_addr.s_addr, buf), port, sfd);

  if (daemonize) {
    setsid ();
  }

  if (change_user (username) < 0) {
    kprintf ("fatal: cannot change user to %s\n", username ? username : "******");
    exit (1);
  }

  if (binlogname && !binlog_disabled) {
    assert (append_to_binlog (Binlog) == log_readto_pos);
  }

  init_listening_connection (sfd, &ct_rpc_server, &copyexec_result_rpc_server);

  sigset_t signal_set;
  sigemptyset (&signal_set);
  sigaddset (&signal_set, SIGINT);
  sigaddset (&signal_set, SIGTERM);
  sigaddset (&signal_set, SIGUSR1);
  if (daemonize) {
    sigaddset (&signal_set, SIGHUP);
  }
  struct sigaction act;
  act.sa_handler = copyexec_results_sig_handler;
  act.sa_mask = signal_set;
  act.sa_flags = 0;
  for (i = 1; i <= SIGRTMAX; i++) {
    if (sigismember (&signal_set, i)) {
      if (sigaction (i, &act, NULL) < 0) {
        kprintf ("sigaction (%d) failed. %m\n", i);
        exit (1);
      }
    }
  }

  for (i = 0; ; i++) {
    if (!(i & 255)) {
      vkprintf (1, "epoll_work(): %d out of %d connections, network buffers: %d used, %d out of %d allocated\n",
	       active_connections, maxconn, NB_used, NB_alloc, NB_max);
    }
    epoll_work (71);

    if (interrupted_by_term_signal ()) {
      break;
    }

    if (pending_signals & (1LL << SIGHUP)) {
      pending_signals_clear_bit (&signal_set, SIGHUP);
      kprintf ("got SIGHUP.\n");
      sync_binlog (2);
    }

    if (pending_signals & (1LL << SIGUSR1)) {
      pending_signals_clear_bit (&signal_set, SIGUSR1);
      kprintf ("got SIGUSR1, rotate logs.\n");
      reopen_logs ();
      sync_binlog (2);
    }

    if (now != prev_time) {
      prev_time = now;
      cron ();
    }
    if (quit_steps && !--quit_steps) break;
  }

  epoll_close (sfd);
  close (sfd);

  flush_binlog_last ();
  sync_binlog (2);
}