Skip to content

GetFrusRunner: FRU 0 failures fail getFrus(), FRU 0 missing or duplicated, failed chunks shift FRU data #128

Description

@bertysentry

Where: src/main/java/org/metricshub/ipmi/client/runner/GetFrusRunner.java (call, processFruRecord, getFruRecords), src/main/java/org/metricshub/ipmi/core/coding/commands/fru/ReadFruData.java (decodeFruData).

What happens:

  1. FRU 0 failure fails the call. call() reads FRU 0 with getFruRecords(0) before the SDR walk, outside any try. On a BMC that does not expose FRU 0, or does not answer Get FRU Inventory Area Info for it, getFrus() (and getFrusAndSensorsAsStringResult()) fails, although the other FRUs could be read.
  2. No reply on Get FRU Inventory Area Info fails the call for the other FRUs too: processFruRecord() only catches IPMIException, so the ConnectionException of a lost reply propagates, while a failed Read FRU Data chunk is only logged.
  3. FRU 0 is attached to the system board only with a Board Info area. The synthetic system-board FRU needs both a BoardInfo (for its name) and a Compact Sensor record of the System Board entity. A FRU 0 with only Product and/or Chassis areas is not returned unless a FRU Device Locator record points to it.
  4. FRU 0 can be returned twice. When the repository has both a logical FRU Device Locator for device ID 0 and a System Board Compact Sensor record, FRU 0 is added once through each path (systemBoardFruUpdated only guards the second one), so the system board appears twice in getFrus() and in the text output.
  5. A failed chunk shifts the rest of the FRU. getFruRecords() skips a Read FRU Data chunk that fails and goes on, and decodeFruData() concatenates the successful chunks without their offsets. The bytes after the gap move into its place and can decode into plausible but wrong manufacturer, model or serial fields, instead of a FRU reported as truncated.

Evidence: by the code (found by Codex while reviewing #124); not reproduced on the test BMCs. On a Lenovo IMM, FRUs 3 and 5 fail every chunk (Requested Sensor, data, or record not present), which is the harmless case: nothing is decoded.

Suggested fix: catch and log failures for FRU 0 and for Get FRU Inventory Area Info like the other FRU errors; build the system-board FRU from whichever of the Board/Product/Chassis areas exist; skip the synthetic entry when a locator already returned FRU 0 (or the reverse); stop reading a FRU at the first failed chunk (or keep the offsets and decode only the areas that are complete). Unit tests for each case.

Related: #85 (FRU decoding bugs), #102 (FRU reads are slow).

Activity

  1. bertysentry commented on Oct 8, 2026

    @bertysentry
    ContributorAuthor

    One more case, also found by Codex on #124: FRU_READ_PACKET_SIZE is fixed at 16 bytes, and the source comment itself says it should be decreased if a BMC answers "Invalid data field in Request." When a Read FRU Data chunk is rejected, getFruRecords() logs it and moves on to the next offset without retrying with a smaller count, so on a BMC whose maximum Read FRU Data transfer is below 16 bytes every FRU ends up corrupted or absent (and point 5 above applies to each skipped chunk). Suggested fix: on CannotReturnRequestedDataBytes (CAh) or InvalidDataFieldInRequest (CCh), retry the same offset with a smaller count (e.g. halving down to 1). By the code; not reproduced on the test BMCs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions