@@ -272,7 +272,6 @@ struct trust_db_metrics {
272272};
273273
274274static struct trust_db_metrics trust_metrics ;
275- static struct trust_db_read_handle walk_read ;
276275
277276struct trust_db_sizing_state {
278277 size_t page_size ;
@@ -373,6 +372,7 @@ static int do_memfd_update_to_dbi_in_env(MDB_env *target_env, int memfd,
373372 MDB_dbi target_dbi , unsigned int maxkeysize , long * entries );
374373static void close_env (int do_close_dbi );
375374static void log_lmdb_state (int priority , const char * context , int lmdb_rc );
375+ static void walk_database_reset (void );
376376
377377// External variables
378378extern atomic_bool stop ;
@@ -2633,7 +2633,6 @@ static void close_env(int do_close_dbi)
26332633 env = NULL ;
26342634 dbi_init = 0 ;
26352635 metadata_dbi_init = 0 ;
2636- memset (& walk_read , 0 , sizeof (walk_read ));
26372636}
26382637
26392638struct lmdb_reader_log {
@@ -5518,65 +5517,150 @@ void database_compact_from_backends(conf_t *config)
55185517 * only operation.
55195518 ***********************************************************************/
55205519static walkdb_entry_t wdb_entry ;
5520+ static MDB_env * walk_env ;
5521+ static MDB_txn * walk_txn ;
5522+ static MDB_cursor * walk_cursor ;
55215523
5522- // Returns WALK_DATABASE_SUCCESS, WALK_DATABASE_EMPTY, or WALK_DATABASE_ERROR
5524+ /*
5525+ * walk_database_reset - close private read-only CLI walk state.
5526+ * @void: no arguments are required.
5527+ *
5528+ * The walker owns these handles. They are intentionally separate from the
5529+ * daemon's global LMDB environment so cleanup here never closes or mutates
5530+ * daemon state.
5531+ *
5532+ * Returns nothing.
5533+ */
5534+ static void walk_database_reset (void )
5535+ {
5536+ if (walk_cursor )
5537+ mdb_cursor_close (walk_cursor );
5538+ if (walk_txn )
5539+ mdb_txn_abort (walk_txn );
5540+ if (walk_env )
5541+ mdb_env_close (walk_env );
5542+ walk_cursor = NULL ;
5543+ walk_txn = NULL ;
5544+ walk_env = NULL ;
5545+ }
5546+
5547+ /*
5548+ * walk_database_start - open the trust DB for CLI verification.
5549+ * @config: Unused legacy argument kept for the CLI walker API.
5550+ *
5551+ * This must stay a read-only walk. Do not call init_db() or
5552+ * trust_db_read_open() here: those paths open the daemon-style environment and
5553+ * may take write-side LMDB state while setting up handles. The CLI verifier
5554+ * only needs a private read transaction and cursor over the active named DB.
5555+ *
5556+ * Returns WALK_DATABASE_SUCCESS, WALK_DATABASE_EMPTY, or WALK_DATABASE_ERROR.
5557+ */
55235558int walk_database_start (conf_t * config )
55245559{
5560+ MDB_dbi walk_metadata_dbi , walk_dbi ;
5561+ struct trust_db_metadata metadata ;
5562+ char active_name [TRUST_DB_GENERATION_NAME_SIZE ];
55255563 int rc ;
55265564
5527- // Initialize the database
5528- if (init_db (config )) {
5529- printf ("Cannot open the trust database\n" );
5530- return WALK_DATABASE_ERROR ;
5531- }
5532- rc = database_empty ();
5533- if (rc > 0 ) {
5534- printf ("The trust database is empty - nothing to do\n" );
5535- close_db (0 );
5536- return WALK_DATABASE_EMPTY ;
5537- } else if (rc < 0 ) {
5538- close_db (0 );
5539- return WALK_DATABASE_ERROR ;
5540- }
5565+ (void )config ;
5566+ walk_database_reset ();
5567+ snprintf (active_name , sizeof (active_name ), "%s" , db );
55415568
5542- // Position to the first entry
5543- if (trust_db_read_open (& walk_read )) {
5544- puts ("Cannot open the trust database for reading" );
5545- close_db (0 );
5569+ rc = mdb_env_create (& walk_env );
5570+ if (rc ) {
5571+ printf ("Cannot create the trust database environment\n" );
55465572 return WALK_DATABASE_ERROR ;
55475573 }
55485574
5549- if ((rc = mdb_cursor_get (walk_read .cursor , & wdb_entry .path ,
5550- & wdb_entry .data ,
5551- MDB_FIRST )) == 0 )
5575+ rc = mdb_env_set_maxdbs (walk_env , TRUST_DB_MAX_NAMED_DBS );
5576+ if (rc )
5577+ goto error ;
5578+
5579+ /*
5580+ * MDB_NOLOCK is paired with MDB_RDONLY so the verifier never opens
5581+ * lock.mdb or touches LMDB's shared robust mutexes.
5582+ */
5583+ rc = mdb_env_open (walk_env , data_dir , MDB_RDONLY |MDB_NOLOCK , 0 );
5584+ if (rc )
5585+ goto error ;
5586+
5587+ rc = mdb_txn_begin (walk_env , NULL , MDB_RDONLY , & walk_txn );
5588+ if (rc )
5589+ goto error ;
5590+
5591+ rc = mdb_dbi_open (walk_txn , TRUST_DB_METADATA_NAME , 0 ,
5592+ & walk_metadata_dbi );
5593+ if (rc == 0 ) {
5594+ rc = trust_db_metadata_read_from_dbi (walk_txn , walk_metadata_dbi ,
5595+ & metadata );
5596+ if (rc == 0 )
5597+ snprintf (active_name , sizeof (active_name ), "%s" ,
5598+ metadata .name );
5599+ else if (rc != MDB_NOTFOUND )
5600+ goto error ;
5601+ } else if (rc != MDB_NOTFOUND )
5602+ goto error ;
5603+
5604+ rc = mdb_dbi_open (walk_txn , active_name , MDB_DUPSORT , & walk_dbi );
5605+ if (rc )
5606+ goto error ;
5607+
5608+ rc = mdb_cursor_open (walk_txn , walk_dbi , & walk_cursor );
5609+ if (rc )
5610+ goto error ;
5611+
5612+ /*
5613+ * Keep walk_txn open for the cursor lifetime. The returned MDB_val
5614+ * buffers point into LMDB-managed memory and remain valid until the
5615+ * cursor/transaction is closed by walk_database_reset().
5616+ */
5617+ rc = mdb_cursor_get (walk_cursor , & wdb_entry .path , & wdb_entry .data ,
5618+ MDB_FIRST );
5619+ if (rc == 0 ) {
5620+ /* Keep handles open so walk_database_next() can continue. */
55525621 return WALK_DATABASE_SUCCESS ;
5622+ }
55535623
5554- if (rc != MDB_NOTFOUND ) {
5555- puts (mdb_strerror (rc ));
5556- rc = WALK_DATABASE_ERROR ;
5557- } else {
5624+ if (rc == MDB_NOTFOUND ) {
55585625 printf ("The trust database is empty - nothing to do\n" );
5559- rc = WALK_DATABASE_EMPTY ;
5626+ walk_database_reset ();
5627+ return WALK_DATABASE_EMPTY ;
55605628 }
55615629
5562- trust_db_read_close (& walk_read );
5563- close_db (0 );
5564- return rc ;
5630+ error :
5631+ if (rc )
5632+ puts (mdb_strerror (rc ));
5633+ walk_database_reset ();
5634+ return WALK_DATABASE_ERROR ;
55655635}
55665636
5637+ /*
5638+ * walk_database_get_entry - return the current walker entry.
5639+ * @void: no arguments are required.
5640+ *
5641+ * The entry's MDB_val buffers are owned by LMDB and are valid until the next
5642+ * walk_database_next() call or walk_database_finish().
5643+ *
5644+ * Returns a pointer to the current walker entry.
5645+ */
55675646walkdb_entry_t * walk_database_get_entry (void )
55685647{
55695648 return & wdb_entry ;
55705649}
55715650
5572- // Returns 1 on success and 0 in error
5651+ /*
5652+ * walk_database_next - advance the CLI verification cursor.
5653+ * @void: no arguments are required.
5654+ *
5655+ * Returns 1 when another entry is available and 0 at end of walk or on error.
5656+ */
55735657int walk_database_next (void )
55745658{
55755659 int rc ;
55765660
5577- if (( rc = mdb_cursor_get (walk_read . cursor , & wdb_entry .path ,
5578- & wdb_entry . data ,
5579- MDB_NEXT )) == 0 )
5661+ rc = mdb_cursor_get (walk_cursor , & wdb_entry .path , & wdb_entry . data ,
5662+ MDB_NEXT );
5663+ if ( rc == 0 )
55805664 return 1 ;
55815665
55825666 if (rc != MDB_NOTFOUND )
@@ -5585,8 +5669,13 @@ int walk_database_next(void)
55855669 return 0 ;
55865670}
55875671
5672+ /*
5673+ * walk_database_finish - close the CLI verification cursor.
5674+ * @void: no arguments are required.
5675+ *
5676+ * Returns nothing.
5677+ */
55885678void walk_database_finish (void )
55895679{
5590- trust_db_read_close (& walk_read );
5591- close_db (0 );
5680+ walk_database_reset ();
55925681}
0 commit comments