For each PDU that arrives at the agent (TCL like pseudo code):
(see snmpAgent.c)
--------------------------------------------
if { request reply in cache } { return reply }
Call BEGIN event binding (if present).
foreach { varbind triple } {
find (or findnext) inst
if { NO inst && set_req } {
if { access is read-create } {
# create an instance binding using mib name and Object index
bind instance inst mibName(inst OID)
Call CREATE bindings for branch (leaf->root)
setDone
}
}
if { NO inst } {
set up appropriate v1 or v2 response
continue
}
if { ! setDone && set_req } {
if { access is readonly || var type wrong } {
goto VarBindError
}
Call SET bindings for branch (leaf->root)
if { result was ERROR } {
goto VarBindError
}
if { result not BREAK } {
set inst binding to value
}
}
Call GET bindings for branch (leaf->root)
if { result was ERROR } {
goto VarBindError
}
set reply binding to inst value
continue
VarBindError:
set error index
}
if { set_req } {
foreach { varbind triple } {
if { inst } {
Call COMMIT or ROLLBACK depending on error_status
bindings for branch (leaf->root)
}
}
}
Call END event binding (if present).
return reply
--------------------------------------------
Now I have a few comments - mostly they relate to supporting the creation of
Table entries.
a) CREATE behaves rather differently from SET - in that it is entirely up
to the CREATE binding to initialise the Value of the Inst. For SET, it is
done automaticly. This can lead to invalid values existing.
b) Although there the bindings for COMMIT & ROLLBACK, more automated support
in terms of either scratchpad / saved / new variables would be nice. That is
support the default cases. So the SNMP semantics of Set PDU atomicity can
be better supported.
c) However may be I am missing something, since the example agents, when tables
are created have no rollback or commit bindings.
d) For scalars to have true atomicity (assuming read/write rather than
read/create): the following bindings are needed:
$s instance scalar scalar
set scalarSaved false
$s bind scalar set {
if { ! scalarSaved } {
set scalarSave $scalar
set scalarSaved true
}
}
$s bind scalar commit { set scalarSaved false }
$s bind scalar rollback { set scalar $scalarSave
set scalarSaved false }
e) And its even more complex for a Table entry. Basicly you have to record
Table entry status and on rollback remember whether to unbind or restore
saved values. The creation can be triggered potentially any variable.
Finally there is the consistency problem (ie is the table entry OK) which ought
to be checked once after all the inital sets have been done, but before
the Commits or Rollbacks. However the Scotty agent only allows error
reporting on the SET or CREATE or GET events alas.
So consistency checking is hard since there is no second phase check point.
My suggested idea is to allow COMMIT to report an error & be reinvoked as
ROLLBACK or event new event of CHECK. See CMU RESERVE1 & RSERVE2 sequence
for agent PDU processing.
Hope this is of help,
Peter Polkinghorne, Email: pjmp@gec-rl-hrc.co.uk
GEC Hirst Research Centre,
Elstree Way, Borehamwood, Tel. +44-181-732-0282 (or +44-181-953-2030)
Herts. WD6 1RX ENGLAND Fax +44-181-732-0200 (UK: 0181-732-0200)