mirror of https://github.com/F-Stack/f-stack.git
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:
parent
a090190f3c
commit
a02c88d651
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -296,7 +296,7 @@ void* mt_get_msg_private();
|
||||||
* 使用spp,直接调用SyncFrame的框架初始化函数即可
|
* 使用spp,直接调用SyncFrame的框架初始化函数即可
|
||||||
* @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 设置微线程独立栈空间大小
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -41,3 +41,4 @@ ff_mbuf_tx_offload
|
||||||
ff_route_ctl
|
ff_route_ctl
|
||||||
ff_rtioctl
|
ff_rtioctl
|
||||||
ff_gettimeofday
|
ff_gettimeofday
|
||||||
|
ff_fdisused
|
||||||
|
|
176
lib/ff_config.c
176
lib/ff_config.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
102
lib/ff_dpdk_if.c
102
lib/ff_dpdk_if.c
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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_ */
|
28
start.sh
28
start.sh
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue