summaryrefslogtreecommitdiff
path: root/usr/src/lib/fm/libfmd_snmp/common/problem.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/fm/libfmd_snmp/common/problem.c')
-rw-r--r--usr/src/lib/fm/libfmd_snmp/common/problem.c212
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;
}