]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
pullup:
authorBrian Wellington <source@isc.org>
Mon, 4 Dec 2000 18:59:42 +0000 (18:59 +0000)
committerBrian Wellington <source@isc.org>
Mon, 4 Dec 2000 18:59:42 +0000 (18:59 +0000)
 589.   [bug]           The server could deadlock if a zone was updated
                        while being transferred out.

CHANGES
bin/named/xfrout.c

diff --git a/CHANGES b/CHANGES
index 56b874e45b4c0d016d2ecb4047fa7c2b450bf4aa..98635410557d48fd68a1c5cbbb02f740850e5de8 100644 (file)
--- 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]
 
index b3e656c12b1c91dac0780d4eeacc27d9fe4d3eca..ee823c326ef5586c90f5ff848015487be4f6bfa1 100644 (file)
@@ -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 <config.h>
 
@@ -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;