diff options
Diffstat (limited to 'usr/src/lib/fm/libfmd_snmp/common/problem.c')
-rw-r--r-- | usr/src/lib/fm/libfmd_snmp/common/problem.c | 212 |
1 files changed, 195 insertions, 17 deletions
diff --git a/usr/src/lib/fm/libfmd_snmp/common/problem.c b/usr/src/lib/fm/libfmd_snmp/common/problem.c index 4a495c5a0a..3410118da9 100644 --- a/usr/src/lib/fm/libfmd_snmp/common/problem.c +++ b/usr/src/lib/fm/libfmd_snmp/common/problem.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -127,6 +127,18 @@ faultevent_lookup_index_exact(sunFmProblem_data_t *data, ulong_t index) return (data->d_suspects[index - 1]); } +static sunFmFaultStatus_data_t +faultstatus_lookup_index_exact(sunFmProblem_data_t *data, ulong_t index) +{ + if (index > data->d_nsuspects) + return (NULL); + + if (data->d_statuses == NULL) + return (NULL); + + return (data->d_statuses[index - 1]); +} + /*ARGSUSED*/ static int problem_update_one(const fmd_adm_caseinfo_t *acp, void *arg) @@ -188,6 +200,11 @@ problem_update_one(const fmd_adm_caseinfo_t *acp, void *arg) ASSERT(nelem == data->d_nsuspects); + (void) nvlist_lookup_uint8_array(data->d_aci_event, + FM_SUSPECT_FAULT_STATUS, &data->d_statuses, &nelem); + + ASSERT(nelem == data->d_nsuspects); + uu_avl_node_init(data, &data->d_uuid_avl, problem_uuid_avl_pool); (void) uu_avl_find(problem_uuid_avl, data, NULL, &idx); @@ -636,6 +653,96 @@ sunFmFaultEventTable_nextfe(netsnmp_handler_registration *reginfo, } } +/* + * Returns the ASN.1 lexicographically first fault event after the one + * identified by table_info. Indexes are updated to reflect the OID + * of the data returned. This allows us to implement GETNEXT. + */ +static sunFmFaultStatus_data_t +sunFmFaultStatusTable_nextfe(netsnmp_handler_registration *reginfo, + netsnmp_table_request_info *table_info) +{ + sunFmProblem_data_t *data; + sunFmFaultStatus_data_t rv; + netsnmp_variable_list *var; + ulong_t index; + + for (;;) { + switch (table_info->number_indexes) { + case 2: + default: + DEBUGMSGTL((MODNAME_STR, "nextfe: 2 indices:\n")); + DEBUGMSGVAR((MODNAME_STR, table_info->indexes)); + DEBUGMSG((MODNAME_STR, "\n")); + DEBUGMSGVAR((MODNAME_STR, + table_info->indexes->next_variable)); + DEBUGMSG((MODNAME_STR, "\n")); + index = *(ulong_t *) + table_info->indexes->next_variable->val.integer + 1; + + if ((data = sunFmProblemTable_pr(reginfo, + table_info)) != NULL && + (rv = faultstatus_lookup_index_exact(data, + index)) != NULL) { + snmp_set_var_typed_value( + table_info->indexes->next_variable, + ASN_UNSIGNED, (uchar_t *)&index, + sizeof (index)); + return (rv); + } + + if (sunFmProblemTable_nextpr(reginfo, table_info) == + NULL) + return (NULL); + break; + case 1: + if ((data = sunFmProblemTable_pr(reginfo, + table_info)) != NULL) { + oid tmpoid[MAX_OID_LEN]; + index = 0; + + DEBUGMSGTL((MODNAME_STR, "nextfe: 1 index:\n")); + DEBUGMSGVAR((MODNAME_STR, table_info->indexes)); + DEBUGMSG((MODNAME_STR, "\n")); + var = + SNMP_MALLOC_TYPEDEF(netsnmp_variable_list); + snmp_set_var_typed_value(var, ASN_UNSIGNED, + (uchar_t *)&index, sizeof (index)); + (void) memcpy(tmpoid, reginfo->rootoid, + reginfo->rootoid_len * sizeof (oid)); + tmpoid[reginfo->rootoid_len] = 1; + tmpoid[reginfo->rootoid_len + 1] = + table_info->colnum; + if (build_oid_segment(var) != SNMPERR_SUCCESS) { + snmp_free_varbind(var); + return (NULL); + } + snmp_free_varbind( + table_info->indexes->next_variable); + table_info->indexes->next_variable = var; + table_info->number_indexes = 2; + DEBUGMSGTL((MODNAME_STR, "nextfe: built fake " + "index:\n")); + DEBUGMSGVAR((MODNAME_STR, table_info->indexes)); + DEBUGMSG((MODNAME_STR, "\n")); + DEBUGMSGVAR((MODNAME_STR, + table_info->indexes->next_variable)); + DEBUGMSG((MODNAME_STR, "\n")); + } else { + if (sunFmProblemTable_nextpr(reginfo, + table_info) == NULL) + return (NULL); + } + break; + case 0: + if (sunFmProblemTable_nextpr(reginfo, table_info) == + NULL) + return (NULL); + break; + } + } +} + static sunFmFaultEvent_data_t * sunFmFaultEventTable_fe(netsnmp_handler_registration *reginfo, netsnmp_table_request_info *table_info) @@ -651,6 +758,21 @@ sunFmFaultEventTable_fe(netsnmp_handler_registration *reginfo, *(ulong_t *)table_info->indexes->next_variable->val.integer)); } +static sunFmFaultStatus_data_t +sunFmFaultStatusTable_fe(netsnmp_handler_registration *reginfo, + netsnmp_table_request_info *table_info) +{ + sunFmProblem_data_t *data; + + ASSERT(table_info->number_indexes == 2); + + if ((data = sunFmProblemTable_pr(reginfo, table_info)) == NULL) + return (NULL); + + return (faultstatus_lookup_index_exact(data, + *(ulong_t *)table_info->indexes->next_variable->val.integer)); +} + /*ARGSUSED*/ static void sunFmProblemTable_return(unsigned int reg, void *arg) @@ -828,6 +950,7 @@ sunFmFaultEventTable_return(unsigned int reg, void *arg) netsnmp_table_request_info *table_info; sunFmProblem_data_t *pdata; sunFmFaultEvent_data_t *data; + sunFmFaultStatus_data_t status; ASSERT(netsnmp_handler_check_cache(cache) != NULL); @@ -869,30 +992,58 @@ sunFmFaultEventTable_return(unsigned int reg, void *arg) * for GETNEXT requests. */ - switch (reqinfo->mode) { - case MODE_GET: - if ((data = sunFmFaultEventTable_fe(reginfo, table_info)) == - NULL) { + if (table_info->colnum == SUNFMFAULTEVENT_COL_STATUS) { + switch (reqinfo->mode) { + case MODE_GET: + if ((status = sunFmFaultStatusTable_fe(reginfo, + table_info)) == NULL) { + netsnmp_free_delegated_cache(cache); + (void) pthread_mutex_unlock(&update_lock); + return; + } + break; + case MODE_GETNEXT: + case MODE_GETBULK: + if ((status = sunFmFaultStatusTable_nextfe(reginfo, + table_info)) == NULL) { + netsnmp_free_delegated_cache(cache); + (void) pthread_mutex_unlock(&update_lock); + return; + } + break; + default: + snmp_log(LOG_ERR, MODNAME_STR + ": Unsupported request mode %d\n", reqinfo->mode); netsnmp_free_delegated_cache(cache); (void) pthread_mutex_unlock(&update_lock); return; } - break; - case MODE_GETNEXT: - case MODE_GETBULK: - if ((data = sunFmFaultEventTable_nextfe(reginfo, table_info)) == - NULL) { + } else { + switch (reqinfo->mode) { + case MODE_GET: + if ((data = sunFmFaultEventTable_fe(reginfo, + table_info)) == NULL) { + netsnmp_free_delegated_cache(cache); + (void) pthread_mutex_unlock(&update_lock); + return; + } + break; + case MODE_GETNEXT: + case MODE_GETBULK: + if ((data = sunFmFaultEventTable_nextfe(reginfo, + table_info)) == NULL) { + netsnmp_free_delegated_cache(cache); + (void) pthread_mutex_unlock(&update_lock); + return; + } + break; + default: + snmp_log(LOG_ERR, MODNAME_STR + ": Unsupported request mode %d\n", reqinfo->mode); netsnmp_free_delegated_cache(cache); (void) pthread_mutex_unlock(&update_lock); return; } - break; - default: - snmp_log(LOG_ERR, MODNAME_STR ": Unsupported request mode %d\n", - reqinfo->mode); - netsnmp_free_delegated_cache(cache); - (void) pthread_mutex_unlock(&update_lock); - return; } switch (table_info->colnum) { @@ -978,6 +1129,33 @@ sunFmFaultEventTable_return(unsigned int reg, void *arg) free(str); break; } + case SUNFMFAULTEVENT_COL_STATUS: + { + ulong_t pl; + + if (status & FM_SUSPECT_FAULTY) + pl = SUNFMFAULTEVENT_STATE_FAULTY; + else if (status & FM_SUSPECT_NOT_PRESENT) + pl = SUNFMFAULTEVENT_STATE_REMOVED; + else if (status & FM_SUSPECT_REPLACED) + pl = SUNFMFAULTEVENT_STATE_REPLACED; + else if (status & FM_SUSPECT_REPAIRED) + pl = SUNFMFAULTEVENT_STATE_REPAIRED; + else if (status & FM_SUSPECT_ACQUITTED) + pl = SUNFMFAULTEVENT_STATE_ACQUITTED; + netsnmp_table_build_result(reginfo, request, table_info, + ASN_UNSIGNED, (uchar_t *)&pl, sizeof (pl)); + break; + } + case SUNFMFAULTEVENT_COL_LOCATION: + { + char *location = "-"; + + (void) nvlist_lookup_string(data, FM_FAULT_LOCATION, &location); + netsnmp_table_build_result(reginfo, request, table_info, + ASN_OCTET_STR, (uchar_t *)location, strlen(location)); + break; + } default: break; } |