檢視原始碼 儀器功能
每個物件的使用者定義儀器功能會將受管理的物件連接到實際資源。 此函式會在 get
或 set
操作時由代理程式呼叫。此函式可以讀取一些硬體暫存器、執行計算,或執行任何實作與概念變數相關聯的語意所需的操作。這些函式必須針對純量變數和表格編寫。它們會在關聯檔案中指定,關聯檔案是一個文字檔。在此檔案中,每個受管理物件的 OBJECT IDENTIFIER
或符號名稱會與 Erlang 元組 {Module,``Function
, ListOfExtraArguments}
相關聯。
當在 SNMP 操作中參照受管理物件時,會呼叫相關聯的 {Module, Function, ListOfExtraArguments}
。此函式會套用至一些標準引數(例如,操作類型)和使用者提供的額外引數。
儀器功能必須針對純量變數和表格的 get
和 set
編寫,且僅針對表格的 get-next
編寫。get-bulk
操作會轉換為一系列對 get-next
的呼叫。
儀器功能
以下章節說明應如何在 Erlang 中針對不同的操作定義儀器功能。在以下內容中,RowIndex
是表格的索引鍵值清單,而 Column
是一個欄號。
這些函式會在 儀器功能定義中詳細說明。
新增/刪除操作
對於純量變數
variable_access(new [, ExtraArg1, ...])
variable_access(delete [, ExtraArg1, ...])
對於表格
table_access(new [, ExtraArg1, ...])
table_access(delete [, ExtraArg1, ...])
當 MIB 分別卸載或載入時,會針對 MIB 中的每個物件呼叫這些函式。
Get 操作
對於純量變數
variable_access(get [, ExtraArg1, ...])
對於表格
table_access(get,RowIndex,Cols [,ExtraArg1, ...])
Cols
是 Column
的清單。代理程式會排序傳入的變數,以便同時提供對同一列(相同索引)的所有操作。這樣做的原因是資料庫通常會逐列擷取資訊。
這些函式必須傳回關聯變數的目前值。
Set 操作
對於純量變數
variable_access(set, NewValue [, ExtraArg1, ...])
對於表格
table_access(set, RowIndex, Cols [, ExtraArg1,..])
Cols
是元組 {Column, NewValue}
的清單。
如果指派成功,這些函式會傳回 noError
,否則會傳回錯誤碼。
Is-set-ok 操作
作為 set
操作的補充,可以指定一個測試函式。此函式具有與上述 set 操作相同的語法,不同之處在於第一個引數是 is_set_ok
而不是 set
。此函式會在設定變數之前呼叫。其目的是確保允許將變數設定為新值。
variable_access(is_set_ok, NewValue [, ExtraArg1, ...])
對於表格
table_access(set, RowIndex, Cols [, ExtraArg1,..])
Cols
是元組 {Column, NewValue}
的清單。
Undo 操作
已使用 is_set_ok
呼叫的函式會再次呼叫,如果沒有錯誤,則使用 set
,如果發生錯誤,則使用 undo
。透過這種方式,可以在 is_set_ok
操作中保留資源,在 undo
操作中釋放資源,或在 set
操作中將資源永久化。
variable_access(undo, NewValue [, ExtraArg1, ...])
對於表格
table_access(set, RowIndex, Cols [, ExtraArg1,..])
Cols
是元組 {Column, NewValue}
的清單。
GetNext 操作
GetNext 操作應僅針對表格定義,因為代理程式可以在 MIB 中找到純變數的下一個實例,並使用 get
操作呼叫儀器。
table_access(get_next, RowIndex, Cols [, ExtraArg1, ...])
Cols
是大於或等於零的整數清單。這表示儀器應尋找下一個可存取的實例。此函式會傳回元組 {NextOid, NextValue}
或 endOfTable
。NextOid
應是表格中受管理物件的詞彙下一個可存取實例。它應是一個整數清單,其中第一個整數是欄,清單的其餘部分是下一列的索引。如果傳回 endOfTable
,代理程式會繼續在其他變數和表格中搜尋下一個實例。
RowIndex
可以是空清單、未完全指定的列索引或未指定列的索引。
此操作最好用範例來說明。
GetNext 範例
名為 myTable
的表格有五個欄。前兩個是索引鍵(無法存取),表格有三列。此表格的儀器功能稱為 my_table
。
注意
不適用表示無法存取。
管理員發出以下 getNext
要求
getNext{ myTable.myTableEntry.3.1.1,
myTable.myTableEntry.5.1.1 }
由於這兩個操作都涉及 1.1 索引,因此會轉換為一次對 my_table
的呼叫
my_table(get_next, [1, 1], [3, 5])
在此呼叫中,[1, 1]
是 RowIndex
,其中索引鍵 1 的值為 1,而索引鍵 2 的值為 1,[3, 5]
是要求的欄清單。此函式現在應傳回詞彙下一個元素
[{[3, 1, 2], d}, {[5, 1, 2], f}]
這會在下表中說明
管理員現在發出以下 getNext
要求
getNext{ myTable.myTableEntry.3.2.1,
myTable.myTableEntry.5.2.1 }
這會轉換為一次對 my_table
的呼叫
my_table(get_next, [2, 1], [3, 5])
此函式現在應傳回
[{[4, 1, 1], b}, endOfTable]
這會在下表中說明
管理員現在發出以下 getNext
要求
getNext{ myTable.myTableEntry.3.1.2,
myTable.myTableEntry.4.1.2 }
這會轉換為一次對 my_table
的呼叫
my_table(get_next, [1, 2], [3, 4])
此函式現在應傳回
[{[3, 2, 1], g}, {[5, 1, 1], c}]
這會在下表中說明
管理員現在發出以下 getNext
要求
getNext{ myTable.myTableEntry,
myTable.myTableEntry.1.3.2 }
這會轉換為兩次對 my_table
的呼叫
my_table(get_next, [], [0]) and
my_table(get_next, [3, 2], [1])
此函式現在應傳回
[{[3, 1, 1], a}] and
[{[3, 1, 1], a}]
在這兩種情況下,都應傳回表格中的第一個可存取元素。由於索引鍵欄無法存取,這表示第三欄是第一列。
注意
通常,上述函式的行為與顯示的完全相同,但它們可以自由執行其他操作。例如,get 請求可能會產生副作用,例如設定其他變數,或許是全域
lastAccessed
變數。
使用額外引數
ListOfExtraArguments
可用來編寫泛型函式。此清單會附加到每個函式的標準引數。考量裝置的兩個唯讀變數,物件識別碼分別為 1.1.23.4 和 1.1.7 的 ipAdr
和 name
。若要存取這些變數,可以實作 MIB 中的兩個 Erlang 函式 ip_access
和 name_access
。可以在文字檔中指定這些函式,如下所示
{ipAdr, {my_module, ip_access, []}}.
% Or using the oid syntax for 'name'
{[1,1,7], {my_module, name_access, []}}.
ExtraArgument
參數是空清單。例如,當代理程式收到對 ipAdr
變數的 get 請求時,會呼叫 ip_access(get)
。此函式傳回的值是 get 請求的答案。
如果 ip_access
和 name_access
的實作方式類似,我們可以使用 ListOfExtraArguments
編寫 generic_access
函式
{ipAdr, {my_module, generic_access, ['IPADR']}}.
% The mnemonic 'name' is more convenient than 1.1.7
{name, {my_module, generic_access, ['NAME']}}.
當代理程式收到與上述相同的 get 請求時,會呼叫 generic_access(get,
'IPADR')
。
另一個更接近硬體的可能性是
{ipAdr, {my_module, generic_access, [16#2543]}}.
{name, {my_module, generic_access, [16#A2B3]}}.
預設儀器
當 MIB 定義工作完成時,還剩下兩個主要問題。
- 實作 MIB
- 實作管理員應用程式。
實作 MIB 可能是一項繁瑣的工作。最有可能的是,需要在實作所有表格和變數之前測試代理程式。在這種情況下,預設儀器功能非常有用。此工具組可以針對變數以及表格產生預設儀器功能。因此,會在沒有任何程式設計的情況下產生可處理 set
、get
、get-next
和表格操作的執行原型代理程式。
代理程式會將值儲存在基於標準模組 ets
的內部揮發性資料庫中。但是,可以讓 MIB 編譯器產生使用內部永久性資料庫或 Mnesia DBMS 的函式。如需更多資訊,請參閱 Mnesia 使用者指南和參考手冊的 SNMP 章節,模組 snmp_generic
。
當實作 MIB 的部分時,您會重新編譯它並繼續使用預設函式。透過這種方法,可以逐步開發 SNMP 代理程式。
預設儀器可讓管理員端的應用程式與代理程式同時開發和測試。ASN.1 檔案完成後,立即讓 MIB 編譯器產生預設實作,並從此開發管理應用程式。
表格操作
針對使用 SNMPv2 中的 RowStatus
文字慣例(在 STANDARD-MIB 和 SNMPv2-TC 中定義)的表格,產生表格的預設函式可以運作。
注意
我們強烈建議針對每個可以從管理員修改的表格使用
RowStatus
慣例,即使是新設計的 SNMPv1 MIB 也是如此。在 SNMPv1 中,每個人都發明了自己的方案來模擬表格操作,這導致了許多不一致之處。SNMPv2 中的慣例既靈活又強大,並且已成功測試。如果表格是唯讀的,則不應使用 RowStatus 欄。
原子 Set
在 SNMP 中,set
操作是原子的。在 set
操作中指定的所有變數都會變更,否則都不會變更。因此,set
操作分為兩個階段。在第一階段,會根據 MIB 中變數的定義來檢查每個變數的新值。會檢查以下定義
- 類型
- 長度
- 範圍
- 變數是可寫入的,並且在 MIB 檢視中。
在第一階段結束時,會針對每個純量變數和每組表格操作呼叫使用者定義的 is_set_ok
函式。
如果沒有發生錯誤,則會執行第二階段。此階段會針對所有變數呼叫使用者定義的 set
函式。
如果在 is_set_ok
階段或 set
階段發生錯誤,則所有已使用 is_set_ok
呼叫但未使用 set
呼叫的函式,都會使用 undo
呼叫。
這個交易機制有一些限制。如果變數之間存在複雜的相依性,例如 month
和 day
之間,則需要另一種機制。透過更通用的交易機制,可以避免將日期設定為「2 月 31 日」。您可以繼續並找到越來越複雜的情況,並建構一個 N 階段的設定機制。此工具組僅包含一個簡單的機制。
交易機制最常見的應用是將列操作保持在一起。由於我們的代理程式會對列操作進行排序,因此實作的機制與 RowStatus(特別是 'createAndWait' 值)結合,可以優雅地解決大多數問題。