Пример #1
0
/*
 * Check a passphrase for validity.
 * There are no restrictions on passphrase characters, just min and max length.
 * These restrictions come from the Security Architecture team.
 */
int check_passphrase(const NVM_PASSPHRASE passphrase, const NVM_SIZE passphrase_len)
{
	COMMON_LOG_ENTRY();
	int rc = NVM_SUCCESS;
	if (passphrase == NULL)
	{
		COMMON_LOG_ERROR("Invalid parameter, new_passphrase is NULL");
		rc = NVM_ERR_BADPASSPHRASE;
	}
	else if (passphrase_len > NVM_PASSPHRASE_LEN)
	{
		COMMON_LOG_ERROR_F("Invalid passphrase length (%d). Passphrase length must be <= %d",
				passphrase_len, NVM_PASSPHRASE_LEN);
		rc = NVM_ERR_BADPASSPHRASE;
	}
	// TODO: this might change to minimum of 10.
	else if (passphrase_len == 0)
	{
		COMMON_LOG_ERROR_F("Invalid passphrase length (%d). Passphrase length must be > 0",
				passphrase_len);
		rc = NVM_ERR_BADPASSPHRASE;
	}
	COMMON_LOG_EXIT_RETURN_I(rc);
	return rc;
}
Пример #2
0
void wbem::profile::RegisteredProfileFactory::buildInstanceFromProfileInfoMap(framework::Instance& instance,
		const framework::attribute_names_t& attributes) throw (framework::Exception)
{
	framework::Attribute instanceIdAttr;
	if (instance.getAttribute(INSTANCEID_KEY, instanceIdAttr) != framework::SUCCESS)
	{
		COMMON_LOG_ERROR_F("couldn't get key '%s'", INSTANCEID_KEY.c_str());
		throw framework::ExceptionBadAttribute(INSTANCEID_KEY.c_str());
	}

	// Make sure the InstanceID is in our map
	std::string instanceId = instanceIdAttr.stringValue(); // hostname + registeredname 
	std::string hostName = server::getHostName();

	if ((instanceId.size() >  hostName.size()) &&
		(instanceId.substr(0, hostName.size()) == hostName))
	{ // remove hostname from instanceid for comparision
		instanceId = instanceId.substr(hostName.length());
	}

	std::map<std::string, struct ProfileInfo>::iterator profileIter = m_profileInfoMap.find(instanceId);
	if (profileIter == m_profileInfoMap.end()) // not found!
	{
		COMMON_LOG_ERROR_F("value of key '%s' (%s) doesn't match a real instance",
				INSTANCEID_KEY.c_str(),
				instanceId.c_str());
		throw framework::ExceptionBadAttribute(INSTANCEID_KEY.c_str());
	}

	buildInstanceFromProfileInfo(instance, attributes, profileIter->second);
}
Пример #3
0
/*
 * Helper function to enable/disable software trigger
 */
int inject_software_trigger(struct device_discovery *p_discovery,
		enum error_type type, NVM_BOOL enable_trigger)
{
	COMMON_LOG_ENTRY();
	int rc = NVM_SUCCESS;

	// Set up input payload
	struct pt_payload_sw_triggers input;
	memset(&input, 0, sizeof (input));
	switch (type)
	{
	case ERROR_TYPE_DIE_SPARING:
		if (!p_discovery->device_capabilities.die_sparing_capable)
		{
			COMMON_LOG_ERROR_F("Die sparing is not supported on dimm %u",
					p_discovery->device_handle.handle);
			rc = NVM_ERR_NOTSUPPORTED;
		}
		input.die_sparing_trigger = enable_trigger;
		break;
	case ERROR_TYPE_SPARE_ALARM:
		input.user_spare_block_alarm_trip_trigger = enable_trigger;
		break;
	case ERROR_TYPE_MEDIA_FATAL_ERROR:
		input.fatal_error_trigger = enable_trigger;
		break;
	default:
		break;
	}

	if (rc == NVM_SUCCESS)
	{
		struct fw_cmd cmd;
		memset(&cmd, 0, sizeof (cmd));
		cmd.device_handle = p_discovery->device_handle.handle;
		cmd.opcode = PT_INJECT_ERROR;
		cmd.sub_opcode = SUBOP_ERROR_SW_TRIGGERS;
		cmd.input_payload = &input;
		cmd.input_payload_size = sizeof (input);
		rc = ioctl_passthrough_cmd(&cmd);
		if (rc != NVM_SUCCESS)
		{
			COMMON_LOG_ERROR_F("Failed to trigger software alarm trip on dimm %u",
					cmd.device_handle);
		}
	}

	COMMON_LOG_EXIT_RETURN_I(rc);
	return rc;
}
Пример #4
0
/*
 * Helper function to inject/clear a particular artificial temperature into the part
 */
int inject_temperature_error(NVM_UINT32 device_handle, NVM_UINT64 temperature,
	NVM_BOOL enable_injection)
{
	COMMON_LOG_ENTRY();
	int rc = NVM_SUCCESS;

	// Set up input
	struct pt_payload_temp_err temp_err_input;
	memset(&temp_err_input, 0, sizeof (temp_err_input));
	temp_err_input.enable = enable_injection;
	temp_err_input.temperature = fw_convert_float_to_fw_celsius(
		nvm_decode_temperature(temperature));

	struct fw_cmd cmd;
	memset(&cmd, 0, sizeof (cmd));
	cmd.device_handle = device_handle;
	cmd.opcode = PT_INJECT_ERROR;
	cmd.sub_opcode = SUBOP_ERROR_TEMP;
	cmd.input_payload = &temp_err_input;
	cmd.input_payload_size = sizeof (temp_err_input);
	rc = ioctl_passthrough_cmd(&cmd);
	if (rc != NVM_SUCCESS)
	{
		COMMON_LOG_ERROR_F("Failed to set temperature on dimm %u",
			device_handle);
	}

	COMMON_LOG_EXIT_RETURN_I(rc);
	return rc;
}
Пример #5
0
void core::memory_allocator::MemoryAllocator::allocate(struct MemoryAllocationLayout &layout)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);
	bool atLeastOneRequestSucceeded = false;

	for (std::map<std::string, struct config_goal>::iterator goalIter = layout.goals.begin();
			goalIter != layout.goals.end(); goalIter++)
	{
		try
		{
			std::string uid = goalIter->first;
			m_nvmLib.createConfigGoal(uid, (*goalIter).second);

			atLeastOneRequestSucceeded = true;
		}
		catch (core::LibraryException &e)
		{
			COMMON_LOG_ERROR_F("creating config goal failed with rc = %d",
					e.getErrorCode());
			if (atLeastOneRequestSucceeded)
			{
				throw core::NvmExceptionPartialResultsCouldNotBeUndone();
			}
			else
			{
				throw;
			}
		}
	}
}
Пример #6
0
std::string CreateGoalCommand::UserPrompt::getStringForLayoutWarning(
    enum core::memory_allocator::LayoutWarningCode warningCode)
{
    LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

    std::string warningStr;

    switch (warningCode)
    {
    case core::memory_allocator::LAYOUT_WARNING_APP_DIRECT_NOT_SUPPORTED_BY_DRIVER:
        warningStr = CREATE_GOAL_APP_DIRECT_NOT_SUPPORTED_BY_DRIVER_WARNING;
        break;
    case core::memory_allocator::LAYOUT_WARNING_STORAGE_NOT_SUPPORTED_BY_DRIVER:
        warningStr = CREATE_GOAL_STORAGE_ONLY_NOT_SUPPORTED_BY_DRIVER_WARNING;
        break;
    case core::memory_allocator::LAYOUT_WARNING_NONOPTIMAL_POPULATION:
        warningStr = CREATE_GOAL_NON_OPTIMAL_DIMM_POPULATION_WARNING;
        break;
    case core::memory_allocator::LAYOUT_WARNING_REQUESTED_MEMORY_MODE_NOT_USABLE:
        warningStr = CREATE_GOAL_REQUESTED_MEMORY_MODE_NOT_USABLE_WARNING;
        break;
    default:
        COMMON_LOG_ERROR_F("Unrecognized layout warning code: %d", warningCode);
        warningStr = "";
    }

    return warningStr;
}
Пример #7
0
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;
}
Пример #8
0
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;
}
/*
 * Retrieve pool struct given an object path
 */
struct pool *wbem::pmem_config::PersistentMemoryCapabilitiesFactory::getPool(
	wbem::framework::ObjectPath &object)
	throw (wbem::framework::Exception)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

	std::string poolUidStr = object.getKeyValue(INSTANCEID_KEY).stringValue();
	if (!core::Helper::isValidPoolUid(poolUidStr))
	{
		COMMON_LOG_ERROR_F("PersistentMemoryCapabilitiesFactory InstanceID is not a valid pool uid %s",
				poolUidStr.c_str());
		throw framework::ExceptionBadParameter(INSTANCEID_KEY.c_str());
	}
	return mem_config::PoolViewFactory::getPool(poolUidStr);
}
Пример #10
0
/*
 * Helper function to validate setting poison on a particular DPA
 * Poison is only possible for addresses in the PM range but not while the PM region is locked
 */
int validate_poison_injection(struct device_discovery *p_discovery, NVM_UINT64 dpa)
{
	int rc = NVM_SUCCESS;
	COMMON_LOG_ENTRY();

	// check if dimm is locked
	if (p_discovery->lock_state != LOCK_STATE_LOCKED)
	{
		// get the DPA start address of PMEM region from the dimm partition info
		struct pt_payload_get_dimm_partition_info partition_info;
		memset(&partition_info, 0, sizeof (partition_info));
		struct fw_cmd partition_cmd;
		memset(&partition_cmd, 0, sizeof (partition_cmd));
		partition_cmd.device_handle = p_discovery->device_handle.handle;
		partition_cmd.opcode = PT_GET_ADMIN_FEATURES;
		partition_cmd.sub_opcode = SUBOP_DIMM_PARTITION_INFO;
		partition_cmd.output_payload_size = sizeof (partition_info);
		partition_cmd.output_payload = &partition_info;
		if ((rc = ioctl_passthrough_cmd(&partition_cmd)) != NVM_SUCCESS)
		{
			COMMON_LOG_ERROR_F("Failed getting dimm %u partition information",
					p_discovery->device_handle.handle);
		}
		else
		{
			// DPA is in PM range
			if ((dpa >= partition_info.start_pmem) &&
					(dpa < partition_info.start_pmem + partition_info.pmem_capacity))
			{
				rc = NVM_SUCCESS;
			}
			else
			{
				rc = NVM_ERR_INVALIDPARAMETER;
				COMMON_LOG_ERROR("Setting poison is only possible in PM range.");
			}
		}
	}
	else
	{
		rc = NVM_ERR_BADSECURITYSTATE;
		COMMON_LOG_ERROR("Setting poison is not possible when dimm is locked.");
	}

	COMMON_LOG_EXIT_RETURN_I(rc);
	return rc;
}
Пример #11
0
/*
 * Helper function to allow setting/clearing poison on a particular DPA
 */
