]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add DTRACE probes to dns_delegdb
authorOndřej Surý <ondrej@isc.org>
Wed, 15 Apr 2026 12:53:37 +0000 (14:53 +0200)
committerOndřej Surý <ondrej@isc.org>
Mon, 20 Apr 2026 11:14:19 +0000 (13:14 +0200)
Instrument the delegation cache (introduced to back both NS-based and
DELEG-based delegations) with 11 USDT probes in the libdns provider so
that hit rate, eviction pressure, and lookup latency can be measured
without recompiling or enabling logging.

The probes are:

- delegdb_lookup_start / delegdb_lookup_done wrap dns_delegdb_lookup()
  and pass the query name plus the result code.

- delegdb_insert_start / delegdb_insert_done wrap dns_delegset_insert().
  The early SHUTTINGDOWN return is funneled through the cleanup label
  so the done probe fires on every path.

- delegdb_cleanup_start / delegdb_cleanup_done bracket the SIEVE-based
  eviction triggered when the cache goes overmem, reporting the number
  of bytes requested and actually reclaimed.  An additional per-node
  delegdb_evict probe (guarded by _ENABLED() because it fires inside
  the loop) exposes which zones are being evicted.

- delegdb_create, delegdb_reuse, and delegdb_shutdown trace the per-view
  lifecycle across server reloads.

- delegdb_delete traces rndc flush-delegation paths, reporting whether
  a subtree or single name was removed.

Name arguments are stringified with dns_name_format() behind
LIBDNS_*_ENABLED() guards so that the hot lookup and insert paths remain
zero-cost when no consumer is attached.

lib/dns/deleg.c
lib/dns/meson.build
lib/dns/probes-dns.d
tests/dns/meson.build

index 708f53ad04974d99054c78b04056436ae22370c6..7b2560ca47a7f6c169021620706d229a2deebef8 100644 (file)
@@ -24,6 +24,8 @@
 #include <dns/qp.h>
 #include <dns/view.h>
 
+#include "probes-dns.h"
+
 #define DELEGDB_NODE_MAGIC      ISC_MAGIC('D', 'e', 'G', 'N')
 #define VALID_DELEGDB_NODE(node) ISC_MAGIC_VALID(node, DELEGDB_NODE_MAGIC)
 
@@ -225,6 +227,8 @@ dns_delegdb_create(dns_delegdb_t **delegdbp) {
                ISC_SIEVE_INIT(delegdb->lru[i]);
        }
 
+       LIBDNS_DELEGDB_CREATE(delegdb);
+
        *delegdbp = delegdb;
 }
 
