LCOV - code coverage report
Current view: top level - app/shared_dev/commands - dump.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 61 0.0 %
Date: 2025-07-01 05:00:49 Functions: 0 3 0.0 %

          Line data    Source code
       1             : #include "../../shared/fd_config.h"
       2             : #include "../../shared/fd_action.h"
       3             : #include "../../../util/net/fd_pcap.h"
       4             : 
       5             : #include <stdio.h>
       6             : 
       7             : void
       8             : dump_cmd_args( int      * argc,
       9             :                char * * * argv,
      10           0 :                args_t   * args ) {
      11           0 :   char const * out_file = fd_env_strip_cmdline_cstr( argc, argv, "--out-file", NULL, "dump.pcap" );
      12           0 :   char const * link     = fd_env_strip_cmdline_cstr( argc, argv, "--link",     NULL, ""          );
      13           0 :   fd_cstr_fini( fd_cstr_append_cstr_safe( fd_cstr_init( args->dump.pcap_path ), out_file, sizeof(args->dump.pcap_path)-1UL ) );
      14           0 :   fd_cstr_fini( fd_cstr_append_cstr_safe( fd_cstr_init( args->dump.link_name ), link,     sizeof(args->dump.link_name)-1UL ) );
      15           0 : }
      16             : 
      17             : static void
      18             : dump_link( void           * out_file,
      19             :            fd_topo_link_t * link,
      20           0 :            void           * mem ) {
      21           0 :   fd_frag_meta_t const * mcache = link->mcache;
      22           0 :   ulong seq0 = fd_mcache_seq0( mcache );
      23           0 :   ulong seq_init = fd_mcache_seq_query( fd_mcache_seq_laddr_const( mcache ) );
      24           0 :   ulong depth = fd_mcache_depth( mcache );
      25             : 
      26           0 :   ulong dumped_count = 0UL;
      27             : 
      28           0 :   uint link_hash = (uint)((fd_hash( 17UL, link->name, strlen( link->name ) ) << 8) | link->kind_id);
      29             :   /* For links that are published reliably, we can trust the value of
      30             :      seq_init.  For unreliable links, we'll just publish one whole
      31             :      depth. */
      32             : 
      33             :   /* We know at this point [seq0, seq_init) were published, but they may
      34             :      be long overwritten, and there may be more published than that. */
      35             : 
      36           0 :   ulong min_seq_seen = seq_init; /* What we actually dumped is [min_seq_seen, seq_init) */
      37           0 :   for( ulong seq=fd_seq_dec( seq_init, 1UL ); fd_seq_ge( seq, seq0 ); seq=fd_seq_dec( seq, 1UL ) ) {
      38             :     /* It's not necessary for this to be atomic, since this is a
      39             :        post-mortem tool. */
      40           0 :     fd_frag_meta_t const * line = mcache+fd_mcache_line_idx( seq, depth );
      41           0 :     ulong read_seq = fd_frag_meta_seq_query( line );
      42           0 :     if( FD_UNLIKELY( read_seq!=seq ) ) break;
      43             : 
      44           0 :     min_seq_seen = seq;
      45             : 
      46           0 :     ulong chunk = line->chunk;
      47           0 :     ulong sz    = line->sz;
      48             : 
      49           0 :     void const * buffer = fd_chunk_to_laddr_const( mem, chunk );
      50             : 
      51           0 :     fd_pcap_fwrite_pkt( (long)seq, line, sizeof(fd_frag_meta_t), buffer, sz, link_hash, out_file );
      52           0 :     dumped_count++;
      53           0 :   }
      54             : 
      55             :   /* Now check everything after seq_init.  This could potentially loop
      56             :      forever if the producer is still going, so we cap it at one depth. */
      57           0 :   for( ulong off=0UL; off<depth; off++ ) {
      58           0 :     ulong seq = fd_seq_inc( seq_init, off );
      59             : 
      60           0 :     fd_frag_meta_t const * line = mcache+fd_mcache_line_idx( seq, depth );
      61           0 :     ulong read_seq = fd_frag_meta_seq_query( line );
      62             : 
      63             :     /* Skip anything we processed in the first loop, also skipping any
      64             :        with the err control bit set.  When an mcache is initialized, all
      65             :        the frags have err set to true, so this will skip those in
      66             :        particular as well. */
      67           0 :     if( FD_UNLIKELY( (fd_seq_le( min_seq_seen, read_seq ) & fd_seq_lt( read_seq, seq_init )) | (line->ctl & (1<<2)) ) ) continue;
      68             : 
      69           0 :     ulong chunk = line->chunk;
      70           0 :     ulong sz    = line->sz;
      71             : 
      72           0 :     void const * buffer = fd_chunk_to_laddr_const( mem, chunk );
      73             : 
      74           0 :     fd_pcap_fwrite_pkt( (long)seq, line, sizeof(fd_frag_meta_t), buffer, sz, link_hash, out_file );
      75           0 :     dumped_count++;
      76           0 :   }
      77           0 :   FD_LOG_NOTICE(( "Dumped %lu frags from %s %lu. Link hash: 0x%x", dumped_count, link->name, link->kind_id, link_hash ));
      78           0 : }
      79             : 
      80             : void
      81             : dump_cmd_fn( args_t *   args,
      82           0 :              config_t * config ) {
      83             : 
      84           0 :   FILE * out = fopen( args->dump.pcap_path, "w" );
      85           0 :   FD_TEST( fd_pcap_fwrite_hdr( out, FD_PCAP_LINK_LAYER_USER0 ) );
      86             : 
      87           0 :   fd_topo_join_workspaces( &config->topo, FD_SHMEM_JOIN_MODE_READ_ONLY );
      88           0 :   fd_topo_fill( &config->topo );
      89             : 
      90           0 :   char * tokens[ 16 ];
      91           0 :   ulong token_count = fd_cstr_tokenize( tokens, 16UL, args->dump.link_name, ',' );
      92             : 
      93           0 :   for( ulong i=0UL; i<config->topo.link_cnt; i++ ) {
      94           0 :     int found = (token_count==0UL);
      95           0 :     for( ulong k=0UL; k<token_count; k++ ) found |= !strcmp( tokens[ k ], config->topo.links[ i ].name );
      96           0 :     if( found ) {
      97             : 
      98           0 :       fd_topo_link_t * link = &(config->topo.links[ i ]);
      99           0 :       if( link->mcache==NULL ) {
     100           0 :         FD_LOG_NOTICE(( "Skipping %s %lu", link->name, link->kind_id ));
     101           0 :         continue;
     102           0 :       }
     103           0 :       void * mem = config->topo.workspaces[ config->topo.objs[ link->dcache_obj_id ].wksp_id ].wksp;
     104             : 
     105           0 :       dump_link( out, link, mem );
     106           0 :     }
     107           0 :   }
     108             : 
     109           0 :   fclose( out );
     110           0 :   fd_topo_leave_workspaces( &config->topo );
     111           0 : }
     112             : 
     113             : action_t fd_action_dump = {
     114             :   .name          = "dump",
     115             :   .args          = dump_cmd_args,
     116             :   .fn            = dump_cmd_fn,
     117             :   .perm          = NULL,
     118             :   .description   = "Dump tango links to a packet capture file",
     119             :   .is_diagnostic = 1
     120             : };

Generated by: LCOV version 1.14