int inject_poison_error(struct device_discovery *p_discovery, NVM_UINT64 dpa, NVM_BOOL set_poison)
{
	int rc = NVM_SUCCESS;
	COMMON_LOG_ENTRY();

	if (set_poison)
	{
		if ((rc = validate_poison_injection(p_discovery, dpa)) != NVM_SUCCESS)
		{
			COMMON_LOG_ERROR("Invalid parameter, DPA is invalid");
		}
	}

	if (rc == NVM_SUCCESS)
	{
		// Set up input
		struct pt_payload_poison_err poison_err_input;
		memset(&poison_err_input, 0, sizeof (poison_err_input));
		poison_err_input.enable = set_poison;
		poison_err_input.dpa_address = dpa;

		struct fw_cmd cmd;
		memset(&cmd, 0, sizeof (cmd));
		cmd.device_handle = p_discovery->device_handle.handle;
		cmd.opcode = PT_INJECT_ERROR;
		cmd.sub_opcode = SUBOP_ERROR_POISON;
		cmd.input_payload = &poison_err_input;
		cmd.input_payload_size = sizeof (poison_err_input);
		rc = ioctl_passthrough_cmd(&cmd);

		if (rc != NVM_SUCCESS)
		{
			COMMON_LOG_ERROR_F("Failed to set/clear poison on dimm %u",
					p_discovery->device_handle.handle);
		}
	}

	COMMON_LOG_EXIT_RETURN_I(rc);
	return rc;
}
Пример #12
0
/*
 * Check for device health changes
 */
void monitor::EventMonitor::monitorDimmStatus(const std::string &uidStr,
		const struct device_discovery &discovery,
		struct db_dimm_state &storedState,
		bool &storedStateChanged,
		bool firstState)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

	struct device_status status;
	int rc = nvm_get_device_status(discovery.uid, &status);
	if (rc != NVM_SUCCESS)
	{
		COMMON_LOG_ERROR_F("nvm_get_device_status for dimm %s failed with error %d\n",
				uidStr.c_str(), rc);
	}
	else
	{
		// first pass, just store current values
		if (firstState)
		{
			storedState.health_state = status.health;
			storedState.die_spares_used = status.die_spares_used;
		}
		// check for changes
		else
		{
			// check dimm health
			if (status.health != storedState.health_state)
			{
				// log transition event
				enum event_severity severity = EVENT_SEVERITY_INFO;
				bool actionRequired = false;
				if (status.health == DEVICE_HEALTH_NONCRITICAL)
				{
					severity = EVENT_SEVERITY_WARN;
				}
				else if (status.health == DEVICE_HEALTH_CRITICAL)
				{
					severity = EVENT_SEVERITY_CRITICAL;
					actionRequired = true;
				}
				else if (status.health >= DEVICE_HEALTH_FATAL)
				{
					severity = EVENT_SEVERITY_FATAL;
					actionRequired = true;
				}

				std::string oldState = deviceHealthToStr(
						(enum device_health)storedState.health_state);
				std::string newState = deviceHealthToStr(status.health);
				store_event_by_parts(
						EVENT_TYPE_HEALTH,
						severity,
						EVENT_CODE_HEALTH_HEALTH_STATE_CHANGED,
						discovery.uid,
						actionRequired,
						uidStr.c_str(),
						oldState.c_str(),
						newState.c_str(),
						DIAGNOSTIC_RESULT_UNKNOWN);

				storedState.health_state = status.health;
				storedStateChanged = true;
			}

			// check additional die consumed
			if (status.die_spares_used > storedState.die_spares_used)
			{
				std::stringstream numDieConsumed;
				numDieConsumed << status.die_spares_used;
				store_event_by_parts(EVENT_TYPE_HEALTH,
						EVENT_SEVERITY_WARN,
						EVENT_CODE_HEALTH_SPARE_DIE_CONSUMED,
						discovery.uid,
						false,
						uidStr.c_str(),
						numDieConsumed.str().c_str(),
						NULL,
						DIAGNOSTIC_RESULT_UNKNOWN);

				storedState.die_spares_used = status.die_spares_used;
				storedStateChanged = true;
			}
		}
	}
}
Пример #13
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;
}
Пример #14
0
void monitor::EventMonitor::checkConfigGoalStatus(const std::string &uidStr, const deviceInfo &device) const
{
	// check platform config errors
	struct event_filter filter;
	memset(&filter, 0, sizeof (filter));
	filter.filter_mask = NVM_FILTER_ON_UID | NVM_FILTER_ON_TYPE;
	memmove(filter.uid, device.discovery.uid, NVM_MAX_UID_LEN);
	filter.type = EVENT_TYPE_CONFIG;

	struct config_goal goal;
	memset(&goal, 0, sizeof (goal));
	int rc = nvm_get_config_goal(device.discovery.uid, &goal);
	if (rc == NVM_SUCCESS)
	{
		enum config_goal_status configGoalStatus = goal.status;
		// ensure this is a new event
		if (!device.stored ||
		    configGoalStatus != device.storedState.config_goal_status)
		{
			// configuration processed successfully
			if (configGoalStatus == CONFIG_GOAL_STATUS_SUCCESS)
			{
				store_event_by_parts(EVENT_TYPE_CONFIG,
				                     EVENT_SEVERITY_INFO,
				                     EVENT_CODE_CONFIG_GOAL_APPLIED,
				                     device.discovery.uid,
				                     false,
				                     uidStr.c_str(),
				                     NULL,
				                     NULL,
				                     DIAGNOSTIC_RESULT_UNKNOWN);

				// acknowledge any old config events for this dimm
				acknowledge_events(&filter);
			}
			else if (configGoalStatus == CONFIG_GOAL_STATUS_ERR_BADREQUEST)
			{
				store_event_by_parts(EVENT_TYPE_CONFIG,
				                     EVENT_SEVERITY_WARN,
				                     EVENT_CODE_CONFIG_GOAL_FAILED_CONFIG_ERROR,
				                     device.discovery.uid,
				                     true,
				                     uidStr.c_str(),
				                     NULL,
				                     NULL,
				                     DIAGNOSTIC_RESULT_UNKNOWN);
			}
			else if (configGoalStatus == CONFIG_GOAL_STATUS_ERR_FW)
			{
				store_event_by_parts(EVENT_TYPE_CONFIG,
				                     EVENT_SEVERITY_WARN,
				                     EVENT_CODE_CONFIG_GOAL_FAILED_FW_ERROR,
				                     device.discovery.uid,
				                     true,
				                     uidStr.c_str(),
				                     NULL,
				                     NULL,
				                     DIAGNOSTIC_RESULT_UNKNOWN);
			}
			else if (configGoalStatus == CONFIG_GOAL_STATUS_ERR_INSUFFICIENTRESOURCES)
			{
				store_event_by_parts(EVENT_TYPE_CONFIG,
				                     EVENT_SEVERITY_WARN,
				                     EVENT_CODE_CONFIG_GOAL_FAILED_INSUFFICIENT_RESOURCES,
				                     device.discovery.uid,
				                     true,
				                     uidStr.c_str(),
				                     NULL,
				                     NULL,
				                     DIAGNOSTIC_RESULT_UNKNOWN);
			}
			else if (configGoalStatus == CONFIG_GOAL_STATUS_ERR_UNKNOWN)
			{
				store_event_by_parts(EVENT_TYPE_CONFIG,
				                     EVENT_SEVERITY_WARN,
				                     EVENT_CODE_CONFIG_GOAL_FAILED_UNKNOWN,
				                     device.discovery.uid,
				                     true,
				                     uidStr.c_str(),
				                     NULL,
				                     NULL,
				                     DIAGNOSTIC_RESULT_UNKNOWN);
			}
			else if (configGoalStatus == CONFIG_GOAL_STATUS_UNKNOWN)
			{
				store_event_by_parts(EVENT_TYPE_CONFIG,
				                     EVENT_SEVERITY_CRITICAL,
				                     EVENT_CODE_CONFIG_DATA_INVALID,
				                     device.discovery.uid,
				                     true,
				                     uidStr.c_str(),
				                     NULL,
				                     NULL,
				                     DIAGNOSTIC_RESULT_UNKNOWN);
			}
		} // end new config status
	}
	else if (rc == NVM_ERR_BADDEVICECONFIG)
	{
		store_event_by_parts(EVENT_TYPE_CONFIG,
		                     EVENT_SEVERITY_CRITICAL,
		                     EVENT_CODE_CONFIG_DATA_INVALID,
		                     device.discovery.uid,
		                     true,
		                     uidStr.c_str(),
		                     NULL,
		                     NULL,
		                     DIAGNOSTIC_RESULT_UNKNOWN);
	}
	else if (rc == NVM_ERR_NOTFOUND)
	{
		COMMON_LOG_DEBUG_F("No config goal found for DIMM %s", uidStr.c_str());
	}
	else
	{
		COMMON_LOG_ERROR_F("Error fetching config goal for DIMM %s, rc=%d", uidStr.c_str(), rc);
	}
}
Пример #15
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);
					}
				}
			}
		}
	}
}
Пример #16
0
void monitor::EventMonitor::monitor()
{
	PersistentStore *pStore = get_lib_store();
	if (pStore)
	{
		LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

		// clean up any context
		nvm_create_context();

		DeviceMap devMap;
		buildDeviceMap(devMap);
		for (DeviceMap::const_iterator devIter = devMap.begin();
				devIter != devMap.end(); devIter++)
		{
			const std::string &uidStr = devIter->first;
			const struct device_discovery &discovery = devIter->second.discovery;

			// ignore unmanageable dimms
			if (discovery.manageability == MANAGEMENT_VALIDCONFIG)
			{
				bool storedStateChanged = false;
				bool firstState = false;

				// get stored device state
				struct db_dimm_state storedState;
				memset(&storedState, 0, sizeof (storedState));
				if (db_get_dimm_state_by_device_handle(pStore,
						discovery.device_handle.handle, &storedState) != DB_SUCCESS)
				{
					// initial state, just store current
					firstState = true;
					COMMON_LOG_INFO_F("Failed to retrieve the stored health state of dimm %u",
							discovery.device_handle.handle);
					storedState.device_handle = discovery.device_handle.handle;
					storedStateChanged = true;
				}

				// check for dimm health state transition
				monitorDimmStatus(uidStr, discovery, storedState,
						storedStateChanged, firstState);

				// check for dimm sensor transitions
				monitorDimmSensors(uidStr, discovery, storedState,
						storedStateChanged, firstState);

				// update stored dimm state
				if (storedStateChanged)
				{
					// clear existing dimm state
					if (!firstState)
					{
						db_delete_dimm_state_by_device_handle(pStore,
								discovery.device_handle.handle);
					}
					// add current state
					if (db_add_dimm_state(pStore, &storedState) != DB_SUCCESS)
					{
						COMMON_LOG_ERROR_F("Failed to store the health state of dimm %u",
								discovery.device_handle.handle);
					}
				}
			}
		}

		// Monitor namespace health transitions
		monitorNamespaces(pStore);

		// clean up
		devMap.clear();
		nvm_free_context();
	}

}
Пример #17
0
/*
 * Retrieve a specific instance given an object path
 */
