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 0 : #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[ 14UL ]; /* 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[ 14UL ]; /* The name of this link, like "pack_execle". 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 txsend_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 : 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. */
130 : int is_agave; /* If the tile needs to run in the Agave (Anza) address space or not. */
131 : int allow_shutdown; /* If the tile is allowed to shutdown gracefully. If false, when the tile exits it will tear down the entire application. */
132 :
133 : 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. */
134 :
135 : ulong in_cnt; /* The number of links that this tile reads from. */
136 : 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). */
137 : 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). */
138 : 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).
139 : If the link is not polled, the tile will not receive frags for it and the tile writer is responsible for
140 : reading from the link. The link must be marked as unreliable as it is not flow controlled. */
141 :
142 : ulong out_cnt; /* The number of links that this tile writes to. */
143 : 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). */
144 :
145 : ulong tile_obj_id;
146 : ulong metrics_obj_id;
147 : ulong id_keyswitch_obj_id; /* keyswitch object id for identity key updates */
148 : ulong av_keyswitch_obj_id; /* keyswitch object id for authority key updates */
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 : fd_hash_t wait_for_supermajority_with_bank_hash;
241 :
242 : struct {
243 : ushort gossip;
244 : ushort tvu;
245 : ushort tvu_quic;
246 : ushort tpu;
247 : ushort tpu_quic;
248 : ushort repair;
249 : } ports;
250 : } gossip;
251 :
252 : struct {
253 : uint out_depth;
254 : uint reasm_cnt;
255 : ulong max_concurrent_connections;
256 : ulong max_concurrent_handshakes;
257 : ushort quic_transaction_listen_port;
258 : long idle_timeout_millis;
259 : uint ack_delay_millis;
260 : int retry;
261 : char key_log_path[ PATH_MAX ];
262 : } quic;
263 :
264 : struct {
265 : ulong tcache_depth;
266 : } verify;
267 :
268 : struct {
269 : ulong tcache_depth;
270 : } dedup;
271 :
272 : struct {
273 : char url[ 256 ];
274 : ulong url_len;
275 : char sni[ 256 ];
276 : ulong sni_len;
277 : char identity_key_path[ PATH_MAX ];
278 : char key_log_path[ PATH_MAX ];
279 : ulong buf_sz;
280 : ulong out_depth;
281 : ulong ssl_heap_sz;
282 : ulong keepalive_interval_nanos;
283 : uchar tls_cert_verify : 1;
284 : } bundle;
285 :
286 : struct {
287 : char url[ 256 ];
288 : char identity_key_path[ PATH_MAX ];
289 : } event;
290 :
291 : struct {
292 : ulong max_pending_transactions;
293 : ulong execle_tile_count;
294 : int larger_max_cost_per_block;
295 : int larger_shred_limits_per_block;
296 : int use_consumed_cus;
297 : int schedule_strategy;
298 : struct {
299 : int enabled;
300 : uchar tip_distribution_program_addr[ 32 ];
301 : uchar tip_payment_program_addr[ 32 ];
302 : uchar tip_distribution_authority[ 32 ];
303 : ulong commission_bps;
304 : char identity_key_path[ PATH_MAX ];
305 : char vote_account_path[ PATH_MAX ]; /* or pubkey is okay */
306 : } bundle;
307 : } pack;
308 :
309 : struct {
310 : int lagged_consecutive_leader_start;
311 : int plugins_enabled;
312 : ulong execle_cnt;
313 : char identity_key_path[ PATH_MAX ];
314 : struct {
315 : int enabled;
316 : uchar tip_payment_program_addr[ 32 ];
317 : uchar tip_distribution_program_addr[ 32 ];
318 : char vote_account_path[ PATH_MAX ];
319 : } bundle;
320 : } pohh;
321 :
322 : struct {
323 : ulong execle_cnt;
324 : char identity_key_path[ PATH_MAX ];
325 : } poh;
326 :
327 : struct {
328 : ulong depth;
329 : ulong fec_resolver_depth;
330 : char identity_key_path[ PATH_MAX ];
331 : ushort shred_listen_port;
332 : int larger_shred_limits_per_block;
333 : ushort expected_shred_version;
334 : ulong adtl_dests_retransmit_cnt;
335 : fd_topo_ip_port_t adtl_dests_retransmit[ FD_TOPO_ADTL_DESTS_MAX ];
336 : ulong adtl_dests_leader_cnt;
337 : fd_topo_ip_port_t adtl_dests_leader[ FD_TOPO_ADTL_DESTS_MAX ];
338 : } shred;
339 :
340 : struct {
341 : ulong disable_blockstore_from_slot;
342 : } store;
343 :
344 : struct {
345 : char identity_key_path[ PATH_MAX ];
346 : ulong authorized_voter_paths_cnt;
347 : char authorized_voter_paths[ 16 ][ PATH_MAX ];
348 : } sign;
349 :
350 : struct {
351 : uint listen_addr;
352 : ushort listen_port;
353 :
354 : int is_voting;
355 :
356 : char cluster[ 32 ];
357 : char identity_key_path[ PATH_MAX ];
358 : char vote_key_path[ PATH_MAX ];
359 :
360 : ulong max_http_connections;
361 : ulong max_websocket_connections;
362 : ulong max_http_request_length;
363 : ulong send_buffer_size_mb;
364 : int schedule_strategy;
365 :
366 : int websocket_compression;
367 : int frontend_release_channel;
368 : ulong tile_cnt;
369 : } gui;
370 :
371 : struct {
372 : uint listen_addr;
373 : ushort listen_port;
374 :
375 : ulong max_http_connections;
376 : ulong send_buffer_size_mb;
377 : ulong max_http_request_length;
378 :
379 : ulong max_live_slots;
380 : ulong accdb_max_depth;
381 :
382 : char identity_key_path[ PATH_MAX ];
383 : int delay_startup;
384 : } rpc;
385 :
386 : struct {
387 : uint prometheus_listen_addr;
388 : ushort prometheus_listen_port;
389 : } metric;
390 :
391 : struct {
392 : ulong fec_max;
393 :
394 : ulong txncache_obj_id;
395 :
396 : char shred_cap[ PATH_MAX ];
397 :
398 : char identity_key_path[ PATH_MAX ];
399 : uint ip_addr;
400 : char vote_account_path[ PATH_MAX ];
401 :
402 : fd_hash_t wait_for_supermajority_with_bank_hash;
403 : ushort expected_shred_version;
404 : int wait_for_vote_to_start_leader;
405 :
406 : ulong heap_size_gib;
407 : ulong sched_depth;
408 : ulong max_live_slots;
409 : ulong write_delay_slots;
410 :
411 : /* not specified in TOML */
412 :
413 : ulong enable_features_cnt;
414 : char enable_features[ 16 ][ FD_BASE58_ENCODED_32_SZ ];
415 :
416 : char genesis_path[ PATH_MAX ];
417 :
418 : int larger_max_cost_per_block;
419 :
420 : ulong capture_start_slot;
421 : char solcap_capture[ PATH_MAX ];
422 : char dump_proto_dir[ PATH_MAX ];
423 : int dump_block_to_pb;
424 :
425 : struct {
426 : int enabled;
427 : uchar tip_payment_program_addr[ 32 ];
428 : uchar tip_distribution_program_addr[ 32 ];
429 : char vote_account_path[ PATH_MAX ];
430 : } bundle;
431 :
432 : } replay;
433 :
434 : struct {
435 : ulong txncache_obj_id;
436 : ulong acc_pool_obj_id;
437 :
438 : ulong max_live_slots;
439 : ulong accdb_max_depth;
440 :
441 : ulong capture_start_slot;
442 : char solcap_capture[ PATH_MAX ];
443 : char dump_proto_dir[ PATH_MAX ];
444 : char dump_syscall_name_filter[ PATH_MAX ];
445 : char dump_instr_program_id_filter[ FD_BASE58_ENCODED_32_SZ ];
446 : int dump_instr_to_pb;
447 : int dump_txn_to_pb;
448 : int dump_txn_as_fixture;
449 : int dump_syscall_to_pb;
450 : } execrp;
451 :
452 : struct {
453 : ushort send_to_port;
454 : uint send_to_ip_addr;
455 : ulong conn_cnt;
456 : int no_quic;
457 : } benchs;
458 :
459 : struct {
460 : ushort rpc_port;
461 : uint rpc_ip_addr;
462 : } bencho;
463 :
464 : struct {
465 : ulong accounts_cnt;
466 : int mode;
467 : float contending_fraction;
468 : float cu_price_spread;
469 : } benchg;
470 :
471 : struct {
472 : ushort repair_intake_listen_port;
473 : ushort repair_serve_listen_port;
474 : char identity_key_path[ PATH_MAX ];
475 : ulong max_pending_shred_sets;
476 : ulong slot_max;
477 :
478 : /* non-config */
479 :
480 : ulong repair_sign_depth;
481 : ulong repair_sign_cnt;
482 :
483 : ulong end_slot; /* repair profiler mode only */
484 : } repair;
485 :
486 : struct {
487 : ushort txsend_src_port;
488 :
489 : /* non-config */
490 :
491 : uint ip_addr;
492 : char identity_key_path[ PATH_MAX ];
493 : } txsend;
494 :
495 : struct {
496 : uint fake_dst_ip;
497 : } pktgen;
498 :
499 : struct {
500 : ulong end_slot;
501 : char rocksdb_path[ PATH_MAX ];
502 : char ingest_mode[ 32 ];
503 :
504 : /* Set internally by the archiver tile */
505 : int archive_fd;
506 : } archiver;
507 :
508 : struct {
509 : int ingest_dead_slots;
510 : ulong root_distance;
511 : ulong end_slot;
512 : char rocksdb_path[ PATH_MAX ];
513 : char shredcap_path[ PATH_MAX ];
514 : } backtest;
515 :
516 : struct {
517 : ulong authorized_voter_paths_cnt;
518 : char authorized_voter_paths[ 16 ][ PATH_MAX ];
519 : int hard_fork_fatal;
520 : ulong max_live_slots;
521 : ulong accdb_max_depth;
522 : char identity_key[ PATH_MAX ];
523 : char vote_account[ PATH_MAX ];
524 : char base_path[PATH_MAX];
525 : } tower;
526 :
527 : struct {
528 : char folder_path[ PATH_MAX ];
529 : ushort repair_intake_listen_port;
530 : ulong write_buffer_size; /* Size of the write buffer for the capture tile */
531 : int enable_publish_stake_weights;
532 : char manifest_path[ PATH_MAX ];
533 :
534 : /* Set internally by the capture tile */
535 : int shreds_fd;
536 : int requests_fd;
537 : int fecs_fd;
538 : int peers_fd;
539 : int bank_hashes_fd;
540 : int slices_fd;
541 : } shredcap;
542 :
543 : #define FD_TOPO_SNAPSHOTS_GOSSIP_LIST_MAX (32UL)
544 0 : #define FD_TOPO_SNAPSHOTS_SERVERS_MAX (16UL)
545 0 : #define FD_TOPO_MAX_RESOLVED_ADDRS ( 4UL)
546 0 : #define FD_TOPO_SNAPSHOTS_SERVERS_MAX_RESOLVED (FD_TOPO_MAX_RESOLVED_ADDRS*FD_TOPO_SNAPSHOTS_SERVERS_MAX)
547 :
548 : struct fd_topo_tile_snapct {
549 : char snapshots_path[ PATH_MAX ];
550 :
551 : struct {
552 : uint max_local_full_effective_age;
553 : uint max_local_incremental_age;
554 :
555 : struct {
556 : int allow_any;
557 : ulong allow_list_cnt;
558 : fd_pubkey_t allow_list[ FD_TOPO_SNAPSHOTS_GOSSIP_LIST_MAX ];
559 : ulong block_list_cnt;
560 : fd_pubkey_t block_list[ FD_TOPO_SNAPSHOTS_GOSSIP_LIST_MAX ];
561 : } gossip;
562 :
563 : ulong servers_cnt;
564 : struct {
565 : fd_ip4_port_t addr;
566 : char hostname[ 256UL ];
567 : int is_https;
568 : } servers[ FD_TOPO_SNAPSHOTS_SERVERS_MAX_RESOLVED ];
569 : } sources;
570 :
571 : int incremental_snapshots;
572 : uint max_full_snapshots_to_keep;
573 : uint max_incremental_snapshots_to_keep;
574 : uint max_retry_abort;
575 : } snapct;
576 :
577 : struct {
578 : char snapshots_path[ PATH_MAX ];
579 : int incremental_snapshots;
580 : uint min_download_speed_mibs;
581 : } snapld;
582 :
583 : struct {
584 : ulong max_live_slots;
585 : ulong accdb_max_depth;
586 : ulong funk_obj_id;
587 : ulong funk_locks_obj_id;
588 : ulong txncache_obj_id;
589 :
590 : uint lthash_disabled : 1;
591 : uint use_vinyl : 1;
592 : } snapin;
593 :
594 : struct {
595 : ulong vinyl_meta_map_obj_id;
596 : ulong vinyl_meta_pool_obj_id;
597 : ulong snapwr_depth;
598 : char vinyl_path[ PATH_MAX ];
599 : uint lthash_disabled : 1;
600 : ulong max_accounts;
601 : } snapwm;
602 :
603 : struct {
604 : ulong dcache_obj_id;
605 : char vinyl_path[ PATH_MAX ];
606 : uint lthash_disabled : 1;
607 : } snapwr;
608 :
609 : struct {
610 : ulong dcache_obj_id;
611 : int io_uring_enabled;
612 : char vinyl_path[ PATH_MAX ];
613 : } snaplh;
614 :
615 : struct {
616 :
617 : uint bind_address;
618 : ushort bind_port;
619 :
620 : ushort expected_shred_version;
621 : ulong entrypoints_cnt;
622 : fd_ip4_port_t entrypoints[ FD_TOPO_GOSSIP_ENTRYPOINTS_MAX ];
623 : } ipecho;
624 :
625 : struct {
626 : ulong max_live_slots;
627 : ulong accdb_max_depth;
628 : ulong txncache_obj_id;
629 : ulong acc_pool_obj_id;
630 : } execle;
631 :
632 : struct {
633 : int validate_genesis_hash;
634 : int allow_download;
635 :
636 : ushort expected_shred_version;
637 : ulong entrypoints_cnt;
638 : fd_ip4_port_t entrypoints[ FD_TOPO_GOSSIP_ENTRYPOINTS_MAX ];
639 :
640 : int has_expected_genesis_hash;
641 : uchar expected_genesis_hash[ 32UL ];
642 :
643 : char genesis_path[ PATH_MAX ];
644 :
645 : uint target_gid;
646 : uint target_uid;
647 :
648 : ulong accdb_max_depth;
649 : } genesi;
650 :
651 : struct {
652 : ulong meta_map_obj_id;
653 : ulong meta_pool_obj_id;
654 : ulong line_max;
655 : ulong data_obj_id;
656 : char bstream_path[ PATH_MAX ];
657 : ulong pair_cnt_limit;
658 :
659 : int io_type; /* FD_VINYL_IO_TYPE_* */
660 : uint uring_depth;
661 : } accdb;
662 :
663 : struct {
664 : ulong capture_start_slot;
665 : char solcap_capture[ PATH_MAX ];
666 : int recent_only;
667 : ulong recent_slots_per_file;
668 : } solcap;
669 :
670 : struct {
671 : ulong accdb_max_depth;
672 : } resolv;
673 : };
674 : };
675 :
676 : typedef struct fd_topo_tile fd_topo_tile_t;
677 :
678 : typedef struct {
679 : ulong id;
680 : char name[ 13UL ]; /* object type */
681 : ulong wksp_id;
682 :
683 : /* Optional label for object */
684 : char label[ 13UL ]; /* object label */
685 : ulong label_idx; /* index of object for this label (ULONG_MAX if not labelled) */
686 :
687 : ulong offset;
688 : ulong footprint;
689 : } fd_topo_obj_t;
690 :
691 : /* An fd_topo_t represents the overall structure of a Firedancer
692 : configuration, describing all the workspaces, tiles, and links
693 : between them. */
694 : struct fd_topo {
695 : char app_name[ 256UL ];
696 : uchar props[ 16384UL ];
697 :
698 : ulong wksp_cnt;
699 : ulong link_cnt;
700 : ulong tile_cnt;
701 : ulong obj_cnt;
702 :
703 : fd_topo_wksp_t workspaces[ FD_TOPO_MAX_WKSPS ];
704 : fd_topo_link_t links[ FD_TOPO_MAX_LINKS ];
705 : fd_topo_tile_t tiles[ FD_TOPO_MAX_TILES ];
706 : fd_topo_obj_t objs[ FD_TOPO_MAX_OBJS ];
707 :
708 : ulong agave_affinity_cnt;
709 : ulong agave_affinity_cpu_idx[ FD_TILE_MAX ];
710 : ulong blocklist_cores_cnt;
711 : ulong blocklist_cores_cpu_idx[ FD_TILE_MAX ];
712 :
713 : ulong max_page_size; /* 2^21 or 2^30 */
714 : ulong gigantic_page_threshold; /* see [hugetlbfs.gigantic_page_threshold_mib]*/
715 : };
716 : typedef struct fd_topo fd_topo_t;
717 :
718 : typedef struct {
719 : char const * name;
720 :
721 : int keep_host_networking;
722 : int allow_connect;
723 : int allow_renameat;
724 : ulong rlimit_file_cnt;
725 : ulong rlimit_address_space;
726 : ulong rlimit_data;
727 : ulong rlimit_nproc;
728 : int for_tpool;
729 :
730 : ulong (*populate_allowed_seccomp)( fd_topo_t const * topo, fd_topo_tile_t const * tile, ulong out_cnt, struct sock_filter * out );
731 : ulong (*populate_allowed_fds )( fd_topo_t const * topo, fd_topo_tile_t const * tile, ulong out_fds_sz, int * out_fds );
732 : ulong (*scratch_align )( void );
733 : ulong (*scratch_footprint )( fd_topo_tile_t const * tile );
734 : ulong (*loose_footprint )( fd_topo_tile_t const * tile );
735 : void (*privileged_init )( fd_topo_t * topo, fd_topo_tile_t * tile );
736 : void (*unprivileged_init )( fd_topo_t * topo, fd_topo_tile_t * tile );
737 : void (*run )( fd_topo_t * topo, fd_topo_tile_t * tile );
738 : ulong (*rlimit_file_cnt_fn )( fd_topo_t const * topo, fd_topo_tile_t const * tile );
739 : } fd_topo_run_tile_t;
740 :
741 : struct fd_topo_obj_callbacks {
742 : char const * name;
743 : ulong (* footprint )( fd_topo_t const * topo, fd_topo_obj_t const * obj );
744 : ulong (* align )( fd_topo_t const * topo, fd_topo_obj_t const * obj );
745 : ulong (* loose )( fd_topo_t const * topo, fd_topo_obj_t const * obj );
746 : void (* new )( fd_topo_t const * topo, fd_topo_obj_t const * obj );
747 : };
748 :
749 : typedef struct fd_topo_obj_callbacks fd_topo_obj_callbacks_t;
750 :
751 : FD_PROTOTYPES_BEGIN
752 :
753 : FD_FN_CONST static inline ulong
754 0 : fd_topo_workspace_align( void ) {
755 : /* This needs to be the max( align ) of all the child members that
756 : could be aligned into this workspace, otherwise our footprint
757 : calculation will not be correct. For now just set to 4096 but this
758 : should probably be calculated dynamically, or we should reduce
759 : those child aligns if we can. */
760 0 : return 4096UL;
761 0 : }
762 :
763 : void *
764 : fd_topo_obj_laddr( fd_topo_t const * topo,
765 : ulong obj_id );
766 :
767 : /* Returns a pointer in the local address space to the base address of
768 : the workspace out of which the given object was allocated. */
769 :
770 : static inline void *
771 : fd_topo_obj_wksp_base( fd_topo_t const * topo,
772 0 : ulong obj_id ) {
773 0 : FD_TEST( obj_id<FD_TOPO_MAX_OBJS );
774 0 : fd_topo_obj_t const * obj = &topo->objs[ obj_id ];
775 0 : FD_TEST( obj->id == obj_id );
776 0 : ulong const wksp_id = obj->wksp_id;
777 :
778 0 : FD_TEST( wksp_id<FD_TOPO_MAX_WKSPS );
779 0 : fd_topo_wksp_t const * wksp = &topo->workspaces[ wksp_id ];
780 0 : FD_TEST( wksp->id == wksp_id );
781 0 : return wksp->wksp;
782 0 : }
783 :
784 : FD_FN_PURE static inline ulong
785 : fd_topo_tile_name_cnt( fd_topo_t const * topo,
786 0 : char const * name ) {
787 0 : ulong cnt = 0;
788 0 : for( ulong i=0; i<topo->tile_cnt; i++ ) {
789 0 : if( FD_UNLIKELY( !strcmp( topo->tiles[ i ].name, name ) ) ) cnt++;
790 0 : }
791 0 : return cnt;
792 0 : }
793 :
794 : /* Finds the workspace of a given name in the topology. Returns
795 : ULONG_MAX if there is no such workspace. There can be at most one
796 : workspace of a given name. */
797 :
798 : FD_FN_PURE static inline ulong
799 : fd_topo_find_wksp( fd_topo_t const * topo,
800 0 : char const * name ) {
801 0 : for( ulong i=0; i<topo->wksp_cnt; i++ ) {
802 0 : if( FD_UNLIKELY( !strcmp( topo->workspaces[ i ].name, name ) ) ) return i;
803 0 : }
804 0 : return ULONG_MAX;
805 0 : }
806 :
807 : /* Find the tile of a given name and kind_id in the topology, there will
808 : be at most one such tile, since kind_id is unique among the name.
809 : Returns ULONG_MAX if there is no such tile. */
810 :
811 : FD_FN_PURE static inline ulong
812 : fd_topo_find_tile( fd_topo_t const * topo,
813 : char const * name,
814 0 : ulong kind_id ) {
815 0 : for( ulong i=0; i<topo->tile_cnt; i++ ) {
816 0 : if( FD_UNLIKELY( !strcmp( topo->tiles[ i ].name, name ) ) && topo->tiles[ i ].kind_id == kind_id ) return i;
817 0 : }
818 0 : return ULONG_MAX;
819 0 : }
820 :
821 : /* Find the link of a given name and kind_id in the topology, there will
822 : be at most one such link, since kind_id is unique among the name.
823 : Returns ULONG_MAX if there is no such link. */
824 :
825 : FD_FN_PURE static inline ulong
826 : fd_topo_find_link( fd_topo_t const * topo,
827 : char const * name,
828 0 : ulong kind_id ) {
829 0 : for( ulong i=0; i<topo->link_cnt; i++ ) {
830 0 : if( FD_UNLIKELY( !strcmp( topo->links[ i ].name, name ) ) && topo->links[ i ].kind_id == kind_id ) return i;
831 0 : }
832 0 : return ULONG_MAX;
833 0 : }
834 :
835 : FD_FN_PURE static inline ulong
836 : fd_topo_find_tile_in_link( fd_topo_t const * topo,
837 : fd_topo_tile_t const * tile,
838 : char const * name,
839 0 : ulong kind_id ) {
840 0 : for( ulong i=0; i<tile->in_cnt; i++ ) {
841 0 : if( FD_UNLIKELY( !strcmp( topo->links[ tile->in_link_id[ i ] ].name, name ) )
842 0 : && topo->links[ tile->in_link_id[ i ] ].kind_id == kind_id ) return i;
843 0 : }
844 0 : return ULONG_MAX;
845 0 : }
846 :
847 : FD_FN_PURE static inline ulong
848 : fd_topo_find_tile_out_link( fd_topo_t const * topo,
849 : fd_topo_tile_t const * tile,
850 : char const * name,
851 0 : ulong kind_id ) {
852 0 : for( ulong i=0; i<tile->out_cnt; i++ ) {
853 0 : if( FD_UNLIKELY( !strcmp( topo->links[ tile->out_link_id[ i ] ].name, name ) )
854 0 : && topo->links[ tile->out_link_id[ i ] ].kind_id == kind_id ) return i;
855 0 : }
856 0 : return ULONG_MAX;
857 0 : }
858 :
859 : /* Find the id of the tile which is a producer for the given link. If
860 : no tile is a producer for the link, returns ULONG_MAX. This should
861 : not be possible for a well formed and validated topology. */
862 : FD_FN_PURE static inline ulong
863 : fd_topo_find_link_producer( fd_topo_t const * topo,
864 0 : fd_topo_link_t const * link ) {
865 0 : for( ulong i=0; i<topo->tile_cnt; i++ ) {
866 0 : fd_topo_tile_t const * tile = &topo->tiles[ i ];
867 :
868 0 : for( ulong j=0; j<tile->out_cnt; j++ ) {
869 0 : if( FD_UNLIKELY( tile->out_link_id[ j ] == link->id ) ) return i;
870 0 : }
871 0 : }
872 0 : return ULONG_MAX;
873 0 : }
874 :
875 : /* Given a link, count the number of consumers of that link among all
876 : the tiles in the topology. */
877 : FD_FN_PURE static inline ulong
878 : fd_topo_link_consumer_cnt( fd_topo_t const * topo,
879 0 : fd_topo_link_t const * link ) {
880 0 : ulong cnt = 0;
881 0 : for( ulong i=0; i<topo->tile_cnt; i++ ) {
882 0 : fd_topo_tile_t const * tile = &topo->tiles[ i ];
883 0 : for( ulong j=0; j<tile->in_cnt; j++ ) {
884 0 : if( FD_UNLIKELY( tile->in_link_id[ j ] == link->id ) ) cnt++;
885 0 : }
886 0 : }
887 :
888 0 : return cnt;
889 0 : }
890 :
891 : /* Given a link, count the number of reliable consumers of that link
892 : among all the tiles in the topology. */
893 : FD_FN_PURE static inline ulong
894 : fd_topo_link_reliable_consumer_cnt( fd_topo_t const * topo,
895 0 : fd_topo_link_t const * link ) {
896 0 : ulong cnt = 0;
897 0 : for( ulong i=0; i<topo->tile_cnt; i++ ) {
898 0 : fd_topo_tile_t const * tile = &topo->tiles[ i ];
899 0 : for( ulong j=0; j<tile->in_cnt; j++ ) {
900 0 : if( FD_UNLIKELY( tile->in_link_id[ j ] == link->id && tile->in_link_reliable[ j ] ) ) cnt++;
901 0 : }
902 0 : }
903 :
904 0 : return cnt;
905 0 : }
906 :
907 : FD_FN_PURE static inline ulong
908 : fd_topo_tile_consumer_cnt( fd_topo_t const * topo,
909 0 : fd_topo_tile_t const * tile ) {
910 0 : (void)topo;
911 0 : return tile->out_cnt;
912 0 : }
913 :
914 : FD_FN_PURE static inline ulong
915 : fd_topo_tile_reliable_consumer_cnt( fd_topo_t const * topo,
916 0 : fd_topo_tile_t const * tile ) {
917 0 : ulong reliable_cons_cnt = 0UL;
918 0 : for( ulong i=0UL; i<topo->tile_cnt; i++ ) {
919 0 : fd_topo_tile_t const * consumer_tile = &topo->tiles[ i ];
920 0 : for( ulong j=0UL; j<consumer_tile->in_cnt; j++ ) {
921 0 : for( ulong k=0UL; k<tile->out_cnt; k++ ) {
922 0 : if( FD_UNLIKELY( consumer_tile->in_link_id[ j ]==tile->out_link_id[ k ] && consumer_tile->in_link_reliable[ j ] ) ) {
923 0 : reliable_cons_cnt++;
924 0 : }
925 0 : }
926 0 : }
927 0 : }
928 0 : return reliable_cons_cnt;
929 0 : }
930 :
931 : FD_FN_PURE static inline ulong
932 : fd_topo_tile_producer_cnt( fd_topo_t const * topo,
933 0 : fd_topo_tile_t const * tile ) {
934 0 : (void)topo;
935 0 : ulong in_cnt = 0UL;
936 0 : for( ulong i=0UL; i<tile->in_cnt; i++ ) {
937 0 : if( FD_UNLIKELY( !tile->in_link_poll[ i ] ) ) continue;
938 0 : in_cnt++;
939 0 : }
940 0 : return in_cnt;
941 0 : }
942 :
943 : FD_FN_PURE FD_FN_UNUSED static ulong
944 : fd_topo_obj_cnt( fd_topo_t const * topo,
945 : char const * obj_type,
946 0 : char const * label ) {
947 0 : ulong cnt = 0UL;
948 0 : for( ulong i=0UL; i<topo->obj_cnt; i++ ) {
949 0 : fd_topo_obj_t const * obj = &topo->objs[ i ];
950 0 : if( strncmp( obj->name, obj_type, sizeof(obj->name) ) ) continue;
951 0 : if( label &&
952 0 : strncmp( obj->label, label, sizeof(obj->label) ) ) continue;
953 0 : cnt++;
954 0 : }
955 0 : return cnt;
956 0 : }
957 :
958 : FD_FN_PURE FD_FN_UNUSED static fd_topo_obj_t const *
959 : fd_topo_find_obj( fd_topo_t const * topo,
960 : char const * obj_type,
961 : char const * label,
962 0 : ulong label_idx ) {
963 0 : for( ulong i=0UL; i<topo->obj_cnt; i++ ) {
964 0 : fd_topo_obj_t const * obj = &topo->objs[ i ];
965 0 : if( strncmp( obj->name, obj_type, sizeof(obj->name) ) ) continue;
966 0 : if( label &&
967 0 : strncmp( obj->label, label, sizeof(obj->label) ) ) continue;
968 0 : if( label_idx != ULONG_MAX && obj->label_idx != label_idx ) continue;
969 0 : return obj;
970 0 : }
971 0 : return NULL;
972 0 : }
973 :
974 : FD_FN_PURE FD_FN_UNUSED static fd_topo_obj_t const *
975 : fd_topo_find_tile_obj( fd_topo_t const * topo,
976 : fd_topo_tile_t const * tile,
977 0 : char const * obj_type ) {
978 0 : for( ulong i=0UL; i<(tile->uses_obj_cnt); i++ ) {
979 0 : fd_topo_obj_t const * obj = &topo->objs[ tile->uses_obj_id[ i ] ];
980 0 : if( strncmp( obj->name, obj_type, sizeof(obj->name) ) ) continue;
981 0 : return obj;
982 0 : }
983 0 : return NULL;
984 0 : }
985 :
986 : /* Join (map into the process) all shared memory (huge/gigantic pages)
987 : needed by the tile, in the given topology. All memory associated
988 : with the tile (aka. used by links that the tile either produces to or
989 : consumes from, or used by the tile itself for its cnc) will be
990 : attached (mapped into the process).
991 :
992 : This is needed to play nicely with the sandbox. Once a process is
993 : sandboxed we can no longer map any memory. */
994 : void
995 : fd_topo_join_tile_workspaces( fd_topo_t * topo,
996 : fd_topo_tile_t * tile,
997 : int core_dump_level );
998 :
999 : /* Join (map into the process) the shared memory (huge/gigantic pages)
1000 : for the given workspace. Mode is one of
1001 : FD_SHMEM_JOIN_MODE_READ_WRITE or FD_SHMEM_JOIN_MODE_READ_ONLY and
1002 : determines the prot argument that will be passed to mmap when mapping
1003 : the pages in (PROT_WRITE or PROT_READ respectively).
1004 :
1005 : Dump should be set to 1 if the workspace memory should be dumpable
1006 : when the process crashes, or 0 if not. */
1007 : void
1008 : fd_topo_join_workspace( fd_topo_t * topo,
1009 : fd_topo_wksp_t * wksp,
1010 : int mode,
1011 : int dump );
1012 :
1013 : /* Join (map into the process) all shared memory (huge/gigantic pages)
1014 : needed by all tiles in the topology. Mode is one of
1015 : FD_SHMEM_JOIN_MODE_READ_WRITE or FD_SHMEM_JOIN_MODE_READ_ONLY and
1016 : determines the prot argument that will be passed to mmap when
1017 : mapping the pages in (PROT_WRITE or PROT_READ respectively). */
1018 : void
1019 : fd_topo_join_workspaces( fd_topo_t * topo,
1020 : int mode,
1021 : int core_dump_level );
1022 :
1023 : /* Leave (unmap from the process) the shared memory needed for the
1024 : given workspace in the topology, if it was previously mapped.
1025 :
1026 : topo and wksp are assumed non-NULL. It is OK if the workspace
1027 : has not been previously joined, in which case this is a no-op. */
1028 :
1029 : void
1030 : fd_topo_leave_workspace( fd_topo_t * topo,
1031 : fd_topo_wksp_t * wksp );
1032 :
1033 : /* Leave (unmap from the process) all shared memory needed by all
1034 : tiles in the topology, if each of them was mapped.
1035 :
1036 : topo is assumed non-NULL. Only workspaces which were previously
1037 : joined are unmapped. */
1038 :
1039 : void
1040 : fd_topo_leave_workspaces( fd_topo_t * topo );
1041 :
1042 : /* Create the given workspace needed by the topology on the system.
1043 : This does not "join" the workspaces (map their memory into the
1044 : process), but only creates the .wksp file and formats it correctly
1045 : as a workspace.
1046 :
1047 : Returns 0 on success and -1 on failure, with errno set to the error.
1048 : The only reason for failure currently that will be returned is
1049 : ENOMEM, as other unexpected errors will cause the program to exit.
1050 :
1051 : If update_existing is 1, the workspace will not be created from
1052 : scratch but it will be assumed that it already exists from a prior
1053 : run and needs to be maybe resized and then have the header
1054 : structures reinitialized. This can save a very expensive operation
1055 : of zeroing all of the workspace pages. This is dangerous in
1056 : production because it can leave stray memory from prior runs around,
1057 : and should only be used in development environments. */
1058 :
1059 : int
1060 : fd_topo_create_workspace( fd_topo_t * topo,
1061 : fd_topo_wksp_t * wksp,
1062 : int update_existing );
1063 :
1064 : /* Join the standard IPC objects needed by the topology of this particular
1065 : tile */
1066 :
1067 : void
1068 : fd_topo_fill_tile( fd_topo_t * topo,
1069 : fd_topo_tile_t * tile );
1070 :
1071 : /* Same as fd_topo_fill_tile but fills in all the objects for a
1072 : particular workspace with the given mode. */
1073 : void
1074 : fd_topo_workspace_fill( fd_topo_t * topo,
1075 : fd_topo_wksp_t * wksp );
1076 :
1077 : /* Apply a new function to every object that is resident in the given
1078 : workspace in the topology. */
1079 :
1080 : void
1081 : fd_topo_wksp_new( fd_topo_t const * topo,
1082 : fd_topo_wksp_t const * wksp,
1083 : fd_topo_obj_callbacks_t ** callbacks );
1084 :
1085 : /* Same as fd_topo_fill_tile but fills in all tiles in the topology. */
1086 :
1087 : void
1088 : fd_topo_fill( fd_topo_t * topo );
1089 :
1090 : /* fd_topo_tile_stack_join joins a huge page optimized stack for the
1091 : provided tile. The stack is assumed to already exist at a known
1092 : path in the hugetlbfs mount. */
1093 :
1094 : void *
1095 : fd_topo_tile_stack_join( char const * app_name,
1096 : char const * tile_name,
1097 : ulong tile_kind_id );
1098 :
1099 : /* fd_topo_run_single_process runs all the tiles in a single process
1100 : (the calling process). This spawns a thread for each tile, switches
1101 : that thread to the given UID and GID and then runs the tile in it.
1102 : Each thread will never exit, as tiles are expected to run forever.
1103 : An error is logged and the application will exit if a tile exits.
1104 : The function itself does return after spawning all the threads.
1105 :
1106 : The threads will not be sandboxed in any way, except switching to the
1107 : provided UID and GID, so they will share the same address space, and
1108 : not have any seccomp restrictions or use any Linux namespaces. The
1109 : calling thread will also switch to the provided UID and GID before
1110 : it returns.
1111 :
1112 : In production, when running with an Agave child process this is
1113 : used for spawning certain tiles inside the Agave address space.
1114 : It's also useful for tooling and debugging, but is not how the main
1115 : production Firedancer process runs. For production, each tile is run
1116 : in its own address space with a separate process and full security
1117 : sandbox.
1118 :
1119 : The agave argument determines which tiles are started. If the
1120 : argument is 0 or 1, only non-agave (or only agave) tiles are started.
1121 : If the argument is any other value, all tiles in the topology are
1122 : started regardless of if they are Agave tiles or not. */
1123 :
1124 : void
1125 : fd_topo_run_single_process( fd_topo_t * topo,
1126 : int agave,
1127 : uint uid,
1128 : uint gid,
1129 : fd_topo_run_tile_t (* tile_run )( fd_topo_tile_t const * tile ) );
1130 :
1131 : /* fd_topo_run_tile runs the given tile directly within the current
1132 : process (and thread). The function will never return, as tiles are
1133 : expected to run forever. An error is logged and the application will
1134 : exit if the tile exits.
1135 :
1136 : The sandbox argument determines if the current process will be
1137 : sandboxed fully before starting the tile. The thread will switch to
1138 : the UID and GID provided before starting the tile, even if the thread
1139 : is not being sandboxed. Although POSIX specifies that all threads in
1140 : a process must share a UID and GID, this is not the case on Linux.
1141 : The thread will switch to the provided UID and GID without switching
1142 : the other threads in the process.
1143 :
1144 : If keep_controlling_terminal is set to 0, and the sandbox is enabled
1145 : the controlling terminal will be detached as an additional sandbox
1146 : measure, but you will not be able to send Ctrl+C or other signals
1147 : from the terminal. See fd_sandbox.h for more information.
1148 :
1149 : The allow_fd argument is only used if sandbox is true, and is a file
1150 : descriptor which will be allowed to exist in the process. Normally
1151 : the sandbox code rejects and aborts if there is an unexpected file
1152 : descriptor present on boot. This is helpful to allow a parent
1153 : process to be notified on termination of the tile by waiting for a
1154 : pipe file descriptor to get closed.
1155 :
1156 : wait and debugger are both used in debugging. If wait is non-NULL,
1157 : the runner will wait until the value pointed to by wait is non-zero
1158 : before launching the tile. Likewise, if debugger is non-NULL, the
1159 : runner will wait until a debugger is attached before setting the
1160 : value pointed to by debugger to non-zero. These are intended to be
1161 : used as a pair, where many tiles share a waiting reference, and then
1162 : one of the tiles (a tile you want to attach the debugger to) has the
1163 : same reference provided as the debugger, so all tiles will stop and
1164 : wait for the debugger to attach to it before proceeding. */
1165 :
1166 : void
1167 : fd_topo_run_tile( fd_topo_t * topo,
1168 : fd_topo_tile_t * tile,
1169 : int sandbox,
1170 : int keep_controlling_terminal,
1171 : int dumpable,
1172 : uint uid,
1173 : uint gid,
1174 : int allow_fd,
1175 : volatile int * wait,
1176 : volatile int * debugger,
1177 : fd_topo_run_tile_t * tile_run );
1178 :
1179 : /* This is for determining the value of RLIMIT_MLOCK that we need to
1180 : successfully run all tiles in separate processes. The value returned
1181 : is the maximum amount of memory that will be locked with mlock() by
1182 : any individual process in the tree. Specifically, if we have three
1183 : tile processes, and they each need to lock 5, 9, and 2 MiB of memory
1184 : respectively, RLIMIT_MLOCK needs to be 9 MiB to allow all three
1185 : process mlock() calls to succeed.
1186 :
1187 : Tiles lock memory in three ways. Any workspace they are using, they
1188 : lock the entire workspace. Then each tile uses huge pages for the
1189 : stack which are also locked, and finally some tiles use private
1190 : locked mmaps outside the workspace for storing key material. The
1191 : results here include all of this memory together.
1192 :
1193 : The result is not necessarily the amount of memory used by the tile
1194 : process, although it will be quite close. Tiles could potentially
1195 : allocate memory (eg, with brk) without needing to lock it, which
1196 : would not need to included, and some kernel memory that tiles cause
1197 : to be allocated (for example XSK buffers) is also not included. The
1198 : actual amount of memory used will not be less than this value. */
1199 : FD_FN_PURE ulong
1200 : fd_topo_mlock_max_tile( fd_topo_t const * topo );
1201 :
1202 : /* Same as fd_topo_mlock_max_tile, but for loading the entire topology
1203 : into one process, rather than a separate process per tile. This is
1204 : used, for example, by the configuration code when it creates all the
1205 : workspaces, or the monitor that maps the entire system into one
1206 : address space. */
1207 : FD_FN_PURE ulong
1208 : fd_topo_mlock( fd_topo_t const * topo );
1209 :
1210 : /* This returns the number of gigantic pages needed by the topology on
1211 : the provided numa node. It includes pages needed by the workspaces,
1212 : as well as additional allocations like huge pages for process stacks
1213 : and private key storage. */
1214 :
1215 : FD_FN_PURE ulong
1216 : fd_topo_gigantic_page_cnt( fd_topo_t const * topo,
1217 : ulong numa_idx );
1218 :
1219 : /* This returns the number of huge pages in the application needed by
1220 : the topology on the provided numa node. It includes pages needed by
1221 : things placed in the hugetlbfs (workspaces, process stacks). If
1222 : include_anonymous is true, it also includes anonymous hugepages which
1223 : are needed but are not placed in the hugetlbfs. */
1224 :
1225 : FD_FN_PURE ulong
1226 : fd_topo_huge_page_cnt( fd_topo_t const * topo,
1227 : ulong numa_idx,
1228 : int include_anonymous );
1229 :
1230 : /* Returns the number of normal (4 KiB) pages needed by the topology
1231 : for extra allocations like private key storage and XSK rings. */
1232 :
1233 : FD_FN_PURE ulong
1234 : fd_topo_normal_page_cnt( fd_topo_t const * topo );
1235 :
1236 : /* Prints a message describing the topology to an output stream. If
1237 : stdout is true, will be written to stdout, otherwise will be written
1238 : as a NOTICE log message to the log file. */
1239 : void
1240 : fd_topo_print_log( int stdout,
1241 : fd_topo_t * topo );
1242 :
1243 : FD_PROTOTYPES_END
1244 :
1245 : #endif /* HEADER_fd_src_disco_topo_fd_topo_h */
|