net-snmp移植項目總結

1、       項目移植總結

1.1  交叉編譯的configure參數的配置

交叉編譯參數的設置,這個部分是最基本的,如果參數設置的有問題,snmpd運行起來就會有問題。

在x86環境下進行測試的時候,選用一個簡單的編譯參數,可以工作:

LDFLAGS="-L/home/zmj/work/LNOS/mc218/lib/x86"LIBS="-lsqlite3 -lmc218 -lpthread"CPPFLAGS="-I/home/zmj/work/LNOS/mc218/include" ./configure  --enable-shared --with-perl-modules--with-mib-modules="XXX-MIB mibII/system_mib"--prefix=/home/zmj/work/snmp

對編譯參數進行一下說明,

LDFLAGS:是要引用到的私有庫的路徑,

LIBS:是要引用的庫,

CPPFLAGS:要引用的頭文件的路徑

--with-mib-modules:要編譯進來的庫,net-snmp有一些自帶的庫,其中mibII/system_mib就是net-snmp自帶的庫,還可以加一些自定義的庫,如XXX_MIB

 

交叉編譯的時候,參數如下:

LDFLAGS="-L`pwd`/../mc218/lib/arm"LIBS="-lsqlite3 -lmc218 -lpthread" CPPFLAGS="-I`pwd`/../mc218/include" ./configure --build=i386-linux--host=arm-linux --disable-ipv6 --with-endianness=little --disable-manuals--disable-ucd-snmp-compatibility --disable-embedded-perl --without-perl-modules--disable-snmptrapd-subagent --disable-applications --disable-scripts--with-enterprise-oid=n --with-enterprise-sysoid=.1.3.6.1.4.1.x.x--enable-mini-agent --with-mib-modules="mibII/system_mib XXX-MIB"--with-sys-location="Beijing"--with-sys-contact="wyz@localhost"-with-default-snmp-version="2"--with-logfile="/var/log/snmpd.log" --with-persistent-directory="/var/net-snmp"--sysconfdir="/etc/" --disable-mib-loading  --prefix=$PREFIX

爲了在嵌入式環境當中編譯出來的文件最小,對snmp進行了一定的簡化,沒有編譯help、snmptrapd等信息,最小化snmpd,配置爲小端模式,其中--with-enterprise-oid配置的是企業號是一個整數,--with-enterprise-sysoid配置的是企業系統ID,這樣在snmp管理軟件讀取的時候才能正確顯示相關信息

1.2  編譯自定義的mib文件

具體詳情可以參見《snmp學習筆記-自定義節點的實現.docx》文檔

1.3  增加自定義的trap,inotify的使用

具體詳情可行參見《RD030-snmptrap設計文檔.docx》文檔

1.4  修改啓動daemon進程代碼的位置

在net-snmp運行的過程中發現,snmpd啓動的過程當中,如果打開調試開關,使用命令snmpd –f –Le運行snmpd,那麼snmpd發送trap是正常的,指定的服務器可以接收到trap信息。但是,如果直接打開snmpd,使用命令snmpd,則snmpd在後臺運行,這個時候發現服務器接收不到snmpd發送trap信息。

查看代碼發現,啓動daemon進程是在net-snmp-5.7.2/agent/snmpd.c文件當中入口函數main中,並且開啓daemon進程的函數netsnmp_daemonize函數是在初始化mib(init_mib_modules)之後。應該是trap的某些工作在fork之前操作,但是子進程又沒有繼承過來。導致了trap的初始化工作做的不到位。

因此修改代碼,把daemon的操作移到int_mib_modules之前去執行,這樣後面的代碼子進程就會執行一遍了。

1.5  解決發送冷啓動、熱啓動trap的問題

在net-snmp的代碼當中,默認發送coldstart告警,並且不論是冷啓動還是熱啓動,都發送coldstart告警,在net-snmp官網上查看FAQ,發現這是一個一致存在的問題,官方沒有找到解決方案。

在這個項目中,我們結合電源管理部分的特徵,在啓動的時候動一下手腳,創建一個只讀文件/proc/tsc,如果是冷重啓,那麼創建文件的時候,寫入0;否則就寫入一個不等於0的數字。這樣,我們就可以在snmpd啓動的時候(net-snmp-5.7.2/agent/snmpd.c文件main函數當中),增加一個判斷,讀取文件/proc/tsc的值,如果是0,就發送coldstart告警(send_easy_trap(0,0);)否則,發送warmstart告警(send_easy_trap(1,0);)

1.6  sysName的問題

在net-snmp當中有三個節點sysName、sysLocation、sysContact,這三個節點比較特殊,在mib文件當中可以發現這三個節點是可讀可寫的,可是在實際的應用當中發現,在snmpd啓動之後沒有/etc/snmp/snmpd.conf配置文件的時候,sysName、sysLocation、sysContact三個節點都是可讀可寫的;如果已經存在了/etc/snmp/snmpd.conf配置文件,這時候sysLocation、sysContact兩個節點是不可以寫的,sysName可以寫,但是修改的值並不對hostname造成影響,而是修改了配置文件/var/net-snmp/snmpd.conf,增加了psysName字段。

在官網的FAQ中解釋說,出於安全考慮,sysName、sysLocation、sysContact只有在配置文件不存在的情況下纔可以修改。

實際的情況跟官網有出入,就是sysName的特殊性,並且在網上也找到一些網友發出這樣的疑問,但是目前沒有得到解答。

追蹤代碼可以發現,在文件system_mib.c當中,這三個節點的更新是通過system_store函數實現,並且使用了三個特殊的變量sysLocationSet、sysContactSet、sysNameSet。就是這三個變量成爲三個節點是否可寫的開關。
目前,還沒有找到爲什麼sysName跟sysLocation和sysContact兩個節點表現不一樣,後期還需要修改。

1.7  未解決的問題

在移植net-snmp的過程當中,需要引用外部自己寫的庫,包含外部頭文件的時候發現使用相對路徑包含不成功,最終使用了絕對路徑進行引用,代碼才編譯通過,這個問題至今還沒有找到原因。

2、       總結的經驗教訓

總體來說,net-snmp的移植只要掌握了技巧,移植的過程並不是特別難,因爲net-snmp本來代碼完整,還有編譯自定義mib的軟件mib2c,所以移植的過程當中注意以下幾點:

1、   首先是自定義mib文件的形成,這個文件很重要,如果後期反覆修改的話,每次都要編譯一遍,增加了很多工作量。編寫mib文件的時候要規範,結構要清楚,否則,後期snmp服務器就無法識別,而且也不好擴展,在snmp服務器上畫面板圖等工作就不好執行。

2、   其次,根據需要設置configure參數,這個參數直接影響了移植出來的snmpd是否可以工作,需要反覆實驗。

3、   不要蠻目的相信mib2c軟件,在實際應用的過程當中,我就發現mib2c生成的代碼有出錯的情況,例如生成的XXX_interface.c文件裏面把配置只讀,還是可讀可寫的地方寫反了。當然,這樣的情況就發現一處,大部分的代碼還是正確的。實際的應用當中,自己要稍微檢查一下生成的代碼,看看是否有問題。

4、   在使用mib2c編譯自定義代碼的時候,會生成一個配置文件,當第二次編譯的時候就可以直接修改生成的配置文件,而不用一步一步的選擇配置項了。例如使用mib2c –c mib2c.mfd.conf 命令的時候,就會在snmp\share\snmp\mibs\defaults文件夾下生成配置文件table-XXX.m2d

 

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