From: Brian Wellington Date: Mon, 4 Dec 2000 18:59:42 +0000 (+0000) Subject: pullup: X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a30c241172e918788522491eb2dfbe3b4ab417d3;p=thirdparty%2Fbind9.git pullup: 589. [bug] The server could deadlock if a zone was updated while being transferred out. --- diff --git a/CHANGES b/CHANGES index 56b874e45b4..98635410557 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,7 @@ + 589. [bug] The server could deadlock if a zone was updated + while being transferred out. + 581. [bug] Log severity was not being correctly processed. [RT #485] diff --git a/bin/named/xfrout.c b/bin/named/xfrout.c index b3e656c12b1..ee823c326ef 100644 --- a/bin/named/xfrout.c +++ b/bin/named/xfrout.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: xfrout.c,v 1.68.2.3 2000/08/22 19:59:44 gson Exp $ */ +/* $Id: xfrout.c,v 1.68.2.4 2000/12/04 18:59:40 bwelling Exp $ */ #include @@ -213,6 +213,11 @@ db_rr_iterator_next(db_rr_iterator_t *it) { return (it->result); } +static void +db_rr_iterator_pause(db_rr_iterator_t *it) { + dns_dbiterator_pause(it->dbit); +} + static void db_rr_iterator_destroy(db_rr_iterator_t *it) { if (dns_rdataset_isassociated(&it->rdataset)) @@ -303,9 +308,15 @@ struct rrstream_methods { dns_name_t **, isc_uint32_t *, dns_rdata_t **); + void (*pause)(rrstream_t *); void (*destroy)(rrstream_t **); }; +static void +rrstream_noop_pause(rrstream_t *rs) { + UNUSED(rs); +} + /**************************************************************************/ /* * An 'ixfr_rrstream_t' is an 'rrstream_t' that returns @@ -396,13 +407,14 @@ ixfr_rrstream_destroy(rrstream_t **rsp) { static rrstream_methods_t ixfr_rrstream_methods = { ixfr_rrstream_first, ixfr_rrstream_next, - ixfr_rrstream_current, + ixfr_rrstream_current, + rrstream_noop_pause, ixfr_rrstream_destroy }; /**************************************************************************/ /* - * An 'ixfr_rrstream_t' is an 'rrstream_t' that returns + * An 'axfr_rrstream_t' is an 'rrstream_t' that returns * an AXFR-like RR stream from a database. * * The SOAs at the beginning and end of the transfer are @@ -412,7 +424,7 @@ static rrstream_methods_t ixfr_rrstream_methods = { typedef struct axfr_rrstream { rrstream_t common; int state; - db_rr_iterator_t it; + db_rr_iterator_t it; isc_boolean_t it_valid; } axfr_rrstream_t; @@ -503,6 +515,12 @@ axfr_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, db_rr_iterator_current(&s->it, name, ttl, rdata); } +static void +axfr_rrstream_pause(rrstream_t *rs) { + axfr_rrstream_t *s = (axfr_rrstream_t *) rs; + db_rr_iterator_pause(&s->it); +} + static void axfr_rrstream_destroy(rrstream_t **rsp) { axfr_rrstream_t *s = (axfr_rrstream_t *) *rsp; @@ -514,7 +532,8 @@ axfr_rrstream_destroy(rrstream_t **rsp) { static rrstream_methods_t axfr_rrstream_methods = { axfr_rrstream_first, axfr_rrstream_next, - axfr_rrstream_current, + axfr_rrstream_current, + axfr_rrstream_pause, axfr_rrstream_destroy }; @@ -597,7 +616,8 @@ soa_rrstream_destroy(rrstream_t **rsp) { static rrstream_methods_t soa_rrstream_methods = { soa_rrstream_first, soa_rrstream_next, - soa_rrstream_current, + soa_rrstream_current, + rrstream_noop_pause, soa_rrstream_destroy }; @@ -685,6 +705,11 @@ compound_rrstream_next(rrstream_t *rs) { rrstream_t *curstream = s->components[s->state]; s->result = curstream->methods->next(curstream); while (s->result == ISC_R_NOMORE) { + /* + * Make sure locks held by the current stream + * are released before we switch streams. + */ + curstream->methods->pause(curstream); if (s->state == 2) return (ISC_R_NOMORE); s->state++; @@ -706,6 +731,16 @@ compound_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, curstream->methods->current(curstream, name, ttl, rdata); } +static void +compound_rrstream_pause(rrstream_t *rs) +{ + compound_rrstream_t *s = (compound_rrstream_t *) rs; + rrstream_t *curstream; + INSIST(0 <= s->state && s->state < 3); + curstream = s->components[s->state]; + curstream->methods->pause(curstream); +} + static void compound_rrstream_destroy(rrstream_t **rsp) { compound_rrstream_t *s = (compound_rrstream_t *) *rsp; @@ -718,7 +753,8 @@ compound_rrstream_destroy(rrstream_t **rsp) { static rrstream_methods_t compound_rrstream_methods = { compound_rrstream_first, compound_rrstream_next, - compound_rrstream_current, + compound_rrstream_current, + compound_rrstream_pause, compound_rrstream_destroy }; @@ -1392,7 +1428,8 @@ sendstream(xfrout_ctx_t *xfr) { msg = NULL; ns_client_send(xfr->client); xfrout_ctx_destroy(&xfr); - return; + result = ISC_R_SUCCESS; + goto done; } /* Advance lasttsig to be the last TSIG generated */ @@ -1407,6 +1444,14 @@ sendstream(xfrout_ctx_t *xfr) { if (msg != NULL) { dns_message_destroy(&msg); } + + done: + /* + * Make sure to release any locks held by database + * iterators before returning from the event handler. + */ + xfr->stream->methods->pause(xfr->stream); + if (result == ISC_R_SUCCESS) return;