1*a9643ea8Slogwang# F-Stack Nginx APP Guide 2*a9643ea8Slogwang 3*a9643ea8SlogwangF-Stack is an open source network framework based on DPDK. F-Stack supports standard Nginx as HTTP framework which means all web application based on HTTP can easily use F-Stack. 4*a9643ea8Slogwang 5*a9643ea8Slogwang## How does Nginx use F-Stack? 6*a9643ea8Slogwang 7*a9643ea8Slogwang Nginx APP is in `app/nginx-1.11.10` directory. 8*a9643ea8Slogwang 9*a9643ea8Slogwang### New nginx module `ngx_ff_module.c` 10*a9643ea8Slogwang 11*a9643ea8SlogwangHook operation of Network IO interface , the transformation of the ff socket, in order to distinguish from regular file descriptor. 12*a9643ea8Slogwang 13*a9643ea8SlogwangFirst, define network interface functions. 14*a9643ea8Slogwang 15*a9643ea8Slogwang static int (*real_close)(int); 16*a9643ea8Slogwang static int (*real_socket)(int, int, int); 17*a9643ea8Slogwang static int (*real_bind)(int, const struct sockaddr*, socklen_t); 18*a9643ea8Slogwang static int (*real_connect)(int, const struct sockaddr*, socklen_t); 19*a9643ea8Slogwang static int (*real_listen)(int, int); 20*a9643ea8Slogwang static int (*real_setsockopt)(int, int, int, const void *, socklen_t); 21*a9643ea8Slogwang 22*a9643ea8Slogwang static int (*real_accept)(int, struct sockaddr *, socklen_t *); 23*a9643ea8Slogwang static int (*real_accept4)(int, struct sockaddr *, socklen_t *, int); 24*a9643ea8Slogwang static ssize_t (*real_recv)(int, void *, size_t, int); 25*a9643ea8Slogwang static ssize_t (*real_send)(int, const void *, size_t, int); 26*a9643ea8Slogwang 27*a9643ea8Slogwang static ssize_t (*real_writev)(int, const struct iovec *, int); 28*a9643ea8Slogwang static ssize_t (*real_write)(int, const void *, size_t ); 29*a9643ea8Slogwang static ssize_t (*real_read)(int, void *, size_t ); 30*a9643ea8Slogwang static ssize_t (*real_readv)(int, const struct iovec *, int); 31*a9643ea8Slogwang 32*a9643ea8Slogwang static int (*real_ioctl)(int, int, void *); 33*a9643ea8Slogwang 34*a9643ea8Slogwang static int (*real_select) (int, fd_set *, fd_set *, fd_set *, struct timeval *); 35*a9643ea8Slogwang 36*a9643ea8SlogwangInitialize the F-Stack module, hook network interface functions, using our interface to replace the System Interface. Initialize F-Stack. 37*a9643ea8Slogwang 38*a9643ea8Slogwang void ff_mod_init(int argc, char * const *argv) { 39*a9643ea8Slogwang int rc; 40*a9643ea8Slogwang 41*a9643ea8Slogwang #define INIT_FUNCTION(func) \ 42*a9643ea8Slogwang real_##func = dlsym(RTLD_NEXT, #func); \ 43*a9643ea8Slogwang assert(real_##func) 44*a9643ea8Slogwang 45*a9643ea8Slogwang INIT_FUNCTION(socket); 46*a9643ea8Slogwang INIT_FUNCTION(bind); 47*a9643ea8Slogwang INIT_FUNCTION(connect); 48*a9643ea8Slogwang INIT_FUNCTION(close); 49*a9643ea8Slogwang INIT_FUNCTION(listen); 50*a9643ea8Slogwang INIT_FUNCTION(setsockopt); 51*a9643ea8Slogwang INIT_FUNCTION(accept); 52*a9643ea8Slogwang INIT_FUNCTION(accept4); 53*a9643ea8Slogwang INIT_FUNCTION(recv); 54*a9643ea8Slogwang INIT_FUNCTION(send); 55*a9643ea8Slogwang INIT_FUNCTION(writev); 56*a9643ea8Slogwang INIT_FUNCTION(write); 57*a9643ea8Slogwang INIT_FUNCTION(read); 58*a9643ea8Slogwang INIT_FUNCTION(readv); 59*a9643ea8Slogwang 60*a9643ea8Slogwang INIT_FUNCTION(ioctl); 61*a9643ea8Slogwang INIT_FUNCTION(select); 62*a9643ea8Slogwang 63*a9643ea8Slogwang #undef INIT_FUNCTION 64*a9643ea8Slogwang 65*a9643ea8Slogwang assert(argc >= 2); 66*a9643ea8Slogwang 67*a9643ea8Slogwang rc = ff_init(argv[1], argc, argv); 68*a9643ea8Slogwang assert(0 == rc); 69*a9643ea8Slogwang 70*a9643ea8Slogwang inited = 1; 71*a9643ea8Slogwang } 72*a9643ea8Slogwang 73*a9643ea8SlogwangRe-implement the network interface with FF API to replace the System network interface. Take socket () as an example, use ff\_socket instead of real\_socket, and return the F-Stack file descriptor. Other APIs refers to module code. 74*a9643ea8Slogwang 75*a9643ea8Slogwang int socket(int domain, int type, int protocol) 76*a9643ea8Slogwang { 77*a9643ea8Slogwang int rc; 78*a9643ea8Slogwang 79*a9643ea8Slogwang if ((inited == 0) || (AF_INET != domain) || (SOCK_STREAM != type && SOCK_DGRAM != type)) 80*a9643ea8Slogwang { 81*a9643ea8Slogwang rc = real_socket(domain, type, protocol); 82*a9643ea8Slogwang return rc; 83*a9643ea8Slogwang } 84*a9643ea8Slogwang 85*a9643ea8Slogwang rc = ff_socket(domain, type, protocol); 86*a9643ea8Slogwang if(rc >= 0) 87*a9643ea8Slogwang rc |= 1 << FST_FD_BITS; 88*a9643ea8Slogwang 89*a9643ea8Slogwang return rc; 90*a9643ea8Slogwang } 91*a9643ea8Slogwang 92*a9643ea8Slogwang### Other modifications 93*a9643ea8Slogwang 94*a9643ea8Slogwang `auto/sources` 95*a9643ea8Slogwang 96*a9643ea8SlogwangAdd compiling file 97*a9643ea8Slogwang 98*a9643ea8Slogwang `auto/make` 99*a9643ea8Slogwang 100*a9643ea8SlogwangAdd link lib 101*a9643ea8Slogwang 102*a9643ea8Slogwang `auto/options` 103*a9643ea8Slogwang 104*a9643ea8SlogwangAdd module 105*a9643ea8Slogwang 106*a9643ea8Slogwang`ngx_kqueue_module.c` 107*a9643ea8Slogwang 108*a9643ea8Slogwangkqueue module adapted to F-Stack ff API 109*a9643ea8Slogwang 110*a9643ea8Slogwang## Start Nginx compiling 111*a9643ea8Slogwang 112*a9643ea8SlogwangConfiguration needs to include F-Stack `ff_module` 113*a9643ea8Slogwang 114*a9643ea8Slogwang ./configure --prefix=/usr/local/nginx_fstack --with-ff_module 115*a9643ea8Slogwang make 116*a9643ea8Slogwang make install 117*a9643ea8Slogwang 118*a9643ea8SlogwangNotes for Nginx based F-Stack configuration file. 119*a9643ea8Slogwang 120*a9643ea8Slogwang worker_processes 1; # always be 1 121*a9643ea8Slogwang 122*a9643ea8Slogwang events { 123*a9643ea8Slogwang worker_connections 102400; # to 102400 124*a9643ea8Slogwang use kqueue; # use kqueue 125*a9643ea8Slogwang } 126*a9643ea8Slogwang 127*a9643ea8Slogwang sendfile off; # sendfile off 128*a9643ea8Slogwang 129*a9643ea8SlogwangStart Nginx with `start.sh` 130*a9643ea8Slogwang 131*a9643ea8Slogwang ./start.sh -b /usr/local/nginx_fstack/sbin/nginx -c config.ini 132*a9643ea8Slogwang 133*a9643ea8Slogwang or with the method below. Description of arguments is as bellow, 134*a9643ea8Slogwang 135*a9643ea8Slogwang # -c coremask, The primary and secondary processes need to specify the coremask of the individual lcore they want to use, for example, primary process -c 1, secondary -c 2, -c 4, -c 8, -c 10, etc. 136*a9643ea8Slogwang # --proc-type = primary/secondary primary/secondary 137*a9643ea8Slogwang # --num-procs = number of process 138*a9643ea8Slogwang # --proc-id = current process ID, increase from 0 139*a9643ea8Slogwang 140*a9643ea8Slogwang <nginx_dir>/nginx config.ini -c <cmask> --proc-type=primary --num-procs=<num_procs> --proc-id=<proc_id> # primary process 141*a9643ea8Slogwang <nginx_dir>/nginx config.ini -c <cmask> --proc-type=secondary --num-procs=<num_procs> --proc-id=<proc_id> # seconary process, if needed 142*a9643ea8Slogwang 143*a9643ea8Slogwang Other is identical to the standard Nginx. 144