The agent I'm writing uses mib2c.iterator.conf, and creates fairly
straightforward C as expected. I fix a couple of syntax errors and fill in a
few of the details the mib2c configuration needs, and in the
initialize_table_<my table> function, I create several items using the linked
list system mib2c generated for me. Log messages I've sprinkled throughout the
get_first_data_point, get_next_data_point, and other similar functions
demonstrate that the linked list is correctly populated, and remains correctly
populated throughout the life of the agent, as expected. However, when I try
to walk the table with snmpwalk, it only ever returns one element in the
table. What's more, it never shows me any of the values of the three index
columns I have on the table. I can't help but think these problems are
related. Attached are the relevant section of the MIB I'm implementing, as
well as the two source files from mib2c, with my modifications, should anyone
care to peek inside. Many thanks, in advance, for any light shed...

 - Josh / eggyknap
pgsqlPgAmopTable                OBJECT-TYPE
        SYNTAX          SEQUENCE OF pgsqlPgAmopEntry
        MAX-ACCESS      not-accessible
        STATUS          current
        DESCRIPTION
                "The catalog pg_amop stores information about operators 
associated with index access method operator classes. There is one row for each 
operator that is a member of an operator class."
        ::= { pgsqlCatalogTables 3 }

pgsqlPgAmopEntry                OBJECT-TYPE
        SYNTAX          PgsqlPgAmopEntry
        MAX-ACCESS      not-accessible
        STATUS          current
        DESCRIPTION
                "pg_amop entry"
        INDEX  { pgsnmpdConnID, rdbmsDbIndex, pgsqlPgAmopEntryOID }
        ::= { pgsqlPgAmopTable 1 }

PgsqlPgAmopEntry ::=
        SEQUENCE {
                pgsqlPgAmopEntryOID             INTEGER,
                pgsqlPgAmopAmopfamily           INTEGER,
                pgsqlPgAmopAmoplefttype         INTEGER,
                pgsqlPgAmopAmoprighttype                INTEGER,
                pgsqlPgAmopAmopstrategy         INTEGER,
                pgsqlPgAmopAmopreqcheck         TruthValue,
                pgsqlPgAmopAmopopr              INTEGER,
                pgsqlPgAmopAmopmethod           INTEGER
        }

pgsqlPgAmopEntryOID                     OBJECT-TYPE
        SYNTAX          INTEGER
        MAX-ACCESS      not-accessible
        STATUS          current
        DESCRIPTION
                "OID of this entry"
        ::= { pgsqlPgAmopEntry 1 }

pgsqlPgAmopAmopfamily                   OBJECT-TYPE
        SYNTAX          INTEGER
        MAX-ACCESS      read-only
        STATUS          current
        DESCRIPTION
                "The operator family this entry is for"
        ::= { pgsqlPgAmopEntry 2 }

pgsqlPgAmopAmoplefttype                 OBJECT-TYPE
        SYNTAX          INTEGER
        MAX-ACCESS      read-only
        STATUS          current
        DESCRIPTION
                "Left-hand input data type of operator"
        ::= { pgsqlPgAmopEntry 3 }

pgsqlPgAmopAmoprighttype                        OBJECT-TYPE
        SYNTAX          INTEGER
        MAX-ACCESS      read-only
        STATUS          current
        DESCRIPTION
                "Right-hand input data type of operator"
        ::= { pgsqlPgAmopEntry 4 }

pgsqlPgAmopAmopstrategy                 OBJECT-TYPE
        SYNTAX          INTEGER
        MAX-ACCESS      read-only
        STATUS          current
        DESCRIPTION
                "Operator strategy number"
        ::= { pgsqlPgAmopEntry 5 }

pgsqlPgAmopAmopreqcheck                 OBJECT-TYPE
        SYNTAX          TruthValue
        MAX-ACCESS      read-only
        STATUS          current
        DESCRIPTION
                "Index hit must be rechecked"
        ::= { pgsqlPgAmopEntry 6 }

pgsqlPgAmopAmopopr                      OBJECT-TYPE
        SYNTAX          INTEGER
        MAX-ACCESS      read-only
        STATUS          current
        DESCRIPTION
                "OID of the operator"
        ::= { pgsqlPgAmopEntry 7 }

pgsqlPgAmopAmopmethod                   OBJECT-TYPE
        SYNTAX          INTEGER
        MAX-ACCESS      read-only
        STATUS          current
        DESCRIPTION
                "Index access method operator family is for"
        ::= { pgsqlPgAmopEntry 8 }


---------------------------------------
/*
 * Note: this file originally auto-generated by mib2c using
 *  : mib2c.iterate.conf 15999 2007-03-25 22:32:02Z dts12 $
 */

