Commit 79ce8609 authored by Witold Krecicki's avatar Witold Krecicki
Browse files

rndc reconfig should not touch already loaded zones, some refactoring of...

rndc reconfig should not touch already loaded zones, some refactoring of dns_{zone,view,zt}_{async,}load
parent c268c47c
......@@ -691,7 +691,7 @@ load_zone(isc_mem_t *mctx, const char *zonename, const char *filename,
if (dochecksrv)
dns_zone_setchecksrv(zone, checksrv);
CHECK(dns_zone_load(zone));
CHECK(dns_zone_load(zone, false));
/*
* When loading map files we can't catch oversize TTLs during
......
......@@ -2608,12 +2608,12 @@ catz_addmodzone_taskaction(isc_task_t *task, isc_event_t *event0) {
* Load the zone from the master file. If this fails, we'll
* need to undo the configuration we've done already.
*/
result = dns_zone_loadnew(zone);
result = dns_zone_load(zone, true);
if (result != ISC_R_SUCCESS) {
dns_db_t *dbp = NULL;
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
"catz: dns_zone_loadnew() failed "
"catz: dns_zone_load() failed "
"with %s; reverting.",
isc_result_totext(result));
......@@ -9209,14 +9209,14 @@ load_zones(named_server_t *server, bool init, bool reconfig) {
view = ISC_LIST_NEXT(view, link))
{
if (view->managed_keys != NULL) {
result = dns_zone_load(view->managed_keys);
result = dns_zone_load(view->managed_keys, false);
if (result != ISC_R_SUCCESS &&
result != DNS_R_UPTODATE &&
result != DNS_R_CONTINUE)
goto cleanup;
}
if (view->redirect != NULL) {
result = dns_zone_load(view->redirect);
result = dns_zone_load(view->redirect, false);
if (result != ISC_R_SUCCESS &&
result != DNS_R_UPTODATE &&
result != DNS_R_CONTINUE)
......@@ -9228,7 +9228,7 @@ load_zones(named_server_t *server, bool init, bool reconfig) {
* zones.
*/
isc_refcount_increment(&zl->refs);
CHECK(dns_view_asyncload(view, view_loaded, zl));
CHECK(dns_view_asyncload(view, reconfig, view_loaded, zl));
}
cleanup:
......@@ -10124,7 +10124,7 @@ named_server_reloadcommand(named_server_t *server, isc_lex_t *lex,
dns_zone_detach(&zone);
msg = "zone refresh queued";
} else {
result = dns_zone_load(zone);
result = dns_zone_load(zone, false);
dns_zone_detach(&zone);
switch (result) {
case ISC_R_SUCCESS:
......@@ -12778,7 +12778,7 @@ do_addzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
* Load the zone from the master file. If this fails, we'll
* need to undo the configuration we've done already.
*/
result = dns_zone_loadnew(zone);
result = dns_zone_load(zone, true);
if (result != ISC_R_SUCCESS) {
dns_db_t *dbp = NULL;
......@@ -12968,7 +12968,7 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
}
/* Load the zone from the master file if it needs reloading. */
result = dns_zone_loadnew(zone);
result = dns_zone_load(zone, true);
/*
* Dynamic zones need no reloading, so we can pass this result.
......
......@@ -122,7 +122,7 @@ setup(const char *zonename, const char *filename, const char *classname) {
if (zonetype == dns_zone_slave)
dns_zone_setmasters(zone, &addr, 1);
result = dns_zone_load(zone);
result = dns_zone_load(zone, false);
ERRRET(result, "dns_zone_load");
result = dns_zonemgr_managezone(zonemgr, zone);
......
......@@ -151,7 +151,7 @@ load_zone(dns_zone_t *zone) {
bool zone_dynamic;
uint32_t serial;
result = dns_zone_load(zone);
result = dns_zone_load(zone, false);
if (result != ISC_R_SUCCESS && result != DNS_R_UPTODATE
&& result != DNS_R_DYNAMIC && result != DNS_R_CONTINUE)
goto cleanup;
......
......@@ -798,18 +798,15 @@ dns_view_findzone(dns_view_t *view, const dns_name_t *name,
*/
isc_result_t
dns_view_load(dns_view_t *view, bool stop);
dns_view_load(dns_view_t *view, bool stop, bool newonly);
isc_result_t
dns_view_loadnew(dns_view_t *view, bool stop);
isc_result_t
dns_view_asyncload(dns_view_t *view, dns_zt_allloaded_t callback, void *arg);
dns_view_asyncload(dns_view_t *view, bool newonly, dns_zt_allloaded_t callback,
void *arg);
/*%<
* Load zones attached to this view. dns_view_load() loads
* all zones whose master file has changed since the last
* load; dns_view_loadnew() loads only zones that have never
* been loaded.
* load
*
* dns_view_asyncload() loads zones asynchronously. When all zones
* in the view have finished loading, 'callback' is called with argument
......@@ -818,6 +815,8 @@ dns_view_asyncload(dns_view_t *view, dns_zt_allloaded_t callback, void *arg);
* If 'stop' is true, stop on the first error and return it.
* If 'stop' is false (or we are loading asynchronously), ignore errors.
*
* If 'newonly' is true load only zones that were never loaded.
*
* Requires:
*
*\li 'view' is valid.
......
......@@ -338,10 +338,7 @@ dns_zone_getmaxttl(dns_zone_t *zone);
*/
isc_result_t
dns_zone_load(dns_zone_t *zone);
isc_result_t
dns_zone_loadnew(dns_zone_t *zone);
dns_zone_load(dns_zone_t *zone, bool newonly);
isc_result_t
dns_zone_loadandthaw(dns_zone_t *zone);
......@@ -351,9 +348,7 @@ dns_zone_loadandthaw(dns_zone_t *zone);
* Confirm that the minimum requirements for the zone type are
* met, otherwise DNS_R_BADZONE is returned.
*
* dns_zone_loadnew() only loads zones that are not yet loaded.
* dns_zone_load() also loads zones that are already loaded and
* and whose master file has changed since the last load.
* If newonly is set dns_zone_load() only loads new zones.
* dns_zone_loadandthaw() is similar to dns_zone_load() but will
* also re-enable DNS UPDATEs when the load completes.
*
......@@ -371,7 +366,8 @@ dns_zone_loadandthaw(dns_zone_t *zone);
*/
isc_result_t
dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg);
dns_zone_asyncload(dns_zone_t *zone, bool newonly,
dns_zt_zoneloaded_t done, void *arg);
/*%<
* Cause the database to be loaded from its backing store asynchronously.
* Other zone maintenance functions are suspended until this is complete.
......
......@@ -141,21 +141,17 @@ dns_zt_attach(dns_zt_t *zt, dns_zt_t **ztp);
*/
isc_result_t
dns_zt_load(dns_zt_t *zt, bool stop);
dns_zt_load(dns_zt_t *zt, bool stop, bool newonly);
isc_result_t
dns_zt_loadnew(dns_zt_t *zt, bool stop);
isc_result_t
dns_zt_asyncload(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg);
dns_zt_asyncload(dns_zt_t *zt, bool newonly, dns_zt_allloaded_t alldone,
void *arg);
/*%<
* Load all zones in the table. If 'stop' is true,
* stop on the first error and return it. If 'stop'
* is false, ignore errors.
*
* dns_zt_loadnew() only loads zones that are not yet loaded.
* dns_zt_load() also loads zones that are already loaded and
* and whose master file has changed since the last load.
* if newonly is set only zones that were never loaded are loaded.
* dns_zt_asyncload() loads zones asynchronously; when all
* zones in the zone table have finished loaded (or failed due
* to errors), the caller is informed by calling 'alldone'
......
......@@ -593,7 +593,7 @@ get_entry(dns_rrl_t *rrl, const isc_sockaddr_t *client_addr,
static void
debit_log(const dns_rrl_entry_t *e, int age, const char *action) {
char buf[sizeof("age=12345678")];
char buf[sizeof("age=2147483647")];
const char *age_str;
if (age == DNS_RRL_FOREVER) {
......
......@@ -34,6 +34,7 @@
struct args {
void *arg1;
void *arg2;
bool arg3;
};
/*
......@@ -77,7 +78,7 @@ start_zt_asyncload(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
dns_zt_asyncload(args->arg1, all_done, args->arg2);
dns_zt_asyncload(args->arg1, false, all_done, args->arg2);
isc_event_free(&event);
}
......@@ -88,7 +89,7 @@ start_zone_asyncload(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
dns_zone_asyncload(args->arg1, load_done, args->arg2);
dns_zone_asyncload(args->arg1, args->arg3, load_done, args->arg2);
isc_event_free(&event);
}
......@@ -117,8 +118,8 @@ ATF_TC_BODY(apply, tc) {
ATF_REQUIRE(view->zonetable != NULL);
ATF_CHECK_EQ(0, nzones);
result = dns_zt_apply(view->zonetable, false, NULL, count_zone,
&nzones);
result = dns_zt_apply(view->zonetable, false, NULL,
count_zone, &nzones);
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
ATF_CHECK_EQ(1, nzones);
......@@ -143,9 +144,12 @@ ATF_TC_HEAD(asyncload_zone, tc) {
}
ATF_TC_BODY(asyncload_zone, tc) {
isc_result_t result;
int n;
dns_zone_t *zone = NULL;
dns_view_t *view = NULL;
dns_db_t *db = NULL;
FILE* zonefile, *origfile;
char buf[4096];
bool done = false;
int i = 0;
struct args args;
......@@ -168,21 +172,67 @@ ATF_TC_BODY(asyncload_zone, tc) {
ATF_CHECK(!dns__zone_loadpending(zone));
ATF_CHECK(!done);
dns_zone_setfile(zone, "testdata/zt/zone1.db", dns_masterformat_text,
&dns_master_style_default);
zonefile = fopen("./zone.data", "wb");
ATF_CHECK(zonefile != NULL);
origfile = fopen("./testdata/zt/zone1.db", "r+b");
ATF_CHECK(origfile != NULL);
n = fread(buf, 1, 4096, origfile);
fwrite(buf, 1, n, zonefile);
fflush(zonefile);
dns_zone_setfile(zone, "./zone.data",
dns_masterformat_text, &dns_master_style_default);
args.arg1 = zone;
args.arg2 = &done;
args.arg3 = false;
isc_app_onrun(mctx, maintask, start_zone_asyncload, &args);
isc_app_run();
while (dns__zone_loadpending(zone) && i++ < 5000)
dns_test_nap(1000);
ATF_CHECK(done);
/* The zone should now be loaded; test it */
result = dns_zone_getdb(zone, &db);
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
dns_db_detach(&db);
/*
* Add something to zone file, reload zone with newonly - it should
* not be reloaded.
*/
fprintf(zonefile, "\nb in b 1.2.3.4\n");
fflush(zonefile);
args.arg1 = zone;
args.arg2 = &done;
args.arg3 = true;
isc_app_onrun(mctx, maintask, start_zone_asyncload, &args);
isc_app_run();
while (dns__zone_loadpending(zone) && i++ < 5000)
dns_test_nap(1000);
ATF_CHECK(done);
/* The zone should now be loaded; test it */
result = dns_zone_getdb(zone, &db);
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
dns_db_detach(&db);
/* Now reload it without newonly - it should be reloaded */
args.arg1 = zone;
args.arg2 = &done;
args.arg3 = false;
isc_app_onrun(mctx, maintask, start_zone_asyncload, &args);
isc_app_run();
while (dns__zone_loadpending(zone) && i++ < 5000)
dns_test_nap(1000);
ATF_CHECK(done);
/* The zone should now be loaded; test it */
result = dns_zone_getdb(zone, &db);
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
ATF_CHECK(db != NULL);
if (db != NULL)
dns_db_detach(&db);
......@@ -204,7 +254,7 @@ ATF_TC_BODY(asyncload_zt, tc) {
isc_result_t result;
dns_zone_t *zone1 = NULL, *zone2 = NULL, *zone3 = NULL;
dns_view_t *view;
dns_zt_t *zt;
dns_zt_t *zt = NULL;
dns_db_t *db = NULL;
bool done = false;
int i = 0;
......
......@@ -1520,29 +1520,21 @@ dns_viewlist_findzone(dns_viewlist_t *list, const dns_name_t *name,
}
isc_result_t
dns_view_load(dns_view_t *view, bool stop) {
dns_view_load(dns_view_t *view, bool stop, bool newonly) {
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(view->zonetable != NULL);
return (dns_zt_load(view->zonetable, stop));
return (dns_zt_load(view->zonetable, stop, newonly));
}
isc_result_t
dns_view_loadnew(dns_view_t *view, bool stop) {
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(view->zonetable != NULL);
return (dns_zt_loadnew(view->zonetable, stop));
}
isc_result_t
dns_view_asyncload(dns_view_t *view, dns_zt_allloaded_t callback, void *arg) {
dns_view_asyncload(dns_view_t *view, bool newonly,
dns_zt_allloaded_t callback, void *arg) {
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(view->zonetable != NULL);
return (dns_zt_asyncload(view->zonetable, callback, arg));
return (dns_zt_asyncload(view->zonetable, newonly, callback, arg));
}
isc_result_t
......
......@@ -701,6 +701,7 @@ struct dns_keyfetch {
*/
struct dns_asyncload {
dns_zone_t *zone;
unsigned int flags;
dns_zt_zoneloaded_t loaded;
void *loaded_arg;
};
......@@ -2156,13 +2157,8 @@ zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
}
isc_result_t
dns_zone_load(dns_zone_t *zone) {
return (zone_load(zone, 0, false));
}
isc_result_t
dns_zone_loadnew(dns_zone_t *zone) {
return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT, false));
dns_zone_load(dns_zone_t *zone, bool newonly) {
return (zone_load(zone, newonly ? DNS_ZONELOADFLAG_NOSTAT : 0, false));
}
static void
......@@ -2178,7 +2174,7 @@ zone_asyncload(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event);
LOCK_ZONE(zone);
result = zone_load(zone, 0, true);
result = zone_load(zone, asl->flags, true);
if (result != DNS_R_CONTINUE) {
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
}
......@@ -2193,7 +2189,9 @@ zone_asyncload(isc_task_t *task, isc_event_t *event) {
}
isc_result_t
dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg) {
dns_zone_asyncload(dns_zone_t *zone, bool newonly,
dns_zt_zoneloaded_t done, void *arg)
{
isc_event_t *e;
dns_asyncload_t *asl = NULL;
isc_result_t result = ISC_R_SUCCESS;
......@@ -2215,6 +2213,7 @@ dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg) {
CHECK(ISC_R_NOMEMORY);
asl->zone = NULL;
asl->flags = newonly ? DNS_ZONELOADFLAG_NOSTAT : 0;
asl->loaded = done;
asl->loaded_arg = arg;
......
......@@ -33,6 +33,11 @@
#include <dns/zone.h>
#include <dns/zt.h>
struct zt_load_params {
dns_zt_zoneloaded_t dl;
bool newonly;
};
struct dns_zt {
/* Unlocked. */
unsigned int magic;
......@@ -41,6 +46,7 @@ struct dns_zt {
isc_rwlock_t rwlock;
dns_zt_allloaded_t loaddone;
void * loaddone_arg;
struct zt_load_params *loadparams;
/* Locked by lock. */
bool flush;
uint32_t references;
......@@ -51,6 +57,7 @@ struct dns_zt {
#define ZTMAGIC ISC_MAGIC('Z', 'T', 'b', 'l')
#define VALID_ZT(zt) ISC_MAGIC_VALID(zt, ZTMAGIC)
static void
auto_detach(void *, void *);
......@@ -60,9 +67,6 @@ load(dns_zone_t *zone, void *uap);
static isc_result_t
asyncload(dns_zone_t *zone, void *callback);
static isc_result_t
loadnew(dns_zone_t *zone, void *uap);
static isc_result_t
freezezones(dns_zone_t *zone, void *uap);
......@@ -97,6 +101,7 @@ dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **ztp) {
zt->magic = ZTMAGIC;
zt->loaddone = NULL;
zt->loaddone_arg = NULL;
zt->loadparams = NULL;
zt->loads_pending = 0;
*ztp = zt;
......@@ -259,41 +264,45 @@ dns_zt_detach(dns_zt_t **ztp) {
}
isc_result_t
dns_zt_load(dns_zt_t *zt, bool stop) {
dns_zt_load(dns_zt_t *zt, bool stop, bool newonly) {
isc_result_t result;
struct zt_load_params params;
REQUIRE(VALID_ZT(zt));
params.newonly = newonly;
RWLOCK(&zt->rwlock, isc_rwlocktype_read);
result = dns_zt_apply(zt, stop, NULL, load, NULL);
result = dns_zt_apply(zt, stop, NULL, load, &params);
RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
return (result);
}
static isc_result_t
load(dns_zone_t *zone, void *uap) {
load(dns_zone_t *zone, void *paramsv) {
isc_result_t result;
UNUSED(uap);
result = dns_zone_load(zone);
if (result == DNS_R_CONTINUE || result == DNS_R_UPTODATE)
struct zt_load_params *params = (struct zt_load_params*) paramsv;
result = dns_zone_load(zone, params->newonly);
if (result == DNS_R_CONTINUE || result == DNS_R_UPTODATE ||
result == DNS_R_DYNAMIC) {
result = ISC_R_SUCCESS;
}
return (result);
}
isc_result_t
dns_zt_asyncload(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg) {
dns_zt_asyncload(dns_zt_t *zt, bool newonly,
dns_zt_allloaded_t alldone, void *arg) {
isc_result_t result;
static dns_zt_zoneloaded_t dl = doneloading;
int pending;
REQUIRE(VALID_ZT(zt));
zt->loadparams = isc_mem_get(zt->mctx, sizeof(struct zt_load_params));
if (zt->loadparams == NULL) {
return (ISC_R_NOMEMORY);
}
zt->loadparams->dl = doneloading;
zt->loadparams->newonly = newonly;
RWLOCK(&zt->rwlock, isc_rwlocktype_write);
INSIST(zt->loads_pending == 0);
result = dns_zt_apply(zt, false, NULL, asyncload, &dl);
result = dns_zt_apply(zt, false, NULL, asyncload, zt);
pending = zt->loads_pending;
if (pending != 0) {
......@@ -303,8 +312,11 @@ dns_zt_asyncload(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg) {
RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
if (pending == 0)
if (pending == 0) {
isc_mem_put(zt->mctx, zt->loadparams, sizeof(struct zt_load_params));
zt->loadparams = NULL;
alldone(arg);
}
return (result);
}
......@@ -315,20 +327,15 @@ dns_zt_asyncload(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg) {
* the zone loading is complete.
*/
static isc_result_t
asyncload(dns_zone_t *zone, void *callback) {
asyncload(dns_zone_t *zone, void *zt_) {
isc_result_t result;
dns_zt_zoneloaded_t *loaded = callback;
dns_zt_t *zt;
struct dns_zt *zt = (dns_zt_t*) zt_;
REQUIRE(zone != NULL);
zt = dns_zone_getview(zone)->zonetable;
INSIST(VALID_ZT(zt));
INSIST(zt->references > 0);
zt->references++;
zt->loads_pending++;
result = dns_zone_asyncload(zone, *loaded, zt);
result = dns_zone_asyncload(zone, zt->loadparams->newonly, *zt->loadparams->dl, zt);
if (result != ISC_R_SUCCESS) {
zt->references--;
zt->loads_pending--;
......@@ -337,30 +344,6 @@ asyncload(dns_zone_t *zone, void *callback) {
return (ISC_R_SUCCESS);
}
isc_result_t
dns_zt_loadnew(dns_zt_t *zt, bool stop) {
isc_result_t result;
REQUIRE(VALID_ZT(zt));
RWLOCK(&zt->rwlock, isc_rwlocktype_read);
result = dns_zt_apply(zt, stop, NULL, loadnew, NULL);
RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
return (result);
}
static isc_result_t
loadnew(dns_zone_t *zone, void *uap) {
isc_result_t result;
UNUSED(uap);
result = dns_zone_loadnew(zone);
if (result == DNS_R_CONTINUE || result == DNS_R_UPTODATE ||
result == DNS_R_DYNAMIC)
result = ISC_R_SUCCESS;
return (result);
}
isc_result_t
dns_zt_freezezones(dns_zt_t *zt, bool freeze) {
isc_result_t result, tresult;
......@@ -566,6 +549,8 @@ doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) {
arg = zt->loaddone_arg;
zt->loaddone = NULL;
zt->loaddone_arg = NULL;
isc_mem_put(zt->mctx, zt->loadparams, sizeof(struct zt_load_params));
zt->loadparams = NULL;
}
RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
......
......@@ -453,7 +453,7 @@ ns_test_serve_zone(const char *zonename, const char *filename,
*/
dns_zone_setfile(served_zone, filename, dns_masterformat_text,
&dns_master_style_default);
result = dns_zone_load(served_zone);
result = dns_zone_load(served_zone, false);
if (result != ISC_R_SUCCESS) {
goto release_zone;
}
......
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