~statik/ubuntu/maverick/erlang/erlang-merge-testing

« back to all changes in this revision

Viewing changes to lib/snmp/doc/src/snmp_advanced_agent.xml

  • Committer: Bazaar Package Importer
  • Author(s): Sergei Golovan
  • Date: 2009-05-01 10:14:38 UTC
  • mfrom: (3.1.4 sid)
  • Revision ID: james.westby@ubuntu.com-20090501101438-6qlr6rsdxgyzrg2z
Tags: 1:13.b-dfsg-2
* Cleaned up patches: removed unneeded patch which helped to support
  different SCTP library versions, made sure that changes for m68k
  architecture applied only when building on this architecture.
* Removed duplicated information from binary packages descriptions.
* Don't require libsctp-dev build-dependency on solaris-i386 architecture
  which allows to build Erlang on Nexenta (thanks to Tim Spriggs for
  the suggestion).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="latin1" ?>
 
2
<!DOCTYPE chapter SYSTEM "chapter.dtd">
 
3
 
 
4
<chapter>
 
5
  <header>
 
6
    <copyright>
 
7
      <year>1997</year><year>2009</year>
 
8
      <holder>Ericsson AB. All Rights Reserved.</holder>
 
9
    </copyright>
 
10
    <legalnotice>
 
11
      The contents of this file are subject to the Erlang Public License,
 
12
      Version 1.1, (the "License"); you may not use this file except in
 
13
      compliance with the License. You should have received a copy of the
 
14
      Erlang Public License along with this software. If not, it can be
 
15
      retrieved online at http://www.erlang.org/.
 
16
    
 
17
      Software distributed under the License is distributed on an "AS IS"
 
18
      basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 
19
      the License for the specific language governing rights and limitations
 
20
      under the License.
 
21
    
 
22
    </legalnotice>
 
23
 
 
24
    <title>Advanced Agent Topics</title>
 
25
    <prepared></prepared>
 
26
    <responsible></responsible>
 
27
    <docno></docno>
 
28
    <approved></approved>
 
29
    <checked></checked>
 
30
    <date></date>
 
31
    <rev></rev>
 
32
    <file>snmp_advanced_agent.xml</file>
 
33
  </header>
 
34
  <p>The chapter <em>Advanced Agent Topics</em> describes the more advanced 
 
35
    agent related features of the SNMP development tool. The following topics 
 
36
    are covered:
 
37
    </p>
 
38
  <list type="bulleted">
 
39
    <item>When to use a Sub-agent</item>
 
40
    <item>Agent semantics</item>
 
41
    <item>Sub-agents and dependencies</item>
 
42
    <item>Distributed tables</item>
 
43
    <item>Fault tolerance</item>
 
44
    <item>Using Mnesia tables as SNMP tables</item>
 
45
    <item>Audit Trail Logging</item>
 
46
    <item>Deviations from the standard
 
47
    </item>
 
48
  </list>
 
49
 
 
50
  <section>
 
51
    <title>When to use a Sub-agent</title>
 
52
    <p>The section <em>When to use a Sub-agent</em> describes situations
 
53
      where the mechanism of loading and unloading MIBs is insufficient. 
 
54
      In these cases a sub-agent is needed.
 
55
      </p>
 
56
 
 
57
    <section>
 
58
      <title>Special Set Transaction Mechanism</title>
 
59
      <p>Each sub-agent can implement its own mechanisms for
 
60
        <c>set</c>, <c>get</c> and <c>get-next</c>. For example, if the
 
61
        application requires the <c>get</c> mechanism to be
 
62
        asynchronous, or needs a N-phase <c>set</c> mechanism, a
 
63
        specialized sub-agent should be used.
 
64
        </p>
 
65
      <p>The toolkit allows different kinds of sub-agents at the same
 
66
        time. Accordingly, different MIBs can have different <c>set</c>
 
67
        or <c>get</c> mechanisms.
 
68
        </p>
 
69
    </section>
 
70
 
 
71
    <section>
 
