LCOV - code coverage report
Current view: top level - disco/topo - fd_topo.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 23 148 15.5 %
Date: 2026-01-16 05:17:52 Functions: 5 2329 0.2 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_disco_topo_fd_topo_h
       2             : #define HEADER_fd_src_disco_topo_fd_topo_h
       3             : 
       4             : #include "../stem/fd_stem.h"
       5             : #include "../../tango/fd_tango.h"
       6             : #include "../../waltz/xdp/fd_xdp1.h"
       7             : #include "../../ballet/base58/fd_base58.h"
       8             : #include "../../util/net/fd_net_headers.h"
       9             : 
      10             : /* Maximum number of workspaces that may be present in a topology. */
      11             : #define FD_TOPO_MAX_WKSPS         (256UL)
      12             : /* Maximum number of links that may be present in a topology. */
      13             : #define FD_TOPO_MAX_LINKS         (256UL)
      14             : /* Maximum number of tiles that may be present in a topology. */
      15           0 : #define FD_TOPO_MAX_TILES         (256UL)
      16             : /* Maximum number of objects that may be present in a topology. */
      17             : #define FD_TOPO_MAX_OBJS          (4096UL)
      18             : /* Maximum number of links that may go into any one tile in the
      19             :    topology. */
      20             : #define FD_TOPO_MAX_TILE_IN_LINKS  ( 128UL)
      21             : /* Maximum number of links that a tile may write to. */
      22             : #define FD_TOPO_MAX_TILE_OUT_LINKS ( 32UL)
      23             : /* Maximum number of objects that a tile can use. */
      24             : #define FD_TOPO_MAX_TILE_OBJS      ( 256UL)
      25             : 
      26             : /* Maximum number of additional ip addresses */
      27             : #define FD_NET_MAX_SRC_ADDR 4
      28             : 
      29             : /* Maximum number of additional destinations for leader shreds and for retransmitted shreds */
      30             : #define FD_TOPO_ADTL_DESTS_MAX ( 32UL)
      31             : 
      32           0 : #define FD_TOPO_CORE_DUMP_LEVEL_DISABLED (0)
      33           0 : #define FD_TOPO_CORE_DUMP_LEVEL_MINIMAL  (1)
      34           6 : #define FD_TOPO_CORE_DUMP_LEVEL_REGULAR  (2)
      35           0 : #define FD_TOPO_CORE_DUMP_LEVEL_FULL     (3)
      36           0 : #define FD_TOPO_CORE_DUMP_LEVEL_NEVER    (4)
      37             : 
      38             : /* A workspace is a Firedancer specific memory management structure that
      39             :    sits on top of 1 or more memory mapped gigantic or huge pages mounted
      40             :    to the hugetlbfs. */
      41             : typedef struct {
      42             :   ulong id;           /* The ID of this workspace.  Indexed from [0, wksp_cnt).  When placed in a topology, the ID must be the index of the workspace in the workspaces list. */
      43             :   char  name[ 13UL ]; /* The name of this workspace, like "pack".  There can be at most one of each workspace name in a topology. */
      44             : 
      45             :   ulong numa_idx;     /* The index of the NUMA node on the system that this workspace should be allocated from. */
      46             : 
      47             :   ulong min_part_max; /* Artificially raise part_max */
      48             :   ulong min_loose_sz; /* Artificially raise loose footprint */
      49             : 
      50             :   /* Computed fields.  These are not supplied as configuration but calculated as needed. */
      51             :   struct {
      52             :     ulong page_sz;  /* The size of the pages that this workspace is backed by.  One of FD_PAGE_SIZE_*. */
      53             :     ulong page_cnt; /* The number of pages that must be mapped to this workspace to store all the data needed by consumers. */
      54             :     ulong part_max; /* The maximum number of partitions in the underlying workspace.  There can only be this many allocations made at any one time. */
      55             : 
      56             :     int core_dump_level; /* The core dump level required to be set in the application configuration to have this workspace appear in core dumps. */
      57             : 
      58             :     fd_wksp_t * wksp;            /* The workspace memory in the local process. */
      59             :     ulong       known_footprint; /* Total size in bytes of all data in Firedancer that will be stored in this workspace at startup. */
      60             :     ulong       total_footprint; /* Total size in bytes of all data in Firedancer that could be stored in this workspace, includes known data and loose data. */
      61             :   };
      62             : } fd_topo_wksp_t;
      63             : 
      64             : /* A link is an mcache in a workspace that has one producer and one or
      65             :    more consumers. A link may optionally also have a dcache, that holds
      66             :    fragments referred to by the mcache entries.
      67             : 
      68             :    A link belongs to exactly one workspace.  A link has exactly one
      69             :    producer, and 1 or more consumers.  Each consumer is either reliable
      70             :    or not reliable.  A link has a depth and a MTU, which correspond to
      71             :    the depth and MTU of the mcache and dcache respectively.  A MTU of
      72             :    zero means no dcache is needed, as there is no data. */
      73             : typedef struct {
      74             :   ulong id;           /* The ID of this link.  Indexed from [0, link_cnt).  When placed in a topology, the ID must be the index of the link in the links list. */
      75             :   char  name[ 13UL ]; /* The name of this link, like "pack_bank". There can be multiple of each link name in a topology. */
      76             :   ulong kind_id;      /* The ID of this link within its name.  If there are N links of a particular name, they have IDs [0, N).  The pair (name, kind_id) uniquely identifies a link, as does "id" on its own. */
      77             : 
      78             :   ulong depth;    /* The depth of the mcache representing the link. */
      79             :   ulong mtu;      /* The MTU of data fragments in the mcache.  A value of 0 means there is no dcache. */
      80             :   ulong burst;    /* The max amount of MTU sized data fragments that might be bursted to the dcache. */
      81             : 
      82             :   ulong mcache_obj_id;
      83             :   ulong dcache_obj_id;
      84             : 
      85             :   /* Computed fields.  These are not supplied as configuration but calculated as needed. */
      86             :   struct {
      87             :     fd_frag_meta_t * mcache; /* The mcache of this link. */
      88             :     void *           dcache; /* The dcache of this link, if it has one. */
      89             :   };
      90             : 
      91             :   uint permit_no_consumers : 1;  /* Permit a topology where this link has no consumers */
      92             :   uint permit_no_producers : 1;  /* Permit a topology where this link has no producers */
      93             : } fd_topo_link_t;
      94             : 
      95             : /* Be careful: ip and host are in different byte order */
      96             : typedef struct {
      97             :   uint   ip;   /* in network byte order */
      98             :   ushort port; /* in host byte order */
      99             : } fd_topo_ip_port_t;
     100             : 
     101             : struct fd_topo_net_tile {
     102             :   ulong umem_dcache_obj_id;  /* dcache for XDP UMEM frames */
     103             :   uint  bind_address;
     104             : 
     105             :   ushort shred_listen_port;
     106             :   ushort quic_transaction_listen_port;
     107             :   ushort legacy_transaction_listen_port;
     108             :   ushort gossip_listen_port;
     109             :   ushort repair_intake_listen_port;
     110             :   ushort repair_serve_listen_port;
     111             :   ushort send_src_port;
     112             : };
     113             : typedef struct fd_topo_net_tile fd_topo_net_tile_t;
     114             : 
     115             : /* A tile is a unique process that is spawned by Firedancer to represent
     116             :    one thread of execution.  Firedancer sandboxes all tiles to their own
     117             :    process for security reasons.
     118             : 
     119             :    A tile belongs to exactly one workspace.  A tile is a consumer of 0
     120             :    or more links, it's inputs.  A tile is a producer of 0 or more output
     121             :    links.
     122             : 
     123             :    All input links will be automatically polled by the tile
     124             :    infrastructure, and output links will automatically source and manage
     125             :    credits from consumers. */
     126             : struct fd_topo_tile {
     127             :   ulong id;                     /* The ID of this tile.  Indexed from [0, tile_cnt).  When placed in a topology, the ID must be the index of the tile in the tiles list. */
     128             :   char  name[ 7UL ];            /* The name of this tile.  There can be multiple of each tile name in a topology. */
     129             :   char  metrics_name[ 10UL ];   /* The name of this tile for looking up metrics.  This is used so tiles can share a name but report different metrics, for Frankendancer and Firedancer. */
     130             :   ulong kind_id;                /* The ID of this tile within its name.  If there are n tile of a particular name, they have IDs [0, N).  The pair (name, kind_id) uniquely identifies a tile, as does "id" on its own. */
     131             :   int   is_agave;               /* If the tile needs to run in the Agave (Anza) address space or not. */
     132             :   int   allow_shutdown;         /* If the tile is allowed to shutdown gracefully.  If false, when the tile exits it will tear down the entire application. */
     133             : 
     134             :   ulong cpu_idx;                /* The CPU index to pin the tile on.  A value of ULONG_MAX or more indicates the tile should be floating and not pinned to a core. */
     135             : 
     136             :   ulong in_cnt;                 /* The number of links that this tile reads from. */
     137             :   ulong in_link_id[ FD_TOPO_MAX_TILE_IN_LINKS ];       /* The link_id of each link that this tile reads from, indexed in [0, in_cnt). */
     138             :   int   in_link_reliable[ FD_TOPO_MAX_TILE_IN_LINKS ]; /* If each link that this tile reads from is a reliable or unreliable consumer, indexed in [0, in_cnt). */
     139             :   int   in_link_poll[ FD_TOPO_MAX_TILE_IN_LINKS ];     /* If each link that this tile reads from should be polled by the tile infrastructure, indexed in [0, in_cnt).
     140             :                                                           If the link is not polled, the tile will not receive frags for it and the tile writer is responsible for
     141             :                                                           reading from the link.  The link must be marked as unreliable as it is not flow controlled. */
     142             : 
     143             :   ulong out_cnt;                                   /* The number of links that this tile writes to. */
     144             :   ulong out_link_id[ FD_TOPO_MAX_TILE_OUT_LINKS ]; /* The link_id of each link that this tile writes to, indexed in [0, link_cnt). */
     145             : 
     146             :   ulong tile_obj_id;
     147             :   ulong metrics_obj_id;
     148             :   ulong keyswitch_obj_id;
     149             :   ulong in_link_fseq_obj_id[ FD_TOPO_MAX_TILE_IN_LINKS ];
     150             : 
     151             :   ulong uses_obj_cnt;
     152             :   ulong uses_obj_id[ FD_TOPO_MAX_TILE_OBJS ];
     153             :   int   uses_obj_mode[ FD_TOPO_MAX_TILE_OBJS ];
     154             : 
     155             :   /* Computed fields.  These are not supplied as configuration but calculated as needed. */
     156             :   struct {
     157             :     ulong *    metrics; /* The shared memory for metrics that this tile should write.  Consumer by monitoring and metrics writing tiles. */
     158             : 
     159             :     /* The fseq of each link that this tile reads from.  Multiple fseqs
     160             :        may point to the link, if there are multiple consumers.  An fseq
     161             :        can be uniquely identified via (link_id, tile_id), or (link_kind,
     162             :        link_kind_id, tile_kind, tile_kind_id) */
     163             :     ulong *    in_link_fseq[ FD_TOPO_MAX_TILE_IN_LINKS ];
     164             :   };
     165             : 
     166             :   /* Configuration fields.  These are required to be known by the topology so it can determine the
     167             :      total size of Firedancer in memory. */
     168             :   union {
     169             :     fd_topo_net_tile_t net;
     170             : 
     171             :     struct {
     172             :       fd_topo_net_tile_t net;
     173             : 
     174             :       char if_virt[ 16 ];  /* device name (virtual, for routing) */
     175             :       char if_phys[ 16 ];  /* device name (physical, for RX/TX) */
     176             :       uint if_queue;       /* device queue index */
     177             : 
     178             :       /* xdp specific options */
     179             :       ulong  xdp_rx_queue_size;
     180             :       ulong  xdp_tx_queue_size;
     181             :       ulong  free_ring_depth;
     182             :       long   tx_flush_timeout_ns;
     183             :       char   xdp_mode[8];
     184             :       int    zero_copy;
     185             : 
     186             :       ulong netdev_dbl_buf_obj_id; /* dbl_buf containing netdev_tbl */
     187             :       ulong fib4_main_obj_id;      /* fib4 containing main route table */
     188             :       ulong fib4_local_obj_id;     /* fib4 containing local route table */
     189             :       ulong neigh4_obj_id;         /* neigh4 hash map */
     190             : 
     191             :       int xsk_core_dump;
     192             :     } xdp;
     193             : 
     194             :     struct {
     195             :       fd_topo_net_tile_t net;
     196             :       /* sock specific options */
     197             :       int so_sndbuf;
     198             :       int so_rcvbuf;
     199             :     } sock;
     200             : 
     201             :     struct {
     202             :       ulong netdev_dbl_buf_obj_id; /* dbl_buf containing netdev_tbl */
     203             :       ulong fib4_main_obj_id;      /* fib4 containing main route table */
     204             :       ulong fib4_local_obj_id;     /* fib4 containing local route table */
     205             :       char  neigh_if[ 16 ];        /* neigh4 interface name */
     206             :       ulong neigh4_obj_id;         /* neigh4 hash map */
     207             :     } netlink;
     208             : 
     209           0 : #define FD_TOPO_GOSSIP_ENTRYPOINTS_MAX 16UL
     210             : 
     211             :     struct {
     212             :       char identity_key_path[ PATH_MAX ];
     213             : 
     214             :       ulong         entrypoints_cnt;
     215             :       fd_ip4_port_t entrypoints[ FD_TOPO_GOSSIP_ENTRYPOINTS_MAX ];
     216             : 
     217             :       long boot_timestamp_nanos;
     218             : 
     219             :       ulong tcache_depth;
     220             : 
     221             :       ushort shred_version;
     222             :       int allow_private_address;
     223             :     } gossvf;
     224             : 
     225             :     struct {
     226             :       char identity_key_path[ PATH_MAX ];
     227             : 
     228             :       ulong         entrypoints_cnt;
     229             :       fd_ip4_port_t entrypoints[ FD_TOPO_GOSSIP_ENTRYPOINTS_MAX ];
     230             : 
     231             :       long boot_timestamp_nanos;
     232             : 
     233             :       uint   ip_addr;
     234             :       ushort shred_version;
     235             : 
     236             :       ulong  max_entries;
     237             :       ulong  max_purged;
     238             :       ulong  max_failed;
     239             : 
     240             :       struct {
     241             :         ushort gossip;
     242             :         ushort tvu;
     243             :         ushort tvu_quic;
     244             :         ushort tpu;
     245             :         ushort tpu_quic;
     246             :         ushort repair;
     247             :       } ports;
     248             :     } gossip;
     249             : 
     250             :     struct {
     251             :       uint   out_depth;
     252             :       uint   reasm_cnt;
     253             :       ulong  max_concurrent_connections;
     254             :       ulong  max_concurrent_handshakes;
     255             :       ushort quic_transaction_listen_port;
     256             :       long   idle_timeout_millis;
     257             :       uint   ack_delay_millis;
     258             :       int    retry;
     259             :       char   key_log_path[ PATH_MAX ];
     260             :     } quic;
     261             : 
     262             :     struct {
     263             :       ulong tcache_depth;
     264             :     } verify;
     265             : 
     266             :     struct {
     267             :       ulong tcache_depth;
     268             :     } dedup;
     269             : 
     270             :     struct {
     271             :       char  url[ 256 ];
     272             :       ulong url_len;
     273             :       char  sni[ 256 ];
     274             :       ulong sni_len;
     275             :       char  identity_key_path[ PATH_MAX ];
     276             :       char  key_log_path[ PATH_MAX ];
     277             :       ulong buf_sz;
     278             :       ulong ssl_heap_sz;
     279             :       ulong keepalive_interval_nanos;
     280             :       uchar tls_cert_verify : 1;
     281             :     } bundle;
     282             : 
     283             :     struct {
     284             :       ulong max_pending_transactions;
     285             :       ulong bank_tile_count;
     286             :       int   larger_max_cost_per_block;
     287             :       int   larger_shred_limits_per_block;
     288             :       int   use_consumed_cus;
     289             :       int   schedule_strategy;
     290             :       struct {
     291             :         int   enabled;
     292             :         uchar tip_distribution_program_addr[ 32 ];
     293             :         uchar tip_payment_program_addr[ 32 ];
     294             :         uchar tip_distribution_authority[ 32 ];
     295             :         ulong commission_bps;
     296             :         char  identity_key_path[ PATH_MAX ];
     297             :         char  vote_account_path[ PATH_MAX ]; /* or pubkey is okay */
     298             :       } bundle;
     299             :     } pack;
     300             : 
     301             :     struct {
     302             :       int   lagged_consecutive_leader_start;
     303             :       int   plugins_enabled;
     304             :       ulong bank_cnt;
     305             :       char  identity_key_path[ PATH_MAX ];
     306             :       struct {
     307             :         int   enabled;
     308             :         uchar tip_payment_program_addr[ 32 ];
     309             :         uchar tip_distribution_program_addr[ 32 ];
     310             :         char  vote_account_path[ PATH_MAX ];
     311             :       } bundle;
     312             :     } poh;
     313             : 
     314             :     struct {
     315             :       ulong             depth;
     316             :       ulong             fec_resolver_depth;
     317             :       char              identity_key_path[ PATH_MAX ];
     318             :       ushort            shred_listen_port;
     319             :       int               larger_shred_limits_per_block;
     320             :       ushort            expected_shred_version;
     321             :       ulong             adtl_dests_retransmit_cnt;
     322             :       fd_topo_ip_port_t adtl_dests_retransmit[ FD_TOPO_ADTL_DESTS_MAX ];
     323             :       ulong             adtl_dests_leader_cnt;
     324             :       fd_topo_ip_port_t adtl_dests_leader[ FD_TOPO_ADTL_DESTS_MAX ];
     325             :     } shred;
     326             : 
     327             :     struct {
     328             :       ulong disable_blockstore_from_slot;
     329             :     } store;
     330             : 
     331             :     struct {
     332             :       char   identity_key_path[ PATH_MAX ];
     333             :     } sign;
     334             : 
     335             :     struct {
     336             :       uint   listen_addr;
     337             :       ushort listen_port;
     338             : 
     339             :       int    is_voting;
     340             : 
     341             :       char   cluster[ 32 ];
     342             :       char   identity_key_path[ PATH_MAX ];
     343             :       char   vote_key_path[ PATH_MAX ];
     344             : 
     345             :       ulong  max_http_connections;
     346             :       ulong  max_websocket_connections;
     347             :       ulong  max_http_request_length;
     348             :       ulong  send_buffer_size_mb;
     349             :       int    schedule_strategy;
     350             : 
     351             :       int websocket_compression;
     352             :       int frontend_release_channel;
     353             :     } gui;
     354             : 
     355             :     struct {
     356             :       uint   listen_addr;
     357             :       ushort listen_port;
     358             : 
     359             :       ulong max_http_connections;
     360             :       ulong send_buffer_size_mb;
     361             :       ulong max_http_request_length;
     362             : 
     363             :       ulong max_live_slots;
     364             : 
     365             :       char identity_key_path[ PATH_MAX ];
     366             :     } rpc;
     367             : 
     368             :     struct {
     369             :       uint   prometheus_listen_addr;
     370             :       ushort prometheus_listen_port;
     371             :     } metric;
     372             : 
     373             :     struct {
     374             :       ulong fec_max;
     375             :       ulong max_vote_accounts;
     376             : 
     377             :       ulong funk_obj_id;
     378             : 
     379             :       ulong txncache_obj_id;
     380             :       ulong progcache_obj_id;
     381             : 
     382             :       char  shred_cap[ PATH_MAX ];
     383             : 
     384             :       char  identity_key_path[ PATH_MAX ];
     385             :       uint  ip_addr;
     386             :       char  vote_account_path[ PATH_MAX ];
     387             : 
     388             :       ushort expected_shred_version;
     389             : 
     390             :       ulong heap_size_gib;
     391             :       ulong max_live_slots;
     392             : 
     393             :       /* not specified in TOML */
     394             : 
     395             :       ulong enable_features_cnt;
     396             :       char  enable_features[ 16 ][ FD_BASE58_ENCODED_32_SZ ];
     397             : 
     398             :       char  genesis_path[ PATH_MAX ];
     399             : 
     400             :       int   larger_max_cost_per_block;
     401             : 
     402             :       ulong capture_start_slot;
     403             :       char  solcap_capture[ PATH_MAX ];
     404             :       char  dump_proto_dir[ PATH_MAX ];
     405             :       int   dump_block_to_pb;
     406             : 
     407             :       struct {
     408             :         int   enabled;
     409             :         uchar tip_payment_program_addr[ 32 ];
     410             :         uchar tip_distribution_program_addr[ 32 ];
     411             :         char  vote_account_path[ PATH_MAX ];
     412             :       } bundle;
     413             : 
     414             :     } replay;
     415             : 
     416             :     struct {
     417             :       ulong funk_obj_id;
     418             :       ulong txncache_obj_id;
     419             :       ulong progcache_obj_id;
     420             :       ulong acc_pool_obj_id;
     421             : 
     422             :       ulong max_live_slots;
     423             : 
     424             :       ulong capture_start_slot;
     425             :       char  solcap_capture[ PATH_MAX ];
     426             :       char  dump_proto_dir[ PATH_MAX ];
     427             :       int   dump_instr_to_pb;
     428             :       int   dump_txn_to_pb;
     429             :       int   dump_syscall_to_pb;
     430             :       int   dump_elf_to_pb;
     431             :     } exec;
     432             : 
     433             :     struct {
     434             :       ushort send_to_port;
     435             :       uint   send_to_ip_addr;
     436             :       ulong  conn_cnt;
     437             :       int    no_quic;
     438             :     } benchs;
     439             : 
     440             :     struct {
     441             :       ushort rpc_port;
     442             :       uint   rpc_ip_addr;
     443             :     } bencho;
     444             : 
     445             :     struct {
     446             :       ulong accounts_cnt;
     447             :       int   mode;
     448             :       float contending_fraction;
     449             :       float cu_price_spread;
     450             :     } benchg;
     451             : 
     452             :     struct {
     453             :       ushort  repair_intake_listen_port;
     454             :       ushort  repair_serve_listen_port;
     455             :       char    identity_key_path[ PATH_MAX ];
     456             :       ulong   max_pending_shred_sets;
     457             :       ulong   slot_max;
     458             : 
     459             :       /* non-config */
     460             : 
     461             :       ulong   repair_sign_depth;
     462             :       ulong   repair_sign_cnt;
     463             : 
     464             :       ulong   end_slot; /* repair profiler mode only */
     465             :     } repair;
     466             : 
     467             :     struct {
     468             :       ushort  send_src_port;
     469             : 
     470             :       /* non-config */
     471             : 
     472             :       uint    ip_addr;
     473             :       char  identity_key_path[ PATH_MAX ];
     474             :     } send;
     475             : 
     476             :     struct {
     477             :       uint fake_dst_ip;
     478             :     } pktgen;
     479             : 
     480             :     struct {
     481             :       ulong end_slot;
     482             :       char  rocksdb_path[ PATH_MAX ];
     483             :       char  ingest_mode[ 32 ];
     484             : 
     485             :       /* Set internally by the archiver tile */
     486             :       int archive_fd;
     487             :     } archiver;
     488             : 
     489             :     struct {
     490             :       ulong end_slot;
     491             :       char rocksdb_path[ PATH_MAX ];
     492             :       char shredcap_path[ PATH_MAX ];
     493             :     } backtest;
     494             : 
     495             :     struct {
     496             :       int   hard_fork_fatal;
     497             :       ulong max_live_slots;
     498             :       ulong max_vote_lookahead;
     499             :       char  identity_key[ PATH_MAX ];
     500             :       char  vote_account[ PATH_MAX ];
     501             :       char  base_path[PATH_MAX];
     502             :     } tower;
     503             : 
     504             :     struct {
     505             :       char   folder_path[ PATH_MAX ];
     506             :       ushort repair_intake_listen_port;
     507             :       ulong   write_buffer_size; /* Size of the write buffer for the capture tile */
     508             :       int    enable_publish_stake_weights;
     509             :       char   manifest_path[ PATH_MAX ];
     510             : 
     511             :       /* Set internally by the capture tile */
     512             :       int shreds_fd;
     513             :       int requests_fd;
     514             :       int fecs_fd;
     515             :       int peers_fd;
     516             :       int bank_hashes_fd;
     517             :       int slices_fd;
     518             :     } shredcap;
     519             : 
     520             : #define FD_TOPO_SNAPSHOTS_GOSSIP_LIST_MAX      (32UL)
     521           0 : #define FD_TOPO_SNAPSHOTS_SERVERS_MAX          (16UL)
     522           0 : #define FD_TOPO_MAX_RESOLVED_ADDRS             ( 4UL)
     523           0 : #define FD_TOPO_SNAPSHOTS_SERVERS_MAX_RESOLVED (FD_TOPO_MAX_RESOLVED_ADDRS*FD_TOPO_SNAPSHOTS_SERVERS_MAX)
     524             : 
     525             :     struct fd_topo_tile_snapct {
     526             :       char snapshots_path[ PATH_MAX ];
     527             : 
     528             :       struct {
     529             :         uint max_local_full_effective_age;
     530             :         uint max_local_incremental_age;
     531             : 
     532             :         struct {
     533             :           int         allow_any;
     534             :           ulong       allow_list_cnt;
     535             :           fd_pubkey_t allow_list[ FD_TOPO_SNAPSHOTS_GOSSIP_LIST_MAX ];
     536             :           ulong       block_list_cnt;
     537             :           fd_pubkey_t block_list[ FD_TOPO_SNAPSHOTS_GOSSIP_LIST_MAX ];
     538             :         } gossip;
     539             : 
     540             :         ulong         servers_cnt;
     541             :         struct {
     542             :           fd_ip4_port_t addr;
     543             :           char          hostname[ 256UL ];
     544             :           int           is_https;
     545             :         } servers[ FD_TOPO_SNAPSHOTS_SERVERS_MAX_RESOLVED ];
     546             :       } sources;
     547             : 
     548             :       int  incremental_snapshots;
     549             :       uint max_full_snapshots_to_keep;
     550             :       uint max_incremental_snapshots_to_keep;
     551             :       uint full_effective_age_cancel_threshold;
     552             :       uint max_retry_abort;
     553             :     } snapct;
     554             : 
     555             :     struct {
     556             :       char snapshots_path[ PATH_MAX ];
     557             :     } snapld;
     558             : 
     559             :     struct {
     560             :       ulong max_live_slots;
     561             :       ulong funk_obj_id;
     562             :       ulong txncache_obj_id;
     563             : 
     564             :       uint  lthash_disabled : 1;
     565             :       uint  use_vinyl : 1;
     566             :     } snapin;
     567             : 
     568             :     struct {
     569             :       uint  lthash_disabled : 1;
     570             :       ulong vinyl_meta_map_obj_id;
     571             :       ulong vinyl_meta_pool_obj_id;
     572             :       ulong snapwr_depth;
     573             :       char  vinyl_path[ PATH_MAX ];
     574             :     } snapwm;
     575             : 
     576             :     struct {
     577             :       ulong dcache_obj_id;
     578             :       char  vinyl_path[ PATH_MAX ];
     579             :     } snapwr;
     580             : 
     581             :     struct {
     582             :       ulong dcache_obj_id;
     583             :       int   io_uring_enabled;
     584             :       char  vinyl_path[ PATH_MAX ];
     585             :     } snaplh;
     586             : 
     587             :     struct {
     588             : 
     589             :       uint   bind_address;
     590             :       ushort bind_port;
     591             : 
     592             :       ushort expected_shred_version;
     593             :       ulong entrypoints_cnt;
     594             :       fd_ip4_port_t entrypoints[ FD_TOPO_GOSSIP_ENTRYPOINTS_MAX ];
     595             :     } ipecho;
     596             : 
     597             :     struct {
     598             :       ulong max_live_slots;
     599             :       ulong txncache_obj_id;
     600             :       ulong funk_obj_id;
     601             :       ulong progcache_obj_id;
     602             :       ulong acc_pool_obj_id;
     603             :     } bank;
     604             : 
     605             :     struct {
     606             :       ulong funk_obj_id;
     607             :     } resolv;
     608             : 
     609             :     struct {
     610             :       ulong funk_obj_id;
     611             : 
     612             :       int allow_download;
     613             : 
     614             :       ushort expected_shred_version;
     615             :       ulong entrypoints_cnt;
     616             :       fd_ip4_port_t entrypoints[ FD_TOPO_GOSSIP_ENTRYPOINTS_MAX ];
     617             : 
     618             :       int has_expected_genesis_hash;
     619             :       uchar expected_genesis_hash[ 32UL ];
     620             : 
     621             :       char genesis_path[ PATH_MAX ];
     622             : 
     623             :       uint target_gid;
     624             :       uint target_uid;
     625             :     } genesi;
     626             : 
     627             :     struct {
     628             :       ulong vinyl_meta_map_obj_id;
     629             :       ulong vinyl_meta_pool_obj_id;
     630             :       ulong vinyl_line_max;
     631             :       ulong vinyl_data_obj_id;
     632             :       char  vinyl_bstream_path[ PATH_MAX ];
     633             : 
     634             :       int  io_type; /* FD_VINYL_IO_TYPE_* */
     635             :       uint uring_depth;
     636             :     } vinyl;
     637             : 
     638             :     struct {
     639             :       ulong capture_start_slot;
     640             :       char  solcap_capture[ PATH_MAX ];
     641             :       int   recent_only;
     642             :       ulong recent_slots_per_file;
     643             :     } solcap;
     644             :   };
     645             : };
     646             : 
     647             : typedef struct fd_topo_tile fd_topo_tile_t;
     648             : 
     649             : typedef struct {
     650             :   ulong id;
     651             :   char  name[ 13UL ];  /* object type */
     652             :   ulong wksp_id;
     653             : 
     654             :   /* Optional label for object */
     655             :   char  label[ 13UL ];  /* object label */
     656             :   ulong label_idx;      /* index of object for this label (ULONG_MAX if not labelled) */
     657             : 
     658             :   ulong offset;
     659             :   ulong footprint;
     660             : } fd_topo_obj_t;
     661             : 
     662             : /* An fd_topo_t represents the overall structure of a Firedancer
     663             :    configuration, describing all the workspaces, tiles, and links
     664             :    between them. */
     665             : struct fd_topo {
     666             :   char           app_name[ 256UL ];
     667             :   uchar          props[ 16384UL ];
     668             : 
     669             :   ulong          wksp_cnt;
     670             :   ulong          link_cnt;
     671             :   ulong          tile_cnt;
     672             :   ulong          obj_cnt;
     673             : 
     674             :   fd_topo_wksp_t workspaces[ FD_TOPO_MAX_WKSPS ];
     675             :   fd_topo_link_t links[ FD_TOPO_MAX_LINKS ];
     676             :   fd_topo_tile_t tiles[ FD_TOPO_MAX_TILES ];
     677             :   fd_topo_obj_t  objs[ FD_TOPO_MAX_OBJS ];
     678             : 
     679             :   ulong          agave_affinity_cnt;
     680             :   ulong          agave_affinity_cpu_idx[ FD_TILE_MAX ];
     681             : 
     682             :   ulong          max_page_size; /* 2^21 or 2^30 */
     683             :   ulong          gigantic_page_threshold; /* see [hugetlbfs.gigantic_page_threshold_mib]*/
     684             : };
     685             : typedef struct fd_topo fd_topo_t;
     686             : 
     687             : typedef struct {
     688             :   char const * name;
     689             : 
     690             :   int          keep_host_networking;
     691             :   int          allow_connect;
     692             :   int          allow_renameat;
     693             :   ulong        rlimit_file_cnt;
     694             :   ulong        rlimit_address_space;
     695             :   ulong        rlimit_data;
     696             :   int          for_tpool;
     697             : 
     698             :   ulong (*populate_allowed_seccomp)( fd_topo_t const * topo, fd_topo_tile_t const * tile, ulong out_cnt, struct sock_filter * out );
     699             :   ulong (*populate_allowed_fds    )( fd_topo_t const * topo, fd_topo_tile_t const * tile, ulong out_fds_sz, int * out_fds );
     700             :   ulong (*scratch_align           )( void );
     701             :   ulong (*scratch_footprint       )( fd_topo_tile_t const * tile );
     702             :   ulong (*loose_footprint         )( fd_topo_tile_t const * tile );
     703             :   void  (*privileged_init         )( fd_topo_t * topo, fd_topo_tile_t * tile );
     704             :   void  (*unprivileged_init       )( fd_topo_t * topo, fd_topo_tile_t * tile );
     705             :   void  (*run                     )( fd_topo_t * topo, fd_topo_tile_t * tile );
     706             :   ulong (*rlimit_file_cnt_fn      )( fd_topo_t const * topo, fd_topo_tile_t const * tile );
     707             : } fd_topo_run_tile_t;
     708             : 
     709             : struct fd_topo_obj_callbacks {
     710             :   char const * name;
     711             :   ulong (* footprint )( fd_topo_t const * topo, fd_topo_obj_t const * obj );
     712             :   ulong (* align     )( fd_topo_t const * topo, fd_topo_obj_t const * obj );
     713             :   ulong (* loose     )( fd_topo_t const * topo, fd_topo_obj_t const * obj );
     714             :   void  (* new       )( fd_topo_t const * topo, fd_topo_obj_t const * obj );
     715             : };
     716             : 
     717             : typedef struct fd_topo_obj_callbacks fd_topo_obj_callbacks_t;
     718             : 
     719             : FD_PROTOTYPES_BEGIN
     720             : 
     721             : FD_FN_CONST static inline ulong
     722           0 : fd_topo_workspace_align( void ) {
     723             :   /* This needs to be the max( align ) of all the child members that
     724             :      could be aligned into this workspace, otherwise our footprint
     725             :      calculation will not be correct.  For now just set to 4096 but this
     726             :      should probably be calculated dynamically, or we should reduce
     727             :      those child aligns if we can. */
     728           0 :   return 4096UL;
     729           0 : }
     730             : 
     731             : void *
     732             : fd_topo_obj_laddr( fd_topo_t const * topo,
     733             :                    ulong             obj_id );
     734             : 
     735             : /* Returns a pointer in the local address space to the base address of
     736             :    the workspace out of which the given object was allocated. */
     737             : 
     738             : static inline void *
     739             : fd_topo_obj_wksp_base( fd_topo_t const * topo,
     740           0 :                        ulong             obj_id ) {
     741           0 :   FD_TEST( obj_id<FD_TOPO_MAX_OBJS );
     742           0 :   fd_topo_obj_t const * obj = &topo->objs[ obj_id ];
     743           0 :   FD_TEST( obj->id == obj_id );
     744           0 :   ulong const wksp_id = obj->wksp_id;
     745             : 
     746           0 :   FD_TEST( wksp_id<FD_TOPO_MAX_WKSPS );
     747           0 :   fd_topo_wksp_t const * wksp = &topo->workspaces[ wksp_id ];
     748           0 :   FD_TEST( wksp->id == wksp_id );
     749           0 :   return wksp->wksp;
     750           0 : }
     751             : 
     752             : FD_FN_PURE static inline ulong
     753             : fd_topo_tile_name_cnt( fd_topo_t const * topo,
     754           3 :                        char const *      name ) {
     755           3 :   ulong cnt = 0;
     756           6 :   for( ulong i=0; i<topo->tile_cnt; i++ ) {
     757           3 :     if( FD_UNLIKELY( !strcmp( topo->tiles[ i ].name, name ) ) ) cnt++;
     758           3 :   }
     759           3 :   return cnt;
     760           3 : }
     761             : 
     762             : /* Finds the workspace of a given name in the topology.  Returns
     763             :    ULONG_MAX if there is no such workspace.  There can be at most one
     764             :    workspace of a given name. */
     765             : 
     766             : FD_FN_PURE static inline ulong
     767             : fd_topo_find_wksp( fd_topo_t const * topo,
     768          66 :                    char const *      name ) {
     769          66 :   for( ulong i=0; i<topo->wksp_cnt; i++ ) {
     770          66 :     if( FD_UNLIKELY( !strcmp( topo->workspaces[ i ].name, name ) ) ) return i;
     771          66 :   }
     772           0 :   return ULONG_MAX;
     773          66 : }
     774             : 
     775             : /* Find the tile of a given name and kind_id in the topology, there will
     776             :    be at most one such tile, since kind_id is unique among the name.
     777             :    Returns ULONG_MAX if there is no such tile. */
     778             : 
     779             : FD_FN_PURE static inline ulong
     780             : fd_topo_find_tile( fd_topo_t const * topo,
     781             :                    char const *      name,
     782          21 :                    ulong             kind_id ) {
     783          21 :   for( ulong i=0; i<topo->tile_cnt; i++ ) {
     784          21 :     if( FD_UNLIKELY( !strcmp( topo->tiles[ i ].name, name ) ) && topo->tiles[ i ].kind_id == kind_id ) return i;
     785          21 :   }
     786           0 :   return ULONG_MAX;
     787          21 : }
     788             : 
     789             : /* Find the link of a given name and kind_id in the topology, there will
     790             :    be at most one such link, since kind_id is unique among the name.
     791             :    Returns ULONG_MAX if there is no such link. */
     792             : 
     793             : FD_FN_PURE static inline ulong
     794             : fd_topo_find_link( fd_topo_t const * topo,
     795             :                    char const *      name,
     796          18 :                    ulong             kind_id ) {
     797          39 :   for( ulong i=0; i<topo->link_cnt; i++ ) {
     798          39 :     if( FD_UNLIKELY( !strcmp( topo->links[ i ].name, name ) ) && topo->links[ i ].kind_id == kind_id ) return i;
     799          39 :   }
     800           0 :   return ULONG_MAX;
     801          18 : }
     802             : 
     803             : FD_FN_PURE static inline ulong
     804             : fd_topo_find_tile_in_link( fd_topo_t const *      topo,
     805             :                            fd_topo_tile_t const * tile,
     806             :                            char const *           name,
     807           0 :                            ulong                  kind_id ) {
     808           0 :   for( ulong i=0; i<tile->in_cnt; i++ ) {
     809           0 :     if( FD_UNLIKELY( !strcmp( topo->links[ tile->in_link_id[ i ] ].name, name ) )
     810           0 :         && topo->links[ tile->in_link_id[ i ] ].kind_id == kind_id ) return i;
     811           0 :   }
     812           0 :   return ULONG_MAX;
     813           0 : }
     814             : 
     815             : FD_FN_PURE static inline ulong
     816             : fd_topo_find_tile_out_link( fd_topo_t const *      topo,
     817             :                             fd_topo_tile_t const * tile,
     818             :                             char const *           name,
     819           0 :                             ulong                  kind_id ) {
     820           0 :   for( ulong i=0; i<tile->out_cnt; i++ ) {
     821           0 :     if( FD_UNLIKELY( !strcmp( topo->links[ tile->out_link_id[ i ] ].name, name ) )
     822           0 :         && topo->links[ tile->out_link_id[ i ] ].kind_id == kind_id ) return i;
     823           0 :   }
     824           0 :   return ULONG_MAX;
     825           0 : }
     826             : 
     827             : /* Find the id of the tile which is a producer for the given link.  If
     828             :    no tile is a producer for the link, returns ULONG_MAX.  This should
     829             :    not be possible for a well formed and validated topology.  */
     830             : FD_FN_PURE static inline ulong
     831             : fd_topo_find_link_producer( fd_topo_t const *      topo,
     832           0 :                             fd_topo_link_t const * link ) {
     833           0 :   for( ulong i=0; i<topo->tile_cnt; i++ ) {
     834           0 :     fd_topo_tile_t const * tile = &topo->tiles[ i ];
     835             : 
     836           0 :     for( ulong j=0; j<tile->out_cnt; j++ ) {
     837           0 :       if( FD_UNLIKELY( tile->out_link_id[ j ] == link->id ) ) return i;
     838           0 :     }
     839           0 :   }
     840           0 :   return ULONG_MAX;
     841           0 : }
     842             : 
     843             : /* Given a link, count the number of consumers of that link among all
     844             :    the tiles in the topology. */
     845             : FD_FN_PURE static inline ulong
     846             : fd_topo_link_consumer_cnt( fd_topo_t const *      topo,
     847           0 :                            fd_topo_link_t const * link ) {
     848           0 :   ulong cnt = 0;
     849           0 :   for( ulong i=0; i<topo->tile_cnt; i++ ) {
     850           0 :     fd_topo_tile_t const * tile = &topo->tiles[ i ];
     851           0 :     for( ulong j=0; j<tile->in_cnt; j++ ) {
     852           0 :       if( FD_UNLIKELY( tile->in_link_id[ j ] == link->id ) ) cnt++;
     853           0 :     }
     854           0 :   }
     855             : 
     856           0 :   return cnt;
     857           0 : }
     858             : 
     859             : /* Given a link, count the number of reliable consumers of that link
     860             :    among all the tiles in the topology. */
     861             : FD_FN_PURE static inline ulong
     862             : fd_topo_link_reliable_consumer_cnt( fd_topo_t const *      topo,
     863           0 :                                     fd_topo_link_t const * link ) {
     864           0 :   ulong cnt = 0;
     865           0 :   for( ulong i=0; i<topo->tile_cnt; i++ ) {
     866           0 :     fd_topo_tile_t const * tile = &topo->tiles[ i ];
     867           0 :     for( ulong j=0; j<tile->in_cnt; j++ ) {
     868           0 :       if( FD_UNLIKELY( tile->in_link_id[ j ] == link->id && tile->in_link_reliable[ j ] ) ) cnt++;
     869           0 :     }
     870           0 :   }
     871             : 
     872           0 :   return cnt;
     873           0 : }
     874             : 
     875             : FD_FN_PURE static inline ulong
     876             : fd_topo_tile_consumer_cnt( fd_topo_t const *      topo,
     877           0 :                            fd_topo_tile_t const * tile ) {
     878           0 :   (void)topo;
     879           0 :   return tile->out_cnt;
     880           0 : }
     881             : 
     882             : FD_FN_PURE static inline ulong
     883             : fd_topo_tile_reliable_consumer_cnt( fd_topo_t const *      topo,
     884           0 :                                     fd_topo_tile_t const * tile ) {
     885           0 :   ulong reliable_cons_cnt = 0UL;
     886           0 :   for( ulong i=0UL; i<topo->tile_cnt; i++ ) {
     887           0 :     fd_topo_tile_t const * consumer_tile = &topo->tiles[ i ];
     888           0 :     for( ulong j=0UL; j<consumer_tile->in_cnt; j++ ) {
     889           0 :       for( ulong k=0UL; k<tile->out_cnt; k++ ) {
     890           0 :         if( FD_UNLIKELY( consumer_tile->in_link_id[ j ]==tile->out_link_id[ k ] && consumer_tile->in_link_reliable[ j ] ) ) {
     891           0 :           reliable_cons_cnt++;
     892           0 :         }
     893           0 :       }
     894           0 :     }
     895           0 :   }
     896           0 :   return reliable_cons_cnt;
     897           0 : }
     898             : 
     899             : FD_FN_PURE static inline ulong
     900             : fd_topo_tile_producer_cnt( fd_topo_t const *     topo,
     901           0 :                            fd_topo_tile_t const * tile ) {
     902           0 :   (void)topo;
     903           0 :   ulong in_cnt = 0UL;
     904           0 :   for( ulong i=0UL; i<tile->in_cnt; i++ ) {
     905           0 :     if( FD_UNLIKELY( !tile->in_link_poll[ i ] ) ) continue;
     906           0 :     in_cnt++;
     907           0 :   }
     908           0 :   return in_cnt;
     909           0 : }
     910             : 
     911             : FD_FN_PURE FD_FN_UNUSED static ulong
     912             : fd_topo_obj_cnt( fd_topo_t const * topo,
     913             :                  char const *      obj_type,
     914           0 :                  char const *      label ) {
     915           0 :   ulong cnt = 0UL;
     916           0 :   for( ulong i=0UL; i<topo->obj_cnt; i++ ) {
     917           0 :     fd_topo_obj_t const * obj = &topo->objs[ i ];
     918           0 :     if( strncmp( obj->name, obj_type, sizeof(obj->name) ) ) continue;
     919           0 :     if( label &&
     920           0 :         strncmp( obj->label, label, sizeof(obj->label) ) ) continue;
     921           0 :     cnt++;
     922           0 :   }
     923           0 :   return cnt;
     924           0 : }
     925             : 
     926             : FD_FN_PURE FD_FN_UNUSED static fd_topo_obj_t const *
     927             : fd_topo_find_obj( fd_topo_t const * topo,
     928             :                   char const *      obj_type,
     929             :                   char const *      label,
     930           0 :                   ulong             label_idx ) {
     931           0 :   for( ulong i=0UL; i<topo->obj_cnt; i++ ) {
     932           0 :     fd_topo_obj_t const * obj = &topo->objs[ i ];
     933           0 :     if( strncmp( obj->name, obj_type, sizeof(obj->name) ) ) continue;
     934           0 :     if( label &&
     935           0 :         strncmp( obj->label, label, sizeof(obj->label) ) ) continue;
     936           0 :     if( label_idx != ULONG_MAX && obj->label_idx != label_idx ) continue;
     937           0 :     return obj;
     938           0 :   }
     939           0 :   return NULL;
     940           0 : }
     941             : 
     942             : FD_FN_PURE FD_FN_UNUSED static fd_topo_obj_t const *
     943             : fd_topo_find_tile_obj( fd_topo_t const *      topo,
     944             :                        fd_topo_tile_t const * tile,
     945           0 :                        char const *           obj_type ) {
     946           0 :   for( ulong i=0UL; i<(tile->uses_obj_cnt); i++ ) {
     947           0 :     fd_topo_obj_t const * obj = &topo->objs[ tile->uses_obj_id[ i ] ];
     948           0 :     if( strncmp( obj->name, obj_type, sizeof(obj->name) ) ) continue;
     949           0 :     return obj;
     950           0 :   }
     951           0 :   return NULL;
     952           0 : }
     953             : 
     954             : /* Join (map into the process) all shared memory (huge/gigantic pages)
     955             :    needed by the tile, in the given topology.  All memory associated
     956             :    with the tile (aka. used by links that the tile either produces to or
     957             :    consumes from, or used by the tile itself for its cnc) will be
     958             :    attached (mapped into the process).
     959             : 
     960             :    This is needed to play nicely with the sandbox.  Once a process is
     961             :    sandboxed we can no longer map any memory. */
     962             : void
     963             : fd_topo_join_tile_workspaces( fd_topo_t *      topo,
     964             :                               fd_topo_tile_t * tile,
     965             :                               int              core_dump_level );
     966             : 
     967             : /* Join (map into the process) the shared memory (huge/gigantic pages)
     968             :    for the given workspace.  Mode is one of
     969             :    FD_SHMEM_JOIN_MODE_READ_WRITE or FD_SHMEM_JOIN_MODE_READ_ONLY and
     970             :    determines the prot argument that will be passed to mmap when mapping
     971             :    the pages in (PROT_WRITE or PROT_READ respectively).
     972             : 
     973             :    Dump should be set to 1 if the workspace memory should be dumpable
     974             :    when the process crashes, or 0 if not. */
     975             : void
     976             : fd_topo_join_workspace( fd_topo_t *      topo,
     977             :                         fd_topo_wksp_t * wksp,
     978             :                         int              mode,
     979             :                         int              dump );
     980             : 
     981             : /* Join (map into the process) all shared memory (huge/gigantic pages)
     982             :    needed by all tiles in the topology.  Mode is one of
     983             :    FD_SHMEM_JOIN_MODE_READ_WRITE or FD_SHMEM_JOIN_MODE_READ_ONLY and
     984             :    determines the prot argument that will be passed to mmap when
     985             :    mapping the pages in (PROT_WRITE or PROT_READ respectively). */
     986             : void
     987             : fd_topo_join_workspaces( fd_topo_t *  topo,
     988             :                          int          mode,
     989             :                          int          core_dump_level );
     990             : 
     991             : /* Leave (unmap from the process) the shared memory needed for the
     992             :    given workspace in the topology, if it was previously mapped.
     993             : 
     994             :    topo and wksp are assumed non-NULL.  It is OK if the workspace
     995             :    has not been previously joined, in which case this is a no-op. */
     996             : 
     997             : void
     998             : fd_topo_leave_workspace( fd_topo_t *      topo,
     999             :                          fd_topo_wksp_t * wksp );
    1000             : 
    1001             : /* Leave (unmap from the process) all shared memory needed by all
    1002             :    tiles in the topology, if each of them was mapped.
    1003             : 
    1004             :    topo is assumed non-NULL.  Only workspaces which were previously
    1005             :    joined are unmapped. */
    1006             : 
    1007             : void
    1008             : fd_topo_leave_workspaces( fd_topo_t * topo );
    1009             : 
    1010             : /* Create the given workspace needed by the topology on the system.
    1011             :    This does not "join" the workspaces (map their memory into the
    1012             :    process), but only creates the .wksp file and formats it correctly
    1013             :    as a workspace.
    1014             : 
    1015             :    Returns 0 on success and -1 on failure, with errno set to the error.
    1016             :    The only reason for failure currently that will be returned is
    1017             :    ENOMEM, as other unexpected errors will cause the program to exit.
    1018             : 
    1019             :    If update_existing is 1, the workspace will not be created from
    1020             :    scratch but it will be assumed that it already exists from a prior
    1021             :    run and needs to be maybe resized and then have the header
    1022             :    structures reinitialized.  This can save a very expensive operation
    1023             :    of zeroing all of the workspace pages.  This is dangerous in
    1024             :    production because it can leave stray memory from prior runs around,
    1025             :    and should only be used in development environments. */
    1026             : 
    1027             : int
    1028             : fd_topo_create_workspace( fd_topo_t *      topo,
    1029             :                           fd_topo_wksp_t * wksp,
    1030             :                           int              update_existing );
    1031             : 
    1032             : /* Join the standard IPC objects needed by the topology of this particular
    1033             :    tile */
    1034             : 
    1035             : void
    1036             : fd_topo_fill_tile( fd_topo_t *      topo,
    1037             :                    fd_topo_tile_t * tile );
    1038             : 
    1039             : /* Same as fd_topo_fill_tile but fills in all the objects for a
    1040             :    particular workspace with the given mode. */
    1041             : void
    1042             : fd_topo_workspace_fill( fd_topo_t *      topo,
    1043             :                         fd_topo_wksp_t * wksp );
    1044             : 
    1045             : /* Apply a new function to every object that is resident in the given
    1046             :    workspace in the topology. */
    1047             : 
    1048             : void
    1049             : fd_topo_wksp_new( fd_topo_t const *          topo,
    1050             :                   fd_topo_wksp_t const *     wksp,
    1051             :                   fd_topo_obj_callbacks_t ** callbacks );
    1052             : 
    1053             : /* Same as fd_topo_fill_tile but fills in all tiles in the topology. */
    1054             : 
    1055             : void
    1056             : fd_topo_fill( fd_topo_t * topo );
    1057             : 
    1058             : /* fd_topo_tile_stack_join joins a huge page optimized stack for the
    1059             :    provided tile.  The stack is assumed to already exist at a known
    1060             :    path in the hugetlbfs mount. */
    1061             : 
    1062             : void *
    1063             : fd_topo_tile_stack_join( char const * app_name,
    1064             :                          char const * tile_name,
    1065             :                          ulong        tile_kind_id );
    1066             : 
    1067             : /* fd_topo_run_single_process runs all the tiles in a single process
    1068             :    (the calling process).  This spawns a thread for each tile, switches
    1069             :    that thread to the given UID and GID and then runs the tile in it.
    1070             :    Each thread will never exit, as tiles are expected to run forever.
    1071             :    An error is logged and the application will exit if a tile exits.
    1072             :    The function itself does return after spawning all the threads.
    1073             : 
    1074             :    The threads will not be sandboxed in any way, except switching to the
    1075             :    provided UID and GID, so they will share the same address space, and
    1076             :    not have any seccomp restrictions or use any Linux namespaces.  The
    1077             :    calling thread will also switch to the provided UID and GID before
    1078             :    it returns.
    1079             : 
    1080             :    In production, when running with an Agave child process this is
    1081             :    used for spawning certain tiles inside the Agave address space.
    1082             :    It's also useful for tooling and debugging, but is not how the main
    1083             :    production Firedancer process runs.  For production, each tile is run
    1084             :    in its own address space with a separate process and full security
    1085             :    sandbox.
    1086             : 
    1087             :    The agave argument determines which tiles are started.  If the
    1088             :    argument is 0 or 1, only non-agave (or only agave) tiles are started.
    1089             :    If the argument is any other value, all tiles in the topology are
    1090             :    started regardless of if they are Agave tiles or not. */
    1091             : 
    1092             : void
    1093             : fd_topo_run_single_process( fd_topo_t *       topo,
    1094             :                             int               agave,
    1095             :                             uint              uid,
    1096             :                             uint              gid,
    1097             :                             fd_topo_run_tile_t (* tile_run )( fd_topo_tile_t const * tile ) );
    1098             : 
    1099             : /* fd_topo_run_tile runs the given tile directly within the current
    1100             :    process (and thread).  The function will never return, as tiles are
    1101             :    expected to run forever.  An error is logged and the application will
    1102             :    exit if the tile exits.
    1103             : 
    1104             :    The sandbox argument determines if the current process will be
    1105             :    sandboxed fully before starting the tile.  The thread will switch to
    1106             :    the UID and GID provided before starting the tile, even if the thread
    1107             :    is not being sandboxed.  Although POSIX specifies that all threads in
    1108             :    a process must share a UID and GID, this is not the case on Linux.
    1109             :    The thread will switch to the provided UID and GID without switching
    1110             :    the other threads in the process.
    1111             : 
    1112             :    If keep_controlling_terminal is set to 0, and the sandbox is enabled
    1113             :    the controlling terminal will be detached as an additional sandbox
    1114             :    measure, but you will not be able to send Ctrl+C or other signals
    1115             :    from the terminal.  See fd_sandbox.h for more information.
    1116             : 
    1117             :    The allow_fd argument is only used if sandbox is true, and is a file
    1118             :    descriptor which will be allowed to exist in the process.  Normally
    1119             :    the sandbox code rejects and aborts if there is an unexpected file
    1120             :    descriptor present on boot.  This is helpful to allow a parent
    1121             :    process to be notified on termination of the tile by waiting for a
    1122             :    pipe file descriptor to get closed.
    1123             : 
    1124             :    wait and debugger are both used in debugging.  If wait is non-NULL,
    1125             :    the runner will wait until the value pointed to by wait is non-zero
    1126             :    before launching the tile.  Likewise, if debugger is non-NULL, the
    1127             :    runner will wait until a debugger is attached before setting the
    1128             :    value pointed to by debugger to non-zero.  These are intended to be
    1129             :    used as a pair, where many tiles share a waiting reference, and then
    1130             :    one of the tiles (a tile you want to attach the debugger to) has the
    1131             :    same reference provided as the debugger, so all tiles will stop and
    1132             :    wait for the debugger to attach to it before proceeding. */
    1133             : 
    1134             : void
    1135             : fd_topo_run_tile( fd_topo_t *          topo,
    1136             :                   fd_topo_tile_t *     tile,
    1137             :                   int                  sandbox,
    1138             :                   int                  keep_controlling_terminal,
    1139             :                   int                  dumpable,
    1140             :                   uint                 uid,
    1141             :                   uint                 gid,
    1142             :                   int                  allow_fd,
    1143             :                   volatile int *       wait,
    1144             :                   volatile int *       debugger,
    1145             :                   fd_topo_run_tile_t * tile_run );
    1146             : 
    1147             : /* This is for determining the value of RLIMIT_MLOCK that we need to
    1148             :    successfully run all tiles in separate processes.  The value returned
    1149             :    is the maximum amount of memory that will be locked with mlock() by
    1150             :    any individual process in the tree.  Specifically, if we have three
    1151             :    tile processes, and they each need to lock 5, 9, and 2 MiB of memory
    1152             :    respectively, RLIMIT_MLOCK needs to be 9 MiB to allow all three
    1153             :    process mlock() calls to succeed.
    1154             : 
    1155             :    Tiles lock memory in three ways.  Any workspace they are using, they
    1156             :    lock the entire workspace.  Then each tile uses huge pages for the
    1157             :    stack which are also locked, and finally some tiles use private
    1158             :    locked mmaps outside the workspace for storing key material.  The
    1159             :    results here include all of this memory together.
    1160             : 
    1161             :    The result is not necessarily the amount of memory used by the tile
    1162             :    process, although it will be quite close.  Tiles could potentially
    1163             :    allocate memory (eg, with brk) without needing to lock it, which
    1164             :    would not need to included, and some kernel memory that tiles cause
    1165             :    to be allocated (for example XSK buffers) is also not included.  The
    1166             :    actual amount of memory used will not be less than this value. */
    1167             : FD_FN_PURE ulong
    1168             : fd_topo_mlock_max_tile( fd_topo_t const * topo );
    1169             : 
    1170             : /* Same as fd_topo_mlock_max_tile, but for loading the entire topology
    1171             :    into one process, rather than a separate process per tile.  This is
    1172             :    used, for example, by the configuration code when it creates all the
    1173             :    workspaces, or the monitor that maps the entire system into one
    1174             :    address space. */
    1175             : FD_FN_PURE ulong
    1176             : fd_topo_mlock( fd_topo_t const * topo );
    1177             : 
    1178             : /* This returns the number of gigantic pages needed by the topology on
    1179             :    the provided numa node.  It includes pages needed by the workspaces,
    1180             :    as well as additional allocations like huge pages for process stacks
    1181             :    and private key storage. */
    1182             : 
    1183             : FD_FN_PURE ulong
    1184             : fd_topo_gigantic_page_cnt( fd_topo_t const * topo,
    1185             :                            ulong             numa_idx );
    1186             : 
    1187             : /* This returns the number of huge pages in the application needed by
    1188             :    the topology on the provided numa node.  It includes pages needed by
    1189             :    things placed in the hugetlbfs (workspaces, process stacks).  If
    1190             :    include_anonymous is true, it also includes anonymous hugepages which
    1191             :    are needed but are not placed in the hugetlbfs. */
    1192             : 
    1193             : FD_FN_PURE ulong
    1194             : fd_topo_huge_page_cnt( fd_topo_t const * topo,
    1195             :                        ulong             numa_idx,
    1196             :                        int               include_anonymous );
    1197             : 
    1198             : /* Prints a message describing the topology to an output stream.  If
    1199             :    stdout is true, will be written to stdout, otherwise will be written
    1200             :    as a NOTICE log message to the log file. */
    1201             : void
    1202             : fd_topo_print_log( int         stdout,
    1203             :                    fd_topo_t * topo );
    1204             : 
    1205             : FD_PROTOTYPES_END
    1206             : 
    1207             : #endif /* HEADER_fd_src_disco_topo_fd_topo_h */

Generated by: LCOV version 1.14