Skip to content

[BMC] Report a missing firmware inventory member instead of OK - #765

Closed
brcarr-nv wants to merge 1 commit into
sonic-net:masterfrom
brcarr-nv:bmc-firmware-version-missing-member
Closed

brcarr-nv wants to merge 1 commit into
sonic-net:masterfrom
brcarr-nv:bmc-firmware-version-missing-member

Conversation

@brcarr-nv

Copy link
Copy Markdown

Why I did it

redfish_api_get_firmware_version() derives its return code from curl's exit status alone. exec_curl_cmd() special-cases only HTTP 401, so a device that answers "no such inventory member" comes back as ERR_CODE_OK: the response body carries a Redfish error object instead of a Version key, so the function logs an error and returns the 'N/A' it started from.

A caller cannot distinguish that from a device whose version is genuinely unknown. In particular, a caller that probes several candidate IDs to find the one its device carries stops at the first ID, because every ID reports success.

Observed on an SPC6 BMC, querying an inventory member it does not have:

HTTP: 400
BODY: {
  "error": {
    "code": "Base.1.19.ResourceMissingAtURI",
    "message": "The resource at the URI '/redfish/v1/UpdateService/FirmwareInventory/FW_BMC_0' was not found."
  }
}
RET:  0        <- ERR_CODE_OK

A second effect is log noise: the miss is logged at error level, so a healthy device emits an ERR line on every query. That is enough to trip log scanners that treat ERR as a failure signal.

How I did it

Inspect the Redfish error body in redfish_api_get_firmware_version():

  • a missing resource returns ERR_CODE_URI_NOT_FOUND and is logged at notice level, since probing an ID a device does not carry is a normal step of resolution rather than a fault;
  • any other error returns ERR_CODE_GENERIC_ERROR and stays logged at error level.

The code spelling varies by implementation — the SPC6 BMC above answers Base.1.19.ResourceMissingAtURI, while other implementations use ResourceNotFound — so both are accepted.

How to verify it

pytest tests/redfish_client_test.py — 78 passed.

Two tests are added, both driven through the public API:

  • test_get_bmc_version_missing_inventory_member — asserts ERR_CODE_URI_NOT_FOUND. Fails without the change with assert 0 == -9.
  • test_get_bmc_version_unrecognized_error — asserts an unrecognised error code still returns ERR_CODE_GENERIC_ERROR, so real failures are not reclassified as "absent". Fails without the change with assert 0 == -12.

The mock body in mock_get_bmc_info_missing_response is a verbatim error response captured from an SPC6 BMC, so the error code and HTTP status under test are the ones a real device sends.

Verified on hardware: with this behaviour, probing FW_BMC_0 on a device that carries MGX_FW_BMC_0 reports the member as missing and the caller resolves to the ID the device actually has.

Description for the changelog

Return ERR_CODE_URI_NOT_FOUND when a Redfish firmware inventory member does not exist, instead of ERR_CODE_OK with a version of N/A.

redfish_api_get_firmware_version() took its return code from curl's exit
status alone. exec_curl_cmd() special-cases only HTTP 401, so a device
answering "no such inventory member" came back as ERR_CODE_OK: the body
carries a Redfish error object rather than a 'Version' key, so the
function logged an error and returned the 'N/A' it started from.

A caller cannot tell that apart from a device whose version is genuinely
unknown. One that probes several candidate IDs to find the one its
device carries stops at the first, because every ID reports success.

Inspect the error body and return ERR_CODE_URI_NOT_FOUND for a missing
resource. The code spelling varies by implementation: an SPC6 BMC
answers HTTP 400 with Base.1.19.ResourceMissingAtURI, others use
ResourceNotFound, so accept either and keep anything else a loud
ERR_CODE_GENERIC_ERROR.

Log the missing member at notice rather than error. Probing an ID a
device does not carry is a normal step of resolution; logging it at
error level makes a healthy device emit an ERR line on every query,
which is enough to trip log scanners that treat ERR as a failure.

The mock body in the added test is a verbatim error response from an
SPC6 BMC, so the code and HTTP status under test are what a real device
sends.
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@brcarr-nv brcarr-nv closed this by deleting the head repository Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants