Repository navigation
Conversation
…lready matches SetSecureBootKeyManagement skipped the PATCH whenever the BIOS attribute's currently-applied value already matched what was requested. Confirmed live: this is the same class of bug UpdateBiosAttributesExact fixed in gofish - currently-applied state can spuriously match while a different value is genuinely pending from an earlier, unrelated call in the same boot cycle (e.g. a stale pending change left staged by an interrupted Workflow). Skipping the PATCH left that stale pending value in place, silently reverting an explicit request to change it on the next reboot - observed live as a certificate import rejected because SecureBootPolicy committed as Standard despite requesting Custom moments earlier. Route through setBiosConfiguration (added in bmc-toolbox#467) instead of c.redfishwrapper.SetBiosConfiguration directly, so a genuine conflict with a different pending job is recovered from rather than failing outright, matching every other Dell BIOS-backed feature. Depends on bmc-toolbox#467. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
c036feb to
d29e6b6
Compare
…atches SetSecureBootKeyManagement read the attribute's currently applied value and returned early when it already matched what was requested. Confirmed live, that's unsafe: currently-applied state can match while a different value is genuinely pending from an earlier call in the same boot cycle (e.g. a stale pending PATCH left staged by an interrupted, unrelated caller). Skipping the write left that stale pending value in place, silently reverting an explicit request on the next reboot - observed as a certificate import rejected because SecureBootPolicy committed as Standard despite requesting Custom moments earlier. It's the same class of bug UpdateBiosAttributesExact was written to fix in gofish, one layer up. The attribute is still read first, but only to reject platforms that don't expose it at all. The write itself is now unconditional; recovery from a genuine pending-job conflict comes for free from the recovering client (bmc-toolbox#467), so a redundant write costs a round trip rather than a hard failure. Depends on bmc-toolbox#467. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
f927ee3 to
522710f
Compare
…ct recovery) Reopened bmc-toolbox/bmclib#467 and rebased it under tinkerbell#471/tinkerbell#472 in tink-integration: the earlier conclusion that tinkerbell#471 alone eliminated the IDRAC.2.14.SYS011 conflict class was based on bmc-debug tests using bare Bios/Settings PATCHes, which don't reflect what bmclib actually sends. bmclib always asserts @Redfish.SettingsApplyTime, which is itself what creates the one BIOS Configuration Job iDRAC allows at a time - so any two separate Dell BIOS-attribute setter calls in one boot cycle still conflict without tinkerbell#467's recoveringRedfishClient, including within a single NetworkBootConfig action (SetNetworkBootEnabled then SetHTTPBootURI) - verified live, through the real bmclib/gofish code path, not just raw PATCHes. Signed-off-by: Mickael Canevet <mickael.canevet@proton.ch> Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
a3365f7 to
2922ede
Compare
…ct recovery) Reopened bmc-toolbox/bmclib#467 and rebased it under tinkerbell#471/tinkerbell#472 in tink-integration: the earlier conclusion that tinkerbell#471 alone eliminated the IDRAC.2.14.SYS011 conflict class was based on bmc-debug tests using bare Bios/Settings PATCHes, which don't reflect what bmclib actually sends. bmclib always asserts @Redfish.SettingsApplyTime, which is itself what creates the one BIOS Configuration Job iDRAC allows at a time - so any two separate Dell BIOS-attribute setter calls in one boot cycle still conflict without tinkerbell#467's recoveringRedfishClient, including within a single NetworkBootConfig action (SetNetworkBootEnabled then SetHTTPBootURI) - verified live, through the real bmclib/gofish code path, not just raw PATCHes. Signed-off-by: Mickael Canevet <mickael.canevet@proton.ch> Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ct recovery) Reopened bmc-toolbox/bmclib#467 and rebased it under tinkerbell#471/tinkerbell#472 in tink-integration: the earlier conclusion that tinkerbell#471 alone eliminated the IDRAC.2.14.SYS011 conflict class was based on bmc-debug tests using bare Bios/Settings PATCHes, which don't reflect what bmclib actually sends. bmclib always asserts @Redfish.SettingsApplyTime, which is itself what creates the one BIOS Configuration Job iDRAC allows at a time - so any two separate Dell BIOS-attribute setter calls in one boot cycle still conflict without tinkerbell#467's recoveringRedfishClient, including within a single NetworkBootConfig action (SetNetworkBootEnabled then SetHTTPBootURI) - verified live, through the real bmclib/gofish code path, not just raw PATCHes. Signed-off-by: Mickael Canevet <mickael.canevet@proton.ch> Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
ca8397d to
00a3a46
Compare
|
@mcanevet can you elaborate what problem is this PR trying to solve and why |
00a3a46 to
7e14bef
Compare
|
@joelrebel I updated the PR description. Does it make more sense now? I'm not convinced on the solution, but the problem is real. Currently we can't change 2 BIOS parameters on Dell iDRAC without rebooting. |
@mcanevet based on my understanding, what this PR is trying to achieve is to clear a pending operation that is in conflict and apply the provided settings, correct me if I'm misunderstanding By forcing all of this into a single method, we prevent the caller from being able to make a decision and it often bmclib methods should ideally perform a single operation (read, write) on the BMC and return quickly,
Also note, we could re-use some of how the dell Job and task state is being converted instead of re-implementing, see bmclib/providers/dell/firmware.go Line 192 in fec875d |
|
From what I observe, Dell iDRAC works like this:
So two BIOS changes in the same boot cycle can only work by either cancelling the job and resubmitting the merged set (what this PR does), or by splitting stage and commit into separate calls. This also affects In Tinkerbell's case an explicit commit would just be one more action before the reboot, which is fine. What I'd like to avoid is making the caller aware of Dell's quirk. So if we go that way, I'd rather have a generic stage/commit contract (commit is a no-op on vendors that already apply at reset) than a Dell-specific opt-in. The options I can see:
Open to other approaches if you see a better one. |
7e14bef to
b4c93a2
Compare
|
@mcanevet thanks for elaborating that helps clear up the reasoning, the concerns I have is based on these two points, if you can look into resolving these then we likely have a path to have this merged
side note: The orchestrator (Rufio) in this case should ideally batch up the BIOS changes required and create a single request to set the configuration and follow up the related job on the BMC is finalized |
|
One alternative to the current "PATCH, then recover on SYS011": check for a pending job first and only write once nothing is blocking.
From what I observe, any pending BIOS job locks The cost is one extra GET on every Dell BIOS write, which is about 0.5s in my setup. Today a write with no conflict is a single PATCH. Stacked writes in a Tinkerbell workflow would save the rejected PATCH each time. Not sure which fits bmclib better. Happy to keep it as is, or rework it if you'd prefer this. |
What you suggest here sounds like a fair approach, if you can include those changes, and also if determine if any of the existing dell job struct, task unpacking can be re-used |
ApplyBiosAttributes writes BIOS attributes keeping their native JSON types (bool, number, string), for callers that resubmit attributes they read back from the BMC, where stringifying a value could be rejected by a strict attribute registry. SetBiosConfiguration now delegates to it, so the apply-time handling exists once. Jobs lists the jobs of the Redfish JobService, in a single request on a BMC that supports $expand: a used iDRAC holds well over a hundred jobs, and reading them one by one takes a request each. Both are used by the Dell provider to merge a BIOS write into an already pending job. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: Mickaël Canévet <mickael.canevet@proton.ch>
iDRAC allows one pending BIOS config job at a time. Any write to Bios/Settings, or to a resource that mirrors a BIOS attribute such as the SecureBoot resource, seals that job, and every further write is rejected with SYS011 until the job is deleted or has run. Two BIOS-affecting calls in one boot cycle therefore fail on the second, although both would apply together at the next reset. SetBiosConfiguration now reads the pending attributes before writing: - Nothing pending: a plain write, as before. - Something pending: delete the live job (only if it has not started applying), merge the requested attributes over the staged ones and write once. The merge carries attributes an earlier caller staged, because iDRAC keeps a single job and deleting it discards what it staged. If the merged write fails, the attributes the deleted job held are staged again and the error says whether that worked. The deletion is logged. - Every requested attribute already at the requested value, staged or, where nothing is staged for it, applied, with a live job carrying the staged ones: nothing is done, so repeating a call is idempotent. A SYS011 the read could not foresee is returned to the caller, with a note when no job could be found to delete. The sequence is not safe against another client writing BIOS settings on the same BMC at the same time. A job is recognized by Oem.Dell.JobType or by its "ConfigBIOS:" name, as not every iDRAC generation returns an Oem block in the JobService collection. It is deleted only in a state in which it has not started, and only if Dell's own job resource, the one the firmware code already reads, shows no ActualRunningStartTime: that resource reports it on every generation. A pending job shows "Scheduled" or "Starting" depending on the generation; gofish's JobState set has neither. Unknown states are refused rather than assumed safe. Tested against a PowerEdge R760xd2 (iDRAC 7.30.10.50) and a PowerEdge R6715 (iDRAC 1.20.80.51). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: Mickaël Canévet <mickael.canevet@proton.ch>
b4c93a2 to
e34b654
Compare
|
@joelrebel I reworked this along the lines you agreed to, and rewrote the description to be shorter.
I ran two writes in one boot cycle against a PowerEdge R6715 (iDRAC 1.20.80.51) and an R760xd2 (7.30.10.50): they end up as one job, repeats leave it alone, and the iDRAC is clean afterwards. I also did read-only checks on 29 other Dell hosts (iDRAC 5.00 to 7.30, and 1.20) for the settings redirect, |
tink-integration is rebuilt from upstream main plus bmc-toolbox/bmclib#467 and tinkerbell#471. It now merges BIOS writes into a pending Dell BIOS job instead of failing the second write of a boot cycle with SYS011, which the customboot BMC actions (NetworkBootConfig, SecureBoot, ...) hit when several run before one reboot. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: Mickaël Canévet <mickael.canevet@proton.ch>
Problem
iDRAC keeps one pending BIOS config job. Any write to
Bios/Settings, or to a resource that mirrors a BIOS attribute (such as theSecureBootresource), seals it, and every further write is rejected withSYS011until the job is deleted or has run. Two BIOS-affecting calls in the same boot cycle therefore fail on the second one, although both would apply together at the next reset.Change
The Dell provider's
SetBiosConfigurationreads the pending attributes before writing:The merge carries along attributes an earlier caller staged, because deleting the job discards what it staged. The deletion is logged, and if the merged write fails afterwards the staged attributes are put back. An unexpected
SYS011is returned to the caller. It is not safe against another client writing BIOS settings on the same BMC at the same time.redfishwrappergainsApplyBiosAttributes(typed values;SetBiosConfigurationnow delegates to it) andJobs()(one$expandrequest, falling back to per-job reads).Testing
Unit tests, plus runs against a PowerEdge R6715 (iDRAC 1.20.80.51) and an R760xd2 (7.30.10.50): two writes in one boot cycle end up as one job, repeats leave the job alone, and the iDRAC is clean afterwards. Read-only checks on 29 other Dell hosts (iDRAC 5.00 to 7.30, and 1.20) confirmed the settings redirect, the
JobService, theConfigBIOS:job naming and Dell's job resource.