components/net-snmp-57/sun/agent/modules/entityMib/entLPMappingTable.c
changeset 5867 445e2cf1c845
parent 252 ee0fb1eabcbf
equal deleted inserted replaced
5866:683c5c035a79 5867:445e2cf1c845
       
     1 /*
       
     2  * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
       
     3  *
       
     4  * U.S. Government Rights - Commercial software. Government users are subject
       
     5  * to the Sun Microsystems, Inc. standard license agreement and applicable
       
     6  * provisions of the FAR and its supplements.
       
     7  *
       
     8  *
       
     9  * This distribution may include materials developed by third parties. Sun,
       
    10  * Sun Microsystems, the Sun logo and Solaris are trademarks or registered
       
    11  * trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
       
    12  *
       
    13  */
       
    14 #pragma ident   "@(#)entLPMappingTable.c 1.1     03/02/24 SMI"
       
    15 
       
    16 /*
       
    17  * Note: this file originally auto-generated by mib2c using
       
    18  *        : mib2c.iterate.conf,v 5.4 2002/09/11 22:42:04 hardaker Exp $
       
    19  */
       
    20 
       
    21 #include <net-snmp/net-snmp-config.h>
       
    22 #include <net-snmp/net-snmp-includes.h>
       
    23 #include <net-snmp/agent/net-snmp-agent-includes.h>
       
    24 #include "stdhdr.h"
       
    25 #include "entLPMappingTable.h"
       
    26 #include "entLogicalTable.h"
       
    27 #include "entPhysicalTable.h"
       
    28 #include "entLastChangeTime.h"
       
    29 
       
    30 typedef struct LPIndex_s {
       
    31     entLPMappingTableEntry_t *pLPEntry;
       
    32     int_l *pPhyIndex;      /* Pointer to the current phy index */
       
    33 } LPIndex_t;
       
    34 
       
    35 static LPIndex_t tracker;
       
    36 
       
    37 
       
    38 entLPMappingTableEntry_t* gLPMappingTableHead;
       
    39 int gLPMappingTableSize;
       
    40 
       
    41 /*
       
    42  * Initialize the entLPMappingTable table by defining its contents and how
       
    43  * it's structured
       
    44  */
       
    45 void
       
    46 initialize_table_entLPMappingTable(void)
       
    47 {
       
    48     static oid entLPMappingTable_oid[] = { 1, 3, 6, 1, 2, 1, 47, 1, 3, 1 };
       
    49     netsnmp_table_registration_info *table_info;
       
    50     netsnmp_handler_registration *my_handler;
       
    51     netsnmp_iterator_info *iinfo;
       
    52 
       
    53     /*
       
    54      * create the table structure itself
       
    55      */
       
    56     table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
       
    57     iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
       
    58 
       
    59     /*
       
    60      * if your table is read only, it's easiest to change the
       
    61      * HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY
       
    62      */
       
    63     my_handler =
       
    64         netsnmp_create_handler_registration("entLPMappingTable",
       
    65                                             entLPMappingTable_handler, entLPMappingTable_oid,
       
    66                                             OID_LENGTH(entLPMappingTable_oid), HANDLER_CAN_RONLY);
       
    67 
       
    68     if (!my_handler || !table_info || !iinfo)
       
    69         return;		/* mallocs failed */
       
    70 
       
    71     /*
       
    72      * Setting up the table's definition
       
    73      */
       
    74     netsnmp_table_helper_add_indexes(table_info,
       
    75                                      ASN_INTEGER,	/* index: entLogicalIndex */
       
    76                                      ASN_INTEGER,	/* index: entLPPhysicalIndex */
       
    77                                      0);
       
    78 
       
    79     table_info->min_column = 1;
       
    80     table_info->max_column = 1;
       
    81 
       
    82     /*
       
    83      * iterator access routines
       
    84      */
       
    85     iinfo->get_first_data_point = entLPMappingTable_get_first_data_point;
       
    86     iinfo->get_next_data_point = entLPMappingTable_get_next_data_point;
       
    87 
       
    88     iinfo->table_reginfo = table_info;
       
    89 
       
    90     /*
       
    91      * registering the table with the master agent
       
    92      */
       
    93     DEBUGMSGTL(("initialize_table_entLPMappingTable",
       
    94 		"Registering table entLPMappingTable as a table iterator\n"));
       
    95     netsnmp_register_table_iterator(my_handler, iinfo);
       
    96 }
       
    97 
       
    98 /* Initializes the entLPMappingTable module */
       
    99 void
       
   100 init_entLPMappingTable(void)
       
   101 {
       
   102 
       
   103     /*
       
   104      * here we initialize all the tables we're planning on supporting
       
   105      */
       
   106     initialize_table_entLPMappingTable();
       
   107     gLPMappingTableSize = 0;
       
   108     gLPMappingTableHead = NULL;
       
   109 }
       
   110 
       
   111 /*
       
   112  * returns the first data point within the entLPMappingTable table data.
       
   113  *
       
   114  *  Set the my_loop_context variable to the first data point structure
       
   115  *  of your choice (from which you can find the next one).  This could
       
   116  *  be anything from the first node in a linked list, to an integer
       
   117  *  pointer containing the beginning of an array variable.
       
   118  *
       
   119  *  Set the my_data_context variable to something to be returned to
       
   120  *  you later that will provide you with the data to return in a given
       
   121  *  row.  This could be the same pointer as what my_loop_context is
       
   122  *  set to, or something different.
       
   123  *
       
   124  *  The put_index_data variable contains a list of snmp variable
       
   125  *  bindings, one for each index in your table.  Set the values of
       
   126  *  each appropriately according to the data matching the first row
       
   127  *  and return the put_index_data variable at the end of the function.
       
   128  */
       
   129 netsnmp_variable_list *
       
   130 entLPMappingTable_get_first_data_point(void **my_loop_context,
       
   131                                        void **my_data_context, netsnmp_variable_list * put_index_data,
       
   132                                        netsnmp_iterator_info * mydata)
       
   133 {
       
   134     netsnmp_variable_list *vptr;
       
   135     entLPMappingTableEntry_t *zRunner, *zpValidEntry;
       
   136     int_l *zPhyIndexes, zValidPhyIdx=0, *zpValidPhyIdx;
       
   137 
       
   138     zRunner = gLPMappingTableHead;
       
   139     while (zRunner) {
       
   140         if (zRunner->entLogicalIndex > 0) {
       
   141             zPhyIndexes = zRunner->physicalIndexes;
       
   142             while ((zPhyIndexes != NULL) && (*zPhyIndexes != 0)){
       
   143                 if (*zPhyIndexes > 0) {
       
   144                     zValidPhyIdx = *zPhyIndexes;
       
   145                     break;
       
   146                 }
       
   147                 zPhyIndexes++;
       
   148             }
       
   149             if (zValidPhyIdx) {
       
   150                 zpValidEntry = zRunner;
       
   151                 zpValidPhyIdx = zPhyIndexes;
       
   152                 break;
       
   153             }
       
   154         }
       
   155         zRunner = zRunner->pNextLPMappingTableEntry;
       
   156     }
       
   157     if (zRunner == NULL) return NULL;
       
   158 
       
   159     *my_loop_context = (void *) zpValidEntry;
       
   160     *my_data_context = (void *) zpValidPhyIdx;
       
   161     tracker.pPhyIndex = zpValidPhyIdx;
       
   162 
       
   163     vptr = put_index_data;
       
   164 
       
   165     snmp_set_var_value(vptr, (u_char *) &zpValidEntry->entLogicalIndex,
       
   166                        sizeof(zpValidEntry->entLogicalIndex));
       
   167     vptr = vptr->next_variable;
       
   168     snmp_set_var_value(vptr, (u_char *) zpValidPhyIdx, sizeof(int_l));
       
   169     vptr = vptr->next_variable;
       
   170 
       
   171     return (put_index_data);
       
   172 }
       
   173 
       
   174 /*
       
   175  * functionally the same as entLPMappingTable_get_first_data_point, but
       
   176  * my_loop_context has already been set to a previous value and should
       
   177  * be updated to the next in the list.  For example, if it was a
       
   178  * linked list, you might want to cast it and the return
       
   179  * my_loop_context->next.  The my_data_context pointer should be set
       
   180  * to something you need later and the indexes in put_index_data
       
   181  * updated again.
       
   182  */
       
   183 
       
   184 netsnmp_variable_list *
       
   185 entLPMappingTable_get_next_data_point(void **my_loop_context,
       
   186                                       void **my_data_context, netsnmp_variable_list * put_index_data,
       
   187                                       netsnmp_iterator_info * mydata)
       
   188 {
       
   189     netsnmp_variable_list *vptr;
       
   190     entLPMappingTableEntry_t *zRunner, *zpValidEntry;
       
   191     int_l *zPhyIndexes, zValidPhyIdx=0, *zpValidPhyIdx;
       
   192 
       
   193     zRunner = (entLPMappingTableEntry_t *)*my_loop_context;
       
   194     zPhyIndexes =  tracker.pPhyIndex;
       
   195     if (zPhyIndexes != NULL)
       
   196         zPhyIndexes++;
       
   197     while (zRunner) {
       
   198         if (zRunner->entLogicalIndex > 0) {
       
   199             while ((zPhyIndexes != NULL) && (*zPhyIndexes != 0)){
       
   200                 if (*zPhyIndexes > 0) {
       
   201                     zValidPhyIdx = *zPhyIndexes;
       
   202                     break;
       
   203                 }
       
   204                 zPhyIndexes++;
       
   205             }
       
   206             if (zValidPhyIdx) {
       
   207                 zpValidEntry = zRunner;
       
   208                 zpValidPhyIdx = zPhyIndexes;
       
   209                 break;
       
   210             }
       
   211         }
       
   212         zRunner = zRunner->pNextLPMappingTableEntry;
       
   213         if (zRunner)
       
   214             zPhyIndexes = zRunner->physicalIndexes;
       
   215     }
       
   216     if (zRunner == NULL) return NULL;
       
   217 
       
   218 
       
   219     *my_loop_context = (void *) zpValidEntry;
       
   220     *my_data_context = (void *) zpValidPhyIdx;
       
   221     tracker.pPhyIndex =  zpValidPhyIdx;
       
   222 
       
   223     vptr = put_index_data;
       
   224 
       
   225     snmp_set_var_value(vptr, (u_char *) &zpValidEntry->entLogicalIndex,
       
   226                        sizeof(int_l));
       
   227     vptr = vptr->next_variable;
       
   228     snmp_set_var_value(vptr, (u_char *) zpValidPhyIdx, sizeof(int_l));
       
   229     vptr = vptr->next_variable;
       
   230 
       
   231     return (put_index_data);
       
   232 }
       
   233 
       
   234 /*
       
   235  * handles requests for the entLPMappingTable table, if anything else
       
   236  * needs to be done
       
   237  */
       
   238 int
       
   239 entLPMappingTable_handler(netsnmp_mib_handler * handler,
       
   240                           netsnmp_handler_registration * reginfo,
       
   241                           netsnmp_agent_request_info * reqinfo, netsnmp_request_info * requests)
       
   242 {
       
   243     netsnmp_request_info *request;
       
   244     netsnmp_table_request_info *table_info;
       
   245     netsnmp_variable_list *var;
       
   246     int_l *idx;
       
   247 
       
   248     for (request = requests; request; request = request->next) {
       
   249         var = request->requestvb;
       
   250         if (request->processed != 0)
       
   251             continue;
       
   252 
       
   253         /*
       
   254          * perform anything here that you need to do.  The request have
       
   255          * already been processed by the master table_dataset handler,
       
   256          * but this gives you chance to act on the request in some
       
   257          * other way if need be.
       
   258          */
       
   259 
       
   260         /*
       
   261          * the following extracts the my_data_context pointer set in
       
   262          * the loop functions above.  You can then use the results to
       
   263          * help return data for the columns of the entLPMappingTable
       
   264          * table in question
       
   265          */
       
   266         /*
       
   267          * XXX
       
   268          */
       
   269         idx = (int_l *) netsnmp_extract_iterator_context(request);
       
   270         if (idx == NULL) {
       
   271             if (reqinfo->mode == MODE_GET) {
       
   272                 netsnmp_set_request_error(reqinfo, request,
       
   273                                           SNMP_NOSUCHINSTANCE);
       
   274                 continue;
       
   275             }
       
   276             /*
       
   277              * XXX: no row existed, if you support creation and
       
   278              * this is a set, start dealing with it here, else
       
   279              * continue
       
   280              */
       
   281         }
       
   282 
       
   283         /*
       
   284          * extracts the information about the table from the request
       
   285          */
       
   286         table_info = netsnmp_extract_table_info(request);
       
   287         /*
       
   288          * table_info->colnum contains the column number requested
       
   289          */
       
   290         /*
       
   291          * table_info->indexes contains a linked list of snmp variable
       
   292          * bindings for the indexes of the table.  Values in the list
       
   293          * have been set corresponding to the indexes of the
       
   294          * request
       
   295          */
       
   296         if (table_info == NULL) {
       
   297             continue;
       
   298         }
       
   299 
       
   300         switch (reqinfo->mode) {
       
   301             /*
       
   302              * the table_iterator helper should change all GETNEXTs
       
   303              * into GETs for you automatically, so you don't have to
       
   304              * worry about the GETNEXT case. Only GETs and SETs need
       
   305              * to be dealt with here
       
   306              */
       
   307         case MODE_GET:
       
   308             switch (table_info->colnum) {
       
   309             case COLUMN_ENTLPPHYSICALINDEX:
       
   310                 snmp_set_var_typed_value(var, ASN_INTEGER,
       
   311                                          (u_char *) idx,
       
   312                                          sizeof (idx));
       
   313                 break;
       
   314 
       
   315             default:
       
   316 				/*
       
   317 				 * We shouldn't get here
       
   318 				 */
       
   319                 snmp_log(LOG_ERR, "problem encountered in entLPMappingTable_handler: unknown column\n");
       
   320             }
       
   321             break;
       
   322 
       
   323         case MODE_SET_RESERVE1:
       
   324             /*
       
   325              * set handling...
       
   326              */
       
   327 
       
   328         default:
       
   329             snmp_log(LOG_ERR, "problem encountered in entLPMappingTable_handler: unsupported mode\n");
       
   330         }
       
   331     }
       
   332     return (SNMP_ERR_NOERROR);
       
   333 }
       
   334 
       
   335 /* Return 0 for success
       
   336    1 for entry already exists
       
   337    -1 for failure
       
   338    -2 for stale index */
       
   339 int
       
   340 addLPMappingTableEntry(int xentLogicalIndex, int xentPhysicalIndex)
       
   341 {
       
   342     entLogicalEntry_t *zLogicalEntry; 
       
   343     entPhysicalEntry_t *physentry;
       
   344     entLPMappingTableEntry_t *zLPMappingTableEntry, *zRunner, *zlastEntry;
       
   345     int_l *zPhyIndexes;
       
   346 
       
   347     /* Fix for 4888088: return -1 for out of bound index, return -2 for */
       
   348     /*                  stale entry */
       
   349     if (xentLogicalIndex <= 0 || xentLogicalIndex > MAX_ENTITY_INDEX || xentPhysicalIndex <= 0 || xentPhysicalIndex > MAX_ENTITY_INDEX)
       
   350         return -1;
       
   351     zLogicalEntry = getLogicalTableStaleEntry(xentLogicalIndex); 
       
   352     physentry = getPhysicalTableStaleEntry(xentPhysicalIndex);
       
   353     if ((zLogicalEntry != NULL) || (physentry != NULL)) {
       
   354         return -2;
       
   355     }
       
   356     /* End of Fix for 4888088 */
       
   357 
       
   358     zLogicalEntry = getLogicalTableEntry(xentLogicalIndex); 
       
   359     physentry = getPhysicalTableEntry(xentPhysicalIndex);
       
   360 
       
   361     if ((zLogicalEntry == NULL) || (physentry == NULL)) {
       
   362 /* 
       
   363    Handle error here. Send it to log files
       
   364 */
       
   365         return (-1);
       
   366     }
       
   367     zlastEntry = NULL;
       
   368     zRunner = gLPMappingTableHead;
       
   369     while (zRunner != NULL) {
       
   370         if (zRunner->entLogicalIndex == xentLogicalIndex) {
       
   371             break;
       
   372         }
       
   373         zlastEntry = zRunner;
       
   374         zRunner = zRunner->pNextLPMappingTableEntry;
       
   375     }
       
   376     if (zRunner != NULL ) {/* Found a entry with log index */
       
   377         int_l *p; 
       
   378         p = zRunner->physicalIndexes;
       
   379         if (p == NULL) {
       
   380 	    zPhyIndexes = (int_l *) malloc(2 * sizeof (int_l));
       
   381 	    if (!zPhyIndexes) return -1;
       
   382 	    zPhyIndexes[0] = xentPhysicalIndex;
       
   383             zPhyIndexes[1] = 0;
       
   384 	    zRunner->physicalIndexes = zPhyIndexes;
       
   385         } else {/* Add phy index to last entry in the array */
       
   386             int i=0;
       
   387 	    while (p != NULL && *p != 0) {
       
   388                 /* Fix for 4888088: entry already exists, return 1 */
       
   389 		if (*p == xentPhysicalIndex)
       
   390                     return (1);
       
   391                 /* End of Fix for 4888088 */
       
   392 		if (*p == -xentPhysicalIndex) { /* Reuse a 'deleted' entry */
       
   393 		    *p = xentPhysicalIndex;
       
   394                     /* Fix for 4928821 - does not generate notification event */
       
   395                     configChanged();
       
   396                     /* End of Fix for 4928821 */
       
   397 	            return (0);
       
   398 		}
       
   399 	        p++;
       
   400 		i++;
       
   401 	    }
       
   402 	    zRunner->physicalIndexes = 
       
   403 	        (int_l *)realloc(zRunner->physicalIndexes, (i + 2)*sizeof(int_l));
       
   404 	    zRunner->physicalIndexes[i] = xentPhysicalIndex;
       
   405 	    zRunner->physicalIndexes[i+1] = 0;
       
   406         }
       
   407         configChanged();
       
   408         return (0);
       
   409     } 
       
   410 
       
   411     /* New entry*/
       
   412     zLPMappingTableEntry = (entLPMappingTableEntry_t *)malloc(sizeof(entLPMappingTableEntry_t));
       
   413     if (!zLPMappingTableEntry) return -1; /* malloc failed */
       
   414     zLPMappingTableEntry->entLogicalIndex = xentLogicalIndex;
       
   415     zPhyIndexes = (int_l *) malloc(2 * sizeof (int_l));
       
   416     if (!zPhyIndexes) return -1;
       
   417     zPhyIndexes[0] = xentPhysicalIndex;
       
   418     zPhyIndexes[1] = 0;
       
   419     zLPMappingTableEntry->physicalIndexes = zPhyIndexes;
       
   420     zLPMappingTableEntry->pNextLPMappingTableEntry = NULL;
       
   421     if (gLPMappingTableHead){
       
   422         zlastEntry->pNextLPMappingTableEntry = zLPMappingTableEntry;
       
   423     } else {
       
   424         gLPMappingTableHead = zLPMappingTableEntry;
       
   425     }
       
   426     gLPMappingTableSize++;
       
   427     configChanged();
       
   428     return (0);
       
   429 }
       
   430 
       
   431 
       
   432 /*
       
   433   This function deletes the table entries for a given logical index
       
   434   and physical index. 
       
   435   Returns 0 for success,
       
   436   -1 for failure,
       
   437   -2 for stale entry
       
   438  */
       
   439 int
       
   440 deleteLPMappingTableEntry(int xentLogicalIndex, int xentPhysicalIndex)
       
   441 {
       
   442     entLPMappingTableEntry_t *zRunner;
       
   443     int_l *p;
       
   444 
       
   445     /* Fix for 4888088: return -1 for invalid index, -2 for stale entry */
       
   446     entLogicalEntry_t *zLogicalEntry;
       
   447     entPhysicalEntry_t *zPhysicalEntry;
       
   448 
       
   449     if (xentLogicalIndex <= 0 || xentLogicalIndex > MAX_ENTITY_INDEX || xentPhysicalIndex <= 0 || xentPhysicalIndex > MAX_ENTITY_INDEX)
       
   450         return -1;
       
   451     zLogicalEntry = getLogicalTableStaleEntry(xentLogicalIndex);
       
   452     if (zLogicalEntry != NULL)
       
   453         return -2;
       
   454 
       
   455     zPhysicalEntry = getPhysicalTableStaleEntry(xentPhysicalIndex);
       
   456     if (zPhysicalEntry != NULL)
       
   457         return -2;
       
   458 
       
   459     zLogicalEntry = getLogicalTableEntry(xentLogicalIndex);
       
   460     if (zLogicalEntry == NULL)
       
   461         return -1;
       
   462     zPhysicalEntry = getPhysicalTableEntry(xentPhysicalIndex);
       
   463     if (zPhysicalEntry == NULL)
       
   464         return -1;
       
   465     /* End of Fix for 4888088 */
       
   466 
       
   467     zRunner = gLPMappingTableHead;
       
   468     while (zRunner != NULL) {
       
   469         if ((zRunner->entLogicalIndex == xentLogicalIndex)) {
       
   470             p = zRunner->physicalIndexes;
       
   471             while (p != NULL && *p != 0) {
       
   472                 if (*p == xentPhysicalIndex) {
       
   473                     *p = -xentPhysicalIndex;
       
   474                     configChanged();
       
   475                     return (0);
       
   476                 }
       
   477                 p++;
       
   478             }
       
   479             return (-1);
       
   480         }
       
   481         zRunner = zRunner->pNextLPMappingTableEntry;
       
   482     }
       
   483     return (-1);
       
   484 }
       
   485 
       
   486 static int 
       
   487 FreeLPMappingTableEntry(entLPMappingTableEntry_t *xEntry)
       
   488 {
       
   489     int nFound = 0;
       
   490     /* Fix for 4888088 */
       
   491     int_l *zPhyIndexes;
       
   492     /* End of Fix for 4888088 */
       
   493 
       
   494     if (xEntry == NULL) return (-1);
       
   495     /* Fix for 4888088: We need to count the number of entries deleted, and */
       
   496     /*                  return that accordingly.  Hence the loop */
       
   497     zPhyIndexes = xEntry->physicalIndexes;
       
   498     while ((zPhyIndexes != NULL) && (*zPhyIndexes != 0)) {
       
   499         if (*zPhyIndexes > 0) {
       
   500             /* Only count valid entries (i.e. non-negative ones) */
       
   501             nFound++;
       
   502         }
       
   503         zPhyIndexes++;
       
   504     }
       
   505     /* End of Fix for 4888088 */
       
   506     free(xEntry->physicalIndexes);
       
   507     free(xEntry);
       
   508     xEntry = NULL;
       
   509     /* Fix for 4888088 */
       
   510     return (nFound);
       
   511     /* End of Fix for 4888088 */
       
   512 }
       
   513 
       
   514 /* Returns num of successful deletion
       
   515    -1 for entry not found
       
   516    -2 for stale physical entry
       
   517 */
       
   518 int
       
   519 deleteLPMappingPhysicalIndex(int xentPhysicalIndex) {
       
   520     entLPMappingTableEntry_t *zRunner;
       
   521     int_l *p;
       
   522     int num=0;
       
   523 
       
   524     /* Fix for 4888088: -2 for stale entry, -1 for invalid index */
       
   525     entPhysicalEntry_t *zPhysicalEntry;
       
   526     if (xentPhysicalIndex <= 0 || xentPhysicalIndex > MAX_ENTITY_INDEX)
       
   527         return -1;
       
   528     zPhysicalEntry = getPhysicalTableStaleEntry(xentPhysicalIndex);
       
   529     if (zPhysicalEntry != NULL)
       
   530         return -2;
       
   531     zPhysicalEntry = getPhysicalTableEntry(xentPhysicalIndex);
       
   532     if (zPhysicalEntry == NULL)
       
   533         return -1;
       
   534     /* End of Fix for 4888088 */
       
   535 
       
   536     zRunner = gLPMappingTableHead;
       
   537     while (zRunner != NULL) {
       
   538         p = zRunner->physicalIndexes;
       
   539         while (p != NULL && *p != 0) {
       
   540             if (*p == xentPhysicalIndex) {
       
   541                 *p = -xentPhysicalIndex;
       
   542                 num++;
       
   543                 break;
       
   544             }
       
   545             p++;
       
   546         }
       
   547         zRunner = zRunner->pNextLPMappingTableEntry;
       
   548     }
       
   549     if (num) {
       
   550         configChanged();
       
   551         return (num);
       
   552     } else {
       
   553         return -1;
       
   554     }
       
   555 }
       
   556 
       
   557 /* Returns num of successful deletion
       
   558    -1 for entry not found
       
   559    -2 for stale logical entry
       
   560 */
       
   561 int
       
   562 deleteLPMappingLogicalIndex(int xentLogicalIndex) {
       
   563     entLPMappingTableEntry_t *zRunner, *temp, *prevEntry;
       
   564     int zLogicalIndex, nEntries=0;
       
   565 
       
   566     /* Fix for 4888088: -1 for invalid index, -2 for stale entry */
       
   567     entLogicalEntry_t *zLogicalEntry;
       
   568     if (xentLogicalIndex <= 0 || xentLogicalIndex > MAX_ENTITY_INDEX)
       
   569         return -1;
       
   570     zLogicalEntry = getLogicalTableStaleEntry(xentLogicalIndex);
       
   571     if (zLogicalEntry != NULL)
       
   572         return -2;
       
   573     zLogicalEntry = getLogicalTableEntry(xentLogicalIndex);
       
   574     if (zLogicalEntry == NULL)
       
   575         return -1;
       
   576     /* End of Fix for 4888088 */
       
   577 
       
   578     zRunner = gLPMappingTableHead;
       
   579     prevEntry = NULL;
       
   580     while (zRunner != NULL) {
       
   581         zLogicalIndex = zRunner->entLogicalIndex;
       
   582         if (zLogicalIndex > 0) {
       
   583             if (zLogicalIndex == xentLogicalIndex) {
       
   584                 temp =  zRunner->pNextLPMappingTableEntry;
       
   585                 zRunner->pNextLPMappingTableEntry = NULL;
       
   586                 if (prevEntry)
       
   587                     prevEntry->pNextLPMappingTableEntry = temp;
       
   588                 else
       
   589                     gLPMappingTableHead = temp;
       
   590                 /* Fix for 4888088: we are going to return the number of */
       
   591                 /*                  entries removed */
       
   592                 nEntries = FreeLPMappingTableEntry(zRunner);
       
   593                 /* End of Fix for 4888088 */
       
   594                 gLPMappingTableSize--;
       
   595                 configChanged();
       
   596                 /* Fix for 4888088 */
       
   597                 return (nEntries); /* Successful deletion */
       
   598                 /* End of Fix for 4888088 */
       
   599             }
       
   600         }
       
   601         prevEntry = zRunner;
       
   602         zRunner = zRunner->pNextLPMappingTableEntry;
       
   603     }
       
   604     return (-1); /* Entry not found */
       
   605 } 
       
   606