Simplify startup arguments and add ff_fdisused.

Changes:
1.Simplify f-stack startup arguments:"--conf, --proc-type, --proc-id".
2.add a function `ff_fdisused` to check if fd is used in f-stack.
This commit is contained in:
logwang 2017-08-08 22:36:49 +08:00
parent a090190f3c
commit a02c88d651
32 changed files with 714 additions and 698 deletions

View File

@ -26,7 +26,11 @@ endif
DEBUG= -g DEBUG= -g
BINARY = libmt.a BINARY = libmt.a
FF_LIB=$(FF_PATH)/libfstack.a FF_LIB=$(FF_PATH)/libfstack.a
DPDK_LIBS = $(shell pkg-config --define-variable=TOPDIR=${FF_PATH} --libs f-stack.pc) DPDK_LIBS+= -L${FF_PATH}/lib -L${FF_DPDK}/lib -Wl,--whole-archive,-lfstack,--no-whole-archive
DPDK_LIBS+= -Wl,--whole-archive -lrte_pmd_vmxnet3_uio -lrte_pmd_i40e -lrte_pmd_ixgbe -lrte_pmd_e1000 -lrte_pmd_ring
DPDK_LIBS+= -Wl,--whole-archive -lrte_hash -lrte_kvargs -Wl,-lrte_mbuf -lethdev -lrte_eal -Wl,-lrte_mempool
DPDK_LIBS+= -lrte_ring -lrte_cmdline -lrte_cfgfile -lrte_kni -lrte_timer -Wl,-lrte_pmd_virtio
DPDK_LIBS+= -Wl,--no-whole-archive -lrt -lm -ldl -lcrypto -pthread
# Comment the following line if you are not using the gnu c compiler # Comment the following line if you are not using the gnu c compiler
#C_ARGS = -Wall -g -fPIC -D_DEBUG #C_ARGS = -Wall -g -fPIC -D_DEBUG

View File

@ -97,6 +97,6 @@ int echo_server()
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
mt_init_frame("./config.ini", argc, argv); mt_init_frame(argc, argv);
echo_server(); echo_server();
} }

View File

@ -1,7 +0,0 @@
DPDK = ${TOPDIR}/dpdk/x86_64-native-linuxapp-gcc
Name: F-Stack
Description: F-Stack pkg-config pc
Version: 1.0
Libs: -L${TOPDIR}/lib -Wl,--whole-archive,-lfstack,--no-whole-archive -Wl,--no-as-needed -fvisibility=default -pthread -lm -lrt -L${DPDK}/lib -Wl,--whole-archive -lrte_pmd_vmxnet3_uio -lrte_pmd_i40e -lrte_pmd_ixgbe -lrte_pmd_e1000 -lrte_pmd_ring -Wl,--whole-archive -lrte_hash -lrte_kvargs -Wl,-lrte_mbuf -lethdev -lrte_eal -Wl,-lrte_mempool -lrte_ring -lrte_cmdline -lrte_cfgfile -lrte_kni -lrte_timer -Wl,-lrte_pmd_virtio -Wl,--no-whole-archive -lrt -lm -ldl -lcrypto
Cflags: -Wall -Werror -include ${DPDK}/include/rte_config.h -I${DPDK}/include -march=native -DRTE_MACHINE_CPUFLAG_SSE -DRTE_MACHINE_CPUFLAG_SSE2 -DRTE_MACHINE_CPUFLAG_SSE3 -DRTE_MACHINE_CPUFLAG_SSSE3 -DRTE_MACHINE_CPUFLAG_SSE4_1 -DRTE_MACHINE_CPUFLAG_SSE4_2 -DRTE_COMPILE_TIME_CPUFLAGS=RTE_CPUFLAG_SSE,RTE_CPUFLAG_SSE2,RTE_CPUFLAG_SSE3,RTE_CPUFLAG_SSSE3,RTE_CPUFLAG_SSE4_1,RTE_CPUFLAG_SSE4_2

View File

