Commit 7922962f authored by Daniel Salzman's avatar Daniel Salzman

confio: remove automatic read_txn refresh after commit

This should be done during the server reload.
parent dfc3a5b5
......@@ -124,6 +124,19 @@ static int init_and_check(
return conf->api->txn_commit(&txn);
}
int conf_refresh(
conf_t *conf)
{
if (conf == NULL) {
return KNOT_EINVAL;
}
// Close previously opened transaction.
conf->api->txn_abort(&conf->read_txn);
return conf->api->txn_begin(conf->db, &conf->read_txn, KNOT_DB_RDONLY);
}
int conf_new(
conf_t **conf,
const yp_item_t *scheme,
......@@ -200,7 +213,7 @@ int conf_new(
}
// Open common read-only transaction.
ret = out->api->txn_begin(out->db, &out->read_txn, KNOT_DB_RDONLY);
ret = conf_refresh(out);
if (ret != KNOT_EOK) {
out->api->deinit(out->db);
goto new_error;
......@@ -247,7 +260,7 @@ int conf_clone(
out->db = s_conf->db;
// Open common read-only transaction.
ret = out->api->txn_begin(out->db, &out->read_txn, KNOT_DB_RDONLY);
ret = conf_refresh(out);
if (ret != KNOT_EOK) {
yp_scheme_free(out->scheme);
free(out);
......@@ -730,8 +743,7 @@ int conf_import(
}
// Update read-only transaction.
conf->api->txn_abort(&conf->read_txn);
ret = conf->api->txn_begin(conf->db, &conf->read_txn, KNOT_DB_RDONLY);
ret = conf_refresh(conf);
if (ret != KNOT_EOK) {
goto import_error;
}
......
......@@ -119,6 +119,17 @@ typedef enum {
*/
conf_t* conf(void);
/*!
* Refreshes common read-only transaction.
*
* \param[out] conf Configuration.
*
* \return Error code, KNOT_EOK if success.
*/
int conf_refresh(
conf_t *conf
);
/*!
* Creates new or opens old configuration database.
*
......
......@@ -15,7 +15,6 @@
*/
#include <assert.h>
#include <pthread.h>
#include "knot/conf/confdb.h"
#include "knot/conf/confio.h"
......@@ -100,43 +99,10 @@ int conf_io_commit(
// Commit the writing transaction.
int ret = conf()->api->txn_commit(txn);
conf()->io.txn = child ? txn - 1 : NULL;
if (ret != KNOT_EOK) {
return ret;
}
// Don't reload the configuration if child transaction.
if (child) {
return KNOT_EOK;
}
// Clone new configuration.
conf_t *new_conf = NULL;
ret = conf_clone(&new_conf);
if (ret != KNOT_EOK) {
return ret;
}
// Update read-only transaction.
new_conf->api->txn_abort(&new_conf->read_txn);
ret = new_conf->api->txn_begin(new_conf->db, &new_conf->read_txn,
KNOT_DB_RDONLY);
if (ret != KNOT_EOK) {
conf_free(new_conf);
return ret;
}
// Run post-open config operations.
ret = conf_post_open(new_conf);
if (ret != KNOT_EOK) {
conf_free(new_conf);
return ret;
}
// Update to the new config.
conf_update(new_conf);
conf()->io.txn = child ? txn - 1 : NULL;
return KNOT_EOK;
return ret;
}
int conf_io_abort(
......
......@@ -88,6 +88,9 @@ int conf_io_begin(
/*!
* Commits the current writing transaction.
*
* \note Remember to call conf_refresh to publish the changes into the common
* configuration.
*
* \param[in] child Nested transaction indicator.
*
* \return Error code, KNOT_EOK if success.
......
......@@ -97,40 +97,49 @@ static void test_conf_io_abort()
#else
conf_io_t io = { NULL };
// Test child persistence after subchild abort.
ok(conf_io_begin(false) == KNOT_EOK, "begin parent txn");
char idx[2] = { '0' };
ok(conf_io_set("server", "version", NULL, idx, &io) ==
KNOT_EOK, "set single value '%s'", idx);
for (int i = 1; i < CONF_MAX_TXN_DEPTH; i++) {
char idx[2] = "0";
idx[0] += i;
ok(conf_io_begin(true) == KNOT_EOK, "begin child txn");
char idx[2] = { '0' + i };
ok(conf_io_begin(true) == KNOT_EOK, "begin child txn %s", idx);
ok(conf_io_set("server", "version", NULL, idx, &io) ==
KNOT_EOK, "set single value");
KNOT_EOK, "set single value '%s'", idx);
}
for (int i = CONF_MAX_TXN_DEPTH - 1; i > 0; i--) {
char idx[2] = "0";
idx[0] += i;
char idx[2] = { '0' + i };
ok(conf_io_abort(true) == KNOT_EOK, "abort child txn %s", idx);
conf_val_t val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION);
ok(val.code == KNOT_EOK, "check entry");
const char *data = conf_str(&val);
ok(*data == idx[0], "compare txn data");
ok(conf_io_abort(true) == KNOT_EOK, "abort child txn");
ok(*data == (idx[0] - 1), "compare txn data '%s'", data);
}
conf_val_t val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION);
ok(val.code == KNOT_ENOENT, "check entry");
ok(conf_io_abort(false) == KNOT_EOK, "abort parent txn");
ok(conf()->io.txn == NULL, "check txn depth");
// Test child abort with commited subchild.
ok(conf_io_begin(false) == KNOT_EOK, "begin new parent txn");
ok(conf_io_begin(true) == KNOT_EOK, "begin child txn");
ok(conf_io_begin(true) == KNOT_EOK, "begin subchild txn");
ok(conf_io_set("server", "version", NULL, "text", &io) ==
KNOT_EOK, "set single value");
ok(conf_io_commit(true) == KNOT_EOK, "commit subchild txn");
val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION);
conf_val_t val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION);
ok(val.code == KNOT_EOK, "check entry");
const char *data = conf_str(&val);
ok(strcmp(data, "text") == 0, "compare subchild txn data '%s'", data);
ok(conf_io_abort(true) == KNOT_EOK, "abort child txn");
val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION);
ok(val.code == KNOT_ENOENT, "check entry");
ok(conf_io_abort(false) == KNOT_EOK, "abort parent txn");
ok(conf()->io.txn == NULL, "check txn depth");
// Test unchanged read_txn.
val = conf_get_txn(conf(), &conf()->read_txn, C_SERVER, C_VERSION);
ok(val.code == KNOT_ENOENT, "check entry");
#endif
......@@ -146,35 +155,44 @@ static void test_conf_io_commit()
#else
conf_io_t io = { NULL };
// Test subchild persistence after commit.
ok(conf_io_begin(false) == KNOT_EOK, "begin parent txn");
char idx[2] = { '0' };
ok(conf_io_set("server", "version", NULL, idx, &io) ==
KNOT_EOK, "set single value '%s'", idx);
for (int i = 1; i < CONF_MAX_TXN_DEPTH; i++) {
char idx[2] = "0";
idx[0] += i;
ok(conf_io_begin(true) == KNOT_EOK, "begin child txn");
char idx[2] = { '0' + i };
ok(conf_io_begin(true) == KNOT_EOK, "begin child txn %s", idx);
ok(conf_io_set("server", "version", NULL, idx, &io) ==
KNOT_EOK, "set single value");
KNOT_EOK, "set single value '%s'", idx);
}
for (int i = CONF_MAX_TXN_DEPTH - 1; i > 0; i--) {
ok(conf_io_commit(true) == KNOT_EOK, "commit child txn");
char idx[2] = { '0' + i };
ok(conf_io_commit(true) == KNOT_EOK, "commit child txn %s", idx);
conf_val_t val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION);
ok(val.code == KNOT_EOK, "check entry");
const char *data = conf_str(&val);
ok(*data == ('0' + CONF_MAX_TXN_DEPTH - 1), "compare txn data '%s'", data);
}
conf_val_t val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION);
ok(val.code == KNOT_EOK, "check entry");
ok(conf_io_commit(false) == KNOT_EOK, "commit parent txn");
val = conf_get_txn(conf(), &conf()->read_txn, C_SERVER, C_VERSION);
ok(conf()->io.txn == NULL, "check txn depth");
// Test child persistence after parent commit.
ok(conf_io_begin(false) == KNOT_EOK, "begin new parent txn");
conf_val_t val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION);
ok(val.code == KNOT_EOK, "check entry");
char idx = '0' + CONF_MAX_TXN_DEPTH - 1;
idx[0] = '0' + CONF_MAX_TXN_DEPTH - 1;
const char *data = conf_str(&val);
ok(*data == idx, "check entry value");
ok(strcmp(data, idx) == 0, "compare final data '%s'", data);
ok(conf_io_abort(false) == KNOT_EOK, "abort new parent txn");
// Reset the database.
ok(conf_io_begin(false) == KNOT_EOK, "begin parent txn");
ok(conf_io_unset("server", "version", NULL, NULL) ==
KNOT_EOK, "unset single value");
ok(conf_io_commit(false) == KNOT_EOK, "commit parent txn");
// Test unchanged read_txn.
val = conf_get_txn(conf(), &conf()->read_txn, C_SERVER, C_VERSION);
ok(val.code == KNOT_ENOENT, "check entry");
#endif
}
......@@ -316,6 +334,9 @@ static void test_conf_io_set()
knot_dname_free(&zone3, NULL);
ok(conf_io_commit(false) == KNOT_EOK, "commit txn");
// Update read-only transaction.
ok(conf_refresh(conf()) == KNOT_EOK, "update read-only txn");
}
static void test_conf_io_unset()
......
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