/* * On start-up look for deleted namespaces and auto-acknowledge action required events */ void monitor::EventMonitor::acknowledgeDeletedNamespaces() { LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__); // find action required events for all namespaces struct event_filter filter; memset(&filter, 0, sizeof(filter)); filter.filter_mask = NVM_FILTER_ON_AR | NVM_FILTER_ON_CODE; filter.action_required = true; filter.code = EVENT_CODE_HEALTH_NAMESPACE_HEALTH_STATE_CHANGED; int eventCount = nvm_get_event_count(&filter); if (eventCount < 0) { COMMON_LOG_ERROR_F("nvm_get_event_count failed with error %d", eventCount); } else if (eventCount > 0) { struct event events[eventCount]; memset(events, 0, sizeof (struct event) * eventCount); eventCount = nvm_get_events(&filter, events, eventCount); if (eventCount < 0) { COMMON_LOG_ERROR_F("nvm_get_events failed with error %d", eventCount); } else if (eventCount > 0) { std::vector<std::string> nsUids; bool ackAll = false; // get namespace list int nsCount = nvm_get_namespace_count(); if (nsCount < 0) { COMMON_LOG_ERROR_F("nvm_get_namespace_count failed with error %d", nsCount); } else if (nsCount == 0) { ackAll = true; // no namespaces, acknowledge them all } else // at least one namespace { struct namespace_discovery namespaces[nsCount]; nsCount = nvm_get_namespaces(namespaces, nsCount); if (nsCount < 0) // error retrieving namespace list { COMMON_LOG_ERROR_F("nvm_get_namespaces failed with error %d", nsCount); } else if (nsCount == 0) // no namespaces, acknowledge them all { ackAll = true; } else // at least one namespace { for (int i = 0; i < nsCount; i++) { NVM_UID uidStr; uid_copy(namespaces[i].namespace_uid, uidStr); nsUids.push_back(uidStr); } } } // don't auto-acknowledge on failure to get namespaces if (nsCount || ackAll) { for (int i = 0; i < eventCount; i++) { if (ackAll || namespaceDeleted(events[i].uid, nsUids)) { acknowledgeEvent(EVENT_CODE_HEALTH_NAMESPACE_HEALTH_STATE_CHANGED, events[i].uid); } } } } } }
int LibWrapper::getNamespaces(struct namespace_discovery *pNamespaces, const NVM_UINT8 count) const { LogEnterExit(__FUNCTION__, __FILE__, __LINE__); return nvm_get_namespaces(pNamespaces, count); }
/* * Check for namespace health transitions */ void monitor::EventMonitor::monitorNamespaces(PersistentStore *pStore) { LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__); if (pStore) { // get namespaces int nsCount = nvm_get_namespace_count(); if (nsCount < 0) { COMMON_LOG_ERROR_F("nvm_get_namespace_count failed with error %d", nsCount); } else if (nsCount > 0) { struct namespace_discovery namespaces[nsCount]; memset(namespaces, 0, sizeof (struct namespace_discovery) * nsCount); nsCount = nvm_get_namespaces(namespaces, nsCount); if (nsCount < 0) { COMMON_LOG_ERROR_F("nvm_get_namespaces failed with error %d", nsCount); } else if (nsCount > 0) { // for each namespace for (int i = 0; i < nsCount; i++) { struct namespace_details details; memset(&details, 0, sizeof (details)); NVM_UID uidStr; uid_copy(namespaces[i].namespace_uid, uidStr); int rc = nvm_get_namespace_details(namespaces[i].namespace_uid, &details); if (rc != NVM_SUCCESS) { COMMON_LOG_ERROR_F("nvm_get_namespace_details for namespace %s failed with error %d", uidStr, rc); } else { // get the stored state for this namespace bool storedStateChanged = false; struct db_namespace_state storedState; memset(&storedState, 0, sizeof (storedState)); if (db_get_namespace_state_by_namespace_uid(pStore, uidStr, &storedState) != DB_SUCCESS) { // initial state, just store current state s_strcpy(storedState.namespace_uid, uidStr, NAMESPACE_STATE_NAMESPACE_UID_LEN); storedState.health_state = details.health; storedStateChanged = true; } // log health transition event else if (details.health != storedState.health_state) { enum event_severity severity = EVENT_SEVERITY_INFO; bool actionRequired = false; // namespace is failed if (details.health == NAMESPACE_HEALTH_CRITICAL || details.health == NAMESPACE_HEALTH_BROKENMIRROR) { severity = EVENT_SEVERITY_CRITICAL; actionRequired = true; } // namespace is not failed else { // auto-acknowledge any old namespace health failed events acknowledgeEvent(EVENT_CODE_HEALTH_NAMESPACE_HEALTH_STATE_CHANGED, namespaces[i].namespace_uid); } std::string oldState = namespaceHealthToStr( (enum namespace_health)storedState.health_state); std::string newState = namespaceHealthToStr(details.health); store_event_by_parts( EVENT_TYPE_HEALTH, severity, EVENT_CODE_HEALTH_NAMESPACE_HEALTH_STATE_CHANGED, namespaces[i].namespace_uid, actionRequired, uidStr, oldState.c_str(), newState.c_str(), DIAGNOSTIC_RESULT_UNKNOWN); storedStateChanged = true; storedState.health_state = details.health; if (db_delete_namespace_state_by_namespace_uid(pStore, uidStr) != DB_SUCCESS) { COMMON_LOG_ERROR_F( "Failed to clean up the stored health state for namespace %s", uidStr); } } if (storedStateChanged) { if (db_add_namespace_state(pStore, &storedState) != DB_SUCCESS) { COMMON_LOG_ERROR_F( "Failed to update the stored health state for namespace %s", uidStr); } } } // end nvm_get_namespace_details } // end for each namespace } // end nvm_get_namespaces } // end nvm_get_namespace_count } // end get peristent store }