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