mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 05:57:52 +00:00
Move the zone loading to the offloaded threads
Instead of doing incremental zone loading with fixed quantum - 100 loaded lines per event, move the zone loading process to the offloaded libuv threads using isc_work_enqueue() API. This has the advantage that the thread scheduling is given back to the operating system that understands blocking operations, and the zone loading operation doesn't block the networking threads directly.
This commit is contained in:
parent
dcc4c3e3ec
commit
77aeed6231
@ -136,17 +136,17 @@ dns_master_loadbuffer(isc_buffer_t *buffer, dns_name_t *top, dns_name_t *origin,
|
||||
dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx);
|
||||
|
||||
isc_result_t
|
||||
dns_master_loadfileinc(const char *master_file, dns_name_t *top,
|
||||
dns_name_t *origin, dns_rdataclass_t zclass,
|
||||
unsigned int options, uint32_t resign,
|
||||
dns_rdatacallbacks_t *callbacks, isc_loop_t *loop,
|
||||
dns_loaddonefunc_t done, void *done_arg,
|
||||
dns_loadctx_t **ctxp, dns_masterincludecb_t include_cb,
|
||||
void *include_arg, isc_mem_t *mctx,
|
||||
dns_masterformat_t format, uint32_t maxttl);
|
||||
dns_master_loadfileasync(const char *master_file, dns_name_t *top,
|
||||
dns_name_t *origin, dns_rdataclass_t zclass,
|
||||
unsigned int options, uint32_t resign,
|
||||
dns_rdatacallbacks_t *callbacks, isc_loop_t *loop,
|
||||
dns_loaddonefunc_t done, void *done_arg,
|
||||
dns_loadctx_t **ctxp, dns_masterincludecb_t include_cb,
|
||||
void *include_arg, isc_mem_t *mctx,
|
||||
dns_masterformat_t format, uint32_t maxttl);
|
||||
|
||||
/*%<
|
||||
* Loads a RFC1305 master file from a file, stream, or buffer
|
||||
* Loads a RFC1035 master file from a file, stream, or buffer
|
||||
* into rdatasets and then calls 'callbacks->commit' to commit the
|
||||
* rdatasets. Rdata memory belongs to dns_master_load and will be
|
||||
* reused / released when the callback completes. dns_load_master will
|
||||
@ -188,7 +188,6 @@ dns_master_loadfileinc(const char *master_file, dns_name_t *top,
|
||||
*\li DNS_R_NOOWNER failed to specify a ownername.
|
||||
*\li DNS_R_NOTTL failed to specify a ttl.
|
||||
*\li DNS_R_BADCLASS record class did not match zone class.
|
||||
*\li DNS_R_CONTINUE load still in progress (dns_master_loadfileinc() only).
|
||||
*\li Any dns_rdata_fromtext() error code.
|
||||
*\li Any error code from callbacks->commit().
|
||||
*/
|
||||
|
192
lib/dns/master.c
192
lib/dns/master.c
@ -31,6 +31,7 @@
|
||||
#include <isc/stdtime.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/util.h>
|
||||
#include <isc/work.h>
|
||||
|
||||
#include <dns/callbacks.h>
|
||||
#include <dns/events.h>
|
||||
@ -105,7 +106,6 @@ struct dns_loadctx {
|
||||
dns_masterformat_t format;
|
||||
|
||||
dns_rdatacallbacks_t *callbacks;
|
||||
isc_loop_t *loop;
|
||||
dns_loaddonefunc_t done;
|
||||
void *done_arg;
|
||||
|
||||
@ -138,8 +138,6 @@ struct dns_loadctx {
|
||||
dns_masterrawheader_t header;
|
||||
|
||||
/* Which fixed buffers we are using? */
|
||||
unsigned int loop_cnt; /*% records per quantum,
|
||||
* 0 => all. */
|
||||
isc_result_t result;
|
||||
|
||||
/* Atomic */
|
||||
@ -206,9 +204,6 @@ static dns_rdata_t *
|
||||
grow_rdata(int, dns_rdata_t *, int, rdatalist_head_t *, rdatalist_head_t *,
|
||||
isc_mem_t *);
|
||||
|
||||
static void
|
||||
load_quantum(void *arg);
|
||||
|
||||
static void
|
||||
loadctx_destroy(dns_loadctx_t *lctx);
|
||||
|
||||
@ -293,11 +288,10 @@ loadctx_destroy(dns_loadctx_t *lctx);
|
||||
((result != ISC_R_SUCCESS) && (result != ISC_R_IOERROR) && \
|
||||
((lctx)->options & DNS_MASTER_MANYERRORS) != 0)
|
||||
|
||||
#define SETRESULT(lctx, r) \
|
||||
do { \
|
||||
if ((lctx)->result == ISC_R_SUCCESS) \
|
||||
(lctx)->result = r; \
|
||||
} while (0)
|
||||
#define SETRESULT(lctx, r) \
|
||||
if ((lctx)->result == ISC_R_SUCCESS) { \
|
||||
(lctx)->result = r; \
|
||||
}
|
||||
|
||||
#define LOGITFILE(result, filename) \
|
||||
if (result == ISC_R_INVALIDFILE || result == ISC_R_FILENOTFOUND || \
|
||||
@ -453,14 +447,10 @@ loadctx_destroy(dns_loadctx_t *lctx) {
|
||||
isc_lex_destroy(&lctx->lex);
|
||||
}
|
||||
|
||||
if (lctx->loop != NULL) {
|
||||
isc_loop_detach(&lctx->loop);
|
||||
}
|
||||
|
||||
isc_mem_putanddetach(&lctx->mctx, lctx, sizeof(*lctx));
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
static void
|
||||
incctx_create(isc_mem_t *mctx, dns_name_t *origin, dns_incctx_t **ictxp) {
|
||||
dns_incctx_t *ictx;
|
||||
isc_region_t r;
|
||||
@ -490,20 +480,17 @@ incctx_create(isc_mem_t *mctx, dns_name_t *origin, dns_incctx_t **ictxp) {
|
||||
ictx->origin_changed = true;
|
||||
|
||||
*ictxp = ictx;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
static void
|
||||
loadctx_create(dns_masterformat_t format, isc_mem_t *mctx, unsigned int options,
|
||||
uint32_t resign, dns_name_t *top, dns_rdataclass_t zclass,
|
||||
dns_name_t *origin, dns_rdatacallbacks_t *callbacks,
|
||||
isc_loop_t *loop, dns_loaddonefunc_t done, void *done_arg,
|
||||
dns_loaddonefunc_t done, void *done_arg,
|
||||
dns_masterincludecb_t include_cb, void *include_arg,
|
||||
isc_lex_t *lex, dns_loadctx_t **lctxp) {
|
||||
dns_loadctx_t *lctx = NULL;
|
||||
isc_result_t result;
|
||||
isc_region_t r;
|
||||
isc_lexspecials_t specials;
|
||||
|
||||
REQUIRE(lctxp != NULL && *lctxp == NULL);
|
||||
REQUIRE(callbacks != NULL);
|
||||
@ -513,8 +500,6 @@ loadctx_create(dns_masterformat_t format, isc_mem_t *mctx, unsigned int options,
|
||||
REQUIRE(mctx != NULL);
|
||||
REQUIRE(dns_name_isabsolute(top));
|
||||
REQUIRE(dns_name_isabsolute(origin));
|
||||
REQUIRE((loop == NULL && done == NULL) ||
|
||||
(loop != NULL && done != NULL));
|
||||
|
||||
lctx = isc_mem_get(mctx, sizeof(*lctx));
|
||||
*lctx = (dns_loadctx_t){
|
||||
@ -533,14 +518,9 @@ loadctx_create(dns_masterformat_t format, isc_mem_t *mctx, unsigned int options,
|
||||
.done = done,
|
||||
.callbacks = callbacks,
|
||||
.done_arg = done_arg,
|
||||
.loop_cnt = (done != NULL) ? 100 : 0,
|
||||
|
||||
};
|
||||
|
||||
result = incctx_create(mctx, origin, &lctx->inc);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_ctx;
|
||||
}
|
||||
incctx_create(mctx, origin, &lctx->inc);
|
||||
|
||||
switch (format) {
|
||||
case dns_masterformat_text:
|
||||
@ -559,6 +539,7 @@ loadctx_create(dns_masterformat_t format, isc_mem_t *mctx, unsigned int options,
|
||||
lctx->lex = lex;
|
||||
lctx->keep_lex = true;
|
||||
} else {
|
||||
isc_lexspecials_t specials;
|
||||
lctx->lex = NULL;
|
||||
isc_lex_create(mctx, TOKENSIZ, &lctx->lex);
|
||||
lctx->keep_lex = false;
|
||||
@ -583,20 +564,12 @@ loadctx_create(dns_masterformat_t format, isc_mem_t *mctx, unsigned int options,
|
||||
|
||||
dns_master_initrawheader(&lctx->header);
|
||||
|
||||
if (loop != NULL) {
|
||||
isc_loop_attach(loop, &lctx->loop);
|
||||
}
|
||||
|
||||
isc_refcount_init(&lctx->references, 1); /* Implicit attach. */
|
||||
isc_mem_attach(mctx, &lctx->mctx);
|
||||
|
||||
lctx->magic = DNS_LCTX_MAGIC;
|
||||
*lctxp = lctx;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup_ctx:
|
||||
isc_mem_put(mctx, lctx, sizeof(*lctx));
|
||||
return (result);
|
||||
return;
|
||||
}
|
||||
|
||||
static const char *hex = "0123456789abcdef0123456789ABCDEF";
|
||||
@ -1037,7 +1010,6 @@ load_text(dns_loadctx_t *lctx) {
|
||||
uint32_t ttl_offset = 0;
|
||||
dns_name_t *new_name;
|
||||
bool current_has_delegation = false;
|
||||
bool done = false;
|
||||
bool finish_origin = false;
|
||||
bool finish_include = false;
|
||||
bool read_till_eol = false;
|
||||
@ -1065,7 +1037,6 @@ load_text(dns_loadctx_t *lctx) {
|
||||
unsigned char *target_mem = NULL;
|
||||
int target_size = TSIZ;
|
||||
int new_in_use;
|
||||
unsigned int loop_cnt = 0;
|
||||
isc_mem_t *mctx;
|
||||
dns_rdatacallbacks_t *callbacks;
|
||||
dns_incctx_t *ictx;
|
||||
@ -1109,7 +1080,12 @@ load_text(dns_loadctx_t *lctx) {
|
||||
options |= DNS_RDATA_CHECKMXFAIL;
|
||||
}
|
||||
source = isc_lex_getsourcename(lctx->lex);
|
||||
do {
|
||||
while (true) {
|
||||
if (atomic_load_acquire(&lctx->canceled)) {
|
||||
result = ISC_R_CANCELED;
|
||||
goto log_and_cleanup;
|
||||
}
|
||||
|
||||
initialws = false;
|
||||
line = isc_lex_getsourceline(lctx->lex);
|
||||
GETTOKEN(lctx->lex, ISC_LEXOPT_INITIALWS | ISC_LEXOPT_QSTRING,
|
||||
@ -1134,8 +1110,7 @@ load_text(dns_loadctx_t *lctx) {
|
||||
ictx = lctx->inc;
|
||||
continue;
|
||||
}
|
||||
done = true;
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
if (token.type == isc_tokentype_eol) {
|
||||
@ -1688,7 +1663,7 @@ load_text(dns_loadctx_t *lctx) {
|
||||
SETRESULT(lctx, result);
|
||||
read_till_eol = true;
|
||||
continue;
|
||||
} else if (result != ISC_R_SUCCESS) {
|
||||
} else {
|
||||
goto insist_and_cleanup;
|
||||
}
|
||||
}
|
||||
@ -2097,7 +2072,7 @@ load_text(dns_loadctx_t *lctx) {
|
||||
COMMITALL;
|
||||
}
|
||||
next_line:;
|
||||
} while (!done && (lctx->loop_cnt == 0 || loop_cnt++ < lctx->loop_cnt));
|
||||
}
|
||||
|
||||
/*
|
||||
* Commit what has not yet been committed.
|
||||
@ -2115,16 +2090,12 @@ load_text(dns_loadctx_t *lctx) {
|
||||
SETRESULT(lctx, result);
|
||||
} else if (result != ISC_R_SUCCESS) {
|
||||
goto insist_and_cleanup;
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
INSIST(lctx->done != NULL && lctx->loop != NULL);
|
||||
result = DNS_R_CONTINUE;
|
||||
} else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) {
|
||||
} else if (lctx->result != ISC_R_SUCCESS) {
|
||||
result = lctx->result;
|
||||
} else if (result == ISC_R_SUCCESS && lctx->seen_include) {
|
||||
} else if (lctx->seen_include) {
|
||||
result = DNS_R_SEENINCLUDE;
|
||||
}
|
||||
|
||||
goto cleanup;
|
||||
|
||||
log_and_cleanup:
|
||||
@ -2165,6 +2136,7 @@ cleanup:
|
||||
if (rhs != NULL) {
|
||||
isc_mem_free(mctx, rhs);
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
@ -2181,10 +2153,7 @@ pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx) {
|
||||
ictx = lctx->inc;
|
||||
lctx->seen_include = true;
|
||||
|
||||
result = incctx_create(lctx->mctx, origin, &newctx);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
incctx_create(lctx->mctx, origin, &newctx);
|
||||
|
||||
/*
|
||||
* Push origin_changed.
|
||||
@ -2341,8 +2310,6 @@ openfile_raw(dns_loadctx_t *lctx, const char *master_file) {
|
||||
static isc_result_t
|
||||
load_raw(dns_loadctx_t *lctx) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
bool done = false;
|
||||
unsigned int loop_cnt = 0;
|
||||
dns_rdatacallbacks_t *callbacks;
|
||||
unsigned char namebuf[DNS_NAME_MAXWIRE];
|
||||
dns_fixedname_t fixed;
|
||||
@ -2387,9 +2354,7 @@ load_raw(dns_loadctx_t *lctx) {
|
||||
* in this format, and so trying to continue parsing erroneous data
|
||||
* does not really make sense.
|
||||
*/
|
||||
for (loop_cnt = 0; (lctx->loop_cnt == 0 || loop_cnt < lctx->loop_cnt);
|
||||
loop_cnt++)
|
||||
{
|
||||
while (true) {
|
||||
unsigned int i, rdcount;
|
||||
uint16_t namelen;
|
||||
uint32_t totallen;
|
||||
@ -2403,7 +2368,6 @@ load_raw(dns_loadctx_t *lctx) {
|
||||
lctx->f, NULL);
|
||||
if (result == ISC_R_EOF) {
|
||||
result = ISC_R_SUCCESS;
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
@ -2612,10 +2576,7 @@ load_raw(dns_loadctx_t *lctx) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
INSIST(lctx->done != NULL && lctx->loop != NULL);
|
||||
result = DNS_R_CONTINUE;
|
||||
} else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) {
|
||||
if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) {
|
||||
result = lctx->result;
|
||||
}
|
||||
|
||||
@ -2630,7 +2591,7 @@ cleanup:
|
||||
if (target_mem != NULL) {
|
||||
isc_mem_put(mctx, target_mem, target_size);
|
||||
}
|
||||
if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE) {
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
(*callbacks->error)(callbacks, "dns_master_load: %s",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
@ -2649,12 +2610,9 @@ dns_master_loadfile(const char *master_file, dns_name_t *top,
|
||||
dns_loadctx_t *lctx = NULL;
|
||||
isc_result_t result;
|
||||
|
||||
result = loadctx_create(format, mctx, options, resign, top, zclass,
|
||||
origin, callbacks, NULL, NULL, NULL, include_cb,
|
||||
include_arg, NULL, &lctx);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
loadctx_create(format, mctx, options, resign, top, zclass, origin,
|
||||
callbacks, NULL, NULL, include_cb, include_arg, NULL,
|
||||
&lctx);
|
||||
|
||||
lctx->maxttl = maxttl;
|
||||
|
||||
@ -2671,27 +2629,39 @@ cleanup:
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
load(void *arg) {
|
||||
dns_loadctx_t *lctx = arg;
|
||||
lctx->result = (lctx->load)(lctx);
|
||||
}
|
||||
|
||||
static void
|
||||
load_done(void *arg) {
|
||||
dns_loadctx_t *lctx = arg;
|
||||
|
||||
(lctx->done)(lctx->done_arg, lctx->result);
|
||||
dns_loadctx_detach(&lctx);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_master_loadfileinc(const char *master_file, dns_name_t *top,
|
||||
dns_name_t *origin, dns_rdataclass_t zclass,
|
||||
unsigned int options, uint32_t resign,
|
||||
dns_rdatacallbacks_t *callbacks, isc_loop_t *loop,
|
||||
dns_loaddonefunc_t done, void *done_arg,
|
||||
dns_loadctx_t **lctxp, dns_masterincludecb_t include_cb,
|
||||
void *include_arg, isc_mem_t *mctx,
|
||||
dns_masterformat_t format, uint32_t maxttl) {
|
||||
dns_master_loadfileasync(const char *master_file, dns_name_t *top,
|
||||
dns_name_t *origin, dns_rdataclass_t zclass,
|
||||
unsigned int options, uint32_t resign,
|
||||
dns_rdatacallbacks_t *callbacks, isc_loop_t *loop,
|
||||
dns_loaddonefunc_t done, void *done_arg,
|
||||
dns_loadctx_t **lctxp,
|
||||
dns_masterincludecb_t include_cb, void *include_arg,
|
||||
isc_mem_t *mctx, dns_masterformat_t format,
|
||||
uint32_t maxttl) {
|
||||
dns_loadctx_t *lctx = NULL;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(loop != NULL);
|
||||
REQUIRE(done != NULL);
|
||||
|
||||
result = loadctx_create(format, mctx, options, resign, top, zclass,
|
||||
origin, callbacks, loop, done, done_arg,
|
||||
include_cb, include_arg, NULL, &lctx);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
loadctx_create(format, mctx, options, resign, top, zclass, origin,
|
||||
callbacks, done, done_arg, include_cb, include_arg, NULL,
|
||||
&lctx);
|
||||
|
||||
lctx->maxttl = maxttl;
|
||||
|
||||
@ -2701,9 +2671,10 @@ dns_master_loadfileinc(const char *master_file, dns_name_t *top,
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_async_run(loop, load_quantum, lctx);
|
||||
dns_loadctx_attach(lctx, lctxp);
|
||||
return (DNS_R_CONTINUE);
|
||||
isc_work_enqueue(loop, load, load_done, lctx);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
@ -2715,26 +2686,19 @@ dns_master_loadstream(FILE *stream, dns_name_t *top, dns_name_t *origin,
|
||||
|
||||
REQUIRE(stream != NULL);
|
||||
|
||||
result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
|
||||
zclass, origin, callbacks, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, &lctx);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
loadctx_create(dns_masterformat_text, mctx, options, 0, top, zclass,
|
||||
origin, callbacks, NULL, NULL, NULL, NULL, NULL, &lctx);
|
||||
|
||||
result = isc_lex_openstream(lctx->lex, stream);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_loadctx_detach(&lctx);
|
||||
return (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = (lctx->load)(lctx);
|
||||
INSIST(result != DNS_R_CONTINUE);
|
||||
|
||||
cleanup:
|
||||
if (lctx != NULL) {
|
||||
dns_loadctx_detach(&lctx);
|
||||
}
|
||||
dns_loadctx_detach(&lctx);
|
||||
return (result);
|
||||
}
|
||||
|
||||
@ -2747,12 +2711,8 @@ dns_master_loadbuffer(isc_buffer_t *buffer, dns_name_t *top, dns_name_t *origin,
|
||||
|
||||
REQUIRE(buffer != NULL);
|
||||
|
||||
result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
|
||||
zclass, origin, callbacks, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, &lctx);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
loadctx_create(dns_masterformat_text, mctx, options, 0, top, zclass,
|
||||
origin, callbacks, NULL, NULL, NULL, NULL, NULL, &lctx);
|
||||
|
||||
result = isc_lex_openbuffer(lctx->lex, buffer);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
@ -3011,26 +2971,6 @@ is_glue(rdatalist_head_t *head, dns_name_t *owner) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
static void
|
||||
load_quantum(void *arg) {
|
||||
isc_result_t result;
|
||||
dns_loadctx_t *lctx = (dns_loadctx_t *)arg;
|
||||
|
||||
REQUIRE(DNS_LCTX_VALID(lctx));
|
||||
|
||||
if (atomic_load_acquire(&lctx->canceled)) {
|
||||
result = ISC_R_CANCELED;
|
||||
} else {
|
||||
result = (lctx->load)(lctx);
|
||||
}
|
||||
if (result == DNS_R_CONTINUE) {
|
||||
isc_async_run(lctx->loop, load_quantum, lctx);
|
||||
} else {
|
||||
(lctx->done)(lctx->done_arg, result);
|
||||
dns_loadctx_detach(&lctx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dns_loadctx_cancel(dns_loadctx_t *lctx) {
|
||||
REQUIRE(DNS_LCTX_VALID(lctx));
|
||||
|
@ -2616,19 +2616,17 @@ zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
options = get_primary_options(load->zone);
|
||||
|
||||
result = dns_master_loadfileinc(
|
||||
result = dns_master_loadfileasync(
|
||||
load->zone->masterfile, dns_db_origin(load->db),
|
||||
dns_db_origin(load->db), load->zone->rdclass, options, 0,
|
||||
&load->callbacks, load->zone->loop, zone_loaddone, load,
|
||||
&load->zone->lctx, zone_registerinclude, load->zone,
|
||||
load->zone->mctx, load->zone->masterformat, load->zone->maxttl);
|
||||
if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
|
||||
result != DNS_R_SEENINCLUDE)
|
||||
{
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto fail;
|
||||
}
|
||||
return;
|
||||
|
||||
return;
|
||||
fail:
|
||||
zone_loaddone(load, result);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user