72
      <title>Process Communication</title>
 
73
      <p>A simple distributed agent can be managed without sub-agents. 
 
74
        The instrumentation functions can use distributed Erlang to 
 
75
        communicate with other parts of the application. However, a 
 
76
        sub-agent can be used on each node if this generates too much 
 
77
        unnecessary traffic. A sub-agent processes requests per 
 
78
        incoming SNMP request, not per variable. Therefore the network 
 
79
        traffic is minimized.
 
80
        </p>
 
81
      <p>If the instrumentation functions communicate with UNIX
 
82
        processes, it might be a good idea to use a special
 
83
        sub-agent. This sub-agent sends the SNMP request to the other
 
84
        process in one packet in order to minimize context switches. For
 
85
        example, if a whole MIB is implemented on the C level in UNIX,
 
86
        but you still want to use the Erlang SNMP tool, then you may
 
87
        have one special sub-agent, which sends the variables in the
 
88
        request as a single operation down to C.
 
89
        </p>
 
90
    </section>
 
91
 
 
92
    <section>
 
93
      <title>Frequent Loading of MIBs</title>
 
94
      <p>Loading and unloading of MIBs are quite cheap
 
95
        operations. However, if the application does this very often,
 
96
        perhaps several times per minute, it should load the MIBs once
 
97
        and for all in a sub-agent. This sub-agent only registers and
 
98
        unregisters itself under another agent instead of loading the
 
99
        MIBs each time. This is cheaper than loading an MIB.
 
100
        </p>
 
101
    </section>
 
102
 
 
103
    <section>
 
104
      <title>Interaction With Other SNMP Agent Toolkits</title>
 
105
      <p>If the SNMP agent needs to interact with sub-agents
 
106
        constructed in another package, a special sub-agent should be
 
107
        used, which communicates through a protocol specified by the
 
108
        other package.
 
109
        </p>
 
110
    </section>
 
111
  </section>
 
112
 
 
113
  <section>
 
114
    <title>Agent Semantics</title>
 
115
    <p>The agent can be configured to be multi-threaded, to process
 
116
      one incoming request at a time, or to have a request limit
 
117
      enabled (this can be used for load control or to limit the effect
 
118
      of DoS attacks). If it is multi-threaded, read requests (<c>get</c>, 
 
119
      <c>get-next</c> and <c>get-bulk</c>) and traps are processed in 
 
120
      parallel with each other and <c>set</c> requests. However, all 
 
121
      <c>set</c> requests are serialized, which means that if the agent 
 
122
      is waiting for the application to complete a complicated write 
 
123
      operation, it will not process any new write requests until this 
 
124
      operation is finished. It processes read requests and sends traps, 
 
125
      concurrently. The reason for not handle write requests in parallel is 
 
126
      that a complex locking mechanism would be needed even in the simplest 
 
127
      cases. Even with the scheme described above, the user must be 
 
128
      careful not to violate that the <c>set</c> requests are atoms. 
 
129
      If this is hard to do, do not use the multi-threaded feature.
 
130
      </p>
 
131
    <p>The order within an request is undefined and variables are not
 
132
      processed in a defined order. Do not assume that the first
 
133
      variable in the PDU will be processed before the second, even if
 
134
      the agent processes variables in this order. It
 
135
      cannot even be  assumed that requests belonging to different
 
136
      sub-agents have any order.
 
137
      </p>
 
138
    <p>If the manager tries to set the same variable many times in the
 
139
      same PDU, the agent is free to improvise. There is no definition
 
140
      which determines if the instrumentation will be called once or
 
141
      twice. If called once only, there is no definition that determines 
 
142
      which of the new values is going to be supplied.
 
143
      </p>
 
144
    <p>When the agent receives a request, it keeps the request ID for
 
145
      one second after the response is sent. If the agent receives
 
146
      another request with the same request ID during this time, from
 
147
      the same IP address and UDP port, that request will be
 
148
      discarded. This mechanism has nothing to do with the function
 