wbem::framework::Instance* wbem::memory::MemoryControllerFactory::getInstance(
	framework::ObjectPath &path, framework::attribute_names_t &attributes)
	throw (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);

		path.checkKey(CREATIONCLASSNAME_KEY, MEMORYCONTROLLER_CREATIONCLASSNAME);
		path.checkKey(SYSTEMCREATIONCLASSNAME_KEY, server::BASESERVER_CREATIONCLASSNAME);
		path.checkKey(SYSTEMNAME_KEY, server::getHostName());

		// extract the memory controller id from the object path
		framework::Attribute devIdAttr = path.getKeyValue(DEVICEID_KEY);
		COMMON_LOG_DEBUG_F("DeviceID: %s", devIdAttr.asStr().c_str());

		int rc = nvm_get_device_count();
		if (rc < NVM_SUCCESS)
		{
			throw exception::NvmExceptionLibError(rc);
		}
		else if (rc == 0)
		{
			throw framework::Exception(
					"Could not find any NVDIMMs connected to Memory Controller");
		}

		// get the device_discovery information for all of the dimms
		struct device_discovery dimms[rc];
		if ((rc = nvm_get_devices(dimms, rc)) < NVM_SUCCESS)
		{
			throw exception::NvmExceptionLibError(rc);
		}
		else if (rc == 0)
		{
			throw framework::Exception(
					"Could not find any NVDIMMs connected to Memory Controller");
		}

		// initialize indicator
		int instance_found = 0;
		// find the set of unique memory controller ids used across all DIMMs
		for (int i = 0; i < rc; i++)
		{
			// compare the current DIMM's mem controller to the one that we are searching for
			instance_found = (devIdAttr.stringValue().compare(
					generateUniqueMemoryControllerID(&(dimms[i]))) == 0);
			if (instance_found)
			{
				// if found, update pInstance
				MemoryControllerFactory::addNonKeyAttributesToInstance(
						pInstance, &attributes, &(dimms[i]));

				// break the loop since we found what we were looking for
				break;
			}
		}

		// handle failures
		if (!instance_found)
		{
			COMMON_LOG_ERROR_F("Device ID Not Found: %s", devIdAttr.stringValue().c_str());
			throw framework::ExceptionBadParameter(DEVICEID_KEY.c_str());
		}
	}
	catch (framework::Exception) // clean up and re-throw
	{
		delete pInstance;
		throw;
	}

	return pInstance;
}
/*
 * entry point for CIMOM to execute an extrinsic method
 */
