From 7a819640ca141276e71c8e1db910116023856d34 Mon Sep 17 00:00:00 2001 From: Jan Vcelak <jan.vcelak@nic.cz> Date: Wed, 15 Oct 2014 19:03:43 +0200 Subject: [PATCH] LMDB namedb: error mapping from MDB_ error codes to KNOT_DATABASE_ERROR --- src/common/namedb/namedb_lmdb.c | 54 ++++++++++++++++++++++----------- src/libknot/errcode.c | 3 ++ src/libknot/errcode.h | 7 +++-- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/common/namedb/namedb_lmdb.c b/src/common/namedb/namedb_lmdb.c index 92bdfe6a07..de6c4bb33a 100644 --- a/src/common/namedb/namedb_lmdb.c +++ b/src/common/namedb/namedb_lmdb.c @@ -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; diff --git a/src/libknot/errcode.c b/src/libknot/errcode.c index a85f6a9d05..a54996675b 100644 --- a/src/libknot/errcode.c +++ b/src/libknot/errcode.c @@ -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 */ }; diff --git a/src/libknot/errcode.h b/src/libknot/errcode.h index 88bec58fc4..2b2b1fc5e5 100644 --- a/src/libknot/errcode.h +++ b/src/libknot/errcode.h @@ -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) -- GitLab