コード例 #1
0
/*
 * Return the object paths for each instance of the class.
 * One per persistent memory pool in the system.
 */
wbem::framework::instance_names_t *wbem::pmem_config::PersistentMemoryCapabilitiesFactory::getInstanceNames()
	throw(wbem::framework::Exception)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

	framework::instance_names_t *pNames = new framework::instance_names_t();
	try
	{
		// get PM pools
		std::vector<struct pool> pools = wbem::mem_config::PoolViewFactory::getPoolList(true);
		for (std::vector<struct pool>::const_iterator iter = pools.begin();
				iter != pools.end(); iter++)
		{
			framework::attributes_t keys;

			// Instance ID = Pool UID
			NVM_UID poolUidStr;
			uid_copy((*iter).pool_uid, poolUidStr);
			keys[INSTANCEID_KEY] = framework::Attribute(poolUidStr, true);

			framework::ObjectPath path(wbem::server::getHostName(),
					NVM_NAMESPACE, PMCAP_CREATIONCLASSNAME, keys);
			pNames->push_back(path);
		}
	}
	catch (framework::Exception &)
	{
		delete pNames;
		throw;
	}
	return pNames;
}
コード例 #2
0
/*
 * for each device uid, call the library to update it's firmware with the path provided
 */
void wbem::software::NVDIMMSoftwareInstallationServiceFactory::installFromPath(
		const std::string& deviceUid,
		const std::string& path, bool activate, bool force) const
throw (framework::Exception)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);
	COMMON_LOG_DEBUG_F("URI: %s", path.c_str());

	if(path.empty())
	{
		throw framework::ExceptionBadParameter("path");
	}
	if (!core::device::isUidValid(deviceUid))
	{
		throw framework::ExceptionBadParameter("deviceUid");
	}

	int rc;
	NVM_UID uid;
	uid_copy(deviceUid.c_str(), uid);
	// library will check if device is manageable and can update the FW ... if not it will return an error
	if (NVM_SUCCESS !=
			(rc = m_UpdateDeviceFw(uid, path.c_str(), path.length(), activate, force)))
	{
		throw exception::NvmExceptionLibError(rc);
	}
}
コード例 #3
0
void wbem::mem_config::MemoryConfigurationFactory::populateInstanceDimmInfoFromDiscovery(
		framework::attribute_names_t &attributes,
		wbem::framework::Instance *pInstance,
		const struct device_discovery &discovery)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

	// Parent - dimm UID
	if (containsAttribute(PARENT_KEY, attributes))
	{
		NVM_UID uidStr;
		uid_copy(discovery.uid, uidStr);

		framework::Attribute uidAttr(uidStr, false);
		pInstance->setAttribute(PARENT_KEY, uidAttr, attributes);
	}

	// SocketID of DIMM
	if (containsAttribute(SOCKETID_KEY, attributes))
	{
		framework::Attribute socketIdAttr(discovery.socket_id, false);
		pInstance->setAttribute(SOCKETID_KEY, socketIdAttr, attributes);
	}

}
コード例 #4
0
/*
 * Helper function to retrieve just goal instance names
 */