wbem::framework::UINT32 wbem::software::NVDIMMSoftwareInstallationServiceFactory::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__);
	wbem::framework::UINT32 httpRc = framework::MOF_ERR_SUCCESS;
	wbemRc = framework::MOF_ERR_SUCCESS;
	// valid InstallOptions for InstallFromURI
	const NVM_UINT16 DEFER = 2; 
	const NVM_UINT16 FORCE = 3;
	const NVM_UINT16 REBOOT = 7;
	const NVM_UINT16 EXAMINE = 32768;

	if (method == NVDIMMSOFTWAREINSTALLATIONSERVICE_INSTALLFROMURI)
	{
		/*
		 * uint32 InstallFromURI(CIM_ConcreateJob REF Job, string URI,
		 * 		CIM_ManagedElement REF Target, uint16 InstallOptions[],
		 * 		string InstallOptionsValues[])
		 *
		 * Returns one of:
		 * 		0 		- Job Completed with No Error
		 * 		2 		- Unspecified Error
		 * 		4 		- Failed
		 * 		5 		- Invalid Parameter
		 * 		4097 	- Unsupported Target Type
		 * 		4099 	- Downgrade/reinstall not supported
		 * 		4100	- Not enough memory
		 * 		4107 	- URI not accessible
		 *
		 */

		std::string uri = inParms[NVDIMMSOFTWAREINSTALLATIONSERVICE_INSTALLFROMURI_PARAM_URI].stringValue();
		std::string target = inParms[NVDIMMSOFTWAREINSTALLATIONSERVICE_INSTALLFROMURI_PARAM_TARGET].stringValue();
		framework::UINT16_LIST installOptions = inParms[NVDIMMSOFTWAREINSTALLATIONSERVICE_INSTALLFROMURI_INSTALLOPTIONS].uint16ListValue();
		// get valid install options
		bool rebootOption =
				std::find(installOptions.begin(), installOptions.end(), REBOOT) != installOptions.end();
		bool deferOption =
				std::find(installOptions.begin(), installOptions.end(), DEFER) != installOptions.end();
		bool forceOption =
				std::find(installOptions.begin(), installOptions.end(), FORCE) != installOptions.end();
		bool examineOption =
				std::find(installOptions.begin(), installOptions.end(), EXAMINE) != installOptions.end();

		// count invalid install options
		int invalidOptions = 0;
		for (size_t i = 0; i < installOptions.size(); i++)
		{
			if (!(installOptions[i] == DEFER ||
					installOptions[i] == REBOOT ||
					installOptions[i] == FORCE ||
					installOptions[i] == EXAMINE))
			{
				invalidOptions++;
			}
		}
		try
		{
			COMMON_PATH absPath;
			if (uri.empty())
			{
				httpRc = framework::CIM_ERR_INVALID_PARAMETER;
				COMMON_LOG_ERROR("URI parameter was missing");
			}
			else if (target.empty())
			{
				httpRc = framework::CIM_ERR_INVALID_PARAMETER;
				COMMON_LOG_ERROR("Target parameter was missing");
			}
			else if (get_absolute_path(uri.c_str(), uri.length() + 1, absPath) != COMMON_SUCCESS)
			{
				httpRc = framework::CIM_ERR_INVALID_PARAMETER;
				COMMON_LOG_ERROR("URI parameter is not valid");
			}
			else if (invalidOptions > 0)
			{
				httpRc = framework::CIM_ERR_INVALID_PARAMETER;
				COMMON_LOG_ERROR_F("Only %d, %d, %d and/or %d are valid InstallOptions",
						DEFER, REBOOT, FORCE, EXAMINE);
			}
			else if (rebootOption && deferOption)
			{
				httpRc = framework::CIM_ERR_INVALID_PARAMETER;
				COMMON_LOG_ERROR_F("%d and %d cannot be used together as InstallOptions",
						DEFER, REBOOT);
			}
			else
			{
				framework::ObjectPathBuilder targetBuilder(target);
				framework::ObjectPath targetObject;
				targetBuilder.Build(&targetObject);

				if (targetObject.getClass() == NVDIMMCOLLECTION_CREATIONCLASSNAME)
				{
					// all devices on system
					if (examineOption)
					{
						std::string version;

						framework::return_codes rc = examineFwImage(absPath, version);
						if (rc == framework::REQUIRES_FORCE)
						{
							wbemRc = SWINSTALLSERVICE_ERR_DOWNGRADE_NOT_SUPPORTED;
						}
						else if (rc != framework::SUCCESS)
						{
							wbemRc = SWINSTALLSERVICE_ERR_NOT_APPLICABLE_TO_TARGET;
						}
					}
					else
					{
						installFromPath(absPath, rebootOption, forceOption);
					}
				}
				else if (targetObject.getClass() == physical_asset::NVDIMM_CREATIONCLASSNAME)
				{
					// single device
					if (examineOption)
					{
						std::string version;
						framework::return_codes rc = examineFwImage(
								targetObject.getKeyValue(TAG_KEY).stringValue(),
								absPath, version);
						if (rc == framework::REQUIRES_FORCE)
						{
							wbemRc = SWINSTALLSERVICE_ERR_DOWNGRADE_NOT_SUPPORTED;
						}
						else if (rc != framework::SUCCESS)
						{
							wbemRc = SWINSTALLSERVICE_ERR_NOT_APPLICABLE_TO_TARGET;
						}
					}
					else
					{
						installFromPath(targetObject.getKeyValue(TAG_KEY).stringValue(),
								absPath, rebootOption, forceOption);
					}
				}
				else
				{
					httpRc = framework::CIM_ERR_INVALID_PARAMETER;
				}
			}
		}
		catch (wbem::framework::ExceptionBadParameter &)
		{
			wbemRc = SWINSTALLSERVICE_ERR_INVALID_PARAMETER;
		}
		catch (wbem::exception::NvmExceptionLibError &e)
		{
			wbemRc = getReturnCodeFromLibException(e);
		}
		catch (wbem::framework::ExceptionNoMemory &)
		{
			wbemRc = SWINSTALLSERVICE_ERR_NOT_ENOUGH_MEMORY;
		}
		catch (wbem::framework::ExceptionNotSupported &)
		{
			wbemRc = SWINSTALLSERVICE_ERR_FAILED;
		}
		catch (wbem::framework::Exception &)
		{
			wbemRc = SWINSTALLSERVICE_ERR_FAILED;
		}
	}
	else
	{
		httpRc = framework::CIM_ERR_METHOD_NOT_AVAILABLE;
	}
	return httpRc;
}
Пример #19
0
/*
 * 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];
							}
						}
					}
				}
			}
		}
	}
}
Пример #20
0
void monitor::EventMonitor::saveCurrentTopologyState(const DeviceMap &devices)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

	bool saved = true;

	PersistentStore *pStore = get_lib_store();
	if (pStore)
	{
		// Only keep the latest topology
		if (db_delete_all_topology_states(pStore) != DB_SUCCESS)
		{
			COMMON_LOG_ERROR("couldn't delete old topology_state");
			saved = false;
		}
		else
		{
			// Preserve topology state in config DB
			for (DeviceMap::const_iterator iter = devices.begin();
					iter != devices.end(); iter++)
			{
				const std::string &uidStr = iter->first;
				const struct deviceInfo &device = iter->second;

				// only store current devices
				if (device.discovered)
				{
					struct db_topology_state topoState;
					memset(&topoState, 0, sizeof(topoState));
					s_strcpy(topoState.uid, uidStr.c_str(), NVM_MAX_UID_LEN);
					topoState.device_handle = device.discovery.device_handle.handle;
					topoState.manufacturer = MANUFACTURER_TO_UINT(device.discovery.manufacturer);
					topoState.serial_num = SERIAL_NUMBER_TO_UINT(device.discovery.serial_number);
					memmove(topoState.model_num, device.discovery.model_number, NVM_MODEL_LEN);

					topoState.current_config_status = device.status.config_status;
					topoState.config_goal_status = CONFIG_GOAL_STATUS_UNKNOWN;

					struct config_goal goal;
					memset(&goal, 0, sizeof (goal));
					int rc = nvm_get_config_goal(device.discovery.uid, &goal);
					if (rc == NVM_SUCCESS)
					{
						topoState.config_goal_status = goal.status;
					}
					else if (rc == NVM_ERR_NOTFOUND)
					{
						COMMON_LOG_DEBUG_F("No goal for DIMM %s", uidStr.c_str());
					}
					else
					{
						COMMON_LOG_ERROR_F("Error fetching config goalfor DIMM %s: %d",
						                   uidStr.c_str(),
						                   rc);
					}

					if (db_add_topology_state(pStore, &topoState) != DB_SUCCESS)
					{
						COMMON_LOG_ERROR_F("couldn't add topology_state for DIMM %s",
								topoState.uid);
						saved = false;
						break;
					}
				}
			}
		}

		// everything succeeded
		if (saved)
		{
			add_config_value(SQL_KEY_TOPOLOGY_STATE_VALID, "1");
		}
	}
}
Пример #21
0
int nvm_get_jobs(struct job *p_jobs, const NVM_UINT32 count)
{
	COMMON_LOG_ENTRY();
	int rc = NVM_SUCCESS;
	int job_index = 0;

	if (check_caller_permissions() != NVM_SUCCESS)
	{
		rc = NVM_ERR_INVALIDPERMISSIONS;
	}
	else if (!is_supported_driver_available())
	{
		rc = NVM_ERR_BADDRIVER;
	}
	else if (p_jobs == NULL)
	{
		COMMON_LOG_ERROR("Invalid parameter, p_jobs is NULL");
		rc = NVM_ERR_INVALIDPARAMETER;
	}
	else if ((rc = get_job_count()) < 0)
	{
		COMMON_LOG_ERROR("Failed to retrieve job count.");
	}
	else if (rc > 0)
	{
		// clear the structure
		memset(p_jobs, 0, sizeof (struct job) * count);

		if ((rc = nvm_get_device_count()) >= 0)
		{
			int device_count = rc;
			struct device_discovery devices[rc];
			if ((rc = nvm_get_devices(devices, device_count)) > 0)
			{
				// iterate through all devices and add up the capacities
				for (int i = 0; i < device_count; i++)
				{
					if (job_index >= count)
					{
						rc = NVM_ERR_ARRAYTOOSMALL;
						COMMON_LOG_ERROR("Invalid parameter, "
								"count is smaller than number of jobs");
						break;
					}

					if (devices[i].manageability == MANAGEMENT_VALIDCONFIG)
					{
						struct pt_payload_sanitize_dimm_status sanitize_status;
						struct fw_cmd cmd;
						memset(&cmd, 0, sizeof (struct fw_cmd));
						cmd.device_handle = devices[i].device_handle.handle;
						cmd.opcode = PT_GET_SEC_INFO;
						cmd.sub_opcode = SUBOP_GET_SAN_STATE;
						cmd.output_payload_size = sizeof (sanitize_status);
						cmd.output_payload = &sanitize_status;
						if (NVM_SUCCESS != ioctl_passthrough_cmd(&cmd))
						{
							COMMON_LOG_ERROR_F(
									"Unable to get sanitize status for handle: [%d]",
									devices[i].device_handle.handle);
						}
						else
						{
							if (sanitize_status.state != SAN_IDLE)
							{
								if (sanitize_status.state == SAN_INPROGRESS)
								{
									p_jobs[job_index].status = NVM_JOB_STATUS_RUNNING;
								}
								else if (sanitize_status.state ==  SAN_COMPLETED)
								{
									p_jobs[job_index].status = NVM_JOB_STATUS_COMPLETE;
								}
								else
								{
									p_jobs[job_index].status = NVM_JOB_STATUS_UNKNOWN;
								}

								p_jobs[job_index].type = NVM_JOB_TYPE_SANITIZE;
								p_jobs[job_index].percent_complete = sanitize_status.progress;
								memmove(p_jobs[job_index].uid, devices[i].uid, NVM_MAX_UID_LEN);
								memmove(p_jobs[job_index].affected_element,
									devices[i].uid, NVM_MAX_UID_LEN);
								p_jobs[job_index].result = NULL;
								job_index++;
							}
						}
					}
					rc = job_index;
				}
			}
			else
			{
				COMMON_LOG_ERROR_F("Unable to get device discovery: rc = %d", rc);
			}
		}
		else
		{
			COMMON_LOG_ERROR_F("Unable to get device count: rc = %d", rc);
		}
	}
	return rc;
}
Пример #22
0
/*
 * Check for device sensor changes
 */
