Commit f10c107d authored by Jan Včelák's avatar Jan Včelák 🚀

Merge branch 'knotc_readonly' into 'master'

parents 17a99e32 378a4032
......@@ -91,7 +91,8 @@ static void rm_dir(const char *path)
int conf_new(
conf_t **conf,
const yp_item_t *scheme,
const char *db_dir)
const char *db_dir,
bool read_only)
{
if (conf == NULL) {
return KNOT_EINVAL;
......@@ -117,6 +118,11 @@ int conf_new(
lmdb_opts.mapsize = 500 * 1024 * 1024;
lmdb_opts.flags.env = KNOT_DB_LMDB_NOTLS;
// Set read-only mode.
if (read_only) {
lmdb_opts.flags.env |= KNOT_DB_LMDB_RDONLY;
}
// Open database.
if (db_dir == NULL) {
char tpl[] = "/tmp/knot-confdb.XXXXXX";
......@@ -142,15 +148,16 @@ int conf_new(
goto new_error;
}
// Initialize/check database.
// Initialize and check the database.
knot_db_txn_t txn;
ret = out->api->txn_begin(out->db, &txn, 0);
unsigned flags = read_only ? KNOT_DB_RDONLY : 0;
ret = out->api->txn_begin(out->db, &txn, flags);
if (ret != KNOT_EOK) {
out->api->deinit(out->db);
goto new_error;
}
ret = conf_db_init(out, &txn);
ret = read_only ? conf_db_check(out, &txn) : conf_db_init(out, &txn);
if (ret != KNOT_EOK) {
out->api->txn_abort(&txn);
out->api->deinit(out->db);
......
......@@ -110,16 +110,18 @@ conf_t* conf(void);
/*!
* Creates new or opens old configuration database.
*
* \param[out] conf Configuration.
* \param[in] scheme Configuration scheme.
* \param[in] db_dir Database path or NULL.
* \param[out] conf Configuration.
* \param[in] scheme Configuration scheme.
* \param[in] db_dir Database path or NULL.
* \param[in] read_only Set to read-only access.
*
* \return Error code, KNOT_EOK if success.
*/
int conf_new(
conf_t **conf,
const yp_item_t *scheme,
const char *db_dir
const char *db_dir,
bool read_only
);
/*!
......
......@@ -108,20 +108,6 @@ static int db_check_version(
return KNOT_EOK;
}
static int db_check(
conf_t *conf,
knot_db_txn_t *txn)
{
int ret = conf->api->count(txn);
if (ret == 0) { // Empty DB.
return KNOT_CONF_EMPTY;
} else if (ret > 0) { // Check existing DB.
return db_check_version(conf, txn);
} else { // DB error.
return ret;
}
}
int conf_db_init(
conf_t *conf,
knot_db_txn_t *txn)
......@@ -139,7 +125,21 @@ int conf_db_init(
knot_db_val_t data = { d, sizeof(d) };
return conf->api->insert(txn, &key, &data, 0);
} else if (ret > 0) { // Check existing DB.
return db_check(conf, txn);
return conf_db_check(conf, txn);
} else { // DB error.
return ret;
}
}
int conf_db_check(
conf_t *conf,
knot_db_txn_t *txn)
{
int ret = conf->api->count(txn);
if (ret == 0) { // Empty DB.
return KNOT_CONF_EMPTY;
} else if (ret > 0) { // Check existing DB.
return db_check_version(conf, txn);
} else { // DB error.
return ret;
}
......
......@@ -42,7 +42,7 @@
#define CONF_MAX_DATA_LEN 65536
/*!
* Opens and checks old or initializes new configuration DB.
* Opens and checks or initializes the configuration DB.
*
* \param[in] conf Configuration.
* \param[in] txn Configuration DB transaction.
......@@ -54,6 +54,19 @@ int conf_db_init(
knot_db_txn_t *txn
);
/*!
* Checks the configuration DB.
*
* \param[in] conf Configuration.
* \param[in] txn Configuration DB transaction.
*
* \return Error code, KNOT_EOK if success.
*/
int conf_db_check(
conf_t *conf,
knot_db_txn_t *txn
);
/*!
* Sets the item with data in the configuration DB.
*
......
......@@ -69,6 +69,7 @@ typedef int (*knot_cmdf_t)(cmd_args_t *args);
/*! \brief Command table item. */
typedef struct knot_cmd {
knot_cmdf_t cb;
bool ronly_conf;
const char *name;
const char *params;
const char *desc;
......@@ -99,29 +100,29 @@ static int cmd_conf_unset(cmd_args_t *args);
/*! \brief Table of remote commands. */
knot_cmd_t knot_cmd_tbl[] = {
{ &cmd_stop, "stop", "", "Stop server." },
{ &cmd_reload, "reload", "[<zone>...]", "Reload particular zones or reload whole\n"
" configuration and changed zones." },
{ &cmd_refresh, "refresh", "[<zone>...]", "Refresh slave zones. Flag '-f' forces retransfer\n"
" (zone(s) must be specified)." },
{ &cmd_flush, "flush", "[<zone>...]", "Flush journal and update zone files." },
{ &cmd_status, "status", "", "Check if server is running." },
{ &cmd_zonestatus, "zonestatus", "[<zone>...]", "Show status of configured zones." },
{ &cmd_checkconf, "checkconf", "", "Check current server configuration." },
{ &cmd_checkzone, "checkzone", "[<zone>...]", "Check zones." },
{ &cmd_memstats, "memstats", "[<zone>...]", "Estimate memory use for zones." },
{ &cmd_signzone, "signzone", "<zone>...", "Sign zones with available DNSSEC keys." },
{ &cmd_conf_import, "conf-import", "<filename>", "Offline config DB import from file." },
{ &cmd_conf_export, "conf-export", "<filename>", "Export config DB to file." },
{ &cmd_conf_desc, "conf-desc", "[<item>]", "Get config DB item list." },
{ &cmd_conf_read, "conf-read", "[<item>]", "Read item(s) from active config DB." },
{ &cmd_conf_begin, "conf-begin", "", "Begin config DB transaction." },
{ &cmd_conf_commit, "conf-commit", "", "Commit config DB transaction." },
{ &cmd_conf_abort, "conf-abort", "", "Rollback config DB transaction." },
{ &cmd_conf_diff, "conf-diff", "[<item>]", "Get config DB transaction difference." },
{ &cmd_conf_get, "conf-get", "[<item>]", "Get item(s) from config DB transaction." },
{ &cmd_conf_set, "conf-set", "<item> [<data>...]", "Set item(s) in config DB transaction." },
{ &cmd_conf_unset, "conf-unset", "[<item>] [<data>...]", "Unset item(s) in config DB transaction." },
{ &cmd_stop, true, "stop", "", "Stop server." },
{ &cmd_reload, true, "reload", "[<zone>...]", "Reload particular zones or reload whole\n"
" configuration and changed zones." },
{ &cmd_refresh, true, "refresh", "[<zone>...]", "Refresh slave zones. Flag '-f' forces retransfer\n"
" (zone(s) must be specified)." },
{ &cmd_flush, true, "flush", "[<zone>...]", "Flush journal and update zone files." },
{ &cmd_status, true, "status", "", "Check if server is running." },
{ &cmd_zonestatus, true, "zonestatus", "[<zone>...]", "Show status of configured zones." },
{ &cmd_checkconf, true, "checkconf", "", "Check current server configuration." },
{ &cmd_checkzone, true, "checkzone", "[<zone>...]", "Check zones." },
{ &cmd_memstats, true, "memstats", "[<zone>...]", "Estimate memory use for zones." },
{ &cmd_signzone, true, "signzone", "<zone>...", "Sign zones with available DNSSEC keys." },
{ &cmd_conf_import, false, "conf-import", "<filename>", "Offline config DB import from file." },
{ &cmd_conf_export, true, "conf-export", "<filename>", "Export config DB to file." },
{ &cmd_conf_desc, true, "conf-desc", "[<item>]", "Get config DB item list." },
{ &cmd_conf_read, true, "conf-read", "[<item>]", "Read item(s) from active config DB." },
{ &cmd_conf_begin, true, "conf-begin", "", "Begin config DB transaction." },
{ &cmd_conf_commit, true, "conf-commit", "", "Commit config DB transaction." },
{ &cmd_conf_abort, true, "conf-abort", "", "Rollback config DB transaction." },
{ &cmd_conf_diff, true, "conf-diff", "[<item>]", "Get config DB transaction difference." },
{ &cmd_conf_get, true, "conf-get", "[<item>]", "Get item(s) from config DB transaction." },
{ &cmd_conf_set, true, "conf-set", "<item> [<data>...]", "Set item(s) in config DB transaction." },
{ &cmd_conf_unset, true, "conf-unset", "[<item>] [<data>...]", "Unset item(s) in config DB transaction." },
{ NULL }
};
......@@ -434,7 +435,7 @@ int main(int argc, char **argv)
/* Open configuration. */
conf_t *new_conf = NULL;
if (config_db == NULL) {
int ret = conf_new(&new_conf, conf_scheme, NULL);
int ret = conf_new(&new_conf, conf_scheme, NULL, false);
if (ret != KNOT_EOK) {
log_fatal("failed to initialize configuration database "
"(%s)", knot_strerror(ret));
......@@ -455,7 +456,8 @@ int main(int argc, char **argv)
new_conf->filename = strdup(config_fn);
} else {
/* Open configuration database. */
int ret = conf_new(&new_conf, conf_scheme, config_db);
bool ronly = cmd->ronly_conf;
int ret = conf_new(&new_conf, conf_scheme, config_db, ronly);
if (ret != KNOT_EOK) {
log_fatal("failed to open configuration database '%s' "
"(%s)", config_db, knot_strerror(ret));
......@@ -609,7 +611,7 @@ static int cmd_conf_import(cmd_args_t *args)
}
conf_t *new_conf = NULL;
int ret = conf_new(&new_conf, conf_scheme, args->conf_db);
int ret = conf_new(&new_conf, conf_scheme, args->conf_db, false);
if (ret == KNOT_EOK) {
ret = conf_import(new_conf, args->argv[0], true);
}
......
......@@ -332,7 +332,7 @@ int main(int argc, char **argv)
/* Open configuration. */
conf_t *new_conf = NULL;
if (config_db == NULL) {
int ret = conf_new(&new_conf, conf_scheme, NULL);
int ret = conf_new(&new_conf, conf_scheme, NULL, false);
if (ret != KNOT_EOK) {
log_fatal("failed to initialize configuration database "
"(%s)", knot_strerror(ret));
......@@ -353,7 +353,7 @@ int main(int argc, char **argv)
new_conf->filename = strdup(config_fn);
} else {
/* Open configuration database. */
int ret = conf_new(&new_conf, conf_scheme, config_db);
int ret = conf_new(&new_conf, conf_scheme, config_db, false);
if (ret != KNOT_EOK) {
log_fatal("failed to open configuration database '%s' "
"(%s)", config_db, knot_strerror(ret));
......
......@@ -32,8 +32,8 @@
#define LMDB_DIR_MODE 0770
#define LMDB_FILE_MODE 0660
_public_
const unsigned KNOT_DB_LMDB_NOTLS = MDB_NOTLS;
_public_ const unsigned KNOT_DB_LMDB_NOTLS = MDB_NOTLS;
_public_ const unsigned KNOT_DB_LMDB_RDONLY = MDB_RDONLY;
struct lmdb_env
{
......@@ -167,9 +167,14 @@ static int dbase_open_env(struct lmdb_env *env, struct knot_db_lmdb_opts *opts)
static int dbase_open(struct lmdb_env *env, struct knot_db_lmdb_opts *opts)
{
unsigned flags = 0;
if (opts->flags.env & KNOT_DB_LMDB_RDONLY) {
flags = MDB_RDONLY;
}
/* Open the database. */
MDB_txn *txn = NULL;
int ret = mdb_txn_begin(env->env, NULL, 0, &txn);
int ret = mdb_txn_begin(env->env, NULL, flags, &txn);
if (ret != MDB_SUCCESS) {
mdb_env_close(env->env);
return lmdb_error_to_knot(ret);
......
......@@ -23,6 +23,7 @@
/* LMDB specific flags. */
extern const unsigned KNOT_DB_LMDB_NOTLS;
extern const unsigned KNOT_DB_LMDB_RDONLY;
/* Native options. */
struct knot_db_lmdb_opts {
......
......@@ -28,7 +28,7 @@ static inline int test_conf(const char *conf_str, const yp_item_t *scheme)
}
conf_t *conf;
int ret = conf_new(&conf, scheme, NULL);
int ret = conf_new(&conf, scheme, NULL, false);
if (ret != KNOT_EOK) {
return ret;
}
......
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