[AMD Official Use Only - General] Hi Nickle, One comment and few questions,
> -----Original Message----- > From: Nickle Wang <nick...@nvidia.com> > Sent: Thursday, April 18, 2024 8:28 PM > To: devel@edk2.groups.io > Cc: Chang, Abner <abner.ch...@amd.com>; Igor Kulchytskyy > <ig...@ami.com>; Nick Ramirez <nrami...@nvidia.com> > Subject: [edk2-redfish-client][PATCH] RedfishClientPkg: introduce > RedfishBootstrapAccountDxe > > Caution: This message originated from an External Source. Use proper caution > when opening attachments, clicking links, or responding. > > > -Introduce RedfishBootstrapAccountDxe to delete bootstrap > account from /redfish/v1/AccountService/Accounts after BIOS > finished all Redfish jobs. The bootstrap account won't be > available to other application. So deleting bootstrap account > helps to release resource at BMC. > - After bootstrap account is deleted at BMC, the Redfish service > instance is no longer usable. Close Redfish service instance to > release the HTTP connection between BIOS and BMC. > > Signed-off-by: Nickle Wang <nick...@nvidia.com> > Cc: Abner Chang <abner.ch...@amd.com> > Cc: Igor Kulchytskyy <ig...@ami.com> > Cc: Nick Ramirez <nrami...@nvidia.com> > --- > .../RedfishClientComponents.dsc.inc | 1 + > .../RedfishBootstrapAccountDxe.inf | 53 +++ > .../RedfishBootstrapAccountDxe.h | 58 ++++ > .../RedfishBootstrapAccountDxe.c | 328 ++++++++++++++++++ > RedfishClientPkg/RedfishClient.fdf.inc | 1 + > 5 files changed, 441 insertions(+) > create mode 100644 > RedfishClientPkg/RedfishBootstrapAccountDxe/RedfishBootstrapAccountDxe.inf > create mode 100644 > RedfishClientPkg/RedfishBootstrapAccountDxe/RedfishBootstrapAccountDxe.h > create mode 100644 > RedfishClientPkg/RedfishBootstrapAccountDxe/RedfishBootstrapAccountDxe.c > > diff --git a/RedfishClientPkg/RedfishClientComponents.dsc.inc > b/RedfishClientPkg/RedfishClientComponents.dsc.inc > index 42fc0c299..fe5248b62 100644 > --- a/RedfishClientPkg/RedfishClientComponents.dsc.inc > +++ b/RedfishClientPkg/RedfishClientComponents.dsc.inc > @@ -20,6 +20,7 @@ > RedfishClientPkg/HiiToRedfishMemoryDxe/HiiToRedfishMemoryDxe.inf > RedfishClientPkg/HiiToRedfishBootDxe/HiiToRedfishBootDxe.inf > RedfishClientPkg/HiiToRedfishBiosDxe/HiiToRedfishBiosDxe.inf > + > RedfishClientPkg/RedfishBootstrapAccountDxe/RedfishBootstrapAccountDxe.inf > !endif > # > # Below two modules should be pulled in by build tool. > diff --git > a/RedfishClientPkg/RedfishBootstrapAccountDxe/RedfishBootstrapAccountDxe.in > f > b/RedfishClientPkg/RedfishBootstrapAccountDxe/RedfishBootstrapAccountDxe.in > f > new file mode 100644 > index 000000000..4073e95f4 > --- /dev/null > +++ > b/RedfishClientPkg/RedfishBootstrapAccountDxe/RedfishBootstrapAccountDxe.in > f > @@ -0,0 +1,53 @@ > +## @file > +# This driver deletes bootstrap account in BMC after BIOS Redfish finished > +# all jobs > +# > +# (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR> > +# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. Not sure if you want to update the copyright to 2024. > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION = 0x0001000b > + BASE_NAME = RedfishBootstrapAccountDxe > + FILE_GUID = 87555253-2F7E-45FC-B469-FD35B2E51210 > + MODULE_TYPE = DXE_DRIVER > + VERSION_STRING = 1.0 > + ENTRY_POINT = RedfishBootstrapAccountEntryPoint > + UNLOAD_IMAGE = RedfishBootstrapAccountUnload > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + RedfishPkg/RedfishPkg.dec > + RedfishClientPkg/RedfishClientPkg.dec > + > +[Sources] > + RedfishBootstrapAccountDxe.h > + RedfishBootstrapAccountDxe.c > + > +[LibraryClasses] > + BaseLib > + BaseMemoryLib > + DebugLib > + MemoryAllocationLib > + PrintLib > + RedfishEventLib > + RedfishFeatureUtilityLib > + RedfishDebugLib > + RedfishVersionLib > + RedfishHttpLib > + UefiLib > + UefiBootServicesTableLib > + UefiRuntimeServicesTableLib > + UefiDriverEntryPoint > + > +[Protocols] > + gEdkIIRedfishConfigHandlerProtocolGuid ## CONSUMES ## > + gEdkIIRedfishCredentialProtocolGuid ## CONSUMES ## > + gEfiRestExProtocolGuid ## CONSUMES ## > + > +[Depex] > + gEdkIIRedfishCredentialProtocolGuid > diff --git > a/RedfishClientPkg/RedfishBootstrapAccountDxe/RedfishBootstrapAccountDxe.h > b/RedfishClientPkg/RedfishBootstrapAccountDxe/RedfishBootstrapAccountDxe.h > new file mode 100644 > index 000000000..5262f1e6b > --- /dev/null > +++ > b/RedfishClientPkg/RedfishBootstrapAccountDxe/RedfishBootstrapAccountDxe.h > @@ -0,0 +1,58 @@ > +/** @file > + Common header file for RedfishBootstrapAccountDxe driver. > + > + (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR> > + Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef REDFISH_BOOTSTRAP_ACCOUNT_DXE_H_ > +#define REDFISH_BOOTSTRAP_ACCOUNT_DXE_H_ > + > +#include <Uefi.h> > +#include <RedfishBase.h> > + > +// > +// Libraries > +// > +#include <Library/BaseLib.h> > +#include <Library/BaseMemoryLib.h> > +#include <Library/DebugLib.h> > + > +#include <Library/MemoryAllocationLib.h> > +#include <Library/PrintLib.h> > +#include <Library/RedfishEventLib.h> > +#include <Library/RedfishFeatureUtilityLib.h> > +#include <Library/RedfishDebugLib.h> > +#include <Library/RedfishVersionLib.h> > +#include <Library/RedfishHttpLib.h> > +#include <Library/UefiBootServicesTableLib.h> > +#include <Library/UefiDriverEntryPoint.h> > +#include <Library/UefiLib.h> > +#include <Library/UefiRuntimeServicesTableLib.h> > + > +#include <Protocol/EdkIIRedfishConfigHandler.h> > +#include <Protocol/EdkIIRedfishCredential.h> > +#include <Protocol/RestEx.h> > + > +#define REDFISH_BOOTSTRAP_ACCOUNT_DEBUG DEBUG_VERBOSE > +#define REDFISH_MANAGER_ACCOUNT_COLLECTION_URI > L"AccountService/Accounts" > +#define REDFISH_URI_LENGTH 128 > + > +// > +// Definitions of REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE > +// > +typedef struct { > + EFI_HANDLE ImageHandle; > + EFI_HANDLE RestExHandle; > + REDFISH_SERVICE RedfishService; > + EFI_EVENT RedfishEvent; > + EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL Protocol; > +} REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE; > + > +#define REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE_FROM_PROTOCOL(This) \ > + BASE_CR ((This), REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE, Protocol) > + > +#endif > diff --git > a/RedfishClientPkg/RedfishBootstrapAccountDxe/RedfishBootstrapAccountDxe.c > b/RedfishClientPkg/RedfishBootstrapAccountDxe/RedfishBootstrapAccountDxe.c > new file mode 100644 > index 000000000..6fe4856f8 > --- /dev/null > +++ > b/RedfishClientPkg/RedfishBootstrapAccountDxe/RedfishBootstrapAccountDxe.c > @@ -0,0 +1,328 @@ > +/** @file > + This driver deletes bootstrap account in BMC after BIOS Redfish finished > + all jobs. > + > + (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR> > + Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "RedfishBootstrapAccountDxe.h" > + > +REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE *mBootstrapPrivate = NULL; > + > +/** > + Close Redfish service instance by calling RestEx protocol to release > instance. > + > + @param[in] RestExHandle Handle of RestEx protocol. > + > + @retval EFI_SUCCESS The Redfish service is closed successfully. > + @retval EFI_INVALID_PARAMETER RestExHandle is NULL. > + @retval Others Error occurs. > + > +**/ > +EFI_STATUS > +CloseRedfishService ( > + IN EFI_HANDLE RestExHandle > + ) > +{ > + EFI_REST_EX_PROTOCOL *RestEx; > + EFI_STATUS Status; > + > + if (RestExHandle == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + Status = gBS->HandleProtocol ( > + RestExHandle, > + &gEfiRestExProtocolGuid, > + (VOID **)&RestEx > + ); > + if (!EFI_ERROR (Status)) { > + Status = RestEx->Configure (RestEx, NULL); > + DEBUG ((REDFISH_BOOTSTRAP_ACCOUNT_DEBUG, "%a: release RestEx > instance: %r\n", __func__, Status)); > + } > + > + return Status; > +} > + > +/** > + Callback function executed when the AfterProvisioning event group is > signaled. > + > + @param[in] Event Event whose notification function is being invoked. > + @param[out] Context Pointer to the Context buffer > + > +**/ > +VOID > +EFIAPI > +RedfishBootstrapAccountOnRedfishAfterProvisioning ( > + IN EFI_EVENT Event, > + OUT VOID *Context > + ) > +{ > + EFI_STATUS Status; > + REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE *Private; > + EDKII_REDFISH_CREDENTIAL_PROTOCOL *credentialProtocol; > + EDKII_REDFISH_AUTH_METHOD AuthMethod; > + CHAR8 *AccountName; > + CHAR8 *AccountCredential; > + CHAR16 TargetUri[REDFISH_URI_LENGTH]; > + CHAR16 *RedfishVersion; > + REDFISH_RESPONSE RedfishResponse; > + > + RedfishVersion = NULL; > + > + Private = (REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE *)Context; > + if ((Private == NULL) || (Private->RedfishService == NULL)) { > + DEBUG ((DEBUG_ERROR, "%a: Redfish service is not available\n", > __func__)); > + return; > + } > + > + // > + // Locate Redfish Credential Protocol to get credential for > + // accessing to Redfish service. > + // > + Status = gBS->LocateProtocol ( > + &gEdkIIRedfishCredentialProtocolGuid, > + NULL, > + (VOID **)&credentialProtocol > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((REDFISH_BOOTSTRAP_ACCOUNT_DEBUG, "%a: No Redfish > Credential Protocol is installed on system.", __func__)); > + return; > + } > + > + Status = credentialProtocol->GetAuthInfo ( > + credentialProtocol, > + &AuthMethod, > + &AccountName, > + &AccountCredential > + ); HI Nickle, I am not quite understand why do we acquire a credential here but delete it from the Redfish account service here after provision. 1. We suppose acquire the credential before we start to communicate with Redfish. Will Redfish credential driver create another bootstrap account here after provisioning? 2. And why do we delete the credential after provisioning? How about the later Redfish property updating process? Or do I misunderstand the code logic? Regards, Abner > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: can not get bootstrap account information: > %r\n", __func__, Status)); > + return; > + } > + > + // > + // Carving the URI > + // > + RedfishVersion = RedfishGetVersion (Private->RedfishService); > + if (RedfishVersion == NULL) { > + DEBUG ((DEBUG_ERROR, "%a: can not get Redfish version\n", __func__)); > + return; > + } > + > + UnicodeSPrint (TargetUri, (sizeof (CHAR16) * REDFISH_URI_LENGTH), > L"%s%s/%a", RedfishVersion, REDFISH_MANAGER_ACCOUNT_COLLECTION_URI, > AccountName); > + > + DEBUG ((REDFISH_BOOTSTRAP_ACCOUNT_DEBUG, "%a: bootstrap account: > %a\n", __func__, AccountName)); > + DEBUG ((REDFISH_BOOTSTRAP_ACCOUNT_DEBUG, "%a: bootstrap > credential: %a\n", __func__, AccountCredential)); > + DEBUG ((REDFISH_BOOTSTRAP_ACCOUNT_DEBUG, "%a: bootstrap URI: > %s\n", __func__, TargetUri)); > + > + // > + // Remove bootstrap account at /redfish/v1/AccountService/Account > + // > + ZeroMem (&RedfishResponse, sizeof (REDFISH_RESPONSE)); > + Status = RedfishHttpDeleteResource ( > + Private->RedfishService, > + TargetUri, > + &RedfishResponse > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: can not remove bootstrap account at BMC: > %r", __func__, Status)); > + DumpRedfishResponse (__func__, DEBUG_ERROR, &RedfishResponse); > + } else { > + DEBUG ((REDFISH_BOOTSTRAP_ACCOUNT_DEBUG, "%a: bootstrap account: > %a is removed from: %s\n", __func__, AccountName, > REDFISH_MANAGER_ACCOUNT_COLLECTION_URI)); > + } > + > + // > + // Clean credential > + // > + ZeroMem (AccountName, AsciiStrSize (AccountName)); > + ZeroMem (AccountCredential, AsciiStrSize (AccountCredential)); > + > + // > + // Since the bootstrap account is deleted at BMC, the Redfish service > instance > is no longer usable. > + // Close Redfish service instance to release the HTTP connection between > BIOS and BMC. > + // > + Status = CloseRedfishService (Private->RestExHandle); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: cannot close Redfish service instance: %r\n", > __func__, Status)); > + } > + > + RedfishHttpFreeResponse (&RedfishResponse); > + > + return; > +} > + > +/** > + Initialize a Redfish configure handler. > + > + This function will be called by the Redfish config driver to initialize > each > Redfish configure > + handler. > + > + @param[in] This Pointer to > EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL instance. > + @param[in] RedfishConfigServiceInfo Redfish service informaiton. > + > + @retval EFI_SUCCESS The handler has been initialized > successfully. > + @retval EFI_DEVICE_ERROR Failed to create or configure the > REST EX > protocol instance. > + @retval EFI_ALREADY_STARTED This handler has already been > initialized. > + @retval Other Error happens during the > initialization. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishBootstrapAccountInit ( > + IN EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL *This, > + IN REDFISH_CONFIG_SERVICE_INFORMATION *RedfishConfigServiceInfo > + ) > +{ > + REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE *Private; > + > + Private = REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE_FROM_PROTOCOL > (This); > + > + Private->RedfishService = RedfishCreateService (RedfishConfigServiceInfo); > + if (Private->RedfishService == NULL) { > + return EFI_DEVICE_ERROR; > + } > + > + Private->RestExHandle = RedfishConfigServiceInfo- > >RedfishServiceRestExHandle; > + > + return EFI_SUCCESS; > +} > + > +/** > + Stop a Redfish configure handler. > + > + @param[in] This Pointer to > EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL instance. > + > + @retval EFI_SUCCESS This handler has been stoped successfully. > + @retval Others Some error happened. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishBootstrapAccountStop ( > + IN EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL *This > + ) > +{ > + REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE *Private; > + > + Private = REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE_FROM_PROTOCOL > (This); > + > + if (Private->RedfishService != NULL) { > + RedfishCleanupService (Private->RedfishService); > + Private->RedfishService = NULL; > + } > + > + return EFI_SUCCESS; > +} > + > +EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL mRedfishConfigHandler = { > + RedfishBootstrapAccountInit, > + RedfishBootstrapAccountStop > +}; > + > +/** > + Unloads an image. > + > + @param[in] ImageHandle Handle that identifies the image to be > unloaded. > + > + @retval EFI_SUCCESS The image has been unloaded. > + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishBootstrapAccountUnload ( > + IN EFI_HANDLE ImageHandle > + ) > +{ > + EFI_STATUS Status; > + > + if (mBootstrapPrivate == NULL) { > + return EFI_SUCCESS; > + } > + > + if (mBootstrapPrivate->RedfishEvent != NULL) { > + gBS->CloseEvent (mBootstrapPrivate->RedfishEvent); > + } > + > + Status = gBS->UninstallProtocolInterface ( > + mBootstrapPrivate->ImageHandle, > + &gEdkIIRedfishConfigHandlerProtocolGuid, > + (VOID *)&mBootstrapPrivate->Protocol > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: can not uninstall Redfish config handler > protocol: %r\n", __func__, Status)); > + } > + > + FreePool (mBootstrapPrivate); > + mBootstrapPrivate = NULL; > + > + return EFI_SUCCESS; > +} > + > +/** > + This is the declaration of an EFI image entry point. This entry point is > + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including > + both device drivers and bus drivers. > + > + @param[in] ImageHandle The firmware allocated handle for the UEFI > image. > + @param[in] SystemTable A pointer to the EFI System Table. > + > + @retval EFI_SUCCESS The operation completed successfully. > + @retval Others An unexpected error occurred. > +**/ > +EFI_STATUS > +EFIAPI > +RedfishBootstrapAccountEntryPoint ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_STATUS Status; > + > + if (mBootstrapPrivate != NULL) { > + return EFI_ALREADY_STARTED; > + } > + > + mBootstrapPrivate = AllocateZeroPool (sizeof > (REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE)); > + if (mBootstrapPrivate == NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + CopyMem (&mBootstrapPrivate->Protocol, &mRedfishConfigHandler, sizeof > (EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL)); > + Status = gBS->InstallProtocolInterface ( > + &ImageHandle, > + &gEdkIIRedfishConfigHandlerProtocolGuid, > + EFI_NATIVE_INTERFACE, > + &mBootstrapPrivate->Protocol > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: can not install Redfish config handler > protocol: %r\n", __func__, Status)); > + goto ON_ERROR; > + } > + > + // > + // Register after provisioning event to remove bootstrap account. > + // > + Status = CreateAfterProvisioningEvent ( > + RedfishBootstrapAccountOnRedfishAfterProvisioning, > + (VOID *)mBootstrapPrivate, > + &mBootstrapPrivate->RedfishEvent > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: failed to register after-provisioning event: > %r\n", __func__, Status)); > + goto ON_ERROR; > + } > + > + return EFI_SUCCESS; > + > +ON_ERROR: > + > + RedfishBootstrapAccountUnload (ImageHandle); > + > + return Status; > +} > diff --git a/RedfishClientPkg/RedfishClient.fdf.inc > b/RedfishClientPkg/RedfishClient.fdf.inc > index 154f641b2..47e5093f2 100644 > --- a/RedfishClientPkg/RedfishClient.fdf.inc > +++ b/RedfishClientPkg/RedfishClient.fdf.inc > @@ -15,6 +15,7 @@ > INF RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf > INF RedfishClientPkg/RedfishETagDxe/RedfishETagDxe.inf > INF > RedfishClientPkg/RedfishConfigLangMapDxe/RedfishConfigLangMapDxe.inf > + INF > RedfishClientPkg/RedfishBootstrapAccountDxe/RedfishBootstrapAccountDxe.inf > INF RedfishClientPkg/Features/Memory/V1_7_1/Dxe/MemoryDxe.inf > INF > RedfishClientPkg/Features/MemoryCollectionDxe/MemoryCollectionDxe.inf > INF > RedfishClientPkg/Features/ComputerSystem/v1_5_0/Dxe/ComputerSystemDxe.i > nf > -- > 2.34.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#118065): https://edk2.groups.io/g/devel/message/118065 Mute This Topic: https://groups.io/mt/105596648/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-