wbem::framework::instance_names_t* wbem::mem_config::MemoryConfigurationFactory::getGoalInstanceNames(
	const bool onlyUnappliedGoals)
		throw (wbem::framework::Exception)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);
	framework::instance_names_t *pNames = new framework::instance_names_t();

	try
	{
		std::string hostName = wbem::server::getHostName();

		// get dimm uids
		std::vector<std::string> uids = wbem::physical_asset::NVDIMMFactory::getManageableDeviceUids();

		for (unsigned int i = 0; i < uids.size(); i++)
		{
			framework::attributes_t keys;
			struct config_goal goal;

			NVM_UID uid;
			uid_copy(uids[i].c_str(), uid);
			int rc;
			if ((rc = nvm_get_config_goal(uid, &goal)) == NVM_SUCCESS)
			{
				if (goal.status != CONFIG_GOAL_STATUS_SUCCESS)
				{
					std::string instanceIdStr(uids[i]);
					instanceIdStr += GOAL_CONFIG;
					keys[INSTANCEID_KEY] = framework::Attribute(instanceIdStr, true);

					framework::ObjectPath configPath(hostName, NVM_NAMESPACE,
						MEMORYCONFIGURATION_CREATIONCLASSNAME, keys);
					pNames->push_back(configPath);
				}
				if ((!onlyUnappliedGoals) &&
					(goal.status == CONFIG_GOAL_STATUS_SUCCESS))
				{
					std::string instanceIdStr(uids[i]);
					instanceIdStr += CURRENT_CONFIG;
					keys[INSTANCEID_KEY] = framework::Attribute(instanceIdStr, true);

					framework::ObjectPath configPath(hostName, NVM_NAMESPACE,
						MEMORYCONFIGURATION_CREATIONCLASSNAME, keys);
					pNames->push_back(configPath);
				}
			}
			else if (rc != NVM_ERR_NOTFOUND)
			{
				throw exception::NvmExceptionLibError(rc);
			}
		}
	}
	catch (framework::Exception &) // clean up and re-throw
	{
		delete pNames;
		throw;
	}

	return pNames;
}
コード例 #5
0
wbem::framework::UINT64 wbem::pmem_config::PersistentMemoryCapabilitiesFactory::getMaxNamespacesPerPool(struct pool *pPool,
		NVM_UINT64 minNamespaceSize)
	throw (framework::Exception)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);
	NVM_UINT64 maxAppDirectNS = 0;
	NVM_UINT64 maxBlockNS = 0;

	NVM_UID poolUidStr;
	uid_copy(pPool->pool_uid, poolUidStr);

	// A pool can have as many App Direct Namespaces as its interleave sets as long as the size is greater
	// than minimum namespace size
	for (int i = 0; i < pPool->ilset_count; i++)
	{
		if (pPool->ilsets[i].size >= minNamespaceSize)
		{
			maxAppDirectNS++;
		}
	}

	// A pool can have as many storage namespaces as its dimms as long as the size is greater
	// than minimum namespace size
	for (int j = 0; j < pPool->dimm_count; j++)
	{
		if (pPool->storage_capacities[j] >= minNamespaceSize)
		{
			maxBlockNS++;
		}
	}

	return (maxAppDirectNS + maxBlockNS);
}
コード例 #6
0
ファイル: security.c プロジェクト: 01org/ixpdimm_sw
int security_change_prepare(struct device_discovery *p_discovery,
		const NVM_PASSPHRASE passphrase, const NVM_SIZE passphrase_len)
{
	COMMON_LOG_ENTRY();
	int rc = NVM_SUCCESS;
	NVM_UID uid_str;

	rc = check_lock_state(p_discovery);

	if (rc != NVM_SUCCESS)
	{
		uid_copy(p_discovery->uid, uid_str);
		COMMON_LOG_ERROR_F("device lock state was not correct for the "
				"requested operation on the device %s", uid_str);
	}
	// Do not proceed if user sends passphrase in disabled state
	else if (passphrase_len > 0 && p_discovery->lock_state == LOCK_STATE_DISABLED)
	{
		uid_copy(p_discovery->uid, uid_str);
		COMMON_LOG_ERROR_F("Failed to modify security on device %s \
				because passphrase is provided when the security is disabled",
				uid_str);
		rc = NVM_ERR_SECURITYDISABLED;
	}
	// if locked, try to unlock
	else if (p_discovery->lock_state == LOCK_STATE_LOCKED)
	{
		// send the pass through ioctl to unlock the dimm
		struct pt_payload_passphrase input_payload;
		memset(&input_payload, 0, sizeof (input_payload));
		s_strncpy(input_payload.passphrase_current, NVM_PASSPHRASE_LEN,
				passphrase, passphrase_len);

		struct fw_cmd cmd;
		memset(&cmd, 0, sizeof (struct fw_cmd));
		cmd.device_handle = p_discovery->device_handle.handle;
		cmd.opcode = PT_SET_SEC_INFO;
		cmd.sub_opcode = SUBOP_UNLOCK_UNIT;
		cmd.input_payload_size = sizeof (input_payload);
		cmd.input_payload = &input_payload;
		rc = ioctl_passthrough_cmd(&cmd);
		s_memset(&input_payload, sizeof (input_payload));
	}

	COMMON_LOG_EXIT_RETURN_I(rc);
	return rc;
}
コード例 #7
0
/*
 * Retrieve a specific instance given an object path
 */
wbem::framework::Instance* wbem::performance::PerformanceMetricFactory::getInstance(
	framework::ObjectPath &path, framework::attribute_names_t &attributes)
throw (wbem::framework::Exception)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

	// Verify attributes
	checkAttributes(attributes);

	framework::Instance *pInstance = NULL;
	try
	{
		pInstance = new framework::Instance(path);

		framework::Attribute instanceIdAttr = path.getKeyValue(INSTANCEID_KEY);

		std::string deviceUid;
		metric_type metric;
		if (!splitInstanceID(instanceIdAttr, deviceUid, metric))
		{
			throw framework::ExceptionBadParameter(instanceIdAttr.asStr().c_str());
		}

		NVM_UID nvmUid;
		uid_copy(deviceUid.c_str(), nvmUid);

		// serialNumberStr is used in more than 1 attribute so getting here.
		std::string serialNumberStr = getDeviceSerialNumber(nvmUid);

		std::string metricName = getMetricElementNameFromType(metric) + " " + serialNumberStr;
		framework::Attribute elementNameAttr(metricName, false);
		(*pInstance).setAttribute(wbem::ELEMENTNAME_KEY, elementNameAttr, attributes);

		const std::string metricDefId
			= PerformanceMetricDefinitionFactory::getMetricId(metric);
		framework::Attribute metricDefinitionAttr(metricDefId, false);
		(*pInstance).setAttribute(wbem::METRICDEFINITION_ID_KEY, metricDefinitionAttr, attributes);

		std::string metricDimm = METRIC_DIMM_STR + serialNumberStr;
		framework::Attribute measuredElementNameAttr(metricDimm, false);
		(*pInstance).setAttribute(wbem::MEASUREDELEMENTNAME_KEY, measuredElementNameAttr, attributes);

		NVM_UINT64 metricValue = getValueForDeviceMetric(nvmUid, metric);
		std::ostringstream stream;
		stream << metricValue;
		framework::Attribute metricValueAttr(stream.str(), false);
		(*pInstance).setAttribute(wbem::METRICVALUE_KEY, metricValueAttr, attributes);
	}
	catch (framework::Exception) // clean up and re-throw
	{
		if (pInstance != NULL)
		{
			delete pInstance;
			pInstance = NULL;
		}
		throw;
	}
	return pInstance;
}
コード例 #8
0
ファイル: security.c プロジェクト: 01org/ixpdimm_sw
int check_lock_state(struct device_discovery *p_discovery)
{
	COMMON_LOG_ENTRY();
	int rc = NVM_SUCCESS;
	NVM_UID uid_str;
	// Do not proceed if frozen
	if (p_discovery->lock_state == LOCK_STATE_FROZEN)
	{
		uid_copy(p_discovery->uid, uid_str);
		COMMON_LOG_ERROR_F("Failed to modify security on device %s \
				because security is frozen",
				uid_str);
		rc = NVM_ERR_SECURITYFROZEN;
	}
	// Do not proceed if max password attempts have been reached
	else if (p_discovery->lock_state == LOCK_STATE_PASSPHRASE_LIMIT)
	{
		uid_copy(p_discovery->uid, uid_str);
		COMMON_LOG_ERROR_F("Failed to modify security on device %s \
				because the passphrase limit has been reached",
				uid_str);
		rc = NVM_ERR_LIMITPASSPHRASE;
	}
	// Do not proceed if unknown
	else if (p_discovery->lock_state == LOCK_STATE_UNKNOWN)
	{
		uid_copy(p_discovery->uid, uid_str);
		COMMON_LOG_ERROR_F("Failed to modify security on device %s \
					because security is unknown",
					uid_str);
		rc = NVM_ERR_LIMITPASSPHRASE;
	}
	// Do not proceed if not supported
	else if (p_discovery->lock_state == LOCK_STATE_NOT_SUPPORTED)
	{
		uid_copy(p_discovery->uid, uid_str);
		COMMON_LOG_ERROR_F("Failed to modify security on device %s \
					because security is not supported",
					uid_str);
		rc = NVM_ERR_NOTSUPPORTED;
	}
	return rc;
}
コード例 #9
0
/*
 * Return the object paths for the MemoryConfiguration Class.
 */
wbem::framework::instance_names_t* wbem::mem_config::MemoryConfigurationFactory::getInstanceNames()
		throw (wbem::framework::Exception)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

	framework::instance_names_t *pNames = new framework::instance_names_t();
	try
	{
		lib_interface::NvmApi *pApi = lib_interface::NvmApi::getApi();
		std::string hostName = pApi->getHostName();

		std::vector<struct pool> pools;
		pApi->getPools(pools);

		std::vector<std::string> uids = wbem::physical_asset::NVDIMMFactory::getManageableDeviceUids();

		for (unsigned int i = 0; i < uids.size(); i++)
		{
			framework::attributes_t keys;

			NVM_UID uid;
			uid_copy(uids[i].c_str(), uid);

			if (MemoryConfigurationServiceFactory::dimmHasGoal(uid))
			{
				std::string instanceIdStr(uids[i]);
				instanceIdStr += GOAL_CONFIG;
				keys[INSTANCEID_KEY] = framework::Attribute(instanceIdStr, true);

				framework::ObjectPath configPath(hostName, NVM_NAMESPACE,
							MEMORYCONFIGURATION_CREATIONCLASSNAME, keys);
				pNames->push_back(configPath);
			}

			if (dimmIsInAPool(uid, pools))
			{
				std::string instanceIdStr(uids[i]);
				instanceIdStr += CURRENT_CONFIG;
				keys[INSTANCEID_KEY] = framework::Attribute(instanceIdStr, true);

				framework::ObjectPath goalPath(hostName, NVM_NAMESPACE,
						MEMORYCONFIGURATION_CREATIONCLASSNAME, keys);
				pNames->push_back(goalPath);
			}
		}
	}
	catch (framework::Exception &) // clean up and re-throw
	{
		delete pNames;
		throw;
	}

	return pNames;
}
コード例 #10
0
ファイル: EventMonitor.cpp プロジェクト: jubalh/IXPDIMMSW
void monitor::EventMonitor::processTopologyModifiedDimms(const DeviceMap &devices,
		const std::vector<std::string> &replacedUids)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

	for (DeviceMap::const_iterator iter = devices.begin();
				iter != devices.end(); iter++)
	{
		const std::string &uidStr = iter->first;
		const struct deviceInfo &device = iter->second;

		// device has moved (handle has changed)
		if (device.discovered && device.stored &&
				(device.discovery.device_handle.handle !=
				device.storedState.device_handle))
		{
			store_event_by_parts(EVENT_TYPE_CONFIG,
					EVENT_SEVERITY_INFO,
					EVENT_CODE_CONFIG_TOPOLOGY_MOVED_DEVICE,
					device.discovery.uid,
					false,
					uidStr.c_str(),
					NULL,
					NULL,
					DIAGNOSTIC_RESULT_UNKNOWN);
		}
		// old device not discovered
		else if (device.stored && !device.discovered)
		{
			// Make sure it's not in the replaced UIDs list
			// if so it's already been covered by replacement events
			if (std::find(replacedUids.begin(), replacedUids.end(),
					uidStr) == replacedUids.end())
			{
				NVM_UID uid;
				uid_copy(uidStr.c_str(), uid);
				store_event_by_parts(EVENT_TYPE_CONFIG,
							EVENT_SEVERITY_CRITICAL,
							EVENT_CODE_CONFIG_TOPOLOGY_MISSING_DEVICE,
							uid,
							false,
							uidStr.c_str(),
							NULL,
							NULL,
							DIAGNOSTIC_RESULT_UNKNOWN);

				// since the dimm is missing,
				// automatically acknowledge any action required events for this dimm
				acknowledgeEvent(-1, uid);
			}
		}
	}
}
コード例 #11
0
wbem::logic::Dimm wbem::logic::MemoryAllocationUtil::deviceDiscoveryToDimm(
		const struct device_discovery& deviceDiscovery)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

	wbem::logic::Dimm dimm;

	NVM_UID uidStr;
	uid_copy(deviceDiscovery.uid, uidStr);
	dimm.uid = uidStr;

	dimm.capacity = deviceDiscovery.capacity;
	dimm.socket = deviceDiscovery.socket_id;
	dimm.memoryController = deviceDiscovery.memory_controller_id;
	dimm.channel = deviceDiscovery.device_handle.parts.mem_channel_id;

	return dimm;
}
コード例 #12
0
ファイル: EventMonitor.cpp プロジェクト: jubalh/IXPDIMMSW
bool monitor::EventMonitor::namespaceDeleted(const NVM_UID nsUid,
		const std::vector<std::string> &nsUids)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);
	bool deleted = false;

	// look for the uid in the list
	NVM_UID uidStr;
	uid_copy(nsUid, uidStr);
	if (std::find(nsUids.begin(), nsUids.end(), uidStr) == nsUids.end())
	{
		// if not found, then deleted
		deleted = true;
	}


	return deleted;
}
コード例 #13
0
void wbem::erasure::ErasureServiceFactory::eraseDevice(std::string deviceUid,
		std::string password)
