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 72175568 : int ldb_mdb_err_map(int lmdb_err)
37 : {
38 72175568 : switch (lmdb_err) {
39 72131391 : case MDB_SUCCESS:
40 72131391 : return LDB_SUCCESS;
41 0 : case EIO:
42 0 : return LDB_ERR_OPERATIONS_ERROR;
43 : #ifdef EBADE
44 53 : case EBADE:
45 : #endif
46 : case MDB_INCOMPATIBLE:
47 : case MDB_CORRUPTED:
48 : case MDB_INVALID:
49 53 : return LDB_ERR_UNAVAILABLE;
50 0 : 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 0 : return LDB_ERR_PROTOCOL_ERROR;
58 0 : 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 0 : return LDB_ERR_BUSY;
65 608 : case MDB_KEYEXIST:
66 608 : return LDB_ERR_ENTRY_ALREADY_EXISTS;
67 43516 : case MDB_NOTFOUND:
68 : case ENOENT:
69 43516 : 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 22062 : static int lmdb_error_at(struct ldb_context *ldb,
80 : int ecode,
81 : const char *file,
82 : int line)
83 : {
84 22062 : int ldb_err = ldb_mdb_err_map(ecode);
85 22062 : char *reason = mdb_strerror(ecode);
86 22062 : ldb_asprintf_errstring(ldb,
87 : "(%d) - %s at %s:%d",
88 : ecode,
89 : reason,
90 : file,
91 : line);
92 22062 : return ldb_err;
93 : }
94 :
95 177194611 : static bool lmdb_transaction_active(struct ldb_kv_private *ldb_kv)
96 : {
97 177194611 : return ldb_kv->lmdb_private->txlist != NULL;
98 : }
99 :
100 131967316 : static MDB_txn *lmdb_trans_get_tx(struct lmdb_trans *ltx)
101 : {
102 131967316 : if (ltx == NULL) {
103 71350849 : return NULL;
104 : }
105 :
106 60616467 : return ltx->tx;
107 : }
108 :
109 747381 : static void trans_push(struct lmdb_private *lmdb, struct lmdb_trans *ltx)
110 : {
111 747381 : if (lmdb->txlist) {
112 344712 : talloc_steal(lmdb->txlist, ltx);
113 : }
114 :
115 747381 : DLIST_ADD(lmdb->txlist, ltx);
116 747381 : }
117 :
118 747381 : static void trans_finished(struct lmdb_private *lmdb, struct lmdb_trans *ltx)
119 : {
120 747381 : DLIST_REMOVE(lmdb->txlist, ltx);
121 747381 : talloc_free(ltx);
122 747381 : }
123 :
124 :
125 132856492 : static struct lmdb_trans *lmdb_private_trans_head(struct lmdb_private *lmdb)
126 : {
127 : struct lmdb_trans *ltx;
128 :
129 132856492 : ltx = lmdb->txlist;
130 132856492 : return ltx;
131 : }
132 :
133 :
134 126939228 : static MDB_txn *get_current_txn(struct lmdb_private *lmdb)
135 : {
136 126939228 : MDB_txn *txn = NULL;
137 :
138 126939228 : txn = lmdb_trans_get_tx(lmdb_private_trans_head(lmdb));
139 126939228 : if (txn != NULL) {
140 55991048 : return txn;
141 : }
142 70948180 : if (lmdb->read_txn != NULL) {
143 70948180 : return lmdb->read_txn;
144 : }
145 0 : lmdb->error = MDB_BAD_TXN;
146 0 : ldb_set_errstring(lmdb->ldb, __location__":No active transaction\n");
147 0 : return NULL;
148 : }
149 :
150 4124136 : 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 4124136 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
156 : MDB_val mdb_key;
157 : MDB_val mdb_data;
158 : int mdb_flags;
159 4124136 : MDB_txn *txn = NULL;
160 4124136 : MDB_dbi dbi = 0;
161 :
162 4124136 : if (ldb_kv->read_only) {
163 0 : return LDB_ERR_UNWILLING_TO_PERFORM;
164 : }
165 :
166 4124136 : txn = lmdb_trans_get_tx(lmdb_private_trans_head(lmdb));
167 4124136 : if (txn == NULL) {
168 0 : ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction");
169 0 : lmdb->error = MDB_PANIC;
170 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
171 : }
172 :
173 4124136 : lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi);
174 4124136 : if (lmdb->error != MDB_SUCCESS) {
175 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
176 : }
177 :
178 4124136 : mdb_key.mv_size = key.length;
179 4124136 : mdb_key.mv_data = key.data;
180 :
181 4124136 : mdb_data.mv_size = data.length;
182 4124136 : mdb_data.mv_data = data.data;
183 :
184 4124136 : if (flags == TDB_INSERT) {
185 216841 : mdb_flags = MDB_NOOVERWRITE;
186 3907295 : } else if (flags == TDB_MODIFY) {
187 : /*
188 : * Modifying a record, ensure that it exists.
189 : * This mimics the TDB semantics
190 : */
191 : MDB_val value;
192 1608986 : lmdb->error = mdb_get(txn, dbi, &mdb_key, &value);
193 1608986 : if (lmdb->error != MDB_SUCCESS) {
194 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
195 : }
196 1608986 : mdb_flags = 0;
197 : } else {
198 2298309 : mdb_flags = 0;
199 : }
200 :
201 4124136 : lmdb->error = mdb_put(txn, dbi, &mdb_key, &mdb_data, mdb_flags);
202 4124136 : if (lmdb->error != MDB_SUCCESS) {
203 304 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
204 : }
205 :
206 4123832 : return ldb_mdb_err_map(lmdb->error);
207 : }
208 :
209 156571 : static int lmdb_delete(struct ldb_kv_private *ldb_kv, struct ldb_val key)
210 : {
211 156571 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
212 : MDB_val mdb_key;
213 156571 : MDB_txn *txn = NULL;
214 156571 : MDB_dbi dbi = 0;
215 :
216 156571 : if (ldb_kv->read_only) {
217 0 : return LDB_ERR_UNWILLING_TO_PERFORM;
218 : }
219 :
220 156571 : txn = lmdb_trans_get_tx(lmdb_private_trans_head(lmdb));
221 156571 : if (txn == NULL) {
222 0 : ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction");
223 0 : lmdb->error = MDB_PANIC;
224 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
225 : }
226 :
227 156571 : lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi);
228 156571 : if (lmdb->error != MDB_SUCCESS) {
229 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
230 : }
231 :
232 156571 : mdb_key.mv_size = key.length;
233 156571 : mdb_key.mv_data = key.data;
234 :
235 156571 : lmdb->error = mdb_del(txn, dbi, &mdb_key, NULL);
236 156571 : if (lmdb->error != MDB_SUCCESS) {
237 21758 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
238 : }
239 134813 : return ldb_mdb_err_map(lmdb->error);
240 : }
241 :
242 5604 : static int lmdb_traverse_fn(struct ldb_kv_private *ldb_kv,
243 : ldb_kv_traverse_fn fn,
244 : void *ctx)
245 : {
246 5604 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
247 : MDB_val mdb_key;
248 : MDB_val mdb_data;
249 5604 : MDB_txn *txn = NULL;
250 5604 : MDB_dbi dbi = 0;
251 5604 : MDB_cursor *cursor = NULL;
252 : int ret;
253 :
254 5604 : txn = get_current_txn(lmdb);
255 5604 : 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 5604 : lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi);
262 5604 : if (lmdb->error != MDB_SUCCESS) {
263 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
264 : }
265 :
266 5604 : lmdb->error = mdb_cursor_open(txn, dbi, &cursor);
267 5604 : if (lmdb->error != MDB_SUCCESS) {
268 0 : goto done;
269 : }
270 :
271 6384619 : while ((lmdb->error = mdb_cursor_get(
272 : cursor, &mdb_key,
273 85312 : &mdb_data, MDB_NEXT)) == MDB_SUCCESS) {
274 :
275 12661934 : struct ldb_val key = {
276 6373553 : .length = mdb_key.mv_size,
277 6373553 : .data = mdb_key.mv_data,
278 : };
279 12661934 : struct ldb_val data = {
280 6373553 : .length = mdb_data.mv_size,
281 6373553 : .data = mdb_data.mv_data,
282 : };
283 :
284 6373553 : ret = fn(ldb_kv, key, data, ctx);
285 6373553 : 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 2 : goto done;
297 : }
298 : }
299 5602 : if (lmdb->error == MDB_NOTFOUND) {
300 5602 : lmdb->error = MDB_SUCCESS;
301 : }
302 5464 : done:
303 5604 : if (cursor != NULL) {
304 5604 : mdb_cursor_close(cursor);
305 : }
306 :
307 5604 : if (lmdb->error != MDB_SUCCESS) {
308 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
309 : }
310 5604 : return ldb_mdb_err_map(lmdb->error);
311 : }
312 :
313 0 : 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 0 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
320 : struct ldb_val copy;
321 0 : 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 0 : copy.length = data.length;
328 0 : copy.data = talloc_memdup(ldb_kv, data.data, data.length);
329 0 : if (copy.data == NULL) {
330 0 : lmdb->error = MDB_PANIC;
331 0 : return ldb_oom(lmdb->ldb);
332 : }
333 :
334 0 : lmdb->error = lmdb_delete(ldb_kv, key);
335 0 : 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 0 : lmdb->error = lmdb_store(ldb_kv, key2, copy, 0);
351 0 : 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 0 : done:
366 0 : if (copy.data != NULL) {
367 0 : TALLOC_FREE(copy.data);
368 0 : copy.length = 0;
369 : }
370 :
371 : /*
372 : * Explicity invalidate the data, as the delete has done this
373 : */
374 0 : data.length = 0;
375 0 : data.data = NULL;
376 :
377 0 : return ret;
378 : }
379 :
380 : /* Handles only a single record */
381 126921674 : 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 126921674 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
389 : MDB_val mdb_key;
390 : MDB_val mdb_data;
391 126921674 : MDB_txn *txn = NULL;
392 : MDB_dbi dbi;
393 : struct ldb_val data;
394 :
395 126921674 : txn = get_current_txn(lmdb);
396 126921674 : if (txn == NULL) {
397 0 : ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction active");
398 0 : lmdb->error = MDB_PANIC;
399 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
400 : }
401 :
402 126921674 : lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi);
403 126921674 : if (lmdb->error != MDB_SUCCESS) {
404 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
405 : }
406 :
407 126921674 : mdb_key.mv_size = key.length;
408 126921674 : mdb_key.mv_data = key.data;
409 :
410 126921674 : lmdb->error = mdb_get(txn, dbi, &mdb_key, &mdb_data);
411 126921674 : if (lmdb->error != MDB_SUCCESS) {
412 : /* TODO closing a handle should not even be necessary */
413 15640515 : mdb_dbi_close(lmdb->env, dbi);
414 15640515 : if (lmdb->error == MDB_NOTFOUND) {
415 15640515 : return LDB_ERR_NO_SUCH_OBJECT;
416 : }
417 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
418 : }
419 111281159 : data.data = mdb_data.mv_data;
420 111281159 : data.length = mdb_data.mv_size;
421 :
422 : /* TODO closing a handle should not even be necessary */
423 111281159 : mdb_dbi_close(lmdb->env, dbi);
424 :
425 111281159 : return parser(key, data, ctx);
426 : }
427 :
428 : /*
429 : * Exactly the same as iterate, except we have a start key and an end key
430 : * (which are both included in the results if present).
431 : *
432 : * If start > end, return MDB_PANIC.
433 : */
434 11950 : static int lmdb_iterate_range(struct ldb_kv_private *ldb_kv,
435 : struct ldb_val start_key,
436 : struct ldb_val end_key,
437 : ldb_kv_traverse_fn fn,
438 : void *ctx)
439 : {
440 11950 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
441 : MDB_val mdb_key;
442 : MDB_val mdb_data;
443 11950 : MDB_txn *txn = NULL;
444 11950 : MDB_dbi dbi = 0;
445 11950 : MDB_cursor *cursor = NULL;
446 : int ret;
447 :
448 : MDB_val mdb_s_key;
449 : MDB_val mdb_e_key;
450 :
451 11950 : txn = get_current_txn(lmdb);
452 11950 : if (txn == NULL) {
453 0 : ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction");
454 0 : lmdb->error = MDB_PANIC;
455 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
456 : }
457 :
458 11950 : lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi);
459 11950 : if (lmdb->error != MDB_SUCCESS) {
460 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
461 : }
462 :
463 11950 : mdb_s_key.mv_size = start_key.length;
464 11950 : mdb_s_key.mv_data = start_key.data;
465 :
466 11950 : mdb_e_key.mv_size = end_key.length;
467 11950 : mdb_e_key.mv_data = end_key.data;
468 :
469 11950 : if (mdb_cmp(txn, dbi, &mdb_s_key, &mdb_e_key) > 0) {
470 0 : lmdb->error = MDB_PANIC;
471 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
472 : }
473 :
474 11950 : lmdb->error = mdb_cursor_open(txn, dbi, &cursor);
475 11950 : if (lmdb->error != MDB_SUCCESS) {
476 0 : goto done;
477 : }
478 :
479 11950 : lmdb->error = mdb_cursor_get(cursor, &mdb_s_key, &mdb_data, MDB_SET_RANGE);
480 :
481 11950 : if (lmdb->error != MDB_SUCCESS) {
482 17 : if (lmdb->error == MDB_NOTFOUND) {
483 17 : lmdb->error = MDB_SUCCESS;
484 : }
485 17 : goto done;
486 : } else {
487 23819 : struct ldb_val key = {
488 11933 : .length = mdb_s_key.mv_size,
489 11933 : .data = mdb_s_key.mv_data,
490 : };
491 23819 : struct ldb_val data = {
492 11933 : .length = mdb_data.mv_size,
493 11933 : .data = mdb_data.mv_data,
494 : };
495 :
496 11933 : if (mdb_cmp(txn, dbi, &mdb_s_key, &mdb_e_key) > 0) {
497 194 : goto done;
498 : }
499 :
500 11836 : ret = fn(ldb_kv, key, data, ctx);
501 11836 : if (ret != 0) {
502 : /*
503 : * NOTE: This DOES NOT set lmdb->error!
504 : *
505 : * This means that the caller will get success.
506 : * This matches TDB traverse behaviour, where callbacks
507 : * may terminate the traverse, but do not change the
508 : * return code from success.
509 : *
510 : * Callers SHOULD store their own error codes.
511 : */
512 0 : goto done;
513 : }
514 : }
515 :
516 24729398 : while ((lmdb->error = mdb_cursor_get(
517 : cursor, &mdb_key,
518 37777 : &mdb_data, MDB_NEXT)) == MDB_SUCCESS) {
519 :
520 49375334 : struct ldb_val key = {
521 24706532 : .length = mdb_key.mv_size,
522 24706532 : .data = mdb_key.mv_data,
523 : };
524 49375334 : struct ldb_val data = {
525 24706532 : .length = mdb_data.mv_size,
526 24706532 : .data = mdb_data.mv_data,
527 : };
528 :
529 24706532 : if (mdb_cmp(txn, dbi, &mdb_key, &mdb_e_key) > 0) {
530 1509 : goto done;
531 : }
532 :
533 24705782 : ret = fn(ldb_kv, key, data, ctx);
534 24705782 : if (ret != 0) {
535 : /*
536 : * NOTE: This DOES NOT set lmdb->error!
537 : *
538 : * This means that the caller will get success.
539 : * This matches TDB traverse behaviour, where callbacks
540 : * may terminate the traverse, but do not change the
541 : * return code from success.
542 : *
543 : * Callers SHOULD store their own error codes.
544 : */
545 9 : goto done;
546 : }
547 : }
548 11077 : if (lmdb->error == MDB_NOTFOUND) {
549 11077 : lmdb->error = MDB_SUCCESS;
550 : }
551 11903 : done:
552 11950 : if (cursor != NULL) {
553 11950 : mdb_cursor_close(cursor);
554 : }
555 :
556 11950 : if (lmdb->error != MDB_SUCCESS) {
557 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
558 : }
559 11950 : return ldb_mdb_err_map(lmdb->error);
560 : }
561 :
562 67107811 : static int lmdb_lock_read(struct ldb_module *module)
563 : {
564 67107811 : void *data = ldb_module_get_private(module);
565 65955847 : struct ldb_kv_private *ldb_kv =
566 1151964 : talloc_get_type(data, struct ldb_kv_private);
567 67107811 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
568 67107811 : pid_t pid = getpid();
569 :
570 67107811 : if (pid != lmdb->pid) {
571 0 : ldb_asprintf_errstring(
572 : lmdb->ldb,
573 : __location__": Reusing ldb opened by pid %d in "
574 : "process %d\n",
575 : lmdb->pid,
576 : pid);
577 0 : lmdb->error = MDB_BAD_TXN;
578 0 : return LDB_ERR_PROTOCOL_ERROR;
579 : }
580 :
581 67107811 : lmdb->error = MDB_SUCCESS;
582 105979916 : if (lmdb_transaction_active(ldb_kv) == false &&
583 39257633 : ldb_kv->read_lock_count == 0) {
584 9350909 : lmdb->error = mdb_txn_begin(lmdb->env,
585 : NULL,
586 : MDB_RDONLY,
587 : &lmdb->read_txn);
588 : }
589 67107811 : if (lmdb->error != MDB_SUCCESS) {
590 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
591 : }
592 :
593 67107811 : ldb_kv->read_lock_count++;
594 67107811 : return ldb_mdb_err_map(lmdb->error);
595 : }
596 :
597 67107811 : static int lmdb_unlock_read(struct ldb_module *module)
598 : {
599 67107811 : void *data = ldb_module_get_private(module);
600 65955847 : struct ldb_kv_private *ldb_kv =
601 1151964 : talloc_get_type(data, struct ldb_kv_private);
602 :
603 105979916 : if (lmdb_transaction_active(ldb_kv) == false &&
604 39257633 : ldb_kv->read_lock_count == 1) {
605 9350909 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
606 9350909 : mdb_txn_commit(lmdb->read_txn);
607 9350909 : lmdb->read_txn = NULL;
608 9350909 : ldb_kv->read_lock_count--;
609 9350909 : return LDB_SUCCESS;
610 : }
611 57756902 : ldb_kv->read_lock_count--;
612 57756902 : return LDB_SUCCESS;
613 : }
614 :
615 747381 : static int lmdb_transaction_start(struct ldb_kv_private *ldb_kv)
616 : {
617 747381 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
618 : struct lmdb_trans *ltx;
619 : struct lmdb_trans *ltx_head;
620 : MDB_txn *tx_parent;
621 747381 : pid_t pid = getpid();
622 :
623 : /* Do not take out the transaction lock on a read-only DB */
624 747381 : if (ldb_kv->read_only) {
625 0 : return LDB_ERR_UNWILLING_TO_PERFORM;
626 : }
627 :
628 747381 : ltx = talloc_zero(lmdb, struct lmdb_trans);
629 747381 : if (ltx == NULL) {
630 0 : return ldb_oom(lmdb->ldb);
631 : }
632 :
633 747381 : if (pid != lmdb->pid) {
634 0 : ldb_asprintf_errstring(
635 : lmdb->ldb,
636 : __location__": Reusing ldb opened by pid %d in "
637 : "process %d\n",
638 : lmdb->pid,
639 : pid);
640 0 : lmdb->error = MDB_BAD_TXN;
641 0 : return LDB_ERR_PROTOCOL_ERROR;
642 : }
643 :
644 : /*
645 : * Clear out any stale readers
646 : */
647 : {
648 747381 : int stale = 0;
649 747381 : mdb_reader_check(lmdb->env, &stale);
650 747381 : if (stale > 0) {
651 0 : ldb_debug(
652 : lmdb->ldb,
653 : LDB_DEBUG_ERROR,
654 : "LMDB Stale readers, deleted (%d)",
655 : stale);
656 : }
657 : }
658 :
659 :
660 :
661 747381 : ltx_head = lmdb_private_trans_head(lmdb);
662 :
663 747381 : tx_parent = lmdb_trans_get_tx(ltx_head);
664 :
665 747381 : lmdb->error = mdb_txn_begin(lmdb->env, tx_parent, 0, <x->tx);
666 747381 : if (lmdb->error != MDB_SUCCESS) {
667 0 : return ldb_mdb_error(lmdb->ldb, lmdb->error);
668 : }
669 :
670 747381 : trans_push(lmdb, ltx);
671 :
672 747381 : return ldb_mdb_err_map(lmdb->error);
673 : }
674 :
675 41622 : static int lmdb_transaction_cancel(struct ldb_kv_private *ldb_kv)
676 : {
677 : struct lmdb_trans *ltx;
678 41622 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
679 :
680 41622 : ltx = lmdb_private_trans_head(lmdb);
681 41622 : if (ltx == NULL) {
682 1 : return LDB_ERR_OPERATIONS_ERROR;
683 : }
684 :
685 41621 : mdb_txn_abort(ltx->tx);
686 41621 : trans_finished(lmdb, ltx);
687 41621 : return LDB_SUCCESS;
688 : }
689 :
690 361091 : static int lmdb_transaction_prepare_commit(struct ldb_kv_private *ldb_kv)
691 : {
692 : /* No need to prepare a commit */
693 361091 : return LDB_SUCCESS;
694 : }
695 :
696 705760 : static int lmdb_transaction_commit(struct ldb_kv_private *ldb_kv)
697 : {
698 : struct lmdb_trans *ltx;
699 705760 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
700 :
701 705760 : ltx = lmdb_private_trans_head(lmdb);
702 705760 : if (ltx == NULL) {
703 0 : return LDB_ERR_OPERATIONS_ERROR;
704 : }
705 :
706 705760 : lmdb->error = mdb_txn_commit(ltx->tx);
707 705760 : trans_finished(lmdb, ltx);
708 :
709 705760 : return lmdb->error;
710 : }
711 :
712 22062 : static int lmdb_error(struct ldb_kv_private *ldb_kv)
713 : {
714 22062 : return ldb_mdb_err_map(ldb_kv->lmdb_private->error);
715 : }
716 :
717 0 : static const char *lmdb_errorstr(struct ldb_kv_private *ldb_kv)
718 : {
719 0 : return mdb_strerror(ldb_kv->lmdb_private->error);
720 : }
721 :
722 0 : static const char *lmdb_name(struct ldb_kv_private *ldb_kv)
723 : {
724 0 : return "lmdb";
725 : }
726 :
727 50651570 : static bool lmdb_changed(struct ldb_kv_private *ldb_kv)
728 : {
729 : /*
730 : * lmdb does no provide a quick way to determine if the database
731 : * has changed. This function always returns true.
732 : *
733 : * Note that tdb uses a sequence number that allows this function
734 : * to be implemented efficiently.
735 : */
736 50651570 : return true;
737 : }
738 :
739 : /*
740 : * Get the number of records in the database.
741 : *
742 : * The mdb_env_stat call returns an accurate count, so we return the actual
743 : * number of records in the database rather than an estimate.
744 : */
745 0 : static size_t lmdb_get_size(struct ldb_kv_private *ldb_kv)
746 : {
747 :
748 0 : struct MDB_stat stats = {0};
749 0 : struct lmdb_private *lmdb = ldb_kv->lmdb_private;
750 0 : int ret = 0;
751 :
752 0 : ret = mdb_env_stat(lmdb->env, &stats);
753 0 : if (ret != 0) {
754 0 : return 0;
755 : }
756 0 : return stats.ms_entries;
757 : }
758 :
759 : /*
760 : * Start a sub transaction
761 : * As lmdb supports nested transactions we can start a new transaction
762 : */
763 344712 : static int lmdb_nested_transaction_start(struct ldb_kv_private *ldb_kv)
764 : {
765 344712 : int ret = lmdb_transaction_start(ldb_kv);
766 344712 : return ret;
767 : }
768 :
769 : /*
770 : * Commit a sub transaction
771 : * As lmdb supports nested transactions we can commit the nested transaction
772 : */
773 343967 : static int lmdb_nested_transaction_commit(struct ldb_kv_private *ldb_kv)
774 : {
775 343967 : int ret = lmdb_transaction_commit(ldb_kv);
776 343967 : return ret;
777 : }
778 :
779 : /*
780 : * Cancel a sub transaction
781 : * As lmdb supports nested transactions we can cancel the nested transaction
782 : */
783 745 : static int lmdb_nested_transaction_cancel(struct ldb_kv_private *ldb_kv)
784 : {
785 745 : int ret = lmdb_transaction_cancel(ldb_kv);
786 745 : return ret;
787 : }
788 :
789 : static struct kv_db_ops lmdb_key_value_ops = {
790 : .options = LDB_KV_OPTION_STABLE_READ_LOCK,
791 :
792 : .store = lmdb_store,
793 : .delete = lmdb_delete,
794 : .iterate = lmdb_traverse_fn,
795 : .update_in_iterate = lmdb_update_in_iterate,
796 : .fetch_and_parse = lmdb_parse_record,
797 : .iterate_range = lmdb_iterate_range,
798 : .lock_read = lmdb_lock_read,
799 : .unlock_read = lmdb_unlock_read,
800 : .begin_write = lmdb_transaction_start,
801 : .prepare_write = lmdb_transaction_prepare_commit,
802 : .finish_write = lmdb_transaction_commit,
803 : .abort_write = lmdb_transaction_cancel,
804 : .error = lmdb_error,
805 : .errorstr = lmdb_errorstr,
806 : .name = lmdb_name,
807 : .has_changed = lmdb_changed,
808 : .transaction_active = lmdb_transaction_active,
809 : .get_size = lmdb_get_size,
810 : .begin_nested_write = lmdb_nested_transaction_start,
811 : .finish_nested_write = lmdb_nested_transaction_commit,
812 : .abort_nested_write = lmdb_nested_transaction_cancel,
813 : };
814 :
815 150865 : static const char *lmdb_get_path(const char *url)
816 : {
817 : const char *path;
818 :
819 : /* parse the url */
820 150865 : if (strchr(url, ':')) {
821 150812 : if (strncmp(url, MDB_URL_PREFIX, MDB_URL_PREFIX_SIZE) != 0) {
822 0 : return NULL;
823 : }
824 150812 : path = url + MDB_URL_PREFIX_SIZE;
825 : } else {
826 53 : path = url;
827 : }
828 :
829 150865 : return path;
830 : }
831 :
832 145344 : static int lmdb_pvt_destructor(struct lmdb_private *lmdb)
833 : {
834 145344 : struct lmdb_trans *ltx = NULL;
835 :
836 : /* Check if this is a forked child */
837 145344 : if (getpid() != lmdb->pid) {
838 3550 : int fd = 0;
839 : /*
840 : * We cannot call mdb_env_close or commit any transactions,
841 : * otherwise they might appear finished in the parent.
842 : *
843 : */
844 :
845 3550 : if (mdb_env_get_fd(lmdb->env, &fd) == 0) {
846 3550 : close(fd);
847 : }
848 :
849 : /* Remove the pointer, so that no access should occur */
850 3550 : lmdb->env = NULL;
851 :
852 3550 : return 0;
853 : }
854 :
855 : /*
856 : * Close the read transaction if it's open
857 : */
858 141794 : if (lmdb->read_txn != NULL) {
859 0 : mdb_txn_abort(lmdb->read_txn);
860 : }
861 :
862 141794 : if (lmdb->env == NULL) {
863 0 : return 0;
864 : }
865 :
866 : /*
867 : * Abort any currently active transactions
868 : */
869 141794 : ltx = lmdb_private_trans_head(lmdb);
870 277788 : while (ltx != NULL) {
871 0 : mdb_txn_abort(ltx->tx);
872 0 : trans_finished(lmdb, ltx);
873 0 : ltx = lmdb_private_trans_head(lmdb);
874 : }
875 141794 : lmdb->env = NULL;
876 :
877 141794 : return 0;
878 : }
879 :
880 : struct mdb_env_wrap {
881 : struct mdb_env_wrap *next, *prev;
882 : dev_t device;
883 : ino_t inode;
884 : MDB_env *env;
885 : pid_t pid;
886 : };
887 :
888 : static struct mdb_env_wrap *mdb_list;
889 :
890 : /* destroy the last connection to an mdb */
891 23485 : static int mdb_env_wrap_destructor(struct mdb_env_wrap *w)
892 : {
893 23485 : mdb_env_close(w->env);
894 23485 : DLIST_REMOVE(mdb_list, w);
895 23485 : return 0;
896 : }
897 :
898 150865 : static int lmdb_open_env(TALLOC_CTX *mem_ctx,
899 : MDB_env **env,
900 : struct ldb_context *ldb,
901 : const char *path,
902 : const size_t env_map_size,
903 : unsigned int flags)
904 : {
905 : int ret;
906 150865 : unsigned int mdb_flags = MDB_NOSUBDIR|MDB_NOTLS;
907 : /*
908 : * MDB_NOSUBDIR implies there is a separate file called path and a
909 : * separate lockfile called path-lock
910 : */
911 :
912 : struct mdb_env_wrap *w;
913 : struct stat st;
914 150865 : pid_t pid = getpid();
915 150865 : int fd = 0;
916 : unsigned v;
917 :
918 150865 : if (stat(path, &st) == 0) {
919 500336 : for (w=mdb_list;w;w=w->next) {
920 922488 : if (st.st_dev == w->device &&
921 599039 : st.st_ino == w->inode &&
922 132275 : pid == w->pid) {
923 : /*
924 : * We must have only one MDB_env per process
925 : */
926 121895 : if (!talloc_reference(mem_ctx, w)) {
927 0 : return ldb_oom(ldb);
928 : }
929 121895 : *env = w->env;
930 121895 : return LDB_SUCCESS;
931 : }
932 : }
933 : }
934 :
935 28970 : w = talloc(mem_ctx, struct mdb_env_wrap);
936 28970 : if (w == NULL) {
937 0 : return ldb_oom(ldb);
938 : }
939 :
940 28970 : ret = mdb_env_create(env);
941 28970 : if (ret != 0) {
942 0 : ldb_asprintf_errstring(
943 : ldb,
944 : "Could not create MDB environment %s: %s\n",
945 : path,
946 : mdb_strerror(ret));
947 0 : return ldb_mdb_err_map(ret);
948 : }
949 :
950 28970 : if (env_map_size > 0) {
951 199 : ret = mdb_env_set_mapsize(*env, env_map_size);
952 199 : if (ret != 0) {
953 0 : ldb_asprintf_errstring(
954 : ldb,
955 : "Could not set MDB mmap() size to %llu "
956 : "on %s: %s\n",
957 : (unsigned long long)(env_map_size),
958 : path,
959 : mdb_strerror(ret));
960 0 : TALLOC_FREE(w);
961 0 : return ldb_mdb_err_map(ret);
962 : }
963 : }
964 :
965 28970 : mdb_env_set_maxreaders(*env, 100000);
966 : /*
967 : * As we ensure that there is only one MDB_env open per database per
968 : * process. We can not use the MDB_RDONLY flag, as another ldb may be
969 : * opened in read write mode
970 : */
971 28970 : if (flags & LDB_FLG_NOSYNC) {
972 28294 : mdb_flags |= MDB_NOSYNC;
973 : }
974 28970 : ret = mdb_env_open(*env, path, mdb_flags, 0644);
975 28970 : if (ret != 0) {
976 53 : ldb_asprintf_errstring(ldb,
977 : "Could not open DB %s: %s\n",
978 : path, mdb_strerror(ret));
979 53 : TALLOC_FREE(w);
980 53 : return ldb_mdb_err_map(ret);
981 : }
982 :
983 : {
984 28917 : MDB_envinfo stat = {0};
985 28917 : ret = mdb_env_info (*env, &stat);
986 28917 : if (ret != 0) {
987 0 : ldb_asprintf_errstring(
988 : ldb,
989 : "Could not get MDB environment stats %s: %s\n",
990 : path,
991 : mdb_strerror(ret));
992 0 : return ldb_mdb_err_map(ret);
993 : }
994 : }
995 :
996 28917 : ret = mdb_env_get_fd(*env, &fd);
997 28917 : if (ret != 0) {
998 0 : ldb_asprintf_errstring(ldb,
999 : "Could not obtain DB FD %s: %s\n",
1000 : path, mdb_strerror(ret));
1001 0 : TALLOC_FREE(w);
1002 0 : return ldb_mdb_err_map(ret);
1003 : }
1004 :
1005 : /* Just as for TDB: on exec, don't inherit the fd */
1006 28917 : v = fcntl(fd, F_GETFD, 0);
1007 28917 : if (v == -1) {
1008 0 : TALLOC_FREE(w);
1009 0 : return LDB_ERR_OPERATIONS_ERROR;
1010 : }
1011 :
1012 28917 : ret = fcntl(fd, F_SETFD, v | FD_CLOEXEC);
1013 28917 : if (ret == -1) {
1014 0 : TALLOC_FREE(w);
1015 0 : return LDB_ERR_OPERATIONS_ERROR;
1016 : }
1017 :
1018 28917 : if (fstat(fd, &st) != 0) {
1019 0 : ldb_asprintf_errstring(
1020 : ldb,
1021 : "Could not stat %s:\n",
1022 : path);
1023 0 : TALLOC_FREE(w);
1024 0 : return LDB_ERR_OPERATIONS_ERROR;
1025 : }
1026 28917 : w->env = *env;
1027 28917 : w->device = st.st_dev;
1028 28917 : w->inode = st.st_ino;
1029 28917 : w->pid = pid;
1030 :
1031 28917 : talloc_set_destructor(w, mdb_env_wrap_destructor);
1032 :
1033 28917 : DLIST_ADD(mdb_list, w);
1034 :
1035 28917 : return LDB_SUCCESS;
1036 :
1037 : }
1038 :
1039 150865 : static int lmdb_pvt_open(struct lmdb_private *lmdb,
1040 : struct ldb_context *ldb,
1041 : const char *path,
1042 : const size_t env_map_size,
1043 : unsigned int flags)
1044 : {
1045 : int ret;
1046 : int lmdb_max_key_length;
1047 :
1048 150865 : if (flags & LDB_FLG_DONT_CREATE_DB) {
1049 : struct stat st;
1050 149457 : if (stat(path, &st) != 0) {
1051 0 : return LDB_ERR_UNAVAILABLE;
1052 : }
1053 : }
1054 :
1055 150865 : ret = lmdb_open_env(lmdb, &lmdb->env, ldb, path, env_map_size, flags);
1056 150865 : if (ret != 0) {
1057 53 : return ret;
1058 : }
1059 :
1060 : /* Close when lmdb is released */
1061 150812 : talloc_set_destructor(lmdb, lmdb_pvt_destructor);
1062 :
1063 : /* Store the original pid during the LMDB open */
1064 150812 : lmdb->pid = getpid();
1065 :
1066 150812 : lmdb_max_key_length = mdb_env_get_maxkeysize(lmdb->env);
1067 :
1068 : /* This will never happen, but if it does make sure to freak out */
1069 150812 : if (lmdb_max_key_length < LDB_MDB_MAX_KEY_LENGTH) {
1070 0 : return ldb_operr(ldb);
1071 : }
1072 :
1073 150812 : return LDB_SUCCESS;
1074 : }
1075 :
1076 150865 : int lmdb_connect(struct ldb_context *ldb,
1077 : const char *url,
1078 : unsigned int flags,
1079 : const char *options[],
1080 : struct ldb_module **_module)
1081 : {
1082 150865 : const char *path = NULL;
1083 150865 : struct lmdb_private *lmdb = NULL;
1084 150865 : struct ldb_kv_private *ldb_kv = NULL;
1085 : int ret;
1086 150865 : size_t env_map_size = 0;
1087 :
1088 : /*
1089 : * We hold locks, so we must use a private event context
1090 : * on each returned handle
1091 : */
1092 150865 : ldb_set_require_private_event_context(ldb);
1093 :
1094 150865 : path = lmdb_get_path(url);
1095 150865 : if (path == NULL) {
1096 0 : ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid mdb URL '%s'", url);
1097 0 : return LDB_ERR_OPERATIONS_ERROR;
1098 : }
1099 :
1100 150865 : ldb_kv = talloc_zero(ldb, struct ldb_kv_private);
1101 150865 : if (!ldb_kv) {
1102 0 : ldb_oom(ldb);
1103 0 : return LDB_ERR_OPERATIONS_ERROR;
1104 : }
1105 :
1106 150865 : lmdb = talloc_zero(ldb_kv, struct lmdb_private);
1107 150865 : if (lmdb == NULL) {
1108 0 : TALLOC_FREE(ldb_kv);
1109 0 : return ldb_oom(ldb);
1110 : }
1111 150865 : lmdb->ldb = ldb;
1112 150865 : ldb_kv->kv_ops = &lmdb_key_value_ops;
1113 :
1114 : {
1115 150865 : const char *size = ldb_options_find(
1116 : ldb, ldb->options, "lmdb_env_size");
1117 150865 : if (size != NULL) {
1118 199 : env_map_size = strtoull(size, NULL, 0);
1119 : }
1120 : }
1121 :
1122 150865 : ret = lmdb_pvt_open(lmdb, ldb, path, env_map_size, flags);
1123 150865 : if (ret != LDB_SUCCESS) {
1124 53 : TALLOC_FREE(ldb_kv);
1125 53 : return ret;
1126 : }
1127 :
1128 150812 : ldb_kv->lmdb_private = lmdb;
1129 150812 : if (flags & LDB_FLG_RDONLY) {
1130 30 : ldb_kv->read_only = true;
1131 : }
1132 :
1133 : /*
1134 : * This maximum length becomes encoded in the index values so
1135 : * must never change even if LMDB starts to allow longer keys.
1136 : * The override option is max_key_len_for_self_test, and is
1137 : * used for testing only.
1138 : */
1139 150812 : ldb_kv->max_key_length = LDB_MDB_MAX_KEY_LENGTH;
1140 :
1141 150812 : return ldb_kv_init_store(
1142 : ldb_kv, "ldb_mdb backend", ldb, options, _module);
1143 : }
|