@@ -236,6 +240,8 @@ dns_delegdb_reuse(dns_view_t *oldview, dns_view_t *newview) {
 
        dns_delegdb_attach(oldview->deleg, &newview->deleg);
        isc_refcount_increment(&oldview->deleg->owners);
+
+       LIBDNS_DELEGDB_REUSE(newview->deleg);
 }
 
 typedef struct nodes_rcu_head {
@@ -355,6 +361,14 @@ dns_delegdb_lookup(dns_delegdb_t *delegdb, const dns_name_t *name,
        isc_result_t result = ISC_R_SHUTTINGDOWN;
        dns_qpmulti_t *nodes = NULL;
        dns_qpread_t qpr = {};
+       char namebuf[DNS_NAME_FORMATSIZE];
+
+       if (LIBDNS_DELEGDB_LOOKUP_START_ENABLED() ||
+           LIBDNS_DELEGDB_LOOKUP_DONE_ENABLED())
+       {
+               dns_name_format(name, namebuf, sizeof(namebuf));
+       }
+       LIBDNS_DELEGDB_LOOKUP_START(delegdb, namebuf);
 
        rcu_read_lock();
        nodes = rcu_dereference(delegdb->nodes);
@@ -367,6 +381,8 @@ dns_delegdb_lookup(dns_delegdb_t *delegdb, const dns_name_t *name,
        }
        rcu_read_unlock();
 
+       LIBDNS_DELEGDB_LOOKUP_DONE(delegdb, namebuf, result);
+
        return result;
 }
 
@@ -465,6 +481,8 @@ delegdb_cleanup(dns_qp_t *qp, dns_delegdb_t *delegdb, size_t requested) {
                return;
        }
 
+       LIBDNS_DELEGDB_CLEANUP_START(delegdb, (int)requested);
+
        while (reclaimed < requested) {
                node = ISC_SIEVE_NEXT(delegdb->lru[isc_tid()], visited, link);
 
@@ -473,10 +491,19 @@ delegdb_cleanup(dns_qp_t *qp, dns_delegdb_t *delegdb, size_t requested) {
                }
                reclaimed += node->size;
 
+               if (LIBDNS_DELEGDB_EVICT_ENABLED()) {
+                       char namebuf[DNS_NAME_FORMATSIZE];
+                       dns_name_format(&node->zonecut, namebuf,
+                                       sizeof(namebuf));
+                       LIBDNS_DELEGDB_EVICT(delegdb, node, namebuf);
+               }
+
                ISC_SIEVE_UNLINK(delegdb->lru[isc_tid()], node, link);
                (void)dns_qp_deletename(qp, &node->zonecut,
                                        DNS_DBNAMESPACE_NORMAL, NULL, NULL);
        }
+
+       LIBDNS_DELEGDB_CLEANUP_DONE(delegdb, (int)reclaimed);
 }
 
 static size_t