@ -34,55 +34,17 @@
#include "mt_sys_hook.h" #include "mt_sys_hook.h"
#include "ff_hook.h" #include "ff_hook.h"
/*
void ff_hook_new_fd(int fd)
{
if (fd < 0 || fd >= ff_HOOK_MAX_FD) {
return;
}
g_ff_hook_fd_tab[fd] = 1;
}
bool ff_hook_find_fd(int fd) {
if (fd < 0 || fd >= ff_HOOK_MAX_FD) {
return false;
}
if (g_ff_hook_fd_tab[fd] == 1) {
return true;
} else {
return false;
}
}
void ff_hook_free_fd(int fd)
{
if (fd < 0 || fd >= ff_HOOK_MAX_FD) {
return;
}
g_ff_hook_fd_tab[fd] = 0;
}
*/
int ff_hook_socket(int domain, int type, int protocol) int ff_hook_socket(int domain, int type, int protocol)
{ {
if (!ff_hook_active() || (AF_INET != domain) || (SOCK_STREAM != type && SOCK_DGRAM != type)) { if ((AF_INET != domain) || (SOCK_STREAM != type && SOCK_DGRAM != type)) {
return mt_real_func(socket)(domain, type, protocol); return mt_real_func(socket)(domain, type, protocol);
} }
int fd = ff_socket(domain, type, protocol); return ff_socket(domain, type, protocol);
if (fd >= 0) {
fd |= 1 << FF_FD_BITS;
}
return fd;
} }
int ff_hook_close(int fd) int ff_hook_close(int fd)
{ {
if (CHK_FD_BIT(fd)) { if (ff_fdisused(fd)) {
fd = CLR_FD_BIT(fd);
return ff_close(fd); return ff_close(fd);
} else { } else {
return mt_real_func(close)(fd); return mt_real_func(close)(fd);
@ -91,8 +53,7 @@ int ff_hook_close(int fd)
int ff_hook_connect(int fd, const struct sockaddr *address, socklen_t addrlen_len) int ff_hook_connect(int fd, const struct sockaddr *address, socklen_t addrlen_len)
{ {
if (CHK_FD_BIT(fd)) { if (ff_fdisused(fd)) {
fd = CLR_FD_BIT(fd);
return ff_connect(fd, (struct linux_sockaddr *)address, addrlen_len); return ff_connect(fd, (struct linux_sockaddr *)address, addrlen_len);
} else { } else {
return mt_real_func(connect)(fd, address, addrlen_len); return mt_real_func(connect)(fd, address, addrlen_len);
@ -101,8 +62,7 @@ int ff_hook_connect(int fd, const struct sockaddr *address, socklen_t addrlen_le
ssize_t ff_hook_read(int fd, void *buf, size_t nbyte) ssize_t ff_hook_read(int fd, void *buf, size_t nbyte)
{ {
if (CHK_FD_BIT(fd)) { if (ff_fdisused(fd)) {
fd = CLR_FD_BIT(fd);
return ff_read(fd, buf, nbyte); return ff_read(fd, buf, nbyte);
} else { } else {
return mt_real_func(read)(fd, buf, nbyte); return mt_real_func(read)(fd, buf, nbyte);
@ -111,8 +71,7 @@ ssize_t ff_hook_read(int fd, void *buf, size_t nbyte)
ssize_t ff_hook_write(int fd, const void *buf, size_t nbyte) ssize_t ff_hook_write(int fd, const void *buf, size_t nbyte)
{ {
if (CHK_FD_BIT(fd)) { if (ff_fdisused(fd)) {
fd = CLR_FD_BIT(fd);
return ff_write(fd, buf, nbyte); return ff_write(fd, buf, nbyte);
} else { } else {
return mt_real_func(write)(fd, buf, nbyte); return mt_real_func(write)(fd, buf, nbyte);
@ -121,8 +80,7 @@ ssize_t ff_hook_write(int fd, const void *buf, size_t nbyte)
ssize_t ff_hook_sendto(int fd, const void *message, size_t length, int flags, ssize_t ff_hook_sendto(int fd, const void *message, size_t length, int flags,
const struct sockaddr *dest_addr, socklen_t dest_len) const struct sockaddr *dest_addr, socklen_t dest_len)
{ {
if (CHK_FD_BIT(fd)) { if (ff_fdisused(fd)) {
fd = CLR_FD_BIT(fd);
return ff_sendto(fd, message, length, flags, (struct linux_sockaddr *)dest_addr, dest_len); return ff_sendto(fd, message, length, flags, (struct linux_sockaddr *)dest_addr, dest_len);
} else { } else {
return mt_real_func(sendto)(fd, message, length, flags, dest_addr, dest_len); return mt_real_func(sendto)(fd, message, length, flags, dest_addr, dest_len);
@ -131,8 +89,7 @@ ssize_t ff_hook_sendto(int fd, const void *message, size_t length, int flags,
ssize_t ff_hook_recvfrom(int fd, void *buffer, size_t length, int flags, ssize_t ff_hook_recvfrom(int fd, void *buffer, size_t length, int flags,
struct sockaddr *address, socklen_t *address_len) struct sockaddr *address, socklen_t *address_len)
{ {
if (CHK_FD_BIT(fd)) { if (ff_fdisused(fd)) {
fd = CLR_FD_BIT(fd);
return ff_recvfrom(fd, buffer, length, flags, (struct linux_sockaddr *)address, address_len); return ff_recvfrom(fd, buffer, length, flags, (struct linux_sockaddr *)address, address_len);
} else { } else {
return mt_real_func(recvfrom)(fd, buffer, length, flags, address, address_len); return mt_real_func(recvfrom)(fd, buffer, length, flags, address, address_len);
@ -140,8 +97,7 @@ ssize_t ff_hook_recvfrom(int fd, void *buffer, size_t length, int flags,
} }
ssize_t ff_hook_recv(int fd, void *buffer, size_t length, int flags) ssize_t ff_hook_recv(int fd, void *buffer, size_t length, int flags)
{ {
if (CHK_FD_BIT(fd)) { if (ff_fdisused(fd)) {
fd = CLR_FD_BIT(fd);
return ff_recv(fd, buffer, length, flags); return ff_recv(fd, buffer, length, flags);
} else { } else {
return mt_real_func(recv)(fd, buffer, length, flags); return mt_real_func(recv)(fd, buffer, length, flags);
@ -149,8 +105,7 @@ ssize_t ff_hook_recv(int fd, void *buffer, size_t length, int flags)
} }
ssize_t ff_hook_send(int fd, const void *buf, size_t nbyte, int flags) ssize_t ff_hook_send(int fd, const void *buf, size_t nbyte, int flags)
{ {
if (CHK_FD_BIT(fd)) { if (ff_fdisused(fd)) {
fd = CLR_FD_BIT(fd);
return ff_send(fd, buf, nbyte, flags); return ff_send(fd, buf, nbyte, flags);
} else { } else {
return mt_real_func(send)(fd, buf, nbyte, flags); return mt_real_func(send)(fd, buf, nbyte, flags);
@ -159,8 +114,7 @@ ssize_t ff_hook_send(int fd, const void *buf, size_t nbyte, int flags)
} }
int ff_hook_setsockopt(int fd, int level, int option_name, const void *option_value, socklen_t option_len) int ff_hook_setsockopt(int fd, int level, int option_name, const void *option_value, socklen_t option_len)
{ {
if (CHK_FD_BIT(fd)) { if (ff_fdisused(fd)) {
fd = CLR_FD_BIT(fd);
return ff_setsockopt(fd, level, option_name, option_value, option_len); return ff_setsockopt(fd, level, option_name, option_value, option_len);
} else { } else {
return mt_real_func(setsockopt)(fd, level, option_name, option_value, option_len); return mt_real_func(setsockopt)(fd, level, option_name, option_value, option_len);
@ -169,8 +123,7 @@ int ff_hook_setsockopt(int fd, int level, int option_name, const void *option_va
int ff_hook_ioctl(int fd, int cmd, void *arg) int ff_hook_ioctl(int fd, int cmd, void *arg)
{ {
if (CHK_FD_BIT(fd)) { if (ff_fdisused(fd)) {
fd = CLR_FD_BIT(fd);
return ff_ioctl(fd, cmd, arg); return ff_ioctl(fd, cmd, arg);
} else { } else {
return mt_real_func(ioctl)(fd, cmd, arg); return mt_real_func(ioctl)(fd, cmd, arg);
@ -179,8 +132,7 @@ int ff_hook_ioctl(int fd, int cmd, void *arg)
int ff_hook_fcntl(int fd, int cmd, void *arg) int ff_hook_fcntl(int fd, int cmd, void *arg)
{ {
if (CHK_FD_BIT(fd)) { if (ff_fdisused(fd)) {
fd = CLR_FD_BIT(fd);
return ff_fcntl(fd, cmd, arg); return ff_fcntl(fd, cmd, arg);
} else { } else {
return mt_real_func(fcntl)(fd, cmd, arg); return mt_real_func(fcntl)(fd, cmd, arg);
@ -189,8 +141,7 @@ int ff_hook_fcntl(int fd, int cmd, void *arg)
int ff_hook_listen(int fd, int backlog) int ff_hook_listen(int fd, int backlog)
{ {
if (CHK_FD_BIT(fd)) { if (ff_fdisused(fd)) {
fd = CLR_FD_BIT(fd);
return ff_listen(fd, backlog); return ff_listen(fd, backlog);
} else { } else {
return mt_real_func(listen)(fd, backlog); return mt_real_func(listen)(fd, backlog);
@ -199,8 +150,7 @@ int ff_hook_listen(int fd, int backlog)
int ff_hook_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) int ff_hook_bind(int fd, const struct sockaddr *addr, socklen_t addrlen)
{ {
if (CHK_FD_BIT(fd)) { if (ff_fdisused(fd)) {
fd = CLR_FD_BIT(fd);
return ff_bind(fd, (struct linux_sockaddr *)addr, addrlen); return ff_bind(fd, (struct linux_sockaddr *)addr, addrlen);
} else { } else {
return mt_real_func(bind)(fd, addr, addrlen); return mt_real_func(bind)(fd, addr, addrlen);
@ -208,14 +158,8 @@ int ff_hook_bind(int fd, const struct sockaddr *addr, socklen_t addrlen)
} }
int ff_hook_accept(int fd, struct sockaddr *addr, socklen_t *addrlen) int ff_hook_accept(int fd, struct sockaddr *addr, socklen_t *addrlen)
{ {
if (CHK_FD_BIT(fd)) { if (ff_fdisused(fd)) {
fd = CLR_FD_BIT(fd); return ff_accept(fd, (struct linux_sockaddr *)addr, addrlen);
int c = ff_accept(fd, (struct linux_sockaddr *)addr, addrlen);
if (c < 0) {
return c;
}
c |= 1 << FF_FD_BITS;
return c;
} else { } else {
return mt_real_func(accept)(fd, addr, addrlen); return mt_real_func(accept)(fd, addr, addrlen);
} }

View File

@ -22,14 +22,6 @@
#include <stdint.h> #include <stdint.h>
#define FF_FD_BITS 16
#define CHK_FD_BIT(fd) (fd & (1 << FF_FD_BITS))
#define CLR_FD_BIT(fd) (fd & ~(1 << FF_FD_BITS))
void ff_hook_new_fd(int fd);
bool ff_hook_find_fd(int fd);
void ff_hook_free_fd(int fd);
int ff_hook_socket(int domain, int type, int protocol); int ff_hook_socket(int domain, int type, int protocol);
int ff_hook_close(int fd); int ff_hook_close(int fd);

View File

@ -187,9 +187,6 @@ bool KqueueProxy::KqueueCtrlAdd(int fd, int events)
KqEvent ke; KqEvent ke;
int ret; int ret;
if (CHK_FD_BIT(fd)) {
fd = CLR_FD_BIT(fd);
}
if (old_events & KQ_EVENT_WRITE) { if (old_events & KQ_EVENT_WRITE) {
EV_SET(&ke, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); EV_SET(&ke, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL); ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL);
@ -274,9 +271,6 @@ bool KqueueProxy::KqueueCtrlDelRef(int fd, int events, bool use_ref)
} }
KqEvent ke; KqEvent ke;
int ret; int ret;
if (CHK_FD_BIT(fd)) {
fd = CLR_FD_BIT(fd);
}
if (old_events & KQ_EVENT_WRITE) { if (old_events & KQ_EVENT_WRITE) {
EV_SET(&ke, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); EV_SET(&ke, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL); ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL);
@ -380,7 +374,7 @@ void KqueueProxy::KqueueRcvEventList(int evtfdnum)
for (int i = 0; i < evtfdnum; i++) for (int i = 0; i < evtfdnum; i++)
{ {
osfd = _evtlist[i].ident |= 1 << FF_FD_BITS; osfd = _evtlist[i].ident;
item = KqFdRefGet(osfd); item = KqFdRefGet(osfd);
if (item == NULL) if (item == NULL)

View File

@ -716,10 +716,10 @@ void* mt_get_msg_private()
* @info 使spp线 * @info 使spp线
* @return false: true: * @return false: true:
*/ */
bool mt_init_frame(const char *conf, int argc, char * const argv[]) bool mt_init_frame(int argc, char * const argv[])
{ {
if (conf && argc) { if (argc) {
ff_init(conf, argc, argv); ff_init(argc, argv);
ff_set_hook_flag(); ff_set_hook_flag();
} }
memset(&g_mt_syscall_tab, 0, sizeof(g_mt_syscall_tab)); memset(&g_mt_syscall_tab, 0, sizeof(g_mt_syscall_tab));

View File

@ -296,7 +296,7 @@ void* mt_get_msg_private();
* 使sppSyncFrame的框架初始化函数即可 * 使sppSyncFrame的框架初始化函数即可
* @return false: true: * @return false: true:
*/ */
bool mt_init_frame(const char *conf=NULL, int argc=0, char * const argv[]=NULL); bool mt_init_frame(int argc=0, char * const argv[]=NULL);
/** /**
* @brief 线 * @brief 线

View File

@ -239,7 +239,7 @@ int main(int argc, char* argv[])
addr.sin_addr.s_addr = inet_addr("112.90.143.29"); addr.sin_addr.s_addr = inet_addr("112.90.143.29");
addr.sin_port = htons(19999); addr.sin_port = htons(19999);
mt_init_frame("./config.ini", argc, argv); mt_init_frame(argc, argv);
mt_start_thread((void*)server,NULL); mt_start_thread((void*)server,NULL);

View File

@ -122,7 +122,7 @@ int ioctl(int fd, unsigned long cmd, ...)
mt_hook_syscall(ioctl); mt_hook_syscall(ioctl);
MtHookFd* hook_fd = mt_hook_find_fd(fd); MtHookFd* hook_fd = mt_hook_find_fd(fd);
if (!mt_hook_active() || !hook_fd) if (!mt_hook_active() || !hook_fd || !ff_hook_active())
{ {
return ff_hook_ioctl(fd, cmd, arg); return ff_hook_ioctl(fd, cmd, arg);
} }
@ -145,9 +145,9 @@ int socket(int domain, int type, int protocol)
{ {
mt_hook_syscall(socket); mt_hook_syscall(socket);
if (!mt_hook_active()) if (!ff_hook_active())
{ {
return ff_hook_socket(domain, type, protocol); return mt_real_func(socket)(domain, type, protocol);
} }
int fd = ff_hook_socket(domain, type, protocol); int fd = ff_hook_socket(domain, type, protocol);
@ -158,7 +158,6 @@ int socket(int domain, int type, int protocol)
mt_hook_new_fd(fd); mt_hook_new_fd(fd);
mt_hook_syscall(ioctl); mt_hook_syscall(ioctl);
int nb = 1; int nb = 1;
ff_hook_ioctl(fd, FIONBIO, &nb); ff_hook_ioctl(fd, FIONBIO, &nb);
@ -172,9 +171,9 @@ int socket(int domain, int type, int protocol)
int close(int fd) int close(int fd)
{ {
mt_hook_syscall(close); mt_hook_syscall(close);
if (!mt_hook_active()) if (!ff_hook_active())
{ {
return ff_hook_close(fd); return mt_real_func(close)(fd);
} }
mt_hook_free_fd(fd); mt_hook_free_fd(fd);
@ -189,9 +188,9 @@ int connect(int fd, const struct sockaddr *address, socklen_t address_len)
{ {
mt_hook_syscall(connect); mt_hook_syscall(connect);
MtHookFd* hook_fd = mt_hook_find_fd(fd); MtHookFd* hook_fd = mt_hook_find_fd(fd);
if (!mt_hook_active() || !hook_fd) if (!mt_hook_active() || !hook_fd || !ff_hook_active())
{ {
return ff_hook_connect(fd, address, address_len); return mt_real_func(connect)(fd, address, address_len);
} }
if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK) if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK)
@ -209,9 +208,9 @@ ssize_t read(int fd, void *buf, size_t nbyte)
{ {
mt_hook_syscall(read); mt_hook_syscall(read);
MtHookFd* hook_fd = mt_hook_find_fd(fd); MtHookFd* hook_fd = mt_hook_find_fd(fd);
if (!mt_hook_active() || !hook_fd) if (!mt_hook_active() || !hook_fd || !ff_hook_active())
{ {
return ff_hook_read(fd, buf, nbyte); return mt_real_func(read)(fd, buf, nbyte);
} }
if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK) if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK)
@ -229,9 +228,9 @@ ssize_t write(int fd, const void *buf, size_t nbyte)
{ {
mt_hook_syscall(write); mt_hook_syscall(write);
MtHookFd* hook_fd = mt_hook_find_fd(fd); MtHookFd* hook_fd = mt_hook_find_fd(fd);
if (!mt_hook_active() || !hook_fd) if (!mt_hook_active() || !hook_fd || !ff_hook_active())
{ {
return ff_hook_write(fd, buf, nbyte); return mt_real_func(write)(fd, buf, nbyte);
} }
if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK) if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK)
@ -250,9 +249,9 @@ ssize_t sendto(int fd, const void *message, size_t length, int flags,
{ {
mt_hook_syscall(sendto); mt_hook_syscall(sendto);
MtHookFd* hook_fd = mt_hook_find_fd(fd); MtHookFd* hook_fd = mt_hook_find_fd(fd);
if (!mt_hook_active() || !hook_fd) if (!mt_hook_active() || !hook_fd || !ff_hook_active())
{ {
return ff_hook_sendto(fd, message, length, flags, dest_addr, dest_len); return mt_real_func(sendto)(fd, message, length, flags, dest_addr, dest_len);
} }
if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK) if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK)
@ -272,9 +271,9 @@ ssize_t recvfrom(int fd, void *buffer, size_t length, int flags,
{ {
mt_hook_syscall(recvfrom); mt_hook_syscall(recvfrom);
MtHookFd* hook_fd = mt_hook_find_fd(fd); MtHookFd* hook_fd = mt_hook_find_fd(fd);
if (!mt_hook_active() || !hook_fd) if (!mt_hook_active() || !hook_fd || !ff_hook_active())
{ {
return ff_hook_recvfrom(fd, buffer, length, flags, address, address_len); return mt_real_func(recvfrom)(fd, buffer, length, flags, address, address_len);
} }
if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK) if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK)
@ -293,9 +292,9 @@ ssize_t recv(int fd, void *buffer, size_t length, int flags)
{ {
mt_hook_syscall(recv); mt_hook_syscall(recv);
MtHookFd* hook_fd = mt_hook_find_fd(fd); MtHookFd* hook_fd = mt_hook_find_fd(fd);
if (!mt_hook_active() || !hook_fd) if (!mt_hook_active() || !hook_fd || !ff_hook_active())
{ {
return ff_hook_recv(fd, buffer, length, flags); return mt_real_func(recv)(fd, buffer, length, flags);
} }
if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK) if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK)
@ -313,9 +312,9 @@ ssize_t send(int fd, const void *buf, size_t nbyte, int flags)
{ {
mt_hook_syscall(send); mt_hook_syscall(send);
MtHookFd* hook_fd = mt_hook_find_fd(fd); MtHookFd* hook_fd = mt_hook_find_fd(fd);
if (!mt_hook_active() || !hook_fd) if (!mt_hook_active() || !hook_fd || !ff_hook_active())
{ {
return ff_hook_send(fd, buf, nbyte, flags); return mt_real_func(send)(fd, buf, nbyte, flags);
} }
if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK) if (hook_fd->sock_flag & MT_FD_FLG_UNBLOCK)
@ -334,9 +333,9 @@ int setsockopt(int fd, int level, int option_name, const void *option_value, soc
{ {
mt_hook_syscall(setsockopt); mt_hook_syscall(setsockopt);
MtHookFd* hook_fd = mt_hook_find_fd(fd); MtHookFd* hook_fd = mt_hook_find_fd(fd);
if (!mt_hook_active() || !hook_fd) if (!mt_hook_active() || !hook_fd || !ff_hook_active())
{ {
return ff_hook_setsockopt(fd, level, option_name, option_value, option_len); return mt_real_func(setsockopt)(fd, level, option_name, option_value, option_len);
} }
if (SOL_SOCKET == level) if (SOL_SOCKET == level)
@ -369,9 +368,9 @@ int fcntl(int fd, int cmd, ...)
mt_hook_syscall(fcntl); mt_hook_syscall(fcntl);
MtHookFd* hook_fd = mt_hook_find_fd(fd); MtHookFd* hook_fd = mt_hook_find_fd(fd);
if (!mt_hook_active() || !hook_fd) if (!mt_hook_active() || !hook_fd || !ff_hook_active())
{ {
return ff_hook_fcntl(fd, cmd, arg); return mt_real_func(fcntl)(fd, cmd, arg);
} }
if (cmd == F_SETFL) if (cmd == F_SETFL)
@ -393,18 +392,33 @@ int fcntl(int fd, int cmd, ...)
int listen(int sockfd, int backlog) int listen(int sockfd, int backlog)
{ {
mt_hook_syscall(listen); mt_hook_syscall(listen);
if (!ff_hook_active())
{
return mt_real_func(listen)(sockfd, backlog);
}
return ff_hook_listen(sockfd, backlog); return ff_hook_listen(sockfd, backlog);
} }
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{ {
mt_hook_syscall(bind); mt_hook_syscall(bind);
if (!ff_hook_active())
{
return mt_real_func(bind)(sockfd, addr, addrlen);
}
return ff_hook_bind(sockfd, addr, addrlen); return ff_hook_bind(sockfd, addr, addrlen);
} }
int accept(int fd, struct sockaddr *addr, socklen_t *addrlen) int accept(int fd, struct sockaddr *addr, socklen_t *addrlen)
{ {
mt_hook_syscall(accept); mt_hook_syscall(accept);
if (!ff_hook_active())
{
return mt_real_func(accept)(fd, addr, addrlen);
}
return ff_hook_accept(fd, addr, addrlen); return ff_hook_accept(fd, addr, addrlen);
} }

View File

@ -1,40 +1,62 @@
/* /*
* Inspired by nginx_ofp's ngx_ofp_module.c. * Inspired by opendp/dpdk-nginx's ans_module.c.
* https://github.com/OpenFastPath/nginx_ofp. * License of opendp:
* But According to #42, nginx_ofp's ngx_ofp_module.c may be derived from https://github.com/opendp/dpdk-nginx/blob/master/src/event/modules/ans_module.c, *
* so add a license of opendp/dpdk-nginx. BSD LICENSE
Copyright(c) 2015-2017 Ansyun anssupport@163.com. All rights reserved.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
Neither the name of Ansyun anssupport@163.com nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Author: JiaKai (jiakai1000@gmail.com) and Bluestar (anssupport@163.com)
*/ */
/*- /*
BSD LICENSE * Copyright (C) 2017 THL A29 Limited, a Tencent company.
Copyright(c) 2015-2017 Ansyun anssupport@163.com. All rights reserved. * All rights reserved.
All rights reserved. *
Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions are met:
are met: *
* 1. Redistributions of source code must retain the above copyright notice, this
Redistributions of source code must retain the above copyright * list of conditions and the following disclaimer.
notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice,
Redistributions in binary form must reproduce the above copyright * this list of conditions and the following disclaimer in the documentation
notice, this list of conditions and the following disclaimer in * and/or other materials provided with the distribution.
the documentation and/or other materials provided with the *
distribution. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
Neither the name of Ansyun anssupport@163.com nor the names of its * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
contributors may be used to endorse or promote products derived * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
from this software without specific prior written permission. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Author: JiaKai (jiakai1000@gmail.com) and Bluestar (anssupport@163.com)
*/
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
@ -64,9 +86,17 @@ Author: JiaKai (jiakai1000@gmail.com) and Bluestar (anssupport@163.com)
#include <sys/syscall.h> #include <sys/syscall.h>
#include <dlfcn.h> #include <dlfcn.h>
#define FF_FD_BITS 16 #ifndef likely
#define CHK_FD_BIT(fd) (fd & (1 << FF_FD_BITS)) #define likely(x) __builtin_expect((x),1)
#define CLR_FD_BIT(fd) (fd & ~(1 << FF_FD_BITS)) #endif
#ifndef unlikely
#define unlikely(x) __builtin_expect((x),0)
#endif
#define INIT_FUNCTION(func) \
real_##func = dlsym(RTLD_NEXT, #func); \
assert(real_##func)
static int (*real_close)(int); static int (*real_close)(int);
static int (*real_socket)(int, int, int); static int (*real_socket)(int, int, int);
@ -89,14 +119,12 @@ static int (*real_ioctl)(int, int, void *);
static int (*real_select) (int, fd_set *, fd_set *, fd_set *, struct timeval *); static int (*real_select) (int, fd_set *, fd_set *, fd_set *, struct timeval *);
static int inited;
void void
ff_mod_init(int argc, char * const *argv) { ff_mod_init(int argc, char * const *argv) {
int rc; int rc;
#define INIT_FUNCTION(func) \
real_##func = dlsym(RTLD_NEXT, #func); \
assert(real_##func)
INIT_FUNCTION(socket); INIT_FUNCTION(socket);
INIT_FUNCTION(bind); INIT_FUNCTION(bind);
INIT_FUNCTION(connect); INIT_FUNCTION(connect);
@ -115,12 +143,10 @@ ff_mod_init(int argc, char * const *argv) {
INIT_FUNCTION(ioctl); INIT_FUNCTION(ioctl);
INIT_FUNCTION(select); INIT_FUNCTION(select);
#undef INIT_FUNCTION rc = ff_init(argc, argv);
assert(argc >= 2);
rc = ff_init(argv[1], argc, argv);
assert(0 == rc); assert(0 == rc);
inited = 1;
} }
int int
@ -128,14 +154,17 @@ socket(int domain, int type, int protocol)
{ {
int rc; int rc;
if (unlikely(inited == 0)) {
INIT_FUNCTION(socket);
return real_socket(domain, type, protocol);
}
if ((AF_INET != domain) || (SOCK_STREAM != type && SOCK_DGRAM != type)) { if ((AF_INET != domain) || (SOCK_STREAM != type && SOCK_DGRAM != type)) {
rc = real_socket(domain, type, protocol); rc = real_socket(domain, type, protocol);
return rc; return rc;
} }
rc = ff_socket(domain, type, protocol); rc = ff_socket(domain, type, protocol);
if(rc >= 0)
rc |= 1 << FF_FD_BITS;
return rc; return rc;
} }
@ -143,8 +172,12 @@ socket(int domain, int type, int protocol)
int int
bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(bind);
return real_bind(sockfd, addr, addrlen);
}
if (ff_fdisused(sockfd)) {
return ff_bind(sockfd, (struct linux_sockaddr *)addr, addrlen); return ff_bind(sockfd, (struct linux_sockaddr *)addr, addrlen);
} else { } else {
return real_bind(sockfd, addr, addrlen); return real_bind(sockfd, addr, addrlen);
@ -154,8 +187,12 @@ bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
int int
connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(connect);
return real_connect(sockfd, addr, addrlen);
}
if (ff_fdisused(sockfd)) {
return ff_connect(sockfd, (struct linux_sockaddr *)addr, addrlen); return ff_connect(sockfd, (struct linux_sockaddr *)addr, addrlen);
} else { } else {
return real_connect(sockfd, addr, addrlen); return real_connect(sockfd, addr, addrlen);
@ -165,8 +202,12 @@ connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
ssize_t ssize_t
send(int sockfd, const void *buf, size_t len, int flags) send(int sockfd, const void *buf, size_t len, int flags)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(send);
return real_send(sockfd, buf, len, flags);
}
if (ff_fdisused(sockfd)) {
return ff_send(sockfd, buf, len, flags); return ff_send(sockfd, buf, len, flags);
} else { } else {
return real_send(sockfd, buf, len, flags); return real_send(sockfd, buf, len, flags);
@ -177,10 +218,14 @@ ssize_t
sendto(int sockfd, const void *buf, size_t len, int flags, sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen) const struct sockaddr *dest_addr, socklen_t addrlen)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(sendto);
return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
}
if (ff_fdisused(sockfd)) {
return ff_sendto(sockfd, buf, len, flags, return ff_sendto(sockfd, buf, len, flags,
(struct linux_sockaddr *)dest_addr, addrlen); (struct linux_sockaddr *)dest_addr, addrlen);
} else { } else {
return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen); return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
} }
@ -189,8 +234,12 @@ sendto(int sockfd, const void *buf, size_t len, int flags,
ssize_t ssize_t
sendmsg(int sockfd, const struct msghdr *msg, int flags) sendmsg(int sockfd, const struct msghdr *msg, int flags)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(sendmsg);
return real_sendmsg(sockfd, msg, flags);
}
if (ff_fdisused(sockfd)) {
return ff_sendmsg(sockfd, msg, flags); return ff_sendmsg(sockfd, msg, flags);
} else { } else {
return real_sendmsg(sockfd, msg, flags); return real_sendmsg(sockfd, msg, flags);
@ -200,8 +249,12 @@ sendmsg(int sockfd, const struct msghdr *msg, int flags)
ssize_t ssize_t
recv(int sockfd, void *buf, size_t len, int flags) recv(int sockfd, void *buf, size_t len, int flags)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(recv);
return real_recv(sockfd, buf, len, flags);
}
if (ff_fdisused(sockfd)) {
return ff_recv(sockfd, buf, len, flags); return ff_recv(sockfd, buf, len, flags);
} else { } else {
return real_recv(sockfd, buf, len, flags); return real_recv(sockfd, buf, len, flags);
@ -211,8 +264,12 @@ recv(int sockfd, void *buf, size_t len, int flags)
int int
listen(int sockfd, int backlog) listen(int sockfd, int backlog)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(listen);
return real_listen(sockfd, backlog);
}
if (ff_fdisused(sockfd)) {
return ff_listen(sockfd, backlog); return ff_listen(sockfd, backlog);
} else { } else {
return real_listen(sockfd, backlog); return real_listen(sockfd, backlog);
@ -223,8 +280,12 @@ int
setsockopt (int sockfd, int level, int optname, setsockopt (int sockfd, int level, int optname,
const void *optval, socklen_t optlen) const void *optval, socklen_t optlen)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(setsockopt);
return real_setsockopt(sockfd, level, optname, optval, optlen);
}
if (ff_fdisused(sockfd)) {
return ff_setsockopt(sockfd, level, optname, optval, optlen); return ff_setsockopt(sockfd, level, optname, optval, optlen);
} else { } else {
return real_setsockopt(sockfd, level, optname, optval, optlen); return real_setsockopt(sockfd, level, optname, optval, optlen);
@ -234,14 +295,13 @@ setsockopt (int sockfd, int level, int optname,
int int
accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(accept);
int fd = ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen); return real_accept(sockfd, addr, addrlen);
if (fd < 0) { }
return fd;
} if (ff_fdisused(sockfd)) {
fd |= 1 << FF_FD_BITS; return ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen);
return fd;
} else { } else {
return real_accept(sockfd, addr, addrlen); return real_accept(sockfd, addr, addrlen);
} }
@ -250,8 +310,12 @@ accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
int int
accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(accept4);
return real_accept4(sockfd, addr, addrlen, flags);
}
if (ff_fdisused(sockfd)) {
return ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen); return ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen);
} else { } else {
return real_accept4(sockfd, addr, addrlen, flags); return real_accept4(sockfd, addr, addrlen, flags);
@ -261,13 +325,14 @@ accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
int int
close(int sockfd) close(int sockfd)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(close);
return real_close(sockfd);
}
if (ff_fdisused(sockfd)) {
return ff_close(sockfd); return ff_close(sockfd);
} else { } else {
if (__builtin_expect(!!(real_close == NULL), 0)) {
real_close = dlsym(RTLD_NEXT, "close");
}
return real_close(sockfd); return real_close(sockfd);
} }
} }
@ -275,8 +340,12 @@ close(int sockfd)
ssize_t ssize_t
writev(int sockfd, const struct iovec *iov, int iovcnt) writev(int sockfd, const struct iovec *iov, int iovcnt)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(writev);
return real_writev(sockfd, iov, iovcnt);
}
if (ff_fdisused(sockfd)) {
return ff_writev(sockfd, iov, iovcnt); return ff_writev(sockfd, iov, iovcnt);
} else { } else {
return real_writev(sockfd, iov, iovcnt); return real_writev(sockfd, iov, iovcnt);
@ -286,8 +355,12 @@ writev(int sockfd, const struct iovec *iov, int iovcnt)
ssize_t ssize_t
readv(int sockfd, const struct iovec *iov, int iovcnt) readv(int sockfd, const struct iovec *iov, int iovcnt)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(readv);
return real_readv(sockfd, iov, iovcnt);
}
if (ff_fdisused(sockfd)) {
return ff_readv(sockfd, iov, iovcnt); return ff_readv(sockfd, iov, iovcnt);
} else { } else {
return real_readv(sockfd, iov, iovcnt); return real_readv(sockfd, iov, iovcnt);
@ -297,8 +370,12 @@ readv(int sockfd, const struct iovec *iov, int iovcnt)
int int
ioctl(int sockfd, int request, void *p) ioctl(int sockfd, int request, void *p)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(ioctl);
return real_ioctl(sockfd, request, p);
}
if (ff_fdisused(sockfd)) {
return ff_ioctl(sockfd, request, p); return ff_ioctl(sockfd, request, p);
} else { } else {
return real_ioctl(sockfd, request, p); return real_ioctl(sockfd, request, p);
@ -309,8 +386,12 @@ int
select(int nfds, fd_set *readfds, fd_set *writefds, select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout) fd_set *exceptfds, struct timeval *timeout)
{ {
if (CHK_FD_BIT(nfds)) { if (unlikely(inited == 0)) {
nfds = CLR_FD_BIT(nfds); INIT_FUNCTION(select);
return real_select(nfds, readfds, writefds, exceptfds, timeout);
}
if (ff_fdisused(nfds)) {
struct timeval tv; struct timeval tv;
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = 0; tv.tv_usec = 0;

View File

@ -51,10 +51,6 @@ static struct kevent notify_kev;
#endif #endif
#if (NGX_HAVE_FSTACK) #if (NGX_HAVE_FSTACK)
#define FF_FD_BITS 16
#define CHK_FD_BIT(fd) (fd & (1 << FF_FD_BITS))
#define CLR_FD_BIT(fd) (fd & ~(1 << FF_FD_BITS))
extern int kqueue(void); extern int kqueue(void);
extern int kevent(int kq, const struct kevent *changelist, int nchanges, extern int kevent(int kq, const struct kevent *changelist, int nchanges,
struct kevent *eventlist, int nevents, const struct timespec *timeout); struct kevent *eventlist, int nevents, const struct timespec *timeout);
@ -430,15 +426,7 @@ ngx_kqueue_set_event(ngx_event_t *ev, ngx_int_t filter, ngx_uint_t flags)
kev = &change_list[nchanges]; kev = &change_list[nchanges];
#if (NGX_HAVE_FSTACK)
ngx_socket_t fd = c->fd;
if (CHK_FD_BIT(fd))
fd = CLR_FD_BIT(fd);
kev->ident = fd;
#else
kev->ident = c->fd; kev->ident = c->fd;
#endif
kev->filter = (short) filter; kev->filter = (short) filter;
kev->flags = (u_short) flags; kev->flags = (u_short) flags;
kev->udata = NGX_KQUEUE_UDATA_T ((uintptr_t) ev | ev->instance); kev->udata = NGX_KQUEUE_UDATA_T ((uintptr_t) ev | ev->instance);
@ -593,9 +581,6 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
} }
for (i = 0; i < events; i++) { for (i = 0; i < events; i++) {
#if (NGX_HAVE_FSTACK)
event_list[i].ident |= 1 << FF_FD_BITS;
#endif
ngx_kqueue_dump_event(cycle->log, &event_list[i]); ngx_kqueue_dump_event(cycle->log, &event_list[i]);
if (event_list[i].flags & EV_ERROR) { if (event_list[i].flags & EV_ERROR) {

View File

@ -72,12 +72,6 @@ ngx_module_t ngx_select_module = {
NGX_MODULE_V1_PADDING NGX_MODULE_V1_PADDING
}; };
#if (NGX_HAVE_FSTACK)
#define FF_FD_BITS 16
#define CHK_FD_BIT(fd) (fd & (1 << FF_FD_BITS))
#define CLR_FD_BIT(fd) (fd & ~(1 << FF_FD_BITS))
#endif
static ngx_int_t static ngx_int_t
ngx_select_init(ngx_cycle_t *cycle, ngx_msec_t timer) ngx_select_init(ngx_cycle_t *cycle, ngx_msec_t timer)
{ {
@ -154,20 +148,10 @@ ngx_select_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
} }
if (event == NGX_READ_EVENT) { if (event == NGX_READ_EVENT) {
#if (NGX_HAVE_FSTACK)
if (CHK_FD_BIT(c->fd))
FD_SET(CLR_FD_BIT(c->fd), &master_read_fd_set);
#else
FD_SET(c->fd, &master_read_fd_set); FD_SET(c->fd, &master_read_fd_set);
#endif
} else if (event == NGX_WRITE_EVENT) { } else if (event == NGX_WRITE_EVENT) {
#if (NGX_HAVE_FSTACK)
if (CHK_FD_BIT(c->fd))
FD_SET(CLR_FD_BIT(c->fd), &master_write_fd_set);
#else
FD_SET(c->fd, &master_write_fd_set); FD_SET(c->fd, &master_write_fd_set);
#endif
} }
if (max_fd != -1 && max_fd < c->fd) { if (max_fd != -1 && max_fd < c->fd) {
@ -202,20 +186,10 @@ ngx_select_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
"select del event fd:%d ev:%i", c->fd, event); "select del event fd:%d ev:%i", c->fd, event);
if (event == NGX_READ_EVENT) { if (event == NGX_READ_EVENT) {
#if (NGX_HAVE_FSTACK)
if (CHK_FD_BIT(c->fd))
FD_CLR(CLR_FD_BIT(c->fd), &master_read_fd_set);
#else
FD_CLR(c->fd, &master_read_fd_set); FD_CLR(c->fd, &master_read_fd_set);
#endif
} else if (event == NGX_WRITE_EVENT) { } else if (event == NGX_WRITE_EVENT) {
#if (NGX_HAVE_FSTACK)
if (CHK_FD_BIT(c->fd))
FD_CLR(CLR_FD_BIT(c->fd), &master_write_fd_set);
#else
FD_CLR(c->fd, &master_write_fd_set); FD_CLR(c->fd, &master_write_fd_set);
#endif
} }
if (max_fd == c->fd) { if (max_fd == c->fd) {

View File

@ -139,11 +139,6 @@ void aeStop(aeEventLoop *eventLoop) {
int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask, int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,
aeFileProc *proc, void *clientData) aeFileProc *proc, void *clientData)
{ {
#ifdef HAVE_FF_KQUEUE
if (CHK_FD_BIT(fd)) {
fd = CLR_FD_BIT(fd);
}
#endif
if (fd >= eventLoop->setsize) { if (fd >= eventLoop->setsize) {
errno = ERANGE; errno = ERANGE;
return AE_ERR; return AE_ERR;
@ -163,11 +158,6 @@ int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,
void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask) void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask)
{ {
#ifdef HAVE_FF_KQUEUE
if (CHK_FD_BIT(fd)) {
fd = CLR_FD_BIT(fd);
}
#endif
if (fd >= eventLoop->setsize) return; if (fd >= eventLoop->setsize) return;
aeFileEvent *fe = &eventLoop->events[fd]; aeFileEvent *fe = &eventLoop->events[fd];
if (fe->mask == AE_NONE) return; if (fe->mask == AE_NONE) return;
@ -415,11 +405,7 @@ int aeProcessEvents(aeEventLoop *eventLoop, int flags)
for (j = 0; j < numevents; j++) { for (j = 0; j < numevents; j++) {
aeFileEvent *fe = &eventLoop->events[eventLoop->fired[j].fd]; aeFileEvent *fe = &eventLoop->events[eventLoop->fired[j].fd];
int mask = eventLoop->fired[j].mask; int mask = eventLoop->fired[j].mask;
#ifdef HAVE_FF_KQUEUE
int fd = eventLoop->fired[j].fd | (1 << FF_FD_BITS);
#else
int fd = eventLoop->fired[j].fd; int fd = eventLoop->fired[j].fd;
#endif
int rfired = 0; int rfired = 0;
/* note the fe->mask & mask & ... code: maybe an already processed /* note the fe->mask & mask & ... code: maybe an already processed

View File

@ -35,10 +35,6 @@ typedef unsigned short u_short;
typedef unsigned int u_int; typedef unsigned int u_int;
#include "ff_api.h" #include "ff_api.h"
#define FF_FD_BITS 16
#define CHK_FD_BIT(fd) (fd & (1 << FF_FD_BITS))
#define CLR_FD_BIT(fd) (fd & ~(1 << FF_FD_BITS))
typedef struct aeApiState { typedef struct aeApiState {
int kqfd; int kqfd;
struct kevent *events; struct kevent *events;

View File

@ -1,39 +1,62 @@
/* /*
* Inspired by nginx_ofp's ngx_ofp_module.c. * Inspired by opendp/dpdk-nginx's ans_module.c.
* https://github.com/OpenFastPath/nginx_ofp. * License of opendp:
* Related #42. *
BSD LICENSE
Copyright(c) 2015-2017 Ansyun anssupport@163.com. All rights reserved.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
Neither the name of Ansyun anssupport@163.com nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Author: JiaKai (jiakai1000@gmail.com) and Bluestar (anssupport@163.com)
*/ */
/*- /*
BSD LICENSE * Copyright (C) 2017 THL A29 Limited, a Tencent company.
Copyright(c) 2015-2017 Ansyun anssupport@163.com. All rights reserved. * All rights reserved.
All rights reserved. *
Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions are met:
are met: *
* 1. Redistributions of source code must retain the above copyright notice, this
Redistributions of source code must retain the above copyright * list of conditions and the following disclaimer.
notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice,
Redistributions in binary form must reproduce the above copyright * this list of conditions and the following disclaimer in the documentation
notice, this list of conditions and the following disclaimer in * and/or other materials provided with the distribution.
the documentation and/or other materials provided with the *
distribution. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
Neither the name of Ansyun anssupport@163.com nor the names of its * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
contributors may be used to endorse or promote products derived * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
from this software without specific prior written permission. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Author: JiaKai (jiakai1000@gmail.com) and Bluestar (anssupport@163.com)
*/
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
@ -64,9 +87,20 @@ typedef unsigned int u_int;
#include <sys/syscall.h> #include <sys/syscall.h>
#include <dlfcn.h> #include <dlfcn.h>
#define FF_FD_BITS 16 #pragma GCC diagnostic push
#define CHK_FD_BIT(fd) (fd & (1 << FF_FD_BITS)) #pragma GCC diagnostic ignored "-Wpedantic"
#define CLR_FD_BIT(fd) (fd & ~(1 << FF_FD_BITS))
#ifndef likely
#define likely(x) __builtin_expect((x),1)
#endif
#ifndef unlikely
#define unlikely(x) __builtin_expect((x),0)
#endif
#define INIT_FUNCTION(func) \
real_##func = dlsym(RTLD_NEXT, #func); \
assert(real_##func)
static int inited = 0; static int inited = 0;
@ -94,14 +128,6 @@ static int (*real_select) (int, fd_set *, fd_set *, fd_set *, struct timeval *);
void ff_mod_init() { void ff_mod_init() {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
//int rc;
#define INIT_FUNCTION(func) \
real_##func = dlsym(RTLD_NEXT, #func); \
assert(real_##func)
INIT_FUNCTION(socket); INIT_FUNCTION(socket);
INIT_FUNCTION(bind); INIT_FUNCTION(bind);
INIT_FUNCTION(connect); INIT_FUNCTION(connect);
@ -121,169 +147,232 @@ void ff_mod_init() {
INIT_FUNCTION(fcntl); INIT_FUNCTION(fcntl);
INIT_FUNCTION(select); INIT_FUNCTION(select);
#undef INIT_FUNCTION
inited = 1; inited = 1;
#pragma GCC diagnostic pop
} }
int socket(int domain, int type, int protocol) int
socket(int domain, int type, int protocol)
{ {
int rc; int rc;
if ((inited == 0) || (AF_INET != domain) || (SOCK_STREAM != type && SOCK_DGRAM != type)) if (unlikely(inited == 0)) {
{ INIT_FUNCTION(socket);
return real_socket(domain, type, protocol);
}
if ((AF_INET != domain) || (SOCK_STREAM != type && SOCK_DGRAM != type)) {
rc = real_socket(domain, type, protocol); rc = real_socket(domain, type, protocol);
return rc; return rc;
} }
rc = ff_socket(domain, type, protocol); rc = ff_socket(domain, type, protocol);
if(rc >= 0)
rc |= 1 << FF_FD_BITS;
return rc; return rc;
} }
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) int
bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(bind);
return real_bind(sockfd, addr, addrlen);
}
if (ff_fdisused(sockfd)) {
return ff_bind(sockfd, (struct linux_sockaddr *)addr, addrlen); return ff_bind(sockfd, (struct linux_sockaddr *)addr, addrlen);
} else { } else {
return real_bind(sockfd, addr, addrlen); return real_bind(sockfd, addr, addrlen);
} }
} }
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) int
connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(connect);
return real_connect(sockfd, addr, addrlen);
}
if (ff_fdisused(sockfd)) {
return ff_connect(sockfd, (struct linux_sockaddr *)addr, addrlen); return ff_connect(sockfd, (struct linux_sockaddr *)addr, addrlen);
} else { } else {
return real_connect(sockfd, addr, addrlen); return real_connect(sockfd, addr, addrlen);
} }
} }
ssize_t send(int sockfd, const void *buf, size_t len, int flags) ssize_t
send(int sockfd, const void *buf, size_t len, int flags)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(send);
return real_send(sockfd, buf, len, flags);
}
if (ff_fdisused(sockfd)) {
return ff_send(sockfd, buf, len, flags); return ff_send(sockfd, buf, len, flags);
} else { } else {
return real_send(sockfd, buf, len, flags); return real_send(sockfd, buf, len, flags);
} }
} }
ssize_t write(int sockfd, const void *buf, size_t count) ssize_t
recv(int sockfd, void *buf, size_t len, int flags)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(recv);
return ff_write(sockfd, buf, count); return real_recv(sockfd, buf, len, flags);
} else {
return real_write(sockfd, buf, count);
} }
}
ssize_t recv(int sockfd, void *buf, size_t len, int flags) if (ff_fdisused(sockfd)) {
{
if (CHK_FD_BIT(sockfd)) {
sockfd = CLR_FD_BIT(sockfd);
return ff_recv(sockfd, buf, len, flags); return ff_recv(sockfd, buf, len, flags);
} else { } else {
return real_recv(sockfd, buf, len, flags); return real_recv(sockfd, buf, len, flags);
} }
} }
ssize_t read(int sockfd, void *buf, size_t count) int
listen(int sockfd, int backlog)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(listen);
return ff_read(sockfd, buf, count); return real_listen(sockfd, backlog);
} else {
return real_read(sockfd, buf, count);
} }
}
int listen(int sockfd, int backlog) if (ff_fdisused(sockfd)) {
{
if (CHK_FD_BIT(sockfd)) {
sockfd = CLR_FD_BIT(sockfd);
return ff_listen(sockfd, backlog); return ff_listen(sockfd, backlog);
} else { } else {
return real_listen(sockfd, backlog); return real_listen(sockfd, backlog);
} }
} }
int setsockopt (int sockfd, int level, int optname, int
setsockopt (int sockfd, int level, int optname,
const void *optval, socklen_t optlen) const void *optval, socklen_t optlen)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(setsockopt);
return real_setsockopt(sockfd, level, optname, optval, optlen);
}
if (ff_fdisused(sockfd)) {
return ff_setsockopt(sockfd, level, optname, optval, optlen); return ff_setsockopt(sockfd, level, optname, optval, optlen);
} else { } else {
return real_setsockopt(sockfd, level, optname, optval, optlen); return real_setsockopt(sockfd, level, optname, optval, optlen);
} }
} }
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) int
accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(accept);
int fd = ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen); return real_accept(sockfd, addr, addrlen);
if (fd < 0) { }
return fd;
} if (ff_fdisused(sockfd)) {
fd |= 1 << FF_FD_BITS; return ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen);
return fd;
} else { } else {
return real_accept(sockfd, addr, addrlen); return real_accept(sockfd, addr, addrlen);
} }
} }
int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) int
accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(accept4);
return real_accept4(sockfd, addr, addrlen, flags);
}
if (ff_fdisused(sockfd)) {
return ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen); return ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen);
} else { } else {
return real_accept4(sockfd, addr, addrlen, flags); return real_accept4(sockfd, addr, addrlen, flags);
} }
} }
int close(int sockfd) int
close(int sockfd)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(close);
return real_close(sockfd);
}
if (ff_fdisused(sockfd)) {
return ff_close(sockfd); return ff_close(sockfd);
} else { } else {
return real_close(sockfd); return real_close(sockfd);
} }
} }
ssize_t writev(int sockfd, const struct iovec *iov, int iovcnt) ssize_t write(int sockfd, const void *buf, size_t count)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(write);
return real_write(sockfd, buf, count);
}
if (ff_fdisused(sockfd)) {
return ff_write(sockfd, buf, count);
} else {
return real_write(sockfd, buf, count);
}
}
ssize_t
writev(int sockfd, const struct iovec *iov, int iovcnt)
{
if (unlikely(inited == 0)) {
INIT_FUNCTION(writev);
return real_writev(sockfd, iov, iovcnt);
}
if (ff_fdisused(sockfd)) {
return ff_writev(sockfd, iov, iovcnt); return ff_writev(sockfd, iov, iovcnt);
} else { } else {
return real_writev(sockfd, iov, iovcnt); return real_writev(sockfd, iov, iovcnt);
} }
} }
ssize_t readv(int sockfd, const struct iovec *iov, int iovcnt) ssize_t read(int sockfd, void *buf, size_t count)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(read);
return real_read(sockfd, buf, count);
}
if (ff_fdisused(sockfd)) {
return ff_read(sockfd, buf, count);
} else {
return real_read(sockfd, buf, count);
}
}
ssize_t
readv(int sockfd, const struct iovec *iov, int iovcnt)
{
if (unlikely(inited == 0)) {
INIT_FUNCTION(readv);
return real_readv(sockfd, iov, iovcnt);
}
if (ff_fdisused(sockfd)) {
return ff_readv(sockfd, iov, iovcnt); return ff_readv(sockfd, iov, iovcnt);
} else { } else {
return real_readv(sockfd, iov, iovcnt); return real_readv(sockfd, iov, iovcnt);
} }
} }
int ioctl(int sockfd, int request, void *p) int
ioctl(int sockfd, int request, void *p)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(ioctl);
return real_ioctl(sockfd, request, p);
}
if (ff_fdisused(sockfd)) {
return ff_ioctl(sockfd, request, p); return ff_ioctl(sockfd, request, p);
} else { } else {
return real_ioctl(sockfd, request, p); return real_ioctl(sockfd, request, p);
@ -292,19 +381,28 @@ int ioctl(int sockfd, int request, void *p)
int fcntl(int sockfd, int cmd, void *p) int fcntl(int sockfd, int cmd, void *p)
{ {
if (CHK_FD_BIT(sockfd)) { if (unlikely(inited == 0)) {
sockfd = CLR_FD_BIT(sockfd); INIT_FUNCTION(fcntl);
return real_fcntl(sockfd, cmd, p);
}
if (ff_fdisused(sockfd)) {
return ff_fcntl(sockfd, cmd, p); return ff_fcntl(sockfd, cmd, p);
} else { } else {
return real_fcntl(sockfd, cmd, p); return real_fcntl(sockfd, cmd, p);
} }
} }
int select(int nfds, fd_set *readfds, fd_set *writefds, int
select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout) fd_set *exceptfds, struct timeval *timeout)
{ {
if (CHK_FD_BIT(nfds)) { if (unlikely(inited == 0)) {
nfds = CLR_FD_BIT(nfds); INIT_FUNCTION(select);
return real_select(nfds, readfds, writefds, exceptfds, timeout);
}
if (ff_fdisused(nfds)) {
struct timeval tv; struct timeval tv;
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = 0; tv.tv_usec = 0;
@ -314,3 +412,5 @@ int select(int nfds, fd_set *readfds, fd_set *writefds,
} }
} }
#pragma GCC diagnostic pop

View File

@ -1,68 +0,0 @@
[dpdk]
lcore_mask=1
# set lcore_mask=1, use only one processor (https://redis.io/topics/faq#redis-is-single-threaded-how-can-i-exploit-multiple-cpu--cores)
## Port mask, enable and disable ports.
## Default: all ports are enabled.
#port_mask=1
channel=4
nb_ports=1
promiscuous=1
numa_on=1
[port0]
addr=192.168.1.2
netmask=255.255.255.0
broadcast=192.168.1.255
gateway=192.168.1.1
## Packet capture path, this will hurt performance
#pcap=./a.pcap
## Kni config: if enabled and method=reject,
## all packets that do not belong to the following tcp_port and udp_port
## will transmit to kernel; if method=accept, all packets that belong to
## the following tcp_port and udp_port will transmit to kernel.
#[kni]
#enable=1
#method=reject
#tcp_port=80
#udp_port=53
[log]
level=1
dir=/var/log
## FreeBSD network performance tuning configurations.
## Most native FreeBSD configurations are supported.
[freebsd.boot]
hz=100
kern.ipc.maxsockets=262144
net.inet.tcp.syncache.hashsize=4096
net.inet.tcp.syncache.bucketlimit=100
net.inet.tcp.tcbhashsize=65536
[freebsd.sysctl]
kern.ipc.somaxconn=32768
kern.ipc.maxsockbuf=16777216
net.inet.tcp.fast_finwait2_recycle=1
net.inet.tcp.sendspace=16384
net.inet.tcp.recvspace=8192
net.inet.tcp.nolocaltimewait=1
net.inet.tcp.cc.algorithm=htcp
net.inet.tcp.sendbuf_max=16777216
net.inet.tcp.recvbuf_max=16777216
net.inet.tcp.sendbuf_auto=1
net.inet.tcp.recvbuf_auto=1
net.inet.tcp.sendbuf_inc=16384
net.inet.tcp.recvbuf_inc=524288
net.inet.tcp.inflight.enable=0
net.inet.tcp.sack=1
net.inet.tcp.blackhole=1
net.inet.tcp.msl=2000
net.inet.tcp.delayed_ack=0
net.inet.udp.blackhole=1
net.inet.ip.redirect=0

View File

@ -3954,18 +3954,22 @@ int main(int argc, char **argv) {
int j; int j;
#ifdef HAVE_FF_KQUEUE #ifdef HAVE_FF_KQUEUE
ff_mod_init(); int rc = ff_init(argc, argv);
int rc = ff_init(argv[1], argc, argv);
assert(0 == rc); assert(0 == rc);
// TODO ff_mod_init();
char **tmp_argv = zmalloc(sizeof(char *) * (argc - 6)); //split fstack arguments.
int new_argc = argc - 3;
if (new_argc <= 0) {
new_argc = 1;
}
char **new_argv = zmalloc(sizeof(char *) * new_argc);
new_argv[0] = argv[0];
int i; int i;
for (i = 0; i < argc; i++) { for (i = 1; i < new_argc; i++) {
tmp_argv[i] = argv[i + 6]; new_argv[i] = argv[i + 3];
} }
tmp_argv[0] = argv[0]; argv = new_argv;
argv = tmp_argv; argc = new_argc;
argc -= 6;
#endif #endif
#ifdef REDIS_TEST #ifdef REDIS_TEST
@ -4139,7 +4143,7 @@ int main(int argc, char **argv) {
ff_run(loop, server.el); ff_run(loop, server.el);
aeDeleteEventLoop(server.el); aeDeleteEventLoop(server.el);
#ifdef HAVE_FF_KQUEUE #ifdef HAVE_FF_KQUEUE
zfree(tmp_argv); zfree(new_argv);
#endif #endif
return 0; return 0;
} }

View File

@ -1,67 +0,0 @@
#!/bin/bash
function usage() {
echo "F-Stack app start tool"
echo "Options:"
echo " -c [conf] Path of config file"
echo " -b [N] Path of binary"
echo " -h show this help"
exit
}
conf=./config.ini
bin=./redis-server
while getopts "c:b:h" args
do
case $args in
c)
conf=$OPTARG
;;
b)
bin=$OPTARG
;;
h)
usage
exit 0
;;
esac
done
allcmask0x=`cat ${conf}|grep lcore_mask|awk -F '=' '{print $2}'`
((allcmask=16#$allcmask0x))
num_procs=0
PROCESSOR=$(grep 'processor' /proc/cpuinfo |sort |uniq |wc -l)
for((i=0;i<${PROCESSOR};++i))
do
mask=`echo "2^$i"|bc`
((result=${allcmask} & ${mask}))
if [ ${result} != 0 ]
then
((num_procs++));
cpuinfo[$i]=1
else
cpuinfo[$i]=0
fi
done
proc_id=0
for((i=0;i<${PROCESSOR};++i))
do
if ((cpuinfo[$i] == 1))
then
cmask=`echo "2^$i"|bc`
cmask=`echo "obase=16;${cmask}"|bc`
if ((proc_id == 0))
then
echo "${bin} ${conf} -c $cmask --proc-type=primary --num-procs=${num_procs} --proc-id=${proc_id}"
${bin} ${conf} -c ${cmask} --proc-type=primary --num-procs=${num_procs} --proc-id=${proc_id} ../redis.conf &
sleep 5
else
echo "${bin} ${conf} -c $cmask --proc-type=secondary --num-procs=${num_procs} --proc-id=${proc_id}"
${bin} ${conf} -c $cmask --proc-type=secondary --num-procs=${num_procs} --proc-id=${proc_id} ../redis.conf &
fi
((proc_id++))
fi
done

View File

@ -37,6 +37,11 @@ gateway=192.168.1.1
[freebsd.boot] [freebsd.boot]
hz=100 hz=100
## Block out a range of descriptors to avoid overlap
## with the kernel's descriptor space.
## You can increase this value according to your app.
fd_reserve=1024
kern.ipc.maxsockets=262144 kern.ipc.maxsockets=262144
net.inet.tcp.syncache.hashsize=4096 net.inet.tcp.syncache.hashsize=4096

View File

@ -103,14 +103,7 @@ int loop(void *arg)
int main(int argc, char * argv[]) int main(int argc, char * argv[])
{ {
char *conf; ff_init(argc, argv);
if (argc < 2) {
conf = "./config.ini";
} else {
conf = argv[1];
}
ff_init(conf, argc, argv);
int sockfd = ff_socket(AF_INET, SOCK_STREAM, 0); int sockfd = ff_socket(AF_INET, SOCK_STREAM, 0);
printf("sockfd:%d\n", sockfd); printf("sockfd:%d\n", sockfd);

View File

@ -18,9 +18,7 @@
#define MAX_EVENTS 512 #define MAX_EVENTS 512
struct epoll_event ev; struct epoll_event ev;
struct epoll_event events[MAX_EVENTS]; struct epoll_event events[MAX_EVENTS];
struct kevent kqevents[MAX_EVENTS];
int epfd; int epfd;
int sockfd; int sockfd;
@ -100,14 +98,7 @@ int loop(void *arg)
int main(int argc, char * argv[]) int main(int argc, char * argv[])
{ {
char *conf; ff_init(argc, argv);
if (argc < 2) {
conf = "./config.ini";
} else {
conf = argv[1];
}
ff_init(conf, argc, argv);
sockfd = ff_socket(AF_INET, SOCK_STREAM, 0); sockfd = ff_socket(AF_INET, SOCK_STREAM, 0);
printf("sockfd:%d\n", sockfd); printf("sockfd:%d\n", sockfd);

View File

@ -4105,4 +4105,30 @@ fildesc_drvinit(void *unused)
SYSINIT(fildescdev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, fildesc_drvinit, NULL); SYSINIT(fildescdev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, fildesc_drvinit, NULL);
#else
int
ff_fdisused(int fd)
{
struct thread *td = curthread;
return (fd < td->td_proc->p_fd->fd_nfiles &&
fdisused(td->td_proc->p_fd, fd) &&
td->td_proc->p_fd->fd_ofiles[fd].fde_file != NULL);
}
/*
* block out a range of descriptors to avoid overlap with
* the kernel's descriptor space
*/
void
ff_fdused_range(struct filedesc *fdp, int max)
{
int i;
for (i = 0; i < max; i++)
fdused(fdp, i);
}
#endif #endif

View File

@ -46,7 +46,7 @@ struct linux_sockaddr {
typedef int (*loop_func_t)(void *arg); typedef int (*loop_func_t)(void *arg);
int ff_init(const char *conf, int argc, char * const argv[]); int ff_init(int argc, char * const argv[]);
void ff_run(loop_func_t loop, void *arg); void ff_run(loop_func_t loop, void *arg);
@ -109,6 +109,9 @@ int ff_kevent_do_each(int kq, const struct kevent *changelist, int nchanges,
int ff_gettimeofday(struct timeval *tv, struct timezone *tz); int ff_gettimeofday(struct timeval *tv, struct timezone *tz);
extern int ff_fdisused(int fd);
/* route api begin */ /* route api begin */
enum FF_ROUTE_CTL { enum FF_ROUTE_CTL {
FF_ROUTE_ADD, FF_ROUTE_ADD,

View File

@ -41,3 +41,4 @@ ff_mbuf_tx_offload
ff_route_ctl ff_route_ctl
ff_rtioctl ff_rtioctl
ff_gettimeofday ff_gettimeofday
ff_fdisused

View File

@ -29,24 +29,109 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <getopt.h> #include <getopt.h>
#include <ctype.h>
#include <rte_config.h>
#include "ff_config.h" #include "ff_config.h"
#include "ff_ini_parser.h" #include "ff_ini_parser.h"
#define DEFAULT_CONFIG_FILE "config.ini"
#define BITS_PER_HEX 4
struct ff_config ff_global_cfg; struct ff_config ff_global_cfg;
int dpdk_argc; int dpdk_argc;
char *dpdk_argv[DPDK_CONFIG_NUM + 1]; char *dpdk_argv[DPDK_CONFIG_NUM + 1];
int dpdk_argc_arg; char* const short_options = "c:t:p:";
char *dpdk_argv_arg[DPDK_CONFIG_NUM + 1]; struct option long_options[] = {
{ "conf", 1, NULL, 'c'},
char* const short_options = "c:"; { "proc-type", 1, NULL, 't'},
struct option long_options[] = { { "proc-id", 1, NULL, 'p'},
{ "proc-type", 1, NULL, 0 }, { 0, 0, 0, 0},
{ "num-procs", 1, NULL, 0 },
{ "proc-id", 1, NULL, 0 },
{ 0, 0, 0, 0},
}; };
static int
xdigit2val(unsigned char c)
{
int val;
if (isdigit(c))
val = c - '0';
else if (isupper(c))
val = c - 'A' + 10;
else
val = c - 'a' + 10;
return val;
}
static int
parse_lcore_mask(struct ff_config *cfg, const char *coremask)
{
int i, j, idx = 0;
unsigned count = 0;
char c;
int val;
uint16_t *proc_lcore;
char buf[RTE_MAX_LCORE] = {0};
if (coremask == NULL)
return 0;
cfg->dpdk.proc_lcore = (uint16_t *)calloc(RTE_MAX_LCORE, sizeof(uint16_t));
if (cfg->dpdk.proc_lcore == NULL) {
fprintf(stderr, "parse_lcore_mask malloc failed\n");
return 0;
}
proc_lcore = cfg->dpdk.proc_lcore;
/*
* Remove all blank characters ahead and after.
* Remove 0x/0X if exists.
*/
while (isblank(*coremask))
coremask++;
if (coremask[0] == '0' && ((coremask[1] == 'x')
|| (coremask[1] == 'X')))
coremask += 2;
i = strlen(coremask);
while ((i > 0) && isblank(coremask[i - 1]))
i--;
if (i == 0)
return 0;
for (i = i - 1; i >= 0 && idx < RTE_MAX_LCORE; i--) {
c = coremask[i];
if (isxdigit(c) == 0) {
return 0;
}
val = xdigit2val(c);
for (j = 0; j < BITS_PER_HEX && idx < RTE_MAX_LCORE; j++, idx++) {
if ((1 << j) & val) {
proc_lcore[count] = idx;
if (cfg->dpdk.proc_id == count) {
sprintf(buf, "%x", 1<<idx);
cfg->dpdk.proc_mask = strdup(buf);
}
count++;
}
}
}
for (; i >= 0; i--)
if (coremask[i] != '0')
return 0;
if (cfg->dpdk.proc_id >= count)
return 0;
cfg->dpdk.nb_procs = count;
return 1;
}
static int static int
is_integer(const char *s) is_integer(const char *s)
{ {
@ -160,10 +245,10 @@ port_cfg_handler(struct ff_config *cfg, const char *section,
} }
static int static int
handler(void* user, const char* section, const char* name, ini_parse_handler(void* user, const char* section, const char* name,
const char* value) const char* value)
{ {
struct ff_config* pconfig = (struct ff_config*)user; struct ff_config *pconfig = (struct ff_config*)user;
printf("[%s]: %s=%s\n", section, name, value); printf("[%s]: %s=%s\n", section, name, value);
@ -176,6 +261,7 @@ handler(void* user, const char* section, const char* name,
pconfig->dpdk.no_huge = atoi(value); pconfig->dpdk.no_huge = atoi(value);
} else if (MATCH("dpdk", "lcore_mask")) { } else if (MATCH("dpdk", "lcore_mask")) {
pconfig->dpdk.lcore_mask = strdup(value); pconfig->dpdk.lcore_mask = strdup(value);
return parse_lcore_mask(pconfig, pconfig->dpdk.lcore_mask);
} else if (MATCH("dpdk", "port_mask")) { } else if (MATCH("dpdk", "port_mask")) {
pconfig->dpdk.port_mask = atoi(value); pconfig->dpdk.port_mask = atoi(value);
} else if (MATCH("dpdk", "nb_ports")) { } else if (MATCH("dpdk", "nb_ports")) {
@ -212,7 +298,7 @@ handler(void* user, const char* section, const char* name,
} }
static int static int
dpdk_argc_argv_setup(struct ff_config *cfg) dpdk_args_setup(struct ff_config *cfg)
{ {
int n = 0, i; int n = 0, i;
dpdk_argv[n++] = strdup("f-stack"); dpdk_argv[n++] = strdup("f-stack");
@ -233,9 +319,9 @@ dpdk_argc_argv_setup(struct ff_config *cfg)
sprintf(temp, "-m%d", cfg->dpdk.memory); sprintf(temp, "-m%d", cfg->dpdk.memory);
dpdk_argv[n++] = strdup(temp); dpdk_argv[n++] = strdup(temp);
} }
if (cfg->dpdk.proc_type) {
for(i = 0; i < dpdk_argc_arg; ++i) { sprintf(temp, "--proc-type=%s", cfg->dpdk.proc_type);
dpdk_argv[n++] = dpdk_argv_arg[i]; dpdk_argv[n++] = strdup(temp);
} }
dpdk_argc = n; dpdk_argc = n;
@ -243,33 +329,40 @@ dpdk_argc_argv_setup(struct ff_config *cfg)
return n; return n;
} }
static void static int
ff_load_arg(struct ff_config *cfg, int argc, char *const argv[]) ff_parse_args(struct ff_config *cfg, int argc, char *const argv[])
{ {
dpdk_argc_arg = 0;
int c; int c;
int index = 0; int index = 0;
while((c = getopt_long(argc, argv, short_options, long_options, &index)) != -1) { while((c = getopt_long(argc, argv, short_options, long_options, &index)) != -1) {
switch (c) { switch (c) {
case 'c': case 'c':
cfg->dpdk.proc_mask = strdup(optarg); cfg->filename = strdup(optarg);
break; break;
case 0: case 'p':
if (0 == strcmp(long_options[index].name, "num-procs")) { cfg->dpdk.proc_id = atoi(optarg);
cfg->dpdk.nb_procs = atoi(optarg); break;
} else if(0 == strcmp(long_options[index].name, "proc-id")) { case 't':
cfg->dpdk.proc_id = atoi(optarg); cfg->dpdk.proc_type = strdup(optarg);
} else if(0 == strcmp(long_options[index].name, "proc-type")) {
char temp[DPDK_CONFIG_MAXLEN] = {0};
sprintf(temp, "--proc-type=%s",optarg);
dpdk_argv_arg[dpdk_argc_arg++] = strdup(temp);
}
break; break;
default: default:
break; return -1;
} }
} }
return;
if (cfg->dpdk.proc_type == NULL ||
(strcmp(cfg->dpdk.proc_type, "primary") &&
strcmp(cfg->dpdk.proc_type, "secondary"))) {
printf("invalid proc-type\n");
return -1;
}
if ((uint16_t)cfg->dpdk.proc_id > RTE_MAX_LCORE) {
printf("proc_id:%d is too large\n", cfg->dpdk.proc_id);
return -1;
}
return 0;
} }
static int static int
@ -315,21 +408,31 @@ ff_default_config(struct ff_config *cfg)
{ {
memset(cfg, 0, sizeof(struct ff_config)); memset(cfg, 0, sizeof(struct ff_config));
cfg->filename = DEFAULT_CONFIG_FILE;
cfg->dpdk.proc_id = -1;
cfg->dpdk.numa_on = 1; cfg->dpdk.numa_on = 1;
cfg->dpdk.promiscuous = 1; cfg->dpdk.promiscuous = 1;
cfg->freebsd.hz = 100; cfg->freebsd.hz = 100;
cfg->freebsd.physmem = 1048576*256; cfg->freebsd.physmem = 1048576*256;
cfg->freebsd.fd_reserve = 0;
} }
int int
ff_load_config(const char *conf, int argc, char * const argv[]) ff_load_config(int argc, char *const argv[])
{ {
ff_default_config(&ff_global_cfg); ff_default_config(&ff_global_cfg);
int ret = ini_parse(conf, handler, &ff_global_cfg); int ret = ff_parse_args(&ff_global_cfg, argc, argv);
if (ret < 0) {
return ret;
}
ret = ini_parse(ff_global_cfg.filename, ini_parse_handler,
&ff_global_cfg);
if (ret != 0) { if (ret != 0) {
printf("parse %s failed on line %d\n", conf, ret); printf("parse %s failed on line %d\n", ff_global_cfg.filename, ret);
return -1; return -1;
} }
@ -337,8 +440,7 @@ ff_load_config(const char *conf, int argc, char * const argv[])
return -1; return -1;
} }
ff_load_arg(&ff_global_cfg, argc, argv); if (dpdk_args_setup(&ff_global_cfg) <= 0) {
if (dpdk_argc_argv_setup(&ff_global_cfg) <= 0) {
return -1; return -1;
} }

View File

@ -63,7 +63,9 @@ struct ff_freebsd_cfg {
}; };
struct ff_config { struct ff_config {
struct { char *filename;
struct {
char *proc_type;
/* mask of enabled lcores */ /* mask of enabled lcores */
char *lcore_mask; char *lcore_mask;
/* mask of current proc on all lcores */ /* mask of current proc on all lcores */
@ -81,6 +83,8 @@ struct ff_config {
int promiscuous; int promiscuous;
int numa_on; int numa_on;
int tso; int tso;
/* list of proc-lcore */
uint16_t *proc_lcore;
struct ff_port_cfg *port_cfgs; struct ff_port_cfg *port_cfgs;
} dpdk; } dpdk;
@ -101,11 +105,12 @@ struct ff_config {
struct ff_freebsd_cfg *sysctl; struct ff_freebsd_cfg *sysctl;
long physmem; long physmem;
int hz; int hz;
int fd_reserve;
} freebsd; } freebsd;
}; };
extern struct ff_config ff_global_cfg; extern struct ff_config ff_global_cfg;
int ff_load_config(const char *conf, int argc, char * const argv[]); int ff_load_config(int argc, char * const argv[]);
#endif /* ifndef __FSTACK_CONFIG_H */ #endif /* ifndef __FSTACK_CONFIG_H */

View File

@ -87,8 +87,6 @@
#define MAX_TX_QUEUE_PER_PORT RTE_MAX_ETHPORTS #define MAX_TX_QUEUE_PER_PORT RTE_MAX_ETHPORTS
#define MAX_RX_QUEUE_PER_PORT 128 #define MAX_RX_QUEUE_PER_PORT 128
#define BITS_PER_HEX 4
#define KNI_MBUF_MAX 2048 #define KNI_MBUF_MAX 2048
#define KNI_QUEUE_SIZE 2048 #define KNI_QUEUE_SIZE 2048
@ -147,7 +145,7 @@ struct lcore_conf {
uint16_t nb_procs; uint16_t nb_procs;
uint16_t socket_id; uint16_t socket_id;
uint16_t nb_rx_queue; uint16_t nb_rx_queue;
uint16_t *lcore_proc; uint16_t *proc_lcore;
struct lcore_rx_queue rx_queue_list[MAX_RX_QUEUE_PER_LCORE]; struct lcore_rx_queue rx_queue_list[MAX_RX_QUEUE_PER_LCORE];
uint16_t tx_queue_id[RTE_MAX_ETHPORTS]; uint16_t tx_queue_id[RTE_MAX_ETHPORTS];
struct mbuf_table tx_mbufs[RTE_MAX_ETHPORTS]; struct mbuf_table tx_mbufs[RTE_MAX_ETHPORTS];
@ -270,77 +268,6 @@ check_all_ports_link_status(void)
} }
} }
static int
xdigit2val(unsigned char c)
{
int val;
if (isdigit(c))
val = c - '0';
else if (isupper(c))
val = c - 'A' + 10;
else
val = c - 'a' + 10;
return val;
}
static int
parse_lcore_mask(const char *coremask, uint16_t *lcore_proc,
uint16_t nb_procs)
{
int i, j, idx = 0;
unsigned count = 0;
char c;
int val;
if (coremask == NULL)
return -1;
/* Remove all blank characters ahead and after.
* Remove 0x/0X if exists.
*/
while (isblank(*coremask))
coremask++;
if (coremask[0] == '0' && ((coremask[1] == 'x')
|| (coremask[1] == 'X')))
coremask += 2;
i = strlen(coremask);
while ((i > 0) && isblank(coremask[i - 1]))
i--;
if (i == 0)
return -1;
for (i = i - 1; i >= 0 && idx < RTE_MAX_LCORE && count < nb_procs; i--) {
c = coremask[i];
if (isxdigit(c) == 0) {
return -1;
}
val = xdigit2val(c);
for (j = 0; j < BITS_PER_HEX && idx < RTE_MAX_LCORE && count < nb_procs;
j++, idx++) {
if ((1 << j) & val) {
if (!lcore_config[idx].detected) {
RTE_LOG(ERR, EAL, "lcore %u unavailable\n", idx);
return -1;
}
lcore_proc[count] = idx;
count++;
}
}
}
for (; i >= 0; i--)
if (coremask[i] != '0')
return -1;
if (count < nb_procs)
return -1;
return 0;
}
static int static int
init_lcore_conf(void) init_lcore_conf(void)
{ {
@ -351,17 +278,20 @@ init_lcore_conf(void)
lcore_conf.proc_id = ff_global_cfg.dpdk.proc_id; lcore_conf.proc_id = ff_global_cfg.dpdk.proc_id;
lcore_conf.nb_procs = ff_global_cfg.dpdk.nb_procs; lcore_conf.nb_procs = ff_global_cfg.dpdk.nb_procs;
lcore_conf.lcore_proc = rte_zmalloc(NULL,
sizeof(uint16_t)*lcore_conf.nb_procs, 0);
if (lcore_conf.lcore_proc == NULL) {
rte_exit(EXIT_FAILURE, "rte_zmalloc lcore_proc failed\n");
}
int ret = parse_lcore_mask(ff_global_cfg.dpdk.lcore_mask, lcore_conf.proc_lcore = rte_zmalloc(NULL,
lcore_conf.lcore_proc, lcore_conf.nb_procs); sizeof(uint16_t) * lcore_conf.nb_procs, 0);
if (ret < 0) { if (lcore_conf.proc_lcore == NULL) {
rte_exit(EXIT_FAILURE, "parse_lcore_mask failed:%s\n", rte_exit(EXIT_FAILURE, "rte_zmalloc proc_lcore failed\n");
ff_global_cfg.dpdk.lcore_mask); }
rte_memcpy(lcore_conf.proc_lcore, ff_global_cfg.dpdk.proc_lcore,
sizeof(uint16_t) * lcore_conf.nb_procs);
uint16_t proc_id;
for (proc_id = 0; proc_id < lcore_conf.nb_procs; proc_id++) {
uint16_t lcore_id = lcore_conf.proc_lcore[proc_id];
if (!lcore_config[lcore_id].detected) {
rte_exit(EXIT_FAILURE, "lcore %u unavailable\n", lcore_id);
}
} }
uint16_t socket_id = 0; uint16_t socket_id = 0;
@ -427,7 +357,7 @@ init_mem_pool(void)
int numa_on = ff_global_cfg.dpdk.numa_on; int numa_on = ff_global_cfg.dpdk.numa_on;
for (i = 0; i < lcore_conf.nb_procs; i++) { for (i = 0; i < lcore_conf.nb_procs; i++) {
lcore_id = lcore_conf.lcore_proc[i]; lcore_id = lcore_conf.proc_lcore[i];
if (numa_on) { if (numa_on) {
socketid = rte_lcore_to_socket_id(lcore_id); socketid = rte_lcore_to_socket_id(lcore_id);
} }
@ -932,7 +862,7 @@ process_packets(uint8_t port_id, uint16_t queue_id, struct rte_mbuf **bufs,
if(i == queue_id) if(i == queue_id)
continue; continue;
mbuf_pool = pktmbuf_pool[rte_lcore_to_socket_id(qconf->lcore_proc[i])]; mbuf_pool = pktmbuf_pool[rte_lcore_to_socket_id(qconf->proc_lcore[i])];
mbuf_clone = rte_pktmbuf_clone(rtem, mbuf_pool); mbuf_clone = rte_pktmbuf_clone(rtem, mbuf_pool);
if(mbuf_clone) { if(mbuf_clone) {
int ret = rte_ring_enqueue(arp_ring[i][port_id], mbuf_clone); int ret = rte_ring_enqueue(arp_ring[i][port_id], mbuf_clone);

View File

@ -36,6 +36,7 @@
#include <sys/vmmeter.h> #include <sys/vmmeter.h>
#include <sys/cpuset.h> #include <sys/cpuset.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <sys/filedesc.h>
#include <vm/uma.h> #include <vm/uma.h>
#include <vm/uma_int.h> #include <vm/uma_int.h>
@ -111,6 +112,7 @@ ff_freebsd_init(void)
mutex_init(); mutex_init();
mi_startup(); mi_startup();
sx_init(&proctree_lock, "proctree"); sx_init(&proctree_lock, "proctree");
ff_fdused_range(curthread->td_proc->p_fd, ff_global_cfg.freebsd.fd_reserve);
cur = ff_global_cfg.freebsd.sysctl; cur = ff_global_cfg.freebsd.sysctl;
while (cur) { while (cur) {

View File

@ -33,10 +33,10 @@
extern int ff_freebsd_init(); extern int ff_freebsd_init();
int int
ff_init(const char *conf, int argc, char * const argv[]) ff_init(int argc, char * const argv[])
{ {
int ret; int ret;
ret = ff_load_config(conf, argc, argv); ret = ff_load_config(argc, argv);
if (ret < 0) if (ret < 0)
exit(1); exit(1);

View File

@ -0,0 +1,36 @@
/*-
* Copyright (c) 2010 Kip Macy
* Copyright (C) 2017 THL A29 Limited, a Tencent company.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSTACK_SYS_FILEDESC_H_
#define _FSTACK_SYS_FILEDESC_H_
#include_next <sys/filedesc.h>
void ff_fdused_range(struct filedesc *fdp, int max);
int ff_fdisused(int fd);
#endif /* _FSTACK_SYS_FILEDESC_H_ */

View File

@ -40,28 +40,18 @@ do
if [ ${result} != 0 ] if [ ${result} != 0 ]
then then
((num_procs++)); ((num_procs++));
cpuinfo[$i]=1
else
cpuinfo[$i]=0
fi fi
done done
proc_id=0 for((proc_id=0; proc_id<${num_procs}; ++proc_id))
for((i=0;i<${PROCESSOR};++i))
do do
if ((cpuinfo[$i] == 1)) if ((proc_id == 0))
then then
cmask=`echo "2^$i"|bc` echo "${bin} --conf ${conf} --proc-type=primary --proc-id=${proc_id}"
cmask=`echo "obase=16;${cmask}"|bc` ${bin} --conf ${conf} --proc-type=primary --proc-id=${proc_id} &
if ((proc_id == 0)) sleep 5
then else
echo "${bin} ${conf} -c $cmask --proc-type=primary --num-procs=${num_procs} --proc-id=${proc_id}" echo "${bin} --conf ${conf} --proc-type=secondary --proc-id=${proc_id}"
${bin} ${conf} -c ${cmask} --proc-type=primary --num-procs=${num_procs} --proc-id=${proc_id} & ${bin} --conf ${conf} --proc-type=secondary --proc-id=${proc_id} &
sleep 5 fi
else
echo "${bin} ${conf} -c $cmask --proc-type=secondary --num-procs=${num_procs} --proc-id=${proc_id}"
${bin} ${conf} -c $cmask --proc-type=secondary --num-procs=${num_procs} --proc-id=${proc_id} &
fi
((proc_id++))
fi
done done