Removal of builtin and inheritance
Builtin and inheritance code are removed. The way it will work now will be specific to options, view and zone clauses. Materialization will be used. In otherwords, 3 versions of the config co-exists: - the builtin (the one hard-coded) - the user (the one coming from named.conf) - the running The running configuration is a copy of the builtin one, and on top of that, a copy of the user one overriding values already existing from the builtin one. Then, each modifications applied override it. In order to keep things simple initially, the next changes will be: - removal of lists: the API feels brittle, it's non deterministic order (might be problematic), it enforces a size of values to 511 bytes, and it's very specific to LMDB implementation. The better approach will need to be found later. - removal of "repeatable clauses" this concepts was to be able to iterate over views and zones, but it forces to have random IDs generated for clause names, which make materialization over-complex. (i.e. the ID for a clause "x" in the builtin wouldn't be the same in user or running, and would force some cotortions). Short term: removal of newclause/nextclause, this will also break validation. This will need to be addressed. Probably by having an extra LMDB DB which tells the list of top-level keys from a given prefix, so we would be able to quickly jump from one clause to another.
This commit is contained in:
+195
-242
@@ -31,11 +31,6 @@
|
||||
*/
|
||||
#define BUFLEN 511
|
||||
|
||||
/*
|
||||
* The builtin prefix name of a property
|
||||
*/
|
||||
#define BUILTIN_PREFIX "__[builtin]__"
|
||||
|
||||
typedef struct openedclause openedclause_t;
|
||||
struct openedclause {
|
||||
char *name;
|
||||
@@ -48,10 +43,12 @@ typedef struct {
|
||||
openedclauses_t openedclauses;
|
||||
char *prefix;
|
||||
char *buffer;
|
||||
MDB_cursor *cursor;
|
||||
MDB_cursor *builtincursor;
|
||||
MDB_cursor *usercursor;
|
||||
MDB_cursor *runningcursor;
|
||||
MDB_txn *txn;
|
||||
bool readonly;
|
||||
bool builtinon;
|
||||
isc_cfgmgr_mode_t mode;
|
||||
} context_t;
|
||||
|
||||
static const isc_cfgmgr_clause_t **isc__cfgmgr_configformat = NULL;
|
||||
@@ -61,10 +58,11 @@ static thread_local context_t isc__cfgmgr_ctx =
|
||||
(context_t){ .openedclauses = ISC_LIST_INITIALIZER,
|
||||
.prefix = NULL,
|
||||
.buffer = NULL,
|
||||
.cursor = NULL,
|
||||
.builtincursor = NULL,
|
||||
.usercursor = NULL,
|
||||
.runningcursor = NULL,
|
||||
.txn = NULL,
|
||||
.readonly = false,
|
||||
.builtinon = false };
|
||||
.readonly = false };
|
||||
|
||||
/*
|
||||
* lasterror is not in the context_t object because it must outlives a
|
||||
@@ -112,6 +110,76 @@ isc__cfgmgr_parseid(const char *dbkey) {
|
||||
return id;
|
||||
}
|
||||
|
||||
static bool
|
||||
isc__cfgmgr_openlmdbcursor(const char *dbname, MDB_cursor **cursor) {
|
||||
MDB_dbi dbi;
|
||||
|
||||
/*
|
||||
* There might be a bug here: LMDB doc says MDB_CREATE can't be used
|
||||
* for read-only transaction. It might be simply ignored. But we
|
||||
* shouldn't put it eitherway in such case (and assert in the DB aren't
|
||||
* already created
|
||||
*/
|
||||
if (mdb_dbi_open(isc__cfgmgr_ctx.txn, dbname, MDB_CREATE | MDB_DUPSORT,
|
||||
&dbi) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mdb_cursor_open(isc__cfgmgr_ctx.txn, dbi, cursor) != 0) {
|
||||
return false;
|
||||
}
|
||||
INSIST(*cursor != NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
isc__cfgmgr_closelmdbcursors(void) {
|
||||
mdb_cursor_close(isc__cfgmgr_ctx.builtincursor);
|
||||
isc__cfgmgr_ctx.builtincursor = NULL;
|
||||
|
||||
mdb_cursor_close(isc__cfgmgr_ctx.usercursor);
|
||||
isc__cfgmgr_ctx.usercursor = NULL;
|
||||
|
||||
mdb_cursor_close(isc__cfgmgr_ctx.runningcursor);
|
||||
isc__cfgmgr_ctx.runningcursor = NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
isc__cfgmgr_startlmdbtransaction(bool readonly) {
|
||||
if (mdb_txn_begin(isc__cfgmgr_env, NULL, readonly ? MDB_RDONLY : 0,
|
||||
&isc__cfgmgr_ctx.txn) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
INSIST(isc__cfgmgr_ctx.txn != NULL);
|
||||
|
||||
if (!isc__cfgmgr_openlmdbcursor("builtin",
|
||||
&isc__cfgmgr_ctx.builtincursor) ||
|
||||
!isc__cfgmgr_openlmdbcursor("user", &isc__cfgmgr_ctx.usercursor) ||
|
||||
!isc__cfgmgr_openlmdbcursor("running",
|
||||
&isc__cfgmgr_ctx.runningcursor))
|
||||
{
|
||||
isc__cfgmgr_closelmdbcursors();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
isc__cfgmgr_checkofftransaction(void) {
|
||||
REQUIRE(isc__cfgmgr_env != NULL);
|
||||
REQUIRE(ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses));
|
||||
REQUIRE(isc__cfgmgr_ctx.prefix == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.buffer == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.txn == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.builtincursor == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.usercursor == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.runningcursor == NULL);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_cfgmgr_init(isc_mem_t *mctx, const char *dbpath,
|
||||
const isc_cfgmgr_clause_t **configformat) {
|
||||
@@ -125,7 +193,9 @@ isc_cfgmgr_init(isc_mem_t *mctx, const char *dbpath,
|
||||
REQUIRE(ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses));
|
||||
REQUIRE(isc__cfgmgr_ctx.prefix == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.buffer == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.cursor == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.builtincursor == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.usercursor == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.runningcursor == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.txn == NULL);
|
||||
REQUIRE(isc__cfgmgr_mctx == NULL);
|
||||
REQUIRE(isc__cfgmgr_env == NULL);
|
||||
@@ -154,6 +224,12 @@ isc_cfgmgr_init(isc_mem_t *mctx, const char *dbpath,
|
||||
REQUIRE(snprintf(dblockname, BUFLEN, "%s-%" PRIu32 "-lock", dbpath,
|
||||
random) < BUFLEN);
|
||||
|
||||
result = mdb_env_set_maxdbs(isc__cfgmgr_env, 3);
|
||||
if (result != 0) {
|
||||
result = ISC_R_FAILURE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Using MDB_NOSYNC as it avoids force disk flush after a
|
||||
* transaction. It's quicker and in our case we don't need it
|
||||
@@ -177,6 +253,19 @@ isc_cfgmgr_init(isc_mem_t *mctx, const char *dbpath,
|
||||
|
||||
isc__cfgmgr_configformat = configformat;
|
||||
|
||||
/*
|
||||
* Let's do a read-write transaction, so LMDB can create the DBs (and it
|
||||
* avoid to explain that the very first transaction must be RW, even if
|
||||
* doing differently makes little sense...
|
||||
*/
|
||||
if (isc__cfgmgr_startlmdbtransaction(false) == false) {
|
||||
goto cleanup;
|
||||
}
|
||||
isc__cfgmgr_closelmdbcursors();
|
||||
if (mdb_txn_commit(isc__cfgmgr_ctx.txn) != 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
goto out;
|
||||
|
||||
cleanup:
|
||||
@@ -186,6 +275,7 @@ cleanup:
|
||||
}
|
||||
|
||||
out:
|
||||
isc__cfgmgr_ctx.txn = NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -205,7 +295,9 @@ isc_cfgmgr_deinit(void) {
|
||||
REQUIRE(ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses));
|
||||
REQUIRE(isc__cfgmgr_ctx.prefix == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.buffer == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.cursor == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.builtincursor == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.usercursor == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.runningcursor == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.txn == NULL);
|
||||
REQUIRE(isc__cfgmgr_mctx != NULL);
|
||||
REQUIRE(isc__cfgmgr_env != NULL);
|
||||
@@ -220,9 +312,6 @@ isc__cfgmgr_buildkey(const char *name, bool isclause) {
|
||||
size_t written;
|
||||
const char *prefix = "";
|
||||
const char *dot = isclause ? "." : "";
|
||||
const char *builtin = isclause == false && isc__cfgmgr_ctx.builtinon
|
||||
? BUILTIN_PREFIX
|
||||
: "";
|
||||
|
||||
REQUIRE(name != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.buffer != NULL);
|
||||
@@ -232,11 +321,27 @@ isc__cfgmgr_buildkey(const char *name, bool isclause) {
|
||||
prefix = isc__cfgmgr_ctx.prefix;
|
||||
}
|
||||
|
||||
written = snprintf(isc__cfgmgr_ctx.buffer, BUFLEN, "%s%s%s%s", prefix,
|
||||
builtin, name, dot);
|
||||
written = snprintf(isc__cfgmgr_ctx.buffer, BUFLEN, "%s%s%s", prefix,
|
||||
name, dot);
|
||||
INSIST(written <= BUFLEN);
|
||||
}
|
||||
|
||||
static MDB_cursor *
|
||||
isc__cfgmgr_lmdbcursor(void) {
|
||||
switch (isc__cfgmgr_ctx.mode) {
|
||||
case ISC_CFGMGR_MODEUNKNOWN:
|
||||
UNREACHABLE();
|
||||
case ISC_CFGMGR_MODEBUILTIN:
|
||||
return isc__cfgmgr_ctx.builtincursor;
|
||||
case ISC_CFGMGR_MODEUSER:
|
||||
return isc__cfgmgr_ctx.usercursor;
|
||||
case ISC_CFGMGR_MODERUNNING:
|
||||
return isc__cfgmgr_ctx.runningcursor;
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
isc__cfgmgr_findclause(const char *name, unsigned long *id) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
@@ -255,7 +360,7 @@ isc__cfgmgr_findclause(const char *name, unsigned long *id) {
|
||||
* key/val won't just have the "name.id" prefix, but also the
|
||||
* id and the first property name (so "name.id.prop").
|
||||
*/
|
||||
if (mdb_cursor_get(isc__cfgmgr_ctx.cursor, &dbkey, NULL,
|
||||
if (mdb_cursor_get(isc__cfgmgr_lmdbcursor(), &dbkey, NULL,
|
||||
MDB_SET_RANGE) != 0)
|
||||
{
|
||||
result = ISC_R_NOTFOUND;
|
||||
@@ -327,8 +432,6 @@ isc__cfgmgr_freectx(void) {
|
||||
isc_mem_free(isc__cfgmgr_mctx, isc__cfgmgr_ctx.buffer);
|
||||
isc_mem_free(isc__cfgmgr_mctx, isc__cfgmgr_ctx.prefix);
|
||||
isc__cfgmgr_ctx.txn = NULL;
|
||||
isc__cfgmgr_ctx.cursor = NULL;
|
||||
isc__cfgmgr_ctx.builtinon = false;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -340,53 +443,51 @@ isc__cfgmgr_setlasterror(const char *fmt, ...) {
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void
|
||||
isc__cfgmgr_checkontransaction(void) {
|
||||
REQUIRE(isc__cfgmgr_env != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.buffer != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.txn != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.builtincursor != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.usercursor != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.runningcursor != NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
isc__cfgmgr_checkopenedclause(void) {
|
||||
isc__cfgmgr_checkontransaction();
|
||||
REQUIRE(isc__cfgmgr_ctx.prefix != NULL);
|
||||
REQUIRE(ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses) == false);
|
||||
}
|
||||
|
||||
void
|
||||
isc_cfgmgr_setmode(isc_cfgmgr_mode_t mode) {
|
||||
isc__cfgmgr_checkontransaction();
|
||||
REQUIRE(mode != ISC_CFGMGR_MODEUNKNOWN);
|
||||
|
||||
isc__cfgmgr_ctx.mode = mode;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
isc__cfgmgr_starttransaction(bool readonly) {
|
||||
MDB_dbi dbi;
|
||||
|
||||
REQUIRE(isc__cfgmgr_env != NULL);
|
||||
REQUIRE(ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses));
|
||||
REQUIRE(isc__cfgmgr_ctx.prefix == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.buffer == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.txn == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.cursor == NULL);
|
||||
|
||||
isc__cfgmgr_checkofftransaction();
|
||||
isc__cfgmgr_setlasterror("");
|
||||
|
||||
if (mdb_txn_begin(isc__cfgmgr_env, NULL, readonly ? MDB_RDONLY : 0,
|
||||
&isc__cfgmgr_ctx.txn) != 0)
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
INSIST(isc__cfgmgr_ctx.txn != NULL);
|
||||
|
||||
if (mdb_dbi_open(isc__cfgmgr_ctx.txn, NULL, MDB_CREATE | MDB_DUPSORT,
|
||||
&dbi) != 0)
|
||||
{
|
||||
goto failure;
|
||||
if (isc__cfgmgr_startlmdbtransaction(readonly) == false) {
|
||||
if (isc__cfgmgr_ctx.txn) {
|
||||
mdb_txn_abort(isc__cfgmgr_ctx.txn);
|
||||
isc__cfgmgr_ctx.txn = NULL;
|
||||
}
|
||||
return ISC_R_FAILURE;
|
||||
}
|
||||
|
||||
if (mdb_cursor_open(isc__cfgmgr_ctx.txn, dbi,
|
||||
&isc__cfgmgr_ctx.cursor) != 0)
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
INSIST(isc__cfgmgr_ctx.cursor != NULL);
|
||||
isc__cfgmgr_ctx.readonly = readonly;
|
||||
isc__cfgmgr_ctx.buffer = isc_mem_allocate(isc__cfgmgr_mctx, BUFLEN);
|
||||
isc__cfgmgr_ctx.prefix = isc_mem_allocate(isc__cfgmgr_mctx, BUFLEN);
|
||||
isc__cfgmgr_ctx.mode = ISC_CFGMGR_MODERUNNING;
|
||||
isc__cfgmgr_checkontransaction();
|
||||
|
||||
return ISC_R_SUCCESS;
|
||||
|
||||
failure:
|
||||
if (isc__cfgmgr_ctx.txn) {
|
||||
mdb_txn_abort(isc__cfgmgr_ctx.txn);
|
||||
isc__cfgmgr_freectx();
|
||||
}
|
||||
ENSURE(isc__cfgmgr_ctx.buffer == NULL &&
|
||||
isc__cfgmgr_ctx.prefix == NULL);
|
||||
|
||||
return ISC_R_FAILURE;
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
@@ -564,8 +665,7 @@ isc__cfgmgr_validate(void) {
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
isc__cfgmgr_getval(const char *name, isc_cfgmgr_val_t *value,
|
||||
isc_cfgmgr_dumpmode_t dumpmode);
|
||||
isc__cfgmgr_getval(const char *name, isc_cfgmgr_val_t *value);
|
||||
|
||||
static isc_result_t
|
||||
isc__cfgmgr_dumpprop(const isc_cfgmgr_dumpcfg_t *cfg,
|
||||
@@ -573,7 +673,7 @@ isc__cfgmgr_dumpprop(const isc_cfgmgr_dumpcfg_t *cfg,
|
||||
isc_result_t result;
|
||||
isc_cfgmgr_val_t val;
|
||||
|
||||
result = isc__cfgmgr_getval(prop->name, &val, cfg->mode);
|
||||
result = isc__cfgmgr_getval(prop->name, &val);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if (result == ISC_R_NOTFOUND) {
|
||||
result = ISC_R_SUCCESS;
|
||||
@@ -585,21 +685,6 @@ isc__cfgmgr_dumpprop(const isc_cfgmgr_dumpcfg_t *cfg,
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: There is problem here because we're calling clausestarts/clauseends
|
||||
* even if there is nothing inside the clause (i.e. missing properties, or turns
|
||||
* out we're in a builtin mode and no builtin properties inside, etc.)
|
||||
*
|
||||
* So, to be done:
|
||||
*
|
||||
* - the call of clausestarts/clauseends must be lazy and only when we're
|
||||
* about the add a property or a sub-clause for the first time
|
||||
*
|
||||
* - when cfg->mode == ISC_CFGMGR_DUMPBUILTIN we need to call
|
||||
* isc_cfgmgr_builtinon/isc_cfgmgr_builtinoff between the loop to print the
|
||||
* properties (so we'll be sure to only print properties/clause with exists
|
||||
* only in builtin mode).
|
||||
*/
|
||||
static isc_result_t
|
||||
isc__cfgmgr_dumpclause(const isc_cfgmgr_dumpcfg_t *cfg,
|
||||
const isc_cfgmgr_clause_t *clause, size_t lvl) {
|
||||
@@ -650,14 +735,9 @@ isc_cfgmgr_dump(const isc_cfgmgr_dumpcfg_t *cfg) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
size_t lvl = 0;
|
||||
|
||||
REQUIRE(isc__cfgmgr_env != NULL);
|
||||
REQUIRE(ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses));
|
||||
REQUIRE(isc__cfgmgr_ctx.prefix == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.buffer == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.txn == NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.cursor == NULL);
|
||||
isc__cfgmgr_checkofftransaction();
|
||||
REQUIRE(cfg != NULL);
|
||||
REQUIRE(cfg->mode != ISC_CFGMGR_DUMPUNKNOWN);
|
||||
REQUIRE(cfg->dumpmode != ISC_CFGMGR_MODEUNKNOWN);
|
||||
|
||||
if (isc__cfgmgr_configformat == NULL) {
|
||||
result = ISC_R_FAILURE;
|
||||
@@ -665,6 +745,7 @@ isc_cfgmgr_dump(const isc_cfgmgr_dumpcfg_t *cfg) {
|
||||
}
|
||||
|
||||
result = isc_cfgmgr_transaction();
|
||||
isc_cfgmgr_setmode(cfg->dumpmode);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
@@ -682,31 +763,11 @@ out:
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
isc_cfgmgr_builtinon(void) {
|
||||
REQUIRE(isc__cfgmgr_env != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.txn != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.cursor != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.builtinon == false);
|
||||
isc__cfgmgr_ctx.builtinon = true;
|
||||
}
|
||||
|
||||
void
|
||||
isc_cfgmgr_builtinoff(void) {
|
||||
REQUIRE(isc__cfgmgr_env != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.txn != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.cursor != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.builtinon == true);
|
||||
isc__cfgmgr_ctx.builtinon = false;
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_cfgmgr_commit(void) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
REQUIRE(isc__cfgmgr_env != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.txn != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.cursor != NULL);
|
||||
isc__cfgmgr_checkontransaction();
|
||||
|
||||
while (ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses) == false) {
|
||||
isc_cfgmgr_close();
|
||||
@@ -715,7 +776,7 @@ isc_cfgmgr_commit(void) {
|
||||
result = isc__cfgmgr_validate();
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
mdb_cursor_close(isc__cfgmgr_ctx.cursor);
|
||||
isc__cfgmgr_closelmdbcursors();
|
||||
if (mdb_txn_commit(isc__cfgmgr_ctx.txn) != 0) {
|
||||
isc__cfgmgr_setlasterror(
|
||||
"configuration database error");
|
||||
@@ -726,22 +787,23 @@ isc_cfgmgr_commit(void) {
|
||||
isc_cfgmgr_rollback();
|
||||
}
|
||||
|
||||
isc__cfgmgr_checkofftransaction();
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
isc_cfgmgr_rollback(void) {
|
||||
REQUIRE(isc__cfgmgr_env != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.txn != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.cursor != NULL);
|
||||
isc__cfgmgr_checkontransaction();
|
||||
|
||||
while (ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses) == false) {
|
||||
isc_cfgmgr_close();
|
||||
}
|
||||
|
||||
mdb_cursor_close(isc__cfgmgr_ctx.cursor);
|
||||
isc__cfgmgr_closelmdbcursors();
|
||||
mdb_txn_abort(isc__cfgmgr_ctx.txn);
|
||||
isc__cfgmgr_freectx();
|
||||
|
||||
isc__cfgmgr_checkofftransaction();
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
@@ -749,10 +811,11 @@ isc_cfgmgr_open(const char *name) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
unsigned long id = 0;
|
||||
|
||||
isc__cfgmgr_checkontransaction();
|
||||
REQUIRE(isc__cfgmgr_env != NULL);
|
||||
REQUIRE(name != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.txn != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.cursor != NULL);
|
||||
REQUIRE(isc__cfgmgr_lmdbcursor() != NULL);
|
||||
|
||||
result = isc__cfgmgr_findclause(name, &id);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
@@ -762,34 +825,12 @@ isc_cfgmgr_open(const char *name) {
|
||||
return result;
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_cfgmgr_openornew(const char *name) {
|
||||
REQUIRE(isc__cfgmgr_ctx.readonly == false);
|
||||
|
||||
isc_result_t result = isc_cfgmgr_open(name);
|
||||
|
||||
if (isc_cfgmgr_open(name) == ISC_R_NOTFOUND) {
|
||||
isc_cfgmgr_newclause(name);
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
isc_cfgmgr_close(void) {
|
||||
openedclause_t *clause;
|
||||
|
||||
REQUIRE(isc__cfgmgr_env != NULL);
|
||||
REQUIRE(ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses) == false);
|
||||
REQUIRE(isc__cfgmgr_ctx.prefix != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.buffer != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.txn != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.cursor != NULL);
|
||||
isc__cfgmgr_checkopenedclause();
|
||||
|
||||
if (isc__cfgmgr_ctx.builtinon) {
|
||||
isc_cfgmgr_builtinoff();
|
||||
}
|
||||
clause = ISC_LIST_HEAD(isc__cfgmgr_ctx.openedclauses);
|
||||
ISC_LIST_UNLINK(isc__cfgmgr_ctx.openedclauses, clause, link);
|
||||
isc_mem_free(isc__cfgmgr_mctx, clause->name);
|
||||
@@ -801,12 +842,7 @@ void
|
||||
isc_cfgmgr_delclause(void) {
|
||||
MDB_val dbkey;
|
||||
|
||||
REQUIRE(isc__cfgmgr_env != NULL);
|
||||
REQUIRE(ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses) == false);
|
||||
REQUIRE(isc__cfgmgr_ctx.prefix != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.buffer != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.txn != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.cursor != NULL);
|
||||
isc__cfgmgr_checkopenedclause();
|
||||
REQUIRE(isc__cfgmgr_ctx.readonly == false);
|
||||
|
||||
dbkey = (MDB_val){ .mv_size = strlen(isc__cfgmgr_ctx.prefix) + 1,
|
||||
@@ -819,7 +855,7 @@ isc_cfgmgr_delclause(void) {
|
||||
* to the next one with the same prefix as soon it
|
||||
* gets deleted
|
||||
*/
|
||||
int mdbres = mdb_cursor_get(isc__cfgmgr_ctx.cursor, &dbkey,
|
||||
int mdbres = mdb_cursor_get(isc__cfgmgr_lmdbcursor(), &dbkey,
|
||||
NULL, MDB_SET_RANGE);
|
||||
if (mdbres == MDB_NOTFOUND) {
|
||||
break;
|
||||
@@ -836,8 +872,8 @@ isc_cfgmgr_delclause(void) {
|
||||
* avoid extra iterations if there are lists in the
|
||||
* clause
|
||||
*/
|
||||
REQUIRE(mdb_cursor_del(isc__cfgmgr_ctx.cursor, MDB_NODUPDATA) ==
|
||||
0);
|
||||
REQUIRE(mdb_cursor_del(isc__cfgmgr_lmdbcursor(),
|
||||
MDB_NODUPDATA) == 0);
|
||||
} while (1);
|
||||
|
||||
isc_cfgmgr_close();
|
||||
@@ -845,11 +881,8 @@ isc_cfgmgr_delclause(void) {
|
||||
|
||||
void
|
||||
isc_cfgmgr_newclause(const char *name) {
|
||||
REQUIRE(isc__cfgmgr_env != NULL);
|
||||
REQUIRE(name != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.txn != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.cursor != NULL);
|
||||
INSIST(isc__cfgmgr_ctx.readonly == false);
|
||||
isc__cfgmgr_checkontransaction();
|
||||
REQUIRE(isc__cfgmgr_ctx.readonly == false);
|
||||
|
||||
isc__cfgmgr_pushclause(name, isc_random32());
|
||||
INSIST(isc__cfgmgr_ctx.prefix != NULL);
|
||||
@@ -863,12 +896,7 @@ isc_cfgmgr_nextclause(void) {
|
||||
size_t idstarts = 0;
|
||||
size_t written = 0;
|
||||
|
||||
REQUIRE(isc__cfgmgr_env != NULL);
|
||||
REQUIRE(ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses) == false);
|
||||
REQUIRE(isc__cfgmgr_ctx.prefix != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.buffer != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.txn != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.cursor != NULL);
|
||||
isc__cfgmgr_checkopenedclause();
|
||||
|
||||
/*
|
||||
* Let's pick the very next id (even if doesn't exists) of the
|
||||
@@ -904,7 +932,7 @@ isc_cfgmgr_nextclause(void) {
|
||||
* id. Thanks for LMDB sort and MDB_SET_RANGE, we'll bump to
|
||||
* the first key/val of the next clause of the same type
|
||||
*/
|
||||
if (mdb_cursor_get(isc__cfgmgr_ctx.cursor, &dbkey, NULL,
|
||||
if (mdb_cursor_get(isc__cfgmgr_lmdbcursor(), &dbkey, NULL,
|
||||
MDB_SET_RANGE) != 0)
|
||||
{
|
||||
result = ISC_R_NOMORE;
|
||||
@@ -936,81 +964,13 @@ out:
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
isc__cfgmgr_getvalparent(const char *name, isc_cfgmgr_val_t *value,
|
||||
isc_cfgmgr_dumpmode_t dumpmode) {
|
||||
isc_result_t result = ISC_R_NOTFOUND;
|
||||
openedclause_t *clause;
|
||||
|
||||
REQUIRE(ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses) == false);
|
||||
clause = ISC_LIST_HEAD(isc__cfgmgr_ctx.openedclauses);
|
||||
|
||||
if (isc__cfgmgr_ctx.builtinon) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not run fallback lookup as we're buildin the original user
|
||||
* configuration.
|
||||
*/
|
||||
if (dumpmode == ISC_CFGMGR_DUMPUSER) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (clause->link.next == NULL) {
|
||||
/*
|
||||
* We were already at a top-level clause, so let's enable the
|
||||
* builtin mode to attempt to find name in the defaults.
|
||||
*/
|
||||
isc_cfgmgr_builtinon();
|
||||
result = isc__cfgmgr_getval(name, value, dumpmode);
|
||||
isc_cfgmgr_builtinoff();
|
||||
} else {
|
||||
/*
|
||||
* Not at the top-level clause, so let's recursively attempt in
|
||||
* the parent clauses until we reach the top-level (and attempt
|
||||
* the builtin mode above).
|
||||
*
|
||||
* It is not possible to directly use isc_cfgmgr_open/close
|
||||
* here, becuase if the clause is repeated, there is no garantee
|
||||
* that we find the same instance when re-opening it (if it was
|
||||
* opened using isc_cfgmgr_nextclause).
|
||||
*
|
||||
* Also it's quicker this way as avoid extra LMDB lookups.
|
||||
*/
|
||||
ISC_LIST_UNLINK(isc__cfgmgr_ctx.openedclauses, clause, link);
|
||||
isc__cfgmgr_updateprefix();
|
||||
|
||||
/*
|
||||
* Recursively attempt to get a value in the parents then
|
||||
* restore the current opened clause state
|
||||
*/
|
||||
result = isc__cfgmgr_getval(name, value, dumpmode);
|
||||
|
||||
/*
|
||||
* Restore the previous opened clause
|
||||
*/
|
||||
ISC_LIST_PREPEND(isc__cfgmgr_ctx.openedclauses, clause, link);
|
||||
isc__cfgmgr_updateprefix();
|
||||
}
|
||||
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
isc__cfgmgr_getval(const char *name, isc_cfgmgr_val_t *value,
|
||||
isc_cfgmgr_dumpmode_t dumpmode) {
|
||||
isc__cfgmgr_getval(const char *name, isc_cfgmgr_val_t *value) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
MDB_val dbkey;
|
||||
MDB_val dbval;
|
||||
const int opt = name == NULL ? MDB_NEXT_DUP : MDB_SET;
|
||||
|
||||
REQUIRE(isc__cfgmgr_env != NULL);
|
||||
REQUIRE(ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses) == false);
|
||||
REQUIRE(isc__cfgmgr_ctx.prefix != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.buffer != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.txn != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.cursor != NULL);
|
||||
isc__cfgmgr_checkopenedclause();
|
||||
REQUIRE(value != NULL);
|
||||
|
||||
if (name != NULL) {
|
||||
@@ -1021,13 +981,9 @@ isc__cfgmgr_getval(const char *name, isc_cfgmgr_val_t *value,
|
||||
: strlen(isc__cfgmgr_ctx.buffer) + 1,
|
||||
.mv_data = name == NULL ? NULL : isc__cfgmgr_ctx.buffer
|
||||
};
|
||||
if (mdb_cursor_get(isc__cfgmgr_ctx.cursor, &dbkey, &dbval, opt) != 0) {
|
||||
if (mdb_cursor_get(isc__cfgmgr_lmdbcursor(), &dbkey, &dbval, opt) != 0)
|
||||
{
|
||||
result = opt == MDB_NEXT_DUP ? ISC_R_NOMORE : ISC_R_NOTFOUND;
|
||||
|
||||
if (result == ISC_R_NOTFOUND) {
|
||||
result = isc__cfgmgr_getvalparent(name, value,
|
||||
dumpmode);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1048,12 +1004,12 @@ out:
|
||||
|
||||
isc_result_t
|
||||
isc_cfgmgr_getval(const char *name, isc_cfgmgr_val_t *value) {
|
||||
return isc__cfgmgr_getval(name, value, ISC_CFGMGR_DUMPUNKNOWN);
|
||||
return isc__cfgmgr_getval(name, value);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_cfgmgr_getnextlistval(isc_cfgmgr_val_t *value) {
|
||||
return isc__cfgmgr_getval(NULL, value, ISC_CFGMGR_DUMPUNKNOWN);
|
||||
return isc__cfgmgr_getval(NULL, value);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
@@ -1062,12 +1018,7 @@ isc__cfgmgr_setval(const char *name, const isc_cfgmgr_val_t *value, bool list) {
|
||||
MDB_val dbkey;
|
||||
MDB_val dbval;
|
||||
|
||||
REQUIRE(isc__cfgmgr_env != NULL);
|
||||
REQUIRE(ISC_LIST_EMPTY(isc__cfgmgr_ctx.openedclauses) == false);
|
||||
REQUIRE(isc__cfgmgr_ctx.prefix != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.buffer != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.txn != NULL);
|
||||
REQUIRE(isc__cfgmgr_ctx.cursor != NULL);
|
||||
isc__cfgmgr_checkopenedclause();
|
||||
REQUIRE(isc__cfgmgr_ctx.readonly == false);
|
||||
REQUIRE(name != NULL);
|
||||
REQUIRE((value != NULL && value->type != ISC_CFGMGR_UNDEFINED) ||
|
||||
@@ -1077,15 +1028,15 @@ isc__cfgmgr_setval(const char *name, const isc_cfgmgr_val_t *value, bool list) {
|
||||
dbkey = (MDB_val){ .mv_size = strlen(isc__cfgmgr_ctx.buffer) + 1,
|
||||
.mv_data = isc__cfgmgr_ctx.buffer };
|
||||
if (value == NULL) {
|
||||
if (mdb_cursor_get(isc__cfgmgr_ctx.cursor, &dbkey, NULL,
|
||||
if (mdb_cursor_get(isc__cfgmgr_lmdbcursor(), &dbkey, NULL,
|
||||
MDB_SET) == MDB_NOTFOUND)
|
||||
{
|
||||
result = ISC_R_NOTFOUND;
|
||||
goto out;
|
||||
}
|
||||
|
||||
REQUIRE(mdb_cursor_del(isc__cfgmgr_ctx.cursor, MDB_NODUPDATA) ==
|
||||
0);
|
||||
REQUIRE(mdb_cursor_del(isc__cfgmgr_lmdbcursor(),
|
||||
MDB_NODUPDATA) == 0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1119,14 +1070,16 @@ isc__cfgmgr_setval(const char *name, const isc_cfgmgr_val_t *value, bool list) {
|
||||
* list. Making a value copy ahead just in case is likely more
|
||||
* expensive than an extra lookup
|
||||
*/
|
||||
if (mdb_cursor_get(isc__cfgmgr_ctx.cursor, &dbkey, NULL,
|
||||
if (mdb_cursor_get(isc__cfgmgr_lmdbcursor(), &dbkey, NULL,
|
||||
MDB_SET) != MDB_NOTFOUND)
|
||||
{
|
||||
REQUIRE(mdb_cursor_del(isc__cfgmgr_ctx.cursor, 0) == 0);
|
||||
REQUIRE(mdb_cursor_del(isc__cfgmgr_lmdbcursor(), 0) ==
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
REQUIRE(mdb_cursor_put(isc__cfgmgr_ctx.cursor, &dbkey, &dbval, 0) == 0);
|
||||
REQUIRE(mdb_cursor_put(isc__cfgmgr_lmdbcursor(), &dbkey, &dbval, 0) ==
|
||||
0);
|
||||
if (value->type == ISC_CFGMGR_STRING) {
|
||||
isc_mem_free(isc__cfgmgr_mctx, dbval.mv_data);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,36 @@
|
||||
#include <isc/sockaddr.h>
|
||||
#include <isc/types.h>
|
||||
|
||||
/*
|
||||
* cfgmgr has three modes. The builtin mode is used to set all the builtin named
|
||||
* configuration. The user mode is used to set all the named.conf user provided
|
||||
* configuration. The running mode (which is the one used by default when
|
||||
* starting a transaction) is a mode which materialize the builtin mode, the
|
||||
* user mode, and override those with "live" updates using cfgmgr API.
|
||||
*
|
||||
* The materialization of the running mode is based on the following rules:
|
||||
*
|
||||
* - the "options" clause gets all the values from the builtin
|
||||
* "option" clause, then all the values from the user "options" clause
|
||||
* (potentially overriding those from the builtin mode)
|
||||
*
|
||||
* - the "view" clauses gets all the values of the running "options"
|
||||
* clause, then can override those. It also means that an update in the
|
||||
* running "options" clause automatically applies to all "view" clauses as
|
||||
* well.
|
||||
*
|
||||
* - the "zone" clauses gets all the values of its parent running "view" clause,
|
||||
* then can override those. It also means that an update in the running parent
|
||||
* "view" clause propagates to all its zones.
|
||||
*/
|
||||
typedef enum isc_cfgmgr_mode isc_cfgmgr_mode_t;
|
||||
enum isc_cfgmgr_mode {
|
||||
ISC_CFGMGR_MODEUNKNOWN = 0,
|
||||
ISC_CFGMGR_MODEBUILTIN,
|
||||
ISC_CFGMGR_MODEUSER,
|
||||
ISC_CFGMGR_MODERUNNING
|
||||
};
|
||||
|
||||
/*
|
||||
* Supported data types for read/write operations from/to cfgmgr.
|
||||
*/
|
||||
@@ -70,41 +100,17 @@ typedef struct isc_cfgmgr_val {
|
||||
} isc_cfgmgr_val_t;
|
||||
|
||||
/*
|
||||
* Those both functions enable or disable the "builtin" mode. (disabled by
|
||||
* default, and automatically disabled anytime a transaction finished). This
|
||||
* implicitely "namespace" the clause properties names when reading or
|
||||
* writting values in cfgmgr. Must be called under a transaction.
|
||||
*
|
||||
* Closing a close/transaction automatically turn the builtin mode off.
|
||||
*
|
||||
* User must be careful of one thing: creating new clause when builtin mode is
|
||||
* like creating a new clause on non-builtin mode. This means that if (1) user
|
||||
* calls isc_cfgmgr_newclause("foo") while on builtin mode, adds some builtin
|
||||
* properties, then (2) calls isc_cfgmgr_newclause("foo") on non-builtin mode,
|
||||
* this will create a second instance of the clause foo (and builtin properties
|
||||
* would be accessible only from the first instance of the clause foo). In such
|
||||
* cases, the user probably want to do "isc_cfgmgr_open("foo") or
|
||||
* "isc_cfgmgr_openornew("foo").
|
||||
* Set the cfgmgr mode. This must be called under a transaction. By default, a
|
||||
* tansaction always starts on ISC_CFGMGR_MODERUNNING.
|
||||
*/
|
||||
void
|
||||
isc_cfgmgr_builtinon(void);
|
||||
|
||||
void
|
||||
isc_cfgmgr_builtinoff(void);
|
||||
isc_cfgmgr_setmode(isc_cfgmgr_mode_t mode);
|
||||
|
||||
/*
|
||||
* Get the property "name" in the opened clause into the caller
|
||||
* allocated "value" and returns ISC_R_SUCCESS. Returns ISC_R_NOTFOUND
|
||||
* and "*value" is not mutated if "name" is not found. If "name" is a list
|
||||
* property, get its head.
|
||||
*
|
||||
* If a value is not found and builtin mode is off, and before returning
|
||||
* ISC_R_NOTFOUND, cfgmgr internally attempts to lookup for such value in the
|
||||
* parent clauses. If the name is found, the parent value is returned. When the
|
||||
* top-level parent is reached (or if the current clause is a top-level one), a
|
||||
* last attempt is made by trying the builtin mode namespacing of the clause
|
||||
* name (which is how isc_cfgmgr_setval() store values when
|
||||
* isc_cfgmgr_builtinon() is set).
|
||||
*/
|
||||
isc_result_t
|
||||
isc_cfgmgr_getval(const char *name, isc_cfgmgr_val_t *value);
|
||||
@@ -178,13 +184,6 @@ isc_cfgmgr_delclause(void);
|
||||
isc_result_t
|
||||
isc_cfgmgr_open(const char *name);
|
||||
|
||||
/*
|
||||
* Open the clause "name" or create it if it doesn't exits already. Must be
|
||||
* called under a write transaction. Return ISC_R_SUCCESS.
|
||||
*/
|
||||
isc_result_t
|
||||
isc_cfgmgr_openornew(const char *name);
|
||||
|
||||
/*
|
||||
* Close the currently opened clause and returns ISC_R_SUCCESS. If the
|
||||
* closed clause was nested, the currently opened clause is now the
|
||||
@@ -261,23 +260,15 @@ isc_cfgmgr_lasterror(void);
|
||||
* A configuration format must be provided to cfgmgr (when isc_cfgmgr_init is
|
||||
* called) in order to build a dump, otherwise, ISC_R_FAILURE will be returned.
|
||||
*/
|
||||
typedef enum isc_cfgmgr_dumpmode isc_cfgmgr_dumpmode_t;
|
||||
enum isc_cfgmgr_dumpmode {
|
||||
ISC_CFGMGR_DUMPUNKNOWN = 0,
|
||||
ISC_CFGMGR_DUMPBUILTIN,
|
||||
ISC_CFGMGR_DUMPUSER,
|
||||
ISC_CFGMGR_DUMPRUNNING
|
||||
};
|
||||
|
||||
typedef struct isc_cfgmgr_dumpcfg isc_cfgmgr_dumpcfg_t;
|
||||
struct isc_cfgmgr_dumpcfg {
|
||||
void (*clausestarts)(void *state, const char *name, size_t indent);
|
||||
void (*clauseends)(void *state, const char *name, size_t indent);
|
||||
void (*property)(void *state, const char *name,
|
||||
const isc_cfgmgr_val_t *val, size_t indent);
|
||||
void *state;
|
||||
size_t indent;
|
||||
isc_cfgmgr_dumpmode_t mode;
|
||||
void *state;
|
||||
size_t indent;
|
||||
isc_cfgmgr_mode_t dumpmode;
|
||||
};
|
||||
|
||||
isc_result_t
|
||||
|
||||
+390
-378
@@ -1506,141 +1506,141 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_validationtest) {
|
||||
isc_cfgmgr_deinit();
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(isc_cfgmgr_getparent) {
|
||||
isc_result_t result;
|
||||
isc_cfgmgr_val_t val;
|
||||
|
||||
result = isc_cfgmgr_init(mctx, TEST_DBPATH, NULL);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_rwtransaction();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
assert_int_equal(isc_cfgmgr_open("foo"), ISC_R_NOTFOUND);
|
||||
assert_int_equal(isc_cfgmgr_open("bar"), ISC_R_NOTFOUND);
|
||||
assert_int_equal(isc_cfgmgr_open("baz"), ISC_R_NOTFOUND);
|
||||
|
||||
isc_cfgmgr_newclause("foo");
|
||||
|
||||
val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 42 };
|
||||
result = isc_cfgmgr_setval("prop1", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_cfgmgr_newclause("bar");
|
||||
val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 24 };
|
||||
result = isc_cfgmgr_setval("prop2", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_cfgmgr_newclause("baz");
|
||||
val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 999 };
|
||||
result = isc_cfgmgr_setval("prop3", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_commit();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_transaction();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_open("foo");
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_getval("prop1", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
assert_int_equal(val.uint32, 42);
|
||||
|
||||
/*
|
||||
* prop2 and prop3 are in child clauses, can't be found
|
||||
*/
|
||||
result = isc_cfgmgr_getval("prop2", &val);
|
||||
assert_int_equal(result, ISC_R_NOTFOUND);
|
||||
result = isc_cfgmgr_getval("prop3", &val);
|
||||
assert_int_equal(result, ISC_R_NOTFOUND);
|
||||
|
||||
/*
|
||||
* open the child bar clause and it gets possible to read prop2 _and_
|
||||
* prop1 (thanks to getvalparent flow) but still not prop3 as it's in a
|
||||
* child clause
|
||||
*/
|
||||
result = isc_cfgmgr_open("bar");
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_getval("prop2", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
assert_int_equal(val.uint32, 24);
|
||||
|
||||
result = isc_cfgmgr_getval("prop1", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
assert_int_equal(val.uint32, 42);
|
||||
|
||||
result = isc_cfgmgr_getval("prop3", &val);
|
||||
assert_int_equal(result, ISC_R_NOTFOUND);
|
||||
|
||||
/*
|
||||
* finally open the baz clause (nested in bar), all properties can be
|
||||
* read
|
||||
*/
|
||||
result = isc_cfgmgr_open("baz");
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_getval("prop3", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
assert_int_equal(val.uint32, 999);
|
||||
|
||||
result = isc_cfgmgr_getval("prop2", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
assert_int_equal(val.uint32, 24);
|
||||
|
||||
result = isc_cfgmgr_getval("prop1", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
assert_int_equal(val.uint32, 42);
|
||||
|
||||
result = isc_cfgmgr_commit();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* bar override prop1, so it has its own prop1 (and this doesn't affect
|
||||
* the one in foo, but baz now see the overriden one)
|
||||
*/
|
||||
result = isc_cfgmgr_rwtransaction();
|
||||
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
result = isc_cfgmgr_open("foo");
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_open("bar");
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
val.uint32 = 42424242;
|
||||
result = isc_cfgmgr_setval("prop1", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_open("baz");
|
||||
val.uint32 = 0;
|
||||
result = isc_cfgmgr_getval("prop1", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_int_equal(val.uint32, 42424242);
|
||||
|
||||
/*
|
||||
* Let's go back to foo and make sure we still have 42 for prop1
|
||||
* there...
|
||||
*/
|
||||
isc_cfgmgr_close();
|
||||
isc_cfgmgr_close();
|
||||
|
||||
result = isc_cfgmgr_getval("prop1", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_int_equal(val.uint32, 42);
|
||||
|
||||
isc_cfgmgr_commit();
|
||||
isc_cfgmgr_deinit();
|
||||
}
|
||||
// ISC_RUN_TEST_IMPL(isc_cfgmgr_getparent) {
|
||||
// isc_result_t result;
|
||||
// isc_cfgmgr_val_t val;
|
||||
//
|
||||
// result = isc_cfgmgr_init(mctx, TEST_DBPATH, NULL);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_rwtransaction();
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// assert_int_equal(isc_cfgmgr_open("foo"), ISC_R_NOTFOUND);
|
||||
// assert_int_equal(isc_cfgmgr_open("bar"), ISC_R_NOTFOUND);
|
||||
// assert_int_equal(isc_cfgmgr_open("baz"), ISC_R_NOTFOUND);
|
||||
//
|
||||
// isc_cfgmgr_newclause("foo");
|
||||
//
|
||||
// val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 42 };
|
||||
// result = isc_cfgmgr_setval("prop1", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// isc_cfgmgr_newclause("bar");
|
||||
// val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 24 };
|
||||
// result = isc_cfgmgr_setval("prop2", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// isc_cfgmgr_newclause("baz");
|
||||
// val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 999 };
|
||||
// result = isc_cfgmgr_setval("prop3", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_commit();
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_transaction();
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_open("foo");
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_getval("prop1", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
// assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
// assert_int_equal(val.uint32, 42);
|
||||
//
|
||||
// /*
|
||||
// * prop2 and prop3 are in child clauses, can't be found
|
||||
// */
|
||||
// result = isc_cfgmgr_getval("prop2", &val);
|
||||
// assert_int_equal(result, ISC_R_NOTFOUND);
|
||||
// result = isc_cfgmgr_getval("prop3", &val);
|
||||
// assert_int_equal(result, ISC_R_NOTFOUND);
|
||||
//
|
||||
// /*
|
||||
// * open the child bar clause and it gets possible to read prop2 _and_
|
||||
// * prop1 (thanks to getvalparent flow) but still not prop3 as it's in a
|
||||
// * child clause
|
||||
// */
|
||||
// result = isc_cfgmgr_open("bar");
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_getval("prop2", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
// assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
// assert_int_equal(val.uint32, 24);
|
||||
//
|
||||
// result = isc_cfgmgr_getval("prop1", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
// assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
// assert_int_equal(val.uint32, 42);
|
||||
//
|
||||
// result = isc_cfgmgr_getval("prop3", &val);
|
||||
// assert_int_equal(result, ISC_R_NOTFOUND);
|
||||
//
|
||||
// /*
|
||||
// * finally open the baz clause (nested in bar), all properties can be
|
||||
// * read
|
||||
// */
|
||||
// result = isc_cfgmgr_open("baz");
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_getval("prop3", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
// assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
// assert_int_equal(val.uint32, 999);
|
||||
//
|
||||
// result = isc_cfgmgr_getval("prop2", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
// assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
// assert_int_equal(val.uint32, 24);
|
||||
//
|
||||
// result = isc_cfgmgr_getval("prop1", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
// assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
// assert_int_equal(val.uint32, 42);
|
||||
//
|
||||
// result = isc_cfgmgr_commit();
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// /*
|
||||
// * bar override prop1, so it has its own prop1 (and this doesn't affect
|
||||
// * the one in foo, but baz now see the overriden one)
|
||||
// */
|
||||
// result = isc_cfgmgr_rwtransaction();
|
||||
//
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
// result = isc_cfgmgr_open("foo");
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_open("bar");
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// val.uint32 = 42424242;
|
||||
// result = isc_cfgmgr_setval("prop1", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_open("baz");
|
||||
// val.uint32 = 0;
|
||||
// result = isc_cfgmgr_getval("prop1", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
// assert_int_equal(val.uint32, 42424242);
|
||||
//
|
||||
// /*
|
||||
// * Let's go back to foo and make sure we still have 42 for prop1
|
||||
// * there...
|
||||
// */
|
||||
// isc_cfgmgr_close();
|
||||
// isc_cfgmgr_close();
|
||||
//
|
||||
// result = isc_cfgmgr_getval("prop1", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
// assert_int_equal(val.uint32, 42);
|
||||
//
|
||||
// isc_cfgmgr_commit();
|
||||
// isc_cfgmgr_deinit();
|
||||
// }
|
||||
|
||||
ISC_RUN_TEST_IMPL(isc_cfgmgr_opentests) {
|
||||
isc_result_t result;
|
||||
@@ -1719,183 +1719,183 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_opentests) {
|
||||
isc_cfgmgr_deinit();
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(isc_cfgmgr_builtintests) {
|
||||
isc_result_t result;
|
||||
isc_cfgmgr_val_t val;
|
||||
|
||||
result = isc_cfgmgr_init(mctx, TEST_DBPATH, NULL);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_rwtransaction();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_cfgmgr_newclause("foo");
|
||||
|
||||
/*
|
||||
* Set a user property and check that it is not possible to read it
|
||||
* from builtin mode
|
||||
*/
|
||||
val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_STRING,
|
||||
.string = "userval1" };
|
||||
result = isc_cfgmgr_setval("userprop1", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
expect_assert_failure(isc_cfgmgr_builtinoff());
|
||||
isc_cfgmgr_builtinon();
|
||||
expect_assert_failure(isc_cfgmgr_builtinon());
|
||||
|
||||
result = isc_cfgmgr_getval("userprop1", &val);
|
||||
assert_int_equal(result, ISC_R_NOTFOUND);
|
||||
|
||||
/*
|
||||
* Set a builtin property and check that is is readable from non-builtin
|
||||
* mode
|
||||
*/
|
||||
val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 1234 };
|
||||
result = isc_cfgmgr_setval("builtinval1", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
val = (isc_cfgmgr_val_t){};
|
||||
isc_cfgmgr_builtinoff();
|
||||
expect_assert_failure(isc_cfgmgr_builtinoff());
|
||||
|
||||
result = isc_cfgmgr_getval("builtinval1", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
assert_int_equal(val.uint32, 1234);
|
||||
|
||||
/*
|
||||
* user override builtin property, now only the user value is visible in
|
||||
* builtin mode off, but the original value is still readable with
|
||||
* builtin mode on
|
||||
*/
|
||||
val.uint32 = 5678;
|
||||
result = isc_cfgmgr_setval("builtinval1", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
val = (isc_cfgmgr_val_t){};
|
||||
result = isc_cfgmgr_getval("builtinval1", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
assert_int_equal(val.uint32, 5678);
|
||||
|
||||
isc_cfgmgr_builtinon();
|
||||
val = (isc_cfgmgr_val_t){};
|
||||
result = isc_cfgmgr_getval("builtinval1", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
assert_int_equal(val.uint32, 1234);
|
||||
|
||||
/*
|
||||
* builtin mode on is automatically turned off when closing a clause
|
||||
* (commit automatically clause opened clauses)
|
||||
*/
|
||||
result = isc_cfgmgr_commit();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_transaction();
|
||||
result = isc_cfgmgr_open("foo");
|
||||
expect_assert_failure(isc_cfgmgr_builtinoff());
|
||||
isc_cfgmgr_builtinon();
|
||||
isc_cfgmgr_close();
|
||||
|
||||
result = isc_cfgmgr_open("foo");
|
||||
expect_assert_failure(isc_cfgmgr_builtinoff());
|
||||
isc_cfgmgr_builtinon();
|
||||
|
||||
isc_cfgmgr_rollback();
|
||||
|
||||
/*
|
||||
* create a clause with builtin property and user never override it, but
|
||||
* can still get the builtin value with a default lookup.
|
||||
*/
|
||||
result = isc_cfgmgr_rwtransaction();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_cfgmgr_builtinon();
|
||||
isc_cfgmgr_newclause("gee");
|
||||
|
||||
val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 42 };
|
||||
result = isc_cfgmgr_setval("foo", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_commit();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_transaction();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_open("gee");
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
val = (isc_cfgmgr_val_t){};
|
||||
result = isc_cfgmgr_getval("foo", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
assert_int_equal(val.uint32, 42);
|
||||
|
||||
isc_cfgmgr_rollback();
|
||||
|
||||
/*
|
||||
* then let's re-open this clause and update "foo" property to another
|
||||
* value, we won't read the builtin in anymore.
|
||||
*/
|
||||
result = isc_cfgmgr_rwtransaction();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_openornew("gee");
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
val = (isc_cfgmgr_val_t){};
|
||||
result = isc_cfgmgr_getval("foo", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
assert_int_equal(val.uint32, 42);
|
||||
|
||||
val.uint32 = 55555;
|
||||
result = isc_cfgmgr_setval("foo", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_commit();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* lets get the new value of gee.foo, then remove it, we'll get back the
|
||||
* builtin one now.
|
||||
*/
|
||||
result = isc_cfgmgr_rwtransaction();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_openornew("gee");
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
val = (isc_cfgmgr_val_t){};
|
||||
result = isc_cfgmgr_getval("foo", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
assert_int_equal(val.uint32, 55555);
|
||||
|
||||
result = isc_cfgmgr_setval("foo", NULL);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_commit();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_transaction();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_open("gee");
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
val = (isc_cfgmgr_val_t){};
|
||||
result = isc_cfgmgr_getval("foo", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
assert_int_equal(val.uint32, 42);
|
||||
|
||||
isc_cfgmgr_rollback();
|
||||
isc_cfgmgr_deinit();
|
||||
}
|
||||
// ISC_RUN_TEST_IMPL(isc_cfgmgr_builtintests) {
|
||||
// isc_result_t result;
|
||||
// isc_cfgmgr_val_t val;
|
||||
//
|
||||
// result = isc_cfgmgr_init(mctx, TEST_DBPATH, NULL);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_rwtransaction();
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// isc_cfgmgr_newclause("foo");
|
||||
//
|
||||
// /*
|
||||
// * Set a user property and check that it is not possible to read it
|
||||
// * from builtin mode
|
||||
// */
|
||||
// val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_STRING,
|
||||
// .string = "userval1" };
|
||||
// result = isc_cfgmgr_setval("userprop1", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// expect_assert_failure(isc_cfgmgr_builtinoff());
|
||||
// isc_cfgmgr_builtinon();
|
||||
// expect_assert_failure(isc_cfgmgr_builtinon());
|
||||
//
|
||||
// result = isc_cfgmgr_getval("userprop1", &val);
|
||||
// assert_int_equal(result, ISC_R_NOTFOUND);
|
||||
//
|
||||
// /*
|
||||
// * Set a builtin property and check that is is readable from non-builtin
|
||||
// * mode
|
||||
// */
|
||||
// val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 1234 };
|
||||
// result = isc_cfgmgr_setval("builtinval1", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// val = (isc_cfgmgr_val_t){};
|
||||
// isc_cfgmgr_builtinoff();
|
||||
// expect_assert_failure(isc_cfgmgr_builtinoff());
|
||||
//
|
||||
// result = isc_cfgmgr_getval("builtinval1", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
// assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
// assert_int_equal(val.uint32, 1234);
|
||||
//
|
||||
// /*
|
||||
// * user override builtin property, now only the user value is visible in
|
||||
// * builtin mode off, but the original value is still readable with
|
||||
// * builtin mode on
|
||||
// */
|
||||
// val.uint32 = 5678;
|
||||
// result = isc_cfgmgr_setval("builtinval1", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// val = (isc_cfgmgr_val_t){};
|
||||
// result = isc_cfgmgr_getval("builtinval1", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
// assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
// assert_int_equal(val.uint32, 5678);
|
||||
//
|
||||
// isc_cfgmgr_builtinon();
|
||||
// val = (isc_cfgmgr_val_t){};
|
||||
// result = isc_cfgmgr_getval("builtinval1", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
// assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
// assert_int_equal(val.uint32, 1234);
|
||||
//
|
||||
// /*
|
||||
// * builtin mode on is automatically turned off when closing a clause
|
||||
// * (commit automatically clause opened clauses)
|
||||
// */
|
||||
// result = isc_cfgmgr_commit();
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_transaction();
|
||||
// result = isc_cfgmgr_open("foo");
|
||||
// expect_assert_failure(isc_cfgmgr_builtinoff());
|
||||
// isc_cfgmgr_builtinon();
|
||||
// isc_cfgmgr_close();
|
||||
//
|
||||
// result = isc_cfgmgr_open("foo");
|
||||
// expect_assert_failure(isc_cfgmgr_builtinoff());
|
||||
// isc_cfgmgr_builtinon();
|
||||
//
|
||||
// isc_cfgmgr_rollback();
|
||||
//
|
||||
// /*
|
||||
// * create a clause with builtin property and user never override it, but
|
||||
// * can still get the builtin value with a default lookup.
|
||||
// */
|
||||
// result = isc_cfgmgr_rwtransaction();
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// isc_cfgmgr_builtinon();
|
||||
// isc_cfgmgr_newclause("gee");
|
||||
//
|
||||
// val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 42 };
|
||||
// result = isc_cfgmgr_setval("foo", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_commit();
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_transaction();
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_open("gee");
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// val = (isc_cfgmgr_val_t){};
|
||||
// result = isc_cfgmgr_getval("foo", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
// assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
// assert_int_equal(val.uint32, 42);
|
||||
//
|
||||
// isc_cfgmgr_rollback();
|
||||
//
|
||||
// /*
|
||||
// * then let's re-open this clause and update "foo" property to another
|
||||
// * value, we won't read the builtin in anymore.
|
||||
// */
|
||||
// result = isc_cfgmgr_rwtransaction();
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_open("gee");
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// val = (isc_cfgmgr_val_t){};
|
||||
// result = isc_cfgmgr_getval("foo", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
// assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
// assert_int_equal(val.uint32, 42);
|
||||
//
|
||||
// val.uint32 = 55555;
|
||||
// result = isc_cfgmgr_setval("foo", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_commit();
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// /*
|
||||
// * lets get the new value of gee.foo, then remove it, we'll get back the
|
||||
// * builtin one now.
|
||||
// */
|
||||
// result = isc_cfgmgr_rwtransaction();
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_open("gee");
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// val = (isc_cfgmgr_val_t){};
|
||||
// result = isc_cfgmgr_getval("foo", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
// assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
// assert_int_equal(val.uint32, 55555);
|
||||
//
|
||||
// result = isc_cfgmgr_setval("foo", NULL);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_commit();
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_transaction();
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// result = isc_cfgmgr_open("gee");
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// val = (isc_cfgmgr_val_t){};
|
||||
// result = isc_cfgmgr_getval("foo", &val);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
// assert_int_equal(val.type, ISC_CFGMGR_UINT32);
|
||||
// assert_int_equal(val.uint32, 42);
|
||||
//
|
||||
// isc_cfgmgr_rollback();
|
||||
// isc_cfgmgr_deinit();
|
||||
// }
|
||||
|
||||
static void
|
||||
cfgmgr_dumptests_clausestarts(void *state, const char *name, size_t indent) {
|
||||
@@ -1973,6 +1973,8 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_dumptests) {
|
||||
result = isc_cfgmgr_rwtransaction();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_cfgmgr_setmode(ISC_CFGMGR_MODEUSER);
|
||||
|
||||
isc_cfgmgr_newclause("foo");
|
||||
val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_STRING, .string = "a" };
|
||||
result = isc_cfgmgr_setval("prop1", &val);
|
||||
@@ -1985,8 +1987,8 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_dumptests) {
|
||||
* Yes, "prop4" has nothing to do in "foo" (according to the format).
|
||||
* But let's add it anyway: this won't be visible in foo (because it's
|
||||
* not as part of its format) and... Won't be visible in bar, because
|
||||
* we'll iniitally make a ISC_CFGMGR_DUMPUSER, so a dump of the user
|
||||
* configuration only, which does not enable inheritance
|
||||
* we'll iniitally make a ISC_CFGMGR_MODEUSER, so a dump of the user
|
||||
* configuration only, which does have any kind of materialization
|
||||
*/
|
||||
val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_STRING, .string = "zz" };
|
||||
result = isc_cfgmgr_setval("prop4", &val);
|
||||
@@ -2028,7 +2030,7 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_dumptests) {
|
||||
.property = cfgmgr_dumptests_property,
|
||||
.state = &buffer,
|
||||
.indent = 8,
|
||||
.mode = ISC_CFGMGR_DUMPUSER };
|
||||
.dumpmode = ISC_CFGMGR_MODEUSER };
|
||||
|
||||
isc_buffer_init(&buffer, data, sizeof(data));
|
||||
result = isc_cfgmgr_dump(&cfg);
|
||||
@@ -2052,38 +2054,40 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_dumptests) {
|
||||
|
||||
assert_string_equal(buffer.base, expected);
|
||||
|
||||
/*
|
||||
* Let's now run a ISC_CFGMGR_DUMPRUNNING dump. The only difference is
|
||||
* that prop4 will now be visible in bar, as the inheritance is enabled.
|
||||
*/
|
||||
cfg.mode = ISC_CFGMGR_DUMPRUNNING;
|
||||
isc_buffer_init(&buffer, data, sizeof(data));
|
||||
result = isc_cfgmgr_dump(&cfg);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_buffer_putuint8(&buffer, 0);
|
||||
|
||||
const char expected2[] = "foo {\n"
|
||||
" prop1 a;\n"
|
||||
" prop2bis 43;\n"
|
||||
" bar {\n"
|
||||
" prop3 b;\n"
|
||||
" prop4 zz;\n"
|
||||
" }; #bar\n"
|
||||
"}; #foo\n"
|
||||
"baz {\n"
|
||||
" prop5 c;\n"
|
||||
"}; #baz\n"
|
||||
"baz {\n"
|
||||
" prop5 c;\n"
|
||||
"}; #baz\n";
|
||||
|
||||
assert_string_equal(buffer.base, expected2);
|
||||
// /*
|
||||
// * Let's now run a ISC_CFGMGR_DUMPRUNNING dump. The only
|
||||
//difference is
|
||||
// * that prop4 will now be visible in bar, as the inheritance is
|
||||
//enabled.
|
||||
// */
|
||||
// cfg.dumpmode = ISC_CFGMGR_MODERUNNING;
|
||||
// isc_buffer_init(&buffer, data, sizeof(data));
|
||||
// result = isc_cfgmgr_dump(&cfg);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// isc_buffer_putuint8(&buffer, 0);
|
||||
//
|
||||
// const char expected2[] = "foo {\n"
|
||||
// " prop1 a;\n"
|
||||
// " prop2bis 43;\n"
|
||||
// " bar {\n"
|
||||
// " prop3 b;\n"
|
||||
// " prop4 zz;\n"
|
||||
// " }; #bar\n"
|
||||
// "}; #foo\n"
|
||||
// "baz {\n"
|
||||
// " prop5 c;\n"
|
||||
// "}; #baz\n"
|
||||
// "baz {\n"
|
||||
// " prop5 c;\n"
|
||||
// "}; #baz\n";
|
||||
//
|
||||
// assert_string_equal(buffer.base, expected2);
|
||||
|
||||
/*
|
||||
* Dump with ISC_CFGMGR_UNKNOWN is a coding error
|
||||
*/
|
||||
cfg.mode = ISC_CFGMGR_DUMPUNKNOWN;
|
||||
cfg.dumpmode = ISC_CFGMGR_MODEUNKNOWN;
|
||||
isc_buffer_init(&buffer, data, sizeof(data));
|
||||
expect_assert_failure(isc_cfgmgr_dump(&cfg));
|
||||
|
||||
@@ -2093,67 +2097,75 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_dumptests) {
|
||||
result = isc_cfgmgr_rwtransaction();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_open("foo");
|
||||
isc_cfgmgr_setmode(ISC_CFGMGR_MODEBUILTIN);
|
||||
isc_cfgmgr_newclause("foo");
|
||||
|
||||
isc_cfgmgr_builtinon();
|
||||
val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_STRING,
|
||||
.string = "abuiltin" };
|
||||
result = isc_cfgmgr_setval("prop1", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_cfgmgr_close();
|
||||
isc_cfgmgr_newclause("baz");
|
||||
val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_STRING, .string = "c" };
|
||||
result = isc_cfgmgr_setval("prop5", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_commit();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* let's dump in ISC_CFGMGR_DUMPBUILTIN only
|
||||
* TODO: needs to fix this - see todo in cfgmgr.c
|
||||
*/
|
||||
// cfg.mode = ISC_CFGMGR_DUMPBUILTIN;
|
||||
// isc_buffer_init(&buffer, data, sizeof(data));
|
||||
// result = isc_cfgmgr_dump(&cfg);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// isc_buffer_putuint8(&buffer, 0);
|
||||
//
|
||||
// const char expected3[] = "foo {\n"
|
||||
// " prop1 abuiltin;\n"
|
||||
// "}; #foo\n";
|
||||
//
|
||||
// assert_string_equal(buffer.base, expected3);
|
||||
|
||||
/*
|
||||
* let's make a new running dump - foo.prop1 will override the
|
||||
* builtin value.
|
||||
*/
|
||||
cfg.mode = ISC_CFGMGR_DUMPRUNNING;
|
||||
cfg.dumpmode = ISC_CFGMGR_MODEBUILTIN;
|
||||
isc_buffer_init(&buffer, data, sizeof(data));
|
||||
result = isc_cfgmgr_dump(&cfg);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_buffer_putuint8(&buffer, 0);
|
||||
|
||||
const char expected4[] = "foo {\n"
|
||||
" prop1 a;\n"
|
||||
" prop2bis 43;\n"
|
||||
" bar {\n"
|
||||
" prop3 b;\n"
|
||||
" prop4 zz;\n"
|
||||
" }; #bar\n"
|
||||
const char expected3[] = "foo {\n"
|
||||
" prop1 abuiltin;\n"
|
||||
"}; #foo\n"
|
||||
"baz {\n"
|
||||
" prop5 c;\n"
|
||||
"}; #baz\n"
|
||||
"baz {\n"
|
||||
" prop5 c;\n"
|
||||
"}; #baz\n";
|
||||
|
||||
assert_string_equal(buffer.base, expected4);
|
||||
assert_string_equal(buffer.base, expected3);
|
||||
|
||||
// /*
|
||||
// * let's make a new running dump - foo.prop1 will override the
|
||||
// * builtin value.
|
||||
// */
|
||||
// cfg.dumpmode = ISC_CFGMGR_MODERUNNING;
|
||||
// isc_buffer_init(&buffer, data, sizeof(data));
|
||||
// result = isc_cfgmgr_dump(&cfg);
|
||||
// assert_int_equal(result, ISC_R_SUCCESS);
|
||||
//
|
||||
// isc_buffer_putuint8(&buffer, 0);
|
||||
//
|
||||
// const char expected4[] = "foo {\n"
|
||||
// " prop1 a;\n"
|
||||
// " prop2bis 43;\n"
|
||||
// " bar {\n"
|
||||
// " prop3 b;\n"
|
||||
// " prop4 zz;\n"
|
||||
// " }; #bar\n"
|
||||
// "}; #foo\n"
|
||||
// "baz {\n"
|
||||
// " prop5 c;\n"
|
||||
// "}; #baz\n"
|
||||
// "baz {\n"
|
||||
// " prop5 c;\n"
|
||||
// "}; #baz\n";
|
||||
//
|
||||
// assert_string_equal(buffer.base, expected4);
|
||||
|
||||
/*
|
||||
* And another user only dump, which will be as the first dump (do the
|
||||
* builtin value in foo is ignored)
|
||||
*/
|
||||
cfg.mode = ISC_CFGMGR_DUMPUSER;
|
||||
cfg.dumpmode = ISC_CFGMGR_MODEUSER;
|
||||
isc_buffer_init(&buffer, data, sizeof(data));
|
||||
result = isc_cfgmgr_dump(&cfg);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
@@ -2177,9 +2189,9 @@ ISC_TEST_ENTRY(isc_cfgmgr_nested_clauses)
|
||||
ISC_TEST_ENTRY(isc_cfgmgr_threads)
|
||||
ISC_TEST_ENTRY(isc_cfgmgr_parseid)
|
||||
ISC_TEST_ENTRY(isc_cfgmgr_validationtest)
|
||||
ISC_TEST_ENTRY(isc_cfgmgr_getparent)
|
||||
// ISC_TEST_ENTRY(isc_cfgmgr_getparent)
|
||||
ISC_TEST_ENTRY(isc_cfgmgr_opentests)
|
||||
ISC_TEST_ENTRY(isc_cfgmgr_builtintests)
|
||||
// ISC_TEST_ENTRY(isc_cfgmgr_builtintests)
|
||||
ISC_TEST_ENTRY(isc_cfgmgr_dumptests)
|
||||
ISC_TEST_LIST_END
|
||||
ISC_TEST_MAIN
|
||||
|
||||
Reference in New Issue
Block a user