throw (wbem::framework::Exception)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);
	if (deviceUid.empty() || deviceUid.length() != NVM_MAX_UID_LEN - 1)
	{
		throw framework::ExceptionBadParameter("deviceUid");
	}

	NVM_UID uid;
	uid_copy(deviceUid.c_str(), uid);

	int rc = m_eraseDevice(uid, password.c_str(), password.length());
	if (rc != NVM_SUCCESS)
	{
		throw exception::NvmExceptionLibError(rc);
	}
}
コード例 #14
0
ファイル: WbemToCli.cpp プロジェクト: jubalh/IXPDIMMSW
/*
 * For commands that support the -pool target, verify the pool UID specified
 * or retrieve it if not specified
 */
cli::framework::ErrorResult *cli::nvmcli::WbemToCli::checkPoolUid(
		const cli::framework::ParsedCommand &parsedCommand, std::string &poolUid)
{
    LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

    cli::framework::ErrorResult *pResult = NULL;
    std::string poolTarget =
    		cli::framework::Parser::getTargetValue(parsedCommand, cli::nvmcli::TARGET_POOL.name);
    try
    {
    	std::vector<struct pool> allPools = wbem::mem_config::PoolViewFactory::getPoolList(true);
    	// validity of the pool target is verified in the API layer
        if (!poolTarget.empty())
        {
        	poolUid = poolTarget;
        }
        // no pool target was specified.
        else
        {
        	// only 1 pool, then use it
            if (allPools.size() == 1)
            {
            	NVM_UID uidStr;
                uid_copy(allPools[0].pool_uid, uidStr);
            	poolUid = uidStr;
            }
            // more than one pool, the pool target is required
            else
            {
            	pResult = new framework::SyntaxErrorMissingValueResult(
            			framework::TOKENTYPE_TARGET,
						TARGET_POOL.name.c_str());
            }
        }
    }
    catch (wbem::framework::Exception &e)
    {
        pResult = cli::nvmcli::NvmExceptionToResult(e);
    }
    return pResult;
}
コード例 #15
0
bool wbem::logic::RuleRejectLockedDimms::isDimmLocked(const wbem::logic::Dimm& dimm)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

	bool isLocked = false;

	NVM_UID dimmUid;
	uid_copy(dimm.uid.c_str(), dimmUid);

	for (std::vector<struct device_discovery>::const_iterator iter = m_manageableDevices.begin();
			iter != m_manageableDevices.end(); iter++)
	{
		if (uid_cmp(iter->uid, dimmUid))
		{
			isLocked = isSecurityStateLocked(iter->lock_state);
			break;
		}
	}

	return isLocked;
}
コード例 #16
0
enum wbem::framework::return_codes wbem::software::NVDIMMSoftwareInstallationServiceFactory::examineFwImage(
		const std::string& deviceUid, const std::string& path, std::string &version) const
