Merge statistics code (ATT SoW, rt24117)

This includes the following changes:

3326.	[func]		Added task list statistics: task model, worker
			threads, quantum, tasks running, tasks ready.
			[RT #27678]

3325.	[func]		Report cache statistics: memory use, number of
			nodes, number of hash buckets, hit and miss counts.
			[RT #27056]

3324.	[test]		Add better tests for ADB stats [RT #27057]

3323.	[func]		Report the number of buckets the resolver is using.
			[RT #27020]

3322.	[func]		Monitor the number of active TCP and UDP dispatches.
			[RT #27055]

3321.	[func]		Monitor the number of recursive fetches and the
			number of open sockets, and report these values in
			the statistics channel. [RT #27054]

3320.	[func]		Added support for monitoring of recursing client
			count. [RT #27009]

3319.	[func]		Added support for monitoring of ADB entry count and
			hash size. [RT #27057]
This commit is contained in:
Evan Hunt 2012-05-14 10:06:05 -07:00
parent 4dd8c4517e
commit dd2a0a6d2d
49 changed files with 1576 additions and 91 deletions

26
CHANGES
View file

@ -1,3 +1,29 @@
3326. [func] Added task list statistics: task model, worker
threads, quantum, tasks running, tasks ready.
[RT #27678]
3325. [func] Report cache statistics: memory use, number of
nodes, number of hash buckets, hit and miss counts.
[RT #27056]
3324. [test] Add better tests for ADB stats [RT #27057]
3323. [func] Report the number of buckets the resolver is using.
[RT #27020]
3322. [func] Monitor the number of active TCP and UDP dispatches.
[RT #27055]
3321. [func] Monitor the number of recursive fetches and the
number of open sockets, and report these values in
the statistics channel. [RT #27054]
3320. [func] Added support for monitoring of recursing client
count. [RT #27009]
3319. [func] Added support for monitoring of ADB entry count and
hash size. [RT #27057]
3318. [tuning] Reduce the amount of work performed while holding a
bucket lock when finshed with a fetch context.
[RT #29239]

View file

@ -233,6 +233,47 @@ div.statcounter br {
<br />
<div class="statcounter">
<h2>ADB Statistics (Common)</h2>
<xsl:for-each select="server/adbstat">
<dl>
<dt><xsl:value-of select="name"/></dt>
<dd><xsl:value-of select="counter"/></dd>
</dl>
</xsl:for-each>
<br />
</div>
<xsl:for-each select="views/view">
<div class="statcounter">
<h2>ADB Statistics for View <xsl:value-of select="name"/></h2>
<xsl:for-each select="adbstat">
<dl>
<dt><xsl:value-of select="name"/></dt>
<dd><xsl:value-of select="counter"/></dd>
</dl>
</xsl:for-each>
<br />
</div>
</xsl:for-each>
<br />
<xsl:for-each select="views/view">
<table>
<tr class="rowh">
<th colspan="2">Cache Statistics for View <xsl:value-of select="name"/></th>
</tr>
<xsl:for-each select="cachestats/cachestat">
<tr class="lrow">
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="value"/></td>
</tr>
</xsl:for-each>
</table>
<br/>
</xsl:for-each>
<xsl:for-each select="views/view">
<table>
<tr class="rowh">
@ -388,11 +429,17 @@ div.statcounter br {
<xsl:value-of select="taskmgr/thread-model/tasks-running"/>
</td>
</tr>
<tr class="lrow">
<td>Tasks Ready</td>
<td>
<xsl:value-of select="taskmgr/thread-model/tasks-ready"/>
</td>
</tr>
</table>
<br/>
<table>
<tr class="rowh">
<th colspan="5">Tasks</th>
<th colspan="6">Tasks</th>
</tr>
<tr class="rowh">
<th>ID</th>
@ -400,6 +447,7 @@ div.statcounter br {
<th>References</th>
<th>State</th>
<th>Quantum</th>
<th>Events</th>
</tr>
<xsl:for-each select="taskmgr/tasks/task">
<tr class="lrow">
@ -418,6 +466,9 @@ div.statcounter br {
<td>
<xsl:value-of select="quantum"/>
</td>
<td>
<xsl:value-of select="events"/>
</td>
</tr>
</xsl:for-each>
</table>

View file

@ -238,6 +238,47 @@ static char xslmsg[] =
"\n"
" <br />\n"
"\n"
" <div class=\"statcounter\">\n"
" <h2>ADB Statistics (Common)</h2>\n"
" <xsl:for-each select=\"server/adbstat\">\n"
" <dl>\n"
" <dt><xsl:value-of select=\"name\"/></dt>\n"
" <dd><xsl:value-of select=\"counter\"/></dd>\n"
" </dl>\n"
" </xsl:for-each>\n"
" <br />\n"
" </div>\n"
"\n"
" <xsl:for-each select=\"views/view\">\n"
" <div class=\"statcounter\">\n"
" <h2>ADB Statistics for View <xsl:value-of select=\"name\"/></h2>\n"
" <xsl:for-each select=\"adbstat\">\n"
" <dl>\n"
" <dt><xsl:value-of select=\"name\"/></dt>\n"
" <dd><xsl:value-of select=\"counter\"/></dd>\n"
" </dl>\n"
" </xsl:for-each>\n"
" <br />\n"
" </div>\n"
" </xsl:for-each>\n"
"\n"
" <br />\n"
"\n"
" <xsl:for-each select=\"views/view\">\n"
" <table>\n"
" <tr class=\"rowh\">\n"
" <th colspan=\"2\">Cache Statistics for View <xsl:value-of select=\"name\"/></th>\n"
" </tr>\n"
" <xsl:for-each select=\"cachestats/cachestat\">\n"
" <tr class=\"lrow\">\n"
" <td><xsl:value-of select=\"name\"/></td>\n"
" <td><xsl:value-of select=\"value\"/></td>\n"
" </tr>\n"
" </xsl:for-each>\n"
" </table>\n"
" <br/>\n"
" </xsl:for-each>\n"
"\n"
" <xsl:for-each select=\"views/view\">\n"
" <table>\n"
" <tr class=\"rowh\">\n"
@ -393,11 +434,17 @@ static char xslmsg[] =
" <xsl:value-of select=\"taskmgr/thread-model/tasks-running\"/>\n"
" </td>\n"
" </tr>\n"
" <tr class=\"lrow\">\n"
" <td>Tasks Ready</td>\n"
" <td>\n"
" <xsl:value-of select=\"taskmgr/thread-model/tasks-ready\"/>\n"
" </td>\n"
" </tr>\n"
" </table>\n"
" <br/>\n"
" <table>\n"
" <tr class=\"rowh\">\n"
" <th colspan=\"5\">Tasks</th>\n"
" <th colspan=\"6\">Tasks</th>\n"
" </tr>\n"
" <tr class=\"rowh\">\n"
" <th>ID</th>\n"
@ -405,6 +452,7 @@ static char xslmsg[] =
" <th>References</th>\n"
" <th>State</th>\n"
" <th>Quantum</th>\n"
" <th>Events</th>\n"
" </tr>\n"
" <xsl:for-each select=\"taskmgr/tasks/task\">\n"
" <tr class=\"lrow\">\n"
@ -423,6 +471,9 @@ static char xslmsg[] =
" <td>\n"
" <xsl:value-of select=\"quantum\"/>\n"
" </td>\n"
" <td>\n"
" <xsl:value-of select=\"events\"/>\n"
" </td>\n"
" </tr>\n"
" </xsl:for-each>\n"
" </table>\n"

View file

@ -670,8 +670,11 @@ ns_client_endrequest(ns_client_t *client) {
client->ednsversion = -1;
dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE);
if (client->recursionquota != NULL)
if (client->recursionquota != NULL) {
isc_quota_detach(&client->recursionquota);
isc_stats_decrement(ns_g_server->nsstats,
dns_nsstatscounter_recursclients);
}
/*
* Clear all client attributes that are specific to

View file

@ -165,7 +165,9 @@ enum {
dns_nsstatscounter_updatefail = 34,
dns_nsstatscounter_updatebadprereq = 35,
dns_nsstatscounter_max = 36
dns_nsstatscounter_recursclients =36,
dns_nsstatscounter_max = 37
};
void

View file

@ -30,6 +30,7 @@
#include <dns/adb.h>
#include <dns/byaddr.h>
#include <dns/cache.h>
#include <dns/db.h>
#include <dns/dlz.h>
#include <dns/dns64.h>
@ -1133,6 +1134,31 @@ query_isduplicate(ns_client_t *client, dns_name_t *name,
return (ISC_FALSE);
}
static void
update_cachestats(dns_cache_t *cache, isc_result_t result) {
isc_stats_t *cachestats = NULL;
if (cache == NULL)
return;
isc_stats_attach(dns_cache_getstats(cache), &cachestats);
switch (result) {
case ISC_R_SUCCESS:
case DNS_R_NCACHENXDOMAIN:
case DNS_R_NCACHENXRRSET:
case DNS_R_CNAME:
case DNS_R_DNAME:
case DNS_R_GLUE:
case DNS_R_ZONECUT:
isc_stats_increment(cachestats,
dns_cachestatscounter_queryhits);
break;
default:
isc_stats_increment(cachestats,
dns_cachestatscounter_querymisses);
}
isc_stats_detach(&cachestats);
}
static isc_result_t
query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
ns_client_t *client = arg;
@ -1264,6 +1290,8 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK,
client->now, &node, fname, &cm, &ci,
rdataset, sigrdataset);
update_cachestats(client->view->cache, result);
if (result == DNS_R_GLUE &&
validate(client, db, fname, rdataset, sigrdataset))
result = ISC_R_SUCCESS;
@ -1272,6 +1300,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
if (result == ISC_R_SUCCESS)
goto found;
if (dns_rdataset_isassociated(rdataset))
dns_rdataset_disassociate(rdataset);
if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset))
@ -3727,6 +3756,10 @@ query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
if (client->recursionquota == NULL) {
result = isc_quota_attach(&ns_g_server->recursionquota,
&client->recursionquota);
isc_stats_increment(ns_g_server->nsstats,
dns_nsstatscounter_recursclients);
if (result == ISC_R_SOFTQUOTA) {
static isc_stdtime_t last = 0;
isc_stdtime_t now;
@ -3773,6 +3806,8 @@ query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
"ns_client_replace() failed: %s",
isc_result_totext(result));
isc_quota_detach(&client->recursionquota);
isc_stats_decrement(ns_g_server->nsstats,
dns_nsstatscounter_recursclients);
}
}
if (result != ISC_R_SUCCESS)
@ -5677,6 +5712,9 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
client->query.dboptions, client->now,
&node, fname, &cm, &ci, rdataset, sigrdataset);
if (db == client->view->cachedb)
update_cachestats(client->view->cache, result);
resume:
CTRACE("query_find: resume");

View file

@ -2138,12 +2138,6 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
goto cleanup;
}
ndisp = 4 * ISC_MIN(ns_g_udpdisp, MAX_UDP_DISPATCH);
CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31, ndisp,
ns_g_socketmgr, ns_g_timermgr,
resopts, ns_g_dispatchmgr,
dispatch4, dispatch6));
if (resstats == NULL) {
CHECK(isc_stats_create(mctx, &resstats,
dns_resstatscounter_max));
@ -2153,6 +2147,12 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
CHECK(dns_rdatatypestats_create(mctx, &resquerystats));
dns_view_setresquerystats(view, resquerystats);
ndisp = 4 * ISC_MIN(ns_g_udpdisp, MAX_UDP_DISPATCH);
CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31, ndisp,
ns_g_socketmgr, ns_g_timermgr,
resopts, ns_g_dispatchmgr,
dispatch4, dispatch6));
/*
* Set the ADB cache size to 1/8th of the max-cache-size or
* MAX_ADB_SIZE_FOR_CACHESHARE when the cache is shared.

View file

@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: statschannel.c,v 1.28 2011/03/12 04:59:46 tbox Exp $ */
/* $Id: statschannel.c,v 1.28.224.1 2011/12/22 07:48:27 marka Exp $ */
/*! \file */
@ -62,16 +62,14 @@ struct ns_statschannel {
ISC_LINK(struct ns_statschannel) link;
};
typedef enum { statsformat_file, statsformat_xml } statsformat_t;
typedef struct
stats_dumparg {
statsformat_t type;
void *arg; /* type dependent argument */
int ncounters; /* used for general statistics */
int *counterindices; /* used for general statistics */
isc_uint64_t *countervalues; /* used for general statistics */
isc_result_t result;
isc_statsformat_t type;
void *arg; /* type dependent argument */
int ncounters; /* for general statistics */
int *counterindices; /* for general statistics */
isc_uint64_t *countervalues; /* for general statistics */
isc_result_t result;
} stats_dumparg_t;
static isc_once_t once = ISC_ONCE_INIT;
@ -83,16 +81,19 @@ static isc_once_t once = ISC_ONCE_INIT;
*/
static const char *nsstats_desc[dns_nsstatscounter_max];
static const char *resstats_desc[dns_resstatscounter_max];
static const char *adbstats_desc[dns_adbstats_max];
static const char *zonestats_desc[dns_zonestatscounter_max];
static const char *sockstats_desc[isc_sockstatscounter_max];
#ifdef HAVE_LIBXML2
static const char *nsstats_xmldesc[dns_nsstatscounter_max];
static const char *resstats_xmldesc[dns_resstatscounter_max];
static const char *adbstats_xmldesc[dns_adbstats_max];
static const char *zonestats_xmldesc[dns_zonestatscounter_max];
static const char *sockstats_xmldesc[isc_sockstatscounter_max];
#else
#define nsstats_xmldesc NULL
#define resstats_xmldesc NULL
#define adbstats_xmldesc NULL
#define zonestats_xmldesc NULL
#define sockstats_xmldesc NULL
#endif /* HAVE_LIBXML2 */
@ -108,6 +109,7 @@ static int nsstats_index[dns_nsstatscounter_max];
static int resstats_index[dns_resstatscounter_max];
static int zonestats_index[dns_zonestatscounter_max];
static int sockstats_index[isc_sockstatscounter_max];
static int adbstats_index[dns_adbstats_max];
static inline void
set_desc(int counter, int maxcounter, const char *fdesc, const char **fdescs,
@ -198,6 +200,8 @@ init_desc(void) {
SET_NSSTATDESC(updatebadprereq,
"updates rejected due to prerequisite failure",
"UpdateBadPrereq");
SET_NSSTATDESC(recursclients, "recursing clients",
"RecursClients");
INSIST(i == dns_nsstatscounter_max);
/* Initialize resolver statistics */
@ -234,6 +238,8 @@ init_desc(void) {
"QueryAbort");
SET_RESSTATDESC(dispsockfail, "failures in opening query sockets",
"QuerySockFail");
SET_RESSTATDESC(disprequdp, "UDP queries in progress", "QueryCurUDP");
SET_RESSTATDESC(dispreqtcp, "TCP queries in progress", "QueryCurTCP");
SET_RESSTATDESC(querytimeout, "query timeouts", "QueryTimeout");
SET_RESSTATDESC(gluefetchv4, "IPv4 NS address fetches", "GlueFetchv4");
SET_RESSTATDESC(gluefetchv6, "IPv6 NS address fetches", "GlueFetchv6");
@ -268,8 +274,32 @@ init_desc(void) {
SET_RESSTATDESC(queryrtt5, "queries with RTT > "
DNS_RESOLVER_QRYRTTCLASS4STR "ms",
"QryRTT" DNS_RESOLVER_QRYRTTCLASS4STR "+");
SET_RESSTATDESC(nfetch, "active fetches", "NumFetch");
SET_RESSTATDESC(buckets, "bucket size", "BucketSize");
INSIST(i == dns_resstatscounter_max);
/* Initialize adb statistics */
for (i = 0; i < dns_adbstats_max; i++)
adbstats_desc[i] = NULL;
#ifdef HAVE_LIBXML2
for (i = 0; i < dns_adbstats_max; i++)
adbstats_xmldesc[i] = NULL;
#endif
#define SET_ADBSTATDESC(id, desc, xmldesc) \
do { \
set_desc(dns_adbstats_ ## id, dns_adbstats_max, \
desc, adbstats_desc, xmldesc, adbstats_xmldesc); \
adbstats_index[i++] = dns_adbstats_ ## id; \
} while (0)
i = 0;
SET_ADBSTATDESC(nentries, "Address hash table size", "nentries");
SET_ADBSTATDESC(entriescnt, "Addresses in hash table", "entriescnt");
SET_ADBSTATDESC(nnames, "Name hash table size", "nnames");
SET_ADBSTATDESC(namescnt, "Names in hash table", "namescnt");
INSIST(i == dns_adbstats_max);
/* Initialize zone statistics */
for (i = 0; i < dns_zonestatscounter_max; i++)
zonestats_desc[i] = NULL;
@ -407,6 +437,12 @@ init_desc(void) {
"UnixRecvErr");
SET_SOCKSTATDESC(fdwatchrecvfail, "FDwatch recv errors",
"FDwatchRecvErr");
SET_SOCKSTATDESC(udp4active, "UDP/IPv4 sockets active", "UDP4Active");
SET_SOCKSTATDESC(udp6active, "UDP/IPv6 sockets active", "UDP6Active");
SET_SOCKSTATDESC(tcp4active, "TCP/IPv4 sockets active", "TCP4Active");
SET_SOCKSTATDESC(tcp6active, "TCP/IPv6 sockets active", "TCP6Active");
SET_SOCKSTATDESC(unixactive, "Unix domain sockets active",
"UnixActive");
INSIST(i == isc_sockstatscounter_max);
/* Sanity check */
@ -414,6 +450,8 @@ init_desc(void) {
INSIST(nsstats_desc[i] != NULL);
for (i = 0; i < dns_resstatscounter_max; i++)
INSIST(resstats_desc[i] != NULL);
for (i = 0; i < dns_adbstats_max; i++)
INSIST(adbstats_desc[i] != NULL);
for (i = 0; i < dns_zonestatscounter_max; i++)
INSIST(zonestats_desc[i] != NULL);
for (i = 0; i < isc_sockstatscounter_max; i++)
@ -423,6 +461,8 @@ init_desc(void) {
INSIST(nsstats_xmldesc[i] != NULL);
for (i = 0; i < dns_resstatscounter_max; i++)
INSIST(resstats_xmldesc[i] != NULL);
for (i = 0; i < dns_adbstats_max; i++)
INSIST(adbstats_xmldesc[i] != NULL);
for (i = 0; i < dns_zonestatscounter_max; i++)
INSIST(zonestats_xmldesc[i] != NULL);
for (i = 0; i < isc_sockstatscounter_max; i++)
@ -442,7 +482,7 @@ generalstat_dump(isc_statscounter_t counter, isc_uint64_t val, void *arg) {
}
static isc_result_t
dump_counters(isc_stats_t *stats, statsformat_t type, void *arg,
dump_counters(isc_stats_t *stats, isc_statsformat_t type, void *arg,
const char *category, const char **desc, int ncounters,
int *indices, isc_uint64_t *values, int options)
{
@ -475,12 +515,12 @@ dump_counters(isc_stats_t *stats, statsformat_t type, void *arg,
continue;
switch (dumparg.type) {
case statsformat_file:
case isc_statsformat_file:
fp = arg;
fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n",
value, desc[index]);
break;
case statsformat_xml:
case isc_statsformat_xml:
#ifdef HAVE_LIBXML2
writer = arg;
@ -542,11 +582,11 @@ rdtypestat_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) {
typestr = "Others";
switch (dumparg->type) {
case statsformat_file:
case isc_statsformat_file:
fp = dumparg->arg;
fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n", val, typestr);
break;
case statsformat_xml:
case isc_statsformat_xml:
#ifdef HAVE_LIBXML2
writer = dumparg->arg;
@ -603,12 +643,12 @@ rdatasetstats_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) {
nxrrset = ISC_TRUE;
switch (dumparg->type) {
case statsformat_file:
case isc_statsformat_file:
fp = dumparg->arg;
fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s%s\n", val,
nxrrset ? "!" : "", typestr);
break;
case statsformat_xml:
case isc_statsformat_xml:
#ifdef HAVE_LIBXML2
writer = dumparg->arg;
@ -652,11 +692,11 @@ opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) {
codebuf[isc_buffer_usedlength(&b)] = '\0';
switch (dumparg->type) {
case statsformat_file:
case isc_statsformat_file:
fp = dumparg->arg;
fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n", val, codebuf);
break;
case statsformat_xml:
case isc_statsformat_xml:
#ifdef HAVE_LIBXML2
writer = dumparg->arg;
@ -724,10 +764,10 @@ zone_xmlrender(dns_zone_t *zone, void *arg) {
zonestats = dns_zone_getrequeststats(zone);
if (zonestats != NULL) {
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
result = dump_counters(zonestats, statsformat_xml, writer, NULL,
nsstats_xmldesc, dns_nsstatscounter_max,
nsstats_index, nsstat_values,
ISC_STATSDUMP_VERBOSE);
result = dump_counters(zonestats, isc_statsformat_xml, writer,
NULL, nsstats_xmldesc,
dns_nsstatscounter_max, nsstats_index,
nsstat_values, ISC_STATSDUMP_VERBOSE);
if (result != ISC_R_SUCCESS)
goto error;
TRY0(xmlTextWriterEndElement(writer)); /* counters */
@ -750,9 +790,10 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
int xmlrc;
dns_view_t *view;
stats_dumparg_t dumparg;
dns_stats_t *cachestats;
dns_stats_t *cacherrstats;
isc_uint64_t nsstat_values[dns_nsstatscounter_max];
isc_uint64_t resstat_values[dns_resstatscounter_max];
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_result_t result;
@ -777,7 +818,7 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
ISC_XMLCHAR "2.2"));
/* Set common fields for statistics dump */
dumparg.type = statsformat_xml;
dumparg.type = isc_statsformat_xml;
dumparg.arg = writer;
/*
@ -809,9 +850,9 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
}
if (view->resstats != NULL) {
result = dump_counters(view->resstats, statsformat_xml,
writer, "resstat",
resstats_xmldesc,
result = dump_counters(view->resstats,
isc_statsformat_xml, writer,
"resstat", resstats_xmldesc,
dns_resstatscounter_max,
resstats_index, resstat_values,
ISC_STATSDUMP_VERBOSE);
@ -819,8 +860,8 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
goto error;
}
cachestats = dns_db_getrrsetstats(view->cachedb);
if (cachestats != NULL) {
cacherrstats = dns_db_getrrsetstats(view->cachedb);
if (cacherrstats != NULL) {
TRY0(xmlTextWriterStartElement(writer,
ISC_XMLCHAR "cache"));
TRY0(xmlTextWriterWriteAttribute(writer,
@ -828,13 +869,29 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
ISC_XMLCHAR
dns_cache_getname(view->cache)));
dumparg.result = ISC_R_SUCCESS;
dns_rdatasetstats_dump(cachestats, rdatasetstats_dump,
dns_rdatasetstats_dump(cacherrstats, rdatasetstats_dump,
&dumparg, 0);
if (dumparg.result != ISC_R_SUCCESS)
goto error;
TRY0(xmlTextWriterEndElement(writer)); /* cache */
}
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR
"cachestats"));
dns_cache_renderxml(view->cache, writer);
TRY0(xmlTextWriterEndElement(writer)); /* cachestats */
if (view->adbstats != NULL) {
result = dump_counters(view->adbstats,
isc_statsformat_xml, writer,
"adbstat", adbstats_xmldesc,
dns_adbstats_max,
adbstats_index, adbstat_values,
ISC_STATSDUMP_VERBOSE);
if (result != ISC_R_SUCCESS)
goto error;
}
TRY0(xmlTextWriterEndElement(writer)); /* view */
view = ISC_LIST_NEXT(view, link);
@ -873,7 +930,7 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
goto error;
TRY0(xmlTextWriterEndElement(writer)); /* queries-in */
result = dump_counters(server->nsstats, statsformat_xml, writer,
result = dump_counters(server->nsstats, isc_statsformat_xml, writer,
"nsstat", nsstats_xmldesc,
dns_nsstatscounter_max,
nsstats_index, nsstat_values,
@ -881,7 +938,7 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
if (result != ISC_R_SUCCESS)
goto error;
result = dump_counters(server->zonestats, statsformat_xml, writer,
result = dump_counters(server->zonestats, isc_statsformat_xml, writer,
"zonestat", zonestats_xmldesc,
dns_zonestatscounter_max, zonestats_index,
zonestat_values, ISC_STATSDUMP_VERBOSE);
@ -892,14 +949,14 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
* Most of the common resolver statistics entries are 0, so we don't
* use the verbose dump here.
*/
result = dump_counters(server->resolverstats, statsformat_xml, writer,
result = dump_counters(server->resolverstats, isc_statsformat_xml, writer,
"resstat", resstats_xmldesc,
dns_resstatscounter_max, resstats_index,
resstat_values, 0);
if (result != ISC_R_SUCCESS)
goto error;
result = dump_counters(server->sockstats, statsformat_xml, writer,
result = dump_counters(server->sockstats, isc_statsformat_xml, writer,
"sockstat", sockstats_xmldesc,
isc_sockstatscounter_max, sockstats_index,
sockstat_values, ISC_STATSDUMP_VERBOSE);
@ -1332,13 +1389,14 @@ ns_stats_dump(ns_server_t *server, FILE *fp) {
stats_dumparg_t dumparg;
isc_uint64_t nsstat_values[dns_nsstatscounter_max];
isc_uint64_t resstat_values[dns_resstatscounter_max];
isc_uint64_t adbstat_values[dns_adbstats_max];
isc_uint64_t zonestat_values[dns_zonestatscounter_max];
isc_uint64_t sockstat_values[isc_sockstatscounter_max];
RUNTIME_CHECK(isc_once_do(&once, init_desc) == ISC_R_SUCCESS);
/* Set common fields */
dumparg.type = statsformat_file;
dumparg.type = isc_statsformat_file;
dumparg.arg = fp;
isc_stdtime_get(&now);
@ -1366,19 +1424,19 @@ ns_stats_dump(ns_server_t *server, FILE *fp) {
}
fprintf(fp, "++ Name Server Statistics ++\n");
(void) dump_counters(server->nsstats, statsformat_file, fp, NULL,
(void) dump_counters(server->nsstats, isc_statsformat_file, fp, NULL,
nsstats_desc, dns_nsstatscounter_max,
nsstats_index, nsstat_values, 0);
fprintf(fp, "++ Zone Maintenance Statistics ++\n");
(void) dump_counters(server->zonestats, statsformat_file, fp, NULL,
(void) dump_counters(server->zonestats, isc_statsformat_file, fp, NULL,
zonestats_desc, dns_zonestatscounter_max,
zonestats_index, zonestat_values, 0);
fprintf(fp, "++ Resolver Statistics ++\n");
fprintf(fp, "[Common]\n");
(void) dump_counters(server->resolverstats, statsformat_file, fp, NULL,
resstats_desc, dns_resstatscounter_max,
(void) dump_counters(server->resolverstats, isc_statsformat_file, fp,
NULL, resstats_desc, dns_resstatscounter_max,
resstats_index, resstat_values, 0);
for (view = ISC_LIST_HEAD(server->viewlist);
view != NULL;
@ -1389,19 +1447,37 @@ ns_stats_dump(ns_server_t *server, FILE *fp) {
fprintf(fp, "[View: default]\n");
else
fprintf(fp, "[View: %s]\n", view->name);
(void) dump_counters(view->resstats, statsformat_file, fp, NULL,
resstats_desc, dns_resstatscounter_max,
resstats_index, resstat_values, 0);
(void) dump_counters(view->resstats, isc_statsformat_file, fp,
NULL, resstats_desc,
dns_resstatscounter_max, resstats_index,
resstat_values, 0);
}
fprintf(fp, "++ Cache Statistics ++\n");
for (view = ISC_LIST_HEAD(server->viewlist);
view != NULL;
view = ISC_LIST_NEXT(view, link)) {
if (strcmp(view->name, "_default") == 0)
fprintf(fp, "[View: default]\n");
else
fprintf(fp, "[View: %s (Cache: %s)]\n", view->name,
dns_cache_getname(view->cache));
/*
* Avoid dumping redundant statistics when the cache is shared.
*/
if (dns_view_iscacheshared(view))
continue;
dns_cache_dumpstats(view->cache, fp);
}
fprintf(fp, "++ Cache DB RRsets ++\n");
for (view = ISC_LIST_HEAD(server->viewlist);
view != NULL;
view = ISC_LIST_NEXT(view, link)) {
dns_stats_t *cachestats;
dns_stats_t *cacherrstats;
cachestats = dns_db_getrrsetstats(view->cachedb);
if (cachestats == NULL)
cacherrstats = dns_db_getrrsetstats(view->cachedb);
if (cacherrstats == NULL)
continue;
if (strcmp(view->name, "_default") == 0)
fprintf(fp, "[View: default]\n");
@ -1415,12 +1491,27 @@ ns_stats_dump(ns_server_t *server, FILE *fp) {
*/
continue;
}
dns_rdatasetstats_dump(cachestats, rdatasetstats_dump, &dumparg,
0);
dns_rdatasetstats_dump(cacherrstats, rdatasetstats_dump,
&dumparg, 0);
}
fprintf(fp, "++ ADB stats ++\n");
for (view = ISC_LIST_HEAD(server->viewlist);
view != NULL;
view = ISC_LIST_NEXT(view, link)) {
if (view->adbstats == NULL)
continue;
if (strcmp(view->name, "_default") == 0)
fprintf(fp, "[View: default]\n");
else
fprintf(fp, "[View: %s]\n", view->name);
(void) dump_counters(view->adbstats, isc_statsformat_file, fp,
NULL, adbstats_desc, dns_adbstats_max,
adbstats_index, adbstat_values, 0);
}
fprintf(fp, "++ Socket I/O Statistics ++\n");
(void) dump_counters(server->sockstats, statsformat_file, fp, NULL,
(void) dump_counters(server->sockstats, isc_statsformat_file, fp, NULL,
sockstats_desc, isc_sockstatscounter_max,
sockstats_index, sockstat_values, 0);
@ -1443,8 +1534,8 @@ ns_stats_dump(ns_server_t *server, FILE *fp) {
fprintf(fp, " (view: %s)", view->name);
fprintf(fp, "]\n");
(void) dump_counters(zonestats, statsformat_file, fp,
NULL, nsstats_desc,
(void) dump_counters(zonestats, isc_statsformat_file,
fp, NULL, nsstats_desc,
dns_nsstatscounter_max,
nsstats_index, nsstat_values, 0);
}

View file

@ -57,8 +57,8 @@ SUBDIRS="acl allow_query addzone autosign builtin cacheclean checkconf
dname dns64 dnssec forward glue gost ixfr inline limits
logfileconfig lwresd masterfile masterformat metadata notify
nsupdate pending pkcs11 redirect resolver rndc rpz rrsetorder
sortlist smartsign staticstub stub tkey tsig tsiggss unknown
upforwd views xfer xferquota zonechecks"
sortlist smartsign staticstub statistics stub tkey tsig tsiggss
unknown upforwd views xfer xferquota zonechecks"
# PERL will be an empty string if no perl interpreter was found.
PERL=@PERL@

View file

@ -14,7 +14,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: tests.sh,v 1.4 2011/06/10 01:32:37 each Exp $
# $Id: tests.sh,v 1.4.154.1 2012/01/04 20:05:03 smann Exp $
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
@ -225,5 +225,13 @@ $DIGCMD frozen.nil. TXT | grep 'frozen addition' >/dev/null || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
# temp test
echo "I:dumping stats"
$RNDCCMD stats
echo "I: verifying adb records in named.stats"
grep "ADB stats" ns2/named.stats > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I:exit status: $status"
exit $status

View file

@ -0,0 +1,113 @@
#!/usr/bin/perl -w
#
# Copyright (C) 2004, 2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000, 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id$
#
# Ad hoc name server
#
use IO::File;
use IO::Socket;
use Net::DNS;
use Net::DNS::Packet;
my $sock = IO::Socket::INET->new(LocalAddr => "10.53.0.4",
LocalPort => 5300, Proto => "udp") or die "$!";
my $pidf = new IO::File "ans.pid", "w" or die "cannot open pid file: $!";
print $pidf "$$\n" or die "cannot write pid file: $!";
$pidf->close or die "cannot close pid file: $!";
sub rmpid { unlink "ans.pid"; exit 1; };
$SIG{INT} = \&rmpid;
$SIG{TERM} = \&rmpid;
for (;;) {
$sock->recv($buf, 512);
print "**** request from " , $sock->peerhost, " port ", $sock->peerport, "\n";
my ($packet, $err) = new Net::DNS::Packet(\$buf, 0);
$err and die $err;
print "REQUEST:\n";
$packet->print;
$packet->header->qr(1);
my @questions = $packet->question;
my $qname = $questions[0]->qname;
my $qtype = $questions[0]->qtype;
my $donotrespond = 0;
if ($qname eq "foo.info") {
$donotrespond = 1;
} elsif ($qname eq "cname1.example.com") {
# Data for the "cname + other data / 1" test
$packet->push("answer", new Net::DNS::RR("cname1.example.com 300 CNAME cname1.example.com"));
$packet->push("answer", new Net::DNS::RR("cname1.example.com 300 A 1.2.3.4"));
} elsif ($qname eq "cname2.example.com") {
# Data for the "cname + other data / 2" test: same RRs in opposite order
$packet->push("answer", new Net::DNS::RR("cname2.example.com 300 A 1.2.3.4"));
$packet->push("answer", new Net::DNS::RR("cname2.example.com 300 CNAME cname2.example.com"));
} elsif ($qname eq "www.example.org" || $qname eq "www.example.net" ||
$qname eq "badcname.example.org" ||
$qname eq "goodcname.example.org" ||
$qname eq "foo.baddname.example.org" ||
$qname eq "foo.gooddname.example.org") {
# Data for address/alias filtering.
$packet->header->aa(1);
if ($qtype eq "A") {
$packet->push("answer",
new Net::DNS::RR($qname .
" 300 A 192.0.2.1"));
} elsif ($qtype eq "AAAA") {
$packet->push("answer",
new Net::DNS::RR($qname .
" 300 AAAA 2001:db8:beef::1"));
}
} elsif ($qname eq "badcname.example.net" ||
$qname eq "goodcname.example.net") {
# Data for CNAME/DNAME filtering. We need to make one-level
# delegation to avoid automatic acceptance for subdomain aliases
$packet->push("authority", new Net::DNS::RR("example.net 300 NS ns.example.net"));
$packet->push("additional", new Net::DNS::RR("ns.example.net 300 A 10.53.0.3"));
} elsif ($qname =~ /^nodata\.example\.net$/i) {
$packet->header->aa(1);
} elsif ($qname =~ /^nxdomain\.example\.net$/i) {
$packet->header->aa(1);
$packet->header->rcode(NXDOMAIN);
} elsif ($qname =~ /sub\.example\.org/) {
# Data for CNAME/DNAME filtering. The final answers are
# expected to be accepted regardless of the filter setting.
$packet->push("authority", new Net::DNS::RR("sub.example.org 300 NS ns.sub.example.org"));
$packet->push("additional", new Net::DNS::RR("ns.sub.example.org 300 A 10.53.0.3"));
} else {
# Data for the "bogus referrals" test
$packet->push("authority", new Net::DNS::RR("below.www.example.com 300 NS ns.below.www.example.com"));
$packet->push("additional", new Net::DNS::RR("ns.below.www.example.com 300 A 10.53.0.3"));
}
if ($donotrespond == 0) {
$sock->send($packet->data);
print "RESPONSE:\n";
$packet->print;
print "\n";
}
}

View file

@ -0,0 +1,29 @@
#!/bin/sh
#
# Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000, 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id$
#
# Clean up after zone transfer tests.
#
rm -f ns3/example.bk
rm -f ns3/internal.bk
rm -f */named.memstats
rm -f */named.run
rm -f */named.stats
rm -f dig.out*

View file

@ -0,0 +1,42 @@
/*
* Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id$ */
controls { /* empty */ };
options {
query-source address 10.53.0.1;
notify-source 10.53.0.1;
transfer-source 10.53.0.1;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.1; };
listen-on-v6 { none; };
recursion no;
notify yes;
};
zone "." {
type master;
file "root.db";
};
zone "example.info." {
type master;
file "example-info.db";
};

View file

@ -0,0 +1,30 @@
; Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
; Copyright (C) 2000, 2001 Internet Software Consortium.
;
; Permission to use, copy, modify, and/or distribute this software for any
; purpose with or without fee is hereby granted, provided that the above
; copyright notice and this permission notice appear in all copies.
;
; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
; $Id$
$TTL 300
. IN SOA gson.nominum.com. a.root.servers.nil. (
2000042100 ; serial
600 ; refresh
600 ; retry
1200 ; expire
600 ; minimum
)
. NS a.root-servers.nil.
a.root-servers.nil. A 10.53.0.1
example. NS ns2.example.
ns2.example. A 10.53.0.2

View file

@ -0,0 +1,34 @@
; Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
; Copyright (C) 2000, 2001 Internet Software Consortium.
;
; Permission to use, copy, modify, and/or distribute this software for any
; purpose with or without fee is hereby granted, provided that the above
; copyright notice and this permission notice appear in all copies.
;
; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
; $Id: example.db,v 1.1.2.1 2012/01/06 22:40:47 smann Exp $
$ORIGIN .
$TTL 300 ; 5 minutes
example IN SOA mname1. . (
1 ; serial
20 ; refresh (20 seconds)
20 ; retry (20 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
example. NS ns2.example.
ns2.example. A 10.53.0.2
$ORIGIN example.
a A 10.0.0.1
MX 10 mail.example.
mail A 10.0.0.2

View file

@ -0,0 +1,36 @@
; Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
; Copyright (C) 2000, 2001 Internet Software Consortium.
;
; Permission to use, copy, modify, and/or distribute this software for any
; purpose with or without fee is hereby granted, provided that the above
; copyright notice and this permission notice appear in all copies.
;
; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
; $Id: internal.db,v 1.1.2.1 2012/01/06 22:40:47 smann Exp $
$ORIGIN .
$TTL 300 ; 5 minutes
example IN SOA mname1. . (
2 ; serial
20 ; refresh (20 seconds)
20 ; retry (20 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
example. NS ns2.example.
ns2.example. A 10.53.0.2
example. NS ns3.example.
ns3.example. A 10.53.0.3
$ORIGIN example.
a A 10.1.0.1
MX 10 intmail.example.
intmail A 10.1.0.2

View file

@ -0,0 +1,47 @@
/*
* Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id$ */
controls { /* empty */ };
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion yes;
notify yes;
};
#statistics-channels { inet * port 8888 allow { any; }; };
include "../../common/controls.conf";
zone "." {
type hint;
file "../../common/root.hint";
};
zone "example" {
type master;
file "example.db";
allow-update { any; };
};

View file

@ -0,0 +1,34 @@
; Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
; Copyright (C) 2000, 2001 Internet Software Consortium.
;
; Permission to use, copy, modify, and/or distribute this software for any
; purpose with or without fee is hereby granted, provided that the above
; copyright notice and this permission notice appear in all copies.
;
; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
; $Id$
$ORIGIN .
$TTL 300 ; 5 minutes
example IN SOA mname1. . (
1 ; serial
20 ; refresh (20 seconds)
20 ; retry (20 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
example. NS ns3.example.
ns3.example. A 10.53.0.3
$ORIGIN example.
a A 10.1.0.1
MX 10 intmail.example.
intmail A 10.1.0.2

View file

@ -0,0 +1,57 @@
/*
* Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id$ */
controls { /* empty */ };
options {
query-source address 10.53.0.3;
notify-source 10.53.0.3;
transfer-source 10.53.0.3;
port 5300;
directory ".";
pid-file "named.pid";
listen-on { 10.53.0.3; };
listen-on-v6 { none; };
recursion yes;
notify yes;
};
#statistics-channels { inet * port 8888 allow { any; }; };
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
};
controls {
inet 10.53.0.3 port 9953 allow { any; } keys { rndc_key; };
};
zone "." {
type hint;
file "root.hint";
};
zone "example" {
type master;
allow-update { any; };
file "internal.db";
};

View file

@ -0,0 +1,20 @@
; Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
; Copyright (C) 2000, 2001 Internet Software Consortium.
;
; Permission to use, copy, modify, and/or distribute this software for any
; purpose with or without fee is hereby granted, provided that the above
; copyright notice and this permission notice appear in all copies.
;
; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
; $Id$
$TTL 999999
. IN NS d.root-servers.nil.
d.root-servers.nil. IN A 10.53.0.4

View file

@ -0,0 +1,108 @@
#!/bin/sh
#
# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000, 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: tests.sh,v 1.1.4.11 2012/02/01 16:54:32 each Exp $
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
DIGOPTS="+tcp +noadd +nosea +nostat +noquest +nocomm +nocmd"
DIGCMD="$DIG $DIGOPTS -p 5300"
RNDCCMD="$RNDC -p 9953 -c ../common/rndc.conf"
status=0
ret=0
echo "I:fetching a.example from ns2's initial configuration"
$DIGCMD +noauth a.example. @10.53.0.2 any > dig.out.ns2.1 || ret=1
if [ $ret != 0 ]; then echo "I: failed"; fi
status=`expr $status + $ret`
ret=0
echo "I:verifying adb records in named.stats"
$RNDCCMD -s 10.53.0.2 stats > /dev/null 2>&1
echo "I: checking for 1 entry in adb hash table"
grep "1 Addresses in hash table" ns2/named.stats > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
ret=0
echo "I: verifying cache statistics in named.stats"
grep "Cache Statistics" ns2/named.stats > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
ret=0
echo "I: checking for 2 entries in adb hash table"
$DIGCMD a.example.info. @10.53.0.2 any > /dev/null 2>&1
$RNDCCMD -s 10.53.0.2 stats > /dev/null 2>&1
grep "2 Addresses in hash table" ns2/named.stats > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I: failed"; fi
status=`expr $status + $ret`
ret=0
echo "I:dumping initial stats for ns3"
rm -f ns3/named.stats
$RNDCCMD -s 10.53.0.3 stats > /dev/null 2>&1
[ -f ns3/named.stats ] || ret=1
nsock0=`grep "UDP/IPv4 sockets active" ns3/named.stats | awk '{print $1}'`
echo "I:sending queries to ns3"
$DIGCMD +tries=2 +time=1 +recurse @10.53.0.3 foo.info. any > /dev/null 2>&1
#$DIGCMD +tries=2 +time=1 +recurse @10.53.0.3 foo.info. any
echo "I:dumping updated stats for ns3"
rm -f ns3/named.stats
$RNDCCMD -s 10.53.0.3 stats > /dev/null 2>&1
[ -f ns3/named.stats ] || ret=1
if [ $ret != 0 ]; then echo "I: failed"; fi
status=`expr $status + $ret`
ret=0
echo "I: verifying recursing clients output"
grep "2 recursing clients" ns3/named.stats > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I: failed"; fi
status=`expr $status + $ret`
ret=0
echo "I: verifying active fetches output"
grep "1 active fetches" ns3/named.stats > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I: failed"; fi
status=`expr $status + $ret`
ret=0
echo "I: verifying active sockets output"
nsock1=`grep "UDP/IPv4 sockets active" ns3/named.stats | awk '{print $1}'`
[ "$nsock0" -eq 2 ] || ret=1
[ "$nsock1" -eq 3 ] || ret=1
if [ $ret != 0 ]; then echo "I: failed"; fi
status=`expr $status + $ret`
ret=0
# there should be 1 UDP and no TCP queries. As the TCP counter is zero
# no status line is emitted.
echo "I: verifying queries in progress"
grep "1 UDP queries in progress" ns3/named.stats > /dev/null || ret=1
grep "TCP queries in progress" ns3/named.stats > /dev/null && ret=1
if [ $ret != 0 ]; then echo "I: failed"; fi
status=`expr $status + $ret`
ret=0
echo "I: verifying bucket size output"
grep "bucket size" ns3/named.stats > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I: failed"; fi
status=`expr $status + $ret`
echo "I:exit status: $status"
exit $status

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: adb.c,v 1.264 2011/12/05 17:10:51 each Exp $ */
/* $Id: adb.c,v 1.264.16.1 2011/12/22 07:48:27 marka Exp $ */
/*! \file
*
@ -474,6 +474,27 @@ inc_stats(dns_adb_t *adb, isc_statscounter_t counter) {
isc_stats_increment(adb->view->resstats, counter);
}
/*%
* Set adb-related statistics counters.
*/
static inline void
set_adbstat(dns_adb_t *adb, isc_uint64_t val, isc_statscounter_t counter) {
if (adb->view->adbstats != NULL)
isc_stats_set(adb->view->adbstats, val, counter);
}
static inline void
dec_adbstats(dns_adb_t *adb, isc_statscounter_t counter) {
if (adb->view->adbstats != NULL)
isc_stats_increment(adb->view->adbstats, counter);
}
static inline void
inc_adbstats(dns_adb_t *adb, isc_statscounter_t counter) {
if (adb->view->adbstats != NULL)
isc_stats_increment(adb->view->adbstats, counter);
}
static inline dns_ttl_t
ttlclamp(dns_ttl_t ttl) {
if (ttl < ADB_CACHE_MINIMUM)
@ -619,6 +640,8 @@ grow_entries(isc_task_t *task, isc_event_t *ev) {
adb->entry_refcnt = newentry_refcnt;
adb->nentries = n;
set_adbstat(adb, adb->nentries, dns_adbstats_nentries);
/*
* Only on success do we set adb->growentries_sent to ISC_FALSE.
* This will prevent us being continuously being called on error.
@ -771,6 +794,8 @@ grow_names(isc_task_t *task, isc_event_t *ev) {
adb->name_refcnt = newname_refcnt;
adb->nnames = n;
set_adbstat(adb, adb->nnames, dns_adbstats_nnames);
/*
* Only on success do we set adb->grownames_sent to ISC_FALSE.
* This will prevent us being continuously being called on error.
@ -1627,6 +1652,7 @@ new_adbname(dns_adb_t *adb, dns_name_t *dnsname) {
LOCK(&adb->namescntlock);
adb->namescnt++;
inc_adbstats(adb, dns_adbstats_namescnt);
if (!adb->grownames_sent && adb->namescnt > (adb->nnames * 8)) {
isc_event_t *event = &adb->grownames;
inc_adb_irefcnt(adb);
@ -1660,6 +1686,7 @@ free_adbname(dns_adb_t *adb, dns_adbname_t **name) {
isc_mempool_put(adb->nmp, n);
LOCK(&adb->namescntlock);
adb->namescnt--;
dec_adbstats(adb, dns_adbstats_namescnt);
UNLOCK(&adb->namescntlock);
}
@ -1751,6 +1778,7 @@ new_adbentry(dns_adb_t *adb) {
ISC_LINK_INIT(e, plink);
LOCK(&adb->entriescntlock);
adb->entriescnt++;
inc_adbstats(adb, dns_adbstats_entriescnt);
if (!adb->growentries_sent &&
adb->entriescnt > (adb->nentries * 8)) {
isc_event_t *event = &adb->growentries;
@ -1788,6 +1816,7 @@ free_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) {
isc_mempool_put(adb->emp, e);
LOCK(&adb->entriescntlock);
adb->entriescnt--;
dec_adbstats(adb, dns_adbstats_entriescnt);
UNLOCK(&adb->entriescntlock);
}
@ -2559,6 +2588,12 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
goto fail3;
isc_task_setname(adb->task, "ADB", adb);
result = isc_stats_create(adb->mctx, &view->adbstats, dns_adbstats_max);
if (result != ISC_R_SUCCESS)
goto fail3;
set_adbstat(adb, adb->nentries, dns_adbstats_nentries);
set_adbstat(adb, adb->nnames, dns_adbstats_nnames);
/*
* Normal return.
*/

View file

@ -22,7 +22,9 @@
#include <config.h>
#include <isc/mem.h>
#include <isc/print.h>
#include <isc/string.h>
#include <isc/stats.h>
#include <isc/task.h>
#include <isc/time.h>
#include <isc/timer.h>
@ -39,6 +41,7 @@
#include <dns/rdataset.h>
#include <dns/rdatasetiter.h>
#include <dns/result.h>
#include <dns/stats.h>
#include "rbtdb.h"
@ -137,6 +140,7 @@ struct dns_cache {
int db_argc;
char **db_argv;
isc_uint32_t size;
isc_stats_t *stats;
/* Locked by 'filelock'. */
char *filename;
@ -237,10 +241,16 @@ dns_cache_create3(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr,
cache->live_tasks = 0;
cache->rdclass = rdclass;
cache->stats = NULL;
result = isc_stats_create(cmctx, &cache->stats,
dns_cachestatscounter_max);
if (result != ISC_R_SUCCESS)
goto cleanup_filelock;
cache->db_type = isc_mem_strdup(cmctx, db_type);
if (cache->db_type == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup_filelock;
goto cleanup_stats;
}
/*
@ -309,6 +319,11 @@ dns_cache_create3(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr,
if (result != ISC_R_SUCCESS)
goto cleanup_db;
result = dns_db_setcachestats(cache->db, cache->stats);
if (result != ISC_R_SUCCESS)
goto cleanup_db;
*cachep = cache;
return (ISC_R_SUCCESS);
@ -325,6 +340,8 @@ dns_cache_create3(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr,
isc_mem_free(cmctx, cache->db_type);
cleanup_filelock:
DESTROYLOCK(&cache->filelock);
cleanup_stats:
isc_stats_detach(&cache->stats);
cleanup_lock:
DESTROYLOCK(&cache->lock);
cleanup_mem:
@ -387,6 +404,9 @@ cache_free(dns_cache_t *cache) {
if (cache->name != NULL)
isc_mem_free(cache->mctx, cache->name);
if (cache->stats != NULL)
isc_stats_detach(&cache->stats);
DESTROYLOCK(&cache->lock);
DESTROYLOCK(&cache->filelock);
@ -1279,3 +1299,145 @@ dns_cache_flushnode(dns_cache_t *cache, dns_name_t *name,
dns_db_detach(&db);
return (result);
}
isc_stats_t *
dns_cache_getstats(dns_cache_t *cache) {
REQUIRE(VALID_CACHE(cache));
return (cache->stats);
}
/*
* XXX: Much of the following code has been copied in from statschannel.c.
* We should refactor this into a generic function in stats.c that can be
* called from both places.
*/
typedef struct
cache_dumparg {
isc_statsformat_t type;
void *arg; /* type dependent argument */
int ncounters; /* for general statistics */
int *counterindices; /* for general statistics */
isc_uint64_t *countervalues; /* for general statistics */
isc_result_t result;
} cache_dumparg_t;
static void
getcounter(isc_statscounter_t counter, isc_uint64_t val, void *arg) {
cache_dumparg_t *dumparg = arg;
REQUIRE(counter < dumparg->ncounters);
dumparg->countervalues[counter] = val;
}
static void
getcounters(isc_stats_t *stats, isc_statsformat_t type, int ncounters,
int *indices, isc_uint64_t *values)
{
cache_dumparg_t dumparg;
memset(values, 0, sizeof(values[0]) * ncounters);
dumparg.type = type;
dumparg.ncounters = ncounters;
dumparg.counterindices = indices;
dumparg.countervalues = values;
isc_stats_dump(stats, getcounter, &dumparg, ISC_STATSDUMP_VERBOSE);
}
void
dns_cache_dumpstats(dns_cache_t *cache, FILE *fp) {
int indices[dns_cachestatscounter_max];
isc_uint64_t values[dns_cachestatscounter_max];
REQUIRE(VALID_CACHE(cache));
getcounters(cache->stats, isc_statsformat_file,
dns_cachestatscounter_max, indices, values);
fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n",
values[dns_cachestatscounter_hits],
"cache hits");
fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n",
values[dns_cachestatscounter_misses],
"cache misses");
fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n",
values[dns_cachestatscounter_queryhits],
"cache hits (from query)");
fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n",
values[dns_cachestatscounter_querymisses],
"cache misses (from query)");
fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n",
values[dns_cachestatscounter_deletelru],
"cache records deleted due to memory exhaustion");
fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n",
values[dns_cachestatscounter_deletettl],
"cache records deleted due to TTL expiration");
fprintf(fp, "%20u %s\n", dns_db_nodecount(cache->db),
"cache database nodes");
fprintf(fp, "%20u %s\n", dns_db_hashsize(cache->db),
"cache database hash buckets");
fprintf(fp, "%20u %s\n", (unsigned int) isc_mem_total(cache->mctx),
"cache tree memory total");
fprintf(fp, "%20u %s\n", (unsigned int) isc_mem_inuse(cache->mctx),
"cache tree memory in use");
fprintf(fp, "%20u %s\n", (unsigned int) isc_mem_maxinuse(cache->mctx),
"cache tree highest memory in use");
fprintf(fp, "%20u %s\n", (unsigned int) isc_mem_total(cache->hmctx),
"cache heap memory total");
fprintf(fp, "%20u %s\n", (unsigned int) isc_mem_inuse(cache->hmctx),
"cache heap memory in use");
fprintf(fp, "%20u %s\n", (unsigned int) isc_mem_maxinuse(cache->hmctx),
"cache heap highest memory in use");
}
#ifdef HAVE_LIBXML2
static void
renderstat(const char *name, isc_uint64_t value, xmlTextWriterPtr writer) {
xmlTextWriterStartElement(writer, ISC_XMLCHAR "cachestat");
xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
xmlTextWriterWriteString(writer, ISC_XMLCHAR name);
xmlTextWriterEndElement(writer); /* name */
xmlTextWriterStartElement(writer, ISC_XMLCHAR "value");
xmlTextWriterWriteFormatString(writer,
"%" ISC_PRINT_QUADFORMAT "u", value);
xmlTextWriterEndElement(writer); /* value */
xmlTextWriterEndElement(writer); /* cachestat */
}
void
dns_cache_renderxml(dns_cache_t *cache, xmlTextWriterPtr writer) {
int indices[dns_cachestatscounter_max];
isc_uint64_t values[dns_cachestatscounter_max];
REQUIRE(VALID_CACHE(cache));
getcounters(cache->stats, isc_statsformat_file,
dns_cachestatscounter_max, indices, values);
renderstat("CacheHits",
values[dns_cachestatscounter_hits], writer);
renderstat("CacheMisses",
values[dns_cachestatscounter_misses], writer);
renderstat("QueryHits",
values[dns_cachestatscounter_queryhits], writer);
renderstat("QueryMisses",
values[dns_cachestatscounter_querymisses], writer);
renderstat("DeleteLRU",
values[dns_cachestatscounter_deletelru], writer);
renderstat("DeleteTTL",
values[dns_cachestatscounter_deletettl], writer);
renderstat("CacheNodes", dns_db_nodecount(cache->db), writer);
renderstat("CacheBuckets", dns_db_hashsize(cache->db), writer);
renderstat("TreeMemTotal", isc_mem_total(cache->mctx), writer);
renderstat("TreeMemInUse", isc_mem_inuse(cache->mctx), writer);
renderstat("TreeMemMax", isc_mem_maxinuse(cache->mctx), writer);
renderstat("HeapMemTotal", isc_mem_total(cache->hmctx), writer);
renderstat("HeapMemInUse", isc_mem_inuse(cache->hmctx), writer);
renderstat("HeapMemMax", isc_mem_maxinuse(cache->hmctx), writer);
}
#endif

View file

@ -879,6 +879,16 @@ dns_db_nodecount(dns_db_t *db) {
return ((db->methods->nodecount)(db));
}
unsigned int
dns_db_hashsize(dns_db_t *db) {
REQUIRE(DNS_DB_VALID(db));
if (db->methods->hashsize == NULL)
return (ISC_R_NOTIMPLEMENTED);
return ((db->methods->hashsize)(db));
}
void
dns_db_settask(dns_db_t *db, isc_task_t *task) {
REQUIRE(DNS_DB_VALID(db));
@ -965,6 +975,16 @@ dns_db_getrrsetstats(dns_db_t *db) {
return (NULL);
}
isc_result_t
dns_db_setcachestats(dns_db_t *db, isc_stats_t *stats) {
REQUIRE(DNS_DB_VALID(db));
if (db->methods->setcachestats != NULL)
return ((db->methods->setcachestats)(db, stats));
return (ISC_R_NOTIMPLEMENTED);
}
isc_result_t
dns_db_getnsec3parameters(dns_db_t *db, dns_dbversion_t *version,
dns_hash_t *hash, isc_uint8_t *flags,

View file

@ -371,6 +371,12 @@ inc_stats(dns_dispatchmgr_t *mgr, isc_statscounter_t counter) {
isc_stats_increment(mgr->stats, counter);
}
static inline void
dec_stats(dns_dispatchmgr_t *mgr, isc_statscounter_t counter) {
if (mgr->stats != NULL)
isc_stats_decrement(mgr->stats, counter);
}
static void
dispatch_log(dns_dispatch_t *disp, int level, const char *fmt, ...)
ISC_FORMAT_PRINTF(3, 4);
@ -3360,6 +3366,10 @@ dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
ISC_LIST_APPEND(qid->qid_table[bucket], res, link);
UNLOCK(&qid->lock);
inc_stats(disp->mgr, (qid == disp->mgr->qid) ?
dns_resstatscounter_disprequdp :
dns_resstatscounter_dispreqtcp);
request_log(disp, res, LVL(90),
"attached to task %p", res->task);
@ -3377,6 +3387,10 @@ dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
disp->refcount--;
disp->requests--;
dec_stats(disp->mgr, (qid == disp->mgr->qid) ?
dns_resstatscounter_disprequdp :
dns_resstatscounter_dispreqtcp);
UNLOCK(&disp->lock);
isc_task_detach(&res->task);
isc_mempool_put(disp->mgr->rpool, res);
@ -3463,6 +3477,9 @@ dns_dispatch_removeresponse(dns_dispentry_t **resp,
INSIST(disp->requests > 0);
disp->requests--;
dec_stats(disp->mgr, (qid == disp->mgr->qid) ?
dns_resstatscounter_disprequdp :
dns_resstatscounter_dispreqtcp);
INSIST(disp->refcount > 0);
disp->refcount--;
if (disp->refcount == 0) {

View file

@ -578,7 +578,9 @@ static dns_dbmethods_t ecdb_methods = {
NULL, /* rpz_enabled */
NULL, /* rpz_findips */
NULL, /* findnodeext */
NULL /* findext */
NULL, /* findext */
NULL, /* setcachestats */
NULL /* hashsize */
};
static isc_result_t

View file

@ -50,6 +50,7 @@
***/
#include <isc/lang.h>
#include <isc/stats.h>
#include <isc/stdtime.h>
#include <dns/types.h>
@ -312,6 +313,26 @@ dns_cache_flushname(dns_cache_t *cache, dns_name_t *name);
*\li other error returns.
*/
isc_stats_t *
dns_cache_getstats(dns_cache_t *cache);
/*
* Return a pointer to the stats collection object for 'cache'
*/
void
dns_cache_dumpstats(dns_cache_t *cache, FILE *fp);
/*
* Dump cache statistics and status in text to 'fp'
*/
#ifdef HAVE_LIBXML2
void
dns_cache_renderxml(dns_cache_t *cache, xmlTextWriterPtr writer);
/*
* Render cache statistics and status in XML for 'writer'.
*/
#endif /* HAVE_LIBXML2 */
ISC_LANG_ENDDECLS
#endif /* DNS_CACHE_H */

View file

@ -57,6 +57,7 @@
#include <isc/lang.h>
#include <isc/magic.h>
#include <isc/ondestroy.h>
#include <isc/stats.h>
#include <isc/stdtime.h>
#include <dns/clientinfo.h>
@ -194,6 +195,8 @@ typedef struct dns_dbmethods {
dns_clientinfo_t *clientinfo,
dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset);
isc_result_t (*setcachestats)(dns_db_t *db, isc_stats_t *stats);
unsigned int (*hashsize)(dns_db_t *db);
} dns_dbmethods_t;
typedef isc_result_t
@ -1337,6 +1340,21 @@ dns_db_nodecount(dns_db_t *db);
* \li The number of nodes in the database
*/
unsigned int
dns_db_hashsize(dns_db_t *db);
/*%<
* For database implementations using a hash table, report the
* current number of buckets.
*
* Requires:
*
* \li 'db' is a valid database.
*
* Returns:
* \li The number of buckets in the database's hash table, or
* ISC_R_NOTIMPLEMENTED.
*/
void
dns_db_settask(dns_db_t *db, isc_task_t *task);
/*%<
@ -1531,7 +1549,22 @@ dns_db_getrrsetstats(dns_db_t *db);
*
* Requires:
*
* \li 'db' is a valid database (zone or cache).
* \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_result_t
dns_db_setcachestats(dns_db_t *db, isc_stats_t *stats);
/*%<
* Set the location in which to collect 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

View file

@ -632,6 +632,15 @@ dns_rbt_nodecount(dns_rbt_t *rbt);
* \li rbt is a valid rbt manager.
*/
unsigned int
dns_rbt_hashsize(dns_rbt_t *rbt);
/*%<
* Obtain the current number of buckets in the 'rbt' hash table.
*
* Requires:
* \li rbt is a valid rbt manager.
*/
void
dns_rbt_destroy(dns_rbt_t **rbtp);
isc_result_t

View file

@ -61,8 +61,12 @@ enum {
dns_resstatscounter_queryrtt3 = 27,
dns_resstatscounter_queryrtt4 = 28,
dns_resstatscounter_queryrtt5 = 29,
dns_resstatscounter_nfetch = 30,
dns_resstatscounter_disprequdp = 31,
dns_resstatscounter_dispreqtcp = 32,
dns_resstatscounter_buckets = 33,
dns_resstatscounter_max = 30,
dns_resstatscounter_max = 34,
/*%
* Zone statistics counters.
@ -83,9 +87,31 @@ enum {
dns_zonestatscounter_max = 13,
/*
* Adb statistics values.
*/
dns_adbstats_nentries = 0,
dns_adbstats_entriescnt = 1,
dns_adbstats_nnames = 2,
dns_adbstats_namescnt = 3,
dns_adbstats_max = 4,
/*
* Cache statistics values.
*/
dns_cachestatscounter_hits = 1,
dns_cachestatscounter_misses = 2,
dns_cachestatscounter_queryhits = 3,
dns_cachestatscounter_querymisses = 4,
dns_cachestatscounter_deletelru = 5,
dns_cachestatscounter_deletettl = 6,
dns_cachestatscounter_max = 7,
/*%
* Query statistics counters (obsolete).
*/
* Query statistics counters (obsolete).
*/
dns_statscounter_success = 0, /*%< Successful lookup */
dns_statscounter_referral = 1, /*%< Referral result */
dns_statscounter_nxrrset = 2, /*%< NXRRSET result */

View file

@ -108,6 +108,7 @@ struct dns_view {
isc_event_t resevent;
isc_event_t adbevent;
isc_event_t reqevent;
isc_stats_t * adbstats;
isc_stats_t * resstats;
dns_stats_t * resquerystats;
isc_boolean_t cacheshared;
@ -953,6 +954,31 @@ dns_view_freezezones(dns_view_t *view, isc_boolean_t freeze);
* \li 'view' is valid.
*/
void
dns_view_setadbstats(dns_view_t *view, isc_stats_t *stats);
/*%<
* Set a adb statistics set 'stats' for 'view'.
*
* Requires:
* \li 'view' is valid and is not frozen.
*
*\li stats is a valid statistics supporting adb statistics
* (see dns/stats.h).
*/
void
dns_view_getadbstats(dns_view_t *view, isc_stats_t **statsp);
/*%<
* Get the adb statistics counter set for 'view'. If a statistics set is
* set '*statsp' will be attached to the set; otherwise, '*statsp' will be
* untouched.
*
* Requires:
* \li 'view' is valid and is not frozen.
*
*\li 'statsp' != NULL && '*statsp' != NULL
*/
void
dns_view_setresstats(dns_view_t *view, isc_stats_t *stats);
/*%<

View file

@ -310,6 +310,12 @@ dns_rbt_nodecount(dns_rbt_t *rbt) {
return (rbt->nodecount);
}
unsigned int
dns_rbt_hashsize(dns_rbt_t *rbt) {
REQUIRE(VALID_RBT(rbt));
return (rbt->hashsize);
}
static inline isc_result_t
chain_name(dns_rbtnodechain_t *chain, dns_name_t *name,
isc_boolean_t include_chain_end)

View file

@ -367,6 +367,13 @@ typedef enum {
typedef struct dns_rbtdb dns_rbtdb_t;
/* Reason for expiring a record from cache */
typedef enum {
expire_lru,
expire_ttl,
expire_flush
} expire_t;
typedef struct rbtdb_version {
/* Not locked */
rbtdb_serial_t serial;
@ -411,6 +418,7 @@ struct dns_rbtdb {
rbtdb_nodelock_t * node_locks;
dns_rbtnode_t * origin_node;
dns_stats_t * rrsetstats; /* cache DB only */
isc_stats_t * cachestats; /* cache DB only */
/* Locked by lock. */
unsigned int active;
isc_refcount_t references;
@ -530,7 +538,7 @@ static inline isc_boolean_t need_headerupdate(rdatasetheader_t *header,
static void update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
isc_stdtime_t now);
static void expire_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
isc_boolean_t tree_locked);
isc_boolean_t tree_locked, expire_t reason);
static void overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start,
isc_stdtime_t now, isc_boolean_t tree_locked);
static isc_result_t resign_insert(dns_rbtdb_t *rbtdb, int idx,
@ -695,6 +703,26 @@ free_rbtdb_callback(isc_task_t *task, isc_event_t *event) {
free_rbtdb(rbtdb, ISC_TRUE, event);
}
static void
update_cachestats(dns_rbtdb_t *rbtdb, isc_result_t result) {
INSIST(IS_CACHE(rbtdb));
switch (result) {
case ISC_R_SUCCESS:
case DNS_R_CNAME:
case DNS_R_DNAME:
case DNS_R_DELEGATION:
case DNS_R_NCACHENXDOMAIN:
case DNS_R_NCACHENXRRSET:
isc_stats_increment(rbtdb->cachestats,
dns_cachestatscounter_hits);
break;
default:
isc_stats_increment(rbtdb->cachestats,
dns_cachestatscounter_misses);
}
}
static void
update_rrsetstats(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
isc_boolean_t increment)
@ -968,6 +996,8 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) {
if (rbtdb->rrsetstats != NULL)
dns_stats_detach(&rbtdb->rrsetstats);
if (rbtdb->cachestats != NULL)
isc_stats_detach(&rbtdb->cachestats);
#ifdef BIND9
if (rbtdb->rpz_cidr != NULL)
@ -5102,6 +5132,7 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
dns_rbtnodechain_reset(&search.chain);
update_cachestats(search.rbtdb, result);
return (result);
}
@ -5711,6 +5742,8 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
result = DNS_R_NCACHENXRRSET;
}
update_cachestats(rbtdb, result);
return (result);
}
@ -6542,7 +6575,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
header = isc_heap_element(rbtdb->heaps[rbtnode->locknum], 1);
if (header && header->rdh_ttl <= now - RBTDB_VIRTUAL)
expire_header(rbtdb, header, tree_locked);
expire_header(rbtdb, header, tree_locked,
expire_ttl);
/*
* If we've been holding a write lock on the tree just for
@ -7172,6 +7206,22 @@ nodecount(dns_db_t *db) {
return (count);
}
static unsigned int
hashsize(dns_db_t *db) {
dns_rbtdb_t *rbtdb;
unsigned int count;
rbtdb = (dns_rbtdb_t *)db;
REQUIRE(VALID_RBTDB(rbtdb));
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
count = dns_rbt_hashsize(rbtdb->tree);
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
return (count);
}
static void
settask(dns_db_t *db, isc_task_t *task) {
dns_rbtdb_t *rbtdb;
@ -7390,6 +7440,18 @@ resigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version)
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
}
static isc_result_t
setcachestats(dns_db_t *db, isc_stats_t *stats) {
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
REQUIRE(VALID_RBTDB(rbtdb));
REQUIRE(IS_CACHE(rbtdb)); /* current restriction */
REQUIRE(stats != NULL);
isc_stats_attach(stats, &rbtdb->cachestats);
return (ISC_R_SUCCESS);
}
static dns_stats_t *
getrrsetstats(dns_db_t *db) {
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
@ -7445,7 +7507,9 @@ static dns_dbmethods_t zone_methods = {
NULL,
#endif
NULL,
NULL
NULL,
NULL,
hashsize
};
static dns_dbmethods_t cache_methods = {
@ -7488,7 +7552,9 @@ static dns_dbmethods_t cache_methods = {
NULL,
NULL,
NULL,
NULL
NULL,
setcachestats,
hashsize
};
isc_result_t
@ -7566,6 +7632,8 @@ dns_rbtdb_create
goto cleanup_tree_lock;
}
rbtdb->cachestats = NULL;
rbtdb->rrsetstats = NULL;
if (IS_CACHE(rbtdb)) {
result = dns_rdatasetstats_create(mctx, &rbtdb->rrsetstats);
@ -8106,7 +8174,7 @@ rdataset_expire(dns_rdataset_t *rdataset) {
header--;
NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
isc_rwlocktype_write);
expire_header(rbtdb, header, ISC_FALSE);
expire_header(rbtdb, header, ISC_FALSE, expire_flush);
NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
isc_rwlocktype_write);
}
@ -9283,7 +9351,8 @@ overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start,
header = isc_heap_element(rbtdb->heaps[locknum], 1);
if (header && header->rdh_ttl <= now - RBTDB_VIRTUAL) {
expire_header(rbtdb, header, tree_locked);
expire_header(rbtdb, header, tree_locked,
expire_ttl);
purgecount--;
}
@ -9300,7 +9369,8 @@ overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start,
*/
ISC_LIST_UNLINK(rbtdb->rdatasets[locknum], header,
link);
expire_header(rbtdb, header, tree_locked);
expire_header(rbtdb, header, tree_locked,
expire_lru);
purgecount--;
}
@ -9311,7 +9381,7 @@ overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start,
static void
expire_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
isc_boolean_t tree_locked)
isc_boolean_t tree_locked, expire_t reason)
{
set_ttl(rbtdb, header, 0);
header->attributes |= RDATASET_ATTR_STALE;
@ -9332,5 +9402,22 @@ expire_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
isc_rwlocktype_write,
tree_locked ? isc_rwlocktype_write :
isc_rwlocktype_none, ISC_FALSE);
if (rbtdb->cachestats == NULL)
return;
switch (reason) {
case expire_ttl:
isc_stats_increment(rbtdb->cachestats,
dns_cachestatscounter_deletettl);
break;
case expire_lru:
isc_stats_increment(rbtdb->cachestats,
dns_cachestatscounter_deletelru);
break;
default:
break;
}
}
}

View file

@ -471,6 +471,12 @@ inc_stats(dns_resolver_t *res, isc_statscounter_t counter) {
isc_stats_increment(res->view->resstats, counter);
}
static inline void
dec_stats(dns_resolver_t *res, isc_statscounter_t counter) {
if (res->view->resstats != NULL)
isc_stats_decrement(res->view->resstats, counter);
}
static isc_result_t
valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name,
dns_rdatatype_t type, dns_rdataset_t *rdataset,
@ -3102,6 +3108,7 @@ fctx_unlink(fetchctx_t *fctx) {
LOCK(&res->nlock);
res->nfctx--;
UNLOCK(&res->nlock);
dec_stats(res, dns_resstatscounter_nfetch);
if (res->buckets[bucketnum].exiting &&
ISC_LIST_EMPTY(res->buckets[bucketnum].fctxs))
@ -3725,6 +3732,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
LOCK(&res->nlock);
res->nfctx++;
UNLOCK(&res->nlock);
inc_stats(res, dns_resstatscounter_nfetch);
*fctxp = fctx;
@ -7475,6 +7483,9 @@ dns_resolver_create(dns_view_t *view,
res->zero_no_soa_ttl = ISC_FALSE;
res->query_timeout = DEFAULT_QUERY_TIMEOUT;
res->nbuckets = ntasks;
if (view->resstats != NULL)
isc_stats_set(view->resstats, ntasks,
dns_resstatscounter_buckets);
res->activebuckets = ntasks;
res->buckets = isc_mem_get(view->mctx,
ntasks * sizeof(fctxbucket_t));

View file

@ -1298,7 +1298,9 @@ static dns_dbmethods_t sdb_methods = {
NULL, /* rpz_enabled */
NULL, /* rpz_findips */
findnodeext,
findext
findext,
NULL, /* setcachestats */
NULL /* hashsize */
};
static isc_result_t

View file

@ -1263,7 +1263,9 @@ static dns_dbmethods_t sdlzdb_methods = {
NULL, /* rpz_enabled */
NULL, /* rpz_findips */
findnodeext,
findext
findext,
NULL, /* setcachestats */
NULL /* hashsize */
};
/*

View file

@ -22,8 +22,11 @@
#include <atf-c.h>
#include <stdio.h>
#include <unistd.h>
#include <isc/xml.h>
#include <dns/cache.h>
#include <dns/callbacks.h>
#include <dns/db.h>

View file

@ -149,6 +149,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
view->delonly = NULL;
view->rootdelonly = ISC_FALSE;
view->rootexclude = NULL;
view->adbstats = NULL;
view->resstats = NULL;
view->resquerystats = NULL;
view->cacheshared = ISC_FALSE;
@ -416,6 +417,8 @@ destroy(dns_view_t *view) {
sizeof(dns_namelist_t) * DNS_VIEW_DELONLYHASH);
view->rootexclude = NULL;
}
if (view->adbstats != NULL)
isc_stats_detach(&view->adbstats);
if (view->resstats != NULL)
isc_stats_detach(&view->resstats);
if (view->resquerystats != NULL)
@ -1682,6 +1685,24 @@ dns_view_freezezones(dns_view_t *view, isc_boolean_t value) {
}
#endif
void
dns_view_setadbstats(dns_view_t *view, isc_stats_t *stats) {
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(!view->frozen);
REQUIRE(view->adbstats == NULL);
isc_stats_attach(stats, &view->adbstats);
}
void
dns_view_getadbstats(dns_view_t *view, isc_stats_t **statsp) {
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(statsp != NULL && *statsp == NULL);
if (view->adbstats != NULL)
isc_stats_attach(view->adbstats, statsp);
}
void
dns_view_setresstats(dns_view_t *view, isc_stats_t *stats) {
REQUIRE(DNS_VIEW_VALID(view));

View file

@ -114,6 +114,7 @@ dns_db_getnsec3parameters
dns_db_getoriginnode
dns_db_getrrsetstats
dns_db_getsoaserial
dns_db_hashsize
dns_db_iscache
dns_db_isdnssec
dns_db_ispersistent
@ -132,6 +133,7 @@ dns_db_printnode
dns_db_register
dns_db_rpz_enabled
dns_db_rpz_findips
dns_db_setcachestats
dns_db_subtractrdataset
dns_db_unregister
dns_dbiterator_current
@ -493,6 +495,7 @@ dns_rbt_findname
dns_rbt_findnode
dns_rbt_formatnodename
dns_rbt_fullnamefromnode
dns_rbt_hashsize
dns_rbt_namefromnode
dns_rbt_nodecount
dns_rbt_printall

View file

@ -224,6 +224,8 @@ typedef struct isc_memmethods {
void *water_arg, size_t hiwater, size_t lowater);
void (*waterack)(isc_mem_t *ctx, int flag);
size_t (*inuse)(isc_mem_t *mctx);
size_t (*maxinuse)(isc_mem_t *mctx);
size_t (*total)(isc_mem_t *mctx);
isc_boolean_t (*isovermem)(isc_mem_t *mctx);
isc_result_t (*mpcreate)(isc_mem_t *mctx, size_t size,
isc_mempool_t **mpctxp);
@ -416,11 +418,25 @@ isc_mem_getquota(isc_mem_t *);
size_t
isc_mem_inuse(isc_mem_t *mctx);
/*%<
* Get an estimate of the number of memory in use in 'mctx', in bytes.
* Get an estimate of the amount of memory in use in 'mctx', in bytes.
* This includes quantization overhead, but does not include memory
* allocated from the system but not yet used.
*/
size_t
isc_mem_maxinuse(isc_mem_t *mctx);
/*%<
* Get an estimate of the largest amount of memory that has been in
* use in 'mctx' at any time.
*/
size_t
isc_mem_total(isc_mem_t *mctx);
/*%<
* Get the total amount of memory in 'mctx', in bytes, including memory
* not yet used.
*/
isc_boolean_t
isc_mem_isovermem(isc_mem_t *mctx);
/*%<

View file

@ -68,6 +68,8 @@
#define isc_mem_getquota isc__mem_getquota
#define isc_mem_gettag isc__mem_gettag
#define isc_mem_inuse isc__mem_inuse
#define isc_mem_maxinuse isc__mem_maxinuse
#define isc_mem_total isc__mem_total
#define isc_mem_isovermem isc__mem_isovermem
#define isc_mem_setname isc__mem_setname
#define isc_mem_setwater isc__mem_setwater

View file

@ -150,7 +150,13 @@ enum {
isc_sockstatscounter_unixrecvfail = 50,
isc_sockstatscounter_fdwatchrecvfail = 51,
isc_sockstatscounter_max = 52
isc_sockstatscounter_udp4active = 52,
isc_sockstatscounter_udp6active = 53,
isc_sockstatscounter_tcp4active = 54,
isc_sockstatscounter_tcp6active = 55,
isc_sockstatscounter_unixactive = 56,
isc_sockstatscounter_max = 57
};
/***

View file

@ -116,6 +116,26 @@ isc_stats_dump(isc_stats_t *stats, isc_stats_dumper_t dump_fn, void *arg,
*\li 'stats' is a valid isc_stats_t.
*/
void
isc_stats_set(isc_stats_t *stats, isc_uint64_t val,
isc_statscounter_t counter);
/*%<
* Set the given counter to the specfied value.
*
* Requires:
*\li 'stats' is a valid isc_stats_t.
*/
void
isc_stats_set(isc_stats_t *stats, isc_uint64_t val,
isc_statscounter_t counter);
/*%<
* Set the given counter to the specfied value.
*
* Requires:
*\li 'stats' is a valid isc_stats_t.
*/
ISC_LANG_ENDDECLS
#endif /* ISC_STATS_H */

View file

@ -126,4 +126,10 @@ typedef enum {
isc_resource_stacksize
} isc_resource_t;
/*% Statistics formats (text file or XML) */
typedef enum {
isc_statsformat_file,
isc_statsformat_xml
} isc_statsformat_t;
#endif /* ISC_TYPES_H */

View file

@ -270,6 +270,10 @@ ISC_MEMFUNC_SCOPE size_t
isc__mem_getquota(isc_mem_t *ctx);
ISC_MEMFUNC_SCOPE size_t
isc__mem_inuse(isc_mem_t *ctx);
ISC_MEMFUNC_SCOPE size_t
isc__mem_maxinuse(isc_mem_t *ctx);
ISC_MEMFUNC_SCOPE size_t
isc__mem_total(isc_mem_t *ctx);
ISC_MEMFUNC_SCOPE isc_boolean_t
isc__mem_isovermem(isc_mem_t *ctx);
ISC_MEMFUNC_SCOPE void
@ -348,6 +352,8 @@ static struct isc__memmethods {
isc__mem_setwater,
isc__mem_waterack,
isc__mem_inuse,
isc__mem_maxinuse,
isc__mem_total,
isc__mem_isovermem,
isc__mempool_create
}
@ -1737,6 +1743,36 @@ isc__mem_inuse(isc_mem_t *ctx0) {
return (inuse);
}
ISC_MEMFUNC_SCOPE size_t
isc__mem_maxinuse(isc_mem_t *ctx0) {
isc__mem_t *ctx = (isc__mem_t *)ctx0;
size_t maxinuse;
REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock);
maxinuse = ctx->maxinuse;
MCTXUNLOCK(ctx, &ctx->lock);
return (maxinuse);
}
ISC_MEMFUNC_SCOPE size_t
isc__mem_total(isc_mem_t *ctx0) {
isc__mem_t *ctx = (isc__mem_t *)ctx0;
size_t total;
REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock);
total = ctx->total;
MCTXUNLOCK(ctx, &ctx->lock);
return (total);
}
ISC_MEMFUNC_SCOPE void
isc__mem_setwater(isc_mem_t *ctx0, isc_mem_water_t water, void *water_arg,
size_t hiwater, size_t lowater)

View file

@ -206,6 +206,20 @@ isc_mem_isovermem(isc_mem_t *mctx) {
return (mctx->methods->isovermem(mctx));
}
size_t
isc_mem_maxinuse(isc_mem_t *mctx) {
REQUIRE(ISCAPI_MCTX_VALID(mctx));
return (mctx->methods->maxinuse(mctx));
}
size_t
isc_mem_total(isc_mem_t *mctx) {
REQUIRE(ISCAPI_MCTX_VALID(mctx));
return (mctx->methods->total(mctx));
}
void
isc_mem_setname(isc_mem_t *mctx, const char *name, void *tag) {
REQUIRE(ISCAPI_MCTX_VALID(mctx));

View file

@ -324,3 +324,31 @@ isc_stats_dump(isc_stats_t *stats, isc_stats_dumper_t dump_fn,
dump_fn((isc_statscounter_t)i, stats->copiedcounters[i], arg);
}
}
void
isc_stats_set(isc_stats_t *stats, isc_uint64_t val,
isc_statscounter_t counter)
{
REQUIRE(ISC_STATS_VALID(stats));
REQUIRE(counter < stats->ncounters);
#ifdef ISC_RWLOCK_USEATOMIC
/*
* We use a "write" lock before "reading" the statistics counters as
* an exclusive lock.
*/
isc_rwlock_lock(&stats->counterlock, isc_rwlocktype_write);
#endif
#if ISC_STATS_USEMULTIFIELDS
stats->counters[counter].hi = (val >> 32) & 0xffffffff;
stats->counters[counter].lo = val & 0xffffffff;
#else
stats->counters[counter] = val;
#endif
#ifdef ISC_RWLOCK_USEATOMIC
isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_write);
#endif
}

View file

@ -110,6 +110,7 @@ struct isc__task {
unsigned int references;
isc_eventlist_t events;
isc_eventlist_t on_shutdown;
unsigned int nevents;
unsigned int quantum;
unsigned int flags;
isc_stdtime_t now;
@ -153,6 +154,7 @@ struct isc__taskmgr {
isc_condition_t paused;
#endif /* ISC_PLATFORM_USETHREADS */
unsigned int tasks_running;
unsigned int tasks_ready;
isc_boolean_t pause_requested;
isc_boolean_t exclusive_requested;
isc_boolean_t exiting;
@ -298,6 +300,7 @@ task_finished(isc__task_t *task) {
isc__taskmgr_t *manager = task->manager;
REQUIRE(EMPTY(task->events));
REQUIRE(task->nevents == 0);
REQUIRE(EMPTY(task->on_shutdown));
REQUIRE(task->references == 0);
REQUIRE(task->state == task_state_done);
@ -351,6 +354,7 @@ isc__task_create(isc_taskmgr_t *manager0, unsigned int quantum,
task->references = 1;
INIT_LIST(task->events);
INIT_LIST(task->on_shutdown);
task->nevents = 0;
task->quantum = quantum;
task->flags = 0;
task->now = 0;
@ -436,6 +440,7 @@ task_shutdown(isc__task_t *task) {
prev = PREV(event, ev_link);
DEQUEUE(task->on_shutdown, event, ev_link);
ENQUEUE(task->events, event, ev_link);
task->nevents++;
}
}
@ -547,6 +552,7 @@ task_send(isc__task_t *task, isc_event_t **eventp) {
INSIST(task->state == task_state_ready ||
task->state == task_state_running);
ENQUEUE(task->events, event, ev_link);
task->nevents++;
*eventp = NULL;
return (was_idle);
@ -660,6 +666,7 @@ dequeue_events(isc__task_t *task, void *sender, isc_eventtype_t first,
(tag == NULL || event->ev_tag == tag) &&
(!purging || PURGE_OK(event))) {
DEQUEUE(task->events, event, ev_link);
task->nevents--;
ENQUEUE(*events, event, ev_link);
count++;
}
@ -745,6 +752,7 @@ isc__task_purgeevent(isc_task_t *task0, isc_event_t *event) {
next_event = NEXT(curr_event, ev_link);
if (curr_event == event && PURGE_OK(event)) {
DEQUEUE(task->events, curr_event, ev_link);
task->nevents--;
break;
}
}
@ -968,6 +976,7 @@ push_readyq(isc__taskmgr_t *manager, isc__task_t *task) {
if ((task->flags & TASK_F_PRIVILEGED) != 0)
ENQUEUE(manager->ready_priority_tasks, task,
ready_priority_link);
manager->tasks_ready++;
}
static void
@ -977,6 +986,7 @@ dispatch(isc__taskmgr_t *manager) {
unsigned int total_dispatch_count = 0;
isc__tasklist_t new_ready_tasks;
isc__tasklist_t new_priority_tasks;
unsigned int tasks_ready = 0;
#endif /* USE_WORKER_THREADS */
REQUIRE(VALID_MANAGER(manager));
@ -1083,6 +1093,7 @@ dispatch(isc__taskmgr_t *manager) {
* have a task to do. We must reacquire the manager
* lock before exiting the 'if (task != NULL)' block.
*/
manager->tasks_ready--;
manager->tasks_running++;
UNLOCK(&manager->lock);
@ -1096,6 +1107,7 @@ dispatch(isc__taskmgr_t *manager) {
if (!EMPTY(task->events)) {
event = HEAD(task->events);
DEQUEUE(task->events, event, ev_link);
task->nevents--;
/*
* Execute the event action.
@ -1235,6 +1247,7 @@ dispatch(isc__taskmgr_t *manager) {
if ((task->flags & TASK_F_PRIVILEGED) != 0)
ENQUEUE(new_priority_tasks, task,
ready_priority_link);
tasks_ready++;
#endif
}
}
@ -1258,6 +1271,7 @@ dispatch(isc__taskmgr_t *manager) {
ISC_LIST_APPENDLIST(manager->ready_tasks, new_ready_tasks, ready_link);
ISC_LIST_APPENDLIST(manager->ready_priority_tasks, new_priority_tasks,
ready_priority_link);
manager->tasks_ready += tasks_ready;
if (empty_readyq(manager))
manager->mode = isc_taskmgrmode_normal;
#endif
@ -1393,6 +1407,7 @@ isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
INIT_LIST(manager->ready_tasks);
INIT_LIST(manager->ready_priority_tasks);
manager->tasks_running = 0;
manager->tasks_ready = 0;
manager->exclusive_requested = ISC_FALSE;
manager->pause_requested = ISC_FALSE;
manager->exiting = ISC_FALSE;
@ -1761,6 +1776,10 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) {
xmlTextWriterWriteFormatString(writer, "%d", mgr->tasks_running);
xmlTextWriterEndElement(writer); /* tasks-running */
xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-ready");
xmlTextWriterWriteFormatString(writer, "%d", mgr->tasks_ready);
xmlTextWriterEndElement(writer); /* tasks-ready */
xmlTextWriterEndElement(writer); /* thread-model */
xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks");
@ -1793,6 +1812,10 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) {
xmlTextWriterWriteFormatString(writer, "%d", task->quantum);
xmlTextWriterEndElement(writer); /* quantum */
xmlTextWriterStartElement(writer, ISC_XMLCHAR "events");
xmlTextWriterWriteFormatString(writer, "%d", task->nevents);
xmlTextWriterEndElement(writer); /* events */
xmlTextWriterEndElement(writer);
UNLOCK(&task->lock);

View file

@ -624,7 +624,8 @@ enum {
STATID_ACCEPTFAIL = 6,
STATID_ACCEPT = 7,
STATID_SENDFAIL = 8,
STATID_RECVFAIL = 9
STATID_RECVFAIL = 9,
STATID_ACTIVE = 10
};
static const isc_statscounter_t upd4statsindex[] = {
isc_sockstatscounter_udp4open,
@ -636,7 +637,8 @@ static const isc_statscounter_t upd4statsindex[] = {
-1,
-1,
isc_sockstatscounter_udp4sendfail,
isc_sockstatscounter_udp4recvfail
isc_sockstatscounter_udp4recvfail,
isc_sockstatscounter_udp4active
};
static const isc_statscounter_t upd6statsindex[] = {
isc_sockstatscounter_udp6open,
@ -648,7 +650,8 @@ static const isc_statscounter_t upd6statsindex[] = {
-1,
-1,
isc_sockstatscounter_udp6sendfail,
isc_sockstatscounter_udp6recvfail
isc_sockstatscounter_udp6recvfail,
isc_sockstatscounter_udp6active
};
static const isc_statscounter_t tcp4statsindex[] = {
isc_sockstatscounter_tcp4open,
@ -660,7 +663,8 @@ static const isc_statscounter_t tcp4statsindex[] = {
isc_sockstatscounter_tcp4acceptfail,
isc_sockstatscounter_tcp4accept,
isc_sockstatscounter_tcp4sendfail,
isc_sockstatscounter_tcp4recvfail
isc_sockstatscounter_tcp4recvfail,
isc_sockstatscounter_tcp4active
};
static const isc_statscounter_t tcp6statsindex[] = {
isc_sockstatscounter_tcp6open,
@ -672,7 +676,8 @@ static const isc_statscounter_t tcp6statsindex[] = {
isc_sockstatscounter_tcp6acceptfail,
isc_sockstatscounter_tcp6accept,
isc_sockstatscounter_tcp6sendfail,
isc_sockstatscounter_tcp6recvfail
isc_sockstatscounter_tcp6recvfail,
isc_sockstatscounter_tcp6active
};
static const isc_statscounter_t unixstatsindex[] = {
isc_sockstatscounter_unixopen,
@ -684,7 +689,8 @@ static const isc_statscounter_t unixstatsindex[] = {
isc_sockstatscounter_unixacceptfail,
isc_sockstatscounter_unixaccept,
isc_sockstatscounter_unixsendfail,
isc_sockstatscounter_unixrecvfail
isc_sockstatscounter_unixrecvfail,
isc_sockstatscounter_unixactive
};
static const isc_statscounter_t fdwatchstatsindex[] = {
-1,
@ -696,7 +702,8 @@ static const isc_statscounter_t fdwatchstatsindex[] = {
-1,
-1,
isc_sockstatscounter_fdwatchsendfail,
isc_sockstatscounter_fdwatchrecvfail
isc_sockstatscounter_fdwatchrecvfail,
-1
};
#if defined(USE_KQUEUE) || defined(USE_EPOLL) || defined(USE_DEVPOLL) || \
@ -803,6 +810,17 @@ inc_stats(isc_stats_t *stats, isc_statscounter_t counterid) {
isc_stats_increment(stats, counterid);
}
/*%
* Decrement socket-related statistics counters.
*/
static inline void
dec_stats(isc_stats_t *stats, isc_statscounter_t counterid) {
REQUIRE(counterid != -1);
if (stats != NULL)
isc_stats_decrement(stats, counterid);
}
static inline isc_result_t
watch_fd(isc__socketmgr_t *manager, int fd, int msg) {
isc_result_t result = ISC_R_SUCCESS;
@ -1970,6 +1988,7 @@ closesocket(isc__socketmgr_t *manager, isc__socket_t *sock, int fd) {
select_poke(manager, fd, SELECT_POKE_CLOSE);
inc_stats(manager->stats, sock->statsindex[STATID_CLOSE]);
dec_stats(manager->stats, sock->statsindex[STATID_ACTIVE]);
/*
* update manager->maxfd here (XXX: this should be implemented more
@ -1997,6 +2016,7 @@ closesocket(isc__socketmgr_t *manager, isc__socket_t *sock, int fd) {
manager->maxfd = manager->pipe_fds[0];
#endif
}
UNLOCK(&manager->lock);
#endif /* USE_SELECT */
}
@ -2313,6 +2333,7 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
ISC_MSG_TOOMANYFDS,
"socket: file descriptor exceeds limit (%d/%u)",
sock->fd, manager->maxsocks);
inc_stats(manager->stats, sock->statsindex[STATID_OPENFAIL]);
return (ISC_R_NORESOURCES);
}
@ -2328,6 +2349,8 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
"%s: %s", err, strbuf);
/* fallthrough */
case ENOBUFS:
inc_stats(manager->stats,
sock->statsindex[STATID_OPENFAIL]);
return (ISC_R_NORESOURCES);
case EPROTONOSUPPORT:
@ -2338,6 +2361,8 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
* EAFNOSUPPORT.
*/
case EINVAL:
inc_stats(manager->stats,
sock->statsindex[STATID_OPENFAIL]);
return (ISC_R_FAMILYNOSUPPORT);
default:
@ -2349,6 +2374,8 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
ISC_MSG_FAILED,
"failed"),
strbuf);
inc_stats(manager->stats,
sock->statsindex[STATID_OPENFAIL]);
return (ISC_R_UNEXPECTED);
}
}
@ -2359,6 +2386,7 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
result = make_nonblock(sock->fd);
if (result != ISC_R_SUCCESS) {
(void)close(sock->fd);
inc_stats(manager->stats, sock->statsindex[STATID_OPENFAIL]);
return (result);
}
@ -2543,7 +2571,7 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
setup_done:
inc_stats(manager->stats, sock->statsindex[STATID_OPEN]);
inc_stats(manager->stats, sock->statsindex[STATID_ACTIVE]);
return (ISC_R_SUCCESS);
}
@ -2590,7 +2618,6 @@ socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type,
result = opensocket(manager, sock, (isc__socket_t *)dup_socket);
if (result != ISC_R_SUCCESS) {
inc_stats(manager->stats, sock->statsindex[STATID_OPENFAIL]);
free_socket(&sock);
return (result);
}
@ -3298,6 +3325,7 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
UNLOCK(&manager->lock);
inc_stats(manager->stats, sock->statsindex[STATID_ACCEPT]);
inc_stats(manager->stats, sock->statsindex[STATID_ACTIVE]);
} else {
inc_stats(manager->stats, sock->statsindex[STATID_ACCEPTFAIL]);
NEWCONNSOCK(dev)->references--;