LCOV - code coverage report
Current view: top level - util/wksp - fd_wksp_restore_v1.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 246 305 80.7 %
Date: 2025-01-08 12:08:44 Functions: 4 4 100.0 %

          Line data    Source code
       1             : #include "fd_wksp_private.h"
       2             : 
       3             : #include <stdio.h>
       4             : #include <errno.h>
       5             : #include <unistd.h>
       6             : #include <fcntl.h>
       7             : #include <sys/stat.h>
       8             : 
       9             : /* fd_wksp_private_restore_ulong restores a ulong from the stream in.
      10             :    Returns 0 on success and, on return, *_val will contain the restored
      11             :    val.  Returns non-zero on failure (will be an errno compat error
      12             :    code) and, on failure, *_val will be zero.  This will implicitly read
      13             :    ahead for future restores. */
      14             : 
      15             : static int
      16             : fd_wksp_private_restore_v1_ulong( fd_io_buffered_istream_t * in,
      17         981 :                                   ulong *                    _val ) {
      18         981 :   ulong         csz;
      19         981 :   uchar const * buf;
      20         981 :   uchar         _buf[9UL];
      21             : 
      22             :   /* Read the encoded val */
      23             : 
      24         981 :   ulong peek_sz = fd_io_buffered_istream_peek_sz( in );
      25             : 
      26         981 :   if( FD_LIKELY( peek_sz>=9UL ) ) { /* encoded val already prefetched */
      27         906 :     buf = fd_io_buffered_istream_peek( in );
      28         906 :     csz = fd_ulong_svw_dec_sz( buf );
      29         906 :     fd_io_buffered_istream_seek( in, csz );
      30         906 :   } else { /* encoded val not guaranteed prefetched (this will also implicitly prefetch for future restores) */
      31          75 :     int err;
      32          75 :     err = fd_io_buffered_istream_read( in, _buf,     1UL     ); if( FD_UNLIKELY( err ) ) { *_val = 0UL; return err; }
      33          75 :     csz = fd_ulong_svw_dec_sz( _buf );
      34          75 :     err = fd_io_buffered_istream_read( in, _buf+1UL, csz-1UL ); if( FD_UNLIKELY( err ) ) { *_val = 0UL; return err; }
      35          75 :     buf = _buf;
      36          75 :   }
      37             : 
      38             :   /* Decode encoded val */
      39             : 
      40         981 :   *_val = fd_ulong_svw_dec_fixed( buf, csz );
      41         981 :   return 0;
      42         981 : }
      43             : 
      44             : /* fd_wksp_private_restore_buf restores a variable length buffer buf of
      45             :    maximum size buf_max from the stream in.  Returns 0 on success and,
      46             :    on success, buf will contain the buffer and *_buf_sz will contain the
      47             :    buffer's size (will be in [0,buf_max]).  Returns non-zero on failure
      48             :    (will be an errno compat error code) and, on failure, buf will be
      49             :    clobbered and *_buf_sz will be zero.  This will implicitly read ahead
      50             :    for future restores.  Zero buf_max is fine (and NULL buf is fine if
      51             :    buf_max is zero). */
      52             : 
      53             : static int
      54             : fd_wksp_private_restore_v1_buf( fd_io_buffered_istream_t * in,
      55             :                                 void *                     buf,
      56             :                                 ulong                      buf_max,
      57         378 :                                 ulong *                    _buf_sz ) {
      58             : 
      59             :   /* Restore buf_sz */
      60             : 
      61         378 :   ulong buf_sz;
      62         378 :   int   err = fd_wksp_private_restore_v1_ulong( in, &buf_sz );
      63         378 :   if( FD_UNLIKELY( (!!err) | (buf_sz>buf_max) ) ) { /* I/O error, unexpected EOF, or buf_max too small */
      64           0 :     if( !!err ) err = EPROTO; /* cmov */
      65           0 :     *_buf_sz = 0UL;
      66           0 :     return err;
      67           0 :   }
      68             : 
      69             :   /* Restore buf */
      70             : 
      71         378 :   err = fd_io_buffered_istream_read( in, buf, buf_sz );
      72         378 :   *_buf_sz = fd_ulong_if( !err, buf_sz, 0UL );
      73         378 :   return err;
      74         378 : }
      75             : 
      76         603 : #define RESTORE_ULONG(v) do {                                \
      77         603 :     err = fd_wksp_private_restore_v1_ulong( restore, &v );   \
      78         603 :     if( FD_UNLIKELY( err ) ) { err_info = #v; goto io_err; } \
      79         603 :   } while(0)
      80             : 
      81             : /* Note: on success, v_len==strlen( v ) and will be in [0,max).  Assumes
      82             :    max is positive. */
      83             : 
      84         378 : #define RESTORE_CSTR(v,max) do {                                              \
      85         378 :     err = fd_wksp_private_restore_v1_buf( restore, v, (max)-1UL, &v##_len );  \
      86         378 :     if( FD_UNLIKELY( err ) ) { err_info = #v; goto io_err; }                  \
      87         378 :     v[v##_len] = '\0'; /* v##_len in [0,max) at this point */                 \
      88         378 :     if( FD_UNLIKELY( strlen( v )!=v##_len ) ) { err_info = #v; goto io_err; } \
      89         378 :   } while(0)
      90             : 
      91             : #define RBUF_ALIGN     (4096UL)
      92          42 : #define RBUF_FOOTPRINT (65536UL)
      93             : 
      94             : int
      95             : fd_wksp_private_restore_v1( fd_tpool_t * tpool,
      96             :                             ulong        t0,
      97             :                             ulong        t1,
      98             :                             fd_wksp_t *  wksp,
      99             :                             char const * path,
     100          21 :                             uint         new_seed ) {
     101          21 :   (void)tpool; (void)t0; (void)t1; /* Note: Thread parallel v1 checkpoint not supported */
     102             : 
     103          21 :   FD_LOG_INFO(( "Restore checkpt \"%s\" into wksp \"%s\" (seed %u)", path, wksp->name, new_seed ));
     104             : 
     105          21 :   int fd = open( path, O_RDONLY, (mode_t)0 );
     106          21 :   if( FD_UNLIKELY( fd==-1 ) ) {
     107           0 :     FD_LOG_WARNING(( "open(\"%s\",O_RDONLY,0) failed (%i-%s)", path, errno, fd_io_strerror( errno ) ));
     108           0 :     return FD_WKSP_ERR_FAIL;
     109           0 :   }
     110             : 
     111          21 :   uchar                    rbuf[ RBUF_FOOTPRINT ] __attribute__((aligned( RBUF_ALIGN )));
     112          21 :   fd_io_buffered_istream_t restore[1];
     113          21 :   fd_io_buffered_istream_init( restore, fd, rbuf, RBUF_FOOTPRINT );
     114             : 
     115          21 :   int err;
     116             : 
     117          21 :   err = fd_wksp_private_lock( wksp ); if( FD_UNLIKELY( err ) ) goto fini; /* logs details */
     118             : 
     119          21 :   ulong                     wksp_part_max = wksp->part_max;
     120          21 :   ulong                     wksp_data_max = wksp->data_max;
     121          21 :   ulong                     wksp_data_lo  = wksp->gaddr_lo;
     122          21 :   ulong                     wksp_data_hi  = wksp->gaddr_hi;
     123          21 :   fd_wksp_private_pinfo_t * wksp_pinfo    = fd_wksp_private_pinfo( wksp );
     124          21 :   int                       wksp_dirty    = 0;
     125             : 
     126          21 :   char const * err_info;
     127             : 
     128         114 : # define RESTORE_TEST(c) do { if( FD_UNLIKELY( !(c) ) ) { err_info = #c; goto stream_err; } } while(0)
     129             : 
     130          21 :   ulong orig_part_max;
     131          21 :   ulong orig_data_max;
     132             : 
     133          21 :   {
     134          21 :     FD_LOG_INFO(( "Restore header (v1)" ));
     135             : 
     136          21 :     ulong magic;     RESTORE_ULONG( magic     );
     137          21 :     ulong style_ul;  RESTORE_ULONG( style_ul  );
     138          21 :     ulong seed_ul;   RESTORE_ULONG( seed_ul   );
     139          21 :     ulong part_max;  RESTORE_ULONG( part_max  );
     140          21 :     ulong data_max;  RESTORE_ULONG( data_max  );
     141          21 :     ulong ts_ul;     RESTORE_ULONG( ts_ul     ); /* considered metadata */
     142          21 :     ulong app_id;    RESTORE_ULONG( app_id    ); /* " */
     143          21 :     ulong thread_id; RESTORE_ULONG( thread_id ); /* " */
     144          21 :     ulong host_id;   RESTORE_ULONG( host_id   ); /* " */
     145          21 :     ulong cpu_id;    RESTORE_ULONG( cpu_id    ); /* " */
     146          21 :     ulong group_id;  RESTORE_ULONG( group_id  ); /* " */
     147          21 :     ulong tid;       RESTORE_ULONG( tid       ); /* " */
     148          21 :     ulong user_id;   RESTORE_ULONG( user_id   ); /* " */
     149             : 
     150          21 :     char name[ FD_SHMEM_NAME_MAX ]; ulong name_len; RESTORE_CSTR( name, FD_SHMEM_NAME_MAX );
     151             : 
     152          21 :     RESTORE_TEST( magic==FD_WKSP_MAGIC                                   );
     153          21 :     RESTORE_TEST( style_ul==(ulong)FD_WKSP_CHECKPT_STYLE_V1              );
     154          21 :     RESTORE_TEST( seed_ul==(ulong)(uint)seed_ul                          );
     155          21 :     RESTORE_TEST( fd_wksp_footprint( part_max, data_max )>0UL            );
     156          21 :     RESTORE_TEST( (name_len>0UL) & (fd_shmem_name_len( name )==name_len) );
     157             : 
     158          21 :     FD_LOG_INFO(( "Restore metadata (v1)" ));
     159             : 
     160          21 :     char ts_cstr[ FD_LOG_WALLCLOCK_CSTR_BUF_SZ ];
     161          21 :     fd_log_wallclock_cstr( (long)ts_ul, ts_cstr );
     162             : 
     163          21 :     char app   [ FD_LOG_NAME_MAX              ]; ulong app_len;    RESTORE_CSTR( app,    FD_LOG_NAME_MAX              );
     164          21 :     char thread[ FD_LOG_NAME_MAX              ]; ulong thread_len; RESTORE_CSTR( thread, FD_LOG_NAME_MAX              );
     165          21 :     char host  [ FD_LOG_NAME_MAX              ]; ulong host_len;   RESTORE_CSTR( host,   FD_LOG_NAME_MAX              );
     166          21 :     char cpu   [ FD_LOG_NAME_MAX              ]; ulong cpu_len;    RESTORE_CSTR( cpu,    FD_LOG_NAME_MAX              );
     167          21 :     char group [ FD_LOG_NAME_MAX              ]; ulong group_len;  RESTORE_CSTR( group,  FD_LOG_NAME_MAX              );
     168          21 :     char user  [ FD_LOG_NAME_MAX              ]; ulong user_len;   RESTORE_CSTR( user,   FD_LOG_NAME_MAX              );
     169          21 :     char binfo [ FD_WKSP_CHECKPT_V1_BINFO_MAX ]; ulong binfo_len;  RESTORE_CSTR( binfo,  FD_WKSP_CHECKPT_V1_BINFO_MAX );
     170          21 :     char uinfo [ FD_WKSP_CHECKPT_V1_UINFO_MAX ]; ulong uinfo_len;  RESTORE_CSTR( uinfo,  FD_WKSP_CHECKPT_V1_UINFO_MAX );
     171             : 
     172             :     /* Note: this mirrors v2 */
     173             : 
     174          21 :     FD_LOG_INFO(( "\n"
     175          21 :                   "\tstyle                  %-20i\n"       /* verbose 0 info */
     176          21 :                   "\tname                   %s\n"
     177          21 :                   "\tseed                   %-20u\n"
     178          21 :                   "\tpart_max               %-20lu\n"
     179          21 :                   "\tdata_max               %-20lu\n"
     180          21 :                   "\tmagic                  %016lx\n"      /* verbose 1 info */
     181          21 :                   "\twallclock              %-20li (%s)\n"
     182          21 :                   "\tapp                    %-20lu (%s)\n"
     183          21 :                   "\tthread                 %-20lu (%s)\n"
     184          21 :                   "\thost                   %-20lu (%s)\n"
     185          21 :                   "\tcpu                    %-20lu (%s)\n"
     186          21 :                   "\tgroup                  %-20lu (%s)\n"
     187          21 :                   "\ttid                    %-20lu\n"
     188          21 :                   "\tuser                   %-20lu (%s)\n"
     189          21 :                   "\tbinfo\n\t\t%s\n"                     /* verbose 2 info */
     190          21 :                   "\tuinfo\n\t\t%s",
     191          21 :                   (int)style_ul, name, (uint)seed_ul, part_max, data_max,
     192          21 :                   magic, (long)ts_ul, ts_cstr,
     193          21 :                   app_id,    app,
     194          21 :                   thread_id, thread,
     195          21 :                   host_id,   host,
     196          21 :                   cpu_id,    cpu,
     197          21 :                   group_id,  group,
     198          21 :                   tid,
     199          21 :                   user_id,   user,
     200          21 :                   binfo,
     201          21 :                   uinfo ));
     202             : 
     203          21 :     orig_part_max = part_max;
     204          21 :     orig_data_max = data_max;
     205          21 :   }
     206             : 
     207          21 :   FD_LOG_INFO(( "Restore allocations" ));
     208             : 
     209          21 :   ulong orig_data_lo  = fd_wksp_private_data_off( orig_part_max );
     210          21 :   ulong orig_data_hi  = orig_data_lo + orig_data_max;
     211          21 :   ulong wksp_part_cnt = 0UL;
     212             : 
     213          30 :   for(;;) {
     214             : 
     215             :     /* Restore the allocation header */
     216             : 
     217          30 :     ulong tag;      RESTORE_ULONG( tag      ); if( FD_UNLIKELY( !tag ) ) break; /* Optimize for lots of partitions */
     218           9 :     ulong gaddr_lo; RESTORE_ULONG( gaddr_lo );
     219           9 :     ulong sz;       RESTORE_ULONG( sz       );
     220             : 
     221           9 :     ulong gaddr_hi = gaddr_lo + sz;
     222             : 
     223           9 :     RESTORE_TEST( (orig_data_lo<=gaddr_lo) & (gaddr_lo<gaddr_hi) & (gaddr_hi<=orig_data_hi) );
     224             : 
     225           9 :     if( FD_UNLIKELY( wksp_part_cnt>=wksp_part_max ) ) {
     226           0 :       FD_LOG_WARNING(( "Restore \"%s\" to wksp \"%s\" failed because too few wksp partitions (part_max checkpt %lu, wksp %lu)",
     227           0 :                        path, wksp->name, orig_part_max, wksp_part_max ));
     228           0 :       goto unlock;
     229           0 :     }
     230             : 
     231           9 :     if( FD_UNLIKELY( !((wksp_data_lo<=gaddr_lo) & (gaddr_hi<=wksp_data_hi)) ) ) {
     232           0 :       FD_LOG_WARNING(( "Restore \"%s\" to wksp \"%s\" failed because checkpt partition [0x%016lx,0x%016lx) tag %lu "
     233           0 :                        "does not fit into wksp data region [0x%016lx,0x%016lx) (data_max checkpt %lu, wksp %lu)",
     234           0 :                        path, wksp->name, gaddr_lo, gaddr_hi, tag, wksp_data_lo, wksp_data_hi, orig_data_max, wksp_data_max ));
     235           0 :       goto unlock;
     236           0 :     }
     237             : 
     238             :     /* Restore the allocation payload into the wksp and record this
     239             :        allocation in the wksp */
     240             : 
     241           9 :     wksp_dirty = 1;
     242             : 
     243             :     #if FD_HAS_DEEPASAN
     244             :     /* Poison the restored allocations. Potentially under poison to respect
     245             :        manual poisoning alignment requirements. Don't poison if the allocation
     246             :        is smaller than FD_ASAN_ALIGN. */
     247             :     ulong laddr_lo = (ulong)fd_wksp_laddr_fast( wksp, gaddr_lo );
     248             :     ulong laddr_hi = laddr_lo + sz;
     249             :     ulong aligned_laddr_lo = fd_ulong_align_up( laddr_lo, FD_ASAN_ALIGN );
     250             :     ulong aligned_laddr_hi = fd_ulong_align_dn( laddr_hi, FD_ASAN_ALIGN );
     251             :     if( aligned_laddr_lo < aligned_laddr_hi ) {
     252             :       fd_asan_poison( (void*)aligned_laddr_lo, aligned_laddr_hi - aligned_laddr_lo );
     253             :     }
     254             :     #endif
     255             : 
     256           9 :     err = fd_io_buffered_istream_read( restore, fd_wksp_laddr_fast( wksp, gaddr_lo ), sz );
     257           9 :     if( FD_UNLIKELY( err ) ) {
     258           0 :       FD_LOG_WARNING(( "Restore \"%s\" to wksp \"%s\" failed because of I/O error (%i-%s)",
     259           0 :                        path, wksp->name, err, fd_io_strerror( err ) ));
     260           0 :       goto unlock;
     261           0 :     }
     262             : 
     263           9 :     wksp_pinfo[ wksp_part_cnt ].gaddr_lo = gaddr_lo;
     264           9 :     wksp_pinfo[ wksp_part_cnt ].gaddr_hi = gaddr_hi;
     265           9 :     wksp_pinfo[ wksp_part_cnt ].tag      = tag;
     266           9 :     wksp_part_cnt++;
     267           9 :   }
     268             : 
     269          21 :   FD_LOG_INFO(( "Rebuilding wksp with restored allocations" ));
     270             : 
     271          21 :   wksp_dirty = 1;
     272             : 
     273      343740 :   for( ulong i=wksp_part_cnt; i<wksp_part_max; i++ ) wksp_pinfo[ i ].tag = 0UL; /* Remove all remaining old allocations */
     274          21 :   err = fd_wksp_rebuild( wksp, new_seed ); /* logs details */
     275          21 :   if( FD_UNLIKELY( err ) ) { /* wksp dirty */
     276           0 :     FD_LOG_WARNING(( "Restore \"%s\" to wksp \"%s\" failed because of rebuild error", path, wksp->name ));
     277           0 :     goto unlock;
     278           0 :   }
     279             : 
     280          21 :   wksp_dirty = 0;
     281             : 
     282          21 :   FD_LOG_INFO(( "Restore successful" ));
     283             : 
     284             :   /* err = 0 at this point */
     285             : 
     286          21 : unlock: /* note: wksp locked at this point */
     287             : 
     288             :   /* If wksp is not clean, reset it to get it back to a clean state */
     289             : 
     290          21 :   if( wksp_dirty ) {
     291           0 :     FD_LOG_WARNING(( "wksp \"%s\" dirty; attempting to reset it and continue", wksp->name ));
     292           0 :     for( ulong i=0UL; i<wksp_part_max; i++ ) wksp_pinfo[ i ].tag = 0UL;
     293           0 :     fd_wksp_rebuild( wksp, new_seed ); /* logs details */
     294           0 :     err = FD_WKSP_ERR_CORRUPT;
     295           0 :   }
     296             : 
     297          21 :   fd_wksp_private_unlock( wksp );
     298             : 
     299          21 : fini: /* Note: wksp unlocked at this point */
     300             : 
     301          21 :   fd_io_buffered_istream_fini( restore );
     302             : 
     303          21 :   if( FD_UNLIKELY( close( fd ) ) )
     304           0 :     FD_LOG_WARNING(( "close(\"%s\") failed (%i-%s); attempting to continue", path, errno, fd_io_strerror( errno ) ));
     305             : 
     306          21 :   return err;
     307             : 
     308           0 : io_err: /* Note: wksp locked at this point */
     309             : 
     310           0 :   FD_LOG_WARNING(( "Restore \"%s\" to wksp \"%s\" failed (%s) due to I/O error (%i-%s)",
     311           0 :                    path, wksp->name, err_info, err, fd_io_strerror( err ) ));
     312           0 :   err = FD_WKSP_ERR_FAIL;
     313             : 
     314           0 :   goto unlock;
     315             : 
     316           0 : stream_err: /* Note: wksp locked at this point */
     317             : 
     318           0 :   FD_LOG_WARNING(( "Restore \"%s\" to wksp \"%s\" failed due to checkpt format error (%s)", path, wksp->name, err_info ));
     319           0 :   err = FD_WKSP_ERR_FAIL;
     320             : 
     321           0 :   goto unlock;
     322             : 
     323          21 : # undef RESTORE_TEST
     324          21 : }
     325             : 
     326             : int
     327             : fd_wksp_private_printf_v1( int          out,
     328             :                            char const * path,
     329          21 :                            int          verbose ) {
     330             : 
     331          54 : # define TRAP(x)         do { err = (x); if( FD_UNLIKELY( err<0 ) ) { ret = err; goto done; } ret += err; } while(0)
     332         105 : # define RESTORE_TEST(c) do { if( FD_UNLIKELY( !(c) ) ) { err_info = #c; goto stream_err; } } while(0)
     333             : 
     334          21 :   int                        fd      = -1;
     335          21 :   fd_io_buffered_istream_t * restore = NULL;
     336          21 :   int                        ret     = 0;
     337          21 :   int                        err;
     338          21 :   char const *               err_info;
     339          21 :   uchar                      rbuf[ RBUF_FOOTPRINT ] __attribute__((aligned( RBUF_ALIGN )));
     340          21 :   fd_io_buffered_istream_t   _restore[1];
     341             : 
     342          21 :   fd = open( path, O_RDONLY, (mode_t)0 );
     343          21 :   if( FD_UNLIKELY( fd==-1 ) ) TRAP( dprintf( out, "\topen(O_RDONLY) failed (%i-%s)\n", errno, fd_io_strerror( errno ) ) );
     344             : 
     345          21 :   restore = fd_io_buffered_istream_init( _restore, fd, rbuf, RBUF_FOOTPRINT );
     346             : 
     347             :   /* Print the header and metadata (note: fd_wksp_private_printf
     348             :      already printed the preview info and verbose is at least 1) */
     349             : 
     350          21 :   ulong orig_part_max;
     351          21 :   ulong orig_data_max;
     352             : 
     353          21 :   {
     354          21 :     ulong magic;     RESTORE_ULONG( magic     );
     355          21 :     ulong style_ul;  RESTORE_ULONG( style_ul  );
     356          21 :     ulong seed_ul;   RESTORE_ULONG( seed_ul   );
     357          21 :     ulong part_max;  RESTORE_ULONG( part_max  );
     358          21 :     ulong data_max;  RESTORE_ULONG( data_max  );
     359          21 :     ulong ts_ul;     RESTORE_ULONG( ts_ul     ); /* considered metadata */
     360          21 :     ulong app_id;    RESTORE_ULONG( app_id    ); /* " */
     361          21 :     ulong thread_id; RESTORE_ULONG( thread_id ); /* " */
     362          21 :     ulong host_id;   RESTORE_ULONG( host_id   ); /* " */
     363          21 :     ulong cpu_id;    RESTORE_ULONG( cpu_id    ); /* " */
     364          21 :     ulong group_id;  RESTORE_ULONG( group_id  ); /* " */
     365          21 :     ulong tid;       RESTORE_ULONG( tid       ); /* " */
     366          21 :     ulong user_id;   RESTORE_ULONG( user_id   ); /* " */
     367             : 
     368          21 :     char name[ FD_SHMEM_NAME_MAX ]; ulong name_len; RESTORE_CSTR( name, FD_SHMEM_NAME_MAX );
     369             : 
     370          21 :     RESTORE_TEST( magic==FD_WKSP_MAGIC                                   );
     371          21 :     RESTORE_TEST( style_ul==(ulong)FD_WKSP_CHECKPT_STYLE_V1              );
     372          21 :     RESTORE_TEST( seed_ul==(ulong)(uint)seed_ul                          );
     373          21 :     RESTORE_TEST( fd_wksp_footprint( part_max, data_max )>0UL            );
     374          21 :     RESTORE_TEST( (name_len>0UL) & (fd_shmem_name_len( name )==name_len) );
     375             : 
     376          21 :     char app   [ FD_LOG_NAME_MAX              ]; ulong app_len;    RESTORE_CSTR( app,    FD_LOG_NAME_MAX              );
     377          21 :     char thread[ FD_LOG_NAME_MAX              ]; ulong thread_len; RESTORE_CSTR( thread, FD_LOG_NAME_MAX              );
     378          21 :     char host  [ FD_LOG_NAME_MAX              ]; ulong host_len;   RESTORE_CSTR( host,   FD_LOG_NAME_MAX              );
     379          21 :     char cpu   [ FD_LOG_NAME_MAX              ]; ulong cpu_len;    RESTORE_CSTR( cpu,    FD_LOG_NAME_MAX              );
     380          21 :     char group [ FD_LOG_NAME_MAX              ]; ulong group_len;  RESTORE_CSTR( group,  FD_LOG_NAME_MAX              );
     381          21 :     char user  [ FD_LOG_NAME_MAX              ]; ulong user_len;   RESTORE_CSTR( user,   FD_LOG_NAME_MAX              );
     382          21 :     char binfo [ FD_WKSP_CHECKPT_V1_BINFO_MAX ]; ulong binfo_len;  RESTORE_CSTR( binfo,  FD_WKSP_CHECKPT_V1_BINFO_MAX );
     383          21 :     char uinfo [ FD_WKSP_CHECKPT_V1_UINFO_MAX ]; ulong uinfo_len;  RESTORE_CSTR( uinfo,  FD_WKSP_CHECKPT_V1_UINFO_MAX );
     384             : 
     385          21 :     char ts_cstr[ FD_LOG_WALLCLOCK_CSTR_BUF_SZ ];
     386          21 :     fd_log_wallclock_cstr( (long)ts_ul, ts_cstr );
     387             : 
     388             :     /* Note: this mirrors v2 printf */
     389             : 
     390          21 :     if( verbose>=1 )
     391          21 :       TRAP( dprintf( out,
     392             :                    //"\tstyle                  %-20i\n"        /* verbose 0 info (already printed) */
     393             :                    //"\tname                   %s\n"
     394             :                    //"\tseed                   %-20u\n"
     395             :                    //"\tpart_max               %-20lu\n"
     396             :                    //"\tdata_max               %-20lu\n"
     397          21 :                      "\tmagic                  %016lx\n"       /* verbose 1 info */
     398          21 :                      "\twallclock              %-20li (%s)\n"
     399          21 :                      "\tapp                    %-20lu (%s)\n"
     400          21 :                      "\tthread                 %-20lu (%s)\n"
     401          21 :                      "\thost                   %-20lu (%s)\n"
     402          21 :                      "\tcpu                    %-20lu (%s)\n"
     403          21 :                      "\tgroup                  %-20lu (%s)\n"
     404          21 :                      "\ttid                    %-20lu\n"
     405          21 :                      "\tuser                   %-20lu (%s)\n",
     406          21 :                      magic,
     407          21 :                      (long)ts_ul, ts_cstr,
     408          21 :                      app_id,      app,
     409          21 :                      thread_id,   thread,
     410          21 :                      host_id,     host,
     411          21 :                      cpu_id,      cpu,
     412          21 :                      group_id,    group,
     413          21 :                      tid,
     414          21 :                      user_id,     user ) );
     415          21 :     if( verbose>=2 )
     416          18 :       TRAP( dprintf( out, "\tbinfo\n\t\t%s\n"
     417          21 :                           "\tuinfo\n\t\t%s\n", binfo, uinfo ) ); /* verbose 2 info */
     418             : 
     419          21 :     orig_part_max = part_max;
     420          21 :     orig_data_max = data_max;
     421          21 :   }
     422             : 
     423          21 :   if( verbose>=3 ) {
     424             : 
     425           9 :     ulong orig_data_lo = fd_wksp_private_data_off( orig_part_max );
     426           9 :     ulong orig_data_hi = orig_data_lo + orig_data_max;
     427             : 
     428           9 :     ulong alloc_tot = 0UL;
     429           9 :     ulong alloc_cnt = 0UL;
     430           9 :     ulong alloc_big = 0UL;
     431             : 
     432           9 :     if( verbose>=4 ) TRAP( dprintf( out, "\tgaddr          [0x%016lx,0x%016lx)\n", orig_data_lo, orig_data_hi ) );
     433             : 
     434           9 :     for(;;) {
     435             : 
     436             :       /* Print partition metadata */
     437             : 
     438           9 :       ulong tag;      RESTORE_ULONG( tag      ); if( !tag ) break; /* no more partitions */
     439           0 :       ulong gaddr_lo; RESTORE_ULONG( gaddr_lo );
     440           0 :       ulong sz;       RESTORE_ULONG( sz       );
     441             : 
     442           0 :       ulong gaddr_hi = gaddr_lo + sz;
     443             : 
     444           0 :       RESTORE_TEST( (orig_data_lo<=gaddr_lo) & (gaddr_lo<gaddr_hi) & (gaddr_hi<=orig_data_hi) );
     445             : 
     446           0 :       if( verbose>=4 ) TRAP( dprintf( out, "\tpartition      [0x%016lx,0x%016lx) sz %20lu tag %20lu\n", gaddr_lo, gaddr_hi, sz, tag ) );
     447             : 
     448           0 :       alloc_cnt += 1UL;
     449           0 :       alloc_tot += sz;
     450           0 :       alloc_big  = fd_ulong_max( alloc_big, sz );
     451             : 
     452             :       /* Skip partition data (TODO: add verbose 5 for pretty printing
     453             :          the raw partition data too). */
     454             : 
     455           0 :       int err = fd_io_buffered_istream_skip( restore, sz );
     456           0 :       if( FD_UNLIKELY( err ) ) { err_info = "partition data"; goto io_err; }
     457           0 :     }
     458             : 
     459           9 :     TRAP( dprintf( out, "\t%20lu bytes used (%20lu blocks, largest %20lu bytes)\n"
     460           9 :                         "\t%20lu bytes free (%20s blocks, largest %20s bytes)\n"
     461           9 :                         "\t%20lu errors detected\n"
     462           9 :                         , alloc_tot, alloc_cnt, alloc_big, orig_data_max-alloc_tot, "-", "-", 0UL /* no err if we got here */ ) );
     463             : 
     464           9 :   }
     465             : 
     466          21 : done:
     467          21 :   if( FD_LIKELY( restore ) ) fd_io_buffered_istream_fini( restore );
     468          21 :   if( FD_LIKELY( fd!=-1  ) ) close( fd ); /* TODO: Consider trapping (but we might be in a dprintf err) */
     469          21 :   return ret;
     470             : 
     471           0 : io_err:
     472           0 :   if( err<0 ) TRAP( dprintf( out, "\tFAIL: io: %s (unexpected end of file)\n", err_info ) );
     473           0 :   else        TRAP( dprintf( out, "\tFAIL: io: %s (%i-%s)\n", err_info, err, fd_io_strerror( err ) ) );
     474           0 :   goto done;
     475             : 
     476           0 : stream_err:
     477           0 :   TRAP( dprintf( fd, "\tFAIL: stream: %s\n", err_info ) );
     478           0 :   goto done;
     479             : 
     480           0 : # undef RESTORE_TEST
     481           0 : # undef TRAP
     482           0 : }
     483             : 
     484             : #undef RBUF_FOOTPRINT
     485             : #undef RBUF_ALIGN
     486             : 
     487             : #undef RESTORE_CSTR
     488             : #undef RESTORE_ULONG

Generated by: LCOV version 1.14