You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
4.6 KiB
150 lines
4.6 KiB
#include <stdlib.h> |
|
#include <string.h> |
|
#include <stdint.h> |
|
#include <sys/stat.h> |
|
#include "route_node_lmdb.h" |
|
#include "route_bgp.h" |
|
#include "../lib/debug_config.h" |
|
#include "../lib/mem.h" |
|
|
|
#define NODEINFO_DB_MAPSIZE (10UL * 1024 * 1024) |
|
|
|
int route_node_lmdb_init(struct ROUTE_BGP* bgp, const char* db_path) { |
|
if (!bgp || !db_path || !db_path[0]) return -1; |
|
|
|
int rc = mdb_env_create(&bgp->nodeinfo_env); |
|
if (rc != MDB_SUCCESS) { |
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "LMDB mdb_env_create failed: %s", mdb_strerror(rc)); |
|
return -1; |
|
} |
|
|
|
rc = mdb_env_set_mapsize(bgp->nodeinfo_env, NODEINFO_DB_MAPSIZE); |
|
if (rc != MDB_SUCCESS) { |
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "LMDB mdb_env_set_mapsize failed: %s", mdb_strerror(rc)); |
|
mdb_env_close(bgp->nodeinfo_env); |
|
bgp->nodeinfo_env = NULL; |
|
return -1; |
|
} |
|
|
|
rc = mdb_env_set_maxdbs(bgp->nodeinfo_env, 2); |
|
if (rc != MDB_SUCCESS) { |
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "LMDB mdb_env_set_maxdbs failed: %s", mdb_strerror(rc)); |
|
mdb_env_close(bgp->nodeinfo_env); |
|
bgp->nodeinfo_env = NULL; |
|
return -1; |
|
} |
|
|
|
rc = mdb_env_open(bgp->nodeinfo_env, db_path, 0, 0644); |
|
if (rc != MDB_SUCCESS) { |
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "LMDB mdb_env_open(%s) failed: %s", db_path, mdb_strerror(rc)); |
|
mdb_env_close(bgp->nodeinfo_env); |
|
bgp->nodeinfo_env = NULL; |
|
return -1; |
|
} |
|
|
|
MDB_txn* txn = NULL; |
|
rc = mdb_txn_begin(bgp->nodeinfo_env, NULL, 0, &txn); |
|
if (rc != MDB_SUCCESS) { |
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "LMDB mdb_txn_begin failed: %s", mdb_strerror(rc)); |
|
mdb_env_close(bgp->nodeinfo_env); |
|
bgp->nodeinfo_env = NULL; |
|
return -1; |
|
} |
|
|
|
rc = mdb_dbi_open(txn, "nodeinfo", MDB_CREATE, &bgp->nodeinfo_dbi); |
|
if (rc != MDB_SUCCESS) { |
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "LMDB mdb_dbi_open(nodeinfo) failed: %s", mdb_strerror(rc)); |
|
mdb_txn_abort(txn); |
|
mdb_env_close(bgp->nodeinfo_env); |
|
bgp->nodeinfo_env = NULL; |
|
return -1; |
|
} |
|
|
|
rc = mdb_txn_commit(txn); |
|
if (rc != MDB_SUCCESS) { |
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "LMDB mdb_txn_commit failed: %s", mdb_strerror(rc)); |
|
mdb_env_close(bgp->nodeinfo_env); |
|
bgp->nodeinfo_env = NULL; |
|
return -1; |
|
} |
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "LMDB nodeinfo database opened: %s", db_path); |
|
return 0; |
|
} |
|
|
|
void route_node_lmdb_destroy(struct ROUTE_BGP* bgp) { |
|
if (!bgp) return; |
|
if (bgp->nodeinfo_env) { |
|
mdb_env_close(bgp->nodeinfo_env); |
|
bgp->nodeinfo_env = NULL; |
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "LMDB nodeinfo database closed"); |
|
} |
|
} |
|
|
|
int route_node_lmdb_put(struct ROUTE_BGP* bgp, struct NODEINFO_Q* nq) { |
|
if (!bgp || !bgp->nodeinfo_env || !nq) return -1; |
|
|
|
int dyn_size = nodeinfo_dyn_size(&nq->node); |
|
size_t val_size = sizeof(struct NODEINFO) + dyn_size; |
|
|
|
MDB_val key, data; |
|
key.mv_size = 8; |
|
key.mv_data = &nq->node.node_id; |
|
|
|
data.mv_size = val_size; |
|
data.mv_data = (void*)&nq->node; |
|
|
|
MDB_txn* txn = NULL; |
|
int rc = mdb_txn_begin(bgp->nodeinfo_env, NULL, 0, &txn); |
|
if (rc != MDB_SUCCESS) { |
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "LMDB put mdb_txn_begin failed: %s", mdb_strerror(rc)); |
|
return -1; |
|
} |
|
|
|
rc = mdb_put(txn, bgp->nodeinfo_dbi, &key, &data, 0); |
|
if (rc != MDB_SUCCESS) { |
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "LMDB mdb_put node %016llx failed: %s", |
|
(unsigned long long)nq->node.node_id, mdb_strerror(rc)); |
|
mdb_txn_abort(txn); |
|
return -1; |
|
} |
|
|
|
rc = mdb_txn_commit(txn); |
|
if (rc != MDB_SUCCESS) { |
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "LMDB put mdb_txn_commit failed: %s", mdb_strerror(rc)); |
|
return -1; |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
int route_node_lmdb_del(struct ROUTE_BGP* bgp, uint64_t node_id) { |
|
if (!bgp || !bgp->nodeinfo_env) return -1; |
|
|
|
MDB_val key; |
|
key.mv_size = 8; |
|
key.mv_data = &node_id; |
|
|
|
MDB_txn* txn = NULL; |
|
int rc = mdb_txn_begin(bgp->nodeinfo_env, NULL, 0, &txn); |
|
if (rc != MDB_SUCCESS) { |
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "LMDB del mdb_txn_begin failed: %s", mdb_strerror(rc)); |
|
return -1; |
|
} |
|
|
|
rc = mdb_del(txn, bgp->nodeinfo_dbi, &key, NULL); |
|
if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND) { |
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "LMDB mdb_del node %016llx failed: %s", |
|
(unsigned long long)node_id, mdb_strerror(rc)); |
|
mdb_txn_abort(txn); |
|
return -1; |
|
} |
|
|
|
rc = mdb_txn_commit(txn); |
|
if (rc != MDB_SUCCESS) { |
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "LMDB del mdb_txn_commit failed: %s", mdb_strerror(rc)); |
|
return -1; |
|
} |
|
|
|
return 0; |
|
}
|
|
|