背景
在一次项目中需要使用配置热更新的功能,所以采用了NET-SNMP官方推荐方法,增加定时读取配置的功能,参加配置如下:
repeat 1800 1.3.6.1.4.1.2021.100.11.0 = 1
刚开始配置之后,功能是正常的,但是在一夜过后,发现cpu和内存在疯狂暴涨,为了复现方便,将1800改为60,每秒加载一次配置,通过追踪token发现如下:
./snmpd -Lo -f -Ddisman:schedule
disman:schedule:conf: periodic: repeat 60 1.3.6.1.4.1.2021.100.11.0 = 1
disman:schedule:entry: creating entry (snmpd.conf, _conf001)
disman:schedule:time: periodic: (18008) Thu Jan 1 13:00:08 1970
Turning on AgentX master support.
/wns/etc/config/ap/snmp/snmp.conf: line 1: Warning: Unknown token: 0.
disman:schedule:conf: Storing schedTable:
disman:schedule:conf: done.
disman:schedule:callback: assignment iso.3.6.1.4.1.2021.100.11.0 = 1
disman:schedule:conf: periodic: repeat 60 1.3.6.1.4.1.2021.100.11.0 = 1
disman:schedule:entry: creating entry (snmpd.conf, _conf002)
disman:schedule:time: periodic: (18068) Thu Jan 1 13:01:08 1970
Turning on AgentX master support.
/wns/etc/config/ap/snmp/snmp.conf: line 1: Warning: Unknown token: 0.
disman:schedule:conf: Storing schedTable:
disman:schedule:conf: done.
disman:schedule:callback: assignment iso.3.6.1.4.1.2021.100.11.0 = 1
disman:schedule:conf: periodic: repeat 60 1.3.6.1.4.1.2021.100.11.0 = 1
disman:schedule:entry: creating entry (snmpd.conf, _conf003)
disman:schedule:time: periodic: (18128) Thu Jan 1 13:02:08 1970
Turning on AgentX master support.
/wns/etc/config/ap/snmp/snmp.conf: line 1: Warning: Unknown token: 0.
disman:schedule:conf: Storing schedTable:
disman:schedule:conf: done.
disman:schedule:callback: assignment iso.3.6.1.4.1.2021.100.11.0 = 1
disman:schedule:conf: periodic: repeat 60 1.3.6.1.4.1.2021.100.11.0 = 1
disman:schedule:entry: creating entry (snmpd.conf, _conf004)
disman:schedule:time: periodic: (18128) Thu Jan 1 13:02:08 1970
Turning on AgentX master support.
/wns/etc/config/ap/snmp/snmp.conf: line 1: Warning: Unknown token: 0.
disman:schedule:conf: Storing schedTable:
disman:schedule:conf: done.
通过跟踪代码发现:
repeat参数对应的回调在执行时会创建一个结构体让之后的一次性定时器使用,而定时器在执行时会再次调用repeat参数对应的回调,如此形成一个死循环导致内存指数型泄露。