LCOV - code coverage report
Current view: top level - util/checkpt - fd_checkpt.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 49 49 100.0 %
Date: 2025-01-08 12:08:44 Functions: 33 13692 0.2 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_util_checkpt_fd_checkpt_h
       2             : #define HEADER_fd_src_util_checkpt_fd_checkpt_h
       3             : 
       4             : /* APIs for fast parallel compressed checkpoint and restore.  Concepts:
       5             : 
       6             :    - A checkpoint contains of zero or more frames.
       7             : 
       8             :    - Each frame resides in a disjoint contiguous sequence of bytes in
       9             :      the checkpoint and contains a sequence of zero of more data
      10             :      buffers.
      11             : 
      12             :    - Data buffers can have (up to physical limitation) arbitrary
      13             :      variable byte size.
      14             : 
      15             :    - A frame has a style that specifies how data buffers have been
      16             :      encoded into it.
      17             : 
      18             :    - Buffers in a RAW frame are stored verbatim with no gaps.  As such,
      19             :      the space needed for a raw frame and the location of buffers in a
      20             :      raw frame can computed exactly up front.
      21             : 
      22             :    - Buffers in a LZ4 frame are stored via LZ4 streaming compression.  A
      23             :      worst case upper bound for the space needed for a LZ4 frame can be
      24             :      computed up front, roughly:
      25             : 
      26             :        (256/255) total_sz_all_buffers + 19 buffer_count.
      27             : 
      28             :      The location of buffers in LZ4 frame is not practically computable
      29             :      in advance and decompression of a buffer in a frame depends on
      30             :      previous buffers in that frame.
      31             : 
      32             :    - Checkpoints can be read and written in a streaming IO mode or in a
      33             :      memory IO mode with the exact same APIs (i.e. no changes to the
      34             :      calling code outside of specifying the mode when starting a
      35             :      checkpoint or a restore).  The checkpoint and restore processes
      36             :      will produce bit-level identical results regardless of mode.
      37             : 
      38             :    - Frames are independent such that different frames can be generated
      39             :      in parallel.  Each frame generated will be bit-level identical
      40             :      regardless how generation is distributed over threads.
      41             : 
      42             :    - Similarly, frames can restored in parallel.  The restored results
      43             :      will be bit-level identical regardles how restoration is
      44             :      distributed over threads.
      45             : 
      46             :    - As such, arbitrary streaming/mmio serial/parallel operation is fine
      47             :      (e.g. have a single thread write a checkpoint file with streaming
      48             :      I/O and then use multiple threads to restore from that checkpoint
      49             :      file with memory mapped I/O). */
      50             : 
      51             : #include "../log/fd_log.h"
      52             : 
      53             : /* FD_CHECKPT_SUCCESS / FD_CHECKPT_ERR_* are return values from various
      54             :    fd_checkpt APIs.  SUCCESS is zero and ERR_* are negative integers. */
      55             : 
      56     8887512 : #define FD_CHECKPT_SUCCESS   (0)  /* operation was successful */
      57         276 : #define FD_CHECKPT_ERR_INVAL (-1) /* operation failed because bad input arguments */
      58          15 : #define FD_CHECKPT_ERR_UNSUP (-2) /* operation failed because it is unsupported on this target */
      59           9 : #define FD_CHECKPT_ERR_IO    (-3) /* operation failed because an I/O error occurred */
      60           6 : #define FD_CHECKPT_ERR_COMP  (-4) /* operation failed because a compressor/decompressor error occurred */
      61             : 
      62             : /* FD_CHECKPT_FRAME_STYLE_* specify a checkpoint frame style.  These are
      63             :    positive integers. */
      64             : 
      65     4453380 : #define FD_CHECKPT_FRAME_STYLE_RAW (1) /* uncompressed   frame */
      66     3629082 : #define FD_CHECKPT_FRAME_STYLE_LZ4 (2) /* lz4 compressed frame */
      67             : 
      68      844440 : #define FD_CHECKPT_FRAME_STYLE_DEFAULT FD_CHECKPT_FRAME_STYLE_RAW
      69             : 
      70             : /* FD_CHECKPT_META_MAX is the maximum size buffer supported by
      71             :    fd_checkpt_meta.  64 KiB is recommended. */
      72             : 
      73     6912861 : #define FD_CHECKPT_META_MAX (65536UL)
      74             : 
      75             : /* FD_CHECKPT_WBUF_MIN is the minimum write buffer size needed by a
      76             :    fd_checkpt_t in streaming mode.  Must be at least 65813 ~
      77             :      FD_CHECKPT_PRIVATE_CSZ_MAX( FD_CHECKPT_PRIVATE_CHUNK_USZ_MAX ) */
      78             : 
      79          96 : #define FD_CHECKPT_WBUF_MIN (69632UL) /* 68 KiB */
      80             : 
      81             : /* FD_CHECKPT_{ALIGN,FOOTPRINT} give the required {alignment,footprint}
      82             :    of a memory region suitable for use as a fd_checkpt_t. */
      83             : 
      84             : #define FD_CHECKPT_ALIGN     alignof( fd_checkpt_t )
      85             : #define FD_CHECKPT_FOOTPRINT sizeof(  fd_checkpt_t )
      86             : 
      87             : /* A fd_checkpt_t is a semi-opaque handle for an in-progress checkpoint
      88             :    (a stack or global declaration of an fd_checkpt_t is sufficient to
      89             :    get the correct alignment and footprint). */
      90             : 
      91             : struct fd_checkpt_private;
      92             : typedef struct fd_checkpt_private fd_checkpt_t;
      93             : 
      94             : /* FD_RESTORE_META_MAX is the maximum size buffer supported by
      95             :    fd_restore_meta.  Must match FD_CHECKPT_META_MAX currently. */
      96             : 
      97     1727067 : #define FD_RESTORE_META_MAX FD_CHECKPT_META_MAX
      98             : 
      99             : /* FD_RESTORE_RBUF_MIN is the minimum read buffer size needed by a
     100             :    fd_restore_t in streaming mode.  Must be at least
     101             :    FD_CHECKPT_WBUF_MIN. */
     102             : 
     103          66 : #define FD_RESTORE_RBUF_MIN FD_CHECKPT_WBUF_MIN
     104             : 
     105             : /* FD_RESTORE_{ALIGN,FOOTPRINT} give the required {alignment,footprint}
     106             :    of a memory region suitable for use as a fd_restore_t. */
     107             : 
     108             : #define FD_RESTORE_ALIGN     alignof( fd_restore_t )
     109             : #define FD_RESTORE_FOOTPRINT sizeof(  fd_restore_t )
     110             : 
     111             : /* A fd_restore_t is a semi-opaque handle of an in-progress restore (a
     112             :    stack or global declaration of an fd_restore_t is sufficient to get
     113             :    the correct alignment and footprint). */
     114             : 
     115             : struct fd_restore_private;
     116             : typedef struct fd_restore_private fd_restore_t;
     117             : 
     118             : /* Internal use only **************************************************/
     119             : 
     120             : /* These are exposed to facilitate things like stack declaration */
     121             : 
     122             : /* FD_CHECKPT_PRIVATE_CHUNK_USZ_MAX is the maximum amount of checkpt
     123             :    data fed into the underlying compressor at a time.  Should be much
     124             :    less than LZ4_MAX_INPUT_SIZE (and probably much less than 2^24-1).
     125             :    Must be at least FD_CHECKPT_BUF_META_MAX.  64 KiB recommended. */
     126             : 
     127     3456114 : #define FD_CHECKPT_PRIVATE_CHUNK_USZ_MAX (65536UL)
     128             : 
     129             : /* FD_CHECKPT_PRIVATE_CSZ_MAX returns a reasonably tight upper bound to
     130             :    the number of compressed output bytes generated given usz
     131             :    uncompressed input bytes.  Assumes usz is safe against multiple
     132             :    evaluation and usz<=FD_CHECKPT_PRIVATE_CHUNK_USZ_MAX.  (This is the
     133             :    same as LZ4_COMPRESSBOUND plus 3 extra bytes for checkpt related
     134             :    metadata plus ulong typing usz and the usz limit.) */
     135             : 
     136      862899 : #define FD_CHECKPT_PRIVATE_CSZ_MAX(usz) ((usz) + ((usz)/255UL) + 19UL)
     137             : 
     138             : FD_STATIC_ASSERT( FD_CHECKPT_PRIVATE_CHUNK_USZ_MAX <= (1UL<<30), adjust_buf_limits );
     139             : FD_STATIC_ASSERT( FD_CHECKPT_WBUF_MIN >= FD_CHECKPT_PRIVATE_CSZ_MAX( FD_CHECKPT_PRIVATE_CHUNK_USZ_MAX ), adjust_buf_limits );
     140             : FD_STATIC_ASSERT( FD_RESTORE_RBUF_MIN >= FD_CHECKPT_WBUF_MIN, adjust_buf_limits );
     141             : 
     142             : /* FD_CHECKPT_PRIVATE_GBUF_SZ is the size of the checkpt gather buffer.
     143             :    Must be at least 2*META_MAX + 65536 - 1 (the 64KiB is from LZ4). */
     144             : 
     145     3456114 : #define FD_CHECKPT_PRIVATE_GBUF_SZ (2UL*FD_CHECKPT_META_MAX + 65536UL)
     146             : 
     147             : FD_STATIC_ASSERT( FD_CHECKPT_META_MAX        <= FD_CHECKPT_PRIVATE_CHUNK_USZ_MAX,  adjust_buf_limits );
     148             : FD_STATIC_ASSERT( FD_CHECKPT_PRIVATE_GBUF_SZ >= 2UL*FD_CHECKPT_META_MAX + 65535UL, adjust_buf_limits );
     149             : 
     150             : /* FD_RESTORE_PRIVATE_SBUF_SZ similarly gives the configuration for
     151             :    restore scatter optimizations.  This currently need to match the
     152             :    gather configuration. */
     153             : 
     154     1727067 : #define FD_RESTORE_PRIVATE_SBUF_SZ FD_CHECKPT_PRIVATE_GBUF_SZ
     155             : 
     156             : /* fd_checkpt_t internals */
     157             : 
     158             : struct fd_checkpt_private_wbuf { /* very similar to fd_io_buffered_ostream */
     159             :   uchar * mem;  /* Buffer of compressed bytes not yet written to fd, byte indexed [0,wbuf_sz) */
     160             :   ulong   sz;   /* Buffer size in bytes, >=FD_CHECKPT_WBUF_MIN */
     161             :   ulong   used; /* Buffer bytes [0,wbuf_used) are not yet written to fd,
     162             :                    buffer bytes [wbuf_used,wbuf_sz) are free */
     163             : };
     164             : 
     165             : typedef struct fd_checkpt_private_wbuf fd_checkpt_private_wbuf_t;
     166             : 
     167             : struct fd_checkpt_private_mmio {
     168             :   uchar * mem; /* Checkpoint memory region, indexed [0,sz) */
     169             :   ulong   sz;  /* Checkpoint memory region size in bytes */
     170             : };
     171             : 
     172             : typedef struct fd_checkpt_private_mmio fd_checkpt_private_mmio_t;
     173             : 
     174             : struct fd_checkpt_private {
     175             :   int    fd;          /* (stream) File descriptor for the checkpt (>=0), (mmio) -1 */
     176             :   int    frame_style; /* FD_CHECKPT_FRAME_STYLE_* (>0), 0: not in frame (valid), -1: not in frame (failed) */
     177             :   void * lz4;         /* Handle of the underlying compressor */
     178             :   ulong  gbuf_cursor; /* Cursor for small buffer gather optimizations, in [0,FD_CHECKPT_PRIVATE_GBUF_SZ] */
     179             :   ulong  off;         /* Offset of the next byte to write (relative to the checkpoint first byte), in [0,mmio_sz) in mmio mode */
     180             :   union {
     181             :     fd_checkpt_private_wbuf_t wbuf; /* used in streaming mode */
     182             :     fd_checkpt_private_mmio_t mmio; /* used in mmio mode */
     183             :   };
     184             :   uchar gbuf[ FD_CHECKPT_PRIVATE_GBUF_SZ ]; /* gather optimization buffer */
     185             : };
     186             : 
     187             : /* fd_restore_t internals */
     188             : 
     189             : struct fd_restore_private_rbuf { /* very similar to fd_io_buffered_istream */
     190             :   uchar * mem;   /* Buffer of compressed bytes read from fd, byte indexed [0,rbuf_sz) */
     191             :   ulong   sz;    /* Buffer size in bytes, >=FD_RESTORE_RBUF_MIN */
     192             :   ulong   lo;    /* Buffer bytes [0,rbuf_lo) have been read and restored */
     193             :   ulong   ready; /* Number of compressed bytes that haven't been processed, 0<=rbuf_lo<=(rbuf_lo+rbuf_ready)<=rbuf_sz */
     194             : };
     195             : 
     196             : typedef struct fd_restore_private_rbuf fd_restore_private_rbuf_t;
     197             : 
     198             : struct fd_restore_private_mmio {
     199             :   uchar const * mem; /* Checkpoint memory region, indexed [0,sz) */
     200             : };
     201             : 
     202             : typedef struct fd_restore_private_mmio fd_restore_private_mmio_t;
     203             : 
     204             : struct fd_restore_private {
     205             :   int    fd;          /* (stream) File descriptor for the restore (>=0), (mmio) -1 */
     206             :   int    frame_style; /* FD_CHECKPT_FRAME_STYLE_* (>0), 0: not in frame (valid), -1: not in frame (failed) */
     207             :   void * lz4;         /* Handle of the underlying decompressor used */
     208             :   ulong  sbuf_cursor; /* Cursor for small buffer scatter optimizations, in [0,FD_RESTORE_PRIVATE_SBUF_SZ] */
     209             :   ulong  sz;          /* (stream) if seekable, file size, otherwise ULONG_MAX, (mmio) mmio region size */
     210             :   ulong  off;         /* Offset of the next byte to read.  In [0,sz].  Relative to:
     211             :                          (stream) first byte of file if seekable, fd position when initialized otherwise,
     212             :                          (mmio) first byte of mmio region. */
     213             :   union {
     214             :     fd_restore_private_rbuf_t rbuf; /* used in streaming mode */
     215             :     fd_restore_private_mmio_t mmio; /* used in mmio mode */
     216             :   };
     217             :   uchar sbuf[ FD_RESTORE_PRIVATE_SBUF_SZ ]; /* scatter optimization buffer */
     218             : };
     219             : 
     220             : /* End internal use only **********************************************/
     221             : 
     222             : FD_PROTOTYPES_BEGIN
     223             : 
     224             : /* Checkpt APIs *******************************************************/
     225             : 
     226             : /* fd_checkpt_init_stream formats a memory region, mem, with suitable
     227             :    alignment and footprint into a fd_checkpt_t (a pointer to a stack
     228             :    declared fd_checkpt_t is fine).  fd is an open normal-ish file
     229             :    descriptor where the checkpoint should be streamed out.  wbuf points
     230             :    to the first byte in the caller's address space to an unused wbuf_sz
     231             :    byte size memory region to use for write buffering.  wbuf_sz should
     232             :    be at least FD_CHECKPT_WBUF_MIN.
     233             : 
     234             :    On success, returns mem formatted as a fd_checkpt_t in streaming
     235             :    mode.  On return, the fd_checkpt_t will be valid, not in a frame and
     236             :    will have ownership of mem, fd, and wbuf.
     237             : 
     238             :    On failure, returns NULL (logs details).  No ownership changed. */
     239             : 
     240             : fd_checkpt_t *
     241             : fd_checkpt_init_stream( void * mem,
     242             :                         int    fd,
     243             :                         void * wbuf,
     244             :                         ulong  wbuf_sz );
     245             : 
     246             : /* fd_checkpt_init_mmio is the same as fd_checkpt_init_stream but
     247             :    checkpoints frames into a mmio_sz byte sized memory region whose
     248             :    first byte in the caller's local address space is pointed to by mmio. */
     249             : 
     250             : fd_checkpt_t *
     251             : fd_checkpt_init_mmio( void * mem,
     252             :                       void * mmio,
     253             :                       ulong  mmio_sz );
     254             : 
     255             : /* fd_checkpt_fini finishes a checkpoint.  checkpt should be valid and
     256             :    not in a frame.
     257             : 
     258             :    On success, returns mem.  On return, checkpt is no longer valid and
     259             :    the caller will have ownership of mem, fd and wbuf (streaming mode)
     260             :    or mem and mmio (mmio mode).
     261             : 
     262             :    On failure, returns NULL (logs details).  Reasons for failure include
     263             :    NULL checkpt and checkpt in a frame.  The checkpt (and underlying fd
     264             :    in streaming mode) should be considered failed (i.e. checkpt no
     265             :    longer has any interest in checkpointed data and the user should only
     266             :    fini checkpt, close fd in streaming mode and discard the failed
     267             :    checkpoint). */
     268             : 
     269             : void *
     270             : fd_checkpt_fini( fd_checkpt_t * checkpt );
     271             : 
     272             : /* fd_checkpt_is_mmio returns 0/1 if checkpt is in streaming/mmio mode.
     273             :    Assumes checkpt is valid. */
     274             : 
     275     3618696 : FD_FN_PURE static inline int fd_checkpt_is_mmio( fd_checkpt_t const * checkpt ) { return checkpt->fd<0; }
     276             : 
     277             : /* fd_checkpt_{fd,wbuf,wbuf_sz} return the values used to initialize a
     278             :    streaming checkpt.  Assumes checkpt is valid and in streaming mode.  */
     279             : 
     280           3 : FD_FN_PURE static inline int    fd_checkpt_fd     ( fd_checkpt_t const * checkpt ) { return checkpt->fd;       }
     281           3 : FD_FN_PURE static inline void * fd_checkpt_wbuf   ( fd_checkpt_t       * checkpt ) { return checkpt->wbuf.mem; }
     282           3 : FD_FN_PURE static inline ulong  fd_checkpt_wbuf_sz( fd_checkpt_t const * checkpt ) { return checkpt->wbuf.sz;  }
     283             : 
     284             : /* fd_checkpt_{mmio,mmio_sz} return the values used to initialzie a
     285             :    mmio checkpt.  Assumes checkpt is valid and in mmio mode. */
     286             : 
     287           3 : FD_FN_PURE static inline void * fd_checkpt_mmio   ( fd_checkpt_t       * checkpt ) { return checkpt->mmio.mem; }
     288           3 : FD_FN_PURE static inline ulong  fd_checkpt_mmio_sz( fd_checkpt_t const * checkpt ) { return checkpt->mmio.sz;  }
     289             : 
     290             : /* fd_checkpt_{can_open,in_frame} returns 1 if {a frame can be
     291             :    opened,the checkpt is in a frame} and 0 otherwise.  A failed checkpt
     292             :    is not in a frame but cannot open a new frame.  Assumes checkpt is
     293             :    valid. */
     294             : 
     295      422127 : FD_FN_PURE static inline int fd_checkpt_can_open( fd_checkpt_t const * checkpt ) { return !checkpt->frame_style; }
     296     4054812 : FD_FN_PURE static inline int fd_checkpt_in_frame( fd_checkpt_t const * checkpt ) { return checkpt->frame_style>0; }
     297             : 
     298             : /* fd_checkpt_open_advanced opens a new frame.  Different frames in a
     299             :    checkpoint can be restored in parallel.  frame_style is a
     300             :    FD_CHECKPT_FRAME_STYLE_* that specifies the style of frame to write
     301             :    (0 indicates to use FD_CHECKPT_FRAME_STYLE_DEFAULT).  checkpt should
     302             :    be valid and openable (not currently in a frame or failed).
     303             : 
     304             :    On success, returns FD_CHECKPT_SUCCESS (0).  On return, *_off will
     305             :    contain the offset of this frame from the beginning of the
     306             :    checkpoint.  This is to allow parallel restore threads to jump to
     307             :    frames they are assigned to restore.  Retains no interest in _off.
     308             : 
     309             :    On failure, logs details and returns a FD_CHECKPT_ERR (negative).
     310             :    *_off will be untouched.  Retains no interest in _off.  Reasons for
     311             :    failure include INVAL (NULL checkpt, in a frame, failed), UNSUP
     312             :    (unsupported frame style on this target), IO (an i/o error) and COMP
     313             :    (a compressor error).  The checkpt (and underlying fd in streaming
     314             :    mode) should be considered failed (i.e. the checkpt no longer has
     315             :    any interest in checkpointed data and the user should only fini
     316             :    checkpt, close fd in streaming mode and discard the failed
     317             :    checkpoint).
     318             : 
     319             :    IMPORTANT SAFETY TIP!  The returned offset is relative to the start
     320             :    of the _checkpoint_, _not_ the start of the _file_.  These are often
     321             :    the same but do not have to be (e.g. writing a checkpoint to an
     322             :    unseekable file descriptor like stdout, the caller has already
     323             :    written other data to the file descriptor before starting the
     324             :    checkpoint, etc).
     325             : 
     326             :    IMPORTANT SAFETY TIP!  Compression ratios for compressed frames can
     327             :    be optimized by putting similar items into the same frame and then
     328             :    putting more similar items near each other sequentially.
     329             : 
     330             :    fd_checkpt_open is a convenience for when the frame offset isn't
     331             :    needed. */
     332             : 
     333             : int
     334             : fd_checkpt_open_advanced( fd_checkpt_t * checkpt,
     335             :                           int            frame_style,
     336             :                           ulong *        _off );
     337             : 
     338             : static inline int
     339             : fd_checkpt_open( fd_checkpt_t * checkpt,
     340       12078 :                  int            frame_style ) {
     341       12078 :   ulong off;
     342       12078 :   return fd_checkpt_open_advanced( checkpt, frame_style, &off );
     343       12078 : }
     344             : 
     345             : /* fd_checkpt_close_advanced closes the current frame.  checkpt should
     346             :    be valid and in a frame.
     347             : 
     348             :    On success, returns FD_CHECKPT_SUCCESS (0).  On return, *_off will
     349             :    contain the offset of one past the last byte of the just closed
     350             :    frame.  That is, [off_open,off_close) specify the range of bytes
     351             :    relative to the start of the checkpoint used by this frame and
     352             :    off_close-off_open is the frame byte size.  This is to facilitate
     353             :    parallel checkpoint writing and then concatentating results from
     354             :    different threads into a compact checkpoint.  checkpt will no longer
     355             :    have any interest in checkpointed data or in _off.
     356             : 
     357             :    On failure, logs details and returns a FD_CHECKPT_ERR (negative).  On
     358             :    return, *_off will be untouched and checkpoint will have no interest
     359             :    in _off.  Reasons for failure include INVAL (NULL checkpt, not in a
     360             :    frame), IO (write failed, too many bytes written) and COMP (a
     361             :    compressor error).  The checkpt (and underlying fd in streaming mode)
     362             :    should be considered failed (i.e. the checkpt no longer has any
     363             :    interest in checkpointed data and the user should only fini checkpt,
     364             :    close fd in streaming mode and discard the failed checkpoint).
     365             : 
     366             :    fd_checkpt_close is a convenience for when the frame offset isn't
     367             :    needed. */
     368             : 
     369             : int
     370             : fd_checkpt_close_advanced( fd_checkpt_t * checkpt,
     371             :                            ulong *        _off );
     372             : 
     373             : static inline int
     374       12018 : fd_checkpt_close( fd_checkpt_t * checkpt ) {
     375       12018 :   ulong off;
     376       12018 :   return fd_checkpt_close_advanced( checkpt, &off );
     377       12018 : }
     378             : 
     379             : /* fd_checkpt_meta checkpoints the sz byte memory region whose first
     380             :    byte in the caller's local address space is pointed to by buf.
     381             :    checkpt should be valid and in a frame.  sz should be at most
     382             :    FD_CHECKPT_META_MAX.  sz==0 is fine (and buf==NULL if sz==0 is also
     383             :    fine).
     384             : 
     385             :    On success, returns FD_CHECKPT_SUCCESS (0).  On return, checkpt
     386             :    retains no interest in buf.
     387             : 
     388             :    On failure, logs details and returns a FD_CHECKPT_ERR (negative).
     389             :    Reasons for failure include INVAL (NULL checkpt, not in a frame, NULL
     390             :    buf with a non-zero sz, too large sz), IO (write failed, too many
     391             :    bytes written) and COMP (compressor error).  The checkpt (and
     392             :    underlying fd in streaming mode) should be considered failed (i.e.
     393             :    should only fini checkpt, close fd in streaming mode and discard the
     394             :    failed checkpoint). */
     395             : 
     396             : int
     397             : fd_checkpt_meta( fd_checkpt_t * checkpt,
     398             :                  void const *   buf,
     399             :                  ulong          sz );
     400             : 
     401             : /* fd_checkpt_data checkpoints the sz byte memory region whose first
     402             :    byte in the caller's local address space is pointed to by buf.
     403             :    checkpt should be valid and in a frame.  There is no practical limit
     404             :    on sz.  sz==0 is fine (and buf==NULL if sz==0 is also fine).
     405             : 
     406             :    On success, returns FD_CHECKPT_SUCCESS (0).  On return, checkpt
     407             :    retains an interest in buf until the frame is closed (e.g. buf should
     408             :    continue to exist unchanged until the frame is closed).  IMPORTANT
     409             :    SAFETY TIP!  AMONG OTHER THINGS, THIS MEANS IT IS UNSAFE TO GATHER
     410             :    DATA INTO A TEMP BUFFER, CHECKPT THE TEMP BUFFER AND THEN FREE /
     411             :    REUSE THAT TEMP BUFFER BEFORE THE FRAME IS CLOSED!  USE
     412             :    FD_CHECKPT_META FOR THAT.
     413             : 
     414             :    On failure, logs details and returns a FD_CHECKPT_ERR (negative).
     415             :    Reasons for failure include INVAL (NULL checkpt, not in a frame, NULL
     416             :    buf with a non-zero sz), IO (write failed, too many bytes written)
     417             :    and COMP (compressor error).  The checkpt (and underlying fd in
     418             :    streaming mode) should be considered failed (i.e. should only fini
     419             :    checkpt, close fd in streaming mode and discard the failed
     420             :    checkpoint). */
     421             : 
     422             : int
     423             : fd_checkpt_data( fd_checkpt_t * checkpt,
     424             :                  void const *   buf,
     425             :                  ulong          sz );
     426             : 
     427             : /* Restore APIs *******************************************************/
     428             : 
     429             : /* fd_restore_init_stream formats a memory region, mem, with suitable
     430             :    alignment and footprint into a fd_restore_t in streaming mode (a
     431             :    pointer to a stack declared fd_restore_t is fine).  fd is an open
     432             :    normal-ish file descriptor usually positioned at the start of the
     433             :    first checkpoint frame to read.  rbuf points to the first byte in the
     434             :    caller's address space of an unused rbuf_sz byte size memory region
     435             :    to use for read buffering.  rbuf_sz should be at least
     436             :    FD_RESTORE_RBUF_MIN (it does _not_ need to match the wbuf_sz used to
     437             :    make the checkpoint).
     438             : 
     439             :    On success, returns mem formatted as a fd_restore_t.  On return, the
     440             :    fd_restore_t will be valid, not in a frame and will have ownership of
     441             :    mem, fd, and rbuf.
     442             : 
     443             :    On failure, returns NULL (logs details).  No ownership changed. */
     444             : 
     445             : fd_restore_t *
     446             : fd_restore_init_stream( void * mem,
     447             :                         int    fd,
     448             :                         void * rbuf,
     449             :                         ulong  rbuf_sz );
     450             : 
     451             : /* fd_restore_init_mmio is the same as fd_restore_init_stream but the
     452             :    frames to restore have been memory mapped into the mmio_sz byte
     453             :    memory region whose first byte in the caller's local address space is
     454             :    pointed to by mmio. */
     455             : 
     456             : fd_restore_t *
     457             : fd_restore_init_mmio( void *       mem,
     458             :                       void const * mmio,
     459             :                       ulong        mmio_sz );
     460             : 
     461             : /* fd_restore_fini finishes restoring from a checkpoint.  restore should
     462             :    be valid and not in a frame.
     463             : 
     464             :    On success, returns mem.  On return, restore is no longer valid and
     465             :    the caller will have ownership of mem, fd and rbuf (streaming mode)
     466             :    or mem and mmio (mmio mode).
     467             : 
     468             :    On failure, returns NULL (logs details).  Reasons for failure include
     469             :    NULL restore and restore in a frame.  The restore (and underlying fd
     470             :    in streaming mode) should be considered failed (i.e. the restore no
     471             :    longer has any interest in restored data and the user should only
     472             :    fini restore and close fd in streaming mode). */
     473             : 
     474             : void *
     475             : fd_restore_fini( fd_restore_t * restore );
     476             : 
     477             : /* fd_restore_is_mmio returns 0/1 if restore is in streaming/mmio mode.
     478             :    Assumes restore is valid. */
     479             : 
     480     3214512 : FD_FN_PURE static inline int fd_restore_is_mmio( fd_restore_t const * restore ) { return restore->fd<0; }
     481             : 
     482             : /* fd_restore_{fd,rbuf,rbuf_sz} return the values used to initialize a
     483             :    streaming restore.  Assumes restore is valid and in streaming mode.  */
     484             : 
     485           3 : FD_FN_PURE static inline int    fd_restore_fd     ( fd_restore_t const * restore ) { return restore->fd;       }
     486           3 : FD_FN_PURE static inline void * fd_restore_rbuf   ( fd_restore_t       * restore ) { return restore->rbuf.mem; }
     487           3 : FD_FN_PURE static inline ulong  fd_restore_rbuf_sz( fd_restore_t const * restore ) { return restore->rbuf.sz;  }
     488             : 
     489             : /* fd_restore_{mmio,mmio_sz} return the values used to initialzie a
     490             :    mmio restore.  Assumes restore is valid and in mmio mode. */
     491             : 
     492          66 : FD_FN_PURE static inline void const * fd_restore_mmio   ( fd_restore_t const * restore ) { return restore->mmio.mem; }
     493          66 : FD_FN_PURE static inline ulong        fd_restore_mmio_sz( fd_restore_t const * restore ) { return restore->sz;       }
     494             : 
     495             : /* fd_restore_{can_open,in_frame} returns 1 if {a frame can be
     496             :    opened,the restore is in a frame} and 0 otherwise.  A failed restore
     497             :    is not in a frame but cannot open a new frame.  Assumes restore is
     498             :    valid. */
     499             : 
     500      440622 : FD_FN_PURE static inline int fd_restore_can_open( fd_restore_t const * restore ) { return !restore->frame_style; }
     501     4054725 : FD_FN_PURE static inline int fd_restore_in_frame( fd_restore_t const * restore ) { return restore->frame_style>0; }
     502             : 
     503             : /* fd_restore_sz returns the size of the checkpt (mmio mode == mmio_sz
     504             :    <= LONG_MAX, streaming mode with seekable file == fd_io_sz <=
     505             :    LONG_MAX, streaming mode with a non-seekable file == ULONG_MAX).
     506             :    Assumes restore is valid. */
     507             : 
     508          69 : FD_FN_PURE static inline ulong fd_restore_sz( fd_restore_t const * restore ) { return restore->sz; }
     509             : 
     510             : /* fd_restore_open_advanced opens a new frame.  Different frames in a
     511             :    checkpoint can be restored in parallel.  frame_style is a
     512             :    FD_CHECKPT_FRAME_STYLE_* that specifies the style of frame to read (0
     513             :    indicates to use FD_CHECKPT_FRAME_STYLE_DEFAULT).  restore should be
     514             :    valid and openable (not currently in a frame or failed).
     515             : 
     516             :    On success, returns FD_CHECKPT_SUCCESS (0).  On return, *_off will
     517             :    contain the offset of this frame from the beginning of the
     518             :    checkpoint.  Retains no interest in _off.
     519             : 
     520             :    On failure, logs details and returns a FD_CHECKPT_ERR (negative).
     521             :    *_off will be untouched.  Retains no interest in _off.  Reasons for
     522             :    failure include INVAL (NULL restore, in a frame, failed), UNSUP
     523             :    (unsupported frame style on this target), IO (an i/o error) and COMP
     524             :    (a decompressor error).  The restore (and underlying fd in streaming
     525             :    mode) should be considered failed (i.e. the restore no longer has any
     526             :    interest in restored data and the user should only fini restore and
     527             :    close fd in streaming mode).
     528             : 
     529             :    IMPORTANT SAFETY TIP!  The returned offset is relative to the start
     530             :    first byte of the mmio region (mmio mode), first byte of the file
     531             :    (seekable file descriptor) or the stream position when the restore
     532             :    was initialized (unseekable file descriptor).  These are often the
     533             :    same as the first byte of the checkpt but do not have to be (e.g.
     534             :    restoring from a file where data was prepended to the file).
     535             : 
     536             :    IMPORTANT SAFETY TIP!  frame_style should match the frame_style used
     537             :    when the frame was written.
     538             : 
     539             :    IMPORTANT SAFETY TIP!  The sequence of restore_open / restore_meta /
     540             :    restore_data / restore_close calls should _exactly_ match the
     541             :    sequence of checkpt_open / checkpt_meta / checkpt_data /
     542             :    checkpt_close used when the frame was created.
     543             : 
     544             :    fd_restore_open is a convenience for when the frame offset isn't
     545             :    needed. */
     546             : 
     547             : int
     548             : fd_restore_open_advanced( fd_restore_t * restore,
     549             :                           int            frame_style,
     550             :                           ulong *        _off );
     551             : 
     552             : static inline int
     553             : fd_restore_open( fd_restore_t * restore,
     554      421869 :                  int            frame_style ) {
     555      421869 :   ulong off;
     556      421869 :   return fd_restore_open_advanced( restore, frame_style, &off );
     557      421869 : }
     558             : 
     559             : /* fd_restore_close_advanced closes the current frame.  restore should
     560             :    be valid and in a frame.
     561             : 
     562             :    On success, returns FD_CHECKPT_SUCCESS (0).  On return, *_off will
     563             :    contain the offset of one past the last byte of the just closed
     564             :    frame.  That is, [off_open,off_close) specify the range of bytes
     565             :    relative to the first byte of the mmio region (mmio mode), file
     566             :    (streaming mode with a seekable file descriptor) or stream when the
     567             :    restore was initialized (streaming mode with unseekable file
     568             :    descriptor).  The restore will no longer have any interest in
     569             :    restored data or in _off.
     570             : 
     571             :    On failure, logs details and returns a FD_CHECKPT_ERR (negative).
     572             :    Reasons for failure include INVAL (NULL restore, not in a frame), IO
     573             :    (an i/o error) and COMP (a decompressor error).  The restore (and
     574             :    underlying fd in streaming mode) should be considered failed (i.e.
     575             :    the restore no longer has any interest in restored data or _off and
     576             :    the user should only fini restore and close fd in streaming mode).
     577             : 
     578             :    IMPORTANT SAFETY TIP!  The sequence of restore_open / restore_meta /
     579             :    restore_data / restore_close calls should _exactly_ match the
     580             :    sequence of checkpt_open / checkpt_meta / checkpt_data /
     581             :    checkpt_close used when the frame was created.
     582             : 
     583             :    fd_restore_close is a convenience for when the frame offset isn't
     584             :    needed. */
     585             : 
     586             : int
     587             : fd_restore_close_advanced( fd_restore_t * restore,
     588             :                            ulong *        _off );
     589             : 
     590             : static inline int
     591      421797 : fd_restore_close( fd_restore_t * restore ) {
     592      421797 :   ulong off;
     593      421797 :   return fd_restore_close_advanced( restore, &off );
     594      421797 : }
     595             : 
     596             : /* fd_restore_seek sets the restore to the position offset.  restore
     597             :    should be valid, openable and seekable, offset should be in [0,sz].
     598             :    In streaming mode, seeking may flush underlying read-ahead-buffering
     599             :    and thus should be minimized.
     600             : 
     601             :    On success, returns FD_CHECKPT_SUCCESS (0).  On return, the restore
     602             :    will be ready to open the frame at off.
     603             : 
     604             :    On failure, logs details and returns a FD_CHECKPT_ERR (negative).
     605             :    Reasons for failure include INVAL (NULL restore, not openable, not
     606             :    seekable, offset past end of file), IO (underlying error seeking the
     607             :    descriptor) The restore (and underlying fd in streaming mode) should
     608             :    be considered failed (i.e. the restore no longer has any interest in
     609             :    restored data and the user should only fini restore and close fd in
     610             :    streaming mode).
     611             : 
     612             :    IMPORTANT SAFETY TIP!  This offset is relative to the first byte of
     613             :    the mmio region (mmio mode) or the file (streaming mode with a
     614             :    seekable file descriptor). */
     615             : 
     616             : int
     617             : fd_restore_seek( fd_restore_t * restore,
     618             :                  ulong          off );
     619             : 
     620             : /* fd_restore_meta restores sz bytes to the memory region whose first
     621             :    byte in the caller's local address space is pointed to by buf.
     622             :    restore should be valid and in a frame.  sz should be at most
     623             :    FD_RESTORE_META_MAX.  sz==0 is fine (and buf==NULL if sz==0 is also
     624             :    fine).
     625             : 
     626             :    On success, returns FD_CHECKPT_SUCCESS (0).  On return, the restored
     627             :    data will be in buf and the restore retains no interest in buf.
     628             : 
     629             :    On failure, logs details and returns a FD_CHECKPT_ERR (negative).
     630             :    Reasons for failure include INVAL (NULL restore, not in a frame, NULL
     631             :    buf with a non-zero sz, too large sz), IO (read failed, too many
     632             :    bytes read) and COMP (a decompressor error).  The restore (and
     633             :    underlying fd in streaming mode) should be considered failed (i.e.
     634             :    the restore no longer has any interest in restored data and the user
     635             :    should only fini restore and close fd in streaming mode).
     636             : 
     637             :    IMPORTANT SAFETY TIP!  The sequence of restore_open / restore_meta /
     638             :    restore_data / restore_close calls should _exactly_ match the
     639             :    sequence of checkpt_open / checkpt_meta / checkpt_data /
     640             :    checkpt_close used when the frame was created. */
     641             : 
     642             : int
     643             : fd_restore_meta( fd_restore_t * restore,
     644             :                  void *         buf,
     645             :                  ulong          sz );
     646             : 
     647             : /* fd_restore_data restores sz bytes to the memory region whose first
     648             :    byte in the caller's local address space is pointed to by buf.
     649             :    restore should be valid and in a frame.  There is no practical
     650             :    limitation on sz.  sz==0 is fine (and buf==NULL if sz==0 is also
     651             :    fine).
     652             : 
     653             :    On success, returns FD_CHECKPT_SUCCESS (0).  On return, the restore
     654             :    retains an interest in buf until the frame close (e.g. buf should
     655             :    continue to exist and be untouched until the frame close) and the
     656             :    data in it may not be available until frame close.  IMPORTANT SAFETY
     657             :    TIP!  AMONG OTHER THINGS, THIS IMPLIES RESTORED DATA REGIONS SHOULD
     658             :    NOT OVERLAP AND THAT IT IS UNSAFE TO RESTORE DATA TO A TEMP BUFFER,
     659             :    SCATTER DATA FROM THE TEMP BUFFER AND THEN FREE / REUSE THAT TEMP
     660             :    BUFFER BEFORE THE FRAME IS CLOSED!  USE FD_RESTORE_META FOR THIS
     661             :    CASE.
     662             : 
     663             :    On failure, logs details and returns a FD_CHECKPT_ERR (negative).
     664             :    Reasons for failure include INVAL (NULL restore, not in a frame, NULL
     665             :    buf with a non-zero sz), IO (read failed, too many bytes read) and
     666             :    COMP (a decompressor error).  The restore (and underlying fd in
     667             :    streaming mode) should be considered failed (i.e. the restore no
     668             :    longer has any interest in restored data and the user should only
     669             :    fini restore and close fd in streaming mode).
     670             : 
     671             :    IMPORTANT SAFETY TIP!  The sequence of restore_open / restore_meta /
     672             :    restore_data / restore_close calls should _exactly_ match the
     673             :    sequence of checkpt_open / checkpt_meta / checkpt_data /
     674             :    checkpt_close used when the frame was created. */
     675             : 
     676             : int
     677             : fd_restore_data( fd_restore_t * restore,
     678             :                  void *         buf,
     679             :                  ulong          sz );
     680             : 
     681             : /* Misc APIs **********************************************************/
     682             : 
     683             : /* fd_checkpt_frame_style_is_supported returns 1 if the given
     684             :    frame_style is supported on this target and 0 otherwise. */
     685             : 
     686             : FD_FN_CONST int fd_checkpt_frame_style_is_supported( int frame_style );
     687             : 
     688             : /* fd_checkpt_strerror converts a FD_CHECKPT_SUCCESS / FD_CHECKPT_ERR_*
     689             :    code into a human readable cstr.  The lifetime of the returned
     690             :    pointer is infinite.  The returned pointer is always to a non-NULL
     691             :    cstr. */
     692             : 
     693             : char const *
     694             : fd_checkpt_strerror( int err );
     695             : 
     696             : FD_PROTOTYPES_END
     697             : 
     698             : #endif /* HEADER_fd_src_util_checkpt_fd_checkpt_h */

Generated by: LCOV version 1.14