throw (framework::Exception)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);
	framework::return_codes rc = framework::SUCCESS;
	if (path.empty())
	{
		throw framework::ExceptionBadParameter("path");
	}
	if (!core::device::isUidValid(deviceUid))
	{
		throw framework::ExceptionBadParameter("deviceUid");
	}

	NVM_UID uid;
	uid_copy(deviceUid.c_str(), uid);
	NVM_VERSION fw_version;
	memset(fw_version, 0, NVM_VERSION_LEN);
	int lib_rc;
	if ((lib_rc = m_ExamineFwImage(uid, path.c_str(), path.length(), fw_version, NVM_VERSION_LEN))
			!= NVM_SUCCESS)
	{
		if (lib_rc == NVM_ERR_REQUIRESFORCE)
		{
			rc = framework::REQUIRES_FORCE;
		}
		else
		{
			rc = framework::FAIL;
		}
	}

	version = fw_version;
	return rc;
}
コード例 #17
0
wbem::framework::UINT32 wbem::erasure::ErasureServiceFactory::executeMethod(
		wbem::framework::UINT32 &wbemRc,
		const std::string method,
		wbem::framework::ObjectPath &object,
		wbem::framework::attributes_t &inParms,
		wbem::framework::attributes_t &outParms)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);
	framework::UINT32 httpRc = framework::MOF_ERR_SUCCESS;
	wbemRc = framework::MOF_ERR_SUCCESS;

	if (method == ERASURESERVICE_ERASEDEVICE)
	{
		// uint32 EraseDevice(CIM_Job REF Job, CIM_ManagedElement REF Element,
		//						string ErasureMethod, string Password)

		// get parameters from inParms
		std::string elementObjectString = inParms[ERASURESERVICE_ERASEDEVICE_ELEMENT].stringValue();
		std::string erasureMethod = inParms[ERASURESERVICE_ERASEDEVICE_ERASUREMETHOD].stringValue();
		std::string password = inParms[ERASURESERVICE_ERASEDEVICE_PASSWORD].stringValue();

		enum eraseType eraseType = getEraseType(erasureMethod);

		if (elementObjectString.empty())
		{
			COMMON_LOG_ERROR_F("%s is required.", ERASURESERVICE_ERASEDEVICE_ELEMENT.c_str());
			httpRc = framework::CIM_ERR_INVALID_PARAMETER;
		}
		else if (erasureMethod.empty())
		{
			COMMON_LOG_ERROR_F("%s is required.", ERASURESERVICE_ERASEDEVICE_ERASUREMETHOD.c_str());
			httpRc = framework::CIM_ERR_INVALID_PARAMETER;
		}
		else if (eraseType == ERASETYPE_UNKNOWN)
		{
			COMMON_LOG_ERROR_F("Erasure Method %s is not supported", erasureMethod.c_str());
			httpRc = framework::CIM_ERR_INVALID_PARAMETER;
		}
		// Note: Password will get checked by eraseDevice
		else
		{
			// Build the object path from the attribute
			framework::ObjectPathBuilder builder(elementObjectString);
			framework::ObjectPath elementObject;
			builder.Build(&elementObject);

			try
			{
				if (elementObject.getClass() == physical_asset::NVDIMM_CREATIONCLASSNAME)
				{
					std::string deviceUidStr = elementObject.getKeyValue(TAG_KEY).stringValue();
					if (deviceUidStr.length() != NVM_MAX_UID_LEN - 1)
					{
						throw framework::ExceptionBadParameter("Tag");
					}
					NVM_UID deviceUid;
					uid_copy(deviceUidStr.c_str(), deviceUid);
					eraseDevice(deviceUidStr, password);
				}
				else if (elementObject.getClass() == software::NVDIMMCOLLECTION_CREATIONCLASSNAME)
				{
					eraseDevice(password);
				}
			}
			catch (wbem::exception::NvmExceptionLibError &e)
			{
				wbemRc = getReturnCodeFromLibException(e);
			}
			catch (wbem::framework::ExceptionBadParameter &)
			{
				httpRc = framework::CIM_ERR_INVALID_PARAMETER;
			}
		}
	}
	else if (method == ERASURESERVICE_ERASE)
	{
		// specific "Erase()" return code for "Not Supported"
		// don't use httpRc here because it's a valid method,
		// just not supported by our implementation
		wbemRc = ERASURESERVICE_ERR_NOT_SUPPORTED;
	}
	else
	{
		// all others are unsupported, including "Erase"
		httpRc = framework::CIM_ERR_METHOD_NOT_AVAILABLE;
	}

	return httpRc;
}
コード例 #18
0
ファイル: EventMonitor.cpp プロジェクト: jubalh/IXPDIMMSW
/*
 * 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
}
コード例 #19
0
/*
 * Retrieve a specific instance given an object path
 */
wbem::framework::Instance *wbem::pmem_config::NamespaceSettingsFactory::getInstance(
		framework::ObjectPath &path, framework::attribute_names_t &attributes)
