@@ -162,6 +162,10 @@ pub struct ControlPlaneStarter<'a, N: NexusServer> {
162162 pub dendrite : RwLock < HashMap < SwitchSlot , dev:: dendrite:: DendriteInstance > > ,
163163 pub mgd : HashMap < SwitchSlot , dev:: maghemite:: MgdInstance > ,
164164 pub ddm : HashMap < SwitchSlot , dev:: maghemite:: DdmInstance > ,
165+ /// Maps scrimlet sled IDs to their switch slot. Populated by
166+ /// `record_switch_dns()` and used by `start_sled()` to configure
167+ /// the sled-agent with `is_scrimlet = true` and start reconcilers.
168+ scrimlets : BTreeMap < SledUuid , SwitchSlot > ,
165169
166170 // NOTE: Only exists after starting Nexus, until external Nexus is
167171 // initialized.
@@ -225,6 +229,7 @@ impl<'a, N: NexusServer> ControlPlaneStarter<'a, N> {
225229 dendrite : RwLock :: new ( HashMap :: new ( ) ) ,
226230 mgd : HashMap :: new ( ) ,
227231 ddm : HashMap :: new ( ) ,
232+ scrimlets : BTreeMap :: new ( ) ,
228233 nexus_internal : None ,
229234 nexus_internal_addr : None ,
230235 external_dns_zone_name : None ,
@@ -509,6 +514,10 @@ impl<'a, N: NexusServer> ControlPlaneStarter<'a, N> {
509514 "switch_slot" => ?switch_slot,
510515 ) ;
511516
517+ // Record that this sled is a scrimlet so that `start_sled()` can
518+ // configure it with `is_scrimlet = true` and start reconcilers.
519+ self . scrimlets . insert ( sled_id, switch_slot) ;
520+
512521 self . rack_init_builder
513522 . internal_dns_config
514523 . host_zone_switch (
@@ -944,6 +953,9 @@ impl<'a, N: NexusServer> ControlPlaneStarter<'a, N> {
944953 let nexus_address =
945954 self . nexus_internal_addr . expect ( "Must launch Nexus first" ) ;
946955
956+ let switch_slot = self . scrimlets . get ( & sled_id) . copied ( ) ;
957+ let is_scrimlet = switch_slot. is_some ( ) ;
958+
947959 let sled_agent = start_sled_agent (
948960 self . logctx . log . new ( o ! (
949961 "component" => "omicron_sled_agent::sim::Server" ,
@@ -954,11 +966,39 @@ impl<'a, N: NexusServer> ControlPlaneStarter<'a, N> {
954966 self . sled_index_allocator . next ( ) ,
955967 sim_mode,
956968 SledCpuFamily :: AmdMilan ,
969+ is_scrimlet,
957970 & self . simulated_upstairs ,
958971 )
959972 . await
960973 . expect ( "Failed to start sled agent" ) ;
961974
975+ // If this is a scrimlet, start the scrimlet reconcilers so they can
976+ // react to bootstore network config updates.
977+ if let Some ( slot) = switch_slot {
978+ let mgs_addr: SocketAddr =
979+ self . gateway . get ( & slot) . unwrap ( ) . address ( ) . into ( ) ;
980+ let dpd_addr: SocketAddr = self
981+ . dendrite
982+ . read ( )
983+ . unwrap ( )
984+ . get ( & slot)
985+ . unwrap ( )
986+ . address ( )
987+ . into ( ) ;
988+ let mgd_addr: SocketAddr =
989+ self . mgd . get ( & slot) . unwrap ( ) . address ( ) . into ( ) ;
990+ // Our test mgd uses --no-bgp-dispatcher, so pass the mgd admin
991+ // address as a dummy bgp_dispatcher_addr. As long as tests don't
992+ // configure BGP, the reconciler won't use this address.
993+ let bgp_dispatcher_addr = mgd_addr;
994+ sled_agent. sled_agent . start_scrimlet_reconcilers (
995+ mgs_addr,
996+ dpd_addr,
997+ mgd_addr,
998+ bgp_dispatcher_addr,
999+ ) ;
1000+ }
1001+
9621002 // Add a DNS entry for the TUF Repo Depot on this simulated sled agent.
9631003 let SocketAddr :: V6 ( server_addr_v6) = sled_agent. repo_depot_address
9641004 else {
@@ -1076,6 +1116,7 @@ impl<'a, N: NexusServer> ControlPlaneStarter<'a, N> {
10761116 self . sled_index_allocator . next ( ) ,
10771117 sim_mode,
10781118 SledCpuFamily :: AmdMilan ,
1119+ false ,
10791120 & self . simulated_upstairs ,
10801121 )
10811122 . await
@@ -1929,13 +1970,15 @@ impl SledIndexAllocator {
19291970/// Note: you should probably use the `extra_sled_agents` macro parameter on
19301971/// `nexus_test` instead! To start a sled agent partway through a test, use
19311972/// [`ControlPlaneTestContext::add_sled`].
1973+ #[ allow( clippy:: too_many_arguments) ]
19321974pub ( crate ) async fn start_sled_agent (
19331975 log : Logger ,
19341976 nexus_address : SocketAddr ,
19351977 id : SledUuid ,
19361978 sled_index : u16 ,
19371979 sim_mode : sim:: SimMode ,
19381980 cpu_family : SledCpuFamily ,
1981+ is_scrimlet : bool ,
19391982 simulated_upstairs : & Arc < sim:: SimulatedUpstairs > ,
19401983) -> Result < sim:: Server , String > {
19411984 // Generate a baseboard serial number that matches the SP configuration
@@ -1950,6 +1993,7 @@ pub(crate) async fn start_sled_agent(
19501993 sim:: ZpoolConfig :: None ,
19511994 cpu_family,
19521995 Some ( baseboard_serial) ,
1996+ is_scrimlet,
19531997 ) ;
19541998 start_sled_agent_with_config ( log, & config, sled_index, simulated_upstairs)
19551999 . await
0 commit comments