LCOV - code coverage report
Current view: top level - app/firedancer/commands/monitor_gossip - monitor_gossip.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 103 0.0 %
Date: 2026-03-19 18:19:27 Functions: 0 4 0.0 %

          Line data    Source code
       1             : #include "monitor_gossip.h"
       2             : #include "gossip_diag.h"
       3             : #include "generated/monitor_gossip_seccomp.h"
       4             : 
       5             : #include "../../../shared/commands/monitor/monitor.h" /* reconstruct_topo */
       6             : #include "../../../../disco/metrics/fd_metrics.h"
       7             : #include "../../../../util/clock/fd_clock.h"
       8             : 
       9             : #include <errno.h>
      10             : #include <unistd.h>
      11             : #include <signal.h>
      12             : #include <stdio.h>
      13             : #include <sys/resource.h>
      14             : #include <linux/capability.h>
      15             : 
      16             : void
      17             : monitor_gossip_cmd_args( int *    pargc,
      18             :                          char *** pargv,
      19           0 :                          args_t * args ) {
      20           0 :   if( FD_UNLIKELY( fd_env_strip_cmdline_contains( pargc, pargv, "--help" ) ) ) {
      21           0 :     fputs(
      22           0 :       "\nUsage: firedancer monitor-gossip [GLOBAL FLAGS] [FLAGS]\n"
      23           0 :       "\n"
      24           0 :       "  Monitor gossip diagnostics on a running Firedancer\n"
      25           0 :       "  instance.  Attaches read-only to the validator's\n"
      26           0 :       "  shared memory and prints CRDS tables, message\n"
      27           0 :       "  statistics, and tile performance.\n"
      28           0 :       "\n"
      29           0 :       "Global Flags:\n"
      30           0 :       "  --mainnet            Use Solana mainnet-beta defaults\n"
      31           0 :       "  --testnet            Use Solana testnet defaults\n"
      32           0 :       "  --devnet             Use Solana devnet defaults\n"
      33           0 :       "\n"
      34           0 :       "Flags:\n"
      35           0 :       "  --topo <name>        Reconstruct topology from a named\n"
      36           0 :       "                       action (e.g. gossip). Default uses\n"
      37           0 :       "                       the production topology.\n"
      38           0 :       "  --compact            Use compact output format\n"
      39           0 :       "\n",
      40           0 :       stderr );
      41           0 :     exit( EXIT_SUCCESS );
      42           0 :   }
      43             : 
      44           0 :   char const * topo_name = fd_env_strip_cmdline_cstr( pargc, pargv, "--topo", NULL, "" );
      45           0 :   ulong topo_name_len = strlen( topo_name );
      46           0 :   if( FD_UNLIKELY( topo_name_len > sizeof(args->monitor_gossip.topo)-1 ) ) FD_LOG_ERR(( "Unknown --topo %s", topo_name ));
      47           0 :   fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( args->monitor_gossip.topo ), topo_name, topo_name_len ) );
      48             : 
      49           0 :   args->monitor_gossip.compact_mode = fd_env_strip_cmdline_contains( pargc, pargv, "--compact" );
      50           0 : }
      51             : 
      52             : static void
      53           0 : signal_handler( int sig ) {
      54           0 :   (void)sig;
      55           0 :   exit( 0 );
      56           0 : }
      57             : 
      58             : void
      59             : monitor_gossip_cmd_perm( args_t *         args FD_PARAM_UNUSED,
      60             :                          fd_cap_chk_t *   chk,
      61           0 :                          config_t const * config ) {
      62           0 :   ulong mlock_limit = fd_topo_mlock( &config->topo );
      63             : 
      64           0 :   fd_cap_chk_raise_rlimit( chk, "monitor-gossip", RLIMIT_MEMLOCK, mlock_limit, "call `rlimit(2)` to increase `RLIMIT_MEMLOCK` so all memory can be locked with `mlock(2)`" );
      65             : 
      66           0 :   if( fd_sandbox_requires_cap_sys_admin( config->uid, config->gid ) )
      67           0 :     fd_cap_chk_cap( chk, "monitor-gossip", CAP_SYS_ADMIN, "call `unshare(2)` with `CLONE_NEWUSER` to sandbox the process in a user namespace" );
      68           0 :   if( FD_LIKELY( getuid() != config->uid ) )
      69           0 :     fd_cap_chk_cap( chk, "monitor-gossip", CAP_SETUID,    "call `setresuid(2)` to switch uid to the sandbox user" );
      70           0 :   if( FD_LIKELY( getgid() != config->gid ) )
      71           0 :     fd_cap_chk_cap( chk, "monitor-gossip", CAP_SETGID,    "call `setresgid(2)` to switch gid to the sandbox user" );
      72           0 : }
      73             : 
      74             : void
      75             : monitor_gossip_cmd_fn( args_t *   args,
      76           0 :                        config_t * config ) {
      77           0 :   reconstruct_topo( config, args->monitor_gossip.topo );
      78             : 
      79           0 :   struct sigaction sa = {
      80           0 :     .sa_handler = signal_handler,
      81           0 :     .sa_flags   = 0,
      82           0 :   };
      83           0 :   if( FD_UNLIKELY( sigaction( SIGTERM, &sa, NULL ) ) )
      84           0 :     FD_LOG_ERR(( "sigaction(SIGTERM) failed (%i-%s)", errno, fd_io_strerror( errno ) ));
      85           0 :   if( FD_UNLIKELY( sigaction( SIGINT, &sa, NULL ) ) )
      86           0 :     FD_LOG_ERR(( "sigaction(SIGINT) failed (%i-%s)", errno, fd_io_strerror( errno ) ));
      87             : 
      88           0 :   int allow_fds[ 4 ];
      89           0 :   ulong allow_fds_cnt = 0;
      90           0 :   allow_fds[ allow_fds_cnt++ ] = 0; /* stdin */
      91           0 :   allow_fds[ allow_fds_cnt++ ] = 1; /* stdout */
      92           0 :   allow_fds[ allow_fds_cnt++ ] = 2; /* stderr */
      93           0 :   if( FD_LIKELY( fd_log_private_logfile_fd()!=-1 ) )
      94           0 :     allow_fds[ allow_fds_cnt++ ] = fd_log_private_logfile_fd();
      95             : 
      96           0 :   fd_topo_join_workspaces( &config->topo, FD_SHMEM_JOIN_MODE_READ_ONLY, FD_TOPO_CORE_DUMP_LEVEL_DISABLED );
      97             : 
      98           0 :   struct sock_filter seccomp_filter[ 128UL ];
      99           0 :   populate_sock_filter_policy_monitor_gossip( 128UL, seccomp_filter, (uint)fd_log_private_logfile_fd() );
     100             : 
     101           0 :   if( FD_LIKELY( config->development.sandbox ) ) {
     102           0 :     if( FD_UNLIKELY( close( config->log.lock_fd ) ) ) FD_LOG_ERR(( "close() failed (%i-%s)", errno, fd_io_strerror( errno ) ));
     103             : 
     104           0 :     fd_sandbox_enter( config->uid,
     105           0 :                       config->gid,
     106           0 :                       0,
     107           0 :                       0,
     108           0 :                       0,
     109           0 :                       1, /* Keep controlling terminal for Ctrl+C */
     110           0 :                       0,
     111           0 :                       0UL,
     112           0 :                       0UL,
     113           0 :                       0UL,
     114           0 :                       0UL,
     115           0 :                       allow_fds_cnt,
     116           0 :                       allow_fds,
     117           0 :                       sock_filter_policy_monitor_gossip_instr_cnt,
     118           0 :                       seccomp_filter );
     119           0 :   } else {
     120           0 :     fd_sandbox_switch_uid_gid( config->uid, config->gid );
     121           0 :   }
     122             : 
     123           0 :   fd_topo_fill( &config->topo );
     124             : 
     125           0 :   fd_gossip_diag_ctx_t diag_ctx[1];
     126           0 :   if( FD_UNLIKELY( fd_gossip_diag_init( diag_ctx, &config->topo, config ) ) ) {
     127           0 :     FD_LOG_ERR(( "Failed to initialize gossip diagnostics. "
     128           0 :                  "Is a Firedancer instance running with gossip tiles?" ));
     129           0 :   }
     130             : 
     131           0 :   printf( "Found %lu gossvf tiles\n", diag_ctx->gossvf.tile_count );
     132             : 
     133           0 :   fd_clock_t   clock_lmem[1];
     134           0 :   void       * clock_mem = aligned_alloc( FD_CLOCK_ALIGN, FD_CLOCK_FOOTPRINT );
     135           0 :   FD_TEST( clock_mem );
     136           0 :   fd_clock_default_init( clock_lmem, clock_mem );
     137             : 
     138           0 :   long next_report_time = fd_clock_now( clock_lmem ) + 1000000000L;
     139             : 
     140           0 :   for(;;) {
     141           0 :     long current_time = fd_clock_now( clock_lmem );
     142           0 :     if( FD_LIKELY( current_time < next_report_time ) ) continue;
     143           0 :     next_report_time += 1000000000L;
     144             : 
     145           0 :     fd_gossip_diag_render( diag_ctx, args->monitor_gossip.compact_mode );
     146           0 :   }
     147           0 : }
     148             : 
     149             : action_t fd_action_monitor_gossip = {
     150             :   .name           = "monitor-gossip",
     151             :   .args           = monitor_gossip_cmd_args,
     152             :   .fn             = monitor_gossip_cmd_fn,
     153             :   .require_config = 1,
     154             :   .perm           = monitor_gossip_cmd_perm,
     155             :   .is_diagnostic  = 1,
     156             :   .description    = "Monitor gossip diagnostics on a running Firedancer instance",
     157             : };

Generated by: LCOV version 1.14