throw(wbem::framework::Exception)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

	// create the instance, initialize with attributes from the path
	framework::Instance *pInstance = new framework::Instance(path);
	try
	{
		checkAttributes(attributes);

		std::string nsUidStr = path.getKeyValue(INSTANCEID_KEY).stringValue();
		if (!core::Helper::isValidNamespaceUid(nsUidStr))
		{
			COMMON_LOG_ERROR_F("NamespaceSettings InstanceID is not a valid namespace uid %s",
					nsUidStr.c_str());
			throw framework::ExceptionBadParameter(INSTANCEID_KEY.c_str());
		}

		struct namespace_details ns = NamespaceViewFactory::getNamespaceDetails(nsUidStr);

		// ElementName = Friendly Name
		if (containsAttribute(ELEMENTNAME_KEY, attributes))
		{
			framework::Attribute a(
					std::string(NSSETTINGS_ELEMENTNAME_PREFIX + ns.discovery.friendly_name), false);
			pInstance->setAttribute(ELEMENTNAME_KEY, a, attributes);
		}

		// AllocationUnits = block size as a string
		if (containsAttribute(ALLOCATIONUNITS_KEY, attributes))
		{
			std::stringstream allocationUnits;
			allocationUnits << NSSETTINGS_ALLOCATIONUNITS_BYTES;
			allocationUnits << "*";
			allocationUnits << ns.block_size;
			framework::Attribute a(allocationUnits.str(), false);
			pInstance->setAttribute(ALLOCATIONUNITS_KEY, a, attributes);
		}

		// Reservation = block count
		if (containsAttribute(RESERVATION_KEY, attributes))
		{
			NVM_UINT64 nsBytes = ns.block_count * ns.block_size;
			framework::Attribute a(nsBytes, false);
			pInstance->setAttribute(RESERVATION_KEY, a, attributes);
		}

		// PoolID = Pool UID
		if (containsAttribute(POOLID_KEY, attributes))
		{
			NVM_UID poolUidStr;
			uid_copy(ns.pool_uid, poolUidStr);
			framework::Attribute a(poolUidStr, false);
			pInstance->setAttribute(POOLID_KEY, a, attributes);
		}

		// ResourceType = type
		if (containsAttribute(RESOURCETYPE_KEY, attributes))
		{
			framework::Attribute a(
					namespaceResourceTypeToValue(ns.type),
					namespaceResourceTypeToStr(ns.type), false);
			pInstance->setAttribute(RESOURCETYPE_KEY, a, attributes);
		}

		// Optimize = Btt
		if (containsAttribute(OPTIMIZE_KEY, attributes))
		{
			framework::Attribute a(
					NamespaceViewFactory::namespaceOptimizeToValue(ns.btt),
					NamespaceViewFactory::namespaceOptimizeToStr(ns.btt), false);
			pInstance->setAttribute(OPTIMIZE_KEY, a, attributes);
		}

		// ChangeableType = 0 - "Fixed � Not Changeable"
		if (containsAttribute(CHANGEABLETYPE_KEY, attributes))
		{
			framework::Attribute a(NSSETTINGS_CHANGEABLETYPE_NOTCHANGEABLETRANSIENT, false);
			pInstance->setAttribute(CHANGEABLETYPE_KEY, a, attributes);
		}
	
		// SecurityFeatures
                if (containsAttribute(ENCRYPTIONENABLED_KEY, attributes))
                {
                        pInstance->setAttribute(ENCRYPTIONENABLED_KEY,
                                framework::Attribute((NVM_UINT16)ns.security_features.encryption, false));
                }

                if (containsAttribute(ERASECAPABLE_KEY, attributes))
                {
                        pInstance->setAttribute(ERASECAPABLE_KEY,
                                framework::Attribute((NVM_UINT16)ns.security_features.erase_capable, false));
                }

		// ChannelInterleaveSize
		if (containsAttribute(CHANNELINTERLEAVESIZE_KEY, attributes))
		{
			NVM_UINT16 channelSize =
					(NVM_UINT16)mem_config::InterleaveSet::getExponentFromInterleaveSize(
								ns.interleave_format.channel);

			framework::Attribute a(channelSize, false);
			pInstance->setAttribute(CHANNELINTERLEAVESIZE_KEY, a, attributes);
		}

		// ControllerInterleaveSize
		if (containsAttribute(CONTROLLERINTERLEAVESIZE_KEY, attributes))
		{
			NVM_UINT16 channelSize =
					(NVM_UINT16)mem_config::InterleaveSet::getExponentFromInterleaveSize(
								ns.interleave_format.imc);

			framework::Attribute a(channelSize, false);
			pInstance->setAttribute(CONTROLLERINTERLEAVESIZE_KEY, a, attributes);
		}

		if (containsAttribute(MEMORYPAGEALLOCATION_KEY, attributes))
		{
			framework::Attribute a((NVM_UINT16)ns.memory_page_allocation,
				NamespaceViewFactory::namespaceMemoryPageAllocationToStr(ns.memory_page_allocation), false);
			pInstance->setAttribute(MEMORYPAGEALLOCATION_KEY, a, attributes);
		}

		// NOTE: No need to populate Parent, or InitialState - only for create
	}
	catch (framework::Exception &)
	{
		if (pInstance)
		{
			delete pInstance;
			pInstance = NULL;
		}
		throw;
	}

	return pInstance;
}
コード例 #20
0
ファイル: EventMonitor.cpp プロジェクト: jubalh/IXPDIMMSW
/*
 * Build a map of uids to discovery information for all NVM-DIMM in the system
 */
void monitor::EventMonitor::buildDeviceMap(DeviceMap& map, bool addStoredTopology)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

	// build a map of the current devices
	int devCount = nvm_get_device_count();
	if (devCount < 0) // error getting dimm count
	{
		COMMON_LOG_ERROR_F("nvm_get_device_count failed with error %d", devCount);
	}
	else if (devCount > 0) // at least one dimm
	{
		struct device_discovery devList[devCount];
		devCount = nvm_get_devices(devList, devCount);
		if (devCount < 0) // error get dimm discovery
		{
			COMMON_LOG_ERROR_F("nvm_get_devices failed with error %d", devCount);
		}
		else if (devCount > 0) // at least one dimm
		{
			for (int i = 0; i < devCount; i++)
			{
				NVM_UID uidStr;
				uid_copy(devList[i].uid, uidStr);
				struct deviceInfo devInfo;
				memset(&devInfo, 0, sizeof (deviceInfo));
				devInfo.discovered = true;
				devInfo.discovery = devList[i];
				if (devList[i].manageability == MANAGEMENT_VALIDCONFIG)
				{
					// Fetch the device status
					int rc = nvm_get_device_status(devList[i].uid, &devInfo.status);
					if (rc != NVM_SUCCESS)
					{
						COMMON_LOG_ERROR_F("nvm_get_device_status failed for dimm %s, error = %d",
								uidStr, rc);
					}
				}
				map[uidStr] = devInfo;
			}
		}
	}

	// add stored db info
	if (addStoredTopology)
	{
		int valid = 0;
		PersistentStore *pStore = get_lib_store();
		if (pStore)
		{
			if ((get_config_value_int(SQL_KEY_TOPOLOGY_STATE_VALID, &valid) == COMMON_SUCCESS) &&
					(valid))
			{
				int topoStateCount = 0;
				if (db_get_topology_state_count(pStore, &topoStateCount) == DB_SUCCESS &&
						topoStateCount > 0)
				{
					// Populate the previous topology state map
					struct db_topology_state topologyState[topoStateCount];
					if (db_get_topology_states(pStore, topologyState, topoStateCount) == topoStateCount)
					{
						for (int i = 0; i < topoStateCount; i++)
						{
							std::string uidStr = topologyState[i].uid;
							if (map.find(uidStr) == map.end()) // doesn't exist - missing dimm
							{
								struct deviceInfo devInfo;
								memset(&devInfo, 0, sizeof (deviceInfo));
								devInfo.discovered = false;
								devInfo.stored = true;
								devInfo.storedState = topologyState[i];
								map[uidStr] = devInfo;
							}
							else
							{
								map[uidStr].stored = true;
								map[uidStr].storedState = topologyState[i];
							}
						}
					}
				}
			}
		}
	}
}
コード例 #21
0
ファイル: EventMonitor.cpp プロジェクト: jubalh/IXPDIMMSW
void monitor::EventMonitor::processTopologyNewDimms(const DeviceMap &devices,
		std::vector<std::string> &replacedUids)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

	for (DeviceMap::const_iterator iter = devices.begin();
			iter != devices.end(); iter++)
	{
		const std::string &uidStr = iter->first;
		const struct deviceInfo &device = iter->second;

		// device is new if it's discovered, but not stored
		if (device.discovered && !device.stored)
		{
			std::string replacedUid =
					getReplacedDimmUid(devices, device.discovery.device_handle.handle);

			// new dimm
			if (replacedUid.empty())
			{
				if (device.status.is_new)
				{
					// user needs to configure the DIMM
					LOG_NEW_DIMM_EVENT(EVENT_CODE_CONFIG_TOPOLOGY_ADDED_NEW_DEVICE,
							device.discovery.uid,
							uidStr.c_str(),
							NULL,
							true);
				}
				else
				{
					// configured DIMM found
					LOG_NEW_DIMM_EVENT(EVENT_CODE_CONFIG_TOPOLOGY_ADDED_CONFIGURED_DEVICE,
							device.discovery.uid,
							uidStr.c_str(),
							NULL,
							false);
				}
			}
			// replaced dimm
			else
			{
				replacedUids.push_back(replacedUid);
				if (device.status.is_new)
				{
					// user needs to configure the DIMM
					LOG_NEW_DIMM_EVENT(EVENT_CODE_CONFIG_TOPOLOGY_REPLACED_NEW_DEVICE,
							device.discovery.uid,
							replacedUid.c_str(),
							uidStr.c_str(),
							true);
				}
				else
				{
					// configured DIMM found
					LOG_NEW_DIMM_EVENT(EVENT_CODE_CONFIG_TOPOLOGY_REPLACED_CONFIGURED_DEVICE,
							device.discovery.uid,
							replacedUid.c_str(),
							uidStr.c_str(),
							false);
				}

				// acknowledge any action required events on the replaced dimm
				NVM_UID uid;
				uid_copy(replacedUid.c_str(), uid);
				acknowledgeEvent(-1, uid);
			}
		}
	}
}
コード例 #22
0
/*
 * Retrieve a specific instance given an object path
 */
