Skip to content

Don't abort the SDR repository walk on OEM or undecodable records - #112

Merged
bertysentry merged 4 commits into
mainfrom
fix/sdr-oem-record-types
Oct 7, 2026
Merged

bertysentry merged 4 commits into
mainfrom
fix/sdr-oem-record-types

Conversation

@bertysentry

@bertysentry bertysentry commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #76.

What changed

  • SensorRecord.populateSensorRecord: every record type ≥ 0xC0 now maps to OemRecord instead of throwing IllegalArgumentException("Invalid record type"). IPMI 2.0 reserves C0h–FFh for OEM records and vendors use values above C0h (19 of the 85 SDR records on a GIGABYTE ME62-GE0-00 BMC are D0h).
  • OemRecord.populateTypeSpecficValues: tolerates records shorter than the C0h layout (3-byte manufacturer ID + data) so vendor-specific types cannot trigger NegativeArraySize/ArrayIndexOutOfBounds.
  • AbstractIpmiRunner: nextRecId is advanced before decoding in both the whole-record and chunked paths, and a record that fails to decode is logged at WARN and skipped (decodeRecord) instead of aborting the walk. The header copy in getSensorViaChunks is bounded by the record size.

Why

A single SDR record the library does not model killed the entire repository walk: IpmiClient.getFrus() and IpmiClient.getSensors() both failed in under 200 ms with ExecutionException: Invalid record type: -48 on the BMC above, so no FRU and no sensor was ever collected from it. The deprecated 0x14 record type has the same effect and is now skipped too.

Verification

  • mvn test: 13 tests pass.
  • Live against the GIGABYTE BMC: chassis status, 2 FRUs and 62 sensors collected (previously nothing); the 19 OEM records are retained as OemRecord with their raw bytes.
  • Live against a Lenovo IMM (58 records, one 0xC0 OEM record): output unchanged.

Also in this PR

  • CLAUDE.md (a single @AGENTS.md import, as in jawk) and AGENTS.md with the project instructions for AI agents: Java 8 target, license headers, current (ungated) quality reports and the SpotBugs workaround on recent JDKs, plus the IPMI-specific rules learned during the review (never abort an SDR/FRU walk on an unknown record, no BMC credentials in the repo, expect dropped UDP replies when testing against hardware).

Reviewer notes

🤖 Generated with Claude Code

Fixes #76.

populateSensorRecord threw IllegalArgumentException for any SDR record
type it does not model, and the runners only advanced nextRecId after a
successful decode, so a single unknown record killed both FRU and sensor
collection. IPMI 2.0 reserves C0h-FFh for OEM records and vendors use
values above C0h (19 of 85 records are D0h on a GIGABYTE ME62-GE0-00).

- SensorRecord: map every record type >= C0h to OemRecord.
- OemRecord: tolerate records shorter than the C0h layout.
- AbstractIpmiRunner: advance nextRecId before decoding, log and skip a
  record that fails to decode, and bound the header copy in the chunked
  path by the record size.

Verified live: chassis, 2 FRUs and 62 sensors now collected from the
GIGABYTE BMC that previously failed in under 200 ms; Lenovo IMM unchanged.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-07T11:15:22.389473Z a602881 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e6f3487656

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/main/java/org/metricshub/ipmi/core/coding/commands/sdr/record/OemRecord.java Outdated
Only the C0h OEM record defines a 3-byte manufacturer ID followed by
OEM data. Record types C1h-FFh, which populateSensorRecord now also maps
to OemRecord, have a vendor-defined layout: interpreting bytes 5-7 as a
manufacturer ID fabricated an ID and dropped the first three payload
bytes. For those types the manufacturer ID stays 0 and getOemData()
returns the entire type-specific payload.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
…AUDE.md

Same convention as jawk: CLAUDE.md only imports AGENTS.md. The
instructions describe this repository as it is today (Java 8 target,
license headers, no formatter yet, ungated quality reports and the
workaround for SpotBugs on recent JDKs) plus the IPMI-specific lessons
from the October 2026 review: never abort an SDR or FRU walk on an
unknown record, keep BMC credentials out of the repository, and expect
dropped UDP replies when testing against real hardware.

Co-Authored-By: Claude Fable 5.1 <[email protected]>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7aac625fb6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread AGENTS.md
…rd tests

Some BMCs answer a whole-record Get SDR with a success code but fewer
bytes than the record length declared in the SDR header. Advancing to
the next record before decoding would have turned such a record into a
silent skip, so the runner now detects the short reply and uses the
existing chunked read while the record ID is still known. The chunked
path also tolerates a BMC returning fewer bytes than requested instead
of throwing ArrayIndexOutOfBounds.

New unit tests cover the OEM decoding path (vendor-defined types keep
their whole payload, C0h parses the manufacturer ID, short records do
not throw, reserved types are still rejected), the runner's skip
behaviour for undecodable records, and the truncation check.

AGENTS.md now states that the LGPL header requirement applies to the
Java sources under src/main/java only, which is what the license plugin
checks; tests, Markdown and resources carry no header.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
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.

SDR repository walk aborts on OEM/unknown record types (e.g. 0xD0) – no FRUs, no sensors

1 participant