SNMP功能開發簡介 四 net-snmp動態監聽自定義端口

SNMP項目有個需求,就是能夠動態改變net-snmp監聽的端口而不需要重啓設備。關於這個功能,一開始想的是如果端口變更了,那就直接使用pthread_kill 關閉原來的代理線程,然後重新執行線程。但是這樣子測試後發現重啓的線程會自動導致整個進程退出。

模塊框架大致是這樣,進程啓動讀取配置,然後創建一個獨立的代理線程,這個線程執行net-snmp庫的啓動入口(snmpd.c/SnmpDaemonMain)。

實測發現該接口不能夠重新執行,因爲第一次執行的時候庫裏面的很多靜態變量已經初始化,在進程內這些變量只會初始化一次,所以當後續的線程重新調用net-snmp庫的入口會初始化失敗。照這樣打算以多進程的方式來實現這個功能,畢竟進程的數據是獨立的。不過這樣開發的話進程之間的通信也是一個問題,想想這個複雜度還是算了。之前分析過庫的執行代碼,對庫的運行流程有了基本的瞭解,既然是重新監聽端口,那就將之前的端口關掉,重新執行以便就好了。

如上圖所示,打開監聽端口是在init_master_agent裏面,分析了裏面的函數調用,大致流程搞清楚後,在庫裏增加了幾個接口用於更新端口:

/* 相當於關閉之前的agent */
shutdown_master_agent()

/* 關閉執行的所有會話 */
snmp_close_sessions();

/* 重新執行下列步驟來刷新端口 */

/* 重新初始化庫內部使用的一個結構體 */
_init_agent_callback_transport();


/* 因爲snmp_close_sessions 關閉了所有會話,所以這裏要重新創建 */
if (agentx_callback_sess == NULL) {
        agentx_callback_sess = netsnmp_callback_open(callback_master_num,
                                                     handle_subagent_response,
                                                     NULL, NULL);
        DEBUGMSGTL(("agentx/subagent", "subagent_init sess %p\n",
                    agentx_callback_sess));
}

接下里重新調用正常的流程就可以了
init_master_agent()

如果有其它特殊的功能需要開發並且庫自身並不支持的話,可以多看看net-snmp源碼,嘗試修改就可以了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章