1LIBPMEMBLK(7) PMDK Programmer's Manual LIBPMEMBLK(7)
2
3
4
6 libpmemblk - persistent memory resident array of blocks
7
9 #include <libpmemblk.h>
10 cc ... -lpmemblk -lpmem
11
12 Library API versioning:
13 const char *pmemblk_check_version(
14 unsigned major_required,
15 unsigned minor_required);
16
17 Managing library behavior:
18 void pmemblk_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 const char *pmemblk_errormsg(void);
26
27 Other library functions:
28 A description of other libpmemblk functions can be found on the follow‐
29 ing manual pages:
30
31 pmemblk_bsize(3), pmemblk_create(3), pmemblk_ctl_exec(3), pmem‐
32 blk_ctl_get(3), pmemblk_ctl_set(3), pmemblk_read(3), pmemblk_set_ze‐
33 ro(3),
34
36 libpmemblk provides an array of blocks in persistent memory (pmem) such
37 that updates to a single block are atomic. This library is intended
38 for applications using direct access storage (DAX), which is storage
39 that supports load/store access without paging blocks from a block
40 storage device. Some types of non-volatile memory DIMMs (NVDIMMs) pro‐
41 vide this type of byte addressable access to storage. A persistent
42 memory aware file system is typically used to expose the direct access
43 to applications. Memory mapping a file from this type of file system
44 results in the load/store, non-paged access to pmem. libpmemblk builds
45 on this type of memory mapped file.
46
47 This library is for applications that need a potentially large array of
48 blocks, all the same size, where any given block is updated atomically
49 (the update cannot be torn by program interruption such as power fail‐
50 ures). This library builds on the low-level pmem support provided by
51 libpmem(7), handling the transactional update of the blocks, flushing
52 to persistence, and recovery for the application. libpmemblk is one of
53 a collection of persistent memory libraries available, the others are:
54
55 • libpmemobj(7), a general use persistent memory API, providing memory
56 allocation and transactional operations on variable-sized objects.
57
58 • libpmemlog(7), providing a pmem-resident log file.
59
60 • libpmem(7), low-level persistent memory support.
61
62 Under normal usage, libpmemblk will never print messages or intention‐
63 ally cause the process to exit. The only exception to this is the de‐
64 bugging information, when enabled, as described under DEBUGGING AND ER‐
65 ROR HANDLING below.
66
67 To use the atomic block arrays supplied by libpmemblk, a memory pool is
68 first created using the pmemblk_create() function described in pmem‐
69 blk_create(3). The other libpmemblk functions operate on the resulting
70 block memory pool using the opaque handle, of type PMEMblkpool*, that
71 is returned by pmemblk_create() or pmemblk_open(). Internally, libp‐
72 memblk will use either pmem_persist(3) or msync(2) when it needs to
73 flush changes, depending on whether the memory pool appears to be per‐
74 sistent memory or a regular file (see the pmem_is_pmem(3) function in
75 libpmem(7) for more information). There is no need for applications to
76 flush changes directly when using the block memory API provided by
77 libpmemblk.
78
80 libpmemblk relies on the library destructor being called from the main
81 thread. For this reason, all functions that might trigger destruction
82 (e.g. dlclose(3)) should be called in the main thread. Otherwise some
83 of the resources associated with that thread might not be cleaned up
84 properly.
85
87 This section describes how the library API is versioned, allowing ap‐
88 plications to work with an evolving API.
89
90 The pmemblk_check_version() function is used to determine whether the
91 installed libpmemblk supports the version of the library API required
92 by an application. The easiest way to do this is for the application
93 to supply the compile-time version information, supplied by defines in
94 <libpmemblk.h>, like this:
95
96 reason = pmemblk_check_version(PMEMBLK_MAJOR_VERSION,
97 PMEMBLK_MINOR_VERSION);
98 if (reason != NULL) {
99 /* version check failed, reason string tells you why */
100 }
101
102 Any mismatch in the major version number is considered a failure, but a
103 library with a newer minor version number will pass this check since
104 increasing minor versions imply backwards compatibility.
105
106 An application can also check specifically for the existence of an in‐
107 terface by checking for the version where that interface was intro‐
108 duced. These versions are documented in this man page as follows: un‐
109 less otherwise specified, all interfaces described here are available
110 in version 1.0 of the library. Interfaces added after version 1.0 will
111 contain the text introduced in version x.y in the section of this manu‐
112 al describing the feature.
113
114 When the version check performed by pmemblk_check_version() is success‐
115 ful, the return value is NULL. Otherwise the return value is a static
116 string describing the reason for failing the version check. The string
117 returned by pmemblk_check_version() must not be modified or freed.
118
120 The pmemblk_set_funcs() function allows an application to override mem‐
121 ory allocation calls used internally by libpmemblk. Passing in NULL
122 for any of the handlers will cause the libpmemblk default function to
123 be used. The library does not make heavy use of the system malloc
124 functions, but it does allocate approximately 4-8 kilobytes for each
125 memory pool in use.
126
128 The pmemblk_errormsg() function returns a pointer to a static buffer
129 containing the last error message logged for the current thread. If
130 errno was set, the error message may include a description of the cor‐
131 responding error code, as returned by strerror(3). The error message
132 buffer is thread-local; errors encountered in one thread do not affect
133 its value in other threads. The buffer is never cleared by any library
134 function; its content is significant only when the return value of the
135 immediately preceding call to a libpmemblk function indicated an error,
136 or if errno was set. The application must not modify or free the error
137 message string, but it may be modified by subsequent calls to other li‐
138 brary functions.
139
140 Two versions of libpmemblk are typically available on a development
141 system. The normal version, accessed when a program is linked using
142 the -lpmemblk option, is optimized for performance. That version skips
143 checks that impact performance and never logs any trace information or
144 performs any run-time assertions. If an error is detected in a call to
145 libpmemblk, the error message describing the failure may be retrieved
146 with pmemblk_errormsg() as described above.
147
148 A second version of libpmemblk, accessed when a program uses the li‐
149 braries under /usr/lib/pmdk_debug, contains run-time assertions and
150 trace points. The typical way to access the debug version is to set
151 the LD_LIBRARY_PATH environment variable to /usr/lib/pmdk_debug or
152 /usr/lib64/pmdk_debug, as appropriate. Debugging output is controlled
153 using the following environment variables. These variables have no ef‐
154 fect on the non-debug version of the library.
155
156 • PMEMBLK_LOG_LEVEL
157
158 The value of PMEMBLK_LOG_LEVEL enables trace points in the debug ver‐
159 sion of the library, as follows:
160
161 • 0 - This is the default level when PMEMBLK_LOG_LEVEL is not set. No
162 log messages are emitted at this level.
163
164 • 1 - Additional details on any errors detected are logged, in addition
165 to returning the errno-based errors as usual. The same information
166 may be retrieved using pmemblk_errormsg().
167
168 • 2 - A trace of basic operations is logged.
169
170 • 3 - Enables a very verbose amount of function call tracing in the li‐
171 brary.
172
173 • 4 - Enables voluminous and fairly obscure tracing information that is
174 likely only useful to the libpmemblk developers.
175
176 Unless PMEMBLK_LOG_FILE is set, debugging output is written to stderr.
177
178 • PMEMBLK_LOG_FILE
179
180 Specifies the name of a file where all logging information should be
181 written. If the last character in the name is “-”, the PID of the cur‐
182 rent process will be appended to the file name when the log file is
183 created. If PMEMBLK_LOG_FILE is not set, the logging output is written
184 to stderr.
185
186 See also libpmem(7) for information on other environment variables that
187 may affect libpmemblk behavior.
188
190 The following example illustrates how the libpmemblk API is used.
191
192 #include <fcntl.h>
193 #include <errno.h>
194 #include <stdlib.h>
195 #include <unistd.h>
196 #include <string.h>
197 #include <libpmemblk.h>
198
199 /* size of the pmemblk pool -- 1 GB */
200 #define POOL_SIZE ((size_t)(1 << 30))
201
202 /* size of each element in the pmem pool */
203 #define ELEMENT_SIZE 1024
204
205 int
206 main(int argc, char *argv[])
207 {
208 const char path[] = "/pmem-fs/myfile";
209 PMEMblkpool *pbp;
210 size_t nelements;
211 char buf[ELEMENT_SIZE];
212
213 /* create the pmemblk pool or open it if it already exists */
214 pbp = pmemblk_create(path, ELEMENT_SIZE, POOL_SIZE, 0666);
215
216 if (pbp == NULL)
217 pbp = pmemblk_open(path, ELEMENT_SIZE);
218
219 if (pbp == NULL) {
220 perror(path);
221 exit(1);
222 }
223
224 /* how many elements fit into the file? */
225 nelements = pmemblk_nblock(pbp);
226 printf("file holds %zu elements", nelements);
227
228 /* store a block at index 5 */
229 strcpy(buf, "hello, world");
230 if (pmemblk_write(pbp, buf, 5) < 0) {
231 perror("pmemblk_write");
232 exit(1);
233 }
234
235 /* read the block at index 10 (reads as zeros initially) */
236 if (pmemblk_read(pbp, buf, 10) < 0) {
237 perror("pmemblk_read");
238 exit(1);
239 }
240
241 /* zero out the block at index 5 */
242 if (pmemblk_set_zero(pbp, 5) < 0) {
243 perror("pmemblk_set_zero");
244 exit(1);
245 }
246
247 /* ... */
248
249 pmemblk_close(pbp);
250 }
251
252 See <https://pmem.io/pmdk/libpmemblk> for more examples using the libp‐
253 memblk API.
254
256 Unlike libpmemobj(7), data replication is not supported in libpmemblk.
257 Thus, specifying replica sections in pool set files is not allowed.
258
260 libpmemblk builds on the persistent memory programming model recommend‐
261 ed by the SNIA NVM Programming Technical Work Group:
262 <https://snia.org/nvmp>
263
265 msync(2), dlclose(3), pmemblk_bsize(3), pmemblk_create(3), pmem‐
266 blk_ctl_exec(3), pmemblk_ctl_get(3), pmemblk_ctl_set(3), pmem‐
267 blk_read(3), pmemblk_set_zero(3), pmem_is_pmem(3), pmem_persist(3),
268 strerror(3), libpmem(7), libpmemlog(7), libpmemobj(7) and
269 <https://pmem.io>
270
271
272
273PMDK - pmemblk API version 1.1 2022-05-24 LIBPMEMBLK(7)