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/framework/CMakeLists.txt | 61 + .../common/base/include/common/common_func.h | 98 + .../common/base/include/common/common_mem_api.h | 144 ++ .../base/include/common/common_mem_base_type.h | 85 + .../common/base/include/common/common_mem_buf.h | 75 + .../common/base/include/common/common_mem_common.h | 25 + .../common/base/include/common/common_mem_malloc.h | 25 + .../common/base/include/common/common_mem_mbuf.h | 40 + .../base/include/common/common_mem_mempool.h | 25 + .../base/include/common/common_mem_memzone.h | 25 + .../common/base/include/common/common_mem_pal.h | 30 + .../base/include/common/common_mem_pal_memconfig.h | 26 + .../base/include/common/common_mem_spinlock.h | 40 + .../common/base/include/common/common_sys_config.h | 46 + .../include/common/generic/common_mem_rwlock.h | 25 + .../base/include/common_pal_bitwide_adjust.h | 222 +++ .../common/base/include/nsfw_base_linux_api.h | 58 + src/framework/common/base/include/nsfw_getopt.h | 50 + .../base/liblinuxapi/base_linux_api_declare.h | 51 + .../common/base/liblinuxapi/nsfw_base_linux_api.c | 628 ++++++ .../common/base/liblinuxapi/nsfw_getopt.c | 455 +++++ .../common/base/liblinuxapi/nsfw_lock_file.c | 174 ++ src/framework/common/data_struct/eprb_tree.c | 492 +++++ src/framework/common/data_struct/list.c | 163 ++ src/framework/common/data_struct/pidinfo.c | 125 ++ src/framework/common/data_struct/sha256.c | 397 ++++ src/framework/common/include/compile_config.h | 30 + src/framework/common/include/compiling_check.h | 106 + src/framework/common/include/ephlist.h | 199 ++ src/framework/common/include/eprb_tree.h | 84 + src/framework/common/include/list.h | 181 ++ src/framework/common/include/pidinfo.h | 48 + src/framework/common/include/sha256.h | 94 + src/framework/common/include/types.h | 97 + .../common/mem_mgr/include/nsfw_mem_desc.h | 172 ++ .../common/mem_mgr/include/nsfw_ring_data.h | 95 + .../common/mem_mgr/include/nsfw_ring_fun.h | 110 ++ src/framework/common/mem_mgr/nsfw_mem_api.c | 879 +++++++++ src/framework/common/mem_mgr/nsfw_mem_construct.c | 21 + src/framework/common/mem_mgr/nsfw_mem_desc.c | 92 + src/framework/common/mem_mgr/nsfw_mem_stat.c | 292 +++ .../common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.c | 47 + .../common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.h | 22 + .../common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.c | 544 ++++++ .../common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.h | 70 + .../common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.c | 436 +++++ .../common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.h | 37 + src/framework/common/mem_mgr/nsfw_res_mgr.c | 429 +++++ .../common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.c | 987 ++++++++++ .../common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.h | 51 + .../common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.c | 47 + .../common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.h | 22 + .../common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.c | 880 +++++++++ .../common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.h | 133 ++ .../common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.c | 839 ++++++++ .../common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.h | 60 + src/framework/hal/hal.c | 865 +++++++++ src/framework/hal/hal.h | 182 ++ src/framework/include/hal_api.h | 148 ++ src/framework/include/nsfw_fd_timer_api.h | 64 + src/framework/include/nsfw_init.h | 148 ++ src/framework/include/nsfw_maintain_api.h | 320 +++ src/framework/include/nsfw_mem_api.h | 546 ++++++ src/framework/include/nsfw_mgr_com_api.h | 198 ++ src/framework/include/nsfw_ps_api.h | 134 ++ src/framework/include/nsfw_ps_mem_api.h | 36 + src/framework/include/nsfw_recycle_api.h | 92 + src/framework/include/nsfw_snapshot.h | 144 ++ src/framework/include/nsfw_upgrade.h | 51 + src/framework/include/nstack_log.h | 580 ++++++ src/framework/include/nstack_rd_data.h | 80 + src/framework/include/nstack_securec.h | 145 ++ src/framework/include/nstack_trace.h | 76 + src/framework/init/CMakeLists.txt | 24 + src/framework/init/fw_init.c | 320 +++ src/framework/init/fw_module.c | 331 ++++ src/framework/init/fw_module.h | 85 + src/framework/ipc/mgr_com/mgr_com.c | 2037 ++++++++++++++++++++ src/framework/ipc/mgr_com/mgr_com.h | 150 ++ src/framework/ipc/ps/nsfw_fd_timer.c | 378 ++++ src/framework/ipc/ps/nsfw_ps_mem_module.c | 924 +++++++++ src/framework/ipc/ps/nsfw_ps_mem_module.h | 87 + src/framework/ipc/ps/nsfw_ps_module.c | 1725 +++++++++++++++++ src/framework/ipc/ps/nsfw_ps_module.h | 99 + src/framework/ipc/ps/nsfw_recycle_module.c | 666 +++++++ src/framework/ipc/ps/nsfw_recycle_module.h | 84 + src/framework/ipc/ps/nsfw_soft_param.c | 296 +++ src/framework/lib_common_mem/common_api.c | 325 ++++ src/framework/lib_common_mem/common_buf.c | 260 +++ src/framework/lib_common_mem/common_func.c | 205 ++ src/framework/log/nsfw_set_log.c | 228 +++ src/framework/log/nstack_log.c | 825 ++++++++ src/framework/snapshot/fw_snapshot.c | 483 +++++ src/framework/snapshot/fw_ss_tlv.h | 47 + src/framework/tracing/nstack_trace.c | 52 + 95 files changed, 24129 insertions(+) create mode 100644 src/framework/CMakeLists.txt create mode 100644 src/framework/common/base/include/common/common_func.h create mode 100644 src/framework/common/base/include/common/common_mem_api.h create mode 100644 src/framework/common/base/include/common/common_mem_base_type.h create mode 100644 src/framework/common/base/include/common/common_mem_buf.h create mode 100644 src/framework/common/base/include/common/common_mem_common.h create mode 100644 src/framework/common/base/include/common/common_mem_malloc.h create mode 100644 src/framework/common/base/include/common/common_mem_mbuf.h create mode 100644 src/framework/common/base/include/common/common_mem_mempool.h create mode 100644 src/framework/common/base/include/common/common_mem_memzone.h create mode 100644 src/framework/common/base/include/common/common_mem_pal.h create mode 100644 src/framework/common/base/include/common/common_mem_pal_memconfig.h create mode 100644 src/framework/common/base/include/common/common_mem_spinlock.h create mode 100644 src/framework/common/base/include/common/common_sys_config.h create mode 100644 src/framework/common/base/include/common/generic/common_mem_rwlock.h create mode 100644 src/framework/common/base/include/common_pal_bitwide_adjust.h create mode 100644 src/framework/common/base/include/nsfw_base_linux_api.h create mode 100644 src/framework/common/base/include/nsfw_getopt.h create mode 100644 src/framework/common/base/liblinuxapi/base_linux_api_declare.h create mode 100644 src/framework/common/base/liblinuxapi/nsfw_base_linux_api.c create mode 100644 src/framework/common/base/liblinuxapi/nsfw_getopt.c create mode 100644 src/framework/common/base/liblinuxapi/nsfw_lock_file.c create mode 100644 src/framework/common/data_struct/eprb_tree.c create mode 100644 src/framework/common/data_struct/list.c create mode 100644 src/framework/common/data_struct/pidinfo.c create mode 100644 src/framework/common/data_struct/sha256.c create mode 100644 src/framework/common/include/compile_config.h create mode 100644 src/framework/common/include/compiling_check.h create mode 100644 src/framework/common/include/ephlist.h create mode 100644 src/framework/common/include/eprb_tree.h create mode 100644 src/framework/common/include/list.h create mode 100644 src/framework/common/include/pidinfo.h create mode 100644 src/framework/common/include/sha256.h create mode 100644 src/framework/common/include/types.h create mode 100644 src/framework/common/mem_mgr/include/nsfw_mem_desc.h create mode 100644 src/framework/common/mem_mgr/include/nsfw_ring_data.h create mode 100644 src/framework/common/mem_mgr/include/nsfw_ring_fun.h create mode 100644 src/framework/common/mem_mgr/nsfw_mem_api.c create mode 100644 src/framework/common/mem_mgr/nsfw_mem_construct.c create mode 100644 src/framework/common/mem_mgr/nsfw_mem_desc.c create mode 100644 src/framework/common/mem_mgr/nsfw_mem_stat.c create mode 100644 src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.c create mode 100644 src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.h create mode 100644 src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.c create mode 100644 src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.h create mode 100644 src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.c create mode 100644 src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.h create mode 100644 src/framework/common/mem_mgr/nsfw_res_mgr.c create mode 100644 src/framework/common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.c create mode 100644 src/framework/common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.h create mode 100644 src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.c create mode 100644 src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.h create mode 100644 src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.c create mode 100644 src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.h create mode 100644 src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.c create mode 100644 src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.h create mode 100644 src/framework/hal/hal.c create mode 100644 src/framework/hal/hal.h create mode 100644 src/framework/include/hal_api.h create mode 100644 src/framework/include/nsfw_fd_timer_api.h create mode 100644 src/framework/include/nsfw_init.h create mode 100644 src/framework/include/nsfw_maintain_api.h create mode 100644 src/framework/include/nsfw_mem_api.h create mode 100644 src/framework/include/nsfw_mgr_com_api.h create mode 100644 src/framework/include/nsfw_ps_api.h create mode 100644 src/framework/include/nsfw_ps_mem_api.h create mode 100644 src/framework/include/nsfw_recycle_api.h create mode 100644 src/framework/include/nsfw_snapshot.h create mode 100644 src/framework/include/nsfw_upgrade.h create mode 100644 src/framework/include/nstack_log.h create mode 100644 src/framework/include/nstack_rd_data.h create mode 100644 src/framework/include/nstack_securec.h create mode 100644 src/framework/include/nstack_trace.h create mode 100644 src/framework/init/CMakeLists.txt create mode 100644 src/framework/init/fw_init.c create mode 100644 src/framework/init/fw_module.c create mode 100644 src/framework/init/fw_module.h create mode 100644 src/framework/ipc/mgr_com/mgr_com.c create mode 100644 src/framework/ipc/mgr_com/mgr_com.h create mode 100644 src/framework/ipc/ps/nsfw_fd_timer.c create mode 100644 src/framework/ipc/ps/nsfw_ps_mem_module.c create mode 100644 src/framework/ipc/ps/nsfw_ps_mem_module.h create mode 100644 src/framework/ipc/ps/nsfw_ps_module.c create mode 100644 src/framework/ipc/ps/nsfw_ps_module.h create mode 100644 src/framework/ipc/ps/nsfw_recycle_module.c create mode 100644 src/framework/ipc/ps/nsfw_recycle_module.h create mode 100644 src/framework/ipc/ps/nsfw_soft_param.c create mode 100644 src/framework/lib_common_mem/common_api.c create mode 100644 src/framework/lib_common_mem/common_buf.c create mode 100644 src/framework/lib_common_mem/common_func.c create mode 100644 src/framework/log/nsfw_set_log.c create mode 100644 src/framework/log/nstack_log.c create mode 100644 src/framework/snapshot/fw_snapshot.c create mode 100644 src/framework/snapshot/fw_ss_tlv.h create mode 100644 src/framework/tracing/nstack_trace.c (limited to 'src/framework') diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt new file mode 100644 index 0000000..78c5a45 --- /dev/null +++ b/src/framework/CMakeLists.txt @@ -0,0 +1,61 @@ +######################################################################### +# +# 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. +######################################################################### + +if(WITH_HAL_LIB) +else() + SET(PAL_H_DIRECTORIES "${DMM_DPDK_INSTALL_DIR}/include/dpdk/") + FILE(GLOB_RECURSE LIBCOMM lib_common_mem/*.c) +endif() + +FILE(GLOB_RECURSE COMMON common/*.c) +FILE(GLOB INIT init/*.c) +FILE(GLOB_RECURSE IPC ipc/*.c) +FILE(GLOB LOG log/*.c) +FILE(GLOB SNAPSHOT snapshot/*.c) +FILE(GLOB STARTUP startup/*.c) +FILE(GLOB MAINTAIN maintain/*.c) +FILE(GLOB TRACEING tracing/*.c) +FILE(GLOB HAL hal/*.c) +FILE(GLOB DMM_ADPT ../adapt/*.c) + + + +ADD_LIBRARY(dmm_api STATIC ${COMMON} ${INIT} ${IPC} ${LOG} ${SNAPSHOT} ${STARTUP} ${MAINTAIN} ${TRACEING} ${HAL} ${DMM_ADPT} ${LIBCOMM}) +if(WITH_SECUREC_LIB) +ADD_DEPENDENCIES(dmm_api SECUREC JSON GLOG) +else() +ADD_DEPENDENCIES(dmm_api JSON GLOG) +endif() +INCLUDE_DIRECTORIES( + dmm_api + PRIVATE + ${JSON_C_SRC} + ${GLOG_SRC} + ${SECUREC_SRC_H} + ipc/mgr_com/ + hal/ + include/ + common/base/include/generic + common/base/include/ + ${PAL_H_DIRECTORIES} + common/base/liblinuxapi/ + common/mem_mgr/include + common/mem_mgr/nsfw_shmem/ + common/mem_mgr/nsfw_nshmem/ + ${CMAKE_CURRENT_LIST_DIR}/../nSocket/nstack/event/ + ${CMAKE_CURRENT_LIST_DIR}/../nSocket/nstack/event/epoll + ${CMAKE_CURRENT_LIST_DIR}/../nSocket/include +) \ No newline at end of file diff --git a/src/framework/common/base/include/common/common_func.h b/src/framework/common/base/include/common/common_func.h new file mode 100644 index 0000000..fdf2802 --- /dev/null +++ b/src/framework/common/base/include/common/common_func.h @@ -0,0 +1,98 @@ +/* +* +* 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 _RTE_COMM_FUNC_H_ +#define _RTE_COMM_FUNC_H_ + +#ifdef HAL_LIB + +#else + +#define common_mem_rwlock_t rte_rwlock_t +#define common_mem_spinlock_t rte_spinlock_t + //typedef rte_rwlock_t common_mem_rwlock_t; + +#define nsfw_write_lock(plock) rte_rwlock_write_lock(plock) +#define nsfw_write_unlock(plock) rte_rwlock_write_unlock(plock) +#define nsfw_read_lock(plock) rte_rwlock_read_lock(plock) +#define nsfw_read_unlock(plock) rte_rwlock_read_unlock(plock) + +#define common_mem_align32pow2 rte_align32pow2 + +#define common_mem_atomic32_cmpset rte_atomic32_cmpset +#define common_mem_pause rte_pause + +#define COMMON_MEM_MAX_MEMZONE RTE_MAX_MEMZONE + +#define common_mem_atomic32_t rte_atomic32_t + +#define common_mem_memseg rte_memseg +#define common_mem_mem_config rte_mem_config + +#define common_mem_pal_get_configuration rte_eal_get_configuration + + //#define commem_mem_pal_module_info rte_eal_module_info + // +#define common_mem_pal_init rte_eal_init + +#define COMMON_MEM_MEMPOOL_NAMESIZE RTE_MEMPOOL_NAMESIZE + +#define common_mem_memzone_lookup rte_memzone_lookup +#define common_mem_memzone rte_memzone +#define common_mem_atomic32_add_return rte_atomic32_add_return + +#define common_mem_spinlock_init rte_spinlock_init +#define common_mem_spinlock_lock rte_spinlock_lock +#define common_mem_spinlock_unlock rte_spinlock_unlock + +#define common_mem_memzone_free rte_memzone_free +#define common_mem_pktmbuf_pool_create rte_pktmbuf_pool_create + +#define common_mem_pktmbuf_alloc rte_pktmbuf_alloc + +#define common_mem_mempool rte_mempool + +#define common_mem_pktmbuf_free rte_pktmbuf_free +#define common_mem_mbuf rte_mbuf + +#define common_mem_mempool_lookup rte_mempool_lookup + +#define common_mem_ring_get_memsize rte_ring_get_memsize +#define common_mem_ring rte_ring + +#define COMMON_MEM_MAX_MEMSEG RTE_MAX_MEMSEG + +#define common_mem_memzone_reserve rte_memzone_reserve +#define common_mem_rwlock_read_lock rte_rwlock_read_lock +#define common_mem_rwlock_read_unlock rte_rwlock_read_unlock + +#define common_mem_rwlock_write_lock rte_rwlock_write_lock +#define common_mem_rwlock_write_unlock rte_rwlock_write_unlock +#define common_mem_spinlock_trylock rte_spinlock_trylock + +#define common_mem_socket_id rte_socket_id +#define common_mem_malloc_socket_stats rte_malloc_socket_stats + +#define COMMON_MEM_MIN RTE_MIN + +#define common_pal_module_init nscomm_pal_module_init +#define common_memzone_data_reserve_name nscomm_memzone_data_reserve_name +#define common_memzone_data_lookup_name nscomm_memzone_data_lookup_name + +#define common_dump_stack rte_dump_stack +#endif + +#endif // _RTE_COMM_FUNC_H_ diff --git a/src/framework/common/base/include/common/common_mem_api.h b/src/framework/common/base/include/common/common_mem_api.h new file mode 100644 index 0000000..9eb4344 --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_api.h @@ -0,0 +1,144 @@ +/* +* +* 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 __COMMON_MEM_API_H__ +#define __COMMON_MEM_API_H__ + +#ifdef HAL_LIB +#else + +#include "rte_atomic.h" +#include "common_mem_spinlock.h" +#include +#include +#include + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#ifndef NSTACK_LINT_CODE_DISABLE +#define NSTACK_LINT_CODE_DISABLE(code) /*lint -e#code */ +#endif + +#ifndef NSTACK_LINT_CODE_ENABLE +#define NSTACK_LINT_CODE_ENABLE(code) /*lint +e#code */ +#endif + +#define SYS_MBOX_NULL (sys_mbox_t)0 + +typedef sem_t *sys_sem_t_v1; +typedef sem_t sys_sem_st_v1; +typedef struct queue *sys_mbox_t; + +typedef rte_spinlock_t *sys_sem_t_v2; +typedef rte_spinlock_t sys_sem_st_v2; + +#ifndef u32_t +typedef uint32_t u32_t; +#endif + +#ifndef u8_t +typedef uint8_t u8_t; +#endif + +#ifndef s8_t +typedef int8_t s8_t; +#endif + +#ifndef err_t +typedef s8_t err_t; +#endif + +/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */ +#define SYS_ARCH_TIMEOUT 0xffffffffUL + +/** sys_mbox_tryfetch() returns SYS_MBOX_EMPTY if appropriate. + * For now we use the same magic value, but we allow this to change in future. + */ +#define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT + +void sys_sem_signal_s_v2 (sys_sem_t_v2 sem); +void sys_sem_init_v2 (sys_sem_t_v2 sem); + +u32_t sys_arch_sem_wait_s_v2 (sys_sem_t_v2 sem); + +#define SYS_HOST_INITIAL_PID 1 +extern volatile pid_t g_sys_host_pid; +pid_t sys_get_hostpid_from_file (pid_t pid); +static inline pid_t +get_sys_pid () +{ + if (SYS_HOST_INITIAL_PID == g_sys_host_pid) + (void) sys_get_hostpid_from_file (getpid ()); + return g_sys_host_pid; +} + +pid_t updata_sys_pid (); +long sys_now (void); + +#define sys_sem_t sys_sem_t_v2 +#define sys_sem_st sys_sem_st_v2 +#define sys_sem_new(sem, count) sys_sem_new_v2(sem, count) +#define sys_sem_free(sem) sys_sem_free_v2(sem) +#define sys_sem_signal(sem) sys_sem_signal_v2(sem) +#define sys_arch_sem_wait(sem, timeout) sys_arch_sem_wait_v2(sem) +#define sys_arch_sem_trywait(sem) sys_arch_sem_trywait_v2(sem) + +#define sys_sem_init(sem) sys_sem_init_v2(sem) +#define sys_sem_s_signal(sem) sys_sem_signal_s_v2(sem) +#define sys_arch_sem_s_wait(sem, timeout) sys_arch_sem_wait_s_v2(sem) +#define sys_arch_lock_with_pid(sem) (void)sys_arch_lock_with_pid_v2(sem) + +#define BUF_SIZE_FILEPATH 256 +#define STR_PID "pid:" +#define READ_FILE_BUFLEN 512 + +extern pid_t sys_get_hostpid_from_file (pid_t pid); +extern pid_t get_hostpid_from_file (u32_t pid); +extern void get_exec_name_by_pid (pid_t pid, char *task_name, + int task_name_len); + +static inline u32_t +sys_arch_lock_with_pid_v2 (sys_sem_t_v2 sem) +{ + if (SYS_HOST_INITIAL_PID == g_sys_host_pid) + (void) sys_get_hostpid_from_file (getpid ()); + dmm_spinlock_lock_with_pid (sem, g_sys_host_pid); + return 0; +} + +#define NSTACK_SEM_MALLOC(sys_sem,count) \ +{ \ + rte_spinlock_init(&(sys_sem)); \ + /*lint -e506*/\ + if (!(count)) \ + /*lint +e506*/\ + { \ + rte_spinlock_lock(&(sys_sem)); \ + } \ +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#endif + +#endif /* __COMMON_MEM_API_H__ */ diff --git a/src/framework/common/base/include/common/common_mem_base_type.h b/src/framework/common/base/include/common/common_mem_base_type.h new file mode 100644 index 0000000..01707d9 --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_base_type.h @@ -0,0 +1,85 @@ +/* +* +* 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 _COMMON_MEM_BASE_TYPE_H_ +#define _COMMON_MEM_BASE_TYPE_H_ + +#ifdef HAL_LIB + +#else + +#define ALIGN_TYPE uint64_t +#define PTR_ALIGN_TYPE uint64_t + +/*alignment define*/ +#define ALIGNMENT_DEF(name, type, aligntype) \ + union { \ + type name; \ + aligntype name##_align; \ + } + +#define PTR_ALIGNMENT_DEF(name, type) ALIGNMENT_DEF(name, type, PTR_ALIGN_TYPE) + +#define OTHER_ALIGNMENT_DEF(name, type) ALIGNMENT_DEF(name, type, ALIGN_TYPE) + +/* + * * List definitions. + * */ +#define DMM_LIST_HEAD(name, type) \ +struct name { \ + PTR_ALIGNMENT_DEF(lh_first, struct type *); /* first element */ \ +} + +#define DMM_LIST_ENTRY(type) \ +struct { \ + PTR_ALIGNMENT_DEF(le_next, struct type *); /* next element */\ + PTR_ALIGNMENT_DEF(le_prev, struct type **); /* address of previous next element */ \ +} + +/* + * * Tail queue definitions. + * */ +#define _DMM_TAILQ_HEAD(name, type, qual) \ +struct name { \ + PTR_ALIGNMENT_DEF(tqh_first, qual type *); /* first element */ \ + PTR_ALIGNMENT_DEF(tqh_last, qual type * qual *); /* addr of last next element */ \ +} + +#define DMM_TAILQ_HEAD(name, type) _DMM_TAILQ_HEAD(name, struct type,) + +#define _DMM_TAILQ_ENTRY(type, qual) \ +struct { \ + PTR_ALIGNMENT_DEF(tqe_next, qual type *); /* next element */\ + PTR_ALIGNMENT_DEF(tqe_prev, qual type * qual*); /* address of previous next element */\ +} +#define DMM_TAILQ_ENTRY(type) _DMM_TAILQ_ENTRY(struct type,) + +/* + * * Singly-linked Tail queue declarations. + * */ +#define DMM_STAILQ_HEAD(name, type) \ + struct name { \ + PTR_ALIGNMENT_DEF(stqh_first, struct type *); /* first element */ \ + PTR_ALIGNMENT_DEF(stqh_last, struct type **); /* addr of last next element */ \ + } + +#define DMM_STAILQ_ENTRY(type) \ + struct { \ + PTR_ALIGNMENT_DEF(stqe_next, struct type *); /* next element */ \ + } +#endif + +#endif diff --git a/src/framework/common/base/include/common/common_mem_buf.h b/src/framework/common/base/include/common/common_mem_buf.h new file mode 100644 index 0000000..d0d3588 --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_buf.h @@ -0,0 +1,75 @@ +/* +* +* 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 _COMMON_MEM_BUF_H_ +#define _COMMON_MEM_BUF_H_ + +#ifdef HAL_LIB +#else + +#include "common_mem_base_type.h" + +typedef enum __DMM_PROC_TYPE +{ + DMM_PROC_T_AUTO = 0, /*auto detect */ + DMM_PROC_T_PRIMARY = 1, /* set to primary */ + DMM_PROC_T_SECONDARY = 2, /* set to seconday */ + DMM_PROC_T_INVALID +} DMM_PROC_TYPE; + +#define DMM_MBUF_RET_OK 0 +#define DMM_MBUF_RET_ERR 1 + +#define LCORE_MAX 128 +#define LCORE_MASK_PER (sizeof(int) * 8) +#define LCORE_MASK_MAX (LCORE_MAX/LCORE_MASK_PER) + +#define LCORE_MASK_SET(ilcoremask, value) \ + if (value < LCORE_MAX) \ + { \ + ilcoremask[(value/LCORE_MASK_PER)] = (int) ( (ilcoremask[(value/LCORE_MASK_PER)]) | (1< (value%LCORE_MASK_PER))); \ + } \ + +#define DMM_HUGTBL_ENABLE 0 +#define DMM_HUGTBL_DISABLE 1 + +typedef struct __common_pal_module_info +{ + int ishare_mem_size; /*shared memory size */ + int ilcoremask[LCORE_MASK_MAX]; + /**/ unsigned char uchugeflag; + unsigned char ucproctype; + unsigned char ucinstance; + unsigned char ucresrv2; +} common_mem_pal_module_info; + +/** + * rte pal module init. + * + * + * @param name + * The name of the buf pool. + */ +int nscomm_pal_module_init (common_mem_pal_module_info * pinfo); + +void *nscomm_memzone_data_reserve_name (const char *name, size_t len, + int socket_id); + +void *nscomm_memzone_data_lookup_name (const char *name); + +#endif + +#endif /* _COMMON_MEM_BUF_H_ */ diff --git a/src/framework/common/base/include/common/common_mem_common.h b/src/framework/common/base/include/common/common_mem_common.h new file mode 100644 index 0000000..1e4cf56 --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_common.h @@ -0,0 +1,25 @@ +/* +* +* 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 _COMMON_MEM_COMMON_H_ +#define _COMMON_MEM_COMMON_H_ + +#ifdef HAL_LIB +#else +#include "rte_common.h" +#endif + +#endif diff --git a/src/framework/common/base/include/common/common_mem_malloc.h b/src/framework/common/base/include/common/common_mem_malloc.h new file mode 100644 index 0000000..68721cd --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_malloc.h @@ -0,0 +1,25 @@ +/* +* +* 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 _COMMON_MEM_MALLOC_H_ +#define _COMMON_MEM_MALLOC_H_ + +#ifdef HAL_LIB +#else +#include "rte_malloc.h" +#endif + +#endif /* _COMMON_MEM_MALLOC_H_ */ diff --git a/src/framework/common/base/include/common/common_mem_mbuf.h b/src/framework/common/base/include/common/common_mem_mbuf.h new file mode 100644 index 0000000..0bb7696 --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_mbuf.h @@ -0,0 +1,40 @@ +/* +* +* 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. +*/ + +/******************************************************************* + Copyright 2017 - 2047, Huawei Tech. Co., Ltd. + ALL RIGHTS RESERVED + +Filename : common_mem_mbuf.h +Description : +Version : 1.1 +********************************************************************/ + +#ifndef _COMMON_MEM_MBUF_H_ +#define _COMMON_MEM_MBUF_H_ + +#ifdef HAL_LIB +#else +#include "rte_mbuf.h" +#include "common_func.h" + +typedef uint32_t (*dmm_mbuf_item_fun) (void *data, void *argv); +int32_t dmm_pktmbuf_pool_iterator (struct common_mem_mempool *mp, + uint32_t start, uint32_t end, + dmm_mbuf_item_fun fun, void *argv); +#endif + +#endif /* _COMMON_MEM_MBUF_H_ */ diff --git a/src/framework/common/base/include/common/common_mem_mempool.h b/src/framework/common/base/include/common/common_mem_mempool.h new file mode 100644 index 0000000..58a8e82 --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_mempool.h @@ -0,0 +1,25 @@ +/* +* +* 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 _COMMON_MEM_MEMPOOL_H_ +#define _COMMON_MEM_MEMPOOL_H_ + +#ifdef HAL_LIB +#else +#include "rte_mempool.h" +#endif + +#endif /* _COMMON_MEM_MEMPOOL_H_ */ diff --git a/src/framework/common/base/include/common/common_mem_memzone.h b/src/framework/common/base/include/common/common_mem_memzone.h new file mode 100644 index 0000000..20e18c2 --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_memzone.h @@ -0,0 +1,25 @@ +/* +* +* 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 _COMMON_MEM_MEMZONE_H_ +#define _COMMON_MEM_MEMZONE_H_ + +#ifdef HAL_LIB +#else +#include "rte_memzone.h" +#endif + +#endif /* _COMMON_MEM_MEMZONE_H_ */ diff --git a/src/framework/common/base/include/common/common_mem_pal.h b/src/framework/common/base/include/common/common_mem_pal.h new file mode 100644 index 0000000..209b8bd --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_pal.h @@ -0,0 +1,30 @@ +/* +* +* 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 _COMMON_MEM_PAL_H_ +#define _COMMON_MEM_PAL_H_ + +#ifdef HAL_LIB +#else + +#include "nsfw_base_linux_api.h" + +/*print the map address*/ +void dmm_addr_print (void); + +#endif + +#endif /* _COMMON_MEM_PAL_H_ */ diff --git a/src/framework/common/base/include/common/common_mem_pal_memconfig.h b/src/framework/common/base/include/common/common_mem_pal_memconfig.h new file mode 100644 index 0000000..65b6e04 --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_pal_memconfig.h @@ -0,0 +1,26 @@ +/* +* +* 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 _COMMON_MEM_PAL_MEMCONFIG_H_ +#define _COMMON_MEM_PAL_MEMCONFIG_H_ + +#ifdef HAL_LIB +#else +#include "rte_eal_memconfig.h" + +#endif + +#endif diff --git a/src/framework/common/base/include/common/common_mem_spinlock.h b/src/framework/common/base/include/common/common_mem_spinlock.h new file mode 100644 index 0000000..23f6b1e --- /dev/null +++ b/src/framework/common/base/include/common/common_mem_spinlock.h @@ -0,0 +1,40 @@ +/* +* +* 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 _COMMON_MEM_SPINLOCK_X86_64_H_ +#define _COMMON_MEM_SPINLOCK_X86_64_H_ + +#ifdef HAL_LIB +#else +#include "rte_spinlock.h" + +static inline void +dmm_spinlock_lock_with_pid (rte_spinlock_t * sl, int pid) +{ + while (!__sync_bool_compare_and_swap (&sl->locked, 0, pid)) + while (sl->locked) + rte_pause (); +} + +static inline int +dmm_spinlock_try_lock_with_pid (rte_spinlock_t * sl, int pid) +{ + return __sync_bool_compare_and_swap (&sl->locked, 0, pid); +} + +#endif + +#endif /* _COMMON_MEM_SPINLOCK_X86_64_H_ */ diff --git a/src/framework/common/base/include/common/common_sys_config.h b/src/framework/common/base/include/common/common_sys_config.h new file mode 100644 index 0000000..552cae3 --- /dev/null +++ b/src/framework/common/base/include/common/common_sys_config.h @@ -0,0 +1,46 @@ +/* +* +* 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 __COMMON_SYS_CONFIG_H_ +#define __COMMON_SYS_CONFIG_H_ + +/* Below compile macro is used only in UT makefile */ +#if (HAL_LIB) +#else +#undef RTE_CACHE_LINE_SIZE +#define RTE_CACHE_LINE_SIZE 64 +#undef RTE_MAX_LCORE +#define RTE_MAX_LCORE 128 +#undef RTE_MAX_NUMA_NODES +#define RTE_MAX_NUMA_NODES 8 +#undef RTE_MAX_MEMSEG +#define RTE_MAX_MEMSEG 256 +#undef RTE_MAX_MEMZONE +#define RTE_MAX_MEMZONE 2560 +#undef RTE_MAX_TAILQ +#define RTE_MAX_TAILQ 32 +#undef RTE_ARCH_X86 +#define RTE_ARCH_X86 1 +#undef RTE_ARCH_64 +#define RTE_ARCH_64 1 +#undef RTE_PKTMBUF_HEADROOM +#define RTE_PKTMBUF_HEADROOM 128 +#undef RTE_MEMPOOL_CACHE_MAX_SIZE +#define RTE_MEMPOOL_CACHE_MAX_SIZE 512 + +#endif + +#endif // __COMMON_SYS_CONFIG_H_ diff --git a/src/framework/common/base/include/common/generic/common_mem_rwlock.h b/src/framework/common/base/include/common/generic/common_mem_rwlock.h new file mode 100644 index 0000000..2eed259 --- /dev/null +++ b/src/framework/common/base/include/common/generic/common_mem_rwlock.h @@ -0,0 +1,25 @@ +/* +* +* 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 _COMMON_MEM_RWLOCK_H_ +#define _COMMON_MEM_RWLOCK_H_ + +#ifdef HAL_LIB +#else +#include "rte_rwlock.h" +#endif + +#endif /* _COMMON_MEM_RWLOCK_H_ */ diff --git a/src/framework/common/base/include/common_pal_bitwide_adjust.h b/src/framework/common/base/include/common_pal_bitwide_adjust.h new file mode 100644 index 0000000..850742b --- /dev/null +++ b/src/framework/common/base/include/common_pal_bitwide_adjust.h @@ -0,0 +1,222 @@ +/* +* +* 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 _COMMON_PAL_BITWIDE_ADJUST_H_ +#define _COMMON_PAL_BITWIDE_ADJUST_H_ + +#ifdef HAL_LIB +#include "pal_bitwide_adjust.h" +#else +#define MODULE(name) (1) + +#include "common_mem_common.h" + +#include "common_func.h" + +#ifndef _UT_FUN_DISABLE_ +/*define struct for UT restore global variant*/ +struct ut_adjust_global +{ + void **ut_PrimAddr2LocalMap; + uint64_t *ut_LocalAddr2PrimMap; + void *ut_LocalBaseAddr; + void *ut_LocalMaxAddr; + void *ut_LocalCfgAddrBase; + uint64_t ut_PrimBaseAddr; + uint64_t ut_PrimMaxAddr; + uint64_t ut_PrimCfgAddrBase; + int ut_PrimSameFlg; + uint64_t ut_LBitMask; + int ut_LBitMaskLen; + struct common_mem_memseg *ut_PMemSegArry; + void **ut_LMegAddrArry; +}; +#endif + +#define ALIGN_SIZET(size) ((uint64_t)(size)) +#define ALIGN_PTR(PTR) ((uint64_t)(PTR)) + +extern struct common_mem_memseg *g_PMemSegArry; +extern void **g_LMegAddrArry; + +/*get Local Seg addr by segIdx*/ +#define HMEM_SEG_LVADDR(segid) (g_LMegAddrArry[segid]) +/*get SegIDX by PrimSegAddr, just get the arry Idx of g_PMemSegArry*/ +#define HMEM_SEGID(segaddr) ((struct common_mem_memseg*)segaddr - &(g_PMemSegArry[0])) + +/***************************************************************** +Parameters : LMegAddrArry[] Loacol common_mem_memseg addr Arry + SegNum common_mem_memseg Num. +Return : +Description : init g_PrimAddr2LocalMap g_LocalAddr2PrimMap while the process start +*****************************************************************/ +void *pal_shddr_to_laddr (uint64_t shaddr); +uint64_t pal_laddr_to_shddr (void *laddr); +int dmm_pal_addr_align (); + +extern int g_PrimSameFlg; + +/* if __NSTACK_MAIN__ is defined, no need do addr trans*/ +#ifndef __NSTACK_MAIN__ +/* g_PrimSameFlg check should be done before calling cast functions */ + +/*share memory address to local virtual address*/ +#define ADDR_SHTOL(addr) (g_PrimSameFlg ? ((void*) (addr)) : pal_shddr_to_laddr((uint64_t)(addr))) + +/*local virtual address to share memory address according to memseg*/ +#define ADDR_LTOSH(addr) (g_PrimSameFlg ? ((uint64_t)(addr)) : pal_laddr_to_shddr((void*)(addr))) + +#define PTR_SHTOL(type, addr) ((type)ADDR_SHTOL(addr)) + +/*local virtual address to share memory address; for compatible, not delete ADDR_LTOSH_EXT*/ +#define ADDR_LTOSH_EXT(addr) ADDR_LTOSH(addr) +#else +/*share memory address to local virtual address*/ +#define ADDR_SHTOL(addr) ((void*)(addr)) + +/*local virtual address to share memory address according to memseg*/ +#define ADDR_LTOSH(addr) ((uint64_t)(addr)) + +#define PTR_SHTOL(type, addr) ((type)(addr)) + +/*local virtual address to share memory address; for compatible, not delete ADDR_LTOSH_EXT*/ +#define ADDR_LTOSH_EXT(addr) ADDR_LTOSH(addr) +#endif + +#if MODULE("list") +#define COMMON_LIST_INSERT_HEAD(lhead, lelm, field) do { \ + if (((lelm)->field.le_next_align = (lhead)->lh_first_align) != ((typeof((lhead)->lh_first_align))(long)NULL)) \ + ((typeof((lhead)->lh_first))ADDR_SHTOL((lhead)->lh_first_align))->field.le_prev_align = \ + ADDR_LTOSH(&(lelm)->field.le_next); \ + (lhead)->lh_first_align = ADDR_LTOSH(lelm); \ + (lelm)->field.le_prev_align = ADDR_LTOSH(&(lhead)->lh_first); \ +} while (/*CONSTCOND*/0) + +#define COMMON_LIST_REMOVE(lelm, field) do { \ + if ((lelm)->field.le_next_align != ((typeof((lelm)->field.le_next_align))ALIGN_PTR(NULL))) \ + ((typeof((lelm)->field.le_next))ADDR_SHTOL((lelm)->field.le_next_align))->field.le_prev_align = \ + (lelm)->field.le_prev_align; \ + if (EOK != (MEMCPY_S((typeof((lelm)->field.le_prev))ADDR_SHTOL((lelm)->field.le_prev_align), \ + sizeof((lelm)->field.le_next_align), \ + &((lelm)->field.le_next_align), \ + sizeof((lelm)->field.le_next_align)))) \ + {\ + NSCOMM_LOGERR("MEMCPY_S failed.");\ + return;\ + }\ +} while (/*CONSTCOND*/0) + +#define COMMON_LIST_EMPTY(lhead) ((typeof((lhead)->lh_first))ADDR_SHTOL((lhead)->lh_first_align) == NULL) +#define COMMON_LIST_FIRST(lhead) ((typeof((lhead)->lh_first))ADDR_SHTOL((lhead)->lh_first_align)) +#define COMMON_LIST_NEXT(lelm, field) ((typeof((lelm)->field.le_next))ADDR_SHTOL((lelm)->field.le_next_align)) + +#endif + +#if MODULE("tailq") + +#define COMMON_TAILQ_INSERT_TAIL(lhead, lelm, field) do { \ + (lelm)->field.tqe_next_align = (typeof((lelm)->field.tqe_next_align))NULL; \ + (lelm)->field.tqe_prev_align = (lhead)->tqh_last_align; \ + typeof((lhead)->tqh_last_align) tempelm = ADDR_LTOSH(lelm);\ + if (EOK != (MEMCPY_S(ADDR_SHTOL((lhead)->tqh_last_align), sizeof(tempelm), &tempelm, sizeof(tempelm)))) \ + {\ + NSCOMM_LOGERR("MEMCPY_S failed.");\ + }\ + (lhead)->tqh_last_align = ADDR_LTOSH(&(lelm)->field.tqe_next); \ +} while (/*CONSTCOND*/0) + +#define COMMON_TAILQ_FOREACH(lvar, lhead, field) \ + for ((lvar) = (typeof(lvar))ADDR_SHTOL((lhead)->tqh_first_align); \ + (lvar); \ + (lvar) = (typeof(lvar))ADDR_SHTOL((lvar)->field.tqe_next_align)) + +#define COMMON_TAILQ_REMOVE(lhead, lelm, field) do { \ + if (((lelm)->field.tqe_next_align) != (typeof((lelm)->field.tqe_next_align))NULL) \ + ((typeof((lelm)->field.tqe_next))ADDR_SHTOL((lelm)->field.tqe_next_align))->field.tqe_prev_align = \ + (lelm)->field.tqe_prev_align; \ + else \ + (lhead)->tqh_last_align = (lelm)->field.tqe_prev_align; \ + if (EOK != (MEMCPY_S(ADDR_SHTOL((lelm)->field.tqe_prev_align), \ + sizeof((lelm)->field.tqe_next_align), \ + &((lelm)->field.tqe_next_align), \ + sizeof((lelm)->field.tqe_next_align)))) \ + {\ + NSCOMM_LOGERR("MEMCPY_S failed.");\ + }\ + } while (/*CONSTCOND*/0) + +/* + * Tail queue functions. + */ +#define COMMON_TAILQ_INIT(head) do { \ + (head)->tqh_first_align = (typeof((head)->tqh_first_align))NULL; \ + (head)->tqh_last_align = ADDR_LTOSH(&(head)->tqh_first); \ + } while (/*CONSTCOND*/0) + +/* + * Tail queue access methods. + */ +#define COMMON_TAILQ_EMPTY(head) ((head)->tqh_first_align == (typeof((head)->tqh_first_align))NULL) +#define COMMON_TAILQ_FIRST(head) ((typeof((head)->tqh_first))ADDR_SHTOL((head)->tqh_first_align)) +#define COMMON_TAILQ_NEXT(elm, field) ((typeof((elm)->field.tqe_next))ADDR_SHTOL((elm)->field.tqe_next_align)) + +#endif + +#if MODULE("stailq") +/* +* Singly-linked Tail queue functions. +*/ +#define COMMON_STAILQ_INIT(head) do { \ + (head)->stqh_first_align = ALIGN_PTR(NULL); \ + (head)->stqh_last_align = ADDR_LTOSH(&(head)->stqh_first); \ +} while (/*CONSTCOND*/0) + +#define COMMON_STAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.stqe_next_align = ALIGN_PTR(NULL); \ + typeof((head)->stqh_last_align) telm = ADDR_LTOSH(elm);\ + if (EOK != (MEMCPY_S(ADDR_SHTOL((head)->stqh_last_align), sizeof(telm), &telm, sizeof(telm))))\ + {\ + NSCOMM_LOGERR("MEMCPY_S failed.");\ + }\ + (head)->stqh_last_align = ADDR_LTOSH(&(elm)->field.stqe_next); \ +} while (/*CONSTCOND*/0) + +#define COMMON_STAILQ_REMOVE_HEAD(head, field) do { \ + if (((head)->stqh_first_align = \ + ((typeof((head)->stqh_first))ADDR_SHTOL((head)->stqh_first_align))->field.stqe_next_align) == \ + (PTR_ALIGN_TYPE)NULL) \ + (head)->stqh_last_align = ADDR_LTOSH(&(head)->stqh_first); \ +} while (/*CONSTCOND*/0) + +#define COMMON_STAILQ_FOREACH(var, head, field) \ + for ((var) = ADDR_SHTOL((head)->stqh_first_align); \ + (var); \ + (var) = ADDR_SHTOL((var)->field.stqe_next_align)) + +/* +* Singly-linked Tail queue access methods. +*/ + +#define COMMON_STAILQ_EMPTY(head) ((head)->stqh_first_align == (PTR_ALIGN_TYPE)NULL) + +#define COMMON_STAILQ_FIRST(head) (ADDR_SHTOL((head)->stqh_first_align)) + +#define COMMON_STAILQ_NEXT(elm, field) (ADDR_SHTOL((elm)->field.stqe_next_align)) +#endif + +#endif + +#endif diff --git a/src/framework/common/base/include/nsfw_base_linux_api.h b/src/framework/common/base/include/nsfw_base_linux_api.h new file mode 100644 index 0000000..83b5a32 --- /dev/null +++ b/src/framework/common/base/include/nsfw_base_linux_api.h @@ -0,0 +1,58 @@ +/* +* +* 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 _NSFW_BASE_LINUX_API_H_ +#define _NSFW_BASE_LINUX_API_H_ + +#include +#include +#include +#include + +int nsfw_base_socket (int, int, int); +int nsfw_base_bind (int, const struct sockaddr *, socklen_t); +int nsfw_base_listen (int, int); +int nsfw_base_shutdown (int, int); +int nsfw_base_getsockname (int, struct sockaddr *, socklen_t *); +int nsfw_base_getpeername (int, struct sockaddr *, socklen_t *); +int nsfw_base_getsockopt (int, int, int, void *, socklen_t *); +int nsfw_base_setsockopt (int, int, int, const void *, socklen_t); +int nsfw_base_accept (int, struct sockaddr *, socklen_t *); +int nsfw_base_accept4 (int, struct sockaddr *, socklen_t *, int flags); +int nsfw_base_connect (int, const struct sockaddr *, socklen_t); +ssize_t nsfw_base_recv (int, void *, size_t, int); +ssize_t nsfw_base_send (int, const void *, size_t, int); +ssize_t nsfw_base_read (int, void *, size_t); +ssize_t nsfw_base_write (int, const void *, size_t); +ssize_t nsfw_base_writev (int, const struct iovec *, int); +ssize_t nsfw_base_readv (int, const struct iovec *, int); +ssize_t nsfw_base_sendto (int, const void *, size_t, int, + const struct sockaddr *, socklen_t); +ssize_t nsfw_base_recvfrom (int, void *, size_t, int, struct sockaddr *, + socklen_t *); +ssize_t nsfw_base_sendmsg (int, const struct msghdr *, int flags); +ssize_t nsfw_base_recvmsg (int, struct msghdr *, int flags); +int nsfw_base_close (int); +int nsfw_base_select (int, fd_set *, fd_set *, fd_set *, struct timeval *); +int nsfw_base_ioctl (int, unsigned long, unsigned long); +int nsfw_base_fcntl (int, int, unsigned long); +int nsfw_base_epoll_create (int); +int nsfw_base_epoll_create1 (int); +int nsfw_base_epoll_ctl (int, int, int, struct epoll_event *); +int nsfw_base_epoll_wait (int, struct epoll_event *, int, int); +pid_t nsfw_base_fork (void); + +#endif diff --git a/src/framework/common/base/include/nsfw_getopt.h b/src/framework/common/base/include/nsfw_getopt.h new file mode 100644 index 0000000..f1394cf --- /dev/null +++ b/src/framework/common/base/include/nsfw_getopt.h @@ -0,0 +1,50 @@ +/* +* +* 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 NSFW_GETOPT_H +#define NSFW_GETOPT_H 1 + +#if defined(__cplusplus) +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define nsfw_no_argument 0 +#define nsfw_required_argument 1 +#define nsfw_optional_argument 2 + +struct option +{ + const char *name; + int has_arg; + int *flag; + int val; +}; + +int nsfw_getopt_long (int argc, char *const argv[], const char *optstring, + const struct option *longopts, int *longindex); + +extern char *nsfw_optarg; +extern int nsfw_optind, nsfw_opterr, nsfw_optopt; + +#if defined(__cplusplus) +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/src/framework/common/base/liblinuxapi/base_linux_api_declare.h b/src/framework/common/base/liblinuxapi/base_linux_api_declare.h new file mode 100644 index 0000000..943ae04 --- /dev/null +++ b/src/framework/common/base/liblinuxapi/base_linux_api_declare.h @@ -0,0 +1,51 @@ +/* +* +* 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. +*/ + +BASE_MK_DECL (int, socket, (int, int, int)); +BASE_MK_DECL (int, bind, (int, const struct sockaddr *, socklen_t)); +BASE_MK_DECL (int, listen, (int, int)); +BASE_MK_DECL (int, shutdown, (int, int)); +BASE_MK_DECL (int, getsockname, (int, struct sockaddr *, socklen_t *)); +BASE_MK_DECL (int, getpeername, (int, struct sockaddr *, socklen_t *)); +BASE_MK_DECL (int, getsockopt, (int, int, int, void *, socklen_t *)); +BASE_MK_DECL (int, setsockopt, (int, int, int, const void *, socklen_t)); +BASE_MK_DECL (int, accept, (int, struct sockaddr *, socklen_t *)); +BASE_MK_DECL (int, accept4, (int, struct sockaddr *, socklen_t *, int flags)); +BASE_MK_DECL (int, connect, (int, const struct sockaddr *, socklen_t)); +BASE_MK_DECL (ssize_t, recv, (int, void *, size_t, int)); +BASE_MK_DECL (ssize_t, send, (int, const void *, size_t, int)); +BASE_MK_DECL (ssize_t, read, (int, void *, size_t)); +BASE_MK_DECL (ssize_t, write, (int, const void *, size_t)); +BASE_MK_DECL (ssize_t, writev, (int, const struct iovec *, int)); +BASE_MK_DECL (ssize_t, readv, (int, const struct iovec *, int)); +BASE_MK_DECL (ssize_t, sendto, + (int, const void *, size_t, int, const struct sockaddr *, + socklen_t)); +BASE_MK_DECL (ssize_t, recvfrom, + (int, void *, size_t, int, struct sockaddr *, socklen_t *)); +BASE_MK_DECL (ssize_t, sendmsg, (int, const struct msghdr *, int flags)); +BASE_MK_DECL (ssize_t, recvmsg, (int, struct msghdr *, int flags)); +BASE_MK_DECL (int, close, (int)); +BASE_MK_DECL (int, select, + (int, fd_set *, fd_set *, fd_set *, struct timeval *)); +BASE_MK_DECL (int, ioctl, (int, unsigned long, unsigned long)); +BASE_MK_DECL (int, fcntl, (int, int, unsigned long)); +BASE_MK_DECL (int, epoll_create, (int)); +BASE_MK_DECL (int, epoll_create1, (int)); +BASE_MK_DECL (int, epoll_ctl, (int, int, int, struct epoll_event *)); +BASE_MK_DECL (int, epoll_wait, (int, struct epoll_event *, int, int)); +BASE_MK_DECL (pid_t, fork, (void)); +#undef BASE_MK_DECL diff --git a/src/framework/common/base/liblinuxapi/nsfw_base_linux_api.c b/src/framework/common/base/liblinuxapi/nsfw_base_linux_api.c new file mode 100644 index 0000000..de98877 --- /dev/null +++ b/src/framework/common/base/liblinuxapi/nsfw_base_linux_api.c @@ -0,0 +1,628 @@ +/* +* +* 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 "nsfw_base_linux_api.h" +#include "nstack_log.h" +#include +#include +#include +#include + +#define NSFW_BASE_OK 0 +#define NSFW_BASE_FAIL (-1) + +#define nsfw_call_ret(symbol, para){ \ + if (NSFW_BASE_OK != nsfw_posix_api_init()) \ + { \ + return NSFW_BASE_FAIL; \ + } \ + if (g_nsfw_posix_api.pf##symbol) \ + { \ + return g_nsfw_posix_api.pf##symbol para;\ + } \ + errno = ENOSYS; \ + return NSFW_BASE_FAIL; \ +} + +typedef enum +{ + BASE_STATE_INIT, + BASE_STATE_SUCCESS, + BASE_STATE_FAIL +} nsfw_base_state; + +typedef struct __base_linux_api +{ +#define BASE_MK_DECL(ret, fn, args) ret (*pf##fn) args; +#include "base_linux_api_declare.h" +} base_linux_api; + +nsfw_base_state g_nsfw_mudule_state = BASE_STATE_INIT; +pthread_mutex_t g_nsfw_init_mutex = PTHREAD_MUTEX_INITIALIZER; +base_linux_api g_nsfw_posix_api = { 0 }; + +void *g_linux_lib_handle = (void *) 0; + +int +nsfw_posix_symbol_load () +{ + g_linux_lib_handle = dlopen ("libc.so.6", RTLD_NOW | RTLD_GLOBAL); + if ((void *) 0 == g_linux_lib_handle) + { + /* optimize dlopen err print */ + NSSOC_LOGERR ("cannot dlopen libc.so.6] err_string=%s", dlerror ()); + return NSFW_BASE_FAIL; + } +#define BASE_MK_DECL(ret, fn, args) \ + g_nsfw_posix_api.pf##fn = (typeof(g_nsfw_posix_api.pf##fn))dlsym(g_linux_lib_handle, #fn); +#include + + return NSFW_BASE_OK; +} + +/***************************************************************** +Parameters : void +Return : +Description : linux posix api init with threadonce +*****************************************************************/ +static inline int +nsfw_posix_api_init () +{ + int iret = NSFW_BASE_OK; + + /*if init already, just return success, if init fail before, just return err */ + if (BASE_STATE_INIT != g_nsfw_mudule_state) + { + return (BASE_STATE_SUCCESS == + g_nsfw_mudule_state ? NSFW_BASE_OK : NSFW_BASE_FAIL); + } + + (void) pthread_mutex_lock (&g_nsfw_init_mutex); + + /*if init already, just return success, if init fail before, just return err */ + if (BASE_STATE_INIT != g_nsfw_mudule_state) + { + (void) pthread_mutex_unlock (&g_nsfw_init_mutex); + return (BASE_STATE_SUCCESS == + g_nsfw_mudule_state ? NSFW_BASE_OK : NSFW_BASE_FAIL); + } + + iret = nsfw_posix_symbol_load (); + if (NSFW_BASE_OK == iret) + { + g_nsfw_mudule_state = BASE_STATE_SUCCESS; + } + else + { + g_nsfw_mudule_state = BASE_STATE_FAIL; + } + + (void) pthread_mutex_unlock (&g_nsfw_init_mutex); + return iret; +} +/* *INDENT-OFF* */ +/***************************************************************************** +* Prototype : nsfw_base_socket +* Description : linux socket api +* Input : int a +* int b +* int c +* Output : None +* Return Value : int +* Calls : +* Called By : + +* +*****************************************************************************/ +int nsfw_base_socket(int a, int b, int c) +{ + nsfw_call_ret(socket, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_bind +* Description : linux fd bind api +* Input : int a +* const struct sockaddr* b +* socklen_t c +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_bind(int a, const struct sockaddr* b, socklen_t c) +{ + nsfw_call_ret(bind, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_listen +* Description : linux fd listen api +* Input : int a +* int b +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_listen(int a, int b) +{ + nsfw_call_ret(listen, (a, b)) +} + +/***************************************************************************** +* Prototype : nsfw_base_shutdown +* Description : linux shutdown api +* Input : int a +* int b +* Output : None +* Return Value : int +* Calls : +* Called By : +* +* +*****************************************************************************/ +int nsfw_base_shutdown(int a, int b) +{ + nsfw_call_ret(shutdown, (a, b)) +} + +/***************************************************************************** +* Prototype : nsfw_base_getsockname +* Description : linux getsockname api +* Input : int a +* struct sockaddr* b +* socklen_t* c +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_getsockname(int a, struct sockaddr* b, socklen_t* c) +{ + nsfw_call_ret(getsockname, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_getpeername +* Description : linux getpername api +* Input : int a +* struct sockaddr* b +* socklen_t* c +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_getpeername(int a, struct sockaddr* b, socklen_t* c) +{ + nsfw_call_ret(getpeername, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_getsockopt +* Description : linux getsockopt api +* Input : int a +* int b +* int c +* void* d +* socklen_t* e +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_getsockopt(int a, int b, int c, void* d, socklen_t* e) +{ + nsfw_call_ret(getsockopt, (a, b, c, d, e)) +} + +/***************************************************************************** +* Prototype : nsfw_base_setsockopt +* Description : linux setsockopt api +* Input : int a +* int b +* int c +* const void* d +* socklen_t e +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int nsfw_base_setsockopt(int a, int b, int c, const void* d, socklen_t e) +{ + nsfw_call_ret(setsockopt, (a, b, c, d, e)) +} + +/***************************************************************************** +* Prototype : nsfw_base_accept +* Description : linux accept api +* Input : int a +* struct sockaddr* b +* socklen_t* c +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int nsfw_base_accept(int a, struct sockaddr* b, socklen_t* c) +{ + nsfw_call_ret(accept, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_accept4 +* Description : linux accept4 api +* Input : int a +* struct sockaddr* b +* socklen_t* c +* int flags +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int nsfw_base_accept4(int a, struct sockaddr* b, socklen_t* c, int flags) +{ + nsfw_call_ret(accept4, (a, b, c, flags)) +} + +/***************************************************************************** +* Prototype : nsfw_base_connect +* Description : linux connect api +* Input : int a +* const struct sockaddr* b +* socklen_t c +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_connect(int a, const struct sockaddr* b, socklen_t c) +{ + nsfw_call_ret(connect, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_recv +* Description : linux recv api +* Input : int a +* void* b +* size_t c +* int d +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_recv(int a, void* b, size_t c, int d) +{ + nsfw_call_ret(recv, (a, b, c, d)) +} + +/***************************************************************************** +* Prototype : nsfw_base_send +* Description : linux send api +* Input : int a +* const void* b +* size_t c +* int d +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_send(int a, const void* b, size_t c, int d) +{ + nsfw_call_ret(send, (a, b, c, d)) +} + +/***************************************************************************** +* Prototype : nsfw_base_read +* Description : linux read api +* Input : int a +* void* b +* size_t c +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_read(int a, void* b, size_t c) +{ + nsfw_call_ret(read, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_write +* Description : linux write api +* Input : int a +* const void* b +* size_t c +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_write(int a, const void* b, size_t c) +{ + nsfw_call_ret(write, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_writev +* Description : linux writev api +* Input : int a +* const struct iovec * b +* int c +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +*****************************************************************************/ +ssize_t nsfw_base_writev(int a, const struct iovec * b, int c) +{ + nsfw_call_ret(writev, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_readv +* Description : linux readv api +* Input : int a +* const struct iovec * b +* int c +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_readv(int a, const struct iovec * b, int c) +{ + nsfw_call_ret(readv, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_sendto +* Description : linux sendto api +* Input : int a +* const void * b +* size_t c +* int d +* const struct sockaddr *e +* socklen_t f +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +*****************************************************************************/ +ssize_t nsfw_base_sendto(int a, const void * b, size_t c, int d, const struct sockaddr *e, socklen_t f) +{ + nsfw_call_ret(sendto, (a, b, c, d, e, f)) +} + +/***************************************************************************** +* Prototype : nsfw_base_recvfrom +* Description : linux recvfrom api +* Input : int a +* void *b +* size_t c +* int d +* struct sockaddr *e +* socklen_t *f +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +*****************************************************************************/ +ssize_t nsfw_base_recvfrom(int a, void *b, size_t c, int d,struct sockaddr *e, socklen_t *f) +{ + nsfw_call_ret(recvfrom, (a, b, c, d, e, f)) +} + +/***************************************************************************** +* Prototype : nsfw_base_sendmsg +* Description : linux sendmsg api +* Input : int a +* const struct msghdr *b +* int flags +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_sendmsg(int a, const struct msghdr *b, int flags) +{ + nsfw_call_ret(sendmsg, (a, b, flags)) +} + +/***************************************************************************** +* Prototype : nsfw_base_recvmsg +* Description : linux recvmsg api +* Input : int a +* struct msghdr *b +* int flags +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_recvmsg(int a, struct msghdr *b, int flags) +{ + nsfw_call_ret(recvmsg, (a, b, flags)) +} + +/***************************************************************************** +* Prototype : nsfw_base_close +* Description : linux close api +* Input : int a +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_close(int a) +{ + nsfw_call_ret(close, (a)) +} + +/***************************************************************************** +* Prototype : nsfw_base_select +* Description : linux select api +* Input : int a +* fd_set *b +* fd_set *c +* fd_set *d +* struct timeval *e +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int nsfw_base_select(int a, fd_set *b, fd_set *c, fd_set *d, struct timeval *e) +{ + nsfw_call_ret(select, (a, b, c, d, e)) +} + +/***************************************************************************** +* Prototype : nsfw_base_ioctl +* Description : linux ioctl api +* Input : int a +* unsigned long b +* unsigned long c +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_ioctl(int a, unsigned long b, unsigned long c) +{ + nsfw_call_ret(ioctl, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_fcntl +* Description : linux fcntl api +* Input : int a +* int b +* unsigned long c +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_fcntl(int a, int b, unsigned long c) +{ + nsfw_call_ret(fcntl, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_epoll_create +* Description : linux epoll_create api +* Input : int a +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_epoll_create(int a) +{ + nsfw_call_ret(epoll_create, (a)) +} + +/***************************************************************************** +* Prototype : nsfw_base_epoll_create1 +* Description : linux epoll_create1 api +* Input : int a +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_epoll_create1(int a) +{ + nsfw_call_ret(epoll_create1, (a)) +} + +/***************************************************************************** +* Prototype : nsfw_base_epoll_ctl +* Description : linux epoll_ctl api +* Input : int a +* int b +* int c +* struct epoll_event *d +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_epoll_ctl(int a, int b, int c, struct epoll_event *d) +{ + nsfw_call_ret(epoll_ctl, (a, b, c, d)) +} + +/***************************************************************************** +* Prototype : nsfw_base_epoll_wait +* Description : linux epoll_wait api +* Input : int a +* struct epoll_event *b +* int c +* int d +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_epoll_wait(int a, struct epoll_event *b, int c, int d) +{ + nsfw_call_ret(epoll_wait, (a, b, c, d)) +} + +/***************************************************************************** +* Prototype : nsfw_base_fork +* Description : linux fork api +* Input : void +* Output : None +* Return Value : pid_t +* Calls : +* Called By : +* +*****************************************************************************/ +pid_t nsfw_base_fork(void) +{ + nsfw_call_ret(fork, ()) +} +/* *INDENT-ON* */ diff --git a/src/framework/common/base/liblinuxapi/nsfw_getopt.c b/src/framework/common/base/liblinuxapi/nsfw_getopt.c new file mode 100644 index 0000000..ac7d6bf --- /dev/null +++ b/src/framework/common/base/liblinuxapi/nsfw_getopt.c @@ -0,0 +1,455 @@ +/* +* +* 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 +#include +#include +#include "nsfw_getopt.h" +#include "nstack_log.h" + +char *nsfw_optarg = NULL; +int nsfw_optind = 1; +int nsfw_opterr = 1; +int nsfw_optopt = '?'; +NSTACK_STATIC char *nsfw_optnext = NULL; +NSTACK_STATIC int posixly_correct = -1; +NSTACK_STATIC int handle_nonopt_argv = 0; +NSTACK_STATIC int start = 0; +NSTACK_STATIC int end = 0; + +NSTACK_STATIC void check_gnu_extension (const char *optstring); +NSTACK_STATIC int nsfw_getopt_internal (int argc, char *const argv[], + const char *optstring, + const struct option *longopts, + int *longindex, int long_only); +NSTACK_STATIC int nsfw_getopt_shortopts (int argc, char *const argv[], + const char *optstring, + int long_only); +NSTACK_STATIC int nsfw_getopt_longopts (int argc, char *const argv[], + char *arg, const char *optstring, + const struct option *longopts, + int *longindex, int *long_only_flag); +NSTACK_STATIC inline int nsfw_getopt_internal_check_opts (const char + *optstring); +NSTACK_STATIC inline int nsfw_getopt_check_optind (); +NSTACK_STATIC inline int nsfw_getopt_internal_init (char *const argv[]); +NSTACK_STATIC inline int nsfw_getopt_longopts_check_longonly (int + *long_only_flag, + const char + *optstring, + char *const + argv[]); + +NSTACK_STATIC void +check_gnu_extension (const char *optstring) +{ + if (optstring[0] == '+' || getenv ("POSIXLY_CORRECT") != NULL) + { + posixly_correct = 1; + } + else + { + posixly_correct = 0; + } + if (optstring[0] == '-') + { + handle_nonopt_argv = 1; + } + else + { + handle_nonopt_argv = 0; + } +} + +int +nsfw_getopt_long (int argc, char *const argv[], const char *optstring, + const struct option *longopts, int *longindex) +{ + return nsfw_getopt_internal (argc, argv, optstring, longopts, longindex, 0); +} + +NSTACK_STATIC inline int +nsfw_getopt_internal_check_opts (const char *optstring) +{ + if (NULL == optstring) + { + return -1; + } + + if (nsfw_optopt == '?') + { + nsfw_optopt = 0; + } + + if (posixly_correct == -1) + { + check_gnu_extension (optstring); + } + + if (nsfw_optind == 0) + { + check_gnu_extension (optstring); + nsfw_optind = 1; + nsfw_optnext = NULL; + } + + switch (optstring[0]) + { + case '+': + case '-': + optstring++; + break; + default: + break; + } + return 0; +} + +NSTACK_STATIC inline int +nsfw_getopt_check_optind () +{ + if (nsfw_optind <= 0) + nsfw_optind = 1; + return 0; +} + +NSTACK_STATIC inline int +nsfw_getopt_internal_init (char *const argv[]) +{ + if (nsfw_optnext == NULL && start != 0) + { + int last_pos = nsfw_optind - 1; + + nsfw_optind -= end - start; + (void) nsfw_getopt_check_optind (); + + while (start < end--) + { + int i; + char *arg = argv[end]; + + for (i = end; i < last_pos; i++) + { + int j = i + 1; + ((char **) argv)[i] = argv[j]; + } + ((char const **) argv)[i] = arg; + last_pos--; + } + start = 0; + } + return 0; +} + +NSTACK_STATIC int +nsfw_getopt_internal (int argc, char *const argv[], const char *optstring, + const struct option *longopts, int *longindex, + int long_only) +{ + + (void) nsfw_getopt_internal_check_opts (optstring); + + (void) nsfw_getopt_internal_init (argv); + + if (nsfw_optind >= argc) + { + nsfw_optarg = NULL; + return -1; + } + if (nsfw_optnext == NULL) + { + const char *arg = argv[nsfw_optind]; + if (*arg != '-') + { + if (handle_nonopt_argv) + { + nsfw_optarg = argv[nsfw_optind++]; + start = 0; + return 1; + } + else if (posixly_correct) + { + nsfw_optarg = NULL; + return -1; + } + else + { + int i; + + start = nsfw_optind; + for (i = nsfw_optind + 1; i < argc; i++) + { + if (argv[i][0] == '-') + { + end = i; + break; + } + } + if (i == argc) + { + nsfw_optarg = NULL; + return -1; + } + nsfw_optind = i; + arg = argv[nsfw_optind]; + } + } + if (strcmp (arg, "--") == 0) + { + nsfw_optind++; + return -1; + } + if (longopts != NULL && arg[1] == '-') + { + return nsfw_getopt_longopts (argc, argv, argv[nsfw_optind] + 2, + optstring, longopts, longindex, NULL); + } + } + + if (nsfw_optnext == NULL) + { + nsfw_optnext = argv[nsfw_optind] + 1; + } + if (long_only) + { + int long_only_flag = 0; + int rv = + nsfw_getopt_longopts (argc, argv, nsfw_optnext, optstring, longopts, + longindex, &long_only_flag); + if (!long_only_flag) + { + nsfw_optnext = NULL; + return rv; + } + } + + return nsfw_getopt_shortopts (argc, argv, optstring, long_only); +} + +NSTACK_STATIC int +nsfw_getopt_shortopts (int argc, char *const argv[], const char *optstring, + int long_only) +{ + int opt = *nsfw_optnext; + const char *os; + if (optstring != NULL) + { + os = strchr (optstring, opt); + } + else + { + /* here try to keep same with below behavior */ + return '?'; + } + + if (os == NULL) + { + nsfw_optarg = NULL; + if (long_only) + { + if (':' != optstring[0]) + { + NSFW_LOGERR ("unrecognized option] argv_0=%s, netopt=%s", + argv[0], nsfw_optnext); + } + nsfw_optind++; + nsfw_optnext = NULL; + } + else + { + nsfw_optopt = opt; + if (':' != optstring[0]) + { + NSFW_LOGERR ("invalid option] argv_0=%s, opt=%c", argv[0], opt); + } + if (*(++nsfw_optnext) == 0) + { + nsfw_optind++; + nsfw_optnext = NULL; + } + } + return '?'; + } + if (os[1] == ':') + { + if (nsfw_optnext[1] == 0) + { + nsfw_optind++; + if (os[2] == ':') + { + nsfw_optarg = NULL; + } + else + { + if (nsfw_optind == argc) + { + nsfw_optarg = NULL; + nsfw_optopt = opt; + if (':' != optstring[0]) + { + NSFW_LOGERR + ("option requires an argument] argv_0=%s, opt=%c", + argv[0], opt); + } + return optstring[0] == ':' ? ':' : '?'; + } + nsfw_optarg = argv[nsfw_optind]; + nsfw_optind++; + } + } + else + { + nsfw_optarg = nsfw_optnext + 1; + nsfw_optind++; + } + nsfw_optnext = NULL; + } + else + { + nsfw_optarg = NULL; + if (nsfw_optnext[1] == 0) + { + nsfw_optnext = NULL; + nsfw_optind++; + } + else + { + nsfw_optnext++; + } + } + return opt; +} + +NSTACK_STATIC inline int +nsfw_getopt_longopts_check_longonly (int *long_only_flag, + const char *optstring, + char *const argv[]) +{ + if (long_only_flag) + { + *long_only_flag = 1; + } + else + { + if (':' != optstring[0]) + { + NSFW_LOGERR ("unrecognized option] argv_0=%s, option=%s", argv[0], + argv[nsfw_optind]); + } + nsfw_optind++; + } + return 0; +} + +NSTACK_STATIC int +nsfw_getopt_longopts (int argc, char *const argv[], char *arg, + const char *optstring, const struct option *longopts, + int *longindex, int *long_only_flag) +{ + char *val = NULL; + const struct option *opt; + size_t namelen; + int idx; + + if ((longopts == NULL) || (arg == NULL)) + { + return -1; + } + + for (idx = 0; longopts[idx].name != NULL; idx++) + { + opt = &longopts[idx]; + namelen = strlen (opt->name); + + if (strncmp (arg, opt->name, namelen) == 0) + { + switch (arg[namelen]) + { + case '\0': + switch (opt->has_arg) + { + case nsfw_required_argument: + nsfw_optind++; + + if (nsfw_optind == argc) + { + nsfw_optarg = NULL; + nsfw_optopt = opt->val; + if (':' != optstring[0]) + { + NSFW_LOGERR + ("requires an argument] argv_0=%s, opt name=%s", + argv[0], opt->name); + } + return optstring[0] == ':' ? ':' : '?'; + } + + val = argv[nsfw_optind]; + break; + + default: + break; + } + + goto found; + + case '=': + if (opt->has_arg == nsfw_no_argument) + { + const char *hyphens = + (argv[nsfw_optind][1] == '-') ? "--" : "-"; + nsfw_optind++; + nsfw_optarg = NULL; + nsfw_optopt = opt->val; + if (':' != optstring[0]) + { + NSFW_LOGERR + ("doesn't allow an argument] argv_0=%s, hyphens=%s, opt name=%s", + argv[0], hyphens, opt->name); + } + return '?'; + } + + val = arg + namelen + 1; + goto found; + + default: + break; + } + } + } + + (void) nsfw_getopt_longopts_check_longonly (long_only_flag, optstring, + argv); + return '?'; + +found: + nsfw_optarg = val; + nsfw_optind++; + + if (opt->flag) + { + *opt->flag = opt->val; + } + + if (longindex) + { + *longindex = idx; + } + + return opt->flag ? 0 : opt->val; +} diff --git a/src/framework/common/base/liblinuxapi/nsfw_lock_file.c b/src/framework/common/base/liblinuxapi/nsfw_lock_file.c new file mode 100644 index 0000000..0ec196f --- /dev/null +++ b/src/framework/common/base/liblinuxapi/nsfw_lock_file.c @@ -0,0 +1,174 @@ +/* +* +* 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 +#include +#include +#include + +#include "types.h" +#include "nstack_securec.h" +#include "nsfw_init.h" +#include "common_mem_api.h" + +#include "nstack_log.h" +#include "nsfw_maintain_api.h" +#include "nsfw_mgr_com_api.h" + +#include "nsfw_base_linux_api.h" +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#define NSFW_FILE_PATH_LEN 128 +#define LOCK_FOLDER "/ip_module/" +#define LOCK_SUFFIX ".pid" + +#define read_lock(fd, offset, whence, len) nsfw_lock_reg((fd), F_SETLK, F_RDLCK, (offset), (whence), (len)) +#define readw_lock(fd, offset, whence, len) nsfw_lock_reg((fd), F_SETLKW, F_RDLCK, (offset), (whence), (len)) +#define write_lock(fd, offset, whence, len) nsfw_lock_reg((fd), F_SETLK, F_WRLCK, (offset), (whence), (len)) +#define writew_lock(fd, offset, whence, len) nsfw_lock_reg((fd), F_SETLKW, F_WRLCK, (offset), (whence), (len)) +#define un_lock(fd, offset, whence, len) nsfw_lock_reg((fd), F_SETLK, F_UNLCK, (offset), (whence), (len)) + +i32 +nsfw_lock_reg (i32 fd, i32 cmd, i32 type, off_t offset, i32 whence, off_t len) +{ + struct flock lock_file; + lock_file.l_type = type; + lock_file.l_start = offset; + lock_file.l_whence = whence; + lock_file.l_len = len; + return (fcntl (fd, cmd, &lock_file)); +} + +/***************************************************************************** +* Prototype : nsfw_proc_start_with_lock +* Description : lock file start +* Input : u8 proc_type +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_proc_start_with_lock (u8 proc_type) +{ + NSFW_LOGINF ("lock_file init]type=%u", proc_type); + char *module_name = nsfw_get_proc_name (proc_type); + if (NULL == module_name) + { + NSFW_LOGERR ("proc type error]proc_type=%u", proc_type); + return 0; + } + + const char *directory = NSFW_DOMAIN_DIR; + const char *home_dir = getenv ("HOME"); + + if (getuid () != 0 && home_dir != NULL) + { + directory = home_dir; + } + + int ret; + char lock_fpath[NSFW_FILE_PATH_LEN] = { 0 }; + ret = STRCPY_S (lock_fpath, NSFW_FILE_PATH_LEN, directory); + if (EOK != ret) + { + NSFW_LOGERR ("lock init STRCPY_S failed]ret=%d", ret); + return -1; + } + + ret = STRCAT_S (lock_fpath, NSFW_FILE_PATH_LEN, LOCK_FOLDER); + if (EOK != ret) + { + NSFW_LOGERR ("lock init STRCAT_S failed]ret=%d", ret); + return -1; + } + + ret = STRCAT_S (lock_fpath, NSFW_FILE_PATH_LEN, module_name); + if (EOK != ret) + { + NSFW_LOGERR ("lock init STRCAT_S failed]ret=%d", ret); + return -1; + } + + ret = STRCAT_S (lock_fpath, NSFW_FILE_PATH_LEN, LOCK_SUFFIX); + if (EOK != ret) + { + NSFW_LOGERR ("lock init STRCAT_S failed]ret=%d", ret); + return -1; + } + + i32 fd; + if ((fd = open (lock_fpath, O_RDWR | O_CREAT, 0640)) == -1) + { /* file permission no large than 0640 */ + NSFW_LOGERR ("open lock file error!]path=%s,error = %d", lock_fpath, + errno); + return -1; + } + + int rc = nsfw_set_close_on_exec (fd); + if (rc == -1) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("set exec err]fd=%d, errno=%d", fd, errno); + return -1; + } + + if (write_lock (fd, 0, SEEK_SET, 0) < 0) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("get lock file error!]path=%s,error = %d", lock_fpath, + errno); + return -1; + } + + char buf[32] = { 0 }; + if (ftruncate (fd, 0) < 0) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("ftruncate file error!]path=%s,error = %d", lock_fpath, + errno); + return -1; + } + + ret = + SNPRINTF_S (buf, sizeof (buf), sizeof (buf) - 1, "%ld", (long) getpid ()); + if (-1 == ret) + { + NSTCP_LOGERR ("SNPRINTF_S failed]ret=%d", ret); + (void) nsfw_base_close (fd); + return -1; + } + + if (write (fd, buf, strlen (buf) + 1) < 0) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("write file error!]path=%s,error = %d", lock_fpath, errno); + return -1; + } + + return 0; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/framework/common/data_struct/eprb_tree.c b/src/framework/common/data_struct/eprb_tree.c new file mode 100644 index 0000000..c8af17c --- /dev/null +++ b/src/framework/common/data_struct/eprb_tree.c @@ -0,0 +1,492 @@ +/* +* +* 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 "eprb_tree.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/* + * This function returns the first node (in sort order) of the tree. + */ +struct ep_rb_node * +ep_rb_first (const struct ep_rb_root *root) +{ + if (NULL == root) + return NULL; + + struct ep_rb_node *n; + n = (struct ep_rb_node *) ADDR_SHTOL (root->rb_node); + + if (!n) + { + return NULL; + } + + while (n->rb_left) + { + n = (struct ep_rb_node *) ADDR_SHTOL (n->rb_left); + } + + return n; +} + +void +__ep_rb_rotate_left (struct ep_rb_node *X, struct ep_rb_root *root) +{ + /************************** + * rotate Node X to left * + **************************/ + struct ep_rb_node *Y = (struct ep_rb_node *) ADDR_SHTOL (X->rb_right); + + /* estblish X->Right link */ + X->rb_right = Y->rb_left; + + if (Y->rb_left != NULL) + { + ((struct ep_rb_node *) ADDR_SHTOL (Y->rb_left))->rb_parent = + (struct ep_rb_node *) ADDR_LTOSH_EXT (X); + } + + /* estblish Y->Parent link */ + Y->rb_parent = X->rb_parent; + + if (X->rb_parent) + { + struct ep_rb_node *xParent = + (struct ep_rb_node *) ADDR_SHTOL (X->rb_parent); + + if (X == ADDR_SHTOL (xParent->rb_left)) + { + xParent->rb_left = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y); + } + else + { + xParent->rb_right = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y); + } + } + else + { + root->rb_node = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y); + } + + /* link X and Y */ + Y->rb_left = (struct ep_rb_node *) ADDR_LTOSH_EXT (X); + X->rb_parent = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y); + + return; +} + +void +__ep_rb_rotate_right (struct ep_rb_node *X, struct ep_rb_root *root) +{ + /**************************** + * rotate Node X to right * + ****************************/ + struct ep_rb_node *Y = (struct ep_rb_node *) ADDR_SHTOL (X->rb_left); + + /* estblish X->Left link */ + X->rb_left = Y->rb_right; + + if (Y->rb_right != NULL) + { + ((struct ep_rb_node *) ADDR_SHTOL (Y->rb_right))->rb_parent = + (struct ep_rb_node *) ADDR_LTOSH_EXT (X); + } + + /* estblish Y->Parent link */ + Y->rb_parent = X->rb_parent; + + if (X->rb_parent) + { + struct ep_rb_node *xParent = + (struct ep_rb_node *) ADDR_SHTOL (X->rb_parent); + + if (X == (struct ep_rb_node *) ADDR_SHTOL (xParent->rb_right)) + { + xParent->rb_right = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y); + } + else + { + xParent->rb_left = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y); + } + } + else + { + root->rb_node = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y); + } + + /* link X and Y */ + Y->rb_right = (struct ep_rb_node *) ADDR_LTOSH_EXT (X); + X->rb_parent = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y); + + return; +} + +#define EP_RBTREE_PARENT(X) ((struct ep_rb_node*) ADDR_SHTOL((X)->rb_parent)) +#define EP_RBTREE_GRANDF(X) EP_RBTREE_PARENT(EP_RBTREE_PARENT(X)) + +/* X, Y are for application */ +void +ep_rb_insert_color (struct ep_rb_node *X, struct ep_rb_root *root) +{ + /************************************* + * maintain red-black tree balance * + * after inserting node X * + *************************************/ + /* check red-black properties */ + while (X != (struct ep_rb_node *) ADDR_SHTOL (root->rb_node) + && EP_RBTREE_PARENT (X)->color == EP_RB_RED) + { + /* we have a violation */ + if (X->rb_parent == EP_RBTREE_GRANDF (X)->rb_left) + { + struct ep_rb_node *Y = + (struct ep_rb_node *) ADDR_SHTOL (EP_RBTREE_GRANDF (X)->rb_right); + + if (Y && Y->color == EP_RB_RED) + { + + /* uncle is red */ + EP_RBTREE_PARENT (X)->color = EP_RB_BLACK; + Y->color = EP_RB_BLACK; + EP_RBTREE_GRANDF (X)->color = EP_RB_RED; + X = EP_RBTREE_GRANDF (X); + } + else + { + + /* uncle is black */ + if (X == + (struct ep_rb_node *) + ADDR_SHTOL (EP_RBTREE_PARENT (X)->rb_right)) + { + /* make X a left child */ + X = EP_RBTREE_PARENT (X); + __ep_rb_rotate_left (X, root); + } + + /* recolor and rotate */ + EP_RBTREE_PARENT (X)->color = EP_RB_BLACK; + EP_RBTREE_GRANDF (X)->color = EP_RB_RED; + __ep_rb_rotate_right (EP_RBTREE_GRANDF (X), root); + } + } + else + { + /* miror image of above code */ + struct ep_rb_node *Y = + (struct ep_rb_node *) ADDR_SHTOL (EP_RBTREE_GRANDF (X)->rb_left); + + if (Y && (Y->color == EP_RB_RED)) + { + + /* uncle is red */ + EP_RBTREE_PARENT (X)->color = EP_RB_BLACK; + Y->color = EP_RB_BLACK; + EP_RBTREE_GRANDF (X)->color = EP_RB_RED; + X = EP_RBTREE_GRANDF (X); + } + else + { + + /* uncle is black */ + if (X == + (struct ep_rb_node *) + ADDR_SHTOL (EP_RBTREE_PARENT (X)->rb_left)) + { + X = EP_RBTREE_PARENT (X); + __ep_rb_rotate_right (X, root); + } + + EP_RBTREE_PARENT (X)->color = EP_RB_BLACK; + EP_RBTREE_GRANDF (X)->color = EP_RB_RED; + __ep_rb_rotate_left (EP_RBTREE_GRANDF (X), root); + } + } + } + + ((struct ep_rb_node *) ADDR_SHTOL (root->rb_node))->color = EP_RB_BLACK; + + return; +} + +void +__ep_rb_erase_color (struct ep_rb_node *X, struct ep_rb_node *Parent, + struct ep_rb_root *root) +{ + /************************************* + * maintain red-black tree balance * + * after deleting node X * + *************************************/ + while (X != (struct ep_rb_node *) ADDR_SHTOL (root->rb_node) + && (!X || X->color == EP_RB_BLACK)) + { + + if (Parent == NULL) + { + break; + } + + if (X == (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_left)) + { + struct ep_rb_node *W = + (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_right); + + if (W->color == EP_RB_RED) + { + W->color = EP_RB_BLACK; + Parent->color = EP_RB_RED; /* Parent != NIL? */ + __ep_rb_rotate_left (Parent, root); + W = (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_right); + } + + if ((!W->rb_left + || ((struct ep_rb_node *) ADDR_SHTOL (W->rb_left))->color == + EP_RB_BLACK) && (!W->rb_right + || ((struct ep_rb_node *) + ADDR_SHTOL (W->rb_right))->color == + EP_RB_BLACK)) + { + W->color = EP_RB_RED; + X = Parent; + Parent = (struct ep_rb_node *) ADDR_SHTOL (X->rb_parent); + } + else + { + if (!W->rb_right + || ((struct ep_rb_node *) ADDR_SHTOL (W->rb_right))->color + == EP_RB_BLACK) + { + if (W->rb_left != NULL) + { + ((struct ep_rb_node *) ADDR_SHTOL (W->rb_left))->color + = EP_RB_BLACK; + } + + W->color = EP_RB_RED; + __ep_rb_rotate_right (W, root); + W = (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_right); + } + + W->color = Parent->color; + Parent->color = EP_RB_BLACK; + + if (((struct ep_rb_node *) ADDR_SHTOL (W->rb_right))->color != + EP_RB_BLACK) + { + ((struct ep_rb_node *) ADDR_SHTOL (W->rb_right))->color = + EP_RB_BLACK; + } + + __ep_rb_rotate_left (Parent, root); + X = (struct ep_rb_node *) ADDR_SHTOL (root->rb_node); + break; + } + } + else + { + + struct ep_rb_node *W = + (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_left); + + if (W->color == EP_RB_RED) + { + W->color = EP_RB_BLACK; + Parent->color = EP_RB_RED; /* Parent != NIL? */ + __ep_rb_rotate_right (Parent, root); + W = (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_left); + } + + if ((!W->rb_left + || (((struct ep_rb_node *) ADDR_SHTOL (W->rb_left))->color == + EP_RB_BLACK)) && (!W->rb_right + || + (((struct ep_rb_node *) + ADDR_SHTOL (W->rb_right))->color == + EP_RB_BLACK))) + { + W->color = EP_RB_RED; + X = Parent; + Parent = (struct ep_rb_node *) ADDR_SHTOL (X->rb_parent); + } + else + { + if (!W->rb_left + || ((struct ep_rb_node *) ADDR_SHTOL (W->rb_left))->color + == EP_RB_BLACK) + { + if (W->rb_right != NULL) + { + ((struct ep_rb_node *) + ADDR_SHTOL (W->rb_right))->color = EP_RB_BLACK; + } + + W->color = EP_RB_RED; + __ep_rb_rotate_left (W, root); + W = (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_left); + } + + W->color = Parent->color; + Parent->color = EP_RB_BLACK; + + if (((struct ep_rb_node *) ADDR_SHTOL (W->rb_left))->color != + EP_RB_BLACK) + { + ((struct ep_rb_node *) ADDR_SHTOL (W->rb_left))->color = + EP_RB_BLACK; + } + + __ep_rb_rotate_right (Parent, root); + X = (struct ep_rb_node *) ADDR_SHTOL (root->rb_node); + break; + } + } + } + + if (X) + { + X->color = EP_RB_BLACK; + } + + return; +} + +void +ep_rb_erase (struct ep_rb_node *node, struct ep_rb_root *root) +{ + struct ep_rb_node *child, *parent; + int color; + + if (!node->rb_left) + { + child = (struct ep_rb_node *) ADDR_SHTOL (node->rb_right); + } + else if (!node->rb_right) + { + child = (struct ep_rb_node *) ADDR_SHTOL (node->rb_left); + } + else + { + struct ep_rb_node *old = node, *left; + + node = (struct ep_rb_node *) ADDR_SHTOL (node->rb_right); + + while ((left = + (struct ep_rb_node *) ADDR_SHTOL (node->rb_left)) != NULL) + { + node = left; + } + + if (old->rb_parent) + { + struct ep_rb_node *oldParent = + (struct ep_rb_node *) ADDR_SHTOL (old->rb_parent); + + if (oldParent->rb_left == + (struct ep_rb_node *) ADDR_LTOSH_EXT (old)) + { + oldParent->rb_left = + (struct ep_rb_node *) ADDR_LTOSH_EXT (node); + } + else + { + oldParent->rb_right = + (struct ep_rb_node *) ADDR_LTOSH_EXT (node); + } + } + else + { + root->rb_node = (struct ep_rb_node *) ADDR_LTOSH_EXT (node); + } + + child = (struct ep_rb_node *) ADDR_SHTOL (node->rb_right); + parent = (struct ep_rb_node *) ADDR_SHTOL (node->rb_parent); + color = node->color; + + if (parent == old) + { + parent = node; + } + else + { + if (child) + { + child->rb_parent = + (struct ep_rb_node *) ADDR_LTOSH_EXT (parent); + } + + parent->rb_left = (struct ep_rb_node *) ADDR_LTOSH_EXT (child); + + node->rb_right = old->rb_right; + ((struct ep_rb_node *) ADDR_SHTOL (old->rb_right))->rb_parent = + (struct ep_rb_node *) ADDR_LTOSH_EXT (node); + } + + node->color = old->color; + node->rb_parent = old->rb_parent; + node->rb_left = old->rb_left; + ((struct ep_rb_node *) ADDR_SHTOL (old->rb_left))->rb_parent = + (struct ep_rb_node *) ADDR_LTOSH_EXT (node); + + if (color == EP_RB_BLACK) + { + __ep_rb_erase_color (child, parent, root); + } + + return; + + } + + parent = (struct ep_rb_node *) ADDR_SHTOL (node->rb_parent); + color = node->color; + + if (child) + { + child->rb_parent = (struct ep_rb_node *) ADDR_LTOSH_EXT (parent); + } + + if (parent) + { + if (parent->rb_left == (struct ep_rb_node *) ADDR_LTOSH_EXT (node)) + { + parent->rb_left = (struct ep_rb_node *) ADDR_LTOSH_EXT (child); + } + else + { + parent->rb_right = (struct ep_rb_node *) ADDR_LTOSH_EXT (child); + } + } + else + { + root->rb_node = (struct ep_rb_node *) ADDR_LTOSH_EXT (child); + } + + if (color == EP_RB_BLACK) + { + __ep_rb_erase_color (child, parent, root); + } + return; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif diff --git a/src/framework/common/data_struct/list.c b/src/framework/common/data_struct/list.c new file mode 100644 index 0000000..7645640 --- /dev/null +++ b/src/framework/common/data_struct/list.c @@ -0,0 +1,163 @@ +/* +* +* 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 "list.h" + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +inline int +list_empty (const struct list_head *head) +{ + return head->next == head; +} + +inline void +list_del (struct list_head *entry) +{ + if (entry->prev == NULL || entry->next == NULL) + { + return; + } + entry->next->prev = entry->prev; + entry->prev->next = entry->next; + entry->next = NULL; + entry->prev = NULL; +} + +/*get the first element of the list, need to check if list empty or not before calling this.*/ +inline struct list_head * +list_get_first (struct list_head *head) +{ + return head->next; +} + +inline void +list_add (struct list_head *newp, struct list_head *head) +{ + head->next->prev = newp; + newp->next = head->next; + newp->prev = head; + head->next = newp; +} + +inline void +list_link (struct list_head *newhead, struct list_head *head) +{ + struct list_head *tmp; + + newhead->prev->next = head; + head->prev->next = newhead; + + tmp = newhead->prev; + newhead->prev = head->prev; + head->prev = tmp; +} + +inline void +list_add_tail (struct list_head *newp, struct list_head *head) +{ + list_add (newp, head->prev); +} + +inline void +hlist_del_init (struct hlist_node *n) +{ + struct hlist_node *next = n->next; + struct hlist_node **pprev = n->pprev; + + if (pprev == NULL && next == NULL) + { + return; + } + + if (pprev) + { + *pprev = next; + } + + if (next) + { + next->pprev = pprev; + } + + n->next = NULL; + n->pprev = NULL; +} + +/** + * next must be != NULL + * add n node before next node + * + * @n: new node + * @next: node in the hlist + */ +inline void +hlist_add_before (struct hlist_node *n, struct hlist_node *next) +{ + n->pprev = next->pprev; + n->next = next; + next->pprev = &n->next; + *(n->pprev) = n; +} + +/** + * next must be != NULL + * add n node after next node + * actual behavior is add after n + * @n: node in the hlist + * @next: new node + */ +inline void +hlist_add_after (struct hlist_node *n, struct hlist_node *next) +{ + next->next = n->next; + n->next = next; + next->pprev = &n->next; + if (next->next) + { + next->next->pprev = &next->next; + } +} + +/* add after the head */ +inline void +hlist_add_head (struct hlist_node *n, struct hlist_head *h) +{ + struct hlist_node *first = h->first; + + n->next = first; + if (first) + { + first->pprev = &n->next; + } + + h->first = n; + n->pprev = &h->first; +} + +inline int +hlist_unhashed (const struct hlist_node *h) +{ + return !h->pprev; +} + +inline int +hlist_empty (const struct hlist_head *h) +{ + return !h->first; +} diff --git a/src/framework/common/data_struct/pidinfo.c b/src/framework/common/data_struct/pidinfo.c new file mode 100644 index 0000000..08e551f --- /dev/null +++ b/src/framework/common/data_struct/pidinfo.c @@ -0,0 +1,125 @@ +/* +* +* 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 "pidinfo.h" +#include "nstack_securec.h" + +inline i32 +nsfw_pidinfo_init (nsfw_pidinfo * pidinfo) +{ + int retVal = + MEMSET_S (pidinfo, sizeof (nsfw_pidinfo), 0, sizeof (nsfw_pidinfo)); + if (EOK != retVal) + { + return -1; + } + + return 0; +} + +inline int +nsfw_add_pid (nsfw_pidinfo * pidinfo, u32 pid) +{ + u32 i; + + for (i = 0; i < NSFW_MAX_FORK_NUM; i++) + { + if ((0 == pidinfo->apid[i]) + && (__sync_bool_compare_and_swap (&pidinfo->apid[i], 0, pid))) + { + if (pidinfo->used_size < i + 1) + { + pidinfo->used_size = i + 1; + } + return 0; + } + } + return -1; +} + +inline int +nsfw_del_pid (nsfw_pidinfo * pidinfo, u32 pid) +{ + u32 i; + + for (i = 0; i < pidinfo->used_size && i < NSFW_MAX_FORK_NUM; i++) + { + if (pid == pidinfo->apid[i]) + { + pidinfo->apid[i] = 0; + return 0; + } + } + return -1; +} + +inline int +nsfw_del_last_pid (nsfw_pidinfo * pidinfo, u32 pid) +{ + u32 i; + int count = 0; + int deleted = 0; + for (i = 0; i < pidinfo->used_size && i < NSFW_MAX_FORK_NUM; i++) + { + if (pid == pidinfo->apid[i]) + { + pidinfo->apid[i] = 0; + deleted = 1; + continue; + } + + if (pidinfo->apid[i] != 0) + { + ++count; + } + } + + if (!deleted) + { + return -1; + } + + return count; +} + +inline int +nsfw_pid_exist (nsfw_pidinfo * pidinfo, u32 pid) +{ + u32 i; + + for (i = 0; i < pidinfo->used_size && i < NSFW_MAX_FORK_NUM; i++) + { + if (pid == pidinfo->apid[i]) + { + return 1; + } + } + return 0; +} + +inline int +nsfw_pidinfo_empty (nsfw_pidinfo * pidinfo) +{ + u32 i; + for (i = 0; i < pidinfo->used_size && i < NSFW_MAX_FORK_NUM; i++) + { + if (pidinfo->apid[i] != 0) + { + return 0; + } + } + return 1; +} diff --git a/src/framework/common/data_struct/sha256.c b/src/framework/common/data_struct/sha256.c new file mode 100644 index 0000000..504b365 --- /dev/null +++ b/src/framework/common/data_struct/sha256.c @@ -0,0 +1,397 @@ +/* +* +* 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. +*/ + +/*Possible access of out-of-bounds pointer: + The algorithms has been tested on purify. So no + out of bounds access possible.*/ + +/*Possible creation of out-of-bounds pointer + No Out of bounds pointers are created.- false positive.*/ + +#include /* for mem copy function etc. */ +#include "sha256.h" +#include "nstack_securec.h" +#include "types.h" +#include "nstack_log.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n))) +#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n))) + +#if !defined(bswap_32) +#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00)) +#endif + +#ifdef LITTLE_ENDIAN +#define SWAP_BYTES +#else +#undef SWAP_BYTES +#endif + +#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) +#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y)))) + + /* round transforms for SHA256 and SHA512 compression functions */ + +#define vf(n,i) v[(n - i) & 7] + +#define hf(i) (p[i & 15] += \ + g_1(p[(i + 14) & 15]) + p[(i + 9) & 15] + g_0(p[(i + 1) & 15])) + +#define v_cycle(i,j) \ +{ \ + vf(7,i) += (j ? hf(i) : p[i]) + k_0[i+j] \ + + s_1(vf(4,i)) + ch(vf(4,i),vf(5,i),vf(6,i)); \ + vf(3,i) += vf(7,i); \ + vf(7,i) += s_0(vf(0,i))+ maj(vf(0,i),vf(1,i),vf(2,i)); \ +} + +#define SHA256_MASK (SHA256_BLOCK_SIZE - 1) + +#if defined(SWAP_BYTES) +#define bsw_32(p,n) \ +{ \ + u32 _i = (n); \ + while (_i--) \ + { \ + ((u32*)p)[_i] = bswap_32(((u32*)p)[_i]); \ + } \ +} + +#else +#define bsw_32(p,n) +#endif + +#define s_0(x) (rotr32((x), 2) ^ rotr32((x), 13) ^ rotr32((x), 22)) +#define s_1(x) (rotr32((x), 6) ^ rotr32((x), 11) ^ rotr32((x), 25)) +#define g_0(x) (rotr32((x), 7) ^ rotr32((x), 18) ^ ((x) >> 3)) +#define g_1(x) (rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10)) +#define k_0 k256 + +/* rotated SHA256 round definition. Rather than swapping variables as in */ +/* FIPS-180, different variables are 'rotated' on each round, returning */ +/* to their starting positions every eight rounds */ + +#define q(n) v##n + +#define one_cycle(a,b,c,d,e,f,g,h,k,w) \ + q(h) += s_1(q(e)) + ch(q(e), q(f), q(g)) + k + w; \ + q(d) += q(h); q(h) += s_0(q(a)) + maj(q(a), q(b), q(c)) + +/* +Description: SHA256 mixing data +Value Range: None +Access: Used to mix with data to create SHA256 key. +Remarks: +*/ +static const u32 k256[64] = { + 010242427630, 016115642221, 026560175717, 035155355645, + 07125541133, 013174210761, 022217701244, 025307057325, + 033001725230, 02240655401, 04414302676, 012503076703, + 016257456564, 020067530776, 023367003247, 030146770564, + 034446664701, 035757443606, 01760316706, 04403120714, + 05572226157, 011235102252, 013454124734, 016676304332, + 023017450522, 025014343155, 026000623710, 027726277707, + 030670005763, 032551710507, 0662461521, 02412224547, + 04755605205, 05606620470, 011513066774, 012316006423, + 014502471524, 016632405273, 020160544456, 022234426205, + 024257764241, 025006463113, 030222705560, 030733050643, + 032144564031, 032646203044, 036403432605, 02032520160, + 03151140426, 03615666010, 04722073514, 06454136265, + 07107006263, 011666125112, 013347145117, 015013467763, + 016443701356, 017051261557, 020462074024, 021461601010, + 022057577772, 024424066353, 027676321767, 030634274362, +}; + +/* Compile 64 bytes of hash data into SHA256 digest value */ +/* NOTE: this routine assumes that the byte order in the */ +/* ctx->wbuf[] at this point is such that low address bytes */ +/* in the ORIGINAL byte stream will go into the high end of */ +/* words on BOTH big and little endian systems */ + +#define v_ v +#define ptr p + +/*===========================================================================*\ + Function :Sha256_compile__ + Description : This function generates the digest value for SHA256. + Compile 64 bytes of hash data into SHA256 digest value + Calls : mem copy - Secure mem copy function. + Called by : + Return : This is a static internal function which doesn't return any value. + Parameters : + SHA256_CTX ctx[1] - + Note : this routine assumes that the byte order in the + ctx->wbuf[] at this point is such that low address bytes in + the ORIGINAL byte stream will go into the high end of + words on BOTH big and little endian systems. +\*===========================================================================*/ +NSTACK_STATIC void +Sha256_compile__ (SHA256_CTX ctx[1]) +{ + + /* macros defined above to this function i.e. v_ and ptr should not be removed */ + /* v_cycle - for 0 to 15 */ + u32 j; + u32 *ptr = ctx->wbuf; + u32 v_[8]; + + int ret = MEMCPY_S (v_, 8 * sizeof (u32), ctx->hash, 8 * sizeof (u32)); + if (EOK != ret) + { + NSPOL_LOGERR ("MEMCPY_S failed"); + return; + } + + for (j = 0; j < 64; j += 16) + { + /*v_cycle operations from 0 to 15 */ + v_cycle (0, j); + v_cycle (1, j); + v_cycle (2, j); + v_cycle (3, j); + v_cycle (4, j); + v_cycle (5, j); + v_cycle (6, j); + v_cycle (7, j); + v_cycle (8, j); + v_cycle (9, j); + v_cycle (10, j); + v_cycle (11, j); + v_cycle (12, j); + v_cycle (13, j); + v_cycle (14, j); + v_cycle (15, j); + } + + /* update the context */ + ctx->hash[0] += v_[0]; + ctx->hash[1] += v_[1]; + ctx->hash[2] += v_[2]; + ctx->hash[3] += v_[3]; + ctx->hash[4] += v_[4]; + ctx->hash[5] += v_[5]; + ctx->hash[6] += v_[6]; + ctx->hash[7] += v_[7]; + + return; +} + +#undef v_ +#undef ptr + +/* SHA256 hash data in an array of bytes into hash buffer */ +/* and call the hash_compile function as required. */ + +/*===========================================================================*\ + Function :Sha256_upd + Description : + Calls : + Called by : + Return :void - + Parameters : + SHA256_CTX ctx[1] - + const unsigned char data[] - + size_t len - + Note : +\*===========================================================================*/ +void +Sha256_upd (SHA256_CTX ctx[1], const u8 data[], size_t len) +{ + u32 pos = (u32) (ctx->count[0] & SHA256_MASK); + u32 space = SHA256_BLOCK_SIZE - pos; + const u8 *sp = data; + int ret; + + if ((ctx->count[0] += (u32) len) < len) + { + ++(ctx->count[1]); + } + + while (len >= space) + { + + /* tranfer whole blocks while possible */ + ret = MEMCPY_S (((u8 *) ctx->wbuf) + pos, space, sp, space); + if (EOK != ret) + { + NSPOL_LOGERR ("MEMCPY_S failed"); + return; + } + + sp += space; + len -= space; + space = SHA256_BLOCK_SIZE; + pos = 0; + bsw_32 (ctx->wbuf, SHA256_BLOCK_SIZE >> 2); + Sha256_compile__ (ctx); + } + + if (len != 0) + { + ret = MEMCPY_S (((u8 *) ctx->wbuf) + pos, (u32) len, sp, (u32) len); + if (EOK != ret) + { + NSPOL_LOGERR ("MEMCPY_S failed"); + return; + } + } + + return; +} + +/* SHA256 Final padding and digest calculation */ + +/*===========================================================================*\ + Function :SHA_fin1 + Description : + Calls : + Called by : + Return :void - + Parameters : + unsigned char hval[] - + SHA256_CTX ctx[1] - + const unsigned int hlen - + Note : +\*===========================================================================*/ +NSTACK_STATIC void +SHA_fin1 (u8 hval[], SHA256_CTX ctx[1], const unsigned int hlen) +{ + u32 i = (u32) (ctx->count[0] & SHA256_MASK); + + /* Not unusal shift operation. Checked with purify. */ + + /*put bytes in the buffer in an order in which references to */ + /*32-bit words will put bytes with lower addresses into the */ + /*top of 32 bit words on BOTH big and little endian machines */ + bsw_32 (ctx->wbuf, (i + 3) >> 2); + + /*we now need to mask valid bytes and add the padding which is */ + /*a single 1 bit and as many zero bits as necessary. Note that */ + /*we can always add the first padding byte here because the */ + /*buffer always has at least one empty slot */ + ctx->wbuf[i >> 2] &= (u32) 0xffffff80 << 8 * (~i & 3); + ctx->wbuf[i >> 2] |= (u32) 0x00000080 << 8 * (~i & 3); + + /* we need 9 or more empty positions, one for the padding byte */ + /* (above) and eight for the length count. If there is not */ + /* enough space pad and empty the buffer */ + if (i > SHA256_BLOCK_SIZE - 9) + { + if (i < 60) + { + ctx->wbuf[15] = 0; + } + + Sha256_compile__ (ctx); + i = 0; + } + else + { + /* compute a word index for the empty buffer positions */ + i = (i >> 2) + 1; + } + + while (i < 14) + { + /* and zero pad all but last two positions */ + ctx->wbuf[i++] = 0; + } + + /* the following 32-bit length fields are assembled in the */ + /* wrong byte order on little endian machines but this is */ + /* corrected later since they are only ever used as 32-bit */ + /* word values. */ + ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29); + ctx->wbuf[15] = ctx->count[0] << 3; + Sha256_compile__ (ctx); + + /* extract the hash value as bytes in case the hash buffer is */ + /* mislaigned for 32-bit words */ + for (i = 0; i < hlen; ++i) + { + hval[i] = (u8) (ctx->hash[i >> 2] >> (8 * (~i & 3))); + } + + return; +} + +/* +Description: Internal data for SHA256 digest calculation +Value Range: None +Access: Used to store internal data for SHA256 digest calculation +Remarks: +*/ +static const u32 g_i256[] = { + 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, + 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 +}; + +/*===========================================================================*\ + Function :Sha256_set + Description : + Calls : + Called by : + Return :void - + Parameters : + SHA256_CTX ctx[1] - + Note : +\*===========================================================================*/ +void +Sha256_set (SHA256_CTX ctx[1]) +{ + int ret; + ctx->count[0] = ctx->count[1] = 0; + + ret = MEMCPY_S (ctx->hash, sizeof (ctx->hash), g_i256, sizeof (g_i256)); + if (EOK != ret) + { + NSPOL_LOGERR ("MEMCPY_S failed"); + return; + } + + return; +} + +/*===========================================================================*\ + Function :Sha256_fin + Description : + Calls : + Called by : + Return :void - + Parameters : + SHA256_CTX ctx[1] - + unsigned char hval[] - + Note : +\*===========================================================================*/ +void +Sha256_fin (SHA256_CTX ctx[1], u8 hval[]) +{ + SHA_fin1 (hval, ctx, SHA256_DIGEST_SIZE); + + return; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif diff --git a/src/framework/common/include/compile_config.h b/src/framework/common/include/compile_config.h new file mode 100644 index 0000000..2ec5373 --- /dev/null +++ b/src/framework/common/include/compile_config.h @@ -0,0 +1,30 @@ +/* +* +* 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 COMPILE_CONFIG_H +#define COMPILE_CONFIG_H + +#ifndef NSTACK_STATIC +#ifndef NSTACK_STATIC_CHECK +#define NSTACK_STATIC static +#else +#define NSTACK_STATIC +#endif +#endif + +#include "compiling_check.h" + +#endif /*compile_config.h */ diff --git a/src/framework/common/include/compiling_check.h b/src/framework/common/include/compiling_check.h new file mode 100644 index 0000000..e4a7538 --- /dev/null +++ b/src/framework/common/include/compiling_check.h @@ -0,0 +1,106 @@ +/* +* +* 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 COMPILING_CHECK_H +#define COMPILING_CHECK_H + +/* protect the value of macro whose value impacts the version + * compatibility, can't be changed!!! */ +#define COMPAT_PROTECT(name, value) \ +static inline char value_of_##name##_equal_to() \ +{ \ + char __dummy1[(name) - (value)]; \ + char __dummy2[(value) - (name)]; \ + return __dummy1[-1] + __dummy2[-1]; \ +} + +/* check whether struct size is equal to a special value */ +#define SIZE_OF_TYPE_EQUAL_TO(type, size) \ +static inline char size_of_##type##_equal_to_##size() \ +{ \ + char __dummy1[sizeof(type) - size]; \ + char __dummy2[size - sizeof(type)]; \ + return __dummy1[-1] + __dummy2[-1]; \ +} + +/* check whether struct size is not equal to a special value */ +#define SIZE_OF_TYPE_UNEQUAL_TO(type, size) \ +static inline char size_of_##type##_unequal_to_##size() \ +{ \ + char __dummy1[0==(10/(sizeof(type)-size))]; \ + return __dummy1[-1]; \ +} + +/* check whether struct size is not larger than a special value */ +#define SIZE_OF_TYPE_NOT_LARGER_THAN(type, size) \ +static inline char size_of_##type##_not_larger_than_##size() \ +{ \ + char __dummy1[size - sizeof(type)]; \ + return __dummy1[-1]; \ +} + +/* check whether struct size + sizeof(void*) is not larger than a special value */ +/* reserve 8 bytes for 64 bits pointers */ +#define SIZE_OF_TYPE_PLUS8_NOT_LARGER_THAN(type, size) \ +static inline char size_of_##type##_not_larger_than_##size() \ +{ \ + char __dummy1[size - sizeof(type) - sizeof(void*)]; \ + return __dummy1[-1]; \ +} + +/* check whether struct size is not smaller than a special value */ +#define SIZE_OF_TYPE_NOT_SMALLER_THAN(type, size) \ +static inline char size_of_##type##_not_smaller_than_##size() \ +{ \ + char __dummy1[sizeof(type) - size]; \ + return __dummy1[-1]; \ +} + +/* check whether struct size is smaller than a special value */ +#define SIZE_OF_TYPE_SMALLER_THAN(type, size) \ + SIZE_OF_TYPE_NOT_LARGER_THAN(type, size) \ + SIZE_OF_TYPE_UNEQUAL_TO(type, size) + +/* check whether struct size is larger than a special value */ +#define SIZE_OF_TYPE_LARGER_THAN(type, size) \ + SIZE_OF_TYPE_NOT_SMALLER_THAN(type, size) \ + SIZE_OF_TYPE_UNEQUAL_TO(type, size) + +/* check whether struct size is smaller than a special value, version 2 */ +#define SIZE_OF_TYPE_SMALLER_THAN2(type, size) \ +static inline char size_of_##type##_smaller_than2_##size() \ +{ \ + char __dummy1[size - sizeof(type) - 1]; \ + return __dummy1[-1]; \ +} + +/* check whether struct size is larger than a special value, version 2 */ +#define SIZE_OF_TYPE_LARGER_THAN2(type, size) \ +static inline char size_of_##type##_larger_than2_##size() \ +{ \ + char __dummy1[sizeof(type) - size - 1]; \ + return __dummy1[-1]; \ +} + +/* check whether struct size is equal to an integer multiple of a special value */ +#define SIZE_OF_TYPE_IS_MULTIPLE_OF(type, size) \ +static inline char size_of_##type##_is_multiple_of_##size() \ +{ \ + char __dummy1[0 - (sizeof(type) % size)]; \ + return __dummy1[-1]; \ +} + +#endif /*compiling_check.h */ diff --git a/src/framework/common/include/ephlist.h b/src/framework/common/include/ephlist.h new file mode 100644 index 0000000..90491b0 --- /dev/null +++ b/src/framework/common/include/ephlist.h @@ -0,0 +1,199 @@ +/* +* +* 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 _EPHLIST_H_ +#define _EPHLIST_H_ + +#include +#include "types.h" +#include "common_mem_pal.h" +#include "common_mem_buf.h" +#include "common_pal_bitwide_adjust.h" +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +struct ep_hlist_node +{ + struct ep_hlist_node *next, **pprev; +}; + +struct ep_node_list +{ + struct ep_hlist_node *head; + struct ep_hlist_node *tail; +}; + +struct ep_hlist +{ + struct ep_hlist_node node; + struct ep_hlist_node *head; + struct ep_hlist_node *tail; +}; + +#define ep_hlist_entry(ptr, type, member) container_of(ptr, type, member) + +#define EP_HLIST_INIT_NODE(node) {\ + (node)->next = NULL;\ + (node)->pprev = NULL; \ + } + +#define EP_HLIST_INIT(ptr) {\ + EP_HLIST_INIT_NODE(&((ptr)->node)); \ + (ptr)->head = (struct ep_hlist_node*)ADDR_LTOSH_EXT(&((ptr)->node)); \ + (ptr)->tail = (struct ep_hlist_node*)ADDR_LTOSH_EXT(&((ptr)->node)); \ + } + +#define EP_HLIST_PREV(ptr) ((struct ep_hlist_node*)(ADDR_SHTOL((ptr)->pprev))) +/* list check may below zero check header, because if app crash before + do list->size++, it will lead problem */ +#define EP_HLIST_EMPTY(list) (NULL == ((struct ep_hlist_node*)ADDR_SHTOL((list)->head))->next) +#define EP_HLIST_NODE_LINKED(node) (!(!(node)->pprev)) + +static __inline void ep_hlist_del (struct ep_hlist *list, + struct ep_hlist_node *n); +static __inline void ep_hlist_add_tail (struct ep_hlist *list, + struct ep_hlist_node *node); + +/* + * list , n are local pointer, don't need to cast + */ +static __inline void +ep_hlist_del (struct ep_hlist *list, struct ep_hlist_node *n) +{ + if (!EP_HLIST_NODE_LINKED (n)) + return; + EP_HLIST_PREV (n)->next = n->next; + if (n->next) + { + ((struct ep_hlist_node *) ADDR_SHTOL (n->next))->pprev = n->pprev; + } + else + { + list->tail = (struct ep_hlist_node *) (n->pprev); + } + EP_HLIST_INIT_NODE (n); +} + +/** + * list, node are local pointer , don't need to case + */ +static __inline void +ep_hlist_add_tail (struct ep_hlist *list, struct ep_hlist_node *node) +{ + struct ep_hlist_node *tail = + (struct ep_hlist_node *) ADDR_SHTOL (list->tail); + EP_HLIST_INIT_NODE (node); + node->pprev = (struct ep_hlist_node **) ADDR_LTOSH_EXT (&tail->next); + tail->next = (struct ep_hlist_node *) ADDR_LTOSH_EXT (node); + list->tail = (struct ep_hlist_node *) ADDR_LTOSH_EXT (node); +} + +/*#########################################################*/ +struct list_node +{ + struct list_node *next; +}; + +struct ep_list +{ + struct list_node node; + struct list_node *head; +}; + +#define ep_list_entry(ptr, type, member) container_of(ptr, type, member) + +#define EP_LIST_INIT_NODE(node) {\ + (node)->next = NULL;\ + } + +#define EP_LIST_INIT(ptr) {\ + EP_LIST_INIT_NODE(&((ptr)->node)); \ + (ptr)->head = (struct list_node*)ADDR_LTOSH_EXT(&((ptr)->node)); \ + } + +#define EP_LIST_EMPTY(list) (NULL == ((struct list_node*)ADDR_SHTOL((list)->head))->next) + +static __inline void ep_list_del (struct ep_list *list, struct list_node *n); +static __inline void ep_list_add_tail (struct ep_list *list, + struct list_node *node); + +/* + * list , n are local pointer, don't need to cast + */ +static __inline void +ep_list_del (struct ep_list *list, struct list_node *n) +{ + if (NULL == n) + { + return; + } + + struct list_node *p_node; + struct list_node *p_prev = NULL; + p_node = ((struct list_node *) ADDR_SHTOL (list->head)); + while (NULL != p_node && p_node != n) + { + p_prev = p_node; + p_node = ((struct list_node *) ADDR_SHTOL (p_node->next)); + } + + if (p_node != n || p_prev == NULL) + { + return; + } + + p_prev->next = n->next; + + EP_LIST_INIT_NODE (n); + return; +} + +/** + * list, node are local pointer , don't need to case + */ +static __inline void +ep_list_add_tail (struct ep_list *list, struct list_node *node) +{ + + struct list_node *p_node; + struct list_node *p_prev = NULL; + p_node = ((struct list_node *) ADDR_SHTOL (list->head)); + while (NULL != p_node) + { + p_prev = p_node; + p_node = ((struct list_node *) ADDR_SHTOL (p_node->next)); + } + + if (NULL == p_prev) + { + return; + } + + EP_LIST_INIT_NODE (node); + p_prev->next = (struct list_node *) ADDR_LTOSH_EXT (node); + return; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /* _HLIST_H_ */ diff --git a/src/framework/common/include/eprb_tree.h b/src/framework/common/include/eprb_tree.h new file mode 100644 index 0000000..558ab2d --- /dev/null +++ b/src/framework/common/include/eprb_tree.h @@ -0,0 +1,84 @@ +/* +* +* 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 _EPRB_TREE_H_ +#define _EPRB_TREE_H_ + +#include +#include +#include "types.h" +#include "common_mem_pal.h" +#include "common_mem_buf.h" +#include "common_pal_bitwide_adjust.h" +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define EP_RB_RED 0 +#define EP_RB_BLACK 1 + +struct ep_rb_node +{ + int color; + + struct ep_rb_node *rb_parent; + struct ep_rb_node *rb_right; + struct ep_rb_node *rb_left; +}; + +/* The alignment might seem pointless, but allegedly CRIS needs it */ + +struct ep_rb_root +{ + struct ep_rb_node *rb_node; +}; + +#define ep_rb_parent(r) ((struct ep_rb_node *)((r)->rb_parent)) + +static inline void +ep_rb_set_parent (struct ep_rb_node *rb, struct ep_rb_node *p) +{ + rb->rb_parent = (struct ep_rb_node *) ADDR_LTOSH_EXT (p); +} + +#define ep_rb_entry(ptr, type, member) container_of(ptr, type, member) + +extern void ep_rb_insert_color (struct ep_rb_node *, struct ep_rb_root *); +extern void ep_rb_erase (struct ep_rb_node *, struct ep_rb_root *); +struct ep_rb_node *ep_rb_first (const struct ep_rb_root *); + +static inline void +ep_rb_link_node (struct ep_rb_node *node, + struct ep_rb_node *parent, struct ep_rb_node **rb_link) +{ + + node->rb_parent = (struct ep_rb_node *) ADDR_LTOSH_EXT (parent); + node->rb_left = node->rb_right = NULL; + + *rb_link = (struct ep_rb_node *) ADDR_LTOSH_EXT (node); + node->color = EP_RB_RED; + +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/src/framework/common/include/list.h b/src/framework/common/include/list.h new file mode 100644 index 0000000..01860bc --- /dev/null +++ b/src/framework/common/include/list.h @@ -0,0 +1,181 @@ +/* +* +* 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 LIST_H_ +#define LIST_H_ + +#include +#include +#include +#include + +#include "types.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +struct list_head +{ + union + { + struct list_head *next; + }; + + union + { + struct list_head *prev; + }; +}; + +struct hlist_node +{ + /** + * @pprev: point the previous node's next pointer + */ + union + { + struct hlist_node *next; + }; + + union + { + struct hlist_node **pprev; + }; +}; + +struct hlist_head +{ + struct hlist_node *first; +}; + +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +#define list_for_each_entry_type(tpos, typeof_tpos,pos, head, member) \ + for (pos = ((head)->next); \ + pos && pos != (head) && ({tpos = list_entry(pos, typeof_tpos, member); 1;}); \ + pos = ((pos)->next)) + +#define LINT_LIST() + +#define list_for_each_entry(tpos, pos, head, member) \ + for (pos = ((head)->next); \ + pos && pos != (head) && ({tpos = list_entry(pos, typeof(*tpos), member); 1;}); \ + pos = ((pos)->next)) + +#define list_for_each_entry_list_head(tpos, pos, head, member) \ + for (pos = (struct list_head *)((head)->next); \ + pos && pos != (struct list_head *)(head) && ({tpos = list_entry(pos, typeof(*tpos), member); 1;}); \ + pos = (pos)->next) +#define list_for_each_safe_entry(tpos, pos, n, head, member) \ + for (pos = (head)->next,n = pos->next; \ + pos && pos != (head) && ({tpos = list_entry(pos, typeof(*tpos), member); 1;}); \ + pos = n,n = (pos)->next) + +#define INIT_LIST_HEAD(list) {(list)->next = (list); (list)->prev = (list);} + +/* + * @head: the list to test. + */ +inline void list_add (struct list_head *newp, struct list_head *head); +inline void list_link (struct list_head *newhead, struct list_head *head); +inline void list_add_tail (struct list_head *newp, struct list_head *head); +inline int list_empty (const struct list_head *head); +inline void list_del (struct list_head *entry); +inline struct list_head *list_get_first (struct list_head *head); +inline void hlist_del_init (struct hlist_node *n); + +struct hlist_tail +{ + struct hlist_node *end; +}; + +struct hlist_ctl +{ + struct hlist_head head; + struct hlist_tail tail; +}; +#define INIT_HLIST_CTRL(ptr) {(ptr)->head.first = NULL; (ptr)->tail.end = NULL;} + +inline int hlist_empty (const struct hlist_head *h); +inline void hlist_add_head (struct hlist_node *n, struct hlist_head *h); + +#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) +#define INIT_HLIST_NODE(ptr) {(ptr)->next = NULL; (ptr)->pprev = NULL;} +#define hlist_entry(ptr, type, member) \ + container_of(ptr, type, member) + +/*** + * hlist_for_each_entry - iterate over list of given type + * @member: the name of the hlist_node within the struct. + * @head: the head for your list. + * @pos: the &struct hlist_node to use as a loop cursor. + * @tpos: the type * to use as a loop cursor. + */ +#define hlist_for_each_entry(tpos, pos, head, member) \ + for (pos = (head)->first; \ + pos && ({tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = pos->next) + +/** + * hlist_for_each_entry_type - iterate over list of given type + * @member: the name of the hlist_node within the struct. + * @head: the head for your list. + * @pos: the &struct hlist_node to use as a loop cursor. + * @tpos: the type * to use as a loop cursor. + */ +#define hlist_for_each_entry_type(tpos, typeof_tpos,pos, head, member) \ + for (pos = (head)->first; \ + pos && ({tpos = hlist_entry(pos, typeof_tpos, member); 1;}); \ + pos = pos->next) + +inline void hlist_del_init (struct hlist_node *n); + +/** + * next must be != NULL + * add n node before next node + * + * @n: new node + * @next: node in the hlist + */ +inline void hlist_add_before (struct hlist_node *n, struct hlist_node *next); + +/** + * next must be != NULL + * add n node after next node + * actual behavior is add after n + * @n: node in the hlist + * @next: new node + */ +inline void hlist_add_after (struct hlist_node *n, struct hlist_node *next); + +/* add after the head */ +inline void hlist_add_head (struct hlist_node *n, struct hlist_head *h); + +inline int hlist_unhashed (const struct hlist_node *h); + +inline int hlist_empty (const struct hlist_head *h); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +}; +/* *INDENT-ON* */ +#endif + +#endif /* HASH_H_ */ diff --git a/src/framework/common/include/pidinfo.h b/src/framework/common/include/pidinfo.h new file mode 100644 index 0000000..7438756 --- /dev/null +++ b/src/framework/common/include/pidinfo.h @@ -0,0 +1,48 @@ +/* +* +* 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 _PIDINFO_H_ +#define _PIDINFO_H_ + +#include "types.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define NSFW_MAX_FORK_NUM 32 +typedef struct +{ + u32 used_size; + u32 apid[NSFW_MAX_FORK_NUM]; +} nsfw_pidinfo; + +inline i32 nsfw_pidinfo_init (nsfw_pidinfo * pidinfo); +inline int nsfw_add_pid (nsfw_pidinfo * pidinfo, u32 pid); +inline int nsfw_del_pid (nsfw_pidinfo * pidinfo, u32 pid); +inline int nsfw_del_last_pid (nsfw_pidinfo * pidinfo, u32 pid); +inline int nsfw_pid_exist (nsfw_pidinfo * pidinfo, u32 pid); +inline int nsfw_pidinfo_empty (nsfw_pidinfo * pidinfo); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +}; +/* *INDENT-ON* */ +#endif + +#endif /* _PIDINFO_H_ */ diff --git a/src/framework/common/include/sha256.h b/src/framework/common/include/sha256.h new file mode 100644 index 0000000..b1c7f3c --- /dev/null +++ b/src/framework/common/include/sha256.h @@ -0,0 +1,94 @@ +/* +* +* 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 _SHA256_H_ +#define _SHA256_H_ +#include "types.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/* Note that the following function prototypes are the same */ +/* for both the bit and byte oriented implementations. But */ +/* the length fields are in bytes or bits as is appropriate */ +/* for the version used. Bit sequences are arrays of bytes */ +/* in which bit sequence indexes increase from the most to */ +/* the least significant end of each byte */ + +#define SHA256_DIGEST_SIZE 32 /* in bytes */ +#define SHA256_BLOCK_SIZE 64 /* in bytes */ + +typedef struct +{ + u32 count[2]; + u32 hash[8]; + u32 wbuf[16]; +} SHA256_CTX; + +/* SHA256 hash data in an array of bytes into hash buffer */ +/* and call the hash_compile function as required. */ + +/*===========================================================================*\ + Function :Sha256_upd + Description : + Calls : + Called by : + Return :void - + Parameters : + SHA256_CTX ctx[1] - + const unsigned char data[] - + size_t len - + Note : +\*===========================================================================*/ +void Sha256_upd (SHA256_CTX ctx[1], const u8 data[], size_t len); + +/* SHA256 Final padding and digest calculation */ + +/*===========================================================================*\ + Function :Sha256_set + Description : + Calls : + Called by : + Return :void - + Parameters : + SHA256_CTX ctx[1] - + Note : +\*===========================================================================*/ +void Sha256_set (SHA256_CTX ctx[1]); + +/*===========================================================================*\ + Function :Sha256_fin + Description : + Calls : + Called by : + Return :void - + Parameters : + SHA256_CTX ctx[1] - + unsigned char hval[] - + Note : +\*===========================================================================*/ +void Sha256_fin (SHA256_CTX ctx[1], u8 hval[]); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /* _SHA256_H_ */ diff --git a/src/framework/common/include/types.h b/src/framework/common/include/types.h new file mode 100644 index 0000000..c7d013c --- /dev/null +++ b/src/framework/common/include/types.h @@ -0,0 +1,97 @@ +/* +* +* 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 clib_types_h +#define clib_types_h +#include + +/* Standard CLIB types. */ + +/* Define signed and unsigned 8, 16, 32, and 64 bit types + and machine signed/unsigned word for all architectures. */ +typedef char i8; +typedef short i16; + +typedef unsigned char u8; +typedef unsigned short u16; + +typedef int i32; +typedef long long i64; + +typedef unsigned int u32; +typedef unsigned long long u64; + +#ifndef bool +#define bool int +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef true +#define true 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef false +#define false 0 +#endif + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#define container_of(ptr, type, member) ( \ + (type *)((char *)(ptr) - offsetof(type,member)) \ + ) + +#define PRIMARY_ADDR + +typedef struct _nsfw_res +{ + u8 alloc_flag; + u8 u8Reserve; + u16 chk_count; + u32 data; +} nsfw_res; + +static inline void +res_alloc (nsfw_res * res) +{ + res->alloc_flag = TRUE; + res->chk_count = 0; + res->u8Reserve = 0; +} + +static inline int +res_free (nsfw_res * res) +{ + if (TRUE != res->alloc_flag) + { + return -1; + } + res->chk_count = 0; + res->alloc_flag = FALSE; + return 0; +} + +#define NSFW_THREAD __thread + +#endif /*clib_types_h */ diff --git a/src/framework/common/mem_mgr/include/nsfw_mem_desc.h b/src/framework/common/mem_mgr/include/nsfw_mem_desc.h new file mode 100644 index 0000000..1e959d9 --- /dev/null +++ b/src/framework/common/mem_mgr/include/nsfw_mem_desc.h @@ -0,0 +1,172 @@ +/* +* +* 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 _NSFW_MEM_DESC_H +#define _NSFW_MEM_DESC_H +#include +#include +#include +#include "nsfw_mem_api.h" +#include "nsfw_mgr_com_api.h" +#include "nsfw_ring_data.h" + +#define NSFW_MEM_NOT_INIT (0) +#define NSFW_MEM_INIT_ERR (1) +#define NSFW_MEM_INIT_OK (2) + +#define NSFW_NAME_LENCHECK_RET(name, desc) \ + { \ + i32 inamelen = strlen(name); \ + if (inamelen >= NSFW_MEM_APPNAME_LENTH) \ + { \ + NSCOMM_LOGERR("name length check fail] desc=%s, name len=%d, expected max=%d", \ + #desc, inamelen, NSFW_MEM_APPNAME_LENTH); \ + return NSFW_MEM_ERR; \ + } \ + } + +#define NSFW_NAME_LENCHECK_RET_NULL(name, desc) \ + { \ + i32 inamelen = strlen(name); \ + if (inamelen >= NSFW_MEM_APPNAME_LENTH) \ + { \ + NSCOMM_LOGERR("name length check fail] desc=%s, name len=%d, expected max=%d", \ + #desc, inamelen, NSFW_MEM_APPNAME_LENTH); \ + return NULL; \ + } \ + } + +#define NSFW_MEM_PARA_CHECK_RET(handle, pdata, desc, num) {\ + if ((NULL == (handle)) || (NULL == (pdata)) || (num <= 0)\ + || (((struct nsfw_mem_ring*)(handle))->memtype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSCOMM_LOGERR("input para error] desc=%s,mhandle=%p, pdata=%p, inum=%d", desc, (handle), (pdata), num); \ + return 0; \ + } \ + } + +#define NSFW_MEM_ENQ_PARA_CHECK_RET(handle, desc) {\ + if ((NULL == (handle)) \ + || (((struct nsfw_mem_ring*)(handle))->memtype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSCOMM_LOGERR("input para error] desc=%s,mhandle=%p", desc, (handle)); \ + return 0; \ + } \ + } + +#define NSFW_MEM_NAME_CHECK_RET_ERR(pname, desc) {\ + if ((NULL == (pname)) || ((pname)->entype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSCOMM_LOGERR("input para error] desc=%s, pname=%p, mtype=%d", desc, pname, (pname) ? (pname)->entype:-1); \ + return NSFW_MEM_ERR; \ + } \ + } + +#define NSFW_MEM_NAME_CHECK_RET_NULL(pname, desc) {\ + if ((NULL == (pname)) || ((pname)->entype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSCOMM_LOGERR("input para error] desc=%s, pname=%p, mtype=%d", desc, pname, (pname) ? (pname)->entype:-1); \ + return NULL; \ + } \ + } + +#define NSFW_MEM_RING_CHECK_RET(pringinfo, pringhandle_array, iringnum) {\ + if ((NULL == pringinfo) || (NULL == pringhandle_array) || (pringinfo[0].stname.entype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSCOMM_LOGERR("input para error] pringinfo=%p, iringnum=%d, pringhandle_array=%p, mtype=%d", \ + pringinfo, iringnum, pringhandle_array, pringinfo ? pringinfo[0].stname.entype : (-1)); \ + return NSFW_MEM_ERR; \ + } \ + } + +#define NSFW_MEM_RINGV_CHECK_RET(pmpinfo, inum, pringhandle_array, iarray_num) { \ + if ((NULL == pmpinfo) || (NULL == pringhandle_array) \ + || (inum != iarray_num) || (inum <= 0) || (pmpinfo[0].stname.entype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSCOMM_LOGERR("input para error] pmpinfo=%p, inum=%d, pringhandle_array=%p, iarray_num=%d", \ + pmpinfo, inum, pringhandle_array, iarray_num, pmpinfo ? pmpinfo[0].stname.entype : (-1)); \ + return NSFW_MEM_ERR; \ + } \ + } + +#define NSFW_MEM_MBUF_CHECK_RET_ERR(mhandle, entype, desc) {\ + if ((NULL == mhandle) || (entype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSCOMM_LOGERR("input para error] desc=%s, mhandle=%p, mtype=%d", desc, mhandle, entype); \ + return NSFW_MEM_ERR; \ + } \ + } + +#define NSFW_MEM_MBUF_CHECK_RET_NULL(mhandle, entype, desc) {\ + if ((NULL == mhandle) || (entype >= NSFW_MEM_TYPEMAX)) \ + { \ + NSCOMM_LOGERR("input para error] desc=%s, mhandle=%p, mtype=%d", desc, mhandle, entype); \ + return NULL; \ + } \ + } + +/*memory access inferface define*/ +typedef struct +{ + i32 (*mem_ops_init) (nsfw_mem_para * para); + void (*mem_ops_destroy) (void); + mzone_handle (*mem_ops_zone_creae) (nsfw_mem_zone * pinfo); + i32 (*mem_ops_zone_createv) (nsfw_mem_zone * pmeminfo, i32 inum, + mzone_handle * paddr_array, i32 iarray_num); + mzone_handle (*mem_ops_zone_lookup) (nsfw_mem_name * pname); + i32 (*mem_ops_mzone_release) (nsfw_mem_name * pname); + mpool_handle (*mem_ops_mbfmp_create) (nsfw_mem_mbfpool * pbufinfo); + i32 (*mem_ops_mbfmp_createv) (nsfw_mem_mbfpool * pmbfname, i32 inum, + mpool_handle * phandle_array, + i32 iarray_num); + mbuf_handle (*mem_ops_mbf_alloc) (mpool_handle mhandle); + i32 (*mem_ops_mbf_free) (mbuf_handle mhandle); + mpool_handle (*mem_ops_mbfmp_lookup) (nsfw_mem_name * pmbfname); + i32 (*mem_ops_mbfmp_release) (nsfw_mem_name * pname); + mring_handle (*mem_ops_sp_create) (nsfw_mem_sppool * pmpinfo); + i32 (*mem_ops_sp_createv) (nsfw_mem_sppool * pmpinfo, i32 inum, + mring_handle * pringhandle_array, + i32 iarray_num); + i32 (*mem_ops_spring_create) (nsfw_mem_mring * prpoolinfo, + mring_handle * pringhandle_array, + i32 iringnum); + i32 (*mem_ops_sp_release) (nsfw_mem_name * pname); + mring_handle (*mem_ops_sp_lookup) (nsfw_mem_name * pname); + mring_handle (*mem_ops_ring_create) (nsfw_mem_mring * pringinfo); + mring_handle (*mem_ops_ring_lookup) (nsfw_mem_name * pname); + i32 (*mem_ops_ring_release) (nsfw_mem_name * pname); + ssize_t (*mem_ops_mem_statics) (void *handle, nsfw_mem_struct_type type); + i32 (*mem_ops_mbuf_recycle) (mpool_handle handle); + i32 (*mem_ops_sp_iterator) (mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv); + i32 (*mem_ops_mbuf_iterator) (mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv); +} nsfw_mem_ops; + +typedef struct +{ + nsfw_mem_type entype; + nsfw_mem_ops *stmemop; +} nsfw_mem_attr; + +typedef struct +{ + fw_poc_type enflag; /*app, nStackMain, Master */ +} nsfw_mem_localdata; + +extern nsfw_mem_attr g_nsfw_mem_ops[]; +extern i32 g_mem_type_num; +#endif diff --git a/src/framework/common/mem_mgr/include/nsfw_ring_data.h b/src/framework/common/mem_mgr/include/nsfw_ring_data.h new file mode 100644 index 0000000..99ec0ed --- /dev/null +++ b/src/framework/common/mem_mgr/include/nsfw_ring_data.h @@ -0,0 +1,95 @@ +/* +* +* 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 _NSFW_RING_DATA_H_ +#define _NSFW_RING_DATA_H_ + +#include +#include "types.h" +#include "common_mem_api.h" + +#define VALUE_LEN 40 + +/* +Ring Data has two part; Ver&Data +val is a pointer offset base on rte_perf_ring::Addrbase, this struct support 1TB, it's enough now; +future __int128 maybe used, this type can perfectly solve the version & address rang problem. +*/ +union RingData_U +{ + struct RingData_S + { + /* + value of data, indeed it's a pointer offset base on rte_perf_ring::Addrbase;40bit is enough for user space addr + ver must using 24bit, so val using 40bit; a CAS now just support 64bit; in future, we may using __int128,now __int128 not support well. + */ + volatile unsigned long long val:VALUE_LEN; + /* + version of data, using 16b store version flg is more suitable for Address save, but using 16b version is too short, it's value range is [0-65535]; + between two cpu schedule time (TM-SPACE) of one process/thread, other processes/threads do N times queue oper. if N > 65535, still have a chance of ABA. + if using a 24bit save version flg, if ABA happened, 16777216 times queue oper need done in one TM-SPACE, it's impossible for today cpu. + */ + volatile unsigned long long ver:(64 - VALUE_LEN); + } data_s; + u64 data_l; +}; + +/* + this high perf Ring rely on the init value of Ring Slot; + Ring Must init using PerfRingInit, Pool Must init using PerfPoolInit + + the addrbase is base addr for all element; now we support 1024G offset; + for nstack the Ring element is from hugepage, and the addr is in stack space. + + 1. not support a ring who's element space range bigger than 1024GB + [if one element from heep, one from stack, range will bigger than 1024GB, we not support] + 2. one more thing addr from mmap is in stack + 3. rte_perf_ring must create by rte_perf_ring_create/rte_perf_pool_create +*/ +struct nsfw_mem_ring +{ + u8 memtype; //shared, no shared + u8 ringflag; //scmp, scsp, mcsp,mcmp + u16 reserv; //reserv data + u32 size; //size of the Ring, must 2^n + u32 eltsize; //for sppool, it is the size of per buf, if is ring, eltsize is zero. + u32 mask; //mask of the Ring, used mask mod Head/Tail to get real pos, must 2^n-1 + void *Addrbase; /*Cause the Addr we support just 40b(1024G), we using a basAddr+offset to get the real addr; ring[x].data_s.val just store offset; + * not used when no shared mode + */ + volatile u32_t prodhflag; //for nshmem fork recover + volatile u32_t prodtflag; //for nshmem fork recover + volatile u32_t conshflag; //for nshmem fork recover + volatile u32_t constflag; //for nshmem fork recover + nsfw_res res_chk; + + struct + { + volatile u32 head; //Head of the Ring, used to indicat pos where to pull a val + volatile u32 tail; //for nshmem, shmem not used. + } prod; + struct + { + volatile u32 head; //for nshmem, shmem not used. + volatile u32 tail; //Tail of the Ring, used to indicat pos where to push a val + } cons; + u32 uireserv[4]; //reserved for update + union RingData_U ring[0]; //Value of Ring +}; + +#define PERFRING_ADDR_RANGE (0xFFFFFFFFFFL) + +#endif /*_NSFW_RING_DATA_H_*/ diff --git a/src/framework/common/mem_mgr/include/nsfw_ring_fun.h b/src/framework/common/mem_mgr/include/nsfw_ring_fun.h new file mode 100644 index 0000000..57a7bf3 --- /dev/null +++ b/src/framework/common/mem_mgr/include/nsfw_ring_fun.h @@ -0,0 +1,110 @@ +/* +* +* 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 _NSFW_RING_FUN_H_ +#define _NSFW_RING_FUN_H_ + +#include +#include "common_pal_bitwide_adjust.h" +#include "nsfw_mem_api.h" +#include "nsfw_ring_data.h" + +/* + for nstack I advise addrbase set to lowest of mmaped hugepage Addr. + to simple: + 1. ring element is from mmaped mem, set Addrbase to 0x7fffffffffff - 0xffffffffff is OK; + 1. ring element is from heap, set Addrbase to NULL is ok; +*/ +static inline void +nsfw_mem_ring_init (struct nsfw_mem_ring *ring, unsigned int size, + void *addrbase, unsigned char memtype, unsigned char flag) +{ + unsigned int loop = 0; + + if (!ring) + { + return; + } + + ring->prod.head = 0; + ring->prod.tail = 0; + ring->cons.head = 0; + ring->cons.tail = 0; + ring->size = size; + ring->eltsize = 0; + ring->mask = size - 1; + ring->memtype = memtype; + ring->ringflag = flag; + ring->prodtflag = ring->prodhflag = get_sys_pid (); + ring->conshflag = ring->constflag = get_sys_pid (); + /*if shmem, addrbase already changed to primary memory address */ + ring->Addrbase = addrbase; + ring->uireserv[0] = 0; + ring->uireserv[1] = 0; + ring->uireserv[2] = 0; + ring->uireserv[3] = 0; + + /*init Ring */ + for (loop = 0; loop < size; loop++) + { + /* + for a empty ring, version is the mapping head val - size + so the empty ring's ver is loop-size; + */ + ring->ring[loop].data_s.ver = (loop - size); + ring->ring[loop].data_s.val = 0; + } +} + +/* +another way to init Pool while no continuous space +1. init a empt rte_perf_ring +2. add element to PerRing. +*/ +static inline void +nsfw_mem_pool_head_init (struct nsfw_mem_ring *ring, unsigned int size, + unsigned int eltsize, void *addrbase, + nsfw_mem_type memtype, nsfw_mpool_type flag) +{ + ring->prod.head = size; + ring->prod.tail = size; + ring->cons.head = 0; + ring->cons.tail = 0; + ring->size = size; + ring->eltsize = eltsize; + ring->mask = size - 1; + ring->memtype = memtype; + ring->ringflag = flag; + ring->prodtflag = ring->prodhflag = get_sys_pid (); + ring->conshflag = ring->constflag = get_sys_pid (); + /*if shmem, addrbase already changed to primary memory address */ + ring->Addrbase = addrbase; + ring->uireserv[0] = 0; + ring->uireserv[1] = 0; + ring->uireserv[2] = 0; + ring->uireserv[3] = 0; + return; +} + +#define NSFW_RING_FLAG_CHECK_RET(handle, desc) {\ + if (((struct nsfw_mem_ring*)mhandle)->ringflag >= NSFW_MPOOL_TYPEMAX) \ + { \ + NSCOMM_LOGERR("invalid ring] desc=%s, ringflag=%d", desc, ((struct nsfw_mem_ring*)mhandle)->ringflag); \ + return 0; \ + } \ + } + +#endif /*_NSFW_RING_FUN_H_*/ diff --git a/src/framework/common/mem_mgr/nsfw_mem_api.c b/src/framework/common/mem_mgr/nsfw_mem_api.c new file mode 100644 index 0000000..b795921 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_mem_api.c @@ -0,0 +1,879 @@ +/* +* +* 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 +#include "nsfw_mem_desc.h" +#include "nstack_securec.h" + +#ifdef SYS_MEM_RES_STAT +#include "common_mem_ring.h" +#include "common_mem_mempool.h" +#endif + +#define MEM_OP_CALL_OK_RET(mtype, fun, para) { \ + if (g_nsfw_mem_ops[mtype].stmemop->fun) \ + { \ + return g_nsfw_mem_ops[mtype].stmemop->fun para; \ + } \ + } + +/***************************************************************************** +* Prototype : nsfw_mem_init +* Description : memory mgr module init +* Input : point to nstak_fwmem_para +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_init (void *para) +{ + nsfw_mem_para *ptempara = NULL; + i32 iret = NSFW_MEM_OK; + i32 icount = 0; + i32 iindex = 0; + + if (NULL == para) + { + NSCOMM_LOGERR ("ns mem init input error"); + return NSFW_MEM_ERR; + } + + ptempara = (nsfw_mem_para *) para; + + if (ptempara->enflag >= NSFW_PROC_MAX) + { + NSCOMM_LOGERR ("ns mem init input enflag invalid] enflag=%d", + ptempara->enflag); + return NSFW_MEM_ERR; + } + + NSCOMM_LOGINF ("ns mem init begin] enflag=%d, iargsnum=%d", + ptempara->enflag, ptempara->iargsnum); + + for (iindex = 0; iindex < ptempara->iargsnum; iindex++) + { + NSCOMM_LOGINF ("%s", ptempara->pargs[iindex]); + } + + for (icount = 0; icount < g_mem_type_num; icount++) + { + if ((NULL != g_nsfw_mem_ops[icount].stmemop) + && (NULL != g_nsfw_mem_ops[icount].stmemop->mem_ops_init)) + { + iret = g_nsfw_mem_ops[icount].stmemop->mem_ops_init (ptempara); + + if (NSFW_MEM_OK != iret) + { + NSCOMM_LOGERR ("mem init failed]index=%d, memtype=%d", icount, + g_nsfw_mem_ops[icount].entype); + break; + } + } + } + + /*if some module init fail, destory the moudles that success */ + if (icount < g_mem_type_num) + { + for (iindex = 0; iindex < icount; iindex++) + { + if (g_nsfw_mem_ops[icount].stmemop->mem_ops_destroy) + { + g_nsfw_mem_ops[icount].stmemop->mem_ops_destroy (); + } + } + + return NSFW_MEM_ERR; + } + + NSCOMM_LOGINF ("ns mem init end"); + return NSFW_MEM_OK; +} + +/***************************************************************************** +* Prototype : nsfw_mem_zone_create +* Description : create a block memory with name +* nsfw_mem_zone::stname +* nsfw_mem_zone::isize +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_zone* pinfo +* Output : None +* Return Value : mzone_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mzone_handle +nsfw_mem_zone_create (nsfw_mem_zone * pinfo) +{ + + if ((NULL == pinfo) || (pinfo->stname.entype >= NSFW_MEM_TYPEMAX)) + { + NSCOMM_LOGERR ("zone create input para error] pinfo=%p, mtype=%d", + pinfo, pinfo ? pinfo->stname.entype : (-1)); + return NULL; + } + + MEM_OP_CALL_OK_RET (pinfo->stname.entype, mem_ops_zone_creae, (pinfo)); + NSCOMM_LOGINF ("mem create fail] memtype=%d, name=%s, size=%zu", + pinfo->stname.entype, pinfo->stname.aname, pinfo->lenth); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_mem_zone_createv +* Description : create some memory blocks +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_zone* pmeminfo +* i32 inum +* mzone_handle* paddr_array +* i32 iarray_num +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_zone_createv (nsfw_mem_zone * pmeminfo, i32 inum, + mzone_handle * paddr_array, i32 iarray_num) +{ + if ((NULL == pmeminfo) || (NULL == paddr_array) + || (inum != iarray_num) || (inum <= 0) + || (pmeminfo[0].stname.entype >= NSFW_MEM_TYPEMAX)) + { + NSCOMM_LOGERR + ("input para error] pmeminfo=%p, inum=%d, paddr_array=%p, iarray_num=%d, mtype=%d", + pmeminfo, inum, paddr_array, iarray_num, + pmeminfo ? pmeminfo[0].stname.entype : (-1)); + return NSFW_MEM_ERR; + } + + MEM_OP_CALL_OK_RET (pmeminfo[0].stname.entype, mem_ops_zone_createv, + (pmeminfo, inum, paddr_array, iarray_num)); + NSCOMM_LOGINF ("mem create fail] memtype=%d", pmeminfo[0].stname.entype); + return NSFW_MEM_ERR; +} + +/***************************************************************************** +* Prototype : nsfw_mem_zone_lookup +* Description : look up a memory +* 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* 2. if the memory is shared, pname->enowner indicate that who create this memory. +* note : 1. when calling any shared memory create inferface, the name of memory end with _0 created by nStackMain, +* end with none created by nStackMaster, and end with _ created by other. +* 2. pname->enowner is available only when call look up shared memory. +* 3. if the roles of process is NSFW_PROC_MASTER but the memory was created by others, or pname->enowner is NSFW_PROC_NULL, +* the name must be full name. +* for examles if the memory was created by nStackMain and pname->enowner is NSFW_PROC_NULL, +* must add '_0' at the end of name, if the memory was created by app and the role of process is NSFW_PROC_MASTER, must add +* _(pid) at the end of name, nstack_123. +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : mzone_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mzone_handle +nsfw_mem_zone_lookup (nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_NULL (pname, "mem zone look up"); + MEM_OP_CALL_OK_RET (pname->entype, mem_ops_zone_lookup, (pname)); + NSCOMM_LOGERR ("mem lookup fail] memtype=%d, name=%s ", pname->entype, + pname->aname); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_mem_zone_release +* Description : release a memory +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_zone_release (nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_ERR (pname, "mem zone release"); + MEM_OP_CALL_OK_RET (pname->entype, mem_ops_mzone_release, (pname)); + NSCOMM_LOGERR ("mem release fail] memtype=%d, name=%s", pname->entype, + pname->aname); + return NSFW_MEM_ERR; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbfmp_create +* Description : create a mbuf pool +* Input : nsfw_mem_mbfpool* pbufinfo +* Output : None +* Return Value : mpool_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mpool_handle +nsfw_mem_mbfmp_create (nsfw_mem_mbfpool * pbufinfo) +{ + if ((NULL == pbufinfo) || (pbufinfo->stname.entype >= NSFW_MEM_TYPEMAX)) + { + NSCOMM_LOGERR ("input para error] pbufinfo=%p, mtype=%d", pbufinfo, + pbufinfo ? pbufinfo->stname.entype : (-1)); + return NULL; + } + + MEM_OP_CALL_OK_RET (pbufinfo->stname.entype, mem_ops_mbfmp_create, + (pbufinfo)); + NSCOMM_LOGERR ("mbufmp create fail] memtype=%d, name=%s ", + pbufinfo->stname.entype, pbufinfo->stname.aname); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbfmp_createv +* Description : create some mbuf pools +* 1. the name of lenth must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_mbfpool* pmbfname +* i32 inum +* mpool_handle* phandle_array +* i32 iarray_num +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_mbfmp_createv (nsfw_mem_mbfpool * pmbfname, i32 inum, + mpool_handle * phandle_array, i32 iarray_num) +{ + if ((NULL == pmbfname) || (NULL == phandle_array) + || (inum != iarray_num) || (inum <= 0) + || (pmbfname[0].stname.entype >= NSFW_MEM_TYPEMAX)) + { + NSCOMM_LOGERR + ("input para error] pmbfname=%p, inum=%d, phandle_array=%p, iarray_num=%d", + pmbfname, inum, phandle_array, iarray_num, + pmbfname ? pmbfname[0].stname.entype : (-1)); + return NSFW_MEM_ERR; + } + + MEM_OP_CALL_OK_RET (pmbfname[0].stname.entype, mem_ops_mbfmp_createv, + (pmbfname, inum, phandle_array, iarray_num)); + NSCOMM_LOGERR ("mbufmp createv fail] memtype=%d", + pmbfname[0].stname.entype); + return NSFW_MEM_ERR; +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbf_alloc +* Description : alloc a mbuf from mbuf pool +* Input : mpool_handle mhandle +* nsfw_mem_type entype +* Output : None +* Return Value : mbuf_handle +* Calls : +* Called By : +*****************************************************************************/ +mbuf_handle +nsfw_mem_mbf_alloc (mpool_handle mhandle, nsfw_mem_type entype) +{ + NSFW_MEM_MBUF_CHECK_RET_NULL (mhandle, entype, "mbf alloc"); + MEM_OP_CALL_OK_RET (entype, mem_ops_mbf_alloc, (mhandle)); + NSCOMM_LOGERR ("mbf alloc fail] handle=%p, type=%d", mhandle, entype); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbf_free +* Description : put a mbuf backintp mbuf pool +* Input : mbuf_handle mhandle +* nsfw_mem_type entype +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_mbf_free (mbuf_handle mhandle, nsfw_mem_type entype) +{ + NSFW_MEM_MBUF_CHECK_RET_ERR (mhandle, entype, "mbuf free"); + MEM_OP_CALL_OK_RET (entype, mem_ops_mbf_free, (mhandle)); + NSCOMM_LOGERR ("mbf free fail] handle=%p, type=%d", mhandle, entype); + return NSFW_MEM_ERR; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbfmp_lookup +* Description : look up mbuf mpool +* 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* 2. if the memory is shared, pname->enowner indicate that who create this memory. +* note : 1. when calling any shared memory create inferface, the name of memory end with _0 created by nStackMain, +* end with none created by nStackMaster, and end with _ created by other. +* 2. pname->enowner is available only when call look up shared memory. +* 3. if the roles of process is NSFW_PROC_MASTER but the memory was created by others, or pname->enowner is NSFW_PROC_NULL, +* the name must be full name. +* for examles if the memory was created by nStackMain and pname->enowner is NSFW_PROC_NULL, +* must add '_0' at the end of name, if the memory was created by app and the role of process is NSFW_PROC_MASTER, must add +* _(pid) at the end of name, nstack_123. +* Input : nsfw_mem_name* pmbfname +* Output : None +* Return Value : mpool_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mpool_handle +nsfw_mem_mbfmp_lookup (nsfw_mem_name * pmbfname) +{ + NSFW_MEM_NAME_CHECK_RET_NULL (pmbfname, "mbuf pool look up"); + MEM_OP_CALL_OK_RET (pmbfname->entype, mem_ops_mbfmp_lookup, (pmbfname)); + NSCOMM_LOGERR ("mbufmp lookup fail] memtype=%d, name=%s ", pmbfname->entype, + pmbfname->aname); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbfmp_release +* Description : release mbuf pool +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_mbfmp_release (nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_ERR (pname, "mbuf mp release"); + MEM_OP_CALL_OK_RET (pname->entype, mem_ops_mbfmp_release, (pname)); + NSCOMM_LOGERR ("mbfmp release fail] memtype=%d, name=%s", pname->entype, + pname->aname); + return NSFW_MEM_ERR; +} + +/***************************************************************************** +* Prototype : nsfw_mem_sp_create +* Description : create a simple pool +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_sppool* pmpinfo +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mring_handle +nsfw_mem_sp_create (nsfw_mem_sppool * pmpinfo) +{ + if ((NULL == pmpinfo) || (pmpinfo->stname.entype >= NSFW_MEM_TYPEMAX)) + { + NSCOMM_LOGERR ("input para error] pmpinfo=%p, mtype=%d", pmpinfo, + pmpinfo ? pmpinfo->stname.entype : (-1)); + return NULL; + } + + MEM_OP_CALL_OK_RET (pmpinfo->stname.entype, mem_ops_sp_create, (pmpinfo)); + NSCOMM_LOGERR ("sp create fail] memtype=%d, name=%s ", + pmpinfo->stname.entype, pmpinfo->stname.aname); + return NULL; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_sp_createv +* Description : create some simple pools one time +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_sppool* pmpinfo +* i32 inum +* mring_handle* pringhandle_array +* i32 iarray_num +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_sp_createv (nsfw_mem_sppool * pmpinfo, i32 inum, + mring_handle * pringhandle_array, i32 iarray_num) +{ + NSFW_MEM_RINGV_CHECK_RET (pmpinfo, inum, pringhandle_array, iarray_num); + MEM_OP_CALL_OK_RET (pmpinfo[0].stname.entype, mem_ops_sp_createv, + (pmpinfo, inum, pringhandle_array, iarray_num)); + NSCOMM_LOGERR ("sp createv fail] memtype=%d", pmpinfo[0].stname.entype); + return NSFW_MEM_ERR; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_sp_ring_create +* Description : create a simple pool with many rings +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_mring* pringinfo +* mring_handle* pringhandle_array +* i32 iringnum +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_sp_ring_create (nsfw_mem_mring * pringinfo, + mring_handle * pringhandle_array, i32 iringnum) +{ + NSFW_MEM_RING_CHECK_RET (pringinfo, pringhandle_array, iringnum); + MEM_OP_CALL_OK_RET (pringinfo[0].stname.entype, mem_ops_spring_create, + (pringinfo, pringhandle_array, iringnum)); + NSCOMM_LOGERR ("mppool spring creat fail] memtype=%d", + pringinfo[0].stname.entype); + return NSFW_MEM_ERR; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_sp_release +* Description : release a simple mempool +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_mem_sp_release (nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_ERR (pname, "sp release"); + MEM_OP_CALL_OK_RET (pname->entype, mem_ops_sp_release, (pname)); + NSCOMM_LOGERR ("sp release fail] memtype=%d, name=%s ", pname->entype, + pname->aname); + return NSFW_MEM_ERR; +} + +/***************************************************************************** +* Prototype : nsfw_mem_sp_lookup +* Description : look up a simpile ring +* 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* 2. if the memory is shared, pname->enowner indicate that who create this memory. +* note : 1. when calling any shared memory create inferface, the name of memory end with _0 created by nStackMain, +* end with none created by nStackMaster, and end with _ created by other. +* 2. pname->enowner is available only when call look up shared memory. +* 3. if the roles of process is NSFW_PROC_MASTER but the memory was created by others, or pname->enowner is NSFW_PROC_NULL, +* the name must be full name. +* for examles if the memory was created by nStackMain and pname->enowner is NSFW_PROC_NULL, +* must add '_0' at the end of name, if the memory was created by app and the role of process is NSFW_PROC_MASTER, must add +* _(pid) at the end of name, nstack_123. +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mring_handle +nsfw_mem_sp_lookup (nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_NULL (pname, "sp look up"); + MEM_OP_CALL_OK_RET (pname->entype, mem_ops_sp_lookup, (pname)); + NSCOMM_LOGERR ("sp lookup fail] memtype=%d, name=%s", pname->entype, + pname->aname); + return NULL; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_create +* Description : create a ring +* note : 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* 2. shared memory ring (NSFW_SHMEM) just can put a pointor into the queue, the queue also point to a shared block memory. +* no shared memory ring(NSFW_NSHMEM) is other wise. +* Input : nsfw_mem_mring* pringinfo +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mring_handle +nsfw_mem_ring_create (nsfw_mem_mring * pringinfo) +{ + if ((NULL == pringinfo) || (pringinfo->stname.entype >= NSFW_MEM_TYPEMAX)) + { + NSCOMM_LOGERR ("input para error] pmpinfo=%p, mtype=%d", pringinfo, + pringinfo ? pringinfo->stname.entype : (-1)); + return NULL; + } + + MEM_OP_CALL_OK_RET (pringinfo->stname.entype, mem_ops_ring_create, + (pringinfo)); + NSCOMM_LOGERR ("ring create fail] memtype=%d, name=%s ", + pringinfo->stname.entype, pringinfo->stname.aname); + return NULL; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_lookup +* Description : look up a ring by name +* 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. +* 2. if the memory is shared, pname->enowner indicate that who create this memory. +* note: +* 1. when calling any shared memory create inferface, the name of memory end with _0 created by nStackMain, +* end with none created by nStackMaster, and end with _ created by other. +* 2. pname->enowner is available only when call look up shared memory. +* 3. if the roles of process is NSFW_PROC_MASTER but the memory was created by others, or pname->enowner is NSFW_PROC_NULL, +* the name must be full name. +* for examles if the memory was created by nStackMain and pname->enowner is NSFW_PROC_NULL, +* must add '_0' at the end of name, if the memory was created by app and the role of process is NSFW_PROC_MASTER, must add +* _(pid) at the end of name, nstack_123. +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +* +* +*****************************************************************************/ +mring_handle +nsfw_mem_ring_lookup (nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_NULL (pname, "ring lookup"); + MEM_OP_CALL_OK_RET (pname->entype, mem_ops_ring_lookup, (pname)); + NSCOMM_LOGERR ("ring lookup fail] memtype=%d, name=%s", pname->entype, + pname->aname); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_reset +* Description : reset the number of producer and consumer, also, the +* state of ring reset to empty +* notes : must be called before doing any operations base on the ring +* Input : mring_handle mhandle +* nsfw_mpool_type entype +* Output : None +* Return Value : void +* Calls : +* Called By : +* +*****************************************************************************/ +void +nsfw_mem_ring_reset (mring_handle mhandle, nsfw_mpool_type entype) +{ + u32 loop = 0; + struct nsfw_mem_ring *ring = (struct nsfw_mem_ring *) mhandle; + + if (!ring) + { + return; + } + + ring->prod.head = 0; + ring->cons.tail = 0; + ring->ringflag = (u8) entype; + + /*init Ring */ + for (loop = 0; loop < ring->size; loop++) + { + /* + for a empty ring, version is the mapping head val - size + so the empty ring's ver is loop-size; + */ + ring->ring[loop].data_s.ver = (loop - ring->size); + ring->ring[loop].data_s.val = 0; + } + + return; +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_free_count +* Description : get the free number of ring +* Input : mring_handle mhandle +* Output : None +* Return Value : u32 +* Calls : +* Called By : +* +*****************************************************************************/ +u32 +nsfw_mem_ring_free_count (mring_handle mhandle) +{ + struct nsfw_mem_ring *temp = NULL; + u32 thead = 0; + u32 ttail = 0; + if (NULL == mhandle) + { + NSCOMM_LOGERR ("input para error] mhandle=%p", mhandle); + return 0; + } + + temp = (struct nsfw_mem_ring *) mhandle; + thead = temp->prod.head; + ttail = temp->cons.tail; + return ttail + temp->size - thead; +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_using_count +* Description : get the in using number of ring +* Input : mring_handle mhandle +* Output : None +* Return Value : u32 +* Calls : +* Called By : +* +*****************************************************************************/ +u32 +nsfw_mem_ring_using_count (mring_handle mhandle) +{ + struct nsfw_mem_ring *temp = NULL; + u32 thead = 0; + u32 ttail = 0; + if (NULL == mhandle) + { + NSCOMM_LOGERR ("input para error] mhandle=%p", mhandle); + return 0; + } + + temp = (struct nsfw_mem_ring *) mhandle; + thead = temp->prod.head; + ttail = temp->cons.tail; + return thead - ttail; +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_size +* Description : get size of ring +* Input : mring_handle mhandle +* Output : None +* Return Value : u32 +* Calls : +* Called By : +*****************************************************************************/ +u32 +nsfw_mem_ring_size (mring_handle mhandle) +{ + struct nsfw_mem_ring *temp = NULL; + + if (NULL == mhandle) + { + NSCOMM_LOGERR ("input para error] mhandle=%p", mhandle); + return 0; + } + + temp = (struct nsfw_mem_ring *) mhandle; + + return temp->size; +} + +#ifdef SYS_MEM_RES_STAT +/***************************************************************************** +* Prototype : nsfw_mem_mbfpool_free_count +* Description : get the free mbuf count of a mbuf pool +* Input : mpool_handle mhandle +* Output : None +* Return Value : u32 +* Calls : +* Called By : +* +*****************************************************************************/ +u32 +nsfw_mem_mbfpool_free_count (mpool_handle mhandle) +{ + if (!mhandle) + { + NSCOMM_LOGERR ("input para error] mhandle=%p", mhandle); + return 0; + } + struct common_mem_mempool *mp = (struct common_mem_mempool *) mhandle; + struct common_mem_ring *mp_ring = + (struct common_mem_ring *) (mp->ring_align); + if (!mp_ring) + { + NSCOMM_LOGERR ("ring is null"); + return 0; + } + u32 p_head = mp_ring->prod.head; + u32 c_tail = mp_ring->cons.tail; + + return p_head - c_tail; +} +#endif /* SYS_MEM_RES_STAT */ + +/***************************************************************************** +* Prototype : nsfw_mem_ring_release +* Description : release a ring memory +* notes : the lenth of name must be less than NSFW_MEM_APPNAME_LENTH +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_mem_ring_release (nsfw_mem_name * pname) +{ + NSFW_MEM_NAME_CHECK_RET_ERR (pname, "ring release"); + MEM_OP_CALL_OK_RET (pname->entype, mem_ops_ring_release, (pname)); + NSCOMM_LOGERR ("ring release fail] name=%s, type=%d", pname->aname, + pname->entype); + return NSFW_MEM_ERR; + +} + +/***************************************************************************** +* Prototype : nsfw_mem_get_len +* Description : statics mbufpool, sppool, ring mem size. +* return: <=0, err happen, >0 mem size +* NSFW_MEM_MZONE: not surport because you already know the lenth when create +* Input : void * handle +* nsfw_mem_struct_type type +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +*****************************************************************************/ +ssize_t +nsfw_mem_get_len (void *handle, nsfw_mem_struct_type type) +{ + if (NULL == handle) + { + NSCOMM_LOGERR ("input para error] handle=%p", handle); + return -1; + } + if ((NSFW_MEM_SPOOL == type) || (NSFW_MEM_RING == type)) + { + struct nsfw_mem_ring *ring = (struct nsfw_mem_ring *) handle; + if (ring->memtype >= NSFW_MEM_TYPEMAX) + { + NSCOMM_LOGERR ("invalid ring] ring type=%u ,handle=%p", + ring->memtype, handle); + return -1; + } + MEM_OP_CALL_OK_RET (ring->memtype, mem_ops_mem_statics, (handle, type)); + } + else + { + MEM_OP_CALL_OK_RET (NSFW_SHMEM, mem_ops_mem_statics, (handle, type)); + } + return -1; +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbuf_pool_recycle +* Description : recycle mbuf +* Input : mpool_handle handle +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_mem_mbuf_pool_recycle (mpool_handle handle) +{ + MEM_OP_CALL_OK_RET (NSFW_SHMEM, mem_ops_mbuf_recycle, (handle)); + return -1; +} + +/***************************************************************************** +* Prototype : nsfw_mem_sp_iterator +* Description : spool iterator +* Input : mpool_handle handle +* u32 start +* u32 end +* nsfw_mem_item_fun fun +* void *argv +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_sp_iterator (mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv) +{ + MEM_OP_CALL_OK_RET (NSFW_SHMEM, mem_ops_sp_iterator, + (handle, start, end, fun, argv)); + return -1; +} + +/***************************************************************************** +* Prototype : nsfw_mem_mbuf_iterator +* Description : mbuf iterator +* Input : mpool_handle handle +* u32 start +* u32 end +* nsfw_mem_item_fun fun +* void *argv +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_mem_mbuf_iterator (mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv) +{ + MEM_OP_CALL_OK_RET (NSFW_SHMEM, mem_ops_mbuf_iterator, + (handle, start, end, fun, argv)); + return -1; +} + +/***************************************************************************** +* Prototype : nsfw_mem_dfx_ring_print +* Description : print ring info +* Input : mring_handle mhandle +* Output : None +* Return Value : if no err happen, return the lenth of string print, 0 or -1 maybe err happen +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_mem_dfx_ring_print (mring_handle mhandle, char *pbuf, int lenth) +{ + struct nsfw_mem_ring *temp = (struct nsfw_mem_ring *) mhandle; + u32 head = 0; + u32 tail = 0; + int ret = 0; + if ((!temp) || (!pbuf) || (lenth <= 0)) + { + return 0; + } + head = temp->prod.head; + tail = temp->cons.tail; + ret = + SPRINTF_S (pbuf, lenth, + "[.Head=%u,\n .Tail=%u,\n .(|Tail-Head|)=%u,\n .size=%u,\n .mask=%u]\n", + head, tail, (tail >= head) ? (tail - head) : (head - tail), + temp->size, temp->mask); + return ret; +} diff --git a/src/framework/common/mem_mgr/nsfw_mem_construct.c b/src/framework/common/mem_mgr/nsfw_mem_construct.c new file mode 100644 index 0000000..ed6fe27 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_mem_construct.c @@ -0,0 +1,21 @@ +/* +* +* 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 "nsfw_init.h" +#include "nsfw_mem_api.h" + +NSFW_MODULE_NAME (NSFW_MEM_MGR_MODULE) +NSFW_MODULE_PRIORITY (10) NSFW_MODULE_INIT (nsfw_mem_init) diff --git a/src/framework/common/mem_mgr/nsfw_mem_desc.c b/src/framework/common/mem_mgr/nsfw_mem_desc.c new file mode 100644 index 0000000..d0fbfd3 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_mem_desc.c @@ -0,0 +1,92 @@ +/* +* +* 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 +#include "nsfw_mem_desc.h" +#include "nsfw_shmem_mdesc.h" +#include "nsfw_nshmem_mdesc.h" +#include "nsfw_shmem_ring.h" +#include "nsfw_nshmem_ring.h" + +/* *INDENT-OFF* */ +/*the order you add must be NSFW_SHMEM, NSFW_NSHMEM*/ +nsfw_mem_attr g_nsfw_mem_ops[] = +{ + {NSFW_SHMEM, &g_shmem_ops}, + {NSFW_NSHMEM, &g_nshmem_ops}, +}; + +i32 g_mem_type_num = sizeof(g_nsfw_mem_ops) / sizeof(nsfw_mem_attr); + + +nsfw_ring_ops g_ring_ops_arry[NSFW_MEM_TYPEMAX][NSFW_MPOOL_TYPEMAX] = { + { + { + (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_sp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_sc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_sc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_mp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_sc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_sc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_sp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_mc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_mc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_mp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_mc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_mc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_shmem_ring_singlethread_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_shmem_ring_singlethread_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_shmem_ring_singlethread_dequeuev + } + }, + { + { + (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_sp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_sc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_sc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_mp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_sc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_sc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_sp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_mc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_mc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_mp_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_mc_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_mc_dequeuev + }, + { + (nsfw_mem_ring_enqueue_fun)nsfw_nshmem_ring_singlethread_enqueue, \ + (nsfw_mem_ring_dequeue_fun)nsfw_nshmem_ring_singlethread_dequeue, \ + (nsfw_mem_ring_dequeuev_fun)nsfw_nshmem_ring_singlethread_dequeuev + } + } +}; +/* *INDENT-ON* */ diff --git a/src/framework/common/mem_mgr/nsfw_mem_stat.c b/src/framework/common/mem_mgr/nsfw_mem_stat.c new file mode 100644 index 0000000..f7a1f41 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_mem_stat.c @@ -0,0 +1,292 @@ +/* +* +* 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 "types.h" +#include "nstack_securec.h" +#include "nsfw_init.h" + +#include "nstack_log.h" +#include "nsfw_maintain_api.h" +#include "nsfw_mem_api.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#define NSFW_MEM_STAT_NUM 512 + +#define NSFW_MEM_STAT_MODULE "nsfw_mem_stat_module" + +typedef struct _nsfw_mem_stat +{ + u8 mem_type; + u8 alloc_flag; + char module[NSFW_MEM_MODULE_LEN]; + char mem_name[NSFW_MEM_NAME_LEN]; + u32 mem_size; +} nsfw_mem_stat_t; + +nsfw_mem_stat_t g_mem_stat[NSFW_MEM_STAT_NUM]; + +#ifdef SYS_MEM_RES_STAT +#define MAX_STAT_ITEM_NUM 20 +typedef struct _mem_stat_item_t +{ + char name[32]; + u64 size; +} mem_stat_item_t; + +typedef struct _mem_stat_mgr_t +{ + u32 item_num; + mem_stat_item_t item[MAX_STAT_ITEM_NUM]; +} mem_stat_mgr; + +mem_stat_mgr g_max_mem_list; +#endif + +/***************************************************************************** +* Prototype : nsfw_mem_stat +* Description : add memory stat +* Input : char *module +* char *mem_name +* u8 mem_type +* u32 mem_size +* Output : None +* Return Value : void +* Calls : +* Called By : +* +*****************************************************************************/ +void +nsfw_mem_stat (char *module, char *mem_name, u8 mem_type, u32 mem_size) +{ + if (NULL == module || NULL == mem_name) + { + NSFW_LOGERR ("argv err]module=%p,mem_name=%p", module, mem_name); + return; + } + + int i; + nsfw_mem_stat_t *mem_stat_item = NULL; + for (i = 0; i < NSFW_MEM_STAT_NUM; i++) + { + if (FALSE == g_mem_stat[i].alloc_flag) + { + g_mem_stat[i].alloc_flag = TRUE; + mem_stat_item = &g_mem_stat[i]; + break; + } + } + + if (NULL == mem_stat_item) + { + NSFW_LOGERR ("mem stat full]module=%s,type=%u,name=%s,size=%u", + module, mem_type, mem_name, mem_size); + return; + } + + mem_stat_item->mem_type = mem_type; + mem_stat_item->mem_size = mem_size; + + if (EOK != STRCPY_S (mem_stat_item->module, NSFW_MEM_MODULE_LEN, module)) + { + NSFW_LOGERR ("STRNCPY_S failed"); + return; + } + if (EOK != STRCPY_S (mem_stat_item->mem_name, NSFW_MEM_NAME_LEN, mem_name)) + { + NSFW_LOGERR ("STRNCPY_S failed"); + return; + } + + return; +} + +/***************************************************************************** +* Prototype : nsfw_mem_stat_print +* Description : print all memory info +* Input : None +* Output : None +* Return Value : void +* Calls : +* Called By : +* +*****************************************************************************/ +void +nsfw_mem_stat_print () +{ + int i; + for (i = 0; i < NSFW_MEM_STAT_NUM; i++) + { + if (TRUE == g_mem_stat[i].alloc_flag) + { + NSFW_LOGINF ("mem_module=%s,name=%s,type=%u,size=%u", + g_mem_stat[i].module, g_mem_stat[i].mem_name, + g_mem_stat[i].mem_type, g_mem_stat[i].mem_size); + } + } + +} + +#ifdef SYS_MEM_RES_STAT +void +clear_mem_stat_item () +{ + if (EOK != MEMSET_S ((char *) &g_max_mem_list, sizeof (mem_stat_mgr), + 0, sizeof (mem_stat_mgr))) + { + NSFW_LOGERR ("MEMSET_S failed"); + } +} + +void +insert_mem_stat_item (char *name, u64 len) +{ + int j, temp; + + if (g_max_mem_list.item_num == 0) + { + if (EOK != + STRCPY_S (g_max_mem_list.item[0].name, + sizeof (g_max_mem_list.item[0].name), name)) + { + NSFW_LOGERR ("STRCPY_S failed"); + } + g_max_mem_list.item[0].size = len; + g_max_mem_list.item_num++; + return; + } + else if (g_max_mem_list.item_num < MAX_STAT_ITEM_NUM) + { + if (len <= g_max_mem_list.item[g_max_mem_list.item_num - 1].size) + { + if (EOK != + STRCPY_S (g_max_mem_list.item[g_max_mem_list.item_num].name, + sizeof (g_max_mem_list.item + [g_max_mem_list.item_num].name), name)) + { + NSFW_LOGERR ("STRCPY_S failed"); + } + g_max_mem_list.item[g_max_mem_list.item_num].size = len; + g_max_mem_list.item_num++; + return; + } + j = 0; + temp = g_max_mem_list.item_num; + while (j < temp) + { + if (len >= g_max_mem_list.item[j].size) + { + goto insert_it; + } + j++; + } + if (j == temp) + { + if (EOK != + STRCPY_S (g_max_mem_list.item[j].name, + sizeof (g_max_mem_list.item[j].name), name)) + { + NSFW_LOGERR ("STRCPY_S failed"); + } + g_max_mem_list.item[j].size = len; + g_max_mem_list.item_num++; + return; + } + } + else + { + j = 0; + temp = MAX_STAT_ITEM_NUM - 1; + while (j < MAX_STAT_ITEM_NUM) + { + if (len >= g_max_mem_list.item[j].size) + { + goto insert_it; + } + j++; + } + } + + return; + +insert_it: + while (temp - 1 >= j) + { + if (EOK != + STRCPY_S (g_max_mem_list.item[temp].name, + sizeof (g_max_mem_list.item[temp].name), + g_max_mem_list.item[temp - 1].name)) + { + NSFW_LOGERR ("STRCPY_S failed"); + } + g_max_mem_list.item[temp].size = g_max_mem_list.item[temp - 1].size; + temp--; + } + if (EOK != + STRCPY_S (g_max_mem_list.item[j].name, + sizeof (g_max_mem_list.item[j].name), name)) + { + NSFW_LOGERR ("STRCPY_S failed"); + } + g_max_mem_list.item[j].size = len; + g_max_mem_list.item_num++; + return; +} + +int +get_mem_stat_item (int idx, char **name, u64 * len) +{ + if (idx < 0 || idx >= MAX_STAT_ITEM_NUM) + { + return -1; + } + + *name = g_max_mem_list.item[idx].name; + *len = g_max_mem_list.item[idx].size; + + return 0; +} +#endif + +static int nsfw_mem_stat_init (void *param); +static int +nsfw_mem_stat_init (void *param) +{ + MEM_STAT (NSFW_MEM_STAT_MODULE, "g_mem_stat", NSFW_NSHMEM, + sizeof (g_mem_stat)); + nsfw_mem_stat_print (); +#ifdef SYS_MEM_RES_STAT + clear_mem_stat_item (); +#endif + return 0; +} + +/* *INDENT-OFF* */ +NSFW_MODULE_NAME (NSFW_MEM_STAT_MODULE) +NSFW_MODULE_PRIORITY (99) +NSFW_MODULE_INIT (nsfw_mem_stat_init) +/* *INDENT-ON* */ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.c b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.c new file mode 100644 index 0000000..c78c27e --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.c @@ -0,0 +1,47 @@ +/* +* +* 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 "nsfw_mem_desc.h" +#include "nsfw_nshmem_mng.h" +#include "nsfw_nshmem_mdesc.h" + +/*no share memory access inferface*/ +nsfw_mem_ops g_nshmem_ops = { + nsfw_nshmem_init, + nsfw_nshmem_destory, + nsfw_nshmem_create, + NULL, + nsfw_nshmem_lookup, + nsfw_nshmem_release, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + nsfw_nshmem_spcreate, + NULL, + NULL, + nsfw_nshmem_sprelease, + nsfw_nshmem_sp_lookup, + nsfw_nshmem_ringcreate, + NULL, + nsfw_nshmem_ringrelease, + nsfw_nshmem_stactic, + NULL, + NULL, /*mem_ops_sp_iterator */ + NULL, /*mem_ops_mbuf_iterator */ +}; diff --git a/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.h b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.h new file mode 100644 index 0000000..1b63520 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mdesc.h @@ -0,0 +1,22 @@ +/* +* +* 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 _NSFW_NSHMEM_MDESC_H +#define _NSFW_NSHMEM_MDESC_H + +extern nsfw_mem_ops g_nshmem_ops; + +#endif diff --git a/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.c b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.c new file mode 100644 index 0000000..d5661fd --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.c @@ -0,0 +1,544 @@ +/* +* +* 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_log.h" +#include "nstack_securec.h" +#include "nsfw_mem_desc.h" +#include "nsfw_ring_fun.h" +#include "nsfw_nshmem_ring.h" +#include "nsfw_nshmem_mng.h" + +#include "common_func.h" + +#define nsfw_get_glb_lock() (&g_nshmem_internal_cfg->mlock) + +#define NSFW_NSHMEM_INIT_CHK_RET_NULL() \ + if ((!g_nshmem_internal_cfg) || (!g_nshmem_localdata)) \ + { \ + NSCOMM_LOGDBG("Error] g_nshmem_internal_cfg=%p, g_nshmem_localdata=%p", g_nshmem_internal_cfg, g_nshmem_localdata); \ + return NULL; \ + } + +#define NSFW_NSHMEM_INIT_CHK_RET() \ + if ((!g_nshmem_internal_cfg) || (!g_nshmem_localdata)) \ + { \ + NSCOMM_LOGDBG("Error] g_nshmem_internal_cfg=%p, g_nshmem_localdata=%p", g_nshmem_internal_cfg, g_nshmem_localdata); \ + return NSFW_MEM_ERR; \ + } + +nsfw_mem_localdata *g_nshmem_localdata = NULL; +nsfw_nshmem_cfg *g_nshmem_internal_cfg = NULL; + +/*look up a mem zone*/ +NSTACK_STATIC inline nsfw_nshmem_mzone * +nsfw_nshmem_get_free_zone (void) +{ + int icnt = 0; + + /*g_nshmem_internal_cfg must not be null if come here */ + for (icnt = 0; icnt < COMMON_MEM_MAX_MEMZONE; icnt++) + { + if (g_nshmem_internal_cfg->amemzone[icnt].addr == NULL) + { + return &g_nshmem_internal_cfg->amemzone[icnt]; + } + } + + return NULL; +} + +NSTACK_STATIC inline void +nsfw_nshmem_free_zone (nsfw_nshmem_mzone * pzone) +{ + nsfw_nshmem_mzone *pzonebase = &g_nshmem_internal_cfg->amemzone[0]; + nsfw_nshmem_mzone *pzoneend = + &g_nshmem_internal_cfg->amemzone[NSFW_NSHMEM_ZONE_MAX - 1]; + + if ((((int) ((char *) pzone - (char *) pzonebase) < 0) + || ((int) ((char *) pzone - (char *) pzoneend) > 0)) + && ((unsigned int) ((char *) pzone - (char *) pzonebase) % + sizeof (nsfw_nshmem_mzone) != 0)) + { + NSCOMM_LOGERR ("nshmem free fail] mem=%p", pzone); + return; + } + if (pzone->addr) + { + free (pzone->addr); + } + pzone->addr = NULL; + + int ret = MEMSET_S ((void *) pzone, sizeof (nsfw_nshmem_mzone), 0, + sizeof (nsfw_nshmem_mzone)); + if (EOK != ret) + { + NSCOMM_LOGERR ("MEMSET_S failed] mem=%p, ret=%d", pzone, ret); + } + return; +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_init +* Description : nsh module init +* Input : nsfw_mem_para* para +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_nshmem_init (nsfw_mem_para * para) +{ + i32 iret = NSFW_MEM_OK; + NSCOMM_LOGINF ("nsfw nshmem init begin"); + g_nshmem_localdata = + (nsfw_mem_localdata *) malloc (sizeof (nsfw_mem_localdata)); + + if (NULL == g_nshmem_localdata) + { + NSCOMM_LOGERR ("nshmem init g_nshmem_localdata malloc fail"); + return NSFW_MEM_ERR; + } + + iret = + MEMSET_S (g_nshmem_localdata, sizeof (nsfw_mem_localdata), 0, + sizeof (nsfw_mem_localdata)); + + if (EOK != iret) + { + NSCOMM_LOGERR ("nshmem init g_nshmem_localdata MEMSET_S fail"); + goto ERROR; + } + + g_nshmem_internal_cfg = + (nsfw_nshmem_cfg *) malloc (sizeof (nsfw_nshmem_cfg)); + + if (NULL == g_nshmem_internal_cfg) + { + NSCOMM_LOGERR ("nshmem init g_nshmem_internal_cfg malloc fail"); + goto ERROR; + } + + iret = + MEMSET_S (g_nshmem_internal_cfg, sizeof (nsfw_nshmem_cfg), 0, + sizeof (nsfw_nshmem_cfg)); + + if (EOK != iret) + { + NSCOMM_LOGERR ("nshmem init g_nshmem_internal_cfg MEMSET_S fail"); + goto ERROR; + } + + g_nshmem_localdata->enflag = para->enflag; + NSCOMM_LOGINF ("nsfw nshmem init end"); + goto OK; + +ERROR: + iret = NSFW_MEM_ERR; + nsfw_nshmem_destory (); + return iret; +OK: + iret = NSFW_MEM_OK; + return iret; +} + +/* + * memory destory + */ +void +nsfw_nshmem_destory (void) +{ + if (g_nshmem_localdata) + { + free (g_nshmem_localdata); + g_nshmem_localdata = NULL; + } + + if (g_nshmem_internal_cfg) + { + free (g_nshmem_internal_cfg); + g_nshmem_internal_cfg = NULL; + } + + return; +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_reserv_safe +* Description : malloc a memory and save to memzone +* Input : const char* name +* size_t lenth +* Output : None +* Return Value : mzone_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mzone_handle +nsfw_nshmem_reserv_safe (const char *name, size_t lenth) +{ + void *addr = NULL; + i32 iret = NSFW_MEM_OK; + nsfw_nshmem_mzone *pmemzone = NULL; + + if (lenth <= 0) + { + return NULL; + } + + nsfw_write_lock (nsfw_get_glb_lock ()); + + addr = malloc (lenth); + if (!addr) + { + NSCOMM_LOGERR ("nshmem malloc addr fail] addr=%p", addr); + nsfw_write_unlock (nsfw_get_glb_lock ()); + return NULL; + } + + iret = MEMSET_S (addr, lenth, 0, lenth); + if (EOK != iret) + { + NSCOMM_LOGERR ("nshmem malloc addr MEMSET_S fail] addr=%p", addr); + free (addr); + nsfw_write_unlock (nsfw_get_glb_lock ()); + return NULL; + } + + pmemzone = nsfw_nshmem_get_free_zone (); + + if (!pmemzone) + { + NSCOMM_LOGERR ("nshmem get free zone fail"); + free (addr); + nsfw_write_unlock (nsfw_get_glb_lock ()); + return NULL; + } + + pmemzone->addr = addr; + pmemzone->lenth = lenth; + /*name must be less than NSFW_MEM_APPNAME_LENTH */ + if (EOK != + STRCPY_S ((char *) pmemzone->aname, sizeof (pmemzone->aname), name)) + { + NSCOMM_LOGERR ("STRCPY_S failed]name=%s", name); + free (addr); + nsfw_write_unlock (nsfw_get_glb_lock ()); + return NULL; + } + + nsfw_write_unlock (nsfw_get_glb_lock ()); + return addr; +} + +/* + * create no shared memory + * nsfw_mem_zone::stname no shared memory name + * nsfw_mem_zone::isize memory size + */ +mzone_handle +nsfw_nshmem_create (nsfw_mem_zone * pinfo) +{ + + NSFW_NAME_LENCHECK_RET_NULL (pinfo->stname.aname, "nshmem create"); + NSFW_NSHMEM_INIT_CHK_RET_NULL (); + return nsfw_nshmem_reserv_safe (pinfo->stname.aname, pinfo->lenth); +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_lookup +* Description : find a block memory by name +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : mzone_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mzone_handle +nsfw_nshmem_lookup (nsfw_mem_name * pname) +{ + int icnt = 0; + nsfw_nshmem_mzone *mz = NULL; + + NSFW_NAME_LENCHECK_RET_NULL (pname->aname, "nshmem lookup"); + NSFW_NSHMEM_INIT_CHK_RET_NULL (); + nsfw_read_lock (nsfw_get_glb_lock ()); + + for (icnt = 0; icnt < NSFW_NSHMEM_ZONE_MAX; icnt++) + { + mz = &g_nshmem_internal_cfg->amemzone[icnt]; + + if (mz->addr != NULL + && !strncmp (pname->aname, mz->aname, NSFW_MEM_NAME_LENTH)) + { + nsfw_read_unlock (nsfw_get_glb_lock ()); + return mz->addr; + } + } + + nsfw_read_unlock (nsfw_get_glb_lock ()); + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_release +* Description : free a block memory +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_nshmem_release (nsfw_mem_name * pname) +{ + int icnt = 0; + nsfw_nshmem_mzone *mz = NULL; + + NSFW_NAME_LENCHECK_RET (pname->aname, "nshmem release"); + NSFW_NSHMEM_INIT_CHK_RET (); + nsfw_read_lock (nsfw_get_glb_lock ()); + + for (icnt = 0; icnt < NSFW_NSHMEM_ZONE_MAX; icnt++) + { + mz = &g_nshmem_internal_cfg->amemzone[icnt]; + + if (mz->addr != NULL + && !strncmp (pname->aname, mz->aname, NSFW_MEM_NAME_LENTH)) + { + nsfw_nshmem_free_zone (mz); + nsfw_read_unlock (nsfw_get_glb_lock ()); + return NSFW_MEM_OK; + } + } + + nsfw_read_unlock (nsfw_get_glb_lock ()); + return NSFW_MEM_OK; + +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_spcreate +* Description : create a memory pool by ring +* Input : nsfw_mem_sppool* pmpinfo +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +*****************************************************************************/ +mring_handle +nsfw_nshmem_spcreate (nsfw_mem_sppool * pmpinfo) +{ + size_t len = 0; + unsigned int usnum = common_mem_align32pow2 (pmpinfo->usnum + 1); + unsigned int uselt_size = pmpinfo->useltsize; + struct nsfw_mem_ring *pringhead = NULL; + unsigned int uscnt = 0; + char *pmz = NULL; + NSFW_NAME_LENCHECK_RET_NULL (pmpinfo->stname.aname, "nshmem sp create"); + NSFW_NSHMEM_INIT_CHK_RET_NULL (); + + len = + sizeof (struct nsfw_mem_ring) + + (size_t) usnum *sizeof (union RingData_U) + (size_t) usnum *uselt_size; + pringhead = + (struct nsfw_mem_ring *) nsfw_nshmem_reserv_safe (pmpinfo->stname.aname, + len); + + if (!pringhead) + { + NSCOMM_LOGERR ("nshmem sp create mzone reserv fail"); + return NULL; + } + + nsfw_mem_ring_init (pringhead, usnum, pringhead, NSFW_NSHMEM, + pmpinfo->enmptype); + pmz = + ((char *) pringhead + sizeof (struct nsfw_mem_ring) + + usnum * sizeof (union RingData_U)); + + for (uscnt = 0; uscnt < usnum; uscnt++) + { + if (0 == + g_ring_ops_arry[pringhead->memtype][pringhead-> + ringflag].ring_ops_enqueue + (pringhead, (void *) pmz)) + { + NSCOMM_LOGERR ("nsfw_nshmem_ringenqueue enque fail] uscnt=%u", + uscnt); + } + + pmz = pmz + uselt_size; + } + + return pringhead; +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_sp_lookup +* Description : look up a sppool memory +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +*****************************************************************************/ +mring_handle +nsfw_nshmem_sp_lookup (nsfw_mem_name * pname) +{ + return nsfw_nshmem_lookup (pname); +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_sprelease +* Description : release a sp pool +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_nshmem_sprelease (nsfw_mem_name * pname) +{ + NSFW_NAME_LENCHECK_RET (pname->aname, "nshmem sp mempool release"); + NSFW_NSHMEM_INIT_CHK_RET (); + return nsfw_nshmem_release (pname); +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_ringcreate +* Description : create a ring +* Input : nsfw_mem_mring* pringinfo +* Output : None +* Return Value : mring_handle +* Calls : +* Called By : +* +*****************************************************************************/ +mring_handle +nsfw_nshmem_ringcreate (nsfw_mem_mring * pringinfo) +{ + size_t len = 0; + unsigned int usnum = common_mem_align32pow2 (pringinfo->usnum + 1); + struct nsfw_mem_ring *pringhead = NULL; + NSFW_NAME_LENCHECK_RET_NULL (pringinfo->stname.aname, "nshmem ring create"); + NSFW_NSHMEM_INIT_CHK_RET_NULL (); + + len = sizeof (struct nsfw_mem_ring) + usnum * sizeof (union RingData_U); + pringhead = + (struct nsfw_mem_ring *) nsfw_nshmem_reserv_safe (pringinfo->stname.aname, + len); + + if (!pringhead) + { + NSCOMM_LOGERR ("nshmem ring create mzone reserv fail"); + return NULL; + } + + nsfw_mem_ring_init (pringhead, usnum, (void *) pringhead, NSFW_NSHMEM, + pringinfo->enmptype); + return pringhead; + +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_ringrelease +* Description : release a nsh ring memory +* Input : nsfw_mem_name* pname +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 +nsfw_nshmem_ringrelease (nsfw_mem_name * pname) +{ + NSFW_NAME_LENCHECK_RET (pname->aname, "nshmem ring mempool release"); + NSFW_NSHMEM_INIT_CHK_RET (); + return nsfw_nshmem_release (pname); +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_sppool_statics +* Description : static the memory size of sppool +* Input : mring_handle sppool +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t +nsfw_nshmem_sppool_statics (mring_handle sppool) +{ + struct nsfw_mem_ring *phead = (struct nsfw_mem_ring *) sppool; + + return sizeof (struct nsfw_mem_ring) + + (ssize_t) phead->size * sizeof (union RingData_U) + + (ssize_t) phead->size * phead->eltsize; +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_ring_statics +* Description : static the memory size of ring +* Input : mring_handle handle +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t +nsfw_nshmem_ring_statics (mring_handle handle) +{ + struct nsfw_mem_ring *ring = (struct nsfw_mem_ring *) handle; + return ring->size * sizeof (union RingData_U) + + sizeof (struct nsfw_mem_ring); +} + +/***************************************************************************** +* Prototype : nsfw_nshmem_stactic +* Description : static the memory size according to mem type +* Input : void* handle +* nsfw_mem_struct_type type +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t +nsfw_nshmem_stactic (void *handle, nsfw_mem_struct_type type) +{ + switch (type) + { + case NSFW_MEM_MBUF: + return -1; + case NSFW_MEM_SPOOL: + return nsfw_nshmem_sppool_statics (handle); + case NSFW_MEM_RING: + return nsfw_nshmem_ring_statics (handle); + default: + break; + } + return -1; +} diff --git a/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.h b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.h new file mode 100644 index 0000000..3f5b1b9 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_mng.h @@ -0,0 +1,70 @@ +/* +* +* 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 _NSFW_NSHMEM_MNG_H_ +#define _NSFW_NSHMEM_MNG_H_ + +#include "generic/common_mem_rwlock.h" + +#include "common_func.h" + +#define NSFW_NSHMEM_ZONE_MAX 2560 + +typedef struct +{ + i8 aname[NSFW_MEM_NAME_LENTH]; + void *addr; + int lenth; +} nsfw_nshmem_mzone; + +typedef struct +{ + nsfw_nshmem_mzone amemzone[NSFW_NSHMEM_ZONE_MAX]; + common_mem_rwlock_t mlock; +} nsfw_nshmem_cfg; + +/* + * no share memory module init + */ +i32 nsfw_nshmem_init (nsfw_mem_para * para); + +/* + * no share memory moudle destory + */ +void nsfw_nshmem_destory (void); + +/* + * create a no shared memory + */ +mzone_handle nsfw_nshmem_create (nsfw_mem_zone * pinfo); + +mzone_handle nsfw_nshmem_lookup (nsfw_mem_name * pname); + +i32 nsfw_nshmem_release (nsfw_mem_name * pname); + +mring_handle nsfw_nshmem_spcreate (nsfw_mem_sppool * pmpinfo); + +i32 nsfw_nshmem_sprelease (nsfw_mem_name * pname); + +mring_handle nsfw_nshmem_sp_lookup (nsfw_mem_name * pname); + +mring_handle nsfw_nshmem_ringcreate (nsfw_mem_mring * pringinfo); + +i32 nsfw_nshmem_ringrelease (nsfw_mem_name * pname); + +ssize_t nsfw_nshmem_stactic (void *handle, nsfw_mem_struct_type type); + +#endif diff --git a/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.c b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.c new file mode 100644 index 0000000..64e7d57 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.c @@ -0,0 +1,436 @@ +/* +* +* 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 +#include "nstack_securec.h" + +#include "nsfw_mem_desc.h" +#include "nsfw_nshmem_ring.h" +#include "nsfw_ring_fun.h" +#include "common_func.h" + +/*copy the data to obj*/ +NSTACK_STATIC inline void +nsfw_nshmem_ring_obj_copy (struct nsfw_mem_ring *r, uint32_t cons_head, + void **obj_table, unsigned n) +{ + uint32_t idx = cons_head & r->mask; + unsigned i = 0; + const uint32_t size = r->size; + + if (likely (idx + n < size)) + { + for (i = 0; i < (n & (~(unsigned) 0x3)); i += 4, idx += 4) + { + obj_table[i] = (void *) r->ring[idx].data_l; + obj_table[i + 1] = (void *) r->ring[idx + 1].data_l; + obj_table[i + 2] = (void *) r->ring[idx + 2].data_l; + obj_table[i + 3] = (void *) r->ring[idx + 3].data_l; + } + switch (n & 0x3) + { + case 3: + obj_table[i++] = (void *) r->ring[idx++].data_l; + + case 2: + obj_table[i++] = (void *) r->ring[idx++].data_l; + + case 1: + obj_table[i++] = (void *) r->ring[idx++].data_l; + } + } + else + { + for (i = 0; idx < size; i++, idx++) + { + obj_table[i] = (void *) r->ring[idx].data_l; + } + + for (idx = 0; i < n; i++, idx++) + { + obj_table[i] = (void *) r->ring[idx].data_l; + } + } +} + +/*fork recover*/ +NSTACK_STATIC inline void +nsfw_nshmem_enqueue_fork_recov (struct nsfw_mem_ring *r) +{ + u32_t pidflag = 0; + u32_t curpid = get_sys_pid (); + int success = 0; + /*if pid is not the same, maybe mult thread fork happen */ + pidflag = r->prodhflag; + + if (unlikely (pidflag != curpid)) + { + success = common_mem_atomic32_cmpset (&r->prodhflag, pidflag, curpid); + + if (unlikely (success != 0)) + { + /*recover it */ + if (r->prod.tail != r->prod.head) + { + r->prod.head = r->prod.tail; + } + + r->prodtflag = curpid; + } + } + + return; +} + +NSTACK_STATIC inline void +nsfw_nshmem_dequeue_fork_recov (struct nsfw_mem_ring *r) +{ + u32_t pidflag = 0; + u32_t curpid = get_sys_pid (); + int success = 0; + /*if pid is not the same, maybe mult thread fork happen */ + pidflag = r->conshflag; + + if (unlikely (pidflag != curpid)) + { + success = common_mem_atomic32_cmpset (&r->conshflag, pidflag, curpid); + + if (unlikely (success != 0)) + { + /*recover it */ + if (r->cons.tail != r->cons.head) + { + r->cons.head = r->cons.tail; + } + + r->constflag = curpid; + } + } + + return; +} + +/* +this is a multi thread/process enqueue function, please pay attention to the bellow point +1. while Enqueue corrupt, we may lose one element; because no one to add the Head +*/ +int +nsfw_nshmem_ring_mp_enqueue (struct nsfw_mem_ring *mem_ring, void *obj_table) +{ + uint32_t prod_head, prod_next; + uint32_t cons_tail, free_entries; + int success; + unsigned rep = 0; + uint32_t mask = mem_ring->mask; + uint32_t size = mem_ring->size; + uint32_t n = 1; + + /* move prod.head atomically */ + do + { + + prod_head = mem_ring->prod.head; + cons_tail = mem_ring->cons.tail; + /* The subtraction is done between two unsigned 32bits value + * (the result is always modulo 32 bits even if we have + * prod_head > cons_tail). So 'free_entries' is always between 0 + * and size(ring)-1. */ + free_entries = (size + cons_tail - prod_head); + + /* check that we have enough room in ring */ + if (unlikely (n > free_entries)) + { + return 0; + /* Below code is commented currenlty as its a dead code. */ + } + + /*if pid is not the same, maybe mult thread fork happen */ + nsfw_nshmem_enqueue_fork_recov (mem_ring); + + while (unlikely + ((mem_ring->prod.tail != mem_ring->prod.head) + || (mem_ring->prodtflag != mem_ring->prodhflag))) + { + common_mem_pause (); + } + + prod_next = prod_head + n; + success = + common_mem_atomic32_cmpset (&mem_ring->prod.head, prod_head, + prod_next); + } + while (unlikely (success == 0)); + + mem_ring->ring[prod_head & mask].data_l = (u64) obj_table; + + /* + * If there are other enqueues in progress that preceded us, + * we need to wait for them to complete + */ + while (unlikely (mem_ring->prod.tail != prod_head)) + { + common_mem_pause (); + + /* Set COMMON_RING_PAUSE_REP_COUNT to avoid spin too long waiting + * for other thread finish. It gives pre-empted thread a chance + * to proceed and finish with ring dequeue operation. */ + /* check the queue can be operate */ + if (++rep == 5) + { + rep = 0; + (void) sched_yield (); + } + } + + mem_ring->prod.tail = prod_next; + return (int) n; +} + +/* + this is a single thread/process enqueue function + */ +int +nsfw_nshmem_ring_sp_enqueue (struct nsfw_mem_ring *r, void *obj_table) +{ + uint32_t prod_head, cons_tail; + uint32_t prod_next, free_entries; + uint32_t mask = r->mask; + uint32_t n = 1; + uint32_t size = r->size; + + prod_head = r->prod.head; + cons_tail = r->cons.tail; + /* The subtraction is done between two unsigned 32bits value + * (the result is always modulo 32 bits even if we have + * prod_head > cons_tail). So 'free_entries' is always between 0 + * and size(ring)-1. */ + free_entries = size + cons_tail - prod_head; + + /* check that we have enough room in ring */ + if (unlikely (n > free_entries)) + { + return 0; + } + + nsfw_nshmem_enqueue_fork_recov (r); + + prod_next = prod_head + n; + r->prod.head = prod_next; + + r->ring[prod_head & mask].data_l = (u64) obj_table; + + r->prod.tail = prod_next; + return (int) n; +} + +/* + this is enhanced mc_ring_dequeue, support dequeue multi element one time. +*/ +int +nsfw_nshmem_ring_mc_dequeuev (struct nsfw_mem_ring *r, void **obj_table, + unsigned int n) +{ + uint32_t cons_head, prod_tail; + uint32_t cons_next, entries; + int success; + unsigned rep = 0; + uint32_t num = n; + + /* Avoid the unnecessary cmpset operation below, which is also + * potentially harmful when n equals 0. */ + if (unlikely (num == 0)) + { + return 0; + } + + nsfw_nshmem_dequeue_fork_recov (r); + + /* move cons.head atomically */ + do + { + num = n; + cons_head = r->cons.head; + prod_tail = r->prod.tail; + /* The subtraction is done between two unsigned 32bits value + * (the result is always modulo 32 bits even if we have + * cons_head > prod_tail). So 'entries' is always between 0 + * and size(ring)-1. */ + entries = (prod_tail - cons_head); + + /* Set the actual entries for dequeue */ + if (unlikely (num > entries)) + { + if (likely (entries > 0)) + { + num = entries; + } + else + { + return 0; + } + } + + /* check the queue can be operate */ + while (unlikely + ((r->cons.tail != r->cons.head) + || (r->conshflag != r->constflag))) + { + common_mem_pause (); + } + + cons_next = cons_head + num; + + success = + common_mem_atomic32_cmpset (&r->cons.head, cons_head, cons_next); + } + while (unlikely (success == 0)); + + nsfw_nshmem_ring_obj_copy (r, cons_head, obj_table, num); + + /* + * If there are other dequeues in progress that preceded us, + * we need to wait for them to complete + */ + while (unlikely (r->cons.tail != cons_head)) + { + common_mem_pause (); + + /* Set COMMON_RING_PAUSE_REP_COUNT to avoid spin too long waiting + * for other thread finish. It gives pre-empted thread a chance + * to proceed and finish with ring dequeue operation. */ + /* check the queue can be operate */ + if (++rep == 5) + { + rep = 0; + (void) sched_yield (); + } + } + + r->cons.tail = cons_next; + + return (int) num; +} + +/*this is a multi thread/process dequeue function, please pay attention to the bellow point +1. while dequeue corrupt, the tail no one added, may multy the try times. +*/ +int +nsfw_nshmem_ring_mc_dequeue (struct nsfw_mem_ring *ring, void **box) +{ + return nsfw_nshmem_ring_mc_dequeuev (ring, box, 1); +} + +/* + this is a single thread/process dequeue function +*/ +int +nsfw_nshmem_ring_sc_dequeuev (struct nsfw_mem_ring *r, void **obj_table, + unsigned int n) +{ + uint32_t cons_head, prod_tail; + uint32_t cons_next, entries; + uint32_t inum = n; + cons_head = r->cons.head; + prod_tail = r->prod.tail; + /* The subtraction is done between two unsigned 32bits value + * (the result is always modulo 32 bits even if we have + * cons_head > prod_tail). So 'entries' is always between 0 + * and size(ring)-1. */ + entries = prod_tail - cons_head; + + if (unlikely (inum > entries)) + { + if (likely (entries > 0)) + { + inum = entries; + } + else + { + return 0; + } + } + + nsfw_nshmem_dequeue_fork_recov (r); + + cons_next = cons_head + inum; + r->cons.head = cons_next; + + nsfw_nshmem_ring_obj_copy (r, cons_head, obj_table, inum); + + r->cons.tail = cons_next; + return (int) inum; +} + +/* + this is enhanced mc_ring_dequeue, support dequeue multi element one time. +*/ +int +nsfw_nshmem_ring_sc_dequeue (struct nsfw_mem_ring *ring, void **box) +{ + return nsfw_nshmem_ring_sc_dequeuev (ring, box, 1); +} + +/*stack just using one thread, for performance using que not support multi thread*/ +int +nsfw_nshmem_ring_singlethread_enqueue (struct nsfw_mem_ring *ring, void *box) +{ + u32 head = 0; + + /*if queue is full, just return 0 */ + if (unlikely (ring->prod.head >= (ring->size + ring->cons.tail))) + { + return 0; + } + + head = ring->prod.head; + ring->ring[head & ring->mask].data_l = (u64) box; + ring->prod.head++; + return 1; +} + +/*stack just using one thread, for performance using que not support multi thread*/ +int +nsfw_nshmem_ring_singlethread_dequeue (struct nsfw_mem_ring *ring, void **box) +{ + return nsfw_nshmem_ring_singlethread_dequeuev (ring, box, 1); +} + +/*stack just using one thread, for performance using que not support multi thread*/ +int +nsfw_nshmem_ring_singlethread_dequeuev (struct nsfw_mem_ring *ring, + void **box, unsigned int n) +{ + u32 tail = 0; + u32 num = 0; + + while (num < n) + { + tail = ring->cons.tail; + + /* if all entries are dequed return 0 */ + if (unlikely (ring->prod.head == ring->cons.tail)) + { + return num; + } + + box[num] = (void *) ring->ring[tail & ring->mask].data_l; + ring->cons.tail++; + num++; + } + + return num; +} diff --git a/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.h b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.h new file mode 100644 index 0000000..93a4d4a --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_nshmem/nsfw_nshmem_ring.h @@ -0,0 +1,37 @@ +/* +* +* 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 _NSFW_NSHMEM_RING_H_ +#define _NSFW_NSHMEM_RING_H_ + +#include + +int nsfw_nshmem_ring_mp_enqueue (struct nsfw_mem_ring *ring, void *box); +int nsfw_nshmem_ring_sp_enqueue (struct nsfw_mem_ring *ring, void *box); +int nsfw_nshmem_ring_mc_dequeue (struct nsfw_mem_ring *ring, void **box); +int nsfw_nshmem_ring_mc_dequeuev (struct nsfw_mem_ring *ring, void **box, + unsigned int n); +int nsfw_nshmem_ring_sc_dequeue (struct nsfw_mem_ring *ring, void **box); +int nsfw_nshmem_ring_sc_dequeuev (struct nsfw_mem_ring *ring, void **box, + unsigned int n); +int nsfw_nshmem_ring_singlethread_enqueue (struct nsfw_mem_ring *ring, + void *box); +int nsfw_nshmem_ring_singlethread_dequeue (struct nsfw_mem_ring *ring, + void **box); +int nsfw_nshmem_ring_singlethread_dequeuev (struct nsfw_mem_ring *ring, + void **box, unsigned int n); + +#endif /*_NSFW_NSHMEM_RING_H_*/ diff --git a/src/framework/common/mem_mgr/nsfw_res_mgr.c b/src/framework/common/mem_mgr/nsfw_res_mgr.c new file mode 100644 index 0000000..2f676c9 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_res_mgr.c @@ -0,0 +1,429 @@ +/* +* +* 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 header files * + *----------------------------------------------*/ + +/*==============================================* + * constants or macros define * + *----------------------------------------------*/ + +/*==============================================* + * project-wide global variables * + *----------------------------------------------*/ + +/*==============================================* + * routines' or functions' implementations * + *----------------------------------------------*/ + +#include +#include "types.h" +#include "nstack_securec.h" +#include "nsfw_init.h" +#include "common_mem_mbuf.h" + +#include "nstack_log.h" +#include "nsfw_maintain_api.h" + +#include "nsfw_mem_api.h" +#include "nsfw_fd_timer_api.h" +#include "nsfw_ring_data.h" + +#include "common_func.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +nsfw_res_mgr_item_cfg g_all_res_can[NSFW_MAX_RES_SCAN_COUNT]; + +#define NSFW_RES_SCAN_TVLAUE_DEF 60 +#define NSFW_RES_SCAN_TVLAUE (g_scan_cfg.scan_tvalue) + +typedef struct _nsfw_res_scan_init_cfg +{ + nsfw_timer_info *scan_timer; + u16 scan_tvalue; +} nsfw_res_scan_init_cfg; +nsfw_res_scan_init_cfg g_scan_cfg; + +u8 +nsfw_res_mgr_reg (nsfw_res_scn_cfg * cfg) +{ + if (NULL == cfg) + { + NSFW_LOGERR ("argv err!"); + return FALSE; + } + + u32 i; + for (i = 0; i < NSFW_MAX_RES_SCAN_COUNT; i++) + { + if ((NULL == g_all_res_can[i].scn_cfg.free_fun) + && + (__sync_bool_compare_and_swap + (&g_all_res_can[i].scn_cfg.free_fun, 0, cfg->free_fun))) + { + g_all_res_can[i].scn_cfg = *cfg; + NSFW_LOGINF ("reg res_mgr fun suc]fun=%p,data=%p", cfg->free_fun, + cfg->data); + return TRUE; + } + } + + NSFW_LOGERR + ("reg]type=%u,per=%u,chk=%u,cyc=%u,total=%u,size=%u,offset=%u,fun=%p,data=%p", + cfg->type, cfg->force_free_percent, cfg->force_free_chk_num, + cfg->num_per_cyc, cfg->total_num, cfg->elm_size, cfg->res_mem_offset, + cfg->res_mem_offset, cfg->free_fun, cfg->data); + return FALSE; +} + +static inline u32 +nsfw_get_alloc_count (u32 head, u32 tail) +{ + if (head >= tail) + { + return head - tail; + } + + return head + (0xFFFFFFFF - tail); +} + +int +nsfw_res_sp_item_chk (void *data, void *argv) +{ + nsfw_res_mgr_item_cfg *res_scn_item = (nsfw_res_mgr_item_cfg *) argv; + nsfw_res_scn_cfg *scn_cfg = &res_scn_item->scn_cfg; + char *elm = (char *) data; + + if (NULL == scn_cfg || NULL == elm) + { + return FALSE; + } + + nsfw_res *res_item = NULL; + res_item = (nsfw_res *) (elm + scn_cfg->res_mem_offset); + if (0 == res_item->chk_count) + { + res_item->data = res_scn_item->cons_head; + } + res_item->chk_count++; + + if (res_item->chk_count < scn_cfg->force_free_chk_num) + { + return FALSE; + } + + if (res_scn_item->free_percent > scn_cfg->force_free_percent) + { + return FALSE; + } + + if (scn_cfg->total_num * scn_cfg->alloc_speed_factor > + nsfw_get_alloc_count (res_scn_item->cons_head, res_item->data)) + { + return FALSE; + } + + if (NULL == scn_cfg->free_fun) + { + return FALSE; + } + + if (TRUE == scn_cfg->free_fun ((void *) elm)) + { + res_scn_item->force_count++; + } + + res_item->chk_count = 0; + return TRUE; +} + +int +nsfw_res_flash_data (nsfw_res_mgr_item_cfg * res_scn_item) +{ + nsfw_res_scn_cfg *scn_cfg = &res_scn_item->scn_cfg; + + u32 cur_head = 0; + u32 cur_tail = 0; + u32 elm_num = 0; + u32 free_count = 0; + + switch (scn_cfg->type) + { + case NSFW_RES_SCAN_MBUF: + { + struct common_mem_ring *ring = + (struct common_mem_ring *) scn_cfg->mgr_ring; + struct common_mem_mempool *mp = + (struct common_mem_mempool *) scn_cfg->data; + if (NULL == ring) + { + ring = mp->ring; + if (NULL == ring) + return FALSE; + } + cur_head = ring->prod.head; + cur_tail = ring->cons.head; + elm_num = mp->size; + } + break; + case NSFW_RES_SCAN_SPOOL: + { + struct nsfw_mem_ring *mem_ring = + (struct nsfw_mem_ring *) scn_cfg->mgr_ring; + if (NULL == mem_ring) + { + mem_ring = (struct nsfw_mem_ring *) scn_cfg->data; + if (NULL == mem_ring) + return FALSE; + } + + cur_head = mem_ring->prod.head; + cur_tail = mem_ring->cons.tail; + elm_num = mem_ring->size; + } + break; + case NSFW_RES_SCAN_ARRAY: + { + struct nsfw_mem_ring *mem_ring = + (struct nsfw_mem_ring *) scn_cfg->mgr_ring; + if (NULL == mem_ring) + { + return FALSE; + } + + cur_head = mem_ring->prod.head; + cur_tail = mem_ring->cons.tail; + elm_num = scn_cfg->total_num; + } + break; + default: + return FALSE; + } + + free_count = nsfw_get_alloc_count (cur_head, cur_tail); + + res_scn_item->cons_head = cur_head; + res_scn_item->prod_head = cur_tail; + if (0 != elm_num) + { + res_scn_item->free_percent = free_count * 100 / elm_num; + } + else + { + res_scn_item->free_percent = 100; + } + + scn_cfg->total_num = elm_num; + return TRUE; +} + +void +nsfw_res_scan_mem (nsfw_res_mgr_item_cfg * res_scn_item) +{ + if (NULL == res_scn_item) + { + return; + } + + nsfw_res_scn_cfg *scn_cfg = &res_scn_item->scn_cfg; + if (NULL == scn_cfg->data) + { + return; + } + + u32 start = res_scn_item->last_scn_idx; + u32 end = start + scn_cfg->num_per_cyc; + int res_chk_number = 0; + if (NSFW_RES_SCAN_SPOOL == scn_cfg->type) + { + res_chk_number = + nsfw_mem_sp_iterator (scn_cfg->data, start, end, + nsfw_res_sp_item_chk, (void *) res_scn_item); + } + else + { + res_chk_number = + nsfw_mem_mbuf_iterator (scn_cfg->data, start, end, + nsfw_res_sp_item_chk, (void *) res_scn_item); + } + + if (0 == res_chk_number) + { + res_scn_item->last_scn_idx = 0; + start = res_scn_item->last_scn_idx; + end = start + scn_cfg->num_per_cyc; + if (NSFW_RES_SCAN_SPOOL == scn_cfg->type) + { + res_chk_number = + nsfw_mem_sp_iterator (scn_cfg->data, start, end, + nsfw_res_sp_item_chk, + (void *) res_scn_item); + } + else + { + res_chk_number = + nsfw_mem_mbuf_iterator (scn_cfg->data, start, end, + nsfw_res_sp_item_chk, + (void *) res_scn_item); + } + } + + if (res_chk_number + start < end) + { + res_scn_item->last_scn_idx = 0; + } + else + { + res_scn_item->last_scn_idx += res_chk_number; + } + + return; +} + +void +nsfw_res_scan_array (nsfw_res_mgr_item_cfg * res_scn_item) +{ + if (NULL == res_scn_item) + { + return; + } + + nsfw_res_scn_cfg *scn_cfg = &res_scn_item->scn_cfg; + if (NULL == scn_cfg->data) + { + return; + } + + u32 i; + char *elm = + (char *) scn_cfg->data + (res_scn_item->last_scn_idx * scn_cfg->elm_size); + for (i = res_scn_item->last_scn_idx; i < scn_cfg->total_num; i++) + { + if (i >= res_scn_item->last_scn_idx + scn_cfg->num_per_cyc) + { + break; + } + + if (TRUE == nsfw_res_sp_item_chk (elm, (void *) res_scn_item)) + { + NSFW_LOGINF ("force free item]data=%p,cfg=%p", elm, res_scn_item); + } + + elm += scn_cfg->elm_size; + } + + if (i >= scn_cfg->total_num) + { + res_scn_item->last_scn_idx = 0; + } + else + { + res_scn_item->last_scn_idx = i; + } + + return; +} + +void +nsfw_res_scan_proc (nsfw_res_mgr_item_cfg * res_scn_item) +{ + (void) nsfw_res_flash_data (res_scn_item); + switch (res_scn_item->scn_cfg.type) + { + case NSFW_RES_SCAN_ARRAY: + nsfw_res_scan_array (res_scn_item); + break; + case NSFW_RES_SCAN_SPOOL: + case NSFW_RES_SCAN_MBUF: + nsfw_res_scan_mem (res_scn_item); + break; + default: + break; + } +} + +int +nsfw_res_scan_all (u32 timer_type, void *data) +{ + NSFW_LOGDBG ("scan start!"); + struct timespec time_left = { NSFW_RES_SCAN_TVLAUE, 0 }; + g_scan_cfg.scan_timer = + nsfw_timer_reg_timer (0, NULL, nsfw_res_scan_all, time_left); + + if (g_hbt_switch) + { + return TRUE; + } + + int i; + for (i = 0; i < NSFW_MAX_RES_SCAN_COUNT; i++) + { + /*last fun */ + if (NULL == g_all_res_can[i].scn_cfg.data) + { + break; + } + + nsfw_res_scan_proc (&g_all_res_can[i]); + } + + return TRUE; +} + +static int nsfw_resmgr_module_init (void *param); +static int +nsfw_resmgr_module_init (void *param) +{ + u8 proc_type = (u8) ((long long) param); + NSFW_LOGINF ("res mgr module init]type=%u", proc_type); + g_scan_cfg.scan_tvalue = NSFW_RES_SCAN_TVLAUE_DEF; + switch (proc_type) + { + case NSFW_PROC_MAIN: + { + struct timespec time_left = { NSFW_RES_SCAN_TVLAUE, 0 }; + g_scan_cfg.scan_timer = + nsfw_timer_reg_timer (0, NULL, nsfw_res_scan_all, time_left); + return 0; + } + default: + if (proc_type < NSFW_PROC_MAX) + { + break; + } + return -1; + } + + return 0; +} + +/* *INDENT-OFF* */ +NSFW_MODULE_NAME(NSFW_RES_MGR_MODULE) +NSFW_MODULE_PRIORITY(99) +NSFW_MODULE_INIT(nsfw_resmgr_module_init) +/* *INDENT-ON* */ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/framework/common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.c b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.c new file mode 100644 index 0000000..dc3400d --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.c @@ -0,0 +1,987 @@ +/* +* +* 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_securec.h" +#include "nstack_log.h" +#include "nsfw_ring_fun.h" +#include "nsfw_shmem_ring.h" +#include "nsfw_shmem_mng.h" +#include "common_mem_buf.h" +#include "common_mem_common.h" + +#include "common_func.h" + +/*get the base address of msg data */ +#define NSFW_SHMEM_GET_DATA(pmsg, type) (type *)&((pmsg)->aidata[0]) + +/*if input point is nun, just return null*/ +#define NSFW_POINT_CHK_RET_NULL(p, desc) \ + if (NULL == (p)) \ + { \ + NSCOMM_LOGERR("point check fail] desc_para=%s", desc); \ + return NULL; \ + } + +/*if input point is nun, just return err num*/ +#define NSFW_POINT_CHK_RET_ERR(p, desc) \ + if (NULL == (p)) \ + { \ + NSCOMM_LOGDBG("point check fail] desc_para=%s", desc); \ + return NSFW_MEM_ERR; \ + } + +/*if input point is nun, goto flag*/ +#define NSFW_POINT_CHK_RET_GOTO(p, gotoflag, desc) \ + if (NULL == (p)) \ + { \ + NSCOMM_LOGERR("point check fail] desc_para=%s", desc); \ + goto gotoflag; \ + } + +/*init the msg head*/ +#define NSFW_SHMEM_MSG_HEAD_INIT(pmsg, type, lenth) { \ + (pmsg)->usmsg_type = (type); \ + (pmsg)->uslenth = (lenth); \ + } + +/*rsp msg head check, and if err goto*/ +#define NSFW_SHMEM_MSGHEAD_CHK_GOTO(pmsg, type, lenth, gotoflag) { \ + if (((type) != pmsg->usmsg_type) && ((lenth) != pmsg->uslenth)) \ + { \ + NSCOMM_LOGERR("check fail] msgtype=%d, type_para=%d, len=%d", (pmsg->usmsg_type), (type), (lenth)); \ + goto gotoflag; \ + } \ + } + +/*rsp check the state*/ +#define NSFW_SHMEM_ACKSTATE_CHK_GOTO(expret, ret, expseg, seg, gotoflag) { \ + if (((ret) != (expret)) || ((expseg) != (seg))) \ + { \ + NSCOMM_LOGERR("ackstate check fail]msgack exp=%d, real=%d,eseg=%d, rseg=%d", (expret), (ret), (expseg), (seg)); \ + goto gotoflag; \ + } \ + } + +/*mzone msg init*/ +#define NSFW_SHMEM_MZONE_DATA_INIT(pdata, slenth, seg, socketid) { \ + (pdata)->isocket_id = (socketid); \ + (pdata)->lenth = (slenth); \ + (pdata)->usseq = (seg); \ + (pdata)->ireserv = 0; \ + } + +/*mbuf msg init*/ +#define NSFW_SHMEM_MBUF_DATA_INIT(pdata, seg, num, cashsize, priv_size, data_room, flag, socketid) { \ + (pdata)->usseq = (seg); \ + (pdata)->usnum = (num); \ + (pdata)->uscash_size = (cashsize); \ + (pdata)->uspriv_size = (priv_size); \ + (pdata)->usdata_room = (data_room); \ + (pdata)->enmptype = (flag); \ + (pdata)->isocket_id = (socketid); \ + (pdata)->ireserv = 0; \ + } + +/*mpool msg init*/ +#define NSFW_SHMEM_MPOOL_DATA_INIT(pdata, seg, num, eltsize, flag, socketid) { \ + (pdata)->usseq = (seg); \ + (pdata)->usnum = (num); \ + (pdata)->useltsize = (eltsize); \ + (pdata)->enmptype = (flag); \ + (pdata)->isocket_id = (socketid); \ + (pdata)->ireserv = 0; \ + } + +/*mring msg init*/ +#define NSFW_SHMEM_MRING_DATA_INIT(pdata, seg, num, flag, socketid) { \ + (pdata)->usseq = (seg); \ + (pdata)->usnum = (num); \ + (pdata)->enmptype = (flag); \ + (pdata)->isocket_id = (socketid); \ + (pdata)->ireserv = 0; \ + } + +#define NSFW_SHMEM_MSG_FREE(pmsg, prsp_msg) {\ + if (pmsg) \ + { \ + nsfw_mgr_msg_free(pmsg); \ + } \ + if (prsp_msg) \ + { \ + nsfw_mgr_msg_free(prsp_msg); \ + } \ +} + +/* + * create a block memory by send a msg + * + */ +mzone_handle +nsfw_memzone_remote_reserv (const i8 * name, size_t mlen, i32 socket_id) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + + /*msg head point define */ + nsfw_shmem_msg_head *pdata_head = NULL; + + /*msg data point define */ + nsfw_shmem_reserv_req *pdata = NULL; + nsfw_shmem_msg_head *pack_head = NULL; + + /*ack msg define */ + nsfw_shmem_ack *pack_data = NULL; + + mzone_handle hhandle = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + + //pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MASTER); + pmsg = nsfw_mgr_msg_alloc (MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_NULL (pmsg, "remote reserv pmsg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc (); + NSFW_POINT_CHK_RET_GOTO (prsp_msg, release, "remote reserv rspmsg alloc"); + + /*msg head init */ + pdata_head = GET_USER_MSG (nsfw_shmem_msg_head, pmsg); + NSFW_SHMEM_MSG_HEAD_INIT (pdata_head, NSFW_RESERV_REQ_MSG, + sizeof (nsfw_shmem_reserv_req)); + + /*msg data init */ + pdata = NSFW_SHMEM_GET_DATA (pdata_head, nsfw_shmem_reserv_req); + iretval = STRCPY_S (pdata->aname, sizeof (pdata->aname), name); + if (EOK != iretval) + { + NSCOMM_LOGERR ("reserv mem copy name fail] ret=%d", iretval); + goto release; + } + + /*fill msg data */ + NSFW_SHMEM_MZONE_DATA_INIT (pdata, mlen, (u16) 0, socket_id); + + ucret = nsfw_mgr_send_req_wait_rsp (pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSCOMM_LOGERR ("reserv mem req rsp fail] ret=%u", ucret); + goto release; + } + + /*interrupt msg head */ + pack_head = GET_USER_MSG (nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO (pack_head, NSFW_RESERV_ACK_MSG, + sizeof (nsfw_shmem_ack), release); + + pack_data = NSFW_SHMEM_GET_DATA (pack_head, nsfw_shmem_ack); + NSFW_SHMEM_ACKSTATE_CHK_GOTO (NSFW_MEM_ALLOC_SUCC, pack_data->cstate, 0, + pack_data->usseq, release); + + hhandle = (mzone_handle) ADDR_SHTOL (pack_data->pbase_addr); + NSCOMM_LOGDBG ("mem reserve] name=%s, handle=%p, seg=%u", name, hhandle, + pack_data->usseq); +release: + NSFW_SHMEM_MSG_FREE (pmsg, prsp_msg); + return hhandle; +} + +/* + *create some memorys by send a msg + */ +i32 +nsfw_memzone_remote_reserv_v (nsfw_mem_zone * pmeminfo, + mzone_handle * paddr_array, i32 inum, pid_t pid) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + nsfw_shmem_msg_head *pdata_head = NULL; + nsfw_shmem_reserv_req *pdata = NULL; + nsfw_shmem_reserv_req *ptempdata = NULL; + nsfw_shmem_msg_head *pack_head = NULL; + + nsfw_shmem_ack *pack_data = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + i32 icount = 0; + i32 itindex = 0; + i32 iindex = 0; + u16 ussegbase = 0; + u16 ustempv = 0; + i32 ieltnum = 0; + i32 ieltnum_max = + (NSFW_MGR_MSG_BODY_LEN - + sizeof (nsfw_shmem_msg_head)) / sizeof (nsfw_shmem_reserv_req); + + //pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MASTER); + pmsg = nsfw_mgr_msg_alloc (MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_GOTO (pmsg, err, "remote reserv_v msg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc (); + NSFW_POINT_CHK_RET_GOTO (prsp_msg, err, "remote reserv_v rspmsg alloc"); + + pdata_head = GET_USER_MSG (nsfw_shmem_msg_head, pmsg); + + ptempdata = pdata = NSFW_SHMEM_GET_DATA (pdata_head, nsfw_shmem_reserv_req); + + do + { + icount++; + ieltnum++; + + if (((icount % ieltnum_max) == 0) || (icount >= inum)) + { + NSFW_SHMEM_MSG_HEAD_INIT (pdata_head, NSFW_RESERV_REQ_MSG, + ieltnum * sizeof (nsfw_shmem_reserv_req)); + + itindex = icount - 1; + int retVal = + SPRINTF_S (ptempdata->aname, sizeof (ptempdata->aname), "%s_%x", + pmeminfo[itindex].stname.aname, pid); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S faild]ret=%d", retVal); + } + NSFW_SHMEM_MZONE_DATA_INIT (ptempdata, pmeminfo[itindex].lenth, + (u16) itindex, + pmeminfo[itindex].isocket_id); + + ucret = nsfw_mgr_send_req_wait_rsp (pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSCOMM_LOGERR ("reserv v mem req rsp fail] ret=%u", ucret); + goto err; + } + + pack_head = GET_USER_MSG (nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO (pack_head, NSFW_RESERV_ACK_MSG, + ieltnum * sizeof (nsfw_shmem_ack), + err); + + pack_data = NSFW_SHMEM_GET_DATA (pack_head, nsfw_shmem_ack); + + for (iindex = 0; iindex < ieltnum; iindex++) + { + ustempv = ussegbase + iindex; + + NSFW_SHMEM_ACKSTATE_CHK_GOTO (NSFW_MEM_ALLOC_SUCC, + pack_data->cstate, ustempv, + (u16) pack_data->usseq, err); + + paddr_array[ustempv] = ADDR_SHTOL (pack_data->pbase_addr); + NSCOMM_LOGDBG ("remote reserve]index=%u, seg=%u, handle=%p", + ustempv, pack_data->usseq, paddr_array[ustempv]); + pack_data++; + } + + ussegbase = icount; + ieltnum = 0; + ptempdata = pdata; + } + else + { + itindex = icount - 1; + int retVal = + SPRINTF_S (ptempdata->aname, sizeof (ptempdata->aname), "%s_%x", + pmeminfo[itindex].stname.aname, pid); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S faild]ret=%d", retVal); + } + NSFW_SHMEM_MZONE_DATA_INIT (ptempdata, pmeminfo[itindex].lenth, + (u16) itindex, + pmeminfo[itindex].isocket_id); + ptempdata++; + } + } + while (icount < inum); + + iretval = NSFW_MEM_OK; + goto free; + +err: + iretval = NSFW_MEM_ERR; +free: + NSFW_SHMEM_MSG_FREE (pmsg, prsp_msg); + return iretval; +} + +/* + *release a block memory with name by send msg + */ +i32 +nsfw_remote_free (const i8 * name, nsfw_mem_struct_type entype) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + + nsfw_shmem_msg_head *pdata_head = NULL; + + nsfw_shmem_free_req *pdata = NULL; + + nsfw_shmem_msg_head *pack_head = NULL; + nsfw_shmem_ack *pack_data = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + + pmsg = nsfw_mgr_msg_alloc (MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_ERR (pmsg, "remote free msg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc (); + NSFW_POINT_CHK_RET_GOTO (prsp_msg, terr, "remote free rspmsg alloc"); + + pdata_head = GET_USER_MSG (nsfw_shmem_msg_head, pmsg); + NSFW_SHMEM_MSG_HEAD_INIT (pdata_head, NSFW_RELEASE_REQ_MSG, + sizeof (nsfw_shmem_free_req)); + + pdata = NSFW_SHMEM_GET_DATA (pdata_head, nsfw_shmem_free_req); + if (EOK != STRCPY_S (pdata->aname, sizeof (pdata->aname), name)) + { + NSCOMM_LOGERR ("STRCPY_S failed]name=%s", name); + } + pdata->usseq = 0; + pdata->ustype = entype; + pdata->ireserv = 0; + + ucret = nsfw_mgr_send_req_wait_rsp (pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSCOMM_LOGERR ("free mem req rsp fail] ret=%u", ucret); + goto release; + } + + pack_head = GET_USER_MSG (nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO (pack_head, NSFW_RELEASE_ACK_MSG, + sizeof (nsfw_shmem_ack), terr); + + pack_data = NSFW_SHMEM_GET_DATA (pack_head, nsfw_shmem_ack); + NSFW_SHMEM_ACKSTATE_CHK_GOTO (NSFW_MEM_ALLOC_SUCC, pack_data->cstate, 0, + pack_data->usseq, terr); + + iretval = NSFW_MEM_OK; + goto release; +terr: + iretval = NSFW_MEM_ERR; +release: + NSFW_SHMEM_MSG_FREE (pmsg, prsp_msg); + return iretval; +} + +/* + *create a mbuf pool by send a msg + */ +mpool_handle +nsfw_remote_shmem_mbf_create (const i8 * name, unsigned n, + unsigned cache_size, unsigned priv_size, + unsigned data_room_size, i32 socket_id, + nsfw_mpool_type entype) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + nsfw_shmem_msg_head *pdata_head = NULL; + nsfw_shmem_mbuf_req *pdata = NULL; + nsfw_shmem_msg_head *tpack_head = NULL; + nsfw_shmem_ack *tpack_data = NULL; + mpool_handle hhandle = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + + pmsg = nsfw_mgr_msg_alloc (MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_NULL (pmsg, "remote mbf create pmsg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc (); + NSFW_POINT_CHK_RET_GOTO (prsp_msg, release, "remote mbf create msg alloc"); + + pdata_head = GET_USER_MSG (nsfw_shmem_msg_head, pmsg); + NSFW_SHMEM_MSG_HEAD_INIT (pdata_head, NSFW_MBUF_REQ_MSG, + sizeof (nsfw_shmem_mbuf_req)); + + pdata = NSFW_SHMEM_GET_DATA (pdata_head, nsfw_shmem_mbuf_req); + iretval = STRCPY_S (pdata->aname, sizeof (pdata->aname), name); + if (EOK != iretval) + { + NSCOMM_LOGERR ("mbf create name cpy fail] ret=%d", iretval); + goto release; + } + + NSFW_SHMEM_MBUF_DATA_INIT (pdata, 0, n, cache_size, priv_size, + data_room_size, (u16) entype, socket_id); + + ucret = nsfw_mgr_send_req_wait_rsp (pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSCOMM_LOGERR ("mbf create mem req rsp fail] ret=%u", ucret); + goto release; + } + + tpack_head = GET_USER_MSG (nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO (tpack_head, NSFW_MBUF_ACK_MSG, + sizeof (nsfw_shmem_ack), release); + + tpack_data = NSFW_SHMEM_GET_DATA (tpack_head, nsfw_shmem_ack); + NSFW_SHMEM_ACKSTATE_CHK_GOTO (NSFW_MEM_ALLOC_SUCC, tpack_data->cstate, 0, + tpack_data->usseq, release); + + hhandle = ADDR_SHTOL (tpack_data->pbase_addr); + NSCOMM_LOGDBG ("mbf create] name=%s, handle=%p, seg=%u", name, hhandle, + tpack_data->usseq); +release: + NSFW_SHMEM_MSG_FREE (pmsg, prsp_msg); + return hhandle; +} + +/* + *create some mbuf pools + */ +i32 +nsfw_remote_shmem_mbf_createv (nsfw_mem_mbfpool * pmbfname, + mpool_handle * phandle_array, i32 inum, + pid_t pid) +{ + /*msg point define */ + nsfw_mgr_msg *mbpmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + nsfw_shmem_msg_head *pdata_head = NULL; + + nsfw_shmem_mbuf_req *pdata = NULL; + nsfw_shmem_mbuf_req *ptempdata = NULL; + + nsfw_shmem_msg_head *pack_head = NULL; + + nsfw_shmem_ack *pack_data = NULL; + mpool_handle hhandle = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + i32 icount = 0; + i32 itindex = 0; + i32 iindex = 0; + i32 isegbase = 0; + i32 ieltnum = 0; + i32 ieltnum_max = + (NSFW_MGR_MSG_BODY_LEN - + sizeof (nsfw_shmem_msg_head)) / sizeof (nsfw_shmem_mbuf_req); + + mbpmsg = nsfw_mgr_msg_alloc (MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_GOTO (mbpmsg, lerr, "remote mbf createv msg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc (); + NSFW_POINT_CHK_RET_GOTO (prsp_msg, lerr, "remote mbf createv rspmsg alloc"); + + pdata_head = GET_USER_MSG (nsfw_shmem_msg_head, mbpmsg); + + ptempdata = pdata = NSFW_SHMEM_GET_DATA (pdata_head, nsfw_shmem_mbuf_req); + + do + { + icount++; + ieltnum++; + + if (((icount % ieltnum_max) == 0) || (icount >= inum)) + { + NSFW_SHMEM_MSG_HEAD_INIT (pdata_head, NSFW_MBUF_REQ_MSG, + ieltnum * sizeof (nsfw_shmem_mbuf_req)); + + /*fill msg data */ + itindex = icount - 1; + if (-1 == + SPRINTF_S (ptempdata->aname, sizeof (ptempdata->aname), "%s_%x", + pmbfname[itindex].stname.aname, pid)) + { + NSCOMM_LOGERR ("SPRINTF_S failed]"); + goto lerr; + } + NSFW_SHMEM_MBUF_DATA_INIT (ptempdata, (u16) itindex, + pmbfname[itindex].usnum, + pmbfname[itindex].uscash_size, + pmbfname[itindex].uspriv_size, + pmbfname[itindex].usdata_room, + pmbfname[itindex].enmptype, + pmbfname[itindex].isocket_id); + + ucret = nsfw_mgr_send_req_wait_rsp (mbpmsg, prsp_msg); + + if (FALSE == ucret) + { + NSCOMM_LOGERR ("mbf createv mem req rsp fail] ret=%d", ucret); + goto lerr; + } + + /*interrup msg head */ + pack_head = GET_USER_MSG (nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO (pack_head, NSFW_MBUF_ACK_MSG, + ieltnum * sizeof (nsfw_shmem_ack), + lerr); + + pack_data = NSFW_SHMEM_GET_DATA (pack_head, nsfw_shmem_ack); + + for (iindex = 0; iindex < ieltnum; iindex++) + { + NSFW_SHMEM_ACKSTATE_CHK_GOTO (NSFW_MEM_ALLOC_SUCC, + pack_data->cstate, + (isegbase + iindex), + (u16) pack_data->usseq, lerr); + phandle_array[isegbase + iindex] = + ADDR_SHTOL (pack_data->pbase_addr); + NSCOMM_LOGDBG ("mbf createv] seg=%d, handle=%p", + pack_data->usseq, hhandle); + pack_data++; + } + + isegbase = icount; + ieltnum = 0; + ptempdata = pdata; + } + else + { + itindex = icount - 1; + if (-1 == + SPRINTF_S (ptempdata->aname, sizeof (ptempdata->aname), "%s_%x", + pmbfname[itindex].stname.aname, pid)) + { + NSCOMM_LOGERR ("SPRINTF_S failed]"); + goto lerr; + } + NSFW_SHMEM_MBUF_DATA_INIT (ptempdata, (u16) itindex, + pmbfname[itindex].usnum, + pmbfname[itindex].uscash_size, + pmbfname[itindex].uspriv_size, + pmbfname[itindex].usdata_room, + pmbfname[itindex].enmptype, + pmbfname[itindex].isocket_id); + ptempdata++; + } + } + while (icount < inum); + + /*release memory */ + iretval = NSFW_MEM_OK; + goto release; + +lerr: + iretval = NSFW_MEM_ERR; +release: + NSFW_SHMEM_MSG_FREE (mbpmsg, prsp_msg); + return iretval; +} + +/* + *create a simpile pool + */ +mring_handle +nsfw_remote_shmem_mpcreate (const char *name, unsigned int n, + unsigned int elt_size, i32 socket_id, + nsfw_mpool_type entype) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + nsfw_shmem_msg_head *pdata_head = NULL; + nsfw_shmem_sppool_req *pdata = NULL; + nsfw_shmem_msg_head *mppack_head = NULL; + nsfw_shmem_ack *mppack_data = NULL; + mring_handle hhandle = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + + pmsg = nsfw_mgr_msg_alloc (MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_NULL (pmsg, "remote mbf mpcreate pmsg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc (); + NSFW_POINT_CHK_RET_GOTO (prsp_msg, release, "remote mpcreate rspmsg alloc"); + + /*init msg head */ + pdata_head = GET_USER_MSG (nsfw_shmem_msg_head, pmsg); + NSFW_SHMEM_MSG_HEAD_INIT (pdata_head, NSFW_SPPOOL_REQ_MSG, + sizeof (nsfw_shmem_sppool_req)); + + /*fill msg data */ + pdata = NSFW_SHMEM_GET_DATA (pdata_head, nsfw_shmem_sppool_req); + iretval = STRCPY_S (pdata->aname, sizeof (pdata->aname), name); + if (EOK != iretval) + { + NSCOMM_LOGERR ("mp create copy name fail] ret=%d", iretval); + goto release; + } + + /*fill msg data */ + NSFW_SHMEM_MPOOL_DATA_INIT (pdata, 0, n, elt_size, entype, socket_id); + + ucret = nsfw_mgr_send_req_wait_rsp (pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSCOMM_LOGERR ("mp create rsp fail] ret=%d", ucret); + goto release; + } + + /*get msg head */ + mppack_head = GET_USER_MSG (nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO (mppack_head, NSFW_SPPOOL_ACK_MSG, + sizeof (nsfw_shmem_ack), release); + + mppack_data = NSFW_SHMEM_GET_DATA (mppack_head, nsfw_shmem_ack); + NSFW_SHMEM_ACKSTATE_CHK_GOTO (NSFW_MEM_ALLOC_SUCC, mppack_data->cstate, 0, + mppack_data->usseq, release); + + hhandle = ADDR_SHTOL (mppack_data->pbase_addr); + NSCOMM_LOGDBG ("mpcreate] name=%s, handle=%p, seg=%d", name, hhandle, + mppack_data->usseq); +release: + NSFW_SHMEM_MSG_FREE (pmsg, prsp_msg); + return hhandle; +} + +/* + *create some simpile pools by send a msg + */ +i32 +nsfw_remote_shmem_mpcreatev (nsfw_mem_sppool * pmpinfo, + mring_handle * pringhandle_array, i32 inum, + pid_t pid) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + + /*msg head define */ + nsfw_shmem_msg_head *pdata_head = NULL; + + /*msg data define */ + nsfw_shmem_sppool_req *pdata = NULL; + nsfw_shmem_sppool_req *ptempdata = NULL; + + /*ack msg define */ + nsfw_shmem_msg_head *pack_head = NULL; + + nsfw_shmem_ack *pack_data = NULL; + mring_handle hhandle = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + i32 icount = 0; + i32 itindex = 0; + i32 iindex = 0; + i32 isegbase = 0; + i32 ieltnum = 0; + /*the max members that a msg can take */ + i32 ieltnum_max = + (NSFW_MGR_MSG_BODY_LEN - + sizeof (nsfw_shmem_msg_head)) / sizeof (nsfw_shmem_sppool_req); + + /*alloc a msg */ + //pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MASTER); + pmsg = nsfw_mgr_msg_alloc (MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_GOTO (pmsg, mperr, "remote mpcreatev pmsg alloc"); + + /*alloc rsp msg */ + prsp_msg = nsfw_mgr_null_rspmsg_alloc (); + NSFW_POINT_CHK_RET_GOTO (prsp_msg, mperr, "remote mpcreatev rspmsg alloc"); + + pdata_head = GET_USER_MSG (nsfw_shmem_msg_head, pmsg); + + ptempdata = pdata = NSFW_SHMEM_GET_DATA (pdata_head, nsfw_shmem_sppool_req); + + do + { + icount++; + ieltnum++; + + /*if the element num reach the bigest, or already send all, just deal */ + if (((icount % ieltnum_max) == 0) || (icount >= inum)) + { + /*init msg header */ + NSFW_SHMEM_MSG_HEAD_INIT (pdata_head, NSFW_SPPOOL_REQ_MSG, + ieltnum * sizeof (nsfw_shmem_sppool_req)); + + /*fill the msg data */ + itindex = icount - 1; + + int retVal = + SPRINTF_S (ptempdata->aname, sizeof (ptempdata->aname), "%s_%x", + pmpinfo[itindex].stname.aname, pid); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S fail]ret=%d", retVal); + goto mperr; + } + NSFW_SHMEM_MPOOL_DATA_INIT (ptempdata, itindex, + pmpinfo[itindex].usnum, + pmpinfo[itindex].useltsize, + pmpinfo[itindex].enmptype, + pmpinfo[itindex].isocket_id); + + ucret = nsfw_mgr_send_req_wait_rsp (pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSCOMM_LOGERR ("mpcreatev create fail] ret=%u", ucret); + goto mperr; + } + + /*interrup mgs head */ + pack_head = GET_USER_MSG (nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO (pack_head, NSFW_SPPOOL_ACK_MSG, + ieltnum * sizeof (nsfw_shmem_ack), + mperr); + + pack_data = NSFW_SHMEM_GET_DATA (pack_head, nsfw_shmem_ack); + + for (iindex = 0; iindex < ieltnum; iindex++) + { + NSFW_SHMEM_ACKSTATE_CHK_GOTO (NSFW_MEM_ALLOC_SUCC, + pack_data->cstate, + (isegbase + iindex), + (u16) pack_data->usseq, mperr); + pringhandle_array[isegbase + iindex] = + ADDR_SHTOL (pack_data->pbase_addr); + NSCOMM_LOGDBG ("mpcreatev] seg=%u, handle=%p", pack_data->usseq, + hhandle); + pack_data++; + } + + isegbase = icount; + ieltnum = 0; + ptempdata = pdata; + } + else + { + itindex = icount - 1; + int retVal = + SPRINTF_S (ptempdata->aname, sizeof (ptempdata->aname), "%s_%x", + pmpinfo[itindex].stname.aname, pid); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S fail]ret=%d", retVal); + goto mperr; + } + NSFW_SHMEM_MPOOL_DATA_INIT (ptempdata, itindex, + pmpinfo[itindex].usnum, + pmpinfo[itindex].useltsize, + pmpinfo[itindex].enmptype, + pmpinfo[itindex].isocket_id); + + ptempdata++; + } + } + while (icount < inum); + + /*release the memory */ + iretval = NSFW_MEM_OK; + goto release; + +mperr: + iretval = NSFW_MEM_ERR; +release: + NSFW_SHMEM_MSG_FREE (pmsg, prsp_msg); + return iretval; +} + +/* + *create a ring + */ +mring_handle +nsfw_remote_shmem_ringcreate (const char *name, unsigned int n, i32 socket_id, + nsfw_mpool_type entype) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + + /*msg head define */ + nsfw_shmem_msg_head *pdata_head = NULL; + + /*msg data define */ + nsfw_shmem_ring_req *pdata = NULL; + /*ack msg define */ + nsfw_shmem_msg_head *pack_head = NULL; + nsfw_shmem_ack *ppack_data = NULL; + mring_handle hhandle = NULL; + u8 ucret = TRUE; + i32 iretval = NSFW_MEM_OK; + + //pmsg = nsfw_mgr_msg_alloc(MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MASTER); + pmsg = nsfw_mgr_msg_alloc (MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_NULL (pmsg, "remote ringcreate pmsg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc (); + NSFW_POINT_CHK_RET_GOTO (prsp_msg, release, + "remote ringcreate rspmsg alloc"); + + /*fill msg head */ + pdata_head = GET_USER_MSG (nsfw_shmem_msg_head, pmsg); + NSFW_SHMEM_MSG_HEAD_INIT (pdata_head, NSFW_RING_REQ_MSG, + sizeof (nsfw_shmem_ring_req)); + + /*fill msg data */ + pdata = NSFW_SHMEM_GET_DATA (pdata_head, nsfw_shmem_ring_req); + iretval = STRCPY_S (pdata->aname, sizeof (pdata->aname), name); + if (EOK != iretval) + { + NSCOMM_LOGERR ("ring create cpy name fail] ret=%d", iretval); + goto release; + } + + /*fill msg data */ + NSFW_SHMEM_MRING_DATA_INIT (pdata, 0, n, entype, socket_id); + + ucret = nsfw_mgr_send_req_wait_rsp (pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSCOMM_LOGERR ("ring create rsp fail] ret=%d", ucret); + goto release; + } + + /*interrup mgs head */ + pack_head = GET_USER_MSG (nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO (pack_head, NSFW_RING_ACK_MSG, + sizeof (nsfw_shmem_ack), release); + + ppack_data = NSFW_SHMEM_GET_DATA (pack_head, nsfw_shmem_ack); + NSFW_SHMEM_ACKSTATE_CHK_GOTO (NSFW_MEM_ALLOC_SUCC, ppack_data->cstate, 0, + ppack_data->usseq, release); + + hhandle = ADDR_SHTOL (ppack_data->pbase_addr); + NSCOMM_LOGDBG ("ring create] name=%s, handle=%p, seg=%u", name, hhandle, + ppack_data->usseq); +release: + NSFW_SHMEM_MSG_FREE (pmsg, prsp_msg); + return hhandle; +} + +/* + *create a mem pool that the members are rings by send a msg + *ieltnum:the num of ring member + *iringnum:the num of ring in simple mem pook + *entype:the defualt the of ring + */ +i32 +nsfw_remote_shmem_ringcreatev (const char *name, i32 ieltnum, + mring_handle * pringhandle_array, i32 iringnum, + i32 socket_id, nsfw_mpool_type entype) +{ + unsigned int useltsize = 0; + mring_handle nhandle = NULL; + i32 icount = 0; + i32 n = 0; + uint64_t baseaddr = 0; + uint64_t endaddr = 0; + /*the num of ring member must be power of 2 */ + unsigned int usnum = common_mem_align32pow2 (ieltnum + 1); + + useltsize = + sizeof (struct nsfw_mem_ring) + usnum * sizeof (union RingData_U); + nhandle = + nsfw_remote_shmem_mpcreate (name, iringnum, useltsize, socket_id, + NSFW_MRING_SPSC); + NSFW_POINT_CHK_RET_ERR (nhandle, "remote ringcreatev msg alloc"); + + n = + nsfw_shmem_ring_sc_dequeuev (nhandle, (void **) pringhandle_array, + iringnum); + + if (n != iringnum) + { + NSCOMM_LOGERR ("ring dequeue fail] ringnum=%d, retnum=%d", iringnum, n); + return NSFW_MEM_ERR; + } + + nsfw_shmem_ring_baseaddr_query (&baseaddr, &endaddr); + + for (icount = 0; icount < iringnum; icount++) + { + nsfw_mem_ring_init (pringhandle_array[icount], usnum, (void *) baseaddr, + NSFW_SHMEM, entype); + } + + return NSFW_MEM_OK; +} + +/* + *look up a msg by send a msg + */ +void * +nsfw_remote_shmem_lookup (const i8 * name, nsfw_mem_struct_type entype) +{ + /*msg point define */ + nsfw_mgr_msg *pmsg = NULL; + nsfw_mgr_msg *prsp_msg = NULL; + void *addr = NULL; + /*msg head data define */ + nsfw_shmem_msg_head *pdata_head = NULL; + + /*msg data define */ + nsfw_shmem_lookup_req *pdata = NULL; + + /*ack msg define */ + nsfw_shmem_msg_head *pack_head = NULL; + nsfw_shmem_ack *lpack_data = NULL; + u8 ucret = TRUE; + + pmsg = nsfw_mgr_msg_alloc (MGR_MSG_MEM_ALLOC_REQ, NSFW_PROC_MAIN); + NSFW_POINT_CHK_RET_NULL (pmsg, "remote lookup pmsg alloc"); + + prsp_msg = nsfw_mgr_null_rspmsg_alloc (); + NSFW_POINT_CHK_RET_GOTO (prsp_msg, perr, "remote lookup rspmsg alloc"); + + /*msg head init */ + pdata_head = GET_USER_MSG (nsfw_shmem_msg_head, pmsg); + NSFW_SHMEM_MSG_HEAD_INIT (pdata_head, NSFW_MEM_LOOKUP_REQ_MSG, + sizeof (nsfw_shmem_lookup_req)); + + pdata = NSFW_SHMEM_GET_DATA (pdata_head, nsfw_shmem_lookup_req); + if (EOK != STRCPY_S (pdata->aname, sizeof (pdata->aname), name)) + { + NSCOMM_LOGERR ("STRCPY_S faild]name=%s", name); + } + pdata->usseq = 0; + pdata->ustype = entype; + pdata->ireserv = 0; + + ucret = nsfw_mgr_send_req_wait_rsp (pmsg, prsp_msg); + + if (FALSE == ucret) + { + NSCOMM_LOGERR ("mem lookup fail] ret=%u", ucret); + goto release; + } + + /*interrup mgs head */ + pack_head = GET_USER_MSG (nsfw_shmem_msg_head, prsp_msg); + NSFW_SHMEM_MSGHEAD_CHK_GOTO (pack_head, NSFW_MEM_LOOKUP_ACK_MSG, + sizeof (nsfw_shmem_ack), perr); + + lpack_data = NSFW_SHMEM_GET_DATA (pack_head, nsfw_shmem_ack); + NSFW_SHMEM_ACKSTATE_CHK_GOTO (NSFW_MEM_ALLOC_SUCC, lpack_data->cstate, 0, + lpack_data->usseq, perr); + + addr = ADDR_SHTOL (lpack_data->pbase_addr); + NSCOMM_LOGDBG ("shmem lookup] name=%s, handle=%p, seg=%u", name, addr, + lpack_data->usseq); + goto release; +perr: + addr = NULL; + +release: + NSFW_SHMEM_MSG_FREE (pmsg, prsp_msg); + return addr; +} diff --git a/src/framework/common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.h b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.h new file mode 100644 index 0000000..60c4115 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_rshmem_mng.h @@ -0,0 +1,51 @@ +/* +* +* 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 _NSFW_RSHMEM_MNG_H +#define _NSFW_RSHMEM_MNG_H + +mzone_handle nsfw_memzone_remote_reserv (const i8 * name, size_t mlen, + i32 socket_id); +i32 nsfw_memzone_remote_reserv_v (nsfw_mem_zone * pmeminfo, + mzone_handle * paddr_array, i32 inum, + pid_t pid); +i32 nsfw_remote_free (const i8 * name, nsfw_mem_struct_type entype); +mpool_handle nsfw_remote_shmem_mbf_create (const i8 * name, unsigned int n, + unsigned cache_size, + unsigned priv_size, + unsigned data_room_size, + i32 socket_id, + nsfw_mpool_type entype); +i32 nsfw_remote_shmem_mbf_createv (nsfw_mem_mbfpool * pmbfname, + mpool_handle * phandle_array, i32 inum, + pid_t pid); +mring_handle nsfw_remote_shmem_mpcreate (const char *name, unsigned int n, + unsigned int elt_size, i32 socket_id, + nsfw_mpool_type entype); +i32 nsfw_remote_shmem_mpcreatev (nsfw_mem_sppool * pmpinfo, + mring_handle * pringhandle_array, i32 inum, + pid_t pid); +mring_handle nsfw_remote_shmem_ringcreate (const char *name, unsigned int n, + i32 socket_id, + nsfw_mpool_type entype); +i32 nsfw_remote_shmem_ringcreatev (const char *name, i32 ieltnum, + mring_handle * pringhandle_array, + i32 iringnum, i32 socket_id, + nsfw_mpool_type entype); + +void *nsfw_remote_shmem_lookup (const i8 * name, nsfw_mem_struct_type entype); + +#endif diff --git a/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.c b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.c new file mode 100644 index 0000000..e7a11ad --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.c @@ -0,0 +1,47 @@ +/* +* +* 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 "nsfw_mem_desc.h" +#include "nsfw_shmem_mng.h" +#include "nsfw_shmem_mdesc.h" + +/*the inferaces accessing memory*/ +nsfw_mem_ops g_shmem_ops = { + nsfw_shmem_init, + nsfw_shmem_destroy, + nsfw_shmem_create, + nsfw_shmem_createv, + nsfw_shmem_lookup, + nsfw_shmem_release, + nsfw_shmem_mbfmpcreate, + nsfw_shmem_mbfmpcreatev, + nsfw_shmem_mbfalloc, + nsfw_shmem_mbffree, + nsfw_shmem_mbfmplookup, + nsfw_shmem_mbfmprelease, + nsfw_shmem_spcreate, + nsfw_shmem_spcreatev, + nswf_shmem_sp_ringcreate, + nsfw_shmem_sprelease, + nsfw_shmem_sp_lookup, + nsfw_shmem_ringcreate, + nsfw_shmem_ring_lookup, + nsfw_shmem_ringrelease, + nsfw_shmem_stactic, + nsfw_shmem_mbuf_recycle, + nsfw_shmem_sp_iterator, + nsfw_shmem_mbuf_iterator +}; diff --git a/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.h b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.h new file mode 100644 index 0000000..afd9e29 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mdesc.h @@ -0,0 +1,22 @@ +/* +* +* 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 _NSFW_SHMEM_MDESC_H_ +#define _NSFW_SHMEM_MDESC_H_ + +extern nsfw_mem_ops g_shmem_ops; + +#endif diff --git a/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.c b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.c new file mode 100644 index 0000000..f85e70d --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.c @@ -0,0 +1,880 @@ +/* +* +* 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_securec.h" +#include "nstack_log.h" +#include "nsfw_mem_desc.h" +#include "nsfw_ring_fun.h" +#include "nsfw_shmem_ring.h" +#include "nsfw_shmem_mng.h" +#include "common_mem_mempool.h" +#include "common_mem_memzone.h" +#include "common_mem_buf.h" +#include "common_mem_mbuf.h" +#include "nsfw_rshmem_mng.h" +#include "common_mem_api.h" +#include "common_sys_config.h" +#include "nsfw_maintain_api.h" +#include "common_pal_bitwide_adjust.h" + +#include "common_mem_pal.h" + +#include "common_func.h" + +#define NSFW_SHMEM_PID (get_sys_pid()) +#define NSFW_SHMEM_FLAG (g_shmem_localdata->enflag) + +nsfw_mem_localdata *g_shmem_localdata = NULL; + +/*check g_mem_localdata*/ +#define NSFW_INIT_CHK_RET() \ + if (!g_shmem_localdata) \ + { \ + return NSFW_MEM_ERR; \ + } + +#define NSFW_INIT_CHK_RET_NULL() \ + if (!g_shmem_localdata) \ + { \ + return NULL; \ + } + +/* + *share memory mng module init + * + */ +i32 +nsfw_shmem_init (nsfw_mem_para * para) +{ + common_mem_pal_module_info rteinfo = { 0 }; + i32 iret = NSFW_MEM_ERR; + int flag = 0; + if (!para) + { + return NSFW_MEM_ERR; + } + + NSCOMM_LOGINF ("nsfw shmem init begin"); + + if (NSFW_PROC_MASTER == para->enflag) + { + iret = common_mem_pal_init (para->iargsnum, para->pargs); + } + else if (NSFW_PROC_MAIN == para->enflag) + { + iret = common_pal_module_init (NULL); + } + else + { + LCORE_MASK_SET (rteinfo.ilcoremask, 1); + rteinfo.ucproctype = DMM_PROC_T_SECONDARY; + iret = common_pal_module_init (&rteinfo); + } + + if (NSFW_MEM_OK != iret) + { + NSCOMM_LOGERR ("rte init fail] ret=0x%x", iret); + return NSFW_MEM_ERR; + } + + flag = dmm_pal_addr_align (); + if ((0 == flag) && (NSFW_PROC_MAIN == para->enflag)) + { + dmm_addr_print (); + NSCOMM_LOGERR + ("rte init addr is not the same with primary] nstackmain flag=%d", + flag); + return NSFW_MEM_ERR; + } + + g_shmem_localdata = + (nsfw_mem_localdata *) malloc (sizeof (nsfw_mem_localdata)); + + if (NULL == g_shmem_localdata) + { + NSCOMM_LOGERR ("g_shmem_localdata malloc fail"); + return NSFW_MEM_ERR; + } + + iret = + MEMSET_S (g_shmem_localdata, sizeof (nsfw_mem_localdata), 0, + sizeof (nsfw_mem_localdata)); + if (EOK != iret) + { + NSCOMM_LOGERR ("memset fail] g_shmem_localdata=%p ", g_shmem_localdata); + free (g_shmem_localdata); + g_shmem_localdata = NULL; + return NSFW_MEM_ERR; + } + + g_shmem_localdata->enflag = para->enflag; + + NSCOMM_LOGINF ("nsfw shmem init end] enflag=%d", para->enflag); + return NSFW_MEM_OK; + +} + +/* + *module destroy + */ +void +nsfw_shmem_destroy (void) +{ + if (g_shmem_localdata) + { + free (g_shmem_localdata); + g_shmem_localdata = NULL; + } + + return; +} + +/* + * create a shared memory + * nsfw_mem_zone::stname memory name + * nsfw_mem_zone::isize + */ +mzone_handle +nsfw_shmem_create (nsfw_mem_zone * pinfo) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + + NSFW_INIT_CHK_RET_NULL ()if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return common_memzone_data_reserve_name (pinfo->stname.aname, + pinfo->lenth, + pinfo->isocket_id); + } + else + { + /*app must less than NSFW_MEM_APPNAME_LENTH */ + NSFW_NAME_LENCHECK_RET_NULL (pinfo->stname.aname, "shmem create") + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pinfo->stname.aname, NSFW_SHMEM_PID)) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + return NULL; + } + } + + return nsfw_memzone_remote_reserv ((char *) &aname[0], pinfo->lenth, + SOCKET_ID_ANY); +} + +/* + *create some memory + *inum must be equal iarray_num + */ +i32 +nsfw_shmem_createv (nsfw_mem_zone * pmeminfo, i32 inum, + mzone_handle * paddr_array, i32 iarray_num) +{ + NSFW_INIT_CHK_RET (); + + if (NSFW_PROC_MASTER == NSFW_SHMEM_FLAG) + { + return NSFW_MEM_ERR; + } + else if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return nsfw_memzone_remote_reserv_v (pmeminfo, paddr_array, iarray_num, + 0); + } + else + { + return nsfw_memzone_remote_reserv_v (pmeminfo, paddr_array, iarray_num, + NSFW_SHMEM_PID); + } + return NSFW_MEM_ERR; +} + +mzone_handle +nsfw_shmem_lookup (nsfw_mem_name * pname) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + NSFW_INIT_CHK_RET_NULL (); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return common_memzone_data_lookup_name (pname->aname); + } + + if ((NSFW_PROC_NULL == pname->enowner) + || (NSFW_PROC_MAIN == pname->enowner)) + { + int retVal = + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s", pname->aname); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S faild"); + return NULL; + } + } + else + { + /*app must less than NSFW_MEM_APPNAME_LENTH */ + NSFW_NAME_LENCHECK_RET_NULL (pname->aname, "shmem lookup") + int retVal = + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", pname->aname, + NSFW_SHMEM_PID); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S faild"); + return NULL; + } + } + + return nsfw_remote_shmem_lookup (aname, NSFW_MEM_MZONE); +} + +i32 +nsfw_shmem_release (nsfw_mem_name * pname) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + const struct common_mem_memzone *pmzone = NULL; + NSFW_INIT_CHK_RET (); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + pmzone = common_mem_memzone_lookup (pname->aname); + + if (pmzone) + { + common_mem_memzone_free (pmzone); + } + return NSFW_MEM_OK; + } + else + { + NSFW_NAME_LENCHECK_RET (pname->aname, "shmem free") + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pname->aname, NSFW_SHMEM_PID)) + { + NSCOMM_LOGERR ("SPRINTF_S faild"); + return NSFW_MEM_ERR; + } + } + + return nsfw_remote_free (aname, NSFW_MEM_MZONE); +} + +mpool_handle +nsfw_shmem_mbfmpcreate (nsfw_mem_mbfpool * pbufinfo) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + + NSFW_INIT_CHK_RET_NULL (); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return common_mem_pktmbuf_pool_create (pbufinfo->stname.aname, + pbufinfo->usnum, + pbufinfo->uscash_size, + pbufinfo->uspriv_size, + pbufinfo->usdata_room, + pbufinfo->isocket_id); + } + else + { + /*app must less than NSFW_MEM_APPNAME_LENTH */ + NSFW_NAME_LENCHECK_RET_NULL (pbufinfo->stname.aname, "mbufpool create") + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pbufinfo->stname.aname, NSFW_SHMEM_PID)) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + } + } + + return nsfw_remote_shmem_mbf_create (aname, pbufinfo->usnum, + pbufinfo->uscash_size, + pbufinfo->uspriv_size, + pbufinfo->usdata_room, SOCKET_ID_ANY, + pbufinfo->enmptype); +} + +/* + *create some mbuf pools + */ +i32 +nsfw_shmem_mbfmpcreatev (nsfw_mem_mbfpool * pmbfname, i32 inum, + mpool_handle * phandle_array, i32 iarray_num) +{ + NSFW_INIT_CHK_RET (); + + if (NSFW_PROC_MASTER == NSFW_SHMEM_FLAG) + { + return NSFW_MEM_ERR; + } + else if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return nsfw_remote_shmem_mbf_createv (pmbfname, phandle_array, + iarray_num, 0); + } + else + { + return nsfw_remote_shmem_mbf_createv (pmbfname, phandle_array, + iarray_num, NSFW_SHMEM_PID); + } + + return NSFW_MEM_ERR; +} + +mbuf_handle +nsfw_shmem_mbfalloc (mpool_handle mhandle) +{ + return (mbuf_handle) common_mem_pktmbuf_alloc ((struct common_mem_mempool *) + mhandle); +} + +i32 +nsfw_shmem_mbffree (mbuf_handle mhandle) +{ + common_mem_pktmbuf_free ((struct common_mem_mbuf *) mhandle); + return NSFW_MEM_OK; +} + +i32 +nsfw_shmem_mbfmprelease (nsfw_mem_name * pname) +{ + return NSFW_MEM_OK; +} + +mpool_handle +nsfw_shmem_mbfmplookup (nsfw_mem_name * pmbfname) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + + NSFW_INIT_CHK_RET_NULL (); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return common_mem_mempool_lookup (pmbfname->aname); + } + + if ((NSFW_PROC_NULL == pmbfname->enowner) + || (NSFW_PROC_MAIN == pmbfname->enowner)) + { + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s", + pmbfname->aname)) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + } + } + else + { + /*app must less than NSFW_MEM_APPNAME_LENTH */ + NSFW_NAME_LENCHECK_RET_NULL (pmbfname->aname, "shmem lookup") + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pmbfname->aname, NSFW_SHMEM_PID)) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + } + } + + return nsfw_remote_shmem_lookup (aname, NSFW_MEM_MBUF); +} + +mring_handle +nsfw_shmem_spcreate (nsfw_mem_sppool * pmpinfo) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + + NSFW_INIT_CHK_RET_NULL (); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return nsfw_shmem_pool_create (pmpinfo->stname.aname, pmpinfo->usnum, + pmpinfo->useltsize, pmpinfo->isocket_id, + pmpinfo->enmptype); + } + else + { + NSFW_NAME_LENCHECK_RET_NULL (pmpinfo->stname.aname, "mpool create") + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pmpinfo->stname.aname, NSFW_SHMEM_PID)) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + } + } + + return nsfw_remote_shmem_mpcreate (aname, pmpinfo->usnum, + pmpinfo->useltsize, SOCKET_ID_ANY, + pmpinfo->enmptype); +} + +i32 +nsfw_shmem_spcreatev (nsfw_mem_sppool * pmpinfo, i32 inum, + mring_handle * pringhandle_array, i32 iarray_num) +{ + NSFW_INIT_CHK_RET (); + + if (NSFW_PROC_MASTER == NSFW_SHMEM_FLAG) + { + return NSFW_MEM_ERR; + } + else if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return nsfw_remote_shmem_mpcreatev (pmpinfo, pringhandle_array, inum, + 0); + } + else + { + return nsfw_remote_shmem_mpcreatev (pmpinfo, pringhandle_array, inum, + NSFW_SHMEM_PID); + } + return NSFW_MEM_ERR; +} + +i32 +nsfw_lshmem_ringcreatev (const char *name, i32 ieltnum, + mring_handle * pringhandle_array, i32 iringnum, + i32 socket_id, nsfw_mpool_type entype) +{ + i32 useltsize = 0; + mring_handle nhandle = NULL; + i32 icount = 0; + i32 n = 0; + uint64_t baseaddr = 0; + uint64_t endaddr = 0; + i32 usnum = common_mem_align32pow2 (ieltnum + 1); + + useltsize = + sizeof (struct nsfw_mem_ring) + usnum * sizeof (union RingData_U); + nhandle = + nsfw_shmem_pool_create (name, iringnum, useltsize, socket_id, + NSFW_MRING_SPSC); + if (NULL == (nhandle)) + { + return NSFW_MEM_ERR; + } + + n = + nsfw_shmem_ring_sc_dequeuev (nhandle, (void **) pringhandle_array, + iringnum); + + if (n != iringnum) + { + NSCOMM_LOGERR + ("ring dequeuev failed] ring=%p, dequeue num=%d, expect num=%d", + nhandle, n, iringnum); + return NSFW_MEM_ERR; + } + + nsfw_shmem_ring_baseaddr_query (&baseaddr, &endaddr); + + for (icount = 0; icount < iringnum; icount++) + { + nsfw_mem_ring_init (pringhandle_array[icount], usnum, (void *) baseaddr, + NSFW_SHMEM, entype); + } + + return NSFW_MEM_OK; +} + +i32 +nswf_shmem_sp_ringcreate (nsfw_mem_mring * prpoolinfo, + mring_handle * pringhandle_array, i32 iringnum) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + + NSFW_INIT_CHK_RET (); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return nsfw_lshmem_ringcreatev (prpoolinfo->stname.aname, + prpoolinfo->usnum, pringhandle_array, + iringnum, SOCKET_ID_ANY, + prpoolinfo->enmptype); + } + else + { + NSFW_NAME_LENCHECK_RET (prpoolinfo->stname.aname, "ring pool") + int retVal = SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + prpoolinfo->stname.aname, NSFW_SHMEM_PID); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + } + } + + return nsfw_remote_shmem_ringcreatev (aname, prpoolinfo->usnum, + pringhandle_array, iringnum, + SOCKET_ID_ANY, prpoolinfo->enmptype); +} + +i32 +nsfw_shmem_sprelease (nsfw_mem_name * pname) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + void *mz_mem = NULL; + struct nsfw_mem_ring *ring_ptr = NULL; + NSFW_INIT_CHK_RET (); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + mz_mem = common_memzone_data_lookup_name (pname->aname); + + if (mz_mem) + { + ring_ptr = + (struct nsfw_mem_ring *) ((char *) mz_mem + + sizeof (struct nsfw_shmem_ring_head)); + nsfw_shmem_pool_free (ring_ptr); + } + return NSFW_MEM_OK; + } + else + { + NSFW_NAME_LENCHECK_RET (pname->aname, "shmem free") + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pname->aname, NSFW_SHMEM_PID)) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + } + } + + return nsfw_remote_free (aname, NSFW_MEM_SPOOL); +} + +mring_handle +nsfw_shmem_sp_lookup (nsfw_mem_name * pname) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + void *mz_mem = NULL; + struct nsfw_mem_ring *ring_ptr = NULL; + NSFW_INIT_CHK_RET_NULL (); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + mz_mem = common_memzone_data_lookup_name (pname->aname); + + if (mz_mem) + { + ring_ptr = + (struct nsfw_mem_ring *) ((char *) mz_mem + + sizeof (struct nsfw_shmem_ring_head)); + return ring_ptr; + } + return mz_mem; + } + + if ((NSFW_PROC_NULL == pname->enowner) + || (NSFW_PROC_MAIN == pname->enowner)) + { + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s", pname->aname)) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + } + } + else + { + /*app's name can not over NSFW_MEM_APPNAME_LENTH */ + NSFW_NAME_LENCHECK_RET_NULL (pname->aname, "shmem lookup") + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pname->aname, NSFW_SHMEM_PID)) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + } + } + + return nsfw_remote_shmem_lookup (aname, NSFW_MEM_SPOOL); +} + +mring_handle +nsfw_shmem_ringcreate (nsfw_mem_mring * pringinfo) +{ + i8 aname[COMMON_MEM_MEMPOOL_NAMESIZE] = { 0 }; + + NSFW_INIT_CHK_RET_NULL (); + + if (NSFW_PROC_MAIN == NSFW_SHMEM_FLAG) + { + return nsfw_shmem_ring_create (pringinfo->stname.aname, + pringinfo->usnum, pringinfo->isocket_id, + pringinfo->enmptype); + } + else + { + NSFW_NAME_LENCHECK_RET_NULL (pringinfo->stname.aname, "ring create") + if (-1 == + SPRINTF_S (aname, COMMON_MEM_MEMPOOL_NAMESIZE, "%s_%x", + pringinfo->stname.aname, NSFW_SHMEM_PID)) + { + NSCOMM_LOGERR ("SPRINTF_S faild]"); + } + } + + return nsfw_remote_shmem_ringcreate (aname, pringinfo->usnum, SOCKET_ID_ANY, + pringinfo->enmptype); +} + +mring_handle +nsfw_shmem_ring_lookup (nsfw_mem_name * pname) +{ + return nsfw_shmem_lookup (pname); +} + +i32 +nsfw_shmem_ringrelease (nsfw_mem_name * pname) +{ + return nsfw_shmem_release (pname); +} + +size_t +nsfw_shmem_mbufpool_statics (mpool_handle mbufpool) +{ + struct common_mem_mempool *mp = (struct common_mem_mempool *) mbufpool; + return (size_t) mp->size * (mp->header_size + mp->elt_size + + mp->trailer_size) + + (size_t) mp->private_data_size + + (size_t) + common_mem_ring_get_memsize (common_mem_align32pow2 (mp->size + 1)); +} + +size_t +nsfw_shmem_sppool_statics (mring_handle sppool) +{ + struct nsfw_shmem_ring_head *temp = NULL; + size_t lent = 0; + temp = + (struct nsfw_shmem_ring_head *) ((char *) sppool - + sizeof (struct nsfw_shmem_ring_head)); + + while (temp) + { + lent += temp->mem_zone->len; + temp = temp->next; + } + + return lent; +} + +size_t +nsfw_shmem_ring_statics (mring_handle handle) +{ + struct nsfw_mem_ring *ring = (struct nsfw_mem_ring *) handle; + return ring->size * sizeof (union RingData_U) + + sizeof (struct nsfw_mem_ring); +} + +ssize_t +nsfw_shmem_stactic (void *handle, nsfw_mem_struct_type type) +{ + switch (type) + { + case NSFW_MEM_MBUF: + return nsfw_shmem_mbufpool_statics (handle); + case NSFW_MEM_SPOOL: + return nsfw_shmem_sppool_statics (handle); + case NSFW_MEM_RING: + return nsfw_shmem_ring_statics (handle); + default: + break; + } + return -1; +} + +i32 +nsfw_shmem_mbuf_recycle (mpool_handle handle) +{ +#if 0 + const struct common_mem_mempool *mp = (struct common_mem_mempool *) handle; + struct common_mem_ring *rteRing = NULL; + struct common_mem_mbuf *m_buf = NULL; + uint32_t item; + u32_t *recycle_flg; + uint32_t size = mp->size; + uint32_t threadsize = (size >> 2) * 3; + rteRing = (struct common_mem_ring *) ADDR_SHTOL (mp->ring); + + if (rteRing->prod.tail - rteRing->cons.head < threadsize) + { + for (item = 0; item < size - 1; item++) + { + m_buf = (struct common_mem_mbuf *) ADDR_SHTOL (mp->elt_va_start + item * (mp->header_size + mp->elt_size + mp->trailer_size) + mp->header_size); /*lint !e647 */ + recycle_flg = + (uint32_t *) ((char *) (ADDR_SHTOL (m_buf->buf_addr_align)) + + RTE_PKTMBUF_HEADROOM - sizeof (uint32_t)); + + if (m_buf->refcnt > 0 && *recycle_flg == MBUF_HLD_BY_APP) + { + NSCOMM_LOGINF ("free mbuf hold by app]ring=%p, mbuf=%p", handle, + m_buf); + *recycle_flg = MBUF_UNUSED; + common_mem_pktmbuf_free (m_buf); + } + } + } + + NSCOMM_LOGINF ("To recycle app_tx_pool now]ring=%p,prod.head=%u," + "prod.tail=%u,cons.head=%u,cons.tail=%u.", handle, + rteRing->prod.head, rteRing->prod.tail, + rteRing->cons.head, rteRing->cons.tail); + + /*we Must check and recorrect the Queue if Queue is not correct + 1.if proc.head != proc.tail set proc.head to proc.tail [may lost some buf,but the queue still can use] + App May not putIn Data , just done head++, we can't set proc.tail to proc.head. + 2.if cons.head != cons.tail set cons.tail to cons.head [may lost some buf,but the queue still can use] + App May alread finish deque,just not tail++, we can't set cons.head to cons.tail. + */ + if ((rteRing->prod.head != rteRing->prod.tail) + || (rteRing->cons.head != rteRing->cons.tail)) + { + rteRing->prod.head = rteRing->prod.tail; + rteRing->cons.tail = rteRing->cons.head; + } +#endif + return NSFW_MEM_OK; +} + +/***************************************************************************** +* Prototype : nsfw_shmem_sp_iterator +* Description : sp pool iterator +* Input : mpool_handle handle +* u32 start +* u32 end +* nsfw_mem_item_fun fun +* void *argv +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_shmem_sp_iterator (mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv) +{ + struct nsfw_mem_ring *perfring_ptr = (struct nsfw_mem_ring *) handle; + if (NULL == perfring_ptr || NULL == fun) + { + return 0; + } + + if (0 == perfring_ptr->eltsize) + { + return 0; + } + + int num = perfring_ptr->size; + if (start >= (u32) num || end <= start) + { + return 0; + } + + struct nsfw_shmem_ring_head *ring_head = + (struct nsfw_shmem_ring_head *) ((char *) handle - + sizeof (struct nsfw_shmem_ring_head)); + void *mz = + (void *) ((char *) perfring_ptr + sizeof (struct nsfw_mem_ring) + + num * sizeof (union RingData_U)); + + if (ring_head->mem_zone->len < + sizeof (struct nsfw_shmem_ring_head) + sizeof (struct nsfw_mem_ring) + + num * sizeof (union RingData_U)) + { + return 0; + } + + u32 mz_len = + ring_head->mem_zone->len - sizeof (struct nsfw_shmem_ring_head) - + sizeof (struct nsfw_mem_ring) - num * sizeof (union RingData_U); + + u32 start_idx = 0; + u32 elm_num = 0; + elm_num = mz_len / perfring_ptr->eltsize; + while (start > start_idx + elm_num) + { + if (NULL == ring_head->next || NULL == ring_head->next->mem_zone + || 0 == elm_num) + { + return 0; + } + + ring_head = + (struct nsfw_shmem_ring_head *) ring_head->next->mem_zone->addr_64; + mz_len = + ring_head->mem_zone->len - sizeof (struct nsfw_shmem_ring_head); + + elm_num = mz_len / perfring_ptr->eltsize; + mz = + (void *) ((char *) ring_head + sizeof (struct nsfw_shmem_ring_head)); + start_idx += elm_num; + } + + u32 cur_idx = start - start_idx; + char *cur_elm = NULL; + int proc_count = 0; + while (cur_idx + start_idx < end && cur_idx + start_idx < (u32) num) + { + if (cur_idx >= elm_num) + { + if (NULL == ring_head->next || NULL == ring_head->next->mem_zone + || 0 == elm_num) + { + break; + } + + ring_head = + (struct nsfw_shmem_ring_head *) ring_head->next-> + mem_zone->addr_64; + mz_len = + ring_head->mem_zone->len - sizeof (struct nsfw_shmem_ring_head); + + elm_num = mz_len / perfring_ptr->eltsize; + mz = + (void *) ((char *) ring_head + + sizeof (struct nsfw_shmem_ring_head)); + start_idx += elm_num; + + cur_idx = 0; + cur_elm = NULL; + continue; + } + + if (NULL == cur_elm) + { + cur_elm = ((char *) mz + cur_idx * perfring_ptr->eltsize); + } + else + { + cur_elm += perfring_ptr->eltsize; + } + + cur_idx++; + proc_count++; + (void) fun (cur_elm, argv); + } + + return proc_count; +} + +i32 +nsfw_shmem_mbuf_iterator (mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv) +{ + return dmm_pktmbuf_pool_iterator ((struct common_mem_mempool *) handle, + start, end, (dmm_mbuf_item_fun) fun, + argv); +} diff --git a/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.h b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.h new file mode 100644 index 0000000..f81b34a --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_mng.h @@ -0,0 +1,133 @@ +/* +* +* 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 _NSFW_SHMEM_MNG_H +#define _NSFW_SHMEM_MNG_H + +/* + * mem mgr module init + * para:point to nstak_fwmem_para + */ +i32 nsfw_shmem_init (nsfw_mem_para * para); + +/* + * mem mgr module destory + * + */ +void nsfw_shmem_destroy (void); + +/* + * create a block memory with name + * fw_mem_zone::stname name of memory + * fw_mem_zone::isize memory size + */ +mzone_handle nsfw_shmem_create (nsfw_mem_zone * pinfo); + +/* + *create some blocks memeory + */ +i32 nsfw_shmem_createv (nsfw_mem_zone * pmeminfo, i32 inum, + mzone_handle * paddr_array, i32 iarray_num); + +/* + *lookup a memory + */ +mzone_handle nsfw_shmem_lookup (nsfw_mem_name * pname); + +/*release the memory*/ +i32 nsfw_shmem_release (nsfw_mem_name * pname); + +/* + *create mbuf pool + */ +mpool_handle nsfw_shmem_mbfmpcreate (nsfw_mem_mbfpool * pbufinfo); + +/* + *create some mbuf pool + */ +i32 nsfw_shmem_mbfmpcreatev (nsfw_mem_mbfpool * pmbfname, i32 inum, + mpool_handle * phandle_array, i32 iarray_num); + +/* + *alloc a mbuf from mbuf pool + */ +mbuf_handle nsfw_shmem_mbfalloc (mpool_handle mhandle); + +/* + *release a mbuf pool + */ +i32 nsfw_shmem_mbffree (mbuf_handle mhandle); + +/* + *put mbuf backto mbuf pool + */ +i32 nsfw_shmem_mbfmprelease (nsfw_mem_name * pname); + +/*look up mbuf mpool*/ +mpool_handle nsfw_shmem_mbfmplookup (nsfw_mem_name * pmbfname); + +/* + *create simple pool + */ +mring_handle nsfw_shmem_spcreate (nsfw_mem_sppool * pmpinfo); + +/* + *create some simple pools + */ +i32 nsfw_shmem_spcreatev (nsfw_mem_sppool * pmpinfo, i32 inum, + mring_handle * pringhandle_array, i32 iarray_num); + +/* + *create a simple pool that members are rings + */ +i32 nswf_shmem_sp_ringcreate (nsfw_mem_mring * prpoolinfo, + mring_handle * pringhandle_array, i32 iringnum); + +/* + *release a simple pool + */ +i32 nsfw_shmem_sprelease (nsfw_mem_name * pname); + +/* + *look up a simple pool + */ +mring_handle nsfw_shmem_sp_lookup (nsfw_mem_name * pname); + +/* + *create a ring with name + */ +mring_handle nsfw_shmem_ringcreate (nsfw_mem_mring * pringinfo); + +/* + *look up a ring with name + */ +mring_handle nsfw_shmem_ring_lookup (nsfw_mem_name * pname); + +/* + *release ring + */ +i32 nsfw_shmem_ringrelease (nsfw_mem_name * pname); + +ssize_t nsfw_shmem_stactic (void *handle, nsfw_mem_struct_type type); + +i32 nsfw_shmem_mbuf_recycle (mpool_handle handle); + +i32 nsfw_shmem_sp_iterator (mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv); +i32 nsfw_shmem_mbuf_iterator (mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv); + +#endif diff --git a/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.c b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.c new file mode 100644 index 0000000..af46e18 --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.c @@ -0,0 +1,839 @@ +/* +* +* 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 + +#include "common_mem_pal.h" +#include "common_mem_pal_memconfig.h" +#include "nstack_securec.h" +#include "nsfw_shmem_ring.h" +#include "nsfw_ring_fun.h" +#include "common_mem_buf.h" +#include "common_func.h" + +void +nsfw_shmem_ring_baseaddr_query (uint64_t * rte_lowest_addr, + uint64_t * rte_highest_addr) +{ + struct common_mem_mem_config *pMemCfg = + common_mem_pal_get_configuration ()->mem_config; + struct common_mem_memseg *PMemSegArry = pMemCfg->memseg; + + *rte_lowest_addr = PMemSegArry[0].addr_64; + *rte_highest_addr = PMemSegArry[0].addr_64 + PMemSegArry[0].len; + + int s = 1; + + while (s < COMMON_MEM_MAX_MEMSEG && PMemSegArry[s].len > 0) + { + if (*rte_lowest_addr > PMemSegArry[s].addr_64) + { + *rte_lowest_addr = PMemSegArry[s].addr_64; + } + + if (*rte_highest_addr < PMemSegArry[s].addr_64 + PMemSegArry[s].len) + { + *rte_highest_addr = PMemSegArry[s].addr_64 + PMemSegArry[s].len; + } + + s++; + } + +} + +static unsigned +nsfw_shmem_pool_node_alloc (struct nsfw_mem_ring *perfring_ptr, + unsigned alloc_index, unsigned max_index, + void *mz, size_t mz_len, unsigned elt_size) +{ + size_t alloc_size = 0; + unsigned offset_idx = 0; + NSTCP_LOGINF ("mz(%p), mz_len = 0x%x", mz, mz_len); + + while (alloc_size + elt_size <= mz_len) + { + perfring_ptr->ring[alloc_index + offset_idx].data_s.ver = + alloc_index + offset_idx; + perfring_ptr->ring[alloc_index + offset_idx].data_s.val = + ADDR_LTOSH_EXT (mz) - ((uint64_t) perfring_ptr->Addrbase); + mz = (char *) mz + elt_size; + alloc_size += elt_size; + offset_idx++; + + if (alloc_index + offset_idx == max_index) + { + break; + } + } + + return offset_idx; +} + +void +nsfw_shmem_pool_free (struct nsfw_mem_ring *perfring_ptr) +{ + struct nsfw_shmem_ring_head *ptemp; + + if (NULL == perfring_ptr) + { + return; + } + + struct nsfw_shmem_ring_head *pnode = + (struct nsfw_shmem_ring_head *) ((char *) perfring_ptr - + sizeof (struct nsfw_shmem_ring_head)); + + while (pnode) + { + // phead is involved in phead->mem_zone + ptemp = pnode->next; + common_mem_memzone_free (pnode->mem_zone); + pnode = ptemp; + } +} + +struct nsfw_mem_ring * +nsfw_shmem_pool_create (const char *name, unsigned int n, + unsigned int elt_size, int socket_id, + unsigned char flag) +{ + struct nsfw_mem_ring *perfring_ptr = NULL; + struct common_mem_memzone *mz_mem; + void *mz = NULL; + + /*get pool size, pool size must pow of 2 */ + unsigned int num = common_mem_align32pow2 (n + 1); + + struct nsfw_shmem_ring_head *pcur = NULL; + /*calculat the empty rte_perf_ring Size */ + size_t len = + sizeof (struct nsfw_shmem_ring_head) + sizeof (struct nsfw_mem_ring) + + (size_t) num * sizeof (union RingData_U) + (size_t) num * elt_size; + size_t alloc_len = len; + unsigned int alloc_num = 0; + unsigned int alloc_index = 0; + + size_t mz_len = 0; + + unsigned int mz_index = 1; + char mz_name[128] = { 0 }; + int retVal; + /*we'd better use `strlen(src)` or `sizeof(dst)` to explain copying length of src string. + it's meaningless using `sizeof(dst) - 1` to reserve 1 byte for '\0'. + if copying length equals to or bigger than dst length, just let STRNCPY_S() returns failure. */ + retVal = STRNCPY_S (mz_name, sizeof (mz_name), name, sizeof (mz_name)); + + if (EOK != retVal) + { + NSTCP_LOGERR ("STRNCPY_S failed]ret=%d", retVal); + return NULL; + } + + mz_mem = common_memzone_data_lookup_name (name); + NSTCP_LOGINF ("memzone data look up] n=%u,num=%u,len=%zu", n, num, len); + + if (mz_mem) + { + perfring_ptr = + (struct nsfw_mem_ring *) ((char *) mz_mem + + sizeof (struct nsfw_shmem_ring_head)); + return perfring_ptr; + } + + while (alloc_len > 0) + { + if (NULL != perfring_ptr) + { + retVal = + SPRINTF_S (mz_name, sizeof (mz_name), "%s_%03d", name, mz_index); + + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S failed]ret=%d", retVal); + nsfw_shmem_pool_free (perfring_ptr); + return NULL; + } + } + + mz_mem = + (struct common_mem_memzone *) common_mem_memzone_reserve (mz_name, + alloc_len, + socket_id, + 0); + + if (mz_mem == NULL) + { + mz_mem = + (struct common_mem_memzone *) common_mem_memzone_reserve (mz_name, + 0, + socket_id, + 0); + } + + if (mz_mem == NULL) + { + nsfw_shmem_pool_free (perfring_ptr); + return NULL; + } + + if (NULL == perfring_ptr + && (mz_mem->len < + sizeof (struct nsfw_shmem_ring_head) + + sizeof (struct nsfw_mem_ring) + + num * sizeof (union RingData_U))) + { + common_mem_memzone_free (mz_mem); + return NULL; + } + + if (NULL == perfring_ptr) + { + pcur = (struct nsfw_shmem_ring_head *) ADDR_SHTOL (mz_mem->addr_64); + pcur->mem_zone = mz_mem; + pcur->next = NULL; + + perfring_ptr = + (struct nsfw_mem_ring *) ((char *) pcur + + sizeof (struct nsfw_shmem_ring_head)); + + mz = + (void *) ((char *) perfring_ptr + sizeof (struct nsfw_mem_ring) + + num * sizeof (union RingData_U)); + mz_len = + mz_mem->len - sizeof (struct nsfw_shmem_ring_head) - + sizeof (struct nsfw_mem_ring) - num * sizeof (union RingData_U); + + uint64_t rte_base_addr; + uint64_t rte_highest_addr; + nsfw_shmem_ring_baseaddr_query (&rte_base_addr, &rte_highest_addr); + nsfw_mem_pool_head_init (perfring_ptr, num, elt_size, + (void *) rte_base_addr, NSFW_SHMEM, + (nsfw_mpool_type) flag); + } + else + { + if (pcur) + { + pcur->next = + (struct nsfw_shmem_ring_head *) ADDR_SHTOL (mz_mem->addr_64); + pcur = pcur->next; + pcur->mem_zone = mz_mem; + pcur->next = NULL; + + if (mz_mem->len < sizeof (struct nsfw_shmem_ring_head)) + { + NSCOMM_LOGERR ("mz_len error %d", mz_mem->len); + nsfw_shmem_pool_free (perfring_ptr); + return NULL; + } + + mz = + (void *) ((char *) pcur + + sizeof (struct nsfw_shmem_ring_head)); + mz_len = mz_mem->len - sizeof (struct nsfw_shmem_ring_head); + } + } + + alloc_num = + nsfw_shmem_pool_node_alloc (perfring_ptr, alloc_index, num, mz, + mz_len, elt_size); + alloc_index += alloc_num; + + if (alloc_index >= num) + { + break; + } + + // second time allocate should not containd all ring head + alloc_len = + (size_t) (num - alloc_index) * elt_size + + sizeof (struct nsfw_shmem_ring_head); + mz_index++; + } + + return perfring_ptr; +} + +/*ring create*/ +struct nsfw_mem_ring * +nsfw_shmem_ring_create (const char *name, unsigned int n, int socket_id, + unsigned char flag) +{ + struct nsfw_mem_ring *perfring_ptr; + struct common_mem_memzone *mz; + uint64_t rte_base_addr; + uint64_t rte_highest_addr; + + unsigned int num = common_mem_align32pow2 (n); + + mz = + (struct common_mem_memzone *) common_mem_memzone_reserve (name, + sizeof (struct + nsfw_mem_ring) + + + num * + sizeof (union + RingData_U), + socket_id, 0); + + if (mz == NULL) + { + return NULL; + } + + perfring_ptr = mz->addr; + + nsfw_shmem_ring_baseaddr_query (&rte_base_addr, &rte_highest_addr); + nsfw_mem_ring_init (perfring_ptr, num, (void *) rte_base_addr, NSFW_SHMEM, + flag); + + return perfring_ptr; +} + +/* +this is a multi thread/process enqueue function, please pay attention to the bellow point +1. while Enqueue corrupt, we may lose one element; because no one to add the Head +*/ +int +nsfw_shmem_ring_mp_enqueue (struct nsfw_mem_ring *ring, void *box) +{ + union RingData_U expectPostVal; + union RingData_U curVal; + unsigned int tmpHead; + unsigned int tmpTail; + unsigned int CurHead = ring->prod.head; + unsigned int mask = ring->mask; + unsigned int size = ring->size; + void *prmBox = NULL; + + prmBox = (void *) ADDR_LTOSH_EXT (box); + + /*do box range check */ + if ((char *) prmBox <= (char *) ring->Addrbase + || (char *) prmBox > (char *) ring->Addrbase + PERFRING_ADDR_RANGE) + { + /*invalid addr of box, can't put in rte_perf_ring, maybe should set a errno here */ + return -1; + } + + do + { + /* + if the ring is Full return directly; this not a exact check, cause we made tail++ after dequeue success. + the thing we could make sure is ring[ring->Tail&mask] already dequeue + */ + tmpTail = ring->cons.tail; + + if (tmpTail + size - CurHead == 0) + { + /* + here we give enque a chance to recorrect the Tail, if tail not has Data let tail++ + */ + if (ring->ring[tmpTail & mask].data_s.val == 0) + { + (void) __sync_bool_compare_and_swap (&ring->cons.tail, tmpTail, + tmpTail + 1); + } + else + { + return 0; + } + } + + /* + the old version of ring->ring[CurHead&mask] must CurHead - size, which enqueue set to this pos lasttime + & the val must already dequeue. otherwise this pos can't enqueue; + */ + expectPostVal.data_l = + (((unsigned long long) (CurHead - size)) << VALUE_LEN); + + /* + the new version of ring->ring[CurHead&mask] must CurHead, which enqueue set to this pos this time. + */ + curVal.data_l = + ((((unsigned long long) CurHead) << VALUE_LEN) | + ((char *) prmBox - (char *) ring->Addrbase)); + if (ring->ring[CurHead & mask].data_s.ver == expectPostVal.data_s.ver + && __sync_bool_compare_and_swap (&ring->ring[CurHead & mask].data_l, + expectPostVal.data_l, + curVal.data_l)) + { + /* + enqueue success, add Head Value now + here we using CAS set instead __sync_fetch_and_add(&ring->Head, 1) to assume that, if one process enque sucess && been killed before + add Head, other process can recorrect the Head Value; + one more thing the direction of Tail must been add-direction, so we using the condition (ring->Head - CurHead >0x80000000); + while many thread do enque at same time, Head may not correct,exp: + thread A get old head 10, thread A want set head to 11 + thread B get old head 10, thread B want set head to 12 + thread A do CAS && thread B do CAS at same time, thread A do CAS success; + the result of head is 11, but the correct Value should be 12; + + then thread C get old head 11, thread C will set head to 13[cause pos 12 already has value, thread C will skill 12], + the head will be recorrect by thread C. + if no thread C, thread A& B are the last enque thread; the head must recorrect by the deque function. + */ + tmpHead = ring->prod.head; + + if (0 == (CurHead & 0x03) && tmpHead - CurHead > 0x80000000) + { + (void) __sync_bool_compare_and_swap (&ring->prod.head, tmpHead, + CurHead + 1); + } + + break; + } + + /* + CurHead++ here; + may be cpu slice is end here; while re-sched CurHead < ring->Tail < ring->Head; to avoid multi try + we using a cmp & CurHead++ instead CurHead++ directly. + if using CurHead++ will amplify the probability of ABA problem + */ + /*CurHead++; */ + tmpHead = ring->prod.head; + CurHead = CurHead - tmpHead < mask - 1 ? CurHead + 1 : tmpHead; + } + while (1); + + return 1; +} + +/* + this is a single thread/process enqueue function + */ +int +nsfw_shmem_ring_sp_enqueue (struct nsfw_mem_ring *ring, void *box) +{ + union RingData_U texpectPostVal; + union RingData_U curVal; + unsigned int tmpTail; + unsigned int CurHead = ring->prod.head; + unsigned int mask = ring->mask; + unsigned int uisize = ring->size; + void *prmBox = NULL; + + prmBox = (void *) ADDR_LTOSH_EXT (box); + + if ((char *) prmBox <= (char *) ring->Addrbase + || (char *) prmBox > (char *) ring->Addrbase + PERFRING_ADDR_RANGE) + { + return -1; + } + + do + { + tmpTail = ring->cons.tail; + if (tmpTail + uisize - CurHead == 0) + { + /* + *here we give enque a chance to recorrect the Tail, if tail not has Data let tail++ + */ + if (ring->ring[tmpTail & mask].data_s.val == 0) + { + (void) __sync_bool_compare_and_swap (&ring->cons.tail, tmpTail, + tmpTail + 1); + } + else + { + return 0; + } + } + texpectPostVal.data_l = + (((unsigned long long) (CurHead - uisize)) << VALUE_LEN); + + curVal.data_l = + ((((unsigned long long) CurHead) << VALUE_LEN) | + ((char *) prmBox - (char *) ring->Addrbase)); + + if (ring->ring[CurHead & mask].data_l == texpectPostVal.data_l) + { + ring->ring[CurHead & mask].data_l = curVal.data_l; + ring->prod.head = CurHead + 1; + break; + } + + CurHead++; + } + while (1); + return 1; +} + +/*this is a multi thread/process dequeue function, please pay attention to the bellow point +*/ +int +nsfw_shmem_ring_mc_dequeue (struct nsfw_mem_ring *ring, void **box) +{ + unsigned int CurTail; + unsigned int tmpTail; + unsigned int tmpHead; + unsigned int mask = ring->mask; + union RingData_U curNullVal; + union RingData_U ExcpRingVal; + + CurTail = ring->cons.tail; + do + { + /*if ring is empty return directly */ + tmpHead = ring->prod.head; + + if (CurTail == tmpHead) + { + /* + here we give deque a chance to recorrect the Head, if head has Data let Head++ + */ + if (ring->ring[tmpHead & mask].data_s.val != 0) + { + (void) __sync_bool_compare_and_swap (&ring->prod.head, tmpHead, + tmpHead + 1); + } + else + { + return 0; + } + } + curNullVal.data_l = (((unsigned long long) CurTail) << VALUE_LEN); + ExcpRingVal = ring->ring[CurTail & mask]; + /* + *the version of ring->ring[CurTail&mask] must CurTail&0xFFFFFF + */ + if ((curNullVal.data_s.ver == ExcpRingVal.data_s.ver) + && (ExcpRingVal.data_s.val) + && __sync_bool_compare_and_swap (&ring->ring[CurTail & mask].data_l, + ExcpRingVal.data_l, + curNullVal.data_l)) + { + + *box = + ADDR_SHTOL (((char *) ring->Addrbase + ExcpRingVal.data_s.val)); + + /* + enqueue success, add Tail Value now + here we using CAS set instead __sync_fetch_and_add(&ring->Tail, 1) to assume that, if one process dequeue sucess && been killed before + add Tail, other process can recorrect the Tail Value; + one more thing the direction of Tail must been add-direction, so we using the condition (rlTail - CurTail >0x80000000); + while multi CAS done the result value of CurTail may not correct, but we don't care, it will be recorrect while next deque done. + + avg CAS cost 200-300 Cycles, so we using cache loop to instead some CAS;[head&tail not exact guide, so no need Do CAS evertime] + here we using 0 == (CurTail&0x11) means we only do CAS while head/tail low bit is 0x11; four times do one CAS. + */ + tmpTail = ring->cons.tail; + + if (0 == (CurTail & 0x03) && tmpTail - CurTail > 0x80000000) + { + (void) __sync_bool_compare_and_swap (&ring->cons.tail, tmpTail, + CurTail + 1); + } + break; + } + + /* + CurTail++ here; + may be cpu slice is end here; while re-sched CurTail < ring->Tail < ring->Head; to avoid multi try + we using a cmp & CurTail++ instead CurTail++ directly. + if using CurTail++ will amplify the probability of ABA problem + */ + /*CurTail++; */ + tmpTail = ring->cons.tail; + CurTail = CurTail - tmpTail < mask - 1 ? CurTail + 1 : tmpTail; + } + while (1); + + return 1; +} + +/* + this is enhanced mc_ring_dequeue, support dequeue multi element one time. +*/ +int +nsfw_shmem_ring_mc_dequeuev (struct nsfw_mem_ring *ring, void **box, + unsigned int n) +{ + unsigned int uiCurTail; + unsigned int tmpTail; + unsigned int tmpHead; + unsigned int uimask = ring->mask; + union RingData_U curNullVal; + union RingData_U ExcpRingVal; + unsigned int deqNum = 0; + uiCurTail = ring->cons.tail; + do + { + /*if ring is empty return directly */ + tmpHead = ring->prod.head; + if (uiCurTail == tmpHead) + { + /* + here we give deque a chance to recorrect the Head, if head has Data let Head++; + here must done to avoid some msg can't deque. + */ + if (deqNum == 0 && ring->ring[tmpHead & uimask].data_s.val != 0) + { + (void) __sync_bool_compare_and_swap (&ring->prod.head, tmpHead, + tmpHead + 1); + } + else + { + return deqNum; + } + } + + curNullVal.data_l = (((unsigned long long) uiCurTail) << VALUE_LEN); + ExcpRingVal = ring->ring[uiCurTail & uimask]; + + /* + *the version of ring->ring[CurTail&mask] must CurTail&0xFFFFFF + */ + if ((curNullVal.data_s.ver == ExcpRingVal.data_s.ver) + && (ExcpRingVal.data_s.val) + && __sync_bool_compare_and_swap (&ring-> + ring[uiCurTail & uimask].data_l, + ExcpRingVal.data_l, + curNullVal.data_l)) + { + + box[deqNum] = + ADDR_SHTOL (((char *) ring->Addrbase + ExcpRingVal.data_s.val)); + + /* + enqueue success, add Tail Value now + here we using CAS set instead __sync_fetch_and_add(&ring->Tail, 1) to assume that, if one process dequeue sucess && been killed before + add Tail, other process can recorrect the Tail Value; + one more thing the direction of Tail must been add-direction, so we using the condition (rlTail - CurTail >0x80000000); + + avg CAS cost 200-300 Cycles, so we using cache loop to instead some CAS;[head&tail not exact guide, so no need Do CAS evertime] + here we using 0 == (CurTail&0x11) means we only do CAS while head/tail low bit is 0x11; four times do one CAS. + */ + tmpTail = ring->cons.tail; + + if (0 == (uiCurTail & 0x03) && tmpTail - uiCurTail > 0x80000000) + { + (void) __sync_bool_compare_and_swap (&ring->cons.tail, tmpTail, + uiCurTail + 1); + } + + deqNum++; + } + + /* + CurTail++ here; + may be cpu slice is end here; while re-sched CurTail < ring->Tail < ring->Head; to avoid multi try + we using a cmp & CurTail++ instead CurTail++ directly. + if using CurTail++ will amplify the probability of ABA problem + */ + /*CurTail++; */ + tmpTail = ring->cons.tail; + uiCurTail = uiCurTail - tmpTail < uimask - 1 ? uiCurTail + 1 : tmpTail; + + } + while (n > deqNum); + + return deqNum; +} + +/* + this is enhanced mc_ring_dequeue, support dequeue multi element one time. +*/ +int +nsfw_shmem_ring_sc_dequeue (struct nsfw_mem_ring *ring, void **box) +{ + unsigned int CurTail; + unsigned int mask = ring->mask; + union RingData_U curNullVal; + union RingData_U ExcpRingVal; + unsigned int uitmpHead; + + CurTail = ring->cons.tail; + + do + { + /*if ring is empty return directly */ + uitmpHead = ring->prod.head; + if (CurTail == uitmpHead) + { + /* + here we give deque a chance to recorrect the Head, if head has Data let Head++ + */ + if (ring->ring[uitmpHead & mask].data_s.val != 0) + { + (void) __sync_bool_compare_and_swap (&ring->prod.head, + uitmpHead, uitmpHead + 1); + } + else + { + return 0; + } + } + curNullVal.data_l = (((unsigned long long) CurTail) << VALUE_LEN); + ExcpRingVal = ring->ring[CurTail & mask]; + + if ((curNullVal.data_s.ver == ExcpRingVal.data_s.ver) + && (ExcpRingVal.data_s.val)) + { + ring->ring[CurTail & mask].data_l = curNullVal.data_l; + + *box = + ADDR_SHTOL (((char *) ring->Addrbase + ExcpRingVal.data_s.val)); + + ring->cons.tail = CurTail + 1; + break; + } + + CurTail++; + } + while (1); + + return 1; +} + +/* + this is a single thread/process dequeue function +*/ +int +nsfw_shmem_ring_sc_dequeuev (struct nsfw_mem_ring *ring, void **box, + unsigned int n) +{ + unsigned int CurTail; + unsigned int tmpHead; + unsigned int mask = ring->mask; + union RingData_U curNullVal; + union RingData_U ExcpRingVal; + unsigned int usdeqNum = 0; + + CurTail = ring->cons.tail; + + do + { + /*if ring is empty return directly */ + tmpHead = ring->prod.head; + if (CurTail == tmpHead) + { + /* + here we give deque a chance to recorrect the Head, if head has Data let Head++; + here must done to avoid some msg can't deque. + */ + if (usdeqNum == 0 && ring->ring[tmpHead & mask].data_s.val != 0) + { + (void) __sync_bool_compare_and_swap (&ring->prod.head, tmpHead, + tmpHead + 1); + } + else + { + return usdeqNum; + } + } + curNullVal.data_l = (((unsigned long long) CurTail) << VALUE_LEN); + ExcpRingVal = ring->ring[CurTail & mask]; + + /* + the version of ring->ring[CurTail&mask] must CurTail&0xFFFFFF + */ + if ((curNullVal.data_s.ver == ExcpRingVal.data_s.ver) + && (ExcpRingVal.data_s.val)) + { + ring->ring[CurTail & mask].data_l = curNullVal.data_l; + + box[usdeqNum] = + ADDR_SHTOL (((char *) ring->Addrbase + ExcpRingVal.data_s.val)); + + ring->cons.tail = CurTail + 1; + usdeqNum++; + } + + CurTail++; + } + while (n > usdeqNum); + + return usdeqNum; +} + +/* nstack just using one thread, for performance using que not support multi thread*/ +int +nsfw_shmem_ring_singlethread_enqueue (struct nsfw_mem_ring *ring, void *box) +{ + u32 head = 0; + void *prmBox = NULL; + + /*if queue is full, just return 0 */ + if (ring->prod.head >= (ring->size + ring->cons.tail)) + { + return 0; + } + + prmBox = (void *) ADDR_LTOSH_EXT (box); + + head = ring->prod.head; + ring->prod.head = head + 1; + ring->ring[head & ring->mask].data_s.ver = head; + ring->ring[head & ring->mask].data_s.val = + (char *) prmBox - (char *) ring->Addrbase; + return 1; +} + +/* nstack just using one thread, for performance using que not support multi thread*/ +int +nsfw_shmem_ring_singlethread_dequeue (struct nsfw_mem_ring *ring, void **box) +{ + u32 tail = 0; + + /* if all entries are dequed return 0 */ + if (unlikely (ring->prod.head == ring->cons.tail)) + { + return 0; + } + + tail = ring->cons.tail; + *box = + ADDR_SHTOL ((char *) ring->Addrbase + + ring->ring[tail & ring->mask].data_s.val); + ring->ring[tail & ring->mask].data_s.val = 0; + ring->ring[tail & ring->mask].data_s.ver = tail; + ring->cons.tail++; + return 1; +} + +/* nstack just using one thread, for performance using que not support multi thread*/ +int +nsfw_shmem_ring_singlethread_dequeuev (struct nsfw_mem_ring *ring, void **box, + unsigned int n) +{ + u32 tail = 0; + u32 num = 0; + + while (num < n) + { + tail = ring->cons.tail; + + /* if all entries are dequed return 0 */ + if (unlikely (ring->prod.head == ring->cons.tail)) + { + return num; + } + + ring->cons.tail = tail + 1; + + box[num] = + ADDR_SHTOL ((char *) ring->Addrbase + + ring->ring[tail & ring->mask].data_s.val); + + ring->ring[tail & ring->mask].data_s.val = 0; + ring->ring[tail & ring->mask].data_s.ver = tail; + num++; + } + + return num; +} diff --git a/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.h b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.h new file mode 100644 index 0000000..15cd1dd --- /dev/null +++ b/src/framework/common/mem_mgr/nsfw_shmem/nsfw_shmem_ring.h @@ -0,0 +1,60 @@ +/* +* +* 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 _NSFW_SHMEM_RING_H_ +#define _NSFW_SHMEM_RING_H_ + +#include + +#include "common_func.h" + +struct nsfw_shmem_ring_head +{ + struct common_mem_memzone *mem_zone; + struct nsfw_shmem_ring_head *next; + unsigned int uireserv[4]; +}; + +void nsfw_shmem_ring_baseaddr_query (uint64_t * rte_lowest_addr, + uint64_t * rte_highest_addr); +struct nsfw_mem_ring *nsfw_shmem_pool_create (const char *name, + unsigned int n, + unsigned int elt_size, + int socket_id, + unsigned char flag); +struct nsfw_mem_ring *nsfw_shmem_ring_create (const char *name, + unsigned int n, int socket_id, + unsigned char flag); + +void nsfw_shmem_pool_free (struct nsfw_mem_ring *perfring_ptr); + +void nsfw_shmem_ring_reset (struct nsfw_mem_ring *ring, unsigned char flag); +int nsfw_shmem_ring_mp_enqueue (struct nsfw_mem_ring *ring, void *box); +int nsfw_shmem_ring_sp_enqueue (struct nsfw_mem_ring *ring, void *box); +int nsfw_shmem_ring_mc_dequeue (struct nsfw_mem_ring *ring, void **box); +int nsfw_shmem_ring_mc_dequeuev (struct nsfw_mem_ring *ring, void **box, + unsigned int n); +int nsfw_shmem_ring_sc_dequeue (struct nsfw_mem_ring *ring, void **box); +int nsfw_shmem_ring_sc_dequeuev (struct nsfw_mem_ring *ring, void **box, + unsigned int n); +int nsfw_shmem_ring_singlethread_enqueue (struct nsfw_mem_ring *ring, + void *box); +int nsfw_shmem_ring_singlethread_dequeue (struct nsfw_mem_ring *ring, + void **box); +int nsfw_shmem_ring_singlethread_dequeuev (struct nsfw_mem_ring *ring, + void **box, unsigned int n); + +#endif /*_NSFW_SHMEM_RING_H_*/ diff --git a/src/framework/hal/hal.c b/src/framework/hal/hal.c new file mode 100644 index 0000000..1adf274 --- /dev/null +++ b/src/framework/hal/hal.c @@ -0,0 +1,865 @@ +/* +* +* 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 "common_sys_config.h" +#include "common_mem_mbuf.h" +#include "nstack_log.h" +#include "nstack_securec.h" +#include "hal.h" +#include "hal_api.h" + +#define HAL_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +/* *INDENT-OFF* */ +static char hal_invalid_char_script[] = {'|', ';', '&', '$', '>', '<', '`', '\\', '\"', '\'', + '(', ')', '[', ']', '~', '?', '*' + }; + +static char* hal_invalid_str_script[] = {"&&", "||", ">>", "${", ";;", "/./", "/../"}; + +static char* hal_invalid_str_script_begin[] = {"./", "../"}; + +extern const netif_ops_t dpdk_netif_ops; + +static hal_hdl_t hal_invaldi_hdl = {.id = -1}; + +static const netif_ops_t* netif_ops_table[HAL_DRV_MAX]; +static int netif_ops_init_flag = 0; + +netif_inst_t netif_tbl[HAL_MAX_NIC_NUM]; +/* *INDENT-ON* */ + +void +hal_io_adpt_register (const netif_ops_t * ops) +{ + int icnt = 0; + if (netif_ops_init_flag == 0) + { + (void) MEMSET_S (&netif_ops_table[0], sizeof (netif_ops_table), 0, + sizeof (netif_ops_table)); + netif_ops_init_flag = 1; + } + + for (icnt = 0; icnt < HAL_DRV_MAX; icnt++) + { + if (netif_ops_table[icnt] == 0) + { + netif_ops_table[icnt] = ops; + break; + } + } + return; +} + +/***************************************************************************** + Prototype : hal_snprintf + Description : create shell script + Input : char* buffer + size_t buflen + const char* format + ... + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_snprintf (char *buffer, size_t buflen, const char *format, ...) +{ + int len; + va_list ap; + + /* check buffer validity */ + if (NULL == buffer || 0 == buflen) + { + goto einval_error; + } + + if (format == NULL) + { + buffer[0] = '\0'; + + goto einval_error; + } + + (void) va_start (ap, format); + len = VSNPRINTF_S (buffer, buflen, buflen - 1, format, ap); + + if (-1 == len) + { + va_end (ap); + goto einval_error; + } + + va_end (ap); + + buffer[buflen - 1] = '\0'; + + return len; + +einval_error: + errno = EINVAL; + return -1; +} + +/***************************************************************************** + Prototype : hal_is_script_valid + Description : Check External Injection of Shell script Validation + Input : const char* cmd + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_is_script_valid (const char *cmd) +{ + unsigned int i; + + if (cmd) + { + char *cmd_str = (char *) cmd; + + /* skip space */ + while (*cmd_str == ' ' || *cmd_str == '\t') + { + cmd_str++; + } + + /* cmd can not start with ./ and ../ */ + for (i = 0; i < HAL_ARRAY_SIZE (hal_invalid_str_script_begin); i++) + { + if (strstr (cmd_str, hal_invalid_str_script_begin[i]) == cmd_str) + { + return 0; + } + } + + /* cmd can not include | ; $ and so on */ + for (i = 0; i < HAL_ARRAY_SIZE (hal_invalid_char_script); i++) + { + if (strchr (cmd, hal_invalid_char_script[i])) + { + return 0; + } + } + + /* cmd can not include && || >> and so on */ + for (i = 0; i < HAL_ARRAY_SIZE (hal_invalid_str_script); i++) + { + if (strstr (cmd, hal_invalid_str_script[i])) + { + return 0; + } + } + + return 1; + } + + return 0; +} + +/***************************************************************************** + Prototype : hal_run_script + Description : run shell script + Input : const char* cmd + char* result_buf + size_t max_result_len + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_run_script (const char *cmd, char *result_buf, size_t max_result_len) +{ + size_t n; + if (!cmd || !result_buf || max_result_len <= 1) + { + return -1; + } + + FILE *fd = popen (cmd, "r"); + + if (fd != NULL) + { + n = fread (result_buf, sizeof (char), max_result_len - 1, fd); + + if (n == 0) + { + result_buf[0] = '\0'; + } + else if ('\n' == result_buf[n - 1]) + { + result_buf[n - 1] = '\0'; + } + /* make it null terminated */ + else + { + result_buf[n] = '\0'; + } + + (void) pclose (fd); + return n; + } + + return -1; +} + +/***************************************************************************** + Prototype : hal_init_global + Description : init hal when proccess start + Input : int argc + char** argv + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_init_global (int argc, char **argv) +{ + int ret; + int netif_type; + + ret = + MEMSET_S (netif_tbl, HAL_MAX_NIC_NUM * sizeof (netif_inst_t), 0, + HAL_MAX_NIC_NUM * sizeof (netif_inst_t)); + if (EOK != ret) + { + NSHAL_LOGERR ("MEMSET_S failed"); + return -1; + } + + for (netif_type = 0; netif_ops_table[netif_type]; ++netif_type) + { + if (netif_ops_table[netif_type]->init_global) + { + if (netif_ops_table[netif_type]->init_global (argc, argv)) + { + NSHAL_LOGERR ("failed to init global]netif type=%d", + netif_type); + return -1; + } + } + } + + return 0; +} + +/***************************************************************************** + Prototype : hal_init_local + Description : init hal when process or thread start + Input : None + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_init_local () +{ + int netif_type; + + for (netif_type = 0; netif_ops_table[netif_type]; ++netif_type) + { + if (netif_ops_table[netif_type]->init_local) + { + if (netif_ops_table[netif_type]->init_local ()) + { + NSHAL_LOGERR ("failed to init local]netif type=%d", netif_type); + return -1; + } + } + } + + return 0; +} + +/***************************************************************************** + Prototype : hal_get_invalid_hdl + Description : get the invalid object + Input : None + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +hal_hdl_t +hal_get_invalid_hdl () +{ + return hal_invaldi_hdl; +} + +/***************************************************************************** + Prototype : hal_create + Description : create hal object + Input : const char* name + hal_netif_config_t* conf + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +hal_hdl_t +hal_create (const char *name, hal_netif_config_t * conf) +{ + int ret = -1; + uint32_t netif_type; + netif_inst_t *inst; + + if ((NULL == name) || (NULL == conf)) + { + NSHAL_LOGERR ("invalid para]name=%p,conf=%p", name, conf); + return hal_get_invalid_hdl (); + } + + inst = alloc_netif_inst (); + + if (NULL == inst) + { + NSHAL_LOGERR ("failed to alloc netif inst]netif name=%s", name); + + return hal_get_invalid_hdl (); + } + + /*open */ + for (netif_type = 0; NULL != netif_ops_table[netif_type]; ++netif_type) + { + ret = netif_ops_table[netif_type]->open (inst, name); + + if (0 == ret) + { + inst->ops = netif_ops_table[netif_type]; + + NSHAL_LOGINF ("netif ops]netif type=%u, netif name=%s", netif_type, + inst->ops->name); + + break; + } + } + + if (ret != 0) + { + inst->state = NETIF_STATE_FREE; + + inst->ops = NULL; + + NSHAL_LOGERR ("open fail]netif name=%s", name); + + return hal_get_invalid_hdl (); + } + + /*config */ + ret = inst->ops->config (inst, conf); + + if (ret != 0) + { + inst->state = NETIF_STATE_FREE; + + NSHAL_LOGERR ("config fail]netif name=%s", name); + + return hal_get_invalid_hdl (); + } + + /*start */ + ret = inst->ops->start (inst); + + if (ret != 0) + { + inst->state = NETIF_STATE_FREE; + + NSHAL_LOGERR ("start fail]netif name=%s", name); + + return hal_get_invalid_hdl (); + } + + return inst->hdl; +} + +/***************************************************************************** + Prototype : hal_bond + Description : create hal object for bond mode + Input : const char* bond_name + uint8_t slave_num + hal_hdl_t slave_hdl[] + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +hal_hdl_t +hal_bond (const char *bond_name, uint8_t slave_num, hal_hdl_t slave_hdl[]) +{ + int i, ret; + netif_inst_t *inst; + netif_inst_t *slave_inst[HAL_MAX_SLAVES_PER_BOND]; + + if ((0 == slave_num) || (HAL_MAX_SLAVES_PER_BOND < slave_num) + || (NULL == bond_name) || (NULL == slave_hdl)) + { + NSHAL_LOGERR ("invalid para]bond_name=%p,slave_num=%u,slave_hdl=%p,", + bond_name, slave_num, slave_hdl); + + return hal_get_invalid_hdl (); + } + + for (i = 0; i < slave_num; i++) + { + slave_inst[i] = get_netif_inst (slave_hdl[i]); + + if (NULL == slave_inst[i]) + { + NSHAL_LOGERR ("invalid para slave_hdl]index=%d, slave_inst=%d", i, + slave_hdl[i].id); + return hal_get_invalid_hdl (); + } + } + + inst = alloc_netif_inst (); + + if (NULL == inst) + { + NSHAL_LOGERR ("failed to alloc nic inst]bond_name=%s", bond_name); + return hal_get_invalid_hdl (); + } + + inst->ops = slave_inst[0]->ops; + + ret = inst->ops->bond (inst, bond_name, slave_num, slave_inst); + + if (0 != ret) + { + inst->state = NETIF_STATE_FREE; + + inst->ops = NULL; + + NSHAL_LOGERR ("bond netif fail]bond_name=%s", bond_name); + + return hal_get_invalid_hdl (); + } + + return inst->hdl; +} + +/***************************************************************************** + Prototype : hal_close + Description : destroy hal object + Input : hal_hdl_t hdl + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_close (hal_hdl_t hdl) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return -1; + } + + inst->state = NETIF_STATE_FREE; + + return inst->ops->close (inst); +} + +/***************************************************************************** + Prototype : hal_stop + Description : stop recv packet + Input : hal_hdl_t hdl + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_stop (hal_hdl_t hdl) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return -1; + } + + return inst->ops->stop (inst); +} + +/***************************************************************************** + Prototype : hal_get_mtu + Description : get the mtu from nic + Input : hal_hdl_t hdl + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +uint32_t +hal_get_mtu (hal_hdl_t hdl) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return 0; + } + + return inst->ops->mtu (inst); +} + +/***************************************************************************** + Prototype : hal_get_macaddr + Description : in normal mode, get the mac addr from nic + in bond mode1, get the mac addr from primary nic + Input : hal_hdl_t hdl + void* mac_addr + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +void +hal_get_macaddr (hal_hdl_t hdl, void *mac_addr) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return; + } + + (void) inst->ops->macaddr (inst, mac_addr); +} + +/***************************************************************************** + Prototype : hal_get_capability + Description : get offload capability from nic + Input : hal_hdl_t hdl + hal_netif_capa_t* info + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +void +hal_get_capability (hal_hdl_t hdl, hal_netif_capa_t * info) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return; + } + + (void) inst->ops->capability (inst, info); +} + +/***************************************************************************** + Prototype : hal_recv_packet + Description : recv packet from nic + Input : hal_hdl_t hdl + uint16_t queue_id + struct common_mem_mbuf** rx_pkts + uint16_t nb_pkts + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +uint16_t +hal_recv_packet (hal_hdl_t hdl, uint16_t queue_id, + struct common_mem_mbuf **rx_pkts, uint16_t nb_pkts) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return 0; + } + + return inst->ops->recv (inst, queue_id, rx_pkts, nb_pkts); +} + +/***************************************************************************** + Prototype : hal_send_packet + Description : send packet to nic + Input : hal_hdl_t hdl + uint16_t queue_id + struct common_mem_mbuf** tx_pkts + uint16_t nb_pkts + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +uint16_t +hal_send_packet (hal_hdl_t hdl, uint16_t queue_id, + struct common_mem_mbuf ** tx_pkts, uint16_t nb_pkts) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return 0; + } + + return inst->ops->send (inst, queue_id, tx_pkts, nb_pkts); +} + +/***************************************************************************** + Prototype : hal_link_status + Description : get link status form nic + Input : hal_hdl_t hdl + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +uint32_t +hal_link_status (hal_hdl_t hdl) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return 0; + } + + return inst->ops->link_status (inst); +} + +/***************************************************************************** + Prototype : hal_stats + Description : get link statistics form nic + Input : hal_hdl_t hdl + hal_netif_stats_t* stats + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_stats (hal_hdl_t hdl, hal_netif_stats_t * stats) +{ + netif_inst_t *inst; + + if (NULL == stats) + { + NSHAL_LOGERR ("invalid para"); + return -1; + } + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return -1; + } + + return inst->ops->stats (inst, stats); +} + +/***************************************************************************** + Prototype : hal_stats_reset + Description : reset link statistics to nic + Input : hal_hdl_t hdl + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +void +hal_stats_reset (hal_hdl_t hdl) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return; + } + + (void) inst->ops->stats_reset (inst); +} + +/***************************************************************************** + Prototype : hal_add_mcastaddr + Description : set multicast addrs to nic + Input : hal_hdl_t hdl + void* mc_addr_set + void* mc_addr + uint32_t nb_mc_addr + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_add_mcastaddr (hal_hdl_t hdl, void *mc_addr_set, + void *mc_addr, uint32_t nb_mc_addr) +{ + int ret; + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return -1; + } + + ret = inst->ops->mcastaddr (inst, mc_addr_set, mc_addr, nb_mc_addr); + /* if set mcast addr failed, we have to manually add the mac addr to nic. */ + if (ret < 0) + { + ret = inst->ops->add_mac (inst, mc_addr); + } + return ret; +} + +/***************************************************************************** + Prototype : hal_del_mcastaddr + Description : delete multicast addrs to nic + Input : hal_hdl_t hdl + void* mc_addr_set + void* mc_addr + uint32_t nb_mc_addr + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +int +hal_del_mcastaddr (hal_hdl_t hdl, void *mc_addr_set, + void *mc_addr, uint32_t nb_mc_addr) +{ + int ret; + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return -1; + } + + ret = inst->ops->mcastaddr (inst, mc_addr_set, mc_addr, nb_mc_addr); + /* if set mcast addr failed, we have to manually delete the mac addr from nic. */ + if (ret < 0) + { + ret = inst->ops->rmv_mac (inst, mc_addr); + } + return ret; +} + +/***************************************************************************** + Prototype : hal_set_allmulti_mode + Description : set all multicast mode + Input : hal_hdl_t hdl + uint8_t enable + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +void +hal_set_allmulti_mode (hal_hdl_t hdl, uint8_t enable) +{ + netif_inst_t *inst; + + inst = get_netif_inst (hdl); + + if (inst == NULL) + { + NSHAL_LOGERR ("netif does not exist]inst=%i", HAL_HDL_TO_ID (hdl)); + return; + } + + (void) inst->ops->allmcast (inst, enable); +} + +/***************************************************************************** + Prototype : hal_is_nic_exist + Description : check nic is exist + Input : const char *name + Output : None + Return Value : + Calls : + Called By : +*****************************************************************************/ +uint32_t +hal_is_nic_exist (const char *name) +{ + char script_cmmd[HAL_SCRIPT_LENGTH]; + char result_buf[HAL_SCRIPT_LENGTH]; + int len_out; + int retval; + + if (!hal_is_script_valid (name)) + { + NSHAL_LOGERR ("nic name is not valid"); + return 0; + } + + retval = + hal_snprintf (script_cmmd, sizeof (script_cmmd), + "sudo ifconfig -a | grep -w \"%s[ :]\"", name); + if (-1 == retval) + { + NSHAL_LOGERR ("rte_snprintf failed]retval=%d", retval); + return 0; + } + + len_out = hal_run_script (script_cmmd, result_buf, sizeof (result_buf) - 1); + /* buffer not initialized, should take length as decision */ + if (0 != len_out) + { + return 1; + } + + return 0; +} diff --git a/src/framework/hal/hal.h b/src/framework/hal/hal.h new file mode 100644 index 0000000..2f66914 --- /dev/null +++ b/src/framework/hal/hal.h @@ -0,0 +1,182 @@ +/* +* +* 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 _HAL_H_ +#define _HAL_H_ + +#include +#include "hal_api.h" +#include "nstack_log.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define HAL_DRV_MAX 32 + +#define HAL_IO_REGISTER(name, ops) \ + static __attribute__((__constructor__)) void __hal_register##name(void) \ + {\ + hal_io_adpt_register(ops); \ + } \ + + +#define HAL_MAX_PCI_ADDR_LEN 16 + +#define HAL_MAX_DRIVER_NAME_LEN 128 + +#define HAL_MAX_PATH_LEN 4096 //max path length on linux is 4096 + +#define HAL_SCRIPT_LENGTH 256 + +#define HAL_HDL_TO_ID(hdl) (hdl.id) + +/* IO using DPDK interface */ +typedef struct dpdk_if +{ + uint8_t port_id; /**< DPDK port identifier */ + uint8_t slave_num; + uint8_t slave_port[HAL_MAX_SLAVES_PER_BOND]; + + uint32_t hw_vlan_filter:1; + uint32_t hw_vlan_strip:1; + uint32_t rsv30:30; + + uint32_t rx_queue_num; + uint32_t rx_ring_size[HAL_ETH_MAX_QUEUE_NUM]; + struct rte_mempool *rx_pool[HAL_ETH_MAX_QUEUE_NUM]; + + uint32_t tx_queue_num; + uint32_t tx_ring_size[HAL_ETH_MAX_QUEUE_NUM]; + + char pci_addr[HAL_MAX_PCI_ADDR_LEN]; + char nic_name[HAL_MAX_NIC_NAME_LEN]; + char driver_name[HAL_MAX_DRIVER_NAME_LEN]; +} dpdk_if_t; + +typedef struct netif_inst +{ + enum + { + NETIF_STATE_FREE = 0, + NETIF_STATE_ACTIVE + } state; + + hal_hdl_t hdl; + + const struct netif_ops *ops; /**< Implementation specific methods */ + + union + { + dpdk_if_t dpdk_if; /**< using DPDK for IO */ + } data; + +} netif_inst_t; + +typedef struct netif_ops +{ + const char *name; + int (*init_global) (int argc, char **argv); + int (*init_local) (void); + int (*open) (netif_inst_t * inst, const char *name); + int (*close) (netif_inst_t * inst); + int (*start) (netif_inst_t * inst); + int (*stop) (netif_inst_t * inst); + int (*bond) (netif_inst_t * inst, const char *bond_name, + uint8_t slave_num, netif_inst_t * slave[]); + uint32_t (*mtu) (netif_inst_t * inst); + int (*macaddr) (netif_inst_t * inst, void *mac_addr); + int (*capability) (netif_inst_t * inst, hal_netif_capa_t * info); + uint16_t (*recv) (netif_inst_t * inst, uint16_t queue_id, + struct common_mem_mbuf ** rx_pkts, uint16_t nb_pkts); + uint16_t (*send) (netif_inst_t * inst, uint16_t queue_id, + struct common_mem_mbuf ** tx_pkts, uint16_t nb_pkts); + uint32_t (*link_status) (netif_inst_t * inst); + int (*stats) (netif_inst_t * inst, hal_netif_stats_t * stats); + int (*stats_reset) (netif_inst_t * inst); + int (*config) (netif_inst_t * inst, hal_netif_config_t * conf); + int (*mcastaddr) (netif_inst_t * inst, void *mc_addr_set, + void *mc_addr, uint32_t nb_mc_addr); + int (*add_mac) (netif_inst_t * inst, void *mc_addr); + int (*rmv_mac) (netif_inst_t * inst, void *mc_addr); + int (*allmcast) (netif_inst_t * inst, uint8_t enable); +} netif_ops_t; + +extern netif_inst_t netif_tbl[HAL_MAX_NIC_NUM]; + +static inline netif_inst_t * +alloc_netif_inst () +{ + int i; + netif_inst_t *inst; + + for (i = 0; i < HAL_MAX_NIC_NUM; ++i) + { + inst = &netif_tbl[i]; + + if (NETIF_STATE_FREE == inst->state) + { + inst->state = NETIF_STATE_ACTIVE; + + inst->hdl.id = i; + + return inst; + } + } + + return NULL; + +} + +static inline netif_inst_t * +get_netif_inst (hal_hdl_t hdl) +{ + netif_inst_t *inst; + + if (unlikely (!hal_is_valid (hdl))) + { + NSHAL_LOGERR ("inst id is not valid]inst=%i, HAL_MAX_NIC_NUM=%d", + HAL_HDL_TO_ID (hdl), HAL_MAX_NIC_NUM); + + return NULL; + } + + inst = &netif_tbl[HAL_HDL_TO_ID (hdl)]; + + if (unlikely ((NETIF_STATE_ACTIVE != inst->state) || (NULL == inst->ops))) + { + NSHAL_LOGERR ("netif is not active]inst=%i", HAL_HDL_TO_ID (hdl)); + + return NULL; + } + + return inst; +} + +int hal_snprintf (char *buffer, size_t buflen, const char *format, ...); +int hal_is_script_valid (const char *cmd); +int hal_run_script (const char *cmd, char *result_buf, size_t max_result_len); +void hal_io_adpt_register (const netif_ops_t * ops); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/src/framework/include/hal_api.h b/src/framework/include/hal_api.h new file mode 100644 index 0000000..24ed779 --- /dev/null +++ b/src/framework/include/hal_api.h @@ -0,0 +1,148 @@ +/* +* +* 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 _HAL_API_H_ +#define _HAL_API_H_ + +#include "common_mem_mbuf.h" +#include "common_mem_mempool.h" +#include "common_func.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define HAL_ETH_MAX_QUEUE_NUM 4 + +#define HAL_ETH_QUEUE_STAT_CNTRS 16 + +#define HAL_MAX_NIC_NUM 4096 +COMPAT_PROTECT (HAL_MAX_NIC_NUM, 4096); + +#define HAL_MAX_SLAVES_PER_BOND 2 + +#define HAL_MAX_NIC_NAME_LEN 256 + +/** + * TX offload capabilities of a device. + */ +#define HAL_ETH_TX_OFFLOAD_IPV4_CKSUM 0x00000002 +#define HAL_ETH_TX_OFFLOAD_UDP_CKSUM 0x00000004 +#define HAL_ETH_TX_OFFLOAD_TCP_CKSUM 0x00000008 + +/** + * Hal Instance Handler + */ +typedef struct hal_hdl +{ + int id; +} hal_hdl_t; + +/** + * Ethernet device capability + */ +typedef struct hal_netif_capa +{ + uint32_t tx_offload_capa; /**< Device TX offload capabilities. */ +} hal_netif_capa_t; + +/** + * A structure used to retrieve statistics for an Ethernet port. + */ +typedef struct hal_netif_stats +{ + uint64_t ipackets; /**< Total no.of packets that are successfully received . */ + uint64_t opackets; /**< Total no.of packets that are successfully transmitted .*/ + uint64_t ibytes; /**< Total no.of bytes that are successfully received . */ + uint64_t obytes; /**< Total no.of bytes that are successfully transmitted . */ + uint64_t imissed; /**< Total no.of RX packets that are dropped by the HW. */ + uint64_t ierrors; /**< Total no.of packets that are received as erroneous. */ + uint64_t oerrors; /**< Total no.of failed transmitted packets. */ + uint64_t rx_nombuf; /**< Total no.of RX mbuf allocation failures. */ + + uint64_t q_ipackets[HAL_ETH_QUEUE_STAT_CNTRS]; /**< Total no.of queue RX packets. */ + uint64_t q_opackets[HAL_ETH_QUEUE_STAT_CNTRS]; /**< Total no.of queue TX packets. */ + uint64_t q_ibytes[HAL_ETH_QUEUE_STAT_CNTRS]; /**< Total no.of successfully received queue bytes. */ + uint64_t q_obytes[HAL_ETH_QUEUE_STAT_CNTRS]; /**< Total no.of successfully transmitted queue bytes. */ + uint64_t q_errors[HAL_ETH_QUEUE_STAT_CNTRS]; /**< Total no.of queue packets received that are dropped. */ +} hal_netif_stats_t; + +/** + * Ethernet device config + */ +typedef struct hal_netif_config +{ + struct + { + uint32_t hw_vlan_filter:1; + uint32_t hw_vlan_strip:1; + uint32_t rsv30:30; + } bit; + + struct + { + uint32_t queue_num; + uint32_t ring_size[HAL_ETH_MAX_QUEUE_NUM]; + struct common_mem_mempool *ring_pool[HAL_ETH_MAX_QUEUE_NUM]; + } rx; + + struct + { + uint32_t queue_num; + uint32_t ring_size[HAL_ETH_MAX_QUEUE_NUM]; + } tx; + +} hal_netif_config_t; + +int hal_init_global (int argc, char **argv); +int hal_init_local (); +hal_hdl_t hal_create (const char *name, hal_netif_config_t * conf); +hal_hdl_t hal_bond (const char *bond_name, uint8_t slave_num, + hal_hdl_t slave_hdl[]); + +#define hal_is_valid(hdl) ((hdl.id >= 0) && (hdl.id < HAL_MAX_NIC_NUM)) + +#define hal_is_equal(hdl_left, hdl_right) (hdl_left.id == hdl_right.id) + +int hal_close (hal_hdl_t hdl); +int hal_stop (hal_hdl_t hdl); +uint32_t hal_get_mtu (hal_hdl_t hdl); +void hal_get_macaddr (hal_hdl_t hdl, void *mac_addr); +void hal_get_capability (hal_hdl_t hdl, hal_netif_capa_t * info); +uint16_t hal_recv_packet (hal_hdl_t hdl, uint16_t queue_id, + struct common_mem_mbuf **rx_pkts, uint16_t nb_pkts); +uint16_t hal_send_packet (hal_hdl_t hdl, uint16_t queue_id, + struct common_mem_mbuf **tx_pkts, uint16_t nb_pkts); +uint32_t hal_link_status (hal_hdl_t hdl); +int hal_stats (hal_hdl_t hdl, hal_netif_stats_t * stats); +void hal_stats_reset (hal_hdl_t hdl); +int hal_add_mcastaddr (hal_hdl_t hdl, void *mc_addr_set, + void *mc_addr, uint32_t nb_mc_addr); +int hal_del_mcastaddr (hal_hdl_t hdl, void *mc_addr_set, + void *mc_addr, uint32_t nb_mc_addr); +void hal_set_allmulti_mode (hal_hdl_t hdl, uint8_t enable); +uint32_t hal_is_nic_exist (const char *name); +hal_hdl_t hal_get_invalid_hdl (); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/src/framework/include/nsfw_fd_timer_api.h b/src/framework/include/nsfw_fd_timer_api.h new file mode 100644 index 0000000..0b42fe0 --- /dev/null +++ b/src/framework/include/nsfw_fd_timer_api.h @@ -0,0 +1,64 @@ +/* +* +* 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 _NSFW_FD_TIMER_API_H +#define _NSFW_FD_TIMER_API_H + +#include "list.h" +#include + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#define NSFW_TIMER_MODULE "nsfw_timer" + +typedef struct _nsfw_timer_init_cfg +{ + u32 timer_info_size; + void *timer_info_pool; + struct list_head timer_head; + struct list_head exp_timer_head; +} nsfw_timer_init_cfg; + +typedef int (*nsfw_timer_proc_fun) (u32 timer_type, void *argv); +typedef struct _nsfw_timer_info +{ + struct list_head node; + nsfw_timer_proc_fun fun; + void *argv; + struct timespec time_left; + u32 timer_type; + u8 alloc_flag; +} nsfw_timer_info; + +extern nsfw_timer_info *nsfw_timer_reg_timer (u32 timer_type, void *data, + nsfw_timer_proc_fun fun, + struct timespec time_left); +extern void nsfw_timer_rmv_timer (nsfw_timer_info * tm_info); + +extern u8 g_hbt_switch; +extern int nsfw_timer_module_init (void *param); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#endif /* _NSFW_FD_TIMER_API_H */ diff --git a/src/framework/include/nsfw_init.h b/src/framework/include/nsfw_init.h new file mode 100644 index 0000000..def97b2 --- /dev/null +++ b/src/framework/include/nsfw_init.h @@ -0,0 +1,148 @@ +/* +* +* 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 _FW_INIT_H +#define _FW_INIT_H + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#define NSFW_INIT_PRIORITY_ROOT 101 +#define NSFW_INIT_PRIORITY_BASE 102 +#define NSFW_INIT_PRIORITY_INITFN 103 + +#define NSFW_INIT_MODULE_PRIORITY_BASE 1 +#define NSFW_INIT_MODULE_PRIORITY(x) (NSFW_INIT_MODULE_PRIORITY_BASE + x) + +#define NSFW_SET_INSTANCE_VALUE(_attr, _inst, _value) \ + nsfw_module_set_instance_##_attr(_inst, _value) + +#define NSFW_INIT_CRAETE_LOCAL_INSTANCE() \ + if (!nsfwLocalInitInst) {\ + nsfwLocalInitInst = nsfw_module_create_instance(); \ + nsfw_module_add_instance(nsfwLocalInitInst);\ + } + +#define _NSFW_MODULE_ATTRIBUTE_DEFINE_SURFIX(_attr, _value, _priority, _surfix) \ + static __attribute__((__constructor__(_priority))) void nsfw_module_attribute_##_attr##_surfix(void){\ + NSFW_INIT_CRAETE_LOCAL_INSTANCE(); \ + NSFW_SET_INSTANCE_VALUE(_attr, nsfwLocalInitInst, _value);\ + } \ + +#define NSFW_MODULE_ATTRIBUTE_DEFINE_SURFIX(_attr, _value, _priority, _surfix) \ + _NSFW_MODULE_ATTRIBUTE_DEFINE_SURFIX(_attr, _value, _priority, _surfix) + +#define NSFW_MODULE_ATTRIBUTE_DEFINE_UNIQUE(_attr, _value, _priority) \ + NSFW_MODULE_ATTRIBUTE_DEFINE_SURFIX(_attr, _value, _priority, __LINE__) + +#define NSFW_MODULE_ATTRIBUTE_DEFINE(_attr, _value, _priority) \ + NSFW_MODULE_ATTRIBUTE_DEFINE_UNIQUE(_attr, _value, _priority) + +#define NSFW_MODULE_NAME(_name) \ + NSFW_MODULE_ATTRIBUTE_DEFINE(name, _name, NSFW_INIT_PRIORITY_BASE) + +#define NSFW_MODULE_FATHER(_father) \ + NSFW_MODULE_ATTRIBUTE_DEFINE(father, _father, NSFW_INIT_PRIORITY_BASE) + +#define NSFW_MODULE_PRIORITY(_priority) \ + NSFW_MODULE_ATTRIBUTE_DEFINE(priority, _priority, NSFW_INIT_PRIORITY_BASE) + +#define NSFW_MODULE_DEPENDS(_depends) \ + NSFW_MODULE_ATTRIBUTE_DEFINE(depends, _depends, NSFW_INIT_PRIORITY_BASE) + +#define NSFW_MODULE_INIT(_initfn) \ + NSFW_MODULE_ATTRIBUTE_DEFINE(initfn, _initfn, NSFW_INIT_PRIORITY_INITFN) + +#define NSFW_MAX_STRING_LENGTH 128 + +#define NSFW_DEPENDS_SIZE 8 +typedef struct _nsfw_module_depends +{ + char name[NSFW_MAX_STRING_LENGTH]; + int isReady; + struct _nsfw_module_depends *next; /* It is a list, not just only one */ +} nsfw_module_depends_t; + +typedef enum +{ + NSFW_INST_STAT_CHECKING, /* Not check yet */ + NSFW_INST_STAT_DEPENDING, /* Blocked, waiting for other module instances */ + NSFW_INST_STAT_DONE, /* Check done */ + NSFW_INST_STAT_FAIL /* Check Fail */ +} nsfw_module_instance_stat_t; + +typedef int (*nsfw_module_init_fn) (void *); + +typedef struct _nsfw_module_instance +{ + nsfw_module_init_fn fnInit; + char name[NSFW_MAX_STRING_LENGTH]; + char fatherName[NSFW_MAX_STRING_LENGTH]; + int priority; + nsfw_module_depends_t *depends; + nsfw_module_instance_stat_t stat; + void *param; + struct _nsfw_module_instance *next; + struct _nsfw_module_instance *child; + struct _nsfw_module_instance *father; +} nsfw_module_instance_t; + +static nsfw_module_instance_t *nsfwLocalInitInst __attribute__ ((unused)) = + (void *) 0; + +extern nsfw_module_instance_t *nsfw_module_create_instance (); +extern nsfw_module_instance_t *nsfw_module_getModuleByName (char *); +extern void nsfw_module_add_instance (nsfw_module_instance_t * inst); +extern void nsfw_module_del_instance (nsfw_module_instance_t * inst); +extern void nsfw_module_set_instance_name (nsfw_module_instance_t * inst, + char *name); +extern void nsfw_module_set_instance_father (nsfw_module_instance_t * inst, + char *father); +extern void nsfw_module_set_instance_priority (nsfw_module_instance_t * + inst, int priority); +extern void nsfw_module_set_instance_initfn (nsfw_module_instance_t * inst, + nsfw_module_init_fn fn); +extern void nsfw_module_set_instance_depends (nsfw_module_instance_t * inst, + char *name); + +/** + * @Function nstack_framework_init + * @Description This function will do framework initial work, it will involk all initial functions + * registed using macro NSFW_MODULE_INIT before + * @param none + * @return 0 on success, -1 on error + */ +extern int nstack_framework_init (void); + +/** + * @Function nstack_framework_setModuleParam + * @Description This function set parameter of module initial function parameter + * @param module - name of module + * @param param - parameter to set + * @return 0 on success, -1 on error + */ +extern int nstack_framework_setModuleParam (char *module, void *param); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#endif /* _FW_INIT_H */ diff --git a/src/framework/include/nsfw_maintain_api.h b/src/framework/include/nsfw_maintain_api.h new file mode 100644 index 0000000..74cedf6 --- /dev/null +++ b/src/framework/include/nsfw_maintain_api.h @@ -0,0 +1,320 @@ +/* +* +* 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 _NSFW_MEM_STAT_API_H +#define _NSFW_MEM_STAT_API_H + +#include "types.h" +#include "nsfw_mgr_com_api.h" +#include "compiling_check.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +/*################MEM_STAT######################*/ +#define NSFW_MEM_MODULE_LEN 32 +#define NSFW_MEM_NAME_LEN 64 + +#define OMC_PROC_MM "omc_proc_maintain" + +#define MEM_STAT(module, mem_name, mem_type, mem_size)\ + nsfw_mem_stat(module, mem_name, mem_type, mem_size) + +extern void nsfw_mem_stat (char *module, char *mem_name, u8 mem_type, + u32 mem_size); +extern void nsfw_mem_stat_print (); +/*##############################################*/ + +/*################SRV_CTRL######################*/ +typedef enum _nsfw_srv_ctrl_state +{ + NSFW_SRV_CTRL_RESUME = 1, + NSFW_SRV_CTRL_SUSPEND = 2 +} nsfw_srv_ctrl_state; + +typedef struct _nsfw_srv_ctrl_msg +{ + nsfw_srv_ctrl_state srv_state; + u16 rsp_code; +} nsfw_srv_ctrl_msg; +extern u8 nsfw_srv_ctrl_send (nsfw_srv_ctrl_state state, u8 rsp_flag); +/*#############################################*/ + +/*#################RES_MGR######################*/ +#define NSFW_RES_MGR_MODULE "nsfw_res_mgr" + +typedef enum _nsfw_res_scan_type +{ + NSFW_RES_SCAN_ARRAY = 0, + NSFW_RES_SCAN_SPOOL, + NSFW_RES_SCAN_MBUF, + NSFW_RES_SCAN_MAX +} nsfw_res_scan_type; + +typedef int (*nsfw_res_free_fun) (void *pdata); + +typedef struct _nsfw_res_scn_cfg +{ + u8 type; /*nsfw_res_scan_type */ + u8 force_free_percent; /*if the resource free percent below this vlaue, begin to force free the element */ + u16 force_free_chk_num; /*if the check count beyone this vlaue, call free fun release this element */ + u16 alloc_speed_factor; /*alloc fast with higher value */ + + u32 num_per_cyc; /*define the element number in one scan cycle process and increase chk_count of every element */ + u32 total_num; /*total number of elements */ + u32 elm_size; /*element size */ + u32 res_mem_offset; /*the nsfw_res offset from the element start */ + + void *data; /*the array addr or spool addr */ + void *mgr_ring; + + nsfw_res_free_fun free_fun; +} nsfw_res_scn_cfg; + +typedef struct _nsfw_res_mgr_item_cfg +{ + nsfw_res_scn_cfg scn_cfg; + u32 cons_head; + u32 prod_head; + u32 free_percent; + u32 last_scn_idx; + u64 force_count; +} nsfw_res_mgr_item_cfg; + +#define NSFW_MAX_RES_SCAN_COUNT 256 + +extern u8 nsfw_res_mgr_reg (nsfw_res_scn_cfg * cfg); +extern i32 nsfw_proc_start_with_lock (u8 proc_type); +/*#############################################*/ + +typedef enum _nsfw_exit_code +{ + NSFW_EXIT_SUCCESS = 0, + NSFW_EXIT_FAILED = 1, + NSFW_EXIT_DST_ERROR = 2, + NSFW_EXIT_TIME_OUT = 3, + + NSFW_EXIT_MAX_COM_ERR = 31, +} nsfw_exit_code; + +/*#############################################*/ + +/*#################SOFT_PARAM##################*/ +#define NSFW_SOFT_PARAM_MODULE "nsfw_soft_param" + +typedef struct _nsfw_soft_param_msg +{ + u32 param_name; + u32 rsp_code; + u8 param_value[NSFW_MGR_MSG_BODY_LEN - sizeof (u32) - sizeof (u32)]; +} +nsfw_soft_param_msg; + +typedef enum _nsfw_soft_param +{ + NSFW_DBG_MODE_PARAM = 1, + NSFW_HBT_TIMER = 2, + NSFW_HBT_COUNT_PARAM = 3, + NSFW_APP_EXIT_TIMER = 4, + NSFW_SRV_RESTORE_TIMER = 5, + NSFW_APP_RESEND_TIMER = 6, + NSFW_APP_SEND_PER_TIME = 7, + + NSFW_MAX_SOFT_PARAM = 1024 +} nsfw_soft_param; + +typedef int (*nsfw_set_soft_fun) (u32 param, char *buf, u32 buf_len); +extern u8 nsfw_soft_param_reg_fun (u32 param_name, nsfw_set_soft_fun fun); +extern u8 nsfw_soft_param_reg_int (u32 param_name, u32 size, u32 min, + u32 max, u64 * data); + +extern void nsfw_set_soft_para (fw_poc_type proc_type, u32 para_name, + void *value, u32 size); + +extern int nsfw_isdigitstr (const char *str); +#define NSFW_REG_SOFT_INT(_param,_data,_min, _max) nsfw_soft_param_reg_int(_param,sizeof(_data),_min,_max,(u64*)&_data) +/*#############################################*/ + +/*#################LOG_CONFIG##################*/ +#define NSFW_LOG_CFG_MODULE "nsfw_log_cfg" + +#define NSFW_MODULE_NAME_LEN 20 +#define NSFW_LOG_LEVEL_LEN 10 +#define NSFW_LOG_VALUE_LEN 256 + +typedef struct _nsfw_set_log_msg +{ + u16 rsp_code; + char module[NSFW_MODULE_NAME_LEN]; + char log_level[NSFW_LOG_VALUE_LEN]; +} nsfw_set_log_msg; +/*#############################################*/ + +/*################## DFX ######################*/ +#define MAX_DFX_QRY_RES_LEN 28 + +#define SPL_DFX_RES_ALL "all" +#define SPL_DFX_RES_QUEUE "queue" +#define SPL_DFX_RES_CONN "conn" +#define SPL_DFX_RES_L2TO4 "l2to4" +#define SPL_DFX_RES_UNMATCH "version" +#define SPL_DFX_RES_SOCKT_CB "socketcb" +#define SPL_DFX_RES_COMM_MEMPOOL "mbufpool" +#define SPL_DFX_RES_PCBLIST "pcblist" +#define SPL_DFX_RES_ARPLIST "arplist" + +typedef enum +{ + DFX_ACTION_SNAPSHOT, + DFX_ACTION_RST_STATS, + DFX_ACTION_SWITCH, + DFX_ACTION_MAX +} dfx_module_action; + +typedef struct _nsfw_dfx_qry_msg +{ + dfx_module_action action; + char resource[MAX_DFX_QRY_RES_LEN]; + char flag; //for snapshot print "all" +} nsfw_dfx_qry_msg; + +typedef enum +{ + QUERY_ACTION_GET, + QUERY_ACTION_MAX +} query_action; + +typedef struct _nsfw_qry_msg +{ + query_action action; + char resource[MAX_DFX_QRY_RES_LEN]; +} nsfw_get_qry_msg; + +/*##################DFX#########################*/ + +/*#################for tcpdump#####################*/ + +#ifndef nstack_min +#define nstack_min(a, b) (a) < (b) ? (a) : (b) +#endif + +#define GET_CUR_TIME(ptime) \ + (void)clock_gettime(CLOCK_MONOTONIC, ptime); + +#define TCPDUMP_MODULE "tcpdump_tool" + +#define DUMP_MSG_NUM (64 * 1024) +COMPAT_PROTECT (DUMP_MSG_NUM, 64 * 1024); +#define DUMP_MSG_SIZE 128 // can not be less than 14 +COMPAT_PROTECT (DUMP_MSG_SIZE, 128); + +#define DEFAULT_DUMP_TIME 600 +#define MAX_DUMP_TIME 86400 +#define MIN_DUMP_TIME 1 + +#define MAX_DUMP_TASK 16 +#define DUMP_HBT_INTERVAL 2 +#define DUMP_HBT_CHK_INTERVAL 4 +#define DUMP_TASK_HBT_TIME_OUT 30 + +#define DUMP_SHMEM_RIGN_NAME "tcpdump_ring" +#define DUMP_SHMEM_POOL_NAME "tcpdump_pool" + +enum L2_PROTOCOL +{ + PROTOCOL_IP = 0x0800, + PROTOCOL_ARP = 0x0806, + PROTOCOL_RARP = 0x8035, + PROTOCOL_OAM_LACP = 0x8809, + INVALID_L2_PROTOCOL = 0xFFFF +}; + +enum L3_PROTOCOL +{ + PROTOCOL_ICMP = 1, + PROTOCOL_TCP = 6, + PROTOCOL_UDP = 17, + INVALID_L3_PROTOCOL = 0xFF +}; + +enum DUMP_MSG_DIRECTION +{ + DUMP_SEND = 1, + DUMP_RECV = 2, + DUMP_SEND_RECV = 3 +}; + +enum DUMP_MSG_TYPE +{ + START_DUMP_REQ, + STOP_DUMP_REQ, + TOOL_COM_HBT_REQ, + + DUMP_MSG_TYPE_RSP = 0x00010000, + + START_DUMP_RSP = START_DUMP_REQ + DUMP_MSG_TYPE_RSP, + STOP_DUMP_RSP = STOP_DUMP_REQ + DUMP_MSG_TYPE_RSP, + + DUMP_MSG_TYPE_INVALID +}; + +typedef struct _nsfw_tool_hbt +{ + u32 seq; + i16 task_id; +} nsfw_tool_hbt; + +typedef struct _nsfw_tool_dump_msg +{ + u16 op_type; + i16 task_id; + u32 task_keep_time; +} nsfw_tool_dump_msg; + +typedef struct _dump_msg_info +{ + u32 len; + u16 direction; // 1:SEND, 2:RECV + u32 dump_sec; + u32 dump_usec; + nsfw_res res_chk; + char buf[1]; +} dump_msg_info; + +typedef struct _dump_timer_info +{ + u32 seq; + i16 task_id; + void *interval; + void *ptimer; +} dump_timer_info; + +extern void ntcpdump_loop (void *buf, u32 buf_len, u16 direction, + void *eth_addr); +extern void ntcpdump (void *buf, u32 buf_len, u16 direction); + +/*##############for tcpdump######################*/ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#endif /* _NSFW_MEM_STAT_API_H */ diff --git a/src/framework/include/nsfw_mem_api.h b/src/framework/include/nsfw_mem_api.h new file mode 100644 index 0000000..ec78692 --- /dev/null +++ b/src/framework/include/nsfw_mem_api.h @@ -0,0 +1,546 @@ +/* +* +* 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 _NSFW_MEM_API_H +#define _NSFW_MEM_API_H +#include +#include + +#include "types.h" +#include "nsfw_mgr_com_api.h" +#include "nstack_log.h" + +#define NSFW_MEM_MGR_MODULE "nsfw_mem_mgr" + +/* + *the max len of memory name is 32bytes, but app just can use max 22bytes, left 10bytes to memory manager module + */ +#define NSFW_MEM_NAME_LENTH (32) +#define NSFW_MEM_APPNAME_LENTH (22) + +#define NSFW_SOCKET_ANY (-1) +#define NSFW_MEM_OK (0) +#define NSFW_MEM_ERR (-1) + +/* + *type of memory: + *NSFW_SHMEM:shared memory + *NSFW_NSHMEM:allocated by calling malloc + */ +typedef enum +{ + NSFW_SHMEM, + NSFW_NSHMEM, + NSFW_MEM_TYPEMAX, +} nsfw_mem_type; + +/*type of ring operation*/ +typedef enum +{ + NSFW_MRING_SPSC, /*sigle producer sigle consumer ring */ + NSFW_MRING_MPSC, /*multi producer sigle consumer ring */ + NSFW_MRING_SPMC, /*sigle producer multi consumer ring */ + NSFW_MRING_MPMC, /*multi producer multi consumer ring */ + NSFW_MRING_SPSC_ST, /*single producer single consumer and belong to one thread ring */ + NSFW_MPOOL_TYPEMAX, +} nsfw_mpool_type; + +typedef void *mpool_handle; +typedef void *mzone_handle; +typedef void *mbuf_handle; +typedef void *mring_handle; + +/*initial of param*/ +typedef struct +{ + i32 iargsnum; + i8 **pargs; + fw_poc_type enflag; /*app, nStackMain, Master */ +} nsfw_mem_para; + +typedef struct +{ + nsfw_mem_type entype; + fw_poc_type enowner; /*notes: 1. when calling any shared memory create inferface, the name of memory end with _0 created by nStackMain, + * end with null created by nStackMaster, and end with _ created by other. + * 2. pname->enowner is available only when call look up shared memory. + * 3. if the roles of process is NSFW_PROC_MASTER but the memory was created by others, or pname->enowner is NSFW_PROC_NULL, + * the name must be full name. + * for examles if the memory was created by nStackMain and pname->enowner is NSFW_PROC_NULL, + * must add '_0' at the end of name, if the memory was created by app and the role of process is NSFW_PROC_MASTER, must add + * _(pid) at the end of name, nstack_123. + */ + i8 aname[NSFW_MEM_NAME_LENTH]; /*the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. */ +} nsfw_mem_name; + +typedef struct +{ + nsfw_mem_name stname; + size_t lenth; + i32 isocket_id; + i32 ireserv; +} nsfw_mem_zone; + +typedef struct +{ + nsfw_mem_name stname; + unsigned usnum; /*the really created mbfpool num is (num+1) power of 2 */ + unsigned uscash_size; + unsigned uspriv_size; + unsigned usdata_room; + i32 isocket_id; + nsfw_mpool_type enmptype; +} nsfw_mem_mbfpool; + +typedef struct +{ + nsfw_mem_name stname; + u32 usnum; /*the really created sppool num is (num+1) power of 2 */ + u32 useltsize; + i32 isocket_id; + nsfw_mpool_type enmptype; +} nsfw_mem_sppool; + +typedef struct +{ + nsfw_mem_name stname; + u32 usnum; /*the really created ring num is (num+1) power of 2 */ + i32 isocket_id; + nsfw_mpool_type enmptype; +} nsfw_mem_mring; + +typedef enum +{ + NSFW_MEM_ALLOC_SUCC = 1, + NSFW_MEM_ALLOC_FAIL = 2, +} nsfw_mem_alloc_state; + +typedef enum +{ + NSFW_MEM_MZONE, + NSFW_MEM_MBUF, + NSFW_MEM_SPOOL, + NSFW_MEM_RING +} nsfw_mem_struct_type; + +typedef enum +{ + NSFW_RESERV_REQ_MSG, + NSFW_RESERV_ACK_MSG, + NSFW_MBUF_REQ_MSG, + NSFW_MBUF_ACK_MSG, + NSFW_SPPOOL_REQ_MSG, + NSFW_SPPOOL_ACK_MSG, + NSFW_RING_REQ_MSG, + NSFW_RING_ACK_MSG, + NSFW_RELEASE_REQ_MSG, + NSFW_RELEASE_ACK_MSG, + NSFW_MEM_LOOKUP_REQ_MSG, + NSFW_MEM_LOOKUP_ACK_MSG, + NSFW_MEM_MAX_MSG +} nsfw_remote_msg; + +typedef struct __nsfw_shmem_msg_head +{ + unsigned usmsg_type; + unsigned uslenth; + i32 aidata[0]; +} nsfw_shmem_msg_head; + +typedef struct __nsfw_shmem_ack +{ + void *pbase_addr; + u16 usseq; + i8 cstate; + i8 creserv; + i32 ireserv; +} nsfw_shmem_ack; + +typedef struct __nsfw_shmem_reserv_req +{ + i8 aname[NSFW_MEM_NAME_LENTH]; + u16 usseq; + u16 usreserv; + i32 isocket_id; + size_t lenth; + i32 ireserv; +} nsfw_shmem_reserv_req; + +typedef struct __nsfw_shmem_mbuf_req +{ + i8 aname[NSFW_MEM_NAME_LENTH]; + u16 usseq; + u16 enmptype; + unsigned usnum; + unsigned uscash_size; + unsigned uspriv_size; + unsigned usdata_room; + i32 isocket_id; + i32 ireserv; +} nsfw_shmem_mbuf_req; + +typedef struct __nsfw_shmem_sppool_req +{ + i8 aname[NSFW_MEM_NAME_LENTH]; + u16 usseq; + u16 enmptype; + u32 usnum; + u32 useltsize; + i32 isocket_id; + i32 ireserv; +} nsfw_shmem_sppool_req; + +typedef struct __nsfw_shmem_ring_req +{ + i8 aname[NSFW_MEM_NAME_LENTH]; + u16 usseq; + u16 enmptype; + u32 usnum; + i32 isocket_id; + i32 ireserv; +} nsfw_shmem_ring_req; + +typedef struct __nsfw_shmem_free_req +{ + i8 aname[NSFW_MEM_NAME_LENTH]; + u16 usseq; + u16 ustype; /*structure of memory(memzone,mbuf,mpool,ring) */ + i32 ireserv; +} nsfw_shmem_free_req; + +typedef struct __nsfw_shmem_lookup_req +{ + i8 aname[NSFW_MEM_NAME_LENTH]; + u16 usseq; + u16 ustype; /*structure of memory(memzone,mbuf,mpool,ring) */ + i32 ireserv; +} nsfw_shmem_lookup_req; + +typedef int (*nsfw_mem_ring_enqueue_fun) (mring_handle ring, void *box); +typedef int (*nsfw_mem_ring_dequeue_fun) (mring_handle ring, void **box); +typedef int (*nsfw_mem_ring_dequeuev_fun) (mring_handle ring, void **box, + unsigned int n); + +typedef struct +{ + nsfw_mem_ring_enqueue_fun ring_ops_enqueue; + nsfw_mem_ring_dequeue_fun ring_ops_dequeue; + nsfw_mem_ring_dequeuev_fun ring_ops_dequeuev; +} nsfw_ring_ops; + +/* + * memory module init + * para:point to nstak_fwmem_para + */ +i32 nsfw_mem_init (void *para); + +/* + * create a block memory with name + * nsfw_mem_zone::stname + * nsfw_mem_zone::isize + * note: 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. + */ +mzone_handle nsfw_mem_zone_create (nsfw_mem_zone * pinfo); + +/* + *create some memory blocks + * note: 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. + */ +i32 nsfw_mem_zone_createv (nsfw_mem_zone * pmeminfo, i32 inum, + mzone_handle * paddr_array, i32 iarray_num); + +/* + *look up a memory + * note: 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. + * 2. if the memory is shared, pname->enowner indicate that who create this memory, + * note: + * 1. when calling any shared memory create inferface, the name of memory end with _0 created by nStackMain, + * end with none created by nStackMaster, and end with _ created by other. + * 2. pname->enowner is available only when call look up shared memory. + * 3. if the roles of process is NSFW_PROC_MASTER but the memory was created by others, or pname->enowner is NSFW_PROC_NULL, + * the name must be full name. + * for examles if the memory was created by nStackMain and pname->enowner is NSFW_PROC_NULL, + * must add '_0' at the end of name, if the memory was created by app and the role of process is NSFW_PROC_MASTER, must add + * _(pid) at the end of name, nstack_123. + */ +mzone_handle nsfw_mem_zone_lookup (nsfw_mem_name * pname); + +/*release a memory*/ +i32 nsfw_mem_zone_release (nsfw_mem_name * pname); + +/* + *create a mbuf pool + */ +mpool_handle nsfw_mem_mbfmp_create (nsfw_mem_mbfpool * pbufinfo); + +/* + *create some mbuf pools + * note: 1. the name of lenth must be less than NSFW_MEM_APPNAME_LENTH. + */ +i32 nsfw_mem_mbfmp_createv (nsfw_mem_mbfpool * pmbfname, i32 inum, + mpool_handle * phandle_array, i32 iarray_num); + +/* + *alloc a mbuf from mbuf pool + */ +mbuf_handle nsfw_mem_mbf_alloc (mpool_handle mhandle, nsfw_mem_type entype); + +/* + *put a mbuf backintp mbuf pool + */ +i32 nsfw_mem_mbf_free (mbuf_handle mhandle, nsfw_mem_type entype); + +/* + *look up mbuf mpool + * note: 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. + * 2. if the memory is shared, pname->enowner indicate that who create this memory. + * note: + * 1. when calling any shared memory create inferface, the name of memory end with _0 created by nStackMain, + * end with none created by nStackMaster, and end with _ created by other. + * 2. pname->enowner is available only when call look up shared memory. + * 3. if the roles of process is NSFW_PROC_MASTER but the memory was created by others, or pname->enowner is NSFW_PROC_NULL, + * the name must be full name. + * for examles if the memory was created by nStackMain and pname->enowner is NSFW_PROC_NULL, + * must add '_0' at the end of name, if the memory was created by app and the role of process is NSFW_PROC_MASTER, must add + * _(pid) at the end of name, nstack_123. + */ +mpool_handle nsfw_mem_mbfmp_lookup (nsfw_mem_name * pmbfname); + +/* + *release mbuf pool + * note: 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. + */ +i32 nsfw_mem_mbfmp_release (nsfw_mem_name * pname); + +/* + *create a simple pool + *note: 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. + */ +mring_handle nsfw_mem_sp_create (nsfw_mem_sppool * pmpinfo); + +/* + *create some simple pools one time + *note: 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. + */ +i32 nsfw_mem_sp_createv (nsfw_mem_sppool * pmpinfo, i32 inum, + mring_handle * pringhandle_array, i32 iarray_num); + +/* + *create a simple pool with many rings + *note: 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. + */ +i32 nsfw_mem_sp_ring_create (nsfw_mem_mring * prpoolinfo, + mring_handle * pringhandle_array, i32 iringnum); + +/* + *release a simple mempool + *note: 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. + */ +i32 nsfw_mem_sp_release (nsfw_mem_name * pname); + +/* + *look up a simpile ring + * note: 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. + * 2. if the memory is shared, pname->enowner indicate that who create this memory, + * note: + * 1. when calling any shared memory create inferface, the name of memory end with _0 created by nStackMain, + * end with none created by nStackMaster, and end with _ created by other. + * 2. pname->enowner is available only when call look up shared memory. + * 3. if the roles of process is NSFW_PROC_MASTER but the memory was created by others, or pname->enowner is NSFW_PROC_NULL, + * the name must be full name. + * for examles if the memory was created by nStackMain and pname->enowner is NSFW_PROC_NULL, + * must add '_0' at the end of name, if the memory was created by app and the role of process is NSFW_PROC_MASTER, must add + * _(pid) at the end of name, nstack_123. + */ +mring_handle nsfw_mem_sp_lookup (nsfw_mem_name * pname); + +/* + *create a ring + *note: 1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. + * 2. shared memory ring (NSFW_SHMEM) just can put a pointor into the queue, the queue also point to a shared block memory. + * no shared memory ring(NSFW_NSHMEM) is other wise. + */ +mring_handle nsfw_mem_ring_create (nsfw_mem_mring * pringinfo); + +/* + *look up a ring by name + * note:1. the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. + * 2. if the memory is shared, pname->enowner indicate that who create this memory, + * note: + * 1. when calling any shared memory create inferface, the name of memory end with _0 created by nStackMain, + * end with none created by nStackMaster, and end with _ created by other. + * 2. pname->enowner is available only when call look up shared memory. + * 3. if the roles of process is NSFW_PROC_MASTER but the memory was created by others, or pname->enowner is NSFW_PROC_NULL, + * the name must be full name. + * for examles if the memory was created by nStackMain and pname->enowner is NSFW_PROC_NULL, + * must add '_0' at the end of name, if the memory was created by app and the role of process is NSFW_PROC_MASTER, must add + * _(pid) at the end of name, nstack_123. + */ +mring_handle nsfw_mem_ring_lookup (nsfw_mem_name * pname); + +/* + * reset the number of producer and consumer, also, the state of ring reset to empty + * notes: must be called before doing any operations base on the ring + */ +void nsfw_mem_ring_reset (mring_handle mhandle, nsfw_mpool_type entype); + +extern nsfw_ring_ops g_ring_ops_arry[NSFW_MEM_TYPEMAX][NSFW_MPOOL_TYPEMAX]; + +/***************************************************************************** +* Prototype : nsfw_mem_ring_dequeue +* Description : get a member from a ring +* note : if NSFW_SHMEM ring, pdata returned alread a local address +* Input : mring_handle mhandle +* void** pdata +* Output : None +* Return Value : the num of elment get from the queue, =0: get null, <0: err happen, >0: return num. +* Calls : +* Called By : +* +*****************************************************************************/ +static inline i32 +nsfw_mem_ring_dequeue (mring_handle mhandle, void **pdata) +{ + if (NULL == mhandle || *((u8 *) mhandle) >= NSFW_MEM_TYPEMAX + || *((u8 *) mhandle + 1) >= NSFW_MPOOL_TYPEMAX) + { + NSCOMM_LOGERR ("input para error] mhandle=%p", mhandle); + return -1; + } + + return + g_ring_ops_arry[*((u8 *) mhandle)][*((u8 *) mhandle + 1)].ring_ops_dequeue + (mhandle, pdata); +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_dequeuev +* Description : get some members from a ring +* note : if NSFW_SHMEM ring, pdata returned alread a local address +* Input : mring_handle mhandle +* void** pdata +* unsigned inum +* Output : None +* Return Value : the num of elment get from the queue, =0: get null, <0: err happen, >0: return num. +* Calls : +* Called By : +* +*****************************************************************************/ +static inline i32 +nsfw_mem_ring_dequeuev (mring_handle mhandle, void **pdata, unsigned int inum) +{ + if (NULL == mhandle || *((u8 *) mhandle) >= NSFW_MEM_TYPEMAX + || *((u8 *) mhandle + 1) >= NSFW_MPOOL_TYPEMAX) + { + NSCOMM_LOGERR ("input para error] mhandle=%p", mhandle); + return -1; + } + + return + g_ring_ops_arry[*((u8 *) mhandle)][* + ((u8 *) mhandle + + 1)].ring_ops_dequeuev (mhandle, pdata, + inum); +} + +/***************************************************************************** +* Prototype : nsfw_mem_ring_enqueue +* Description : put a member back into a ring +* note : pdata must point to a shared block memory when put into the NSFW_SHMEM type memory ring, and the +* value of pdata must be local address +* Input : mring_handle mhandle +* void* pdata +* Output : None +* Return Value : the num of elment put into the queue, =0: put null, <0: err happen, >0: return num. +* Calls : +* Called By : +* +*****************************************************************************/ +static inline i32 +nsfw_mem_ring_enqueue (mring_handle mhandle, void *pdata) +{ + if (NULL == mhandle || *((u8 *) mhandle) >= NSFW_MEM_TYPEMAX + || *((u8 *) mhandle + 1) >= NSFW_MPOOL_TYPEMAX) + { + NSCOMM_LOGERR ("input para error] mhandle=%p", mhandle); + return -1; + } + + return + g_ring_ops_arry[*((u8 *) mhandle)][*((u8 *) mhandle + 1)].ring_ops_enqueue + (mhandle, pdata); +} + +/* + *get the free number of ring + */ +u32 nsfw_mem_ring_free_count (mring_handle mhandle); + +/* + *get the in using number of ring + */ +u32 nsfw_mem_ring_using_count (mring_handle mhandle); + +/* + *get size of ring + */ +u32 nsfw_mem_ring_size (mring_handle mhandle); + +/* + *release a ring memory + *note: the lenth of name must be less than NSFW_MEM_APPNAME_LENTH. + */ +i32 nsfw_mem_ring_release (nsfw_mem_name * pname); + +/* + *statics mbufpool, sppool, ring mem size + *return: <=0, err happen, >0 mem size + * NSFW_MEM_MZONE: not surport because you already know the lenth when create + */ +ssize_t nsfw_mem_get_len (void *handle, nsfw_mem_struct_type type); + +/* + *recycle mbuf + * + */ +i32 nsfw_mem_mbuf_pool_recycle (mpool_handle handle); + +typedef int (*nsfw_mem_item_fun) (void *data, void *argv); + +i32 nsfw_mem_sp_iterator (mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv); +i32 nsfw_mem_mbuf_iterator (mpool_handle handle, u32 start, u32 end, + nsfw_mem_item_fun fun, void *argv); + +/***************************************************************************** +* Prototype : nsfw_mem_dfx_ring_print +* Description : print ring info +* Input : mring_handle mhandle +* char *pbuf +* int lenth +* Output : None +* Return Value : i32 +* Calls : +* Called By : +* +*****************************************************************************/ +i32 nsfw_mem_dfx_ring_print (mring_handle mhandle, char *pbuf, int lenth); + +#ifdef SYS_MEM_RES_STAT +u32 nsfw_mem_mbfpool_free_count (mpool_handle mhandle); +#endif + +#endif diff --git a/src/framework/include/nsfw_mgr_com_api.h b/src/framework/include/nsfw_mgr_com_api.h new file mode 100644 index 0000000..2499fee --- /dev/null +++ b/src/framework/include/nsfw_mgr_com_api.h @@ -0,0 +1,198 @@ +/* +* +* 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 header files * + *----------------------------------------------*/ +#ifndef _NSFW_MGRCOM_API_H +#define _NSFW_MGRCOM_API_H + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#define NSFW_MGR_COM_MODULE "nsfw_mgr_com" + +#define MRG_RSP(_req_msg) (_req_msg + MGR_MSG_RSP_BASE) + +typedef enum _mgr_msg_type +{ + MGR_MSG_NULL = 0, + /*#############common msg type################# */ + MGR_MSG_CHK_INIT_REQ = 1, + MGR_MSG_INIT_NTY_REQ, + MGR_MSG_CHK_HBT_REQ, + MGR_MSG_APP_EXIT_REQ, + MGR_MSG_SRV_CTL_REQ, + MGR_MSG_VER_MGR_REQ, + MGR_MSG_SOF_PAR_REQ, + + /*############################################# */ + MGR_MSG_MEM_ALLOC_REQ = 64, /* memory msg type */ + + /*############################################# */ + MGR_MSG_DFX_QRY_REQ = 96, /* nStackCtrl maitain msg */ + MGR_MSG_SET_LOG_REQ, + + /*############################################# */ + MGR_MSG_RCC_END_REQ = 128, /* service msg type */ + + /*############################################# */ + MGR_MSG_TOOL_TCPDUMP_REQ = 256, /* for tools */ + MGR_MSG_TOOL_HEART_BEAT, + + /*###query message with large rsp message begin## */ + MGR_MSG_LARGE_QRY_REQ_BEGIN = 384, + MGR_MSG_LARGE_STA_QRY_REQ = MGR_MSG_LARGE_QRY_REQ_BEGIN, + MGR_MSG_LARGE_MT_QRY_REQ, /* nStackCtrl maitain msg */ + + /*############################################# */ + MGR_MSG_LARGE_ALARM_REQ = 500, /* alarm msg type */ + + MGR_MSG_RSP_BASE = 512, + /*#############common msg type################# */ + MGR_MSG_CHK_INIT_RSP = MRG_RSP (MGR_MSG_CHK_INIT_REQ), + MGR_MSG_INIT_NTY_RSP = MRG_RSP (MGR_MSG_INIT_NTY_REQ), + MGR_MSG_CHK_HBT_RSP = MRG_RSP (MGR_MSG_CHK_HBT_REQ), + MGR_MSG_APP_EXIT_RSP = MRG_RSP (MGR_MSG_APP_EXIT_REQ), + MGR_MSG_SRV_CTL_RSP = MRG_RSP (MGR_MSG_SRV_CTL_REQ), + MGR_MSG_VER_MGR_RSP = MRG_RSP (MGR_MSG_VER_MGR_REQ), + MGR_MSG_SOF_PAR_RSP = MRG_RSP (MGR_MSG_SOF_PAR_REQ), + /*############################################# */ + + MGR_MSG_MEM_ALLOC_RSP = MRG_RSP (MGR_MSG_MEM_ALLOC_REQ), + + MGR_MSG_DFX_QRY_RSP = MRG_RSP (MGR_MSG_DFX_QRY_REQ), + + MGR_MSG_SET_LOG_RSP = MRG_RSP (MGR_MSG_SET_LOG_REQ), + + MGR_MSG_RCC_END_RSP = MRG_RSP (MGR_MSG_RCC_END_REQ), + + /*############################################# */ + MGR_MSG_TOOL_TCPDUMP_RSP = MRG_RSP (MGR_MSG_TOOL_TCPDUMP_REQ), + MGR_MSG_TOOL_HEART_BEAT_RSP = MRG_RSP (MGR_MSG_TOOL_HEART_BEAT), + + /*##############LARGE RSP MESSAGE################## */ + MGR_MSG_LAG_QRY_RSP_BEGIN = MRG_RSP (MGR_MSG_LARGE_QRY_REQ_BEGIN), + MGR_MSG_LAG_STA_QRY_RSP = MRG_RSP (MGR_MSG_LARGE_STA_QRY_REQ), + MGR_MSG_LAG_MT_QRY_RSP = MRG_RSP (MGR_MSG_LARGE_MT_QRY_REQ), + MGR_MSG_LARGE_ALARM_RSP = MRG_RSP (MGR_MSG_LARGE_ALARM_REQ), + MGR_MSG_MAX = 1024 +} mgr_msg_type; + +typedef enum _fw_poc_type +{ + NSFW_PROC_NULL = 0, + NSFW_PROC_MAIN, + NSFW_PROC_MASTER, + NSFW_PROC_APP, + NSFW_PROC_CTRL, + NSFW_PROC_TOOLS, + NSFW_PROC_ALARM, + NSFW_PROC_MAX = 16 +} fw_poc_type; + +#define NSFW_DOMAIN_DIR "/var/run" +#define NSTACK_MAX_PROC_NAME_LEN 20 + +typedef enum _nsfw_mgr_msg_rsp_code +{ + NSFW_MGR_SUCESS, + NSFW_MGR_MSG_TYPE_ERROR, +} mgr_msg_rsp_code; + +extern char *nsfw_get_proc_name (u8 proc_type); + +#define GET_USER_MSG(_stu, _msg) ((_stu *)(&(_msg)->msg_body[0])) + +/*for log print*/ +#define MSGINFO "msg=%p,len=%d,t=%d,sq=%d,st=%d,sp=%d,dt=%d,dp=%d" +#define PRTMSG(msg) (msg), (msg)->msg_len,(msg)->msg_type,(msg)->seq, (msg)->src_proc_type,(msg)->src_pid,(msg)->dst_proc_type,(msg)->dst_pid + +#define NSFW_MGR_MSG_LEN 512 +#define NSFW_MGR_MSG_HDR_LEN 32 +#define NSFW_MGR_MSG_BODY_LEN (NSFW_MGR_MSG_LEN - NSFW_MGR_MSG_HDR_LEN) + +#define NSFW_MGR_LARGE_MSG_LEN (256*1024) +#define NSFW_MGR_LARGE_MSG_BODY_LEN (NSFW_MGR_LARGE_MSG_LEN - NSFW_MGR_MSG_HDR_LEN) + +typedef struct _nsfw_mgr_msg +{ + u16 msg_type; /* mgr_msg_type */ + u16 u16Reserve; + u32 msg_len; + + u8 alloc_flag:1; + u8 fw_flag:1; + u8 from_mem:1; + u8 more_msg_flag:1; + u8 reserve_flag:4; + u8 resp_code; + u8 src_proc_type; /* fw_poc_type */ + u8 dst_proc_type; + i32 seq; + + u32 src_pid; + u32 dst_pid; + + u64 traceid; + + u8 msg_body[NSFW_MGR_MSG_BODY_LEN]; +} nsfw_mgr_msg; + +extern nsfw_mgr_msg *nsfw_mgr_msg_alloc (u16 msg_type, u8 dst_proc_type); +extern void nsfw_mgr_msg_free (nsfw_mgr_msg * msg); + +/* for rsp msg alloc*/ +extern nsfw_mgr_msg *nsfw_mgr_null_rspmsg_alloc (); +extern nsfw_mgr_msg *nsfw_mgr_rsp_msg_alloc (nsfw_mgr_msg * req_msg); + +/* for msg proc fun reg*/ +typedef int (*nsfw_mgr_msg_fun) (nsfw_mgr_msg * msg); +extern u8 nsfw_mgr_reg_msg_fun (u16 msg_type, nsfw_mgr_msg_fun fun); + +extern u8 nsfw_mgr_send_msg (nsfw_mgr_msg * msg); +extern u8 nsfw_mgr_send_req_wait_rsp (nsfw_mgr_msg * req_msg, + nsfw_mgr_msg * rsp_msg); + +/* for fork clear parent resource*/ +extern void nsfw_mgr_close_dst_proc (u8 proc_type, u32 dst_pid); +extern u8 nsfw_mgr_clr_fd_lock (); + +/* for epoll thread reg other sock proc fun*/ +typedef int (*nsfw_mgr_sock_fun) (i32 epfd, i32 socket, u32 events); +extern u8 nsfw_mgr_reg_sock_fun (i32 socket, nsfw_mgr_sock_fun fun); +extern void nsfw_mgr_unreg_sock_fun (i32 socket); +extern int nsfw_mgr_com_socket_error (i32 fd, nsfw_mgr_sock_fun fun, + i32 timer); +extern u8 nsfw_mgr_ep_start (); +extern int nsfw_mgr_com_module_init (void *param); +extern int nsfw_mgr_run_script (const char *cmd, char *result, + int result_buf_len); + +extern int nsfw_mgr_com_chk_hbt (int v_add); +extern i32 nsfw_set_close_on_exec (i32 sock); +extern int nsfw_mgr_comm_fd_init (u32 proc_type); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#endif /* _NSFW_MGRCOM_API_H */ diff --git a/src/framework/include/nsfw_ps_api.h b/src/framework/include/nsfw_ps_api.h new file mode 100644 index 0000000..69fa992 --- /dev/null +++ b/src/framework/include/nsfw_ps_api.h @@ -0,0 +1,134 @@ +/* +* +* 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 _NSFW_PS_API_H +#define _NSFW_PS_API_H + +#include "list.h" +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#define NSFW_PS_MODULE "nsfw_ps" + +#define NSFW_PS_MAX_CALLBACK 16 + +#define NSFW_MAX_HBT_CHK_COUNT_DEF 60 + +typedef enum _nsfw_ps_state +{ + NSFW_PS_NULL = 0, + NSFW_PS_START, + NSFW_PS_RUNNING, + NSFW_PS_PARENT_FORK, + NSFW_PS_CHILD_FORK, + NSFW_PS_HBT_FAILED, + NSFW_PS_EXITING, + NSFW_PS_EXIT, + NSFW_PS_MAX +} nsfw_ps_state; + +/* for state change call back proc*/ +typedef int (*nsfw_ps_proc_fun) (void *pps_info, void *argv); +typedef struct _nsfw_ps_callback +{ + u8 state; + nsfw_ps_proc_fun fun; + void *argv; +} nsfw_ps_callback; + +/* for value in ps_info get/set*/ +typedef enum _nsfw_ps_user_value +{ + NSFW_REC_IDX = 1, + NSFW_REC_TIMER = 2, + NSFW_PS_UV_MAX = 16 +} nsfw_ps_user_value; +#define nsfw_ps_set_uv(_pps_info, _type, _value) (_pps_info)->value[(_type)] = (_value) +#define nsfw_ps_get_uv(_pps_info, _type) ((_pps_info)->value[(_type)]) + +typedef struct _nsfw_ps_info +{ + struct list_head node; + u8 alloc_flag; + u8 state; /*nsfw_ps_state */ + u8 proc_type; /*fw_poc_type */ + u8 rechk_flg; + u32 host_pid; + u32 parent_pid; /* only use for fork */ + u32 cur_child_pid; /* only use for fork */ + void *exit_timer_ptr; + void *resend_timer_ptr; + void *hbt_timer_ptr; + u32 hbt_failed_count; + nsfw_ps_callback callback[NSFW_PS_MAX_CALLBACK]; + void *value[NSFW_PS_UV_MAX]; +} nsfw_ps_info; + +typedef struct _nsfw_thread_dogs +{ + u8 alloc_flag; + i32 count; + u32 thread_id; +} nsfw_thread_dogs; + +extern nsfw_ps_info *nsfw_ps_info_alloc (u32 pid, u8 proc_type); +extern nsfw_ps_info *nsfw_ps_info_get (u32 pid); +extern void nsfw_ps_info_free (nsfw_ps_info * ps_info); + +extern u8 nsfw_ps_reg_fun (nsfw_ps_info * pps_info, u8 ps_state, + nsfw_ps_proc_fun fun, void *argv); + +/* will auto reg after ps_info alloc*/ +extern u8 nsfw_ps_reg_global_fun (u8 proc_type, u8 ps_state, + nsfw_ps_proc_fun fun, void *argv); + +typedef struct _nsfw_ps_info_msg +{ + u32 host_pid; + u32 parent_pid; + u64 reserve; +} nsfw_ps_info_msg; +extern u8 nsfw_ps_exit_end_notify (u32 pid); + +/*for heartbeat check*/ +extern u8 nsfw_ps_check_dst_init (u8 dst_proc_type); +extern u8 nsfw_thread_chk (); +extern nsfw_thread_dogs *nsfw_thread_getDog (); +extern u8 nsfw_thread_chk_unreg (); +extern u8 nsfw_ps_hbt_start (nsfw_ps_info * ps_info); +extern u8 nsfw_ps_hbt_stop (nsfw_ps_info * ps_info); + +extern u32 nsfw_ps_iterator (nsfw_ps_proc_fun fun, void *argv); + +#define MAX_THREAD 16 +extern pthread_t g_all_thread[]; +extern u8 nsfw_reg_trace_thread (pthread_t tid); + +typedef int (*nsfw_ps_pid_fun) (u32 pid, u8 proc_type, void *argv); +extern int nsfw_ps_rechk_pid_exit (nsfw_ps_pid_fun fun, void *argv); +extern nsfw_ps_info *nsfw_share_ps_info_get (u32 pid); +extern void nsfw_ps_cfg_set_chk_count (u16 count); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#endif /* _NSFW_PS_API_H */ diff --git a/src/framework/include/nsfw_ps_mem_api.h b/src/framework/include/nsfw_ps_mem_api.h new file mode 100644 index 0000000..01f9cd3 --- /dev/null +++ b/src/framework/include/nsfw_ps_mem_api.h @@ -0,0 +1,36 @@ +/* +* +* 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 _NSFW_PS_MEM_API_H +#define _NSFW_PS_MEM_API_H + +#include "nsfw_mem_api.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#define NSFW_PS_MEM_MODULE "nsfw_ps_mem" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#endif /* _NSFW_PS_MEM_API_H */ diff --git a/src/framework/include/nsfw_recycle_api.h b/src/framework/include/nsfw_recycle_api.h new file mode 100644 index 0000000..fd2bd8f --- /dev/null +++ b/src/framework/include/nsfw_recycle_api.h @@ -0,0 +1,92 @@ +/* +* +* 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 _NSFW_RECYCLE_API_H +#define _NSFW_RECYCLE_API_H + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#define NSFW_RECYCLE_MODULE "nsfw_recycle" + +typedef enum _nsfw_recycle_item_type +{ + NSFW_REC_TYPE_NULL = 0, + NSFW_REC_SBR_START = 1, + NSFW_REC_SBR_SOCKET, + NSFW_REC_SBR_END = NSFW_REC_SBR_START + 63, + NSFW_REC_NSOCKET_START, + NSFW_REC_NSOCKET_EPOLL, + NSFW_REC_NSOCKET_END = NSFW_REC_NSOCKET_START + 63, + NSFW_REC_TYPE_MAX = 512 +} nsfw_recycle_item_type; + +typedef enum _nsfw_recycle_priority +{ + NSFW_REC_PRO_HIGHTEST = 0, + NSFW_REC_PRO_NORMAL = 1, + NSFW_REC_PRO_DEFALUT = 2, + NSFW_REC_PRO_LOWEST = 3, + NSFW_REC_PRO_MAX = 4 +} nsfw_recycle_priority; + +typedef enum _nsfw_rcc_stat +{ + NSFW_RCC_CONTINUE = 0, + NSFW_RCC_SUSPEND = 1, + NSFW_RCC_FAILED = 2, +} nsfw_rcc_stat; + +/*work on nStackMain*/ +typedef nsfw_rcc_stat (*nsfw_recycle_fun) (u32 exit_pid, void *pdata, + u16 rec_type); +extern u8 nsfw_recycle_reg_fun (u16 obj_type, nsfw_recycle_fun fun); +extern u8 nsfw_recycle_obj_end (u32 pid); +extern u8 nsfw_recycle_lock_rel_fun (nsfw_recycle_fun fun, void *data, + u8 proc_type); +extern int nsfw_recycle_exit_pid_lock (u32 pid, u8 proc_type, void *argv); + +#define REGIST_RECYCLE_OBJ_FUN(_obj_type, _fun) \ + NSTACK_STATIC void regist_ ## _obj_type ## _fun (void) \ + __attribute__((__constructor__)); \ + NSTACK_STATIC void regist_ ## _obj_type ## _fun (void) \ + { \ + (void)nsfw_recycle_reg_fun(_obj_type, _fun); \ + } + +#define REGIST_RECYCLE_LOCK_REL(_fun, _data, _proc) \ + NSTACK_STATIC void regist_lock ## _fun (void) \ + __attribute__((__constructor__)); \ + NSTACK_STATIC void regist_lock ## _fun (void) \ + { \ + (void)nsfw_recycle_lock_rel_fun(_fun, _data,_proc); \ + } + +/*work on nStackApp*/ +extern void *nsfw_recycle_reg_obj (u8 priority, u16 rec_type, void *data); +extern u8 nsfw_recycle_fork_init (); +extern int nsfw_recycle_rechk_lock (); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#endif /* _NSFW_RECYCLE_API_H */ diff --git a/src/framework/include/nsfw_snapshot.h b/src/framework/include/nsfw_snapshot.h new file mode 100644 index 0000000..8958c64 --- /dev/null +++ b/src/framework/include/nsfw_snapshot.h @@ -0,0 +1,144 @@ +/* +* +* 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 _FW_SNAPSHOT_H +#define _FW_SNAPSHOT_H + +#include +#include "types.h" +#include "../snapshot/fw_ss_tlv.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +// object type(7 bits) | member type (7 bits) | is object(1 bit) | is array(1 bit) +// member type is the type in object structure , it only effects the own object +/** + * type - object , type object of array, type base item + */ + +#define NSFW_SS_TYPE_OBJ(_objType) (0xfe00 & ((_objType) << 9)) +#define NSFW_SS_TYPE_GETOBJ(_objType) ((0xfe00 & (_objType)) >> 9) + +#define NSFW_SS_TYPE_MEMBER(_memType) (0x01fc & ((_memType) << 2)) +#define NSFW_SS_TYPE_GET_MEMBER(_memType) ((0x01fc & (_memType)) >> 2) + +#define NSFW_SS_TYPE_SET_MEMBER_ITEM(_memType) (NSFW_SS_TYPE_MEMBER((_memType))) +#define NSFW_SS_TYPE_SET_MEMBER_OBJ(_objType, _memType) \ + (NSFW_SS_TYPE_OBJ((_objType)) | NSFW_SS_TYPE_SET_MEMBER_ITEM((_memType)) | 0x02) +#define NSFW_SS_TYPE_SET_MEMBER_OBJ_ARRAY(_objType, _memType) \ + (NSFW_SS_TYPE_SET_MEMBER_OBJ((_objType), (_memType)) | 0x01) + +#define NSFW_SS_TYPE_IS_MEMBER_OBJ(_memType) ((_memType) & 0x02) +#define NSFW_SS_TYPE_IS_MEMBER_ARRAY(_memType) ((_memType) & 0x01) + +/* + * This structure tells how to describe one object and its members + */ +typedef struct _nsfw_ss_objMemDesc +{ + u16 type; // object type(7 bits) | member type (7 bits) | is object(1 bit) | is array(1 bit) + u32 length; + u8 offset; +} nsfw_ss_objMemDesc_t; + +typedef struct _nsfw_ss_objDesc +{ + u16 objType; /* Type number of object */ + u8 memNum; /* Nubmer of object members */ + u32 objSize; + nsfw_ss_objMemDesc_t *memDesc; /* Member descripe */ +} nsfw_ss_objDesc_t; + +#define NSFW_SS_MAX_OBJDESC_NUM 256 + +/* Traversal, you can save the current value to start the search, do not need to start from the beginning of the search, because the value is generally a sequential */ + +typedef struct _nsfw_ss_objDescManager +{ + nsfw_ss_objDesc_t *g_nsfw_ss_objDescs[NSFW_SS_MAX_OBJDESC_NUM]; + int g_nsfw_ss_objDesNum; +} nsfw_ss_objDescManager_t; + +extern nsfw_ss_objDescManager_t g_nsfw_ss_objDescManager; + +#define nsfw_ss_getObjDescManagerInst() (&g_nsfw_ss_objDescManager) + +/** + * @Function nsfw_ss_registe_ObjDesc + * @Description Registe object description to snapshot + * @param objDesc - description of object + * @return void + */ +extern void nsfw_ss_register_ObjDesc (nsfw_ss_objDesc_t * objDesc); + +/** + * @Function nsfw_ss_store + * @Description store object to memory + * @param (in) objType - type of object + * @param (in) obj - adderss of object memory + * @param (in) storeMem - address of memory to store object data + * @param (in) storeMemLen - maximal length of storage memory + * @return positive integer means length of memory cost on success. return -1 if error + */ +extern int nsfw_ss_store (u16 objType, void *obj, void *storeMem, + u32 storeMemLen); + +/** + * @Function nsfw_ss_restore + * @Description restore object from memory + * @param (in) objMem - memory of object + * @param (in) mem - memory of storage + * @param (in) storeMemLen - maximal length of storage memory + * @return positive integer stands on object type, -1 on error + */ +extern int nsfw_ss_restore (void *objMem, void *mem, u32 storeMemLen); + +/** + * @Function nsfw_ss_getObjStoreMemLen + * @Description Get the maximal memory it needs + * @param (in) objType - type of object + * @return length of memory needs, -1 if error + */ +extern int nsfw_ss_getObjStoreMemLen (int objType); + +#define _NSFW_SNAPSHOT_OBJDESC_REGISTER_SURFIX(_value, _surfix) \ + static __attribute__((__constructor__(121))) void nsfw_snapshot_objdesc_register_constructor##_surfix(void){\ + nsfw_ss_register_ObjDesc((_value));\ + } + +#define NSFW_SNAPSHOT_OBJDESC_REGISTER_SURFIX(_value, _surfix) \ + _NSFW_SNAPSHOT_OBJDESC_REGISTER_SURFIX(_value, _surfix) + +#define NSFW_SNAPSHOT_OBJDESC_REGISTER_UNIQUE(_value) \ + NSFW_SNAPSHOT_OBJDESC_REGISTER_SURFIX(_value, __LINE__) + +/** + * Using this marcro to register object description + */ +#define NSFW_SS_REGSITER_OBJDESC(_value) \ + NSFW_SNAPSHOT_OBJDESC_REGISTER_UNIQUE(_value) + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#endif /* _FW_SNAPSHOT_H */ diff --git a/src/framework/include/nsfw_upgrade.h b/src/framework/include/nsfw_upgrade.h new file mode 100644 index 0000000..a4e809c --- /dev/null +++ b/src/framework/include/nsfw_upgrade.h @@ -0,0 +1,51 @@ +/* +* +* 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 NSFW_UPGRADE_H +#define NSFW_UPGRADE_H +#include "types.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +#define ENUM_STRUCT(struct) enum enum_upgrade_ ## struct + +#define ENUM_MEM(struct, mem) struct ## _ ## mem + +#define GET_MEM_BIT(mem_bit, struct, mem) (mem_bit & ((i64)1 << struct ## _ ## mem)) + +#define USE_MEM_BIT(mem_bit, struct, mem) (mem_bit |= ((i64)1 << struct ## _ ## mem)) + +#define UPGRADE_MEM_VAL(mem_bit, struct, mem, obj, defalut) { \ + if (!GET_MEM_BIT(mem_bit, struct, mem)){ \ + obj->mem = defalut; \ + } \ + } + +#define CONSTRUCT_UPGRADE_FUN(struct, obj) void upgrade_ ## struct (struct* obj) + +#define CALL_UPGRADE_FUN(struct, obj) upgrade_ ## struct (obj) + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/src/framework/include/nstack_log.h b/src/framework/include/nstack_log.h new file mode 100644 index 0000000..bb90ec8 --- /dev/null +++ b/src/framework/include/nstack_log.h @@ -0,0 +1,580 @@ +/* +* +* 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_LOG_H_ +#define _NSTACK_LOG_H_ +/*==============================================* + * include header files * + *----------------------------------------------*/ +#pragma GCC diagnostic ignored "-Wcpp" +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "types.h" +#include "nstack_trace.h" + +#include "glog/nstack_glog.ph" +#include "glog/nstack_glog_in.h" + +#define NSTACK_GETVER_MODULE "nStack" +#define NSTACK_GETVER_VERSION "VPP2.0 V100R002C10B053" +#define NSTACK_GETVER_BUILDTIME "[" __DATE__ "]" "[" __TIME__ "]" +#define NSTACK_VERSION NSTACK_GETVER_VERSION " (" NSTACK_GETVER_MODULE ") " NSTACK_GETVER_BUILDTIME + +#define LOG_TIME_STAMP_LEN 17 // "YYYYMMDDHHMMSS"; + +/*==============================================* + * constants or macros define * + *----------------------------------------------*/ +typedef enum _LOG_MODULE +{ + NSOCKET = 1, + STACKX, + OPERATION, + MASTER, + LOGTCP, + LOGUDP, + LOGIP, + LOGCMP, + LOGARP, + LOGRTE, + LOGHAL, + LOGDFX, + LOGFW, + LOGSBR, + MAX_LOG_MODULE +} LOG_MODULE; + +enum _LOG_TYPE +{ + LOG_TYPE_NSTACK = 0, + LOG_TYPE_OPERATION, + LOG_TYPE_MASTER, + LOG_TYPE_APP, + MAX_LOG_TYPE +}; + +enum _LOG_PROCESS +{ + LOG_PRO_NSTACK = 0, + LOG_PRO_MASTER, + LOG_PRO_APP, + LOG_PRO_OMC_CTRL, + LOG_PRO_INVALID +}; + +#define LOG_INVALID_VALUE 0xFFFF + +#define NSLOG_DBG 0x10 +#define NSLOG_INF 0x08 +#define NSLOG_WAR 0x04 +#define NSLOG_ERR 0x02 +#define NSLOG_EMG 0x01 +#define NSLOG_OFF 0x00 + +#define LOG_LEVEL_EMG "emg" +#define LOG_LEVEL_ERR "err" +#define LOG_LEVEL_WAR "war" +#define LOG_LEVEL_DBG "dbg" +#define LOG_LEVEL_INF "inf" + +#define GET_FILE_NAME(name_have_path) strrchr(name_have_path,'/')?strrchr(name_have_path,'/')+1:name_have_path + +#define NSTACK_LOG_NAME "/product/gpaas/log/nStack" + +#define STACKX_LOG_NAME "running.log" + +#define OPERATION_LOG_NAME "operation.log" + +#define MASTER_LOG_NAME "master.log" + +#define OMC_CTRL_LOG_NAME "omc_ctrl.log" + +#define FAILURE_LOG_NAME "fail_dump.log" + +#define FLUSH_TIME 30 + +#define APP_LOG_SIZE 30 +#define APP_LOG_COUNT 10 +#define APP_LOG_PATH "/var/log" +#define APP_LOG_NAME "nStack_nSocket.log" + +#define NS_LOG_STACKX_ON 0x80U +#define NS_LOG_STACKX_TRACE 0x40U +#define NS_LOG_STACKX_STATE 0x20U +#define NS_LOG_STACKX_FRESH 0x10U +#define NS_LOG_STACKX_HALT 0x08U +#define NS_LOG_STACKX_OFF 0x00U + +#define NULL_STRING "" +#define MODULE_INIT_FORMAT_STRING "module %s]name=[%s]%s" +#define MODULE_INIT_START "init" +#define MODULE_INIT_FAIL "start failed" +#define MODULE_INIT_SUCCESS "start success" + +#define PRE_INIT_LOG_LENGTH 128 + +struct nstack_logs +{ + uint32_t level; /**< Log level. */ + int pad64; + int inited; + int file_type; +}; + +struct log_init_para +{ + uint32_t run_log_size; + uint32_t run_log_count; + char *run_log_path; + uint32_t mon_log_size; //master and ctrl both use the parameter to reduce the redundancy + uint32_t mon_log_count; //master and ctrl both use the parameter to reduce the redundancy + char *mon_log_path; //master and ctrl both use the parameter to reduce the redundancy +}; + +enum LOG_CTRL_ID +{ + // for socket api + LOG_CTRL_SEND = 0, + LOG_CTRL_RECV, + LOG_CTRL_SENDMSG, + LOG_CTRL_RECVMSG, + LOG_CTRL_READ, + LOG_CTRL_WRITE, + LOG_CTRL_READV, + LOG_CTRL_WRITEV, + LOG_CTRL_GETSOCKNAME, + LOG_CTRL_GETPEERNAME, + LOG_CTRL_GETSOCKOPT, + + // for nstack service + LOG_CTRL_RECV_QUEUE_FULL, + LOG_CTRL_L4_RECV_QUEUE_FULL, + LOG_CTRL_HUGEPAGE_ALLOC_FAIL, + LOG_CTRL_TCP_MEM_NOT_ENOUGH, + LOG_CTRL_IPREASS_OVERFLOW, + LOG_CTRL_ID_MAX +}; + +struct log_ctrl_info +{ + u32 expire_time; + u32 unprint_count; + struct timespec last_log_time; +}; + +struct pre_init_info +{ + uint32_t level; /**< Log level. */ + char log_buffer[PRE_INIT_LOG_LENGTH]; +}; + +#define NS_LOG_STACKX(dbug,_module,_prestr,_level,fmt, ...) \ +{\ + if ((dbug) & NS_LOG_STACKX_ON)\ + {\ + NS_LOGPID(_module,_prestr,_level,fmt,##__VA_ARGS__);\ + }\ +}\ + + +/***************************************************************************** +* Prototype : nstack_get_log_level +* Description : get log level +* Input : int module +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +extern struct nstack_logs g_nstack_logs[MAX_LOG_MODULE]; +static inline int +nstack_get_log_level (int module) +{ + /* validity check for path */ + if ((MAX_LOG_MODULE <= module) || (module < 0)) + { + return -1; + } + + return g_nstack_logs[module].level; +} + +/***************************************************************************** +* Prototype : level_stoa +* Description : convert stack log level to app log level +* Input : unsigned int nstack_level +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +static inline unsigned int +level_stoa (unsigned int level) +{ + unsigned int golg_level; + switch (level) + { + case NSLOG_DBG: + golg_level = GLOG_LEVEL_DEBUG; + break; + case NSLOG_INF: + golg_level = GLOG_LEVEL_INFO; + break; + case NSLOG_WAR: + golg_level = GLOG_LEVEL_WARNING; + break; + case NSLOG_ERR: + golg_level = GLOG_LEVEL_ERROR; + break; + case NSLOG_EMG: + golg_level = GLOG_LEVEL_FATAL; + break; + default: + golg_level = GLOG_LEVEL_BUTT; + break; + } + return golg_level; +} + +/* use the glog function to replace old nstack log module */ + +/* segregate the dump info */ +#define LOG_TYPE(_module, _level) \ + (((STACKX == _module) && (NSLOG_EMG == _level)) ? GLOG_LEVEL_ERROR : ((OPERATION == _module) ? GLOG_LEVEL_WARNING : GLOG_LEVEL_INFO)) + +#define log_shooting(_module,_level) \ + ((NULL == g_log_hook_tag.log_hook) ? (nstack_get_log_level(_module) >= _level) : (level_stoa(_level) >= g_log_hook_tag.level)) + +/* add the non reentry protection */ +extern __thread unsigned int nstack_log_nonreentry; + +/* hanging up version check log need restrain */ +extern int ctrl_log_switch; + +#if defined MPTCP_UT +#define NS_LOGPID(_module,_prestr,_level,fmt, ...) +#elif !defined FOR_NSTACK_UT +#define NS_LOGPID(_module,_prestr,_level,fmt, ...) \ +{\ + if (log_shooting(_module, _level) && (0 == nstack_log_nonreentry) && (0 == ctrl_log_switch))\ + {\ + nstack_log_nonreentry = 1;\ + NSTACK_TRACING(_level, _prestr, fmt,##__VA_ARGS__);\ + if(nstack_log_info_check(_module, _level))\ + glog_print(LOG_TYPE(_module,_level),_prestr,level_stoa(_level),-1,GET_FILE_NAME(__FILE__),\ + __LINE__,__func__,fmt, ##__VA_ARGS__);\ + nstack_log_nonreentry = 0;\ + }\ +} +#else +static inline void +ut_log_info (const char *file_name, int line_no, const char *func_name, + int _module, const char *_prestr, unsigned int _level, char *fmt, + ...) +{ + va_list ap; + + if (log_shooting (_module, _level) && (0 == nstack_log_nonreentry) + && (0 == ctrl_log_switch)) + { + + nstack_log_nonreentry = 1; + if (nstack_log_info_check (_module, _level)) + { + char pMsgBuf[MAX_LOG_TRANSITIONAL_LEN] = "\0"; + va_start (ap, fmt); + VSNPRINTF_S (pMsgBuf, + MAX_LOG_TRANSITIONAL_LEN, + MAX_LOG_TRANSITIONAL_LEN - 1, fmt, ap); + glog_print (LOG_TYPE (_module, _level), _prestr, + level_stoa (_level), -1, GET_FILE_NAME (file_name), + line_no, func_name, "%s", pMsgBuf); + va_end (ap); + } + nstack_log_nonreentry = 0; + + } +} + +#define NS_LOGPID(_module,_prestr,_level,fmt, ...) \ +{\ + ut_log_info(__FILE__,__LINE__, __func__, _module,_prestr,_level,fmt, ##__VA_ARGS__); \ +} + +#endif + +#ifndef FOR_NSTACK_UT +#define NS_LOG_CTRL(_id, _module, _prestr, _level, fmt, ...) \ +{\ + if (log_shooting(_module, _level) && (0 == nstack_log_nonreentry) && check_log_prt_time(_id))\ + {\ + nstack_log_nonreentry = 1;\ + NSTACK_TRACING(_level, _prestr, fmt,##__VA_ARGS__);\ + if(nstack_log_info_check(_module, _level))\ + glog_print(LOG_TYPE(_module,_level),_prestr,level_stoa(_level),get_unprt_log_count(_id),\ + GET_FILE_NAME(__FILE__),__LINE__,__func__,fmt, ##__VA_ARGS__);\ + clr_unprt_log_count(_id);\ + nstack_log_nonreentry = 0;\ + }\ +} + +#else +static inline void +ut_ctrl_log_info (char *file_name, int line_no, char *func_name, int _id, + int _module, char *_prestr, unsigned int _level, char *fmt, + ...) +{ + va_list ap; + if (log_shooting (_module, _level) && (0 == nstack_log_nonreentry) + && check_log_prt_time (_id)) + { + nstack_log_nonreentry = 1; + if (nstack_log_info_check (_module, _level)) + { + char pMsgBuf[MAX_LOG_TRANSITIONAL_LEN] = "\0"; + va_start (ap, fmt); + VSNPRINTF_S (pMsgBuf, + MAX_LOG_TRANSITIONAL_LEN, + MAX_LOG_TRANSITIONAL_LEN - 1, fmt, ap); + glog_print (LOG_TYPE (_module, _level), _prestr, + level_stoa (_level), get_unprt_log_count (_id), + GET_FILE_NAME (file_name), line_no, func_name, "%s", + pMsgBuf); + va_end (ap); + } + clr_unprt_log_count (_id); + nstack_log_nonreentry = 0; + + } +} + +#define NS_LOG_CTRL(_id, _module, _prestr, _level, fmt, ...) \ +{\ + ut_ctrl_log_info(__FILE__,__LINE__, __func__, _id, _module,_prestr,_level,fmt, ##__VA_ARGS__); \ +} + +#endif + +#define NS_LOG_CTRL_STACKX(_id, dbug,_module,_prestr,_level,fmt, ...) \ +{\ + if ((dbug) & NS_LOG_STACKX_ON)\ + {\ + NS_LOG_CTRL(_id, _module,_prestr,_level,fmt,##__VA_ARGS__);\ + }\ +}\ + + +/*for every log modules should def marcos below use a sort module name, just like MON means Monitor*/ +#define NSMON_LOGINF(fmt, ...) NS_LOGPID(MASTER,"NSMON",NSLOG_INF,fmt,##__VA_ARGS__) +#define NSMON_LOGDBG(fmt, ...) NS_LOGPID(MASTER,"NSMON",NSLOG_DBG,fmt,##__VA_ARGS__) +#define NSMON_LOGWAR(fmt, ...) NS_LOGPID(MASTER,"NSMON",NSLOG_WAR,fmt,##__VA_ARGS__) +#define NSMON_LOGERR(fmt, ...) NS_LOGPID(MASTER,"NSMON",NSLOG_ERR,fmt,##__VA_ARGS__) + +#define NSPOL_LOGINF(debug,fmt, ...)NS_LOG_STACKX(debug,STACKX,"NSPOL",NSLOG_INF,fmt,##__VA_ARGS__) +#define NSPOL_LOGDBG(debug,fmt, ...) NS_LOG_STACKX(debug,STACKX,"NSPOL",NSLOG_DBG,fmt,##__VA_ARGS__) +#define NSPOL_LOGWAR(debug,fmt, ...) NS_LOG_STACKX(debug,STACKX,"NSPOL",NSLOG_WAR,fmt,##__VA_ARGS__) +#define NSPOL_LOGERR(fmt, ...) NS_LOGPID(STACKX,"NSPOL",NSLOG_ERR,fmt,##__VA_ARGS__) +#define NSPOL_LOGEMG(fmt, ...) NS_LOGPID(STACKX,"NSPOL",NSLOG_EMG,fmt,##__VA_ARGS__) + +#define NSOPR_LOGINF(fmt, ...) NS_LOGPID(OPERATION,"NSOPR",NSLOG_INF,fmt,##__VA_ARGS__) +#define NSOPR_LOGDBG(fmt, ...) NS_LOGPID(OPERATION,"NSOPR",NSLOG_DBG,fmt,##__VA_ARGS__) +#define NSOPR_LOGWAR(fmt, ...) NS_LOGPID(OPERATION,"NSOPR",NSLOG_WAR,fmt,##__VA_ARGS__) +#define NSOPR_LOGERR(fmt, ...) NS_LOGPID(OPERATION,"orchestration",NSLOG_ERR,fmt,##__VA_ARGS__) + +#define NSSOC_LOGINF(fmt, ...) NS_LOGPID(NSOCKET,"NSSOC",NSLOG_INF,fmt,##__VA_ARGS__) +#define NSSOC_LOGDBG(fmt, ...) NS_LOGPID(NSOCKET,"NSSOC",NSLOG_DBG,fmt,##__VA_ARGS__) +#define NSSOC_LOGWAR(fmt, ...) NS_LOGPID(NSOCKET,"NSSOC",NSLOG_WAR,fmt,##__VA_ARGS__) +#define NSSOC_LOGERR(fmt, ...) NS_LOGPID(NSOCKET,"NSSOC",NSLOG_ERR,fmt,##__VA_ARGS__) + +#define NSSBR_LOGINF(fmt, ...) NS_LOGPID(LOGSBR,"NSSBR",NSLOG_INF,fmt,##__VA_ARGS__) +#define NSSBR_LOGDBG(fmt, ...) NS_LOGPID(LOGSBR,"NSSBR",NSLOG_DBG,fmt,##__VA_ARGS__) +#define NSSBR_LOGWAR(fmt, ...) NS_LOGPID(LOGSBR,"NSSBR",NSLOG_WAR,fmt,##__VA_ARGS__) +#define NSSBR_LOGERR(fmt, ...) NS_LOGPID(LOGSBR,"NSSBR",NSLOG_ERR,fmt,##__VA_ARGS__) + +#define NSCOMM_LOGINF(fmt, ...) NS_LOGPID(LOGRTE, "NSRTE",NSLOG_INF,fmt,##__VA_ARGS__) +#define NSCOMM_LOGDBG(fmt, ...) NS_LOGPID(LOGRTE, "NSRTE",NSLOG_DBG,fmt,##__VA_ARGS__) +#define NSCOMM_LOGWAR(fmt, ...) NS_LOGPID(LOGRTE, "NSRTE",NSLOG_WAR,fmt,##__VA_ARGS__) +#define NSCOMM_LOGERR(fmt, ...) NS_LOGPID(LOGRTE, "NSRTE",NSLOG_ERR,fmt,##__VA_ARGS__) + +#define NSTCP_LOGINF(fmt, ...) NS_LOGPID(LOGTCP,"NSTCP",NSLOG_INF,fmt,##__VA_ARGS__) +#define NSTCP_LOGDBG(fmt, ...) NS_LOGPID(LOGTCP,"NSTCP",NSLOG_DBG,fmt,##__VA_ARGS__) +#define NSTCP_LOGWAR(fmt, ...) NS_LOGPID(LOGTCP,"NSTCP",NSLOG_WAR,fmt,##__VA_ARGS__) +#define NSTCP_LOGERR(fmt, ...) NS_LOGPID(LOGTCP,"NSTCP",NSLOG_ERR,fmt,##__VA_ARGS__) + +#define NSIP_LOGINF(fmt, ...) NS_LOGPID(LOGIP,"NSIP",NSLOG_INF,fmt,##__VA_ARGS__) +#define NSIP_LOGDBG(fmt, ...) NS_LOGPID(LOGIP,"NSIP",NSLOG_DBG,fmt,##__VA_ARGS__) +#define NSIP_LOGWAR(fmt, ...) NS_LOGPID(LOGIP,"NSIP",NSLOG_WAR,fmt,##__VA_ARGS__) +#define NSIP_LOGERR(fmt, ...) NS_LOGPID(LOGIP,"NSIP",NSLOG_ERR,fmt,##__VA_ARGS__) + +#define NSUDP_LOGINF(fmt, ...) NS_LOGPID(LOGUDP,"NSUDP",NSLOG_INF,fmt,##__VA_ARGS__) +#define NSUDP_LOGDBG(fmt, ...) NS_LOGPID(LOGUDP,"NSUDP",NSLOG_DBG,fmt,##__VA_ARGS__) +#define NSUDP_LOGWAR(fmt, ...) NS_LOGPID(LOGUDP,"NSUDP",NSLOG_WAR,fmt,##__VA_ARGS__) +#define NSUDP_LOGERR(fmt, ...) NS_LOGPID(LOGUDP,"NSUDP",NSLOG_ERR,fmt,##__VA_ARGS__) + +#define NSHAL_LOGINF(fmt, ...) NS_LOGPID(LOGHAL,"NSHAL",NSLOG_INF,fmt,##__VA_ARGS__) +#define NSHAL_LOGDBG(fmt, ...) NS_LOGPID(LOGHAL,"NSHAL",NSLOG_DBG,fmt,##__VA_ARGS__) +#define NSHAL_LOGWAR(fmt, ...) NS_LOGPID(LOGHAL,"NSHAL",NSLOG_WAR,fmt,##__VA_ARGS__) +#define NSHAL_LOGERR(fmt, ...) NS_LOGPID(LOGHAL,"NSHAL",NSLOG_ERR,fmt,##__VA_ARGS__) + +#define NSARP_LOGINF(fmt, ...) NS_LOGPID(LOGARP,"NSARP",NSLOG_INF,fmt,##__VA_ARGS__) +#define NSARP_LOGDBG(fmt, ...) NS_LOGPID(LOGARP,"NSARP",NSLOG_DBG,fmt,##__VA_ARGS__) +#define NSARP_LOGWAR(fmt, ...) NS_LOGPID(LOGARP,"NSARP",NSLOG_WAR,fmt,##__VA_ARGS__) +#define NSARP_LOGERR(fmt, ...) NS_LOGPID(LOGARP,"NSARP",NSLOG_ERR,fmt,##__VA_ARGS__) + +#define NSDFX_LOGINF(fmt, ...) NS_LOGPID(LOGDFX,"NSDFX",NSLOG_INF,fmt,##__VA_ARGS__) +#define NSDFX_LOGDBG(fmt, ...) NS_LOGPID(LOGDFX,"NSDFX",NSLOG_DBG,fmt,##__VA_ARGS__) +#define NSDFX_LOGWAR(fmt, ...) NS_LOGPID(LOGDFX,"NSDFX",NSLOG_WAR,fmt,##__VA_ARGS__) +#define NSDFX_LOGERR(fmt, ...) NS_LOGPID(LOGDFX,"NSDFX",NSLOG_ERR,fmt,##__VA_ARGS__) + +#define NSFW_LOGINF(fmt, ...) NS_LOGPID(LOGFW,"NSFW",NSLOG_INF,fmt,##__VA_ARGS__) +#define NSFW_LOGDBG(fmt, ...) NS_LOGPID(LOGFW,"NSFW",NSLOG_DBG,fmt,##__VA_ARGS__) +#define NSFW_LOGERR(fmt, ...) NS_LOGPID(LOGFW,"NSFW",NSLOG_ERR,fmt,##__VA_ARGS__) +#define NSFW_LOGWAR(fmt, ...) NS_LOGPID(LOGFW,"NSFW",NSLOG_WAR,fmt,##__VA_ARGS__) + +#define NSAM_LOGINF(fmt, ...) NS_LOGPID(LOGFW,"NSAM",NSLOG_INF,fmt,##__VA_ARGS__) +#define NSAM_LOGDBG(fmt, ...) NS_LOGPID(LOGFW,"NSAM",NSLOG_DBG,fmt,##__VA_ARGS__) +#define NSAM_LOGERR(fmt, ...) NS_LOGPID(LOGFW,"NSAM",NSLOG_ERR,fmt,##__VA_ARGS__) +#define NSAM_LOGWAR(fmt, ...) NS_LOGPID(LOGFW,"NSAM",NSLOG_WAR,fmt,##__VA_ARGS__) + +#define INIT_LOG_ASSEM(log_module,_prestr,_level, init_module , function, errString, errValue, status) \ + if ((LOG_INVALID_VALUE <= errValue) && (1 == sizeof(errString))) \ + { \ + NS_LOGPID(log_module,_prestr, _level,MODULE_INIT_FORMAT_STRING, (char*)status, init_module, function ); \ + } \ + else if (LOG_INVALID_VALUE <= errValue)\ + { \ + NS_LOGPID(log_module,_prestr, _level,MODULE_INIT_FORMAT_STRING",err_string=%s", (char*)status, init_module, function, errString ); \ + } \ + else if (1 == sizeof(errString))\ + { \ + NS_LOGPID(log_module,_prestr, _level,MODULE_INIT_FORMAT_STRING",err_value=%d", (char*)status, init_module, function, errValue ); \ + } \ + else \ + { \ + NS_LOGPID(log_module,_prestr, _level,MODULE_INIT_FORMAT_STRING",err_string=%s,err_value=%d", (char*)status, init_module, function, errString, errValue ); \ + } \ + +#define INITPOL_LOGINF(init_module_name, function, err_string, err_value, status) \ + INIT_LOG_ASSEM(STACKX,"NSPOL",NSLOG_INF,init_module_name , function, err_string, err_value, status)\ + +#define INITPOL_LOGERR(init_module_name, function, err_string, err_value, status) \ + INIT_LOG_ASSEM(STACKX,"NSPOL",NSLOG_ERR,init_module_name , function, err_string, err_value, status)\ + +#define INITTCP_LOGINF(init_module_name , function, err_string, err_value, status) \ + INIT_LOG_ASSEM(LOGTCP,"NSTCP",NSLOG_INF,init_module_name , function, err_string, err_value, status)\ + +#define INITTCP_LOGERR(init_module_name , function, err_string, err_value, status) \ + INIT_LOG_ASSEM(LOGTCP,"NSTCP",NSLOG_ERR,init_module_name , function, err_string, err_value, status)\ + +#define INITMON_LOGERR(init_module_name , function, err_string, err_value, status) \ + INIT_LOG_ASSEM(MASTER,"NSMON",NSLOG_ERR,init_module_name , function, err_string, err_value, status)\ + +#define INITSOC_LOGERR(init_module_name , function, err_string, err_value, status) \ + INIT_LOG_ASSEM(NSOCKET,"NSSOC",NSLOG_ERR,init_module_name , function, err_string, err_value, status) + +#define NSPOL_DUMP_LOGINF(fmt, ...) NSPOL_LOGINF(0x80, fmt, ##__VA_ARGS__) +#define NSPOL_DUMP_LOGDBG(fmt, ...) NSPOL_LOGDBG(0x80, fmt, ##__VA_ARGS__) +#define NSPOL_DUMP_LOGERR(fmt, ...) NSPOL_LOGERR(fmt, ##__VA_ARGS__) +#define NSPOL_DUMP_LOGWAR(fmt, ...) NSPOL_LOGWAR(0x80, fmt, ##__VA_ARGS__) + +/*==============================================* + * routines' or functions' implementations * + *----------------------------------------------*/ + +void save_pre_init_log (uint32_t level, char *fmt, ...); +void write_pre_init_log (); + +void set_log_init_para (struct log_init_para *para); + +void nstack_setlog_level (int module, uint32_t level); +bool nstack_log_info_check (uint32_t module, uint32_t level); +int nstack_log_init (); +void nstack_log_init_app (); +int get_app_env_log_path (char *app_file_path, unsigned int app_file_size); +void set_log_proc_type (int log_proc_type); + +int setlog_level_value (const char *param, const char *value); +int get_str_value (const char *arg); +int check_log_dir_valid (const char *path); +void nstack_segment_error (int s); +void init_log_ctrl_info (); +void set_log_ctrl_time (int id, int ctrl_time); + +int cmp_log_path (const char *path); + +#ifndef sys_sleep_ns +#define sys_sleep_ns(_s, _ns)\ + {\ + if ((_s) >= 0 && (_ns) >= 0){\ + struct timespec delay, remain;\ + delay.tv_sec=(_s);\ + delay.tv_nsec=(_ns);\ + while (nanosleep (&delay, &remain) < 0)\ + {\ + delay = remain;\ + }\ + }\ + } +#endif /* sys_sleep_ns */ + +int check_log_prt_time (int id); +int get_unprt_log_count (int id); +void clr_unprt_log_count (int id); + +void get_current_time (char *buf, const int len); + +#ifdef CPU_CYCLES +static __inline__ unsigned long long +nstack_rdtsc (void) +{ + unsigned hi, lo; + __asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi)); + return ((unsigned long long) lo) | (((unsigned long long) hi) << 32); +} + +#define CPUB(name) \ +unsigned long long start##name = 0;\ +unsigned long long stop##name = 0;\ +static unsigned long long total##name = 0;\ +static unsigned long long total_cout##name = 0;\ +start##name = nstack_rdtsc(); + +#define CPUE(name) \ +stop##name = nstack_rdtsc();\ +total##name += (stop##name - start##name);\ +if(++total_cout##name == 1000000)\ +{\ + NSSOC_LOGINF(#name" cpu %llu-------\n", total##name / total_cout##name);\ + total##name = 0;\ + total_cout##name = 0;\ +} +#else +#define CPUB(name) +#define CPUE(name) +#endif + +#endif diff --git a/src/framework/include/nstack_rd_data.h b/src/framework/include/nstack_rd_data.h new file mode 100644 index 0000000..3924680 --- /dev/null +++ b/src/framework/include/nstack_rd_data.h @@ -0,0 +1,80 @@ +/* +* +* 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_DATA_H +#define __NSTACK_RD_DATA_H + +/*choose router base on ip seg*/ +#define STACK_NAME_MAX 32 +#define RD_PLANE_NAMELEN (32) +#define NSTACK_IP_BIT_MAX (32) +#define NSTACK_RD_DATA_MAX (2048) +#define RD_IP_STR_MAX_LEN (32) + +typedef enum __rd_data_type +{ + RD_DATA_TYPE_IP, + RD_DATA_TYPE_PROTO, + RD_DATA_TYPE_MAX, +} rd_data_type; + +typedef enum __rd_node_state +{ + RD_NODE_USELESS, + RD_NODE_USING, + RD_NODE_DELETING, + RD_NODE_MAX, +} rd_node_state; + +/*route info base on ip*/ +typedef struct __rd_route_ip_data +{ + unsigned int addr; + unsigned int masklen; + unsigned int resev[2]; +} rd_ip_data; + +/*route data*/ +typedef struct __rd_route_data +{ + /*route info type , for example base on ip */ + rd_data_type type; + char stack_name[RD_PLANE_NAMELEN]; + union + { + rd_ip_data ipdata; + unsigned int proto_type; + /*:::other type to be add */ + }; +} rd_route_data; + +typedef struct __rd_route_node +{ + rd_node_state flag; + int agetime; + rd_route_data data; +} rd_route_node; + +typedef struct __rd_route_table +{ + int size; + int icnt; + rd_route_node node[NSTACK_RD_DATA_MAX]; +} rd_route_table; + +#define MASK_V(ipaddr, masklen) ((ipaddr) & (~0 << (NSTACK_IP_BIT_MAX - (masklen)))) + +#endif diff --git a/src/framework/include/nstack_securec.h b/src/framework/include/nstack_securec.h new file mode 100644 index 0000000..c9efb4f --- /dev/null +++ b/src/framework/include/nstack_securec.h @@ -0,0 +1,145 @@ +/* +* +* 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_SECUREC_H__ +#define __NSTACK_SECUREC_H__ + +/*if you need export the function of this library in Win32 dll, use __declspec(dllexport) */ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ + +#endif /* */ +#ifndef SECUREC_LIB +#include +#include +#include +#include + +#ifndef NULL +#define NULL ((void *)0) +#endif /* + */ + +/*define error code*/ +#ifndef errno_t +typedef int errno_t; + +#endif /* + */ + +/* success */ +#define EOK (0) + +/* invalid parameter */ +#ifndef EINVAL +#define EINVAL (22) +#endif /* + */ + +#define EINVAL_AND_RESET (22 | 0X80) +#define ERANGE_AND_RESET (34 | 0X80) + +#define SCANF_S scanf +#define WSCANF_S wscanf +#define VSCANF_S vscanf +#define VWSCANF_S vwscanf +#define FSCANF_S fscanf +#define FWSCANF_S fwscanf +#define VFSCANF_S vfscanf +#define VFWSCANF_S vfwscanf +#define SSCANF_S sscanf +#define SWSCANF_S swscanf +#define VSSCANF_S vsscanf +#define VSWSCANF_S vswscanf + +#define SPRINTF_S(a, b, ...) sprintf(a, ##__VA_ARGS__) +#define SWPRINTF_S(a, b, c, ...) swprintf(a, b, c, ##__VA_ARGS__) +#define VSPRINTF_S(a, b, c, d) vsprintf(a, c, d) +#define VSWPRINTF_S(a, b, c, d) vswprintf(a, b, c, d) +#define VSNPRINTF_S(a, b, c, d, e) vsnprintf(a, c, d, e) +#define SNPRINTF_S(a, b, c, d, ...) snprintf(a, c, d, ##__VA_ARGS__) + +#define WMEMCPY_S(a, b, c, d) ((NULL == wmemcpy(a, c, d)) ? EINVAL : EOK) +#define MEMMOVE_S(a, b, c, d) ((NULL == memmove(a, c, d)) ? EINVAL : EOK) +#define WMEMMOVE_S(a, b, c, d) ((NULL == wmemmove(a, c, d)) ? EINVAL : EOK) +#define WCSCPY_S(a, b, c) ((NULL == wcscpy(a, c)) ? EINVAL : EOK) +#define WCSNCPY_S(a, b, c, d) ((NULL == wcsncpy(a, c, d)) ? EINVAL : EOK) +#define WCSCAT_S(a, b, c) ((NULL == wcscat(a, c)) ? EINVAL : EOK) +#define WCSNCAT_S(a, b, c, d) ((NULL == wcsncat(a, c, d)) ? EINVAL : EOK) + +#define MEMSET_S(a, b, c, d) ((NULL == memset(a, c, d)) ? EINVAL : EOK) +#define MEMCPY_S(a, b, c, d) ((NULL == memcpy(a, c, d)) ? EINVAL : EOK) +#define STRCPY_S(a, b, c) ((NULL == strcpy(a, c )) ? EINVAL : EOK) +#define STRNCPY_S(a, b, c, d) ((NULL == strncpy(a, c, d)) ? EINVAL : EOK) +#define STRCAT_S(a, b, c) ((NULL == strcat(a, c)) ? EINVAL : EOK) +#define STRNCAT_S(a, b, c, d) ((NULL == strncat(a, c, d)) ? EINVAL : EOK) + +#define STRTOK_S(a, b, c) strtok(a, b) +#define WCSTOK_S(a, b, c) wcstok(a, b) +#define GETS_S(a, b) gets(a) + +#else /* */ +#include "securec.h" + +#define SCANF_S scanf_s +#define WSCANF_S wscanf_s +#define VSCANF_S vscanf_s +#define VWSCANF_S vwscanf_s +#define FSCANF_S fscanf_s +#define FWSCANF_S fwscanf_s +#define VFSCANF_S vfscanf_s +#define VFWSCANF_S vfwscanf_s +#define SSCANF_S sscanf_s +#define SWSCANF_S swscanf_s +#define VSSCANF_S vsscanf_s +#define VSWSCANF_S vswscanf_s + +#define SPRINTF_S(a, b, ...) sprintf_s (a, b, ##__VA_ARGS__) +#define SWPRINTF_S(a, b, c, ...) swprintf_s(a, b, c, ##__VA_ARGS__) +#define VSPRINTF_S(a, b, c, d) vsprintf_s(a, b, c, d) +#define VSWPRINTF_S(a, b, c, d) vswprintf_s(a, b, c, d) +#define VSNPRINTF_S(a, b, c, d, e) vsnprintf_s(a, b, c, d, e) +#define SNPRINTF_S(a, b, c, d, ...) snprintf_s(a, b, c, d, ##__VA_ARGS__) + +#define WMEMCPY_S(a, b, c, d) wmemcpy_s(a, b, c, d) +#define MEMMOVE_S(a, b, c, d) memmove_s(a, b, c, d) +#define WMEMMOVE_S(a, b, c, d) wmemmove_s(a, b, c, d) +#define WCSCPY_S(a, b, c) wcscpy_s(a, b, c) +#define WCSNCPY_S(a, b, c, d) wcsncpy_s(a, b, c, d) +#define WCSCAT_S(a, b, c) wcscat_s(a, b, c) +#define WCSNCAT_S(a, b, c, d) wcsncat_s(a, b, c, d) + +#define MEMSET_S(a, b, c, d) memset_s(a, b, c, d) +#define MEMCPY_S(a, b, c, d) memcpy_s(a, b, c, d) +#define STRCPY_S(a, b, c) strcpy_s(a, b, c) +#define STRNCPY_S(a, b, c, d) strncpy_s(a, b, c, d) +#define STRCAT_S(a, b, c) strcat_s(a, b, c) +#define STRNCAT_S(a, b, c, d) strncat_s(a, b, c, d) + +#define STRTOK_S(a, b, c) strtok_s(a, b, c) +#define WCSTOK_S(a, b, c) wcstok_s(a, b, c) +#define GETS_S(a, b) gets_s(a, b) +#endif /* */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#endif /* __NSTACK_SECUREC_H__ */ diff --git a/src/framework/include/nstack_trace.h b/src/framework/include/nstack_trace.h new file mode 100644 index 0000000..0f4f640 --- /dev/null +++ b/src/framework/include/nstack_trace.h @@ -0,0 +1,76 @@ +/* +* +* 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_TRACE_H__ +#define __NSTACK_TRACE_H__ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif + +/*==============================================* + * include header files * + *----------------------------------------------*/ +#include "types.h" +#include "nstack_log.h" +#include +#define SPAN_NAME_MAX 64 +#define TRACE_NULL 0 +#define NSTACK_TRACE_ON 0 +#define NSTACK_TRACE_OFF 1 + +typedef struct nst_trace_header +{ + u64 trace_id; + u64 span_pid; + u64 span_id; /*now us */ + int fd; + int thread_id; +} trace_hread_t; + +typedef struct nst_trace_fun +{ + u64 (*current_traceid) (); + void (*span_raw) (char *msg); + void (*tracing_enable) (int enable); + void (*tracing_simpling) (int frequency); + void (*tracing_cleanup) (); + void (*tracing_setup) (u32 process); + u64 (*tracing_string_to_traceid) (const char *input, size_t length); +} trace_fun_t; + +extern __thread struct nst_trace_header strace_header; + +#define get_trace_header() (&strace_header) + +//For Tracing define own tracing feature. +#define nstack_trace_init( a ) +#define nstack_set_tracing_contex( a,b,c) +#define nstack_get_tracing_contex(traceid,spanid,spanpid,fd) +#define nstack_clear_tracing_contex( ) +#define NSTACK_TRACING(level, module_name,famt,...) +#define nstack_tracing_enalbe() +#define nstack_get_traceid() (NULL) + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif diff --git a/src/framework/init/CMakeLists.txt b/src/framework/init/CMakeLists.txt new file mode 100644 index 0000000..ff8d4d2 --- /dev/null +++ b/src/framework/init/CMakeLists.txt @@ -0,0 +1,24 @@ +######################################################################### +# +# 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. +######################################################################### + +SET(LIBSBR_SRC fw_init.c fw_module.c) + +SET(COMM_CONFIG ${PROJECT_SOURCE_DIR}/src/framework/common/base/include/common_sys_config.h) +ADD_DEFINITIONS(-fPIC -mssse3) +ADD_DEFINITIONS(-include ${COMM_CONFIG}) + +ADD_LIBRARY(nStackfwinit static ${LIBSBR_SRC}) + diff --git a/src/framework/init/fw_init.c b/src/framework/init/fw_init.c new file mode 100644 index 0000000..6337b67 --- /dev/null +++ b/src/framework/init/fw_init.c @@ -0,0 +1,320 @@ +/* +* +* 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 +#include +#include "nstack_securec.h" +#include "fw_module.h" +#include "nstack_log.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +NSTACK_STATIC int +nsfw_module_instance_isIndepend (nsfw_module_instance_t * inst) +{ + nsfw_module_depends_t *dep = inst->depends; + while (dep) + { + if (!dep->isReady) + return 1; + dep = dep->next; + } + + return 0; +} + +NSTACK_STATIC void +nsfw_module_instance_depend_check (nsfw_module_instance_t * inst) +{ + nsfw_module_instance_t *curInst = nsfw_module_getManager ()->inst; + while (curInst) + { + if (curInst == inst) + goto nextLoop; + if (NSFW_INST_STAT_CHECKING == curInst->stat + || NSFW_INST_STAT_DEPENDING == curInst->stat) + { + nsfw_module_depends_t *dep = curInst->depends; + while (dep) + { + if (0 == dep->isReady && 0 == strcmp (dep->name, inst->name)) + { + dep->isReady = 1; /* Don't break for case that duplicate name exist, though I think it should + not happen */ + } + dep = dep->next; + } + } + nextLoop: + curInst = curInst->next; + } + +} + +/** + * @Function nstack_framework_init + * @Description Init child modules + * @param father instance , NULL means root + * @return 0 on success, -1 on error + */ +NSTACK_STATIC int +nstack_framework_initChild_unsafe (nsfw_module_instance_t * father) +{ + NSFW_LOGDBG ("init framework module] name=%s", + father ? father->name : "NULL"); + + nsfw_module_instance_t *inst = nsfw_module_getManager ()->inst; + + while (inst) + { + NSFW_LOGDBG + ("init child] inst=%s, inst->father=%s, inst->depends=%s, inst->state=%d", + inst->name, inst->father ? inst->father->name : "NULL", + inst->depends ? inst->depends->name : "NULL", inst->stat); + + if (father != inst->father) + { + NSFW_LOGDBG ("inst->father not match] inst=%s, ", inst->name); + + inst = inst->next; + continue; + } + + switch (inst->stat) + { + case NSFW_INST_STAT_CHECKING: + /* First, check if any depends, then check if other instance depends on it */ + if (nsfw_module_instance_isIndepend (inst)) + { + inst->stat = NSFW_INST_STAT_DEPENDING; + NSFW_LOGDBG ("inst is still depending] name=%s", inst->name); + inst = inst->next; + break; + } + + NSFW_LOGINF ("Going to init module] name=%s, init fun=%p", + inst->name, inst->fnInit); + if (NULL != inst->fnInit && 0 != inst->fnInit (inst->param)) + { + NSFW_LOGERR ("initial fail!!!] inst=%s", inst->name); + inst->stat = NSFW_INST_STAT_FAIL; + return -1; + } + + inst->stat = NSFW_INST_STAT_DONE; + nsfw_module_instance_depend_check (inst); + + if (-1 == nsfw_module_addDoneNode (inst)) + { + NSFW_LOGERR ("add done node fail"); + } + + inst = nsfw_module_getManager ()->inst; /* check from begining */ + break; + case NSFW_INST_STAT_DEPENDING: + /* check if depending stat is still there */ + if (!nsfw_module_instance_isIndepend (inst)) + { + inst->stat = NSFW_INST_STAT_CHECKING; + break; + } + case NSFW_INST_STAT_FAIL: + case NSFW_INST_STAT_DONE: + default: + inst = inst->next; + break; + } + } + + return 0; +} + +NSTACK_STATIC void +nstack_framework_printInstanceInfo (nsfw_module_instance_t * inst) +{ + + if (NULL == inst) + { + NSFW_LOGERR ("param error,inst==NULL"); + return; + } + + char info[1024] = ""; + int plen = 0; + + int ret = SPRINTF_S (info, sizeof (info), "Inst:%s,father:%s,depends:", + inst->name, + inst->father ? inst->father->name : "NULL"); + + if (ret <= 0) + { + NSFW_LOGERR ("Sprintf Error] module=%s,state=%d, ret=%d", inst->name, + inst->stat, ret); + return; + } + else + { + plen += ret; + } + + if (NULL == inst->depends) + { + ret = SPRINTF_S (info + plen, sizeof (info) - plen, "NULL"); + if (ret <= 0) + { + NSFW_LOGERR ("Sprintf Error] module=%s,state=%d, ret=%d", + inst->name, inst->stat, ret); + return; + } + NSFW_LOGINF ("] inst info=%s", info); + return; + } + + nsfw_module_depends_t *dep = inst->depends; + while (dep) + { + ret = SPRINTF_S (info + plen, sizeof (info) - plen, "%s ", dep->name); + if (ret <= 0) + { + NSFW_LOGERR ("Sprintf Error] module=%s,state=%d, ret=%d", + inst->name, inst->stat, ret); + return; + } + plen += ret; + dep = dep->next; + } + + NSFW_LOGINF ("] inst info=%s", info); +} + +NSTACK_STATIC void +nstack_framework_printInitialResult () +{ + nsfw_module_manager_t *manager = nsfw_module_getManager (); + + if (manager->doneHead) + { + NSFW_LOGINF ("Here is the initial done modules: "); + + nsfw_module_doneNode_t *curNode = manager->doneHead; + while (curNode) + { + nstack_framework_printInstanceInfo (curNode->inst); + curNode = curNode->next; + } + } + else + { + NSFW_LOGERR ("No initial done modules"); + } + + nsfw_module_instance_t *curInst = manager->inst; + int unDoneNum = 0; + while (curInst) + { + if (curInst->stat != NSFW_INST_STAT_DONE) + { + if (0 == unDoneNum) + { + NSFW_LOGINF ("Here is the unInited modules:"); + } + unDoneNum++; + nstack_framework_printInstanceInfo (curInst); + } + curInst = curInst->next; + } + if (0 == unDoneNum) + NSFW_LOGINF ("All modules are inited"); +} + +/** + * @Function nstack_framework_init + * @Description This function will do framework initial work, it will involk all initial functions + * registed using macro NSFW_MODULE_INIT before + * @param none + * @return 0 on success, -1 on error + */ +int +nstack_framework_init (void) +{ + int ret = -1; + if (nsfw_module_getManager ()->done) + { + goto init_finished; + } + + if (pthread_mutex_lock (&nsfw_module_getManager ()->initMutex)) + { + return -1; + } + + if (nsfw_module_getManager ()->done) + { + goto done; + } + + ret = nstack_framework_initChild_unsafe (NULL); + + if (0 == ret) + { + nsfw_module_getManager ()->done = 1; + } + else + { + nsfw_module_getManager ()->done = -1; + } + + // Going to print done modules and undone modules + nstack_framework_printInitialResult (); + +done: + if (pthread_mutex_unlock (&nsfw_module_getManager ()->initMutex)) + { + return -1; + } +init_finished: + ret = nsfw_module_getManager ()->done == 1 ? 0 : -1; + return ret; +} + +/** + * @Function nstack_framework_setModuleParam + * @Description This function set parameter of module initial function parameter + * @param module - name of module + * @param param - parameter to set + * @return 0 on success, -1 on error + */ +int +nstack_framework_setModuleParam (char *module, void *param) +{ + nsfw_module_instance_t *inst = nsfw_module_getModuleByName (module); + if (!inst) + return -1; + + inst->param = param; + return 0; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/framework/init/fw_module.c b/src/framework/init/fw_module.c new file mode 100644 index 0000000..65bbb0a --- /dev/null +++ b/src/framework/init/fw_module.c @@ -0,0 +1,331 @@ +/* +* +* 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 +#include +#include +#include "nstack_securec.h" +#include "fw_module.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +COMPAT_PROTECT (NSFW_MOUDLE_INSTANCE_POOL_SIZE, 64); +COMPAT_PROTECT (NSFW_MOUDLE_DEPENDS_POOL_SIZE, 128); + +nsfw_module_instance_pool_t g_nsfw_module_inst_pool; +nsfw_module_depends_pool_t g_nsfw_module_deps_pool; + +/* +* WARNING!!!: +* This function is only used in constructor progress. Multi-thread concurrent is not supported! +*/ +NSTACK_STATIC nsfw_module_instance_t * +nsfw_module_malloc_instance () +{ + if (g_nsfw_module_inst_pool.last_idx >= NSFW_MOUDLE_INSTANCE_POOL_SIZE) + { + return NULL; + } + return + &g_nsfw_module_inst_pool.module_instance_pool[g_nsfw_module_inst_pool. + last_idx++]; +} + +/* +* WARNING!!!: +* This function is only used in constructor progress. Multi-thread concurrent is not supported! +*/ +NSTACK_STATIC nsfw_module_depends_t * +nsfw_module_malloc_depends () +{ + if (g_nsfw_module_deps_pool.last_idx >= NSFW_MOUDLE_DEPENDS_POOL_SIZE) + { + return NULL; + } + return + &g_nsfw_module_deps_pool.module_depends_pool[g_nsfw_module_deps_pool. + last_idx++]; +} + +NSTACK_STATIC void +nsfw_module_setChildInstance (nsfw_module_instance_t * + father, nsfw_module_instance_t * child) +{ + if (NULL == father || NULL == child) + return; + child->father = father; +} + +nsfw_module_depends_t * +nsfw_module_create_depends (char *name) +{ + if (NULL == name) + return NULL; + + /*Change module malloc to pool array */ + nsfw_module_depends_t *dep = nsfw_module_malloc_depends (); + + if (NULL == dep) + return NULL; + + if (EOK != + MEMSET_S (dep, sizeof (nsfw_module_depends_t), 0, + sizeof (nsfw_module_depends_t))) + { + goto fail; + } + + /*change destMax from nameSize - 1 to sizeof(dep->name) */ + if (EOK != STRCPY_S (dep->name, sizeof (dep->name), name)) + { + goto fail; + } + dep->isReady = 0; + + return dep; + +fail: + // NOTE: if dep is not null, we do not free it and just leave it there. + return NULL; +} + +nsfw_module_instance_t * +nsfw_module_create_instance (void) +{ + /*Change module malloc to pool array */ + nsfw_module_instance_t *inst = nsfw_module_malloc_instance (); + if (NULL == inst) + return NULL; + + if (EOK != + MEMSET_S (inst, sizeof (nsfw_module_instance_t), 0, + sizeof (nsfw_module_instance_t))) + { + // NOTE: if inst is not null, we do not free it and just leave it there. + return NULL; + } + + inst->stat = NSFW_INST_STAT_CHECKING; + return inst; +} + +void +nsfw_module_set_instance_name (nsfw_module_instance_t * inst, char *name) +{ + if (NULL == inst || NULL == name || inst->name[0] != '\0') + { + return; + } + + /*change destMax from nameSize - 1 to sizeof(inst->name) */ + if (EOK != STRCPY_S (inst->name, sizeof (inst->name), name)) + { + return; + } + + // Now we need to search if it's any instance's father + nsfw_module_instance_t *curInst = nsfw_module_getManager ()->inst; + while (curInst) + { + if (curInst == inst) + goto next_loop; + + if (0 == strcmp (curInst->fatherName, inst->name) + && NULL == curInst->father) + { + nsfw_module_setChildInstance (inst, curInst); + } + next_loop: + curInst = curInst->next; + } + return; +} + +void +nsfw_module_set_instance_father (nsfw_module_instance_t * inst, + char *fatherName) +{ + if (NULL == inst || NULL == fatherName) + { + return; + } + + if (EOK != + STRCPY_S (inst->fatherName, sizeof (inst->fatherName), fatherName)) + { + return; + } + + nsfw_module_instance_t *fatherInst = + nsfw_module_getModuleByName (fatherName); + if (fatherInst) + { + nsfw_module_setChildInstance (fatherInst, inst); + } + return; +} + +void +nsfw_module_set_instance_priority (nsfw_module_instance_t * inst, + int priority) +{ + if (NULL == inst) + return; + inst->priority = priority; + + nsfw_module_del_instance (inst); + nsfw_module_add_instance (inst); + return; +} + +void +nsfw_module_set_instance_initfn (nsfw_module_instance_t * inst, + nsfw_module_init_fn fn) +{ + if (NULL == inst) + return; + inst->fnInit = fn; + return; +} + +void +nsfw_module_set_instance_depends (nsfw_module_instance_t * inst, char *name) +{ + if (NULL == inst || name == NULL) + return; + + // Check if depends already set + nsfw_module_depends_t *dep = inst->depends; + while (dep) + { + if (0 == strcmp (dep->name, name)) + return; + dep = dep->next; + } + + dep = nsfw_module_create_depends (name); + if (NULL == dep) + return; + + if (NULL == inst->depends) + inst->depends = dep; + else + inst->depends->next = dep; +} + +/* *INDENT-OFF* */ +nsfw_module_manager_t g_nsfw_module_manager = {.inst = NULL, .initMutex = + PTHREAD_MUTEX_INITIALIZER, .done = 0}; +/* *INDENT-ON* */ + +void +nsfw_module_add_instance (nsfw_module_instance_t * inst) +{ + nsfw_module_instance_t *curInst = nsfw_module_getManager ()->inst; + + if (NULL == curInst || curInst->priority > inst->priority) + { + inst->next = curInst; + nsfw_module_getManager ()->inst = inst; + } + else + { + while (curInst->next && curInst->next->priority <= inst->priority) + { + curInst = curInst->next; + } + inst->next = curInst->next; + curInst->next = inst; + } +} + +void +nsfw_module_del_instance (nsfw_module_instance_t * inst) +{ + if (nsfw_module_getManager ()->inst == inst) + { + nsfw_module_getManager ()->inst = inst->next; + return; + } + + nsfw_module_instance_t *curInst = nsfw_module_getManager ()->inst; + + while (curInst->next && curInst->next != inst) + curInst = curInst->next; + + if (!curInst->next) + return; + curInst->next = inst->next; +} + +nsfw_module_instance_t * +nsfw_module_getModuleByName (char *name) +{ + if (NULL == name) + return NULL; + + nsfw_module_instance_t *curInst = nsfw_module_getManager ()->inst; + while (curInst) + { + if (0 == strcmp (curInst->name, name)) + { + return curInst; + } + curInst = curInst->next; + } + + return NULL; +} + +int +nsfw_module_addDoneNode (nsfw_module_instance_t * inst) +{ + nsfw_module_doneNode_t *node = + (nsfw_module_doneNode_t *) malloc (sizeof (nsfw_module_doneNode_t)); + if (NULL == node) + return -1; + node->inst = inst; + node->next = NULL; + + nsfw_module_manager_t *manager = nsfw_module_getManager (); + if (NULL == manager->doneHead) + { + manager->doneHead = node; + } + else + { + nsfw_module_doneNode_t *tail = manager->doneHead; + while (tail->next) + { + tail = tail->next; + } + + tail->next = node; + } + + return 0; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/framework/init/fw_module.h b/src/framework/init/fw_module.h new file mode 100644 index 0000000..1cfc95f --- /dev/null +++ b/src/framework/init/fw_module.h @@ -0,0 +1,85 @@ +/* +* +* 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 _FW_MODULE +#define _FW_MODULE +#include + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* _cplusplus */ + +#include "nsfw_init.h" + +/* Unique name declare */ +#define NSFW__STRINGIFY(x) #x +#define NSFW_STRINGIFY(x) NSFW__STRINGIFY(x) + +#define NSFW__PASTE(a,b) a##b +#define NSFW_PASTE(a,b) NSFW__PASTE(a,b) + +#define NSFW_UNIQUE_ID(prefix) NSFW_PASTE(NSFW_PASTE(__LINE__, prefix), __COUNTER__) + +#define NSFW_MODULE_INITFN(_fn) \ + static int _fn(void* param) +extern nsfw_module_depends_t *nsfw_module_create_depends (char *name); + +#define NSFW_MODULE_SET_STATE(inst, state) ((inst)->stat = (state)) + +typedef struct _nsfw_module_doneNode +{ + nsfw_module_instance_t *inst; + struct _nsfw_module_doneNode *next; +} nsfw_module_doneNode_t; + +typedef struct _nsfw_module_manager +{ + pthread_mutex_t initMutex; + int done; // 0 - not finished, 1 - finished, -1 - error + nsfw_module_instance_t *inst; + nsfw_module_doneNode_t *doneHead; +} nsfw_module_manager_t; + +extern int nsfw_module_addDoneNode (nsfw_module_instance_t * inst); + +extern nsfw_module_manager_t g_nsfw_module_manager; +#define nsfw_module_getManager() (&g_nsfw_module_manager) + +#define NSFW_MOUDLE_INSTANCE_POOL_SIZE 64 +#define NSFW_MOUDLE_DEPENDS_POOL_SIZE 128 + +typedef struct _nsfw_module_instance_pool +{ + int last_idx; + nsfw_module_instance_t + module_instance_pool[NSFW_MOUDLE_INSTANCE_POOL_SIZE]; +} nsfw_module_instance_pool_t; + +typedef struct _nsfw_module_depends_pool +{ + int last_idx; + nsfw_module_depends_t module_depends_pool[NSFW_MOUDLE_DEPENDS_POOL_SIZE]; +} nsfw_module_depends_pool_t; + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* _cplusplus */ + +#endif /* _FW_MODULE */ diff --git a/src/framework/ipc/mgr_com/mgr_com.c b/src/framework/ipc/mgr_com/mgr_com.c new file mode 100644 index 0000000..4a57d6a --- /dev/null +++ b/src/framework/ipc/mgr_com/mgr_com.c @@ -0,0 +1,2037 @@ +/* +* +* 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 header files * + *----------------------------------------------*/ + +#include "types.h" +#include "nstack_securec.h" +#include "nsfw_init.h" +#include "common_mem_api.h" + +#include "nsfw_mgr_com_api.h" +#include "mgr_com.h" +#include "nstack_log.h" +#include "nsfw_base_linux_api.h" + +#include +#include +#include +#include + +#include "nsfw_maintain_api.h" +#include "nsfw_ps_api.h" +#include "nsfw_fd_timer_api.h" + +#include "common_func.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +/* *INDENT-OFF* */ + +/* *INDENT-OFF* */ +nsfw_mgr_msg_fun g_mgr_fun[MGR_MSG_MAX][NSFW_MGRCOM_MAX_PROC_FUN]; +nsfw_mgr_init_cfg g_mgr_com_cfg; +nsfw_mgr_sock_map g_mgr_sockt_map = {{0}, NULL}; +nsfw_mgrcom_stat g_mgr_stat; +nsfw_mgrcom_proc g_ep_proc = { 0 }; +/* *INDENT-ON* */ + +u32 g_mgr_sockfdmax = NSFW_MGRCOM_MAX_SOCKET; + +char g_proc_info[NSFW_PROC_MAX][NSTACK_MAX_PROC_NAME_LEN] = { + "", "nStackMain", "nStackMaster", "nStackLib", "nStackTools", "nStackCtrl", + "", "", "", "", "", "", "", "", "", "" +}; + +/* *INDENT-ON* */ + +int g_thread_policy = 0; +int g_thread_pri = 0; + +void +nsfw_com_attr_set (int policy, int pri) +{ + g_thread_policy = policy; + g_thread_pri = pri; +} + +char * +nsfw_get_proc_name (u8 proc_type) +{ + if (proc_type >= NSFW_PROC_MAX || NSFW_PROC_NULL == proc_type) + { + return NULL; + } + + return g_proc_info[proc_type]; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_reg_msg_fun +* Description : reg the callback funciton when receive new message +* Input : u16 msg_type +* nsfw_mgr_msg_fun fun +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_mgr_reg_msg_fun (u16 msg_type, nsfw_mgr_msg_fun fun) +{ + u32 i; + if (MGR_MSG_MAX <= msg_type) + { + NSFW_LOGERR ("reg mgr_msg]msg_type=%u,fun=%p", msg_type, fun); + return FALSE; + } + + for (i = 0; i < NSFW_MGRCOM_MAX_PROC_FUN; i++) + { + if (NULL == g_mgr_fun[msg_type][i]) + { + /*TODO should use cas */ + g_mgr_fun[msg_type][i] = fun; + NSFW_LOGINF ("reg mgr_msg fun suc]msg_type=%u,fun=%p", msg_type, + fun); + return TRUE; + } + } + + NSFW_LOGERR ("reg mgr_msg type full]msg_type=%u,fun=%p", msg_type, fun); + return FALSE; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_null_rspmsg_alloc +* Description : alloc null response msg for receive message buffer +* Input : None +* Output : None +* Return Value : nsfw_mgr_msg* +* Calls : +* Called By : +*****************************************************************************/ +nsfw_mgr_msg * +nsfw_mgr_null_rspmsg_alloc () +{ + return nsfw_mgr_msg_alloc (MGR_MSG_NULL, NSFW_PROC_NULL); +} + +/***************************************************************************** +* Prototype : nsfw_mgr_msg_alloc +* Description : alloc new request message to send +* Input : u16 msg_type +* u8 dst_proc_type +* Output : None +* Return Value : nsfw_mgr_msg* +* Calls : +* Called By : +*****************************************************************************/ +nsfw_mgr_msg * +nsfw_mgr_msg_alloc (u16 msg_type, u8 dst_proc_type) +{ + nsfw_mgr_msg *p_msg = NULL; + u8 from_mem_flag = FALSE; + u32 alloc_len = sizeof (nsfw_mgr_msg); + + if (MGR_MSG_LAG_QRY_RSP_BEGIN <= msg_type) + { + from_mem_flag = TRUE; + alloc_len = NSFW_MGR_LARGE_MSG_LEN; + } + + if ((NULL == g_mgr_com_cfg.msg_pool) + && (MGR_MSG_INIT_NTY_REQ == msg_type + || MGR_MSG_INIT_NTY_RSP == msg_type)) + { + from_mem_flag = TRUE; + } + + if (FALSE == from_mem_flag) + { + if (0 == + nsfw_mem_ring_dequeue (g_mgr_com_cfg.msg_pool, (void *) &p_msg)) + { + NSFW_LOGERR ("alloc msg full]type=%u,dst=%u", msg_type, + dst_proc_type); + return NULL; + } + alloc_len = sizeof (nsfw_mgr_msg); + } + else + { + p_msg = (nsfw_mgr_msg *) malloc (alloc_len); + } + + if (NULL == p_msg) + { + NSFW_LOGERR ("alloc msg nul]type=%u,dst=%u", msg_type, dst_proc_type); + return NULL; + } + + if (EOK != MEMSET_S (p_msg, alloc_len, 0, alloc_len)) + { + p_msg->from_mem = from_mem_flag; + nsfw_mgr_msg_free (p_msg); + NSFW_LOGERR ("alloc msg MEMSET_S failed]type=%u,dst=%u", msg_type, + dst_proc_type); + return NULL; + } + p_msg->from_mem = from_mem_flag; + + if (msg_type < MGR_MSG_RSP_BASE && msg_type > 0) + { + p_msg->seq = common_mem_atomic32_add_return (&g_mgr_com_cfg.cur_idx, 1); + } + + p_msg->from_mem = from_mem_flag; + p_msg->msg_type = msg_type; + p_msg->src_pid = get_sys_pid (); + p_msg->src_proc_type = g_mgr_com_cfg.proc_type; + p_msg->msg_len = alloc_len; + p_msg->dst_proc_type = dst_proc_type; + p_msg->alloc_flag = TRUE; + p_msg->more_msg_flag = 0; + + g_mgr_stat.msg_alloc++; + return p_msg; +} + +static inline void +lint_lock_1 () +{ + return; +} + +static inline void +lint_unlock_1 () +{ + return; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_rsp_msg_alloc +* Description : alloc response message from request message +* Input : nsfw_mgr_msg* req_msg +* Output : None +* Return Value : nsfw_mgr_msg* +* Calls : +* Called By : +*****************************************************************************/ +nsfw_mgr_msg * +nsfw_mgr_rsp_msg_alloc (nsfw_mgr_msg * req_msg) +{ + nsfw_mgr_msg *p_msg = NULL; + if (NULL == req_msg) + { + NSFW_LOGERR ("req msg nul!"); + return NULL; + } + + p_msg = + nsfw_mgr_msg_alloc (req_msg->msg_type + MGR_MSG_RSP_BASE, + req_msg->src_proc_type); + if (NULL == p_msg) + { + return NULL; + } + + p_msg->dst_pid = req_msg->src_pid; + p_msg->seq = req_msg->seq; + return p_msg; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_msg_free +* Description : message free +* Input : nsfw_mgr_msg *msg +* Output : None +* Return Value : void +* Calls : +* Called By : +*****************************************************************************/ +void +nsfw_mgr_msg_free (nsfw_mgr_msg * msg) +{ + if (NULL == msg) + { + return; + } + + if (FALSE == msg->alloc_flag) + { + NSFW_LOGERR ("msg refree]msg=%p, type=%u", msg, msg->msg_type); + return; + } + + msg->alloc_flag = FALSE; + + if (TRUE == msg->from_mem) + { + if ((MGR_MSG_INIT_NTY_REQ == msg->msg_type + || MGR_MSG_INIT_NTY_RSP == msg->msg_type) + || (MGR_MSG_LAG_QRY_RSP_BEGIN <= msg->msg_type)) + { + free (msg); + g_mgr_stat.msg_free++; + return; + } + NSFW_LOGERR ("msg err free]type=%u", msg->msg_type); + } + + if (0 == nsfw_mem_ring_enqueue (g_mgr_com_cfg.msg_pool, msg)) + { + NSFW_LOGERR ("msg free failed pool full]msg=%p, type=%u", msg, + msg->msg_type); + return; + } + + g_mgr_stat.msg_free++; + return; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_get_listen_socket +* Description : get domain socket listen fd +* Input : None +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_mgr_get_listen_socket () +{ + i32 fd, len; + struct sockaddr_un un; + + if ((fd = nsfw_base_socket (AF_UNIX, SOCK_STREAM, 0)) < 0) + { + NSFW_LOGERR ("create sock failed!"); + return -1; + } + + if (-1 == unlink ((char *) g_mgr_com_cfg.domain_path)) + { + NSFW_LOGWAR ("unlink failed]error=%d", errno); + } + if (EOK != MEMSET_S (&un, sizeof (un), 0, sizeof (un))) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("create sock MEMSET_S failed!] error=%d", errno); + return -1; + } + + un.sun_family = AF_UNIX; + int retVal = STRCPY_S ((char *) un.sun_path, sizeof (un.sun_path), + (char *) g_mgr_com_cfg.domain_path); + if (EOK != retVal) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("create sock STRCPY_S failed!] error=%d", errno); + return -1; + } + + int rc = nsfw_set_close_on_exec (fd); + if (rc == -1) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("set exec err]fd=%d, errno=%d", fd, errno); + return -1; + } + + len = + offsetof (struct sockaddr_un, + sun_path) +strlen ((char *) g_mgr_com_cfg.domain_path); + + if (nsfw_base_bind (fd, (struct sockaddr *) &un, len) < 0) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("bind failed!]mgr_fd=%d,error=%d", fd, errno); + return -1; + } + + if (nsfw_base_listen (fd, 10) < 0) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("listen failed!]mgr_fd=%d,error=%d", fd, errno); + return -1; + } + + NSFW_LOGINF ("mgr com start with]mgr_fd=%d", fd); + return fd; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_get_connect_socket +* Description : get new connect fd to destination procedure +* Input : u8 proc_type +* u32 host_pid +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_mgr_get_connect_socket (u8 proc_type, u32 host_pid) +{ + i32 fd, len; + char *name; + struct sockaddr_un un; + const char *directory = NSFW_DOMAIN_DIR; + const char *home_dir = getenv ("HOME"); + + if (getuid () != 0 && home_dir != NULL) + directory = home_dir; + + switch (proc_type) + { + case NSFW_PROC_MAIN: + name = NSFW_MAIN_FILE; + break; + case NSFW_PROC_MASTER: + name = NSFW_MASTER_FILE; + break; + case NSFW_PROC_ALARM: + directory = "/tmp"; + name = NSFW_ALARM_FILE; + break; + default: + NSFW_LOGERR ("get dst socket err]type=%u,pid=%u", proc_type, host_pid); + return -1; + } + + if ((fd = nsfw_base_socket (AF_UNIX, SOCK_STREAM, 0)) < 0) + { + NSFW_LOGERR ("create socket err]type=%u,pid=%u,errno=%d", proc_type, + host_pid, errno); + return -1; + } + + if (EOK != MEMSET_S (&un, sizeof (un), 0, sizeof (un))) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("get dst socket err]mgr_fd=%d,type=%u,pid=%u", fd, + proc_type, host_pid); + return -1; + } + + struct timeval tv; + tv.tv_sec = MGR_COM_RECV_TIMEOUT; + tv.tv_usec = 0; + if (nsfw_base_setsockopt + (fd, SOL_SOCKET, SO_RCVTIMEO, (char *) &tv, sizeof tv)) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("setsockopt socket err]mgr_fd=%d,type=%u,pid=%u", fd, + proc_type, host_pid); + return -1; + } + + int rc = nsfw_set_close_on_exec (fd); + if (rc == -1) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("set exec err]fd=%d, errno=%d", fd, errno); + return -1; + } + + int size, size_len; + size = MAX_RECV_BUF_DEF; + size_len = sizeof (size); + if (0 > + nsfw_base_setsockopt (fd, SOL_SOCKET, SO_RCVBUF, (void *) &size, + (socklen_t) size_len)) + { + NSFW_LOGERR ("set socket opt err!]error=%d", errno); + } + + if (0 > + nsfw_base_setsockopt (fd, SOL_SOCKET, SO_SNDBUF, (void *) &size, + (socklen_t) size_len)) + { + NSFW_LOGERR ("set socket opt err!]error=%d", errno); + } + + un.sun_family = AF_UNIX;; + int retVal = STRCPY_S ((char *) un.sun_path, sizeof (un.sun_path), + (char *) directory); + if (EOK != retVal) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("create sock STRCPY_S failed!] error=%d", errno); + return -1; + } + + retVal = STRCAT_S (un.sun_path, sizeof (un.sun_path), name); + if (EOK != retVal) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("create sock STRCAT_S failed!] error=%d", errno); + return -1; + } + + len = offsetof (struct sockaddr_un, sun_path) +strlen (un.sun_path); + if (nsfw_base_connect (fd, (struct sockaddr *) &un, len) < 0) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR + ("create socket err]mgr_fd=%d,type=%u,pid=%u,errno=%d,path=%s", fd, + proc_type, host_pid, errno, un.sun_path); + return -1; + } + + NSFW_LOGINF ("get dst socket]mgr_fd=%d,type=%u,pid=%u", fd, proc_type, + host_pid); + return (fd); +} + +/***************************************************************************** +* Prototype : nsfw_mgr_new_socket +* Description : management the new fd to cache +* Input : u32 fd +* u8 proc_type +* u32 host_pid +* Output : None +* Return Value : static inline u8 +* Calls : +* Called By : +*****************************************************************************/ +NSTACK_STATIC inline u8 +nsfw_mgr_new_socket (i32 fd, u8 proc_type, u32 host_pid) +{ + nsfw_mgr_sock_info *sock_info = NULL; + if (((i32) NSFW_MGR_FD_MAX <= fd) || (fd < 0) || (!g_mgr_sockt_map.sock)) + { + NSFW_LOGERR ("fd err]mgr_fd=%d, sock=%p", fd, g_mgr_sockt_map.sock); + return FALSE; + } + + sock_info = &g_mgr_sockt_map.sock[fd]; + if (host_pid != sock_info->host_pid) + { + NSFW_LOGDBG + ("update sock info]mgr_fd=%d,old_pid=%u,new_pid=%u,type=%u", fd, + sock_info->host_pid, host_pid, proc_type); + } + + sock_info->host_pid = host_pid; + sock_info->proc_type = proc_type; + + if (proc_type < NSFW_PROC_MAX) + { + g_mgr_sockt_map.proc_cache[proc_type] = fd; + } + + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_del_socket +* Description : delete the fd from cache when fd close +* Input : u32 fd +* Output : None +* Return Value : static inline u8 +* Calls : +* Called By : +*****************************************************************************/ +NSTACK_STATIC inline u8 +nsfw_mgr_del_socket (u32 fd) +{ + nsfw_mgr_sock_info *sock_info = NULL; + if ((NSFW_MGR_FD_MAX <= fd) || (!g_mgr_sockt_map.sock)) + { + NSFW_LOGERR ("fd err]mgr_fd=%u, sock=%p", fd, g_mgr_sockt_map.sock); + return FALSE; + } + + sock_info = &g_mgr_sockt_map.sock[fd]; + + if (sock_info->proc_type < NSFW_PROC_MAX + && fd == g_mgr_sockt_map.proc_cache[sock_info->proc_type]) + { + g_mgr_sockt_map.proc_cache[sock_info->proc_type] = 0; + } + + NSFW_LOGDBG ("del sock]mgr_fd=%u,type=%u,pid=%u", fd, + sock_info->proc_type, sock_info->host_pid); + sock_info->host_pid = 0; + sock_info->proc_type = 0; + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_get_dst_socket +* Description : get the fd to send message to destination procedure +* Input : u8 proc_type +* u32 dst_pid +* Output : None +* Return Value : static inline i32 +* Calls : +* Called By : +*****************************************************************************/ +NSTACK_STATIC inline i32 +nsfw_mgr_get_dst_socket (u8 proc_type, u32 dst_pid) +{ + i32 fd = -1; + + nsfw_mgr_sock_info *sock_info = NULL; + + if (proc_type < NSFW_PROC_MAX) + { + fd = g_mgr_sockt_map.proc_cache[proc_type]; + } + + if (!g_mgr_sockt_map.sock) + { + return -1; + } + + if (fd > 0 && fd < (i32) NSFW_MGR_FD_MAX) + { + sock_info = &g_mgr_sockt_map.sock[fd]; + if (sock_info->host_pid != 0) + { + if (0 == dst_pid || dst_pid == sock_info->host_pid) + { + return fd; + } + } + else if (proc_type == sock_info->proc_type) + { + return fd; + } + } + + i32 i; + for (i = 0; i < (i32) NSFW_MGR_FD_MAX; i++) + { + sock_info = &g_mgr_sockt_map.sock[i]; + if (sock_info->host_pid != 0 && proc_type == sock_info->proc_type) + { + if (0 == dst_pid || dst_pid == sock_info->host_pid) + { + return i; + } + } + } + + return -1; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_get_new_socket +* Description : get new connect +* Input : u8 proc_type +* u32 dst_pid +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_mgr_get_new_socket (u8 proc_type, u32 dst_pid) +{ + i32 fd = 0; + fd = nsfw_mgr_get_connect_socket (proc_type, dst_pid); + if (fd > 0) + { + (void) nsfw_mgr_new_socket (fd, proc_type, dst_pid); + (void) nsfw_mgr_reg_sock_fun (fd, nsfw_mgr_new_msg); + } + return fd; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_clr_fd_lock +* Description : clear the fd lock when fork in child proc +* Input : None +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_mgr_clr_fd_lock () +{ + i32 i; + if (!g_mgr_sockt_map.sock) + { + NSFW_LOGERR ("clr fd lock fail, sock is null"); + return FALSE; + } + for (i = 0; i < (i32) NSFW_MGR_FD_MAX; i++) + { + common_mem_spinlock_init (&(g_mgr_sockt_map.sock[i].opr_lock)); + } + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_close_dst_proc +* Description : close the remote connect +* Input : u8 proc_type +* u32 dst_pid +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +void +nsfw_mgr_close_dst_proc (u8 proc_type, u32 dst_pid) +{ + i32 fd = nsfw_mgr_get_dst_socket (proc_type, dst_pid); + if (fd > 0) + { + (void) nsfw_mgr_del_socket (fd); + (void) nsfw_mgr_unreg_sock_fun (fd); + (void) nsfw_base_close (fd); + } +} + +/***************************************************************************** +* Prototype : nsfw_mgr_send_msg_socket +* Description : send message to dst fd +* Input : u32 fd +* nsfw_mgr_msg* msg +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_mgr_send_msg_socket (u32 fd, nsfw_mgr_msg * msg) +{ + i32 send_len = 0; + i32 off_set = 0; + + if (NULL == msg) + { + NSFW_LOGERR ("msg nul]mgr_fd=%u", fd); + return FALSE; + } + + if (msg->msg_len < sizeof (nsfw_mgr_msg)) + { + msg->msg_len = sizeof (nsfw_mgr_msg); + } + + if (msg->msg_type == MGR_MSG_LARGE_ALARM_RSP) + { + off_set = NSFW_MGR_MSG_HDR_LEN; + } + + /*TODO if closed by peer, may send failed, should close this fd */ + do + { + off_set += send_len; + send_len = + nsfw_base_send (fd, (char *) msg + off_set, msg->msg_len - off_set, + MSG_NOSIGNAL); + if (send_len <= 0) + { + NSFW_LOGERR + ("send error]mgr_fd=%u,send_len=%d,off_set=%d,errno=%d" MSGINFO, + fd, send_len, off_set, errno, PRTMSG (msg)); + return FALSE; + } + } + while ((send_len + off_set) < (i32) msg->msg_len); + NSFW_LOGDBG ("send mgr_msg suc]mgr_fd=%u," MSGINFO, fd, PRTMSG (msg)); + g_mgr_stat.msg_send[msg->msg_type]++; + return TRUE; +} + +#define MAX_RECV_COUNT 100 + +/***************************************************************************** +* Prototype : nsfw_mgr_recv_msg_socket +* Description : receive new message from fd +* Input : u32 fd +* nsfw_mgr_msg* msg +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_mgr_recv_msg_socket (u32 fd, nsfw_mgr_msg * msg, + nsfw_mgr_msg ** large_msg) +{ + i32 recv_len = 0; + i32 off_set = 0; + u32 msg_len = 0; + i32 max_count = 0; + if (NULL == msg) + { + return FALSE; + } + + u8 from_flag = msg->from_mem; + msg_len = msg->msg_len; + do + { + off_set += recv_len; + recv_len = + nsfw_base_recv (fd, (char *) msg + off_set, msg_len - off_set, 0); + if (recv_len <= 0) + { + if ((EINTR == errno || EAGAIN == errno) + && (max_count < MAX_RECV_COUNT)) + { + recv_len = 0; + max_count++; + continue; + } + + NSFW_LOGERR + ("recv error]mgr_fd=%u,recv_len=%d,off_set=%d,errno=%d," + MSGINFO, fd, recv_len, off_set, errno, PRTMSG (msg)); + msg->from_mem = from_flag; + return FALSE; + } + } + while (recv_len + off_set < (i32) msg_len); + + msg->from_mem = from_flag; + + g_mgr_stat.msg_recv[msg->msg_type]++; + + if (msg->msg_len <= msg_len) + { + NSFW_LOGDBG ("recv mgr_msg suc]mgr_fd=%u," MSGINFO, fd, PRTMSG (msg)); + return TRUE; + } + + if (large_msg == NULL) + { + return TRUE; + } + + nsfw_mgr_msg *l_msg = + nsfw_mgr_msg_alloc (msg->msg_type, msg->dst_proc_type); + if (NULL == l_msg) + { + return TRUE; + } + + if (l_msg->msg_len <= msg_len) + { + NSFW_LOGWAR ("alloc new msg error!]len=%u,org_len=%u,type=%u", + l_msg->msg_len, msg->msg_len, msg->msg_type); + nsfw_mgr_msg_free (l_msg); + return TRUE; + } + + max_count = 0; + (void) nsfw_set_sock_block (fd, FALSE); + from_flag = l_msg->from_mem; + u32 l_msg_len = l_msg->msg_len; + do + { + off_set += recv_len; + recv_len = + nsfw_base_recv (fd, (char *) l_msg + off_set, l_msg_len - off_set, 0); + if (recv_len <= 0) + { + if ((EINTR == errno || EAGAIN == errno) + && (max_count < MAX_RECV_COUNT)) + { + recv_len = 0; + max_count++; + continue; + } + + NSFW_LOGERR + ("recv error]mgr_fd=%u,recv_len=%d,off_set=%d,errno=%d," + MSGINFO, fd, recv_len, off_set, errno, PRTMSG (msg)); + l_msg->from_mem = from_flag; + nsfw_mgr_msg_free (l_msg); + return FALSE; + } + } + while (recv_len + off_set < (i32) l_msg_len); + (void) nsfw_set_sock_block (fd, TRUE); + int retVal = MEMCPY_S (l_msg, msg_len, msg, msg_len); + if (EOK != retVal) + { + NSFW_LOGERR ("MEMCPY_S failed] ret=%d", retVal); + l_msg->from_mem = from_flag; + nsfw_mgr_msg_free (l_msg); + return TRUE; + } + l_msg->from_mem = from_flag; + l_msg->msg_len = l_msg_len; + + *large_msg = l_msg; + NSFW_LOGDBG ("recv large mgr_msg suc]mgr_fd=%u," MSGINFO, fd, + PRTMSG (l_msg)); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_send_req_wait_rsp +* Description : send request message and block waiting for it's response + within MGR_COM_RECV_TIMEOUT +* Input : nsfw_mgr_msg* req_msg +* nsfw_mgr_msg* rsp_msg +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_mgr_send_req_wait_rsp (nsfw_mgr_msg * req_msg, nsfw_mgr_msg * rsp_msg) +{ + if (NULL == req_msg) + { + NSFW_LOGERR ("req msg nul!"); + return FALSE; + } + + i32 dst_socket = + nsfw_mgr_get_dst_socket (req_msg->dst_proc_type, req_msg->dst_pid); + if (dst_socket <= 0) + { + dst_socket = + nsfw_mgr_get_new_socket (req_msg->dst_proc_type, req_msg->dst_pid); + if (dst_socket <= 0) + { + NSFW_LOGERR ("send msg get dst_socket_error]" MSGINFO, + PRTMSG (req_msg)); + return FALSE; + } + } + + if ((NULL == rsp_msg) && (req_msg->msg_len == sizeof (nsfw_mgr_msg))) + { + LOCK_MGR_FD (dst_socket) + if (FALSE == nsfw_mgr_send_msg_socket (dst_socket, req_msg)) + { + NSFW_LOGERR ("send msg error]" MSGINFO, PRTMSG (req_msg)); + g_mgr_stat.msg_send_failed++; + UNLOCK_MGR_FD (dst_socket) return FALSE; + } + UNLOCK_MGR_FD (dst_socket) return TRUE; + } + + LOCK_MGR_FD (dst_socket); + (void) nsfw_mgr_unreg_sock_fun (dst_socket); + if (FALSE == nsfw_mgr_send_msg_socket (dst_socket, req_msg)) + { + NSFW_LOGERR ("send msg error]" MSGINFO, PRTMSG (req_msg)); + g_mgr_stat.msg_send_failed++; + (void) nsfw_mgr_reg_sock_fun (dst_socket, nsfw_mgr_new_msg); + UNLOCK_MGR_FD (dst_socket); + return FALSE; + } + + if (NULL == rsp_msg) + { + (void) nsfw_mgr_reg_sock_fun (dst_socket, nsfw_mgr_new_msg); + UNLOCK_MGR_FD (dst_socket) return TRUE; + } + + u16 i; + for (i = 0; i < MGR_COM_MAX_DROP_MSG; i++) + { + if (FALSE == nsfw_mgr_recv_msg_socket (dst_socket, rsp_msg, NULL)) + { + NSFW_LOGERR ("recv msg error]" MSGINFO, PRTMSG (req_msg)); + (void) nsfw_mgr_reg_sock_fun (dst_socket, nsfw_mgr_new_msg); + UNLOCK_MGR_FD (dst_socket) return FALSE; + } + + if ((rsp_msg->seq == req_msg->seq) + && (rsp_msg->msg_type == req_msg->msg_type + MGR_MSG_RSP_BASE)) + { + break; + } + + NSFW_LOGINF ("recv msg forward]" MSGINFO, PRTMSG (rsp_msg)); + rsp_msg->fw_flag = TRUE; + (void) nsfw_mgr_send_msg (rsp_msg); + } + + (void) nsfw_mgr_reg_sock_fun (dst_socket, nsfw_mgr_new_msg); + if (0 == req_msg->dst_pid) + { + (void) nsfw_mgr_new_socket (dst_socket, rsp_msg->src_proc_type, + rsp_msg->src_pid); + } + UNLOCK_MGR_FD (dst_socket) return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_send_msg +* Description : send message to peer +* Input : nsfw_mgr_msg* msg +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_mgr_send_msg (nsfw_mgr_msg * msg) +{ + return nsfw_mgr_send_req_wait_rsp (msg, NULL); +} + +/***************************************************************************** +* Prototype : nsfw_mgr_msg_in +* Description : when new domain socket mgr message receive, this function will be call +* Input : i32 fd +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_mgr_msg_in (i32 fd) +{ + u32 i = 0; + u8 ret = FALSE; + u8 msg_match = FALSE; + nsfw_mgr_msg *msg = nsfw_mgr_null_rspmsg_alloc (); + nsfw_mgr_msg *large_msg = NULL; + + LOCK_MGR_FD (fd) ret = nsfw_mgr_recv_msg_socket (fd, msg, &large_msg); + UNLOCK_MGR_FD (fd) if (large_msg != NULL) + { + nsfw_mgr_msg_free (msg); + msg = large_msg; + } + + if (FALSE == ret) + { + nsfw_mgr_msg_free (msg); + return FALSE; + } + nstack_get_tracing_contex (msg->traceid, 0, 0, -1); + if (msg->fw_flag != TRUE) + { + (void) nsfw_mgr_new_socket (fd, msg->src_proc_type, msg->src_pid); + } + + if (msg->msg_type < MGR_MSG_MAX) + { + for (i = 0; i < NSFW_MGRCOM_MAX_PROC_FUN; i++) + { + if (NULL == g_mgr_fun[msg->msg_type][i]) + { + break; + } + + (void) g_mgr_fun[msg->msg_type][i] (msg); + msg_match = TRUE; + } + } + + if (FALSE != msg_match) + { + nsfw_mgr_msg_free (msg); + nstack_clear_tracing_contex (); + return TRUE; + } + + if (msg->msg_type < MGR_MSG_RSP_BASE) + { + NSFW_LOGERR ("msg match failed! auto rsp]" MSGINFO, PRTMSG (msg)); + nsfw_mgr_msg *rsp_msg = nsfw_mgr_rsp_msg_alloc (msg); + if (NULL != rsp_msg) + { + rsp_msg->resp_code = NSFW_MGR_MSG_TYPE_ERROR; + (void) nsfw_mgr_send_msg (rsp_msg); + nsfw_mgr_msg_free (rsp_msg); + } + } + + NSFW_LOGERR ("drop msg]" MSGINFO, PRTMSG (msg)); + /* fix "Out-of-bounds write" type codedex issue */ + if (msg->msg_type < MGR_MSG_MAX) + { + g_mgr_stat.recv_drop[msg->msg_type]++; + } + nsfw_mgr_msg_free (msg); + nstack_clear_tracing_contex (); + return FALSE; + +} + +/***************************************************************************** +* Prototype : nsfw_mgr_new_msg +* Description : when new mgr message recive from socket, this funciton + will call back +* Input : i32 epfd +* i32 fd +* u32 events +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_mgr_new_msg (i32 epfd, i32 fd, u32 events) +{ + lint_lock_1 (); + if ((events & EPOLLERR) || (events & EPOLLHUP) || (!(events & EPOLLIN))) + { + (void) nsfw_mgr_del_socket (fd); + (void) nsfw_mgr_unreg_sock_fun (fd); + (void) nsfw_base_close (fd); + lint_unlock_1 (); + return TRUE; + } + + (void) nsfw_mgr_msg_in (fd); + lint_unlock_1 (); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_com_rereg_fun +* Description : rereg the error socket +* Input : u32 timer_type +* void* data +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_mgr_com_rereg_fun (u32 timer_type, void *data) +{ + (void) nsfw_mgr_reg_sock_fun (timer_type, (nsfw_mgr_sock_fun) data); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_com_socket_error +* Description : remove the error fd from ep +* Input : i32 fd +* nsfw_mgr_sock_fun fun +* i32 timer +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_mgr_com_socket_error (i32 fd, nsfw_mgr_sock_fun fun, i32 timer) +{ + struct timespec time_left = { timer, 0 }; + nsfw_mgr_unreg_sock_fun (fd); + nsfw_timer_reg_timer (fd, (void *) fun, nsfw_mgr_com_rereg_fun, time_left); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_new_connection +* Description : when new mgr connection in, this funciton will call back +* Input : i32 epfd +* i32 fd +* u32 events +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_mgr_new_connection (i32 epfd, i32 fd, u32 events) +{ + if ((events & EPOLLERR) || (events & EPOLLHUP) || (!(events & EPOLLIN))) + { + (void) nsfw_base_close (fd); + NSFW_LOGWAR ("listen disconnect!]epfd=%d,listen=%d,event=0x%x", epfd, + fd, events); + (void) nsfw_mgr_unreg_sock_fun (fd); + i32 listen_fd = nsfw_mgr_get_listen_socket (); + if (listen_fd < 0) + { + NSFW_LOGERR + ("get listen_fd faied!]epfd=%d,listen_fd=%d,event=0x%x", epfd, + fd, events); + return FALSE; + } + + (void) nsfw_mgr_reg_sock_fun (listen_fd, nsfw_mgr_new_connection); + return TRUE; + } + + struct sockaddr in_addr; + socklen_t in_len; + int infd; + in_len = sizeof in_addr; + + int size, size_len; + u8 accept_flag = FALSE; + while (1) + { + infd = nsfw_base_accept (fd, &in_addr, &in_len); + if (infd == -1) + { + if (FALSE == accept_flag) + { + nsfw_mgr_com_socket_error (fd, nsfw_mgr_new_connection, 1); + } + break; + } + + if (-1 == nsfw_set_close_on_exec (infd)) + { + (void) nsfw_base_close (infd); + NSFW_LOGERR ("set exec err]fd=%d, errno=%d", infd, errno); + break; + } + + size = MAX_RECV_BUF_DEF; + size_len = sizeof (size); + if (0 > + nsfw_base_setsockopt (infd, SOL_SOCKET, SO_RCVBUF, (void *) &size, + (socklen_t) size_len)) + { + NSFW_LOGERR ("set socket opt err!]error=%d", errno); + } + + if (0 > + nsfw_base_setsockopt (infd, SOL_SOCKET, SO_SNDBUF, (void *) &size, + (socklen_t) size_len)) + { + NSFW_LOGERR ("set socket opt err!]error=%d", errno); + } + + (void) nsfw_mgr_reg_sock_fun (infd, nsfw_mgr_new_msg); + NSFW_LOGDBG ("accept_flag new fd]new_mgr_fd=%d", infd); + accept_flag = TRUE; + } + + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_set_sock_block +* Description : set fd blok or not for epoll thread +* Input : i32 sock +* u8 flag +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_set_sock_block (i32 sock, u8 flag) +{ + i32 flags; + flags = nsfw_base_fcntl (sock, F_GETFL, 0); + if (flags < 0) + { + NSFW_LOGERR ("fcntl err]new_mgr_fd=%d,errno=%d", sock, errno); + return -1; + } + + if (TRUE == flag) + { + flags = flags | O_NONBLOCK; + } + else + { + flags = flags & (~O_NONBLOCK); + struct timeval tv; + tv.tv_sec = MGR_COM_RECV_TIMEOUT; + tv.tv_usec = 0; + if (nsfw_base_setsockopt + (sock, SOL_SOCKET, SO_RCVTIMEO, (char *) &tv, sizeof tv)) + { + NSFW_LOGERR ("setsockopt socket err]mgr_fd=%d", sock); + return -1; + } + } + + if (nsfw_base_fcntl (sock, F_SETFL, flags) < 0) + { + NSFW_LOGERR ("fcntl err]new_mgr_fd=%d,errno=%d,flags=%d", sock, errno, + flags); + return -1; + } + + return 0; +} + +/***************************************************************************** +* Prototype : nsfw_set_close_on_exec +* Description : close on exec set +* Input : i32 sock +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_set_close_on_exec (i32 sock) +{ + i32 flags; + flags = nsfw_base_fcntl (sock, F_GETFD, 0); + if (flags < 0) + { + NSFW_LOGERR ("fcntl err]fd=%d,errno=%d", sock, errno); + return -1; + } + + flags |= FD_CLOEXEC; + + if (nsfw_base_fcntl (sock, F_SETFD, flags) < 0) + { + NSFW_LOGERR ("fcntl err]fd=%d,errno=%d,flags=%d", sock, errno, flags); + return -1; + } + + return 0; +} + +/***************************************************************************** +* Prototype : nsfw_add_sock_to_ep +* Description : add fd to epoll wait thread +* Input : i32 fd +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_add_sock_to_ep (i32 fd) +{ + struct epoll_event event; + event.data.fd = fd; + event.events = EPOLLIN; + if (g_ep_proc.epfd == 0) + { + return TRUE; + } + + (void) nsfw_set_sock_block (fd, TRUE); + + if (0 > nsfw_base_epoll_ctl (g_ep_proc.epfd, EPOLL_CTL_ADD, fd, &event)) + { + NSFW_LOGINF + ("add sock to ep thread failed]mgr_fd=%d,errno=%d,epfd=%d", fd, + errno, g_ep_proc.epfd); + return FALSE; + } + + NSFW_LOGDBG ("add sock to ep thread]mgr_fd=%d,epfd=%d", fd, + g_ep_proc.epfd) return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_rmv_sock_from_ep +* Description : remove fd from epoll thread +* Input : i32 fd +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_rmv_sock_from_ep (i32 fd) +{ + struct epoll_event event; + event.data.fd = fd; + event.events = EPOLLIN; + if (g_ep_proc.epfd == 0) + { + return TRUE; + } + + (void) nsfw_set_sock_block (fd, FALSE); + + if (0 > nsfw_base_epoll_ctl (g_ep_proc.epfd, EPOLL_CTL_DEL, fd, &event)) + { + NSFW_LOGINF + ("rmv sock to ep thread failed] mgr_fd=%d,errno=%d,epfd=%d", fd, + errno, g_ep_proc.epfd); + return FALSE; + } + + NSFW_LOGDBG ("rmv sock to ep thread] mgr_fd=%d,epfd=%d", fd, + g_ep_proc.epfd) return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_reg_sock_fun +* Description : reg fd process function to call back when epoll thread + recvice new event of the reg fd +* Input : i32 fd +* nsfw_mgr_sock_fun fun +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_mgr_reg_sock_fun (i32 fd, nsfw_mgr_sock_fun fun) +{ + lint_lock_1 (); + if ((fd >= (i32) NSFW_MGR_FD_MAX) || (fd < 0) || NULL == fun) + { + NSFW_LOGINF ("reg sock fun error!] mgr_fd=%d,fun=%p", fd, fun); + lint_unlock_1 (); + return FALSE; + } + + if ((g_ep_proc.ep_fun) && (NULL == g_ep_proc.ep_fun[fd])) + { + g_ep_proc.ep_fun[fd] = fun; + if (FALSE == nsfw_add_sock_to_ep (fd)) + { + g_ep_proc.ep_fun[fd] = NULL; + lint_unlock_1 (); + return FALSE; + } + + NSFW_LOGDBG ("reg sock fun] mgr_fd=%d,fun=%p", fd, fun); + lint_unlock_1 (); + return TRUE; + } + lint_unlock_1 (); + return FALSE; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_unreg_sock_fun +* Description : unreg the fd event function +* Input : i32 fd +* Output : None +* Return Value : void +* Calls : +* Called By : +*****************************************************************************/ +void +nsfw_mgr_unreg_sock_fun (i32 fd) +{ + lint_lock_1 (); + if (fd >= (i32) NSFW_MGR_FD_MAX) + { + NSFW_LOGINF ("unreg sock fun failed!] mgr_fd=%d", fd); + lint_unlock_1 (); + return; + } + + if ((g_ep_proc.ep_fun) && (NULL != g_ep_proc.ep_fun[fd])) + { + g_ep_proc.ep_fun[fd] = NULL; + (void) nsfw_rmv_sock_from_ep (fd); + NSFW_LOGDBG ("unreg sock fun] mgr_fd=%d", fd); + lint_unlock_1 (); + return; + } + + lint_unlock_1 (); + return; +} + +/***************************************************************************** +* Prototype : nsfw_sock_fun_callback +* Description : call back the event process function +* Input : i32 epfd +* i32 fd +* u32 events +* Output : None +* Return Value : static inline u8 +* Calls : +* Called By : +*****************************************************************************/ +NSTACK_STATIC inline u8 +nsfw_sock_fun_callback (i32 epfd, i32 fd, u32 events) +{ + if ((fd < (i32) NSFW_MGR_FD_MAX) + && (g_ep_proc.ep_fun) && (NULL != g_ep_proc.ep_fun[fd])) + { + (void) g_ep_proc.ep_fun[fd] (epfd, fd, events); + return TRUE; + } + + return FALSE; +} + +/***************************************************************************** +* Prototype : nsfw_sock_add_to_ep +* Description : add all event process function has ben reg to the epoll + thread when thread start +* Input : i32 epfd +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_sock_add_to_ep (i32 epfd) +{ + u32 i; + + for (i = 0; i < NSFW_MGR_FD_MAX; i++) + { + if ((g_ep_proc.ep_fun) && (NULL == g_ep_proc.ep_fun[i])) + { + continue; + } + (void) nsfw_add_sock_to_ep (i); + } + + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_com_start +* Description : start mgr com module +* Input : None +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_mgr_com_start () +{ + i32 listern_fd = nsfw_mgr_get_listen_socket (); + if (listern_fd < 0) + { + NSFW_LOGERR ("get listern_fd failed!"); + return FALSE; + } + + NSFW_LOGINF ("start mgr_com module!] listern_fd=%d", listern_fd); + (void) nsfw_mgr_reg_sock_fun (listern_fd, nsfw_mgr_new_connection); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_com_start_local +* Description : start_local_msg_com +* Input : None +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_mgr_com_start_local (u8 proc_type) +{ + int fd[2]; + if ((socketpair (AF_UNIX, SOCK_STREAM, 0, fd)) < 0) + { + NSFW_LOGERR ("create socket err] type=%u,errno=%d", proc_type, errno); + return FALSE; + } + + (void) nsfw_mgr_new_socket (fd[0], proc_type, get_sys_pid ()); + (void) nsfw_mgr_new_socket (fd[1], proc_type, get_sys_pid ()); + (void) nsfw_mgr_reg_sock_fun (fd[0], nsfw_mgr_new_msg); + (void) nsfw_mgr_reg_sock_fun (fd[1], nsfw_mgr_new_msg); + NSFW_LOGINF ("create local socket] fd0=%d,fd1=%d", fd[0], fd[1]); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_listen_thread +* Description : epoll thread function +* Input : void* arg +* Output : None +* Return Value : void * +* Calls : +* Called By : +*****************************************************************************/ +void * +nsfw_mgr_listen_thread (void *arg) +{ + i32 epfd = 0; + //i32 listen_socket = 0; + + lint_lock_1 (); +#define MAXEVENTS 10 + epfd = nsfw_base_epoll_create (10); + + struct epoll_event events[MAXEVENTS]; + if (EOK != MEMSET_S (events, sizeof (events), 0, sizeof (events))) + { + NSFW_LOGERR ("MEMSET_S failed!]epfd=%d", epfd); + lint_unlock_1 (); + return NULL; + } + + g_ep_proc.epfd = epfd; + g_ep_proc.hbt_count = 0; + (void) nsfw_sock_add_to_ep (epfd); + lint_unlock_1 (); + while (1) + { + lint_lock_1 (); + int n, i; + n = nsfw_base_epoll_wait (epfd, events, MAXEVENTS, -1); + for (i = 0; i < n; i++) + { + if (TRUE == + nsfw_sock_fun_callback (epfd, events[i].data.fd, + events[i].events)) + { + g_ep_proc.hbt_count = 0; + continue; + } + + NSFW_LOGERR ("error event recv] fd=%d,event=%d", + events[i].data.fd, events[i].events); + } + lint_unlock_1 (); + } + +} + +NSTACK_STATIC inline void +get_thread_policy (pthread_attr_t * attr) +{ + int policy; + int rs = pthread_attr_getschedpolicy (attr, &policy); + if (rs != 0) + { + NSFW_LOGERR ("pthread_attr_getschedpolicy failed"); + return; + } + switch (policy) + { + case SCHED_FIFO: + NSFW_LOGINF ("policy= SCHED_FIFO"); + break; + case SCHED_RR: + NSFW_LOGINF ("policy= SCHED_RR"); + break; + case SCHED_OTHER: + NSFW_LOGINF ("policy=SCHED_OTHER"); + break; + default: + NSFW_LOGINF ("policy=UNKNOWN"); + break; + } + + return; +} + +NSTACK_STATIC inline void +get_thread_priority (pthread_attr_t * attr) +{ + struct sched_param param; + int rs = pthread_attr_getschedparam (attr, ¶m); + if (rs != 0) + { + NSFW_LOGERR ("pthread_attr_getschedparam failed"); + return; + } + + NSFW_LOGINF ("get thread priority] pri=%d", param.sched_priority); +} + +/* support thread priority configuration */ +void +set_thread_attr (pthread_attr_t * pattr, int stacksize, int pri, int policy) +{ + struct sched_param param; + (void) pthread_attr_init (pattr); + + if (stacksize > 0) + { + (void) pthread_attr_setstacksize (pattr, stacksize); + } + + param.sched_priority = pri; + if (SCHED_OTHER != policy) + { + (void) pthread_attr_setschedpolicy (pattr, policy); + (void) pthread_attr_setschedparam (pattr, ¶m); + (void) pthread_attr_setinheritsched (pattr, PTHREAD_EXPLICIT_SCHED); + } + get_thread_policy (pattr); + get_thread_priority (pattr); +} + +/***************************************************************************** +* Prototype : nsfw_mgr_ep_start +* Description : start epoll thread +* Input : None +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_mgr_ep_start () +{ + /* heart beat thread should have the same priority with the tcpip thread */ + pthread_attr_t attr; + pthread_attr_t *pattr = NULL; + + if (g_thread_policy != SCHED_OTHER) + { + set_thread_attr (&attr, 0, g_thread_pri, g_thread_policy); + pattr = &attr; + } + + if (pthread_create + (&g_ep_proc.ep_thread, pattr, nsfw_mgr_listen_thread, NULL)) + { + return FALSE; + } + + NSFW_LOGINF ("start thread] id=%d", g_ep_proc.ep_thread); + + if (pthread_setname_np (g_ep_proc.ep_thread, NSFW_MGRCOM_THREAD)) + { + return TRUE; + } + (void) nsfw_reg_trace_thread (g_ep_proc.ep_thread); + return TRUE; +} + +int +nsfw_mgr_com_chk_hbt (int v_add) +{ + int ret = g_ep_proc.hbt_count; + g_ep_proc.hbt_count += v_add; + return ret; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_comm_fd_destroy +* Description : free the memeory +* Input : +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +void +nsfw_mgr_comm_fd_destroy () +{ + if (g_ep_proc.ep_fun) + { + free (g_ep_proc.ep_fun); + g_ep_proc.ep_fun = NULL; + } + if (g_mgr_sockt_map.sock) + { + free (g_mgr_sockt_map.sock); + g_mgr_sockt_map.sock = NULL; + } + return; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_comm_fd_init +* Description : fd map and socket info init +* Input : u32 proc_type +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_mgr_comm_fd_init (u32 proc_type) +{ + /*only app need to do this */ + if ((g_mgr_sockt_map.sock) && (g_ep_proc.ep_fun)) + { + return 0; + } + if (NSFW_PROC_APP == proc_type) + { + long sysfdmax = 0; + sysfdmax = sysconf (_SC_OPEN_MAX); + NSFW_LOGINF ("] sys max open files=%d", sysfdmax); + if (sysfdmax > 0) + { + NSFW_MGR_FD_MAX = + (int) ((sysfdmax <= + NSFW_MGRCOM_MAX_SOCKET * + 60) ? sysfdmax : NSFW_MGRCOM_MAX_SOCKET * 60); + } + else + { + NSFW_LOGERR ("get sys max open file fail"); + NSFW_MGR_FD_MAX = NSFW_MGRCOM_MAX_SOCKET; + } + } + NSFW_LOGINF ("] final max fd=%d", NSFW_MGR_FD_MAX); + if (!g_mgr_sockt_map.sock) + { + g_mgr_sockt_map.sock = + (nsfw_mgr_sock_info *) malloc (sizeof (nsfw_mgr_sock_info) * + NSFW_MGR_FD_MAX); + if (NULL == g_mgr_sockt_map.sock) + { + NSFW_LOGERR ("malloc fail] length=%d", + sizeof (nsfw_mgr_sock_info) * NSFW_MGR_FD_MAX); + return -1; + } + (void) MEMSET_S (g_mgr_sockt_map.sock, + sizeof (nsfw_mgr_sock_info) * NSFW_MGR_FD_MAX, 0, + sizeof (nsfw_mgr_sock_info) * NSFW_MGR_FD_MAX); + } + if (!g_ep_proc.ep_fun) + { + g_ep_proc.ep_fun = + (nsfw_mgr_sock_fun *) malloc (sizeof (nsfw_mgr_sock_fun) * + NSFW_MGR_FD_MAX); + if (NULL == g_ep_proc.ep_fun) + { + NSFW_LOGERR ("malloc fail] length=%d ", + sizeof (nsfw_mgr_sock_fun) * NSFW_MGR_FD_MAX); + return -1; + } + (void) MEMSET_S (g_ep_proc.ep_fun, + sizeof (nsfw_mgr_sock_fun) * NSFW_MGR_FD_MAX, 0, + sizeof (nsfw_mgr_sock_fun) * NSFW_MGR_FD_MAX); + } + return 0; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_com_module_init +* Description : module init +* Input : void* param +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int nsfw_mgr_com_module_init (void *param); +int +nsfw_mgr_com_module_init (void *param) +{ + lint_lock_1 (); + u32 proc_type = (u32) ((long long) param); + nsfw_mgr_init_cfg *mgr_cfg = &g_mgr_com_cfg; + const char *directory = NSFW_DOMAIN_DIR; + const char *home_dir = getenv ("HOME"); + + NSFW_LOGINF ("module mgr init] type=%u", proc_type); + + if (getuid () != 0 && home_dir != NULL) + directory = home_dir; + + if (0 != nsfw_mgr_comm_fd_init (proc_type)) + { + NSFW_LOGERR ("fd init fail] proc_type=%u", proc_type); + lint_unlock_1 (); + return -1; + } + + switch (proc_type) + { + case NSFW_PROC_MAIN: + /* modify destMax, remove "-1" */ + if (EOK != + STRCPY_S (mgr_cfg->domain_path, NSFW_MGRCOM_PATH_LEN, directory)) + { + NSFW_LOGERR ("module mgr init STRCPY_S failed!"); + lint_unlock_1 (); + return -1; + } + + /* modify destMax, remove "-1" */ + if (EOK != + STRCAT_S (mgr_cfg->domain_path, NSFW_MGRCOM_PATH_LEN, + NSFW_MAIN_FILE)) + { + NSFW_LOGERR ("module mgr init STRCAT_S failed!"); + lint_unlock_1 (); + return -1; + } + + NSFW_LOGINF ("module mgr init]NSFW_PROC_MAIN domain_path=%s", + mgr_cfg->domain_path); + + if (TRUE != nsfw_mgr_com_start ()) + { + NSFW_LOGERR ("module mgr nsfw_mgr_com_start failed!"); + lint_unlock_1 (); + return -1; + } + + break; + case NSFW_PROC_MASTER: + /* modify destMax, remove "-1" */ + if (EOK != + STRCPY_S (mgr_cfg->domain_path, NSFW_MGRCOM_PATH_LEN, directory)) + { + NSFW_LOGERR ("module mgr init STRCPY_S failed!"); + lint_unlock_1 (); + return -1; + } + + /* modify destMax, remove "-1" */ + if (EOK != + STRCAT_S (mgr_cfg->domain_path, NSFW_MGRCOM_PATH_LEN, + NSFW_MASTER_FILE)) + { + NSFW_LOGERR ("module mgr init STRCAT_S failed!"); + lint_unlock_1 (); + return -1; + } + + NSFW_LOGINF ("module mgr init]NSFW_PROC_MASTER domain_path=%s", + mgr_cfg->domain_path); + + if (TRUE != nsfw_mgr_com_start ()) + { + NSFW_LOGERR ("module mgr nsfw_mgr_com_start failed!"); + lint_unlock_1 (); + return -1; + } + + break; + case NSFW_PROC_TOOLS: + break; + case NSFW_PROC_CTRL: + if (TRUE != nsfw_mgr_com_start_local (proc_type)) + { + NSFW_LOGERR ("module mgr nsfw_mgr_com_start_local failed!"); + lint_unlock_1 (); + return -1; + } + break; + default: + if (proc_type < NSFW_PROC_MAX) + { + break; + } + lint_unlock_1 (); + return -1; + } + + mgr_cfg->msg_size = MGR_COM_MSG_COUNT_DEF; + mgr_cfg->max_recv_timeout = MGR_COM_RECV_TIMEOUT_DEF; + mgr_cfg->max_recv_drop_msg = MGR_COM_MAX_DROP_MSG_DEF; + + mgr_cfg->proc_type = proc_type; + + nsfw_mem_sppool pmpinfo; + if (EOK != MEMSET_S (&pmpinfo, sizeof (pmpinfo), 0, sizeof (pmpinfo))) + { + NSFW_LOGERR ("Error to memset!!!"); + nsfw_mgr_comm_fd_destroy (); + lint_unlock_1 (); + return -1; + } + + pmpinfo.enmptype = NSFW_MRING_MPMC; + pmpinfo.usnum = mgr_cfg->msg_size; + pmpinfo.useltsize = sizeof (nsfw_mgr_msg); + pmpinfo.isocket_id = NSFW_SOCKET_ANY; + pmpinfo.stname.entype = NSFW_NSHMEM; + if (-1 == + SPRINTF_S (pmpinfo.stname.aname, sizeof (pmpinfo.stname.aname), "%s", + "MS_MGR_MSGPOOL")) + { + NSFW_LOGERR ("Error to SPRINTF_S!!!"); + nsfw_mgr_comm_fd_destroy (); + lint_unlock_1 (); + return -1; + } + + mgr_cfg->msg_pool = nsfw_mem_sp_create (&pmpinfo); + + if (!mgr_cfg->msg_pool) + { + NSFW_LOGERR ("module mgr init msg_pool alloc failed!"); + nsfw_mgr_comm_fd_destroy (); + lint_unlock_1 (); + return -1; + } + + (void) MEM_STAT (NSFW_MGR_COM_MODULE, pmpinfo.stname.aname, NSFW_NSHMEM, + nsfw_mem_get_len (mgr_cfg->msg_pool, NSFW_MEM_SPOOL)); + + if ((NSFW_PROC_TOOLS == proc_type) + || (NSFW_PROC_CTRL == proc_type) || (NSFW_PROC_MAIN == proc_type)) + { + if (TRUE != nsfw_mgr_ep_start ()) + { + NSFW_LOGERR ("module mgr nsfw_mgr_ep_start failed!"); + nsfw_mgr_comm_fd_destroy (); + lint_unlock_1 (); + return -1; + } + } + lint_unlock_1 (); + return 0; +} + +/***************************************************************************** +* Prototype : nsfw_mgr_run_script +* Description : run a linux shell script +* Input : const char *cmd, char *result, int result_buf_len +* Output : result length +* Return Value : int +* Calls : +* Called By : + *****************************************************************************/ +int +nsfw_mgr_run_script (const char *cmd, char *result, int result_buf_len) +{ + if (!cmd || !result || result_buf_len <= 1) + { + return -1; + } + + FILE *fp = popen (cmd, "r"); + if (fp != NULL) + { + size_t n = fread (result, sizeof (char), result_buf_len - 1, fp); + if (n == 0) + { + result[0] = '\0'; + } + else if ('\n' == result[n - 1]) + { + result[n - 1] = '\0'; + } + else + { + result[n] = '\0'; + } + + pclose (fp); + return n; + } + + return -1; +} + +/* *INDENT-OFF* */ +NSFW_MODULE_NAME(NSFW_MGR_COM_MODULE) +NSFW_MODULE_PRIORITY(10) +NSFW_MODULE_DEPENDS(NSFW_MEM_MGR_MODULE) +NSFW_MODULE_INIT(nsfw_mgr_com_module_init) +/* *INDENT-ON* */ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/framework/ipc/mgr_com/mgr_com.h b/src/framework/ipc/mgr_com/mgr_com.h new file mode 100644 index 0000000..c4333a1 --- /dev/null +++ b/src/framework/ipc/mgr_com/mgr_com.h @@ -0,0 +1,150 @@ +/* +* +* 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. +*/ + +/***************************************************************************** +* Prototype : ifndef _NSFW_MGRCOM_MODULE_H +* Description : mgr com module definition +* Input : None +* Output : None +* Return Value : # +* Calls : +* Called By : + *****************************************************************************/ +#ifndef _NSFW_MGRCOM_MODULE_H +#define _NSFW_MGRCOM_MODULE_H + +#include "pthread.h" +#include "nsfw_mem_api.h" +#include "common_mem_api.h" + +#include "common_func.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#define NSFW_MGRCOM_PATH_LEN 128 +#define NSFW_MGRCOM_MAX_SOCKET 1024 +#define NSFW_MGRCOM_MAX_PROC_FUN 8 + +#define MAX_RECV_BUF_DEF 0x34000*2 + +#define MGR_COM_MSG_COUNT_DEF 1023 /*g_mgr_com_cfg */ +#define MGR_COM_RECV_TIMEOUT_DEF 5 +#define MGR_COM_MAX_DROP_MSG_DEF 1024 + +#define MGR_COM_MSG_COUNT (g_mgr_com_cfg.msg_size) +#define MGR_COM_RECV_TIMEOUT (g_mgr_com_cfg.max_recv_timeout) +#define MGR_COM_MAX_DROP_MSG (g_mgr_com_cfg.max_recv_drop_msg) + +#define NSFW_MAIN_FILE "/ip_module/nStackMainMgr" +#define NSFW_MASTER_FILE "/ip_module/nStackMasterMgr" +#define NSFW_ALARM_FILE "/HuskyAlarm.domain" + +#define NSFW_MGRCOM_THREAD "nStackMgrCom" + +typedef struct _nsfw_mgr_init_cfg +{ + u8 proc_type; /*fw_poc_type */ + u8 max_recv_timeout; + u16 max_recv_drop_msg; + u32 msg_size; + common_mem_atomic32_t cur_idx; + u64 u64reserve; + mring_handle msg_pool; + char domain_path[NSFW_MGRCOM_PATH_LEN]; +} nsfw_mgr_init_cfg; + +typedef struct _nsfw_mgrcom_stat +{ + u64 msg_send[MGR_MSG_MAX]; + u64 msg_recv[MGR_MSG_MAX]; + u64 recv_drop[MGR_MSG_MAX]; + u64 msg_alloc; + u64 msg_free; + u64 msg_send_failed; + u64 reconnect_count; +} nsfw_mgrcom_stat; + +typedef struct _nsfw_mgr_sock_info +{ + u8 proc_type; /*_ns_poc_type*/ + u32 host_pid; + common_mem_spinlock_t opr_lock; +} nsfw_mgr_sock_info; + +typedef struct _nsfw_mgr_sock_map +{ + i32 proc_cache[NSFW_PROC_MAX]; + nsfw_mgr_sock_info *sock; +} nsfw_mgr_sock_map; + +#define NSFW_SOCK_MAX_PROC_FUN 4 + +typedef struct _nsfw_mgrcom_proc_fun +{ + i32 fd; + nsfw_mgr_sock_fun fun; +} nsfw_mgrcom_proc_fun; + +typedef struct _nsfw_mgrcom_proc +{ + i32 epfd; + u32 hbt_count; + pthread_t ep_thread; + nsfw_mgr_sock_fun *ep_fun; +} nsfw_mgrcom_proc; + +i32 nsfw_set_sock_block (i32 sock, u8 flag); + +u8 nsfw_rmv_sock_from_ep (i32 fd); +u8 nsfw_add_sock_to_ep (i32 fd); + +int nsfw_mgr_new_msg (i32 epfd, i32 socket, u32 events); + +u8 nsfw_mgr_ep_start (); +u8 nsfw_mgr_stop (); + +#define LOCK_MGR_FD(_fd){\ + if ((i32)NSFW_MGR_FD_MAX > _fd)\ + {\ + common_mem_spinlock_lock(&g_mgr_sockt_map.sock[_fd].opr_lock);\ + }\ +} + +#define UNLOCK_MGR_FD(_fd){\ + if ((i32)NSFW_MGR_FD_MAX > _fd)\ + {\ + common_mem_spinlock_unlock(&g_mgr_sockt_map.sock[_fd].opr_lock);\ + }\ +} + +#define NSFW_MGR_FD_MAX g_mgr_sockfdmax + +extern void set_thread_attr (pthread_attr_t * pattr, int stacksize, int pri, + int policy); + +extern void nsfw_com_attr_set (int policy, int pri); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#endif /* _NSFW_MGRCOM_MODULE_H */ diff --git a/src/framework/ipc/ps/nsfw_fd_timer.c b/src/framework/ipc/ps/nsfw_fd_timer.c new file mode 100644 index 0000000..57535a3 --- /dev/null +++ b/src/framework/ipc/ps/nsfw_fd_timer.c @@ -0,0 +1,378 @@ +/* +* +* 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 +#include +#include + +#include "types.h" +#include "list.h" + +#include "nstack_securec.h" +#include "nsfw_init.h" +#include "nsfw_mgr_com_api.h" +#include "nsfw_mem_api.h" +#include "nstack_log.h" +#include "nsfw_base_linux_api.h" +#include "nsfw_fd_timer_api.h" +#include "nsfw_maintain_api.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#define NSFW_TIMER_CYCLE 1 +#define NSFW_TIMER_INFO_MAX_COUNT_DEF 8191 +#define NSFW_TIMER_INFO_MAX_COUNT (g_timer_cfg.timer_info_size) +/* *INDENT-OFF* */ +nsfw_timer_init_cfg g_timer_cfg; + +u8 g_hbt_switch = FALSE; +/* *INDENT-ON* */ + +/***************************************************************************** +* Prototype : nsfw_timer_reg_timer +* Description : reg timer with callback function when timeout +* Input : u32 timer_type +* void* data +* nsfw_timer_proc_fun fun +* struct timespec time_left +* Output : None +* Return Value : nsfw_timer_info* +* Calls : +* Called By : +* +*****************************************************************************/ +nsfw_timer_info * +nsfw_timer_reg_timer (u32 timer_type, void *data, + nsfw_timer_proc_fun fun, struct timespec time_left) +{ + nsfw_timer_info *tm_info = NULL; + if (0 == + nsfw_mem_ring_dequeue (g_timer_cfg.timer_info_pool, (void *) &tm_info)) + { + NSFW_LOGERR ("dequeue error]data=%p,fun=%p", data, fun); + return NULL; + } + + if (EOK != MEMSET_S (tm_info, sizeof (*tm_info), 0, sizeof (*tm_info))) + { + if (0 == nsfw_mem_ring_enqueue (g_timer_cfg.timer_info_pool, tm_info)) + { + NSFW_LOGERR ("enqueue error]data=%p,fun=%p", data, fun); + } + NSFW_LOGERR ("mem set error]data=%p,fun=%p", data, fun); + return NULL; + } + + tm_info->fun = fun; + tm_info->argv = data; + tm_info->time_left = time_left; + //tm_info->time_left.tv_sec += NSFW_TIMER_CYCLE; + tm_info->timer_type = timer_type; + list_add_tail (&tm_info->node, &g_timer_cfg.timer_head); + tm_info->alloc_flag = TRUE; + return tm_info; +} + +/***************************************************************************** +* Prototype : nsfw_timer_rmv_timer +* Description : stop timer +* Input : nsfw_timer_info* tm_info +* Output : None +* Return Value : void +* Calls : +* Called By : +* +*****************************************************************************/ +void +nsfw_timer_rmv_timer (nsfw_timer_info * tm_info) +{ + if (NULL == tm_info) + { + NSFW_LOGWAR ("tm_info nul"); + return; + } + + if (FALSE == tm_info->alloc_flag) + { + NSFW_LOGERR ("tm_info refree]tm_info=%p,argv=%p,fun=%p", tm_info, + tm_info->argv, tm_info->fun); + return; + } + + tm_info->alloc_flag = FALSE; + list_del (&tm_info->node); + if (0 == nsfw_mem_ring_enqueue (g_timer_cfg.timer_info_pool, tm_info)) + { + NSFW_LOGERR ("tm_info free failed]tm_info=%p,argv=%p,fun=%p", tm_info, + tm_info->argv, tm_info->fun); + } + return; +} + +/***************************************************************************** +* Prototype : nsfw_timer_exp +* Description : timer expire +* Input : u64 count +* Output : None +* Return Value : u8 +* Calls : +* Called By : +* +*****************************************************************************/ +void +nsfw_timer_exp (u64 count) +{ + nsfw_timer_info *tm_info = NULL; + struct list_head *tNode; + struct list_head *tPretNode; + + LINT_LIST ()list_for_each_entry (tm_info, tNode, (&g_timer_cfg.timer_head), + node) + { + tPretNode = tm_info->node.prev; + if (tm_info->time_left.tv_sec > (long) count * NSFW_TIMER_CYCLE) + { + tm_info->time_left.tv_sec -= count * NSFW_TIMER_CYCLE; + continue; + } + + list_del (&tm_info->node); + list_add_tail (&tm_info->node, &g_timer_cfg.exp_timer_head); + tNode = tPretNode; + } + + u32 i = 0; + while (!list_empty (&g_timer_cfg.exp_timer_head) + && i++ < NSFW_TIMER_INFO_MAX_COUNT) + { + tm_info = + (nsfw_timer_info *) list_get_first (&g_timer_cfg.exp_timer_head); + if (NULL != tm_info->fun) + { + (void) tm_info->fun (tm_info->timer_type, tm_info->argv); + } + nsfw_timer_rmv_timer (tm_info); + } + +} + +/***************************************************************************** +* Prototype : nsfw_get_timer_socket +* Description : get timer socket from kernel +* Input : None +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_get_timer_socket () +{ + i32 tfd = timerfd_create (CLOCK_MONOTONIC, TFD_NONBLOCK); + if (tfd == -1) + { + NSFW_LOGERR ("timerfd_create failed!]errno=%d\n", errno); + return -1; + } + + /* close on exe */ + if (-1 == nsfw_set_close_on_exec (tfd)) + { + (void) nsfw_base_close (tfd); + NSFW_LOGERR ("set exec err]fd=%d, errno=%d", tfd, errno); + return -1; + } + + struct itimerspec ts; + ts.it_interval.tv_sec = NSFW_TIMER_CYCLE; + ts.it_interval.tv_nsec = 0; + ts.it_value.tv_sec = 0; + ts.it_value.tv_nsec = NSFW_TIMER_CYCLE; + + if (timerfd_settime (tfd, 0, &ts, NULL) < 0) + { + NSFW_LOGERR ("timerfd_settime failed] errno=%d", errno); + close (tfd); + return -1; + } + + return tfd; +} + +/***************************************************************************** +* Prototype : nsfw_timer_notify_fun +* Description : receive timer event from kernel +* Input : i32 epfd +* i32 fd +* u32 events +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_timer_notify_fun (i32 epfd, i32 fd, u32 events) +{ + i32 rc; + + if ((events & EPOLLERR) || (events & EPOLLHUP) || (!(events & EPOLLIN))) + { + (void) nsfw_base_close (fd); + NSFW_LOGWAR ("timer disconnect!]epfd=%d,timer=%d,event=0x%x", epfd, + fd, events); + + (void) nsfw_mgr_unreg_sock_fun (fd); + i32 timer_fd = nsfw_get_timer_socket (); + if (timer_fd < 0) + { + NSFW_LOGERR ("get timer_fd faied!]epfd=%d,timer_fd=%d,event=0x%x", + epfd, fd, events); + return FALSE; + } + + (void) nsfw_mgr_reg_sock_fun (timer_fd, nsfw_timer_notify_fun); + return TRUE; + } + + u64 data; + while (1) + { + rc = nsfw_base_read (fd, &data, sizeof (data)); + if (rc == 0) + { + NSFW_LOGERR ("timer_fd recv 0]timer_fd=%d,errno=%d", fd, errno); + break; + } + else if (rc == -1) + { + if (errno == EINTR || errno == EAGAIN) + { + break; + } + NSMON_LOGERR ("timer_fd recv]timer_fd=%d,errno=%d", fd, errno); + break; + } + + nsfw_timer_exp (data); + } + + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_timer_start +* Description : reg the timer module to epoll thread +* Input : None +* Output : None +* Return Value : u8 +* Calls : +* Called By : +* +*****************************************************************************/ +u8 +nsfw_timer_start () +{ + i32 timer_fd = nsfw_get_timer_socket (); + if (timer_fd < 0) + { + NSFW_LOGERR ("get timer_fd failed!"); + return FALSE; + } + + NSFW_LOGINF ("start timer_fd module!]timer_fd=%d", timer_fd); + (void) nsfw_mgr_reg_sock_fun (timer_fd, nsfw_timer_notify_fun); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_timer_module_init +* Description : module init +* Input : void* param +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int +nsfw_timer_module_init (void *param) +{ + u32 proc_type = (u32) ((long long) param); + nsfw_timer_init_cfg *timer_cfg = &g_timer_cfg; + NSFW_LOGINF ("ps module init]type=%u", proc_type); + switch (proc_type) + { + case NSFW_PROC_MASTER: + case NSFW_PROC_MAIN: + (void) NSFW_REG_SOFT_INT (NSFW_DBG_MODE_PARAM, g_hbt_switch, 0, 1); + break; + case NSFW_PROC_TOOLS: + case NSFW_PROC_CTRL: + break; + default: + return 0; + } + + timer_cfg->timer_info_size = NSFW_TIMER_INFO_MAX_COUNT_DEF; + + nsfw_mem_sppool pmpinfo; + pmpinfo.enmptype = NSFW_MRING_MPMC; + pmpinfo.usnum = timer_cfg->timer_info_size; + pmpinfo.useltsize = sizeof (nsfw_timer_info); + pmpinfo.isocket_id = NSFW_SOCKET_ANY; + pmpinfo.stname.entype = NSFW_NSHMEM; + if (-1 == + SPRINTF_S (pmpinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s", + "MS_TM_INFOPOOL")) + { + NSFW_LOGERR ("SPRINTF_S failed"); + return -1; + } + timer_cfg->timer_info_pool = nsfw_mem_sp_create (&pmpinfo); + + if (!timer_cfg->timer_info_pool) + { + NSFW_LOGERR ("alloc timer info pool_err"); + return -1; + } + + MEM_STAT (NSFW_TIMER_MODULE, pmpinfo.stname.aname, NSFW_NSHMEM, + nsfw_mem_get_len (timer_cfg->timer_info_pool, NSFW_MEM_SPOOL)); + + INIT_LIST_HEAD (&(timer_cfg->timer_head)); + INIT_LIST_HEAD (&(timer_cfg->exp_timer_head)); + + (void) nsfw_timer_start (); + return 0; +} + +/* *INDENT-OFF* */ +NSFW_MODULE_NAME (NSFW_TIMER_MODULE) +NSFW_MODULE_PRIORITY (10) +NSFW_MODULE_DEPENDS (NSFW_MGR_COM_MODULE) +NSFW_MODULE_INIT (nsfw_timer_module_init) +/* *INDENT-ON* */ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/framework/ipc/ps/nsfw_ps_mem_module.c b/src/framework/ipc/ps/nsfw_ps_mem_module.c new file mode 100644 index 0000000..9cda6b3 --- /dev/null +++ b/src/framework/ipc/ps/nsfw_ps_mem_module.c @@ -0,0 +1,924 @@ +/* +* +* 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 "types.h" +#include "nstack_securec.h" +#include "nsfw_init.h" + +#include "nsfw_ps_module.h" +#include "nsfw_mgr_com_api.h" +#include "nsfw_ps_mem_api.h" +#include "nsfw_ps_mem_module.h" +#include "nsfw_ps_api.h" +#include "nsfw_maintain_api.h" +#include "nsfw_fd_timer_api.h" + +#include "nstack_log.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +ns_mem_mng_init_cfg g_mem_cfg; + +int mem_ps_exiting (void *pps_info, void *argv); + +int +nsfw_mem_ps_exit_resend_timeout (u32 timer_type, void *data) +{ + nsfw_ps_info *ps_info = data; + if (NULL == ps_info) + { + NSFW_LOGERR ("ps_info nul!"); + return FALSE; + } + + if (NSFW_PROC_APP != ps_info->proc_type) + { + return FALSE; + } + + if (NSFW_PS_EXITING != ps_info->state) + { + return FALSE; + } + + ps_info->resend_timer_ptr = NULL; + (void) mem_ps_exiting (ps_info, NULL); + return TRUE; +} + +/***************************************************************************** +* Prototype : mem_ps_exiting +* Description : send exiting message when ps_info exiting +* Input : void *pps_info +* void* argv +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +mem_ps_exiting (void *pps_info, void *argv) +{ + if (NULL == pps_info) + { + NSFW_LOGERR ("ps_info nul!"); + return FALSE; + } + + if (TRUE == NSFW_SRV_STATE_SUSPEND) + { + NSFW_LOGERR ("main suspend]ps_info=%d,pid=%u", pps_info, + ((nsfw_ps_info *) pps_info)->host_pid); + return FALSE; + } + + nsfw_mgr_msg *msg = + nsfw_mgr_msg_alloc (MGR_MSG_APP_EXIT_REQ, NSFW_PROC_MAIN); + if (NULL == msg) + { + NSFW_LOGERR ("ps_exit alloc msg failed]ps_info=%p,pid=%u", pps_info, + ((nsfw_ps_info *) pps_info)->host_pid); + return FALSE; + } + + nsfw_ps_info_msg *ps_msg = GET_USER_MSG (nsfw_ps_info_msg, msg); + ps_msg->host_pid = ((nsfw_ps_info *) pps_info)->host_pid; + + (void) nsfw_mgr_send_msg (msg); + NSFW_LOGINF ("ps_exiting send msg]ps_info=%p,pid=%u", pps_info, + ps_msg->host_pid); + nsfw_mgr_msg_free (msg); + return TRUE; +} + +/***************************************************************************** +* Prototype : mem_alloc_ps_info +* Description : alloc ps_info +* Input : u32 pid +* u8 proc_type +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +mem_alloc_ps_info (u32 pid, u8 proc_type) +{ + nsfw_ps_info *pps_info = NULL; + pps_info = nsfw_ps_info_get (pid); + if (NULL != pps_info) + { + return TRUE; + } + + pps_info = nsfw_ps_info_alloc (pid, proc_type); + if (NULL == pps_info) + { + NSFW_LOGERR ("alloc ps_info falied!]pid=%u,proc_type=%u", pid, + proc_type); + return FALSE; + } + + NSFW_LOGINF ("alloc new ps_info]pps_info=%p,pid=%u", pps_info, pid); + return TRUE; +} + +/*mem alloc by msg begin*/ +void * +mem_item_zone_create (void *mem_info) +{ + return (void *) nsfw_mem_zone_create ((nsfw_mem_zone *) mem_info); +} + +void * +mem_item_mbfmp_create (void *mem_info) +{ + return (void *) nsfw_mem_mbfmp_create ((nsfw_mem_mbfpool *) mem_info); +} + +void * +mem_item_sp_create (void *mem_info) +{ + return (void *) nsfw_mem_sp_create ((nsfw_mem_sppool *) mem_info); +} + +void * +mem_item_ring_create (void *mem_info) +{ + return (void *) nsfw_mem_ring_create ((nsfw_mem_mring *) mem_info); +} + +nsfw_ps_mem_item_cfg g_ps_mem_map[] = { + { + NSFW_RESERV_REQ_MSG, + sizeof (nsfw_shmem_reserv_req), + NSFW_MEM_MZONE, + mem_item_zone_create, + mem_item_get_callargv} + , + + { + NSFW_MBUF_REQ_MSG, + sizeof (nsfw_shmem_mbuf_req), + NSFW_MEM_MBUF, + mem_item_mbfmp_create, + mem_item_get_callargv} + , + { + NSFW_SPPOOL_REQ_MSG, + sizeof (nsfw_shmem_sppool_req), + NSFW_MEM_SPOOL, + mem_item_sp_create, + mem_item_get_callargv} + , + { + NSFW_RING_REQ_MSG, + sizeof (nsfw_shmem_ring_req), + NSFW_MEM_RING, + mem_item_ring_create, + mem_item_get_callargv} + , + { + NSFW_RELEASE_REQ_MSG, + sizeof (nsfw_shmem_free_req), + 0xFFFF, + mem_item_free, + mem_item_get_callargv, + } + , + { + NSFW_MEM_LOOKUP_REQ_MSG, + sizeof (nsfw_shmem_lookup_req), + 0xFFFF, + mem_item_lookup, + mem_item_get_callargv, + } +}; + +/***************************************************************************** +* Prototype : mem_item_get_cfg_from_msg +* Description : get memory config +* Input : u16 msg_type +* Output : None +* Return Value : nsfw_ps_mem_item_cfg * +* Calls : +* Called By : +*****************************************************************************/ +nsfw_ps_mem_item_cfg * +mem_item_get_cfg_from_msg (u16 msg_type) +{ + int idx; + int map_count = sizeof (g_ps_mem_map) / sizeof (nsfw_ps_mem_item_cfg); + for (idx = 0; idx < map_count; idx++) + { + if (g_ps_mem_map[idx].usmsg_type == msg_type) + { + return &g_ps_mem_map[idx]; + } + } + + return NULL; +} + +/***************************************************************************** +* Prototype : mem_item_get_callargv +* Description : change the message value to structur value +* Input : u16 msg_type +* char* msg_body +* char *memstr_buf +* i32 buf_len +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +mem_item_get_callargv (u16 msg_type, char *msg_body, char *memstr_buf, + i32 buf_len) +{ + switch (msg_type) + { + case NSFW_RESERV_REQ_MSG: + MEM_GET_CALLARGV (lenth, lenth, nsfw_mem_zone, nsfw_shmem_reserv_req, + memstr_buf, msg_body); + MEM_GET_CALLARGV (isocket_id, isocket_id, nsfw_mem_zone, + nsfw_shmem_reserv_req, memstr_buf, msg_body); + break; + case NSFW_MBUF_REQ_MSG: + MEM_GET_CALLARGV (usnum, usnum, nsfw_mem_mbfpool, nsfw_shmem_mbuf_req, + memstr_buf, msg_body); + MEM_GET_CALLARGV (uscash_size, uscash_size, nsfw_mem_mbfpool, + nsfw_shmem_mbuf_req, memstr_buf, msg_body); + MEM_GET_CALLARGV (uspriv_size, uspriv_size, nsfw_mem_mbfpool, + nsfw_shmem_mbuf_req, memstr_buf, msg_body); + MEM_GET_CALLARGV (usdata_room, usdata_room, nsfw_mem_mbfpool, + nsfw_shmem_mbuf_req, memstr_buf, msg_body); + MEM_GET_CALLARGV (enmptype, enmptype, nsfw_mem_mbfpool, + nsfw_shmem_mbuf_req, memstr_buf, msg_body); + MEM_GET_CALLARGV (isocket_id, isocket_id, nsfw_mem_mbfpool, + nsfw_shmem_mbuf_req, memstr_buf, msg_body); + break; + case NSFW_SPPOOL_REQ_MSG: + MEM_GET_CALLARGV (usnum, usnum, nsfw_mem_sppool, + nsfw_shmem_sppool_req, memstr_buf, msg_body); + MEM_GET_CALLARGV (useltsize, useltsize, nsfw_mem_sppool, + nsfw_shmem_sppool_req, memstr_buf, msg_body); + MEM_GET_CALLARGV (enmptype, enmptype, nsfw_mem_sppool, + nsfw_shmem_sppool_req, memstr_buf, msg_body); + MEM_GET_CALLARGV (isocket_id, isocket_id, nsfw_mem_sppool, + nsfw_shmem_sppool_req, memstr_buf, msg_body); + break; + case NSFW_RING_REQ_MSG: + MEM_GET_CALLARGV (usnum, usnum, nsfw_mem_mring, nsfw_shmem_ring_req, + memstr_buf, msg_body); + MEM_GET_CALLARGV (enmptype, enmptype, nsfw_mem_mring, + nsfw_shmem_ring_req, memstr_buf, msg_body); + MEM_GET_CALLARGV (isocket_id, isocket_id, nsfw_mem_mring, + nsfw_shmem_ring_req, memstr_buf, msg_body); + break; + case NSFW_RELEASE_REQ_MSG: + MEM_GET_CALLARGV (ustype, ustype, nsfw_mem_type_info, + nsfw_shmem_free_req, memstr_buf, msg_body); + break; + case NSFW_MEM_LOOKUP_REQ_MSG: + MEM_GET_CALLARGV (ustype, ustype, nsfw_mem_type_info, + nsfw_shmem_lookup_req, memstr_buf, msg_body); + break; + default: + NSFW_LOGERR ("error msg]type=%u", msg_type); + return FALSE; + } + if (EOK != + STRCPY_S (((nsfw_mem_zone *) memstr_buf)->stname.aname, + NSFW_MEM_NAME_LENTH, + ((nsfw_shmem_reserv_req *) msg_body)->aname)) + { + NSFW_LOGERR ("STRCPY_S failed]msg_type=%u", msg_type); + return FALSE; + } + + ((nsfw_mem_zone *) memstr_buf)->stname.entype = NSFW_SHMEM; + + return TRUE; +} + +/***************************************************************************** +* Prototype : mem_item_free +* Description : free memory item +* Input : void *pdata +* Output : None +* Return Value : void* +* Calls : +* Called By : +*****************************************************************************/ +void * +mem_item_free (void *pdata) +{ + nsfw_mem_type_info *mem_free = (nsfw_mem_type_info *) pdata; + i32 ret; + NSFW_LOGINF ("free mem]type=%u,name=%s", mem_free->ustype, + mem_free->stname.aname); + switch (mem_free->ustype) + { + case NSFW_MEM_MZONE: + ret = nsfw_mem_zone_release (&mem_free->stname); + break; + case NSFW_MEM_MBUF: + ret = nsfw_mem_mbfmp_release (&mem_free->stname); + break; + case NSFW_MEM_SPOOL: + ret = nsfw_mem_sp_release (&mem_free->stname); + break; + case NSFW_MEM_RING: + ret = nsfw_mem_ring_release (&mem_free->stname); + break; + default: + NSFW_LOGERR ("free mem err type]type=%u", mem_free->ustype); + return NULL; + } + + if (NSFW_MEM_OK != ret) + { + NSFW_LOGERR ("mem free failed!]ret=%d", ret); + return NULL; + } + + return pdata; +} + +/***************************************************************************** +* Prototype : mem_item_lookup +* Description : lookup memory item +* Input : void *pdata +* Output : None +* Return Value : void* +* Calls : +* Called By : +*****************************************************************************/ +void * +mem_item_lookup (void *pdata) +{ + nsfw_mem_type_info *mem_lookup = (nsfw_mem_type_info *) pdata; + void *ret; + NSFW_LOGDBG ("lookup mem]type=%u,name=%s", mem_lookup->ustype, + mem_lookup->stname.aname); + switch (mem_lookup->ustype) + { + case NSFW_MEM_MZONE: + ret = nsfw_mem_zone_lookup (&mem_lookup->stname); + break; + case NSFW_MEM_MBUF: + ret = nsfw_mem_mbfmp_lookup (&mem_lookup->stname); + break; + case NSFW_MEM_SPOOL: + ret = nsfw_mem_sp_lookup (&mem_lookup->stname); + break; + case NSFW_MEM_RING: + ret = nsfw_mem_ring_lookup (&mem_lookup->stname); + break; + default: + NSFW_LOGERR ("lookup mem err type]type=%d", mem_lookup->ustype); + return NULL; + } + + if (NULL == ret) + { + NSFW_LOGERR ("mem lookup failed!]ret=%p,name=%s", ret, + mem_lookup->stname.aname); + return NULL; + } + + return ret; +} + +/***************************************************************************** +* Prototype : mem_item_proc_by_msg +* Description : call memory item process function +* Input : void *pdata +* nsfw_ps_mem_item_cfg* item_cfg +* Output : None +* Return Value : void* +* Calls : +* Called By : +*****************************************************************************/ +void * +mem_item_proc_by_msg (void *pdata, nsfw_ps_mem_item_cfg * item_cfg) +{ + char argv_buf[NSFW_MEM_CALL_ARG_BUF] = { 0 }; + + if ((NULL == item_cfg->change_fun) || (NULL == item_cfg->create_fun)) + { + NSFW_LOGERR ("item error]change_fun=%p,create_fun=%p", + item_cfg->change_fun, item_cfg->create_fun); + return NULL; + } + + if (FALSE == + item_cfg->change_fun (item_cfg->usmsg_type, pdata, argv_buf, + NSFW_MEM_CALL_ARG_BUF)) + { + NSFW_LOGERR ("call change_fun failed!]type=%u", item_cfg->usmsg_type); + return NULL; + } + + void *pdataret = NULL; + pdataret = (item_cfg->create_fun) ((void *) argv_buf); + return pdataret; +} + +/***************************************************************************** +* Prototype : mem_init_rsp_msg +* Description : init the rsp message +* Input : nsfw_shmem_msg_head* msg +* nsfw_shmem_msg_head *rsp +* Output : None +* Return Value : u8 +* Calls : +* Called By : +* +*****************************************************************************/ +u8 +mem_init_rsp_msg (nsfw_shmem_msg_head * msg, nsfw_shmem_msg_head * rsp) +{ + nsfw_ps_mem_item_cfg *item_cfg = + mem_item_get_cfg_from_msg (msg->usmsg_type); + if (NULL == item_cfg) + { + NSFW_LOGERR ("get item cfg failed!]msg_type=%u", msg->usmsg_type); + return FALSE; + } + + int idx; + int mem_count = msg->uslenth / item_cfg->item_size; + + rsp->usmsg_type = msg->usmsg_type + 1; + rsp->uslenth = mem_count * sizeof (nsfw_shmem_ack); + nsfw_shmem_ack *pack = (nsfw_shmem_ack *) & (rsp->aidata[0]); + char *pdata = NULL; + for (idx = 0; idx < mem_count; idx++) + { + pdata = (char *) msg->aidata + idx * item_cfg->item_size; + pack->pbase_addr = NULL; + pack->usseq = ((nsfw_shmem_reserv_req *) pdata)->usseq; + pack->cstate = NSFW_MEM_ALLOC_FAIL; + pack++; + } + + NSFW_LOGDBG ("init all rsp ack]mem_count=%d,msg_type=%u", mem_count, + msg->usmsg_type); + return TRUE; +} + +/***************************************************************************** +* Prototype : mem_rel_mem_by_msg +* Description : release memory by message +* Input : nsfw_shmem_msg_head* req_msg +* nsfw_shmem_msg_head *rsp +* u32 pid +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +mem_rel_mem_by_msg (nsfw_shmem_msg_head * req_msg, + nsfw_shmem_msg_head * rsp, u32 pid) +{ + u32 i; + nsfw_ps_mem_item_cfg *item_cfg = + mem_item_get_cfg_from_msg (req_msg->usmsg_type); + if (NULL == item_cfg) + { + NSFW_LOGERR ("get item cfg failed!]msg_type=%u", req_msg->usmsg_type); + return FALSE; + } + + unsigned int mem_count = req_msg->uslenth / item_cfg->item_size; + char *pdata = NULL; + nsfw_shmem_ack *pack = (nsfw_shmem_ack *) & (rsp->aidata[0]); + for (i = 0; i < mem_count; i++) + { + pdata = (char *) req_msg->aidata + i * item_cfg->item_size; + if (NULL != mem_item_proc_by_msg ((void *) pdata, item_cfg)) + { + pack->cstate = NSFW_MEM_ALLOC_SUCC; + pack->pbase_addr = NULL; + } + pack++; + } + + return TRUE; +} + +/***************************************************************************** +* Prototype : mem_lookup_mem_by_msg +* Description : lookup memory by message +* Input : nsfw_shmem_msg_head* mgr_msg +* nsfw_shmem_msg_head *rsp +* u32 pid +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +mem_lookup_mem_by_msg (nsfw_shmem_msg_head * mgr_msg, + nsfw_shmem_msg_head * rsp, u32 pid) +{ + i32 idx; + nsfw_ps_mem_item_cfg *item_cfg = + mem_item_get_cfg_from_msg (mgr_msg->usmsg_type); + if (NULL == item_cfg) + { + NSFW_LOGERR ("get item cfg failed!]msg_type=%u", mgr_msg->usmsg_type); + return FALSE; + } + + int mem_count = mgr_msg->uslenth / item_cfg->item_size; + char *pdata = NULL; + void *paddr = NULL; + nsfw_shmem_ack *pack = (nsfw_shmem_ack *) & (rsp->aidata[0]); + + for (idx = 0; idx < mem_count; idx++) + { + pdata = (char *) mgr_msg->aidata + idx * item_cfg->item_size; + paddr = mem_item_proc_by_msg ((void *) pdata, item_cfg); + if (NULL != paddr) + { + pack->cstate = NSFW_MEM_ALLOC_SUCC; + pack->pbase_addr = paddr; + } + pack++; + } + + return TRUE; +} + +/***************************************************************************** +* Prototype : mem_alloc_mem_by_msg +* Description : alloc memory by message +* Input : nsfw_shmem_msg_head* mem_msg +* nsfw_shmem_msg_head *rsp +* Output : None +* Return Value : ns_mem_info* +* Calls : +* Called By : +*****************************************************************************/ +void * +mem_alloc_mem_by_msg (nsfw_shmem_msg_head * mem_msg, + nsfw_shmem_msg_head * rsp) +{ + nsfw_ps_mem_item_cfg *item_cfg = + mem_item_get_cfg_from_msg (mem_msg->usmsg_type); + if (NULL == item_cfg) + { + NSFW_LOGERR ("get item cfg failed!]msg_type=%u", mem_msg->usmsg_type); + return NULL; + } + + int i; + int j; + nsfw_mem_type_info mem_free; + char *pdata = NULL; + void *p_addr = NULL; + + int mem_count = mem_msg->uslenth / item_cfg->item_size; + nsfw_shmem_ack *pack = (nsfw_shmem_ack *) & (rsp->aidata[0]); + for (i = 0; i < mem_count; i++) + { + pdata = (char *) mem_msg->aidata + i * item_cfg->item_size; + p_addr = mem_item_proc_by_msg ((void *) pdata, item_cfg); + if (NULL == p_addr) + { + NSFW_LOGERR + ("alloc mem failed!]type=%u,mem_count=%d,item=%d,name=%s", + mem_msg->usmsg_type, mem_count, i, + ((nsfw_shmem_reserv_req *) pdata)->aname); + goto fail_free_mem; + } + + pack->cstate = NSFW_MEM_ALLOC_SUCC; + pack->pbase_addr = p_addr; + NSFW_LOGINF + ("alloc mem suc!]addr=%p,type=%u,mem_count=%d,item=%d,name=%s", + p_addr, mem_msg->usmsg_type, mem_count, i, + ((nsfw_shmem_reserv_req *) pdata)->aname); + pack++; + } + return p_addr; + +fail_free_mem: + for (j = 0; j < i; j++) + { + pdata = (char *) mem_msg->aidata + j * item_cfg->item_size; + if (EOK != + STRCPY_S (mem_free.stname.aname, NSFW_MEM_NAME_LENTH, + ((nsfw_shmem_reserv_req *) pdata)->aname)) + { + NSFW_LOGERR ("STRCPY_S failed]j=%d", j); + continue; + } + + mem_free.ustype = item_cfg->mem_type; + mem_free.stname.entype = NSFW_SHMEM; + (void) mem_item_free (&mem_free); + NSFW_LOGINF ("free mem]addr=%p,type=%u,mem_count=%d,item=%d,name=%s", + p_addr, mem_msg->usmsg_type, mem_count, j, + ((nsfw_shmem_reserv_req *) pdata)->aname); + pack++; + } + + return NULL; + +} + +/***************************************************************************** +* Prototype : mem_alloc_req_proc +* Description : memory message +* Input : nsfw_mgr_msg* msg +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +mem_alloc_req_proc (nsfw_mgr_msg * msg) +{ + void *mem_addr = NULL; + + if (NULL == msg) + { + NSFW_LOGERR ("msg nul"); + return FALSE; + } + + nsfw_shmem_msg_head *mem_msg = GET_USER_MSG (nsfw_shmem_msg_head, msg); + nsfw_mgr_msg *rsp_msg = nsfw_mgr_rsp_msg_alloc (msg); + if (NULL == rsp_msg) + { + NSFW_LOGERR ("alloc rsp msg failed]msg_type=%u", mem_msg->usmsg_type); + return FALSE; + } + + nsfw_shmem_msg_head *mem_rsp_msg = + GET_USER_MSG (nsfw_shmem_msg_head, rsp_msg); + + if (!mem_init_rsp_msg (mem_msg, mem_rsp_msg)) + { + NSFW_LOGERR ("init rsp msg failed]msg_type=%u", mem_msg->usmsg_type); + nsfw_mgr_msg_free (rsp_msg); + return FALSE; + } + + switch (mem_msg->usmsg_type) + { + case NSFW_MEM_LOOKUP_REQ_MSG: + if (!mem_lookup_mem_by_msg (mem_msg, mem_rsp_msg, msg->src_pid)) + { + NSFW_LOGERR ("lookup mem msg failed]msg_type=%u", + mem_msg->usmsg_type); + goto sendrspmsg; + } + (void) mem_alloc_ps_info (msg->src_pid, msg->src_proc_type); + break; + case NSFW_RESERV_REQ_MSG: + case NSFW_MBUF_REQ_MSG: + case NSFW_SPPOOL_REQ_MSG: + case NSFW_RING_REQ_MSG: + mem_addr = mem_alloc_mem_by_msg (mem_msg, mem_rsp_msg); + if (NULL == mem_addr) + { + NSFW_LOGERR ("alloc mem msg failed]msg_type=%u", + mem_msg->usmsg_type); + (void) mem_init_rsp_msg (mem_msg, mem_rsp_msg); + goto sendrspmsg; + } + (void) mem_alloc_ps_info (msg->src_pid, msg->src_proc_type); + break; + case NSFW_RELEASE_REQ_MSG: + if (!mem_rel_mem_by_msg (mem_msg, mem_rsp_msg, msg->src_pid)) + { + NSFW_LOGERR ("rel mem msg failed]msg_type=%u", mem_msg->usmsg_type); + goto sendrspmsg; + } + break; + default: + break; + } + +sendrspmsg: + (void) nsfw_mgr_send_msg (rsp_msg); + nsfw_mgr_msg_free (rsp_msg); + return TRUE; +} + +/***************************************************************************** +* Prototype : mem_ps_exiting_resend +* Description : send the exiting message again +* Input : void *pps_info +* void* argv +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +mem_ps_exiting_resend (void *pps_info, void *argv) +{ + u32 *count = argv; + nsfw_ps_info *ps_info = pps_info; + if (NULL == ps_info) + { + NSFW_LOGERR ("ps_info nul!"); + return FALSE; + } + + if (NSFW_PROC_APP != ps_info->proc_type) + { + return FALSE; + } + + if (NSFW_PS_EXITING != ps_info->state) + { + return FALSE; + } + + if (NULL != count) + { + NSFW_LOGINF ("send count]count=%u,pid=%u", *count, ps_info->host_pid); + if (NSFW_PS_SEND_PER_TIME < (*count)++) + { + struct timespec time_left = + { NSFW_PS_MEM_RESEND_TVLAUE + +((*count) / NSFW_PS_SEND_PER_TIME), 0 + }; + ps_info->resend_timer_ptr = + (void *) nsfw_timer_reg_timer (NSFW_PS_MEM_RESEND_TIMER, + pps_info, + nsfw_mem_ps_exit_resend_timeout, + time_left); + return TRUE; + } + } + + (void) mem_ps_exiting (ps_info, NULL); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_mem_srv_restore_timeout +* Description : service waiting resume timeout +* Input : u32 timer_type +* void* data +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_mem_srv_restore_timeout (u32 timer_type, void *data) +{ + u32 max_count = 0; + + g_mem_cfg.p_restore_timer = NULL; + if (TRUE == NSFW_SRV_STATE_SUSPEND) + { + NSFW_SRV_STATE_SUSPEND = FALSE; + (void) nsfw_ps_iterator (mem_ps_exiting_resend, &max_count); + } + return TRUE; +} + +/***************************************************************************** +* Prototype : mem_srv_ctrl_proc +* Description : service control message process +* Input : nsfw_mgr_msg* msg +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +mem_srv_ctrl_proc (nsfw_mgr_msg * msg) +{ + if (NULL == msg) + { + NSFW_LOGERR ("msg nul"); + return FALSE; + } + + nsfw_srv_ctrl_msg *ctrl_msg = GET_USER_MSG (nsfw_srv_ctrl_msg, msg); + nsfw_mgr_msg *rsp_msg = nsfw_mgr_rsp_msg_alloc (msg); + if (NULL == rsp_msg) + { + NSFW_LOGERR ("alloc rsp msg failed]msg=%p", msg); + return FALSE; + } + nsfw_srv_ctrl_msg *ctrl_rsp_msg = GET_USER_MSG (nsfw_srv_ctrl_msg, rsp_msg); + NSFW_LOGINF ("get srv ctrl state] state=%d", ctrl_msg->srv_state); + + ctrl_rsp_msg->rsp_code = NSFW_MGR_SUCESS; + + (void) nsfw_mgr_send_msg (rsp_msg); + nsfw_mgr_msg_free (rsp_msg); + + if (NSFW_SRV_CTRL_RESUME == ctrl_msg->srv_state) + { + if (TRUE == NSFW_SRV_STATE_SUSPEND) + { + NSFW_SRV_STATE_SUSPEND = FALSE; + } + u32 max_count = 0; + (void) nsfw_ps_iterator (mem_ps_exiting_resend, &max_count); + if (NULL != g_mem_cfg.p_restore_timer) + { + nsfw_timer_rmv_timer ((nsfw_timer_info *) + g_mem_cfg.p_restore_timer); + g_mem_cfg.p_restore_timer = NULL; + } + } + else + { + NSFW_SRV_STATE_SUSPEND = TRUE; + struct timespec time_left = { NSFW_SRV_RESTORE_TVALUE, 0 }; + g_mem_cfg.p_restore_timer = + (void *) nsfw_timer_reg_timer (0, NULL, + nsfw_mem_srv_restore_timeout, + time_left); + } + + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_ps_mem_module_init +* Description : module init +* Input : void* param +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_ps_mem_module_init (void *param) +{ + u32 proc_type = (u32) ((long long) param); + NSFW_LOGINF ("ps_mem module init]type=%u", proc_type); + switch (proc_type) + { + case NSFW_PROC_MAIN: + (void) nsfw_ps_reg_global_fun (NSFW_PROC_APP, NSFW_PS_EXITING, + mem_ps_exiting, NULL); + (void) nsfw_mgr_reg_msg_fun (MGR_MSG_MEM_ALLOC_REQ, mem_alloc_req_proc); + (void) NSFW_REG_SOFT_INT (NSFW_SRV_RESTORE_TIMER, + NSFW_SRV_RESTORE_TVALUE, 1, 0xFFFF); + (void) NSFW_REG_SOFT_INT (NSFW_APP_RESEND_TIMER, + NSFW_PS_MEM_RESEND_TVLAUE, 1, 0xFFFF); + (void) NSFW_REG_SOFT_INT (NSFW_APP_SEND_PER_TIME, + NSFW_PS_SEND_PER_TIME, 1, 0xFFFF); + break; + default: + if (proc_type < NSFW_PROC_MAX) + { + return 0; + } + return -1; + } + + g_mem_cfg.srv_restore_tvalue = NSFW_SRV_RESTORE_TVALUE_DEF; + g_mem_cfg.ps_exit_resend_tvalue = NSFW_PS_MEM_RESEND_TVLAUE_DEF; + g_mem_cfg.ps_send_per_time = NSFW_PS_SEND_PER_TIME_DEF; + + return 0; +} + +/* *INDENT-OFF* */ +NSFW_MODULE_NAME (NSFW_PS_MEM_MODULE) +NSFW_MODULE_PRIORITY (10) +NSFW_MODULE_DEPENDS (NSFW_PS_MODULE) +NSFW_MODULE_INIT (nsfw_ps_mem_module_init) +/* *INDENT-ON* */ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/framework/ipc/ps/nsfw_ps_mem_module.h b/src/framework/ipc/ps/nsfw_ps_mem_module.h new file mode 100644 index 0000000..6b2b3c9 --- /dev/null +++ b/src/framework/ipc/ps/nsfw_ps_mem_module.h @@ -0,0 +1,87 @@ +/* +* +* 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 _NSFW_PS_MEM_MODULE_H +#define _NSFW_PS_MEM_MODULE_H + +#include "list.h" +#include "pidinfo.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#define MEMZONE_MAX_NAME 32 +#define NS_MAX_FORK_NUM 32 +#define NSFW_PS_MEM_MAX_FILTER 4 + +#define NSFW_SRV_RESTORE_TVALUE_DEF 120 +#define NSFW_SRV_RESTORE_TVALUE g_mem_cfg.srv_restore_tvalue +#define NSFW_SRV_STATE_SUSPEND g_mem_cfg.srv_suspend + +#define NSFW_PS_MEM_RESEND_TIMER 1 +#define NSFW_PS_MEM_RESEND_TVLAUE_DEF 2 +#define NSFW_PS_SEND_PER_TIME_DEF 150 +#define NSFW_PS_SEND_PER_TIME (g_mem_cfg.ps_send_per_time) +#define NSFW_PS_MEM_RESEND_TVLAUE (g_mem_cfg.ps_exit_resend_tvalue) + +typedef struct _ns_mem_mng_init_cfg +{ + u16 srv_restore_tvalue; + u16 ps_exit_resend_tvalue; + u16 ps_send_per_time; + u16 srv_suspend; + void *p_restore_timer; +} ns_mem_mng_init_cfg; + +/*mem alloc by msg begin*/ +typedef struct +{ + nsfw_mem_name stname; + u16 ustype; +} nsfw_mem_type_info; + +#define NSFW_MEM_CALL_ARG_BUF 256 +#define MEM_GET_CALLARGV(_dst_member,_src_member, _dst_type,_srctype,_dst_buf, _src_buf) \ + ((_dst_type*)(void*)_dst_buf)->_dst_member = ((_srctype*)(void*)_src_buf)->_src_member + +typedef void *(*nsfw_ps_mem_create_fun) (void *memstr); +typedef u8 (*nsfw_ps_mem_msg_to_memstr) (u16 msg_type, char *msg_body, + char *memstr_buf, i32 buf_len); + +typedef struct __nsfw_ps_mem_item_cfg +{ + u16 usmsg_type; + u16 item_size; + u16 mem_type; + nsfw_ps_mem_create_fun create_fun; + nsfw_ps_mem_msg_to_memstr change_fun; +} nsfw_ps_mem_item_cfg; + +void *mem_item_free (void *pdata); +void *mem_item_lookup (void *pdata); +u8 mem_item_get_callargv (u16 msg_type, char *msg_body, char *memstr_buf, + i32 buf_len); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#endif /* _NSFW_PS_MEM_MODULE_H */ diff --git a/src/framework/ipc/ps/nsfw_ps_module.c b/src/framework/ipc/ps/nsfw_ps_module.c new file mode 100644 index 0000000..e532c31 --- /dev/null +++ b/src/framework/ipc/ps/nsfw_ps_module.c @@ -0,0 +1,1725 @@ +/* +* +* 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 "types.h" +#include "nstack_securec.h" +#include "nsfw_init.h" + +#include "nsfw_mgr_com_api.h" +#include "nsfw_ps_api.h" +#include "nsfw_ps_module.h" +#include "nsfw_mem_api.h" +#include "nstack_log.h" +#include "nsfw_base_linux_api.h" +#include "nsfw_fd_timer_api.h" +#include "nsfw_maintain_api.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +nsfw_ps_init_cfg g_ps_cfg; + +nsfw_pid_item *g_ps_info = NULL; + +nsfw_pid_item *g_master_ps_info = NULL; + +struct list_head g_ps_runing_list; +nsfw_ps_callback g_ps_init_callback[NSFW_PROC_MAX][NSFW_PS_MAX_CALLBACK]; +nsfw_ps_info g_main_ps_info; + +void *g_ps_chk_timer = NULL; + +/***************************************************************************** +* Prototype : nsfw_ps_reg_fun +* Description : reg the callback fun when process state change +* Input : nsfw_ps_info *pps_info +* u8 ps_state +* nsfw_ps_proc_fun fun +* void* argv +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_ps_reg_fun (nsfw_ps_info * pps_info, u8 ps_state, + nsfw_ps_proc_fun fun, void *argv) +{ + if (NULL == pps_info) + { + NSFW_LOGERR ("reg pps_info nul]state=%d,fun=%p", ps_state, fun); + return FALSE; + } + + u32 i; + for (i = 0; i < NSFW_PS_MAX_CALLBACK; i++) + { + if (NULL == pps_info->callback[i].fun) + { + pps_info->callback[i].fun = fun; + pps_info->callback[i].argv = argv; + pps_info->callback[i].state = ps_state; + NSFW_LOGDBG + ("reg fun suc]ps_info=%p,state=%d,fun=%p,argv=%p,i=%d", + pps_info, ps_state, fun, argv, i); + return TRUE; + } + } + + NSFW_LOGERR ("reg fun failed]ps_info=%p,state=%d,fun=%p,argv=%p,i=%d", + pps_info, ps_state, fun, argv, i); + return FALSE; +} + +/***************************************************************************** +* Prototype : nsfw_ps_reg_global_fun +* Description : reg the callback function of the specify proc_type state + change +* Input : u8 proc_type +* u8 ps_state +* nsfw_ps_proc_fun fun +* void* argv +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_ps_reg_global_fun (u8 proc_type, u8 ps_state, nsfw_ps_proc_fun fun, + void *argv) +{ + if (NSFW_PROC_MAX <= proc_type) + { + NSFW_LOGERR ("proc_type err]state=%u,fun=%p,type=%u", ps_state, fun, + proc_type); + return FALSE; + } + + nsfw_ps_callback *cb_fun = g_ps_init_callback[proc_type]; + u32 i; + for (i = 0; i < NSFW_PS_MAX_CALLBACK; i++) + { + if (NULL == cb_fun[i].fun) + { + cb_fun[i].fun = fun; + cb_fun[i].argv = argv; + cb_fun[i].state = ps_state; + NSFW_LOGINF ("reg fun suc]type=%u,state=%u,fun=%p,argv=%p,i=%u", + proc_type, ps_state, fun, argv, i); + return TRUE; + } + } + + NSFW_LOGERR ("reg fun ful failed]type=%u,state=%u,fun=%p,argv=%p,i=%u", + proc_type, ps_state, fun, argv, i); + return FALSE; +} + +/***************************************************************************** +* Prototype : nsfw_ps_exit +* Description : when recvive the process exit finish message ,change + to exit state +* Input : nsfw_mgr_msg* msg +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_ps_exit (nsfw_mgr_msg * msg) +{ + nsfw_ps_info *pps_info; + if (NULL == msg) + { + NSFW_LOGERR ("msg nul!"); + return FALSE; + } + + nsfw_ps_info_msg *ps_msg = GET_USER_MSG (nsfw_ps_info_msg, msg); + pps_info = nsfw_ps_info_get (ps_msg->host_pid); + NSFW_LOGINF ("recv ps exit]host_pid=%d,ps_info=%p", ps_msg->host_pid, + pps_info); + + if (NULL == pps_info) + { + NSFW_LOGERR ("error msg pps_info nul]host_pid=%d", ps_msg->host_pid); + return true; + } + (void) nsfw_sw_ps_state (pps_info, NSFW_PS_EXIT); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_ps_info_fork_alloc +* Description : alloc fork ps_info +* Input : u32 parent_pid +* u32 child_pid +* Output : None +* Return Value : nsfw_ps_info* +* Calls : +* Called By : +*****************************************************************************/ +nsfw_ps_info * +nsfw_ps_info_fork_alloc (u32 parent_pid, u32 child_pid) +{ + nsfw_ps_info *pps_info = NULL; + nsfw_ps_info *pps_info_parent = NULL; + pps_info_parent = nsfw_ps_info_get (parent_pid); + if (NULL == pps_info_parent) + { + NSFW_LOGERR ("pps_info_parent nul"); + return NULL; + } + + pps_info = nsfw_ps_info_get (child_pid); + if (NULL == pps_info) + { + pps_info = nsfw_ps_info_alloc (child_pid, pps_info_parent->proc_type); + if (NULL == pps_info) + { + NSFW_LOGERR + ("alloc ps_info failed!]ps_info=%p,host_pid=%u,child_pid=%u", + pps_info_parent, pps_info_parent->host_pid, child_pid); + return NULL; + } + } + else + { + NSFW_LOGWAR + ("fork alloc mem before!]ps_info=%p,host_pid=%u,child_pid=%u", + pps_info_parent, pps_info_parent->host_pid, child_pid); + } + + NSFW_LOGWAR ("ps_info fork]ps_info=%p,host_pid=%u,child_pid=%u", + pps_info_parent, pps_info_parent->host_pid, child_pid); + pps_info->parent_pid = parent_pid; + if (EOK != + MEMCPY_S (pps_info->callback, sizeof (pps_info->callback), + pps_info_parent->callback, + sizeof (pps_info_parent->callback))) + { + nsfw_ps_info_free (pps_info); + NSFW_LOGERR ("ps_info set_failed"); + return NULL; + } + + if (EOK != + MEMCPY_S (pps_info->value, sizeof (pps_info->value), + pps_info_parent->value, sizeof (pps_info_parent->value))) + { + nsfw_ps_info_free (pps_info); + NSFW_LOGERR ("ps_info cpy_failed"); + return NULL; + } + + return pps_info; +} + +/***************************************************************************** +* Prototype : nsfw_ps_info_alloc +* Description : alloc ps_info +* Input : u32 pid +* u8 proc_type +* Output : None +* Return Value : nsfw_ps_info* +* Calls : +* Called By : +*****************************************************************************/ +nsfw_ps_info * +nsfw_ps_info_alloc (u32 pid, u8 proc_type) +{ + nsfw_ps_info *pps_info = NULL; + if (0 == nsfw_mem_ring_dequeue (g_ps_cfg.ps_info_pool, (void *) &pps_info)) + { + NSFW_LOGERR ("alloc ps_info falied]pid=%u,type=%u", pid, proc_type); + return NULL; + } + + if (NULL == pps_info) + { + if (NSFW_PROC_MAIN != proc_type || TRUE == g_main_ps_info.alloc_flag) + { + NSFW_LOGERR ("alloc ps_info nul]pid=%u,type=%u", pid, proc_type); + return NULL; + } + pps_info = &g_main_ps_info; + } + + if (EOK != + MEMSET_S (pps_info, sizeof (nsfw_ps_info), 0, sizeof (nsfw_ps_info))) + { + nsfw_ps_info_free (pps_info); + NSFW_LOGERR ("set failed"); + return NULL; + } + + pps_info->proc_type = proc_type; + pps_info->host_pid = pid; + + if (proc_type < NSFW_PROC_MAX) + { + int retval; + retval = + MEMCPY_S (pps_info->callback, sizeof (pps_info->callback), + g_ps_init_callback[proc_type], sizeof (pps_info->callback)); + if (EOK != retval) + { + NSFW_LOGERR ("Failed to MEMCPY_S]retval=%d", retval); + nsfw_ps_info_free (pps_info); + return NULL; + } + } + list_add_tail (&pps_info->node, &g_ps_runing_list); + pps_info->alloc_flag = TRUE; + + (void) nsfw_sw_ps_state (pps_info, NSFW_PS_RUNNING); + if (pid < NSFW_MAX_PID) + { + g_ps_info[pid].ps_info = pps_info; + g_ps_info[pid].proc_type = proc_type; + } + + NSFW_LOGINF ("ps_info alloc]ps_info=%p,pid=%u,type=%u", pps_info, pid, + proc_type); + return pps_info; + +} + +/***************************************************************************** +* Prototype : nsfw_ps_info_get +* Description : get ps_info by pid +* Input : u32 pid +* Output : None +* Return Value : inline nsfw_ps_info* +* Calls : +* Called By : +*****************************************************************************/ +inline nsfw_ps_info * +nsfw_ps_info_get (u32 pid) +{ + if (pid < NSFW_MAX_PID) + { + return g_ps_info[pid].ps_info; + } + + return NULL; +} + +nsfw_ps_info * +nsfw_share_ps_info_get (u32 pid) +{ + if (pid < NSFW_MAX_PID) + { + return g_master_ps_info[pid].ps_info; + } + + return NULL; +} + +/***************************************************************************** +* Prototype : nsfw_ps_info_free +* Description : free ps_info +* Input : nsfw_ps_info *ps_info +* Output : None +* Return Value : void +* Calls : +* Called By : +*****************************************************************************/ +void +nsfw_ps_info_free (nsfw_ps_info * ps_info) +{ + if (NULL == ps_info) + { + NSFW_LOGERR ("ps_info nul"); + return; + } + + if (FALSE == ps_info->alloc_flag) + { + NSFW_LOGERR ("ps_info refree]ps_info=%p,pid=%u,state=%u", ps_info, + ps_info->host_pid, ps_info->state); + return; + } + + if (NULL != ps_info->exit_timer_ptr) + { + nsfw_timer_rmv_timer ((nsfw_timer_info *) ps_info->exit_timer_ptr); + ps_info->exit_timer_ptr = NULL; + } + + if (NULL != ps_info->resend_timer_ptr) + { + nsfw_timer_rmv_timer ((nsfw_timer_info *) ps_info->resend_timer_ptr); + ps_info->resend_timer_ptr = NULL; + } + + if (NULL != ps_info->hbt_timer_ptr) + { + nsfw_timer_rmv_timer ((nsfw_timer_info *) ps_info->hbt_timer_ptr); + ps_info->hbt_timer_ptr = NULL; + } + + list_del (&ps_info->node); + + ps_info->alloc_flag = FALSE; + + NSFW_LOGINF ("ps_info free]ps_info=%p,pid=%u,state=%u", ps_info, + ps_info->host_pid, ps_info->state); + if (ps_info != &g_main_ps_info) + { + if (0 == nsfw_mem_ring_enqueue (g_ps_cfg.ps_info_pool, ps_info)) + { + NSFW_LOGERR ("ps_info free failed]ps_info=%p,pid=%u,state=%u", + ps_info, ps_info->host_pid, ps_info->state); + return; + } + } + + if (ps_info->host_pid < NSFW_MAX_PID) + { + g_ps_info[ps_info->host_pid].proc_type = 0; + g_ps_info[ps_info->host_pid].ps_info = NULL; + } + + return; +} + +/***************************************************************************** +* Prototype : nsfw_ps_exiting_timeout +* Description : waiting for remove ps_info timeout +* Input : u32 timer_type +* void* data +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_ps_exiting_timeout (u32 timer_type, void *data) +{ + nsfw_ps_info *pps_info = (nsfw_ps_info *) data; + NSFW_LOGINF ("ps_info timerout]pps_info=%p,pid=%u", pps_info, + pps_info->host_pid); + if (NULL == pps_info) + { + return TRUE; + } + + pps_info->exit_timer_ptr = NULL; + + if (TRUE == g_hbt_switch) + { + NSFW_LOGINF ("hbt off"); + struct timespec time_left = { NSFW_PS_WEXIT_TVLAUE, 0 }; + pps_info->exit_timer_ptr = + (void *) nsfw_timer_reg_timer (NSFW_PS_WEXIT_TIMER, pps_info, + nsfw_ps_exiting_timeout, time_left); + return TRUE; + } + + if (NSFW_PS_EXITING == pps_info->state) + { + (void) nsfw_sw_ps_state (pps_info, NSFW_PS_EXIT); + } + + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_ps_exit_end_notify +* Description : send exitting state process finished +* Input : u32 pid +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_ps_exit_end_notify (u32 pid) +{ + nsfw_mgr_msg *rsp_msg = + nsfw_mgr_msg_alloc (MGR_MSG_APP_EXIT_RSP, NSFW_PROC_MASTER); + if (NULL == rsp_msg) + { + NSFW_LOGERR ("alloc rsp msg failed]pid=%u", pid); + return FALSE; + } + + nsfw_ps_info_msg *ps_msg = GET_USER_MSG (nsfw_ps_info_msg, rsp_msg); + ps_msg->host_pid = pid; + (void) nsfw_mgr_send_msg (rsp_msg); + nsfw_mgr_msg_free (rsp_msg); + NSFW_LOGINF ("send exit rsp msg]pid=%u", pid); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_sw_ps_state +* Description : switch ps_info state +* Input : nsfw_ps_info* pps_info +* u8 new_state +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_sw_ps_state (nsfw_ps_info * pps_info, u8 new_state) +{ + if (NULL == pps_info) + { + NSFW_LOGERR ("pps_info nul!"); + return FALSE; + } + + NSFW_LOGINF ("sw]ps_info=%p,pid=%u,type=%u,old_state=%u,newstate=%u", + pps_info, pps_info->host_pid, pps_info->proc_type, + pps_info->state, new_state); + + i32 i, ret; + for (i = 0; i < NSFW_PS_MAX_CALLBACK; i++) + { + if (NULL == pps_info->callback[i].fun) + { + /* NULL should be the last fun */ + break; + } + + if (new_state == pps_info->callback[i].state) + { + ret = + pps_info->callback[i].fun (pps_info, pps_info->callback[i].argv); + NSFW_LOGINF ("callback fun]ps_info=%p,i=%d,fun=%p,argv=%p,ret=%d", + pps_info, i, pps_info->callback[i].fun, + pps_info->callback[i].argv, ret); + } + } + + if (NSFW_PS_HBT_FAILED != new_state) + { + pps_info->state = new_state; + } + + if (NSFW_PS_EXIT == new_state) + { + nsfw_ps_info_free (pps_info); + } + + if (NSFW_PS_EXITING == new_state) + { + struct timespec time_left = { NSFW_PS_WEXIT_TVLAUE, 0 }; + pps_info->exit_timer_ptr = + (void *) nsfw_timer_reg_timer (NSFW_PS_WEXIT_TIMER, pps_info, + nsfw_ps_exiting_timeout, time_left); + } + + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_ps_get_netlink_socket +* Description : get netlink socket to kernel +* Input : None +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_ps_get_netlink_socket () +{ + int rc; + int nl_sock; + int size, size_len; + struct sockaddr_nl sa_nl; + + nl_sock = nsfw_base_socket (PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR); + if (nl_sock == -1) + { + NSFW_LOGERR ("get netlink socket err]errno=%d", errno); + return -1; + } + + rc = nsfw_set_close_on_exec (nl_sock); + if (rc == -1) + { + (void) nsfw_base_close (nl_sock); + NSFW_LOGERR ("set exec err]fd=%d, errno=%d", nl_sock, errno); + return -1; + } + + sa_nl.nl_family = AF_NETLINK; + sa_nl.nl_groups = CN_IDX_PROC; + sa_nl.nl_pid = getpid (); + + rc = nsfw_base_bind (nl_sock, (struct sockaddr *) &sa_nl, sizeof (sa_nl)); + if (rc == -1) + { + (void) nsfw_base_close (nl_sock); + NSFW_LOGERR ("netlink bind err]netlink_fd=%d, errno=%d", nl_sock, + errno); + return -1; + } + + struct __attribute__ ((aligned (NLMSG_ALIGNTO))) + { + struct nlmsghdr nl_hdr; + struct __attribute__ ((__packed__)) + { + struct cn_msg cn_msg; + enum proc_cn_mcast_op cn_mcast; + }; + } nlcn_msg; + if (EOK != MEMSET_S (&nlcn_msg, sizeof (nlcn_msg), 0, sizeof (nlcn_msg))) + { + (void) nsfw_base_close (nl_sock); + NSFW_LOGERR ("netlink set failed]netlink_fd=%d", nl_sock); + return -1; + } + nlcn_msg.nl_hdr.nlmsg_len = sizeof (nlcn_msg); + nlcn_msg.nl_hdr.nlmsg_pid = getpid (); + nlcn_msg.nl_hdr.nlmsg_type = NLMSG_DONE; + + nlcn_msg.cn_msg.id.idx = CN_IDX_PROC; + nlcn_msg.cn_msg.id.val = CN_VAL_PROC; + nlcn_msg.cn_msg.len = sizeof (enum proc_cn_mcast_op); + + nlcn_msg.cn_mcast = PROC_CN_MCAST_LISTEN; + rc = nsfw_base_send (nl_sock, &nlcn_msg, sizeof (nlcn_msg), 0); + if (rc == -1) + { + (void) nsfw_base_close (nl_sock); + NSFW_LOGERR ("netlink send err]netlink_fd=%d, errno=%d", nl_sock, + errno); + return -1; + } + + NSFW_LOGINF ("netlink connect]netlink_fd=%d", nl_sock); + int val, len; + len = sizeof (val); + if (0 > + nsfw_base_getsockopt (nl_sock, SOL_SOCKET, SO_RCVBUF, &val, + (socklen_t *) & len)) + { + NSFW_LOGERR ("get socket opt err!]error=%d", errno); + } + else + { + NSFW_LOGINF ("] SO_RCVBUF=0x%x", val); + } + + size = MAX_NET_LINK_BUF; + size_len = sizeof (size); + if (0 > + nsfw_base_setsockopt (nl_sock, SOL_SOCKET, SO_RCVBUFFORCE, + (void *) &size, (socklen_t) size_len)) + { + NSFW_LOGERR ("set socket opt err!]error=%d", errno); + } + + size_len = sizeof (size); + if (0 > + nsfw_base_getsockopt (nl_sock, SOL_SOCKET, SO_RCVBUF, (void *) &size, + (socklen_t *) & size_len)) + { + NSFW_LOGERR ("get socket opt err!]error=%d", errno); + } + + NSFW_LOGINF ("] SO_RCVBUF=0x%x", size); + return nl_sock; +} + +/***************************************************************************** +* Prototype : nsfw_ps_change_fun +* Description : proc change when receive event from kernel +* Input : i32 epfd +* i32 fd +* u32 events +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_ps_change_fun (i32 epfd, i32 fd, u32 events) +{ + i32 rc; + u32 host_pid; + nsfw_ps_info *pps_info = NULL; + + struct __attribute__ ((aligned (NLMSG_ALIGNTO))) + { + struct nlmsghdr nl_hdr; + struct __attribute__ ((__packed__)) + { + struct cn_msg cn_msg; + struct proc_event proc_ev; + }; + } nlcn_msg; + + if (!(events & EPOLLIN)) + { + return TRUE; + } + + while (1) + { + rc = nsfw_base_recv (fd, &nlcn_msg, sizeof (nlcn_msg), 0); + if (rc == 0) + { + NSFW_LOGWAR ("netlink recv 0]netlink_fd=%d,errno=%d", fd, errno); + break; + } + else if (rc == -1) + { + if (errno == EINTR || errno == EAGAIN) + { + break; + } + NSMON_LOGERR ("netlink recv]netlink_fd=%d,errno=%d", fd, errno); + if (errno == ENOBUFS) + { + struct timespec time_left = { NSFW_PS_FIRST_CHK_TVLAUE, 0 }; + g_ps_chk_timer = + (void *) nsfw_timer_reg_timer (NSFW_PS_CHK_TIMER, + (void *) FALSE, + nsfw_ps_chk_timeout, + time_left); + } + break; + } + + switch (nlcn_msg.proc_ev.what) + { + case PROC_EVENT_EXIT: + host_pid = nlcn_msg.proc_ev.event_data.exit.process_pid; + pps_info = nsfw_ps_info_get (host_pid); + if (NULL == pps_info) + { + NSFW_LOGDBG ("pps info is null]host pid=%d", host_pid); + break; + } + + if (NSFW_PS_EXITING == pps_info->state) + { + NSFW_LOGERR ("double pid info]ps_info=%p,pid=%d", pps_info, + host_pid); + break; + } + + (void) nsfw_sw_ps_state (pps_info, NSFW_PS_EXITING); + break; + default: + break; + } + } + + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_ps_start_netlink +* Description : reg ps_module to epoll thread +* Input : None +* Output : None +* Return Value : u8 +* Calls : +* Called By : +* +*****************************************************************************/ +u8 +nsfw_ps_start_netlink () +{ + i32 netlink_fd = nsfw_ps_get_netlink_socket (); + if (netlink_fd < 0) + { + NSFW_LOGERR ("get netlink failed!"); + return FALSE; + } + + NSFW_LOGINF ("start ps_info module!]netlink_fd=%d", netlink_fd); + (void) nsfw_mgr_reg_sock_fun (netlink_fd, nsfw_ps_change_fun); + (void) nsfw_mgr_reg_msg_fun (MGR_MSG_APP_EXIT_RSP, nsfw_ps_exit); + return TRUE; +} + +/* for heartbeat check*/ + +NSTACK_STATIC __thread i32 t_val_idx = 0; +nsfw_thread_dogs g_thread_dogs[NSFW_MAX_THREAD_DOGS_COUNT]; +/***************************************************************************** +* Prototype : nsfw_all_thread_chk +* Description : get all thread check state +* Input : None +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_all_thread_chk () +{ + i32 count = -1; + u32 i; + for (i = 0; i < NSFW_MAX_THREAD_DOGS_COUNT; i++) + { + if (FALSE == g_thread_dogs[i].alloc_flag) + { + continue; + } + + if (count < g_thread_dogs[i].count) + { + count = g_thread_dogs[i].count; + } + + g_thread_dogs[i].count++; + } + return count; +} + +/***************************************************************************** +* Prototype : nsfw_thread_chk_unreg +* Description : cancel the thread check +* Input : None +* Output : None +* Return Value : inline u8 +* Calls : +* Called By : +*****************************************************************************/ +inline u8 +nsfw_thread_chk_unreg () +{ + if (t_val_idx > 0 && t_val_idx < NSFW_MAX_THREAD_DOGS_COUNT) + { + g_thread_dogs[t_val_idx].alloc_flag = FALSE; + g_thread_dogs[t_val_idx].count = 0; + g_thread_dogs[t_val_idx].thread_id = 0; + t_val_idx = 0; + } + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_thread_chk +* Description : add the thread to check, and should be call in every + process cycle +* Input : None +* Output : None +* Return Value : inline u8 +* Calls : +* Called By : +*****************************************************************************/ +inline u8 +nsfw_thread_chk () +{ + u32 i; + if (t_val_idx > 0 && t_val_idx < NSFW_MAX_THREAD_DOGS_COUNT) + { + g_thread_dogs[t_val_idx].count = 0; + return TRUE; + } + + for (i = 1; i < NSFW_MAX_THREAD_DOGS_COUNT; i++) + { + if ((FALSE == g_thread_dogs[i].alloc_flag) + && __sync_bool_compare_and_swap (&g_thread_dogs[i].alloc_flag, + FALSE, TRUE)) + { + t_val_idx = i; + break; + } + } + + if (t_val_idx > 0 && t_val_idx < NSFW_MAX_THREAD_DOGS_COUNT) + { + g_thread_dogs[t_val_idx].count = 0; + g_thread_dogs[t_val_idx].thread_id = syscall (SYS_gettid); + } + + return TRUE; +} + +/***************************************************************** +Parameters : None +Return : +Description : +*****************************************************************/ +nsfw_thread_dogs * +nsfw_thread_getDog () +{ + u32 i; + nsfw_thread_dogs *retPtr = NULL; + if (t_val_idx > 0 && t_val_idx < NSFW_MAX_THREAD_DOGS_COUNT) + { + return &g_thread_dogs[t_val_idx]; + } + + for (i = 1; i < NSFW_MAX_THREAD_DOGS_COUNT; i++) + { + if ((FALSE == g_thread_dogs[i].alloc_flag) + && __sync_bool_compare_and_swap (&g_thread_dogs[i].alloc_flag, + FALSE, TRUE)) + { + t_val_idx = i; + break; + } + } + + if (t_val_idx > 0 && t_val_idx < NSFW_MAX_THREAD_DOGS_COUNT) + { + g_thread_dogs[t_val_idx].count = 0; + g_thread_dogs[t_val_idx].thread_id = syscall (SYS_gettid); + retPtr = &g_thread_dogs[t_val_idx]; + } + return retPtr; +} + +pthread_t g_all_thread[MAX_THREAD] = { 0 }; + +u8 +nsfw_reg_trace_thread (pthread_t tid) +{ + int i; + for (i = 0; i < MAX_THREAD; i++) + { + if ((0 == g_all_thread[i]) + && __sync_bool_compare_and_swap (&g_all_thread[i], 0, tid)) + { + return TRUE; + } + } + return FALSE; +} + +/***************************************************************************** +* Prototype : nsfw_ps_check_dst_init +* Description : send check msg check the dst process is listening +* Input : u8 dst_proc_type +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_ps_check_dst_init (u8 dst_proc_type) +{ + u8 ps_state = FALSE; + nsfw_mgr_msg *msg = + nsfw_mgr_msg_alloc (MGR_MSG_CHK_INIT_REQ, dst_proc_type); + if (NULL == msg) + { + NSFW_LOGERR ("alloc msg failed]dst_typ=%d", dst_proc_type); + return FALSE; + } + + nsfw_ps_chk_msg *ps_msg = GET_USER_MSG (nsfw_ps_chk_msg, msg); + ps_msg->ps_state = TRUE; + + nsfw_mgr_msg *rsp_msg = nsfw_mgr_null_rspmsg_alloc (); + if (NULL == rsp_msg) + { + nsfw_mgr_msg_free (msg); + NSFW_LOGERR ("alloc rsp msg failed]dst_typ=%d", dst_proc_type); + return FALSE; + } + + (void) nsfw_mgr_send_req_wait_rsp (msg, rsp_msg); + + ps_msg = GET_USER_MSG (nsfw_ps_chk_msg, rsp_msg); + ps_state = ps_msg->ps_state; + + nsfw_mgr_msg_free (msg); + nsfw_mgr_msg_free (rsp_msg); + NSFW_LOGINF ("get peer state]dst_type=%d,state=%d", dst_proc_type, + ps_state); + return ps_state; +} + +/***************************************************************************** +* Prototype : nsfw_ps_send_hbt +* Description : seng heart beat message to peer +* Input : nsfw_ps_info* pps_info +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_ps_send_hbt (nsfw_ps_info * pps_info) +{ + if (NULL == pps_info) + { + NSFW_LOGERR ("null ps_info!"); + return FALSE; + } + + nsfw_mgr_msg *req_msg = + nsfw_mgr_msg_alloc (MGR_MSG_CHK_HBT_REQ, pps_info->proc_type); + if (NULL == req_msg) + { + NSFW_LOGERR ("alloc req msg failed]pps_info=%p", pps_info); + return FALSE; + } + + req_msg->dst_pid = pps_info->host_pid; + nsfw_ps_chk_msg *ps_msg = GET_USER_MSG (nsfw_ps_chk_msg, req_msg); + ps_msg->ps_state = TRUE; + u8 ret = nsfw_mgr_send_msg (req_msg); + nsfw_mgr_msg_free (req_msg); + NSFW_LOGDBG ("send hbt msg]ret=%d,pps_info=%p,pid=%d,type=%d", ret, + pps_info, pps_info->host_pid, pps_info->proc_type); + return ret; +} + +/***************************************************************************** +* Prototype : nsfw_ps_recv_hbt +* Description : recv heart beat message process +* Input : nsfw_mgr_msg* msg +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_ps_recv_hbt (nsfw_mgr_msg * msg) +{ + if (NULL == msg) + { + NSFW_LOGERR ("error msg nul!"); + return FALSE; + } + + nsfw_mgr_msg *rsp_msg = nsfw_mgr_rsp_msg_alloc (msg); + if (NULL == rsp_msg) + { + NSFW_LOGERR ("alloc rsp failed,drop msg!" MSGINFO, PRTMSG (msg)); + return FALSE; + } + + nsfw_ps_chk_msg *ps_msg = GET_USER_MSG (nsfw_ps_chk_msg, rsp_msg); + ps_msg->ps_state = TRUE; + ps_msg->thread_chk_count = nsfw_all_thread_chk (); + (void) nsfw_mgr_send_msg (rsp_msg); + nsfw_mgr_msg_free (rsp_msg); + + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_ps_recv_hbt_rsp +* Description : recv heart beat response message process +* Input : nsfw_mgr_msg* msg +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_ps_recv_hbt_rsp (nsfw_mgr_msg * msg) +{ + if (NULL == msg) + { + NSFW_LOGERR ("error msg nul!"); + return FALSE; + } + + nsfw_ps_chk_msg *ps_msg = GET_USER_MSG (nsfw_ps_chk_msg, msg); + if (TRUE != ps_msg->ps_state) + { + NSFW_LOGERR ("Heartbeat failed]pid=%u,type=%u", msg->src_pid, + msg->src_proc_type); + return FALSE; + } + + nsfw_ps_info *pps_info = nsfw_ps_info_get (msg->src_pid); + if (NULL == pps_info) + { + NSFW_LOGERR ("get ps_info failed]pid=%u,type=%u,count=%d", + msg->src_pid, msg->src_proc_type, + ps_msg->thread_chk_count); + return FALSE; + } + + if (0 == ps_msg->thread_chk_count) + { + pps_info->hbt_failed_count = 0; + return TRUE; + } + + if (pps_info->hbt_failed_count > (u32) ps_msg->thread_chk_count) + { + pps_info->hbt_failed_count = (u32) ps_msg->thread_chk_count; + } + + NSFW_LOGERR ("Heartbeat failed]pid=%u,type=%u,count=%d,ps_count=%u", + msg->src_pid, msg->src_proc_type, ps_msg->thread_chk_count, + pps_info->hbt_failed_count); + return FALSE; +} + +int +nsfw_ps_reset_hbt (void *pps_info, void *argv) +{ + nsfw_ps_info *ps_info = pps_info; + if (NULL == ps_info) + { + NSFW_LOGERR ("ps_info nul!"); + return FALSE; + } + + if (NSFW_PROC_MAIN != ps_info->proc_type) + { + return FALSE; + } + + ps_info->hbt_failed_count = *(u32 *) argv; + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_ps_hbt_timeout +* Description : heart beat time out +* Input : u32 timer_type +* void* data +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_ps_hbt_timeout (u32 timer_type, void *data) +{ + nsfw_ps_info *pps_info = (nsfw_ps_info *) data; + + if (NULL == pps_info) + { + NSFW_LOGERR ("null ps_info!"); + return FALSE; + } + + if (NULL == pps_info->hbt_timer_ptr) + { + NSFW_LOGERR ("hbt has stop]pps_info=%p", pps_info); + pps_info->hbt_failed_count = 0; + return TRUE; + } + + if (TRUE == g_hbt_switch) + { + struct timespec time_left = { NSFW_CHK_HBT_TVLAUE, 0 }; + pps_info->hbt_timer_ptr = + (void *) nsfw_timer_reg_timer (NSFW_CHK_HBT_TIMER, data, + nsfw_ps_hbt_timeout, time_left); + return TRUE; + } + + /* nic init may cost a few seconds, master will restart main if heartbeat timeout */ + if (NSFW_SOFT_HBT_CHK_COUNT != NSFW_MAX_HBT_CHK_COUNT) + { + if (NSFW_SOFT_HBT_CHK_COUNT < NSFW_MAX_HBT_CHK_COUNT) + { + u32 new_hbt_count = 0; + (void) nsfw_ps_iterator (nsfw_ps_reset_hbt, &new_hbt_count); + } + + NSFW_MAX_HBT_CHK_COUNT = NSFW_SOFT_HBT_CHK_COUNT; + } + + if (NSFW_MAX_HBT_CHK_COUNT <= pps_info->hbt_failed_count) + { + (void) nsfw_sw_ps_state (pps_info, NSFW_PS_HBT_FAILED); + /*reset counter */ + pps_info->hbt_failed_count = 0; + } + + if (TRUE != nsfw_ps_send_hbt (pps_info)) + { + } + + if (pps_info->hbt_failed_count > 0) + { + NSFW_LOGWAR ("Heartbeat failed]pid=%u,ps_count=%u, max_count=%d", + pps_info->host_pid, pps_info->hbt_failed_count, + NSFW_MAX_HBT_CHK_COUNT); + } + + pps_info->hbt_failed_count++; + struct timespec time_left = { NSFW_CHK_HBT_TVLAUE, 0 }; + pps_info->hbt_timer_ptr = + (void *) nsfw_timer_reg_timer (NSFW_CHK_HBT_TIMER, data, + nsfw_ps_hbt_timeout, time_left); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_ps_hbt_start +* Description : start ps_info heart beat +* Input : nsfw_ps_info* pps_info +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_ps_hbt_start (nsfw_ps_info * pps_info) +{ + if (NULL == pps_info) + { + NSFW_LOGERR ("null ps_info!"); + return FALSE; + } + + if (NULL != pps_info->hbt_timer_ptr) + { + NSFW_LOGERR ("hbt start before!]ps_info=%p,pid=%u,type=%u", pps_info, + pps_info->host_pid, pps_info->proc_type); + return FALSE; + } + + struct timespec time_left = { NSFW_CHK_HBT_TVLAUE, 0 }; + pps_info->hbt_timer_ptr = + (void *) nsfw_timer_reg_timer (NSFW_CHK_HBT_TIMER, (void *) pps_info, + nsfw_ps_hbt_timeout, time_left); + NSFW_LOGINF ("hbt start!]ps_info=%p,pid=%u,type=%u", pps_info, + pps_info->host_pid, pps_info->proc_type); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_ps_hbt_stop +* Description : stop ps_info heart beat +* Input : nsfw_ps_info* pps_info +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_ps_hbt_stop (nsfw_ps_info * pps_info) +{ + if (NULL == pps_info) + { + NSFW_LOGERR ("null ps_info!"); + return FALSE; + } + + if (NULL != pps_info->hbt_timer_ptr) + { + nsfw_timer_rmv_timer ((nsfw_timer_info *) pps_info->hbt_timer_ptr); + pps_info->hbt_timer_ptr = NULL; + } + + NSFW_LOGINF ("hbt stop!]ps_info=%p,pid=%d,type=%d", pps_info, + pps_info->host_pid, pps_info->proc_type); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_ps_iterator +* Description : get all ps_info process by fun +* Input : nsfw_ps_proc_fun fun +* void* argv +* Output : None +* Return Value : u32 +* Calls : +* Called By : +*****************************************************************************/ +u32 +nsfw_ps_iterator (nsfw_ps_proc_fun fun, void *argv) +{ + u32 count = 0; + nsfw_ps_info *pps_info = NULL; + struct list_head *tNode; + + if (NULL == fun) + { + NSFW_LOGERR ("fun null!"); + return count; + } + + LINT_LIST ()list_for_each_entry (pps_info, tNode, (&g_ps_runing_list), node) + { + (void) fun (pps_info, argv); + count++; + } + + NSFW_LOGINF ("proc pid]count=%u", count); + return count; +} + +int +filter (const struct dirent *dir) +{ + return !fnmatch ("[1-9]*", dir->d_name, 0); +} + +/***************************************************************************** +* Prototype : nsfw_ps_realloc_pid +* Description : realloc pid +* Input : u32 pid +* Output : None +* Return Value : inline nsfw_ps_info* +* Calls : +* Called By : +*****************************************************************************/ +inline nsfw_ps_info * +nsfw_ps_realloc_pid (u32 pid, u8 realloc_flg) +{ + nsfw_ps_info *pps_info = NULL; + if (pid >= NSFW_MAX_PID) + { + return NULL; + } + + if (g_ps_info[pid].ps_info == NULL) + { + return NULL; + } + + if (TRUE == realloc_flg) + { + pps_info = nsfw_ps_info_alloc (pid, g_ps_info[pid].proc_type); + if (NULL == pps_info) + { + NSFW_LOGERR ("alloc ps_info failed!]pid=%u,type=%u", pid, + g_ps_info[pid].proc_type); + return NULL; + } + } + else + { + pps_info = g_ps_info[pid].ps_info; + } + + pps_info->rechk_flg = TRUE; + return pps_info; +} + +/***************************************************************************** +* Prototype : nsfw_ps_reload_pid +* Description : reload pid +* Input : None +* Output : None +* Return Value : void +* Calls : +* Called By : +*****************************************************************************/ +void +nsfw_ps_reload_pid () +{ + struct dirent **namelist; + i32 n; + u32 host_pid; + nsfw_ps_info *pps_info = NULL; + + n = scandir ("/proc", &namelist, filter, 0); + if (n < 0) + { + NSFW_LOGERR ("buf null"); + } + else + { + while (n--) + { + host_pid = strtol (namelist[n]->d_name, NULL, 10); + pps_info = nsfw_ps_info_get (host_pid); + if (NULL != pps_info) + { + pps_info->rechk_flg = FALSE; + } + free (namelist[n]); + } + free (namelist); + } + return; +} + +/***************************************************************************** +* Prototype : nsfw_ps_realloc_all_pid +* Description : realloc all pid +* Input : u32 *main_pid +* Output : None +* Return Value : void +* Calls : +* Called By : +*****************************************************************************/ +void +nsfw_ps_realloc_all_pid (u32 * main_pid, u8 realloc_flg) +{ + u32 i; + nsfw_ps_info *pps_info = NULL; + for (i = 0; i < NSFW_MAX_PID; i++) + { + pps_info = nsfw_ps_realloc_pid (i, realloc_flg); + if (NULL != main_pid) + { + if (NULL != pps_info && NSFW_PROC_MAIN == pps_info->proc_type) + { + (*main_pid) = i; + } + } + } +} + +/***************************************************************************** +* Prototype : nsfw_ps_chk_exit_timeout +* Description : chk ps info +* Input : u32 timer_type +* void* data +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_ps_chk_exit_timeout (u32 timer_type, void *data) +{ + u32 i; + nsfw_ps_info *pps_info = NULL; + u32 pid = (u64) data; + + /*main pid exit first */ + if (NULL != data) + { + pps_info = nsfw_ps_info_get (pid); + if (NULL != pps_info && TRUE == pps_info->rechk_flg) + { + if (NSFW_PS_EXITING != pps_info->state) + { + NSFW_LOGWAR ("rechk pid exit]ps_info=%p,pid=%u", pps_info, + pps_info->host_pid); + (void) nsfw_sw_ps_state (pps_info, NSFW_PS_EXITING); + pps_info->rechk_flg = FALSE; + } + } + } + + for (i = 0; i < NSFW_MAX_PID; i++) + { + pps_info = nsfw_ps_info_get (i); + if (NULL != pps_info && TRUE == pps_info->rechk_flg) + { + if (NSFW_PS_EXITING == pps_info->state) + { + NSFW_LOGWAR ("double pid info]ps_info=%p,pid=%u", pps_info, + pps_info->host_pid); + continue; + } + + NSFW_LOGWAR ("rechk pid exit]ps_info=%p,pid=%u", pps_info, + pps_info->host_pid); + (void) nsfw_sw_ps_state (pps_info, NSFW_PS_EXITING); + pps_info->rechk_flg = FALSE; + } + } + + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_ps_chk_timeout +* Description : load all running pid +* Input : u32 timer_type +* void* data +* Output : None +* Return Value : int +* Calls : +* Called By : +****************************************************************************/ +int +nsfw_ps_chk_timeout (u32 timer_type, void *data) +{ + u32 main_pid = 0; + u8 realloc_flg = (u8) (u64) data; + + nsfw_ps_realloc_all_pid (&main_pid, realloc_flg); + nsfw_ps_reload_pid (); + + struct timespec time_left = { NSFW_PS_CHK_EXIT_TVLAUE, 0 }; + g_ps_chk_timer = + (void *) nsfw_timer_reg_timer (NSFW_PS_CHK_EXIT_TVLAUE, + (void *) (u64) main_pid, + nsfw_ps_chk_exit_timeout, time_left); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_ps_rechk_pid_exit +* Description : rechck pid exit +* Input : nsfw_ps_proc_fun fun +* void* argv +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_ps_rechk_pid_exit (nsfw_ps_pid_fun fun, void *argv) +{ + u32 ulI = 0; + if (NULL == fun) + { + NSFW_LOGERR ("input err! fun null"); + return -1; + } + + u8 *ps_pid = malloc (NSFW_MAX_PID); + if (NULL == ps_pid) + { + NSFW_LOGERR ("malloc failed"); + return -1; + } + + int retval = MEMSET_S (ps_pid, NSFW_MAX_PID, 0, NSFW_MAX_PID); + if (EOK != retval) + { + NSFW_LOGERR ("MEMSET_S failed]retval=%d", retval); + free (ps_pid); + return -1; + } + + struct dirent **namelist; + i32 n; + u32 host_pid; + n = scandir ("/proc", &namelist, filter, 0); + if (n < 0) + { + NSFW_LOGERR ("buf null"); + free (ps_pid); + return -1; + } + + while (n--) + { + host_pid = strtol (namelist[n]->d_name, NULL, 10); + if (host_pid < NSFW_MAX_PID) + { + ps_pid[ulI] = TRUE; + } + free (namelist[n]); + } + free (namelist); + + int count = 0; + for (ulI = 0; ulI < NSFW_MAX_PID; ulI++) + { + if ((NULL != g_master_ps_info[ulI].ps_info) && (FALSE == ps_pid[ulI])) + { + (void) fun (ulI, g_master_ps_info[ulI].proc_type, argv); + NSFW_LOGWAR ("rechk pid exit]pid=%d,type=%d", ulI, + g_master_ps_info[ulI].proc_type); + count++; + continue; + } + } + + free (ps_pid); + return count; +} + +void +nsfw_ps_cfg_set_chk_count (u16 count) +{ + g_ps_cfg.ps_chk_hbt_count = count; +} + +/***************************************************************************** +* Prototype : nsfw_ps_module_init +* Description : ps_module init +* Input : void* param +* Output : None +* Return Value : static int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_ps_module_init (void *param) +{ + u32 proc_type = (u32) ((long long) param); + nsfw_ps_init_cfg *ps_cfg = &g_ps_cfg; + int retval; + nsfw_pid_item *pid_info = NULL; + NSFW_LOGINF ("ps module init]type=%u", proc_type); + + ps_cfg->ps_chk_hbt_count = NSFW_MAX_HBT_CHK_COUNT_DEF; + ps_cfg->ps_chk_hbt_tvalue = NSFW_CHK_HBT_TVLAUE_DEF; + ps_cfg->ps_chk_hbt_soft_count = ps_cfg->ps_chk_hbt_count; + + nsfw_mem_zone pzoneinfo; + pzoneinfo.isocket_id = NSFW_SOCKET_ANY; + pzoneinfo.stname.entype = NSFW_SHMEM; + pzoneinfo.lenth = sizeof (nsfw_pid_item) * NSFW_MAX_PID; + if (-1 == + SPRINTF_S (pzoneinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s", + "MAS_PS_INFO")) + { + NSFW_LOGERR ("SPRINTF_S failed]"); + return -1; + } + + switch (proc_type) + { + case NSFW_PROC_MASTER: + { + (void) nsfw_mgr_reg_msg_fun (MGR_MSG_CHK_HBT_RSP, + nsfw_ps_recv_hbt_rsp); + (void) NSFW_REG_SOFT_INT (NSFW_HBT_TIMER, NSFW_CHK_HBT_TVLAUE, 1, + 0xFFFF); + (void) NSFW_REG_SOFT_INT (NSFW_HBT_COUNT_PARAM, + NSFW_SOFT_HBT_CHK_COUNT, 1, 0xFFFF); + (void) NSFW_REG_SOFT_INT (NSFW_APP_EXIT_TIMER, NSFW_PS_WEXIT_TVLAUE, + 1, 0xFFFF); + + pid_info = nsfw_mem_zone_lookup (&pzoneinfo.stname); + if (NULL == pid_info) + { + pid_info = nsfw_mem_zone_create (&pzoneinfo); + if (NULL == pid_info) + { + NSFW_LOGERR ("alloc rec nul!"); + return -1; + } + + retval = + MEMSET_S (pid_info, (sizeof (nsfw_pid_item) * NSFW_MAX_PID), + 0, (sizeof (nsfw_pid_item) * NSFW_MAX_PID)); + if (EOK != retval) + { + NSFW_LOGERR ("MEMSET_S failed]retval=%d.\n", retval); + return -1; + } + } + + MEM_STAT (NSFW_PS_MODULE, pzoneinfo.stname.aname, NSFW_SHMEM, + pzoneinfo.lenth); + g_ps_info = pid_info; + break; + } + case NSFW_PROC_MAIN: + { + pid_info = malloc (sizeof (nsfw_pid_item) * NSFW_MAX_PID); + if (NULL == pid_info) + { + NSFW_LOGERR ("malloc mem failed!"); + return -1; + } + + retval = + MEMSET_S (pid_info, (sizeof (nsfw_pid_item) * NSFW_MAX_PID), 0, + (sizeof (nsfw_pid_item) * NSFW_MAX_PID)); + if (EOK != retval) + { + NSFW_LOGERR ("MEMSET_S failed]retval=%d.\n", retval); + free (pid_info); + return -1; + } + + g_ps_info = pid_info; + + pzoneinfo.stname.enowner = NSFW_PROC_MAIN; + pid_info = nsfw_mem_zone_create (&pzoneinfo); + if (NULL == pid_info) + { + NSFW_LOGERR ("create pid_info failed!"); + return -1; + } + + g_master_ps_info = pid_info; + break; + } + default: + return 0; + } + + ps_cfg->ps_info_size = NSFW_PS_INFO_MAX_COUNT; + ps_cfg->ps_waite_exit_tvalue = NSFW_PS_WEXIT_TVLAUE_DEF; + ps_cfg->net_link_buf = MAX_NET_LINK_BUF_DEF; + + INIT_LIST_HEAD (&(g_ps_runing_list)); + + nsfw_mem_sppool pmpinfo; + pmpinfo.enmptype = NSFW_MRING_MPMC; + pmpinfo.usnum = ps_cfg->ps_info_size; + pmpinfo.useltsize = sizeof (nsfw_ps_info); + pmpinfo.isocket_id = NSFW_SOCKET_ANY; + pmpinfo.stname.entype = NSFW_NSHMEM; + if (-1 == + SPRINTF_S (pmpinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s", + "MAS_PS_INFOPOOL")) + { + NSFW_LOGERR ("SPRINTF_S failed]"); + return -1; + } + + ps_cfg->ps_info_pool = nsfw_mem_sp_create (&pmpinfo); + + if (!ps_cfg->ps_info_pool) + { + NSFW_LOGERR ("alloc ps info pool_err"); + return -1; + } + + MEM_STAT (NSFW_PS_MODULE, pmpinfo.stname.aname, NSFW_NSHMEM, + nsfw_mem_get_len (ps_cfg->ps_info_pool, NSFW_MEM_SPOOL)); + + if (NSFW_PROC_MASTER != proc_type) + { + return 0; + } + + struct timespec time_left = { NSFW_PS_FIRST_CHK_TVLAUE, 0 }; + g_ps_chk_timer = + (void *) nsfw_timer_reg_timer (NSFW_PS_CHK_TIMER, (void *) TRUE, + nsfw_ps_chk_timeout, time_left); + + if (TRUE != nsfw_ps_start_netlink ()) + { + return -1; + } + + return 0; +} + +/* *INDENT-OFF* */ +NSFW_MODULE_NAME (NSFW_PS_MODULE) +NSFW_MODULE_PRIORITY (10) +NSFW_MODULE_DEPENDS (NSFW_MGR_COM_MODULE) +NSFW_MODULE_DEPENDS (NSFW_TIMER_MODULE) +NSFW_MODULE_INIT (nsfw_ps_module_init) +/* *INDENT-ON* */ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/framework/ipc/ps/nsfw_ps_module.h b/src/framework/ipc/ps/nsfw_ps_module.h new file mode 100644 index 0000000..b754cea --- /dev/null +++ b/src/framework/ipc/ps/nsfw_ps_module.h @@ -0,0 +1,99 @@ +/* +* +* 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 _NSFW_PS_MODULE_H +#define _NSFW_PS_MODULE_H + +#include "nsfw_ps_api.h" +#include "nsfw_mem_api.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +/*==============================================* + * constants or macros define * + *----------------------------------------------*/ + +#define NSFW_MAX_PID 65535 +COMPAT_PROTECT (NSFW_MAX_PID, 65535); + +#define NSFW_PS_INFO_MAX_COUNT 4095 +#define MAX_NET_LINK_BUF_DEF 0x34000*32 + +#define NSFW_PS_WEXIT_TIMER 1 +#define NSFW_PS_WEXIT_TVLAUE_DEF 180 + +#define NSFW_PS_WEXIT_TVLAUE (g_ps_cfg.ps_waite_exit_tvalue) +#define MAX_NET_LINK_BUF (g_ps_cfg.net_link_buf) + +typedef struct _nsfw_ps_init_cfg +{ + u32 ps_info_size; + u32 net_link_buf; + + u16 ps_waite_exit_tvalue; + u16 ps_chk_hbt_count; + u16 ps_chk_hbt_soft_count; + u16 ps_chk_hbt_tvalue; + + mring_handle ps_info_pool; +} nsfw_ps_init_cfg; + +#define NSFW_PS_CHK_TIMER 1 +#define NSFW_PS_FIRST_CHK_TVLAUE 1 +#define NSFW_PS_CHK_EXIT_TVLAUE 1 + +typedef struct _nsfw_pid_item +{ + u8 proc_type; + u8 u8_reserve; + u16 u16_reserve; + u32 u32_reserve; + nsfw_ps_info *ps_info; +} nsfw_pid_item; + +int nsfw_ps_change_fun (i32 epfd, i32 socket, u32 events); +u8 nsfw_sw_ps_state (nsfw_ps_info * pps_info, u8 new_state); + +/* for heartbeat checking*/ +#define NSFW_MAX_THREAD_DOGS_COUNT 8 +#define NSFW_CHK_HBT_TIMER 1 +#define NSFW_MAX_HBT_PROC_FUN 4 + +#define NSFW_CHK_HBT_TVLAUE_DEF 1 + +#define NSFW_MAX_HBT_CHK_COUNT (g_ps_cfg.ps_chk_hbt_count) +#define NSFW_SOFT_HBT_CHK_COUNT (g_ps_cfg.ps_chk_hbt_soft_count) +#define NSFW_CHK_HBT_TVLAUE (g_ps_cfg.ps_chk_hbt_tvalue) + +typedef struct _nsfw_ps_chk_msg +{ + u32 ps_state; + i32 thread_chk_count; +} nsfw_ps_chk_msg; + +int nsfw_ps_chk_timeout (u32 timer_type, void *data); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#endif /* _NSFW_PS_MODULE_H */ diff --git a/src/framework/ipc/ps/nsfw_recycle_module.c b/src/framework/ipc/ps/nsfw_recycle_module.c new file mode 100644 index 0000000..bb3844f --- /dev/null +++ b/src/framework/ipc/ps/nsfw_recycle_module.c @@ -0,0 +1,666 @@ +/* +* +* 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 "types.h" +#include "nstack_securec.h" +#include "nsfw_init.h" + +#include "nsfw_mgr_com_api.h" +#include "nsfw_mem_api.h" +#include "nsfw_ps_api.h" +#include "nsfw_ps_mem_api.h" +#include "nsfw_fd_timer_api.h" +#include "nsfw_recycle_module.h" +#include "nsfw_maintain_api.h" +#include "nstack_log.h" +#include "common_mem_api.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +/* only work on nStackMain*/ +nsfw_recycle_cfg g_rec_cfg; + +nsfw_recycle_fun g_rec_fun[NSFW_REC_TYPE_MAX] = { 0 }; + +nsfw_rec_fun_info g_rec_lock_fun[NSFW_REC_LOCK_REL_MAX_FUN]; + +/***************************************************************************** +* Prototype : nsfw_recycle_reg_fun +* Description : reg one recycle type recycle funciton +* Input : u16 rec_type +* nsfw_recycle_fun fun +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_recycle_reg_fun (u16 rec_type, nsfw_recycle_fun fun) +{ + if (NULL == fun || rec_type >= NSFW_REC_TYPE_MAX) + { + NSFW_LOGERR ("argv err]fun=%p,type=%u", fun, rec_type); + return FALSE; + } + + g_rec_fun[rec_type] = fun; + NSFW_LOGINF ("reg]fun=%d,type=%u", fun, rec_type); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_lock_rel_fun +* Description : reg lock release when app exit run +* Input : nsfw_recycle_fun fun +* void* data +* u8 proc_type: NULL as all +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_recycle_lock_rel_fun (nsfw_recycle_fun fun, void *data, u8 proc_type) +{ + if (NULL == fun) + { + NSFW_LOGERR ("argv err]fun=%p,data=%p", fun, data); + return FALSE; + } + + u32 i; + + for (i = 0; i < NSFW_REC_LOCK_REL_MAX_FUN; i++) + { + if (NULL == g_rec_lock_fun[i].rec_fun) + { + g_rec_lock_fun[i].rec_fun = fun; + g_rec_lock_fun[i].data = data; + g_rec_lock_fun[i].proc_type = proc_type; + NSFW_LOGINF ("reg mgr_msg fun suc]fun=%p,data=%p", fun, data); + return TRUE; + } + } + + NSFW_LOGINF ("reg]fun=%p,data=%p", fun, data); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_exit_pid_lock +* Description : release all lock fun +* Input : u32 pid +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_recycle_exit_pid_lock (u32 pid, u8 proc_type, void *argv) +{ + u32 i; + NSFW_LOGINF ("release lock]pid=%d,type=%d", pid, proc_type); + for (i = 0; i < NSFW_REC_LOCK_REL_MAX_FUN; i++) + { + if (NULL == g_rec_lock_fun[i].rec_fun) + { + break; + } + + if ((NSFW_PROC_NULL == g_rec_lock_fun[i].proc_type) + || (proc_type == g_rec_lock_fun[i].proc_type)) + { + (void) g_rec_lock_fun[i].rec_fun (pid, g_rec_lock_fun[i].data, 0); + } + } + + return 0; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_obj_end +* Description : one recycle object process finished notify +* Input : u32 pid +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_recycle_obj_end (u32 pid) +{ + nsfw_mgr_msg *rsp_msg = + nsfw_mgr_msg_alloc (MGR_MSG_RCC_END_REQ, NSFW_PROC_MAIN); + if (NULL == rsp_msg) + { + NSFW_LOGERR ("alloc rsp msg failed]pid=%u", pid); + return FALSE; + } + + nsfw_ps_info_msg *ps_msg = GET_USER_MSG (nsfw_ps_info_msg, rsp_msg); + ps_msg->host_pid = pid; + (void) nsfw_mgr_send_msg (rsp_msg); + nsfw_mgr_msg_free (rsp_msg); + NSFW_LOGINF ("send obj end msg]pid=%d", pid); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_callback_all_obj +* Description : process all recycle object +* Input : u32 pid +* nsfw_recycle_pool *rec_pool +* Output : None +* Return Value : nsfw_rcc_stat +* Calls : +* Called By : +*****************************************************************************/ +nsfw_rcc_stat +nsfw_recycle_callback_all_obj (u32 pid, nsfw_recycle_pool * rec_pool) +{ + u32 match = 0; + nsfw_recycle_obj *obj = NULL; + if (NULL == rec_pool) + { + return NSFW_RCC_CONTINUE; + } + + nsfw_recycle_obj *p_start = rec_pool->obj; + u32 i; + u32 size = rec_pool->pool_size; + + nsfw_ps_info *pps_info; + pps_info = nsfw_ps_info_get (pid); + if (NULL == pps_info) + { + NSFW_LOGERR ("get ps_info falied!]pid=%d", pid); + return NSFW_RCC_CONTINUE; + } + + i32 cur_idx = (i32) (u64) nsfw_ps_get_uv (pps_info, NSFW_REC_IDX); + + if (-1 == cur_idx) + { + cur_idx = 0; + nsfw_ps_set_uv (pps_info, NSFW_REC_IDX, (void *) (u64) cur_idx); + (void) nsfw_recycle_exit_pid_lock (pid, NSFW_PROC_APP, NULL); + } + else + { + cur_idx++; + nsfw_ps_set_uv (pps_info, NSFW_REC_IDX, (void *) (u64) cur_idx); + } + + for (i = cur_idx; i < size; i++) + { + obj = &p_start[i]; + cur_idx = i; + nsfw_ps_set_uv (pps_info, NSFW_REC_IDX, (void *) (u64) cur_idx); + if (FALSE == obj->alloc_flag) + { + continue; + } + + if ((obj->rec_type < NSFW_REC_TYPE_MAX) + && (NULL != g_rec_fun[obj->rec_type])) + { + match++; + if (NSFW_RCC_SUSPEND == + g_rec_fun[obj->rec_type] (pid, obj->data, obj->rec_type)) + { + NSFW_LOGINF + ("call suspend]type=%d,obj_pid=%d,pid=%d,count=%d", + obj->rec_type, obj->host_pid, pid, match); + return NSFW_RCC_SUSPEND; + } + } + else + { + NSFW_LOGERR ("obj_error!drop]type=%d,obj_pid=%d,pid=%d", + obj->rec_type, obj->host_pid, pid); + } + } + + NSFW_LOGWAR ("rec obj]pid=%d,count=%d,cur_idx=%d", pid, match, cur_idx); + return NSFW_RCC_CONTINUE; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_pid_obj +* Description : recycle object with pid +* Input : u32 pid +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_recycle_pid_obj (u32 pid) +{ + nsfw_ps_info *pps_info; + pps_info = nsfw_ps_info_get (pid); + if (NULL == pps_info) + { + NSFW_LOGERR ("get ps_info falied!]pid=%d", pid); + return FALSE; + } + + nsfw_recycle_pool *rec_pool = g_rec_cfg.mem_rec_obj_pool; + void *timer_ptr = nsfw_ps_get_uv (pps_info, NSFW_REC_TIMER); + if (NSFW_RCC_SUSPEND == nsfw_recycle_callback_all_obj (pid, rec_pool)) + { + if (NULL != timer_ptr) + { + nsfw_timer_rmv_timer (timer_ptr); + timer_ptr = NULL; + } + + struct timespec time_left = { NSFW_REC_WEND_TVLAUE, 0 }; + timer_ptr = + (void *) nsfw_timer_reg_timer (NSFW_REC_WEND_TIMER, + (void *) (u64) pid, + nsfw_recycle_obj_timeout, time_left); + nsfw_ps_set_uv (pps_info, NSFW_REC_TIMER, timer_ptr); + return TRUE; + } + + if (NULL != timer_ptr) + { + nsfw_timer_rmv_timer (timer_ptr); + nsfw_ps_set_uv (pps_info, NSFW_REC_TIMER, NULL); + } + + (void) nsfw_ps_exit_end_notify (pid); + nsfw_ps_info_free (pps_info); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_all_obj +* Description : +* Input : u32 pid +* nsfw_mem_addr_msg *addr_msg +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_recycle_all_obj (u32 pid) +{ + nsfw_ps_info *pps_info; + pps_info = nsfw_ps_info_get (pid); + if (NULL == pps_info) + { + pps_info = nsfw_ps_info_alloc (pid, NSFW_PROC_APP); + if (NULL == pps_info) + { + NSFW_LOGERR ("alloc ps_info falied!]pid=%u", pid); + return FALSE; + } + } + + nsfw_ps_set_uv (pps_info, NSFW_REC_IDX, (void *) (-1)); + nsfw_ps_set_uv (pps_info, NSFW_REC_TIMER, NULL); + return nsfw_recycle_pid_obj (pid); +} + +/***************************************************************************** +* Prototype : mem_app_exit_proc +* Description : exiting message process +* Input : nsfw_mgr_msg* msg +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +mem_app_exit_proc (nsfw_mgr_msg * msg) +{ + if (NULL == msg) + { + NSFW_LOGERR ("msg nul"); + return FALSE; + } + + nsfw_ps_info_msg *ps_info_msg = GET_USER_MSG (nsfw_ps_info_msg, msg); + + /* look up the app rec memzone and release all resource */ + /* no need to send rsp for it will be send after stack process over */ + if (TRUE == nsfw_recycle_all_obj (ps_info_msg->host_pid)) + { + NSFW_LOGINF ("obj found!]pid=%d", ps_info_msg->host_pid); + return TRUE; + } + + (void) nsfw_ps_exit_end_notify (ps_info_msg->host_pid); + return FALSE; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_obj_end_proc +* Description : obj recycle finished notify process +* Input : nsfw_mgr_msg* msg +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_recycle_obj_end_proc (nsfw_mgr_msg * msg) +{ + if (NULL == msg) + { + NSFW_LOGERR ("msg nul"); + return FALSE; + } + + nsfw_ps_info_msg *ps_info_msg = GET_USER_MSG (nsfw_ps_info_msg, msg); + + return nsfw_recycle_pid_obj (ps_info_msg->host_pid); +} + +/***************************************************************************** +* Prototype : nsfw_recycle_obj_timeout +* Description : recycle object timeout process +* Input : u32 timer_type +* void* data +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_recycle_obj_timeout (u32 timer_type, void *data) +{ + u32 pid = (u64) data; + void *timer_ptr = NULL; + NSFW_LOGINF ("ps_info timerout]pid=%u", pid); + + nsfw_ps_info *pps_info; + pps_info = nsfw_ps_info_get (pid); + if (NULL != pps_info) + { + nsfw_recycle_pool *rec_pool = g_rec_cfg.mem_rec_obj_pool; + if (NULL != rec_pool) + { + if (TRUE == g_hbt_switch) + { + struct timespec time_left = { NSFW_REC_WEND_TVLAUE, 0 }; + timer_ptr = + (void *) nsfw_timer_reg_timer (timer_type, data, + nsfw_recycle_obj_timeout, + time_left); + nsfw_ps_set_uv (pps_info, NSFW_REC_TIMER, timer_ptr); + return TRUE; + } + } + nsfw_ps_set_uv (pps_info, NSFW_REC_TIMER, timer_ptr); + } + + (void) nsfw_recycle_pid_obj (pid); + return TRUE; +} + +/***************************************************************************** +* Prototype : mem_rec_zone_init +* Description : init recycle zone in app, only work on App +* Input : None +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +mem_rec_zone_init () +{ + nsfw_mem_mring pringinfo; + pringinfo.enmptype = NSFW_MRING_MPMC; + pringinfo.isocket_id = NSFW_SOCKET_ANY; + pringinfo.stname.entype = NSFW_NSHMEM; + pringinfo.usnum = MEM_RECYCLE_PER_PRO_QUE; + u32 i; + for (i = 0; i < NSFW_REC_PRO_MAX; i++) + { + if (-1 == + SPRINTF_S (pringinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s%d", + MEM_REC_QUEUE_NAME, i)) + { + NSFW_LOGERR ("SPRINTF_S failed]"); + return FALSE; + } + g_rec_cfg.mem_rec_pro[i] = nsfw_mem_ring_create (&pringinfo); + if (NULL == g_rec_cfg.mem_rec_pro[i]) + { + NSFW_LOGERR ("alloc rec ring nul!"); + return FALSE; + } + } + + MEM_STAT (NSFW_RECYCLE_MODULE, MEM_REC_QUEUE_NAME, NSFW_NSHMEM, + NSFW_REC_PRO_MAX * nsfw_mem_get_len (g_rec_cfg.mem_rec_pro[0], + NSFW_MEM_RING)); + + nsfw_mem_zone pzoneinfo; + pzoneinfo.isocket_id = NSFW_SOCKET_ANY; + pzoneinfo.stname.entype = NSFW_NSHMEM; + pzoneinfo.lenth = + MEM_RECYCLE_OBJ_MAX_NUM * sizeof (nsfw_recycle_obj) + + sizeof (nsfw_recycle_pool); + if (-1 == + SPRINTF_S (pzoneinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s", + MEM_REC_POOL_NAME)) + { + NSFW_LOGERR ("SPRINTF_S failed]"); + return FALSE; + } + + g_rec_cfg.mem_rec_obj_pool = nsfw_mem_zone_create (&pzoneinfo); + if (NULL == g_rec_cfg.mem_rec_obj_pool) + { + NSFW_LOGERR ("alloc rec pool nul!"); + return FALSE; + } + + MEM_STAT (NSFW_RECYCLE_MODULE, MEM_REC_POOL_NAME, NSFW_NSHMEM, + pzoneinfo.lenth); + + int retval; + retval = + MEMSET_S (g_rec_cfg.mem_rec_obj_pool, pzoneinfo.lenth, 0, + pzoneinfo.lenth); + if (EOK != retval) + { + NSFW_LOGERR ("mem set init failed!"); + return FALSE; + } + + i32 j; + nsfw_recycle_pool *rec_pool = + (nsfw_recycle_pool *) g_rec_cfg.mem_rec_obj_pool; + rec_pool->pool_size = MEM_RECYCLE_OBJ_MAX_NUM; + + nsfw_recycle_obj *p_start = rec_pool->obj; + for (i = 0; i < NSFW_REC_PRO_MAX; i++) + { + for (j = 0; j < MEM_RECYCLE_PER_PRO_QUE; j++) + { + if (FALSE == p_start[j].alloc_flag) + { + if (0 == + nsfw_mem_ring_enqueue (g_rec_cfg.mem_rec_pro[i], + &p_start[j])) + { + NSFW_LOGERR ("enqueue failed"); + break; + } + } + } + p_start = p_start + MEM_RECYCLE_PER_PRO_QUE; + } + + NSFW_LOGINF ("init rec pool and ring suc!"); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_reg_obj +* Description : reg one recycle object +* Input : u8 priority +* u16 rec_type +* void* data +* Output : None +* Return Value : void * +* Calls : +* Called By : +*****************************************************************************/ +void * +nsfw_recycle_reg_obj (u8 priority, u16 rec_type, void *data) +{ + if (NSFW_REC_PRO_MAX <= priority) + { + NSFW_LOGERR ("pro error]priority=%d,rec_type=%d,data=%p", priority, + rec_type, data); + return NULL; + } + + nsfw_recycle_obj *obj = NULL; + if (0 == + nsfw_mem_ring_dequeue (g_rec_cfg.mem_rec_pro[priority], (void *) &obj)) + { + NSFW_LOGERR ("dequeue error]priority=%d,rec_type=%d,data=%p", + priority, rec_type, data); + return NULL; + } + + if (EOK != MEMSET_S (obj, sizeof (*obj), 0, sizeof (*obj))) + { + if (0 == nsfw_mem_ring_enqueue (g_rec_cfg.mem_rec_pro[priority], obj)) + { + NSFW_LOGERR ("enqueue error]priority=%d,rec_type=%d,data=%p", + priority, rec_type, data); + } + + NSFW_LOGERR ("mem set error]priority=%d,rec_type=%d,data=%p", + priority, rec_type, data); + return NULL; + } + + obj->alloc_flag = TRUE; + obj->rec_type = rec_type; + obj->data = data; + obj->host_pid = get_sys_pid (); + obj->alloc_flag = TRUE; + NSFW_LOGINF ("en queue obj]priority=%d,rec_type=%d,data=%p", priority, + rec_type, data); + return obj; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_rechk_lock +* Description : add for rechk lock +* Input : None +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_recycle_rechk_lock () +{ + return nsfw_ps_rechk_pid_exit (nsfw_recycle_exit_pid_lock, NULL); +} + +/***************************************************************************** +* Prototype : nsfw_recycle_module_init +* Description : module init +* Input : void* param +* Output : None +* Return Value : static int +* Calls : +* Called By : +*****************************************************************************/ +NSTACK_STATIC int nsfw_recycle_module_init (void *param); +NSTACK_STATIC int +nsfw_recycle_module_init (void *param) +{ + u32 proc_type = (u32) ((long long) param); + NSFW_LOGINF ("recycle module init]type=%d", proc_type); + g_rec_cfg.rec_waite_end_tvalue = NSFW_REC_WEND_TVLAUE_DEF; + switch (proc_type) + { + case NSFW_PROC_MASTER: + return 0; + case NSFW_PROC_MAIN: + (void) nsfw_mgr_reg_msg_fun (MGR_MSG_APP_EXIT_REQ, mem_app_exit_proc); + (void) nsfw_mgr_reg_msg_fun (MGR_MSG_RCC_END_REQ, + nsfw_recycle_obj_end_proc); + if (TRUE == mem_rec_zone_init ()) + { + return 0; + } + + return 0; + default: + if (proc_type < NSFW_PROC_MAX) + { + break; + } + return -1; + } + + return 0; +} + +/***************************************************************************** +* Prototype : nsfw_recycle_fork_init +* Description : fork init +* Input : None +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_recycle_fork_init () +{ + /* reconnect to master after fork in child proc */ + nsfw_mgr_close_dst_proc (NSFW_PROC_MAIN, 0); + nsfw_mgr_close_dst_proc (NSFW_PROC_MASTER, 0); + if (0 == nsfw_recycle_module_init ((void *) ((long long) NSFW_PROC_APP))) + { + return TRUE; + } + return FALSE; +} + +/* *INDENT-OFF* */ +NSFW_MODULE_NAME (NSFW_RECYCLE_MODULE) +NSFW_MODULE_PRIORITY (10) +NSFW_MODULE_DEPENDS (NSFW_PS_MEM_MODULE) +NSFW_MODULE_INIT (nsfw_recycle_module_init) +/* *INDENT-ON* */ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/framework/ipc/ps/nsfw_recycle_module.h b/src/framework/ipc/ps/nsfw_recycle_module.h new file mode 100644 index 0000000..694c1d2 --- /dev/null +++ b/src/framework/ipc/ps/nsfw_recycle_module.h @@ -0,0 +1,84 @@ +/* +* +* 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 _NSFW_RECYCLE_MODULE_H +#define _NSFW_RECYCLE_MODULE_H + +#include "nsfw_recycle_api.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#define MEM_RECYCLE_PER_PRO_QUE 128 +#define MEM_RECYCLE_OBJ_MAX_NUM (MEM_RECYCLE_PER_PRO_QUE*NSFW_REC_PRO_MAX) + +#define MEM_REC_POOL_NAME "APP_REC_POOL" +#define MEM_REC_QUEUE_NAME "APP_REC_RINGQ" + +#define REC_POOL_MAGIC_FLAG 0xDBFC01A600000000 + +#define NSFW_REC_WEND_TIMER 1 +#define NSFW_REC_WEND_TVLAUE_DEF 60 + +#define NSFW_REC_WEND_TVLAUE (g_rec_cfg.rec_waite_end_tvalue) + +typedef struct _nsfw_recycle_obj +{ + u8 alloc_flag; + u8 u8reserve; + u16 rec_type; + u32 host_pid; + void *data; + u64 u64reserve; +} nsfw_recycle_obj; + +#define NSFW_REC_LOCK_REL_MAX_FUN 32 + +typedef struct _nsfw_rec_fun_info +{ + nsfw_recycle_fun rec_fun; + void *data; + u8 proc_type; +} nsfw_rec_fun_info; + +typedef struct _nsfw_recycle_pool +{ + u32 pool_size; + nsfw_recycle_obj obj[0]; +} nsfw_recycle_pool; + +typedef struct _nsfw_recycle_cfg +{ + u16 rec_waite_end_tvalue; + mring_handle mem_rec_obj_pool; + mzone_handle mem_rec_pro[NSFW_REC_PRO_MAX]; +} nsfw_recycle_cfg; + +extern nsfw_rcc_stat nsfw_recycle_callback_all_obj (u32 pid, + nsfw_recycle_pool * + rec_pool); +extern int nsfw_recycle_obj_timeout (u32 timer_type, void *data); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#endif /* _NSFW_RECYCLE_MODULE_H */ diff --git a/src/framework/ipc/ps/nsfw_soft_param.c b/src/framework/ipc/ps/nsfw_soft_param.c new file mode 100644 index 0000000..d458040 --- /dev/null +++ b/src/framework/ipc/ps/nsfw_soft_param.c @@ -0,0 +1,296 @@ +/* +* +* 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 header files * + *----------------------------------------------*/ + +#include +#include "types.h" +#include "nstack_securec.h" +#include "nsfw_init.h" + +#include "nstack_log.h" +#include "nsfw_maintain_api.h" + +#include "nsfw_mem_api.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +typedef struct _nsfw_set_soft_item +{ + void *data; + u32 size; + u64 max; + u64 min; +} nsfw_set_soft_item; + +/* *INDENT-OFF* */ +nsfw_set_soft_fun g_soft_fun[NSFW_MAX_SOFT_PARAM] = { 0 }; +nsfw_set_soft_item g_soft_int_cfg[NSFW_MAX_SOFT_PARAM]; +/* *INDENT-ON* */ + +int +nsfw_isdigitstr (const char *str) +{ + if (NULL == str || '\0' == str[0]) + return 0; + + while (*str) + { + if (*str < '0' || *str > '9') + return 0; + str++; + } + return 1; +} + +u8 +nsfw_soft_param_reg_fun (u32 param_name, nsfw_set_soft_fun fun) +{ + if (NULL == fun || param_name >= NSFW_MAX_SOFT_PARAM) + { + NSFW_LOGERR ("argv err]fun=%p,type=%u", fun, param_name); + return FALSE; + } + + g_soft_fun[param_name] = fun; + NSFW_LOGINF ("reg]fun=%d,type=%u", fun, param_name); + return TRUE; +} + +int +nsfw_soft_set_int (u32 param, char *buf, u32 buf_len) +{ + u64 buf_value = 0; + if (NULL == buf || param >= NSFW_MAX_SOFT_PARAM) + { + NSFW_LOGERR ("argv err]buf=%p,param=%u", buf, param); + return FALSE; + } + + if (!nsfw_isdigitstr (buf)) + { + NSFW_LOGERR ("argv err]buf=%s,param=%u", buf, param); + return FALSE; + } + + char *parsing_end; + buf_value = (u64) strtol (buf, &parsing_end, 10); + nsfw_set_soft_item *int_item = &g_soft_int_cfg[param]; + if (NULL == int_item->data) + { + NSFW_LOGERR ("data err]buf=%s,param=%u,min=%llu,max=%llu", buf, param, int_item->min, int_item->max); //[DTS2017112402499][2017-11-24][z00316269] Issue #40, fix type dismatch + return FALSE; + } + + if (buf_value < int_item->min || buf_value > int_item->max) + { + NSFW_LOGERR ("argv err]buf=%s,param=%u,min=%llu,max=%llu", buf, param, int_item->min, int_item->max); //[DTS2017112402499][2017-11-24][z00316269] Issue #40, fix type dismatch + return FALSE; + } + + u32 size = int_item->size; + if (size >= sizeof (u64)) + { + size = sizeof (u64); + } + + if (EOK != MEMCPY_S (int_item->data, size, &buf_value, size)) + { + NSFW_LOGERR ("MEMCPY_S failed"); + return FALSE; + } + + NSFW_LOGINF ("set soft param ok]param=%u,value=%llu,size=%u", param, + buf_value, size); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_soft_param_reg_int +* Description : reg int param set +* Input : u32 param_name +* u32 size +* u32 min +* u32 max +* u64 *data +* Output : None +* Return Value : u8 +* Calls : +* Called By : +*****************************************************************************/ +u8 +nsfw_soft_param_reg_int (u32 param_name, u32 size, u32 min, u32 max, + u64 * data) +{ + if (NULL == data || param_name >= NSFW_MAX_SOFT_PARAM) + { + NSFW_LOGERR ("argv err]data=%p,type=%u", data, param_name); + return FALSE; + } + + g_soft_int_cfg[param_name].data = data; + g_soft_int_cfg[param_name].size = size; + g_soft_int_cfg[param_name].max = max; + g_soft_int_cfg[param_name].min = min; + return nsfw_soft_param_reg_fun (param_name, nsfw_soft_set_int); +} + +void +nsfw_set_soft_para (fw_poc_type proc_type, u32 para_name, void *value, + u32 size) +{ + nsfw_mgr_msg *msg = + (nsfw_mgr_msg *) nsfw_mgr_msg_alloc (MGR_MSG_SOF_PAR_REQ, proc_type); + if (NULL == msg) + { + NSFW_LOGERR + ("nsfw_mgr_msg_alloc failed] msg type=%d, proc type=%d, para_name=%u", + MGR_MSG_SOF_PAR_REQ, proc_type, para_name); + return; + } + + nsfw_soft_param_msg *soft_msg = GET_USER_MSG (nsfw_soft_param_msg, msg); + + soft_msg->param_name = para_name; + soft_msg->rsp_code = 0; + + if (EOK != + MEMCPY_S (soft_msg->param_value, sizeof (soft_msg->param_value), + value, size)) + { + NSFW_LOGERR + ("MEMCPY_S failed] msg type=%d, proc type=%d, para_name=%u", + MGR_MSG_SOF_PAR_REQ, proc_type, para_name); + nsfw_mgr_msg_free (msg); + return; + } + + nsfw_mgr_msg *rsp = nsfw_mgr_null_rspmsg_alloc (); + if (NULL == rsp) + { + NSFW_LOGERR + ("nsfw_mgr_null_rspmsg_alloc failed] msg type=%d, proc type=%d, para_name=%u", + MGR_MSG_SOF_PAR_REQ, proc_type, para_name); + nsfw_mgr_msg_free (msg); + return; + } + + if (!nsfw_mgr_send_req_wait_rsp (msg, rsp)) + { + NSFW_LOGERR + ("can not get response] msg type=%d, proc type=%d, para_name=%u", + MGR_MSG_SOF_PAR_REQ, proc_type, para_name); + nsfw_mgr_msg_free (msg); + nsfw_mgr_msg_free (rsp); + return; + } + + nsfw_soft_param_msg *soft_rsp_msg = GET_USER_MSG (nsfw_soft_param_msg, rsp); + if (soft_rsp_msg->rsp_code != NSFW_EXIT_SUCCESS) + { + NSFW_LOGERR + ("set soft param failed] msg type=%d, proc type=%d, para_name=%u, rsp code=%u", + MGR_MSG_SOF_PAR_REQ, proc_type, para_name, soft_rsp_msg->rsp_code); + nsfw_mgr_msg_free (msg); + nsfw_mgr_msg_free (rsp); + return; + } + + NSFW_LOGINF + ("set soft param success] msg type=%d, proc type=%d, para_name=%u", + MGR_MSG_SOF_PAR_REQ, proc_type, para_name); + + nsfw_mgr_msg_free (msg); + nsfw_mgr_msg_free (rsp); + return; +} + +int +nsfw_softparam_msg_proc (nsfw_mgr_msg * msg) +{ + nsfw_mgr_msg *rsp_msg = nsfw_mgr_rsp_msg_alloc (msg); + if (NULL == rsp_msg) + { + NSFW_LOGERR ("alloc rsp failed,drop msg!" MSGINFO, PRTMSG (msg)); + return FALSE; + } + + nsfw_soft_param_msg *soft_msg = GET_USER_MSG (nsfw_soft_param_msg, msg); + nsfw_soft_param_msg *soft_rsp_msg = + GET_USER_MSG (nsfw_soft_param_msg, rsp_msg); + if ((soft_msg->param_name < NSFW_MAX_SOFT_PARAM) + && (NULL != g_soft_fun[soft_msg->param_name])) + { + soft_msg->param_value[sizeof (soft_msg->param_value) - 1] = 0; + (void) g_soft_fun[soft_msg->param_name] (soft_msg->param_name, + (char *) + soft_msg->param_value, + sizeof + (soft_msg->param_value)); + soft_rsp_msg->rsp_code = NSFW_EXIT_SUCCESS; + } + else + { + NSFW_LOGERR ("set soft failed!]soft=%u", soft_msg->param_name); + soft_rsp_msg->rsp_code = NSFW_EXIT_FAILED; + } + + (void) nsfw_mgr_send_msg (rsp_msg); + nsfw_mgr_msg_free (rsp_msg); + return TRUE; +} + +int nsfw_softparam_module_init (void *param); +int +nsfw_softparam_module_init (void *param) +{ + u8 proc_type = (u8) ((long long) param); + NSFW_LOGINF ("softparam module init]type=%u", proc_type); + switch (proc_type) + { + case NSFW_PROC_MAIN: + case NSFW_PROC_MASTER: + (void) nsfw_mgr_reg_msg_fun (MGR_MSG_SOF_PAR_REQ, + nsfw_softparam_msg_proc); + return 0; + default: + if (proc_type < NSFW_PROC_MAX) + { + break; + } + return -1; + } + + return 0; +} + +/* *INDENT-OFF* */ +NSFW_MODULE_NAME (NSFW_SOFT_PARAM_MODULE) +NSFW_MODULE_PRIORITY (99) +NSFW_MODULE_INIT (nsfw_softparam_module_init) +/* *INDENT-ON* */ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/framework/lib_common_mem/common_api.c b/src/framework/lib_common_mem/common_api.c new file mode 100644 index 0000000..b535ee6 --- /dev/null +++ b/src/framework/lib_common_mem/common_api.c @@ -0,0 +1,325 @@ +/* +* +* 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 "common_mem_api.h" +#include "common_mem_pal.h" +#include "nstack_log.h" +#include "nstack_securec.h" +#include "common_func.h" + +void +sys_sem_init_v2 (sys_sem_t_v2 sem) +{ + sem->locked = 1; +} + +/** Returns the current time in milliseconds, + * may be the same as sys_jiffies or at least based on it. */ +long +sys_now (void) +{ + struct timespec now; + + if (unlikely (0 != clock_gettime (CLOCK_MONOTONIC, &now))) + { + NSCOMM_LOGERR ("Failed to get time, errno = %d", errno); + } + + return 1000 * now.tv_sec + now.tv_nsec / 1000000; +} + +long +sys_jiffies (void) +{ + return sys_now (); +} + +err_t +sys_sem_new_v2 (sys_sem_t_v2 * sem, u8_t isUnLockd) +{ + int retVal; + if (!sem) + { + return -1; + } + *sem = malloc (sizeof (common_mem_spinlock_t)); + + if (NULL == *sem) + { + return -1; + } + else + { + retVal = + MEMSET_S (*sem, sizeof (common_mem_spinlock_t), 0, + sizeof (common_mem_spinlock_t)); + if (EOK != retVal) + { + NSCOMM_LOGERR ("MEMSET_S failed]ret=%d", retVal); + free (*sem); + *sem = NULL; + return -1; + } + common_mem_spinlock_init (*sem); + } + + if (!isUnLockd) + { + common_mem_spinlock_lock (*sem); + } + + return 0; +} + +void +sys_sem_free_v2 (sys_sem_t_v2 * sem) +{ + if ((sem != NULL) && (*sem != NULL)) + { + free (*sem); + *sem = NULL; + } + else + { + } +} + +void +sys_sem_signal_v2 (sys_sem_t_v2 * sem) +{ + common_mem_spinlock_unlock (*sem); +} + +void +sys_sem_signal_s_v2 (sys_sem_t_v2 sem) +{ + common_mem_spinlock_unlock (sem); +} + +u32_t +sys_arch_sem_trywait_v2 (sys_sem_t_v2 * sem) +{ + return (u32_t) common_mem_spinlock_trylock (*sem); +} + +u32_t +sys_arch_sem_wait_v2 (sys_sem_t_v2 * pstsem) +{ + common_mem_spinlock_lock (*pstsem); + return 0; +} + +u32_t +sys_arch_sem_wait_s_v2 (sys_sem_t_v2 sem) +{ + common_mem_spinlock_lock (sem); + return 0; +} + +volatile pid_t g_sys_host_pid = SYS_HOST_INITIAL_PID; + +/***************************************************************************** +* Prototype : get_exec_name_by_pid +* Description : get exec name by pid +* Input : pid_t pid +* char *task_name +* Output : None +* Return Value : void +* Calls : +* Called By : +*****************************************************************************/ +void +get_exec_name_by_pid (pid_t pid, char *task_name, int task_name_len) +{ + int retVal; + char path[READ_FILE_BUFLEN] = { 0 }; + char buf[READ_FILE_BUFLEN] = { 0 }; + + retVal = SPRINTF_S (path, sizeof (path), "/proc/%d/status", pid); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S failed]ret=%d", retVal); + return; + } + + FILE *fp = fopen (path, "r"); + if (NULL != fp) + { + if (fgets (buf, READ_FILE_BUFLEN - 1, fp) == NULL) + { + fclose (fp); + return; + } + fclose (fp); + +#ifdef SECUREC_LIB + retVal = SSCANF_S (buf, "%*s %s", task_name, task_name_len); +#else + retVal = SSCANF_S (buf, "%*s %s", task_name); +#endif + + if (1 != retVal) + { + NSSOC_LOGERR ("SSCANF_S failed]ret=%d", retVal); + return; + } + } +} + +pid_t +get_hostpid_from_file_one_time (u32_t pid) +{ + int retVal; + char path[READ_FILE_BUFLEN] = { 0 }; + char buf[READ_FILE_BUFLEN] = { 0 }; + char fmt[READ_FILE_BUFLEN] = { 0 }; + char out[READ_FILE_BUFLEN] = { 0 }; + char task_name[BUF_SIZE_FILEPATH] = { 0 }; + pid_t hostpid = SYS_HOST_INITIAL_PID; + get_exec_name_by_pid (pid, task_name, BUF_SIZE_FILEPATH); + + retVal = SPRINTF_S (fmt, sizeof (fmt), "%s%s", task_name, " (%s"); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S failed]ret=%d", retVal); + return hostpid; + } + retVal = SPRINTF_S (path, sizeof (path), "/proc/%d/sched", pid); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S failed]ret=%d", retVal); + return hostpid; + } + FILE *fp = fopen (path, "r"); + if (NULL != fp) + { + if (fgets (buf, READ_FILE_BUFLEN - 1, fp) == NULL) + { + fclose (fp); + return hostpid; + } + fclose (fp); + /* Compiler needs "fmt" to be like "%s%s" to + understand. But we have "fmt" already prepared and used here. It can + be suppressed, not an issue + */ +#pragma GCC diagnostic ignored "-Wformat-nonliteral" + retVal = SSCANF_S (buf, fmt, out, READ_FILE_BUFLEN); + if (-1 == retVal) + { + NSPOL_LOGERR ("SSCANF_S failed]ret=%d", retVal); + return hostpid; + } + } + + hostpid = (pid_t) strtol (out, NULL, 0); + if (hostpid == 0) + { + hostpid = 1; + } + + return hostpid; +} + +#define MAX_GET_PID_TIME 10 +pid_t +get_hostpid_from_file (u32_t pid) +{ + pid_t ret_pid = SYS_HOST_INITIAL_PID; + int i = 0; + ret_pid = get_hostpid_from_file_one_time (pid); + while (0 == ret_pid || ret_pid == SYS_HOST_INITIAL_PID) + { + i++; + if (i > MAX_GET_PID_TIME) + { + NSFW_LOGERR ("get pid failed]pid=%u,hostpid=%d", pid, ret_pid); + break; + } + sys_sleep_ns (0, 5000000); + ret_pid = get_hostpid_from_file_one_time (pid); + } + + return ret_pid; +} + +/***************************************************************************** +* Prototype : get_hostpid_from_file +* Description : get host pid by sub namespace pid in docker +* Input : uint32_t pid +* Output : None +* Return Value : uint32_t +* Calls : +* Called By : +*****************************************************************************/ +pid_t +sys_get_hostpid_from_file (pid_t pid) +{ + g_sys_host_pid = get_hostpid_from_file (pid); + NSCOMM_LOGDBG ("ok]cur pid=%d, input pid=%d", g_sys_host_pid, pid); + return g_sys_host_pid; +} + +pid_t +updata_sys_pid () +{ + g_sys_host_pid = SYS_HOST_INITIAL_PID; + return get_sys_pid (); +} + +/***************************************************************************** +* Prototype : get_pid_namespace +* Description : Get namespace of pid +* Input : uint32_t pid +* Output : None +* Return Value : uint64_t +* Calls : +* Called By : +*****************************************************************************/ +uint64_t +get_pid_namespace (pid_t pid) +{ + char buf[BUF_SIZE_FILEPATH] = { 0 }; + char path[BUF_SIZE_FILEPATH] = { 0 }; + const char *pstart; + int ret = 0; + if (!pid) + { + NSSOC_LOGERR ("Pid is zero!"); + return 0; + } + + ret = + SNPRINTF_S (path, sizeof (path), sizeof (path) - 1, "/proc/%d/ns/pid", + pid); + if (-1 == ret) + { + NSSOC_LOGERR ("SNPRINTF_S failed]ret=%d", ret); + return 0; + } + + ret = readlink (path, buf, sizeof (buf) - 1); + if (ret <= (int) sizeof (STR_PID)) + { + NSSOC_LOGERR ("readlink pid ns file error]ret=%d", ret); + return 0; + } + + buf[ret - 1] = 0; + pstart = &(buf[sizeof (STR_PID)]); + return strtoull (pstart, NULL, 10); +} diff --git a/src/framework/lib_common_mem/common_buf.c b/src/framework/lib_common_mem/common_buf.c new file mode 100644 index 0000000..523ce54 --- /dev/null +++ b/src/framework/lib_common_mem/common_buf.c @@ -0,0 +1,260 @@ +/* +* +* 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 +#include +#include +#include +#include +#include +#include +#include + +#include "common_mem_base_type.h" + +#include "common_mem_common.h" + +#include "common_mem_memzone.h" + +#include "common_mem_pal.h" + +#include "common_mem_mempool.h" +#include "common_mem_buf.h" + +#include "nstack_log.h" +#include "nstack_securec.h" + +#include "common_func.h" +#include "common_pal_bitwide_adjust.h" + +#define LOG_ERR 0 +#define LOG_WARN 1 +#define LOG_INFO 2 +#define LOG_DEBUG 3 +#define LOG_MAX 4 + +#define COMMON_LOG_PRINT(leve, fmt, args...) \ + if (leve <= log_levl) NSCOMM_LOGERR("===>[COMMON]"fmt, ##args); \ + +#define COMMON_PANIC(fmt) \ + NSCOMM_LOGERR("==>[COMMON_PANIC]"fmt); \ + common_dump_stack(); \ + +#define PARA1_SET(argv, tempargv, Index, para1) do {\ + retVal = STRCPY_S(tempargv[Index], PATA_STRLENT, para1);\ + if (retVal != EOK)\ + {\ + NSCOMM_LOGERR("STRCPY_S failed]ret=%d", retVal);\ + return DMM_MBUF_RET_ERR;\ + }\ + argv[Index] = tempargv[Index]; \ + Index ++; } while (0) + +#define PARA2_SET(argv, tempargv, Index, para1, para2) do {\ + retVal = STRCPY_S(tempargv[Index], PATA_STRLENT, para1); \ + if (retVal != EOK)\ + {\ + NSCOMM_LOGERR("STRCPY_S failed]ret=%d", retVal);\ + return DMM_MBUF_RET_ERR;\ + }\ + argv[Index] = tempargv[Index]; \ + Index++; \ + retVal = STRCPY_S(tempargv[Index], PATA_STRLENT, para2); \ + if (retVal != EOK)\ + {\ + NSCOMM_LOGERR("STRCPY_S failed]ret=%d", retVal);\ + return DMM_MBUF_RET_ERR;\ + }\ + argv[Index] = tempargv[Index]; \ + Index ++; } while (0) + +#define PATA_STRLENT 64 +#define PATA_NUM_MAX 12 + +int log_levl = LOG_INFO; + +int +nscomm_pal_module_init (common_mem_pal_module_info * pinfo) +{ + char tempargv[PATA_NUM_MAX][PATA_STRLENT]; + char *argv[PATA_NUM_MAX]; + char tempbuf[PATA_STRLENT]; + unsigned int Index = 0; + int ioffset = 0; + int agindex = 0; + int intmask = 0; + int retVal; + retVal = MEMSET_S (tempargv, sizeof (tempargv), '\0', sizeof (tempargv)); + if (EOK != retVal) + { + NSCOMM_LOGERR ("MEMSET_S failed]ret=%d", retVal); + return DMM_MBUF_RET_ERR; + } + retVal = MEMSET_S (argv, sizeof (argv), 0, sizeof (argv)); + if (EOK != retVal) + { + NSCOMM_LOGERR ("MEMSET_S failed]ret=%d", retVal); + return DMM_MBUF_RET_ERR; + } + if (NULL == pinfo) + { + PARA1_SET (argv, tempargv, agindex, "nStackMain"); + PARA2_SET (argv, tempargv, agindex, "-c", "0x1"); + PARA2_SET (argv, tempargv, agindex, "-n", "4"); + PARA2_SET (argv, tempargv, agindex, "-m", "2048"); + PARA1_SET (argv, tempargv, agindex, "--huge-dir=/mnt/nstackhuge"); + PARA1_SET (argv, tempargv, agindex, "--proc-type=primary"); + } + else + { + PARA1_SET (argv, tempargv, agindex, "nStackMain"); + + /*[DTS2017032711606 ][2017-04-08][z00353090] There are some unsafe function ,need to be replace with safe function */ + retVal = SPRINTF_S (tempbuf, PATA_STRLENT, "0x"); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S failed]ret=%d", ioffset); + return DMM_MBUF_RET_ERR; + } + ioffset = retVal; + for (Index = 0; Index < LCORE_MASK_MAX; Index++) + { + if (ioffset >= PATA_STRLENT) + { + NSCOMM_LOGERR ("SPRINTF_S tempbuf overflow]ioffset=%d", + ioffset); + return DMM_MBUF_RET_ERR; + } + retVal = + SPRINTF_S (&(tempbuf[ioffset]), PATA_STRLENT - ioffset, "%8u", + pinfo->ilcoremask[Index]); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S failed]ret=%d", ioffset); + return DMM_MBUF_RET_ERR; + } + ioffset = ioffset + retVal; + intmask |= pinfo->ilcoremask[Index]; + } + if (0 == intmask) + { + PARA2_SET (argv, tempargv, agindex, "-c", "0x1"); + } + else + { + PARA2_SET (argv, tempargv, agindex, "-c", tempbuf); + } + if (pinfo->ishare_mem_size > 0) + { + retVal = MEMSET_S (tempbuf, PATA_STRLENT, 0, PATA_NUM_MAX); + if (EOK != retVal) + { + NSCOMM_LOGERR ("MEMSET_S failed]ret=%d", retVal); + return DMM_MBUF_RET_ERR; + } + retVal = + SPRINTF_S (tempbuf, PATA_STRLENT, "%d", pinfo->ishare_mem_size); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S failed]ret=%d", retVal); + return DMM_MBUF_RET_ERR; + } + PARA2_SET (argv, tempargv, agindex, "-m", tempbuf); + } + + retVal = MEMSET_S (tempbuf, PATA_STRLENT, 0, PATA_NUM_MAX); + if (EOK != retVal) + { + NSCOMM_LOGERR ("MEMSET_S failed]ret=%d", retVal); + return DMM_MBUF_RET_ERR; + } + + switch (pinfo->ucproctype) + { + case DMM_PROC_T_PRIMARY: + retVal = SPRINTF_S (tempbuf, PATA_STRLENT, "--proc-type=primary"); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S failed]ret=%d", retVal); + return DMM_MBUF_RET_ERR; + } + break; + case DMM_PROC_T_SECONDARY: + retVal = SPRINTF_S (tempbuf, PATA_STRLENT, "--proc-type=secondary"); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S failed]ret=%d", retVal); + return DMM_MBUF_RET_ERR; + } + break; + case DMM_PROC_T_AUTO: + default: + retVal = SPRINTF_S (tempbuf, PATA_STRLENT, "--proc-type=auto"); + if (-1 == retVal) + { + NSCOMM_LOGERR ("SPRINTF_S failed]ret=%d", retVal); + return DMM_MBUF_RET_ERR; + } + break; + } + PARA1_SET (argv, tempargv, agindex, tempbuf); + + if (DMM_HUGTBL_DISABLE == pinfo->uchugeflag) + { + PARA1_SET (argv, tempargv, agindex, "--no-huge"); + } + } + if (common_mem_pal_init (agindex, argv) < 0) + { + COMMON_LOG_PRINT (LOG_ERR, "Cannot init pal\r\n"); + return DMM_MBUF_RET_ERR; + } + return DMM_MBUF_RET_OK; +} + +void * +nscomm_memzone_data_reserve_name (const char *name, size_t len, int socket_id) +{ + const struct common_mem_memzone *mz = NULL; + /* + rte_memzone_reserve must Call first, cause rte_memzone_reserve has a globe lock. + while proc race happen, who(calls A) got lock first will create memzone success. + others create same memzone proc will got lock after A, and rte_memzone_reserve return NULL; + so while rte_memzone_reserve return NULL we need do rte_memzone_lookup; + */ + mz = common_mem_memzone_reserve (name, len, socket_id, 0); + if (mz == NULL) + { + mz = common_mem_memzone_lookup (name); + } + + return mz ? (void *) ADDR_SHTOL (mz->addr_64) : NULL; +} + +void * +nscomm_memzone_data_lookup_name (const char *name) +{ + void *addr = NULL; + const struct common_mem_memzone *mz = NULL; + mz = common_mem_memzone_lookup (name); + if (mz == NULL) + { + return NULL; + } + addr = (void *) ADDR_SHTOL (mz->addr_64); + return addr; +} diff --git a/src/framework/lib_common_mem/common_func.c b/src/framework/lib_common_mem/common_func.c new file mode 100644 index 0000000..f68380f --- /dev/null +++ b/src/framework/lib_common_mem/common_func.c @@ -0,0 +1,205 @@ +/* +* +* 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 "common_mem_pal_memconfig.h" +#include "common_mem_mbuf.h" +#include "common_mem_common.h" +#include "nstack_log.h" +#include "common_pal_bitwide_adjust.h" + +#include "common_func.h" + +#include "nstack_securec.h" + +#define COMMON_PROCESS_MAPS "/proc/self/maps" + +int g_PrimSameFlg = 1; + +NSTACK_STATIC void **g_PrimAddr2LocalMap = NULL; +NSTACK_STATIC void *g_LocalBaseAddr = NULL; +NSTACK_STATIC void *g_LocalMaxAddr = NULL; +NSTACK_STATIC void *g_LocalCfgAddrBase = NULL; + +NSTACK_STATIC uint64_t *g_LocalAddr2PrimMap = NULL; +NSTACK_STATIC uint64_t g_PrimBaseAddr = 0; +NSTACK_STATIC uint64_t g_PrimMaxAddr = 0; +NSTACK_STATIC uint64_t g_PrimCfgAddrBase = 0; + +NSTACK_STATIC uint64_t g_LBitMask = 0; +NSTACK_STATIC int g_LBitMaskLen = 0; + +uint64_t +pal_laddr_to_shddr (void *LAddr) +{ + size_t l2pIdx; + + if (g_PrimSameFlg || LAddr == NULL) + { + return (uint64_t) LAddr; + } + + /*calculate the IDX */ + l2pIdx = (ALIGN_PTR (LAddr) - ALIGN_PTR (g_LocalBaseAddr)) >> g_LBitMaskLen; + + /*check the Hugepage Addr Rang */ + if (LAddr <= g_LocalMaxAddr && LAddr >= g_LocalBaseAddr + && g_LocalAddr2PrimMap[l2pIdx]) + { + return g_LocalAddr2PrimMap[l2pIdx] + (ALIGN_PTR (LAddr) & g_LBitMask); + } + + /*check the Cfg Mapping Addr Rang */ + if (LAddr >= g_LocalCfgAddrBase + && LAddr <= + (void *) ((char *) g_LocalCfgAddrBase + + sizeof (struct common_mem_mem_config))) + { + return g_PrimCfgAddrBase + ((char *) LAddr - + (char *) g_LocalCfgAddrBase); + } + + NSCOMM_LOGWAR + ("WARNING!!! Input invalid LAddr]LAddr=%p, g_LocalBaseAddr=%p, g_LocalMaxAddr=%p, g_LocalCfgAddrBase=%p, g_LocalCfgAddrMax=%p.", + LAddr, g_LocalBaseAddr, g_LocalMaxAddr, g_LocalCfgAddrBase, + (char *) g_LocalCfgAddrBase + sizeof (struct common_mem_mem_config)); + + return (uint64_t) LAddr; +} + +void * +pal_shddr_to_laddr (uint64_t PAddr) +{ + size_t p2lIdx; + + if (g_PrimSameFlg || PAddr == ALIGN_PTR (NULL)) + { + return (void *) PAddr; + } + + p2lIdx = (PAddr - g_PrimBaseAddr) >> g_LBitMaskLen; + /*check the Hugepage Addr Rang */ + if (PAddr <= g_PrimMaxAddr && PAddr >= g_PrimBaseAddr + && g_PrimAddr2LocalMap[p2lIdx]) + { + return (void *) ((uint64_t) g_PrimAddr2LocalMap[p2lIdx] + + (PAddr & g_LBitMask)); + } + + /*check the Cfg Mapping Addr Rang */ + if (PAddr >= g_PrimCfgAddrBase + && PAddr <= g_PrimCfgAddrBase + sizeof (struct common_mem_mem_config)) + { + return (void *) ((uint64_t) g_LocalCfgAddrBase + PAddr - + g_PrimCfgAddrBase); + } + + NSCOMM_LOGWAR + ("WARNING!!! Input invalid PAddr]PAddr=%lx, g_PrimBaseAddr=%lx, g_PrimMaxAddr=%lx, g_PrimCfgAddrBase=%lx, g_PrimCfgAddrMax=%lx.", + PAddr, g_PrimBaseAddr, g_PrimMaxAddr, g_PrimCfgAddrBase, + g_PrimCfgAddrBase + sizeof (struct common_mem_mem_config)); + + return (void *) PAddr; +} + +/*lint +e539 */ + +int +dmm_pal_addr_align () +{ + return g_PrimSameFlg; +} + +int32_t +dmm_pktmbuf_pool_iterator (struct common_mem_mempool * mp, uint32_t start, + uint32_t end, dmm_mbuf_item_fun fun, void *argv) +{ + if (NULL == mp || fun == NULL) + { + return 0; + } + + if (start >= mp->size || end <= start) + { + return 0; + } + + int32_t elm_size = mp->elt_size + mp->header_size + mp->trailer_size; + struct common_mem_mbuf *elm_mbuf = (struct common_mem_mbuf *) (mp->elt_va_start + start * elm_size + mp->header_size); /*lint !e647 */ + + uint32_t i; + uint32_t mbuf_end = COMMON_MEM_MIN (end, mp->size) - start; + for (i = 0; i < mbuf_end; i++) + { + (void) fun (elm_mbuf, argv); + elm_mbuf = (struct common_mem_mbuf *) ((char *) elm_mbuf + elm_size); + } + + return mbuf_end; +} + +void +dmm_addr_print (void) +{ + const struct common_mem_mem_config *mcfg = + common_mem_pal_get_configuration ()->mem_config; + int s; + FILE *fd; + char *ptembuf = NULL; + if (!mcfg) + { + NSCOMM_LOGERR ("mcfg is null"); + return; + } + /*printf base address */ + NSCOMM_LOGINF ("********master baseaddr begin***************"); + for (s = 0; s < COMMON_MEM_MAX_MEMSEG; ++s) + { + if ((mcfg->memseg[s].len > 0) && (mcfg->memseg[s].addr != 0)) + { + NSCOMM_LOGINF ("addr:%p, len:%u", mcfg->memseg[s].addr, + mcfg->memseg[s].len); + } + } + NSCOMM_LOGINF ("********master baseaddr end***************"); + + fd = fopen (COMMON_PROCESS_MAPS, "r"); + if (!fd) + { + NSCOMM_LOGERR ("/proc/self/maps open fail, erro:%d", errno); + return; + } + + ptembuf = (char *) malloc (BUFSIZ); + if (!ptembuf) + { + NSCOMM_LOGERR ("malloc buff failed]buff_len=%d", BUFSIZ); + fclose (fd); + return; + } + if (EOK != MEMSET_S (ptembuf, BUFSIZ, 0, BUFSIZ)) + { + NSCOMM_LOGERR ("MEMSET_S failed] buff=%p", ptembuf); + } + NSCOMM_LOGINF ("********self process addr space begin***************"); + while (fgets (ptembuf, BUFSIZ, fd) != NULL) + { + NSCOMM_LOGERR ("%s", ptembuf); + } + NSCOMM_LOGINF ("********self process addr space end*****************"); + fclose (fd); + free (ptembuf); + return; +} diff --git a/src/framework/log/nsfw_set_log.c b/src/framework/log/nsfw_set_log.c new file mode 100644 index 0000000..a4b3b92 --- /dev/null +++ b/src/framework/log/nsfw_set_log.c @@ -0,0 +1,228 @@ +/* +* +* 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 "types.h" +#include "nstack_securec.h" +#include "nsfw_init.h" + +#include "nstack_log.h" +#include "nsfw_maintain_api.h" +#include "nsfw_mem_api.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +typedef struct _nsfw_log_cfg +{ + u8 proc_type; + char master_log_path[NSFW_LOG_VALUE_LEN]; + char runing_log_path[NSFW_LOG_VALUE_LEN]; + char opr_log_path[NSFW_LOG_VALUE_LEN]; +} nsfw_log_cfg; + +nsfw_log_cfg g_log_cfg; + +const char nsfw_mas_log[NSFW_LOG_VALUE_LEN] = "maspath"; +const char nsfw_flush_name[NSFW_LOG_VALUE_LEN] = "flush"; + +enum _set_log_type +{ + SET_LOG_LEVEL = 0, + SET_LOG_FLUSH, + SET_LOG_MASTER, + SET_LOG_MAIN, + + SET_LOG_INVALID +}; + +/***************************************************************************** +* Prototype : nsfw_set_log_path +* Description : set log path +* Input : const char *param +* const char *value +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_set_log_path (const char *param, const char *value) +{ + if (NULL == param || NULL == value) + { + NSFW_LOGERR ("log param error!]param=%p,value=%p", param, value); + return FALSE; + } + + if (cmp_log_path (value)) + { + if (check_log_dir_valid (value) < 0) + { + NSFW_LOGERR ("path is invalid]value=%s", value); + return FALSE; + } + if (EOK != + STRCPY_S (g_log_cfg.master_log_path, NSFW_LOG_VALUE_LEN, value)) + { + NSFW_LOGERR ("strcpy error!"); + return FALSE; + } + + NSFW_LOGINF ("renew log path]%s", g_log_cfg.master_log_path); + nstack_modify_log_dir (g_log_cfg.master_log_path); + NSFW_LOGINF ("set log sucess]newpath=%s!", g_log_cfg.master_log_path); + return TRUE; + } + return FALSE; +} + +/***************************************************************************** +* Prototype : nsfw_flush_log_info +* Description : flush the log info +* Input : const char *param +* u8 proc_type +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_flush_log_info (const char *param, u8 proc_type) +{ + if (NULL == param) + { + NSFW_LOGERR ("log param error!]param=%p", param); + return FALSE; + } + glogFlushLogFiles (GLOG_LEVEL_DEBUG); + NSFW_LOGINF ("flush log sucess]proc_type=%u", proc_type); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_set_log_msg_proc +* Description : set log message process +* Input : nsfw_mgr_msg* msg +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +nsfw_set_log_msg_proc (nsfw_mgr_msg * msg) +{ + int ret = -1; + int status = -1; + if (NULL == msg) + { + NSFW_LOGERR ("msg nul"); + return FALSE; + } + + nsfw_set_log_msg *set_log_msg = GET_USER_MSG (nsfw_set_log_msg, msg); + + if (0 == strcmp (set_log_msg->module, nsfw_mas_log)) + { + status = SET_LOG_MASTER; + } + else if (0 == strcmp (set_log_msg->module, nsfw_flush_name)) + { + status = SET_LOG_FLUSH; + } + else if (nsfw_isdigitstr (set_log_msg->module)) + { + status = SET_LOG_LEVEL; + } + + switch (status) + { + case SET_LOG_LEVEL: + ret = setlog_level_value (set_log_msg->module, set_log_msg->log_level); + break; + case SET_LOG_FLUSH: + ret = nsfw_flush_log_info (set_log_msg->module, msg->dst_proc_type); + break; + case SET_LOG_MASTER: + ret = nsfw_set_log_path (set_log_msg->module, set_log_msg->log_level); + break; + default: + NSFW_LOGERR ("default error]status=%d,set_log_msg->module=%s", status, + set_log_msg->module); + return FALSE; + } + + nsfw_mgr_msg *rsp_msg = nsfw_mgr_rsp_msg_alloc (msg); + if (NULL == rsp_msg) + { + NSFW_LOGERR ("alloc rsp failed,drop msg!" MSGINFO, PRTMSG (msg)); + return FALSE; + } + nsfw_set_log_msg *log_rsp_msg = GET_USER_MSG (nsfw_set_log_msg, rsp_msg); + log_rsp_msg->rsp_code = ret; + (void) nsfw_mgr_send_msg (rsp_msg); + nsfw_mgr_msg_free (rsp_msg); + return TRUE; +} + +/***************************************************************************** +* Prototype : nsfw_cfg_module_init +* Description : module init +* Input : void* param +* Output : None +* Return Value : static int +* Calls : +* Called By : +*****************************************************************************/ +static int nsfw_cfg_module_init (void *param); +static int +nsfw_cfg_module_init (void *param) +{ + u8 proc_type = (u8) ((long long) param); + NSFW_LOGINF ("log cfg module init]type=%u", proc_type); + switch (proc_type) + { + case NSFW_PROC_MAIN: + case NSFW_PROC_MASTER: + (void) nsfw_mgr_reg_msg_fun (MGR_MSG_SET_LOG_REQ, + nsfw_set_log_msg_proc); + g_log_cfg.proc_type = proc_type; + return 0; + default: + if (proc_type < NSFW_PROC_MAX) + { + break; + } + return -1; + } + + return 0; +} + +/* *INDENT-OFF* */ +NSFW_MODULE_NAME (NSFW_LOG_CFG_MODULE) +NSFW_MODULE_PRIORITY (99) +NSFW_MODULE_INIT (nsfw_cfg_module_init) +/* *INDENT-ON* */ + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/framework/log/nstack_log.c b/src/framework/log/nstack_log.c new file mode 100644 index 0000000..5e8ffd4 --- /dev/null +++ b/src/framework/log/nstack_log.c @@ -0,0 +1,825 @@ +/* +* +* 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 header files * + *----------------------------------------------*/ + +#include "nstack_log.h" +#include +#include +#include +#include +#include +#include +#include "nstack_securec.h" +#include + +/*==============================================* + * constants or macros define * + *----------------------------------------------*/ + +#define FILE_NAME_LEN 256 +#define MAX_PRE_INIT_LOG_COUNT 256 +#define MAX_LOCK_RETRY_COUNT 50000 /* changed MAX_LOCK_RETRY_COUNT to 50000 to avoid function being blocked for too long */ +/* *INDENT-OFF* */ +int g_l4_dump_enable = 0; +static int pre_init_log_count = 0; +static struct pre_init_info pre_init_log[MAX_PRE_INIT_LOG_COUNT] = {{0, ""}}; +/* *INDENT-ON* */ +__thread unsigned int nstack_log_nonreentry = 0; +int ctrl_log_switch = 0; + +/*==============================================* + * project-wide global variables * + *----------------------------------------------*/ +struct nstack_logs g_nstack_logs[MAX_LOG_MODULE] = { {0, 0, 0, 0}, {0xFFFF, 0, 0, 0} }; /* Clear compile warning */ +struct log_init_para g_log_init_para = + { 50, 10, NSTACK_LOG_NAME, 10, 10, NSTACK_LOG_NAME }; +static int g_my_pro_type = LOG_PRO_INVALID; + +#define DEFAULT_LOG_CTR_TIME 5 +static struct log_ctrl_info g_log_ctrl_info[LOG_CTRL_ID_MAX]; + +/*==============================================* + * routines' or functions' implementations * + *----------------------------------------------*/ + +/* change the print level, not only has err, Begin.*/ +void +save_pre_init_log (uint32_t level, char *fmt, ...) +{ + va_list ap; + int ret = 0; + /* add pre_init_log_count rang check */ + if (level > NSLOG_DBG || pre_init_log_count >= MAX_PRE_INIT_LOG_COUNT + || pre_init_log_count < 0) + + { + return; + } + pre_init_log[pre_init_log_count].log_buffer[PRE_INIT_LOG_LENGTH - 1] = '\0'; + (void) va_start (ap, fmt); + ret = + VSNPRINTF_S (pre_init_log[pre_init_log_count].log_buffer, + PRE_INIT_LOG_LENGTH, PRE_INIT_LOG_LENGTH - 1, fmt, ap); + if (-1 == ret) + { + va_end (ap); + return; + } + va_end (ap); + pre_init_log[pre_init_log_count].level = level; + pre_init_log_count++; +} + +void +write_pre_init_log () +{ + int i = 0; + for (; i < pre_init_log_count; i++) + { + if (NSLOG_ERR == pre_init_log[i].level) + { + NSPOL_LOGERR ("pre init log: %s", pre_init_log[i].log_buffer); + } + else if (NSLOG_WAR == pre_init_log[i].level) + { + NSPOL_LOGWAR (NS_LOG_STACKX_ON, "pre init log: %s", + pre_init_log[i].log_buffer); + } + else if (NSLOG_INF == pre_init_log[i].level) + { + NSPOL_LOGINF (NS_LOG_STACKX_ON, "pre init log: %s", + pre_init_log[i].log_buffer); + } + } +} + +int +cmp_log_path (const char *path) +{ + if (NULL == path) + { + return 1; + } + + /* remove struct log_info g_nstack_log_info */ + if (NULL != g_log_init_para.mon_log_path) + { + if (strcmp (g_log_init_para.mon_log_path, path) == 0) + { + return 0; + } + } + return 1; +} + +void +get_current_time (char *buf, const int len) +{ + int retVal; + time_t cur_tick; + struct tm cur_time; + (void) time (&cur_tick); + /* add return value check, */ + if (NULL == localtime_r (&cur_tick, &cur_time)) + { + return; + } + + // from man page of localtime_r: + // tm_year The number of years since 1900. + // tm_mon The number of months since January, in the range 0 to 11. + retVal = + SNPRINTF_S (buf, len, len - 1, "%04d%02d%02d%02d%02d%02d", + cur_time.tm_year + 1900, cur_time.tm_mon + 1, + cur_time.tm_mday, cur_time.tm_hour, cur_time.tm_min, + cur_time.tm_sec); + if (-1 == retVal) + { + return; + } + buf[len - 1] = 0; +} + +/***************************************************************************** +* Prototype : nstack_setlog_level +* Description : Set global log level +* Input : int module +* uint32_t level +* Output : None +* Return Value : void +* Calls : +* Called By : +*****************************************************************************/ +void +nstack_setlog_level (int module, uint32_t level) +{ + if (MAX_LOG_MODULE <= module || module < 0) + { + return; + } + g_nstack_logs[module].level = level; +} + +/***************************************************************************** +* Prototype : nstack_log_info_check +* Description : log info check +* Input : uint32_t module +* uint32_t level +* ... +* Output : None +* Return Value : bool +* Calls : +* Called By : +*****************************************************************************/ +bool +nstack_log_info_check (uint32_t module, uint32_t level) +{ + if (MAX_LOG_MODULE <= module) + { + return false; + } + + /* no need compare module ,which is done ahead */ + if (LOG_PRO_INVALID == g_my_pro_type) + { + return false; + } + return true; +} + +/* *INDENT-OFF* */ +NSTACK_STATIC inline void init_operation_log_para() +{ + g_nstack_logs[OPERATION].file_type = LOG_TYPE_OPERATION; +} + +NSTACK_STATIC inline void init_nstack_log_para() +{ + int i = 0; + + (void)glogLevelSet(GLOG_LEVEL_DEBUG); + glogBufLevelSet(GLOG_LEVEL_WARNING); + for(; i 0) + { + nstack_setlog_level (module, logLevel); + return 0; + } + if (0 == module) + { + for ( i = 0; i < MAX_LOG_MODULE ; i++ ) + { + nstack_setlog_level(i,logLevel); + } + } + return 0; +} + + +/***************************************************************************** +* Prototype : check_log_dir_valid +* Description : check the log dir valid or not +* Input : const char *arg +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +check_log_dir_valid (const char *path) +{ + size_t length; + struct stat statbuf; + if (NULL == path) + { + return -1; + } + length = strlen (path) + 1; + if ((length <= 1) || (length > FILE_NAME_LEN)) + { + return -1; + } + + /* only write permission is allowed */ + if ((0 != access (path, W_OK))) + { + /* if path can access, use env path */ + return -1; + } + + if ((0 == lstat (path, &statbuf)) && S_ISDIR (statbuf.st_mode)) + { + return 0; + } + else + { + return -1; + } +} + + +/***************************************************************************** +* Prototype : get_app_env_log_path +* Description : called by environment-specific log init function +* Input : app_file_path, a char pointer to store the log path +* Input : app_file_size, the app_file_path size +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int +get_app_env_log_path (char *app_file_path, unsigned int app_file_size) +{ + char *pst_app_log_path_flag = NULL; + char *pst_app_log_path_string = NULL; + int log_to_file = 0; + int ret = -1; + char *app_dir = NULL; + + if ((NULL == app_file_path) || (0 == app_file_size)) + { + return 0; + } + pst_app_log_path_flag = getenv ("NSTACK_LOG_FILE_FLAG"); + if (pst_app_log_path_flag && strcmp (pst_app_log_path_flag, "1") == 0) + { + /* if set enviroment variable to 1,then output to file*/ + log_to_file = 1; + } + else + { + /* if enviroment variable is not equal 1 or + don't set this enviroment variable ,output to STDOUT */ + return 0; + } + + /* add the realpath and dir check */ + /* APP LOG can be set by user */ + pst_app_log_path_string = getenv("NSTACK_APP_LOG_PATH"); + + if ((NULL == pst_app_log_path_string) + ||(strlen (pst_app_log_path_string) > FILE_NAME_LEN - 1)) + { + goto app_default; + } + + app_dir = realpath (pst_app_log_path_string, NULL); + if (check_log_dir_valid (pst_app_log_path_string) < 0) + { + goto app_default; + } + ret = STRCPY_S (app_file_path, app_file_size, app_dir); + if(EOK != ret) + { + log_to_file = 0; + } + + free(app_dir); + return log_to_file; + +app_default: + + if ((0 == access (APP_LOG_PATH, W_OK))) + { + ret = STRCPY_S (app_file_path, app_file_size, APP_LOG_PATH); + if (EOK != ret) + { + log_to_file = 0; + } + } + else + { + log_to_file = 0; + } + + if (NULL != app_dir) + { + free (app_dir); + } + + return log_to_file; + +} + +/***************************************************************************** +* Prototype : nstack_log_init_app +* Description : called by environment-specific log init function +* Input : None +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +void +nstack_log_init_app () +{ + char *pc_temp = NULL; + int log_level = NSLOG_ERR; + int i = 0; + int file_flag = 0; + char app_log_path[FILE_NAME_LEN] = { 0 }; + + /* log alread initialized, just return */ + if (LOG_PRO_INVALID != g_my_pro_type) + { + return; + } + /* Add app log hook module init */ + nstack_log_hook_init (); + + if (0 != g_nstack_logs[NSOCKET].inited) + { + return; + } + glogInit ("APP"); + + pc_temp = getenv ("NSTACK_LOG_ON"); + if (pc_temp) + { + if (strcmp (pc_temp, "INF") == 0) + { + log_level = NSLOG_INF; + } + else if (strcmp (pc_temp, "DBG") == 0) + { + log_level = NSLOG_DBG; + } + else if (strcmp (pc_temp, "WAR") == 0) + { + log_level = NSLOG_WAR; + } + else if (strcmp (pc_temp, "ERR") == 0) + { + log_level = NSLOG_ERR; + } + else if (strcmp (pc_temp, "EMG") == 0) + { + log_level = NSLOG_EMG; + } + else + { + log_level = NSLOG_ERR; + } + + } + else + { + log_level = NSLOG_ERR; + } + + /* socket interface APP called include both stack-x and nstack module! */ + nstack_setlog_level (STACKX, log_level); + nstack_setlog_level (NSOCKET, log_level); + nstack_setlog_level (LOGRTE, log_level); + nstack_setlog_level (LOGDFX, log_level); + nstack_setlog_level (LOGFW, log_level); + nstack_setlog_level (LOGHAL, log_level); + nstack_setlog_level (LOGSBR, log_level); + + /* package the app env handle function, Begin */ + file_flag = get_app_env_log_path (app_log_path, FILE_NAME_LEN); + if ((1 == file_flag) && (strlen (app_log_path) > 0)) + { + glogDir (app_log_path); + glogBufLevelSet (GLOG_LEVEL_WARNING); + (void) glogLevelSet (GLOG_LEVEL_DEBUG); + for (i = 0; i < GLOG_LEVEL_BUTT; i++) + glogSetLogSymlink (i, ""); + nstack_log_count_set (APP_LOG_COUNT); + glogMaxLogSizeSet (APP_LOG_SIZE); + glogSetLogFilenameExtension (APP_LOG_NAME); + glogFlushLogSecsSet (FLUSH_TIME); + } + else + { + glogToStderrSet (1); + } + + for (i = 0; i < MAX_LOG_MODULE; i++) + { + g_nstack_logs[i].file_type = LOG_TYPE_APP; + } + init_log_ctrl_info (); + g_my_pro_type = LOG_PRO_APP; +#ifdef FOR_NSTACK_UT + +#else + SetGlogCtrlOpt (TRUE); +#endif + NSPOL_LOGERR ("app_nStack_version=%s", NSTACK_VERSION); + return; +} + +void +nstack_segment_error (int s) +{ + +#define BACKTRACE_SIZ 20 + void *array[BACKTRACE_SIZ]; + int size; + int i; + char **strings = NULL; + + /*if set, flush the log immediately */ + glogFlushLogFiles (GLOG_LEVEL_DEBUG); + + size = backtrace (array, BACKTRACE_SIZ); + NSPOL_LOGEMG + ("------------------DUMP_BACKTRACE[%d]--------------------------------\n", + size); + + /* easy to view signal in separate log file */ + NSPOL_LOGEMG ("Received signal s=%d", s); + + for (i = 0; i < size; i++) + { + NSPOL_LOGEMG ("[%d]:%p\n", i, array[i]); + } + strings = backtrace_symbols (array, size); + if (NULL == strings) + { + return; + } + for (i = 0; i < size; i++) + { + NSPOL_LOGEMG ("[%d]:%s\n", i, strings[i]); + } + NSPOL_LOGEMG + ("-------------------------------------------------------------------\n"); + free (strings); +} + +void +set_log_init_para (struct log_init_para *para) +{ + if (NULL == para) + + { + return; + } + if (EOK != + MEMCPY_S (&g_log_init_para, sizeof (struct log_init_para), para, + sizeof (struct log_init_para))) + + { + return; + } +} + +/* control log printed counts */ +static inline void +update_log_prt_time (struct timespec *cur_time, struct timespec *log_prt_time) +{ + log_prt_time->tv_sec = cur_time->tv_sec; + log_prt_time->tv_nsec = cur_time->tv_nsec; +} + +int +check_log_prt_time (int id) +{ + struct timespec cur_time; + struct timespec *log_prt_time = NULL; + if (id >= LOG_CTRL_ID_MAX || id < 0) + + { + return 0; + } + (void) clock_gettime (CLOCK_MONOTONIC, &cur_time); + log_prt_time = &g_log_ctrl_info[id].last_log_time; + if (cur_time.tv_sec - log_prt_time->tv_sec >= + g_log_ctrl_info[id].expire_time) + { + /* first log need print */ + set_log_ctrl_time (id, DEFAULT_LOG_CTR_TIME); + update_log_prt_time (&cur_time, log_prt_time); + return 1; + } + g_log_ctrl_info[id].unprint_count++; + return 0; +} + +int +get_unprt_log_count (int id) +{ + return g_log_ctrl_info[id].unprint_count; +} + +void +clr_unprt_log_count (int id) +{ + g_log_ctrl_info[id].unprint_count = 0; +} + +void +set_log_ctrl_time (int id, int ctrl_time) +{ + if (id >= LOG_CTRL_ID_MAX || id < 0) + { + return; + } + + if (ctrl_time <= 0) + { + return; + } + + g_log_ctrl_info[id].expire_time = ctrl_time; +} + +void +init_log_ctrl_info () +{ + int i = 0; + for (; i < LOG_CTRL_ID_MAX; i++) + { + /* first log need print */ + g_log_ctrl_info[i].expire_time = 0; + g_log_ctrl_info[i].unprint_count = 0; + g_log_ctrl_info[i].last_log_time.tv_sec = 0; + g_log_ctrl_info[i].last_log_time.tv_nsec = 0; + } + + // for every socket api, need different log id + + // for nstack inner +} + +void +set_log_proc_type (int log_proc_type) +{ + g_my_pro_type = log_proc_type; +} diff --git a/src/framework/snapshot/fw_snapshot.c b/src/framework/snapshot/fw_snapshot.c new file mode 100644 index 0000000..790ecbf --- /dev/null +++ b/src/framework/snapshot/fw_snapshot.c @@ -0,0 +1,483 @@ +/* +* +* 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_securec.h" +#include "nsfw_snapshot.h" +#include "nstack_log.h" +#include "fw_ss_tlv.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +/* *INDENT-OFF* */ +nsfw_ss_objDescManager_t g_nsfw_ss_objDescManager = +{ +.g_nsfw_ss_objDesNum = 0}; + +/* *INDENT-ON* */ + +void +nsfw_ss_register_ObjDesc (nsfw_ss_objDesc_t * objDesc) +{ + if (objDesc == NULL) + return; + nsfw_ss_objDescManager_t *manager = nsfw_ss_getObjDescManagerInst (); + if (manager->g_nsfw_ss_objDesNum >= NSFW_SS_MAX_OBJDESC_NUM) + return; + manager->g_nsfw_ss_objDescs[manager->g_nsfw_ss_objDesNum++] = objDesc; +} + +static nsfw_ss_objDesc_t * +nsfw_ss_getObjDescFromType (u16 objType) +{ + nsfw_ss_objDescManager_t *manager = nsfw_ss_getObjDescManagerInst (); + int i; + for (i = 0; i < manager->g_nsfw_ss_objDesNum && i < NSFW_SS_MAX_OBJDESC_NUM; + i++) + { + if (manager->g_nsfw_ss_objDescs[i]->objType == objType) + return manager->g_nsfw_ss_objDescs[i]; + } + return NULL; +} + +static nsfw_ss_objMemDesc_t * +nsfw_ss_getMemDescFromType (u16 objType, nsfw_ss_objDesc_t * objDesc) +{ + int i; + for (i = 0; i < objDesc->memNum; i++) + { + if (objDesc->memDesc[i].type == objType) + { + return &objDesc->memDesc[i]; + } + } + return NULL; +} + +/** + * @Function nsfw_ss_store + * @Description store object to memory + * @param (in) objType - type of object with member description + * @param (in) obj - adderss of object memory + * @param (in) storeMem - address of memory to store object data + * @param (in) storeMemLen - maximal length of storage memory + * @return positive integer means length of memory cost on success. return -1 if error + */ +int +nsfw_ss_storeObjMem (u16 objMemType, void *obj, void *storeMem, + u32 storeMemLen) +{ + if (NULL == obj || NULL == storeMem) + return -1; + + // example of object + /* struct A{ */ + /* int a1; */ + /* struct A2 a2; --> struct A2 {int a2} */ + /* struct A3 a3[2]; --> struct A3 [{int a3}, {int a3}] */ + /* } */ + + /* -------------------------------------------- */ + /* | type(object) | length | */ + /* | -------------------------------------- | */// -- + /* | | type(item) | length | | */// member a1 + /* | | item value (object->member) | | */// -- + /* | -------------------------------------- | */// object a2 + /* | | type(object) | length | | */// -- + /* | | ------------------------------- | | */// member a2 + /* | | | type(item) | length | | | */// -- + /* | | | item value (object->member) | | | */// -- + /* | | ------------------------------- | | */// + /* | -------------------------------------- | */// + /* | | type(object array) | length | | */// array member a3 + /* | | ------------------------------- | | */// -- + /* | | | type(object) | length | | | */// object a3_1 + /* | | | ----------------------------| | | */// -- + /* | | | type(item) | length | | | */// member a3_1_1 + /* | | | item value (object->member) | | | */ + /* | | | ----------------------------| | | */ + /* | | ------------------------------- | | */ + /* | | | type(object) | length | | | */ + /* | | | ----------------------------| | | */ + /* | | | type(item) | length | | | */ + /* | | | item value (object->member) | | | */ + /* | | | ----------------------------| | | */ + /* | | ------------------------------- | | */ + /* | |------------------------------------| | */ + /* -------------------------------------------- */ + nsfw_ss_objDesc_t *objDesc = + nsfw_ss_getObjDescFromType (NSFW_SS_TYPE_GETOBJ (objMemType)); + if (NULL == objDesc) + return -1; + + /* Get object header tlv */ + if (storeMemLen < tlv_header_length ()) + return -1; + nsfw_ss_tlv_t *tlv = (nsfw_ss_tlv_t *) storeMem; + tlv->type = objMemType; + tlv->length = 0; + tlv_header (storeMem); + storeMemLen -= tlv_header_length (); + + /* Search every object member */ + + /* For base item(including array of base item), it should start with a tlv header */ + /* For object array, it should start with one tlv header including array information */ + /* For object, it should call nsfw_ss_store recursively */ + int i; + for (i = 0; i < objDesc->memNum; i++) + { + nsfw_ss_objMemDesc_t *memDesc = &objDesc->memDesc[i]; + if (NSFW_SS_TYPE_IS_MEMBER_OBJ (memDesc->type)) + { + + if (NSFW_SS_TYPE_IS_MEMBER_ARRAY (memDesc->type)) + { + /* array object should includes one array tlv header, shows the array informations */ + if (storeMemLen < tlv_header_length ()) + return -1; + nsfw_ss_tlv_t *arrayTlv = (nsfw_ss_tlv_t *) storeMem; + arrayTlv->type = memDesc->type; + arrayTlv->length = 0; + tlv_header (storeMem); + storeMemLen -= tlv_header_length (); + nsfw_ss_objDesc_t *memObjDesc = + nsfw_ss_getObjDescFromType (NSFW_SS_TYPE_GETOBJ + (memDesc->type)); + if (NULL == memObjDesc) + return -1; + u32 arraySize = memDesc->length / memObjDesc->objSize; + u32 j; + for (j = 0; j < arraySize; j++) + { + int ret = + nsfw_ss_storeObjMem (NSFW_SS_TYPE_SET_MEMBER_OBJ + (NSFW_SS_TYPE_GETOBJ (memDesc->type), + 0), + (char *) obj + + (u64) (memDesc->offset) + + (u64) j * memObjDesc->objSize, + storeMem, storeMemLen); + if ((-1 == ret) || (storeMemLen < (u32) ret)) + return -1; + tlv_mem_forward (storeMem, ret); + storeMemLen -= (u32) ret; + arrayTlv->length += (u32) ret; + } + tlv->length += (arrayTlv->length + (u32) tlv_header_length ()); + } + else + { + int ret = nsfw_ss_storeObjMem (memDesc->type, + ((char *) obj + memDesc->offset), + storeMem, storeMemLen); + if (ret < 0 || (storeMemLen < (u32) ret)) + return -1; + storeMemLen -= (u32) ret; + tlv_mem_forward (storeMem, ret); + tlv->length += (u32) ret; + } + } + else + { + // Base Item + if (storeMemLen < tlv_header_length ()) + { + return -1; + } + nsfw_ss_tlv_t *curtlv = (nsfw_ss_tlv_t *) storeMem; // curTlv means next tlv elem + curtlv->type = memDesc->type; + curtlv->length = memDesc->length; + tlv_header (storeMem); + storeMemLen -= tlv_header_length (); + if (storeMemLen < curtlv->length) + return -1; + if (EOK != + MEMCPY_S (storeMem, (size_t) storeMemLen, + ((char *) obj + memDesc->offset), + (size_t) memDesc->length)) + { + return -1; + } + tlv_mem_forward (storeMem, memDesc->length); + storeMemLen -= memDesc->length; + tlv->length += (curtlv->length + (u32) tlv_header_length ()); + } + } + return (int) (tlv->length + tlv_header_length ()); +} + +/** + * @Function nsfw_ss_store + * @Description store object to memory + * @param (in) objType - type of object + * @param (in) obj - adderss of object memory + * @param (in) storeMem - address of memory to store object data + * @param (in) storeMemLen - maximal length of storage memory + * @return positive integer means length of memory cost on success. return -1 if error + */ +int +nsfw_ss_store (u16 objType, void *obj, void *storeMem, u32 storeMemLen) +{ + return nsfw_ss_storeObjMem (NSFW_SS_TYPE_SET_MEMBER_OBJ (objType, 0), + obj, storeMem, storeMemLen); +} + +/** + * @Function nsfw_ss_restoreObjArray + * @Description restore array of objects + * @param (in) objType - type of object + * @param (in) objMem - object memory to restore + * @param (in) mem - memory of storage + * @param (in) storeMemLength - maximal length of storage memroy + * @return 0 on succss , -1 on error + */ +NSTACK_STATIC int +nsfw_ss_restoreObjArray (int objType, void *objMem, void *mem, + u32 storeMemLength) +{ + if (storeMemLength < tlv_header_length ()) + return -1; + nsfw_ss_tlv_t *arrayTlv = (nsfw_ss_tlv_t *) mem; + storeMemLength -= tlv_header_length (); + tlv_header (mem); + if (0 == arrayTlv->length || storeMemLength < arrayTlv->length) + return -1; + storeMemLength = arrayTlv->length; // Only cares tlv->value + nsfw_ss_objDesc_t *objDesc = nsfw_ss_getObjDescFromType ((u16) objType); + if (NULL == objDesc) + return -1; + + /* Now we are going to iterate every object */ + u32 objCnt = 0; + while (storeMemLength) + { + if (storeMemLength < tlv_header_length ()) + return -1; // Format error + nsfw_ss_tlv_t *objTlv = (nsfw_ss_tlv_t *) mem; + if ((int) NSFW_SS_TYPE_GETOBJ (objTlv->type) != objType) + { + return -1; + } + int ret = + nsfw_ss_restore ((char *) objMem + (u64) objDesc->objSize * objCnt, + mem, storeMemLength); + if (-1 == ret) + return -1; + objCnt++; + tlv_mem_forward (mem, (objTlv->length + tlv_header_length ())); + storeMemLength -= (objTlv->length + tlv_header_length ()); + } + return 0; +} + +/** + * @Function nsfw_ss_restore + * @Description restore object from memory + * @param (in) objMem - memory of object + * @param (in) mem - memory of storage + * @param (in) storeMemLen - maximal length of storage memory + * @return positive integer stands on object type, -1 on error + */ +int +nsfw_ss_restore (void *objMem, void *mem, u32 storeMemLen) +{ + if (NULL == objMem || NULL == mem || 0 == storeMemLen) + return -1; + + // example of object + /* struct A{ */ + /* int a1; */ + /* struct A2 a2; --> struct A2 {int a2} */ + /* struct A3 a3[2]; --> struct A3 [{int a3}, {int a3}] */ + /* } */ + + /* -------------------------------------------- */// -- + /* | type(object) | length | */// type length + /* | -------------------------------------- | */// -- + /* | | type(item) | length | | */// member a1 + /* | | item value (object->member) | | */// -- + /* | -------------------------------------- | */// object a2 + /* | | type(object) | length | | */// -- + /* | | ------------------------------- | | */// member a2 + /* | | | type(item) | length | | | */// -- + /* | | | item value (object->member) | | | */// -- + /* | | ------------------------------- | | */// + /* | -------------------------------------- | */// + /* | | type(object array) | length | | */// array member a3 + /* | | ------------------------------- | | */// -- + /* | | | type(object) | length | | | */// object a3_1 + /* | | | ----------------------------| | | */// -- + /* | | | type(item) | length | | | */// member a3_1_1 + /* | | | item value (object->member) | | | */ + /* | | | ----------------------------| | | */ + /* | | ------------------------------- | | */ + /* | | | type(object) | length | | | */ + /* | | | ----------------------------| | | */ + /* | | | type(item) | length | | | */ + /* | | | item value (object->member) | | | */ + /* | | | ----------------------------| | | */ + /* | | ------------------------------- | | */ + /* | |------------------------------------| | */ + /* -------------------------------------------- */ + if (storeMemLen < tlv_header_length ()) + return -1; + nsfw_ss_tlv_t *tlv = (nsfw_ss_tlv_t *) mem; + storeMemLen -= tlv_header_length (); + tlv_header (mem); + nsfw_ss_objDesc_t *objDesc = + nsfw_ss_getObjDescFromType (NSFW_SS_TYPE_GETOBJ (tlv->type)); + if (NULL == objDesc) + { + return -1; + } + if (!NSFW_SS_TYPE_IS_MEMBER_OBJ (tlv->type)) + return -1; + if (0 == tlv->length || storeMemLen < tlv->length) + return -1; + + /* Now we go to inner of object */ + storeMemLen = tlv->length; /* Only care about tlv values */ + while (storeMemLen) + { + if (storeMemLen < tlv_header_length ()) + return -1; // Format error + nsfw_ss_tlv_t *curtlv = (nsfw_ss_tlv_t *) mem; + nsfw_ss_objMemDesc_t *memDesc = + nsfw_ss_getMemDescFromType (curtlv->type, objDesc); + if (NULL == memDesc) + { // This type not support + storeMemLen -= tlv_header_length (); + tlv_header (mem); + if (storeMemLen < curtlv->length) + return -1; + tlv_mem_forward (mem, curtlv->length); + storeMemLen -= curtlv->length; + continue; + } + if (NSFW_SS_TYPE_IS_MEMBER_OBJ (curtlv->type)) + { + if (NSFW_SS_TYPE_IS_MEMBER_ARRAY (curtlv->type)) + { + int ret = + nsfw_ss_restoreObjArray ((int) + NSFW_SS_TYPE_GETOBJ (curtlv->type), + (void *) ((char *) objMem + + memDesc->offset), mem, + storeMemLen); + if (-1 == ret) + return -1; + } + else + { + int ret = + nsfw_ss_restore ((void *) ((char *) objMem + + memDesc->offset), mem, + storeMemLen); + if (-1 == ret) + return -1; + } + tlv_mem_forward (mem, (curtlv->length + tlv_header_length ())); + storeMemLen -= (curtlv->length + tlv_header_length ()); + } + else + { + tlv_header (mem); + storeMemLen -= tlv_header_length (); + NSFW_LOGDBG + ("curtlv->type(%u), curtlv->length(%u), memDesc->offset(%u), memDesc->length(%u), mem(%u)", + curtlv->type, curtlv->length, memDesc->offset, memDesc->length, + *(u32 *) mem); + if (storeMemLen < curtlv->length) + return -1; + if (EOK != + MEMCPY_S ((void *) ((char *) objMem + memDesc->offset), + (size_t) memDesc->length, mem, + (size_t) curtlv->length)) + { + return -1; + } + tlv_mem_forward (mem, curtlv->length); + storeMemLen -= curtlv->length; + } + } + return (int) tlv->type; +} + +/** + * @Function nsfw_ss_getObjStoreMemLen + * @Description Get the maximal memory it needs + * @param (in) objType - type of object + * @return length of memory needs, -1 if error + */ +int +nsfw_ss_getObjStoreMemLen (int objType) +{ + u32 maxlength = tlv_header_length (); + u32 i; + nsfw_ss_objDesc_t *objDesc = nsfw_ss_getObjDescFromType ((u16) objType); + if (!objDesc) + return -1; + for (i = 0; i < objDesc->memNum; i++) + { + nsfw_ss_objMemDesc_t *memDesc = &objDesc->memDesc[i]; + int temp_len; + if (NSFW_SS_TYPE_IS_MEMBER_OBJ (memDesc->type)) + { + nsfw_ss_objDesc_t *curObjDesc = + nsfw_ss_getObjDescFromType (NSFW_SS_TYPE_GETOBJ (memDesc->type)); + if (NULL == curObjDesc) + return -1; + if (NSFW_SS_TYPE_IS_MEMBER_ARRAY (memDesc->type)) + { + maxlength += tlv_header_length (); // array length + u32 arrSize = memDesc->length / curObjDesc->objSize; + u32 j; + for (j = 0; j < arrSize; j++) + { + temp_len = + nsfw_ss_getObjStoreMemLen ((int) curObjDesc->objType); + if (temp_len < 0) + return -1; + maxlength += (u32) temp_len; + } + } + else + { + temp_len = + nsfw_ss_getObjStoreMemLen ((int) curObjDesc->objType); + if (temp_len < 0) + return -1; + maxlength += (u32) temp_len; + } + } + else + { + maxlength += ((u32) tlv_header_length () + memDesc->length); + } + } + return (int) maxlength; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ diff --git a/src/framework/snapshot/fw_ss_tlv.h b/src/framework/snapshot/fw_ss_tlv.h new file mode 100644 index 0000000..0bfbd91 --- /dev/null +++ b/src/framework/snapshot/fw_ss_tlv.h @@ -0,0 +1,47 @@ +/* +* +* 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 _FW_SS_TLV_H +#define _FW_SS_TLV_H + +#include +#include "types.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +typedef struct _nsfw_ss_tlv +{ + u16 type; + u32 length; + void *value; +} nsfw_ss_tlv_t; + +#define tlv_header_length() ((size_t)(&((nsfw_ss_tlv_t*)0)->value)) + +#define tlv_mem_forward(mem, step) ((mem) = (void*) ((char*)(mem) + (step))) +#define tlv_header(mem) tlv_mem_forward((mem), tlv_header_length()) // move header + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#endif /* _FW_SS_TLV_H */ diff --git a/src/framework/tracing/nstack_trace.c b/src/framework/tracing/nstack_trace.c new file mode 100644 index 0000000..88c8ffb --- /dev/null +++ b/src/framework/tracing/nstack_trace.c @@ -0,0 +1,52 @@ +/* +* +* 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 header files * + *----------------------------------------------*/ +#include "nstack_trace.h" +#include "nstack_securec.h" +#include +#include + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif + +/*==============================================* + * constants or macros define * + *----------------------------------------------*/ +#define EVENT_MAX 5 +#define NSTACK_TRACE_SWICH "NSTACK_TRACE_ON" +/*==============================================* + * project-wide global variables * + *----------------------------------------------*/ +trace_fun_t nstack_trace_fun; +__thread trace_hread_t strace_header = { + .thread_id = -1, + .trace_id = TRACE_NULL, +}; + +int tracing_inited = 0; +__thread char *cad_traceID_string = NULL; + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif -- cgit