1LIBPMEM(7) PMDK Programmer's Manual LIBPMEM(7)
2
3
4
6 libpmem - persistent memory support library
7
9 #include <libpmem.h>
10 cc ... -lpmem
11
12 Library API versioning:
13 const char *pmem_check_version(
14 unsigned major_required,
15 unsigned minor_required);
16
17 Error handling:
18 const char *pmem_errormsg(void);
19
20 Other library functions:
21 A description of other libpmem functions can be found on the following
22 manual pages:
23
24 • most commonly used functions: pmem_is_pmem(3)
25
26 • partial flushing operations: pmem_flush(3)
27
28 • copying to persistent memory: pmem_memmove_persist(3)
29
31 libpmem provides low-level persistent memory (pmem) support for appli‐
32 cations using direct access storage (DAX), which is storage that sup‐
33 ports load/store access without paging blocks from a block storage de‐
34 vice. Some types of non-volatile memory DIMMs (NVDIMMs) provide this
35 type of byte addressable access to storage. A persistent memory aware
36 file system is typically used to expose the direct access to applica‐
37 tions. Memory mapping a file from this type of file system results in
38 the load/store, non-paged access to pmem.
39
40 This library is for applications that use persistent memory directly,
41 without the help of any library-supplied transactions or memory alloca‐
42 tion. Higher-level libraries that build on libpmem are available and
43 are recommended for most applications, see:
44
45 • libpmemobj(7), a general use persistent memory API, providing memory
46 allocation and transactional operations on variable-sized objects.
47
48 • libpmemblk(7), providing pmem-resident arrays of fixed-sized blocks
49 with atomic updates.
50
51 • libpmemlog(7), providing a pmem-resident log file.
52
53 Under normal usage, libpmem will never print messages or intentionally
54 cause the process to exit. The only exception to this is the debugging
55 information, when enabled, as described under DEBUGGING AND ERROR HAN‐
56 DLING below.
57
59 libpmem relies on the library destructor being called from the main
60 thread. For this reason, all functions that might trigger destruction
61 (e.g. dlclose(3)) should be called in the main thread. Otherwise some
62 of the resources associated with that thread might not be cleaned up
63 properly.
64
66 This section describes how the library API is versioned, allowing ap‐
67 plications to work with an evolving API.
68
69 The pmem_check_version() function is used to determine whether the in‐
70 stalled libpmem supports the version of the library API required by an
71 application. The easiest way to do this is for the application to sup‐
72 ply the compile-time version information, supplied by defines in <libp‐
73 mem.h>, like this:
74
75 reason = pmem_check_version(PMEM_MAJOR_VERSION,
76 PMEM_MINOR_VERSION);
77 if (reason != NULL) {
78 /* version check failed, reason string tells you why */
79 }
80
81 Any mismatch in the major version number is considered a failure, but a
82 library with a newer minor version number will pass this check since
83 increasing minor versions imply backwards compatibility.
84
85 An application can also check specifically for the existence of an in‐
86 terface by checking for the version where that interface was intro‐
87 duced. These versions are documented in this man page as follows: un‐
88 less otherwise specified, all interfaces described here are available
89 in version 1.0 of the library. Interfaces added after version 1.0 will
90 contain the text introduced in version x.y in the section of this manu‐
91 al describing the feature.
92
93 When the version check performed by pmem_check_version() is successful,
94 the return value is NULL. Otherwise the return value is a static
95 string describing the reason for failing the version check. The string
96 returned by pmem_check_version() must not be modified or freed.
97
99 libpmem can change its default behavior based on the following environ‐
100 ment variables. These are largely intended for testing and are not
101 normally required.
102
103 • PMEM_IS_PMEM_FORCE=val
104
105 If val is 0 (zero), then pmem_is_pmem(3) will always return false.
106 Setting val to 1 causes pmem_is_pmem(3) to always return true. This
107 variable is mostly used for testing but can be used to force pmem be‐
108 havior on a system where a range of pmem is not detectable as pmem for
109 some reason.
110
111 NOTE: Unlike the other variables, the value of
112 PMEM_IS_PMEM_FORCE is not queried (and cached) at library ini‐
113 tialization time, but on the first call to pmem_is_pmem(3).
114 This means that in case of libpmemlog(7), libpmemblk(7), and
115 libpmemobj(7), PMEM_IS_PMEM_FORCE may still be set or modified
116 by the program until the first attempt to create or open the
117 persistent memory pool.
118
119 • PMEM_NO_CLWB=1
120
121 Setting this environment variable to 1 forces libpmem to never issue
122 the CLWB instruction on Intel hardware, falling back to other cache
123 flush instructions instead (CLFLUSHOPT or CLFLUSH on Intel hardware).
124 Without this environment variable, libpmem will always use the CLWB in‐
125 struction for flushing processor caches on platforms that support the
126 instruction. This variable is intended for use during library testing
127 but may be required for some rare cases where using CLWB has a negative
128 impact on performance.
129
130 • PMEM_NO_CLFLUSHOPT=1
131
132 Setting this environment variable to 1 forces libpmem to never issue
133 the CLFLUSHOPT instruction on Intel hardware, falling back to the
134 CLFLUSH instructions instead. Without this environment variable, libp‐
135 mem will always use the CLFLUSHOPT instruction for flushing processor
136 caches on platforms that support the instruction, but where CLWB is not
137 available. This variable is intended for use during library testing.
138
139 • PMEM_NO_FLUSH=1
140
141 Setting this environment variable to 1 forces most libpmem functions to
142 never issue any of CLFLUSH, CLFLUSHOPT or CLWB instructions on Intel
143 hardware. The only exceptions are pmem_deep_flush(3) and
144 pmem_deep_persist(3) functions.
145
146 • PMEM_NO_FLUSH=0
147
148 Setting this environment variable to 0 forces to always flush CPU
149 caches using one of CLFLUSH, CLFLUSHOPT or CLWB instructions even if
150 pmem_has_auto_flush(3) function returns true and the platform supports
151 flushing the processor caches on power loss or system crash.
152
153 • PMEM_NO_MOVNT=1
154
155 Setting this environment variable to 1 forces libpmem to never use the
156 non-temporal move instructions on Intel hardware. Without this envi‐
157 ronment variable, libpmem will use the non-temporal instructions for
158 copying larger ranges to persistent memory on platforms that support
159 the instructions. This variable is intended for use during library
160 testing.
161
162 • PMEM_MOVNT_THRESHOLD=val
163
164 This environment variable allows overriding the minimum length of the
165 pmem_memmove_persist(3) operations, for which libpmem uses non-temporal
166 move instructions. Setting this environment variable to 0 forces libp‐
167 mem to always use the non-temporal move instructions if available. It
168 has no effect if PMEM_NO_MOVNT is set to 1. This variable is intended
169 for use during library testing.
170
171 • PMEM_MMAP_HINT=val
172
173 This environment variable allows overriding the hint address used by
174 pmem_map_file(). If set, it also disables mapping address randomiza‐
175 tion. This variable is intended for use during library testing and de‐
176 bugging. Setting it to some fairly large value (i.e. 0x10000000000)
177 will very likely result in mapping the file at the specified address
178 (if not used) or at the first unused region above given address, with‐
179 out adding any random offset. When debugging, this makes it easier to
180 calculate the actual address of the persistent memory block, based on
181 its offset in the file. In case of libpmemobj it simplifies conversion
182 of a persistent object identifier (OID) into a direct pointer to the
183 object.
184
185 NOTE: Setting this environment variable affects all the PMDK li‐
186 braries, disabling mapping address randomization and causing the
187 specified address to be used as a hint about where to place the
188 mapping.
189
191 If an error is detected during the call to a libpmem function, the ap‐
192 plication may retrieve an error message describing the reason of the
193 failure from pmem_errormsg(). This function returns a pointer to a
194 static buffer containing the last error message logged for the current
195 thread. If errno was set, the error message may include a description
196 of the corresponding error code as returned by strerror(3). The error
197 message buffer is thread-local; errors encountered in one thread do not
198 affect its value in other threads. The buffer is never cleared by any
199 library function; its content is significant only when the return value
200 of the immediately preceding call to a libpmem function indicated an
201 error. The application must not modify or free the error message
202 string. Subsequent calls to other library functions may modify the
203 previous message.
204
205 Two versions of libpmem are typically available on a development sys‐
206 tem. The normal version, accessed when a program is linked using the
207 -lpmem option, is optimized for performance. That version skips checks
208 that impact performance and never logs any trace information or per‐
209 forms any run-time assertions.
210
211 A second version of libpmem, accessed when a program uses the libraries
212 under /usr/lib/pmdk_debug, contains run-time assertions and trace
213 points. The typical way to access the debug version is to set the en‐
214 vironment variable LD_LIBRARY_PATH to /usr/lib/pmdk_debug or
215 /usr/lib64/pmdk_debug, as appropriate. Debugging output is controlled
216 using the following environment variables. These variables have no ef‐
217 fect on the non-debug version of the library.
218
219 • PMEM_LOG_LEVEL
220
221 The value of PMEM_LOG_LEVEL enables trace points in the debug version
222 of the library, as follows:
223
224 • 0 - This is the default level when PMEM_LOG_LEVEL is not set. No log
225 messages are emitted at this level.
226
227 • 1 - Additional details on any errors detected are logged, in addition
228 to returning the errno-based errors as usual. The same information
229 may be retrieved using pmem_errormsg().
230
231 • 2 - A trace of basic operations is logged.
232
233 • 3 - Enables a very verbose amount of function call tracing in the li‐
234 brary.
235
236 • 4 - Enables voluminous and fairly obscure tracing information that is
237 likely only useful to the libpmem developers.
238
239 Unless PMEM_LOG_FILE is set, debugging output is written to stderr.
240
241 • PMEM_LOG_FILE
242
243 Specifies the name of a file where all logging information should be
244 written. If the last character in the name is “-”, the PID of the cur‐
245 rent process will be appended to the file name when the log file is
246 created. If PMEM_LOG_FILE is not set, output is written to stderr.
247
249 The following example uses libpmem to flush changes made to raw, memo‐
250 ry-mapped persistent memory.
251
252 WARNING: There is nothing transactional about the pmem_per‐
253 sist(3) or pmem_msync(3) calls in this example. Interrupting
254 the program may result in a partial write to pmem. Use a trans‐
255 actional library such as libpmemobj(7) to avoid torn updates.
256
257 #include <sys/types.h>
258 #include <sys/stat.h>
259 #include <fcntl.h>
260 #include <stdio.h>
261 #include <errno.h>
262 #include <stdlib.h>
263 #include <unistd.h>
264 #include <string.h>
265 #include <libpmem.h>
266
267 /* using 4k of pmem for this example */
268 #define PMEM_LEN 4096
269
270 #define PATH "/pmem-fs/myfile"
271
272 int
273 main(int argc, char *argv[])
274 {
275 char *pmemaddr;
276 size_t mapped_len;
277 int is_pmem;
278
279 /* create a pmem file and memory map it */
280
281 if ((pmemaddr = pmem_map_file(PATH, PMEM_LEN, PMEM_FILE_CREATE,
282 0666, &mapped_len, &is_pmem)) == NULL) {
283 perror("pmem_map_file");
284 exit(1);
285 }
286
287 /* store a string to the persistent memory */
288 strcpy(pmemaddr, "hello, persistent memory");
289
290 /* flush above strcpy to persistence */
291 if (is_pmem)
292 pmem_persist(pmemaddr, mapped_len);
293 else
294 pmem_msync(pmemaddr, mapped_len);
295
296 /*
297 * Delete the mappings. The region is also
298 * automatically unmapped when the process is
299 * terminated.
300 */
301 pmem_unmap(pmemaddr, mapped_len);
302 }
303
304 See <https://pmem.io/pmdk/libpmem> for more examples using the libpmem
305 API.
306
308 libpmem builds on the persistent memory programming model recommended
309 by the SNIA NVM Programming Technical Work Group:
310 <https://snia.org/nvmp>
311
313 dlclose(3), pmem_flush(3), pmem_is_pmem(3), pmem_memmove_persist(3),
314 pmem_msync(3), pmem_persist(3), strerror(3), libpmemblk(7), libpmem‐
315 log(7), libpmemobj(7) and <https://pmem.io>
316
317
318
319PMDK - pmem API version 1.1 2022-05-24 LIBPMEM(7)