LCOV - code coverage report
Current view: top level - app/shared_dev/boot - fd_dev_boot.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 126 0.0 %
Date: 2026-06-29 05:51:35 Functions: 0 3 0.0 %

          Line data    Source code
       1             : #define _GNU_SOURCE
       2             : #include "fd_dev_boot.h"
       3             : 
       4             : #include "../../shared/fd_config.h"
       5             : #include "../../shared/fd_action.h"
       6             : #include "../../shared/boot/fd_boot.h"
       7             : #include "../../platform/fd_file_util.h"
       8             : 
       9             : #include <errno.h>
      10             : #include <unistd.h>
      11             : #include <stdlib.h>
      12             : #include <stdio.h>
      13             : #include <sys/types.h>
      14             : #include <sys/stat.h>
      15             : 
      16             : extern char fd_log_private_path[ 1024 ];
      17             : 
      18             : extern action_t * ACTIONS[];
      19             : 
      20           0 : #define MAX_ARGC 32
      21             : 
      22             : /* Rerun the currently executing process as root. This will never return,
      23             :    instead it replaces the currently executing process with a new one. */
      24             : static void
      25             : execve_as_root( int     argc,
      26           0 :                 char ** argv ) {
      27           0 :   char _current_executable_path[ PATH_MAX ];
      28           0 :   FD_TEST( -1!=fd_file_util_self_exe( _current_executable_path ) );
      29             : 
      30           0 :   char * args[ MAX_ARGC+4 ];
      31           0 :   for( int i=1; i<argc; i++ ) args[i+2] = argv[i];
      32           0 :   args[ 0 ]      = "sudo";
      33           0 :   args[ 1 ]      = "-E";
      34           0 :   args[ 2 ]      = _current_executable_path;
      35             :   /* always override the log path to use the same one we just opened for ourselves */
      36           0 :   args[ argc+2 ] = "--log-path";
      37           0 :   args[ argc+3 ] = fd_log_private_path;
      38           0 :   args[ argc+4 ] = NULL;
      39             : 
      40             :   /* ok to leak these dynamic strings because we are about to execve anyway */
      41           0 :   char * envp[ 3 ] = {0};
      42           0 :   char * env;
      43           0 :   int    idx = 0;
      44           0 :   if( FD_LIKELY(( env = getenv( "FIREDANCER_CONFIG_TOML" ) )) ) {
      45           0 :     if( FD_UNLIKELY( asprintf( &envp[ idx++ ], "FIREDANCER_CONFIG_TOML=%s", env ) == -1 ) )
      46           0 :       FD_LOG_ERR(( "asprintf() failed (%i-%s)", errno, fd_io_strerror( errno ) ));
      47           0 :   }
      48           0 :   if( FD_LIKELY(( env = getenv( "TERM" ) )) ) {
      49           0 :     if( FD_UNLIKELY( asprintf( &envp[ idx++ ], "TERM=%s", env ) == -1 ) )
      50           0 :       FD_LOG_ERR(( "asprintf() failed (%i-%s)", errno, fd_io_strerror( errno ) ));
      51           0 :   }
      52             : 
      53           0 :   execve( "/usr/bin/sudo", args, envp );
      54           0 :   FD_LOG_ERR(( "execve(sudo) failed (%i-%s)", errno, fd_io_strerror( errno ) ));
      55           0 : }
      56             : 
      57             : config_t config;
      58             : 
      59             : void
      60           0 : fd_global_options_help( fd_action_help_t * help ) {
      61           0 :   fd_action_help_arg( help, "--config",           "<path>",  "Path to a configuration TOML file" );
      62           0 :   fd_action_help_arg( help, "--mainnet",          NULL,      "Use Solana mainnet defaults" );
      63           0 :   fd_action_help_arg( help, "--testnet",          NULL,      "Use Solana testnet defaults" );
      64           0 :   fd_action_help_arg( help, "--devnet",           NULL,      "Use Solana devnet defaults" );
      65           0 :   fd_action_help_arg( help, "--mainnet-jito",     NULL,      "Use Solana mainnet defaults with the Jito relayer/bundles" );
      66           0 :   fd_action_help_arg( help, "--testnet-jito",     NULL,      "Use Solana testnet defaults with the Jito relayer/bundles" );
      67           0 :   fd_action_help_arg( help, "--log-path",         "<path>",  "Path to write the log file to" );
      68           0 :   fd_action_help_arg( help, "--log-level-stderr", "<level>", "Minimum log level to print to stderr" );
      69           0 :   fd_action_help_arg( help, "--no-sandbox",       NULL,      "Disable the security sandbox (development only)" );
      70           0 :   fd_action_help_arg( help, "--no-clone",         NULL,      "Run all tiles in a single process instead of one per tile (development only)" );
      71           0 :   fd_action_help_arg( help, "--version",          NULL,      "Show the current software version" );
      72           0 :   fd_action_help_arg( help, "--help/-h",          NULL,      "Print this help message" );
      73           0 : }
      74             : 
      75             : int
      76             : fd_dev_main( int                        argc,
      77             :              char **                    _argv,
      78             :              int                        is_firedancer,
      79             :              fd_config_file_t * const * configs,
      80           0 :              void (* topo_init )( config_t * config ) ) {
      81           0 :   fd_version_private_boot( &argc, &_argv );
      82             :   /* save original arguments list in case we need to respawn the process
      83             :      as privileged */
      84           0 :   int    orig_argc = argc;
      85           0 :   char * orig_argv[ MAX_ARGC+1 ] = {0};
      86           0 :   for( int i=0; i<fd_int_min( MAX_ARGC, argc ); i++ ) orig_argv[ i ] = _argv[ i ];
      87             : 
      88           0 :   if( FD_UNLIKELY( argc >= MAX_ARGC ) ) FD_LOG_ERR(( "too many arguments (%i)", argc ));
      89           0 :   char ** argv = _argv;
      90             : 
      91           0 :   argc--; argv++;
      92             : 
      93           0 :   fd_env_strip_cmdline_cstr( &argc, &argv, "--log-level-stderr", NULL, NULL );
      94           0 :   char const * log_path = fd_env_strip_cmdline_cstr( &argc, &argv, "--log-path", NULL, NULL );
      95             : 
      96           0 :   int no_sandbox = fd_env_strip_cmdline_contains( &argc, &argv, "--no-sandbox" );
      97           0 :   int no_clone = fd_env_strip_cmdline_contains( &argc, &argv, "--no-clone" );
      98             : 
      99           0 :   const char * opt_user_config_path = fd_env_strip_cmdline_cstr(
     100           0 :     &argc,
     101           0 :     &argv,
     102           0 :     "--config",
     103           0 :     "FIREDANCER_CONFIG_TOML",
     104           0 :     NULL );
     105             : 
     106           0 :   const char * action_name = "dev";
     107           0 :   if( FD_LIKELY( argc > 0 && !strcmp( argv[ 0 ], "--version" ) ) ) {
     108           0 :     action_name = "version";
     109           0 :     argc--; argv++;
     110           0 :   } else if( FD_LIKELY( argc > 0 && ( !strcmp( argv[ 0 ], "--help" ) || !strcmp( argv[ 0 ], "-h" ) ) ) ) {
     111           0 :     action_name = "help";
     112           0 :     argc--; argv++;
     113           0 :   } else if( FD_UNLIKELY( argc > 0 && argv[ 0 ][ 0 ] != '-' ) ) {
     114           0 :     action_name = argv[ 0 ];
     115           0 :     argc--; argv++;
     116           0 :   }
     117             : 
     118           0 :   action_t * action = NULL;
     119           0 :   for( ulong i=0UL; ACTIONS[ i ]; i++ ) {
     120           0 :     if( FD_UNLIKELY( !strcmp( action_name, ACTIONS[ i ]->name ) ) ) {
     121           0 :       action = ACTIONS[ i ];
     122           0 :       if( FD_UNLIKELY( action->is_immediate ) ) {
     123           0 :         action->fn( NULL, NULL );
     124           0 :         return 0;
     125           0 :       }
     126           0 :       break;
     127           0 :     }
     128           0 :   }
     129             : 
     130           0 :   if( FD_UNLIKELY( !action ) ) {
     131           0 :     fprintf( stderr, "unknown subcommand `%s`\n", action_name );
     132           0 :     exit( 1 );
     133           0 :   }
     134             : 
     135           0 :   int help_argc = argc; char ** help_argv = argv;
     136           0 :   if( FD_UNLIKELY( fd_env_strip_cmdline_contains( &help_argc, &help_argv, "--help" ) ||
     137           0 :                     fd_env_strip_cmdline_contains( &help_argc, &help_argv, "-h"     ) ) ) {
     138           0 :     fd_action_help_print( action );
     139           0 :     return 0;
     140           0 :   }
     141             : 
     142           0 : # if !FD_HAS_ASAN && !FD_HAS_MSAN
     143           0 :   fd_log_enable_signal_handler();
     144           0 : # endif
     145           0 :   int load_topo = fd_main_init( &argc, &argv, &config, opt_user_config_path, is_firedancer, action->is_local_cluster, log_path, configs, 1 /* dev */ );
     146           0 :   if( FD_LIKELY( load_topo ) ) fd_cstr_ncpy( config.action, action->name, sizeof( config.action ) );
     147             : 
     148           0 :   config.development.no_clone = config.development.no_clone || no_clone;
     149           0 :   config.development.sandbox = config.development.sandbox && !no_sandbox && !config.development.no_clone;
     150             : 
     151           0 :   int is_allowed_live = action->is_diagnostic==1;
     152           0 :   if( FD_UNLIKELY( config.is_live_cluster && !is_allowed_live ) )
     153           0 :     FD_LOG_ERR(( "The `fddev` command is for development and test environments but your "
     154           0 :                  "configuration targets a live cluster. Use `fdctl` if this is a "
     155           0 :                  "production environment" ));
     156             : 
     157           0 :   if( FD_LIKELY( load_topo ) ) {
     158           0 :     if( FD_LIKELY( action->topo ) ) action->topo( &config );
     159           0 :     else                            topo_init( &config );
     160           0 :   }
     161             : 
     162           0 :   args_t args = {0};
     163           0 :   if( FD_LIKELY( action->args ) ) action->args( &argc, &argv, &args );
     164           0 :   if( FD_UNLIKELY( argc ) ) FD_LOG_ERR(( "unknown argument `%s`", argv[ 0 ] ));
     165             : 
     166             :   /* Check if we are appropriately permissioned to run the desired
     167             :      command. */
     168           0 :   if( FD_LIKELY( action->perm ) ) {
     169           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 ) ) );
     170           0 :     action->perm( &args, chk, &config );
     171           0 :     ulong err_cnt = fd_cap_chk_err_cnt( chk );
     172           0 :     if( FD_UNLIKELY( err_cnt ) ) {
     173           0 :       if( FD_UNLIKELY( !geteuid() ) ) {
     174           0 :         for( ulong i=0UL; i<err_cnt; i++ ) FD_LOG_WARNING(( "%s", fd_cap_chk_err( chk, i ) ));
     175           0 :         FD_LOG_ERR(( "insufficient permissions to execute command `%s` when running as root. "
     176           0 :                      "fddev is likely being run with a reduced capability bounding set.", action_name ));
     177           0 :       }
     178           0 :       FD_LOG_INFO(( "insufficient permissions to execute command `%s`, rerunning as root", action_name ));
     179           0 :       execve_as_root( orig_argc, orig_argv );
     180           0 :     }
     181           0 :   }
     182             : 
     183             :   /* run the command */
     184           0 :   action->fn( &args, &config );
     185           0 :   return 0;
     186           0 : }

Generated by: LCOV version 1.14