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 */
|