Line data Source code
1 : /*
2 : ldb database library using mdb back end
3 :
4 : Copyright (C) Jakub Hrozek 2014
5 : Copyright (C) Catalyst.Net Ltd 2017
6 :
7 : ** NOTE! The following LGPL license applies to the ldb
8 : ** library. This does NOT imply that all of Samba is released
9 : ** under the LGPL
10 :
11 : This library is free software; you can redistribute it and/or
12 : modify it under the terms of the GNU Lesser General Public
13 : License as published by the Free Software Foundation; either
14 : version 3 of the License, or (at your option) any later version.
15 :
16 : This library is distributed in the hope that it will be useful,
17 : but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 : Lesser General Public License for more details.
20 :
21 : You should have received a copy of the GNU Lesser General Public
22 : License along with this library; if not, see <http://www.gnu.org/licenses/>.
23 : */
24 :
25 : #include "ldb_mdb.h"
26 : #include "../ldb_key_value/ldb_kv.h"
27 : #include "include/dlinklist.h"
28 :
29 : #define MDB_URL_PREFIX "mdb://"
30 : #define MDB_URL_PREFIX_SIZE (sizeof(MDB_URL_PREFIX)-1)
31 :
32 : #define LDB_MDB_MAX_KEY_LENGTH 511
33 :
34 : #define GIGABYTE (1024*1024*1024)
35 :
36 144839549 : int ldb_mdb_err_map(int lmdb_err)
37 : {
38 144839549 : switch (lmdb_err) {
39 139016284 : case MDB_SUCCESS:
40 139016284 : return LDB_SUCCESS;
41 0 : case EIO:
42 0 : return LDB_ERR_OPERATIONS_ERROR;
43 : #ifdef EBADE
44 62 : case EBADE:
45 : #endif
46 : case MDB_INCOMPATIBLE:
47 : case MDB_CORRUPTED:
48 : case MDB_INVALID:
49 62 : return LDB_ERR_UNAVAILABLE;
50 6 : case MDB_BAD_TXN:
51 : case MDB_BAD_VALSIZE:
52 : #ifdef MDB_BAD_DBI
53 : case MDB_BAD_DBI:
54 : #endif
55 : case MDB_PANIC:
56 : case EINVAL:
57 6 : return LDB_ERR_PROTOCOL_ERROR;
58 1 : case MDB_MAP_FULL:
59 : case MDB_DBS_FULL:
60 : case MDB_READERS_FULL:
61 : case MDB_TLS_FULL:
62 : case MDB_TXN_FULL:
63 : case EAGAIN:
64 1 : return LDB_ERR_BUSY;
65 754 : case MDB_KEYEXIST:
66 754 : return LDB_ERR_ENTRY_ALREADY_EXISTS;
67 67842 : case MDB_NOTFOUND:
68 : case ENOENT:
69 67842 : return LDB_ERR_NO_SUCH_OBJECT;
70 0 : case EACCES:
71 0 : return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
72 0 : default:
73 0 : break;
74 : }
75 0 : return LDB_ERR_OTHER;
76 : }
77 :
78 : #define ldb_mdb_error(ldb, ecode) lmdb_error_at(ldb, ecode, __FILE__, __LINE__)
79 34304 : static int lmdb_error_at(struct ldb_context *ldb,
80 : int ecode,
81 : const char *file,
82 : int line)
83 : {
84 34304 : int ldb_err = ldb_mdb_err_map(ecode);
85 34304 : char *reason = mdb_strerror(ecode);
86 34304 : ldb_asprintf_errstring(ldb,
87 : "(%d) - %s at %s:%d",
88 : ecode,
89 : reason,
90 : file,
91 : line);
92 34304 : return ldb_err;
93 : }
94 :
95 357884202 : static bool lmdb_transaction_active(struct ldb_kv_private *ldb_kv)
96 : {
97 357884202 : return ldb_kv->lmdb_private->txlist != NULL;
98 : }
99 :
100 259816376 : static MDB_txn *lmdb_trans_get_tx(struct lmdb_trans *ltx)
101 : {
102 259816376 : if (ltx == NULL) {
103 147963432 : return NULL;
104 : }
105 :
106 103575345 : return ltx->tx;
107 : }
108 :
109 1444167 : static void trans_push(struct lmdb_private *lmdb, struct lmdb_trans *ltx)
110 : {
111 1444167 : if (lmdb->txlist) {
112 686843 : talloc_steal(lmdb->txlist, ltx);
113 : }
114 :
115 1444167 : DLIST_ADD(lmdb->txlist, ltx);
116 1444167 : }
117 :
118 1444168 : static void trans_finished(struct lmdb_private *lmdb, struct lmdb_trans *ltx)
119 : {
120 1444168 : DLIST_REMOVE(lmdb->txlist, ltx);
121 1444168 : talloc_free(ltx);
122 1444168 : }
123 :
124 :
125 261690184 : static struct lmdb_trans *lmdb_private_trans_head(struct lmdb_private *lmdb)
126 : {
127 8391180 : struct lmdb_trans *ltx;
128 :
129 261690184 : ltx = lmdb->txlist;
130 261690184 : return ltx;
131 : }
132 :
133 :
134 251236684 : static MDB_txn *get_current_txn(struct lmdb_private *lmdb)
135 : {
136 251236684 : MDB_txn *txn = NULL;
137 :
138 251236684 : txn = lmdb_trans_get_tx(lmdb_private_trans_head(lmdb));
139 246142045 : if (txn != NULL) {
140 96213848 : return txn;
141 : }
142 152313248 : if (lmdb->read_txn != NULL) {
143 147218609 : return lmdb->read_txn;
144 : }
145 1 : lmdb->error = MDB_BAD_TXN;
146 1 : ldb_set_errstring(lmdb->ldb, __location__":No active transaction\n");
147 1 : return NULL;
148 : }
149 :
150 6850605 : static int lmdb_store(struct ldb_kv_private *ldb_kv,
151 : struct ldb_val key,
152 : struct ldb_val data,
153 : int flags)
154 : {
155 6850605 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
156 454769 : MDB_val mdb_key;
157 454769 : MDB_val mdb_data;
158 454769 : int mdb_flags;
159 6850605 : MDB_txn *txn = NULL;
160 6850605 : MDB_dbi dbi = 0;
161 :
162 6850605 : if (ldb_kv->read_only) {
163 0 : return LDB_ERR_UNWILLING_TO_PERFORM;
164 : }
165 :
166 6850605 : txn = lmdb_trans_get_tx(lmdb_private_trans_head(lmdb));
167 6850604 : if (txn == NULL) {
168 1 : ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction");
169 1 : lmdb->error = MDB_PANIC;
170 1 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
171 : }
172 :
173 6850604 : lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi);
174 6850604 : if (lmdb->error != MDB_SUCCESS) {
175 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
176 : }
177 :
178 6850604 : mdb_key.mv_size = key.length;
179 6850604 : mdb_key.mv_data = key.data;
180 :
181 6850604 : mdb_data.mv_size = data.length;
182 6850604 : mdb_data.mv_data = data.data;
183 :
184 6850604 : if (flags == TDB_INSERT) {
185 354880 : mdb_flags = MDB_NOOVERWRITE;
186 6464191 : } else if (flags == TDB_MODIFY) {
187 : /*
188 : * Modifying a record, ensure that it exists.
189 : * This mimics the TDB semantics
190 : */
191 238723 : MDB_val value;
192 2889797 : lmdb->error = mdb_get(txn, dbi, &mdb_key, &value);
193 2889797 : if (lmdb->error != MDB_SUCCESS) {
194 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
195 : }
196 2889797 : mdb_flags = 0;
197 : } else {
198 3389882 : mdb_flags = 0;
199 : }
200 :
201 6850604 : lmdb->error = mdb_put(txn, dbi, &mdb_key, &mdb_data, mdb_flags);
202 6850604 : if (lmdb->error != MDB_SUCCESS) {
203 379 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
204 : }
205 :
206 6850225 : return ldb_mdb_err_map(lmdb->error);
207 : }
208 :
209 284920 : static int lmdb_delete(struct ldb_kv_private *ldb_kv, struct ldb_val key)
210 : {
211 284920 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
212 6102 : MDB_val mdb_key;
213 284920 : MDB_txn *txn = NULL;
214 284920 : MDB_dbi dbi = 0;
215 :
216 284920 : if (ldb_kv->read_only) {
217 0 : return LDB_ERR_UNWILLING_TO_PERFORM;
218 : }
219 :
220 284920 : txn = lmdb_trans_get_tx(lmdb_private_trans_head(lmdb));
221 284919 : if (txn == NULL) {
222 1 : ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction");
223 1 : lmdb->error = MDB_PANIC;
224 1 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
225 : }
226 :
227 284919 : lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi);
228 284919 : if (lmdb->error != MDB_SUCCESS) {
229 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
230 : }
231 :
232 284919 : mdb_key.mv_size = key.length;
233 284919 : mdb_key.mv_data = key.data;
234 :
235 284919 : lmdb->error = mdb_del(txn, dbi, &mdb_key, NULL);
236 284919 : if (lmdb->error != MDB_SUCCESS) {
237 33921 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
238 : }
239 250998 : return ldb_mdb_err_map(lmdb->error);
240 : }
241 :
242 10913 : static int lmdb_traverse_fn(struct ldb_kv_private *ldb_kv,
243 : ldb_kv_traverse_fn fn,
244 : void *ctx)
245 : {
246 10913 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
247 1020 : MDB_val mdb_key;
248 1020 : MDB_val mdb_data;
249 10913 : MDB_txn *txn = NULL;
250 10913 : MDB_dbi dbi = 0;
251 10913 : MDB_cursor *cursor = NULL;
252 1020 : int ret;
253 :
254 10913 : txn = get_current_txn(lmdb);
255 10913 : if (txn == NULL) {
256 0 : ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction");
257 0 : lmdb->error = MDB_PANIC;
258 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
259 : }
260 :
261 10913 : lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi);
262 10913 : if (lmdb->error != MDB_SUCCESS) {
263 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
264 : }
265 :
266 10913 : lmdb->error = mdb_cursor_open(txn, dbi, &cursor);
267 10913 : if (lmdb->error != MDB_SUCCESS) {
268 0 : goto done;
269 : }
270 :
271 8611193 : while ((lmdb->error = mdb_cursor_get(
272 : cursor, &mdb_key,
273 8277794 : &mdb_data, MDB_NEXT)) == MDB_SUCCESS) {
274 :
275 8266885 : struct ldb_val key = {
276 8266885 : .length = mdb_key.mv_size,
277 8266885 : .data = mdb_key.mv_data,
278 : };
279 8266885 : struct ldb_val data = {
280 8266885 : .length = mdb_data.mv_size,
281 8266885 : .data = mdb_data.mv_data,
282 : };
283 :
284 8266885 : ret = fn(ldb_kv, key, data, ctx);
285 8266885 : if (ret != 0) {
286 : /*
287 : * NOTE: This DOES NOT set lmdb->error!
288 : *
289 : * This means that the caller will get success.
290 : * This matches TDB traverse behaviour, where callbacks
291 : * may terminate the traverse, but do not change the
292 : * return code from success.
293 : *
294 : * Callers SHOULD store their own error codes.
295 : */
296 4 : goto done;
297 : }
298 : }
299 10909 : if (lmdb->error == MDB_NOTFOUND) {
300 10909 : lmdb->error = MDB_SUCCESS;
301 : }
302 0 : done:
303 10913 : if (cursor != NULL) {
304 10913 : mdb_cursor_close(cursor);
305 : }
306 :
307 10913 : if (lmdb->error != MDB_SUCCESS) {
308 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
309 : }
310 10913 : return ldb_mdb_err_map(lmdb->error);
311 : }
312 :
313 1032 : static int lmdb_update_in_iterate(struct ldb_kv_private *ldb_kv,
314 : struct ldb_val key,
315 : struct ldb_val key2,
316 : struct ldb_val data,
317 : void *state)
318 : {
319 1032 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
320 1032 : struct ldb_val copy;
321 1032 : int ret = LDB_SUCCESS;
322 :
323 : /*
324 : * Need to take a copy of the data as the delete operation alters the
325 : * data, as it is in private lmdb memory.
326 : */
327 1032 : copy.length = data.length;
328 1032 : copy.data = talloc_memdup(ldb_kv, data.data, data.length);
329 1032 : if (copy.data == NULL) {
330 0 : lmdb->error = MDB_PANIC;
331 0 : return ldb_oom(lmdb->ldb);
332 : }
333 :
334 1032 : lmdb->error = lmdb_delete(ldb_kv, key);
335 1032 : if (lmdb->error != MDB_SUCCESS) {
336 0 : ldb_debug(
337 : lmdb->ldb,
338 : LDB_DEBUG_ERROR,
339 : "Failed to delete %*.*s "
340 : "for rekey as %*.*s: %s",
341 0 : (int)key.length, (int)key.length,
342 0 : (const char *)key.data,
343 0 : (int)key2.length, (int)key2.length,
344 0 : (const char *)key.data,
345 : mdb_strerror(lmdb->error));
346 0 : ret = ldb_mdb_error(lmdb->ldb, lmdb->error);
347 0 : goto done;
348 : }
349 :
350 1032 : lmdb->error = lmdb_store(ldb_kv, key2, copy, 0);
351 1032 : if (lmdb->error != MDB_SUCCESS) {
352 0 : ldb_debug(
353 : lmdb->ldb,
354 : LDB_DEBUG_ERROR,
355 : "Failed to rekey %*.*s as %*.*s: %s",
356 0 : (int)key.length, (int)key.length,
357 0 : (const char *)key.data,
358 0 : (int)key2.length, (int)key2.length,
359 0 : (const char *)key.data,
360 : mdb_strerror(lmdb->error));
361 0 : ret = ldb_mdb_error(lmdb->ldb, lmdb->error);
362 0 : goto done;
363 : }
364 :
365 1032 : done:
366 1032 : if (copy.data != NULL) {
367 1032 : TALLOC_FREE(copy.data);
368 1032 : copy.length = 0;
369 : }
370 :
371 : /*
372 : * Explicitly invalidate the data, as the delete has done this
373 : */
374 1032 : data.length = 0;
375 1032 : data.data = NULL;
376 :
377 1032 : return ret;
378 : }
379 :
380 : /* Handles only a single record */
381 251211906 : static int lmdb_parse_record(struct ldb_kv_private *ldb_kv,
382 : struct ldb_val key,
383 : int (*parser)(struct ldb_val key,
384 : struct ldb_val data,
385 : void *private_data),
386 : void *ctx)
387 : {
388 251211906 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
389 7803008 : MDB_val mdb_key;
390 7803008 : MDB_val mdb_data;
391 251211906 : MDB_txn *txn = NULL;
392 7803008 : MDB_dbi dbi;
393 7803008 : struct ldb_val data;
394 :
395 251211906 : txn = get_current_txn(lmdb);
396 251211906 : if (txn == NULL) {
397 1 : ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction active");
398 1 : lmdb->error = MDB_PANIC;
399 1 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
400 : }
401 :
402 251211905 : lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi);
403 251211905 : if (lmdb->error != MDB_SUCCESS) {
404 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
405 : }
406 :
407 251211905 : mdb_key.mv_size = key.length;
408 251211905 : mdb_key.mv_data = key.data;
409 :
410 251211905 : lmdb->error = mdb_get(txn, dbi, &mdb_key, &mdb_data);
411 251211905 : if (lmdb->error != MDB_SUCCESS) {
412 : /* TODO closing a handle should not even be necessary */
413 30936979 : mdb_dbi_close(lmdb->env, dbi);
414 30936979 : if (lmdb->error == MDB_NOTFOUND) {
415 29874192 : return LDB_ERR_NO_SUCH_OBJECT;
416 : }
417 0 : if (lmdb->error == MDB_CORRUPTED) {
418 0 : ldb_debug(lmdb->ldb, LDB_DEBUG_ERROR,
419 : __location__
420 : ": MDB corrupted for key [%*.*s]\n",
421 0 : (int)key.length,
422 0 : (int)key.length,
423 : key.data);
424 : }
425 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
426 : }
427 220274926 : data.data = mdb_data.mv_data;
428 220274926 : data.length = mdb_data.mv_size;
429 :
430 : /* TODO closing a handle should not even be necessary */
431 220274926 : mdb_dbi_close(lmdb->env, dbi);
432 :
433 220274926 : return parser(key, data, ctx);
434 : }
435 :
436 : /*
437 : * Exactly the same as iterate, except we have a start key and an end key
438 : * (which are both included in the results if present).
439 : *
440 : * If start > end, return MDB_PANIC.
441 : */
442 13865 : static int lmdb_iterate_range(struct ldb_kv_private *ldb_kv,
443 : struct ldb_val start_key,
444 : struct ldb_val end_key,
445 : ldb_kv_traverse_fn fn,
446 : void *ctx)
447 : {
448 13865 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
449 199 : MDB_val mdb_key;
450 199 : MDB_val mdb_data;
451 13865 : MDB_txn *txn = NULL;
452 13865 : MDB_dbi dbi = 0;
453 13865 : MDB_cursor *cursor = NULL;
454 199 : int ret;
455 :
456 199 : MDB_val mdb_s_key;
457 199 : MDB_val mdb_e_key;
458 :
459 13865 : txn = get_current_txn(lmdb);
460 13865 : if (txn == NULL) {
461 0 : ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction");
462 0 : lmdb->error = MDB_PANIC;
463 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
464 : }
465 :
466 13865 : lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi);
467 13865 : if (lmdb->error != MDB_SUCCESS) {
468 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
469 : }
470 :
471 13865 : mdb_s_key.mv_size = start_key.length;
472 13865 : mdb_s_key.mv_data = start_key.data;
473 :
474 13865 : mdb_e_key.mv_size = end_key.length;
475 13865 : mdb_e_key.mv_data = end_key.data;
476 :
477 13865 : if (mdb_cmp(txn, dbi, &mdb_s_key, &mdb_e_key) > 0) {
478 1 : lmdb->error = MDB_PANIC;
479 1 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
480 : }
481 :
482 13864 : lmdb->error = mdb_cursor_open(txn, dbi, &cursor);
483 13864 : if (lmdb->error != MDB_SUCCESS) {
484 0 : goto done;
485 : }
486 :
487 13864 : lmdb->error = mdb_cursor_get(cursor, &mdb_s_key, &mdb_data, MDB_SET_RANGE);
488 :
489 13864 : if (lmdb->error != MDB_SUCCESS) {
490 37 : if (lmdb->error == MDB_NOTFOUND) {
491 37 : lmdb->error = MDB_SUCCESS;
492 : }
493 37 : goto done;
494 : } else {
495 13827 : struct ldb_val key = {
496 13827 : .length = mdb_s_key.mv_size,
497 13827 : .data = mdb_s_key.mv_data,
498 : };
499 13827 : struct ldb_val data = {
500 13827 : .length = mdb_data.mv_size,
501 13827 : .data = mdb_data.mv_data,
502 : };
503 :
504 13827 : if (mdb_cmp(txn, dbi, &mdb_s_key, &mdb_e_key) > 0) {
505 149 : goto done;
506 : }
507 :
508 13678 : ret = fn(ldb_kv, key, data, ctx);
509 13678 : if (ret != 0) {
510 : /*
511 : * NOTE: This DOES NOT set lmdb->error!
512 : *
513 : * This means that the caller will get success.
514 : * This matches TDB traverse behaviour, where callbacks
515 : * may terminate the traverse, but do not change the
516 : * return code from success.
517 : *
518 : * Callers SHOULD store their own error codes.
519 : */
520 0 : goto done;
521 : }
522 : }
523 :
524 29217967 : while ((lmdb->error = mdb_cursor_get(
525 : cursor, &mdb_key,
526 29284069 : &mdb_data, MDB_NEXT)) == MDB_SUCCESS) {
527 :
528 29271263 : struct ldb_val key = {
529 29271263 : .length = mdb_key.mv_size,
530 29271263 : .data = mdb_key.mv_data,
531 : };
532 29271263 : struct ldb_val data = {
533 29271263 : .length = mdb_data.mv_size,
534 29271263 : .data = mdb_data.mv_data,
535 : };
536 :
537 29271263 : if (mdb_cmp(txn, dbi, &mdb_key, &mdb_e_key) > 0) {
538 872 : goto done;
539 : }
540 :
541 29270400 : ret = fn(ldb_kv, key, data, ctx);
542 29270400 : if (ret != 0) {
543 : /*
544 : * NOTE: This DOES NOT set lmdb->error!
545 : *
546 : * This means that the caller will get success.
547 : * This matches TDB traverse behaviour, where callbacks
548 : * may terminate the traverse, but do not change the
549 : * return code from success.
550 : *
551 : * Callers SHOULD store their own error codes.
552 : */
553 9 : goto done;
554 : }
555 : }
556 12806 : if (lmdb->error == MDB_NOTFOUND) {
557 12806 : lmdb->error = MDB_SUCCESS;
558 : }
559 0 : done:
560 13864 : if (cursor != NULL) {
561 13864 : mdb_cursor_close(cursor);
562 : }
563 :
564 13864 : if (lmdb->error != MDB_SUCCESS) {
565 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
566 : }
567 13864 : return ldb_mdb_err_map(lmdb->error);
568 : }
569 :
570 136200718 : static int lmdb_lock_read(struct ldb_module *module)
571 : {
572 136200718 : void *data = ldb_module_get_private(module);
573 5245085 : struct ldb_kv_private *ldb_kv =
574 136200718 : talloc_get_type(data, struct ldb_kv_private);
575 136200718 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
576 136200718 : pid_t pid = getpid();
577 :
578 136200718 : if (pid != lmdb->pid) {
579 1 : ldb_asprintf_errstring(
580 : lmdb->ldb,
581 : __location__": Reusing ldb opened by pid %d in "
582 : "process %d\n",
583 : lmdb->pid,
584 : pid);
585 1 : lmdb->error = MDB_BAD_TXN;
586 1 : return LDB_ERR_PROTOCOL_ERROR;
587 : }
588 :
589 136200717 : lmdb->error = MDB_SUCCESS;
590 136200717 : if (lmdb_transaction_active(ldb_kv) == false &&
591 84877711 : ldb_kv->read_lock_count == 0) {
592 23038131 : lmdb->error = mdb_txn_begin(lmdb->env,
593 : NULL,
594 : MDB_RDONLY,
595 : &lmdb->read_txn);
596 : }
597 136200717 : if (lmdb->error != MDB_SUCCESS) {
598 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
599 : }
600 :
601 136200717 : ldb_kv->read_lock_count++;
602 136200717 : return ldb_mdb_err_map(lmdb->error);
603 : }
604 :
605 136200716 : static int lmdb_unlock_read(struct ldb_module *module)
606 : {
607 136200716 : void *data = ldb_module_get_private(module);
608 5245083 : struct ldb_kv_private *ldb_kv =
609 136200716 : talloc_get_type(data, struct ldb_kv_private);
610 :
611 136200716 : if (lmdb_transaction_active(ldb_kv) == false &&
612 84877710 : ldb_kv->read_lock_count == 1) {
613 23038129 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
614 23038129 : mdb_txn_commit(lmdb->read_txn);
615 23038129 : lmdb->read_txn = NULL;
616 23038129 : ldb_kv->read_lock_count--;
617 23038129 : return LDB_SUCCESS;
618 : }
619 113162587 : ldb_kv->read_lock_count--;
620 113162587 : return LDB_SUCCESS;
621 : }
622 :
623 1444167 : static int lmdb_transaction_start(struct ldb_kv_private *ldb_kv)
624 : {
625 1444167 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
626 50554 : struct lmdb_trans *ltx;
627 50554 : struct lmdb_trans *ltx_head;
628 50554 : MDB_txn *tx_parent;
629 1444167 : pid_t pid = getpid();
630 :
631 : /* Do not take out the transaction lock on a read-only DB */
632 1444167 : if (ldb_kv->read_only) {
633 0 : return LDB_ERR_UNWILLING_TO_PERFORM;
634 : }
635 :
636 1444167 : ltx = talloc_zero(lmdb, struct lmdb_trans);
637 1444167 : if (ltx == NULL) {
638 0 : return ldb_oom(lmdb->ldb);
639 : }
640 :
641 1444167 : if (pid != lmdb->pid) {
642 0 : ldb_asprintf_errstring(
643 : lmdb->ldb,
644 : __location__": Reusing ldb opened by pid %d in "
645 : "process %d\n",
646 : lmdb->pid,
647 : pid);
648 0 : lmdb->error = MDB_BAD_TXN;
649 0 : return LDB_ERR_PROTOCOL_ERROR;
650 : }
651 :
652 : /*
653 : * Clear out any stale readers
654 : */
655 : {
656 1444167 : int stale = 0;
657 1444167 : mdb_reader_check(lmdb->env, &stale);
658 1444167 : if (stale > 0) {
659 1 : ldb_debug(
660 : lmdb->ldb,
661 : LDB_DEBUG_ERROR,
662 : "LMDB Stale readers, deleted (%d)",
663 : stale);
664 : }
665 : }
666 :
667 :
668 :
669 1444167 : ltx_head = lmdb_private_trans_head(lmdb);
670 :
671 1444167 : tx_parent = lmdb_trans_get_tx(ltx_head);
672 :
673 1444167 : lmdb->error = mdb_txn_begin(lmdb->env, tx_parent, 0, <x->tx);
674 1444167 : if (lmdb->error != MDB_SUCCESS) {
675 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
676 : }
677 :
678 1444167 : trans_push(lmdb, ltx);
679 :
680 1444167 : return ldb_mdb_err_map(lmdb->error);
681 : }
682 :
683 74539 : static int lmdb_transaction_cancel(struct ldb_kv_private *ldb_kv)
684 : {
685 235 : struct lmdb_trans *ltx;
686 74539 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
687 :
688 74539 : ltx = lmdb_private_trans_head(lmdb);
689 74539 : if (ltx == NULL) {
690 2 : return LDB_ERR_OPERATIONS_ERROR;
691 : }
692 :
693 74537 : mdb_txn_abort(ltx->tx);
694 74537 : trans_finished(lmdb, ltx);
695 74537 : return LDB_SUCCESS;
696 : }
697 :
698 681108 : static int lmdb_transaction_prepare_commit(struct ldb_kv_private *ldb_kv)
699 : {
700 : /* No need to prepare a commit */
701 681108 : return LDB_SUCCESS;
702 : }
703 :
704 1369629 : static int lmdb_transaction_commit(struct ldb_kv_private *ldb_kv)
705 : {
706 50318 : struct lmdb_trans *ltx;
707 1369629 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
708 :
709 1369629 : ltx = lmdb_private_trans_head(lmdb);
710 1369629 : if (ltx == NULL) {
711 0 : return LDB_ERR_OPERATIONS_ERROR;
712 : }
713 :
714 1369629 : lmdb->error = mdb_txn_commit(ltx->tx);
715 1369629 : trans_finished(lmdb, ltx);
716 :
717 1369629 : return lmdb->error;
718 : }
719 :
720 34299 : static int lmdb_error(struct ldb_kv_private *ldb_kv)
721 : {
722 34299 : return ldb_mdb_err_map(ldb_kv->lmdb_private->error);
723 : }
724 :
725 0 : static const char *lmdb_errorstr(struct ldb_kv_private *ldb_kv)
726 : {
727 0 : return mdb_strerror(ldb_kv->lmdb_private->error);
728 : }
729 :
730 0 : static const char *lmdb_name(struct ldb_kv_private *ldb_kv)
731 : {
732 0 : return "lmdb";
733 : }
734 :
735 99675982 : static bool lmdb_changed(struct ldb_kv_private *ldb_kv)
736 : {
737 : /*
738 : * lmdb does no provide a quick way to determine if the database
739 : * has changed. This function always returns true.
740 : *
741 : * Note that tdb uses a sequence number that allows this function
742 : * to be implemented efficiently.
743 : */
744 99675982 : return true;
745 : }
746 :
747 : /*
748 : * Get the number of records in the database.
749 : *
750 : * The mdb_env_stat call returns an accurate count, so we return the actual
751 : * number of records in the database rather than an estimate.
752 : */
753 2 : static size_t lmdb_get_size(struct ldb_kv_private *ldb_kv)
754 : {
755 :
756 2 : struct MDB_stat stats = {0};
757 2 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
758 2 : int ret = 0;
759 :
760 2 : ret = mdb_env_stat(lmdb->env, &stats);
761 2 : if (ret != 0) {
762 0 : return 0;
763 : }
764 2 : return stats.ms_entries;
765 : }
766 :
767 : /*
768 : * Start a sub transaction
769 : * As lmdb supports nested transactions we can start a new transaction
770 : */
771 686843 : static int lmdb_nested_transaction_start(struct ldb_kv_private *ldb_kv)
772 : {
773 686843 : int ret = lmdb_transaction_start(ldb_kv);
774 686843 : return ret;
775 : }
776 :
777 : /*
778 : * Commit a sub transaction
779 : * As lmdb supports nested transactions we can commit the nested transaction
780 : */
781 684822 : static int lmdb_nested_transaction_commit(struct ldb_kv_private *ldb_kv)
782 : {
783 684822 : int ret = lmdb_transaction_commit(ldb_kv);
784 684822 : return ret;
785 : }
786 :
787 : /*
788 : * Cancel a sub transaction
789 : * As lmdb supports nested transactions we can cancel the nested transaction
790 : */
791 2021 : static int lmdb_nested_transaction_cancel(struct ldb_kv_private *ldb_kv)
792 : {
793 2021 : int ret = lmdb_transaction_cancel(ldb_kv);
794 2021 : return ret;
795 : }
796 :
797 : static struct kv_db_ops lmdb_key_value_ops = {
798 : .options = LDB_KV_OPTION_STABLE_READ_LOCK,
799 :
800 : .store = lmdb_store,
801 : .delete = lmdb_delete,
802 : .iterate = lmdb_traverse_fn,
803 : .update_in_iterate = lmdb_update_in_iterate,
804 : .fetch_and_parse = lmdb_parse_record,
805 : .iterate_range = lmdb_iterate_range,
806 : .lock_read = lmdb_lock_read,
807 : .unlock_read = lmdb_unlock_read,
808 : .begin_write = lmdb_transaction_start,
809 : .prepare_write = lmdb_transaction_prepare_commit,
810 : .finish_write = lmdb_transaction_commit,
811 : .abort_write = lmdb_transaction_cancel,
812 : .error = lmdb_error,
813 : .errorstr = lmdb_errorstr,
814 : .name = lmdb_name,
815 : .has_changed = lmdb_changed,
816 : .transaction_active = lmdb_transaction_active,
817 : .get_size = lmdb_get_size,
818 : .begin_nested_write = lmdb_nested_transaction_start,
819 : .finish_nested_write = lmdb_nested_transaction_commit,
820 : .abort_nested_write = lmdb_nested_transaction_cancel,
821 : };
822 :
823 468730 : static const char *lmdb_get_path(const char *url)
824 : {
825 29220 : const char *path;
826 :
827 : /* parse the url */
828 468730 : if (strchr(url, ':')) {
829 468668 : if (strncmp(url, MDB_URL_PREFIX, MDB_URL_PREFIX_SIZE) != 0) {
830 0 : return NULL;
831 : }
832 468668 : path = url + MDB_URL_PREFIX_SIZE;
833 : } else {
834 57 : path = url;
835 : }
836 :
837 439510 : return path;
838 : }
839 :
840 434415 : static int lmdb_pvt_destructor(struct lmdb_private *lmdb)
841 : {
842 434415 : struct lmdb_trans *ltx = NULL;
843 :
844 : /* Check if this is a forked child */
845 434415 : if (getpid() != lmdb->pid) {
846 4777 : int fd = 0;
847 : /*
848 : * We cannot call mdb_env_close or commit any transactions,
849 : * otherwise they might appear finished in the parent.
850 : *
851 : */
852 :
853 4777 : if (mdb_env_get_fd(lmdb->env, &fd) == 0) {
854 4777 : close(fd);
855 : }
856 :
857 : /* Remove the pointer, so that no access should occur */
858 4777 : lmdb->env = NULL;
859 :
860 4777 : return 0;
861 : }
862 :
863 : /*
864 : * Close the read transaction if it's open
865 : */
866 429638 : if (lmdb->read_txn != NULL) {
867 1 : mdb_txn_abort(lmdb->read_txn);
868 : }
869 :
870 429638 : if (lmdb->env == NULL) {
871 0 : return 0;
872 : }
873 :
874 : /*
875 : * Abort any currently active transactions
876 : */
877 429638 : ltx = lmdb_private_trans_head(lmdb);
878 429640 : while (ltx != NULL) {
879 2 : mdb_txn_abort(ltx->tx);
880 2 : trans_finished(lmdb, ltx);
881 2 : ltx = lmdb_private_trans_head(lmdb);
882 : }
883 429638 : lmdb->env = NULL;
884 :
885 429638 : return 0;
886 : }
887 :
888 : struct mdb_env_wrap {
889 : struct mdb_env_wrap *next, *prev;
890 : dev_t device;
891 : ino_t inode;
892 : MDB_env *env;
893 : pid_t pid;
894 : };
895 :
896 : static struct mdb_env_wrap *mdb_list;
897 :
898 : /* destroy the last connection to an mdb */
899 56149 : static int mdb_env_wrap_destructor(struct mdb_env_wrap *w)
900 : {
901 56149 : mdb_env_close(w->env);
902 56149 : DLIST_REMOVE(mdb_list, w);
903 56149 : return 0;
904 : }
905 :
906 468730 : static int lmdb_open_env(TALLOC_CTX *mem_ctx,
907 : MDB_env **env,
908 : struct ldb_context *ldb,
909 : const char *path,
910 : const size_t env_map_size,
911 : unsigned int flags)
912 : {
913 29220 : int ret;
914 468730 : unsigned int mdb_flags = MDB_NOSUBDIR|MDB_NOTLS;
915 : /*
916 : * MDB_NOSUBDIR implies there is a separate file called path and a
917 : * separate lockfile called path-lock
918 : */
919 :
920 29220 : struct mdb_env_wrap *w;
921 29220 : struct stat st;
922 468730 : pid_t pid = getpid();
923 468730 : int fd = 0;
924 29220 : unsigned v;
925 :
926 468730 : if (stat(path, &st) == 0) {
927 1597712 : for (w=mdb_list;w;w=w->next) {
928 1508885 : if (st.st_dev == w->device &&
929 1508885 : st.st_ino == w->inode &&
930 418266 : pid == w->pid) {
931 : /*
932 : * We must have only one MDB_env per process
933 : */
934 378399 : if (!talloc_reference(mem_ctx, w)) {
935 0 : return ldb_oom(ldb);
936 : }
937 378399 : *env = w->env;
938 378399 : return LDB_SUCCESS;
939 : }
940 : }
941 : }
942 :
943 90331 : w = talloc(mem_ctx, struct mdb_env_wrap);
944 90331 : if (w == NULL) {
945 0 : return ldb_oom(ldb);
946 : }
947 :
948 90331 : ret = mdb_env_create(env);
949 90331 : if (ret != 0) {
950 0 : ldb_asprintf_errstring(
951 : ldb,
952 : "Could not create MDB environment %s: %s\n",
953 : path,
954 : mdb_strerror(ret));
955 0 : return ldb_mdb_err_map(ret);
956 : }
957 :
958 90331 : if (env_map_size > 0) {
959 342 : ret = mdb_env_set_mapsize(*env, env_map_size);
960 342 : if (ret != 0) {
961 0 : ldb_asprintf_errstring(
962 : ldb,
963 : "Could not set MDB mmap() size to %llu "
964 : "on %s: %s\n",
965 : (unsigned long long)(env_map_size),
966 : path,
967 : mdb_strerror(ret));
968 0 : TALLOC_FREE(w);
969 0 : return ldb_mdb_err_map(ret);
970 : }
971 : }
972 :
973 90331 : mdb_env_set_maxreaders(*env, 100000);
974 : /*
975 : * As we ensure that there is only one MDB_env open per database per
976 : * process. We can not use the MDB_RDONLY flag, as another ldb may be
977 : * opened in read write mode
978 : */
979 90331 : if (flags & LDB_FLG_NOSYNC) {
980 89105 : mdb_flags |= MDB_NOSYNC;
981 : }
982 90331 : ret = mdb_env_open(*env, path, mdb_flags, 0644);
983 90331 : if (ret != 0) {
984 62 : ldb_asprintf_errstring(ldb,
985 : "Could not open DB %s: %s\n",
986 : path, mdb_strerror(ret));
987 62 : TALLOC_FREE(w);
988 62 : return ldb_mdb_err_map(ret);
989 : }
990 :
991 : {
992 90269 : MDB_envinfo stat = {0};
993 90269 : ret = mdb_env_info (*env, &stat);
994 90269 : if (ret != 0) {
995 0 : ldb_asprintf_errstring(
996 : ldb,
997 : "Could not get MDB environment stats %s: %s\n",
998 : path,
999 : mdb_strerror(ret));
1000 0 : return ldb_mdb_err_map(ret);
1001 : }
1002 : }
1003 :
1004 90269 : ret = mdb_env_get_fd(*env, &fd);
1005 90269 : if (ret != 0) {
1006 0 : ldb_asprintf_errstring(ldb,
1007 : "Could not obtain DB FD %s: %s\n",
1008 : path, mdb_strerror(ret));
1009 0 : TALLOC_FREE(w);
1010 0 : return ldb_mdb_err_map(ret);
1011 : }
1012 :
1013 : /* Just as for TDB: on exec, don't inherit the fd */
1014 90269 : v = fcntl(fd, F_GETFD, 0);
1015 90269 : if (v == -1) {
1016 0 : TALLOC_FREE(w);
1017 0 : return LDB_ERR_OPERATIONS_ERROR;
1018 : }
1019 :
1020 90269 : ret = fcntl(fd, F_SETFD, v | FD_CLOEXEC);
1021 90269 : if (ret == -1) {
1022 0 : TALLOC_FREE(w);
1023 0 : return LDB_ERR_OPERATIONS_ERROR;
1024 : }
1025 :
1026 90269 : if (fstat(fd, &st) != 0) {
1027 0 : ldb_asprintf_errstring(
1028 : ldb,
1029 : "Could not stat %s:\n",
1030 : path);
1031 0 : TALLOC_FREE(w);
1032 0 : return LDB_ERR_OPERATIONS_ERROR;
1033 : }
1034 90269 : w->env = *env;
1035 90269 : w->device = st.st_dev;
1036 90269 : w->inode = st.st_ino;
1037 90269 : w->pid = pid;
1038 :
1039 90269 : talloc_set_destructor(w, mdb_env_wrap_destructor);
1040 :
1041 90269 : DLIST_ADD(mdb_list, w);
1042 :
1043 82779 : return LDB_SUCCESS;
1044 :
1045 : }
1046 :
1047 468730 : static int lmdb_pvt_open(struct lmdb_private *lmdb,
1048 : struct ldb_context *ldb,
1049 : const char *path,
1050 : const size_t env_map_size,
1051 : unsigned int flags)
1052 : {
1053 29220 : int ret;
1054 29220 : int lmdb_max_key_length;
1055 :
1056 468730 : if (flags & LDB_FLG_DONT_CREATE_DB) {
1057 28958 : struct stat st;
1058 465516 : if (stat(path, &st) != 0) {
1059 0 : return LDB_ERR_UNAVAILABLE;
1060 : }
1061 : }
1062 :
1063 468730 : ret = lmdb_open_env(lmdb, &lmdb->env, ldb, path, env_map_size, flags);
1064 468730 : if (ret != 0) {
1065 57 : return ret;
1066 : }
1067 :
1068 : /* Close when lmdb is released */
1069 468668 : talloc_set_destructor(lmdb, lmdb_pvt_destructor);
1070 :
1071 : /* Store the original pid during the LMDB open */
1072 468668 : lmdb->pid = getpid();
1073 :
1074 468668 : lmdb_max_key_length = mdb_env_get_maxkeysize(lmdb->env);
1075 :
1076 : /* This will never happen, but if it does make sure to freak out */
1077 468668 : if (lmdb_max_key_length < LDB_MDB_MAX_KEY_LENGTH) {
1078 0 : return ldb_operr(ldb);
1079 : }
1080 :
1081 439453 : return LDB_SUCCESS;
1082 : }
1083 :
1084 468730 : int lmdb_connect(struct ldb_context *ldb,
1085 : const char *url,
1086 : unsigned int flags,
1087 : const char *options[],
1088 : struct ldb_module **_module)
1089 : {
1090 468730 : const char *path = NULL;
1091 468730 : struct lmdb_private *lmdb = NULL;
1092 468730 : struct ldb_kv_private *ldb_kv = NULL;
1093 29220 : int ret;
1094 468730 : size_t env_map_size = 0;
1095 :
1096 : /*
1097 : * We hold locks, so we must use a private event context
1098 : * on each returned handle
1099 : */
1100 468730 : ldb_set_require_private_event_context(ldb);
1101 :
1102 468730 : path = lmdb_get_path(url);
1103 468730 : if (path == NULL) {
1104 0 : ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid mdb URL '%s'", url);
1105 0 : return LDB_ERR_OPERATIONS_ERROR;
1106 : }
1107 :
1108 468730 : ldb_kv = talloc_zero(ldb, struct ldb_kv_private);
1109 468730 : if (!ldb_kv) {
1110 0 : ldb_oom(ldb);
1111 0 : return LDB_ERR_OPERATIONS_ERROR;
1112 : }
1113 :
1114 468730 : lmdb = talloc_zero(ldb_kv, struct lmdb_private);
1115 468730 : if (lmdb == NULL) {
1116 0 : TALLOC_FREE(ldb_kv);
1117 0 : return ldb_oom(ldb);
1118 : }
1119 468730 : lmdb->ldb = ldb;
1120 468730 : ldb_kv->kv_ops = &lmdb_key_value_ops;
1121 :
1122 : {
1123 468730 : const char *size = ldb_options_find(
1124 : ldb, ldb->options, "lmdb_env_size");
1125 468730 : if (size != NULL) {
1126 342 : env_map_size = strtoull(size, NULL, 0);
1127 : }
1128 : }
1129 :
1130 468730 : ret = lmdb_pvt_open(lmdb, ldb, path, env_map_size, flags);
1131 468730 : if (ret != LDB_SUCCESS) {
1132 62 : TALLOC_FREE(ldb_kv);
1133 62 : return ret;
1134 : }
1135 :
1136 468668 : ldb_kv->lmdb_private = lmdb;
1137 468668 : if (flags & LDB_FLG_RDONLY) {
1138 36 : ldb_kv->read_only = true;
1139 : }
1140 :
1141 : /*
1142 : * This maximum length becomes encoded in the index values so
1143 : * must never change even if LMDB starts to allow longer keys.
1144 : * The override option is max_key_len_for_self_test, and is
1145 : * used for testing only.
1146 : */
1147 468668 : ldb_kv->max_key_length = LDB_MDB_MAX_KEY_LENGTH;
1148 :
1149 468668 : return ldb_kv_init_store(
1150 : ldb_kv, "ldb_mdb backend", ldb, options, _module);
1151 : }
|