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 eADR is supported.
151
152 · PMEM_NO_MOVNT=1
153
154 Setting this environment variable to 1 forces libpmem to never use the
155 non-temporal move instructions on Intel hardware. Without this envi‐
156 ronment variable, libpmem will use the non-temporal instructions for
157 copying larger ranges to persistent memory on platforms that support
158 the instructions. This variable is intended for use during library
159 testing.
160
161 · PMEM_MOVNT_THRESHOLD=val
162
163 This environment variable allows overriding the minimum length of the
164 pmem_memmove_persist(3) operations, for which libpmem uses non-temporal
165 move instructions. Setting this environment variable to 0 forces libp‐
166 mem to always use the non-temporal move instructions if available. It
167 has no effect if PMEM_NO_MOVNT is set to 1. This variable is intended
168 for use during library testing.
169
170 · PMEM_MMAP_HINT=val
171
172 This environment variable allows overriding the hint address used by
173 pmem_map_file(). If set, it also disables mapping address randomiza‐
174 tion. This variable is intended for use during library testing and de‐
175 bugging. Setting it to some fairly large value (i.e. 0x10000000000)
176 will very likely result in mapping the file at the specified address
177 (if not used) or at the first unused region above given address, with‐
178 out adding any random offset. When debugging, this makes it easier to
179 calculate the actual address of the persistent memory block, based on
180 its offset in the file. In case of libpmemobj it simplifies conversion
181 of a persistent object identifier (OID) into a direct pointer to the
182 object.
183
184 NOTE: Setting this environment variable affects all the PMDK li‐
185 braries, disabling mapping address randomization and causing the
186 specified address to be used as a hint about where to place the
187 mapping.
188
190 If an error is detected during the call to a libpmem function, the ap‐
191 plication may retrieve an error message describing the reason for the
192 failure from pmem_errormsg(). This function returns a pointer to a
193 static buffer containing the last error message logged for the current
194 thread. If errno was set, the error message may include a description
195 of the corresponding error code as returned by strerror(3). The error
196 message buffer is thread-local; errors encountered in one thread do not
197 affect its value in other threads. The buffer is never cleared by any
198 library function; its content is significant only when the return value
199 of the immediately preceding call to a libpmem function indicated an
200 error, or if errno was set. The application must not modify or free
201 the error message string, but it may be modified by subsequent calls to
202 other library functions.
203
204 Two versions of libpmem are typically available on a development sys‐
205 tem. The normal version, accessed when a program is linked using the
206 -lpmem option, is optimized for performance. That version skips checks
207 that impact performance and never logs any trace information or per‐
208 forms any run-time assertions.
209
210 A second version of libpmem, accessed when a program uses the libraries
211 under /usr/lib/pmdk_debug, contains run-time assertions and trace
212 points. The typical way to access the debug version is to set the en‐
213 vironment variable LD_LIBRARY_PATH to /usr/lib/pmdk_debug or
214 /usr/lib64/pmdk_debug, as appropriate. Debugging output is controlled
215 using the following environment variables. These variables have no ef‐
216 fect on the non-debug version of the library.
217
218 · PMEM_LOG_LEVEL
219
220 The value of PMEM_LOG_LEVEL enables trace points in the debug version
221 of the library, as follows:
222
223 · 0 - This is the default level when PMEM_LOG_LEVEL is not set. No log
224 messages are emitted at this level.
225
226 · 1 - Additional details on any errors detected are logged, in addition
227 to returning the errno-based errors as usual. The same information
228 may be retrieved using pmem_errormsg().
229
230 · 2 - A trace of basic operations is logged.
231
232 · 3 - Enables a very verbose amount of function call tracing in the li‐
233 brary.
234
235 · 4 - Enables voluminous and fairly obscure tracing information that is
236 likely only useful to the libpmem developers.
237
238 Unless PMEM_LOG_FILE is set, debugging output is written to stderr.
239
240 · PMEM_LOG_FILE
241
242 Specifies the name of a file where all logging information should be
243 written. If the last character in the name is "-", the PID of the cur‐
244 rent process will be appended to the file name when the log file is
245 created. If PMEM_LOG_FILE is not set, output is written to stderr.
246
248 The following example uses libpmem to flush changes made to raw, memo‐
249 ry-mapped persistent memory.
250
251 WARNING: There is nothing transactional about the pmem_per‐
252 sist(3) or pmem_msync(3) calls in this example. Interrupting
253 the program may result in a partial write to pmem. Use a trans‐
254 actional library such as libpmemobj(7) to avoid torn updates.
255
256 #include <sys/types.h>
257 #include <sys/stat.h>
258 #include <fcntl.h>
259 #include <stdio.h>
260 #include <errno.h>
261 #include <stdlib.h>
262 #include <unistd.h>
263 #include <string.h>
264 #include <libpmem.h>
265
266 /* using 4k of pmem for this example */
267 #define PMEM_LEN 4096
268
269 #define PATH "/pmem-fs/myfile"
270
271 int
272 main(int argc, char *argv[])
273 {
274 char *pmemaddr;
275 size_t mapped_len;
276 int is_pmem;
277
278 /* create a pmem file and memory map it */
279
280 if ((pmemaddr = pmem_map_file(PATH, PMEM_LEN, PMEM_FILE_CREATE,
281 0666, &mapped_len, &is_pmem)) == NULL) {
282 perror("pmem_map_file");
283 exit(1);
284 }
285
286 /* store a string to the persistent memory */
287 strcpy(pmemaddr, "hello, persistent memory");
288
289 /* flush above strcpy to persistence */
290 if (is_pmem)
291 pmem_persist(pmemaddr, mapped_len);
292 else
293 pmem_msync(pmemaddr, mapped_len);
294
295 /*
296 * Delete the mappings. The region is also
297 * automatically unmapped when the process is
298 * terminated.
299 */
300 pmem_unmap(pmemaddr, mapped_len);
301 }
302
303 See <http://pmem.io/pmdk/libpmem> for more examples using the libpmem
304 API.
305
307 libpmem builds on the persistent memory programming model recommended
308 by the SNIA NVM Programming Technical Work Group:
309 <http://snia.org/nvmp>
310
312 dlclose(3), pmem_flush(3), pmem_is_pmem(3), pmem_memmove_persist(3),
313 pmem_msync(3), pmem_persist(3), strerror(3), libpmemblk(7), libpmemc‐
314 to(7), libpmemlog(7), libpmemobj(7) and <http://pmem.io>
315
316
317
318PMDK - pmem API version 1.1 2018-03-13 LIBPMEM(7)