diff options
Diffstat (limited to 'src/nSocket/kernel/linux_kernel_module.c')
-rw-r--r-- | src/nSocket/kernel/linux_kernel_module.c | 419 |
1 files changed, 211 insertions, 208 deletions
diff --git a/src/nSocket/kernel/linux_kernel_module.c b/src/nSocket/kernel/linux_kernel_module.c index eb3dd8d..71371bb 100644 --- a/src/nSocket/kernel/linux_kernel_module.c +++ b/src/nSocket/kernel/linux_kernel_module.c @@ -24,310 +24,313 @@ #include<unistd.h> #include <string.h> #include <pthread.h> -#include "nstack_types.h" +#include "types.h" #include "nstack_sockops.h" #include "nstack_log.h" #include "linux_kernel_module.h" #include "linux_kernel_socket.h" #include "nsfw_base_linux_api.h" #include "nstack_fd_mng.h" -#include "nstack_dmm_api.h" +#include "nstack_epoll_api.h" +#include "dmm_spinlock.h" +#include "nsfw_mem_api.h" +#include "nstack_info_parse.h" +#include "nstack_eventpoll.h" +#include "nstack_rd_api.h" #define SK_MAX_EP_EVENT 1024 -kernel_stack_info_t g_ksInfo = {.thread_inited = ks_false,.epfd = - -1,.checkEpollFD = -1 -}; +void *krd_table = NULL; +kernel_stack_info_t g_ksInfo = {.thread_inited = ks_false }; /*design ensures that g_ksInfo is not write accessed at the same time. only read is done simultaneously with no chance of other thread writing it. so no protection needed.*/ -/* Custodial pointer not freed for events at end of this function */ -/* This can be ignored as this is a thread and runs in infinite loop. Hence will never return */ -void * -ks_ep_thread (void *arg) + +/*no need to free these points because the function is always running */ +/*point is set to NULL because it's freeed */ +void *ks_ep_thread(void *arg) { - int eventNum = 0; - int loop = 0; - struct epoll_event *events = - (struct epoll_event *) malloc (SK_MAX_EP_EVENT * - sizeof (struct epoll_event)); - struct epoll_event *innerEvt = - (struct epoll_event *) malloc (SK_MAX_EP_EVENT * - sizeof (struct epoll_event)); - - if (NULL == events || NULL == innerEvt) + int eventNum = 0; + int loop = 0; + int retval = 0; + int ret; + nsep_epollInfo_t *epInfo; + struct epoll_event *events = + (struct epoll_event *) malloc(SK_MAX_EP_EVENT * + sizeof(struct epoll_event)); + struct epoll_event *innerEvt = + (struct epoll_event *) malloc(SK_MAX_EP_EVENT * + sizeof(struct epoll_event)); + struct list_node *fdEpiHead; + struct list_node *node; + struct epitem *epi = NULL; + struct eventpoll *ep = NULL; + + if (NULL == events || NULL == innerEvt) { - NSSOC_LOGERR ("malloc events failed"); + NSSOC_LOGERR("malloc events failed"); - if (events) + if (events) { - free (events); - events = NULL; /* Set NULL to pointer after free */ + free(events); + events = NULL; /* Set NULL to pointer after free */ } - if (innerEvt) + if (innerEvt) { - free (innerEvt); - innerEvt = NULL; /* Set NULL to pointer after free */ + free(innerEvt); + innerEvt = NULL; /* Set NULL to pointer after free */ } - /* When ks_ep_thread failed, it should set g_ksInfo.thread_inited ks_true, otherwise,it will result kernel_stack_register in dead loop */ - g_ksInfo.thread_inited = ks_true; - return NULL; + + /* When ks_ep_thread failed, it should set g_ksInfo.thread_inited ks_true, otherwise,it will result kernel_stack_register in dead loop */ + g_ksInfo.thread_inited = ks_true; + return NULL; } - if (-1 == g_ksInfo.epfd) + retval = + memset_s(events, SK_MAX_EP_EVENT * sizeof(struct epoll_event), 0, + SK_MAX_EP_EVENT * sizeof(struct epoll_event)); + retval |= + memset_s(innerEvt, SK_MAX_EP_EVENT * sizeof(struct epoll_event), 0, + SK_MAX_EP_EVENT * sizeof(struct epoll_event)); + + if (EOK != retval) { - NSTACK_CAL_FUN (&g_ksInfo.libcOps, epoll_create, (1), g_ksInfo.epfd); + free(events); + events = NULL; + free(innerEvt); + innerEvt = NULL; + g_ksInfo.thread_inited = ks_true; + return NULL; } - if (-1 == g_ksInfo.epfd) + NSTACK_CAL_FUN(&g_ksInfo.libcOps, epoll_create, (1), g_ksInfo.epfd); + + if (-1 == g_ksInfo.epfd) { - g_ksInfo.thread_inited = ks_true; + g_ksInfo.thread_inited = ks_true; - if (events) + if (events) { - free (events); - events = NULL; /* Set NULL to pointer after free */ + free(events); + events = NULL; /* Set NULL to pointer after free */ } - if (innerEvt) + if (innerEvt) { - free (innerEvt); - innerEvt = NULL; /* Set NULL to pointer after free */ + free(innerEvt); + innerEvt = NULL; /* Set NULL to pointer after free */ } - return NULL; + return NULL; } - g_ksInfo.thread_inited = ks_true; + g_ksInfo.thread_inited = ks_true; - do + do { - NSTACK_CAL_FUN (&g_ksInfo.libcOps, epoll_wait, - (g_ksInfo.epfd, events, SK_MAX_EP_EVENT, -1), eventNum); + NSTACK_CAL_FUN(&g_ksInfo.libcOps, epoll_wait, + (g_ksInfo.epfd, events, SK_MAX_EP_EVENT, -1), + eventNum); - if (0 == eventNum) + if (0 == eventNum) { - sys_sleep_ns (0, 100000); + sys_sleep_ns(0, 100000); } - for (loop = 0; loop < eventNum; loop++) + for (loop = 0; loop < eventNum; loop++) { - NSSOC_LOGDBG ("Epoll]events=%u,epfd=%d", events[loop].events, - events[loop].data.fd); + NSSOC_LOGDBG("Epoll]events=%u,epfd=%d", events[loop].events, + events[loop].data.fd); - if (events[loop].events & EPOLLIN) + if (events[loop].events & EPOLLIN) { - int i = 0, num = 0, ret = 0, epfd = events[loop].data.fd; - NSTACK_CAL_FUN (&g_ksInfo.libcOps, epoll_wait, - (epfd, innerEvt, SK_MAX_EP_EVENT, 0), num); + int i = 0, num = 0, epfd = events[loop].data.fd; + NSTACK_CAL_FUN(&g_ksInfo.libcOps, epoll_wait, + (epfd, innerEvt, SK_MAX_EP_EVENT, 0), num); - if (0 == num) + if (0 == num) { - NSSOC_LOGWAR ("Num is zero"); - continue; + /* remove it becasue print in normal scenario */ + NSSOC_LOGDBG("Num is zero]epfd=%d", epfd); + continue; } - NSTACK_CAL_FUN (&g_ksInfo.libcOps, epoll_ctl, - (g_ksInfo.epfd, EPOLL_CTL_DEL, epfd, NULL), - ret); + NSTACK_CAL_FUN(&g_ksInfo.libcOps, epoll_ctl, + (g_ksInfo.epfd, EPOLL_CTL_DEL, epfd, NULL), + ret); - ret = -1; - for (i = 0; i < num; i++) + for (i = 0; i < num; i++) { - ret &= - g_ksInfo.regVal.event_cb (innerEvt[i].data.ptr, - innerEvt[i].events); - NSSOC_LOGDBG ("Kernel got one event]i=%d,ptr=%d,events=%u", - i, innerEvt[i].data.ptr, innerEvt[i].events); - } + epInfo = nsep_get_info_by_sock(innerEvt[i].data.fd); + + if (epInfo + && (epInfo->rmidx < 0 + || epInfo->rmidx == g_ksInfo.regVal.type)) + { + dmm_spin_lock_with_pid((dmm_spinlock_t + *) (&epInfo->epiLock)); + fdEpiHead = + (struct list_node *) + SHMEM_ADDR_SHTOL(epInfo->epiList.head); + node = + (struct list_node *) + SHMEM_ADDR_SHTOL(fdEpiHead->next); + while (node) + { + + epi = + (struct epitem *) ep_list_entry(node, + struct + epitem, + fllink); + + node = + (struct list_node *) + SHMEM_ADDR_SHTOL(node->next); + ep = (struct eventpoll *) + SHMEM_ADDR_SHTOL(epi->ep); + + if (!(epi->event.events & innerEvt[i].events)) + { + continue; + } + + if (ep->pid != get_sys_pid()) + { + continue; + } + + epi->revents |= innerEvt[i].events; + } + + dmm_spin_unlock((dmm_spinlock_t + *) (&epInfo->epiLock)); + g_ksInfo.regVal.event_cb(epInfo, innerEvt[i].events, + EVENT_INFORM_APP); + NSSOC_LOGDBG + ("Kernel got one event]i=%d,fd=%d,events=%u", i, + innerEvt[i].data.fd, innerEvt[i].events); + } - if (ret) - { - struct epoll_event ev; - ev.data.fd = epfd; - ev.events = EPOLLIN; - NSTACK_CAL_FUN (&g_ksInfo.libcOps, epoll_ctl, - (g_ksInfo.epfd, EPOLL_CTL_ADD, epfd, &ev), - ret); } } } } - while (1); + while (1); +} +int kernel_load_default_rd(void *table) +{ + rd_ip_data ip_data; + ip_data.addr = inet_addr("127.0.0.1"); // loopback address + ip_data.masklen = 0; + ip_data.resev[0] = ip_data.resev[1] = 0; + (void) nstack_rd_ip_node_insert(RD_KERNEL_NAME, &ip_data, table); + NSSOC_LOGINF("successfully load default rd"); + return 0; } -int -kernel_fd_check (int fd, int flag) +void *kernel_get_ip_shmem() { - struct epoll_event event; - event.data.fd = fd; - event.events = EPOLLIN | EPOLLERR; - if (fd == g_ksInfo.checkEpollFD) - { - return 0; - } + return krd_table; +} - /*in order to reduce the cost of epoll ctl */ - if (STACK_FD_FUNCALL_CHECK == flag) - { - return 1; - } +int kernel_module_init() +{ + krd_table = nstack_local_rd_malloc(); - if (-1 == - nsfw_base_epoll_ctl (g_ksInfo.checkEpollFD, EPOLL_CTL_ADD, fd, &event)) + if (!krd_table) { - return 0; + NSSOC_LOGERR("kernel rd table create failed!"); + return -1; } - nsfw_base_epoll_ctl (g_ksInfo.checkEpollFD, EPOLL_CTL_DEL, fd, NULL); - return 1; -} - -int -kernel_prewait_proc (int epfd) -{ - int ret = 0; - struct epoll_event ep_event; - - NSSOC_LOGINF ("epfd=%d was added", epfd); - if (epfd < 0) + if (nstack_rd_parse(RD_KERNEL_NAME, krd_table)) { - return -1; + NSSOC_LOGWAR("kernel parse rd data failed, load default instead"); + nstack_rd_table_clear(krd_table); + return kernel_load_default_rd(krd_table); } - ep_event.data.fd = epfd; - ep_event.events = EPOLLIN | EPOLLET; - ret = lk_epollctl (0, EPOLL_CTL_ADD, epfd, &ep_event); - return ret; + + return 0; } -unsigned int -kernel_ep_fd_add (int epFD, int proFD, int ctl_ops, - struct epoll_event *events, void *pdata) +int kernel_stack_register + (nstack_socket_ops * ops, + nstack_event_ops * val, nstack_proc_ops * fddeal) { - struct epoll_event tmpEvt; - int ret = 0; - tmpEvt.data.ptr = pdata; - tmpEvt.events = events->events; - NSSOC_LOGINF ("epfd=%d,fd=%d,ops=%d, events=%u", epFD, proFD, ctl_ops, - events->events); - switch (ctl_ops) + /* Input parameter validation */ + if ((NULL == ops) || (NULL == val) || (NULL == fddeal)) { - case nstack_ep_triggle_add: - ret = nsfw_base_epoll_ctl (epFD, EPOLL_CTL_ADD, proFD, &tmpEvt); - break; - case nstack_ep_triggle_mod: - ret = nsfw_base_epoll_ctl (epFD, EPOLL_CTL_MOD, proFD, &tmpEvt); - break; - case nstack_ep_triggle_del: - ret = nsfw_base_epoll_ctl (epFD, EPOLL_CTL_DEL, proFD, &tmpEvt); - break; - default: - ret = -1; - break; + NSPOL_LOGERR("input param is NULL"); + return ks_fail; } - return ret; -} -int -kernel_socket (int a, int b, int c) -{ +#undef NSTACK_MK_DECL +#define NSTACK_MK_DECL(ret, fn, args) \ + g_ksInfo.libcOps.pf##fn = nsfw_base_##fn; +/*this file can be included more than once */ +#include "declare_syscalls.h.tmpl" - return nsfw_base_socket (a, b, c); -} + g_ksInfo.epfd = -1; + g_ksInfo.regVal = *val; -int -kernel_module_init () -{ - int retval = 0; +#ifdef KERNEL_FD_SUPPORT + g_ksInfo.thread_inited = ks_false; - g_ksInfo.thread_inited = ks_false; - retval = pthread_create (&g_ksInfo.ep_thread, NULL, ks_ep_thread, NULL); - if (retval != 0) - { - NSPOL_LOGERR ("kernel ep thread create fail, errno:%d!", errno); - return ks_fail; - } + NSSOC_LOGDBG("start to regist stack"); - /* The earlier thread "ep_thread" created will exit automatically when - return failure from below if any failure */ - retval = pthread_setname_np (g_ksInfo.ep_thread, K_EPOLL_THREAD_NAME); - if (retval != 0) + if (pthread_create(&g_ksInfo.ep_thread, NULL, ks_ep_thread, NULL)) { - NSMON_LOGERR - ("pthread_setname_np failed for ep_thread]retval=%d, errno:%d", - retval, errno); - /*set thread name failed no need to return */ + NSPOL_LOGERR("Err!"); + return ks_fail; } - NSSOC_LOGDBG ("New thread started"); + /* The earlier thread "ep_thread" created will exit automatically when + return failure from below if any failure */ + int retval = 0; - do + if (pthread_setname_np(g_ksInfo.ep_thread, K_EPOLL_THREAD_NAME)) { - sys_sleep_ns (0, 0); + NSMON_LOGERR("pthread_setname_np failed for ep_thread]retval=%d", + retval); + /*set thread name failed no need to return */ } - while (!g_ksInfo.thread_inited); - if (-1 == g_ksInfo.epfd) + NSSOC_LOGDBG("New thread started"); + + do { - NSPOL_LOGERR ("thread epoll create Err!"); - retval |= -1; + sys_sleep_ns(0, 0); } - return retval; -} - -int -kernel_fd_alloc () -{ - return nsfw_base_socket (AF_UNIX, SOCK_DGRAM, 0); -} + while (!g_ksInfo.thread_inited); -int -kernel_stack_register (nstack_proc_cb * ops, nstack_event_cb * val) -{ - int retval = 0; - /* Input parameter validation */ - if ((NULL == ops) || (NULL == val)) + if (-1 == g_ksInfo.epfd) { - NSPOL_LOGERR ("input param is NULL"); - return ks_fail; + NSPOL_LOGERR("Err!"); + retval = -1; } -#undef NSTACK_MK_DECL -#define NSTACK_MK_DECL(ret, fn, args) \ - g_ksInfo.libcOps.pf##fn = nsfw_base_##fn; - -#include "declare_syscalls.h" - - g_ksInfo.regVal = *val; +#endif - /*create a efpd to check fd is ok */ - if (g_ksInfo.checkEpollFD == -1) - { - g_ksInfo.checkEpollFD = nsfw_base_epoll_create (1); - } + *ops = g_ksInfo.libcOps; - NSSOC_LOGDBG ("start to regist stack"); + NSTACK_SET_OPS_FUN(ops, listen, lk_listen); + NSTACK_SET_OPS_FUN(ops, epoll_ctl, lk_epollctl); - ops->socket_ops = g_ksInfo.libcOps; - MEMSET_S (&(ops->extern_ops), sizeof (ops->extern_ops), 0, - sizeof (ops->extern_ops)); - NSTACK_SET_OPS_FUN (&(ops->socket_ops), listen, lk_listen); - NSTACK_SET_OPS_FUN (&(ops->socket_ops), epoll_ctl, lk_epollctl); - NSTACK_SET_OPS_FUN (&(ops->socket_ops), socket, kernel_socket); - ops->extern_ops.stack_fd_check = kernel_fd_check; - ops->extern_ops.ep_ctl = kernel_ep_fd_add; - ops->extern_ops.ep_prewait_proc = kernel_prewait_proc; - ops->extern_ops.module_init = kernel_module_init; - ops->extern_ops.module_init_child = kernel_module_init; - ops->extern_ops.stack_alloc_fd = kernel_fd_alloc; + /* don't close file descriptor */ - /* don't close file descriptor */ + fddeal->module_init = kernel_module_init; + fddeal->get_ip_shmem = kernel_get_ip_shmem; - return retval ? ks_fail : ks_success; +#ifdef KERNEL_FD_SUPPORT + return retval ? ks_fail : ks_success; +#else + return ks_success; +#endif } |