summaryrefslogtreecommitdiffstats
path: root/src/framework/ipc/ps/nsfw_ps_module.c
diff options
context:
space:
mode:
authorqchang <qing.chang1@huawei.com>2018-03-08 17:39:22 -0800
committerqchang <qing.chang1@huawei.com>2018-03-08 17:39:22 -0800
commit697ade6190b23c80e7f60963983786e679759393 (patch)
treedd9782d1e936b8342163b26795e23571d4b1b415 /src/framework/ipc/ps/nsfw_ps_module.c
parent71a4e2f34afa8018426f0e830050e50a1de6d375 (diff)
dmm initial commit
Change-Id: I049ee277cf4efdb83f9c2ac439365fcd421c159b Signed-off-by: qchang <qing.chang1@huawei.com>
Diffstat (limited to 'src/framework/ipc/ps/nsfw_ps_module.c')
-rw-r--r--src/framework/ipc/ps/nsfw_ps_module.c1725
1 files changed, 1725 insertions, 0 deletions
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 <stdlib.h>
+#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 <errno.h>
+#include <sys/un.h>
+#include <stddef.h>
+#include <sys/epoll.h>
+#include <fcntl.h>
+
+#include <linux/cn_proc.h>
+#include <linux/connector.h>
+#include <linux/netlink.h>
+#include <dirent.h>
+#include <fnmatch.h>
+
+#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 */