Created
July 1, 2026 18:01
-
-
Save ChrisTX/731122de698a13497d808f8e0072310b to your computer and use it in GitHub Desktop.
Postfix LMDB 1.0 fix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| From c2e9644f278ff31cd664c7638d7f5672a71aab33 Mon Sep 17 00:00:00 2001 | |
| From: Christian Pfeiffer <cpfeiffer@rev-crew.info> | |
| Date: Wed, 1 Jul 2026 19:59:03 +0200 | |
| Subject: [PATCH] Postfix: Resolve LMDB 1.0 compatibility | |
| --- | |
| postfix/src/util/slmdb.c | 69 ++++++++++++++++++++++++---------------- | |
| 1 file changed, 42 insertions(+), 27 deletions(-) | |
| diff --git a/postfix/src/util/slmdb.c b/postfix/src/util/slmdb.c | |
| index e1b8fd64c..e30aeee80 100644 | |
| --- a/postfix/src/util/slmdb.c | |
| +++ b/postfix/src/util/slmdb.c | |
| @@ -381,40 +381,55 @@ static int slmdb_saved_key_assign(SLMDB *slmdb, MDB_val *key_val) | |
| static int slmdb_prepare(SLMDB *slmdb) | |
| { | |
| - int status = 0; | |
| + int status = 0; | |
| - /* | |
| - * This is called before accessing the database, or after recovery from | |
| - * an LMDB error. Note: this code cannot recover from errors itself. | |
| - * slmdb->txn is either the database open() transaction or a | |
| - * freshly-created bulk-mode transaction. When slmdb_prepare() commits or | |
| - * aborts commits a transaction, it must set slmdb->txn to null to avoid | |
| - * a use-after-free error in slmdb_close(). | |
| - * | |
| - * - With O_TRUNC we make a "drop" request before updating the database. | |
| - * | |
| - * - With a bulk-mode transaction we commit when the database is closed. | |
| - */ | |
| if (slmdb->open_flags & O_TRUNC) { | |
| - if ((status = mdb_drop(slmdb->txn, slmdb->dbi, 0)) != 0) { | |
| - mdb_txn_abort(slmdb->txn); | |
| - slmdb->txn = 0; | |
| - return (status); | |
| - } | |
| - if ((slmdb->slmdb_flags & SLMDB_FLAG_BULK) == 0) { | |
| - status = mdb_txn_commit(slmdb->txn); | |
| - slmdb->txn = 0; | |
| - if (status != 0) | |
| - return (status); | |
| - } | |
| + | |
| + /* Drop the main DB — this dirties the transaction */ | |
| + status = mdb_drop(slmdb->txn, slmdb->dbi, 0); | |
| + | |
| + /* Regardless of success, this txn MUST be aborted */ | |
| + mdb_txn_abort(slmdb->txn); | |
| + slmdb->txn = 0; | |
| + | |
| + if (status != 0) | |
| + return status; | |
| + | |
| + /* | |
| + * Now reopen the main DB in a fresh transaction. | |
| + * This replaces the old DBI handle. | |
| + */ | |
| + MDB_txn *txn2; | |
| + status = mdb_txn_begin(slmdb->env, NULL, 0, &txn2); | |
| + if (status != 0) | |
| + return status; | |
| + | |
| + status = mdb_dbi_open(txn2, NULL, 0, &slmdb->dbi); | |
| + if (status != 0) { | |
| + mdb_txn_abort(txn2); | |
| + return status; | |
| + } | |
| + | |
| + /* Commit the DBI re-open unless bulk mode defers it */ | |
| + if ((slmdb->slmdb_flags & SLMDB_FLAG_BULK) == 0) { | |
| + status = mdb_txn_commit(txn2); | |
| + if (status != 0) | |
| + return status; | |
| + } else { | |
| + slmdb->txn = txn2; /* bulk mode keeps txn open */ | |
| + } | |
| + | |
| } else if ((slmdb->slmdb_flags & SLMDB_FLAG_BULK) == 0) { | |
| - mdb_txn_abort(slmdb->txn); | |
| - slmdb->txn = 0; | |
| + /* Normal case: abort the open transaction */ | |
| + mdb_txn_abort(slmdb->txn); | |
| + slmdb->txn = 0; | |
| } | |
| + | |
| slmdb->api_retry_count = 0; | |
| - return (status); | |
| + return status; | |
| } | |
| + | |
| /* slmdb_recover - recover from LMDB errors */ | |
| static int slmdb_recover(SLMDB *slmdb, int status) | |
| -- | |
| 2.55.0 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment