Skip to content

Commit

Permalink
RedfishClientPkg/Bios: handle system default condition
Browse files Browse the repository at this point in the history
When BIOS loads default settings and remove all variables, Redfish feature
driver should ignore stale settings on BMC and force update default
settings to BMC.

Code optimization:
- Only consume attributes when number of attributes is not zero.
- Only convert Bios structure to JSON data when attribute value is
changed.
- Initial variable before using it.
- Return EFI_SUCCESS when there is nothing to update and prevent
false alarm.
- In check() function, return EFI_UNSUPPORTED when there is no config
language found for this Redfish resource. And return EFI_NOT_FOUND
when there is config language found but they are missing at BMC. This
is to match the check() function description and feature driver can
understand how to handle these two case separately.

Signed-off-by: Nickle Wang <nicklew@nvidia.com>
  • Loading branch information
nicklela committed Aug 19, 2024
1 parent 55f875f commit 1ee0cf3
Showing 1 changed file with 67 additions and 30 deletions.
97 changes: 67 additions & 30 deletions RedfishClientPkg/Features/Bios/v1_0_9/Common/BiosCommon.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,19 +119,21 @@ RedfishConsumeResourceCommon (
goto ON_RELEASE;
}

//
// Find corresponding configure language for collection resource.
//
ConfigureLang = GetConfigureLang (BiosCs->odata_id, "Attributes");
if (ConfigureLang != NULL) {
Status = ApplyFeatureSettingsVagueType (RESOURCE_SCHEMA, RESOURCE_SCHEMA_VERSION, ConfigureLang, EmptyPropCs->KeyValuePtr, EmptyPropCs->NunmOfProperties);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, apply setting for %s failed: %r\n", __func__, ConfigureLang, Status));
}
if (EmptyPropCs->NunmOfProperties > 0) {
//
// Find corresponding configure language for collection resource.
//
ConfigureLang = GetConfigureLang (BiosCs->odata_id, "Attributes");
if (ConfigureLang != NULL) {
Status = ApplyFeatureSettingsVagueType (RESOURCE_SCHEMA, RESOURCE_SCHEMA_VERSION, ConfigureLang, EmptyPropCs->KeyValuePtr, EmptyPropCs->NunmOfProperties);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, apply setting for %s failed: %r\n", __func__, ConfigureLang, Status));
}

FreePool (ConfigureLang);
} else {
DEBUG ((DEBUG_ERROR, "%a, can not get configure language for URI: %s\n", __func__, Private->Uri));
FreePool (ConfigureLang);
} else {
DEBUG ((DEBUG_ERROR, "%a, can not get configure language for URI: %s\n", __func__, Private->Uri));
}
}
}

Expand Down Expand Up @@ -237,16 +239,18 @@ ProvisioningBiosProperties (
}
}

//
// Convert C structure back to JSON text.
//
Status = JsonStructProtocol->ToJson (
JsonStructProtocol,
(EFI_REST_JSON_STRUCTURE_HEADER *)Bios,
ResultJson
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, ToJson() failed: %r\n", __func__, Status));
if (PropertyChanged) {
//
// Convert C structure back to JSON text.
//
Status = JsonStructProtocol->ToJson (
JsonStructProtocol,
(EFI_REST_JSON_STRUCTURE_HEADER *)Bios,
ResultJson
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, ToJson() failed: %r\n", __func__, Status));
}
}

//
Expand Down Expand Up @@ -285,6 +289,8 @@ ProvisioningBiosResource (
ZeroMem (&Response, sizeof (REDFISH_RESPONSE));
AsciiSPrint (ResourceId, sizeof (ResourceId), "%d", Index);

NewResourceLocation = NULL;

Status = ProvisioningBiosProperties (
Private->JsonStructProtocol,
BiosEmptyJson,
Expand Down Expand Up @@ -437,6 +443,7 @@ ProvisioningBiosExistResource (
if (EFI_ERROR (Status)) {
if (Status == EFI_NOT_FOUND) {
DEBUG ((REDFISH_DEBUG_TRACE, "%a, provisioning existing resource for %s ignored. Nothing changed\n", __func__, ConfigureLang));
Status = EFI_SUCCESS;
} else {
DEBUG ((DEBUG_ERROR, "%a, provisioning existing resource for %s failed: %r\n", __func__, ConfigureLang, Status));
}
Expand Down Expand Up @@ -570,10 +577,10 @@ RedfishCheckResourceCommon (
}

if (Count == 0) {
return EFI_NOT_FOUND;
return EFI_UNSUPPORTED;
}

Status = EFI_SUCCESS;
Status = EFI_NOT_FOUND;
for (Index = 0; Index < Count; Index++) {
Property = GetPropertyFromConfigureLang (Private->Uri, ConfigureLangList[Index]);
if (Property == NULL) {
Expand All @@ -583,7 +590,15 @@ RedfishCheckResourceCommon (
DEBUG ((DEBUG_MANAGEABILITY, "%a, [%d] check attribute for: %s\n", __func__, Index, Property));
if (!MatchPropertyWithJsonContext (Property, Json)) {
DEBUG ((DEBUG_MANAGEABILITY, "%a, property is missing: %s\n", __func__, Property));
Status = EFI_NOT_FOUND;
} else {
//
// When there is any attribute found in /Bios/Attributes, it means that
// the provisioning was performed before. Any missing attribute will
// be handled by update operation.
// When all attributes are missing in /Bios/Attributes, provisioning is
// performed.
//
Status = EFI_SUCCESS;
}
}

Expand Down Expand Up @@ -638,6 +653,7 @@ RedfishUpdateResourceCommon (
if (EFI_ERROR (Status)) {
if (Status == EFI_NOT_FOUND) {
DEBUG ((REDFISH_DEBUG_TRACE, "%a, update resource for %s ignored. Nothing changed\n", __func__, ConfigureLang));
Status = EFI_SUCCESS;
} else {
DEBUG ((DEBUG_ERROR, "%a, update resource for %s failed: %r\n", __func__, ConfigureLang, Status));
}
Expand Down Expand Up @@ -774,6 +790,7 @@ HandleResource (
EFI_STATUS Status;
REDFISH_SCHEMA_INFO SchemaInfo;
EFI_STRING ConfigLang;
BOOLEAN SystemRestDetected;

if ((Private == NULL) || IS_EMPTY_STRING (Uri)) {
return EFI_INVALID_PARAMETER;
Expand All @@ -796,18 +813,29 @@ HandleResource (
// Some resource is handled by other provider so we have to make sure this first.
//
DEBUG ((REDFISH_DEBUG_TRACE, "%a Identify for %s\n", __func__, Uri));
ConfigLang = RedfishGetConfigLanguage (Uri);
SystemRestDetected = FALSE;
ConfigLang = RedfishGetConfigLanguage (Uri);
if (ConfigLang == NULL) {
Status = EdkIIRedfishResourceConfigIdentify (&SchemaInfo, Uri, NULL, Private->InformationExchange);
if (EFI_ERROR (Status)) {
if (Status == EFI_UNSUPPORTED) {
DEBUG ((DEBUG_MANAGEABILITY, "%a, \"%s\" is not handled by us\n", __func__, Uri));
return EFI_SUCCESS;
} else if (Status == EFI_NOT_FOUND) {
DEBUG ((DEBUG_MANAGEABILITY, "%a, \"%s\" has nothing to handle\n", __func__, Uri));
return EFI_SUCCESS;
}

DEBUG ((DEBUG_ERROR, "%a, fail to identify resource: \"%s\": %r\n", __func__, Uri, Status));
return Status;
}

//
// When there is no history record in UEFI variable, this is first boot or
// system is reset by defaulting command. The pending setting on BMC may be
// a stale value so we will ignore pending settings in BMC.
//
SystemRestDetected = TRUE;
} else {
DEBUG ((REDFISH_DEBUG_TRACE, "%a, history record found: %s\n", __func__, ConfigLang));
FreePool (ConfigLang);
Expand All @@ -820,6 +848,11 @@ HandleResource (
DEBUG ((REDFISH_DEBUG_TRACE, "%a Check for %s\n", __func__, Uri));
Status = EdkIIRedfishResourceConfigCheck (&SchemaInfo, Uri, NULL);
if (EFI_ERROR (Status)) {
if (Status == EFI_UNSUPPORTED) {
DEBUG ((REDFISH_DEBUG_TRACE, "%a, \"%s\" has no attribute that is handled by us\n", __func__, Uri));
return EFI_SUCCESS;
}

//
// The target property does not exist, do the provision to create property.
//
Expand All @@ -835,10 +868,14 @@ HandleResource (
//
// Consume first.
//
DEBUG ((REDFISH_DEBUG_TRACE, "%a consume for %s\n", __func__, Uri));
Status = EdkIIRedfishResourceConfigConsume (&SchemaInfo, Uri, NULL);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, failed to consume resource for: %s: %r\n", __func__, Uri, Status));
if (SystemRestDetected) {
DEBUG ((REDFISH_DEBUG_TRACE, "%a system has been reset to default setting. ignore pending settings because they may be stale values\n", __func__));
} else {
DEBUG ((REDFISH_DEBUG_TRACE, "%a consume for %s\n", __func__, Uri));
Status = EdkIIRedfishResourceConfigConsume (&SchemaInfo, Uri, NULL);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a, failed to consume resource for: %s: %r\n", __func__, Uri, Status));
}
}

//
Expand Down

0 comments on commit 1ee0cf3

Please sign in to comment.