@@ -543,6 +570,7 @@ dns_delegset_insert(dns_delegdb_t *delegdb, const dns_name_t *zonecut,
        dns_qpread_t qpr = {};
        isc_stdtime_t now = isc_stdtime_now();
        dns_qpmulti_t *nodes = NULL;
+       char zonecutbuf[DNS_NAME_FORMATSIZE];
 
        REQUIRE(VALID_DELEGDB(delegdb));
        REQUIRE(DNS_NAME_VALID(zonecut));
@@ -555,11 +583,17 @@ dns_delegset_insert(dns_delegdb_t *delegdb, const dns_name_t *zonecut,
         */
        REQUIRE(delegset->mctx == delegdb->mctx);
 
+       if (LIBDNS_DELEGDB_INSERT_START_ENABLED() ||
+           LIBDNS_DELEGDB_INSERT_DONE_ENABLED())
+       {
+               dns_name_format(zonecut, zonecutbuf, sizeof(zonecutbuf));
+       }
+       LIBDNS_DELEGDB_INSERT_START(delegdb, zonecutbuf);
+
        rcu_read_lock();
        nodes = rcu_dereference(delegdb->nodes);
        if (nodes == NULL) {
-               rcu_read_unlock();
-               return ISC_R_SHUTTINGDOWN;
+               CLEANUP(ISC_R_SHUTTINGDOWN);
        }
 
        /*
@@ -632,6 +666,8 @@ dns_delegset_insert(dns_delegdb_t *delegdb, const dns_name_t *zonecut,
 cleanup:
        rcu_read_unlock();
 
+       LIBDNS_DELEGDB_INSERT_DONE(delegdb, zonecutbuf, result);
+
        return result;
 }
 
@@ -923,6 +959,11 @@ dns_delegdb_delete(dns_delegdb_t *delegdb, const dns_name_t *name, bool tree) {
        dns_qpmulti_t *nodes = NULL;
        dns_qp_t *qp = NULL;
        isc_result_t result = ISC_R_SHUTTINGDOWN;
+       char namebuf[DNS_NAME_FORMATSIZE];
+
+       if (LIBDNS_DELEGDB_DELETE_ENABLED()) {
+               dns_name_format(name, namebuf, sizeof(namebuf));
+       }
 
        rcu_read_lock();
        nodes = rcu_dereference(delegdb->nodes);
@@ -940,6 +981,8 @@ dns_delegdb_delete(dns_delegdb_t *delegdb, const dns_name_t *name, bool tree) {
        }
        rcu_read_unlock();
 
+       LIBDNS_DELEGDB_DELETE(delegdb, namebuf, (int)tree, result);
+
        return result;
 }
 
@@ -949,6 +992,7 @@ delegdb_shutdown_async(void *arg) {
 
        REQUIRE(isc_loop_get(isc_tid()) == isc_loop_main());
        REQUIRE(delegdb != NULL && VALID_DELEGDB(delegdb));
+
        if (isc_refcount_decrement(&delegdb->owners) == 1) {
                dns_qpmulti_t *nodes = rcu_xchg_pointer(&delegdb->nodes, NULL);
 
@@ -961,6 +1005,7 @@ delegdb_shutdown_async(void *arg) {
                        };
                        call_rcu(&nrh->rcu_head, deleg_destroy_qpmulti);
                }
+               LIBDNS_DELEGDB_SHUTDOWN(delegdb);
        }
 }
 
index f95cb7a15ff77eace84b1d7485962c32276bf8e0..007d4bb1b3e2070d4a6f1b3f6789cde33b09c282 100644 (file)
@@ -10,7 +10,7 @@
 # information regarding copyright ownership.
 
 probe_hdr = dtrace_header.process('probes-dns.d')
-probe_src = [probe_hdr, files('xfrin.c')]
+probe_src = [probe_hdr, files('deleg.c', 'xfrin.c')]
 
 # dns_inc += include_directories('include')
 dns_inc_p += include_directories('.')
@@ -90,7 +90,6 @@ dns_srcset.add(
         'compress.c',
         'db.c',
         'dbiterator.c',
-        'deleg.c',
         'diff.c',
         'dispatch.c',
         'dlz.c',
index f5abec43ca1d135cd671d4962fba6b714295c52c..ed5ea0b38660b7377c90817d3f5c38e5a828d1e5 100644 (file)
  */
 
 provider libdns {
+       probe delegdb_cleanup_done(void *, int);
+       probe delegdb_cleanup_start(void *, int);
+       probe delegdb_create(void *);
+       probe delegdb_delete(void *, char *, int, int);
+       probe delegdb_evict(void *, void *, char *);
+       probe delegdb_insert_done(void *, char *, int);
+       probe delegdb_insert_start(void *, char *);
+       probe delegdb_lookup_done(void *, char *, int);
+       probe delegdb_lookup_start(void *, char *);
+       probe delegdb_reuse(void *);
+       probe delegdb_shutdown(void *);
        probe xfrin_axfr_finalize_begin(void *, char *);
        probe xfrin_axfr_finalize_end(void *, char *, int);
        probe xfrin_connected(void *, char *, int);
index ba166f5a72bfa792024a07c96d7a01046f559c06..a13482f9d92fe61734cb4af8515625878013c8fe 100644 (file)
@@ -62,7 +62,23 @@ endif
 master_data = []
 subdir('testdata/master')
 
+deleg_probe_stub = custom_target(
+    'deleg-test-probes-dns',
+    input: files('../../lib/dns/probes-dns.d'),
+    output: 'probes-dns.h',
+    command: [
+        files('../../util/dtrace.sh'),
+        '-h',
+        '-s', '@INPUT@',
+        '-o', '@OUTPUT@',
+    ],
+)
+
 foreach unit : dns_tests
+    extra_sources = []
+    if unit == 'deleg'
+        extra_sources += deleg_probe_stub
+    endif
     test_bin = executable(
         unit,
         files(f'@unit@_test.c'),
@@ -77,7 +93,7 @@ foreach unit : dns_tests
                 meson.project_source_root() / 'bin' / 'tests' / 'system' / 'geoip2' / 'data',
             ),
         ],
-        sources: default_sanitize_options,
+        sources: [default_sanitize_options, extra_sources],
         dependencies: [
             libisc_dep,
             libdns_dep,