149
      <c>snmpa:current_request_id/0</c>.</p>
 
150
  </section>
 
151
 
 
152
  <section>
 
153
    <title>Sub-agents and Dependencies </title>
 
154
    <p>The toolkit supports the use of different types of sub-agents,
 
155
      but not the construction of sub-agents.
 
156
      </p>
 
157
    <p>Also, the toolkit does not support dependencies between
 
158
      sub-agents. A sub-agent should by definition be stand alone and it is
 
159
      therefore not good design to create dependencies between them.
 
160
      </p>
 
161
  </section>
 
162
 
 
163
  <section>
 
164
    <title>Distributed Tables</title>
 
165
    <p>A common situation in more complex systems is that the data in
 
166
      a table is distributed. Different table rows are implemented in
 
167
      different places. Some SNMP tool-kits dedicate an SNMP sub-agent for
 
168
      each part of the table and load the corresponding MIB into all
 
169
      sub-agents. The Master Agent is responsible for presenting the
 
170
      distributed table as a single table to the manager. The toolkit
 
171
      supplied uses a different method.
 
172
      </p>
 
173
    <p>The method used to implement distributed tables with this SNMP
 
174
      tool is to implement a table coordinator process responsible for 
 
175
      coordinating the processes, which hold the table data and they 
 
176
      are called  table holders. All table holders must in some way be 
 
177
      known by the coordinator; the structure of the table data 
 
178
      determines how this is achieved. The coordinator may require 
 
179
      that the table holders explicitly register themselves and specify 
 
180
      their information. In other cases, the table holders can be 
 
181
      determined once at compile time.
 
182
      </p>
 
183
    <p>When the instrumentation function for the distributed table is
 
184
      called, the request should be forwarded to the table
 
185
      coordinator. The coordinator finds the requested information among
 
186
      the table holders and then returns the answer to the
 
187
      instrumentation function. The SNMP toolkit contains no support for
 
188
      coordination of tables since this must be independent of the
 
189
      implementation.
 
190
      </p>
 
191
    <p>The advantages of separating the table coordinator from the
 
192
      SNMP tool are:
 
193
      </p>
 
194
    <list type="bulleted">
 
195
      <item>We do not need a sub-agent for each table holder. Normally,
 
196
       the sub-agent is needed to take care of communication, but in
 
197
       Distributed Erlang we use ordinary message passing.
 
198
      </item>
 
199
      <item>Most likely, some type of table coordinator already
 
200
       exists. This process should take care of the instrumentation for
 
201
       the table.
 
202
      </item>
 
203
      <item>The method used to present a distributed table is strongly
 
204
       application dependent. The use of different masking techniques
 
205
       is only valid for a small subset of problems and registering
 
206
       every row in a distributed table makes it non-distributed.
 
207
      </item>
 
208
    </list>
 
209
  </section>
 
210
 
 
211
  <section>
 
212
    <title>Fault Tolerance</title>
 
213
    <p>The SNMP agent toolkit gets input from three different sources:
 
214
      </p>
 
215
    <list type="bulleted">
 
216
      <item>UDP packets from the network</item>
 
217
      <item>return values from the user defined instrumentation functions</item>
 
218
      <item>return values from the MIB.
 
219
      </item>
 
220
    </list>
 
221
    <p>The agent is highly fault tolerant. If the manager gets an
 
222
      unexpected response from the agent, it is possible that some
 
223
      instrumentation function has returned an erroneous value. The
 
224
      agent will not crash even if the instrumentation does. It should
 
225
      be noted that if an instrumentation function enters an infinite
 
226
      loop, the agent will also be blocked forever. The supervisor ,or
 
227
      the application, specifies how to restart the agent.
 
228
      </p>
 
229
 
 
230
    <section>
 
231
      <title>Using the SNMP Agent in a Distributed Environment</title>
 
232
      <p>The normal way to use the agent in a distributed
 
233
        environment is to use one master agent located at one node,
 
234
        and zero or more sub-agents located on other nodes.  However,
 
