10.检测函数 | 10. Instrumentation Functions
10 检测函数
用户定义的每个对象的检测函数都会将管理对象附加到实际资源中。 该功能由代理在get或set操作中调用。 该函数可以读取一些硬件寄存器,执行计算或执行与概念变量关联的语义所需的任何内容。 必须为标量变量和表格写入这些函数。 它们在关联文件中指定,这是一个文本文件。 在这个文件中,OBJECT IDENTIFIER或每个被管理对象的符号名都与一个Erlang元组{Module,Function,ListOfExtraArguments}相关联。
在SNMP操作中引用托管对象时,将{Module, Function, ListOfExtraArguments}
调用关联的对象。该函数应用于一些标准参数(例如操作类型)和用户提供的额外参数。
对于标量变量和表格,必须编写测试函数,对于表格只能使用get-next。 get-bulk操作被翻译为一系列调用get-next。
10.1仪表功能
以下部分描述了如何在Erlang中为不同的操作定义检测函数。以下RowIndex
是该表的关键值列表,并且Column
是列号。
这些功能在详细描述Definition of Instrumentation Functions
详细描述。
新的/删除的业务
对于标量变量:
variable_access(new [, ExtraArg1, ...])
variable_access(delete [, ExtraArg1, ...])
表:
table_access(new [, ExtraArg1, ...])
table_access(delete [, ExtraArg1, ...])
当MIB被卸载或加载时,对MIB中的每个对象分别调用这些函数。
获取操作
对于标量变量:
variable_access(get [, ExtraArg1, ...])
表:
table_access(get,RowIndex,Cols [,ExtraArg1, ...])
Cols
是一个列表Column
。代理将对传入变量进行排序,以便同时提供一行(同一索引)上的所有操作。这是因为数据库通常会逐行检索信息。
这些函数必须返回关联变量的当前值。
集合操作
对于标量变量:
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}
。
撤消操作
使用is_set_ok调用的函数将再次调用,如果没有错误,则使用set,如果发生错误,则使用撤销。 通过这种方式,可以在is_set_ok操作中保留资源,在撤消操作中释放资源,或在set操作中永久使用资源。
variable_access(undo, NewValue [, ExtraArg1, ...])
表:
table_access(set, RowIndex, Cols [, ExtraArg1,..])
Cols
是元组列表{Column, NewValue}
。
GetNext操作
由于代理可以在MIB中找到下一个简单变量实例并使用get操作调用检测,因此应仅为表定义GetNext操作操作。
table_access(get_next, RowIndex, Cols [, ExtraArg1, ...])
Cols是一个整数列表,全部大于或等于零。 这表明仪器应该找到下一个可访问的实例。 该函数返回元组{NextOid,NextValue}或endOfTable。 NextOid应该是表中管理对象的字典顺序下一个可访问的实例。 它应该是一个整数列表,其中第一个整数是列,其余列表是下一行的索引。 如果返回endOfTable,代理将继续在其他变量和表中搜索下一个实例。
RowIndex
可能是空列表,未完整指定的行索引或未指定行的索引。
这个操作最好用一个例子来描述。
GetNext示例
名为myTable的表格有五列。 前两个是键(不可访问),并且该表有三行。 该表的检测功能称为my_table。
Figure 10.1: Contents of my_table
注
N / A表示无法访问。
管理者发出以下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}]
下表说明了这一点:
图10.2:GetNext来自3,1,1和5,1,1...
经理现在发出以下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]
下表说明了这一点:
图10.3:GetNext来自3,2,1和5,2,1...
经理现在发出以下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}]
下表说明了这一点:
图10.4:GetNext来自3,1,2和4,1,2...
管理者现在发出以下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
变量。
10.2使用Extraargument
该ListOfExtraArguments
可用于编写通用的功能。该列表被附加到每个函数的标准参数。考虑两个只读用于设备的变量,ipAdr
和name
分别与对象标识符和1.1.23.4 1.1.7。要访问这些变量,一个可以实现两个二郎功能ip_access
和name_access
,这将是在MIB。这些函数可以在文本文件中指定如下:
{ipAdr, {my_module, ip_access, []}}.
% Or using the oid syntax for 'name'
{[1,1,7], {my_module, name_access, []}}.
该ExtraArgument
参数是空列表。例如,当代理收到该ipAdr
变量的获取请求时,将进行调用ip_access(get)
。该函数返回的值是获取请求的答案。
如果ip_access
和name_access
实现类似,我们可以编写一个generic_access
函数使用ListOfExtraArguments
*
{ipAdr, {my_module, generic_access, ['IPADR']}}.
% The mnemonic 'name' is more convenient than 1.1.7
{name, {my_module, generic_access, ['NAME']}}.
当代理人收到与上述相同的获取请求时,将会拨打generic_access(get,
'' IPADR')
。
另一种更接近硬件的可能性是:
{ipAdr, {my_module, generic_access, [16#2543]}}.
{name, {my_module, generic_access, [16#A2B3]}}.
10.3默认仪表
当MIB定义工作完成后,还有两个主要问题。
- 实施MIB
- 实现Manager应用程序。
实现MIB可能是一项乏味的任务。 最有可能的是,在实施所有表和变量之前,需要测试代理。 在这种情况下,默认的仪器功能很有用。 该工具包可以为变量以及表格生成默认的检测功能。 因此,一个正在运行的原型代理可以处理set,get,get-next和table操作,而不需要任何编程。
代理将值存储在基于标准模块的内部易失性数据库中ets
。但是,可以让MIB编译器生成使用内部持久性数据库或Mnesia DBMS的函数。snmp_generic
有关更多信息,请参阅Mnesia用户指南和参考手册的SNMP部分。
当MIB的部分实现时,您将重新编译它,并使用默认函数继续运行。通过这种方法,可以逐步开发SNMP代理。
默认的工具允许管理端的应用程序与代理同时开发和测试。一旦ASN.1文件完成,就让MIB编译器生成一个默认实现,并由此开发管理应用程序。
表操作
表格的默认功能的生成适用于使用RowStatus
STANDARD-MIB和SNMPv2-TC中定义的SNMPv2文本约定的表格。
注
对于可以从管理器修改的每个表,我们强烈建议使用RowStatus约定,即使是新设计的SNMPv1 MIB也是如此。 在SNMPv1中,每个人都发明了自己的模拟表操作方案,这导致了许多不一致。 SNMPv2中的约定是灵活而强大的,并且已经测试成功。 如果该表是只读的,则不应使用RowStatus列。
10.4 原子集
在SNMP中,set
操作是原子的。中指定的所有变量。set
操作被更改,或者没有被更改。因此,set
操作分为两个阶段。在第一阶段,每个变量的新值将根据MIB中变量的定义进行检查。检查下列定义:
- 类型
- 长度
- 范围
- 变量是可写的,并且在MIB视图中。
在第一阶段结束时,用户定义is_set_ok
为每个标量变量和每组表操作调用函数。
如果没有发生错误,则执行第二阶段。此阶段调用定义的用户。set
所有变量的函数。
如果发生错误,则在is_set_ok
阶段,或处于set
阶段,所有被调用的函数is_set_ok
但不是set
,被调用为undo
...
这种交易机制有局限性。如果变量之间存在复杂的依赖关系,例如month
和之间day
,则需要另一种机制。将日期设置为'Feb 31'可以通过更通用的事务机制来避免。您可以继续并找到越来越复杂的情况,并构建N阶段集机制。该工具包只包含一个微不足道的机制。
事务机制最常见的应用是将行操作保持在一起。由于我们的代理对行操作进行排序,结合RowStatus(特别是'createAndWait'值)实现的机制可以优雅地解决大多数问题。