From 697ade6190b23c80e7f60963983786e679759393 Mon Sep 17 00:00:00 2001 From: qchang Date: Thu, 8 Mar 2018 17:39:22 -0800 Subject: dmm initial commit Change-Id: I049ee277cf4efdb83f9c2ac439365fcd421c159b Signed-off-by: qchang --- src/adapt/nstack_dmm_adpt.c | 250 ++++++++++ src/adapt/nstack_dmm_adpt.h | 62 +++ src/adapt/nstack_epoll_comm.c | 1077 +++++++++++++++++++++++++++++++++++++++++ src/adapt/nstack_rd_mng.c | 317 ++++++++++++ src/adapt/nstack_rd_mng.h | 27 ++ src/adapt/nstack_share_res.c | 176 +++++++ src/adapt/nstack_share_res.h | 66 +++ 7 files changed, 1975 insertions(+) create mode 100644 src/adapt/nstack_dmm_adpt.c create mode 100644 src/adapt/nstack_dmm_adpt.h create mode 100644 src/adapt/nstack_epoll_comm.c create mode 100644 src/adapt/nstack_rd_mng.c create mode 100644 src/adapt/nstack_rd_mng.h create mode 100644 src/adapt/nstack_share_res.c create mode 100644 src/adapt/nstack_share_res.h (limited to 'src/adapt') diff --git a/src/adapt/nstack_dmm_adpt.c b/src/adapt/nstack_dmm_adpt.c new file mode 100644 index 0000000..eea2bf1 --- /dev/null +++ b/src/adapt/nstack_dmm_adpt.c @@ -0,0 +1,250 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#include "nsfw_init.h" +#include "nsfw_mem_api.h" +#include "nsfw_recycle_api.h" +#include "nsfw_mgr_com_api.h" +#include "nsfw_ps_mem_api.h" +#include "nsfw_ps_api.h" +#include "nsfw_recycle_api.h" +#include "nsfw_fd_timer_api.h" +#include "nsfw_maintain_api.h" +#include "nstack_eventpoll.h" +#include "nstack_dmm_api.h" +#include "nstack_dmm_adpt.h" +#include "nstack_rd_mng.h" +#include "mgr_com.h" + +int g_same_process = 1; + +extern int nsep_adpt_attach_memory (); +extern int nstack_init_share_res (); +extern int nstack_attach_share_res (); +extern int nsep_adpt_reg_res_mgr (); + +/** + * This just for linux kernel epoll thread + */ +int +nstack_event_callback (void *pdata, int events) +{ + nsep_epollInfo_t *epInfo = (nsep_epollInfo_t *) pdata; + + if (!epInfo) + { + NSSOC_LOGWAR ("!!!!!!!err pdata=%p,get null epInfo", pdata); + return -1; + } +#if 0 + if (epInfo->rmidx >= 0 && epInfo->rmidx != modInx) + { + NSSOC_LOGDBG ("This fd should not issue events"); + return -1; + } +#endif + + NSSOC_LOGDBG ("Got one event]fd=%d,events=%u", epInfo->fd, events); + + sys_arch_lock_with_pid (&epInfo->epiLock); + struct list_node *fdEpiHead = + (struct list_node *) ADDR_SHTOL (epInfo->epiList.head); + struct list_node *node = (struct list_node *) ADDR_SHTOL (fdEpiHead->next); + struct epitem *epi = NULL; + struct eventpoll *ep = NULL; + while (node) + { + + epi = (struct epitem *) ep_list_entry (node, struct epitem, fllink); + + node = (struct list_node *) ADDR_SHTOL (node->next); + ep = (struct eventpoll *) ADDR_SHTOL (epi->ep); + if (!(epi->event.events & events)) + continue; + + /*event should not notice other process */ + if ((ep->pid != get_sys_pid ()) && g_same_process) + { + continue; + } + + sys_arch_lock_with_pid (&ep->lock); + + if (unlikely (ep->ovflist != NSEP_EP_UNACTIVE_PTR)) + { + if (epi->next == NSEP_EP_UNACTIVE_PTR) + { + epi->next = ep->ovflist; + ep->ovflist = (struct epitem *) ADDR_LTOSH (epi); + } + epi->ovf_revents |= events; + NSSOC_LOGDBG ("Add to ovflist]protoFD=%d,event=%d", epInfo->fd, + events); + goto out_unlock; + } + if (!EP_HLIST_NODE_LINKED (&epi->rdllink)) + { + ep_hlist_add_tail (&ep->rdlist, &epi->rdllink); + sem_post (&ep->waitSem); + } + epi->revents |= events; + out_unlock: + sys_sem_s_signal (&ep->lock); + } + sys_sem_s_signal (&epInfo->epiLock); + /* [Remove fdInf->event_sem post] */ + return 0; +} + +int +nstack_adpt_init (nstack_dmm_para * para) +{ + nsfw_mem_para stinfo = { 0 }; + i32 init_ret = 0; + + if (!para) + { + return -1; + } + stinfo.iargsnum = para->argc; + stinfo.pargs = para->argv; + stinfo.enflag = para->proc_type; + if (para->deploy_type >= NSTACK_MODEL_TYPE1) + { + g_same_process = 0; + } + + nsfw_com_attr_set (para->attr.policy, para->attr.pri); + + (void) nstack_framework_setModuleParam (NSFW_MEM_MGR_MODULE, &stinfo); + (void) nstack_framework_setModuleParam (NSFW_MGR_COM_MODULE, + (void *) ((u64) para->proc_type)); + (void) nstack_framework_setModuleParam (NSFW_TIMER_MODULE, + (void *) ((u64) para->proc_type)); + (void) nstack_framework_setModuleParam (NSFW_PS_MODULE, + (void *) ((u64) para->proc_type)); + (void) nstack_framework_setModuleParam (NSFW_PS_MEM_MODULE, + (void *) ((u64) para->proc_type)); + (void) nstack_framework_setModuleParam (NSFW_RECYCLE_MODULE, + (void *) ((u64) para->proc_type)); + (void) nstack_framework_setModuleParam (NSFW_RES_MGR_MODULE, + (void *) ((u64) para->proc_type)); + (void) nstack_framework_setModuleParam (NSFW_SOFT_PARAM_MODULE, + (void *) ((u64) para->proc_type)); + (void) nstack_framework_setModuleParam (NSFW_LOG_CFG_MODULE, + (void *) ((u64) para->proc_type)); + + init_ret = nstack_framework_init (); + if (init_ret < 0) + { + NSFW_LOGERR + ("######################init failed!!!!######################"); + return -1; + } + + if ((para->proc_type != NSFW_PROC_APP) + && (para->proc_type != NSFW_PROC_MAIN)) + { + return 0; + } + + if (para->proc_type == NSFW_PROC_MAIN) + { + if (nstack_init_share_res () != 0) + { + NSFW_LOGERR ("nstack_init_share_res failed"); + return -1; + } + if (nsep_create_memory () != 0) + { + NSFW_LOGERR ("nsep_create_memory failed"); + return -1; + } + + if (nstack_rd_mng_int (0) != 0) + { + NSFW_LOGERR ("nstack_rd_mng_int failed"); + return -1; + } + } + else + { + if (nstack_attach_share_res () != 0) + { + NSFW_LOGERR ("nstack_attach_share_res failed"); + return -1; + } + + /** + * the share memory for epoll is created and usedy be app, don't clear + * it in fault case. + */ + if (0 != nsep_adpt_attach_memory ()) + { + NSFW_LOGERR ("nsep_adpt_attach_memory failed"); + return -1; + } + + if (nstack_rd_mng_int (1) != 0) + { + NSFW_LOGERR ("nstack_rd_mng_int failed"); + return -1; + } + } + + void *pret = + nsfw_recycle_reg_obj (NSFW_REC_PRO_LOWEST, NSFW_REC_NSOCKET_EPOLL, + NULL); + if (!pret) + { + NSFW_LOGERR ("regist recycle failed"); + return -1; + } + (void) nsep_adpt_reg_res_mgr (); + + return 0; +} + +/*just to used to dependence by other module*/ +int +nstack_init_module (void *para) +{ + return 0; +} + +NSFW_MODULE_NAME (NSTACK_DMM_MODULE) +NSFW_MODULE_PRIORITY (10) +NSFW_MODULE_DEPENDS (NSFW_MEM_MGR_MODULE) +NSFW_MODULE_DEPENDS (NSFW_MGR_COM_MODULE) +NSFW_MODULE_DEPENDS (NSFW_TIMER_MODULE) +NSFW_MODULE_DEPENDS (NSFW_PS_MODULE) +NSFW_MODULE_DEPENDS (NSFW_PS_MEM_MODULE) +NSFW_MODULE_DEPENDS (NSFW_RECYCLE_MODULE) +NSFW_MODULE_DEPENDS (NSFW_LOG_CFG_MODULE) +NSFW_MODULE_DEPENDS (NSFW_RES_MGR_MODULE) +NSFW_MODULE_DEPENDS (NSFW_SOFT_PARAM_MODULE) +NSFW_MODULE_INIT (nstack_init_module) +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/adapt/nstack_dmm_adpt.h b/src/adapt/nstack_dmm_adpt.h new file mode 100644 index 0000000..e71dce3 --- /dev/null +++ b/src/adapt/nstack_dmm_adpt.h @@ -0,0 +1,62 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#ifndef __NSTACK_DMM_ADPT_H__ +#define __NSTACK_DMM_ADPT_H__ + +typedef enum +{ + NSTACK_MODEL_TYPE1 = 1, /*nSocket and stack belong to the same process */ + NSTACK_MODEL_TYPE2 = 2, /*nSocket and stack belong to different processes, + *and nStack don't take care the communication between stack and stack adpt + */ + NSTACK_MODEL_TYPE3 = 3, /*nSocket and stack belong to different processes, and sbr was spplied to communicate whit stack */ + NSTACK_MODEL_INVALID, +} nstack_model_deploy_type; + +#define NSTACK_DMM_MODULE "nstack_dmm_module" + +typedef struct nsfw_com_attr +{ + int policy; + int pri; +} nsfw_com_attr; + +typedef struct __nstack_dmm_para +{ + nstack_model_deploy_type deploy_type; + int proc_type; + nsfw_com_attr attr; + int argc; + char **argv; +} nstack_dmm_para; + +extern int nstack_adpt_init (nstack_dmm_para * para); +extern int nstack_event_callback (void *pdata, int events); + +#endif + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/adapt/nstack_epoll_comm.c b/src/adapt/nstack_epoll_comm.c new file mode 100644 index 0000000..1f3fd02 --- /dev/null +++ b/src/adapt/nstack_epoll_comm.c @@ -0,0 +1,1077 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "nstack_eventpoll.h" +#include "nsfw_mem_api.h" +#include "nstack_log.h" +#include "nstack_securec.h" +#include "nsfw_recycle_api.h" +#include "nsfw_maintain_api.h" +#include +#include + +nsep_epollManager_t g_epollMng = { + .infoSockMap = NULL, +}; + +/* + * This function will find the epitem of fd in eventpool ep + * This is only used in epoll_ctl add + */ +struct epitem * +nsep_find_ep (struct eventpoll *ep, int fd) +{ + struct ep_rb_node *rbp; + struct epitem *epi, *epir = NULL; + u32_t loopCnt = 0; + for (rbp = ADDR_SHTOL (ep->rbr.rb_node); rbp;) + { + ++loopCnt; + if (loopCnt > NSTACK_MAX_EPITEM_NUM) + break; + + epi = (struct epitem *) ep_rb_entry (rbp, struct epitem, rbn); + if (fd > epi->fd) + { + rbp = (struct ep_rb_node *) ADDR_SHTOL (rbp->rb_right); + } + else if (fd < epi->fd) + { + rbp = (struct ep_rb_node *) ADDR_SHTOL (rbp->rb_left); + } + else + { + epir = epi; + break; + } + } + + if (loopCnt > NSTACK_MAX_EPITEM_NUM) + { + NSSOC_LOGERR ("Loop out of range!!!!"); + } + + return epir; +} + +int +nstack_ep_unlink (struct eventpoll *ep, struct epitem *epi) +{ + int error = ENOENT; + + if (ep_rb_parent (&epi->rbn) == + (struct ep_rb_node *) ADDR_LTOSH_EXT (&epi->rbn)) + { + NSSOC_LOGWAR ("ep_rb_parent == epi->rbn"); + return error; + } + + epi->event.events = 0; + + ep_rb_erase (&epi->rbn, &ep->rbr); + ep_rb_set_parent (&epi->rbn, &epi->rbn); + + if (EP_HLIST_NODE_LINKED (&epi->rdllink)) + { + ep_hlist_del (&ep->rdlist, &epi->rdllink); + } + + return 0; +} + +/** + * @Function nsep_free_epitem + * @Description free nstack epitem + * @param in data - the epitem to be free + * @return 0 on success, -1 on error + */ +int +nsep_free_epitem (struct epitem *data) +{ + struct epitem *epiEntry = (struct epitem *) data; + struct epitem_pool *pool = &nsep_getManager ()->epitemPool; + epiEntry->pid = 0; + NSSOC_LOGDBG ("nsep_free_epitem data:%p", data); + if (res_free (&epiEntry->res_chk)) + { + NSFW_LOGERR ("epitem refree!]epitem=%p", epiEntry); + return 0; + } + + if (nsfw_mem_ring_enqueue (pool->ring, (void *) epiEntry) != 1) + { + NSSOC_LOGERR ("Error to free epitem"); + } + return 0; +} + +NSTACK_STATIC void +nsep_initEpInfo (nsep_epollInfo_t * info) +{ + int iindex = 0; + EP_LIST_INIT (&info->epiList); + NSTACK_SEM_MALLOC (info->epiLock, 1); + NSTACK_SEM_MALLOC (info->freeLock, 1); + + info->rlfd = -1; + info->rmidx = -1; + info->fd = -1; + info->ep = NULL; + info->fdtype = 0; + info->private_data = NULL; + info->epaddflag = 0; + for (iindex = 0; iindex < NSEP_SMOD_MAX; iindex++) + { + info->protoFD[iindex] = -1; + } + (void) nsep_for_pidinfo_init (&(info->pidinfo)); +} + +NSTACK_STATIC void +nsep_destroy_epinfo (nsep_epollInfo_t * info) +{ + // TODO: Here we need to free the semaphore + return; +} + +/** + * @Function nstack_eventpoll_allocShareInfo + * @Description alloc nstack share info + * @param out data - the return value alloced + * @return 0 on success, -1 on error + */ +int +nsep_alloc_epinfo (nsep_epollInfo_t ** data) +{ + nsep_epollInfo_t *head_info = NULL; + + if (NULL == data) + return -1; + NSSOC_LOGDBG ("epinfo alloc begin"); + + nsep_infoPool_t *pool = &nsep_getManager ()->infoPool; + if (0 == nsfw_mem_ring_dequeue (pool->ring, (void *) &head_info) + || NULL == head_info) + { + NSSOC_LOGERR ("epinfo ring alloc failed]pool->ring=%p", pool->ring); + return -1; + } + + res_alloc (&head_info->res_chk); + + nsep_initEpInfo (head_info); + if (0 != nsep_add_pid (&head_info->pidinfo, get_sys_pid ())) + { + NSSOC_LOGERR ("epinfo pid add to headinfo failed]pid=%d,headinfo=%p", + get_sys_pid (), head_info); + } + NSSOC_LOGDBG ("epinfo ring:%p alloc epinfo:%p end", pool->ring, head_info); + *data = head_info; + return 0; +} + +/** + * @Function nstack_eventpoll_freeShareInfo + * @Description free nstack share info + * @param in info - the info to be free + * @return 0 on success, -1 on error + */ +int +nsep_free_epinfo (nsep_epollInfo_t * info) +{ + + if (NULL == info) + return -1; + + nsep_infoPool_t *pool = &nsep_getManager ()->infoPool; + NSSOC_LOGDBG ("nsep_free_epinfo info:%p, pool->ring:%p", info, pool->ring); + nsep_destroy_epinfo (info); + + (void) nsep_for_pidinfo_init (&(info->pidinfo)); + if (res_free (&info->res_chk)) + { + NSFW_LOGERR ("epinfo refree!]epitem=%p", info); + return 0; + } + + if (nsfw_mem_ring_enqueue (pool->ring, (void *) info) != 1) + { + NSSOC_LOGERR ("Errot to free epinfo"); + } + + return 0; +} + +int +nsep_force_epinfo_free (void *data) +{ + nsep_epollInfo_t *info = data; + if (NULL == info) + { + return FALSE; + } + + if (!nsep_is_pid_array_empty (&info->pidinfo)) + { + return FALSE; + } + + res_alloc (&info->res_chk); + (void) nsep_free_epinfo (info); + NSFW_LOGINF ("free epinfo]%p", data); + return TRUE; +} + +int +nsep_force_epitem_free (void *data) +{ + struct epitem *item = data; + if (NULL == item) + { + return FALSE; + } + + if (0 != item->pid) + { + return FALSE; + } + + res_alloc (&item->res_chk); + (void) nsep_free_epitem (item); + NSFW_LOGINF ("free epitem]%p", data); + return TRUE; +} + +int +nsep_force_epevent_free (void *data) +{ + struct eventpoll *epevent = data; + if (NULL == epevent) + { + return FALSE; + } + + if (0 != epevent->pid) + { + return FALSE; + } + + res_alloc (&epevent->res_chk); + (void) nsep_free_eventpoll (epevent); + NSFW_LOGINF ("free event pool]%p", data); + return TRUE; +} + +NSTACK_STATIC int +nsep_init_eventpoll (struct eventpoll *ep) +{ + if (0 != sem_init (&ep->waitSem, 1, 0)) + { + return -1; + } + + NSTACK_SEM_MALLOC (ep->lock, 1); + NSTACK_SEM_MALLOC (ep->sem, 1); + + EP_HLIST_INIT (&ep->rdlist); + ep->ovflist = NSEP_EP_UNACTIVE_PTR; + ep->rbr.rb_node = NULL; + ep->epfd = -1; + return 0; +} + +NSTACK_STATIC void +nsep_destroy_eventpoll (struct eventpoll *ep) +{ + (void) sem_destroy (&ep->waitSem); +} + +/** + * @Function nsep_free_eventpoll + * @Description free nstack eventpoll + * @param in ep - the eventpoll to be free + * @return 0 on success, -1 on error + */ +int +nsep_free_eventpoll (struct eventpoll *ep) +{ + if (!ep) + return -1; + struct eventpoll *epEntry = (struct eventpoll *) ep; + struct eventpoll_pool *pool = &nsep_getManager ()->epollPool; + NSSOC_LOGDBG ("nsep_free_eventpoll ep:%p, epollPool:%p", ep, pool); + nsep_destroy_eventpoll (ep); + ep->pid = 0; + NSSOC_LOGDBG ("Free eventpool"); + if (res_free (&ep->res_chk)) + { + NSFW_LOGERR ("ep refree!]epitem=%p", epEntry); + return 0; + } + + if (nsfw_mem_ring_enqueue (pool->ring, epEntry) != 1) + { + NSSOC_LOGERR ("Errot to free eventpoll"); + } + + return 0; +} + +/** + * @Function nsep_alloc_eventpoll + * @Description alloc nstack eventpoll + * @param out data - the eventpoll alloced + * @return 0 on success, -1 on error + */ +int +nsep_alloc_eventpoll (struct eventpoll **data) +{ + struct eventpoll *p_head = NULL; + struct eventpoll_pool *pool = &nsep_getManager ()->epollPool; + + NSSOC_LOGDBG ("ring:%p alloc eventpool begin", pool->ring); + if (0 == nsfw_mem_ring_dequeue (pool->ring, (void *) &p_head) + || NULL == p_head) + { + NSSOC_LOGERR ("ring alloc eventpool failed]ring=%p", pool->ring); + return -1; + } + + NSSOC_LOGDBG ("alloc eventpool, pid=%u", get_sys_pid ()); + res_alloc (&p_head->res_chk); + p_head->pid = get_sys_pid (); + + if (0 != nsep_init_eventpoll ((struct eventpoll *) p_head)) + { + NSSOC_LOGERR ("p_head init pid alloc failed]p_head=%p,pid=%d", p_head, + get_sys_pid ()); + (void) nsep_free_eventpoll ((struct eventpoll *) p_head); + return -1; + } + + NSSOC_LOGDBG ("ring:%p eventpoll:%p alloc eventpool end", pool->ring, + p_head); + *data = p_head; + return 0; +} + +NSTACK_STATIC int +nsep_init_epitem (struct epitem *epi) +{ + int retVal; + epi->rbn.rb_parent = (struct ep_rb_node *) ADDR_LTOSH_EXT (&epi->rbn); + EP_HLIST_INIT_NODE (&epi->rdllink); + EP_HLIST_INIT_NODE (&epi->lkFDllink); + epi->nwait = 0; + epi->ep = NULL; + epi->next = NSEP_EP_UNACTIVE_PTR; + retVal = + MEMSET_S (&epi->event, sizeof (epi->event), 0, sizeof (epi->event)); + if (EOK != retVal) + { + NSSOC_LOGERR ("MEMSET_S failed]ret=%d", retVal); + return -1; + } + + EP_LIST_INIT_NODE (&epi->fllink); + epi->revents = 0; + epi->ovf_revents = 0; + epi->fd = -1; + epi->private_data = NULL; + + return 0; +} + +/** + * @Function nsep_alloc_epitem + * @Description alloc nstack epitem + * @param out data - the epitem alloced + * @return 0 on success, -1 on error + */ +int +nsep_alloc_epitem (struct epitem **data) +{ + struct epitem *p_head_entry = NULL; + struct epitem_pool *pool = &nsep_getManager ()->epitemPool; + + NSSOC_LOGDBG ("epitem alloc begin.."); + + if (0 == nsfw_mem_ring_dequeue (pool->ring, (void *) &p_head_entry) + || NULL == p_head_entry) + { + NSSOC_LOGERR ("epitem ring alloc failed]ring=%p", pool->ring); + return -1; + } + + res_alloc (&p_head_entry->res_chk); + p_head_entry->pid = get_sys_pid (); + + if (nsep_init_epitem ((struct epitem *) p_head_entry)) + { + (void) nsep_free_epitem ((struct epitem *) p_head_entry); + p_head_entry = NULL; + NSSOC_LOGERR ("ring epitem init failed]ring=%p,epitem=%p", pool->ring, + p_head_entry); + return -1; + } + + NSSOC_LOGDBG ("epitem alloc success..ring:%p head:%p", pool->ring, + p_head_entry); + *data = p_head_entry; + return 0; +} + +typedef int (*nsep_shem_initFn_t) (void *, size_t); + +NSTACK_STATIC int +nsep_epPoolInit (void *addr, size_t lenth) +{ + u32_t pos; + int ret; + + NSSOC_LOGDBG ("Start to init eventpoll pool"); + + ret = MEMSET_S (addr, lenth, 0, lenth); + if (EOK != ret) + { + NSSOC_LOGERR ("MEMSET_S failed]ret=%d", ret); + return -1; + } + struct eventpoll *pool = (struct eventpoll *) addr; + nsep_epollManager_t *manager = nsep_getManager (); + manager->epollPool.pool = pool; + + /* init g_nStackInfo.sockPool->nstack_block_array */ + for (pos = 0; pos < NSTACK_MAX_EPOLL_INFO_NUM; pos++) + { + pool[pos].pid = 0; + if (-1 == nsfw_mem_ring_enqueue (manager->epollPool.ring, &pool[pos])) + { + NSSOC_LOGERR ("init fail to enqueue epitem]pos=%u", pos); + return -1; + } + } + return 0; +} + +NSTACK_STATIC int +nsep_epitemPoolInit (void *addr, size_t lenth) +{ + u32_t pos; + int ret; + + NSSOC_LOGDBG ("Start to init epitem pool"); + + ret = MEMSET_S (addr, lenth, 0, lenth); + if (EOK != ret) + { + NSSOC_LOGERR ("MEMSET_S failed]ret=%d", ret); + return -1; + } + struct epitem *pool = (struct epitem *) addr; + nsep_epollManager_t *manager = nsep_getManager (); + manager->epitemPool.pool = pool; + + /* init g_nStackInfo.sockPool->nstack_block_array */ + for (pos = 0; pos < NSTACK_MAX_EPITEM_NUM; pos++) + { + pool[pos].pid = 0; + if (-1 == nsfw_mem_ring_enqueue (manager->epitemPool.ring, &pool[pos])) + { + NSSOC_LOGERR ("init fail to enqueue epitem]pos=%u", pos); + return -1; + } + } + return 0; +} + +NSTACK_STATIC int +nsep_epInfoPoolInit (void *addr, size_t lenth) +{ + u32_t pos; + int ret; + + NSSOC_LOGDBG ("shmem info init start"); + + ret = MEMSET_S (addr, lenth, 0, lenth); + if (EOK != ret) + { + NSSOC_LOGERR ("MEMSET_S failed]ret=%d", ret); + return -1; + } + nsep_epollInfo_t *pool = (nsep_epollInfo_t *) addr; + nsep_epollManager_t *manager = nsep_getManager (); + manager->infoPool.pool = pool; + + /* init g_nStackInfo.sockPool->nstack_block_array */ + for (pos = 0; pos < NSTACK_MAX_EPOLL_INFO_NUM; pos++) + { + if (nsep_for_pidinfo_init (&(pool[pos].pidinfo))) + { + NSSOC_LOGERR ("pid info init failed]pos=%u", pos); + return -1; + } + + if (-1 == nsfw_mem_ring_enqueue (manager->infoPool.ring, &pool[pos])) + { + NSSOC_LOGERR ("init fail to enqueue epInfo]pos=%u", pos); + return -1; + } + } + + NSSOC_LOGDBG ("nstack_shmen_info_init success"); + return 0; +} + +NSTACK_STATIC int +nsep_create_shmem (size_t length, char *name, nsep_shem_initFn_t initFn) +{ + nsfw_mem_zone pmeminfo; + mzone_handle phandle; + int ret; + + pmeminfo.ireserv = 0; + pmeminfo.isocket_id = NSFW_SOCKET_ANY; + pmeminfo.lenth = length; + ret = + STRCPY_S (pmeminfo.stname.aname, sizeof (pmeminfo.stname.aname), name); + if (EOK != ret) + { + NSSOC_LOGERR ("STRCPY_S failed]name=%s,ret=%d", name, ret); + return -1; + } + pmeminfo.stname.entype = NSFW_SHMEM; + + phandle = nsfw_mem_zone_create (&pmeminfo); + if (NULL == phandle) + { + NSSOC_LOGERR ("create nstack epoll memory failed]name=%s", name); + return -1; + } + + if (0 != initFn ((void *) phandle, length)) + { + NSSOC_LOGERR ("Fail to init memory]name=%s", name); + return -1; + } + + return 0; +} + +NSTACK_STATIC int +nsep_create_epInfoMem () +{ + nsfw_mem_mring pringinfo; + pringinfo.enmptype = NSFW_MRING_MPMC; + pringinfo.isocket_id = NSFW_SOCKET_ANY; + pringinfo.stname.entype = NSFW_SHMEM; + pringinfo.usnum = NSTACK_MAX_EPOLL_INFO_NUM; + + if (-1 == + SPRINTF_S (pringinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s", + MP_NSTACK_EPINFO_RING_NAME)) + { + NSSOC_LOGERR ("Error to create ring]name=%s", pringinfo.stname.aname); + return -1; + } + + mring_handle ring_handle = nsfw_mem_ring_create (&pringinfo); + + if (NULL == ring_handle) + { + NSSOC_LOGERR ("Error to create ring]name=%s", pringinfo.stname.aname); + return -1; + } + + nsep_epollManager_t *manager = nsep_getManager (); + manager->infoPool.ring = ring_handle; + + return nsep_create_shmem (sizeof (nsep_epollInfo_t) * + NSTACK_MAX_EPOLL_INFO_NUM, + MP_NSTACK_EPOLL_INFO_NAME, nsep_epInfoPoolInit); +} + +NSTACK_STATIC int +nsep_adpt_attach_epInfoMem () +{ + nsfw_mem_name name; + name.entype = NSFW_SHMEM; + name.enowner = NSFW_PROC_MAIN; + + if (-1 == + SPRINTF_S (name.aname, NSFW_MEM_NAME_LENTH, "%s", + MP_NSTACK_EPINFO_RING_NAME)) + { + NSSOC_LOGERR ("Error to attach ring]name=%s", name.aname); + return -1; + } + mring_handle ring_handle = nsfw_mem_ring_lookup (&name); + + if (NULL == ring_handle) + { + NSSOC_LOGERR ("Error to attach ring]name=%s", name.aname); + return -1; + } + + nsep_epollManager_t *manager = nsep_getManager (); + manager->infoPool.ring = ring_handle; + + if (-1 == + SPRINTF_S (name.aname, NSFW_MEM_NAME_LENTH, "%s", + MP_NSTACK_EPOLL_INFO_NAME)) + { + NSSOC_LOGERR ("SPRINTF_S failed]"); + return -1; + } + manager->infoPool.pool = nsfw_mem_zone_lookup (&name); + if (NULL == manager->infoPool.pool) + { + NSSOC_LOGERR ("Error to attach memzone]name=%s", + MP_NSTACK_EPOLL_INFO_NAME); + return -1; + } + return 0; +} + +NSTACK_STATIC int +nsep_create_epItemMem () +{ + nsfw_mem_mring pringinfo; + pringinfo.enmptype = NSFW_MRING_MPMC; + pringinfo.isocket_id = NSFW_SOCKET_ANY; + pringinfo.stname.entype = NSFW_SHMEM; + pringinfo.usnum = NSTACK_MAX_EPITEM_NUM; + + if (-1 == + SPRINTF_S (pringinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s", + MP_NSTACK_EPITEM_RING_NAME)) + { + NSSOC_LOGERR ("Error to create ring]name=%s", pringinfo.stname.aname); + return -1; + } + + mring_handle ring_handle = nsfw_mem_ring_create (&pringinfo); + + if (NULL == ring_handle) + { + NSSOC_LOGERR ("Error to create ring]name=%s", pringinfo.stname.aname); + return -1; + } + + nsep_epollManager_t *manager = nsep_getManager (); + manager->epitemPool.ring = ring_handle; + + return nsep_create_shmem (sizeof (struct epitem) * NSTACK_MAX_EPITEM_NUM, + MP_NSTACK_EPITEM_POOL, nsep_epitemPoolInit); +} + +NSTACK_STATIC int +nsep_adpt_attach_epItemMem () +{ + nsfw_mem_name name; + name.entype = NSFW_SHMEM; + name.enowner = NSFW_PROC_MAIN; + + if (-1 == + SPRINTF_S (name.aname, NSFW_MEM_NAME_LENTH, "%s", + MP_NSTACK_EPITEM_RING_NAME)) + { + NSSOC_LOGERR ("Error to attach epItemMem]name=%s", name.aname); + return -1; + } + + mring_handle ring_handle = nsfw_mem_ring_lookup (&name); + + if (NULL == ring_handle) + { + NSSOC_LOGERR ("Error to attach ring]name=%s", name.aname); + return -1; + } + + nsep_epollManager_t *manager = nsep_getManager (); + manager->epitemPool.ring = ring_handle; + + if (-1 == + SPRINTF_S (name.aname, NSFW_MEM_NAME_LENTH, "%s", + MP_NSTACK_EPITEM_POOL)) + { + NSSOC_LOGERR ("SPRINTF_S failed]"); + return -1; + } + manager->epitemPool.pool = nsfw_mem_zone_lookup (&name); + if (NULL == manager->epitemPool.pool) + { + NSSOC_LOGERR ("Error to attach memzone]name=%s", MP_NSTACK_EPITEM_POOL); + return -1; + } + return 0; +} + +NSTACK_STATIC int +nsep_create_eventpollMem () +{ + nsfw_mem_mring pringinfo; + pringinfo.enmptype = NSFW_MRING_MPMC; + pringinfo.isocket_id = NSFW_SOCKET_ANY; + pringinfo.stname.entype = NSFW_SHMEM; + pringinfo.usnum = NSTACK_MAX_EPOLL_NUM; + + if (-1 == + SPRINTF_S (pringinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s", + MP_NSTACK_EVENTPOOL_RING_NAME)) + { + NSSOC_LOGERR ("Error to create ring]name=%s", pringinfo.stname.aname); + return -1; + } + + mring_handle ring_handle = nsfw_mem_ring_create (&pringinfo); + + if (NULL == ring_handle) + { + NSSOC_LOGERR ("Error to create ring]name=%s", pringinfo.stname.aname); + return -1; + } + + nsep_epollManager_t *manager = nsep_getManager (); + manager->epollPool.ring = ring_handle; + + return nsep_create_shmem (sizeof (struct eventpoll) * NSTACK_MAX_EPOLL_NUM, + MP_NSTACK_EVENTPOLL_POOL, nsep_epPoolInit); +} + +NSTACK_STATIC int +nsep_adpt_attach_eventpollMem () +{ + nsfw_mem_name name; + name.entype = NSFW_SHMEM; + name.enowner = NSFW_PROC_MAIN; + + if (-1 == + SPRINTF_S (name.aname, NSFW_MEM_NAME_LENTH, "%s", + MP_NSTACK_EVENTPOOL_RING_NAME)) + { + NSSOC_LOGERR ("Error to attach ring]name=%s", name.aname); + return -1; + } + + mring_handle ring_handle = nsfw_mem_ring_lookup (&name); + + if (NULL == ring_handle) + { + NSSOC_LOGERR ("Error to create ring]name=%s", name.aname); + return -1; + } + + nsep_epollManager_t *manager = nsep_getManager (); + manager->epollPool.ring = ring_handle; + + int retVal = SPRINTF_S (name.aname, NSFW_MEM_NAME_LENTH, "%s", + MP_NSTACK_EVENTPOLL_POOL); + if (-1 == retVal) + { + NSSOC_LOGERR ("SPRINTF_S faild]ret=%d", retVal); + return -1; + } + manager->epollPool.pool = nsfw_mem_zone_lookup (&name); + if (NULL == manager->epollPool.pool) + { + NSSOC_LOGERR ("Error to attach memzone]name=%s", + MP_NSTACK_EVENTPOLL_POOL); + return -1; + } + + return 0; +} + +int +nsep_create_memory () +{ + typedef int (*nsep_createMemFunc_t) (void); + nsep_createMemFunc_t createFuncs[] = { nsep_create_epInfoMem, + nsep_create_epItemMem, + nsep_create_eventpollMem + }; + + int i = 0; + for (i = 0; + i < (int) (sizeof (createFuncs) / sizeof (nsep_createMemFunc_t)); i++) + { + if (-1 == createFuncs[i] ()) + return -1; + } + + return 0; +} + +int +nsep_adpt_attach_memory () +{ + typedef int (*nsep_attachMemFunc_t) (void); + nsep_attachMemFunc_t attachFuncs[] = { nsep_adpt_attach_epInfoMem, + nsep_adpt_attach_epItemMem, + nsep_adpt_attach_eventpollMem + }; + + int i = 0; + for (i = 0; + i < (int) (sizeof (attachFuncs) / sizeof (nsep_attachMemFunc_t)); i++) + { + if (-1 == attachFuncs[i] ()) + { + NSSOC_LOGERR ("mem attach fail]idx=%d", i); + return -1; + } + } + + return 0; +} + +int +nsep_adpt_reg_res_mgr () +{ + + nsep_epollManager_t *manager = nsep_getManager (); + + nsfw_res_scn_cfg scn_cfg_info = { NSFW_RES_SCAN_ARRAY, 90, 3, 16, + NSTACK_MAX_EPOLL_INFO_NUM / 128, NSTACK_MAX_EPOLL_INFO_NUM, + sizeof (nsep_epollInfo_t), + offsetof (nsep_epollInfo_t, res_chk), + manager->infoPool.pool, + manager->infoPool.ring, + nsep_force_epinfo_free + }; + + nsfw_res_scn_cfg scn_cfg_item = { NSFW_RES_SCAN_ARRAY, 90, 3, 16, + NSTACK_MAX_EPITEM_NUM / 128, NSTACK_MAX_EPITEM_NUM, + sizeof (struct epitem), + offsetof (struct epitem, res_chk), + manager->epitemPool.pool, + manager->epitemPool.ring, + nsep_force_epitem_free + }; + + nsfw_res_scn_cfg scn_cfg_event = { NSFW_RES_SCAN_ARRAY, 90, 3, 16, + NSTACK_MAX_EPOLL_NUM / 128, NSTACK_MAX_EPOLL_NUM, + sizeof (struct eventpoll), + offsetof (struct eventpoll, res_chk), + manager->epollPool.pool, + manager->epollPool.ring, + nsep_force_epevent_free + }; + + (void) nsfw_res_mgr_reg (&scn_cfg_info); + (void) nsfw_res_mgr_reg (&scn_cfg_item); + (void) nsfw_res_mgr_reg (&scn_cfg_event); + return 0; +} + +int +nsep_epitem_remove (nsep_epollInfo_t * pinfo, u32 pid) +{ + struct list_node *prenode = NULL; + struct list_node *nextnode = NULL; + struct epitem *epi = NULL; + u32_t i = 0; + int icnt = 0; + (void) sys_arch_lock_with_pid (&pinfo->epiLock); + /*list head must be not null */ + prenode = (struct list_node *) ADDR_SHTOL (pinfo->epiList.head); + nextnode = (struct list_node *) ADDR_SHTOL (prenode->next); + while ((nextnode) && (i++ <= NSTACK_MAX_EPOLL_INFO_NUM)) + { + epi = ep_list_entry (nextnode, struct epitem, fllink); + if (pid == epi->pid) + { + /*shmem equal to shmem */ + prenode->next = nextnode->next; + nextnode->next = NULL; + (void) nsep_free_epitem (epi); + nextnode = ADDR_SHTOL (prenode->next); + icnt++; + continue; + } + prenode = nextnode; + nextnode = ADDR_SHTOL (nextnode->next); + } + sys_sem_s_signal (&pinfo->epiLock); + if (i >= NSTACK_MAX_EPOLL_INFO_NUM) + { + NSSOC_LOGERR ("free pinfo:%p pid:%u, error maybe happen", pinfo, pid); + } + return icnt; +} + +void +nsep_recycle_epfd (void *epinfo, u32 pid) +{ + struct eventpoll *ep = NULL; + nsep_epollInfo_t *info = (nsep_epollInfo_t *) epinfo; + int ret = 0; + int ileftcnt = 0; + if (!epinfo) + { + NSSOC_LOGDBG ("input null, pid:%u", pid); + return; + } + (void) sys_arch_lock_with_pid (&info->freeLock); + ileftcnt = nsep_del_last_pid (&info->pidinfo, pid); + sys_sem_s_signal (&info->freeLock); + /*no pid exist */ + if (-1 == ileftcnt) + { + return; + } + if (NSTACK_EPOL_FD == info->fdtype) + { + NSSOC_LOGDBG ("recycle epfd:%d epinfo pid:%u begin...", info->fd, pid); + if (0 == ileftcnt) + { + ep = ADDR_SHTOL (info->ep); + info->ep = NULL; + (void) nsep_free_eventpoll (ep); + (void) nsep_free_epinfo (info); + } + return; + } + + NSSOC_LOGDBG ("recycle fd:%d epinfo pid:%u begin...", info->fd, pid); + + ret = nsep_epitem_remove (info, pid); + if (0 != ret) + { + NSSOC_LOGINF ("info:%p, fd:%d pid:%u, %d items was left", info, + info->fd, pid, ret); + } + + if (0 == ileftcnt) + { + NSSOC_LOGINF ("info:%p, fd:%d pid:%u was finally freed", info, info->fd, + pid); + (void) nsep_free_epinfo (info); + } + return; +} + +int +nsep_recyle_ep (u32 pid) +{ + nsep_epollManager_t *manager = nsep_getManager (); + nsep_epollInfo_t *pool = manager->infoPool.pool; + + u32_t pos; + for (pos = 0; pos < NSTACK_MAX_EPOLL_INFO_NUM; pos++) + { + (void) nsep_recycle_epfd (&pool[pos], pid); + } + return 0; +} + +NSTACK_STATIC int +nsep_recyle_epItem (u32 pid) +{ + nsep_epollManager_t *manager = nsep_getManager (); + struct epitem *pool = manager->epitemPool.pool; + + u32_t pos; + for (pos = 0; pos < NSTACK_MAX_EPITEM_NUM; pos++) + { + if (pool[pos].pid != pid) + continue; + + if (-1 == nsep_free_epitem (&pool[pos])) + return -1; + } + + return 0; +} + +NSTACK_STATIC int +nsep_recyle_eventpoll (u32 pid) +{ + nsep_epollManager_t *manager = nsep_getManager (); + struct eventpoll *pool = manager->epollPool.pool; + + u32_t pos; + for (pos = 0; pos < NSTACK_MAX_EPOLL_INFO_NUM; pos++) + { + if (pool[pos].pid != pid) + continue; + + if (-1 == nsep_free_eventpoll (&pool[pos])) + return -1; + } + + return 0; +} + +NSTACK_STATIC + nsfw_rcc_stat nsep_recycle_resource (u32 exit_pid, void *pdata, + u16 rec_type) +{ + NSSOC_LOGINF ("pid:%u recycle", exit_pid); + (void) nsep_recyle_epItem (exit_pid); + (void) nsep_recyle_eventpoll (exit_pid); + return NSFW_RCC_CONTINUE; +} + +NSTACK_STATIC + nsfw_rcc_stat nsep_recyle_lock (u32 pid, void *pdata, u16 rec_type) +{ + nsep_epollManager_t *manager = nsep_getManager (); + nsep_epollInfo_t *pool = manager->infoPool.pool; + u32_t pos; + if (NULL != pool) + { + for (pos = 0; pos < NSTACK_MAX_EPOLL_INFO_NUM; pos++) + { + if (pid == pool[pos].epiLock.locked) + { + pool[pos].epiLock.locked = 0; + NSFW_LOGWAR ("epiLock locked]pos=%u,pid=%u", pos, pid); + } + if (pid == pool[pos].freeLock.locked) + { + pool[pos].freeLock.locked = 0; + NSFW_LOGWAR ("freelock locked]pos=%u,pid=%u", pos, pid); + } + } + } + + struct eventpoll *ev_pool = manager->epollPool.pool; + if (NULL != ev_pool) + { + for (pos = 0; pos < NSTACK_MAX_EPOLL_NUM; pos++) + { + if (pid == ev_pool[pos].lock.locked) + { + ev_pool[pos].lock.locked = 0; + NSFW_LOGWAR ("event_pollLock locked]pos=%u,pid=%u", pos, pid); + } + + if (pid == ev_pool[pos].sem.locked) + { + ev_pool[pos].sem.locked = 0; + NSFW_LOGWAR ("event_pollLock sem]pos=%u,pid=%u", pos, pid); + } + } + } + + return NSFW_RCC_CONTINUE; +} + +REGIST_RECYCLE_OBJ_FUN (NSFW_REC_NSOCKET_EPOLL, + nsep_recycle_resource) +REGIST_RECYCLE_LOCK_REL (nsep_recyle_lock, NULL, NSFW_PROC_NULL) diff --git a/src/adapt/nstack_rd_mng.c b/src/adapt/nstack_rd_mng.c new file mode 100644 index 0000000..64c54a8 --- /dev/null +++ b/src/adapt/nstack_rd_mng.c @@ -0,0 +1,317 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include "nstack_rd_data.h" +#include "nsfw_mem_api.h" +#include "nstack_log.h" +#include "nstack_securec.h" + +#define RD_SHMEM_NAME "rd_table" + +#define RD_AGE_MAX_TIME 3 + +rd_route_table *g_rd_table_handle = NULL; + +#define RD_IP_ROUTE_CPY(pnode, name, data) { \ + if (EOK != STRCPY_S((pnode)->data.stack_name, RD_PLANE_NAMELEN, (name))) \ + { \ + NSSOC_LOGERR("STRCPY_S failed]copy_name=%s", name); \ + } \ + (pnode)->data.type = RD_DATA_TYPE_IP; \ + (pnode)->agetime = 0; \ + (pnode)->data.ipdata.addr = (data)->addr; \ + (pnode)->data.ipdata.masklen = (data)->masklen; \ + (pnode)->data.ipdata.resev[0] = 0; \ + (pnode)->data.ipdata.resev[1] = 0; \ +} + +/***************************************************************************** +* Prototype : nstack_rd_mng_int +* Description : rd mng moudule init, create a block memory +* Input : int flag +* Output : None +* Return Value : int +* Calls : +* Called By : nStackMain +*****************************************************************************/ +int +nstack_rd_mng_int (int flag) +{ + int ret; + nsfw_mem_zone zname = { + {NSFW_SHMEM, NSFW_PROC_MAIN, RD_SHMEM_NAME}, + sizeof (rd_route_table), + NSFW_SOCKET_ANY, + 0 + }; + NSSOC_LOGINF ("nstack rd mng init begin]flag=%d", flag); + /*nstack main create, app lookup */ + if (0 == flag) + { + g_rd_table_handle = (rd_route_table *) nsfw_mem_zone_create (&zname); + if (!g_rd_table_handle) + { + NSSOC_LOGERR ("mem create fail]mem name=%s", RD_SHMEM_NAME); + return -1; + } + ret = + MEMSET_S (&(g_rd_table_handle->node[0]), sizeof (rd_route_node), 0, + sizeof (rd_route_node)); + if (EOK != ret) + { + NSSOC_LOGERR ("MEMSET_S failed]ret=%d", ret); + return -1; + } + g_rd_table_handle->size = NSTACK_RD_DATA_MAX; + g_rd_table_handle->icnt = 0; + } + else /* static data will not be erased in fault case */ + { + g_rd_table_handle = + (rd_route_table *) nsfw_mem_zone_lookup (&(zname.stname)); + if (!g_rd_table_handle) + { + NSSOC_LOGERR ("mem lookup fail]mem name=%s", RD_SHMEM_NAME); + return -1; + } + } + NSSOC_LOGINF ("nstack rd mng init end flag"); + return 0; +} + +/***************************************************************************** +* Prototype : nstack_rd_ip_node_insert +* Description : insert a rd_ip_data into list +* Input : char *name +* rd_ip_data *data +* Output : None +* Return Value : int +* Calls : +* Called By : nStackMain +*****************************************************************************/ +int +nstack_rd_ip_node_insert (char *name, rd_ip_data * data) +{ + if (!g_rd_table_handle) + { + NSSOC_LOGERR ("nstack rd mng not inited"); + return -1; + } + int iindex = 0; + rd_route_node *pnode = NULL; + int agetime = 0; + int ageindex = -1; + int freeindex = -1; + int repeatflag = 0; + + for (iindex = 0; iindex < NSTACK_RD_DATA_MAX; iindex++) + { + pnode = &(g_rd_table_handle->node[iindex]); + /*record the index of first free element */ + if (RD_NODE_USELESS == pnode->flag) + { + if (-1 == freeindex) + { + freeindex = iindex; + NSSOC_LOGINF ("nstack rd ip free element index:%d was found", + iindex); + } + continue; + } + + /*if is using, and repeat just set flag */ + if (RD_NODE_USING == pnode->flag) + { + if (MASK_V (pnode->data.ipdata.addr, pnode->data.ipdata.masklen) == + MASK_V (data->addr, data->masklen)) + { + NSSOC_LOGWAR + ("nstack:%s, old_addr:0x%x index:%d new_addr:0x%x, masklen:%u was repeat", + name, pnode->data.ipdata.addr, iindex, data->addr, + data->masklen); + repeatflag = 1; + } + continue; + } + + /*if flag is deleting, just update the age time, if agetime is on, just set flag to free */ + if (RD_NODE_DELETING == pnode->flag) + { + pnode->agetime++; + if (pnode->agetime >= RD_AGE_MAX_TIME) + { + pnode->flag = RD_NODE_USELESS; + NSSOC_LOGINF + ("nstack rd ip element index:%d addr:0x%x, masklen:%u was delete and set to free", + iindex, pnode->data.ipdata.addr, pnode->data.ipdata.masklen); + } + /*record delete time */ + if (agetime < pnode->agetime) + { + agetime = pnode->agetime; + ageindex = iindex; + } + continue; + } + } + + /*if repeat, just return */ + if (1 == repeatflag) + { + return 0; + } + if (-1 == freeindex) + { + if (-1 != ageindex) + { + freeindex = ageindex; + } + else + { + NSSOC_LOGERR + ("the rd table is full,nstack:%s, rd addr:0x%x, masklen:%u can't be inserted", + name, data->addr, data->masklen); + return -1; + } + } + pnode = &(g_rd_table_handle->node[freeindex]); + /*if no free found, just reuse the big agetime */ + RD_IP_ROUTE_CPY (pnode, name, data); + pnode->flag = RD_NODE_USING; /*last set */ + g_rd_table_handle->icnt++; + NSSOC_LOGINF ("nstack:%s, rd addr:0x%x, masklen:%u index was inserted", + name, data->addr, data->masklen); + return 0; +} + +/***************************************************************************** +* Prototype : nstack_rd_ip_node_delete +* Description : rd data delete +* Input : rd_ip_data *data +* Output : None +* Return Value : int +* Calls : +* Called By : nStackMain +* just set delete flag, becuase +*****************************************************************************/ +int +nstack_rd_ip_node_delete (rd_ip_data * data) +{ + int iindex = 0; + rd_route_node *pnode = NULL; + + if (!g_rd_table_handle) + { + NSSOC_LOGERR ("nstack rd mng not inited"); + return -1; + } + + for (iindex = 0; iindex < NSTACK_RD_DATA_MAX; iindex++) + { + pnode = &(g_rd_table_handle->node[iindex]); + if ((RD_NODE_USING == pnode->flag) + && (MASK_V (pnode->data.ipdata.addr, pnode->data.ipdata.masklen) == + MASK_V (data->addr, data->masklen))) + { + pnode->flag = RD_NODE_DELETING; /*just set deleting state */ + pnode->agetime = 0; + g_rd_table_handle->icnt--; + NSSOC_LOGINF + ("nstack rd delete:%s, addr:0x%x, masklen:%u index:%d was delete", + pnode->data.stack_name, data->addr, data->masklen, iindex); + return 0; + } + } + NSSOC_LOGINF ("nstack rd delete, addr:0x%x, masklen:%u index was not found", + data->addr, data->masklen); + return 0; +} + +/***************************************************************************** +* Prototype : nstack_rd_ip_get +* Description : get rd data from rd table +* Input : char *planename +* rd_route_data **data +* int *num +* Output : None +* Return Value : int +* Calls : +* Called By : +* Note : a block memory was alloc and return by data, +* this need free by caller if return 0, otherwise no need +*****************************************************************************/ +int +nstack_rd_ip_get (rd_route_data ** data, int *num) +{ + rd_route_data *pdata = NULL; + rd_route_node *pnode = NULL; + int size = 0; + int icnt = 0; + int idex = 0; + int ret; + + if (!g_rd_table_handle || !data || !num) + { + NSSOC_LOGERR ("nstack rd mng not inited or input err"); + return -1; + } + size = sizeof (rd_route_data) * g_rd_table_handle->size; + pdata = (rd_route_data *) malloc (size); + if (!pdata) + { + NSSOC_LOGERR ("rd route data malloc fail"); + return -1; + } + ret = MEMSET_S (pdata, size, 0, size); + if (EOK != ret) + { + NSSOC_LOGERR ("MEMSET_S failed]ret=%d", ret); + free (pdata); + return -1; + } + for (icnt = 0; icnt < g_rd_table_handle->size; icnt++) + { + pnode = &(g_rd_table_handle->node[icnt]); + if (RD_NODE_USING == pnode->flag) + { + pdata[idex].type = pnode->data.type; + pdata[idex].ipdata.addr = pnode->data.ipdata.addr; + pdata[idex].ipdata.masklen = pnode->data.ipdata.masklen; + pdata[idex].ipdata.resev[0] = pnode->data.ipdata.resev[0]; + pdata[idex].ipdata.resev[1] = pnode->data.ipdata.resev[1]; + ret = + STRCPY_S (pdata[idex].stack_name, RD_PLANE_NAMELEN, + pnode->data.stack_name); + if (EOK != ret) + { + NSSOC_LOGERR ("STRCPY_S failed]ret=%d", ret); + free (pdata); + return -1; + } + idex++; + } + } + /*if no data fetched , just return fail */ + if (idex == 0) + { + free (pdata); + return -1; + } + *data = pdata; + *num = idex; + return 0; +} diff --git a/src/adapt/nstack_rd_mng.h b/src/adapt/nstack_rd_mng.h new file mode 100644 index 0000000..f1fe7a3 --- /dev/null +++ b/src/adapt/nstack_rd_mng.h @@ -0,0 +1,27 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef __NSTACK_RD_MNG_H +#define __NSTACK_RD_MNG_H +#include +#include "nstack_rd_data.h" + +int nstack_rd_mng_int (int flag); +int nstack_rd_ip_node_insert (char *name, rd_ip_data * data); +int nstack_rd_ip_node_delete (rd_ip_data * data); +int nstack_rd_ip_get (rd_route_data ** data, int *num); + +#endif diff --git a/src/adapt/nstack_share_res.c b/src/adapt/nstack_share_res.c new file mode 100644 index 0000000..421b5ed --- /dev/null +++ b/src/adapt/nstack_share_res.c @@ -0,0 +1,176 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "nstack_share_res.h" +#include "nsfw_mem_api.h" +#include "types.h" +#include "nsfw_recycle_api.h" +#include "nstack_securec.h" +#include "nstack_log.h" +#include "nsfw_maintain_api.h" +#include "nstack_types.h" + +#define NSTACK_SHARE_FORK_LOCK "share_fork_lock" + +typedef struct +{ + common_mem_spinlock_t *fork_share_lock; +} nstack_share_res; + +NSTACK_STATIC nstack_share_res g_nstack_share_res; + +/** global timer tick */ +nstack_tick_info_t g_nstack_timer_tick; + +NSTACK_STATIC int +nstack_create_share_fork_lock () +{ + mzone_handle zone; + nsfw_mem_zone param; + int ret; + + param.isocket_id = -1; + param.lenth = sizeof (common_mem_spinlock_t); + param.stname.entype = NSFW_SHMEM; + + ret = + STRCPY_S (param.stname.aname, NSFW_MEM_NAME_LENTH, + NSTACK_SHARE_FORK_LOCK); + if (EOK != ret) + { + NSSOC_LOGERR ("STRCPY_S failed]name=%s,ret=%d", NSTACK_SHARE_FORK_LOCK, + ret); + return -1; + } + + zone = nsfw_mem_zone_create (¶m); + if (!zone) + { + NSSOC_LOGERR ("nsfw_mem_zone_create failed]name=%s", + NSTACK_SHARE_FORK_LOCK); + return -1; + } + + g_nstack_share_res.fork_share_lock = (common_mem_spinlock_t *) zone; + common_mem_spinlock_init (g_nstack_share_res.fork_share_lock); + + NSSOC_LOGDBG ("ok"); + return 0; +} + +NSTACK_STATIC int +nstack_lookup_share_fork_lock () +{ + mzone_handle zone; + nsfw_mem_name param; + + param.entype = NSFW_SHMEM; + param.enowner = NSFW_PROC_MAIN; + if (STRCPY_S (param.aname, NSFW_MEM_NAME_LENTH, NSTACK_SHARE_FORK_LOCK) != + 0) + { + NSSOC_LOGERR ("STRCPY_S failed]name=%s", NSTACK_SHARE_FORK_LOCK); + return -1; + } + + zone = nsfw_mem_zone_lookup (¶m); + if (!zone) + { + NSSOC_LOGERR ("nsfw_mem_zone_lookup failed]name=%s", + NSTACK_SHARE_FORK_LOCK); + return -1; + } + + g_nstack_share_res.fork_share_lock = (common_mem_spinlock_t *) zone; + + NSSOC_LOGDBG ("ok"); + + return 0; +} + +NSTACK_STATIC int +nstack_lookup_share_global_tick () +{ + int ret; + nsfw_mem_name name = {.entype = NSFW_SHMEM,.enowner = NSFW_PROC_MAIN }; + + ret = STRCPY_S (name.aname, NSFW_MEM_NAME_LENTH, NSTACK_GLOBAL_TICK_SHM); + if (EOK != ret) + { + NSSOC_LOGERR ("STRCPY_S failed]name=%s,ret=%d", NSTACK_GLOBAL_TICK_SHM, + ret); + return -1; + } + + g_nstack_timer_tick.tick_ptr = (u64_t *) nsfw_mem_zone_lookup (&name); + if (NULL == g_nstack_timer_tick.tick_ptr) + { + NSPOL_LOGERR ("Failed to lookup global timer tick memory"); + return -1; + } + + NSSOC_LOGDBG ("ok"); + return 0; +} + +int +nstack_init_share_res () +{ + if (nstack_create_share_fork_lock () != 0) + { + return -1; + } + + return 0; +} + +int +nstack_attach_share_res () +{ + if (nstack_lookup_share_fork_lock () != 0) + { + return -1; + } + + if (nstack_lookup_share_global_tick () != 0) + { + return -1; + } + + return 0; +} + +common_mem_spinlock_t * +nstack_get_fork_share_lock () +{ + return g_nstack_share_res.fork_share_lock; +} + +NSTACK_STATIC nsfw_rcc_stat +nstack_recycle_fork_share_lock (u32 exit_pid, void *pdata, u16 rec_type) +{ + NSSOC_LOGDBG ("recycle]pid=%u", exit_pid); + + if (g_nstack_share_res.fork_share_lock + && (g_nstack_share_res.fork_share_lock->locked == exit_pid)) + { + common_mem_spinlock_unlock (g_nstack_share_res.fork_share_lock); + } + + return NSFW_RCC_CONTINUE; +} + +REGIST_RECYCLE_LOCK_REL (nstack_recycle_fork_share_lock, NULL, NSFW_PROC_APP) diff --git a/src/adapt/nstack_share_res.h b/src/adapt/nstack_share_res.h new file mode 100644 index 0000000..5025482 --- /dev/null +++ b/src/adapt/nstack_share_res.h @@ -0,0 +1,66 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef NSTACK_SHARE_RES_H +#define NSTACK_SHARE_RES_H + +#include +#include "common_mem_spinlock.h" +#include "nstack_log.h" +#include "common_func.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define NSTACK_VERSION_SHM "nstack_version" +#define NSTACK_VERSION_LEN 128 +COMPAT_PROTECT (NSTACK_VERSION_LEN, 128); +#define MAX_UNMATCH_VER_CNT 32 +COMPAT_PROTECT (MAX_UNMATCH_VER_CNT, 32); + +#define NSTACK_GLOBAL_TICK_SHM "nstack_global_tick" + +typedef struct unmatch_ver_info +{ + int unmatch_count; + char lib_version[NSTACK_VERSION_LEN]; + char first_time_stamp[LOG_TIME_STAMP_LEN]; +} unmatch_ver_info_t; + +#define DFX_TMR_INTERVAL 60000 /*60 seconds */ +typedef struct nstack_tick_info +{ + uint64_t *tick_ptr; // tick from shared memory + uint64_t interval; // tick interval, only used in stack process + /* tick refference, updated periodically and read in tcpip_thread only */ + struct timeval ref_time; // ref tick time + uint64_t ref_tick; // ref tick +} nstack_tick_info_t; + +int nstack_init_share_res (); +int nstack_attach_share_res (); +common_mem_spinlock_t *nstack_get_fork_share_lock (); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif -- cgit