235
        this configuration makes the master agent node a single point
 
236
        of failure.  If that node goes down, the agent will not work.
 
237
        </p>
 
238
      <p>One solution to this problem is to make the snmp application
 
239
        a distributed Erlang application, and that means, the agent
 
240
        may be configured to run on one of several nodes.  If the node
 
241
        where it runs goes down, another node restarts the agent.
 
242
        This is called <em>failover</em>.  When the node starts again,
 
243
        it may  <em>takeover</em> the application.  This solution to
 
244
        the problem adds another problem.  Generally, the new node has
 
245
        another IP address than the first one, which may cause
 
246
        problems in the  communication between the SNMP managers and
 
247
        the agent.
 
248
        </p>
 
249
      <p>If the snmp agent is configured as a distributed Erlang
 
250
        application, it will during takeover try to load the same MIBs
 
251
        that were loaded at the old node. It uses the same filenames
 
252
        as the old node. If the MIBs are not located in the same
 
253
        paths at the different nodes, the MIBs must be loaded
 
254
        explicitly after takeover.
 
255
        </p>
 
256
    </section>
 
257
  </section>
 
258
 
 
259
  <section>
 
260
    <title>Using Mnesia Tables as SNMP Tables</title>
 
261
    <p>The Mnesia DBMS can be used for storing data of SNMP
 
262
      tables. This means that an SNMP table can be implemented as a
 
263
      Mnesia table, and that a Mnesia table can be made visible via
 
264
      SNMP. This mapping is largely automated.
 
265
      </p>
 
266
    <p>There are three main reasons for using this mapping:
 
267
      </p>
 
268
    <list type="bulleted">
 
269
      <item>We get all features of Mnesia, such as fault tolerance,
 
270
       persistent data storage, replication, and so on.
 
271
      </item>
 
272
      <item>Much of the work involved is automated. This includes
 
273
      <c>get-next</c> processing and <c>RowStatus</c> handling.
 
274
      </item>
 
275
      <item>The table may be used as an ordinary Mnesia table, using
 
276
       the Mnesia API internally in the application at the same time as
 
277
       it is visible through SNMP.
 
278
      </item>
 
279
    </list>
 
280
    <p>When this mapping is used, insertion and deletion in the
 
281
      original Mnesia table is slower, with a factor O(log n). The read
 
282
      access is not affected.
 
283
      </p>
 
284
    <p>A drawback with implementing an SNMP table as a Mnesia table is
 
285
      that the internal resource is forced to use the table definition
 
286
      from the MIB, which means that the external data model must be
 
287
      used internally. Actually, this is only partially true. The Mnesia
 
288
      table may extend the SNMP table, which means that the Mnesia table
 
289
      may have columns which are use internally and are not seen by
 
290
      SNMP. Still, the data model from SNMP must be maintained. Although
 
291
      this is undesirable, it is a pragmatic compromise in many
 
292
      situations where simple and efficient implementation is preferable
 
293
      to abstraction.
 
294
      </p>
 
295
 
 
296
    <section>
 
297
      <title>Creating the Mnesia Table</title>
 
298
      <p>The table must be created in Mnesia before the manager can
 
299
        use it. The table must be declared as type <c>snmp</c>.  This
 
300
        makes the table ordered in accordance with the lexicographical
 
301
        ordering rules of SNMP.  The name of the Mnesia table must be
 
302
        identical to the SNMP table name.  The types of the INDEX fields
 
303
        in the corresponding SNMP table must be specified.
 
304
        </p>
 
305
      <p>If the SNMP table has more than one INDEX column, the
 
306
        corresponding Mnesia row is a tuple, where the first element 
 
307
        is a tuple with the INDEX columns. Generally, if the SNMP table 
 
308
        has <em>N</em> INDEX columns and <em>C</em> data columns, the 
 
309
        Mnesia table is of arity <em>(C-N)+1</em>, where the key is a 
 
310
        tuple of arity <em>N</em> if <em>N > 1</em>, or a single term 
 
