diff --git a/app/nginx-1.11.10/auto/sources b/app/nginx-1.11.10/auto/sources index f13310677..8a43d681c 100644 --- a/app/nginx-1.11.10/auto/sources +++ b/app/nginx-1.11.10/auto/sources @@ -106,8 +106,8 @@ WIN32_SELECT_SRCS=src/event/modules/ngx_win32_select_module.c POLL_MODULE=ngx_poll_module POLL_SRCS=src/event/modules/ngx_poll_module.c -KQUEUE_MODULE="ngx_kqueue_module ngx_ff_channel_module" -KQUEUE_SRCS="src/event/modules/ngx_kqueue_module.c src/event/modules/ngx_ff_module.c src/event/modules/ngx_ff_channel.c" +KQUEUE_MODULE="ngx_kqueue_module ngx_ff_host_event_module" +KQUEUE_SRCS="src/event/modules/ngx_kqueue_module.c src/event/modules/ngx_ff_module.c src/event/modules/ngx_ff_host_event_module.c" DEVPOLL_MODULE=ngx_devpoll_module DEVPOLL_SRCS=src/event/modules/ngx_devpoll_module.c diff --git a/app/nginx-1.11.10/conf/nginx.conf b/app/nginx-1.11.10/conf/nginx.conf index ed449976c..d580363ed 100644 --- a/app/nginx-1.11.10/conf/nginx.conf +++ b/app/nginx-1.11.10/conf/nginx.conf @@ -41,6 +41,10 @@ http { listen 80; server_name localhost; + # bulid server on kernel network stack + # + #kernel_network_stack on; + #charset koi8-r; access_log /dev/null; diff --git a/app/nginx-1.11.10/src/core/ngx_connection.c b/app/nginx-1.11.10/src/core/ngx_connection.c index 2af287614..45d90e66b 100644 --- a/app/nginx-1.11.10/src/core/ngx_connection.c +++ b/app/nginx-1.11.10/src/core/ngx_connection.c @@ -376,6 +376,10 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle) return NGX_OK; } +#if (NGX_HAVE_FSTACK) +extern int + fstack_territory(int domain, int type, int protocol); +#endif ngx_int_t ngx_open_listening_sockets(ngx_cycle_t *cycle) @@ -404,6 +408,36 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle) ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { +#if (NGX_HAVE_FSTACK) + + if (ngx_process <= NGX_PROCESS_MASTER) { + + /* process master, kernel network stack*/ + if (!ls[i].belong_to_host) { + /* We should continue to process the listening socket, + if it is not supported by fstack.*/ + if (fstack_territory(ls[i].sockaddr->sa_family, ls[i].type, 0)) { + continue; + } + } + } else if (NGX_PROCESS_WORKER == ngx_process) { + /* process worker, fstack */ + if (ls[i].belong_to_host) { + continue; + } + + if (!fstack_territory(ls[i].sockaddr->sa_family, ls[i].type, 0)) { + continue; + } + } else { + ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, + "unexpected process type: %d, ignored", + ngx_process); + exit(1); + } + +#endif + if (ls[i].ignore) { continue; } @@ -971,6 +1005,15 @@ ngx_close_listening_sockets(ngx_cycle_t *cycle) ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { +#if (NGX_HAVE_FSTACK) + + // No need to deal with, just skip + if (fstack_territory(ls[i].sockaddr->sa_family, ls[i].type, 0)) { + continue; + } + +#endif //(NGX_HAVE_FSTACK) + c = ls[i].connection; if (c) { @@ -1032,6 +1075,9 @@ ngx_get_connection(ngx_socket_t s, ngx_log_t *log) ngx_uint_t instance; ngx_event_t *rev, *wev; ngx_connection_t *c; +#if (NGX_HAVE_FSTACK) + ngx_atomic_uint_t success; +#endif /* disable warning: Win32 SOCKET is u_int while UNIX socket is int */ @@ -1042,7 +1088,35 @@ ngx_get_connection(ngx_socket_t s, ngx_log_t *log) s, ngx_cycle->files_n); return NULL; } +#if (NGX_HAVE_FSTACK) +#ifndef unlikely +#define unlikely(x) __builtin_expect((x),0) +#endif + /* move ngx_cycle->free_connections atomically */ + do { + /* Restore n as it may change every loop */ + c = ngx_cycle->free_connections; + if (c == NULL) { + ngx_drain_connections((ngx_cycle_t *) ngx_cycle); + c = ngx_cycle->free_connections; + } + + if (c == NULL) { + ngx_log_error(NGX_LOG_ALERT, log, 0, + "%ui worker_connections are not enough", + ngx_cycle->connection_n); + + return NULL; + } + + success = ngx_atomic_cmp_set(&ngx_cycle->free_connections, c, + c->data); + + } while (unlikely(success == 0)); + + ngx_memory_barrier(); +#else c = ngx_cycle->free_connections; if (c == NULL) { @@ -1059,6 +1133,7 @@ ngx_get_connection(ngx_socket_t s, ngx_log_t *log) } ngx_cycle->free_connections = c->data; +#endif ngx_cycle->free_connection_n--; if (ngx_cycle->files && ngx_cycle->files[s] == NULL) { @@ -1098,8 +1173,25 @@ ngx_get_connection(ngx_socket_t s, ngx_log_t *log) void ngx_free_connection(ngx_connection_t *c) { - c->data = ngx_cycle->free_connections; +#if (NGX_HAVE_FSTACK) + ngx_atomic_uint_t success; + + /* move ngx_cycle->free_connections atomically */ + do { + /* Restore n as it may change every loop */ + c->data = ngx_cycle->free_connections; + + success = ngx_atomic_cmp_set(&ngx_cycle->free_connections, c->data, + c); + + } while (unlikely(success == 0)); + + ngx_memory_barrier(); + +#else ngx_cycle->free_connections = c; + +#endif ngx_cycle->free_connection_n++; if (ngx_cycle->files && ngx_cycle->files[c->fd] == c) { @@ -1129,7 +1221,11 @@ ngx_close_connection(ngx_connection_t *c) } if (!c->shared) { +#if (NGX_HAVE_FSTACK) + if (ngx_event_actions.del_conn) { +#else if (ngx_del_conn) { +#endif ngx_del_conn(c, NGX_CLOSE_EVENT); } else { diff --git a/app/nginx-1.11.10/src/core/ngx_connection.h b/app/nginx-1.11.10/src/core/ngx_connection.h index 1d3e3a3a1..766516c65 100644 --- a/app/nginx-1.11.10/src/core/ngx_connection.h +++ b/app/nginx-1.11.10/src/core/ngx_connection.h @@ -87,6 +87,9 @@ struct ngx_listening_s { int fastopen; #endif +#if (NGX_HAVE_FSTACK) + unsigned belong_to_host:1; +#endif }; diff --git a/app/nginx-1.11.10/src/core/ngx_cycle.c b/app/nginx-1.11.10/src/core/ngx_cycle.c index 037c731b5..5e95628bf 100644 --- a/app/nginx-1.11.10/src/core/ngx_cycle.c +++ b/app/nginx-1.11.10/src/core/ngx_cycle.c @@ -609,11 +609,9 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) } } -#if (!NGX_HAVE_FSTACK) if (ngx_open_listening_sockets(cycle) != NGX_OK) { goto failed; } -#endif if (!ngx_test_config) { ngx_configure_listening_sockets(cycle); diff --git a/app/nginx-1.11.10/src/core/ngx_resolver.c b/app/nginx-1.11.10/src/core/ngx_resolver.c index 2065f75a0..4112fa95e 100644 --- a/app/nginx-1.11.10/src/core/ngx_resolver.c +++ b/app/nginx-1.11.10/src/core/ngx_resolver.c @@ -4512,7 +4512,11 @@ ngx_tcp_connect(ngx_resolver_connection_t *rec) c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); +#if (NGX_HAVE_FSTACK) + if (ngx_event_actions.add_conn) { +#else if (ngx_add_conn) { +#endif if (ngx_add_conn(c) == NGX_ERROR) { goto failed; } @@ -4564,7 +4568,11 @@ ngx_tcp_connect(ngx_resolver_connection_t *rec) } } +#if (NGX_HAVE_FSTACK) + if (ngx_event_actions.add_conn) { +#else if (ngx_add_conn) { +#endif if (rc == -1) { /* NGX_EINPROGRESS */ diff --git a/app/nginx-1.11.10/src/event/modules/ngx_ff_channel.c b/app/nginx-1.11.10/src/event/modules/ngx_ff_host_event_module.c similarity index 81% rename from app/nginx-1.11.10/src/event/modules/ngx_ff_channel.c rename to app/nginx-1.11.10/src/event/modules/ngx_ff_host_event_module.c index 1ed9eb208..3e57261a1 100644 --- a/app/nginx-1.11.10/src/event/modules/ngx_ff_channel.c +++ b/app/nginx-1.11.10/src/event/modules/ngx_ff_host_event_module.c @@ -33,10 +33,12 @@ #include #if (NGX_HAVE_FSTACK) -static void * ngx_ff_channel_create_conf(ngx_cycle_t *cycle); -static char * ngx_ff_channel_init_conf(ngx_cycle_t *cycle, +static void * ngx_ff_host_event_create_conf(ngx_cycle_t *cycle); +static char * ngx_ff_host_event_init_conf(ngx_cycle_t *cycle, void *conf); -static ngx_int_t ngx_ff_epoll_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_ff_host_event_init_process(ngx_cycle_t *cycle); +static void ngx_ff_host_event_exit_process(ngx_cycle_t *cycle); +static ngx_int_t ngx_ff_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer); static ngx_int_t ngx_ff_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags); static ngx_int_t ngx_ff_epoll_del_event(ngx_event_t *ev, @@ -46,13 +48,18 @@ static ngx_int_t ngx_ff_epoll_process_events(ngx_cycle_t *cycle, static ngx_int_t ngx_ff_create_connection(ngx_cycle_t *cycle); static void ngx_ff_delete_connection(); static void ngx_ff_worker_channel_handler(ngx_event_t *ev); -static void *ngx_ff_channel_thread_main(void *args); +static void *ngx_ff_host_event_thread_main(void *args); static ngx_int_t ngx_ff_add_channel_event(ngx_cycle_t *cycle, ngx_fd_t fd, ngx_int_t event, ngx_event_handler_pt handler); -static ngx_int_t ngx_ff_process_channel_events(ngx_cycle_t *cycle); +static void ngx_ff_process_events_and_timers(ngx_cycle_t *cycle); ngx_int_t ngx_ff_start_worker_channel(ngx_cycle_t *cycle, ngx_fd_t fd, ngx_int_t event); + +void ngx_event_cancel_timers_of_host(void); +void ngx_event_expire_timers_of_host(void); +ngx_msec_t ngx_event_find_timer_of_host(void); +void ngx_event_cancel_timers_of_host(void); struct channel_thread_args { ngx_cycle_t *cycle; @@ -69,41 +76,44 @@ static struct epoll_event *event_list; static ngx_uint_t nevents; static ngx_connection_t *channel_connection; +#include +static sem_t sem; + typedef struct { ngx_uint_t events; -} ngx_ff_channel_conf_t; +} ngx_ff_host_event_conf_t; -static ngx_command_t ngx_ff_channel_commands[] = { +static ngx_command_t ngx_ff_host_event_commands[] = { ngx_null_command }; -ngx_core_module_t ngx_ff_channel_module_ctx = { - ngx_string("ff_channel"), - ngx_ff_channel_create_conf, /* create configuration */ - ngx_ff_channel_init_conf, /* init configuration */ +ngx_core_module_t ngx_ff_host_event_module_ctx = { + ngx_string("ff_host_event"), + ngx_ff_host_event_create_conf, /* create configuration */ + ngx_ff_host_event_init_conf, /* init configuration */ }; -ngx_module_t ngx_ff_channel_module = { +ngx_module_t ngx_ff_host_event_module = { NGX_MODULE_V1, - &ngx_ff_channel_module_ctx, /* module context */ - ngx_ff_channel_commands, /* module directives */ + &ngx_ff_host_event_module_ctx, /* module context */ + ngx_ff_host_event_commands, /* module directives */ NGX_CORE_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ - ngx_ff_epoll_init, /* init process */ + ngx_ff_host_event_init_process, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ - NULL, /* exit process */ + ngx_ff_host_event_exit_process, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING }; static void * -ngx_ff_channel_create_conf(ngx_cycle_t *cycle) +ngx_ff_host_event_create_conf(ngx_cycle_t *cycle) { - ngx_ff_channel_conf_t *cf; - cf = ngx_palloc(cycle->pool, sizeof(ngx_ff_channel_conf_t)); + ngx_ff_host_event_conf_t *cf; + cf = ngx_palloc(cycle->pool, sizeof(ngx_ff_host_event_conf_t)); if (cf == NULL) { return NULL; } @@ -112,15 +122,40 @@ ngx_ff_channel_create_conf(ngx_cycle_t *cycle) } static char * -ngx_ff_channel_init_conf(ngx_cycle_t *cycle, void *conf) +ngx_ff_host_event_init_conf(ngx_cycle_t *cycle, void *conf) { - ngx_ff_channel_conf_t *cf = conf; + ngx_ff_host_event_conf_t *cf = conf; cf->events = 1; return NGX_CONF_OK; } + +static ngx_int_t ngx_ff_host_event_init_process(ngx_cycle_t *cycle) +{ + if (sem_init(&sem, 0, 0) != 0) + { + return NGX_ERROR; + } + + return NGX_OK; +} + +static void ngx_ff_host_event_exit_process(ngx_cycle_t *cycle) +{ + struct timespec ts; + + if (clock_gettime( CLOCK_REALTIME,&ts ) < 0) + return; + + //5s + ts.tv_sec += 4; + + (void) sem_timedwait(&sem, &ts); +} + + static ngx_int_t -ngx_ff_epoll_init(ngx_cycle_t *cycle) +ngx_ff_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer) { if (ep == -1) { ep = epoll_create(1); @@ -413,6 +448,7 @@ ngx_ff_epoll_process_events(ngx_cycle_t *cycle, if ((revents & EPOLLIN) && rev->active) { rev->ready = 1; + rev->available = 1; rev->handler(rev); } @@ -531,6 +567,8 @@ ngx_ff_add_channel_event(ngx_cycle_t *cycle, ngx_fd_t fd, rev->channel = 1; wev->channel = 1; + rev->belong_to_host = wev->belong_to_host = 1; + ev = (event == NGX_READ_EVENT) ? rev : wev; ev->handler = handler; @@ -623,7 +661,7 @@ ngx_ff_worker_channel_handler(ngx_event_t *ev) } static void * -ngx_ff_channel_thread_main(void *args) +ngx_ff_host_event_thread_main(void *args) { struct channel_thread_args *cta = args; ngx_cycle_t *cycle = cta->cycle; @@ -634,21 +672,48 @@ ngx_ff_channel_thread_main(void *args) } for (;;) { - ngx_ff_process_channel_events(cycle); + ngx_ff_process_events_and_timers(cycle); if (thread_quit) { break; } } + ngx_event_cancel_timers_of_host(); + ngx_free(cta); return NULL; } -static ngx_int_t -ngx_ff_process_channel_events(ngx_cycle_t *cycle) +static void +ngx_ff_process_events_and_timers(ngx_cycle_t *cycle) { - return ngx_ff_epoll_process_events(cycle, 500, NGX_UPDATE_TIME); + ngx_uint_t flags; + ngx_msec_t timer, delta; + + timer = ngx_event_find_timer_of_host(); + flags = NGX_UPDATE_TIME; + + /* handle signals from master in case of network inactivity */ + + if (timer == NGX_TIMER_INFINITE || timer > 500) { + timer = 500; + } + + delta = ngx_current_msec; + + (void) ngx_ff_epoll_process_events(cycle, timer, flags); + + delta = ngx_current_msec - delta; + + ngx_event_process_posted(cycle, &ngx_posted_accept_events_of_host); + + if (delta) { + ngx_event_expire_timers_of_host(); + } + + ngx_event_process_posted(cycle, &ngx_posted_events_of_host); + } ngx_int_t @@ -669,7 +734,7 @@ ngx_ff_start_worker_channel(ngx_cycle_t *cycle, ngx_fd_t fd, cta->handler = ngx_ff_worker_channel_handler; ret = pthread_create(&channel_thread, NULL, - ngx_ff_channel_thread_main, (void *)cta); + ngx_ff_host_event_thread_main, (void *)cta); if (ret != 0) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "pthread_create() failed"); @@ -681,4 +746,17 @@ ngx_ff_start_worker_channel(ngx_cycle_t *cycle, ngx_fd_t fd, return NGX_OK; } +ngx_event_actions_t ngx_ff_host_event_actions = { + ngx_ff_epoll_add_event, /* add an event */ + ngx_ff_epoll_del_event, /* delete an event */ + ngx_ff_epoll_add_event, /* enable an event */ + ngx_ff_epoll_add_event, /* disable an event */ + NULL, /* add an connection */ + NULL, /* delete an connection */ + NULL, /* trigger a notify */ + ngx_ff_epoll_process_events, /* process the events */ + ngx_ff_epoll_init, /* init the events */ + NULL, /* done the events */ +}; + #endif diff --git a/app/nginx-1.11.10/src/event/modules/ngx_ff_module.c b/app/nginx-1.11.10/src/event/modules/ngx_ff_module.c index c13dbdb9b..0d37baff5 100644 --- a/app/nginx-1.11.10/src/event/modules/ngx_ff_module.c +++ b/app/nginx-1.11.10/src/event/modules/ngx_ff_module.c @@ -129,6 +129,35 @@ static int inited; real_##func; \ }) +extern intptr_t ngx_max_sockets; + +/*- + * Make sockfd assigned by the fstack plus the value of maximum kernel socket. + * so we can tell them apart according to different scopes. + * Solve the condominium ownership at Application Layer and obtain more freedom. + * fstack tried to do this by 'fd_reserve', unfortunately, it doesn't work well. + */ +static inline int convert_fstack_fd(int sockfd) { + return sockfd + ngx_max_sockets; +} + +/* Restore socket fd. */ +static inline int restore_fstack_fd(int sockfd) { + if(sockfd <= ngx_max_sockets) { + return sockfd; + } + + return sockfd - ngx_max_sockets; +} + +/* Tell whether a 'sockfd' belongs to fstack. */ +static inline int is_fstack_fd(int sockfd) { + if (unlikely(inited == 0)) { + return 0; + } + + return sockfd >= ngx_max_sockets; +} // proc_type, 1: primary, 0: secondary. int @@ -151,8 +180,17 @@ ff_mod_init(const char *conf, int proc_id, int proc_type) { } rc = ff_init(ff_argc, ff_argv); - if (rc == 0) + if (rc == 0) { + /* Ensure that the socket we converted + does not exceed the maximum value of 'int' */ + + if(ngx_max_sockets + (unsigned)ff_getmaxfd() > INT_MAX) + { + rc = -1; + } + inited = 1; + } for (i = 0; i < ff_argc; i++) { free(ff_argv[i]); @@ -163,9 +201,23 @@ ff_mod_init(const char *conf, int proc_id, int proc_type) { return rc; } +/*- + * Verify whether the socket is supported by fstack or not. + */ +int +fstack_territory(int domain, int type, int protocol) +{ + if ((AF_INET != domain) || (SOCK_STREAM != type && SOCK_DGRAM != type)) { + return 0; + } + + return 1; +} + int socket(int domain, int type, int protocol) { + int sock; if (unlikely(inited == 0)) { return SYSCALL(socket)(domain, type, protocol); } @@ -174,249 +226,216 @@ socket(int domain, int type, int protocol) return SYSCALL(socket)(domain, type, protocol); } - return ff_socket(domain, type, protocol); + sock = ff_socket(domain, type, protocol); + + if (sock != -1) { + sock = convert_fstack_fd(sock); + } + + return sock; } int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { - if (unlikely(inited == 0)) { - return SYSCALL(bind)(sockfd, addr, addrlen); - } - - if (ff_fdisused(sockfd)) { + if(is_fstack_fd(sockfd)){ + sockfd = restore_fstack_fd(sockfd); return ff_bind(sockfd, (struct linux_sockaddr *)addr, addrlen); - } else { - return SYSCALL(bind)(sockfd, addr, addrlen); } + + return SYSCALL(bind)(sockfd, addr, addrlen); } int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { - if (unlikely(inited == 0)) { - return SYSCALL(connect)(sockfd, addr, addrlen); - } - - if (ff_fdisused(sockfd)) { + if(is_fstack_fd(sockfd)){ + sockfd = restore_fstack_fd(sockfd); return ff_connect(sockfd, (struct linux_sockaddr *)addr, addrlen); - } else { - return SYSCALL(connect)(sockfd, addr, addrlen); } + + return SYSCALL(connect)(sockfd, addr, addrlen); } ssize_t send(int sockfd, const void *buf, size_t len, int flags) { - if (unlikely(inited == 0)) { - return SYSCALL(send)(sockfd, buf, len, flags); - } - - if (ff_fdisused(sockfd)) { + if(is_fstack_fd(sockfd)){ + sockfd = restore_fstack_fd(sockfd); return ff_send(sockfd, buf, len, flags); - } else { - return SYSCALL(send)(sockfd, buf, len, flags); } + + return SYSCALL(send)(sockfd, buf, len, flags); } ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) { - if (unlikely(inited == 0)) { - return SYSCALL(sendto)(sockfd, buf, len, flags, dest_addr, addrlen); - } - - if (ff_fdisused(sockfd)) { + if(is_fstack_fd(sockfd)){ + sockfd = restore_fstack_fd(sockfd); return ff_sendto(sockfd, buf, len, flags, (struct linux_sockaddr *)dest_addr, addrlen); - } else { - return SYSCALL(sendto)(sockfd, buf, len, flags, dest_addr, addrlen); } + + return SYSCALL(sendto)(sockfd, buf, len, flags, dest_addr, addrlen); } ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) { - if (unlikely(inited == 0)) { - return SYSCALL(sendmsg)(sockfd, msg, flags); - } - - if (ff_fdisused(sockfd)) { + if(is_fstack_fd(sockfd)){ + sockfd = restore_fstack_fd(sockfd); return ff_sendmsg(sockfd, msg, flags); - } else { - return SYSCALL(sendmsg)(sockfd, msg, flags); } + + return SYSCALL(sendmsg)(sockfd, msg, flags); } ssize_t recv(int sockfd, void *buf, size_t len, int flags) { - if (unlikely(inited == 0)) { - return SYSCALL(recv)(sockfd, buf, len, flags); - } - - if (ff_fdisused(sockfd)) { + if(is_fstack_fd(sockfd)){ + sockfd = restore_fstack_fd(sockfd); return ff_recv(sockfd, buf, len, flags); - } else { - return SYSCALL(recv)(sockfd, buf, len, flags); } + + return SYSCALL(recv)(sockfd, buf, len, flags); } int listen(int sockfd, int backlog) { - if (unlikely(inited == 0)) { - return SYSCALL(listen)(sockfd, backlog); - } - - if (ff_fdisused(sockfd)) { + if(is_fstack_fd(sockfd)){ + sockfd = restore_fstack_fd(sockfd); return ff_listen(sockfd, backlog); - } else { - return SYSCALL(listen)(sockfd, backlog); } + + return SYSCALL(listen)(sockfd, backlog); } int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen) { - if (unlikely(inited == 0)) { - return SYSCALL(getsockopt)(sockfd, level, optname, optval, optlen); - } - - if (ff_fdisused(sockfd)) { + if(is_fstack_fd(sockfd)){ + sockfd = restore_fstack_fd(sockfd); return ff_getsockopt(sockfd, level, optname, optval, optlen); - } else { - return SYSCALL(getsockopt)(sockfd, level, optname, optval, optlen); } + + return SYSCALL(getsockopt)(sockfd, level, optname, optval, optlen); } int setsockopt (int sockfd, int level, int optname, const void *optval, socklen_t optlen) { - if (unlikely(inited == 0)) { - return SYSCALL(setsockopt)(sockfd, level, optname, optval, optlen); - } - - if (ff_fdisused(sockfd)) { + if(is_fstack_fd(sockfd)){ + sockfd = restore_fstack_fd(sockfd); return ff_setsockopt(sockfd, level, optname, optval, optlen); - } else { - return SYSCALL(setsockopt)(sockfd, level, optname, optval, optlen); } + + return SYSCALL(setsockopt)(sockfd, level, optname, optval, optlen); } int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { - if (unlikely(inited == 0)) { - return SYSCALL(accept)(sockfd, addr, addrlen); - } + int rc; + if(is_fstack_fd(sockfd)){ + sockfd = restore_fstack_fd(sockfd); + rc = ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen); + if (rc != -1) { + rc = convert_fstack_fd(rc); + } - if (ff_fdisused(sockfd)) { - return ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen); - } else { - return SYSCALL(accept)(sockfd, addr, addrlen); + return rc; } + + return SYSCALL(accept)(sockfd, addr, addrlen); } int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) { - if (unlikely(inited == 0)) { - return SYSCALL(accept4)(sockfd, addr, addrlen, flags); - } + int rc; + if(is_fstack_fd(sockfd)){ + sockfd = restore_fstack_fd(sockfd); + rc = ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen); + if (rc != -1) { + rc = convert_fstack_fd(rc); + } - if (ff_fdisused(sockfd)) { - return ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen); - } else { - return SYSCALL(accept4)(sockfd, addr, addrlen, flags); + return rc; } + + return SYSCALL(accept4)(sockfd, addr, addrlen, flags); } int close(int sockfd) { - if (unlikely(inited == 0)) { - return SYSCALL(close)(sockfd); - } - - if (ff_fdisused(sockfd)) { + if(is_fstack_fd(sockfd)){ + sockfd = restore_fstack_fd(sockfd); return ff_close(sockfd); - } else { - return SYSCALL(close)(sockfd); } + + return SYSCALL(close)(sockfd); } ssize_t writev(int sockfd, const struct iovec *iov, int iovcnt) { - if (unlikely(inited == 0)) { - return SYSCALL(writev)(sockfd, iov, iovcnt); - } - - if (ff_fdisused(sockfd)) { + if(is_fstack_fd(sockfd)){ + sockfd = restore_fstack_fd(sockfd); return ff_writev(sockfd, iov, iovcnt); - } else { - return SYSCALL(writev)(sockfd, iov, iovcnt); } + + return SYSCALL(writev)(sockfd, iov, iovcnt); } ssize_t readv(int sockfd, const struct iovec *iov, int iovcnt) { - if (unlikely(inited == 0)) { - return SYSCALL(readv)(sockfd, iov, iovcnt); - } - - if (ff_fdisused(sockfd)) { + if(is_fstack_fd(sockfd)){ + sockfd = restore_fstack_fd(sockfd); return ff_readv(sockfd, iov, iovcnt); - } else { - return SYSCALL(readv)(sockfd, iov, iovcnt); } + + return SYSCALL(readv)(sockfd, iov, iovcnt); } ssize_t read(int sockfd, void *buf, size_t count) { - if (unlikely(inited == 0)) { - return SYSCALL(read)(sockfd, buf, count); - } - - if (ff_fdisused(sockfd)) { + if(is_fstack_fd(sockfd)){ + sockfd = restore_fstack_fd(sockfd); return ff_read(sockfd, buf, count); - } else { - return SYSCALL(read)(sockfd, buf, count); } + + return SYSCALL(read)(sockfd, buf, count); } ssize_t write(int sockfd, const void *buf, size_t count) { - if (unlikely(inited == 0)) { - return SYSCALL(write)(sockfd, buf, count); - } - - if (ff_fdisused(sockfd)) { + if(is_fstack_fd(sockfd)){ + sockfd = restore_fstack_fd(sockfd); return ff_write(sockfd, buf, count); - } else { - return SYSCALL(write)(sockfd, buf, count); } + + return SYSCALL(write)(sockfd, buf, count); } int ioctl(int sockfd, int request, void *p) { - if (unlikely(inited == 0)) { - return SYSCALL(ioctl)(sockfd, request, p); - } - - if (ff_fdisused(sockfd)) { + if(is_fstack_fd(sockfd)){ + sockfd = restore_fstack_fd(sockfd); return ff_ioctl(sockfd, request, p); - } else { - return SYSCALL(ioctl)(sockfd, request, p); } + + return SYSCALL(ioctl)(sockfd, request, p); } int @@ -429,6 +448,26 @@ int kevent(int kq, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout) { + struct kevent *kev; + int i = 0; + for(i = 0; i < nchanges; i++) { + kev = (struct kevent *)&changelist[i]; + switch (kev->filter) { + + case EVFILT_READ: + case EVFILT_WRITE: + case EVFILT_VNODE: + kev->ident = restore_fstack_fd(kev->ident); + break; + case EVFILT_AIO: + case EVFILT_PROC: + case EVFILT_SIGNAL: + case EVFILT_TIMER: + case EVFILT_USER: + default: + break; + } + } return ff_kevent(kq, changelist, nchanges, eventlist, nevents, timeout); } @@ -441,4 +480,3 @@ gettimeofday(struct timeval *tv, struct timezone *tz) return ff_gettimeofday(tv, tz); } - diff --git a/app/nginx-1.11.10/src/event/ngx_event.c b/app/nginx-1.11.10/src/event/ngx_event.c index 7f27ca080..71016c95b 100644 --- a/app/nginx-1.11.10/src/event/ngx_event.c +++ b/app/nginx-1.11.10/src/event/ngx_event.c @@ -564,6 +564,11 @@ ngx_timer_signal_handler(int signo) #endif +#if (NGX_HAVE_FSTACK) + +extern ngx_event_actions_t ngx_ff_host_event_actions; + +#endif static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle) @@ -602,6 +607,11 @@ ngx_event_process_init(ngx_cycle_t *cycle) ngx_queue_init(&ngx_posted_accept_events); ngx_queue_init(&ngx_posted_events); +#if (NGX_HAVE_FSTACK) + ngx_queue_init(&ngx_posted_accept_events_of_host); + ngx_queue_init(&ngx_posted_events_of_host); +#endif + if (ngx_event_timer_init(cycle->log) == NGX_ERROR) { return NGX_ERROR; } @@ -625,6 +635,13 @@ ngx_event_process_init(ngx_cycle_t *cycle) break; } +#if (NGX_HAVE_FSTACK) + if (ngx_ff_host_event_actions.init(cycle, ngx_timer_resolution) != NGX_OK) { + /* fatal */ + exit(2); + } +#endif + #if !(NGX_WIN32) if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) { @@ -663,8 +680,14 @@ ngx_event_process_init(ngx_cycle_t *cycle) cycle->files_n = (ngx_uint_t) rlmt.rlim_cur; +#if (NGX_HAVE_FSTACK) + cycle->files = ngx_calloc(sizeof(ngx_connection_t *) * cycle->files_n * 2, + cycle->log); +#else cycle->files = ngx_calloc(sizeof(ngx_connection_t *) * cycle->files_n, cycle->log); +#endif + if (cycle->files == NULL) { return NGX_ERROR; } @@ -757,6 +780,12 @@ ngx_event_process_init(ngx_cycle_t *cycle) rev->log = c->log; rev->accept = 1; +#if (NGX_HAVE_FSTACK) + /* Note when nginx running on fstack, + make sure that add the right fd to kqueue !! */ + c->read->belong_to_host = c->write->belong_to_host = ls[i].belong_to_host; +#endif + #if (NGX_HAVE_DEFERRED_ACCEPT) rev->deferred_accept = ls[i].deferred_accept; #endif diff --git a/app/nginx-1.11.10/src/event/ngx_event.h b/app/nginx-1.11.10/src/event/ngx_event.h index 86d3046aa..9c055c370 100644 --- a/app/nginx-1.11.10/src/event/ngx_event.h +++ b/app/nginx-1.11.10/src/event/ngx_event.h @@ -142,6 +142,10 @@ struct ngx_event_s { uint32_t padding[NGX_EVENT_T_PADDING]; #endif #endif + +#if (NGX_HAVE_FSTACK) + unsigned belong_to_host:1; +#endif }; @@ -198,7 +202,9 @@ extern ngx_event_actions_t ngx_event_actions; #if (NGX_HAVE_EPOLLRDHUP) extern ngx_uint_t ngx_use_epoll_rdhup; #endif - +#if (NGX_HAVE_FSTACK) +extern ngx_event_actions_t ngx_ff_host_event_actions; +#endif /* * The event filter requires to read/write the whole data: @@ -407,6 +413,47 @@ extern ngx_uint_t ngx_use_epoll_rdhup; #define NGX_CLEAR_EVENT 0 /* dummy declaration */ #endif +#if (NGX_HAVE_FSTACK) + +static inline ngx_int_t +ngx_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) { + if (1 == ev->belong_to_host) { + return ngx_ff_host_event_actions.add(ev, event, flags); + } else { + return ngx_event_actions.add(ev, event, flags); + } +} + +static inline ngx_int_t +ngx_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) { + if (1 == ev->belong_to_host) { + return ngx_ff_host_event_actions.del(ev, event, flags); + } else { + return ngx_event_actions.del(ev, event, flags); + } +} + +static inline ngx_int_t ngx_add_conn(ngx_connection_t *c) +{ + return ngx_event_actions.add_conn(c); +} + +static inline ngx_int_t ngx_del_conn( + ngx_connection_t *c, ngx_uint_t flags) { + return ngx_event_actions.del_conn(c, flags); +} + +static inline ngx_int_t ngx_notify(ngx_event_handler_pt handler) { + return ngx_event_actions.notify(handler); +} + +static inline ngx_int_t ngx_process_events( + ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags) +{ + return ngx_event_actions.process_events(cycle, timer, flags); +} + +#else #define ngx_process_events ngx_event_actions.process_events #define ngx_done_events ngx_event_actions.done @@ -418,6 +465,8 @@ extern ngx_uint_t ngx_use_epoll_rdhup; #define ngx_notify ngx_event_actions.notify +#endif + #define ngx_add_timer ngx_event_add_timer #define ngx_del_timer ngx_event_del_timer diff --git a/app/nginx-1.11.10/src/event/ngx_event_accept.c b/app/nginx-1.11.10/src/event/ngx_event_accept.c index 91f109c57..ca1077a08 100644 --- a/app/nginx-1.11.10/src/event/ngx_event_accept.c +++ b/app/nginx-1.11.10/src/event/ngx_event_accept.c @@ -230,6 +230,10 @@ ngx_event_accept(ngx_event_t *ev) rev = c->read; wev = c->write; +#if (NGX_HAVE_FSTACK) + rev->belong_to_host = wev->belong_to_host = ev->belong_to_host; +#endif + wev->ready = 1; if (ngx_event_flags & NGX_USE_IOCP_EVENT) { @@ -296,7 +300,11 @@ ngx_event_accept(ngx_event_t *ev) } #endif +#if (NGX_HAVE_FSTACK) + if (ngx_event_actions.add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) { +#else if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) { +#endif if (ngx_add_conn(c) == NGX_ERROR) { ngx_close_accepted_connection(c); return; @@ -432,6 +440,7 @@ ngx_event_recvmsg(ngx_event_t *ev) - ngx_cycle->free_connection_n; c = ngx_get_connection(lc->fd, ev->log); + if (c == NULL) { return; } diff --git a/app/nginx-1.11.10/src/event/ngx_event_connect.c b/app/nginx-1.11.10/src/event/ngx_event_connect.c index c5bb80681..5662094c1 100644 --- a/app/nginx-1.11.10/src/event/ngx_event_connect.c +++ b/app/nginx-1.11.10/src/event/ngx_event_connect.c @@ -181,7 +181,11 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); +#if (NGX_HAVE_FSTACK) + if (ngx_event_actions.add_conn) { +#else if (ngx_add_conn) { +#endif if (ngx_add_conn(c) == NGX_ERROR) { goto failed; } @@ -233,7 +237,11 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) } } +#if (NGX_HAVE_FSTACK) + if (ngx_event_actions.add_conn) { +#else if (ngx_add_conn) { +#endif if (rc == -1) { /* NGX_EINPROGRESS */ diff --git a/app/nginx-1.11.10/src/event/ngx_event_posted.c b/app/nginx-1.11.10/src/event/ngx_event_posted.c index d851f3d14..d6f52c19a 100644 --- a/app/nginx-1.11.10/src/event/ngx_event_posted.c +++ b/app/nginx-1.11.10/src/event/ngx_event_posted.c @@ -13,6 +13,11 @@ ngx_queue_t ngx_posted_accept_events; ngx_queue_t ngx_posted_events; +#if (NGX_HAVE_FSTACK) +ngx_queue_t ngx_posted_accept_events_of_host; +ngx_queue_t ngx_posted_events_of_host; +#endif + void ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted) diff --git a/app/nginx-1.11.10/src/event/ngx_event_posted.h b/app/nginx-1.11.10/src/event/ngx_event_posted.h index 145d30fea..9280f56dd 100644 --- a/app/nginx-1.11.10/src/event/ngx_event_posted.h +++ b/app/nginx-1.11.10/src/event/ngx_event_posted.h @@ -14,6 +14,34 @@ #include +#if (NGX_HAVE_FSTACK) +#define ngx_post_event(ev, q) \ + \ + if (!(ev)->posted) { \ + (ev)->posted = 1; \ + if (1 == (ev)->belong_to_host) { \ + if (q == &ngx_posted_events) { \ + ngx_queue_insert_tail( \ + &ngx_posted_events_of_host, &(ev)->queue); \ + } else if (q == &ngx_posted_accept_events) { \ + ngx_queue_insert_tail( \ + &ngx_posted_accept_events_of_host, &(ev)->queue); \ + } else { \ + ngx_log_error(NGX_LOG_EMERG, (ev)->log, 0, \ + "ngx_post_event: unkowned posted queue"); \ + exit(1); \ + } \ + } else { \ + ngx_queue_insert_tail(q, &(ev)->queue); \ + } \ + \ + ngx_log_debug1(NGX_LOG_DEBUG_CORE, (ev)->log, 0, "post event %p", ev);\ + \ + } else { \ + ngx_log_debug1(NGX_LOG_DEBUG_CORE, (ev)->log, 0, \ + "update posted event %p", ev); \ + } +#else #define ngx_post_event(ev, q) \ \ if (!(ev)->posted) { \ @@ -26,6 +54,7 @@ ngx_log_debug1(NGX_LOG_DEBUG_CORE, (ev)->log, 0, \ "update posted event %p", ev); \ } +#endif #define ngx_delete_posted_event(ev) \ @@ -44,5 +73,9 @@ void ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted); extern ngx_queue_t ngx_posted_accept_events; extern ngx_queue_t ngx_posted_events; +#if (NGX_HAVE_FSTACK) +extern ngx_queue_t ngx_posted_accept_events_of_host; +extern ngx_queue_t ngx_posted_events_of_host; +#endif #endif /* _NGX_EVENT_POSTED_H_INCLUDED_ */ diff --git a/app/nginx-1.11.10/src/event/ngx_event_timer.c b/app/nginx-1.11.10/src/event/ngx_event_timer.c index 8f547b215..dab2168a2 100644 --- a/app/nginx-1.11.10/src/event/ngx_event_timer.c +++ b/app/nginx-1.11.10/src/event/ngx_event_timer.c @@ -13,6 +13,11 @@ ngx_rbtree_t ngx_event_timer_rbtree; static ngx_rbtree_node_t ngx_event_timer_sentinel; +#if (NGX_HAVE_FSTACK) +ngx_rbtree_t ngx_event_timer_rbtree_of_host; +static ngx_rbtree_node_t ngx_event_timer_sentinel_of_host; +#endif + /* * the event timer rbtree may contain the duplicate keys, however, * it should not be a problem, because we use the rbtree to find @@ -25,22 +30,54 @@ ngx_event_timer_init(ngx_log_t *log) ngx_rbtree_init(&ngx_event_timer_rbtree, &ngx_event_timer_sentinel, ngx_rbtree_insert_timer_value); +#if (NGX_HAVE_FSTACK) + + ngx_rbtree_init(&ngx_event_timer_rbtree_of_host, &ngx_event_timer_sentinel_of_host, + ngx_rbtree_insert_timer_value); + +#endif + return NGX_OK; } +#if (NGX_HAVE_FSTACK) + +ngx_msec_t +ngx_event_find_timer_internal( + ngx_rbtree_t *rbtree, ngx_rbtree_node_t *sentinel); ngx_msec_t ngx_event_find_timer(void) { + return ngx_event_find_timer_internal(&ngx_event_timer_rbtree, &ngx_event_timer_sentinel); +} + +ngx_msec_t +ngx_event_find_timer_of_host(void) +{ + return ngx_event_find_timer_internal(&ngx_event_timer_rbtree_of_host, &ngx_event_timer_sentinel_of_host); +} + +ngx_msec_t +ngx_event_find_timer_internal( + ngx_rbtree_t *rbtree, ngx_rbtree_node_t *rbtree_sentinel) +{ +#else +ngx_msec_t +ngx_event_find_timer(void) +{ + ngx_rbtree_t * rbtree = &ngx_event_timer_rbtree; + ngx_rbtree_node_t *rbtree_sentinel = &ngx_event_timer_sentinel; +#endif ngx_msec_int_t timer; ngx_rbtree_node_t *node, *root, *sentinel; - if (ngx_event_timer_rbtree.root == &ngx_event_timer_sentinel) { + if (rbtree->root == rbtree_sentinel) { return NGX_TIMER_INFINITE; } - root = ngx_event_timer_rbtree.root; - sentinel = ngx_event_timer_rbtree.sentinel; + root = rbtree->root; + sentinel = rbtree->sentinel; node = ngx_rbtree_min(root, sentinel); @@ -50,16 +87,39 @@ ngx_event_find_timer(void) } +#if (NGX_HAVE_FSTACK) + +void +ngx_event_expire_timers_internal(ngx_rbtree_t *rbtree); + void ngx_event_expire_timers(void) { + ngx_event_expire_timers_internal(&ngx_event_timer_rbtree); +} + +void +ngx_event_expire_timers_of_host(void) +{ + ngx_event_expire_timers_internal(&ngx_event_timer_rbtree_of_host); +} + +void +ngx_event_expire_timers_internal(ngx_rbtree_t *rbtree) +{ +#else +void +ngx_event_expire_timers(void) +{ + ngx_rbtree_t * rbtree = &ngx_event_timer_rbtree; +#endif ngx_event_t *ev; ngx_rbtree_node_t *node, *root, *sentinel; - sentinel = ngx_event_timer_rbtree.sentinel; + sentinel = rbtree->sentinel; for ( ;; ) { - root = ngx_event_timer_rbtree.root; + root = rbtree->root; if (root == sentinel) { return; @@ -79,7 +139,7 @@ ngx_event_expire_timers(void) "event timer del: %d: %M", ngx_event_ident(ev->data), ev->timer.key); - ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer); + ngx_rbtree_delete(rbtree, &ev->timer); #if (NGX_DEBUG) ev->timer.left = NULL; @@ -96,16 +156,39 @@ ngx_event_expire_timers(void) } +#if (NGX_HAVE_FSTACK) + +void +ngx_event_cancel_timers_internal(ngx_rbtree_t *rbtree); + void ngx_event_cancel_timers(void) { + ngx_event_cancel_timers_internal(&ngx_event_timer_rbtree); +} + +void +ngx_event_cancel_timers_of_host(void) +{ + ngx_event_cancel_timers_internal(&ngx_event_timer_rbtree_of_host); +} + +void +ngx_event_cancel_timers_internal(ngx_rbtree_t *rbtree) +{ +#else +void +ngx_event_cancel_timers(void) +{ + ngx_rbtree_t * rbtree = &ngx_event_timer_rbtree; +#endif ngx_event_t *ev; ngx_rbtree_node_t *node, *root, *sentinel; - sentinel = ngx_event_timer_rbtree.sentinel; + sentinel = rbtree->sentinel; for ( ;; ) { - root = ngx_event_timer_rbtree.root; + root = rbtree->root; if (root == sentinel) { return; @@ -123,7 +206,7 @@ ngx_event_cancel_timers(void) "event timer cancel: %d: %M", ngx_event_ident(ev->data), ev->timer.key); - ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer); + ngx_rbtree_delete(rbtree, &ev->timer); #if (NGX_DEBUG) ev->timer.left = NULL; diff --git a/app/nginx-1.11.10/src/event/ngx_event_timer.h b/app/nginx-1.11.10/src/event/ngx_event_timer.h index 99f8a48fb..533b11134 100644 --- a/app/nginx-1.11.10/src/event/ngx_event_timer.h +++ b/app/nginx-1.11.10/src/event/ngx_event_timer.h @@ -27,6 +27,9 @@ void ngx_event_cancel_timers(void); extern ngx_rbtree_t ngx_event_timer_rbtree; +#if (NGX_HAVE_FSTACK) +extern ngx_rbtree_t ngx_event_timer_rbtree_of_host; +#endif static ngx_inline void ngx_event_del_timer(ngx_event_t *ev) @@ -35,8 +38,20 @@ ngx_event_del_timer(ngx_event_t *ev) "event timer del: %d: %M", ngx_event_ident(ev->data), ev->timer.key); +#if (NGX_HAVE_FSTACK) + + if(ev->belong_to_host){ + ngx_rbtree_delete(&ngx_event_timer_rbtree_of_host, &ev->timer); + } else { + ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer); + } + +#else + ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer); +#endif + #if (NGX_DEBUG) ev->timer.left = NULL; ev->timer.right = NULL; @@ -81,8 +96,20 @@ ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer) "event timer add: %d: %M:%M", ngx_event_ident(ev->data), timer, ev->timer.key); +#if (NGX_HAVE_FSTACK) + + if(ev->belong_to_host){ + ngx_rbtree_insert(&ngx_event_timer_rbtree_of_host, &ev->timer); + } else { + ngx_rbtree_insert(&ngx_event_timer_rbtree, &ev->timer); + } + +#else + ngx_rbtree_insert(&ngx_event_timer_rbtree, &ev->timer); +#endif + ev->timer_set = 1; } diff --git a/app/nginx-1.11.10/src/http/ngx_http.c b/app/nginx-1.11.10/src/http/ngx_http.c index c036389a8..bac1698b6 100644 --- a/app/nginx-1.11.10/src/http/ngx_http.c +++ b/app/nginx-1.11.10/src/http/ngx_http.c @@ -1775,6 +1775,10 @@ ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr) ls->reuseport = addr->opt.reuseport; #endif +#if (NGX_HAVE_FSTACK) + ls->belong_to_host = cscf->kernel_network_stack; +#endif + return ls; } diff --git a/app/nginx-1.11.10/src/http/ngx_http_core_module.c b/app/nginx-1.11.10/src/http/ngx_http_core_module.c index 9e128908a..5bb6591e3 100644 --- a/app/nginx-1.11.10/src/http/ngx_http_core_module.c +++ b/app/nginx-1.11.10/src/http/ngx_http_core_module.c @@ -293,6 +293,17 @@ static ngx_command_t ngx_http_core_commands[] = { 0, NULL }, +#if (NGX_HAVE_FSTACK) + + { ngx_string("kernel_network_stack"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_core_srv_conf_t, kernel_network_stack), + NULL }, + +#endif + { ngx_string("types_hash_max_size"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_num_slot, @@ -3444,6 +3455,7 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf) cscf->ignore_invalid_headers = NGX_CONF_UNSET; cscf->merge_slashes = NGX_CONF_UNSET; cscf->underscores_in_headers = NGX_CONF_UNSET; + cscf->kernel_network_stack = NGX_CONF_UNSET; return cscf; } @@ -3487,6 +3499,12 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_value(conf->underscores_in_headers, prev->underscores_in_headers, 0); +#if (NGX_HAVE_FSTACK) + /* By default, we set up a server on fstack */ + ngx_conf_merge_value(conf->kernel_network_stack, + prev->kernel_network_stack, 0); +#endif + if (conf->server_names.nelts == 0) { /* the array has 4 empty preallocated elements, so push cannot fail */ sn = ngx_array_push(&conf->server_names); diff --git a/app/nginx-1.11.10/src/http/ngx_http_core_module.h b/app/nginx-1.11.10/src/http/ngx_http_core_module.h index 5018da09a..55b02a7ba 100644 --- a/app/nginx-1.11.10/src/http/ngx_http_core_module.h +++ b/app/nginx-1.11.10/src/http/ngx_http_core_module.h @@ -199,6 +199,10 @@ typedef struct { ngx_flag_t merge_slashes; ngx_flag_t underscores_in_headers; +#if (NGX_HAVE_FSTACK) + ngx_flag_t kernel_network_stack; /* kernel_network_stack */ +#endif + unsigned listen:1; #if (NGX_PCRE) unsigned captures:1; diff --git a/app/nginx-1.11.10/src/mail/ngx_mail.c b/app/nginx-1.11.10/src/mail/ngx_mail.c index 9e560bb7c..e3bd0f646 100644 --- a/app/nginx-1.11.10/src/mail/ngx_mail.c +++ b/app/nginx-1.11.10/src/mail/ngx_mail.c @@ -345,6 +345,10 @@ ngx_mail_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports) ls->ipv6only = addr[i].opt.ipv6only; #endif +#if (NGX_HAVE_FSTACK) + ls->belong_to_host = cscf->kernel_network_stack; +#endif + mport = ngx_palloc(cf->pool, sizeof(ngx_mail_port_t)); if (mport == NULL) { return NGX_CONF_ERROR; diff --git a/app/nginx-1.11.10/src/mail/ngx_mail.h b/app/nginx-1.11.10/src/mail/ngx_mail.h index 600250820..9711d529a 100644 --- a/app/nginx-1.11.10/src/mail/ngx_mail.h +++ b/app/nginx-1.11.10/src/mail/ngx_mail.h @@ -112,6 +112,10 @@ typedef struct { ngx_str_t server_name; +#if (NGX_HAVE_FSTACK) + ngx_flag_t kernel_network_stack; /* kernel_network_stack */ +#endif + u_char *file_name; ngx_uint_t line; diff --git a/app/nginx-1.11.10/src/mail/ngx_mail_core_module.c b/app/nginx-1.11.10/src/mail/ngx_mail_core_module.c index b974d905c..fc8876d36 100644 --- a/app/nginx-1.11.10/src/mail/ngx_mail_core_module.c +++ b/app/nginx-1.11.10/src/mail/ngx_mail_core_module.c @@ -64,6 +64,17 @@ static ngx_command_t ngx_mail_core_commands[] = { offsetof(ngx_mail_core_srv_conf_t, server_name), NULL }, +#if (NGX_HAVE_FSTACK) + + { ngx_string("kernel_network_stack"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_core_srv_conf_t, kernel_network_stack), + NULL }, + +#endif + { ngx_string("error_log"), NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE, ngx_mail_core_error_log, @@ -167,6 +178,9 @@ ngx_mail_core_create_srv_conf(ngx_conf_t *cf) cscf->file_name = cf->conf_file->file.name.data; cscf->line = cf->conf_file->line; +#if (NGX_HAVE_FSTACK) + cscf->kernel_network_stack = NGX_CONF_UNSET; +#endif return cscf; } @@ -206,6 +220,12 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_ptr_value(conf->resolver, prev->resolver, NULL); +#if (NGX_HAVE_FSTACK) + /* By default, we set up a server on fstack */ + ngx_conf_merge_value(conf->kernel_network_stack, + prev->kernel_network_stack, 0); +#endif + return NGX_CONF_OK; } diff --git a/app/nginx-1.11.10/src/os/unix/ngx_channel.c b/app/nginx-1.11.10/src/os/unix/ngx_channel.c index 1efa0667c..efeed0dcc 100644 --- a/app/nginx-1.11.10/src/os/unix/ngx_channel.c +++ b/app/nginx-1.11.10/src/os/unix/ngx_channel.c @@ -223,7 +223,11 @@ ngx_add_channel_event(ngx_cycle_t *cycle, ngx_fd_t fd, ngx_int_t event, ev->handler = handler; +#if (NGX_HAVE_FSTACK) + if (ngx_event_actions.add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) { +#else if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) { +#endif if (ngx_add_conn(c) == NGX_ERROR) { ngx_free_connection(c); return NGX_ERROR; diff --git a/app/nginx-1.11.10/src/os/unix/ngx_process_cycle.c b/app/nginx-1.11.10/src/os/unix/ngx_process_cycle.c index ea4f20838..e0997e310 100644 --- a/app/nginx-1.11.10/src/os/unix/ngx_process_cycle.c +++ b/app/nginx-1.11.10/src/os/unix/ngx_process_cycle.c @@ -737,9 +737,7 @@ ngx_master_process_exit(ngx_cycle_t *cycle) } } -#if (!NGX_HAVE_FSTACK) ngx_close_listening_sockets(cycle); -#endif /* * Copy ngx_cycle->log related data to the special static exit cycle, diff --git a/app/nginx-1.11.10/src/stream/ngx_stream.c b/app/nginx-1.11.10/src/stream/ngx_stream.c index 4a394d75e..dcae0905d 100644 --- a/app/nginx-1.11.10/src/stream/ngx_stream.c +++ b/app/nginx-1.11.10/src/stream/ngx_stream.c @@ -512,6 +512,10 @@ ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports) ls->reuseport = addr[i].opt.reuseport; #endif +#if (NGX_HAVE_FSTACK) + ls->belong_to_host = cscf->kernel_network_stack; +#endif + stport = ngx_palloc(cf->pool, sizeof(ngx_stream_port_t)); if (stport == NULL) { return NGX_CONF_ERROR; diff --git a/app/nginx-1.11.10/src/stream/ngx_stream.h b/app/nginx-1.11.10/src/stream/ngx_stream.h index 814e3b99a..6c13bea32 100644 --- a/app/nginx-1.11.10/src/stream/ngx_stream.h +++ b/app/nginx-1.11.10/src/stream/ngx_stream.h @@ -185,6 +185,10 @@ typedef struct { ngx_msec_t proxy_protocol_timeout; +#if (NGX_HAVE_FSTACK) + ngx_flag_t kernel_network_stack; /* kernel_network_stack */ +#endif + ngx_uint_t listen; /* unsigned listen:1; */ } ngx_stream_core_srv_conf_t; diff --git a/app/nginx-1.11.10/src/stream/ngx_stream_core_module.c b/app/nginx-1.11.10/src/stream/ngx_stream_core_module.c index f7870eed5..49592de23 100644 --- a/app/nginx-1.11.10/src/stream/ngx_stream_core_module.c +++ b/app/nginx-1.11.10/src/stream/ngx_stream_core_module.c @@ -56,6 +56,17 @@ static ngx_command_t ngx_stream_core_commands[] = { 0, NULL }, +#if (NGX_HAVE_FSTACK) + + { ngx_string("kernel_network_stack"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_core_srv_conf_t, kernel_network_stack), + NULL }, + +#endif + { ngx_string("error_log"), NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE, ngx_stream_core_error_log, @@ -425,6 +436,9 @@ ngx_stream_core_create_srv_conf(ngx_conf_t *cf) cscf->tcp_nodelay = NGX_CONF_UNSET; cscf->preread_buffer_size = NGX_CONF_UNSET_SIZE; cscf->preread_timeout = NGX_CONF_UNSET_MSEC; +#if (NGX_HAVE_FSTACK) + cscf->kernel_network_stack = NGX_CONF_UNSET; +#endif return cscf; } @@ -483,6 +497,12 @@ ngx_stream_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_msec_value(conf->preread_timeout, prev->preread_timeout, 30000); +#if (NGX_HAVE_FSTACK) + /* By default, we set up a server on fstack */ + ngx_conf_merge_value(conf->kernel_network_stack, + prev->kernel_network_stack, 0); +#endif + return NGX_CONF_OK; } diff --git a/freebsd/kern/kern_descrip.c b/freebsd/kern/kern_descrip.c index 04532bf22..1b95631eb 100644 --- a/freebsd/kern/kern_descrip.c +++ b/freebsd/kern/kern_descrip.c @@ -4134,5 +4134,13 @@ ff_fdused_range(int max) fdalloc(td, 0, &result); } +int +ff_getmaxfd(void) +{ + struct thread *td = curthread; + return getmaxfd(td); + +} + #endif diff --git a/lib/ff_api.h b/lib/ff_api.h index 97f460662..0e1639560 100644 --- a/lib/ff_api.h +++ b/lib/ff_api.h @@ -117,6 +117,7 @@ int ff_gettimeofday(struct timeval *tv, struct timezone *tz); /* Tests if fd is used by F-Stack */ extern int ff_fdisused(int fd); +extern int ff_getmaxfd(void); /* route api begin */ enum FF_ROUTE_CTL { diff --git a/lib/ff_api.symlist b/lib/ff_api.symlist index d3ba841d7..6fc14595f 100644 --- a/lib/ff_api.symlist +++ b/lib/ff_api.symlist @@ -43,4 +43,5 @@ ff_route_ctl ff_rtioctl ff_gettimeofday ff_fdisused +ff_getmaxfd ff_ngctl diff --git a/lib/include/sys/filedesc.h b/lib/include/sys/filedesc.h index 96a0f613e..d5814ef24 100644 --- a/lib/include/sys/filedesc.h +++ b/lib/include/sys/filedesc.h @@ -32,5 +32,6 @@ void ff_fdused_range(int max); int ff_fdisused(int fd); +int ff_getmaxfd(void); #endif /* _FSTACK_SYS_FILEDESC_H_ */