As stated in the previous section, the atomicity of set requests is no longer guaranteed when remote MIBs are involved. Although some strategies exist that try to offer a best-effort regarding the atomicity of set requests, there is no generic mechanism that is guaranteed to work in a master agent application. The best that can be done in a generic toolkit is to identify those cases where atomicity might have been broken, and to inform the manager of that situation. Java DMK 5.1 handles this by responding with undoFailed when an error occurs during the set() phase of a set request. In its default configuration, when an SNMPv2 set request is received, Java DMK guarantees that undoFailed is sent when atomicity might have been broken. This no longer holds if the application code configures the SnmpProxy object to send the remote SNMP set request during the check() phase of the set operation.
Some toolkits attempt to implement atomicity by:
Getting the current values of all variables included in the set.
Performing the set.
Reverting to the old values by sending a second set with the values obtained in 1 above, or the values obtained in 2 if no error is returned.
Although this might seem more satisfactory it is not guaranteed to work. Depending on the semantics of the variables involved in the set, several things might happen:
If the transition from value#1 to value#2 is valid, there is no guarantee that the transition from value#2 to value#1 will be accepted by the agent; reverting to the old value might not be possible
Setting an object to a specific value might already have had unrecoverable effects on the agent; for example removing a resource, destroying a row, and so on
Some objects might be of type Test-And-Increment which means that getting their value in 1 above already modifies them. Trying to perform a set on them will probably generate an error as these objects are usually read-only. In the end, the whole process will return an error while still having modified the objects as a side effect
Even if no generic mechanism is supported, the Java DMK can still be customized to implement any specific behavior. The SnmpUserDataFactory makes it possible to allocate and release contextual data about requests, which can be used to implement transactional behavior. By subclassing SnmpProxy, and mibgen–generated metadata classes, any kind of specific transactional behavior can be implemented. However, no generic solution exists, and if transactional behavior can be implemented, it is specific to the semantics of the objects contained in the application and subagent MIBs.
Another special case is when a subagent is entirely responsible for a given context scope. In that case, the atomicity of set requests can still be achieved by performing the remote SNMP set during the check() phase. See 20.4 MIB Scoping in Master Agents for details.
The following tables show the end-to-end error translation performed by a master agent application.
Table 20–1 Error Translation from SNMPv1 Subagents to SNMPv2/v3 Managers
PDU Type |
Error From SNMPv1 Subagents |
Error Sent to SNMPv2/v3 Managers |
---|---|---|
get |
genErr |
genErr |
get |
noSuchName |
noError => noSuchInstance in varbind |
get |
tooBig |
handled by stack =>resend or tooBig |
get |
any other error |
genErr |
set |
any error |
undoFailed(**) |
get-next/get-bulk |
genErr(*) |
genErr |
get-next/get-bulk |
noSuchName |
noError => skip to next SnmpMibAgent or endOfMibView if none |
get-next/get-bulk |
tooBig |
handled by stack resend or tooBig cated response (get-bulk) |
get-next/get-bulk |
any other error(*) |
genErr |
(*) The SnmpProxy objects can be configured to hide such errors. In this case the master agent skips to the next SnmpMibAgent. This behavior can be very useful when dealing with faulty legacy agents.
(**) See Table 20–5.
Table 20–2 Error Translation from SNMPv2/v3 Subagents to v1 Managers
PDU Type |
Error From SNMPv2/v3 Subagents |
Error Sent to SNMPv1 Managers |
---|---|---|
get |
genErr |
genErr |
get |
noError => noSuchInstance in varbind |
noSuchName |
get |
noError => noSuchInstance in varbind |
noSuchName |
get |
tooBig |
handled by stack => resend or tooBig |
get |
any other error |
genErr |
set |
any error |
genErr (**) - undoFailed is translated into genErr |
get-next |
genErr |
genErr |
get-next |
noError => endOfMibView in varbind |
noSuchName |
get-next |
tooBig |
handled by stack => resend or tooBig |
get-next |
any other error |
genErr |
(**) See Table 20–5.
Table 20–3 Error Translation From SNMPv1 Subagents to SNMPv1 Managers
PDU Type |
Error From SNMPv1 Subagents |
Error Sent to SNMPv1 Managers |
---|---|---|
get |
genErr |
genErr |
get |
noSuchName |
noSuchName |
get |
tooBig |
handled by stack => resend or tooBig |
get |
any other error |
genErr |
set |
any error |
genErr (**) - undoFailed is translated into genErr |
get-next |
genErr |
genErr |
get-next |
noSuchName |
noSuchName |
get-next |
tooBig |
handled by stack => resend or tooBig |
get-next |
any other error |
genErr |
(**) See Table 20–5.
Table 20–4 Error Translation from SNMPv2/v3 Subagents to SNMPv2/v3 Managers
PDU Type |
Error From SNMPv2/v3 Subagents |
Error Sent to SNMPv2/v3 Managers |
---|---|---|
get |
noError |
noError |
get |
tooBig |
handled by stack => resend or tooBig |
get |
any other error |
same error (if valid) or genErr |
set |
any error |
undoFailed (**) |
get-next/get-bulk |
noError |
noError |
get-next/get-bulk |
tooBig |
handled by stack => resend or tooBig or truncated response (GET-BULK) |
get-next/get-bulk |
any other error |
same error (if valid) or genErr |
(**) By default SnmpProxy sends the remote set request during the set() phase of the set operation. When an error occurs during the set() phase, undoFailed is returned to the manager because the atomicity is no longer guaranteed. Note that in the special case where an SnmpProxy is configured to perform the remote set request during the check() phase of the set operation, the following translation is applied for errors returned by the remote set request, even if the atomicity of the set request is broken, as shown in the following table.
Table 20–5 Error Translation When SnmpProxy Performs Remote set
Before Translation |
After Translation |
---|---|
v1 errorStatus |
v2/v3 errorStatus |
noError |
noError |
noSuchName |
noSuchName |
genErr |
genErr |
badValue |
wrongValue |
readOnly |
wrongValue |
v2/v3 errorStatus |
v1 errorStatus |
noError |
noError |
genErr |
genErr |
wrongValue, wrongEncoding, wrongLength, wrongType, inconsistentValue |
badValue |
noAccess, notWritable, noCreation, inconsistentName, authorizationError |
noSuchName |
resourceUnavailable, commitFailed, undoFailed, any other error |
genErr |
v1 errorStatus |
v1 errorStatus |
any error |
same error (if valid); genErr otherwise |
v2/v3 errorStatus |
v2/v3 errorStatus |
any error |
same error (if valid); genErr otherwise |
v1 errorStatus |
v2/v3 errorStatus |
noError |
noError |
noSuchName |
noSuchName |
genErr |
genErr |
badValue |
wrongValue |
readOnly |
wrongValue |
v2/v3 errorStatus |
v1 errorStatus |
noError |
noError |
genErr |
genErr |
wrongValue, wrongEncoding, wrongLength, wrongType, inconsistentValue |
badValue |
noAccess, notWritable, noCreation, inconsistentName, authorizationError |
noSuchName |
resourceUnavailable, commitFailed, undoFailed, any other error |
genErr |
v1 errorStatus |
v1 errorStatus |
any error |
same error (if valid); genErr otherwise |
v2/v3 errorStatus |
v2/v3 errorStatus |
any error |
same error (if valid); genErr otherwise |