查看源码 snmp_generic (snmp v5.18)
在数据库中实现 SNMP 对象的通用函数
模块 snmp_generic
包含用于使用 SNMP 内置数据库或 Mnesia 实现表(和变量)的通用函数。如果 MIB 中的托管对象未提供检测函数,则会使用这些默认函数。有时,可能需要自定义默认函数的行为。例如,在某些情况下,如果删除或修改行,则应发送陷阱,或者在信息更改时应通知某些硬件。
整体结构如下图所示
+---------------+
| SNMP Agent |
+- - - - - - - -+
| MIB |
+---------------+
|
Association file (associates a MIB object with
| snmp_generic:table_funct
| snmp_generic:variable_func)
+--------------------------------------+
| snmp_generic | Support for get-next,
| | RowStatus operations
+----------------------+---------------+
| snmpa_local_db | Mnesia | Database
+--------------+-------+---------------+
| dets | ets |
| (persistent) | |
+--------------+-------+
每个函数都使用参数 NameDb
,它是一个元组 {Name, Db}
,用于标识函数应使用的数据库。Name
是 MIB 中定义的托管对象的符号名称,Db
是 volatile
、persistent
或 mnesia
。如果它是 mnesia
,则所有变量都存储在 Mnesia 表 snmp_variables
中,该表必须是具有两个属性的表(而不是 Mnesia SNMP 表)。SNMP 表存储在与 SNMP 表同名的 Mnesia 表中。所有函数都假定存在具有正确名称和属性的 Mnesia 表。程序员有责任确保这一点。具体而言,如果变量存储在 Mnesia 中,则必须由程序员创建表 snmp_variables
。此表的记录定义在文件 snmp/include/snmp_types.hrl
中定义。
如果在编译 MIB 时,变量 myVar
的关联文件中的检测函数没有名称,则编译器会生成一个条目。
{myVar, {snmp_generic, variable_func, [{myVar, Db]}}.
对于表
{myTable, {snmp_generic, table_func, [{myTable, Db]}}.
示例
以下示例显示了在 Mnesia 中存储的表的实现,但在设置请求操作时执行了一些检查。
myTable_func(new, NameDb) -> % pass unchanged
snmp_generic:table_func(new, NameDb).
myTable_func(delete, NameDb) -> % pass unchanged
snmp_generic:table_func(delete, NameDb).
%% change row
myTable_func(is_set_ok, RowIndex, Cols, NameDb) ->
case snmp_generic:table_func(is_set_ok, RowIndex,
Cols, NameDb) of
{noError, 0} ->
myApplication:is_set_ok(RowIndex, Cols);
Err ->
Err
end;
myTable_func(set, RowIndex, Cols, NameDb) ->
case snmp_generic:table_func(set, RowIndex, Cols,
NameDb),
{noError, 0} ->
% Now the row is updated, tell the application
myApplication:update(RowIndex, Cols);
Err ->
Err
end;
myTable_func(Op, RowIndex, Cols, NameDb) -> % pass unchanged
snmp_generic:table_func(Op, RowIndex, Cols, NameDb).
.funcs
文件如下所示
{myTable, {myModule, myTable_func, [{myTable, mnesia}]}}.
总结
函数
获取 Name
的索引类型
从 Cols
获取状态列的值。
获取特定的表信息项,或者,如果 Item
的值为“all”,则返回一个包含给定表的所有项及其各自值的二元组列表(属性列表)。
这是表的默认检测函数。
这是表的默认检测函数。
返回一个列表,其中包含 Cols
中所有列的值。如果某列未定义,则其值为 noinit
。
查找表中下一行的索引。RestOid
不必指定现有行。
检查表中的行是否存在。
将 Cols
中的元素设置为由 RowIndex
指定的行。不对新值执行任何检查。
这是变量的默认检测函数。
这是带有操作的变量的默认检测函数:is_set_ok | set | undo
。
获取变量的值。
为变量设置新值。如果变量不存在,则会创建该变量。不对新值的类型进行任何检查。
类型
-type column() :: pos_integer().
在 get 操作的情况下,它是列号列表;在 set 操作的情况下,它是列号和值的列表。
-type table_info_item() ::
nbr_of_cols | defvals | status_col | not_accessible | index_types | first_accessible |
first_own_index.
对于普通表,类型将如下所示
nbr_of_cols
- 列数。值类型: pos_integer()
defvals
- 默认值列表,按列排序。值类型: [{Col :: pos_integer(), DefVal :: term()}]
status_col
- 状态列的列号。值类型: pos_integer()
not_accessible
- 一个排序列表,包含“不可访问”的列(> first_accessible)。值类型: [pos_integer()]
index_types
- 索引列的 asn1_type() 列表,按列号或“augment”元组(见下文)排序。值类型: [asn1_type()]
first_accessible
- 第一个可访问的列。值类型: pos_integer()
first_own_index
- 第一个自有索引的列号。如果此表没有此类索引,则为0
。值类型: non_neg_integer()
对于增强表,它将如下所示
index_types
- 值类型: {augments, {atom(), asn1_type()}}nbr_of_cols
- 值类型: pos_integer()not_accessible
- 值类型: [pos_integer()]first_accessible
- 值类型: pos_integer()
函数
-spec get_index_types(Name) -> IndexTypes when Name :: snmpa:name() | snmpa:name_db(), IndexTypes :: [snmp:asn1_type()].
获取 Name
的索引类型
此函数可以在检测函数中使用,以检索表信息的索引类型部分。
-spec get_status_col(Name, Cols) -> false | {value, StatusCol} when Name :: snmpa:name() | snmpa:name_db(), Cols :: columns(), StatusCol :: term().
从 Cols
获取状态列的值。
此函数可以在 is_set_ok
、undo
或 set
的检测函数中使用,以检查是否修改了表的状态列。
-spec get_table_info(Name, Item :: nbr_of_cols) -> Result when Name :: snmpa:name() | snmpa:name_db(), Result :: pos_integer(); (Name, Item :: defvals) -> Result when Name :: snmpa:name() | snmpa:name_db(), Result :: [{Col, DefVal}], Col :: pos_integer(), DefVal :: term(); (Name, Item :: status_col) -> Result when Name :: snmpa:name() | snmpa:name_db(), Result :: pos_integer(); (Name, Item :: not_accessible) -> Result when Name :: snmpa:name() | snmpa:name_db(), Result :: [pos_integer()]; (Name, Item :: index_types) -> Result when Name :: snmpa:name() | snmpa:name_db(), Result :: [snmp:asn1_type()]; (Name, Item :: first_accessible) -> Result when Name :: snmpa:name() | snmpa:name_db(), Result :: pos_integer(); (Name, Item :: first_own_index) -> Result when Name :: snmpa:name() | snmpa:name_db(), Result :: non_neg_integer(); (Name, Item :: all) -> Result when Name :: snmpa:name() | snmpa:name_db(), Result :: [{table_info_item(), term()}].
获取特定的表信息项,或者,如果 Item
的值为“all”,则返回一个包含给定表的所有项及其各自值的二元组列表(属性列表)。
此函数可以在检测函数中使用,以检索表信息的给定部分。
-spec table_func(Op, NameDb) -> Return when Op :: new | delete, NameDb :: snmpa:name_db(), Return :: term().
这是表的默认检测函数。
- 如果表不存在,则
new
操作会创建该表,但前提是数据库是 SNMP 内部数据库。 delete
操作不会从数据库中删除该表,因为卸载 MIB 并不一定意味着应该销毁该表。
如果管理器可以创建或删除表中的行,则必须有一个 RowStatus
列,以便 is_set_ok
、set
和 undo
正常工作。
该函数根据检测函数的规范返回。
-spec table_func(Op, RowIndex, Cols, NameDb) -> Return when Op :: get | next | is_set_ok | set | undo, RowIndex :: snmp:row_index(), Cols :: columns(), NameDb :: snmpa:name_db(), Return :: term().
这是表的默认检测函数。
is_set_ok
操作检查要修改或删除的行是否存在,以及要创建的行是否不存在。undo
操作不执行任何操作。set
操作检查它是否有足够的信息将行的状态从notReady
更改为notInService
(当行已设置为createAndWait
时)。如果将行设置为createAndWait
,则没有值的列将设置为noinit
。如果使用 Mnesia,则 set 功能在事务中处理。
如果管理器可以创建或删除表中的行,则必须有一个 RowStatus
列,以便 is_set_ok
、set
和 undo
正常工作。
该函数根据检测函数的规范返回。
-spec table_get_elements(NameDb, RowIndex, Cols) -> Values when NameDb :: snmpa:name_db(), RowIndex :: snmp:row_index(), Cols :: columns(), Values :: [noinit | Value], Value :: term().
返回一个列表,其中包含 Cols
中所有列的值。如果某列未定义,则其值为 noinit
。
查找表中下一行的索引。RestOid
不必指定现有行。
检查表中的行是否存在。
将 Cols
中的元素设置为由 RowIndex
指定的行。不对新值执行任何检查。
如果使用 Mnesia 数据库,则此函数会调用 mnesia:write
来存储值。这意味着必须从事务 (mnesia:transaction/1
) 中调用此函数。
-spec variable_func(Op :: new, Name) -> Result when Name :: snmpa:name() | snmpa:name_db(), Result :: ok | boolean(); (Op :: delete, Name) -> Result when Name :: snmpa:name() | snmpa:name_db(), Result :: ok; (Op :: get, Name) -> Result when Name :: snmpa:name() | snmpa:name_db(), Result :: {value, Value} | genErr, Value :: term().
这是变量的默认检测函数。
new
操作会在数据库中创建一个新变量,其默认值在 MIB 中定义,或者为零值(取决于类型)。delete
函数不会从数据库中删除变量。
该函数根据检测函数的规范返回。
-spec variable_func(Op :: is_set_ok, Value, Name) -> Result when Value :: term(), Name :: snmpa:name() | snmpa:name_db(), Result :: noError; (Op :: set, Value, Name) -> Result when Value :: term(), Name :: snmpa:name() | snmpa:name_db(), Result :: noError | commitFailed; (Op :: undo, Value, Name) -> Result when Value :: term(), Name :: snmpa:name() | snmpa:name_db(), Result :: noError.
这是带有操作的变量的默认检测函数:is_set_ok | set | undo
。
is_set_ok
操作不执行任何操作。- 如果成功,则
set
操作返回noError
,否则返回commitFailed
。 undo
操作不执行任何操作。
该函数根据检测函数的规范返回。
-spec variable_get(Name) -> {value, Value} | undefined when Name :: snmpa:name() | snmpa:name_db(), Value :: term().
获取变量的值。
-spec variable_set(Name, Value) -> boolean() when Name :: snmpa:name() | snmpa:name_db(), Value :: term().
为变量设置新值。如果变量不存在,则会创建该变量。不对新值的类型进行任何检查。
如果 NameDb
参数指定不正确,则返回 false
,否则返回 true
。