Line data Source code
1 : #include "../dev.h"
2 : #include "../../../shared/commands/configure/configure.h" /* CONFIGURE_CMD_INIT */
3 : #include "../../../shared/commands/run/run.h" /* fdctl_check_configure */
4 : #include "../../../../disco/net/fd_net_tile.h"
5 : #include "../../../../disco/topo/fd_topob.h"
6 : #include "../../../../disco/topo/fd_cpu_topo.h"
7 : #include "../../../../util/net/fd_ip4.h"
8 : #include "../../../../util/tile/fd_tile_private.h" /* fd_tile_private_cpus_parse */
9 :
10 : #include <unistd.h> /* pause */
11 :
12 : extern fd_topo_obj_callbacks_t * CALLBACKS[];
13 :
14 : fd_topo_run_tile_t
15 : fdctl_tile_run( fd_topo_tile_t const * tile );
16 :
17 : static void
18 0 : udpecho_topo( config_t * config ) {
19 0 : char const * affinity = config->development.udpecho.affinity;
20 0 : int is_auto_affinity = !strcmp( affinity, "auto" );
21 :
22 0 : ushort parsed_tile_to_cpu[ FD_TILE_MAX ];
23 0 : for( ulong i=0UL; i<FD_TILE_MAX; i++ ) parsed_tile_to_cpu[ i ] = USHORT_MAX;
24 :
25 0 : fd_topo_cpus_t cpus[1];
26 0 : fd_topo_cpus_init( cpus );
27 :
28 0 : ulong affinity_tile_cnt = 0UL;
29 0 : if( FD_LIKELY( !is_auto_affinity ) ) affinity_tile_cnt = fd_tile_private_cpus_parse( affinity, parsed_tile_to_cpu );
30 :
31 0 : ulong tile_to_cpu[ FD_TILE_MAX ] = {0};
32 0 : for( ulong i=0UL; i<affinity_tile_cnt; i++ ) {
33 0 : if( FD_UNLIKELY( parsed_tile_to_cpu[ i ]!=USHORT_MAX && parsed_tile_to_cpu[ i ]>=cpus->cpu_cnt ) )
34 0 : FD_LOG_ERR(( "The CPU affinity string in the configuration file under [development.udpecho.affinity] specifies a CPU index of %hu, but the system "
35 0 : "only has %lu CPUs. You should either change the CPU allocations in the affinity string, or increase the number of CPUs "
36 0 : "in the system.",
37 0 : parsed_tile_to_cpu[ i ], cpus->cpu_cnt ));
38 0 : tile_to_cpu[ i ] = fd_ulong_if( parsed_tile_to_cpu[ i ]==USHORT_MAX, ULONG_MAX, (ulong)parsed_tile_to_cpu[ i ] );
39 0 : }
40 0 : if( FD_LIKELY( !is_auto_affinity ) ) {
41 0 : if( FD_UNLIKELY( affinity_tile_cnt!=4UL ) )
42 0 : FD_LOG_ERR(( "Invalid [development.udpecho.affinity]: must include exactly three CPUs" ));
43 0 : }
44 :
45 : /* Reset topology from scratch */
46 0 : fd_topo_t * topo = &config->topo;
47 0 : fd_topob_new( &config->topo, config->name );
48 0 : topo->max_page_size = fd_cstr_to_shmem_page_sz( config->hugetlbfs.max_page_size );
49 :
50 0 : fd_topob_wksp( topo, "metric" );
51 0 : fd_topob_wksp( topo, "metric_in" );
52 0 : fd_topos_net_tiles( topo, config->layout.net_tile_count, &config->net, config->tiles.netlink.max_routes, config->tiles.netlink.max_peer_routes, config->tiles.netlink.max_neighbors, tile_to_cpu );
53 0 : fd_topob_tile( topo, "metric", "metric", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 0 );
54 :
55 0 : fd_topob_wksp( topo, "l4swap" );
56 0 : fd_topob_tile( topo, "l4swap", "l4swap", "l4swap", tile_to_cpu[ topo->tile_cnt ], 0, 0 );
57 :
58 0 : fd_topob_link( topo, "quic_net", "l4swap", 2048UL, FD_NET_MTU, 1UL );
59 0 : fd_topob_tile_out( topo, "l4swap", 0UL, "quic_net", 0UL );
60 0 : fd_topob_tile_in( topo, "net", 0UL, "metric_in", "quic_net", 0UL, FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED );
61 :
62 0 : fd_topos_net_rx_link( topo, "net_quic", 0UL, config->net.ingress_buffer_size );
63 0 : fd_topob_tile_in( topo, "l4swap", 0UL, "metric_in", "net_quic", 0UL, FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED );
64 :
65 0 : fd_topos_net_tile_finish( topo, 0UL );
66 0 : if( FD_UNLIKELY( is_auto_affinity ) ) fd_topob_auto_layout( topo, 0 );
67 0 : topo->agave_affinity_cnt = 0;
68 0 : fd_topob_finish( topo, CALLBACKS );
69 0 : fd_topo_print_log( /* stdout */ 1, topo );
70 0 : }
71 :
72 : void
73 : udpecho_cmd_args( int * pargc,
74 : char *** pargv,
75 0 : args_t * args ) {
76 0 : ushort port_l = fd_env_strip_cmdline_ushort( pargc, pargv, "--port", NULL, 0 );
77 0 : ushort port_s = fd_env_strip_cmdline_ushort( pargc, pargv, "-p", NULL, 0 );
78 0 : ushort port = port_s ? port_s : port_l;
79 0 : if( FD_UNLIKELY( !port ) ) FD_LOG_ERR(( "Missing --port argument" ));
80 0 : args->udpecho.listen_port = port;
81 0 : }
82 :
83 : void
84 : udpecho_cmd_fn( args_t * args,
85 0 : config_t * config ) {
86 0 : udpecho_topo( config );
87 0 : fd_topo_t * topo = &config->topo;
88 0 : fd_topo_tile_t * net_tile = &topo->tiles[ fd_topo_find_tile( topo, "net", 0UL ) ];
89 0 : fd_topo_tile_t * metric_tile = &topo->tiles[ fd_topo_find_tile( topo, "metric", 0UL ) ];
90 :
91 0 : net_tile->net.legacy_transaction_listen_port = args->udpecho.listen_port;
92 :
93 0 : if( FD_UNLIKELY( !fd_cstr_to_ip4_addr( config->tiles.metric.prometheus_listen_address, &metric_tile->metric.prometheus_listen_addr ) ) )
94 0 : FD_LOG_ERR(( "failed to parse prometheus listen address `%s`", config->tiles.metric.prometheus_listen_address ));
95 0 : metric_tile->metric.prometheus_listen_port = config->tiles.metric.prometheus_listen_port;
96 :
97 0 : configure_stage( &fd_cfg_stage_sysctl, CONFIGURE_CMD_INIT, config );
98 0 : configure_stage( &fd_cfg_stage_hugetlbfs, CONFIGURE_CMD_INIT, config );
99 0 : configure_stage( &fd_cfg_stage_ethtool_channels, CONFIGURE_CMD_INIT, config );
100 0 : configure_stage( &fd_cfg_stage_ethtool_gro, CONFIGURE_CMD_INIT, config );
101 0 : configure_stage( &fd_cfg_stage_ethtool_loopback, CONFIGURE_CMD_INIT, config );
102 :
103 0 : fdctl_check_configure( config );
104 : /* FIXME this allocates lots of memory unnecessarily */
105 0 : initialize_workspaces( config );
106 0 : initialize_stacks( config );
107 0 : fdctl_setup_netns( config, 1 );
108 0 : (void)fd_topo_install_xdp( topo, config->net.bind_address_parsed );
109 0 : fd_topo_join_workspaces( topo, FD_SHMEM_JOIN_MODE_READ_WRITE );
110 :
111 : /* FIXME allow running sandboxed/multiprocess */
112 0 : fd_topo_run_single_process( topo, 2, config->uid, config->gid, fdctl_tile_run );
113 0 : for(;;) pause();
114 0 : }
115 :
116 : action_t fd_action_udpecho = {
117 : .name = "udpecho",
118 : .args = udpecho_cmd_args,
119 : .fn = udpecho_cmd_fn,
120 : .perm = dev_cmd_perm,
121 : .description = "Run a UDP echo server"
122 : };
|