wbem::framework::Instance *wbem::pmem_config::PersistentMemoryCapabilitiesFactory::getInstance(
		framework::ObjectPath &path, framework::attribute_names_t &attributes)
throw(wbem::framework::Exception)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

	// create the instance, initialize with attributes from the path
	framework::Instance *pInstance = new framework::Instance(path);
	struct pool *pPool = NULL;
	try
	{
		checkAttributes(attributes);

		pPool = getPool(path);
		struct nvm_capabilities capabilities = getNvmCapabilities();

		// ElementName = "Pool Capabilities for: " + pool UUID
		if (containsAttribute(ELEMENTNAME_KEY, attributes))
		{
			NVM_UID poolUidStr;
			uid_copy(pPool->pool_uid, poolUidStr);
			std::string elementNameStr = PMCAP_ELEMENTNAME + poolUidStr;
			framework::Attribute a(elementNameStr, false);
			pInstance->setAttribute(ELEMENTNAME_KEY, a, attributes);
		}

		// MaxNamespaces = Max namespaces for this pool
		if (containsAttribute(MAXNAMESPACES_KEY, attributes))
		{
			framework::UINT64 maxNs = getMaxNamespacesPerPool(pPool, capabilities.sw_capabilities.min_namespace_size);
			framework::Attribute a(maxNs, false);
			pInstance->setAttribute(MAXNAMESPACES_KEY, a, attributes);
		}

		// SecurityFeatures = Supported security features of the pool
		if (containsAttribute(SECURITYFEATURES_KEY, attributes))
		{
			framework::UINT16_LIST secFeaturesList = getPoolSecurityFeatures(pPool);
			framework::Attribute a(secFeaturesList, false);
			pInstance->setAttribute(SECURITYFEATURES_KEY, a, attributes);
		}

		// AccessGranularity = Block/byte
		if (containsAttribute(ACCESSGRANULARITY_KEY, attributes))
		{
			framework::UINT16_LIST accessList;
			accessList.push_back(PMCAP_ACCESSGRANULARITY_BYTE); // all app direct is byte accessible
			if (pPool->type == POOL_TYPE_PERSISTENT)
			{
				accessList.push_back(PMCAP_ACCESSGRANULARITY_BLOCK); // non mirrored = block capable
			}
			framework::Attribute a(accessList, false);
			pInstance->setAttribute(ACCESSGRANULARITY_KEY, a, attributes);
		}

		// MemoryArchitecture = NUMA
		if (containsAttribute(MEMORYARCHITECTURE_KEY, attributes))
		{
			framework::UINT16_LIST memArchList;
			memArchList.push_back(PMCAP_MEMORYARCHITECTURE_NUMA);
			framework::Attribute a(memArchList, false);
			pInstance->setAttribute(MEMORYARCHITECTURE_KEY, a, attributes);
		}

		// Replication = Mirrored locally or nothing
		if (containsAttribute(REPLICATION_KEY, attributes))
		{
			framework::UINT16_LIST replicationList;
			if (pPool->type == POOL_TYPE_PERSISTENT_MIRROR)
			{
				replicationList.push_back(PMCAP_REPLICATION_LOCAL);
			}
			framework::Attribute a(replicationList, false);
			pInstance->setAttribute(REPLICATION_KEY, a, attributes);
		}

		if (containsAttribute(MEMORYPAGEALLOCATIONCAPABLE_KEY, attributes))
		{
			framework::BOOLEAN capable = capabilities.sw_capabilities.namespace_memory_page_allocation_capable;
			framework::Attribute a(capable, false);
			pInstance->setAttribute(MEMORYPAGEALLOCATIONCAPABLE_KEY, a, attributes);
		}
		delete pPool;
	}
	catch (framework::Exception &) // clean up and re-throw
	{
		if (pInstance)
		{
			delete pInstance;
			pInstance = NULL;
		}
		if (pPool)
		{
			delete pPool;
			pPool = NULL;
		}
		throw;
	}

	return pInstance;
}
コード例 #23
0
/*
 * Retrieve a specific instance given an object path
 */
