From a5c4297f0e46c7d1551d0abd2d2ae1500f806487 Mon Sep 17 00:00:00 2001 From: Abner Chang Date: Thu, 4 Jan 2024 14:42:36 +0800 Subject: [PATCH] RedfishClientPkg: Add ETag PCD and revise Redfish ETag functions Add PCD to disable ETag capability for the case Redfish service doesn't support ETag. Signed-off-by: Abner Chang Cc: Nickle Wang Cc: Igor Kulchytskyy Cc: Mike Maslenkin Reviewed-by: Igor Kulchytskyy --- .../Features/Bios/v1_0_9/Dxe/BiosDxe.c | 19 +- .../v1_0_4/Common/BootOptionCommon.c | 5 +- .../BootOption/v1_0_4/Dxe/BootOptionDxe.c | 17 +- .../v1_5_0/Dxe/ComputerSystemDxe.c | 17 +- .../Features/Memory/V1_7_1/Dxe/MemoryDxe.c | 17 +- .../Library/RedfishFeatureUtilityLib.h | 47 +++- .../RedfishFeatureUtilityLib.c | 209 ++++++++++++------ .../RedfishFeatureUtilityLib.inf | 2 + RedfishClientPkg/RedfishClientPkg.dec | 3 + 9 files changed, 206 insertions(+), 130 deletions(-) diff --git a/RedfishClientPkg/Features/Bios/v1_0_9/Dxe/BiosDxe.c b/RedfishClientPkg/Features/Bios/v1_0_9/Dxe/BiosDxe.c index 2a49c5cd2..f40f2d85a 100644 --- a/RedfishClientPkg/Features/Bios/v1_0_9/Dxe/BiosDxe.c +++ b/RedfishClientPkg/Features/Bios/v1_0_9/Dxe/BiosDxe.c @@ -3,6 +3,7 @@ (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved. + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -153,14 +154,10 @@ RedfishResourceConsumeResource ( ASSERT (Private->Json != NULL); // - // Find etag in HTTP response header + // Searching for etag in HTTP response header // - Etag = NULL; - Status = GetEtagAndLocation (ExpectedResponse, &Etag, NULL); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, failed to get ETag from HTTP header\n", __func__)); - } - + Etag = NULL; + GetHttpResponseEtag (ExpectedResponse, &Etag); Status = RedfishConsumeResourceCommon (Private, Private->Json, Etag); if (EFI_ERROR (Status)) { if (Status != EFI_ALREADY_STARTED) { @@ -365,12 +362,8 @@ RedfishResourceCheck ( // // Find etag in HTTP response header // - Etag = NULL; - Status = GetEtagAndLocation (&Response, &Etag, NULL); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: failed to get ETag from HTTP header\n", __func__)); - } - + Etag = NULL; + GetHttpResponseEtag (&Response, &Etag); Status = RedfishCheckResourceCommon (Private, Private->Json, Etag); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "%a, failed to check resource from: %s: %r\n", __func__, Uri, Status)); diff --git a/RedfishClientPkg/Features/BootOption/v1_0_4/Common/BootOptionCommon.c b/RedfishClientPkg/Features/BootOption/v1_0_4/Common/BootOptionCommon.c index 0d4c2162c..0b9f2bf28 100644 --- a/RedfishClientPkg/Features/BootOption/v1_0_4/Common/BootOptionCommon.c +++ b/RedfishClientPkg/Features/BootOption/v1_0_4/Common/BootOptionCommon.c @@ -3,6 +3,7 @@ (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -455,9 +456,9 @@ RedfishProvisioningResourceCommon ( } // - // per Redfish spec. the URL of new resource will be returned in "Location" header. + // Per Redfish spec. the URL of new resource will be returned in "Location" header. // - Status = GetEtagAndLocation (&Response, NULL, &NewResourceLocation); + Status = GetHttpResponseLocation (&Response, &NewResourceLocation); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "%a: cannot find new location: %r\n", __func__, Status)); goto RELEASE_RESOURCE; diff --git a/RedfishClientPkg/Features/BootOption/v1_0_4/Dxe/BootOptionDxe.c b/RedfishClientPkg/Features/BootOption/v1_0_4/Dxe/BootOptionDxe.c index ba090c51d..dc2bd9da8 100644 --- a/RedfishClientPkg/Features/BootOption/v1_0_4/Dxe/BootOptionDxe.c +++ b/RedfishClientPkg/Features/BootOption/v1_0_4/Dxe/BootOptionDxe.c @@ -3,6 +3,7 @@ (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -154,12 +155,8 @@ RedfishResourceConsumeResource ( // // Find etag in HTTP response header // - Etag = NULL; - Status = GetEtagAndLocation (ExpectedResponse, &Etag, NULL); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: failed to get ETag from HTTP header\n", __func__)); - } - + Etag = NULL; + GetHttpResponseEtag (ExpectedResponse, &Etag); Status = RedfishConsumeResourceCommon (Private, Private->Json, Etag); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "%a: failed to consume resource from: %s: %r\n", __func__, Private->Uri, Status)); @@ -358,12 +355,8 @@ RedfishResourceCheck ( // // Find etag in HTTP response header // - Etag = NULL; - Status = GetEtagAndLocation (&Response, &Etag, NULL); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: failed to get ETag from HTTP header\n", __func__)); - } - + Etag = NULL; + GetHttpResponseEtag (&Response, &Etag); Status = RedfishCheckResourceCommon (Private, Private->Json, Etag); if (EFI_ERROR (Status)) { DEBUG ((REDFISH_BOOT_OPTION_DEBUG_TRACE, "%a: failed to check resource from: %s: %r\n", __func__, Uri, Status)); diff --git a/RedfishClientPkg/Features/ComputerSystem/v1_5_0/Dxe/ComputerSystemDxe.c b/RedfishClientPkg/Features/ComputerSystem/v1_5_0/Dxe/ComputerSystemDxe.c index 0bbaa92bf..04ff5c827 100644 --- a/RedfishClientPkg/Features/ComputerSystem/v1_5_0/Dxe/ComputerSystemDxe.c +++ b/RedfishClientPkg/Features/ComputerSystem/v1_5_0/Dxe/ComputerSystemDxe.c @@ -3,6 +3,7 @@ (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
Copyright (c) 2023-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -149,12 +150,8 @@ RedfishResourceConsumeResource ( // // Find etag in HTTP response header // - Etag = NULL; - Status = GetEtagAndLocation (ExpectedResponse, &Etag, NULL); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, failed to get ETag from HTTP header\n", __func__)); - } - + Etag = NULL; + GetHttpResponseEtag (ExpectedResponse, &Etag); Status = RedfishConsumeResourceCommon (Private, Private->Json, Etag); if (EFI_ERROR (Status)) { if (Status != EFI_ALREADY_STARTED) { @@ -359,12 +356,8 @@ RedfishResourceCheck ( // // Find etag in HTTP response header // - Etag = NULL; - Status = GetEtagAndLocation (&Response, &Etag, NULL); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: failed to get ETag from HTTP header\n", __func__)); - } - + Etag = NULL; + GetHttpResponseEtag (&Response, &Etag); Status = RedfishCheckResourceCommon (Private, Private->Json, Etag); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "%a, failed to check resource from: %s: %r\n", __func__, Uri, Status)); diff --git a/RedfishClientPkg/Features/Memory/V1_7_1/Dxe/MemoryDxe.c b/RedfishClientPkg/Features/Memory/V1_7_1/Dxe/MemoryDxe.c index 923007805..4a6e34287 100644 --- a/RedfishClientPkg/Features/Memory/V1_7_1/Dxe/MemoryDxe.c +++ b/RedfishClientPkg/Features/Memory/V1_7_1/Dxe/MemoryDxe.c @@ -3,6 +3,7 @@ (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
Copyright (c) 2023-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -149,12 +150,8 @@ RedfishResourceConsumeResource ( // // Find etag in HTTP response header // - Etag = NULL; - Status = GetEtagAndLocation (ExpectedResponse, &Etag, NULL); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a, failed to get ETag from HTTP header\n", __func__)); - } - + Etag = NULL; + GetHttpResponseEtag (ExpectedResponse, &Etag); Status = RedfishConsumeResourceCommon (Private, Private->Json, Etag); if (EFI_ERROR (Status)) { if (Status != EFI_ALREADY_STARTED) { @@ -359,12 +356,8 @@ RedfishResourceCheck ( // // Find etag in HTTP response header // - Etag = NULL; - Status = GetEtagAndLocation (&Response, &Etag, NULL); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: failed to get ETag from HTTP header\n", __func__)); - } - + Etag = NULL; + GetHttpResponseEtag (&Response, &Etag); Status = RedfishCheckResourceCommon (Private, Private->Json, Etag); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "%a, failed to check resource from: %s: %r\n", __func__, Uri, Status)); diff --git a/RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h b/RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h index 9513a6561..0f8aede5c 100644 --- a/RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h +++ b/RedfishClientPkg/Include/Library/RedfishFeatureUtilityLib.h @@ -3,6 +3,7 @@ (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP
Copyright (c) 2023-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -81,7 +82,7 @@ CopyConfiglanguageList ( /** - Get number of node from the string. Node is seperated by '/'. + Get number of node from the string. Node is separated by '/'. @param[in] NodeString The node string to parse. @@ -559,6 +560,19 @@ GetEtagWithUri ( IN EFI_STRING Uri ); +/** + + This function returns a boolean of ETAG support on Redfish service side. + + @retval TRUE ETAG is supported on Redfish service. + @retval FALSE ETAG is not supported on Redfish service. + +**/ +BOOLEAN +CheckIsServerEtagSupported ( + VOID + ); + /** Get @odata.id from give HTTP payload. It's call responsibility to release returned buffer. @@ -931,22 +945,33 @@ CompareRedfishPropertyVagueValues ( ); /** + Find "ETag" from either HTTP header or Redfish response. - Find "ETag" and "Location" from either HTTP header or Redfish response. + @param[in] Response HTTP response + @param[out] Etag String buffer to return ETag - @param[in] Response HTTP response - @param[out] Etag String buffer to return ETag - @param[out] Location String buffer to return Location + @retval EFI_SUCCESS ETag is returned in Etag + @retval EFI_UNSUPPORTED ETag is unsupported + @retval EFI_INVALID_PARAMETER Response, Etag or both are NULL. - @retval EFI_SUCCESS Data is found and returned. - @retval Others Errors occur. +**/ +EFI_STATUS +GetHttpResponseEtag ( + IN REDFISH_RESPONSE *Response, + OUT CHAR8 **Etag + ); + +/** + Find "Location" from either HTTP header or Redfish response. + + @param[in] Response HTTP response + @param[out] Location String buffer to return Location **/ EFI_STATUS -GetEtagAndLocation ( - IN REDFISH_RESPONSE *Response, - OUT CHAR8 **Etag, OPTIONAL - OUT EFI_STRING *Location OPTIONAL +GetHttpResponseLocation ( + IN REDFISH_RESPONSE *Response, + OUT EFI_STRING *Location ); /** diff --git a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib.c b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib.c index 1c2d40f62..aa723264e 100644 --- a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib.c +++ b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib.c @@ -3,6 +3,7 @@ (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
Copyright (c) 2023-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -133,6 +134,11 @@ SetEtagFromUri ( REDFISH_RESPONSE Response; EFI_STRING PendingSettingUri; + if (!CheckIsServerEtagSupported ()) { + DEBUG ((DEBUG_INFO, "%a: WARNING - ETAG is not supported\n", __func__)); + return EFI_SUCCESS; + } + if ((RedfishService == NULL) || IS_EMPTY_STRING (Uri)) { return EFI_INVALID_PARAMETER; } @@ -157,9 +163,9 @@ SetEtagFromUri ( // // Find etag in HTTP response header // - Status = GetEtagAndLocation (&Response, &Etag, NULL); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: failed to get ETag from HTTP header\n", __func__)); + Status = GetHttpResponseEtag (&Response, &Etag); + if (EFI_ERROR (Status) && (Status != EFI_UNSUPPORTED)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to get ETag from HTTP header\n", __func__)); Status = EFI_NOT_FOUND; goto ON_RELEASE; } @@ -241,6 +247,11 @@ SetEtagWithUri ( EFI_STATUS Status; CHAR8 *AsciiUri; + if (!CheckIsServerEtagSupported ()) { + DEBUG ((DEBUG_INFO, "%a: WARNING - ETAG is not supported\n", __func__)); + return EFI_SUCCESS; + } + if (IS_EMPTY_STRING (EtagStr) || IS_EMPTY_STRING (Uri)) { return EFI_INVALID_PARAMETER; } @@ -286,6 +297,11 @@ GetEtagWithUri ( return NULL; } + if (!CheckIsServerEtagSupported ()) { + DEBUG ((DEBUG_INFO, "%a: WARNING - ETAG is not supported\n", __func__)); + return NULL; + } + Status = RedfishLocateProtocol ((VOID **)&mEtagProtocol, &gEdkIIRedfishETagProtocolGuid); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "%a: fail to locate gEdkIIRedfishETagProtocolGuid: %r\n", __func__, Status)); @@ -1726,44 +1742,39 @@ RedfishFeatureGetUnifiedArrayTypeConfigureLang ( } /** + Find "ETag" from either HTTP header or Redfish response. - Find "ETag" and "Location" from either HTTP header or Redfish response. + @param[in] Response HTTP response + @param[out] Etag String buffer to return ETag - @param[in] Response HTTP response - @param[out] Etag String buffer to return ETag - @param[out] Location String buffer to return Location - - @retval EFI_SUCCESS Data is found and returned. - @retval Others Errors occur. + @retval EFI_SUCCESS ETag is returned in Etag + @retval EFI_UNSUPPORTED ETag is unsupported + @retval EFI_INVALID_PARAMETER Response, Etag or both are NULL. **/ EFI_STATUS -GetEtagAndLocation ( - IN REDFISH_RESPONSE *Response, - OUT CHAR8 **Etag, OPTIONAL - OUT EFI_STRING *Location OPTIONAL +GetHttpResponseEtag ( + IN REDFISH_RESPONSE *Response, + OUT CHAR8 **Etag ) { + EFI_STATUS Status; EDKII_JSON_VALUE JsonValue; EDKII_JSON_VALUE OdataValue; CHAR8 *OdataString; - CHAR8 *AsciiLocation; EFI_HTTP_HEADER *Header; - EFI_STATUS Status; - if (Response == NULL) { + if ((Response == NULL) || (Etag == NULL)) { return EFI_INVALID_PARAMETER; } - if ((Etag == NULL) && (Location == NULL)) { - return EFI_SUCCESS; - } - Status = EFI_SUCCESS; - - if (Etag != NULL) { - *Etag = NULL; - + *Etag = NULL; + if (!CheckIsServerEtagSupported ()) { + // Don't look for ETAG header or property in this case. + DEBUG ((DEBUG_INFO, "%a: WARNING - No ETag support on Redfish service.\n", __func__)); + return EFI_UNSUPPORTED; + } else { if (*(Response->StatusCode) == HTTP_STATUS_200_OK) { Header = HttpFindHeader (Response->HeaderCount, Response->Headers, HTTP_HEADER_ETAG); if (Header != NULL) { @@ -1793,51 +1804,94 @@ GetEtagAndLocation ( if (*Etag == NULL) { Status = EFI_NOT_FOUND; + DEBUG ((DEBUG_ERROR, "%a: Failed to retrieve ETag from HTTP response paylaod.\n", __func__)); } } - if (Location != NULL) { - *Location = NULL; - AsciiLocation = NULL; + return Status; +} - if (*(Response->StatusCode) == HTTP_STATUS_200_OK) { - Header = HttpFindHeader (Response->HeaderCount, Response->Headers, HTTP_HEADER_LOCATION); - if (Header != NULL) { - AsciiLocation = AllocateCopyPool (AsciiStrSize (Header->FieldValue), Header->FieldValue); - ASSERT (AsciiLocation != NULL); - } +/** + Find "Location" from either HTTP header or Redfish response. + + @param[in] Response HTTP response + @param[out] Location String buffer to return Location + +**/ +EFI_STATUS +GetHttpResponseLocation ( + IN REDFISH_RESPONSE *Response, + OUT EFI_STRING *Location + ) +{ + EFI_STATUS Status; + EDKII_JSON_VALUE JsonValue; + EDKII_JSON_VALUE OdataValue; + CHAR8 *OdataString; + CHAR8 *AsciiLocation; + EFI_HTTP_HEADER *Header; + + if ((Response == NULL) || (Location == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Status = EFI_SUCCESS; + *Location = NULL; + AsciiLocation = NULL; + if (*(Response->StatusCode) == HTTP_STATUS_200_OK) { + Header = HttpFindHeader (Response->HeaderCount, Response->Headers, HTTP_HEADER_LOCATION); + if (Header != NULL) { + AsciiLocation = AllocateCopyPool (AsciiStrSize (Header->FieldValue), Header->FieldValue); + ASSERT (AsciiLocation != NULL); } + } - // - // No header is returned. Search payload for location. - // - if ((*Location == NULL) && (Response->Payload != NULL)) { - JsonValue = RedfishJsonInPayload (Response->Payload); - if (JsonValue != NULL) { - OdataValue = JsonObjectGetValue (JsonValueGetObject (JsonValue), "@odata.id"); - if (OdataValue != NULL) { - OdataString = (CHAR8 *)JsonValueGetAsciiString (OdataValue); - if (OdataString != NULL) { - AsciiLocation = AllocateCopyPool (AsciiStrSize (OdataString), OdataString); - ASSERT (AsciiLocation != NULL); - } + // + // No header is returned. Search payload for location. + // + if ((*Location == NULL) && (Response->Payload != NULL)) { + JsonValue = RedfishJsonInPayload (Response->Payload); + if (JsonValue != NULL) { + OdataValue = JsonObjectGetValue (JsonValueGetObject (JsonValue), "@odata.id"); + if (OdataValue != NULL) { + OdataString = (CHAR8 *)JsonValueGetAsciiString (OdataValue); + if (OdataString != NULL) { + AsciiLocation = AllocateCopyPool (AsciiStrSize (OdataString), OdataString); + ASSERT (AsciiLocation != NULL); } - - JsonValueFree (JsonValue); } - } - if (AsciiLocation != NULL) { - *Location = StrAsciiToUnicode (AsciiLocation); - FreePool (AsciiLocation); - } else { - Status = EFI_NOT_FOUND; + JsonValueFree (JsonValue); } } + if (AsciiLocation != NULL) { + *Location = StrAsciiToUnicode (AsciiLocation); + FreePool (AsciiLocation); + } else { + Status = EFI_NOT_FOUND; + DEBUG ((DEBUG_ERROR, "%a: Failed to retrieve Location from HTTP response paylaod.\n", __func__)); + } + return Status; } +/** + + This function returns a boolean of ETAG support on Redfish service side. + + @retval TRUE ETAG is supported on Redfish service. + @retval FALSE ETAG is not supported on Redfish service. + +**/ +BOOLEAN +CheckIsServerEtagSupported ( + VOID + ) +{ + return FixedPcdGetBool (PcdRedfishServiceEtagSupported); +} + /** Create HTTP payload and send them to redfish service with PATCH method. @@ -1861,7 +1915,7 @@ CreatePayloadToPatchResource ( { REDFISH_PAYLOAD Payload; EDKII_JSON_VALUE ResourceJsonValue; - REDFISH_RESPONSE PostResponse; + REDFISH_RESPONSE PatchResponse; EFI_STATUS Status; if ((Service == NULL) || (TargetPayload == NULL) || IS_EMPTY_STRING (Json)) { @@ -1876,8 +1930,8 @@ CreatePayloadToPatchResource ( goto EXIT_FREE_JSON_VALUE; } - ZeroMem (&PostResponse, sizeof (REDFISH_RESPONSE)); - Status = RedfishPatchToPayload (TargetPayload, Payload, &PostResponse); + ZeroMem (&PatchResponse, sizeof (REDFISH_RESPONSE)); + Status = RedfishPatchToPayload (TargetPayload, Payload, &PatchResponse); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "%a:%d Failed to PATCH payload to Redfish service.\n", __func__, __LINE__)); @@ -1885,7 +1939,7 @@ CreatePayloadToPatchResource ( DEBUG ((DEBUG_ERROR, "%a: Request:\n", __func__)); DumpRedfishPayload (DEBUG_ERROR, Payload); DEBUG ((DEBUG_ERROR, "%a: Response:\n", __func__)); - DumpRedfishResponse (__func__, DEBUG_ERROR, &PostResponse); + DumpRedfishResponse (__func__, DEBUG_ERROR, &PatchResponse); DEBUG_CODE_END (); goto EXIT_FREE_JSON_VALUE; } @@ -1893,16 +1947,20 @@ CreatePayloadToPatchResource ( // // Find ETag // - Status = GetEtagAndLocation (&PostResponse, Etag, NULL); - if (EFI_ERROR (Status)) { + Status = GetHttpResponseEtag (&PatchResponse, Etag); + if (Status == EFI_UNSUPPORTED) { + Status = EFI_SUCCESS; + DEBUG ((DEBUG_INFO, "%a: WARNING - ETAG is not supported on Redfish service.\n", __func__)); + } else { Status = EFI_DEVICE_ERROR; + DEBUG ((DEBUG_ERROR, "%a: Fail to get Location header nor Location property from HTTP response payload.\n", __func__)); } RedfishFreeResponse ( - PostResponse.StatusCode, - PostResponse.HeaderCount, - PostResponse.Headers, - PostResponse.Payload + PatchResponse.StatusCode, + PatchResponse.HeaderCount, + PatchResponse.Headers, + PatchResponse.Payload ); EXIT_FREE_JSON_VALUE: @@ -1935,7 +1993,7 @@ CreatePayloadToPostResource ( IN REDFISH_PAYLOAD *TargetPayload, IN CHAR8 *Json, OUT EFI_STRING *Location, - OUT CHAR8 **Etag + OUT CHAR8 **Etag OPTIONAL ) { REDFISH_PAYLOAD Payload; @@ -1943,7 +2001,7 @@ CreatePayloadToPostResource ( REDFISH_RESPONSE PostResponse; EFI_STATUS Status; - if ((Service == NULL) || (TargetPayload == NULL) || IS_EMPTY_STRING (Json) || (Location == NULL) || (Etag == NULL)) { + if ((Service == NULL) || (TargetPayload == NULL) || IS_EMPTY_STRING (Json) || (Location == NULL)) { return EFI_INVALID_PARAMETER; } @@ -1970,12 +2028,22 @@ CreatePayloadToPostResource ( goto EXIT_FREE_JSON_VALUE; } + Status = GetHttpResponseEtag (&PostResponse, Etag); + if (Status == EFI_UNSUPPORTED) { + Status = EFI_SUCCESS; + DEBUG ((DEBUG_INFO, "%a: WARNING - ETAG is not supported on Redfish service.\n", __func__)); + } else if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + DEBUG ((DEBUG_ERROR, "%a: Fail to get ETAG header nor ETAG property from HTTP response payload.\n", __func__)); + } + // // per Redfish spec. the URL of new resource will be returned in "Location" header. // - Status = GetEtagAndLocation (&PostResponse, Etag, Location); + Status = GetHttpResponseLocation (&PostResponse, Location); if (EFI_ERROR (Status)) { Status = EFI_DEVICE_ERROR; + DEBUG ((DEBUG_ERROR, "%a: Fail to get Location header nor Location proerty from HTTP response payload.\n", __func__)); } RedfishFreeResponse ( @@ -3117,6 +3185,11 @@ CheckEtag ( { CHAR8 *EtagInDb; + if (!CheckIsServerEtagSupported ()) { + DEBUG ((DEBUG_INFO, "%a: WARNING - ETAG is not supported, always returns FALSE to consume resource (Performance would be reduced).\n", __func__)); + return FALSE; + } + if (IS_EMPTY_STRING (Uri)) { return FALSE; } diff --git a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib.inf b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib.inf index 718273b24..63330c8e9 100644 --- a/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib.inf +++ b/RedfishClientPkg/Library/RedfishFeatureUtilityLib/RedfishFeatureUtilityLib.inf @@ -3,6 +3,7 @@ # # (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP
# Copyright (c) 2023-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -54,6 +55,7 @@ [Pcd] gEfiRedfishClientPkgTokenSpaceGuid.PcdRedfishSystemRebootRequired + gEfiRedfishClientPkgTokenSpaceGuid.PcdRedfishServiceEtagSupported [Guids] diff --git a/RedfishClientPkg/RedfishClientPkg.dec b/RedfishClientPkg/RedfishClientPkg.dec index b350facae..ce3b6d975 100644 --- a/RedfishClientPkg/RedfishClientPkg.dec +++ b/RedfishClientPkg/RedfishClientPkg.dec @@ -3,6 +3,7 @@ # # (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP
# Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent ## @@ -76,6 +77,8 @@ gEfiRedfishClientPkgTokenSpaceGuid.PcdDefaultRedfishVersion|L"v1"|VOID*|0x10000004 ## The number of seconds that the firmware will wait before system reboot gEfiRedfishClientPkgTokenSpaceGuid.PcdRedfishSystemRebootTimeout|5|UINT16|0x20000002 + ## Default capability of Redfish service side ETAG support + gEfiRedfishClientPkgTokenSpaceGuid.PcdRedfishServiceEtagSupported|TRUE|BOOLEAN|0x10000005 [PcdsDynamicEx] ## The flag used to indicate that system reboot is required due to system configuration change