#include "pgsnmpd.h"
#include "pgsqlPgAmopTable.h"

void fill_pgsqlPgAmopTable(void);

/** Initializes the pgsqlPgAmopTable module */
void
init_pgsqlPgAmopTable(void)
{
  /* here we initialize all the tables we're planning on supporting */
    initialize_table_pgsqlPgAmopTable();
}

  /* TODO: "Determine the first/last column names" */

/** Initialize the pgsqlPgAmopTable table by defining its contents and how it's structured */
void
initialize_table_pgsqlPgAmopTable(void)
{
    static oid pgsqlPgAmopTable_oid[] = {1,3,6,1,4,1,27645,1,2,3};
    size_t pgsqlPgAmopTable_oid_len   = OID_LENGTH(pgsqlPgAmopTable_oid);
    netsnmp_handler_registration    *reg;
    netsnmp_iterator_info           *iinfo;
    netsnmp_table_registration_info *table_info;

    reg = netsnmp_create_handler_registration(
              "pgsqlPgAmopTable",     pgsqlPgAmopTable_handler,
              pgsqlPgAmopTable_oid, pgsqlPgAmopTable_oid_len,
              HANDLER_CAN_RONLY
              );

    table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
    netsnmp_table_helper_add_indexes(table_info,
                           ASN_OCTET_STR,  /* index: pgsnmpdConnID */
                           ASN_INTEGER,  /* index: rdbmsDbIndex */
                           ASN_INTEGER,  /* index: pgsqlPgAmopEntryOID */
                           0);
    table_info->min_column = COLUMN_PGSQLPGAMOPAMOPFAMILY;
    table_info->max_column = COLUMN_PGSQLPGAMOPAMOPMETHOD;
    
    iinfo = SNMP_MALLOC_TYPEDEF( netsnmp_iterator_info );
    iinfo->get_first_data_point = pgsqlPgAmopTable_get_first_data_point;
    iinfo->get_next_data_point  = pgsqlPgAmopTable_get_next_data_point;
    iinfo->table_reginfo        = table_info;
    
    netsnmp_register_table_iterator( reg, iinfo );

    /* Initialise the contents of the table here */
    fill_pgsqlPgAmopTable();
}

#define CONNID_LEN 255

    /* Typical data structure for a row entry */
struct pgsqlPgAmopTable_entry {
    /* Index values */
    u_char pgsnmpdConnID[CONNID_LEN];
    size_t pgsnmpdConnID_len;
    long rdbmsDbIndex;
    long pgsqlPgAmopEntryOID;

    /* Column values */
    long pgsqlPgAmopAmopfamily;
    long pgsqlPgAmopAmoplefttype;
    long pgsqlPgAmopAmoprighttype;
    int  pgsqlPgAmopAmopstrategy;
    int  pgsqlPgAmopAmopreqcheck;
    long pgsqlPgAmopAmopopr;
    long pgsqlPgAmopAmopmethod;

    /* Illustrate using a simple linked list */
    int   valid;
    struct pgsqlPgAmopTable_entry *next;
};

struct pgsqlPgAmopTable_entry  *pgsqlPgAmopTable_head = NULL;

/* Quiet compiler */
struct pgsqlPgAmopTable_entry *
pgsqlPgAmopTable_createEntry(
                 char* pgsnmpdConnID,
                 size_t pgsnmpdConnID_len,
                 long  rdbmsDbIndex,
                 long  pgsqlPgAmopEntryOID
                );
void
pgsqlPgAmopTable_removeEntry( struct pgsqlPgAmopTable_entry *entry );

/* create a new row in the (unsorted) table */
struct pgsqlPgAmopTable_entry *
pgsqlPgAmopTable_createEntry(
                 char* pgsnmpdConnID,
                 size_t pgsnmpdConnID_len,
                 long  rdbmsDbIndex,
                 long  pgsqlPgAmopEntryOID
                ) {
    struct pgsqlPgAmopTable_entry *entry;

    entry = SNMP_MALLOC_TYPEDEF(struct pgsqlPgAmopTable_entry);
    if (!entry)
        return NULL;

    /*memset(entry->pgsnmpdConnID, 0, CONNID_LEN); */
    memcpy(entry->pgsnmpdConnID, pgsnmpdConnID, pgsnmpdConnID_len);
    entry->pgsnmpdConnID_len = pgsnmpdConnID_len;
    entry->rdbmsDbIndex = rdbmsDbIndex;
    entry->pgsqlPgAmopEntryOID = pgsqlPgAmopEntryOID;

    entry->next = pgsqlPgAmopTable_head;
    pgsqlPgAmopTable_head = entry;
    return entry;
}