311
        if <em>N = 1</em>.
 
312
        </p>
 
313
      <p>Refer to the Mnesia User's Guide for information on how to
 
314
        declare a Mnesia table as an SNMP table.
 
315
        </p>
 
316
      <p>The following example illustrates a situation in which we
 
317
        have an SNMP table that we wish to implement as a Mnesia
 
318
        table. The table stores information about employees at a
 
319
        company. Each employee is indexed with the department number and
 
320
        the name.
 
321
        </p>
 
322
      <code type="none">
 
323
       empTable OBJECT-TYPE
 
324
              SYNTAX      SEQUENCE OF EmpEntry
 
325
              ACCESS      not-accessible
 
326
              STATUS      mandatory
 
327
              DESCRIPTION
 
328
                      "A table with information about employees."
 
329
       ::= { emp 1}
 
330
       empEntry OBJECT-TYPE
 
331
              SYNTAX      EmpEntry
 
332
              ACCESS      not-accessible
 
333
              STATUS      mandatory
 
334
              DESCRIPTION
 
335
                 ""
 
336
              INDEX      { empDepNo, empName }
 
337
       ::= { empTable 1 }
 
338
       EmpEntry ::=
 
339
              SEQUENCE {
 
340
                  empDepNo         INTEGER,
 
341
                  empName          DisplayString,
 
342
                  empTelNo         DisplayString
 
343
                  empStatus        RowStatus
 
344
              }
 
345
      </code>
 
346
      <p>The corresponding Mnesia table is specified as follows:
 
347
        </p>
 
348
      <code type="none">
 
349
mnesia:create_table([{name, employees},
 
350
                     {snmp, [{key, {integer, string}}]},
 
351
                     {attributes, [key, telno, row_status]}]).
 
352
      </code>
 
353
      <note>
 
354
        <p>In the Mnesia tables, the two key columns are stored as a
 
355
          tuple with two elements. Therefore, the arity of the table is
 
356
          3.</p>
 
357
      </note>
 
358
    </section>
 
359
 
 
360
    <section>
 
361
      <title>Instrumentation Functions</title>
 
362
      <p>The MIB table shown in the previous section can be compiled
 
363
        as follows:
 
364
        </p>
 
365
      <pre>
 
366
1> <input>snmpc:compile("EmpMIB", [{db, mnesia}]).</input>
 
367
      </pre>
 
368
      <p>This is all that has to be done! Now the manager can read,
 
369
        add, and modify rows. Also, you can use the ordinary Mnesia API
 
370
        to access the table from your programs. The only explicit action
 
371
        is to create the Mnesia table, an action the user has to perform
 
372
        in order to create the required table schemas.</p>
 
373
    </section>
 
374
 
 
375
    <section>
 
376
      <title>Adding Own Actions</title>
 
377
      <p>It is often necessary to take some specific action when a
 
378
        table is modified. This is accomplished with an instrumentation
 
379
        function. It executes some specific code when the table is set,
 
380
        and passes all other requests down to the pre-defined function.
 
381
        </p>
 
382
      <p>The following example illustrates this idea:
 
383
        </p>
 
384
      <code type="none">
 
385
emp_table(set, RowIndex, Cols) ->
 
386
    notify_internal_resources(RowIndex, Cols),
 
387
    snmp_generic:table_func(set, RowIndex, Cols, {empTable, mnesia});
 
388
emp_table(Op, RowIndex, Cols) ->
 
389
    snmp_generic:table_func(Op, RowIndex, Cols, {empTable, mnesia}).
 
390
      </code>
 
391
      <p>The default instrumentation functions are defined in the
 
392
        module <c>snmp_generic</c>. Refer to the Reference Manual,
 
393
        section SNMP, module <c>snmp_generic</c> for details.</p>
 
394
    </section>
 
395
 
 
396
    <section>
 
397
      <title>Extending the Mnesia Table</title>
 
398
      <p>A table may contain columns that are used internally, but
 
399
        should not be visible to a manager. These internal columns must
 
400
        be the last columns in the table. The <c>set</c> operation will
 
401
        not work with this arrangement, because there are columns that
 
402
        the agent does not know about. This situation is handled by
 
403
        adding values for the internal columns in the <c>set</c>
 
404
        function.
 
405
        </p>
 
406
      <p>To illustrate this, suppose we extend our Mnesia
 
407
        <c>empTable</c> with one internal column. We create it as
 
408
        before, but with an arity of 4, by adding another attribute.
 
409
        </p>
 
410
      <code type="none">
 
411
mnesia:create_table([{name, employees},
 
412
                     {snmp, [{key, {integer, string}}]},
 
413
                     {attributes, {key, telno, row_status, internal_col}}]).
 
414
      </code>
 
415
      <p>The last column is the internal column. When performing a
 
416
        <c>set</c> operation, which creates a row, we must give a
 
417
        value to the internal column. The instrumentation functions will now
 
418
        look as follows:
 
419
        </p>
 
420
      <code type="none">
 
421
-define(createAndGo, 4).
 
422
-define(createAndWait, 5).
 
423
 
 
424
emp_table(set, RowIndex, Cols) ->
 
425
  notify_internal_resources(RowIndex, Cols),
 
426
  NewCols =
 
427
    case is_row_created(empTable, Cols) of
 
428
      true -> Cols ++ [{4, "internal"}]; % add internal column
 
429
      false -> Cols                      % keep original cols
 
430
  end,
 
431
  snmp_generic:table_func(set, RowIndex, NewCols, {empTable, mnesia});
 
432
emp_table(Op, RowIndex, Cols) ->
 
433
  snmp_generic:table_func(Op, RowIndex, Cols, {empTable, mnesia}).
 
434
 
 
435
is_row_created(Name, Cols) ->
 
436
  case snmp_generic:get_status_col(Name, Cols) of
 
437
    {ok, ?createAndGo} -> true;
 
438
    {ok, ?createAndWait} -> true;
 
439
    _ -> false
 
440
  end.
 
441
      </code>
 
442
      <p>If a row is created, we always set the internal column to
 
443
        <c>"internal"</c>.
 
444
        </p>
 
445
    </section>
 
446
  </section>
 
447
 
 
448
  <section>
 
449
    <title>Deviations from the Standard</title>
 
450
    <p>In some aspects the agent does not implement SNMP fully.  Here
 
451
      are the differences:
 
452
      </p>
 
453
    <list type="bulleted">
 
454
      <item>The default functions and <c>snmp_generic</c> cannot
 
455
       handle an object of type <c>NetworkAddress</c> as INDEX
 
456
       (SNMPv1 only!).  Use <c>IpAddress</c> instead.
 
457
      </item>
 
458
      <item>The agent does not check complex ranges specified for
 
459
       INTEGER objects.  In these cases it just checks that the value
 
460
       lies within the minimum and maximum values specified.  For
 
461
       example, if the range is specified as <c>1..10 | 12..20</c>
 
462
       the agent would let 11 through, but not 0 or 21.  The
 
463
       instrumentation functions must check the complex ranges
 
464
       itself.
 
465
      </item>
 
466
      <item>The agent will never generate the <c>wrongEncoding</c>
 
467
       error.  If a variable binding is erroneous encoded, the
 
468
      <c>asn1ParseError</c> counter will be incremented.
 
469
      </item>
 
470
      <item>A <c>tooBig</c> error in an SNMPv1 packet will always use
 
471
       the <c>'NULL'</c> value in all variable bindings.
 
472
      </item>
 
473
      <item>The default functions and <c>snmp_generic</c> do not check
 
474
       the range of each OCTET in textual conventions derived from
 
475
       OCTET STRING, e.g. <c>DisplayString</c> and
 
476
      <c>DateAndTime</c>.  This must be checked in an overloaded
 
477
      <c>is_set_ok</c> function.
 
478
      </item>
 
479
    </list>
 
480
  </section>
 
481
</chapter>
 
482