Commit 7a819640 authored by Jan Včelák's avatar Jan Včelák 🚀
Browse files

LMDB namedb: error mapping from MDB_ error codes to KNOT_DATABASE_ERROR

parent bd3da128
......@@ -44,24 +44,43 @@ static int create_env_dir(const char *path)
return KNOT_EOK;
}
/*!
* \brief Convert error code returned by LMDB to Knot DNS error code.
*
* LMDB defines own error codes but uses additional ones from libc. All LMDB
* specific error codes are translated to KNOT_DATABASE_ERROR.
*/
static int lmdb_error_to_knot(int error)
{
if (error == MDB_SUCCESS) {
return KNOT_EOK;
}
if (MDB_KEYEXIST <= error && error <= MDB_LAST_ERRCODE) {
return KNOT_DATABASE_ERROR;
}
return knot_errno_to_error(error);
}
static int dbase_open(struct lmdb_env *env, const char *path)
{
int ret = mdb_env_create(&env->env);
if (ret != 0) {
return ret;
return lmdb_error_to_knot(ret);
}
long page_size = sysconf(_SC_PAGESIZE);
if (page_size <= 0) {
mdb_env_close(env->env);
return KNOT_ENOTSUP;
return KNOT_EINVAL;
}
size_t map_size = (LMDB_MAPSIZE / page_size) * page_size;
ret = mdb_env_set_mapsize(env->env, map_size);
if (ret != 0) {
mdb_env_close(env->env);
return ret;
return lmdb_error_to_knot(ret);
}
ret = create_env_dir(path);
......@@ -73,27 +92,27 @@ static int dbase_open(struct lmdb_env *env, const char *path)
ret = mdb_env_open(env->env, path, 0, LMDB_FILE_MODE);
if (ret != 0) {
mdb_env_close(env->env);
return ret;
return lmdb_error_to_knot(ret);
}
MDB_txn *txn = NULL;
ret = mdb_txn_begin(env->env, NULL, 0, &txn);
if (ret != 0) {
mdb_env_close(env->env);
return ret;
return lmdb_error_to_knot(ret);
}
ret = mdb_open(txn, NULL, 0, &env->dbi);
if (ret != 0) {
mdb_txn_abort(txn);
mdb_env_close(env->env);
return ret;
return lmdb_error_to_knot(ret);
}
ret = mdb_txn_commit(txn);
if (ret != 0) {
mdb_env_close(env->env);
return ret;
return lmdb_error_to_knot(ret);
}
return 0;
......@@ -116,7 +135,7 @@ static int init(const char *config, knot_namedb_t **db_ptr, mm_ctx_t *mm)
int ret = dbase_open(env, config);
if (ret != 0) {
mm_free(mm, env);
return KNOT_ERROR;
return ret;
}
env->pool = mm;
......@@ -148,7 +167,7 @@ static int txn_begin(knot_namedb_t *db, knot_txn_t *txn, unsigned flags)
struct lmdb_env *env = db;
int ret = mdb_txn_begin(env->env, NULL, txn_flags, (MDB_txn **)&txn->txn);
if (ret != 0) {
return KNOT_ERROR;
return lmdb_error_to_knot(ret);
}
return KNOT_EOK;
......@@ -158,7 +177,7 @@ static int txn_commit(knot_txn_t *txn)
{
int ret = mdb_txn_commit((MDB_txn *)txn->txn);
if (ret != 0) {
return KNOT_ERROR;
return lmdb_error_to_knot(ret);
}
return KNOT_EOK;
......@@ -176,7 +195,7 @@ static int count(knot_txn_t *txn)
MDB_stat stat;
int ret = mdb_stat(txn->txn, env->dbi, &stat);
if (ret != 0) {
return KNOT_ERROR;
return lmdb_error_to_knot(ret);
}
return stat.ms_entries;
......@@ -188,7 +207,6 @@ static int find(knot_txn_t *txn, knot_val_t *key, knot_val_t *val, unsigned flag
MDB_val db_key = { key->len, key->data };
MDB_val data = { 0, NULL };
int ret = mdb_get(txn->txn, env->dbi, &db_key, &data);
if (ret != 0) {
if (ret == MDB_NOTFOUND) {
......@@ -210,7 +228,7 @@ static int insert(knot_txn_t *txn, knot_val_t *key, knot_val_t *val, unsigned fl
MDB_cursor *cursor = NULL;
int ret = mdb_cursor_open(txn->txn, env->dbi, &cursor);
if (ret != 0) {
return KNOT_ERROR;
return lmdb_error_to_knot(ret);
}
MDB_val db_key = { key->len, key->data };
......@@ -223,7 +241,7 @@ static int insert(knot_txn_t *txn, knot_val_t *key, knot_val_t *val, unsigned fl
// Insert new item
ret = mdb_put(txn->txn, env->dbi, &db_key, &data, 0);
if (ret != 0) {
return KNOT_ERROR;
return lmdb_error_to_knot(ret);
}
return KNOT_EOK;
......@@ -235,7 +253,7 @@ static int insert(knot_txn_t *txn, knot_val_t *key, knot_val_t *val, unsigned fl
ret = mdb_cursor_put(cursor, &db_key, &data, MDB_CURRENT);
mdb_cursor_close(cursor);
if (ret != 0) {
return KNOT_ERROR;
return lmdb_error_to_knot(ret);
}
return KNOT_EOK;
......@@ -249,7 +267,7 @@ static int del(knot_txn_t *txn, knot_val_t *key)
int ret = mdb_del(txn->txn, env->dbi, &db_key, &data);
if (ret != 0) {
return KNOT_ERROR;
return lmdb_error_to_knot(ret);
}
return KNOT_EOK;
......@@ -294,7 +312,7 @@ static int iter_key(knot_iter_t *iter, knot_val_t *key)
MDB_val mdb_key, mdb_val;
int ret = mdb_cursor_get(cursor, &mdb_key, &mdb_val, MDB_GET_CURRENT);
if (ret != 0) {
return KNOT_ERROR;
return lmdb_error_to_knot(ret);
}
key->data = mdb_key.mv_data;
......@@ -309,7 +327,7 @@ static int iter_val(knot_iter_t *iter, knot_val_t *val)
MDB_val mdb_key, mdb_val;
int ret = mdb_cursor_get(cursor, &mdb_key, &mdb_val, MDB_GET_CURRENT);
if (ret != 0) {
return KNOT_ERROR;
return lmdb_error_to_knot(ret);
}
val->data = mdb_val.mv_data;
......
......@@ -120,6 +120,9 @@ const error_table_t error_messages[] = {
/* NSEC3 errors. */
{ KNOT_NSEC3_ECOMPUTE_HASH, "cannot compute NSEC3 hash" },
/* Dynamic backend errors. */
{ KNOT_DATABASE_ERROR, "unspecified database error" },
{ KNOT_ERROR, NULL } /* Terminator */
};
......
......@@ -134,7 +134,10 @@ enum knot_error {
KNOT_DNSSEC_EMISSINGKEYTYPE,
/* NSEC3 errors. */
KNOT_NSEC3_ECOMPUTE_HASH
KNOT_NSEC3_ECOMPUTE_HASH,
/* Database backend. */
KNOT_DATABASE_ERROR
};
/*!
......@@ -161,7 +164,7 @@ int knot_map_errno_internal(int fallback, int arg0, ...);
/*!
* \brief Map POSIX errno to Knot error code.
*
* KNOT_ERRNO is used as a fallback error, the list is terminated implicitly.
* KNOT_ERROR is used as a fallback error, the list is terminated implicitly.
*/
#define knot_map_errno(errors...) knot_map_errno_internal(KNOT_ERROR, errors, 0)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment