@@ -3295,7 +3295,7 @@ enum FirmwareStatusRouting {
32953295 /// requested IDs are sent to the compute-tray backend.
32963296 DirectDispatch ,
32973297 /// The CM is in state-controller mode: the request is split by whether each
3298- /// machine has a persisted `backend_firmware_object_job_id` .
3298+ /// machine has an in-flight direct-dispatch firmware-object job .
32993299 Partitioned {
33003300 /// IDs with a persisted backend job — route to `compute_tray` so callers
33013301 /// can poll the live in-flight state.
@@ -3305,92 +3305,59 @@ enum FirmwareStatusRouting {
33053305 } ,
33063306}
33073307
3308- /// Partition `machine_ids` into those that have a persisted backend
3309- /// firmware-object job ID on their machine row and those that do not .
3308+ /// Partition `machine_ids` by whether their BMC MAC has a persisted
3309+ /// direct-dispatch firmware-update job (`bmc_macs_with_direct_fw_updates`) .
33103310///
33113311/// Returns `(persisted_ids, fallback_ids)`:
3312- /// - `persisted_ids` — IDs where the loaded machine has a non-null
3313- /// `backend_firmware_object_job_id`; route to `compute_tray`.
3312+ /// - `persisted_ids` — the machine's BMC MAC is in
3313+ /// `bmc_macs_with_direct_fw_updates`; route to `compute_tray` to poll the live
3314+ /// in-flight job.
33143315/// - `fallback_ids` — remaining IDs; route to `machine_firmware_statuses`.
33153316///
3316- /// A tray flashed before ingestion persists its job to `explored_endpoints`
3317- /// rather than the machine row, so the caller augments the split with
3318- /// [`reclassify_preingestion_jobs_from_explored_endpoints`] before routing .
3317+ /// Keyed by BMC MAC because a job dispatched before ingestion is recorded under
3318+ /// the tray's MAC, and stays reachable there after ingestion creates the machine
3319+ /// row — so a tray flashed pre-ingestion still polls the live backend .
33193320fn partition_by_backend_job_id (
33203321 machine_ids : & [ MachineId ] ,
33213322 machines_by_id : & HashMap < MachineId , Machine > ,
3323+ bmc_macs_with_direct_fw_updates : & HashSet < MacAddress > ,
33223324) -> ( Vec < MachineId > , Vec < MachineId > ) {
33233325 machine_ids. iter ( ) . copied ( ) . partition ( |id| {
33243326 machines_by_id
33253327 . get ( id)
3326- . is_some_and ( |m| m. status . backend_firmware_object_job_id . is_some ( ) )
3328+ . and_then ( |m| m. status . bmc_info . mac )
3329+ . is_some_and ( |mac| bmc_macs_with_direct_fw_updates. contains ( & mac) )
33273330 } )
33283331}
33293332
33303333/// Choose how to route a batch of `machine_ids` for firmware-status retrieval.
33313334///
33323335/// When `use_state_controller` is `false` (direct-dispatch mode) all IDs are
33333336/// forwarded to the compute-tray backend. Otherwise the IDs are partitioned by
3334- /// the presence of a persisted `backend_firmware_object_job_id`: those with a job
3335- /// go to the live backend; the rest fall back to the DB-only path.
3337+ /// whether their BMC MAC has a persisted direct-dispatch job
3338+ /// (`bmc_macs_with_direct_fw_updates`): those with a job poll the live backend;
3339+ /// the rest fall back to the DB-only path.
33363340fn select_firmware_status_routing (
33373341 use_state_controller : bool ,
33383342 machine_ids : & [ MachineId ] ,
33393343 machines_by_id : & HashMap < MachineId , Machine > ,
3344+ bmc_macs_with_direct_fw_updates : & HashSet < MacAddress > ,
33403345) -> FirmwareStatusRouting {
33413346 if !use_state_controller {
33423347 FirmwareStatusRouting :: DirectDispatch
33433348 } else {
3344- let ( persisted, fallback) = partition_by_backend_job_id ( machine_ids, machines_by_id) ;
3349+ let ( persisted, fallback) = partition_by_backend_job_id (
3350+ machine_ids,
3351+ machines_by_id,
3352+ bmc_macs_with_direct_fw_updates,
3353+ ) ;
33453354 FirmwareStatusRouting :: Partitioned {
33463355 persisted,
33473356 fallback,
33483357 }
33493358 }
33503359}
33513360
3352- /// Move `fallback` machines whose BMC IP still carries a pre-ingestion firmware
3353- /// job in `explored_endpoints` into `persisted`, so they poll the live backend.
3354- ///
3355- /// A tray flashed before ingestion persists its job id to `explored_endpoints`
3356- /// (keyed by BMC IP), not the machine row. Once ingestion creates the row its
3357- /// `backend_firmware_object_job_id` stays NULL, so the machine-row partition
3358- /// alone would misroute it to the DB-only path and lose live status. One batched
3359- /// query over the fallback set's BMC IPs reclassifies those still tracked.
3360- async fn reclassify_preingestion_jobs_from_explored_endpoints (
3361- api : & Api ,
3362- persisted : & mut Vec < MachineId > ,
3363- fallback : & mut Vec < MachineId > ,
3364- machines_by_id : & HashMap < MachineId , Machine > ,
3365- ) -> Result < ( ) , Status > {
3366- let fallback_ips: Vec < IpAddr > = fallback
3367- . iter ( )
3368- . filter_map ( |id| machines_by_id. get ( id) . and_then ( |m| m. status . bmc_info . ip ) )
3369- . collect ( ) ;
3370- let ips_with_job = db:: explored_endpoints:: find_ips_with_backend_firmware_object_job_id (
3371- api. pg_pool ( ) ,
3372- & fallback_ips,
3373- )
3374- . await
3375- . map_err ( |e| Status :: internal ( format ! ( "db error: {e}" ) ) ) ?;
3376-
3377- if ips_with_job. is_empty ( ) {
3378- return Ok ( ( ) ) ;
3379- }
3380-
3381- fallback. retain ( |id| {
3382- let has_explored_job = machines_by_id
3383- . get ( id)
3384- . and_then ( |m| m. status . bmc_info . ip )
3385- . is_some_and ( |ip| ips_with_job. contains ( & ip) ) ;
3386- if has_explored_job {
3387- persisted. push ( * id) ;
3388- }
3389- !has_explored_job
3390- } ) ;
3391- Ok ( ( ) )
3392- }
3393-
33943361pub ( crate ) async fn get_component_firmware_status (
33953362 api : & Api ,
33963363 request : Request < rpc:: GetComponentFirmwareStatusRequest > ,
@@ -3479,38 +3446,42 @@ pub(crate) async fn get_component_firmware_status(
34793446 }
34803447
34813448 // In direct-dispatch mode all IDs go to the compute-tray backend.
3482- // In state-controller mode the batch is partitioned: IDs with a
3483- // persisted backend_firmware_object_job_id (set when a firmware update
3484- // was dispatched via --bypass-state-controller) are polled from the
3485- // live backend; the rest use the DB-only machine_firmware_statuses()
3486- // path.
3449+ // In state-controller mode the batch is partitioned by whether each
3450+ // tray's BMC MAC has an in-flight direct-dispatch firmware-object job
3451+ // in compute_firmware_object_jobs (set when a firmware update was
3452+ // dispatched via --bypass-state-controller, before or after
3453+ // ingestion): those are polled from the live backend; the rest use
3454+ // the DB-only machine_firmware_statuses() path.
34873455 if let Some ( cm) = api. component_manager . as_ref ( ) {
34883456 let machines_by_id = load_machines_by_id ( api, & list. machine_ids ) . await ?;
34893457
3458+ let bmc_macs_with_direct_fw_updates = if cm. compute_tray_use_state_controller {
3459+ let bmc_macs: Vec < MacAddress > = list
3460+ . machine_ids
3461+ . iter ( )
3462+ . filter_map ( |id| machines_by_id. get ( id) . and_then ( |m| m. status . bmc_info . mac ) )
3463+ . collect ( ) ;
3464+ db:: direct_dispatch_firmware_job:: find_macs_with_job ( api. pg_pool ( ) , & bmc_macs)
3465+ . await
3466+ . map_err ( |e| Status :: internal ( format ! ( "db error: {e}" ) ) ) ?
3467+ } else {
3468+ HashSet :: new ( )
3469+ } ;
3470+
34903471 match select_firmware_status_routing (
34913472 cm. compute_tray_use_state_controller ,
34923473 & list. machine_ids ,
34933474 & machines_by_id,
3475+ & bmc_macs_with_direct_fw_updates,
34943476 ) {
34953477 FirmwareStatusRouting :: DirectDispatch => {
34963478 compute_tray_firmware_statuses ( cm, api, & machines_by_id, & list. machine_ids )
34973479 . await ?
34983480 }
34993481 FirmwareStatusRouting :: Partitioned {
3500- mut persisted,
3501- mut fallback,
3482+ persisted,
3483+ fallback,
35023484 } => {
3503- // A tray flashed before ingestion keeps its job on
3504- // explored_endpoints, not the machine row, so reclassify
3505- // those still tracked there back onto the live-poll path.
3506- reclassify_preingestion_jobs_from_explored_endpoints (
3507- api,
3508- & mut persisted,
3509- & mut fallback,
3510- & machines_by_id,
3511- )
3512- . await ?;
3513-
35143485 let mut statuses = Vec :: with_capacity ( list. machine_ids . len ( ) ) ;
35153486 if !persisted. is_empty ( ) {
35163487 statuses. extend (
@@ -5216,22 +5187,26 @@ mod tests {
52165187 let id_b = dpu_machine_id ( 0 ) ;
52175188 let id_c = dpu_machine_id ( 1 ) ;
52185189
5219- let mut machine_with_rms_job = machine_with_id ( standalone_machine ( ) , id_a) ;
5220- machine_with_rms_job. status . backend_firmware_object_job_id =
5221- Some ( "backend-job-bypass-abc" . to_string ( ) ) ;
5190+ let mac_a: MacAddress = "AA:BB:CC:DD:EE:01" . parse ( ) . unwrap ( ) ;
5191+ let mac_b: MacAddress = "AA:BB:CC:DD:EE:02" . parse ( ) . unwrap ( ) ;
5192+ let mac_c: MacAddress = "AA:BB:CC:DD:EE:03" . parse ( ) . unwrap ( ) ;
5193+
5194+ let mut machine_a = machine_with_id ( standalone_machine ( ) , id_a) ;
5195+ machine_a. status . bmc_info . mac = Some ( mac_a) ;
5196+ let mut machine_b = machine_with_id ( standalone_machine ( ) , id_b. into ( ) ) ;
5197+ machine_b. status . bmc_info . mac = Some ( mac_b) ;
5198+ let mut machine_c = machine_with_id ( standalone_machine ( ) , id_c. into ( ) ) ;
5199+ machine_c. status . bmc_info . mac = Some ( mac_c) ;
52225200
52235201 let machines = HashMap :: from ( [
5224- ( id_a, machine_with_rms_job) ,
5225- (
5226- id_b. into ( ) ,
5227- machine_with_id ( standalone_machine ( ) , id_b. into ( ) ) ,
5228- ) ,
5229- (
5230- id_c. into ( ) ,
5231- machine_with_id ( standalone_machine ( ) , id_c. into ( ) ) ,
5232- ) ,
5202+ ( id_a, machine_a) ,
5203+ ( id_b. into ( ) , machine_b) ,
5204+ ( id_c. into ( ) , machine_c) ,
52335205 ] ) ;
52345206
5207+ // Only machine A has an in-flight direct-dispatch firmware job.
5208+ let bmc_macs_with_direct_fw_updates: HashSet < MacAddress > = HashSet :: from ( [ mac_a] ) ;
5209+
52355210 struct Case {
52365211 scenario : & ' static str ,
52375212 use_state_controller : bool ,
@@ -5283,8 +5258,12 @@ mod tests {
52835258 . map ( |& i| all_ids[ i] )
52845259 . collect ( ) ;
52855260
5286- let routing =
5287- select_firmware_status_routing ( case. use_state_controller , & ids, & machines) ;
5261+ let routing = select_firmware_status_routing (
5262+ case. use_state_controller ,
5263+ & ids,
5264+ & machines,
5265+ & bmc_macs_with_direct_fw_updates,
5266+ ) ;
52885267 match routing {
52895268 FirmwareStatusRouting :: DirectDispatch => {
52905269 assert ! (
0 commit comments