Solaris System Management Agent Developer's Guide

Simple Tables

A simple table has four characteristics:

If any of these conditions are not met, the table is not a simple table but a general table. The techniques described here are applicable only to simple tables.


Note –

mib2c assumes that all tables are simple. For information on handling the general tables case, see General Tables.


If your MIB contains simple tables, you must run mib2c with a configuration file that handles code generation for simple tables. You should use the following command, where mibnode1 and mibnode2 are top level nodes of tabular data for which you want to generate code:


mib2c -c mib2c.iterate.conf mibnode1 mibnode2 ...

You can specify as many nodes of simple table data as you want. This command generates two C code files that are named mibnode.c and mibnode.h for each MIB node that is specified in the command line. You must modify the mibnode1.c and mibnode2.c files to enable the agent to retrieve data from simple tables. See the mib2c(1M) man page for more information about using the mib2c tool.

The demo_module_2 code example shows how to generate code templates for simple tables.

demo_module_2 Code Example for Simple Tables

The demo_module_2 code example is provided to help you understand how to modify the code generated by the mib2c command to perform data retrieval from simple tables. The demo_module_2 code example is located by default in the directory /usr/demo/sma_snmp/demo_module_2.

The README_demo_module_2 file contains instructions that describe how to do the following tasks:

The demo_module_2 is set up to allow you to generate code templates me1FileTable.c and me1FileTable.h. You can then compare the generated files to the files demo_module_2.c and demo_module_2.h.

The mib2c utility generates me1FileTable.c, which contains the init_me1FileTable() function. You should compare this function to the init_demo_module_2() function in the demo_module_2.c file.

Modifications for Simple Table Data Retrieval

In demo_module_2.c, the init_demo_module_2 routine calls the initialize_table_me1FileTable() function. The initialize_table_me1FileTable() function registers the OID for the table handled by the function. The function also calls some Net-SNMP functions to initialize the tables.

You should provide the table data in this initialize_table_me1FileTable() function if needed. The initialize_table_me1FileTable() function performs the following:

Initialization

The initialize_table_me1FileTable() function performs the real table initialization, by performing tasks such as setting the maximum number of rows and columns.

OID Table Definition

The initialize_table_me1FileTable() function defines the table OID:

static oid me1FileTable_oid[] =
  {1,3,6,1,4,1,42,2,2,4,4,1,2,1};
Table Definition

The initialize_table_me1FileTable() function sets up the table's definition. This function specifies another function to call, me1FileTable_get_first_data_point(), to process the first row of data in the table. The function me1FileTable_get_next_data_point() is called to process the remaining rows in the table.

netsnmp_table_helper_add_indexes(table_info,
ASN_UNSIGNED, /* index: me1FileIndex */
0);

     table_info->min_column = 1;
     table_info->max_column = 4;

  /* iterator access routines */
iinfo->get_first_data_point = 
           me1FileTable_get_first_data_point;
iinfo->get_next_data_point = 
           me1FileTable_get_next_data_point;
iinfo->table_reginfo = 
           table_info;

iinfo is a pointer to a netsnmp_iterator_info structure.

Master Agent Registration

The initialize_table_me1FileTable() function registers the table with the master agent:

netsnmp_register_table_iterator(my_handler, iinfo);

The table iterator is a helper function that modules can use to index through rows in a table. Functionally, the table iterator is a specialized version of the more generic table helper. The table iterator eases the burden of GETNEXT processing. The table iterator loops through all the data indexes retrieved through those function calls that should be supplied by the module that requests help. See the API documentation at /usr/sfw/doc/sma_snmp/html/group__table__iterator.html for more information on table iterator APIs.

Note that the input MIB file contains the specification of table and scalar data. However, when you run mib2c with mib2c.iterate.conf and specify the table node name, only template code for the simple table in the MIB is generated.

Data Retrieval From Large Simple Tables

Data retrieval from a simple table requires you to use the single, integer index subidentifier to index into an existing data structure.

With some modules, this underlying table might be relatively large, or only accessible through a cumbersome interface. Data retrieval might be very slow, particularly if performing a walk of a MIB tree requires the table to be reloaded for each variable requested. In these circumstances, a useful technique is to cache the table on the first read and use that cache for subsequent requests.

To cache the table, you must have a separate routine to read in the table. The routine uses two static variables. One variable is a structure or array for the data. The other variable is an additional timestamp to indicate when the table was last loaded. When a call is made to the routine to read the table, the routine can first determine whether the cached table is sufficiently new. If the data is recent enough, the routine can return immediately. The system then uses the cached data. If the cached version is old enough to be considered out of date, the routine can retrieve the current data. The routine updates the cached version of the data and the timestamp value. This approach is particularly useful if the data is relatively static, such as a list of mounted file systems.

Multiple SET Processing in demo_module_2

The demo_module_2 example code shows how to perform a multiple OID set action. In this case, a file name and row status are provided.

When the agent processes a SET request, a series of calls to the MIB module code are made. These calls ensure that all SET requests in the incoming packet can be processed successfully. This processing allows modules the chance to get out of the transaction sequence early. If the module gets out of one transaction early, none of the transactions in the set are completed, in order to maintain continuity. However, this behavior makes the code for processing SET requests more complex. The following diagram is a simple state diagram that shows each step of the master agent's SET processing.

Figure 3–1 Set Processing State Diagram

State diagram shows each
step of the master agent's set processing.

An operation with no failures is illustrated by the vertical path on the left, in the preceding figure. If any of the MIB modules that are being acted upon returns an error, the agent branches to one of the failure states. The failure states are on the right side in the figure. These failure states require you to clean up and, where necessary, undo the actions of previous steps in your module.

See the me1FileTable_handler() function in the demo_module_2 example code, for how to perform SET requests in different states. The following is list describes each of the states:

case MODE_SET_RESERVE1

Checks that the value being set is acceptable.

case MODE_SET_RESERVE2

Allocates any necessary resources. For example, calls to the malloc() function occur here.

case MODE_SET_FREE

Frees resources when one of the other values being SET failed for some reason.

case MODE_SET_ACTION

Sets the variable as requested and saves information that might be needed in order to reverse this SET later.

case MODE_SET_COMMIT

Operation is successful. Discards saved information and makes the change permanent. For example, writes to the snmpd.conf configuration file and frees any allocated resources.

case MODE_SET_UNDO

A failure occurred, so resets the variable to its previous value. Frees any allocated resources.

You can perform the set action using either of the following commands when you use the demo_module_2 example:


snmpset -v1 -c private localhost me1FileTable.1.2.3 s "test"

snmpset -v1 -c private localhost .1.3.6.1.4.1.42.2.2.4.4.1.2.1.1.2.2 s "test"

These commands change the file that you want to monitor.


Note –

In order to use the snmpset command to specify a different file name, you must have a private community string in the snmpd.conf file, which is located in /etc/sma/snmp or $HOME/.snmp.