Ejemplo n.º 1
0
/*
 * 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);
					}
				}
			}
		}
	}
}
Ejemplo n.º 2
0
int LibWrapper::getNamespaceCount() const
{
	LogEnterExit(__FUNCTION__, __FILE__, __LINE__);
	return nvm_get_namespace_count();
}
Ejemplo n.º 3
0
/*
 * 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
}