]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Dump the fetches from dns_resolver_dumpfetches()
authorOndřej Surý <ondrej@isc.org>
Mon, 17 Feb 2025 13:58:28 +0000 (14:58 +0100)
committerOndřej Surý <ondrej@isc.org>
Fri, 21 Feb 2025 21:25:43 +0000 (22:25 +0100)
Previously, the dns_resolver_dumpfetches() would go over the fetch
counters.  Alas, because of the earlier optimization, the fetch counters
would be increased only when fetches-per-zone was not 0, otherwise the
whole counting was skipped for performance reasons.

Instead of using the auxiliary fetch counters hash table, use the real
hash table that stores the fetch contexts to dump the ongoing fetches to
the recursing file.

Additionally print more information about the fetch context like start
and expiry times, number of fetch responses, number of queries and count
of allowed and dropped fetches.

lib/dns/resolver.c

index 37d3ddb2bf15b2c1d855a35f66637bbc0e980662..f12d6ef508eb6ba06bc2442265b4cfd851515987 100644 (file)
@@ -16,6 +16,7 @@
 #include <ctype.h>
 #include <inttypes.h>
 #include <stdbool.h>
+#include <stdint.h>
 
 #include <isc/ascii.h>
 #include <isc/async.h>
@@ -352,6 +353,8 @@ struct fetchctx {
        fetchstate_t state;
        bool cloned;
        bool spilled;
+       uint_fast32_t allowed;
+       uint_fast32_t dropped;
        ISC_LIST(dns_fetchresponse_t) resps;
 
        /*% Locked by loop event serialization. */
@@ -10541,6 +10544,7 @@ dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name,
                        }
                        if (fctx->spilled) {
                                inc_stats(res, dns_resstatscounter_clientquota);
+                               fctx->dropped++;
                                result = DNS_R_DROP;
                                goto unlock;
                        }
@@ -10560,6 +10564,8 @@ dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name,
                fctx->depth = depth;
        }
 
+       fctx->allowed++;
+
        fctx_join(fctx, loop, client, id, cb, arg, edectx, rdataset,
                  sigrdataset, fetch);
 
@@ -10927,22 +10933,68 @@ dns_resolver_dumpfetches(dns_resolver_t *res, isc_statsformat_t format,
        REQUIRE(fp != NULL);
        REQUIRE(format == isc_statsformat_file);
 
-       RWLOCK(&res->counters_lock, isc_rwlocktype_read);
-       isc_hashmap_iter_create(res->counters, &it);
+       LOCK(&res->lock);
+       fprintf(fp, "clients-per-query: %u/%u/%u\n", res->spillatmin,
+               res->spillat, res->spillatmax);
+       UNLOCK(&res->lock);
+
+       RWLOCK(&res->fctxs_lock, isc_rwlocktype_read);
+       isc_hashmap_iter_create(res->fctxs, &it);
        for (result = isc_hashmap_iter_first(it); result == ISC_R_SUCCESS;
             result = isc_hashmap_iter_next(it))
        {
-               fctxcount_t *counter = NULL;
-               isc_hashmap_iter_current(it, (void **)&counter);
+               char typebuf[DNS_RDATATYPE_FORMATSIZE];
+               char timebuf[1024];
+               fetchctx_t *fctx = NULL;
+               dns_fetchresponse_t *resp = NULL;
+               resquery_t *query = NULL;
+               unsigned int resp_count = 0, query_count = 0;
+
+               isc_hashmap_iter_current(it, (void **)&fctx);
+
+               LOCK(&fctx->lock);
+               dns_name_print(fctx->name, fp);
+
+               isc_time_formatISO8601ms(&fctx->start, timebuf,
+                                        sizeof(timebuf));
+
+               dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf));
+
+               fprintf(fp, "/%s (%s): started %s, ", typebuf,
+                       fctx->state == fetchstate_active ? "active" : "done",
+                       timebuf);
+
+               for (resp = ISC_LIST_HEAD(fctx->resps); resp != NULL;
+                    resp = ISC_LIST_NEXT(resp, link))
+               {
+                       resp_count++;
+               }
+
+               for (query = ISC_LIST_HEAD(fctx->queries); query != NULL;
+                    query = ISC_LIST_NEXT(query, link))
+               {
+                       query_count++;
+               }
+
+               if (isc_timer_running(fctx->timer)) {
+                       strlcpy(timebuf, "expires ", sizeof(timebuf));
+                       isc_time_formatISO8601ms(&fctx->expires, timebuf + 8,
+                                                sizeof(timebuf) - 8);
+               } else {
+                       strlcpy(timebuf, "not running", sizeof(timebuf));
+               }
 
-               dns_name_print(counter->domain, fp);
                fprintf(fp,
-                       ": %" PRIuFAST32 " active (%" PRIuFAST32
-                       " spilled, %" PRIuFAST32 " allowed)\n",
-                       counter->count, counter->dropped, counter->allowed);
+                       "fetches: %u active (%" PRIuFAST32
+                       " allowed, %" PRIuFAST32
+                       " dropped%s), queries: %u, timer %s\n",
+                       resp_count, fctx->allowed, fctx->dropped,
+                       fctx->spilled ? ", spilled" : "", query_count, timebuf);
+
+               UNLOCK(&fctx->lock);
        }
-       RWUNLOCK(&res->counters_lock, isc_rwlocktype_read);
        isc_hashmap_iter_destroy(&it);
+       RWUNLOCK(&res->fctxs_lock, isc_rwlocktype_read);
 }
 
 isc_result_t