LCOV - code coverage report
Current view: top level - util/wksp - fd_wksp_ctl.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 422 456 92.5 %
Date: 2024-11-13 11:58:15 Functions: 3 3 100.0 %

          Line data    Source code
       1             : #include "../fd_util.h"
       2             : #include "fd_wksp_private.h"
       3             : 
       4             : #if FD_HAS_HOSTED
       5             : 
       6             : /* TODO: add owner query */
       7             : 
       8             : #include <stdio.h>
       9             : #include <errno.h>
      10             : #include <unistd.h>
      11             : #include <fcntl.h>
      12             : #include <sys/stat.h>
      13             : 
      14             : FD_IMPORT_CSTR( fd_wksp_ctl_help, "src/util/wksp/fd_wksp_ctl_help" );
      15             : 
      16             : /* fd_printf_wksp pretty prints the detailed workspace state to file.
      17             :    Includes detailed metadata integrity checking.  Return value
      18             :    semantics are the same as for fprintf. */
      19             : 
      20             : static int
      21             : fprintf_wksp( FILE *      file,
      22          36 :               fd_wksp_t * wksp ) {
      23             : 
      24          36 :   if( FD_UNLIKELY( !file ) ) {
      25           0 :     FD_LOG_WARNING(( "NULL file" ));
      26           0 :     return -1;
      27           0 :   }
      28             : 
      29          36 :   if( FD_UNLIKELY( !wksp ) ) {
      30           0 :     FD_LOG_WARNING(( "NULL wksp" ));
      31           0 :     return -1;
      32           0 :   }
      33             : 
      34          36 :   int ret = 0;
      35         420 : # define TRAP(x) do { int _err = (x); if( _err<0 ) { fd_wksp_private_unlock( wksp ); return _err; } ret += _err; } while(0)
      36             : 
      37          36 :   ulong part_max = wksp->part_max;
      38          36 :   ulong gaddr_lo = wksp->gaddr_lo;
      39          36 :   ulong gaddr_hi = wksp->gaddr_hi;
      40             : 
      41          36 :   fd_wksp_private_pinfo_t * pinfo = fd_wksp_private_pinfo( wksp );
      42             : 
      43          36 :   TRAP( fprintf( file,
      44          36 :                  "wksp %s\n"
      45          36 :                  "\tmagic     0x%016lx\n"
      46          36 :                  "\tseed      %u\n"
      47          36 :                  "\tpart_max  %lu\n"
      48          36 :                  "\tdata_max  %lu\n"
      49          36 :                  "\tgaddr     [0x%016lx,0x%016lx)\n",
      50          36 :                  wksp->name, wksp->magic, wksp->seed, part_max, wksp->data_max, gaddr_lo, gaddr_hi ) );
      51             : 
      52             :   /* TODO: considering running verify and/or doing extra metadata
      53             :      integrity checks */
      54             : 
      55          36 :   ulong cnt = 0UL;
      56             : 
      57          36 :   if( FD_UNLIKELY( fd_wksp_private_lock( wksp ) ) ) { cnt++; TRAP( fprintf( file, "\tlock err\n" ) ); }
      58          36 :   else {
      59          36 :     ulong used_cnt = 0UL; ulong free_cnt = 0UL;
      60          36 :     ulong used_sz  = 0UL; ulong free_sz  = 0UL;
      61          36 :     ulong used_max = 0UL; ulong free_max = 0UL;
      62             : 
      63          36 :     ulong cycle_tag = wksp->cycle_tag++;
      64             : 
      65          36 :     ulong last_i  = FD_WKSP_PRIVATE_PINFO_IDX_NULL;
      66          36 :     ulong last_hi = gaddr_lo;
      67          36 :     ulong i       = fd_wksp_private_pinfo_idx( wksp->part_head_cidx );
      68         174 :     while( !fd_wksp_private_pinfo_idx_is_null( i ) ) {
      69         138 :       if( FD_UNLIKELY( i>=part_max                     ) ) { cnt++; TRAP( fprintf( file, "\tindex err\n" ) ); break; }
      70         138 :       if( FD_UNLIKELY( pinfo[ i ].cycle_tag==cycle_tag ) ) { cnt++; TRAP( fprintf( file, "\tcycle err\n" ) ); break; }
      71         138 :       pinfo[ i ].cycle_tag = cycle_tag;
      72             : 
      73         138 :       ulong lo  = pinfo[ i ].gaddr_lo;
      74         138 :       ulong hi  = pinfo[ i ].gaddr_hi;
      75         138 :       ulong tag = pinfo[ i ].tag;
      76         138 :       ulong sz  = hi - lo;
      77         138 :       ulong h   = fd_wksp_private_pinfo_idx( pinfo[ i ].prev_cidx );
      78             : 
      79         138 :       int used = !!tag;
      80         138 :       if( used ) {
      81          81 :         used_cnt++;
      82          81 :         used_sz += sz;
      83          81 :         if( sz>used_max ) used_max = sz;
      84          81 :       } else {
      85          57 :         free_cnt++;
      86          57 :         free_sz += sz;
      87          57 :         if( sz>free_max ) free_max = sz;
      88          57 :       }
      89             : 
      90         138 :       TRAP( fprintf( file, "\tpartition [0x%016lx,0x%016lx) sz %20lu tag %20lu idx %lu", lo, hi, sz, tag, i ) );
      91         138 :       if( FD_UNLIKELY( h !=last_i  ) ) { cnt++; TRAP( fprintf( file, ", link_err"     ) ); }
      92         138 :       if( FD_UNLIKELY( lo!=last_hi ) ) { cnt++; TRAP( fprintf( file, ", adjacent_err" ) ); }
      93         138 :       if( FD_UNLIKELY( lo>=hi      ) ) { cnt++; TRAP( fprintf( file, ", size_err"     ) ); }
      94         138 :       TRAP( fprintf( file, "\n" ) );
      95             : 
      96         138 :       last_i  = i;
      97         138 :       last_hi = hi;
      98         138 :       i       = fd_wksp_private_pinfo_idx( pinfo[ i ].next_cidx );
      99         138 :     }
     100             : 
     101          36 :     ulong j = fd_wksp_private_pinfo_idx( wksp->part_tail_cidx );
     102          36 :     if( FD_UNLIKELY(        j!=last_i  ) ) { cnt++; TRAP( fprintf( file, "\ttail err\n"       ) ); }
     103          36 :     if( FD_UNLIKELY( gaddr_hi!=last_hi ) ) { cnt++; TRAP( fprintf( file, "\tincomplete err\n" ) ); }
     104             : 
     105          36 :     TRAP( fprintf( file, "\t%20lu bytes used (%20lu blocks, largest %20lu bytes)\n", used_sz, used_cnt, used_max ) );
     106          36 :     TRAP( fprintf( file, "\t%20lu bytes free (%20lu blocks, largest %20lu bytes)\n", free_sz, free_cnt, free_max ) );
     107             : 
     108          36 :     fd_wksp_private_unlock( wksp );
     109          36 :   }
     110             : 
     111          36 :   TRAP( fprintf( file, "\t%20lu errors detected\n", cnt ) );
     112          36 : # undef TRAP
     113             : 
     114          36 :   return ret;
     115          36 : }
     116             : 
     117             : static int
     118             : fprintf_checkpt( FILE *       file,
     119             :                  char const * path,
     120          15 :                  int          verbose ) {
     121             : 
     122         138 : # define TRAP(x) do { err = (x); if( FD_UNLIKELY( err<0 ) ) { ret = err; goto done; } ret += err; } while(0)
     123             : 
     124         258 : # define TEST(c) do { if( FD_UNLIKELY( !(c) ) ) { err_info = #c; goto stream_err; } } while(0)
     125             : 
     126         306 : # define RESTORE_ULONG(v) do {                               \
     127         306 :     err = fd_wksp_private_restore_ulong( restore, &v );      \
     128         306 :     if( FD_UNLIKELY( err ) ) { err_info = #v; goto io_err; } \
     129         306 :   } while(0)
     130             : 
     131         135 : # define RESTORE_CSTR(v,max) do {                                         \
     132         135 :     err = fd_wksp_private_restore_buf( restore, v, (max)-1UL, &v##_len ); \
     133         135 :     if( FD_UNLIKELY( err ) ) { err_info = #v; goto io_err; }              \
     134         135 :     v[v##_len] = '\0';                                                    \
     135         135 :   } while(0)
     136             : 
     137          15 : # define RBUF_ALIGN     (4096UL)
     138          15 : # define RBUF_FOOTPRINT (65536UL)
     139             : 
     140          15 :   int                        fd      = -1;
     141          15 :   fd_io_buffered_istream_t * restore = NULL;
     142          15 :   int                        ret     = 0;
     143          15 :   int                        err;
     144          15 :   char const *               err_info;
     145          15 :   uchar                      rbuf[ RBUF_FOOTPRINT ] __attribute__((aligned( RBUF_ALIGN )));
     146          15 :   fd_io_buffered_istream_t   _restore[1];
     147             : 
     148          15 :   TRAP( fprintf( file, "checkpt %s (verbose %i)\n", path, verbose ) );
     149             : 
     150          15 :   fd = open( path, O_RDONLY, (mode_t)0 );
     151          15 :   if( FD_UNLIKELY( fd==-1 ) ) TRAP( fprintf( file, "\topen(O_RDONLY) failed (%i-%s)\n", errno, fd_io_strerror( errno ) ) );
     152             : 
     153          15 :   restore = fd_io_buffered_istream_init( _restore, fd, rbuf, RBUF_FOOTPRINT );
     154             : 
     155          15 :   ulong magic;    RESTORE_ULONG( magic    );                                  TEST( magic   ==FD_WKSP_MAGIC      );
     156          15 :   ulong style_ul; RESTORE_ULONG( style_ul ); int style = (int)(uint)style_ul; TEST( style_ul==(ulong)(uint)style );
     157             : 
     158          15 :   TRAP( fprintf( file,
     159          15 :                  "\tcheckpt_magic  %016lx\n"
     160          15 :                  "\tcheckpt_style  %i\n"
     161          15 :                  , magic, style ) );
     162             : 
     163          15 :   switch( style ) {
     164             : 
     165          15 :   case FD_WKSP_CHECKPT_STYLE_RAW: {
     166             : 
     167             :     /* Print out checkpt metadata */
     168             : 
     169          15 :     ulong seed_ul;   RESTORE_ULONG( seed_ul   ); uint seed = (uint)seed_ul; TEST( seed_ul==(ulong)seed                    );
     170          15 :     ulong part_max;  RESTORE_ULONG( part_max  );
     171          15 :     ulong data_max;  RESTORE_ULONG( data_max  );                            TEST( fd_wksp_footprint( part_max, data_max ) );
     172             : 
     173          15 :     ulong ts_ul;     RESTORE_ULONG( ts_ul     ); long ts = (long)ts_ul;     TEST( ts_ul==(ulong)ts                        );
     174          15 :     ulong app_id;    RESTORE_ULONG( app_id    );
     175          15 :     ulong thread_id; RESTORE_ULONG( thread_id );
     176          15 :     ulong host_id;   RESTORE_ULONG( host_id   );
     177          15 :     ulong cpu_id;    RESTORE_ULONG( cpu_id    );
     178          15 :     ulong group_id;  RESTORE_ULONG( group_id  );                            TEST( group_id>=2UL                           );
     179          15 :     ulong tid;       RESTORE_ULONG( tid       );
     180          15 :     ulong user_id;   RESTORE_ULONG( user_id   );
     181             : 
     182          15 :     char name[ FD_SHMEM_NAME_MAX ]; ulong name_len; RESTORE_CSTR( name, FD_SHMEM_NAME_MAX );
     183          15 :     TEST( fd_shmem_name_len( name )==name_len );
     184             : 
     185          15 :     char app   [ FD_LOG_NAME_MAX ]; ulong app_len;    RESTORE_CSTR( app,    FD_LOG_NAME_MAX ); TEST( strlen( app    )==app_len    );
     186          15 :     char thread[ FD_LOG_NAME_MAX ]; ulong thread_len; RESTORE_CSTR( thread, FD_LOG_NAME_MAX ); TEST( strlen( thread )==thread_len );
     187          15 :     char host  [ FD_LOG_NAME_MAX ]; ulong host_len;   RESTORE_CSTR( host,   FD_LOG_NAME_MAX ); TEST( strlen( host   )==host_len   );
     188          15 :     char cpu   [ FD_LOG_NAME_MAX ]; ulong cpu_len;    RESTORE_CSTR( cpu,    FD_LOG_NAME_MAX ); TEST( strlen( cpu    )==cpu_len    );
     189          15 :     char group [ FD_LOG_NAME_MAX ]; ulong group_len;  RESTORE_CSTR( group,  FD_LOG_NAME_MAX ); TEST( strlen( group  )==group_len  );
     190          15 :     char user  [ FD_LOG_NAME_MAX ]; ulong user_len;   RESTORE_CSTR( user,   FD_LOG_NAME_MAX ); TEST( strlen( user   )==user_len   );
     191             : 
     192          15 :     char ts_cstr[ FD_LOG_WALLCLOCK_CSTR_BUF_SZ ]; fd_log_wallclock_cstr( ts, ts_cstr );
     193          15 :     TRAP( fprintf( file,
     194          15 :                    "\tcheckpt_ts     %-20li \"%s\"\n"
     195          15 :                    "\tcheckpt_app    %-20lu \"%s\"\n"
     196          15 :                    "\tcheckpt_thread %-20lu \"%s\"\n"
     197          15 :                    "\tcheckpt_host   %-20lu \"%s\"\n"
     198          15 :                    "\tcheckpt_cpu    %-20lu \"%s\"\n"
     199          15 :                    "\tcheckpt_group  %-20lu \"%s\"\n"
     200          15 :                    "\tcheckpt_tid    %-20lu\n"
     201          15 :                    "\tcheckpt_user   %-20lu \"%s\"\n"
     202          15 :                    , ts, ts_cstr, app_id, app, thread_id, thread,
     203          15 :                    host_id, host, cpu_id, cpu, group_id, group, tid, user_id, user ) );
     204             : 
     205          15 :     char buf[ 16384 ]; ulong buf_len;
     206          15 :     RESTORE_CSTR( buf, 16384UL ); TEST( strlen( buf )==buf_len );
     207          15 :     if( verbose>1 ) TRAP( fprintf( file, "\tcheckpt_build  \"%s\"\n", buf ) );
     208             : 
     209          15 :     RESTORE_CSTR( buf, 16384UL ); TEST( strlen( buf )==buf_len );
     210          15 :     TRAP( fprintf( file,
     211          15 :                    "\tcheckpt_info   \"%s\"\n"
     212          15 :                    "\tshmem_name     \"%s\"\n"
     213          15 :                    , buf, name ) );
     214             : 
     215          15 :     if( verbose>0 ) {
     216             : 
     217          12 :       TRAP( fprintf( file,
     218          12 :                      "\tseed           %-20u\n"
     219          12 :                      "\tpart_max       %-20lu\n"
     220          12 :                      "\tdata_max       %-20lu\n"
     221          12 :                      , seed, part_max, data_max ) );
     222             : 
     223          12 :       ulong data_lo = fd_wksp_private_data_off( part_max );
     224          12 :       ulong data_hi = data_lo + data_max;
     225             : 
     226          12 :       if( verbose>1 ) TRAP( fprintf( file, "\tgaddr          [0x%016lx,0x%016lx)\n", data_lo, data_hi ) );
     227             : 
     228          12 :       ulong alloc_tot = 0UL;
     229          12 :       ulong alloc_cnt = 0UL;
     230          12 :       ulong alloc_big = 0UL;
     231             : 
     232          12 :       ulong free_tot  = 0UL;
     233          12 :       ulong free_cnt  = 0UL;
     234          12 :       ulong free_big  = 0UL;
     235             : 
     236          12 :       ulong free_lo   = data_lo;
     237          45 :       for(;;) {
     238          45 :         ulong tag;      RESTORE_ULONG( tag      ); if( !tag ) break;
     239          33 :         ulong gaddr_lo; RESTORE_ULONG( gaddr_lo );
     240          33 :         ulong sz;       RESTORE_ULONG( sz       );
     241             : 
     242          33 :         ulong gaddr_hi = gaddr_lo + sz;
     243             : 
     244          33 :         TEST( (data_lo<=gaddr_lo) & (gaddr_lo<gaddr_hi) & (gaddr_hi<=data_hi) );
     245             : 
     246             :         /* Print out free partition details (implied) */
     247          33 :         if( free_lo<gaddr_lo ) {
     248           9 :           ulong free_sz = gaddr_lo - free_lo;
     249           9 :           if( verbose>1 )
     250           6 :             TRAP( fprintf( file, "\tpartition      [0x%016lx,0x%016lx) sz %20lu tag %20lu\n", free_lo, gaddr_lo, free_sz, 0UL ) );
     251           9 :           free_tot += free_sz;
     252           9 :           free_cnt += 1UL;
     253           9 :           free_big  = fd_ulong_max( free_big, free_sz );
     254           9 :         }
     255          33 :         free_lo = gaddr_hi;
     256             : 
     257             :         /* Print out allocated partition details (explicit) */
     258          33 :         if( verbose>1 )
     259          21 :           TRAP( fprintf( file, "\tpartition      [0x%016lx,0x%016lx) sz %20lu tag %20lu\n", gaddr_lo, gaddr_hi, sz, tag ) );
     260          33 :         alloc_cnt += 1UL;
     261          33 :         alloc_tot += sz;
     262          33 :         alloc_big  = fd_ulong_max( alloc_big, sz );
     263             : 
     264             :         /* Skip over partition data */
     265          33 :         int err = fd_io_buffered_istream_skip( restore, sz );
     266          33 :         if( FD_UNLIKELY( err ) ) { err_info = "partition data"; goto io_err; }
     267          33 :       }
     268             : 
     269             :       /* Print out any last free partition details (implied) */
     270          12 :       if( free_lo<data_hi ) {
     271          12 :         ulong free_sz = data_hi - free_lo;
     272          12 :         if( verbose>1 )
     273           9 :           TRAP( fprintf( file, "\tpartition      [0x%016lx,0x%016lx) sz %20lu tag %20lu\n", free_lo, data_hi, free_sz, 0UL ) );
     274          12 :         free_tot += free_sz;
     275          12 :         free_cnt += 1UL;
     276          12 :         free_big  = fd_ulong_max( free_big, free_sz );
     277          12 :       }
     278             : 
     279          12 :       TRAP( fprintf( file, "\t%20lu bytes used (%20lu blocks, largest %20lu bytes)\n"
     280          12 :                            "\t%20lu bytes free (%20lu blocks, largest %20lu bytes)\n"
     281          12 :                            "\t%20lu errors detected\n"
     282          12 :                            , alloc_tot, alloc_cnt, alloc_big, free_tot, free_cnt, free_big, 0UL /* no err if we got here */ ) );
     283          12 :     }
     284             : 
     285          15 :     break;
     286          15 :   } /* FD_WKSP_CHECKPT_STYLE_RAW */
     287             : 
     288          15 :   default:
     289           0 :     err_info = "unsupported style";
     290           0 :     goto stream_err;
     291          15 :   }
     292             : 
     293          15 : done:
     294          15 :   if( FD_LIKELY( restore ) ) fd_io_buffered_istream_fini( restore );
     295          15 :   if( FD_LIKELY( fd!=-1  ) ) close( fd ); /* TODO: Consider trapping (but we might be in a fprintf err) */
     296          15 :   fflush( file ); /* TODO: Consider trapping (but we might be in a fprintf err) */
     297          15 :   return ret;
     298             : 
     299           0 : io_err:
     300           0 :   if( err<0 ) TRAP( fprintf( file, "\tFAIL: io: %s (unexpected end of file)\n", err_info ) );
     301           0 :   else        TRAP( fprintf( file, "\tFAIL: io: %s (%i-%s)\n", err_info, err, fd_io_strerror( err ) ) );
     302           0 :   goto done;
     303             : 
     304           0 : stream_err:
     305           0 :   TRAP( fprintf( file, "\tFAIL: stream: %s\n", err_info ) );
     306           0 :   goto done;
     307             : 
     308           0 : # undef RBUF_FOOTPRINT
     309           0 : # undef RBUF_ALIGN
     310           0 : # undef RESTORE_CSTR
     311           0 : # undef RESTORE_ULONG
     312           0 : # undef TEST
     313           0 : # undef TRAP
     314             : 
     315           0 : }
     316             : 
     317             : int
     318             : main( int     argc,
     319         108 :       char ** argv ) {
     320         108 :   fd_boot( &argc, &argv );
     321         765 : # define SHIFT(n) argv+=(n),argc-=(n)
     322             : 
     323         108 :   if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "no arguments" ));
     324         108 :   char const * bin = argv[0];
     325         108 :   SHIFT(1);
     326             : 
     327         108 :   umask( (mode_t)0 ); /* So mode setting gets respected */
     328             : 
     329         108 :   ulong tag = 1UL;
     330             : 
     331         108 :   int cnt = 0;
     332         438 :   while( argc ) {
     333         330 :     char const * cmd = argv[0];
     334         330 :     SHIFT(1);
     335             : 
     336         330 :     if( !strcmp( cmd, "help" ) ) {
     337             : 
     338           3 :       fputs( fd_wksp_ctl_help, stdout );
     339             : 
     340           3 :       FD_LOG_NOTICE(( "%i: %s: success", cnt, cmd ));
     341             : 
     342         327 :     } else if( !strcmp( cmd, "tag" ) ) {
     343             : 
     344          12 :       if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     345             : 
     346          12 :       tag = fd_cstr_to_ulong( argv[0] );
     347             : 
     348          12 :       FD_LOG_NOTICE(( "%i: %s %lu: success", cnt, cmd, tag ));
     349          12 :       SHIFT(1);
     350             : 
     351         315 :     } else if( !strcmp( cmd, "new" ) ) {
     352             : 
     353          18 :       if( FD_UNLIKELY( argc<5 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     354             : 
     355          18 :       char const * name     =                           argv[0];
     356          18 :       ulong        page_cnt = fd_cstr_to_ulong        ( argv[1] );
     357          18 :       ulong        page_sz  = fd_cstr_to_shmem_page_sz( argv[2] );
     358          18 :       char const * seq      =                           argv[3];
     359          18 :       ulong        mode     = fd_cstr_to_ulong_octal  ( argv[4] );
     360             : 
     361             :       /* Partition the pages over the seq */
     362             : 
     363          18 :       ulong sub_page_cnt[ 512 ];
     364          18 :       ulong sub_cpu_idx [ 512 ];
     365          18 :       ulong sub_cnt = fd_cstr_to_ulong_seq( seq, sub_cpu_idx, 512UL );
     366             : 
     367          18 :       if( FD_UNLIKELY( !sub_cnt ) )
     368           0 :         FD_LOG_ERR(( "%i: %s %s %lu %s %s 0%03lo: empty or invalid cpu sequence\n\t"
     369          18 :                      "Do %s help for help", cnt, cmd, name, page_cnt, argv[2], seq, mode, bin ));
     370             : 
     371          18 :       if( FD_UNLIKELY( sub_cnt>512UL ) )
     372           0 :         FD_LOG_ERR(( "%i: %s %s %lu %s %s 0%03lo: sequence too long, increase limit in fd_wksp_ctl.c\n\t"
     373          18 :                      "Do %s help for help", cnt, cmd, name, page_cnt, argv[2], seq, mode, bin ));
     374             : 
     375          18 :       ulong sub_page_min = page_cnt / sub_cnt;
     376          18 :       ulong sub_page_rem = page_cnt % sub_cnt;
     377          36 :       for( ulong sub_idx=0UL; sub_idx<sub_cnt; sub_idx++ ) sub_page_cnt[ sub_idx ] = sub_page_min + (ulong)(sub_idx<sub_page_rem);
     378             : 
     379             :       /* Create the workspace */
     380             : 
     381             :       /* TODO: allow user to specify seed and/or part_max */
     382          18 :       int err = fd_wksp_new_named( name, page_sz, sub_cnt, sub_page_cnt, sub_cpu_idx, mode, 0U, 0UL ); /* logs details */
     383          18 :       if( FD_UNLIKELY( err ) )
     384           0 :         FD_LOG_ERR(( "%i: %s %s %lu %s %s 0%03lo: fd_wksp_new_named failed (%i-%s)\n\t"
     385          18 :                      "Do %s help for help", cnt, cmd, name, page_cnt, argv[2], seq, mode, err, fd_wksp_strerror( err ), bin ));
     386             : 
     387          18 :       FD_LOG_NOTICE(( "%i: %s %s %lu %s %s 0%03lo: success", cnt, cmd, name, page_cnt, argv[2], seq, mode ));
     388          18 :       SHIFT(5);
     389             : 
     390         297 :     } else if( !strcmp( cmd, "delete" ) ) {
     391             : 
     392          18 :       if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     393             : 
     394          18 :       char const * name = argv[0];
     395             : 
     396          18 :       int err = fd_wksp_delete_named( name );
     397          18 :       if( FD_UNLIKELY( err ) )
     398           0 :         FD_LOG_ERR(( "%i: %s %s: fd_wksp_delete_named failed (%i-%s)\n\t"
     399          18 :                      "Do %s help for help", cnt, cmd, name, err, fd_wksp_strerror( err ), bin ));
     400             : 
     401          18 :       FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, name ));
     402          18 :       SHIFT(1);
     403             : 
     404         279 :     } else if( !strcmp( cmd, "alloc" ) ) {
     405             : 
     406          27 :       if( FD_UNLIKELY( argc<3 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     407             : 
     408          27 :       char const * name  =                   argv[0];
     409          27 :       ulong        align = fd_cstr_to_ulong( argv[1] );
     410          27 :       ulong        sz    = fd_cstr_to_ulong( argv[2] );
     411             : 
     412          27 :       char name_gaddr[ FD_WKSP_CSTR_MAX ];
     413          27 :       if( !fd_wksp_cstr_alloc( name, align, sz, tag, name_gaddr ) ) /* logs details */
     414           0 :         FD_LOG_ERR(( "%i: %s %s %lu %lu %lu: fd_wksp_cstr_alloc failed", cnt, cmd, name, align, sz, tag ));
     415          27 :       printf( "%s\n", name_gaddr );
     416             : 
     417          27 :       FD_LOG_NOTICE(( "%i: %s %s %lu %lu: success", cnt, cmd, name, align, sz ));
     418          27 :       SHIFT(3);
     419             : 
     420         252 :     } else if( !strcmp( cmd, "info" ) ) {
     421             : 
     422          21 :       if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     423             : 
     424          21 :       char const * name =                   argv[0];
     425          21 :       ulong        tag  = fd_cstr_to_ulong( argv[1] );
     426             : 
     427          21 :       fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
     428          21 :       if( FD_LIKELY( wksp ) ) {
     429          18 :         fd_wksp_tag_query_info_t info[1];
     430          18 :         ulong tag_cnt = tag ? fd_wksp_tag_query( wksp, &tag, 1UL, info, 1UL ) : 0UL; /* logs details */
     431          18 :         if( tag_cnt ) printf( "%s:%lu %lu\n", name, info->gaddr_lo, info->gaddr_hi - info->gaddr_lo );
     432           9 :         else          printf( "- 0\n" );
     433          18 :         fd_wksp_detach( wksp ); /* logs details */
     434          18 :       }
     435             : 
     436          21 :       FD_LOG_NOTICE(( "%i: %s %s %lu: success", cnt, cmd, name, tag ));
     437          21 :       SHIFT(2);
     438             : 
     439         231 :     } else if( !strcmp( cmd, "free" ) ) {
     440             : 
     441           9 :       if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     442             : 
     443           9 :       char const * name_gaddr = argv[0];
     444             : 
     445           9 :       fd_wksp_cstr_free( name_gaddr ); /* logs details */
     446             : 
     447           9 :       FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, name_gaddr )); /* FIXME: HMMM (print success on bad free?) */
     448           9 :       SHIFT(1);
     449             : 
     450         222 :     } else if( !strcmp( cmd, "tag-query" ) ) {
     451             : 
     452          15 :       if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     453             : 
     454          15 :       char const * name_gaddr = argv[0];
     455             : 
     456          15 :       printf( "%lu\n", fd_wksp_cstr_tag( name_gaddr ) ); /* logs details */
     457             : 
     458          15 :       FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, name_gaddr ));
     459          15 :       SHIFT(1);
     460             : 
     461         207 :     } else if( !strcmp( cmd, "tag-free" ) ) {
     462             : 
     463          21 :       if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     464             : 
     465          21 :       char const * name =                   argv[0];
     466          21 :       ulong        tag  = fd_cstr_to_ulong( argv[1] );
     467             : 
     468          21 :       fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
     469          21 :       if( FD_LIKELY( wksp ) ) {
     470          18 :         fd_wksp_tag_free( wksp, &tag, 1UL ); /* logs details */
     471          18 :         fd_wksp_detach( wksp );              /* logs details */
     472          18 :       }
     473             : 
     474          21 :       FD_LOG_NOTICE(( "%i: %s %s %lu: success", cnt, cmd, name, tag ));
     475          21 :       SHIFT(2);
     476             : 
     477         186 :     } else if( !strcmp( cmd, "memset" ) ) {
     478             : 
     479           6 :       if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     480             : 
     481           6 :       char const * name_gaddr =                 argv[0];
     482           6 :       int          c          = fd_cstr_to_int( argv[1] );
     483             : 
     484           6 :       fd_wksp_cstr_memset( name_gaddr, c ); /* logs details */
     485             : 
     486           6 :       FD_LOG_NOTICE(( "%i: %s %s %i: success", cnt, cmd, name_gaddr, c ));
     487           6 :       SHIFT(2);
     488             : 
     489         180 :     } else if( !strcmp( cmd, "check" ) ) {
     490             : 
     491          66 :       if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     492             : 
     493          66 :       char const * name = argv[0];
     494             : 
     495          66 :       fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
     496          66 :       if( FD_UNLIKELY( !wksp ) ) FD_LOG_ERR(( "%i: %s %s: wksp_attach failed", cnt, cmd, name ));
     497             : 
     498          66 :       if( FD_UNLIKELY( fd_wksp_private_lock( wksp ) ) ) FD_LOG_ERR(( "%i: %s %s: failed", cnt, cmd, name )); /* logs details */
     499          66 :       fd_wksp_private_unlock( wksp );
     500             : 
     501          66 :       fd_wksp_detach( wksp ); /* logs details */
     502             : 
     503          66 :       FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, name ));
     504          66 :       SHIFT(1);
     505             : 
     506         114 :     } else if( !strcmp( cmd, "verify" ) ) {
     507             : 
     508           3 :       if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     509             : 
     510           3 :       char const * name = argv[0];
     511             : 
     512           3 :       fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
     513           3 :       if( FD_UNLIKELY( !wksp ) ) FD_LOG_ERR(( "%i: %s %s: wksp_attach failed", cnt, cmd, name ));
     514             : 
     515           3 :       if( FD_UNLIKELY( fd_wksp_private_lock( wksp ) ) || /* logs details */
     516           3 :           FD_UNLIKELY( fd_wksp_verify( wksp )       ) )  /* logs details */
     517           0 :         FD_LOG_ERR(( "%i: %s %s: failed", cnt, cmd, name ));
     518           3 :       fd_wksp_private_unlock( wksp );
     519             : 
     520           3 :       fd_wksp_detach( wksp ); /* logs details */
     521             : 
     522           3 :       FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, name ));
     523           3 :       SHIFT(1);
     524             : 
     525         111 :     } else if( !strcmp( cmd, "rebuild" ) ) {
     526             : 
     527           6 :       if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     528             : 
     529           6 :       char const * name  = argv[0];
     530           6 :       char const * _seed = argv[1];
     531             : 
     532           6 :       fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
     533           6 :       if( FD_UNLIKELY( !wksp ) ) FD_LOG_ERR(( "%i: %s %s %s: wksp_attach failed", cnt, cmd, name, _seed ));
     534             : 
     535           6 :       uint seed = strcmp( _seed, "-" ) ? fd_cstr_to_uint( _seed ) : fd_wksp_seed( wksp );
     536             : 
     537           6 :       if( FD_UNLIKELY( fd_wksp_private_lock( wksp )  ) || /* logs details */
     538           6 :           FD_UNLIKELY( fd_wksp_rebuild( wksp, seed ) ) )  /* logs details */
     539           0 :         FD_LOG_ERR(( "%i: %s %s %u: failed", cnt, cmd, name, seed ));
     540           6 :       fd_wksp_private_unlock( wksp );
     541             : 
     542           6 :       fd_wksp_detach( wksp ); /* logs details */
     543             : 
     544           6 :       FD_LOG_NOTICE(( "%i: %s %s %u: success", cnt, cmd, name, seed ));
     545           6 :       SHIFT(2);
     546             : 
     547         105 :     } else if( !strcmp( cmd, "reset" ) ) {
     548             : 
     549          12 :       if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     550             : 
     551          12 :       char const * name = argv[0];
     552             : 
     553          12 :       fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
     554          12 :       if( FD_UNLIKELY( !wksp ) ) FD_LOG_ERR(( "%i: %s %s: wksp_attach failed", cnt, cmd, name ));
     555          12 :       fd_wksp_reset( wksp, fd_wksp_seed( wksp ) ); /* logs details */
     556          12 :       fd_wksp_detach( wksp ); /* logs details */
     557             : 
     558          12 :       FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, name ));
     559          12 :       SHIFT(1);
     560             : 
     561          93 :     } else if( !strcmp( cmd, "usage" ) ) {
     562             : 
     563          12 :       if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     564             : 
     565          12 :       char const * name =                   argv[0];
     566          12 :       ulong        tag  = fd_cstr_to_ulong( argv[1] );
     567             : 
     568          12 :       fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
     569          12 :       if( FD_UNLIKELY( !wksp ) ) fprintf( stdout, "-\n" );
     570           9 :       else {
     571           9 :         fd_wksp_usage_t usage[1];
     572           9 :         fd_wksp_usage( wksp, &tag, 1UL, usage );
     573           9 :         fprintf( stdout,
     574           9 :                  "wksp %s\n"
     575           9 :                  "\t%20lu bytes max        (%lu blocks, %lu blocks max)\n"
     576           9 :                  "\t%20lu bytes used       (%lu blocks)\n"
     577           9 :                  "\t%20lu bytes avail      (%lu blocks)\n"
     578           9 :                  "\t%20lu bytes w/tag %4lu (%lu blocks)\n",
     579           9 :                  wksp->name,
     580           9 :                  usage->total_sz,                  usage->total_cnt,                   usage->total_max,
     581           9 :                  usage->total_sz - usage->free_sz, usage->total_cnt - usage->free_cnt,
     582           9 :                  usage->free_sz,                   usage->free_cnt,
     583           9 :                  usage->used_sz, tag,              usage->used_cnt );
     584           9 :         fd_wksp_detach( wksp ); /* logs details */
     585           9 :       }
     586             : 
     587          12 :       FD_LOG_NOTICE(( "%i: %s %s %lu: success", cnt, cmd, name, tag ));
     588          12 :       SHIFT(2);
     589             : 
     590          81 :     } else if( !strcmp( cmd, "query" ) ) {
     591             : 
     592          36 :       if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     593             : 
     594          36 :       char const * name = argv[0];
     595             : 
     596          36 :       fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
     597          36 :       if( FD_UNLIKELY( !wksp ) ) FD_LOG_ERR(( "%i: %s %s: wksp_attach failed", cnt, cmd, name ));
     598          36 :       fprintf_wksp( stdout, wksp ); /* logs details */
     599          36 :       fd_wksp_detach( wksp ); /* logs details */
     600             : 
     601          36 :       FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, name ));
     602          36 :       SHIFT(1);
     603             : 
     604          45 :     } else if( !strcmp( cmd, "checkpt" ) ) {
     605             : 
     606           9 :       if( FD_UNLIKELY( argc<5 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     607             : 
     608           9 :       char const * name  =                         argv[0];
     609           9 :       char const * path  =                         argv[1];
     610           9 :       ulong        mode  = fd_cstr_to_ulong_octal( argv[2] );
     611           9 :       int          style = fd_cstr_to_int        ( argv[3] );
     612           9 :       char const * info  =                         argv[4];
     613             : 
     614           9 :       fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
     615           9 :       if( FD_UNLIKELY( !wksp ) )
     616           0 :         FD_LOG_ERR(( "%i: %s %s %s 0%03lo %i ...: wksp_attach failed", cnt, cmd, name, path, mode, style ));
     617             : 
     618           9 :       int err = fd_wksp_checkpt( wksp, path, mode, style, info ); /* logs details */
     619           9 :       if( FD_UNLIKELY( err ) )
     620           0 :         FD_LOG_ERR(( "%i: %s %s %s 0%03lo %i ...: fd_wksp_checkpt failed", cnt, cmd, name, path, mode, style ));
     621             : 
     622           9 :       fd_wksp_detach( wksp ); /* logs details */
     623             : 
     624           9 :       FD_LOG_NOTICE(( "%i: %s %s %s 0%03lo %i ...: success", cnt, cmd, name, path, mode, style ));
     625           9 :       SHIFT(5);
     626             : 
     627          36 :     } else if( !strcmp( cmd, "checkpt-query" ) ) {
     628             : 
     629          15 :       if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     630             : 
     631          15 :       char const * path    =                 argv[0];
     632          15 :       int          verbose = fd_cstr_to_int( argv[1] );
     633             : 
     634          15 :       fprintf_checkpt( stdout, path, verbose );
     635             : 
     636          15 :       FD_LOG_NOTICE(( "%i: %s %s %i: success", cnt, cmd, path, verbose ));
     637          15 :       SHIFT(2);
     638             : 
     639          21 :     } else if( !strcmp( cmd, "restore" ) ) {
     640             : 
     641          21 :       if( FD_UNLIKELY( argc<3 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     642             : 
     643          21 :       char const * name  = argv[0];
     644          21 :       char const * path  = argv[1];
     645          21 :       char const * _seed = argv[2];
     646             : 
     647          21 :       fd_wksp_t * wksp = fd_wksp_attach( name ); /* logs details */
     648          21 :       if( FD_UNLIKELY( !wksp ) ) FD_LOG_ERR(( "%i: %s %s %s %s: wksp_attach failed", cnt, cmd, name, path, _seed ));
     649             : 
     650          21 :       uint seed = strcmp( _seed, "-" ) ? fd_cstr_to_uint( _seed ) : fd_wksp_seed( wksp );
     651             : 
     652          21 :       int err = fd_wksp_restore( wksp, path, seed ); /* logs details */
     653          21 :       if( FD_UNLIKELY( err ) ) FD_LOG_ERR(( "%i: %s %s %s %u: fd_wksp_restore failed", cnt, cmd, name, path, seed ));
     654             : 
     655          21 :       fd_wksp_detach( wksp ); /* logs details */
     656             : 
     657          21 :       FD_LOG_NOTICE(( "%i: %s %s %s %u: success", cnt, cmd, name, path, seed ));
     658          21 :       SHIFT(3);
     659             : 
     660          21 :     } else {
     661             : 
     662           0 :       FD_LOG_ERR(( "%i: %s: unknown command\n\t"
     663           0 :                    "Do %s help for help", cnt, cmd, bin ));
     664             : 
     665           0 :     }
     666         330 :     cnt++;
     667         330 :   }
     668             : 
     669         108 :   if( FD_UNLIKELY( cnt<1 ) ) FD_LOG_NOTICE(( "processed %i commands\n\tDo %s help for help", cnt, bin ));
     670         105 :   else                       FD_LOG_NOTICE(( "processed %i commands", cnt ));
     671             : 
     672         108 : # undef SHIFT
     673         108 :   fd_halt();
     674         108 :   return 0;
     675         108 : }
     676             : 
     677             : #else
     678             : 
     679             : int
     680             : main( int     argc,
     681             :       char ** argv ) {
     682             :   fd_boot( &argc, &argv );
     683             :   if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "No arguments" ));
     684             :   if( FD_UNLIKELY( argc>1 ) ) FD_LOG_ERR(( "fd_wksp_ctl not supported on this platform" ));
     685             :   FD_LOG_NOTICE(( "processed 0 commands" ));
     686             :   fd_halt();
     687             :   return 0;
     688             : }
     689             : 
     690             : #endif

Generated by: LCOV version 1.14