1LIBPMEMLOG(7)              PMDK Programmer's Manual              LIBPMEMLOG(7)
2
3
4

NAME

6       libpmemlog - persistent memory resident log file
7

SYNOPSIS

9              #include <libpmemlog.h>
10              cc ... -lpmemlog -lpmem
11
12   Library API versioning:
13              const char *pmemlog_check_version(
14                  unsigned major_required,
15                  unsigned minor_required);
16
17   Managing library behavior:
18              void pmemlog_set_funcs(
19                  void *(*malloc_func)(size_t size),
20                  void (*free_func)(void *ptr),
21                  void *(*realloc_func)(void *ptr, size_t size),
22                  char *(*strdup_func)(const char *s));
23
24   Error handling:
25              int pmemlog_check(const char *path);
26
27   Other library functions:
28       A description of other libpmemlog functions can be found on the follow‐
29       ing manual pages:
30
31       pmemlog_append(3),   pmemlog_create(3),   pmemlog_ctl_exec(3),    pmem‐
32       log_ctl_get(3), pmemlog_ctl_set(3), pmemlog_nbyte(3), pmemlog_tell(3)
33

DESCRIPTION

35       libpmemlog  provides  a  log file in persistent memory (pmem) such that
36       additions to the log are appended atomically.  This library is intended
37       for  applications  using  direct access storage (DAX), which is storage
38       that supports load/store access without  paging  blocks  from  a  block
39       storage device.  Some types of non-volatile memory DIMMs (NVDIMMs) pro‐
40       vide this type of byte addressable access  to  storage.   A  persistent
41       memory  aware file system is typically used to expose the direct access
42       to applications.  Memory mapping a file from this type of  file  system
43       results in the load/store, non-paged access to pmem.  libpmemlog builds
44       on thistype of memory mapped file.
45
46       This library is for applications that need a persistent log file updat‐
47       ed  atomically (the updates cannot be torn by program interruption such
48       as power failures).  This library builds on the low-level pmem  support
49       provided  by  libpmem(7), handling the transactional update of the log,
50       flushing to persistence, and recovery for the application.
51
52       libpmemlog is one of a collection of persistent memory libraries avail‐
53       able.  The others are:
54
55libpmemobj(7),  a general use persistent memory API, providing memory
56         allocation and transactional operations on variable-sized objects.
57
58libpmemblk(7), providing pmem-resident arrays of  fixed-sized  blocks
59         with atomic updates.
60
61libpmem(7), low-level persistent memory support.
62
63       Under  normal usage, libpmemlog will never print messages or intention‐
64       ally cause the process to exit.  The only exception to this is the  de‐
65       bugging information, when enabled, as described under DEBUGGING AND ER‐
66       ROR HANDLING below.
67
68       To use the pmem-resident log file provided by libpmemlog, a memory pool
69       is  first  created.   This is done with the pmemlog_create(3) function.
70       The other functions mentioned above in SYNOPSIS section then operate on
71       the resulting log memory pool.
72
73       Once  created,  the  memory pool is represented by an opaque handle, of
74       type PMEMlogpool*, which is passed to most of the other functions  from
75       libpmemlog.   Internally, libpmemlog will use either pmem_persist(3) or
76       msync(2) when it needs to flush changes, depending on whether the memo‐
77       ry  pool  appears  to  be  persistent memory or a regular file (see the
78       pmem_is_pmem(3) function in libpmem(7) for more information).  There is
79       no  need  for applications to flush changes directly when using the log
80       memory API provided by libpmemlog.
81

CAVEATS

83       libpmemlog relies on the library destructor being called from the  main
84       thread.   For this reason, all functions that might trigger destruction
85       (e.g.  dlclose(3)) should be called in the main thread.  Otherwise some
86       of  the  resources  associated with that thread might not be cleaned up
87       properly.
88

LIBRARY API VERSIONING

90       This section describes how the library API is versioned,  allowing  ap‐
91       plications to work with an evolving API.
92
93       The  pmemlog_check_version()  function is used to determine whether the
94       installed libpmemlog supports the version of the library  API  required
95       by  an  application.  The easiest way to do this is for the application
96       to supply the compile-time version information provided by  defines  in
97       <libpmemlog.h>, like this:
98
99              reason = pmemlog_check_version(PMEMLOG_MAJOR_VERSION,
100                                             PMEMLOG_MINOR_VERSION);
101              if (reason != NULL) {
102                  /* version check failed, reason string tells you why */
103              }
104
105       Any mismatch in the major version number is considered a failure, but a
106       library with a newer minor version number will pass  this  check  since
107       increasing minor versions imply backwards compatibility.
108
109       An  application can also check specifically for the existence of an in‐
110       terface by checking for the version where  that  interface  was  intro‐
111       duced.   These versions are documented in this man page as follows: un‐
112       less otherwise specified, all interfaces described here  are  available
113       in version 1.0 of the library.  Interfaces added after version 1.0 will
114       contain the text introduced in version x.y in the section of this manu‐
115       al describing the feature.
116
117       On  success,  pmemlog_check_version() returns NULL.  Otherwise, the re‐
118       turn value is a static string describing the reason the  version  check
119       failed.   The  string  returned  by pmemlog_check_version() must not be
120       modified or freed.
121

MANAGING LIBRARY BEHAVIOR

123       The pmemlog_set_funcs() function allows an application to override mem‐
124       ory  allocation  calls  used internally by libpmemlog.  Passing in NULL
125       for any of the handlers will cause the libpmemlog default  function  to
126       be  used.   The  library  does  not make heavy use of the system malloc
127       functions, but it does allocate approximately 4-8  kilobytes  for  each
128       memory pool in use.
129

