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