Conversation
The contract between the orchestrator and an update source (the PLDM firmware-device service today, self-update later): the UpdateIntake trait a source calls, the IntakeStatus phases the orchestrator answers with, and the wire encoding that carries both over a kernel channel. Api layer only, no transport and no dispatch, so it builds and tests on the host. The source is the channel's initiator and the orchestrator its handler, with no channel the other way, so the orchestrator never waits on the source and a wedged source cannot delay a boot window. That is why the seam is polled: everything the orchestrator decides comes back as the phase on a response, including the two update reports, which latch a phase instead of sending a message.
IntakeStatus documented one order. A board that writes the candidate straight into the target's inactive slot authenticates by reading that slot back, and a target gated on a signed manifest is authenticated before any byte moves, so the order differs by board and a source must not assume one. Staging is now marked as reachable only where the orchestrator stages into a region of its own. Write-through is the expected shape here: the part has 768 KB of SRAM against a payload of tens of megabytes, so there is no room to hold a copy. The README also stops saying complete() hands the state machine the update request. Where that event fires is still open, so the step now says only what complete() itself does.
|
Closing this. The intake seam, handler, and loopback harness from this PR now live on The open question in the description (where |
|
Reopening. The close comment above was wrong: |
|
Closing this. #464 settled the direction the other way around: PLDM-FD is the What carries over goes into the orchestrator-to-FD API when that gets built: The runtime docs page in the first commit is Anthony's, it is #449. |
The IPC channel between
services/pldmand the orchestrator, as its contract.wire.rsis the channel protocol: a 16-byte request header plus the chunk onWrite, a 20-byte response, five opcodes, andMAX_CHUNK = 512to matchFD_MAX_XFER_SIZEinpldm-interfaceso aRequestFirmwareDatachunk passesthrough unsplit. Decoding validates lengths, opcodes, reserved fields and the
chunk bound before anything looks at the payload, and never panics: the
request side is another process and is treated as untrusted.
traits.rsis theUpdateIntakecall surface,status.rstheIntakeStatusphases the orchestrator answers with. Host-buildable, depends only on
zerocopy, and both processes depend on it.
The source is the channel's initiator and the orchestrator its handler, with
no channel the other way, so the orchestrator never waits on a source and a
wedged source cannot delay a boot window or a recovery.
Not here, and why:
channel_transactclient and thechannel_read/channel_respondhandler loop are separate PRs, trait first.
system.json5endpoint declarations cannot land yet:target/ast10x0/erot/system.json5is kernel-only and has noapps:key, sothere are no processes to hang a
channel_handlerandchannel_initiatoroff.
services/storageis still a stub, so nothing moves a real image. The crateand its tests stand alone on the host.
Draft because one thing is unresolved:
Event::UpdateRequestfires atRequestUpdateaccept on main (#442), which entersState::Updatingandemits
AuthenticateUpdatewith no bytes to authenticate. The README no longerclaims
complete()is what hands the state machine the request, but wherethat event should fire is not settled here.
Stacked on Anthony's runtime-concept commit (51b4dfa), which is not merged.
Review the last two commits only.