Coverity (#28)
* stratum_server: resolve CID 210144 (UNINIT_CTOR)
* stratum_server: resolve CID 210042/210085/210104 (UNCAUGHT_EXCEPT)
The potential to throw exists within the logger,
remove_blockchain_update_listener, and any paths involving the logger
(including CATCH_ENTRY_*).
* epee: misc_log_ex: create CATCH_ENTRY_NO_RETURN macro
A temporary substition for what I hope will eventually be a full-fledged
exception-dispatcher (class-based, not macro).
* stratum_server: resolve CID 210080/210084/210089 (UNCAUGHT_EXCEPT)
The potential to throw exists within the logger,
remove_protocol_handler, and any paths involving the logger
(including CATCH_ENTRY_*).
* epee: levin_protocol_handler_async: resolve CID 210140/210182/210165 (UNCAUGHT_EXCEPT)
The potential to throw exists within guarded_critical_region_t, and any
paths involving the logger (including CATCH_ENTRY_*).
* epee: levin_protocol_handler_async: resolve CID 210110/210119/210155 (UNCAUGHT_EXCEPT)
The potential to throw exists within the logger, del_connection, and any
paths involving the logger (including CATCH_ENTRY_*).
* epee: misc_log_ex: move macros to *top* of file
so they can be used *within* this file.
* daemon: resolve CID 210069/210092/210166 (UNCAUGHT_EXCEPT)
The potential to throw exists within log_space, and any paths involving
the logger (including CATCH_ENTRY_*).
* daemon: return cstdlib proper types in main
* simplewallet: resolve 6 different CIDs (UNCAUGHT_EXCEPT)
CID: 210082
CID: 210086
CID: 210096
CID: 210147
CID: 210149
CID: 210150
The potential to throw exists throughout various paths in main.
* simplewallet: return cstdlib proper types in main
* simplewallet: resolve CID 210128/210160 (UNCAUGHT_EXCEPT)
The potential to throw exists within various paths, and any paths
involving the logger (including CATCH_ENTRY_*).
* conn_tool: resolve 5 different CIDs (UNCAUGHT_EXCEPT)
CID: 210038
CID: 210047
CID: 210108
CID: 210122
CID: 210157
The potential to throw exists throughout various paths in main.
* conn_tool: return cstdlib proper types in main
* miniupnp_helper: resolve CID 210050 (UNCAUGHT_EXCEPT)
The potential to throw exists within deinit, including any paths
involving the logger (including CATCH_ENTRY_*).
* epee: profile_tools: resolve CID 210055 (UNCAUGHT_EXCEPT)
The potential to throw exists within boost microsec_clock::localtime(),
and any paths involving the logger (including CATCH_ENTRY_*).
* db_backend_lmdb: resolve CID 210056/210133 (UNCAUGHT_EXCEPT)
The potential to throw exists within close(), including any paths
involving the logger (including CATCH_ENTRY_*).
* epee: misc_log_ex: resolve CID 210060/210124 (UNCAUGHT_EXCEPT)
The potential to throw exists within several paths, including any paths
involving the logger (including CATCH_ENTRY_*).
* epee: misc_language: resolve 4 CIDs (UNCAUGHT_EXCEPT)
CID: 210064
CID: 210093
CID: 210136
CID: 210139
The potential to throw exists within m_func(), including any paths
involving the logger (including CATCH_ENTRY_*).
* db_abstract_accessor: resolve 4 CIDs (UNCAUGHT_EXCEPT)
CID: 210072
CID: 210094
CID: 210116
CID: 210141
The potential to throw exists within m_cache.clear(), including any
paths involving the logger (including CATCH_ENTRY_*).
* epee: net_helper: resolve CID 210100 (UNCAUGHT_EXCEPT)
The potential to throw exists within shutdown(), including any
paths involving the logger (including CATCH_ENTRY_*).
* epee: syncobj: resolve CID 210123 (UNCAUGHT_EXCEPT)
The potential to throw exists within unlock(), including any
paths involving the logger (including CATCH_ENTRY_*).
* epee: profile_tools: resolve CID 210145/210154 (UNCAUGHT_EXCEPT)
The potential to throw exists within various paths, including any paths
involving the logger (including CATCH_ENTRY_*).
* epee: http_base: resolve CID 210176 (UNINIT_CTOR)
* p2p: net_node: resolve CID 210173 (UNINIT_CTOR)
* epee: net_helper: resolve CID 210138 (UNINIT_CTOR)
* p2p: net_peerlist: resolve CID 210137 (UNINIT_CTOR)
* currency_basic: resolve CID 210117 (UNINIT_CTOR)
* epee: abstract_tcp_server2: resolve 3 CIDs (UNINIT_CTOR)
CID: 210040
CID: 210090
CID: 210105
* simplewallet: resolve CID 210103 (UNINIT_CTOR)
* epee: levin_protocol_handler_async: resolve CID 210091 (UNINIT_CTOR)
* json_archive: resolve CID 210087 (UNINIT_CTOR)
* epee: levin_protocol_handler_async: resolve CID 210073 (UNINIT_CTOR)
* miniupnp_helper: resolve CID 210037 (UNINIT_CTOR)
* crypto: ge_frombytes_vartime: resolve CID 210142 (CHECKED_RETURN)
* wallet2: resolve CID 210041 (CHECKED_RETURN)
* epee: misc_log_ex: resolve CID 210127 (DEADCODE)
* epee: levin_protocol_handler_sync: resolve 3 CIDs (PASS_BY_VALUE)
CID: 210167
CID: 210170
CID: 210180
* p2p: net_node: resolve CID 210065 (PASS_BY_VALUE)
* epee: levin_abstract_invoke2: resolve CID 210049 (PASS_BY_VALUE)
* epee: abstract_tcp_server2: resolve CID 210045 (PASS_BY_VALUE)
* epee: misc_log_ex: add NESTED_*_ENTRY macros
* simplewallet: use NESTED_*_ENTRY in message_writer dtor
* stratum_protocol_handler_config: use NESTED_*_ENTRY in dtor
* stratum_protocol_handler: use NESTED_*_ENTRY in dtor
* lmdb_db_backend: use NESTED_*_ENTRY in dtor
* epee: abstract_tcp_server2: resolve 4 CIDs (UNCAUGHT_EXCEPT)
CID: 210088
CID: 210106
CID: 210164
CID: 210179
The potential to throw exists within various paths, including any
paths involving the logger (including CATCH_ENTRY_*).
* db_abstract_accessor: use NESTED_*_ENTRY in dtor
* miniupnp_helper: use NESTED_*_ENTRY in dtor
* epee: misc_log_ex: use NESTED_*_ENTRY in log_frame dtor
* epee: levin_protocol_handler_async: use NESTED_*_ENTRY in dtors
* epee: net_helper: use NESTED_*_ENTRY in dtor
* epee: profile_tools: use NESTED_*_ENTRY in dtors
* epee: misc_language: use NESTED_*_ENTRY in dtor
* epee: syncobj: use NESTED_*_ENTRY in dtor
* zano: license contact w/ zano.org email instead of sekreta.org email
2019-05-20 09:32:36 +00:00
// Copyright (c) 2014-2019 Zano Project
2018-12-27 18:50:45 +03:00
// Copyright (c) 2014-2018 The Louisdor Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
# include "db_backend_lmdb.h"
# include "misc_language.h"
# include "string_coding.h"
# include "profile_tools.h"
2019-08-10 05:31:47 +03:00
# include "util.h"
2018-12-27 18:50:45 +03:00
# define BUF_SIZE 1024
2019-11-29 12:34:10 +03:00
# define CHECK_AND_ASSERT_MESS_LMDB_DB(rc, ret, mess) CHECK_AND_ASSERT_MES(rc == MDB_SUCCESS, ret, "[DB ERROR]:(" << rc << ")" << mdb_strerror(rc) << ", [message]: " << mess);
# define CHECK_AND_ASSERT_THROW_MESS_LMDB_DB(rc, mess) CHECK_AND_ASSERT_THROW_MES(rc == MDB_SUCCESS, "[DB ERROR]:(" << rc << ")" << mdb_strerror(rc) << ", [message]: " << mess);
2019-06-06 23:08:21 +03:00
# define ASSERT_MES_AND_THROW_LMDB(rc, mess) ASSERT_MES_AND_THROW("[DB ERROR]:(" << rc << ")" << mdb_strerror(rc) << ", [message]: " << mess);
2018-12-27 18:50:45 +03:00
# undef LOG_DEFAULT_CHANNEL
# define LOG_DEFAULT_CHANNEL "lmdb"
// 'lmdb' channel is disabled by default
namespace tools
{
namespace db
{
2019-08-29 12:21:05 +03:00
lmdb_db_backend : : lmdb_db_backend ( ) : m_penv ( AUTO_VAL_INIT ( m_penv ) )
2018-12-27 18:50:45 +03:00
{
}
lmdb_db_backend : : ~ lmdb_db_backend ( )
{
Coverity (#28)
* stratum_server: resolve CID 210144 (UNINIT_CTOR)
* stratum_server: resolve CID 210042/210085/210104 (UNCAUGHT_EXCEPT)
The potential to throw exists within the logger,
remove_blockchain_update_listener, and any paths involving the logger
(including CATCH_ENTRY_*).
* epee: misc_log_ex: create CATCH_ENTRY_NO_RETURN macro
A temporary substition for what I hope will eventually be a full-fledged
exception-dispatcher (class-based, not macro).
* stratum_server: resolve CID 210080/210084/210089 (UNCAUGHT_EXCEPT)
The potential to throw exists within the logger,
remove_protocol_handler, and any paths involving the logger
(including CATCH_ENTRY_*).
* epee: levin_protocol_handler_async: resolve CID 210140/210182/210165 (UNCAUGHT_EXCEPT)
The potential to throw exists within guarded_critical_region_t, and any
paths involving the logger (including CATCH_ENTRY_*).
* epee: levin_protocol_handler_async: resolve CID 210110/210119/210155 (UNCAUGHT_EXCEPT)
The potential to throw exists within the logger, del_connection, and any
paths involving the logger (including CATCH_ENTRY_*).
* epee: misc_log_ex: move macros to *top* of file
so they can be used *within* this file.
* daemon: resolve CID 210069/210092/210166 (UNCAUGHT_EXCEPT)
The potential to throw exists within log_space, and any paths involving
the logger (including CATCH_ENTRY_*).
* daemon: return cstdlib proper types in main
* simplewallet: resolve 6 different CIDs (UNCAUGHT_EXCEPT)
CID: 210082
CID: 210086
CID: 210096
CID: 210147
CID: 210149
CID: 210150
The potential to throw exists throughout various paths in main.
* simplewallet: return cstdlib proper types in main
* simplewallet: resolve CID 210128/210160 (UNCAUGHT_EXCEPT)
The potential to throw exists within various paths, and any paths
involving the logger (including CATCH_ENTRY_*).
* conn_tool: resolve 5 different CIDs (UNCAUGHT_EXCEPT)
CID: 210038
CID: 210047
CID: 210108
CID: 210122
CID: 210157
The potential to throw exists throughout various paths in main.
* conn_tool: return cstdlib proper types in main
* miniupnp_helper: resolve CID 210050 (UNCAUGHT_EXCEPT)
The potential to throw exists within deinit, including any paths
involving the logger (including CATCH_ENTRY_*).
* epee: profile_tools: resolve CID 210055 (UNCAUGHT_EXCEPT)
The potential to throw exists within boost microsec_clock::localtime(),
and any paths involving the logger (including CATCH_ENTRY_*).
* db_backend_lmdb: resolve CID 210056/210133 (UNCAUGHT_EXCEPT)
The potential to throw exists within close(), including any paths
involving the logger (including CATCH_ENTRY_*).
* epee: misc_log_ex: resolve CID 210060/210124 (UNCAUGHT_EXCEPT)
The potential to throw exists within several paths, including any paths
involving the logger (including CATCH_ENTRY_*).
* epee: misc_language: resolve 4 CIDs (UNCAUGHT_EXCEPT)
CID: 210064
CID: 210093
CID: 210136
CID: 210139
The potential to throw exists within m_func(), including any paths
involving the logger (including CATCH_ENTRY_*).
* db_abstract_accessor: resolve 4 CIDs (UNCAUGHT_EXCEPT)
CID: 210072
CID: 210094
CID: 210116
CID: 210141
The potential to throw exists within m_cache.clear(), including any
paths involving the logger (including CATCH_ENTRY_*).
* epee: net_helper: resolve CID 210100 (UNCAUGHT_EXCEPT)
The potential to throw exists within shutdown(), including any
paths involving the logger (including CATCH_ENTRY_*).
* epee: syncobj: resolve CID 210123 (UNCAUGHT_EXCEPT)
The potential to throw exists within unlock(), including any
paths involving the logger (including CATCH_ENTRY_*).
* epee: profile_tools: resolve CID 210145/210154 (UNCAUGHT_EXCEPT)
The potential to throw exists within various paths, including any paths
involving the logger (including CATCH_ENTRY_*).
* epee: http_base: resolve CID 210176 (UNINIT_CTOR)
* p2p: net_node: resolve CID 210173 (UNINIT_CTOR)
* epee: net_helper: resolve CID 210138 (UNINIT_CTOR)
* p2p: net_peerlist: resolve CID 210137 (UNINIT_CTOR)
* currency_basic: resolve CID 210117 (UNINIT_CTOR)
* epee: abstract_tcp_server2: resolve 3 CIDs (UNINIT_CTOR)
CID: 210040
CID: 210090
CID: 210105
* simplewallet: resolve CID 210103 (UNINIT_CTOR)
* epee: levin_protocol_handler_async: resolve CID 210091 (UNINIT_CTOR)
* json_archive: resolve CID 210087 (UNINIT_CTOR)
* epee: levin_protocol_handler_async: resolve CID 210073 (UNINIT_CTOR)
* miniupnp_helper: resolve CID 210037 (UNINIT_CTOR)
* crypto: ge_frombytes_vartime: resolve CID 210142 (CHECKED_RETURN)
* wallet2: resolve CID 210041 (CHECKED_RETURN)
* epee: misc_log_ex: resolve CID 210127 (DEADCODE)
* epee: levin_protocol_handler_sync: resolve 3 CIDs (PASS_BY_VALUE)
CID: 210167
CID: 210170
CID: 210180
* p2p: net_node: resolve CID 210065 (PASS_BY_VALUE)
* epee: levin_abstract_invoke2: resolve CID 210049 (PASS_BY_VALUE)
* epee: abstract_tcp_server2: resolve CID 210045 (PASS_BY_VALUE)
* epee: misc_log_ex: add NESTED_*_ENTRY macros
* simplewallet: use NESTED_*_ENTRY in message_writer dtor
* stratum_protocol_handler_config: use NESTED_*_ENTRY in dtor
* stratum_protocol_handler: use NESTED_*_ENTRY in dtor
* lmdb_db_backend: use NESTED_*_ENTRY in dtor
* epee: abstract_tcp_server2: resolve 4 CIDs (UNCAUGHT_EXCEPT)
CID: 210088
CID: 210106
CID: 210164
CID: 210179
The potential to throw exists within various paths, including any
paths involving the logger (including CATCH_ENTRY_*).
* db_abstract_accessor: use NESTED_*_ENTRY in dtor
* miniupnp_helper: use NESTED_*_ENTRY in dtor
* epee: misc_log_ex: use NESTED_*_ENTRY in log_frame dtor
* epee: levin_protocol_handler_async: use NESTED_*_ENTRY in dtors
* epee: net_helper: use NESTED_*_ENTRY in dtor
* epee: profile_tools: use NESTED_*_ENTRY in dtors
* epee: misc_language: use NESTED_*_ENTRY in dtor
* epee: syncobj: use NESTED_*_ENTRY in dtor
* zano: license contact w/ zano.org email instead of sekreta.org email
2019-05-20 09:32:36 +00:00
NESTED_TRY_ENTRY ( ) ;
close ( ) ;
NESTED_CATCH_ENTRY ( __func__ ) ;
2018-12-27 18:50:45 +03:00
}
2019-08-29 12:21:05 +03:00
bool lmdb_db_backend : : open ( const std : : string & path_ , uint64_t cache_sz )
2018-12-27 18:50:45 +03:00
{
int res = 0 ;
res = mdb_env_create ( & m_penv ) ;
CHECK_AND_ASSERT_MESS_LMDB_DB ( res , false , " Unable to mdb_env_create " ) ;
2019-08-29 12:21:05 +03:00
res = mdb_env_set_maxdbs ( m_penv , 15 ) ;
2018-12-27 18:50:45 +03:00
CHECK_AND_ASSERT_MESS_LMDB_DB ( res , false , " Unable to mdb_env_set_maxdbs " ) ;
2019-08-29 12:21:05 +03:00
res = mdb_env_set_mapsize ( m_penv , cache_sz ) ;
CHECK_AND_ASSERT_MESS_LMDB_DB ( res , false , " Unable to mdb_env_set_mapsize " ) ;
2018-12-27 18:50:45 +03:00
m_path = path_ ;
2019-08-10 05:31:47 +03:00
CHECK_AND_ASSERT_MES ( tools : : create_directories_if_necessary ( m_path ) , false , " create_directories_if_necessary failed: " < < m_path ) ;
2019-08-29 12:21:05 +03:00
res = mdb_env_open ( m_penv , m_path . c_str ( ) , MDB_NORDAHEAD , 0644 ) ;
2019-08-17 07:08:00 +03:00
CHECK_AND_ASSERT_MESS_LMDB_DB ( res , false , " Unable to mdb_env_open, m_path= " < < m_path ) ;
2018-12-27 18:50:45 +03:00
return true ;
}
bool lmdb_db_backend : : open_container ( const std : : string & name , container_handle & h )
{
MDB_dbi dbi = AUTO_VAL_INIT ( dbi ) ;
begin_transaction ( ) ;
int res = mdb_dbi_open ( get_current_tx ( ) , name . c_str ( ) , MDB_CREATE , & dbi ) ;
CHECK_AND_ASSERT_MESS_LMDB_DB ( res , false , " Unable to mdb_dbi_open with container name: " < < name ) ;
commit_transaction ( ) ;
h = static_cast < container_handle > ( dbi ) ;
return true ;
}
2020-07-02 14:05:00 +03:00
bool lmdb_db_backend : : close_container ( container_handle & h )
{
static const container_handle null_handle = AUTO_VAL_INIT ( null_handle ) ;
CHECK_AND_ASSERT_MES ( h ! = null_handle , false , " close_container is called for null container handle " ) ;
MDB_dbi dbi = static_cast < MDB_dbi > ( h ) ;
begin_transaction ( ) ;
mdb_dbi_close ( m_penv , dbi ) ;
commit_transaction ( ) ;
h = null_handle ;
return true ;
}
2018-12-27 18:50:45 +03:00
bool lmdb_db_backend : : close ( )
{
{
std : : lock_guard < boost : : recursive_mutex > lock ( m_cs ) ;
for ( auto & tx_thread : m_txs )
{
for ( auto txe : tx_thread . second )
{
int res = mdb_txn_commit ( txe . ptx ) ;
if ( res ! = MDB_SUCCESS )
{
LOG_ERROR ( " [DB ERROR]: On close tranactions: " < < mdb_strerror ( res ) ) ;
}
}
}
m_txs . clear ( ) ;
}
if ( m_penv )
{
mdb_env_close ( m_penv ) ;
m_penv = nullptr ;
}
return true ;
}
bool lmdb_db_backend : : begin_transaction ( bool read_only )
{
if ( ! read_only )
{
LOG_PRINT_CYAN ( " [DB " < < m_path < < " ] WRITE LOCKED " , LOG_LEVEL_3 ) ;
CRITICAL_SECTION_LOCK ( m_write_exclusive_lock ) ;
}
PROFILE_FUNC ( " lmdb_db_backend::begin_transaction " ) ;
{
std : : lock_guard < boost : : recursive_mutex > lock ( m_cs ) ;
CHECK_AND_ASSERT_THROW_MES ( m_penv , " m_penv==null, db closed " ) ;
transactions_list & rtxlist = m_txs [ std : : this_thread : : get_id ( ) ] ;
MDB_txn * pparent_tx = nullptr ;
MDB_txn * p_new_tx = nullptr ;
2019-06-06 14:34:05 +03:00
bool parent_read_only = false ;
2018-12-27 18:50:45 +03:00
if ( rtxlist . size ( ) )
2019-06-06 14:34:05 +03:00
{
2018-12-27 18:50:45 +03:00
pparent_tx = rtxlist . back ( ) . ptx ;
2019-06-06 14:34:05 +03:00
parent_read_only = rtxlist . back ( ) . read_only ;
}
2018-12-27 18:50:45 +03:00
if ( pparent_tx & & read_only )
{
+ + rtxlist . back ( ) . count ;
}
else
{
int res = 0 ;
unsigned int flags = 0 ;
if ( read_only )
flags + = MDB_RDONLY ;
2019-06-06 14:34:05 +03:00
//don't use parent tx in write transactions if parent tx was read-only (restriction in lmdb)
//see "Nested transactions: Max 1 child, write txns only, no writemap"
if ( pparent_tx & & parent_read_only )
pparent_tx = nullptr ;
2018-12-27 18:50:45 +03:00
CHECK_AND_ASSERT_THROW_MES ( m_penv , " m_penv==null, db closed " ) ;
res = mdb_txn_begin ( m_penv , pparent_tx , flags , & p_new_tx ) ;
2019-06-06 23:08:21 +03:00
if ( res ! = MDB_SUCCESS )
{
//Important: if mdb_txn_begin is failed need to unlock previously locked mutex
CRITICAL_SECTION_UNLOCK ( m_write_exclusive_lock ) ;
//throw exception to avoid regular code execution
ASSERT_MES_AND_THROW_LMDB ( res , " Unable to mdb_txn_begin " ) ;
}
2018-12-27 18:50:45 +03:00
rtxlist . push_back ( tx_entry ( ) ) ;
rtxlist . back ( ) . count = read_only ? 1 : 0 ;
rtxlist . back ( ) . ptx = p_new_tx ;
rtxlist . back ( ) . read_only = read_only ;
}
}
LOG_PRINT_L4 ( " [DB] Transaction started " ) ;
return true ;
}
MDB_txn * lmdb_db_backend : : get_current_tx ( )
{
std : : lock_guard < boost : : recursive_mutex > lock ( m_cs ) ;
auto & rtxlist = m_txs [ std : : this_thread : : get_id ( ) ] ;
CHECK_AND_ASSERT_MES ( rtxlist . size ( ) , nullptr , " Unable to find active tx for thread " < < std : : this_thread : : get_id ( ) ) ;
return rtxlist . back ( ) . ptx ;
}
bool lmdb_db_backend : : pop_tx_entry ( tx_entry & txe )
{
std : : lock_guard < boost : : recursive_mutex > lock ( m_cs ) ;
auto it = m_txs . find ( std : : this_thread : : get_id ( ) ) ;
CHECK_AND_ASSERT_MES ( it ! = m_txs . end ( ) , false , " [DB] Unable to find id cor current thread " ) ;
CHECK_AND_ASSERT_MES ( it - > second . size ( ) , false , " [DB] No active tx for current thread " ) ;
txe = it - > second . back ( ) ;
if ( it - > second . back ( ) . read_only & & it - > second . back ( ) . count = = 0 )
{
LOG_ERROR ( " Internal db tx state error: read_only and count readers == 0 " ) ;
}
if ( ( it - > second . back ( ) . read_only & & it - > second . back ( ) . count < 2 ) | | ( ! it - > second . back ( ) . read_only & & it - > second . back ( ) . count < 1 ) )
{
it - > second . pop_back ( ) ;
if ( ! it - > second . size ( ) )
m_txs . erase ( it ) ;
}
else
{
- - it - > second . back ( ) . count ;
}
return true ;
}
bool lmdb_db_backend : : commit_transaction ( )
{
PROFILE_FUNC ( " lmdb_db_backend::commit_transaction " ) ;
{
tx_entry txe = AUTO_VAL_INIT ( txe ) ;
bool r = pop_tx_entry ( txe ) ;
CHECK_AND_ASSERT_MES ( r , false , " Unable to pop_tx_entry " ) ;
if ( txe . count = = 0 | | ( txe . read_only & & txe . count = = 1 ) )
{
int res = 0 ;
res = mdb_txn_commit ( txe . ptx ) ;
CHECK_AND_ASSERT_MESS_LMDB_DB ( res , false , " Unable to mdb_txn_commit (error " < < res < < " ) " ) ;
if ( ! txe . read_only & & ! txe . count )
{
CRITICAL_SECTION_UNLOCK ( m_write_exclusive_lock ) ;
LOG_PRINT_CYAN ( " [DB " < < m_path < < " ] WRITE UNLOCKED " , LOG_LEVEL_3 ) ;
}
}
}
LOG_PRINT_L4 ( " [DB] Transaction committed " ) ;
return true ;
}
void lmdb_db_backend : : abort_transaction ( )
{
{
tx_entry txe = AUTO_VAL_INIT ( txe ) ;
bool r = pop_tx_entry ( txe ) ;
CHECK_AND_ASSERT_MES ( r , void ( ) , " Unable to pop_tx_entry " ) ;
if ( txe . count = = 0 | | ( txe . read_only & & txe . count = = 1 ) )
{
mdb_txn_abort ( txe . ptx ) ;
2019-01-16 18:59:55 +03:00
if ( ! txe . read_only & & ! txe . count )
2018-12-27 18:50:45 +03:00
{
CRITICAL_SECTION_UNLOCK ( m_write_exclusive_lock ) ;
LOG_PRINT_CYAN ( " [DB " < < m_path < < " ] WRITE UNLOCKED(ABORTED) " , LOG_LEVEL_3 ) ;
}
}
}
LOG_PRINT_L4 ( " [DB] Transaction aborted " ) ;
}
bool lmdb_db_backend : : erase ( container_handle h , const char * k , size_t ks )
{
int res = 0 ;
MDB_val key = AUTO_VAL_INIT ( key ) ;
key . mv_data = ( void * ) k ;
key . mv_size = ks ;
res = mdb_del ( get_current_tx ( ) , static_cast < MDB_dbi > ( h ) , & key , nullptr ) ;
if ( res = = MDB_NOTFOUND )
return false ;
CHECK_AND_ASSERT_MESS_LMDB_DB ( res , false , " Unable to mdb_del " ) ;
return true ;
}
bool lmdb_db_backend : : have_tx ( )
{
std : : lock_guard < boost : : recursive_mutex > lock ( m_cs ) ;
auto it = m_txs . find ( std : : this_thread : : get_id ( ) ) ;
if ( it = = m_txs . end ( ) )
return false ;
return it - > second . size ( ) ? true : false ;
}
bool lmdb_db_backend : : get ( container_handle h , const char * k , size_t ks , std : : string & res_buff )
{
PROFILE_FUNC ( " lmdb_db_backend::get " ) ;
int res = 0 ;
MDB_val key = AUTO_VAL_INIT ( key ) ;
MDB_val data = AUTO_VAL_INIT ( data ) ;
key . mv_data = ( void * ) k ;
key . mv_size = ks ;
bool need_to_commit = false ;
if ( ! have_tx ( ) )
{
need_to_commit = true ;
begin_transaction ( true ) ;
}
res = mdb_get ( get_current_tx ( ) , static_cast < MDB_dbi > ( h ) , & key , & data ) ;
if ( need_to_commit )
commit_transaction ( ) ;
if ( res = = MDB_NOTFOUND )
return false ;
2022-10-04 23:13:02 +02:00
if ( res ! = MDB_SUCCESS )
{
return false ;
}
2018-12-27 18:50:45 +03:00
CHECK_AND_ASSERT_MESS_LMDB_DB ( res , false , " Unable to mdb_get, h: " < < h < < " , ks: " < < ks ) ;
res_buff . assign ( ( const char * ) data . mv_data , data . mv_size ) ;
return true ;
}
bool lmdb_db_backend : : clear ( container_handle h )
{
int res = mdb_drop ( get_current_tx ( ) , static_cast < MDB_dbi > ( h ) , 0 ) ;
CHECK_AND_ASSERT_MESS_LMDB_DB ( res , false , " Unable to mdb_drop " ) ;
return true ;
}
uint64_t lmdb_db_backend : : size ( container_handle h )
{
PROFILE_FUNC ( " lmdb_db_backend::size " ) ;
MDB_stat container_stat = AUTO_VAL_INIT ( container_stat ) ;
bool need_to_commit = false ;
if ( ! have_tx ( ) )
{
need_to_commit = true ;
begin_transaction ( true ) ;
}
int res = mdb_stat ( get_current_tx ( ) , static_cast < MDB_dbi > ( h ) , & container_stat ) ;
if ( need_to_commit )
commit_transaction ( ) ;
CHECK_AND_ASSERT_MESS_LMDB_DB ( res , false , " Unable to mdb_stat " ) ;
return container_stat . ms_entries ;
}
bool lmdb_db_backend : : set ( container_handle h , const char * k , size_t ks , const char * v , size_t vs )
{
PROFILE_FUNC ( " lmdb_db_backend::set " ) ;
int res = 0 ;
MDB_val key = AUTO_VAL_INIT ( key ) ;
2020-02-18 17:03:22 +03:00
MDB_val data [ 2 ] = { } ; // mdb_put may access data[1] if some flags are set, this may trigger static code analizers, so here we allocate two elements to avoid it
2018-12-27 18:50:45 +03:00
key . mv_data = ( void * ) k ;
key . mv_size = ks ;
2020-02-18 17:03:22 +03:00
data [ 0 ] . mv_data = ( void * ) v ;
data [ 0 ] . mv_size = vs ;
2018-12-27 18:50:45 +03:00
2020-02-18 17:03:22 +03:00
res = mdb_put ( get_current_tx ( ) , static_cast < MDB_dbi > ( h ) , & key , data , 0 ) ;
2018-12-27 18:50:45 +03:00
CHECK_AND_ASSERT_MESS_LMDB_DB ( res , false , " Unable to mdb_put " ) ;
return true ;
}
bool lmdb_db_backend : : enumerate ( container_handle h , i_db_callback * pcb )
{
CHECK_AND_ASSERT_MES ( pcb , false , " null capback ptr passed to enumerate " ) ;
MDB_val key = AUTO_VAL_INIT ( key ) ;
MDB_val data = AUTO_VAL_INIT ( data ) ;
bool need_to_commit = false ;
if ( ! have_tx ( ) )
{
need_to_commit = true ;
begin_transaction ( true ) ;
}
MDB_cursor * cursor_ptr = nullptr ;
int res = mdb_cursor_open ( get_current_tx ( ) , static_cast < MDB_dbi > ( h ) , & cursor_ptr ) ;
CHECK_AND_ASSERT_MESS_LMDB_DB ( res , false , " Unable to mdb_cursor_open " ) ;
CHECK_AND_ASSERT_MES ( cursor_ptr , false , " cursor_ptr is null after mdb_cursor_open " ) ;
uint64_t count = 0 ;
do
{
int res = mdb_cursor_get ( cursor_ptr , & key , & data , MDB_NEXT ) ;
if ( res = = MDB_NOTFOUND )
break ;
if ( ! pcb - > on_enum_item ( count , key . mv_data , key . mv_size , data . mv_data , data . mv_size ) )
break ;
count + + ;
} while ( cursor_ptr ) ;
mdb_cursor_close ( cursor_ptr ) ;
if ( need_to_commit )
commit_transaction ( ) ;
return true ;
}
bool lmdb_db_backend : : get_stat_info ( tools : : db : : stat_info & si )
{
si = AUTO_VAL_INIT_T ( tools : : db : : stat_info ) ;
MDB_envinfo ei = AUTO_VAL_INIT ( ei ) ;
mdb_env_info ( m_penv , & ei ) ;
si . map_size = ei . me_mapsize ;
std : : lock_guard < boost : : recursive_mutex > lock ( m_cs ) ;
for ( auto & e : m_txs )
{
for ( auto & pr : e . second )
{
+ + si . tx_count ;
if ( ! pr . read_only )
+ + si . write_tx_count ;
}
}
return true ;
}
2019-10-25 00:13:38 +02:00
const char * lmdb_db_backend : : name ( )
{
return " lmdb " ;
}
2018-12-27 18:50:45 +03:00
}
}
# undef LOG_DEFAULT_CHANNEL
Coverity (#28)
* stratum_server: resolve CID 210144 (UNINIT_CTOR)
* stratum_server: resolve CID 210042/210085/210104 (UNCAUGHT_EXCEPT)
The potential to throw exists within the logger,
remove_blockchain_update_listener, and any paths involving the logger
(including CATCH_ENTRY_*).
* epee: misc_log_ex: create CATCH_ENTRY_NO_RETURN macro
A temporary substition for what I hope will eventually be a full-fledged
exception-dispatcher (class-based, not macro).
* stratum_server: resolve CID 210080/210084/210089 (UNCAUGHT_EXCEPT)
The potential to throw exists within the logger,
remove_protocol_handler, and any paths involving the logger
(including CATCH_ENTRY_*).
* epee: levin_protocol_handler_async: resolve CID 210140/210182/210165 (UNCAUGHT_EXCEPT)
The potential to throw exists within guarded_critical_region_t, and any
paths involving the logger (including CATCH_ENTRY_*).
* epee: levin_protocol_handler_async: resolve CID 210110/210119/210155 (UNCAUGHT_EXCEPT)
The potential to throw exists within the logger, del_connection, and any
paths involving the logger (including CATCH_ENTRY_*).
* epee: misc_log_ex: move macros to *top* of file
so they can be used *within* this file.
* daemon: resolve CID 210069/210092/210166 (UNCAUGHT_EXCEPT)
The potential to throw exists within log_space, and any paths involving
the logger (including CATCH_ENTRY_*).
* daemon: return cstdlib proper types in main
* simplewallet: resolve 6 different CIDs (UNCAUGHT_EXCEPT)
CID: 210082
CID: 210086
CID: 210096
CID: 210147
CID: 210149
CID: 210150
The potential to throw exists throughout various paths in main.
* simplewallet: return cstdlib proper types in main
* simplewallet: resolve CID 210128/210160 (UNCAUGHT_EXCEPT)
The potential to throw exists within various paths, and any paths
involving the logger (including CATCH_ENTRY_*).
* conn_tool: resolve 5 different CIDs (UNCAUGHT_EXCEPT)
CID: 210038
CID: 210047
CID: 210108
CID: 210122
CID: 210157
The potential to throw exists throughout various paths in main.
* conn_tool: return cstdlib proper types in main
* miniupnp_helper: resolve CID 210050 (UNCAUGHT_EXCEPT)
The potential to throw exists within deinit, including any paths
involving the logger (including CATCH_ENTRY_*).
* epee: profile_tools: resolve CID 210055 (UNCAUGHT_EXCEPT)
The potential to throw exists within boost microsec_clock::localtime(),
and any paths involving the logger (including CATCH_ENTRY_*).
* db_backend_lmdb: resolve CID 210056/210133 (UNCAUGHT_EXCEPT)
The potential to throw exists within close(), including any paths
involving the logger (including CATCH_ENTRY_*).
* epee: misc_log_ex: resolve CID 210060/210124 (UNCAUGHT_EXCEPT)
The potential to throw exists within several paths, including any paths
involving the logger (including CATCH_ENTRY_*).
* epee: misc_language: resolve 4 CIDs (UNCAUGHT_EXCEPT)
CID: 210064
CID: 210093
CID: 210136
CID: 210139
The potential to throw exists within m_func(), including any paths
involving the logger (including CATCH_ENTRY_*).
* db_abstract_accessor: resolve 4 CIDs (UNCAUGHT_EXCEPT)
CID: 210072
CID: 210094
CID: 210116
CID: 210141
The potential to throw exists within m_cache.clear(), including any
paths involving the logger (including CATCH_ENTRY_*).
* epee: net_helper: resolve CID 210100 (UNCAUGHT_EXCEPT)
The potential to throw exists within shutdown(), including any
paths involving the logger (including CATCH_ENTRY_*).
* epee: syncobj: resolve CID 210123 (UNCAUGHT_EXCEPT)
The potential to throw exists within unlock(), including any
paths involving the logger (including CATCH_ENTRY_*).
* epee: profile_tools: resolve CID 210145/210154 (UNCAUGHT_EXCEPT)
The potential to throw exists within various paths, including any paths
involving the logger (including CATCH_ENTRY_*).
* epee: http_base: resolve CID 210176 (UNINIT_CTOR)
* p2p: net_node: resolve CID 210173 (UNINIT_CTOR)
* epee: net_helper: resolve CID 210138 (UNINIT_CTOR)
* p2p: net_peerlist: resolve CID 210137 (UNINIT_CTOR)
* currency_basic: resolve CID 210117 (UNINIT_CTOR)
* epee: abstract_tcp_server2: resolve 3 CIDs (UNINIT_CTOR)
CID: 210040
CID: 210090
CID: 210105
* simplewallet: resolve CID 210103 (UNINIT_CTOR)
* epee: levin_protocol_handler_async: resolve CID 210091 (UNINIT_CTOR)
* json_archive: resolve CID 210087 (UNINIT_CTOR)
* epee: levin_protocol_handler_async: resolve CID 210073 (UNINIT_CTOR)
* miniupnp_helper: resolve CID 210037 (UNINIT_CTOR)
* crypto: ge_frombytes_vartime: resolve CID 210142 (CHECKED_RETURN)
* wallet2: resolve CID 210041 (CHECKED_RETURN)
* epee: misc_log_ex: resolve CID 210127 (DEADCODE)
* epee: levin_protocol_handler_sync: resolve 3 CIDs (PASS_BY_VALUE)
CID: 210167
CID: 210170
CID: 210180
* p2p: net_node: resolve CID 210065 (PASS_BY_VALUE)
* epee: levin_abstract_invoke2: resolve CID 210049 (PASS_BY_VALUE)
* epee: abstract_tcp_server2: resolve CID 210045 (PASS_BY_VALUE)
* epee: misc_log_ex: add NESTED_*_ENTRY macros
* simplewallet: use NESTED_*_ENTRY in message_writer dtor
* stratum_protocol_handler_config: use NESTED_*_ENTRY in dtor
* stratum_protocol_handler: use NESTED_*_ENTRY in dtor
* lmdb_db_backend: use NESTED_*_ENTRY in dtor
* epee: abstract_tcp_server2: resolve 4 CIDs (UNCAUGHT_EXCEPT)
CID: 210088
CID: 210106
CID: 210164
CID: 210179
The potential to throw exists within various paths, including any
paths involving the logger (including CATCH_ENTRY_*).
* db_abstract_accessor: use NESTED_*_ENTRY in dtor
* miniupnp_helper: use NESTED_*_ENTRY in dtor
* epee: misc_log_ex: use NESTED_*_ENTRY in log_frame dtor
* epee: levin_protocol_handler_async: use NESTED_*_ENTRY in dtors
* epee: net_helper: use NESTED_*_ENTRY in dtor
* epee: profile_tools: use NESTED_*_ENTRY in dtors
* epee: misc_language: use NESTED_*_ENTRY in dtor
* epee: syncobj: use NESTED_*_ENTRY in dtor
* zano: license contact w/ zano.org email instead of sekreta.org email
2019-05-20 09:32:36 +00:00
# define LOG_DEFAULT_CHANNEL NULL