/* remove a row from the table */
void
pgsqlPgAmopTable_removeEntry( struct pgsqlPgAmopTable_entry *entry ) {
    struct pgsqlPgAmopTable_entry *ptr, *prev;

    if (!entry)
        return;    /* Nothing to remove */

    for ( ptr  = pgsqlPgAmopTable_head, prev = NULL;
          ptr != NULL;
          prev = ptr, ptr = ptr->next ) {
        if ( ptr == entry )
            break;
    }
    if ( !ptr )
        return;    /* Can't find it */

    if ( prev == NULL )
        pgsqlPgAmopTable_head = ptr->next;
    else
        prev->next = ptr->next;

    SNMP_FREE( entry );   /* XXX - release any other internal resources */
}

void fill_pgsqlPgAmopTable(void) {
    PGresult *pg_db_query;
    int resultCount, i;
    struct pgsqlPgAmopTable_entry *entry;
    char pgsnmpdConnID[112] = "Default conn ID";
    size_t pgsnmpdConnID_len = strlen(pgsnmpdConnID) + 1;
    long rdbmsDbIndex = 1;

    snmp_log(LOG_INFO, "Initializing pgsqlPgAmopTable\n");
    if (PQstatus(dbconn) == CONNECTION_OK) {
        pg_db_query = PQexec(dbconn, "SELECT oid::INTEGER, amopfamily::INTEGER, amoplefttype::INTEGER, amoprighttype::INTEGER, amopstrategy, amopreqcheck, amopopr::INTEGER , amopmethod::INTEGER FROM pg_amop ORDER BY 1 ASC");
    }
    else {
        snmp_log(LOG_ERR, "Can't get connected to database\n");
        return;
        /* TODO: I should signal MFD_RESOURCE_UNAVAILABLE somehow, here */
    }

    if (PQresultStatus(pg_db_query) != PGRES_TUPLES_OK) {
        snmp_log(LOG_ERR, "Didn't get any results from the database\n");
        PQclear(pg_db_query);
        return;
        /* TODO: I should signal MFD_RESOURCE_UNAVAILABLE somehow, here */
    }
    resultCount = PQntuples(pg_db_query);
    for (i = 0; i < resultCount; i++) {
        entry = pgsqlPgAmopTable_createEntry(pgsnmpdConnID, pgsnmpdConnID_len,
                 rdbmsDbIndex, atol(PQgetvalue(pg_db_query, i, 0)));
        entry->pgsqlPgAmopAmopfamily    = atol(PQgetvalue(pg_db_query, i, 1));
        entry->pgsqlPgAmopAmoplefttype  = atol(PQgetvalue(pg_db_query, i, 2));
        entry->pgsqlPgAmopAmoprighttype = atol(PQgetvalue(pg_db_query, i, 3));
        entry->pgsqlPgAmopAmopstrategy  = atoi(PQgetvalue(pg_db_query, i, 4));
        entry->pgsqlPgAmopAmopreqcheck  = atoi(PQgetvalue(pg_db_query, i, 5));
        entry->pgsqlPgAmopAmopopr       = atol(PQgetvalue(pg_db_query, i, 6));
        entry->pgsqlPgAmopAmopmethod    = atol(PQgetvalue(pg_db_query, i, 7));
    }
    snmp_log(LOG_INFO, "Finished initializing pgsqlPgAmopTable with %d entries\n", resultCount);
}

/* Example iterator hook routines - using 'get_next' to do most of the work */
netsnmp_variable_list *
pgsqlPgAmopTable_get_first_data_point(void **my_loop_context,
                          void **my_data_context,
                          netsnmp_variable_list *put_index_data,
                          netsnmp_iterator_info *mydata)
{
    *my_loop_context = pgsqlPgAmopTable_head;
    return pgsqlPgAmopTable_get_next_data_point(my_loop_context, my_data_context,
                                    put_index_data,  mydata );
}

netsnmp_variable_list *
pgsqlPgAmopTable_get_next_data_point(void **my_loop_context,
                          void **my_data_context,
                          netsnmp_variable_list *put_index_data,
                          netsnmp_iterator_info *mydata)
{
    struct pgsqlPgAmopTable_entry *entry = (struct pgsqlPgAmopTable_entry *)*my_loop_context;
    netsnmp_variable_list *idx = put_index_data;

    if ( entry ) {
        snmp_set_var_value( idx, entry->pgsnmpdConnID, sizeof(entry->pgsnmpdConnID) );
        idx = idx->next_variable;
        snmp_set_var_typed_integer( idx, ASN_INTEGER, entry->rdbmsDbIndex );
        idx = idx->next_variable;
        snmp_set_var_typed_integer( idx, ASN_INTEGER, entry->pgsqlPgAmopEntryOID );
        idx = idx->next_variable;
        *my_data_context = (void *)entry;
        *my_loop_context = (void *)entry->next;
        return put_index_data;
    } else {
        return NULL;
    }
}


/** handles requests for the pgsqlPgAmopTable table */
int
pgsqlPgAmopTable_handler(
    netsnmp_mib_handler               *handler,
    netsnmp_handler_registration      *reginfo,
    netsnmp_agent_request_info        *reqinfo,
    netsnmp_request_info              *requests) {

    netsnmp_request_info       *request;
    netsnmp_table_request_info *table_info;
    struct pgsqlPgAmopTable_entry          *table_entry;

    switch (reqinfo->mode) {
        /*
         * Read-support (also covers GetNext requests)
         */
    case MODE_GET:
        for (request=requests; request; request=request->next) {
            table_entry = (struct pgsqlPgAmopTable_entry *)
                              netsnmp_extract_iterator_context(request);
            table_info  =     netsnmp_extract_table_info(      request);
    
            switch (table_info->colnum) {
            case COLUMN_PGSQLPGAMOPAMOPFAMILY:
                if ( !table_entry ) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->pgsqlPgAmopAmopfamily);
                break;
            case COLUMN_PGSQLPGAMOPAMOPLEFTTYPE:
                if ( !table_entry ) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->pgsqlPgAmopAmoplefttype);
                break;
            case COLUMN_PGSQLPGAMOPAMOPRIGHTTYPE:
                if ( !table_entry ) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->pgsqlPgAmopAmoprighttype);
                break;
            case COLUMN_PGSQLPGAMOPAMOPSTRATEGY:
                if ( !table_entry ) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->pgsqlPgAmopAmopstrategy);
                break;
            case COLUMN_PGSQLPGAMOPAMOPREQCHECK:
                if ( !table_entry ) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->pgsqlPgAmopAmopreqcheck);
                break;
            case COLUMN_PGSQLPGAMOPAMOPOPR:
                if ( !table_entry ) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->pgsqlPgAmopAmopopr);
                break;
            case COLUMN_PGSQLPGAMOPAMOPMETHOD:
                if ( !table_entry ) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->pgsqlPgAmopAmopmethod);
                break;
            default:
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHOBJECT);
                break;
            }
        }
        break;

    }
    return SNMP_ERR_NOERROR;
}
/*
 * Note: this file originally auto-generated by mib2c using
 *  : mib2c.iterate.conf 15999 2007-03-25 22:32:02Z dts12 $
 */
#ifndef PGSQLPGAMOPTABLE_H
#define PGSQLPGAMOPTABLE_H

/* function declarations */
void init_pgsqlPgAmopTable(void);
void initialize_table_pgsqlPgAmopTable(void);
Netsnmp_Node_Handler pgsqlPgAmopTable_handler;
Netsnmp_First_Data_Point  pgsqlPgAmopTable_get_first_data_point;
Netsnmp_Next_Data_Point   pgsqlPgAmopTable_get_next_data_point;

/* column number definitions for table pgsqlPgAmopTable */
       #define COLUMN_PGSQLPGAMOPENTRYOID		1
       #define COLUMN_PGSQLPGAMOPAMOPFAMILY		2
       #define COLUMN_PGSQLPGAMOPAMOPLEFTTYPE		3
       #define COLUMN_PGSQLPGAMOPAMOPRIGHTTYPE		4
       #define COLUMN_PGSQLPGAMOPAMOPSTRATEGY		5
       #define COLUMN_PGSQLPGAMOPAMOPREQCHECK		6
       #define COLUMN_PGSQLPGAMOPAMOPOPR		7
       #define COLUMN_PGSQLPGAMOPAMOPMETHOD		8
#endif /* PGSQLPGAMOPTABLE_H */

Attachment: signature.asc
Description: Digital signature

------------------------------------------------------------------------------
Register Now for Creativity and Technology (CaT), June 3rd, NYC. CaT 
is a gathering of tech-side developers & brand creativity professionals. Meet
the minds behind Google Creative Lab, Visual Complexity, Processing, & 
iPhoneDevCamp as they present alongside digital heavyweights like Barbarian 
Group, R/GA, & Big Spaceship. http://p.sf.net/sfu/creativitycat-com 
_______________________________________________
Net-snmp-users mailing list
Net-snmp-users@lists.sourceforge.net
Please see the following page to unsubscribe or change other options:
https://lists.sourceforge.net/lists/listinfo/net-snmp-users

Reply via email to