/* * 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; }
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); }
/* * 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; }
/* * 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; }
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; } } } }
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; }
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; }
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); }
/* * 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; }
/* * 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; }
/* * 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; } } } }
/* * 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; }
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); } }
/* * 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); } } } } } }
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(); } }
/* * 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; }
/* * 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]; } } } } } } } }
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"); } } }
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; }
/* * 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); } } }
/* * 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 }
/* * 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; }
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; }