void monitor::EventMonitor::monitorDimmSensors(const std::string &uidStr,
		const struct device_discovery &discovery,
		struct db_dimm_state &storedState,
		bool &storedStateChanged,
		bool firstState)
{
	LogEnterExit logging(__FUNCTION__, __FILE__, __LINE__);

	struct sensor sensors[NVM_MAX_DEVICE_SENSORS];
	memset(sensors, 0, sizeof(sensors));
	int rc = nvm_get_sensors(discovery.uid, sensors, NVM_MAX_DEVICE_SENSORS);
		if (rc != NVM_SUCCESS)
	{
		COMMON_LOG_ERROR_F("nvm_get_sensors for dimm %s failed with error %d\n",
				uidStr.c_str(), rc);
	}
	else
	{
		// first pass, just store current values
		if (firstState)
		{
			storedState.mediaerrors_corrected =
					sensors[SENSOR_MEDIAERRORS_CORRECTED].reading;
			storedState.mediaerrors_erasurecoded =
					sensors[SENSOR_MEDIAERRORS_ERASURECODED].reading;
			storedState.mediaerrors_uncorrectable =
					sensors[SENSOR_MEDIAERRORS_UNCORRECTABLE].reading;
			storedState.wearlevel_state =
					sensors[SENSOR_WEARLEVEL].current_state;
			storedState.mediatemperature_state =
					sensors[SENSOR_MEDIA_TEMPERATURE].current_state;
			storedState.controllertemperature_state =
					sensors[SENSOR_CONTROLLER_TEMPERATURE].current_state;
			storedState.spare_capacity_state =
					sensors[SENSOR_SPARECAPACITY].current_state;

		}
		// check for changes
		else
		{
			// monitor media temperature
			monitorDimmMediaTemperature(uidStr, discovery, storedState,
					storedStateChanged, sensors[SENSOR_MEDIA_TEMPERATURE]);

			// monitor controller temperature
			monitorDimmControllerTemperature(uidStr, discovery, storedState,
					storedStateChanged, sensors[SENSOR_CONTROLLER_TEMPERATURE]);

			// monitor spare capacity
			monitorDimmSpare(uidStr, discovery, storedState,
					storedStateChanged, sensors[SENSOR_SPARECAPACITY]);

			// monitor wear level
			monitorDimmWearLevel(uidStr, discovery, storedState,
					storedStateChanged, sensors[SENSOR_WEARLEVEL]);

			// monitor errors - uncorrectable
			monitorDimmErrors(uidStr, discovery, storedState.mediaerrors_uncorrectable,
					sensors[SENSOR_MEDIAERRORS_UNCORRECTABLE].reading,
					UNCORRECTABLE, storedStateChanged);

			// monitor errors - corrected
			monitorDimmErrors(uidStr, discovery, storedState.mediaerrors_corrected,
					sensors[SENSOR_MEDIAERRORS_CORRECTED].reading,
					CORRECTED, storedStateChanged);

			// monitor errors - erasure coded
			monitorDimmErrors(uidStr, discovery, storedState.mediaerrors_erasurecoded,
					sensors[SENSOR_MEDIAERRORS_ERASURECODED].reading,
					ERASURE_CODED, storedStateChanged);
		}
	}
}
Пример #23
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
}
Пример #24
0
/*
 * Execute a passthrough IOCTL
 */
