]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add statistics for glue cache usage (#46028)
authorMukund Sivaraman <muks@isc.org>
Fri, 6 Oct 2017 09:54:16 +0000 (15:24 +0530)
committerMukund Sivaraman <muks@isc.org>
Fri, 6 Oct 2017 10:14:37 +0000 (15:44 +0530)
15 files changed:
bin/named/bind9.xsl
bin/named/bind9.xsl.h
bin/named/statschannel.c
bin/tests/system/dyndb/driver/db.c
lib/dns/db.c
lib/dns/dnsrps.c
lib/dns/ecdb.c
lib/dns/include/dns/db.h
lib/dns/include/dns/stats.h
lib/dns/include/dns/zone.h
lib/dns/rbtdb.c
lib/dns/sdb.c
lib/dns/sdlz.c
lib/dns/win32/libdns.def.in
lib/dns/zone.c

index d34bf9872d70967f6bd105d2428bc9043cc579b3..86f70293054cb62dc7fd6b8e6e89fe3167a2cee4 100644 (file)
             </xsl:for-each>
           </xsl:for-each>
         </xsl:if>
+        <xsl:if test="views/view[zones/zone/counters[@type=&quot;gluecache&quot;]/counter &gt;0]">
+          <h2>Glue cache statistics</h2>
+          <xsl:for-each select="views/view[zones/zone/counters[@type=&quot;gluecache&quot;]/counter &gt;0]">
+            <h3>View <xsl:value-of select="@name"/></h3>
+            <xsl:variable name="thisview2">
+              <xsl:value-of select="@name"/>
+            </xsl:variable>
+            <xsl:for-each select="zones/zone">
+              <xsl:if test="counters[@type=&quot;gluecache&quot;]/counter[. &gt; 0]">
+                <h4>Zone <xsl:value-of select="@name"/></h4>
+                <table class="counters">
+                  <xsl:for-each select="counters[@type=&quot;gluecache&quot;]/counter[. &gt; 0]">
+                    <xsl:sort select="."/>
+                    <xsl:variable name="css-class11">
+                      <xsl:choose>
+                        <xsl:when test="position() mod 2 = 0">even</xsl:when>
+                        <xsl:otherwise>odd</xsl:otherwise>
+                      </xsl:choose>
+                    </xsl:variable>
+                    <tr class="{$css-class11}">
+                      <th>
+                        <xsl:value-of select="@name"/>
+                      </th>
+                      <td>
+                        <xsl:value-of select="."/>
+                      </td>
+                    </tr>
+                  </xsl:for-each>
+                </table>
+              </xsl:if>
+            </xsl:for-each>
+          </xsl:for-each>
+        </xsl:if>
         <xsl:if test="socketmgr/sockets/socket">
           <h2>Network Status</h2>
           <table class="netstat">
index 28f36224cdc1db06cbec2abd8ac99ac91a33d299..d621ecec566672b85de4939d93f505b51bfb559e 100644 (file)
@@ -805,6 +805,39 @@ static char xslmsg[] =
        " </xsl:for-each>\n"
        " </xsl:for-each>\n"
        " </xsl:if>\n"
+       " <xsl:if test=\"views/view[zones/zone/counters[@type=&quot;gluecache&quot;]/counter &gt;0]\">\n"
+       " <h2>Glue cache statistics</h2>\n"
+       " <xsl:for-each select=\"views/view[zones/zone/counters[@type=&quot;gluecache&quot;]/counter &gt;0]\">\n"
+       " <h3>View <xsl:value-of select=\"@name\"/></h3>\n"
+       " <xsl:variable name=\"thisview2\">\n"
+       " <xsl:value-of select=\"@name\"/>\n"
+       " </xsl:variable>\n"
+       " <xsl:for-each select=\"zones/zone\">\n"
+       " <xsl:if test=\"counters[@type=&quot;gluecache&quot;]/counter[. &gt; 0]\">\n"
+       " <h4>Zone <xsl:value-of select=\"@name\"/></h4>\n"
+       " <table class=\"counters\">\n"
+       " <xsl:for-each select=\"counters[@type=&quot;gluecache&quot;]/counter[. &gt; 0]\">\n"
+       " <xsl:sort select=\".\"/>\n"
+       " <xsl:variable name=\"css-class11\">\n"
+       " <xsl:choose>\n"
+       " <xsl:when test=\"position() mod 2 = 0\">even</xsl:when>\n"
+       " <xsl:otherwise>odd</xsl:otherwise>\n"
+       " </xsl:choose>\n"
+       " </xsl:variable>\n"
+       " <tr class=\"{$css-class11}\">\n"
+       " <th>\n"
+       " <xsl:value-of select=\"@name\"/>\n"
+       " </th>\n"
+       " <td>\n"
+       " <xsl:value-of select=\".\"/>\n"
+       " </td>\n"
+       " </tr>\n"
+       " </xsl:for-each>\n"
+       " </table>\n"
+       " </xsl:if>\n"
+       " </xsl:for-each>\n"
+       " </xsl:for-each>\n"
+       " </xsl:if>\n"
        " <xsl:if test=\"socketmgr/sockets/socket\">\n"
        " <h2>Network Status</h2>\n"
        " <table class=\"netstat\">\n"
index a8e18fd87041d8ba997c1736a6b5dd2bf5af9edd..58992215486497be79e0116daec68e02402e5fe2 100644 (file)
@@ -126,6 +126,7 @@ static const char *udpoutsizestats_desc[dns_sizecounter_out_max];
 static const char *tcpinsizestats_desc[dns_sizecounter_in_max];
 static const char *tcpoutsizestats_desc[dns_sizecounter_out_max];
 static const char *dnstapstats_desc[dns_dnstapcounter_max];
+static const char *gluecachestats_desc[dns_gluecachestatscounter_max];
 #if defined(EXTENDED_STATS)
 static const char *nsstats_xmldesc[ns_statscounter_max];
 static const char *resstats_xmldesc[dns_resstatscounter_max];
@@ -138,6 +139,7 @@ static const char *udpoutsizestats_xmldesc[dns_sizecounter_out_max];
 static const char *tcpinsizestats_xmldesc[dns_sizecounter_in_max];
 static const char *tcpoutsizestats_xmldesc[dns_sizecounter_out_max];
 static const char *dnstapstats_xmldesc[dns_dnstapcounter_max];
+static const char *gluecachestats_xmldesc[dns_gluecachestatscounter_max];
 #else
 #define nsstats_xmldesc NULL
 #define resstats_xmldesc NULL
@@ -150,6 +152,7 @@ static const char *dnstapstats_xmldesc[dns_dnstapcounter_max];
 #define tcpinsizestats_xmldesc NULL
 #define tcpoutsizestats_xmldesc NULL
 #define dnstapstats_xmldesc NULL
+#define gluecachestats_xmldesc NULL
 #endif /* EXTENDED_STATS */
 
 #define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0)
@@ -170,6 +173,7 @@ static int udpoutsizestats_index[dns_sizecounter_out_max];
 static int tcpinsizestats_index[dns_sizecounter_in_max];
 static int tcpoutsizestats_index[dns_sizecounter_out_max];
 static int dnstapstats_index[dns_dnstapcounter_max];
+static int gluecachestats_index[dns_gluecachestatscounter_max];
 
 static inline void
 set_desc(int counter, int maxcounter, const char *fdesc, const char **fdescs,
@@ -615,6 +619,30 @@ init_desc(void) {
        SET_DNSTAPSTATDESC(drop, "dnstap messages dropped", "DNSTAPdropped");
        INSIST(i == dns_dnstapcounter_max);
 
+#define SET_GLUECACHESTATDESC(counterid, desc, xmldesc) \
+       do {                                                      \
+               set_desc(dns_gluecachestatscounter_ ## counterid, \
+                        dns_gluecachestatscounter_max,           \
+                        desc, gluecachestats_desc,               \
+                        xmldesc, gluecachestats_xmldesc);              \
+               gluecachestats_index[i++] =                             \
+                       dns_gluecachestatscounter_ ## counterid;        \
+       } while (0)
+       i = 0;
+       SET_GLUECACHESTATDESC(hits_present,
+                             "Hits for present glue (cached)",
+                             "GLUECACHEhitspresent");
+       SET_GLUECACHESTATDESC(hits_absent,
+                             "Hits for non-existent glue (cached)",
+                             "GLUECACHEhitsabsent");
+       SET_GLUECACHESTATDESC(inserts_present,
+                             "Miss-plus-cache-inserts for present glue",
+                             "GLUECACHEinsertspresent");
+       SET_GLUECACHESTATDESC(inserts_absent,
+                             "Miss-plus-cache-inserts for non-existent glue",
+                             "GLUECACHEinsertsabsent");
+       INSIST(i == dns_gluecachestatscounter_max);
+
        /* Sanity check */
        for (i = 0; i < ns_statscounter_max; i++)
                INSIST(nsstats_desc[i] != NULL);
@@ -630,6 +658,8 @@ init_desc(void) {
                INSIST(dnssecstats_desc[i] != NULL);
        for (i = 0; i < dns_dnstapcounter_max; i++)
                INSIST(dnstapstats_desc[i] != NULL);
+       for (i = 0; i < dns_gluecachestatscounter_max; i++)
+               INSIST(gluecachestats_desc[i] != NULL);
 #if defined(EXTENDED_STATS)
        for (i = 0; i < ns_statscounter_max; i++)
                INSIST(nsstats_xmldesc[i] != NULL);
@@ -645,6 +675,8 @@ init_desc(void) {
                INSIST(dnssecstats_xmldesc[i] != NULL);
        for (i = 0; i < dns_dnstapcounter_max; i++)
                INSIST(dnstapstats_xmldesc[i] != NULL);
+       for (i = 0; i < dns_gluecachestatscounter_max; i++)
+               INSIST(gluecachestats_xmldesc[i] != NULL);
 #endif
 
        /* Initialize traffic size statistics */
@@ -1425,10 +1457,7 @@ zone_xmlrender(dns_zone_t *zone, void *arg) {
        dns_rdataclass_t rdclass;
        isc_uint32_t serial;
        xmlTextWriterPtr writer = arg;
-       isc_stats_t *zonestats;
-       dns_stats_t *rcvquerystats;
        dns_zonestat_level_t statlevel;
-       isc_uint64_t nsstat_values[ns_statscounter_max];
        int xmlrc;
        stats_dumparg_t dumparg;
        const char *ztype;
@@ -1466,36 +1495,71 @@ zone_xmlrender(dns_zone_t *zone, void *arg) {
                TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
        TRY0(xmlTextWriterEndElement(writer)); /* serial */
 
-       zonestats = dns_zone_getrequeststats(zone);
-       rcvquerystats = dns_zone_getrcvquerystats(zone);
-       if (statlevel == dns_zonestat_full && zonestats != NULL) {
-               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
-               TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
-                                                ISC_XMLCHAR "rcode"));
+       if (statlevel == dns_zonestat_full) {
+               isc_stats_t *zonestats;
+               isc_stats_t *gluecachestats;
+               dns_stats_t *rcvquerystats;
+               isc_uint64_t nsstat_values[ns_statscounter_max];
+               isc_uint64_t gluecachestats_values[dns_gluecachestatscounter_max];
 
-               result = dump_counters(zonestats, isc_statsformat_xml, writer,
-                                      NULL, nsstats_xmldesc,
-                                      ns_statscounter_max, nsstats_index,
-                                      nsstat_values, ISC_STATSDUMP_VERBOSE);
-               if (result != ISC_R_SUCCESS)
-                       goto error;
-               /* counters type="rcode"*/
-               TRY0(xmlTextWriterEndElement(writer));
-       }
+               zonestats = dns_zone_getrequeststats(zone);
+               if (zonestats != NULL) {
+                       TRY0(xmlTextWriterStartElement(writer,
+                                                      ISC_XMLCHAR "counters"));
+                       TRY0(xmlTextWriterWriteAttribute(writer,
+                                                        ISC_XMLCHAR "type",
+                                                        ISC_XMLCHAR "rcode"));
 
-       if (statlevel == dns_zonestat_full && rcvquerystats != NULL) {
-               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
-               TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
-                                                ISC_XMLCHAR "qtype"));
+                       result = dump_counters(zonestats, isc_statsformat_xml,
+                                              writer, NULL, nsstats_xmldesc,
+                                              ns_statscounter_max,
+                                              nsstats_index, nsstat_values,
+                                              ISC_STATSDUMP_VERBOSE);
+                       if (result != ISC_R_SUCCESS)
+                               goto error;
+                       /* counters type="rcode"*/
+                       TRY0(xmlTextWriterEndElement(writer));
+               }
 
-               dumparg.result = ISC_R_SUCCESS;
-               dns_rdatatypestats_dump(rcvquerystats, rdtypestat_dump,
-                                       &dumparg, 0);
-               if(dumparg.result != ISC_R_SUCCESS)
-                       goto error;
+               gluecachestats = dns_zone_getgluecachestats(zone);
+               if (gluecachestats != NULL) {
+                       TRY0(xmlTextWriterStartElement(writer,
+                                                      ISC_XMLCHAR "counters"));
+                       TRY0(xmlTextWriterWriteAttribute(writer,
+                                                        ISC_XMLCHAR "type",
+                                                        ISC_XMLCHAR "gluecache"));
+
+                       result = dump_counters(gluecachestats,
+                                              isc_statsformat_xml,
+                                              writer, NULL,
+                                              gluecachestats_xmldesc,
+                                              dns_gluecachestatscounter_max,
+                                              gluecachestats_index,
+                                              gluecachestats_values,
+                                              ISC_STATSDUMP_VERBOSE);
+                       if (result != ISC_R_SUCCESS)
+                               goto error;
+                       /* counters type="rcode"*/
+                       TRY0(xmlTextWriterEndElement(writer));
+               }
 
-               /* counters type="qtype"*/
-               TRY0(xmlTextWriterEndElement(writer));
+               rcvquerystats = dns_zone_getrcvquerystats(zone);
+               if (rcvquerystats != NULL) {
+                       TRY0(xmlTextWriterStartElement(writer,
+                                                      ISC_XMLCHAR "counters"));
+                       TRY0(xmlTextWriterWriteAttribute(writer,
+                                                        ISC_XMLCHAR "type",
+                                                        ISC_XMLCHAR "qtype"));
+
+                       dumparg.result = ISC_R_SUCCESS;
+                       dns_rdatatypestats_dump(rcvquerystats, rdtypestat_dump,
+                                               &dumparg, 0);
+                       if(dumparg.result != ISC_R_SUCCESS)
+                               goto error;
+
+                       /* counters type="qtype"*/
+                       TRY0(xmlTextWriterEndElement(writer));
+               }
        }
 
        TRY0(xmlTextWriterEndElement(writer)); /* zone */
@@ -2187,9 +2251,6 @@ zone_jsonrender(dns_zone_t *zone, void *arg) {
        char *class_only = NULL;
        dns_rdataclass_t rdclass;
        isc_uint32_t serial;
-       isc_uint64_t nsstat_values[ns_statscounter_max];
-       isc_stats_t *zonestats;
-       dns_stats_t *rcvquerystats;
        json_object *zonearray = (json_object *) arg;
        json_object *zoneobj = NULL;
        dns_zonestat_level_t statlevel;
@@ -2215,49 +2276,87 @@ zone_jsonrender(dns_zone_t *zone, void *arg) {
        if (zoneobj == NULL)
                return (ISC_R_NOMEMORY);
 
-       zonestats = dns_zone_getrequeststats(zone);
-       rcvquerystats = dns_zone_getrcvquerystats(zone);
-       if (statlevel == dns_zonestat_full && zonestats != NULL) {
-               json_object *counters = json_object_new_object();
-               if (counters == NULL) {
-                       result = ISC_R_NOMEMORY;
-                       goto error;
-               }
+       if (statlevel == dns_zonestat_full) {
+               isc_stats_t *zonestats;
+               isc_stats_t *gluecachestats;
+               dns_stats_t *rcvquerystats;
+               isc_uint64_t nsstat_values[ns_statscounter_max];
+               isc_uint64_t gluecachestats_values[dns_gluecachestatscounter_max];
 
-               result = dump_counters(zonestats, isc_statsformat_json,
-                                      counters, NULL, nsstats_xmldesc,
-                                      ns_statscounter_max, nsstats_index,
-                                      nsstat_values, 0);
-               if (result != ISC_R_SUCCESS) {
-                       json_object_put(counters);
-                       goto error;
+               zonestats = dns_zone_getrequeststats(zone);
+               if (zonestats != NULL) {
+                       json_object *counters = json_object_new_object();
+                       if (counters == NULL) {
+                               result = ISC_R_NOMEMORY;
+                               goto error;
+                       }
+
+                       result = dump_counters(zonestats, isc_statsformat_json,
+                                              counters, NULL, nsstats_xmldesc,
+                                              ns_statscounter_max,
+                                              nsstats_index,
+                                              nsstat_values, 0);
+                       if (result != ISC_R_SUCCESS) {
+                               json_object_put(counters);
+                               goto error;
+                       }
+
+                       if (json_object_get_object(counters)->count != 0)
+                               json_object_object_add(zoneobj,
+                                                      "rcodes", counters);
+                       else
+                               json_object_put(counters);
                }
 
-               if (json_object_get_object(counters)->count != 0)
-                       json_object_object_add(zoneobj, "rcodes", counters);
-               else
-                       json_object_put(counters);
-       }
+               gluecachestats = dns_zone_getgluecachestats(zone);
+               if (gluecachestats != NULL) {
+                       json_object *counters = json_object_new_object();
+                       if (counters == NULL) {
+                               result = ISC_R_NOMEMORY;
+                               goto error;
+                       }
 
-       if (statlevel == dns_zonestat_full && rcvquerystats != NULL) {
-               stats_dumparg_t dumparg;
-               json_object *counters = json_object_new_object();
-               CHECKMEM(counters);
+                       result = dump_counters(gluecachestats,
+                                              isc_statsformat_json,
+                                              counters, NULL,
+                                              gluecachestats_xmldesc,
+                                              dns_gluecachestatscounter_max,
+                                              gluecachestats_index,
+                                              gluecachestats_values, 0);
+                       if (result != ISC_R_SUCCESS) {
+                               json_object_put(counters);
+                               goto error;
+                       }
 
-               dumparg.type = isc_statsformat_json;
-               dumparg.arg = counters;
-               dumparg.result = ISC_R_SUCCESS;
-               dns_rdatatypestats_dump(rcvquerystats, rdtypestat_dump,
-                                       &dumparg, 0);
-               if (dumparg.result != ISC_R_SUCCESS) {
-                       json_object_put(counters);
-                       goto error;
+                       if (json_object_get_object(counters)->count != 0)
+                               json_object_object_add(zoneobj,
+                                                      "gluecache", counters);
+                       else
+                               json_object_put(counters);
                }
 
-               if (json_object_get_object(counters)->count != 0)
-                       json_object_object_add(zoneobj, "qtypes", counters);
-               else
-                       json_object_put(counters);
+               rcvquerystats = dns_zone_getrcvquerystats(zone);
+               if (rcvquerystats != NULL) {
+                       stats_dumparg_t dumparg;
+                       json_object *counters = json_object_new_object();
+                       CHECKMEM(counters);
+
+                       dumparg.type = isc_statsformat_json;
+                       dumparg.arg = counters;
+                       dumparg.result = ISC_R_SUCCESS;
+                       dns_rdatatypestats_dump(rcvquerystats, rdtypestat_dump,
+                                               &dumparg, 0);
+                       if (dumparg.result != ISC_R_SUCCESS) {
+                               json_object_put(counters);
+                               goto error;
+                       }
+
+                       if (json_object_get_object(counters)->count != 0)
+                               json_object_object_add(zoneobj,
+                                                      "qtypes", counters);
+                       else
+                               json_object_put(counters);
+               }
        }
 
        json_object_array_add(zonearray, zoneobj);
@@ -3448,6 +3547,7 @@ named_stats_dump(named_server_t *server, FILE *fp) {
        isc_uint64_t adbstat_values[dns_adbstats_max];
        isc_uint64_t zonestat_values[dns_zonestatscounter_max];
        isc_uint64_t sockstat_values[isc_sockstatscounter_max];
+       isc_uint64_t gluecachestats_values[dns_gluecachestatscounter_max];
 
        RUNTIME_CHECK(isc_once_do(&once, init_desc) == ISC_R_SUCCESS);
 
@@ -3605,6 +3705,36 @@ named_stats_dump(named_server_t *server, FILE *fp) {
                }
        }
 
+       fprintf(fp, "++ Per Zone Glue Cache Statistics ++\n");
+       zone = NULL;
+       for (result = dns_zone_first(server->zonemgr, &zone);
+            result == ISC_R_SUCCESS;
+            next = NULL, result = dns_zone_next(zone, &next), zone = next)
+       {
+               isc_stats_t *gluecachestats = dns_zone_getgluecachestats(zone);
+               if (gluecachestats != NULL) {
+                       char zonename[DNS_NAME_FORMATSIZE];
+
+                       view = dns_zone_getview(zone);
+                       if (view == NULL)
+                               continue;
+
+                       dns_name_format(dns_zone_getorigin(zone),
+                                       zonename, sizeof(zonename));
+                       fprintf(fp, "[%s", zonename);
+                       if (strcmp(view->name, "_default") != 0)
+                               fprintf(fp, " (view: %s)", view->name);
+                       fprintf(fp, "]\n");
+
+                       (void) dump_counters(gluecachestats,
+                                            isc_statsformat_file,
+                                            fp, NULL, gluecachestats_desc,
+                                            dns_gluecachestatscounter_max,
+                                            gluecachestats_index,
+                                            gluecachestats_values, 0);
+               }
+       }
+
        fprintf(fp, "--- Statistics Dump --- (%lu)\n", (unsigned long)now);
 
        return (ISC_R_SUCCESS); /* this function currently always succeeds */
index d720c3a6ddacf0ff80fce4794a19aa6112ef18e2..d867b582cf5599bd2dc7f2f07f2238d643440349 100644 (file)
@@ -609,6 +609,7 @@ static dns_dbmethods_t sampledb_methods = {
        NULL,
        NULL,
        NULL,
+       NULL
 };
 
 /* Auxiliary driver functions. */
index 5924934c1698192565e41590b071634667cabeee..796bbbc06d44de8bcff9d2edad3633bc50ded439 100644 (file)
@@ -1147,3 +1147,14 @@ dns_db_getservestalettl(dns_db_t *db, dns_ttl_t *ttl)
                return ((db->methods->getservestalettl)(db, ttl));
        return (ISC_R_NOTIMPLEMENTED);
 }
+
+isc_result_t
+dns_db_setgluecachestats(dns_db_t *db, isc_stats_t *stats) {
+       REQUIRE(dns_db_iszone(db));
+       REQUIRE(stats != NULL);
+
+       if (db->methods->setgluecachestats != NULL)
+               return ((db->methods->setgluecachestats)(db, stats));
+
+       return (ISC_R_NOTIMPLEMENTED);
+}
index d059dfd82caa1f067cb18a23e4319bf48b937f5f..66e31fadb4ba414a9c8c9e96796efb9f4aa39a16 100644 (file)
@@ -958,6 +958,7 @@ static dns_dbmethods_t rpsdb_db_methods = {
        NULL,                   /* getsize */
        NULL,                   /* setservestalettl */
        NULL,                   /* getservestalettl */
+       NULL                    /* setgluecachestats */
 };
 
 static dns_rdatasetmethods_t rpsdb_rdataset_methods = {
index e39be8fa72068a30f87518daf93ae50d9df4dcf4..653665b9491ae1782608ed20ca748cf1c3f9f5d5 100644 (file)
@@ -583,7 +583,8 @@ static dns_dbmethods_t ecdb_methods = {
        NULL,                   /* nodefullname */
        NULL,                   /* getsize */
        NULL,                   /* setservestalettl */
-       NULL                    /* getservestalettl */
+       NULL,                   /* getservestalettl */
+       NULL                    /* setgluecachestats */
 };
 
 static isc_result_t
index 8ef076b58b59b7bfb1f7169777c6cbf27627a281..04a1eaef99cf409597d40131cfc2df141ac9437e 100644 (file)
@@ -191,6 +191,7 @@ typedef struct dns_dbmethods {
                                   isc_uint64_t *records, isc_uint64_t *bytes);
        isc_result_t    (*setservestalettl)(dns_db_t *db, dns_ttl_t ttl);
        isc_result_t    (*getservestalettl)(dns_db_t *db, dns_ttl_t *ttl);
+       isc_result_t    (*setgluecachestats)(dns_db_t *db, isc_stats_t *stats);
 } dns_dbmethods_t;
 
 typedef isc_result_t
@@ -1722,6 +1723,21 @@ dns_db_getservestalettl(dns_db_t *db, dns_ttl_t *ttl);
  * \li #ISC_R_NOTIMPLEMENTED - Not supported by this DB implementation.
  */
 
+isc_result_t
+dns_db_setgluecachestats(dns_db_t *db, isc_stats_t *stats);
+/*%<
+ * Set the location in which to collect glue cache statistics.
+ * This option may not exist depending on the DB implementation.
+ *
+ * Requires:
+ *
+ * \li 'db' is a valid database (cache only).
+ *
+ * Returns:
+ * \li when available, a pointer to a statistics object created by
+ *     dns_rdatasetstats_create(); otherwise NULL.
+ */
+
 ISC_LANG_ENDDECLS
 
 #endif /* DNS_DB_H */
index f0befaddb452e06015bfaf7cc8bf74b7c59ab7e5..bcfa906e18a399c461ed827a1daf31085d8ccd30 100644 (file)
@@ -134,7 +134,17 @@ enum {
         */
        dns_dnstapcounter_success = 0,
        dns_dnstapcounter_drop =  1,
-       dns_dnstapcounter_max = 2
+       dns_dnstapcounter_max = 2,
+
+       /*
+        * Glue cache statistics counters.
+        */
+       dns_gluecachestatscounter_hits_present = 0,
+       dns_gluecachestatscounter_hits_absent = 1,
+       dns_gluecachestatscounter_inserts_present = 2,
+       dns_gluecachestatscounter_inserts_absent = 3,
+
+       dns_gluecachestatscounter_max = 4,
 };
 
 /*%
index aa08b1f67560fde389f3f2aa2428209740673aab..7412ad7d114a75f419ac3c7050ade8dada1d5d1e 100644 (file)
@@ -2495,5 +2495,17 @@ dns_zone_setserial(dns_zone_t *zone, isc_uint32_t serial);
  */
 ISC_LANG_ENDDECLS
 
+isc_stats_t *
+dns_zone_getgluecachestats(dns_zone_t *zone);
+/*%<
+ * Get the glue cache statistics for zone.
+ *
+ * Requires:
+ * \li 'zone' to be a valid zone.
+ *
+ * Returns:
+ * \li if present, a pointer to the statistics set installed in zone;
+ *     otherwise NULL.
+ */
 
 #endif /* DNS_ZONE_H */
index 74ae6185a3fd59a748c4c7b1dbdbb522de89528b..a8ddf9fd5b0a840c5b41bd907a1152d2d8607dbe 100644 (file)
@@ -257,6 +257,7 @@ typedef isc_uint64_t                    rbtdb_serial_t;
 #define set_index set_index64
 #define set_ttl set_ttl64
 #define setcachestats setcachestats64
+#define setgluecachestats setgluecachestats64
 #define setownercase setownercase64
 #define setservestalettl setservestalettl64
 #define setsigningtime setsigningtime64
@@ -644,6 +645,7 @@ struct dns_rbtdb {
        dns_rbtnode_t *                 nsec3_origin_node;
        dns_stats_t *                   rrsetstats; /* cache DB only */
        isc_stats_t *                   cachestats; /* cache DB only */
+       isc_stats_t *                   gluecachestats; /* zone DB only */
        /* Locked by lock. */
        unsigned int                    active;
        isc_refcount_t                  references;
@@ -1296,6 +1298,8 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) {
                dns_stats_detach(&rbtdb->rrsetstats);
        if (rbtdb->cachestats != NULL)
                isc_stats_detach(&rbtdb->cachestats);
+       if (rbtdb->gluecachestats != NULL)
+               isc_stats_detach(&rbtdb->gluecachestats);
 
        isc_mem_put(rbtdb->common.mctx, rbtdb->node_locks,
                    rbtdb->node_lock_count * sizeof(rbtdb_nodelock_t));
@@ -8181,6 +8185,18 @@ setcachestats(dns_db_t *db, isc_stats_t *stats) {
        return (ISC_R_SUCCESS);
 }
 
+static isc_result_t
+setgluecachestats(dns_db_t *db, isc_stats_t *stats) {
+       dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
+
+       REQUIRE(VALID_RBTDB(rbtdb));
+       REQUIRE(!IS_CACHE(rbtdb) && !IS_STUB(rbtdb));
+       REQUIRE(stats != NULL);
+
+       isc_stats_attach(stats, &rbtdb->gluecachestats);
+       return (ISC_R_SUCCESS);
+}
+
 static dns_stats_t *
 getrrsetstats(dns_db_t *db) {
        dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
@@ -8279,7 +8295,8 @@ static dns_dbmethods_t zone_methods = {
        nodefullname,
        getsize,
        NULL,
-       NULL
+       NULL,
+       setgluecachestats
 };
 
 static dns_dbmethods_t cache_methods = {
@@ -8329,7 +8346,8 @@ static dns_dbmethods_t cache_methods = {
        nodefullname,
        NULL,
        setservestalettl,
-       getservestalettl
+       getservestalettl,
+       NULL
 };
 
 isc_result_t
@@ -8410,6 +8428,8 @@ dns_rbtdb_create
        }
 
        rbtdb->cachestats = NULL;
+       rbtdb->gluecachestats = NULL;
+
        rbtdb->rrsetstats = NULL;
        if (IS_CACHE(rbtdb)) {
                result = dns_rdatasetstats_create(mctx, &rbtdb->rrsetstats);
@@ -10114,9 +10134,9 @@ rdataset_addglue(dns_rdataset_t *rdataset,
        rbtdb_glue_additionaldata_ctx_t ctx;
        isc_result_t result;
 
-       INSIST(rdataset->type == dns_rdatatype_ns);
-       INSIST(rbtdb == rbtversion->rbtdb);
-       INSIST(!IS_CACHE(rbtdb) && !IS_STUB(rbtdb));
+       REQUIRE(rdataset->type == dns_rdatatype_ns);
+       REQUIRE(rbtdb == rbtversion->rbtdb);
+       REQUIRE(!IS_CACHE(rbtdb) && !IS_STUB(rbtdb));
 
        /*
         * The glue table cache that forms a part of the DB version
@@ -10158,8 +10178,20 @@ restart:
         * (void *) -1 is a special value that means no glue is
         * present in the zone.
         */
-       if (ge == (void *) -1)
+       if (ge == (void *) -1) {
+               if (!restarted && (rbtdb->gluecachestats != NULL)) {
+                       isc_stats_increment
+                               (rbtdb->gluecachestats,
+                                dns_gluecachestatscounter_hits_absent);
+               }
                goto no_glue;
+       } else {
+               if (!restarted && (rbtdb->gluecachestats != NULL)) {
+                       isc_stats_increment
+                               (rbtdb->gluecachestats,
+                                dns_gluecachestatscounter_hits_present);
+               }
+       }
 
        for (; ge != NULL; ge = ge->next) {
                isc_buffer_t *buffer = NULL;
@@ -10326,8 +10358,18 @@ no_glue:
                 * No glue was found. Cache it so.
                 */
                cur->glue_list = (void *) -1;
+               if (rbtdb->gluecachestats != NULL) {
+                       isc_stats_increment
+                               (rbtdb->gluecachestats,
+                                dns_gluecachestatscounter_inserts_absent);
+               }
        } else {
                cur->glue_list = ctx.glue_list;
+               if (rbtdb->gluecachestats != NULL) {
+                       isc_stats_increment
+                               (rbtdb->gluecachestats,
+                                dns_gluecachestatscounter_inserts_present);
+               }
        }
 
        cur->next = rbtversion->glue_table[idx];
index 44d010750ea8d1742dad759ee56df2951743ee0f..7d36de75ee1b06770e32b5d96d1d15790a93a778 100644 (file)
@@ -1294,7 +1294,8 @@ static dns_dbmethods_t sdb_methods = {
        NULL,                   /* nodefullname */
        NULL,                   /* getsize */
        NULL,                   /* setservestalettl */
-       NULL                    /* getservestalettl */
+       NULL,                   /* getservestalettl */
+       NULL                    /* setgluecachestats */
 };
 
 static isc_result_t
index 568129ce3888fc755aa84f958193d669cd5f81e0..eac31799d28876b7a7088552dcdf31259ca34125 100644 (file)
@@ -1330,7 +1330,8 @@ static dns_dbmethods_t sdlzdb_methods = {
        NULL,                   /* nodefullname */
        NULL,                   /* getsize */
        NULL,                   /* setservestalettl */
-       NULL                    /* getservestalettl */
+       NULL,                   /* getservestalettl */
+       NULL                    /* setgluecachestats */
 };
 
 /*
index 020079569bfebd6bf263381b3f6c1ccdf4dac058..8086be44cfe7d58629b5da6555cc3d6b2fc5cbec 100644 (file)
@@ -228,6 +228,7 @@ dns_db_rpz_attach
 dns_db_rpz_ready
 dns_db_serialize
 dns_db_setcachestats
+dns_db_setgluecachestats
 dns_db_setservestalettl
 dns_db_setsigningtime
 dns_db_settask
@@ -1186,6 +1187,7 @@ dns_zone_getdbtype
 dns_zone_getexpiretime
 dns_zone_getfile
 dns_zone_getforwardacl
+dns_zone_getgluecachestats
 dns_zone_getidlein
 dns_zone_getidleout
 dns_zone_getincludes
index 4d80027bc1428bb79c422c570304b21e4205e1a4..afdb7049a9a5ba43ec77d033bd24b827d53cb723 100644 (file)
@@ -424,6 +424,8 @@ struct dns_zone {
        dns_zone_t              *rss_raw;
        isc_event_t             *rss_event;
        dns_update_state_t      *rss_state;
+
+       isc_stats_t             *gluecachestats;
 };
 
 typedef struct {
@@ -1064,6 +1066,13 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
 
        zone->magic = ZONE_MAGIC;
 
+       zone->gluecachestats = NULL;
+       result = isc_stats_create(mctx, &zone->gluecachestats,
+                                 dns_gluecachestatscounter_max);
+       if (result != ISC_R_SUCCESS) {
+               goto free_erefs;
+       }
+
        /* Must be after magic is set. */
        result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
        if (result != ISC_R_SUCCESS) {
@@ -1076,6 +1085,10 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
        *zonep = zone;
        return (ISC_R_SUCCESS);
 
+ free_stats:
+       if (zone->gluecachestats != NULL)
+               isc_stats_detach(&zone->gluecachestats);
+
  free_erefs:
        isc_refcount_decrement(&zone->erefs, NULL);
        isc_refcount_destroy(&zone->erefs);
@@ -1237,6 +1250,9 @@ zone_free(dns_zone_t *zone) {
        if (zone->ssutable != NULL) {
                dns_ssutable_detach(&zone->ssutable);
        }
+       if (zone->gluecachestats != NULL) {
+               isc_stats_detach(&zone->gluecachestats);
+       }
 
        /* last stuff */
        ZONEDB_DESTROYLOCK(&zone->dblock);
@@ -2083,6 +2099,12 @@ zone_load(dns_zone_t *zone, unsigned int flags, isc_boolean_t locked) {
        }
        dns_db_settask(db, zone->task);
 
+       if (zone->type == dns_zone_master || zone->type == dns_zone_slave) {
+               result = dns_db_setgluecachestats(db, zone->gluecachestats);
+               if (result != ISC_R_SUCCESS)
+                       goto cleanup;
+       }
+
        if (! dns_db_ispersistent(db)) {
                if (zone->masterfile != NULL) {
                        result = zone_startload(db, zone, loadtime);
@@ -14648,6 +14670,10 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) {
        if (result != ISC_R_SUCCESS)
                goto failure;
 
+       result = dns_db_setgluecachestats(db, zone->gluecachestats);
+       if (result != ISC_R_SUCCESS)
+               goto failure;
+
        result = dns_db_newversion(db, &version);
        if (result != ISC_R_SUCCESS)
                goto failure;
@@ -19167,3 +19193,10 @@ dns_zone_setserial(dns_zone_t *zone, isc_uint32_t serial) {
        UNLOCK_ZONE(zone);
        return (result);
 }
+
+isc_stats_t *
+dns_zone_getgluecachestats(dns_zone_t *zone) {
+       REQUIRE(DNS_ZONE_VALID(zone));
+
+       return (zone->gluecachestats);
+}