suricata 各个线程干的事情 -- FlowRecyclerThread

目录

线程的初始化   

流管理逻辑处理函数

主循环

线程退出


流管理线程的创建与注册的slot 和 TmModule 对应的关系参见我的之前的一遍文章中创建非工作线程的子线程部分 参照: suricata 各个线程干的事情 -- 主线程_xuwaiwai的博客-CSDN博客

线程函数:tv->tm_func()对应的函数,TmThreadsManagement,suricata中较多的管理线程都在这个函数里执行,包括一些初始化,线程循环,线程退出。

线程的初始化   

设置线程名字和绑定cpu。

注册的模块的初始化,管理线程只注册了一个slot(即 FlowManager 模块),

初始化函数为 s->SlotThreadInit 在此对应为

static TmEcode FlowRecyclerThreadInit(ThreadVars *t, const void *initdata, void **data)

函数中执行:

static TmEcode FlowRecyclerThreadInit(ThreadVars *t, const void *initdata, void **data)
{
    FlowRecyclerThreadData *ftd = SCCalloc(1, sizeof(FlowRecyclerThreadData));
    if (ftd == NULL)
        return TM_ECODE_FAILED;
    if (OutputFlowLogThreadInit(t, NULL, &ftd->output_thread_data) != TM_ECODE_OK) {
        SCLogError(SC_ERR_THREAD_INIT, "initializing flow log API for thread failed");
        SCFree(ftd);
        return TM_ECODE_FAILED;
    }
    SCLogDebug("output_thread_data %p", ftd->output_thread_data);

    *data = ftd;
    return TM_ECODE_OK;
}

实例化一个本线程特有的结构FlowRecyclerThreadData *ftd,

初始化流日志记录器,这将为单个注册的日志程序运行线程init函数  。

状态统计数据初始化。

设置tv的flag为THV_INIT_DONE,以便主线程将此 tv->flag 的暂停标记去除。

流管理逻辑处理函数

r = s->Management(tv, SC_ATOMIC_GET(s->slot_data));

由于slot对应的是FlowManager 模块,则此函数为

static TmEcode FlowRecycler(ThreadVars *th_v, void *thread_data)

主循环

FlowRecycler函数中执行死循环

while (1)
    {
...
        SC_ATOMIC_ADD(flowrec_busy,1);
        FlowQueuePrivate list = FlowQueueExtractPrivate(&flow_recycle_q);

        const int bail = (TmThreadsCheckFlag(th_v, THV_KILL));

        /* Get the time */
        memset(&ts, 0, sizeof(ts));
        TimeGet(&ts);
        SCLogDebug("ts %" PRIdMAX "", (intmax_t)ts.tv_sec);

        Flow *f;
        while ((f = FlowQueuePrivateGetFromTop(&list)) != NULL) {
            Recycler(th_v, ftd->output_thread_data, f);
            recycled_cnt++;
        }
        SC_ATOMIC_SUB(flowrec_busy,1);

...

        if (bail) {
            break;
        }

...
        usleep(250);
...
}

在循环中每隔250微秒循环一次,取出flow_recycle_q中的流对流,并通过static void Recycler(ThreadVars *tv, void *output_thread_data, Flow *f) 函数回收。

static void Recycler(ThreadVars *tv, void *output_thread_data, Flow *f)
{
    FLOWLOCK_WRLOCK(f);

    (void)OutputFlowLog(tv, output_thread_data, f);

    FlowClearMemory (f, f->protomap);
    FLOWLOCK_UNLOCK(f);
    FlowSparePoolReturnFlow(f);
}

函数 FlowClearMemory ,清除从回收队列中摘除的Flow的信息。

然后再调用 FowSparePoolReturnFlow 函数,将上一步已经清除信息的Flow 放入到备用队列中,这个备用队列将会在workThread中新会话获取新流时被使用。

void FlowSparePoolReturnFlow(Flow *f)
{
    SCMutexLock(&flow_spare_pool_m);
    if (flow_spare_pool == NULL) {
        flow_spare_pool = FlowSpareGetPool();
    }
    DEBUG_VALIDATE_BUG_ON(flow_spare_pool == NULL);

    /* if the top is full, get a new block */
    if (flow_spare_pool->queue.len >= flow_spare_pool_block_size) {
        FlowSparePool *p = FlowSpareGetPool();
        DEBUG_VALIDATE_BUG_ON(p == NULL);
        p->next = flow_spare_pool;
        flow_spare_pool = p;
    }
    /* add to the (possibly new) top */
    FlowQueuePrivateAppendFlow(&flow_spare_pool->queue, f);
    flow_spare_pool_flow_cnt++;

    SCMutexUnlock(&flow_spare_pool_m);
}

线程退出

      执行线程退出函数,然后退出。


 凡是过往,即为序章

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值