LCOV - code coverage report
Current view: top level - app/fddev - main1.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 83 0.0 %
Date: 2025-03-20 12:08:36 Functions: 0 2 0.0 %

          Line data    Source code
       1             : #define _GNU_SOURCE
       2             : #include "fddev.h"
       3             : 
       4             : #include "../shared/commands/configure/configure.h"
       5             : #include "../shared/fd_file_util.h"
       6             : 
       7             : #include <unistd.h>
       8             : #include <stdlib.h>
       9             : #include <stdio.h>
      10             : #include <sys/types.h>
      11             : #include <sys/stat.h>
      12             : 
      13             : extern configure_stage_t fd_cfg_stage_kill;
      14             : extern configure_stage_t fd_cfg_stage_netns;
      15             : extern configure_stage_t fd_cfg_stage_genesis;
      16             : extern configure_stage_t fd_cfg_stage_blockstore;
      17             : extern configure_stage_t fd_cfg_stage_keys;
      18             : 
      19             : configure_stage_t * STAGES[ CONFIGURE_STAGE_COUNT ] = {
      20             :   &fd_cfg_stage_kill,
      21             :   &fd_cfg_stage_netns,
      22             :   &fd_cfg_stage_hugetlbfs,
      23             :   &fd_cfg_stage_sysctl,
      24             :   &fd_cfg_stage_hyperthreads,
      25             :   &fd_cfg_stage_ethtool_channels,
      26             :   &fd_cfg_stage_ethtool_gro,
      27             :   &fd_cfg_stage_ethtool_loopback,
      28             :   &fd_cfg_stage_keys,
      29             :   &fd_cfg_stage_genesis,
      30             : #ifdef FD_HAS_NO_AGAVE
      31             :   NULL,
      32             : #else
      33             :   &fd_cfg_stage_blockstore,
      34             : #endif
      35             :   NULL,
      36             : };
      37             : 
      38             : extern fd_topo_run_tile_t fd_tile_net;
      39             : extern fd_topo_run_tile_t fd_tile_netlnk;
      40             : extern fd_topo_run_tile_t fd_tile_sock;
      41             : extern fd_topo_run_tile_t fd_tile_quic;
      42             : extern fd_topo_run_tile_t fd_tile_bundle;
      43             : extern fd_topo_run_tile_t fd_tile_verify;
      44             : extern fd_topo_run_tile_t fd_tile_dedup;
      45             : extern fd_topo_run_tile_t fd_tile_pack;
      46             : extern fd_topo_run_tile_t fd_tile_shred;
      47             : extern fd_topo_run_tile_t fd_tile_sign;
      48             : extern fd_topo_run_tile_t fd_tile_metric;
      49             : extern fd_topo_run_tile_t fd_tile_cswtch;
      50             : extern fd_topo_run_tile_t fd_tile_gui;
      51             : extern fd_topo_run_tile_t fd_tile_plugin;
      52             : extern fd_topo_run_tile_t fd_tile_bencho;
      53             : extern fd_topo_run_tile_t fd_tile_benchg;
      54             : extern fd_topo_run_tile_t fd_tile_benchs;
      55             : extern fd_topo_run_tile_t fd_tile_pktgen;
      56             : 
      57             : #ifdef FD_HAS_NO_AGAVE
      58             : extern fd_topo_run_tile_t fd_tile_gossip;
      59             : extern fd_topo_run_tile_t fd_tile_repair;
      60             : extern fd_topo_run_tile_t fd_tile_store_int;
      61             : extern fd_topo_run_tile_t fd_tile_replay;
      62             : extern fd_topo_run_tile_t fd_tile_execor;
      63             : extern fd_topo_run_tile_t fd_tile_replay_thread;
      64             : extern fd_topo_run_tile_t fd_tile_batch;
      65             : extern fd_topo_run_tile_t fd_tile_batch_thread;
      66             : extern fd_topo_run_tile_t fd_tile_poh_int;
      67             : extern fd_topo_run_tile_t fd_tile_sender;
      68             : extern fd_topo_run_tile_t fd_tile_eqvoc;
      69             : extern fd_topo_run_tile_t fd_tile_rpcserv;
      70             : extern fd_topo_run_tile_t fd_tile_restart;
      71             : extern fd_topo_run_tile_t fd_tile_blackhole;
      72             : #else
      73             : extern fd_topo_run_tile_t fd_tile_resolv;
      74             : extern fd_topo_run_tile_t fd_tile_poh;
      75             : extern fd_topo_run_tile_t fd_tile_bank;
      76             : extern fd_topo_run_tile_t fd_tile_store;
      77             : #endif
      78             : 
      79             : fd_topo_run_tile_t * TILES[] = {
      80             :   &fd_tile_net,
      81             :   &fd_tile_netlnk,
      82             :   &fd_tile_sock,
      83             :   &fd_tile_quic,
      84             :   &fd_tile_bundle,
      85             :   &fd_tile_verify,
      86             :   &fd_tile_dedup,
      87             :   &fd_tile_pack,
      88             :   &fd_tile_shred,
      89             :   &fd_tile_sign,
      90             :   &fd_tile_metric,
      91             :   &fd_tile_cswtch,
      92             :   &fd_tile_gui,
      93             :   &fd_tile_plugin,
      94             :   &fd_tile_bencho,
      95             :   &fd_tile_benchg,
      96             :   &fd_tile_benchs,
      97             :   &fd_tile_pktgen,
      98             : #ifdef FD_HAS_NO_AGAVE
      99             :   &fd_tile_gossip,
     100             :   &fd_tile_repair,
     101             :   &fd_tile_store_int,
     102             :   &fd_tile_replay,
     103             :   &fd_tile_replay_thread,
     104             :   &fd_tile_execor,
     105             :   &fd_tile_batch,
     106             :   &fd_tile_batch_thread,
     107             :   &fd_tile_poh_int,
     108             :   &fd_tile_sender,
     109             :   &fd_tile_eqvoc,
     110             :   &fd_tile_rpcserv,
     111             :   &fd_tile_restart,
     112             :   &fd_tile_blackhole,
     113             : #else
     114             :   &fd_tile_resolv,
     115             :   &fd_tile_poh,
     116             :   &fd_tile_bank,
     117             :   &fd_tile_store,
     118             : #endif
     119             :   NULL,
     120             : };
     121             : 
     122             : action_t DEV_ACTIONS[] = {
     123             :   { .name = "bench",      .args = bench_cmd_args,      .fn = bench_cmd_fn,      .perm = dev_cmd_perm,   .description = "Test validator TPS benchmark" },
     124             :   { .name = "dev",        .args = dev_cmd_args,        .fn = dev_cmd_fn,        .perm = dev_cmd_perm,   .description = "Start up a test validator" },
     125             :   { .name = "dev1",       .args = dev1_cmd_args,       .fn = dev1_cmd_fn,       .perm = dev_cmd_perm,   .description = "Start up a single tile" },
     126             :   { .name = "dump",       .args = dump_cmd_args,       .fn = dump_cmd_fn,       .perm = NULL,           .description = "Dump tango links to pcap", .is_diagnostic=1 },
     127             :   { .name = "flame",      .args = flame_cmd_args,      .fn = flame_cmd_fn,      .perm = flame_cmd_perm, .description = "Capture a perf flamegraph", .is_diagnostic=1 },
     128             :   { .name = "help",       .args = NULL,                .fn = dev_help_cmd_fn,   .perm = NULL,           .description = "Print this help message", .is_diagnostic=1 },
     129             :   { .name = "load",       .args = load_cmd_args,       .fn = load_cmd_fn,       .perm = load_cmd_perm,  .description = "Load test an external validator" },
     130             :   { .name = "pktgen",     .args = pktgen_cmd_args,     .fn = pktgen_cmd_fn,     .perm = dev_cmd_perm,   .description = "Flood interface with invalid Ethernet frames" },
     131             :   { .name = "quic-trace", .args = quic_trace_cmd_args, .fn = quic_trace_cmd_fn, .perm = NULL,           .description = "Trace quic tile", .is_diagnostic=1 },
     132             :   { .name = "txn",        .args = txn_cmd_args,        .fn = txn_cmd_fn,        .perm = txn_cmd_perm,   .description = "Send a transaction to an fddev instance" },
     133             :   { .name = "wksp",       .args = NULL,                .fn = wksp_cmd_fn,       .perm = wksp_cmd_perm,  .description = "Initialize workspaces" },
     134             : # if FD_HAS_NO_AGAVE
     135             :   { .name = "gossip",     .args = gossip_cmd_args,     .fn = gossip_cmd_fn,     .perm = gossip_cmd_perm,.description = "Run a standalone gossip node" },
     136             : # endif
     137             :   {0}
     138             : };
     139             : 
     140             : extern char fd_log_private_path[ 1024 ];
     141             : 
     142           0 : #define MAX_ARGC 32
     143             : 
     144             : /* Rerun the currently executing process as root. This will never return,
     145             :    instead it replaces the currently executing process with a new one. */
     146             : static void
     147             : execve_as_root( int     argc,
     148           0 :                 char ** argv ) {
     149           0 :   char _current_executable_path[ PATH_MAX ];
     150           0 :   FD_TEST( -1!=fd_file_util_self_exe( _current_executable_path ) );
     151             : 
     152           0 :   char * args[ MAX_ARGC+4 ];
     153           0 :   for( int i=1; i<argc; i++ ) args[i+2] = argv[i];
     154           0 :   args[ 0 ]      = "sudo";
     155           0 :   args[ 1 ]      = "-E";
     156           0 :   args[ 2 ]      = _current_executable_path;
     157             :   /* always override the log path to use the same one we just opened for ourselves */
     158           0 :   args[ argc+2 ] = "--log-path";
     159           0 :   args[ argc+3 ] = fd_log_private_path;
     160           0 :   args[ argc+4 ] = NULL;
     161             : 
     162             :   /* ok to leak these dynamic strings because we are about to execve anyway */
     163           0 :   char * envp[ 3 ] = {0};
     164           0 :   char * env;
     165           0 :   int    idx = 0;
     166           0 :   if( FD_LIKELY(( env = getenv( "FIREDANCER_CONFIG_TOML" ) )) ) {
     167           0 :     if( FD_UNLIKELY( asprintf( &envp[ idx++ ], "FIREDANCER_CONFIG_TOML=%s", env ) == -1 ) )
     168           0 :       FD_LOG_ERR(( "asprintf() failed (%i-%s)", errno, fd_io_strerror( errno ) ));
     169           0 :   }
     170           0 :   if( FD_LIKELY(( env = getenv( "TERM" ) )) ) {
     171           0 :     if( FD_UNLIKELY( asprintf( &envp[ idx++ ], "TERM=%s", env ) == -1 ) )
     172           0 :       FD_LOG_ERR(( "asprintf() failed (%i-%s)", errno, fd_io_strerror( errno ) ));
     173           0 :   }
     174             : 
     175           0 :   execve( "/usr/bin/sudo", args, envp );
     176           0 :   FD_LOG_ERR(( "execve(sudo) failed (%i-%s)", errno, fd_io_strerror( errno ) ));
     177           0 : }
     178             : 
     179             : static config_t config;
     180             : 
     181             : int
     182             : fddev_main( int     argc,
     183           0 :             char ** _argv ) {
     184             :   /* save original arguments list in case we need to respawn the process
     185             :      as privileged */
     186           0 :   int    orig_argc = argc;
     187           0 :   char * orig_argv[ MAX_ARGC+1 ] = {0};
     188           0 :   for( int i=0; i<fd_int_min( MAX_ARGC, argc ); i++ ) orig_argv[ i ] = _argv[ i ];
     189             : 
     190           0 :   if( FD_UNLIKELY( argc >= MAX_ARGC ) ) FD_LOG_ERR(( "too many arguments (%i)", argc ));
     191           0 :   char ** argv = _argv;
     192             : 
     193           0 :   argc--; argv++;
     194             : 
     195           0 :   fd_env_strip_cmdline_cstr( &argc, &argv, "--log-level-stderr", NULL, NULL );
     196           0 :   char const * log_path = fd_env_strip_cmdline_cstr( &argc, &argv, "--log-path", NULL, NULL );
     197             : 
     198           0 :   fdctl_boot( &argc, &argv, &config, log_path );
     199             : 
     200           0 :   int no_sandbox = fd_env_strip_cmdline_contains( &argc, &argv, "--no-sandbox" );
     201           0 :   int no_clone = fd_env_strip_cmdline_contains( &argc, &argv, "--no-clone" );
     202           0 :   config.development.no_clone = config.development.no_clone || no_clone;
     203           0 :   config.development.sandbox = config.development.sandbox && !no_sandbox && !no_clone;
     204             : 
     205           0 :   const char * action_name = "dev";
     206           0 :   if( FD_UNLIKELY( argc > 0 && argv[ 0 ][ 0 ] != '-' ) ) {
     207           0 :     action_name = argv[ 0 ];
     208           0 :     argc--; argv++;
     209           0 :   }
     210             : 
     211           0 :   action_t * action = NULL;
     212           0 :   for( ulong i=0; ACTIONS[ i ].name; i++ ) {
     213           0 :     if( FD_UNLIKELY( !strcmp( action_name, ACTIONS[ i ].name ) ) ) {
     214           0 :       action = &ACTIONS[ i ];
     215           0 :       break;
     216           0 :     }
     217           0 :   }
     218           0 :   for( ulong i=0; DEV_ACTIONS[ i ].name; i++ ) {
     219           0 :     if( FD_UNLIKELY( !strcmp( action_name, DEV_ACTIONS[ i ].name ) ) ) {
     220           0 :       action = &DEV_ACTIONS[ i ];
     221           0 :       break;
     222           0 :     }
     223           0 :   }
     224             : 
     225           0 :   if( FD_UNLIKELY( !action ) ) FD_LOG_ERR(( "unknown subcommand `%s`", action_name ));
     226             : 
     227           0 :   int is_allowed_live = action->is_diagnostic==1;
     228           0 :   if( FD_UNLIKELY( config.is_live_cluster && !is_allowed_live ) )
     229           0 :     FD_LOG_ERR(( "The `fddev` command is for development and test environments but your "
     230           0 :                  "configuration targets a live cluster. Use `fdctl` if this is a "
     231           0 :                  "production environment" ));
     232             : 
     233           0 :   args_t args = {0};
     234           0 :   if( FD_LIKELY( action->args ) ) action->args( &argc, &argv, &args );
     235           0 :   if( FD_UNLIKELY( argc ) ) FD_LOG_ERR(( "unknown argument `%s`", argv[ 0 ] ));
     236             : 
     237             :   /* Check if we are appropriately permissioned to run the desired
     238             :      command. */
     239           0 :   if( FD_LIKELY( action->perm ) ) {
     240           0 :     fd_cap_chk_t * chk = fd_cap_chk_join( fd_cap_chk_new( __builtin_alloca_with_align( fd_cap_chk_footprint(), FD_CAP_CHK_ALIGN ) ) );
     241           0 :     action->perm( &args, chk, &config );
     242           0 :     ulong err_cnt = fd_cap_chk_err_cnt( chk );
     243           0 :     if( FD_UNLIKELY( err_cnt ) ) {
     244           0 :       if( FD_UNLIKELY( !geteuid() ) ) {
     245           0 :         for( ulong i=0UL; i<err_cnt; i++ ) FD_LOG_WARNING(( "%s", fd_cap_chk_err( chk, i ) ));
     246           0 :         FD_LOG_ERR(( "insufficient permissions to execute command `%s` when running as root. "
     247           0 :                      "fddev is likely being run with a reduced capability bounding set.", action_name ));
     248           0 :       }
     249           0 :       execve_as_root( orig_argc, orig_argv );
     250           0 :     }
     251           0 :   }
     252             : 
     253             :   /* run the command */
     254           0 :   action->fn( &args, &config );
     255           0 :   return 0;
     256           0 : }

Generated by: LCOV version 1.14