/* * * 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 "nstack_securec.h" #include "nstack_log.h" #include "types.h" #include "nsfw_init_api.h" #include "alarm_api.h" #include "nsfw_mgr_com_api.h" #include "nsfw_ps_mem_api.h" #include "nsfw_ps_api.h" #include "nsfw_recycle_api.h" #include "nsfw_fd_timer_api.h" #include "nsfw_maintain_api.h" #include "nstack_dmm_adpt.h" #include "nsfw_mem_api.h" #include "nsfw_mt_config.h" #include "nsfw_shmem_mdesc.h" #include "nsfw_nshmem_mdesc.h" #define GLOBAL_Stack_ARG "stack" #define GlOBAL_HELP "--help" #define GLOBAL_Dpdk_ARG "dpdk" #define GLOBAL_STACK_PORT "-port" #define NSTACK_MAIN_MAX_PARA 32 #define NSTACK_MAIN_MIN_PARA 1 #define MAX_MASTER_OPEN_FD 1024 extern int uStackArgIndex; extern void spl_tcpip_thread(void *arg); extern int globalArgc; extern char **gArgv; extern int g_dpdk_argc; extern char **g_dpdk_argv; extern void print_call_stack(); extern int adjust_mem_arg(int argc, char *argv[]); extern struct cfg_item_info g_cfg_item_info[CFG_SEG_MAX][MAX_CFG_ITEM]; extern int get_network_json_data(); extern int get_ip_json_data(); extern nsfw_ring_ops g_ring_ops_arry_lwip[NSFW_MEM_TYPEMAX][NSFW_MPOOL_TYPEMAX]; #ifdef SYS_MEM_RES_STAT extern void get_resource_stat(); #endif extern alarm_result ms_alarm_check_func(void *para); int g_tcpip_thread_stat = 0; //this variable will be used at health check feature #if (DPDK_MODULE) extern void pal_common_usage(void); #endif typedef void (*pSignalFunc) (int); int app_init(void); void helpInfo() { NSPOL_LOGERR ("-----------------------------------------------------------------" "\nThe format of arg" "\nbash:./nStackMain RTE-ARGS stack STACK-ARGS" "\n RTE-ARGS=-c COREMASK -n NUM [-b ] [--socket-mem=MB,...] [-m MB] [-r NUM] [-v] [--file-prefix] [--proc-type ] [-- xen-dom0]" "\n STACK-ARGS=-port PORTMASK [-c COREMASK] [-thread NUM]" "\nUser examples:" "\nTo make the DPDK run on core mask:0xf,Number of memory channels per processor socket in DPDK is 3 " "\nTo make the stack run on eth coremask:f" "\nbash: ./nStackMain -c 0xf -n 3 stack -port f" "\nTo get more help info for stack:" "\n ./nStackMain --help stack" "\nTo get more help info for dpdk:" "\n ./nStackMain --help dpdk" "\n-----------------------------------------------------------------"); #ifndef FOR_NSTACK_UT exit(0); #endif } #define SIG_PTRACE __SIGRTMIN + 5 void signal_handler(int s) { NSPOL_LOGERR("Received signal exiting.]s=%d", s); if (s == SIGSEGV) /* add for gdb attach work */ { print_call_stack(); } nstack_segment_error(s); if ((SIG_PTRACE != s) && (SIG_PTRACE + 2 != s)) { #ifndef FOR_NSTACK_UT exit(0); #endif } int i; for (i = 0; i < MAX_THREAD; i++) { if (g_all_thread[i] != pthread_self() && 0 != g_all_thread[i]) { NSFW_LOGERR("send sig thread %d", g_all_thread[i]); if (0 == pthread_kill(g_all_thread[i], SIG_PTRACE + 2)) { return; } } g_all_thread[i] = 0; } for (i = 0; i < MAX_THREAD; i++) { if (0 != g_all_thread[i]) { return; } } #ifndef FOR_NSTACK_UT exit(0); #endif //dpdk_signal_handler(); } void register_signal_handler() { /* donot catch SIGHUP SIGTERM */ static const int s_need_handle_signals[] = { SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGIOT, SIGQUIT, SIGSEGV, //SIGTRAP, SIGXCPU, SIGXFSZ, //SIGALRM, //SIGHUP, SIGINT, //SIGKILL, SIGPIPE, SIGPROF, SIGSYS, //SIGTERM, SIGUSR1, SIGUSR2, //SIGVTALRM, //SIGSTOP, //SIGTSTP, //SIGTTIN, //SIGTTOU }; /* here mask signal that will use in sigwait() */ sigset_t waitset, oset; if (0 != sigemptyset(&waitset)) { NSPOL_LOGERR("sigemptyset failed."); } sigaddset(&waitset, SIGRTMIN); /* for timer */ sigaddset(&waitset, SIGRTMIN + 2); pthread_sigmask(SIG_BLOCK, &waitset, &oset); unsigned int i = 0; struct sigaction s; s.sa_handler = signal_handler; if (0 != sigemptyset(&s.sa_mask)) { NSPOL_LOGERR("sigemptyset failed."); } s.sa_flags = (int) SA_RESETHAND; /* register sig handler for more signals */ for (i = 0; i < sizeof(s_need_handle_signals) / sizeof(int); i++) { if (sigaction(s_need_handle_signals[i], &s, NULL) != 0) { NSPOL_LOGERR("Could not register %d signal handler.", s_need_handle_signals[i]); } } } void checkArgs(int argc, char **argv) { int uStackArg = 0; //mark the status whether need helpinfo and return int i; const unsigned int global_para_length = 5; //GLOBAL_Stack_ARG "stack" and GLOBAL_STACK_PORT "-port" string length, both are 5 const unsigned int global_help_length = 6; //GlOBAL_HELP "--help" string length is 6 const unsigned int global_dpdk_length = 4; //GLOBAL_Dpdk_ARG "dpdk" string length is 4 for (i = 0; i < argc; i++) { if (argc > 1) { if (strncmp(argv[i], GLOBAL_Stack_ARG, global_para_length) == 0) { if (i < 5) { NSPOL_LOGERR("Too less args"); helpInfo(); return; } uStackArg = 1; uStackArgIndex = i; continue; } if (strncmp(argv[i], GLOBAL_STACK_PORT, global_para_length) == 0) { continue; } if (strncmp(argv[i], GlOBAL_HELP, global_help_length) == 0) { if (i == (argc - 1)) { helpInfo(); return; } else if ((++i < argc) && (strncmp (argv[i], GLOBAL_Dpdk_ARG, global_dpdk_length) == 0)) { #if (DPDK_MODULE != 1) //eal_common_usage(); #else pal_common_usage(); #endif return; } else { helpInfo(); return; } } } else { NSPOL_LOGERR("Too less args"); helpInfo(); return; } } if (!uStackArg) { helpInfo(); return; } } extern u64 timer_get_threadid(); #ifdef FOR_NSTACK_UT int nstack_main(void) { int argc; char *argv[NSTACK_MAIN_MAX_PARA]; argv[0] = "nStackMain"; argv[1] = "-c";; argv[2] = "0xffffffff"; argv[3] = "-n"; argv[4] = "3"; argv[5] = "stack"; argv[6] = "-port"; argv[7] = "288"; argv[8] = "-c"; argv[9] = "2"; argc = 10; #else int main(int argc, char *argv[]) { #endif fw_poc_type proc_type = NSFW_PROC_MAIN; /* although nStackMaster has set close on exec, here can't be removed. * in upgrade senario, if Master is old which has not set close on exec, here, * if new version Main not close, problem will reappear. Add Begin*/ int i; for (i = 4; i < MAX_MASTER_OPEN_FD; i++) { close(i); } cfg_module_param config_para; config_para.proc_type = proc_type; config_para.argc = argc; config_para.argv = (unsigned char **) argv; config_module_init(&config_para); set_log_proc_type(LOG_PRO_NSTACK); (void) nstack_log_init(); // nstack_tracing_enable(); if (0 != nsfw_proc_start_with_lock(NSFW_PROC_MAIN)) { NSFW_LOGERR("another process is running!!"); return 0; } if (1 != mallopt(M_ARENA_MAX, 1)) { NSPOL_LOGERR("Error: mallopt fail, continue init"); } /* Set different mem args to PAL and EAL */ INITPOL_LOGINF("main_thread", "adjust_mem_arg init", NULL_STRING, LOG_INVALID_VALUE, MODULE_INIT_START); if (adjust_mem_arg(argc, argv)) { INITPOL_LOGERR("main_thread", "adjust_mem_arg init", NULL_STRING, LOG_INVALID_VALUE, MODULE_INIT_FAIL); return -1; } INITPOL_LOGINF("main_thread", "adjust_mem_arg init", NULL_STRING, LOG_INVALID_VALUE, MODULE_INIT_SUCCESS); checkArgs(globalArgc, gArgv); register_signal_handler(); (void) signal(SIG_PTRACE, signal_handler); (void) signal(SIG_PTRACE + 2, signal_handler); if (nsfw_mgr_comm_fd_init(NSFW_PROC_MAIN) < 0) { NSFW_LOGERR("nsfw_mgr_comm_fd_init failed"); } (void) nsfw_reg_trace_thread(pthread_self()); nsfw_mem_para stinfo = { 0 }; stinfo.iargsnum = uStackArgIndex; stinfo.pargs = gArgv; stinfo.enflag = proc_type; (void) nstack_framework_set_module_param(NSFW_MEM_MGR_MODULE, &stinfo); (void) nstack_framework_set_module_param(NSFW_MGR_COM_MODULE, (void *) ((u64) proc_type)); (void) nstack_framework_set_module_param(NSFW_TIMER_MODULE, (void *) ((u64) proc_type)); (void) nstack_framework_set_module_param(NSFW_RECYCLE_MODULE, (void *) ((u64) proc_type)); (void) nstack_framework_set_module_param(NSFW_LOG_CFG_MODULE, (void *) ((u64) proc_type)); (void) nstack_framework_set_module_param(NSFW_VER_MGR_MODULE, (void *) ((u64) proc_type)); (void) nstack_framework_set_module_param(SPL_RES_MGR_MODULE, (void *) ((u64) proc_type)); (void) nstack_framework_set_module_param(NSFW_SOFT_PARAM_MODULE, (void *) ((u64) proc_type)); (void) nstack_framework_set_module_param(NSFW_ALARM_MODULE, (void *) ((u64) proc_type)); (void) nstack_framework_set_module_param(TCPDUMP_MODULE, (void *) ((u64) proc_type)); proc_type = NSFW_PROC_MASTER; (void) nstack_framework_set_module_param(NSFW_PS_MODULE, (void *) ((u64) proc_type)); (void) nstack_framework_set_module_param(NSFW_PS_MEM_MODULE, (void *) ((u64) proc_type)); g_nsfw_mem_ops[NSFW_SHMEM].stmemop = &g_shmem_ops; g_nsfw_mem_ops[NSFW_NSHMEM].stmemop = &g_nshmem_ops; nsfw_ring_ops *ring_ops = (nsfw_ring_ops *) g_ring_ops_arry; nsfw_ring_ops *temp_ring_ops = (nsfw_ring_ops *) g_ring_ops_arry_lwip; for (i = 0; i < NSFW_MEM_TYPEMAX * NSFW_MPOOL_TYPEMAX; i++) { ring_ops[i] = *temp_ring_ops; temp_ring_ops++; } int init_ret = nstack_framework_init(); if (init_ret < 0) { NSFW_LOGERR ("######################init failed!!!!######################"); return -1; } ns_send_init_alarm(ALARM_EVENT_NSTACK_MAIN_ABNORMAL); while (!timer_get_threadid()) { (void) nsfw_thread_chk(); sys_sleep_ns(0, 500000000); } (void) nsfw_thread_chk_unreg(); NSFW_LOGINF("tcpip thread start!"); (void) sleep(2); NSFW_LOGINF("read configuration!"); if (0 != get_network_json_data()) { NSFW_LOGINF("get_network_json_data error"); return -1; } if (0 != get_ip_json_data()) { NSFW_LOGINF("get_ip_json_data error"); return -1; } int ep_thread = 0; while (1) { #ifdef SYS_MEM_RES_STAT get_resource_stat(); #endif (void) sleep(3); ep_thread = nsfw_mgr_com_chk_hbt(1); if (ep_thread > 0) { NSFW_LOGINF("force release lock"); (void) nsfw_recycle_rechk_lock(); } #ifdef FOR_NSTACK_UT return 0; #endif } }