wbem::framework::Instance* wbem::support::DiagnosticCompletionRecordFactory::getInstance(
		framework::ObjectPath &path, framework::attribute_names_t &attributes)
throw (wbem::framework::Exception)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

	// create the instance, initialize with attributes from the path
	framework::Instance *pInstance = new framework::Instance(path);
	try
	{
		checkAttributes(attributes);

		// gather results
		bool diagFound = false;
		wbem::support::diagnosticResults_t results;
		DiagnosticLogFactory::gatherDiagnosticResults(&results);

		// match the instance ID
		framework::Attribute instanceID = path.getKeyValue(INSTANCEID_KEY);
		for (diagnosticResults_t::iterator iter = results.begin(); iter != results.end(); iter++)
		{
			struct diagnosticResult diag = *iter;
			std::stringstream instanceIdStr;
			instanceIdStr << DIAGNOSTICCOMPLETION_INSTANCEID << diag.id;
			if (instanceID.stringValue() == instanceIdStr.str())
			{
				diagFound = true;

				// ServiceName = Diagnostic Test Name
				if (containsAttribute(SERVICENAME_KEY, attributes))
				{
					std::string testName;
					switch (diag.type)
					{
						case EVENT_TYPE_DIAG_QUICK:
							testName = NVDIMMDIAGNOSTIC_TEST_QUICK;
							break;
						case EVENT_TYPE_DIAG_PLATFORM_CONFIG:
							testName = NVDIMMDIAGNOSTIC_TEST_PLATFORM;
							break;
						case EVENT_TYPE_DIAG_PM_META:
							testName = NVDIMMDIAGNOSTIC_TEST_STORAGE;
							break;
						case EVENT_TYPE_DIAG_SECURITY:
							testName = NVDIMMDIAGNOSTIC_TEST_SECURITY;
							break;
						case EVENT_TYPE_DIAG_FW_CONSISTENCY:
							testName = NVDIMMDIAGNOSTIC_TEST_SETTING;
							break;
						default:
							testName = "Unknown";
							break;
					}
					framework::Attribute serviceNameAttr(testName, false);
					pInstance->setAttribute(SERVICENAME_KEY, serviceNameAttr, attributes);
				}

				// ManagedElementName - Intel NVDIMM + UUID
				if (containsAttribute(MANAGEDELEMENTNAME_KEY, attributes))
				{
					std::string elementName = "";
					if (diag.device_uid)
					{
						NVM_UID uid_str;
						uid_copy(diag.device_uid, uid_str);
						elementName = wbem::physical_asset::NVDIMM_ELEMENTNAME_prefix + uid_str;
					}

					framework::Attribute dimmAttr(elementName, false);
					pInstance->setAttribute(MANAGEDELEMENTNAME_KEY, dimmAttr, attributes);
				}

				// CreationTimeStamp - record time stamp
				if (containsAttribute(CREATIONTIMESTAMP_KEY, attributes))
				{
					framework::Attribute timeAttr(diag.time,
									wbem::framework::DATETIME_SUBTYPE_DATETIME, false);
					pInstance->setAttribute(CREATIONTIMESTAMP_KEY, timeAttr, attributes);
				}

				// ErrorCode - Array of diagnostic result messages
				if (containsAttribute(ERRORCODE_KEY, attributes))
				{
					framework::Attribute msgsAttr(diag.messages, false);
					pInstance->setAttribute(ERRORCODE_KEY, msgsAttr, attributes);
				}

				// CompletionState - Combined result of diagnostic
				if (containsAttribute(COMPLETIONSTATE_KEY, attributes))
				{
					std::string stateStr;
					switch (diag.result)
					{
						case DIAGNOSTIC_RESULT_OK:
							stateStr = "OK";
							break;
						case DIAGNOSTIC_RESULT_WARNING:
							stateStr = "Warning";
							break;
						case DIAGNOSTIC_RESULT_FAILED:
							stateStr = "Failed";
							break;
						case DIAGNOSTIC_RESULT_ABORTED:
							stateStr = "Aborted";
							break;
						case DIAGNOSTIC_RESULT_UNKNOWN:
						default:
							stateStr = "Unknown";
							break;
					}
					framework::Attribute stateAttr((NVM_UINT16)diag.result, stateStr, false);
					pInstance->setAttribute(COMPLETIONSTATE_KEY, stateAttr, attributes);
				}

				break;
			} // end record found
		} // for

		if (!diagFound)
		{
			throw framework::ExceptionBadParameter(INSTANCEID_KEY.c_str());
		}
	}
	catch (framework::Exception) // clean up and re-throw
	{
		delete pInstance;
		throw;
	}

	return pInstance;
}
コード例 #24
0
ファイル: EventMonitor.cpp プロジェクト: jubalh/IXPDIMMSW
/*
 * 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);
					}
				}
			}
		}
	}
}