int ioctl_passthrough_cmd(struct fw_cmd *p_cmd)
{
	COMMON_LOG_ENTRY();
	int rc = NVM_ERR_UNKNOWN;

	if (p_cmd == NULL)
	{
		COMMON_LOG_ERROR("Invalid parameter, cmd is NULL");
		rc = NVM_ERR_INVALIDPARAMETER;
	}
	else if ((p_cmd->input_payload_size > 0 && p_cmd->input_payload == NULL) ||
			(p_cmd->input_payload != NULL && p_cmd->input_payload_size == 0) ||
			(p_cmd->output_payload_size > 0 && p_cmd->output_payload == NULL) ||
			(p_cmd->output_payload != NULL && p_cmd->output_payload_size == 0) ||
			(p_cmd->large_input_payload_size > 0 && p_cmd->large_input_payload == NULL) ||
			(p_cmd->large_input_payload != NULL && p_cmd->large_input_payload_size == 0) ||
			(p_cmd->large_output_payload_size > 0 && p_cmd->large_output_payload == NULL) ||
			(p_cmd->large_output_payload != NULL && p_cmd->large_output_payload_size == 0))
	{
		COMMON_LOG_ERROR("bad input/output payload(s)");
		rc = NVM_ERR_INVALIDPARAMETER;
	}
	// avoid any commands that require early HW or large payloads
#if __EARLY_HW__ || (__LARGE_PAYLOAD__ == 0)
	else if ((p_cmd->opcode == 0x08 && p_cmd->sub_opcode == 0x02) || // get fw debug log
			(p_cmd->opcode == 0x08 && p_cmd->sub_opcode == 0x05) || // get error log
			(p_cmd->opcode == 0x0A)) // inject error
	{
		COMMON_LOG_ERROR_F("Intel DIMM Gen 1 FW command OpCode: 0x%x SubOpCode: "
				"0x%x is not supported",
				p_cmd->opcode, p_cmd->sub_opcode);
		rc = NVM_ERR_NOTSUPPORTED;
	}
#endif
	else
	{
		size_t input_buf_size = sizeof (DSM_VENDOR_SPECIFIC_COMMAND_INPUT_PAYLOAD)
				- ARG3_OPCODE_PARAMETER_DATA_BUFFER_PLACEHOLDER	+ p_cmd->input_payload_size;

		size_t output_buf_size = sizeof (DSM_VENDOR_SPECIFIC_COMMAND_OUTPUT_PAYLOAD)
			- DSM_VENDOR_SPECIFIC_COMMAND_OUTPUT_PAYLOAD_PLACEHOLDERS
			+ DEV_SMALL_PAYLOAD_SIZE;

		size_t arg3_size = input_buf_size + output_buf_size;
		size_t buf_size = sizeof (ULONG) + sizeof (NFIT_DEVICE_HANDLE) + arg3_size;

		PPASS_THROUGH_IOCTL p_ioctl_data = calloc(1, buf_size);
		if (p_ioctl_data)
		{
			p_ioctl_data->NfitDeviceHandle.DeviceHandle =
					p_cmd->device_handle;

			p_ioctl_data->InputPayload.Arg3OpCodeParameterDataLength = p_cmd->input_payload_size;
			p_ioctl_data->InputPayload.Arg3OpCode = BUILD_DSM_OPCODE(p_cmd->opcode,
					p_cmd->sub_opcode);

			if (p_cmd->input_payload_size > 0)
			{
				memmove(p_ioctl_data->InputPayload.Arg3OpCodeParameterDataBuffer,
						p_cmd->input_payload,
						p_cmd->input_payload_size);
			}

			if (p_cmd->large_input_payload_size > 0)
			{
				rc = bios_write_large_payload(p_cmd);
			}

			PDSM_VENDOR_SPECIFIC_COMMAND_OUTPUT_PAYLOAD p_output_payload = NULL;

			p_output_payload =
				(PDSM_VENDOR_SPECIFIC_COMMAND_OUTPUT_PAYLOAD)
				(p_ioctl_data->InputPayload.Arg3OpCodeParameterDataBuffer
					+ p_cmd->input_payload_size);

			if ((rc = execute_ioctl(buf_size, p_ioctl_data, IOCTL_CR_PASS_THROUGH))
				== NVM_SUCCESS &&
				(rc = ind_err_to_nvm_lib_err(p_ioctl_data->ReturnCode)) == NVM_SUCCESS)
			{
				if ((rc = dsm_err_to_nvm_lib_err(
					win_dsm_status_to_int(p_output_payload->Arg3Status))) == NVM_SUCCESS)
				{
					if (p_cmd->output_payload_size > 0)
					{
						size_t bytes_to_copy = p_cmd->output_payload_size;
						if (p_output_payload->Arg3OutputBufferLength <
								p_cmd->output_payload_size)
						{
							// User expected more data than the command returned
							// We can safely copy it, but there could be a developer error
							bytes_to_copy = p_output_payload->Arg3OutputBufferLength;
							COMMON_LOG_WARN_F(
									"output buffer size %llu larger than size returned %u",
									p_cmd->output_payload_size,
									p_output_payload->Arg3OutputBufferLength);
						}
						memmove(p_cmd->output_payload, p_output_payload->Arg3OutputBuffer,
								bytes_to_copy);
					}

					if (p_cmd->large_output_payload_size > 0)
					{
						rc = bios_read_large_payload(p_cmd);
					}
				}
			}

			free(p_ioctl_data);
		}
		else
		{
			COMMON_LOG_ERROR("couldn't allocate input payload");
			rc = NVM_ERR_NOMEMORY;
		}
	}

	s_memset(&p_cmd, sizeof (p_cmd));
	COMMON_LOG_EXIT_RETURN_I(rc);
	return rc;
}
Пример #25
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;
}