Materialization of zones
This commit is contained in:
+173
-23
@@ -45,11 +45,44 @@
|
||||
#define NODEINDEXFLG 'i'
|
||||
#define PROPERTYFLG 'p'
|
||||
|
||||
/*
|
||||
* Used to avoid repeated hashing to figure out if we're in those special nodes
|
||||
*
|
||||
* - root options is special as it gets "materialized", if on running mode, from
|
||||
* options node in builtin and user nodes.
|
||||
*
|
||||
* - root views is special as each of each sub-nodes is considered as a view
|
||||
* instance
|
||||
*
|
||||
* - a zones node inside a view instance is special as each sub-node is
|
||||
* considered a zone instance
|
||||
*
|
||||
* - a zone instance gets "materialized" from root options and the view instance
|
||||
* it belongs.
|
||||
*/
|
||||
#define OPTIONS "options"
|
||||
#define VIEWS "views"
|
||||
#define ZONES "zones"
|
||||
|
||||
static uint32_t isc__cfgmgr_hashoptions;
|
||||
static uint32_t isc__cfgmgr_hashviews;
|
||||
static uint32_t isc__cfgmgr_hashzones;
|
||||
|
||||
#define NODE_FLG_OPTIONS 1 << 0
|
||||
#define NODE_FLG_VIEWS 1 << 1
|
||||
#define NODE_FLG_VIEW 1 << 2
|
||||
#define NODE_FLG_ZONES 1 << 3
|
||||
#define NODE_FLG_ZONE 1 << 4
|
||||
|
||||
/*
|
||||
* Defines an opened node.
|
||||
*/
|
||||
typedef struct isc__cfgmgr_node isc__cfgmgr_node_t;
|
||||
struct isc__cfgmgr_node {
|
||||
char *name;
|
||||
char *prefix;
|
||||
uint32_t hash;
|
||||
uint32_t flags;
|
||||
ISC_LINK(isc__cfgmgr_node_t) link;
|
||||
};
|
||||
typedef ISC_LIST(isc__cfgmgr_node_t) isc__cfgmgr_nodes_t;
|
||||
@@ -238,6 +271,10 @@ isc_cfgmgr_init(isc_mem_t *mctx, const char *dbpath) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
isc__cfgmgr_hashoptions = isc_hash32(OPTIONS, strlen(OPTIONS), false);
|
||||
isc__cfgmgr_hashviews = isc_hash32(VIEWS, strlen(VIEWS), false);
|
||||
isc__cfgmgr_hashzones = isc_hash32(ZONES, strlen(ZONES), false);
|
||||
|
||||
goto out;
|
||||
|
||||
cleanup:
|
||||
@@ -452,7 +489,7 @@ isc__cfgmgr_curhash(void) {
|
||||
|
||||
if (node == NULL) {
|
||||
const char *rootprefix = isc__cfgmgr_curprefix();
|
||||
uint64_t roothash = isc_hash64(rootprefix, strlen(rootprefix),
|
||||
uint64_t roothash = isc_hash32(rootprefix, strlen(rootprefix),
|
||||
false);
|
||||
INSIST(roothash > 0);
|
||||
|
||||
@@ -514,6 +551,56 @@ isc__cfgmgr_addindex(MDB_cursor *cursor, const char *name) {
|
||||
REQUIRE(mdb_cursor_put(cursor, &dbkey, &dbval, 0) == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
isc__cfgmgr_setnodeflags(isc__cfgmgr_node_t *node) {
|
||||
isc__cfgmgr_node_t *curnode = isc__cfgmgr_curnode();
|
||||
uint32_t hash = isc_hash32(node->name, strlen(node->name), false);
|
||||
|
||||
/*
|
||||
* At root level, can be options or views special nodes
|
||||
*/
|
||||
if (curnode == NULL) {
|
||||
if (hash == isc__cfgmgr_hashoptions) {
|
||||
node->flags |= NODE_FLG_OPTIONS;
|
||||
} else if (hash == isc__cfgmgr_hashviews) {
|
||||
node->flags |= NODE_FLG_VIEWS;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Inside the views special node, marking the new node as a view
|
||||
* instance.
|
||||
*/
|
||||
else if (curnode->flags & NODE_FLG_VIEWS)
|
||||
{
|
||||
node->flags |= NODE_FLG_VIEW;
|
||||
}
|
||||
|
||||
/*
|
||||
* Knowing that a node is a zone instance doesn't seems needed right
|
||||
* now... I'm leaving the code below for now, just in case, but likely
|
||||
* to be removed later.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Inside a view instance node, looking for the zones special node.
|
||||
*/
|
||||
else if (curnode->flags & NODE_FLG_VIEW &&
|
||||
hash == isc__cfgmgr_hashzones)
|
||||
{
|
||||
node->flags |= NODE_FLG_ZONES;
|
||||
}
|
||||
|
||||
/*
|
||||
* Inside a view zones special instance node, marking the new node as a
|
||||
* zone instance node
|
||||
*/
|
||||
else if (curnode->flags & NODE_FLG_ZONES)
|
||||
{
|
||||
node->flags |= NODE_FLG_ZONE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
isc_cfgmgr_open(const char *name) {
|
||||
isc__cfgmgr_node_t *node = NULL;
|
||||
@@ -526,14 +613,17 @@ isc_cfgmgr_open(const char *name) {
|
||||
.name = isc_mem_allocate(isc__cfgmgr_mctx, strlen(name) + 1),
|
||||
.prefix = isc_mem_get(isc__cfgmgr_mctx, BUFLEN),
|
||||
.link = ISC_LINK_INITIALIZER,
|
||||
.hash = isc_hash64(name, strlen(name), true)
|
||||
};
|
||||
|
||||
strcpy(node->name, name);
|
||||
INSIST(node->hash > 0);
|
||||
REQUIRE(snprintf(node->prefix, BUFLEN, "%s%s/", isc__cfgmgr_curprefix(),
|
||||
name) < BUFLEN);
|
||||
|
||||
node->hash = isc_hash32(node->prefix, strlen(node->prefix), true);
|
||||
INSIST(node->hash > 0);
|
||||
|
||||
isc__cfgmgr_setnodeflags(node);
|
||||
|
||||
if (isc__cfgmgr_ctx.readonly == false) {
|
||||
isc__cfgmgr_addindex(isc__cfgmgr_ctx.builtincursor, name);
|
||||
isc__cfgmgr_addindex(isc__cfgmgr_ctx.usercursor, name);
|
||||
@@ -769,35 +859,95 @@ static isc_result_t
|
||||
isc__cfgmgr_write(MDB_cursor *cursor, const char *name,
|
||||
const isc_cfgmgr_val_t *value, bool materialize);
|
||||
|
||||
typedef struct isc__cfgmgr_materializeprop isc__cfgmgr_materializeprop_t;
|
||||
struct isc__cfgmgr_materializeprop {
|
||||
const char *name;
|
||||
const isc_cfgmgr_val_t *value;
|
||||
};
|
||||
|
||||
static void
|
||||
isc__cfgmgr_materialize(const char *name, const isc_cfgmgr_val_t *value) {
|
||||
isc__cfgmgr_materialize_apply(void *state, const char *nodename) {
|
||||
isc_cfgmgr_mode_t valmode;
|
||||
isc_cfgmgr_val_t val;
|
||||
isc_result_t result;
|
||||
isc__cfgmgr_materializeprop_t *property = state;
|
||||
|
||||
UNUSED(nodename);
|
||||
|
||||
result = isc__cfgmgr_read(isc__cfgmgr_ctx.runningcursor, property->name,
|
||||
&val, &valmode);
|
||||
INSIST(result == ISC_R_NOTFOUND || result == ISC_R_SUCCESS);
|
||||
|
||||
if ((result == ISC_R_NOTFOUND && property->value != NULL) ||
|
||||
(result == ISC_R_SUCCESS && valmode <= isc__cfgmgr_ctx.mode))
|
||||
{
|
||||
REQUIRE(isc__cfgmgr_write(isc__cfgmgr_ctx.runningcursor,
|
||||
property->name, property->value,
|
||||
false) == ISC_R_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
isc__cfgmgr_materialize_foreachview(void *state, const char *nodename) {
|
||||
UNUSED(nodename);
|
||||
|
||||
isc_cfgmgr_open("zones");
|
||||
isc_cfgmgr_foreachnodes(isc__cfgmgr_materialize_apply, state);
|
||||
isc_cfgmgr_close();
|
||||
}
|
||||
|
||||
static void
|
||||
isc__cfgmgr_materialize_zone(isc__cfgmgr_materializeprop_t *property,
|
||||
bool inview) {
|
||||
if (inview) {
|
||||
isc_cfgmgr_open("zones");
|
||||
isc_cfgmgr_foreachnodes(isc__cfgmgr_materialize_apply, property);
|
||||
isc_cfgmgr_close();
|
||||
} else {
|
||||
isc_cfgmgr_open("views");
|
||||
isc_cfgmgr_foreachnodes(isc__cfgmgr_materialize_foreachview,
|
||||
property);
|
||||
isc_cfgmgr_close();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* There is an issue with the materialization on zone: it will copy _all_
|
||||
* options properties/sub-nodes into each zones. While this is not a problem for
|
||||
* reading data (nobody will attempt to read data not expected to be in a zone)
|
||||
* this will be a problem when dumping the zone.
|
||||
*
|
||||
* This is probably something to figure out with the validation of the
|
||||
* configuration, which could be used as a filter in the copy callbacks during
|
||||
* the materialization.
|
||||
*
|
||||
* isc_cfgmgr_delnode doest not supports materialization (i.e. it won't remove
|
||||
* deleted properties if they hasn't been overriden). Not sure the _delnode API
|
||||
* is actually useful. If it is (and we keep it) then it needs to be fixed.
|
||||
*/
|
||||
static void
|
||||
isc__cfgmgr_materialize(const char *name, const isc_cfgmgr_val_t *value) {
|
||||
isc__cfgmgr_node_t *node = isc__cfgmgr_curnode();
|
||||
isc__cfgmgr_materializeprop_t property = { .name = name,
|
||||
.value = value };
|
||||
|
||||
if (isc__cfgmgr_ctx.mode == ISC_CFGMGR_MODERUNNING) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The only nodes which "accepts" materialization
|
||||
* (view/zones cases TBD)
|
||||
* (value == NULL TDB)
|
||||
* (delnode flow TBD)
|
||||
*/
|
||||
if (strcmp(isc__cfgmgr_curprefix(), "/options/") != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
result = isc__cfgmgr_read(isc__cfgmgr_ctx.runningcursor, name, &val,
|
||||
&valmode);
|
||||
INSIST(result == ISC_R_NOTFOUND || result == ISC_R_SUCCESS);
|
||||
|
||||
if (result == ISC_R_NOTFOUND ||
|
||||
(result == ISC_R_SUCCESS && valmode < ISC_CFGMGR_MODERUNNING))
|
||||
{
|
||||
REQUIRE(isc__cfgmgr_write(isc__cfgmgr_ctx.runningcursor, name,
|
||||
value, false) == ISC_R_SUCCESS);
|
||||
if (node->flags & NODE_FLG_OPTIONS) {
|
||||
/*
|
||||
* Materialization of the changed options property in the
|
||||
* running options node as well as all the running zones.
|
||||
*/
|
||||
isc__cfgmgr_materialize_apply(&property, NULL);
|
||||
isc__cfgmgr_materialize_zone(&property, false);
|
||||
} else if (node->flags & NODE_FLG_VIEW) {
|
||||
/*
|
||||
* Materialization of the changed view property in all its
|
||||
* running zones
|
||||
*/
|
||||
isc__cfgmgr_materialize_zone(&property, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+185
-79
@@ -1459,7 +1459,7 @@ struct isc__cfgmgr_dump {
|
||||
size_t indent;
|
||||
size_t lvl;
|
||||
isc_buffer_t buffer;
|
||||
char data[512];
|
||||
char data[1024];
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -1506,6 +1506,21 @@ isc__cfgmgr_dumptestnode(void *state, const char *name) {
|
||||
isc_buffer_putstr(&dump->buffer, " ");
|
||||
}
|
||||
isc_buffer_printf(&dump->buffer, "};\n");
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
cmpdump(isc_cfgmgr_mode_t mode, const char *expected) {
|
||||
isc__cfgmgr_dump_t dump = {
|
||||
.lvl = 0,
|
||||
.indent = 2,
|
||||
};
|
||||
isc_buffer_init(&dump.buffer, dump.data, sizeof(dump.data));
|
||||
dump.data[0] = 0;
|
||||
|
||||
isc_cfgmgr_setmode(mode);
|
||||
isc_cfgmgr_foreachnodes(isc__cfgmgr_dumptestnode, &dump);
|
||||
assert_string_equal(dump.buffer.base, expected);
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(isc_cfgmgr_dumptests) {
|
||||
@@ -1566,41 +1581,32 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_dumptests) {
|
||||
isc_cfgmgr_close(); /* foo1 */
|
||||
isc_cfgmgr_close(); /* foo */
|
||||
|
||||
isc__cfgmgr_dump_t dump = {
|
||||
.lvl = 0,
|
||||
.indent = 8,
|
||||
};
|
||||
isc_buffer_init(&dump.buffer, dump.data, sizeof(dump.data));
|
||||
dump.data[0] = 0;
|
||||
|
||||
isc_cfgmgr_commit();
|
||||
isc_cfgmgr_transaction();
|
||||
|
||||
isc_cfgmgr_foreachnodes(isc__cfgmgr_dumptestnode, &dump);
|
||||
|
||||
const char expected[] = "bar {\n"
|
||||
" another-stuff barstr;\n"
|
||||
" propbar1 42;\n"
|
||||
"};\n"
|
||||
"foo {\n"
|
||||
" foo1 {\n"
|
||||
" foo11 {\n"
|
||||
" fooprop 123;\n"
|
||||
" };\n"
|
||||
" foo12 {\n"
|
||||
" fooprop 456;\n"
|
||||
" prop 123;\n"
|
||||
" };\n"
|
||||
" foo13 {\n"
|
||||
" fooprop 789;\n"
|
||||
" prop 123;\n"
|
||||
" };\n"
|
||||
" };\n"
|
||||
" foo2 {\n"
|
||||
" another-foo-stuff foo2str;\n"
|
||||
" };\n"
|
||||
"};\n";
|
||||
assert_string_equal(dump.buffer.base, expected);
|
||||
cmpdump(ISC_CFGMGR_MODERUNNING,
|
||||
"bar {\n"
|
||||
" another-stuff barstr;\n"
|
||||
" propbar1 42;\n"
|
||||
"};\n"
|
||||
"foo {\n"
|
||||
" foo1 {\n"
|
||||
" foo11 {\n"
|
||||
" fooprop 123;\n"
|
||||
" };\n"
|
||||
" foo12 {\n"
|
||||
" fooprop 456;\n"
|
||||
" prop 123;\n"
|
||||
" };\n"
|
||||
" foo13 {\n"
|
||||
" fooprop 789;\n"
|
||||
" prop 123;\n"
|
||||
" };\n"
|
||||
" };\n"
|
||||
" foo2 {\n"
|
||||
" another-foo-stuff foo2str;\n"
|
||||
" };\n"
|
||||
"};\n");
|
||||
isc_cfgmgr_rollback();
|
||||
|
||||
result = isc_cfgmgr_rwtransaction();
|
||||
@@ -1629,20 +1635,17 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_dumptests) {
|
||||
isc_cfgmgr_close();
|
||||
isc_cfgmgr_close();
|
||||
|
||||
isc_buffer_init(&dump.buffer, dump.data, sizeof(dump.data));
|
||||
isc_cfgmgr_foreachnodes(isc__cfgmgr_dumptestnode, &dump);
|
||||
|
||||
const char expected2[] = "bar {\n"
|
||||
" another-stuff barstr;\n"
|
||||
" propbar1 42;\n"
|
||||
"};\n"
|
||||
"foo {\n"
|
||||
" propfoo 987;\n"
|
||||
" foo14 {\n"
|
||||
" anotherpropfoo14 654;\n"
|
||||
" };\n"
|
||||
"};\n";
|
||||
assert_string_equal(dump.buffer.base, expected2);
|
||||
cmpdump(ISC_CFGMGR_MODERUNNING,
|
||||
"bar {\n"
|
||||
" another-stuff barstr;\n"
|
||||
" propbar1 42;\n"
|
||||
"};\n"
|
||||
"foo {\n"
|
||||
" propfoo 987;\n"
|
||||
" foo14 {\n"
|
||||
" anotherpropfoo14 654;\n"
|
||||
" };\n"
|
||||
"};\n");
|
||||
|
||||
isc_cfgmgr_rollback();
|
||||
isc_cfgmgr_deinit();
|
||||
@@ -1658,6 +1661,38 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_materialization) {
|
||||
result = isc_cfgmgr_rwtransaction();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_cfgmgr_open("views");
|
||||
|
||||
isc_cfgmgr_open("fooview");
|
||||
val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 991 };
|
||||
result = isc_cfgmgr_write("prop2", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_cfgmgr_open("zones");
|
||||
isc_cfgmgr_open("foo.org");
|
||||
val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 661 };
|
||||
result = isc_cfgmgr_write("prop1", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_cfgmgr_close();
|
||||
isc_cfgmgr_close();
|
||||
isc_cfgmgr_close();
|
||||
|
||||
isc_cfgmgr_open("barview");
|
||||
isc_cfgmgr_open("zones");
|
||||
isc_cfgmgr_open("bar.org");
|
||||
val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 662 };
|
||||
result = isc_cfgmgr_write("prop1", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_cfgmgr_close();
|
||||
isc_cfgmgr_open("baz.org");
|
||||
val = (isc_cfgmgr_val_t){ .type = ISC_CFGMGR_UINT32, .uint32 = 663 };
|
||||
result = isc_cfgmgr_write("prop1", &val);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_cfgmgr_close();
|
||||
isc_cfgmgr_close();
|
||||
isc_cfgmgr_close();
|
||||
|
||||
isc_cfgmgr_close(); /* views */
|
||||
|
||||
isc_cfgmgr_open("options");
|
||||
|
||||
isc_cfgmgr_setmode(ISC_CFGMGR_MODERUNNING);
|
||||
@@ -1690,44 +1725,115 @@ ISC_RUN_TEST_IMPL(isc_cfgmgr_materialization) {
|
||||
|
||||
isc_cfgmgr_close();
|
||||
|
||||
isc__cfgmgr_dump_t dump = {
|
||||
.lvl = 0,
|
||||
.indent = 8,
|
||||
};
|
||||
isc_buffer_init(&dump.buffer, dump.data, sizeof(dump.data));
|
||||
dump.data[0] = 0;
|
||||
cmpdump(ISC_CFGMGR_MODEBUILTIN, "options {\n"
|
||||
" prop1 1;\n"
|
||||
" prop2 2;\n"
|
||||
" prop3 3;\n"
|
||||
"};\n");
|
||||
|
||||
isc_cfgmgr_setmode(ISC_CFGMGR_MODEBUILTIN);
|
||||
isc_cfgmgr_foreachnodes(isc__cfgmgr_dumptestnode, &dump);
|
||||
const char expectedbuiltin[] = "options {\n"
|
||||
" prop1 1;\n"
|
||||
" prop2 2;\n"
|
||||
" prop3 3;\n"
|
||||
"};\n";
|
||||
assert_string_equal(dump.buffer.base, expectedbuiltin);
|
||||
cmpdump(ISC_CFGMGR_MODEUSER, "options {\n"
|
||||
" prop2 21;\n"
|
||||
"};\n");
|
||||
|
||||
isc_cfgmgr_setmode(ISC_CFGMGR_MODEUSER);
|
||||
isc_buffer_init(&dump.buffer, dump.data, sizeof(dump.data));
|
||||
isc_cfgmgr_foreachnodes(isc__cfgmgr_dumptestnode, &dump);
|
||||
const char expecteduser[] = "options {\n"
|
||||
" prop2 21;\n"
|
||||
"};\n";
|
||||
assert_string_equal(dump.buffer.base, expecteduser);
|
||||
|
||||
isc_cfgmgr_setmode(ISC_CFGMGR_MODERUNNING);
|
||||
isc_buffer_init(&dump.buffer, dump.data, sizeof(dump.data));
|
||||
isc_cfgmgr_foreachnodes(isc__cfgmgr_dumptestnode, &dump);
|
||||
const char expectedrunning[] = "options {\n"
|
||||
" prop1 31;\n"
|
||||
" prop2 21;\n"
|
||||
" prop3 3;\n"
|
||||
" prop4 34;\n"
|
||||
"};\n";
|
||||
assert_string_equal(dump.buffer.base, expectedrunning);
|
||||
cmpdump(ISC_CFGMGR_MODERUNNING, "options {\n"
|
||||
" prop1 31;\n"
|
||||
" prop2 21;\n"
|
||||
" prop3 3;\n"
|
||||
" prop4 34;\n"
|
||||
"};\n"
|
||||
"views {\n"
|
||||
" barview {\n"
|
||||
" zones {\n"
|
||||
" bar.org {\n"
|
||||
" prop1 662;\n"
|
||||
" prop2 21;\n"
|
||||
" prop3 3;\n"
|
||||
" prop4 34;\n"
|
||||
" };\n"
|
||||
" baz.org {\n"
|
||||
" prop1 663;\n"
|
||||
" prop2 21;\n"
|
||||
" prop3 3;\n"
|
||||
" prop4 34;\n"
|
||||
" };\n"
|
||||
" };\n"
|
||||
" };\n"
|
||||
" fooview {\n"
|
||||
" prop2 991;\n"
|
||||
" zones {\n"
|
||||
" foo.org {\n"
|
||||
" prop1 661;\n"
|
||||
" prop2 991;\n"
|
||||
" prop3 3;\n"
|
||||
" prop4 34;\n"
|
||||
" };\n"
|
||||
" };\n"
|
||||
" };\n"
|
||||
"};\n");
|
||||
|
||||
result = isc_cfgmgr_commit();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* deleting prop3 and prop2 from builtin: only prop3 will be removed
|
||||
* from options, as it's unmodified.
|
||||
*/
|
||||
result = isc_cfgmgr_rwtransaction();
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_cfgmgr_setmode(ISC_CFGMGR_MODEBUILTIN);
|
||||
isc_cfgmgr_open("options");
|
||||
|
||||
result = isc_cfgmgr_write("prop2", NULL);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_cfgmgr_write("prop3", NULL);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_cfgmgr_close();
|
||||
|
||||
cmpdump(ISC_CFGMGR_MODEBUILTIN, "options {\n"
|
||||
" prop1 1;\n"
|
||||
"};\n");
|
||||
|
||||
cmpdump(ISC_CFGMGR_MODEUSER, "options {\n"
|
||||
" prop2 21;\n"
|
||||
"};\n");
|
||||
|
||||
cmpdump(ISC_CFGMGR_MODERUNNING, "options {\n"
|
||||
" prop1 31;\n"
|
||||
" prop2 21;\n"
|
||||
" prop4 34;\n"
|
||||
"};\n"
|
||||
"views {\n"
|
||||
" barview {\n"
|
||||
" zones {\n"
|
||||
" bar.org {\n"
|
||||
" prop1 662;\n"
|
||||
" };\n"
|
||||
" baz.org {\n"
|
||||
" prop1 663;\n"
|
||||
" };\n"
|
||||
" };\n"
|
||||
" };\n"
|
||||
" fooview {\n"
|
||||
" prop2 991;\n"
|
||||
" zones {\n"
|
||||
" foo.org {\n"
|
||||
" prop1 661;\n"
|
||||
" };\n"
|
||||
" };\n"
|
||||
" };\n"
|
||||
"};\n");
|
||||
|
||||
isc_cfgmgr_rollback();
|
||||
|
||||
/*
|
||||
* TODO
|
||||
* Then a zone is added _after_ all of those options changes. It must
|
||||
* contains all of those as well
|
||||
*/
|
||||
|
||||
isc_cfgmgr_deinit();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user