DEBUGGING AND ERROR HANDLING

131       The  pmemlog_errormsg()  function  returns a pointer to a static buffer
132       containing the last error message logged for the  current  thread.   If
133       errno  was set, the error message may include a description of the cor‐
134       responding error code as returned by strerror(3).   The  error  message
135       buffer  is thread-local; errors encountered in one thread do not affect
136       its value in other threads.  The buffer is never cleared by any library
137       function;  its content is significant only when the return value of the
138       immediately preceding call to a libpmemlog function indicated an error,
139       or if errno was set.  The application must not modify or free the error
140       message string, but it may be modified by subsequent calls to other li‐
141       brary functions.
142
143       Two  versions  of  libpmemlog  are typically available on a development
144       system.  The normal version, accessed when a program  is  linked  using
145       the -lpmemlog option, is optimized for performance.  That version skips
146       checks that impact performance and never logs any trace information  or
147       performs any run-time assertions.
148
149       A  second  version  of libpmemlog, accessed when a program uses the li‐
150       braries under /usr/lib/pmdk_debug,  contains  run-time  assertions  and
151       trace  points.   The  typical way to access the debug version is to set
152       the environment  variable  LD_LIBRARY_PATH  to  /usr/lib/pmdk_debug  or
153       /usr/lib64/pmdk_debug,  as appropriate.  Debugging output is controlled
154       using the following environment variables.  These variables have no ef‐
155       fect on the non-debug version of the library.
156
157PMEMLOG_LOG_LEVEL
158
159       The  value  of PMEMLOG_LOG_LEVEL enables trace points in the debug ver‐
160       sion of the library, as follows:
161
1620 - This is the default level when PMEMLOG_LOG_LEVEL is not set.   No
163         log messages are emitted at this level.
164
1651 - Additional details on any errors detected are logged, in addition
166         to returning the errno-based errors as usual.  The  same  information
167         may be retrieved using pmemlog_errormsg().
168
1692 - A trace of basic operations is logged.
170
1713 - Enables a very verbose amount of function call tracing in the li‐
172         brary.
173
1744 - Enables voluminous and fairly obscure tracing information that is
175         likely only useful to the libpmemlog developers.
176
177       Unless PMEMLOG_LOG_FILE is set, debugging output is written to stderr.
178
179PMEMLOG_LOG_FILE
180
181       Specifies  the name of a file name where all logging information should
182       be written.  If the last character in the name is “-”, the PID  of  the
183       current  process will be appended to the file name when the log file is
184       created.  If PMEMLOG_LOG_FILE is not set, logging output is written  to
185       stderr.
186
187       See  also  libpmem(7) for information about other environment variables
188       affecting libpmemlog behavior.
189

EXAMPLE

191       The following example illustrates how the libpmemlog API is used.
192
193              #include <stdio.h>
194              #include <fcntl.h>
195              #include <errno.h>
196              #include <stdlib.h>
197              #include <unistd.h>
198              #include <string.h>
199              #include <libpmemlog.h>
200
201              /* size of the pmemlog pool -- 1 GB */
202              #define POOL_SIZE ((size_t)(1 << 30))
203
204              /*
205               * printit -- log processing callback for use with pmemlog_walk()
206               */
207              int
208              printit(const void *buf, size_t len, void *arg)
209              {
210                  fwrite(buf, len, 1, stdout);
211                  return 0;
212              }
213
214              int
215              main(int argc, char *argv[])
216              {
217                  const char path[] = "/pmem-fs/myfile";
218                  PMEMlogpool *plp;
219                  size_t nbyte;
220                  char *str;
221
222                  /* create the pmemlog pool or open it if it already exists */
223                  plp = pmemlog_create(path, POOL_SIZE, 0666);
224
225                  if (plp == NULL)
226                      plp = pmemlog_open(path);
227
228                  if (plp == NULL) {
229                      perror(path);
230                      exit(1);
231                  }
232
233                  /* how many bytes does the log hold? */
234                  nbyte = pmemlog_nbyte(plp);
235                  printf("log holds %zu bytes", nbyte);
236
237                  /* append to the log... */
238                  str = "This is the first string appended";
239                  if (pmemlog_append(plp, str, strlen(str)) < 0) {
240                      perror("pmemlog_append");
241                      exit(1);
242                  }
243                  str = "This is the second string appended";
244                  if (pmemlog_append(plp, str, strlen(str)) < 0) {
245                      perror("pmemlog_append");
246                      exit(1);
247                  }
248
249                  /* print the log contents */
250                  printf("log contains:");
251                  pmemlog_walk(plp, 0, printit, NULL);
252
253                  pmemlog_close(plp);
254              }
255
256       See <https://pmem.io/pmdk/libpmemlog> for more examples using the libp‐
257       memlog API.
258

BUGS

260       Unlike  libpmemobj(7), data replication is not supported in libpmemlog.
261       Thus, specifying replica sections in pool set files is not allowed.
262

ACKNOWLEDGEMENTS

264       libpmemlog builds on the persistent memory programming model recommend‐
265       ed    by    the    SNIA   NVM   Programming   Technical   Work   Group:
266       <https://snia.org/nvmp>
267

SEE ALSO

269       msync(2),  pmemlog_append(3),  pmemlog_create(3),  pmemlog_ctl_exec(3),
270       pmemlog_ctl_get(3),    pmemlog_ctl_set(3),    pmemlog_nbyte(3),   pmem‐
271       log_tell(3), strerror(3), libpmem(7), libpmemblk(7), libpmemobj(7)  and
272       <https://pmem.io>
273
274
275
276PMDK - pmemlog API version 1.1    2022-08-25                     LIBPMEMLOG(7)
Impressum