>> * number of zones "loaded" as opposed to (or in addition to) >> "allocated"...maybe number of zones in each class? > >can't do that without adding more global state. don't want to add >more global state at this late point in the release cycle. i've never looked, but i figured that since you know how many you've allocated (it tells us), you must be allocating them dynamically, and if you're allocating them dynamically, you must know when you need more, and if you know when you need more, then you know how many you've used. oh well. >> * the server's pid (the ndc shell script told us this, and with this >> i can easily get VSZ and RSS, which status no longer reports) > >#isrv1.isc:i386# ndc -t -c /var/run/ns-ext.ndc getpid >ndc: [220 8.2.3-T6B] >ndc: [250 my pid is <5883>] touche. note that the "8.2.3-T6B" in the above string is the string taken from the config file if the config file has something else specified for options { version ...; }; intentional? >> * snapshots of stuff like NSTATS and XSTATS > >ouch. "that's hard. patches welcome." patch attached. basically, export two things from ns_stats.c (previously declared static) and copy a chunk of code from ns_stats.c. >> * server's start time and/or current run time (aka how long has it >> been running?) the time_t's for start time and current time are printed as part of the usage, nstats, and xstats lines in the patch. that's probably enough to make me happy, except on systems that don't do "date -r". there i guess i'll have to use perl. >> * for xfers...inbound vs. outbound counts (running and deferred) > >those are easy and i'll see if i can put them in for RC3. neat. >> >note that the last line of the display is nonsequitur, since whenever it >> >*is* loading its configuration, the event engine is not running, and it >> >won't be answering NDC *at all*. >> >> heh. i was wondering about that...thought perhaps you'd gone a little >> crazy and had it pause in between each line (or clause) in the config >> file to check if anything else needed to be done. > >well, the original plan was to make rereading the config file incremental. >but it turned out to be easier to just call that result "bind9". fair enough. -- |-----< "CODE WARRIOR" >-----| codewarrior@daemon.org * "ah! i see you have the internet twofsonet@graffiti.com (Andrew Brown) that goes *ping*!" andrew@crossbar.com * "information is power -- share the wealth." -- Attached file included as plaintext by Listar -- --- ns_ctl.c-orig Mon Oct 30 19:01:24 2000 +++ ns_ctl.c Fri Nov 17 02:32:34 2000 @@ -51,6 +51,11 @@ #include "port_after.h" +#ifdef HAVE_GETRUSAGE /* XXX */ +#include +#include +#endif + #include "named.h" /* Defs. */ @@ -645,6 +650,9 @@ e_qrylog, e_priming, e_loading, + e_usage, + e_nstats, + e_xstats, e_finito }; @@ -703,6 +711,93 @@ sprintf(pvt->text, "server %s loading its configuration", loading ? "IS" : "IS NOT"); break; + case e_usage: +#ifdef HAVE_GETRUSAGE + { + char buffer[1024]; + char header[128]; + time_t timenow = time(NULL); + struct rusage usage, childu; +# define tv_float(tv) ((tv).tv_sec + ((tv).tv_usec / 1000000.0)) + + getrusage(RUSAGE_SELF, &usage); + getrusage(RUSAGE_CHILDREN, &childu); + + /* + * Get around a stupid compiler bug in gcc on solaris. + * There is a problem if three or more doubles are passed to + * sprintf. + * + */ + sprintf(buffer, "CPU=%gu/%gs CHILDCPU=", + tv_float(usage.ru_utime), tv_float(usage.ru_stime)); + sprintf(header, "%gu/%gs", + tv_float(childu.ru_utime), tv_float(childu.ru_stime)); + sprintf(pvt->text, "USAGE %lu %lu %s%s", + (u_long)timenow, (u_long)boottime, buffer, header); +# undef tv_float + break; + } +#else /*HAVE_GETRUSAGE*/ + pvt->state++; + /* FALLTHROUGH */ +#endif /*HAVE_GETRUSAGE*/ + case e_nstats: { + char buffer[1024]; + char buffer2[32], header[128]; + time_t timenow = time(NULL); + static int i = 0; + extern u_long typestats[T_ANY+1]; + + sprintf(header, "NSTATS %lu %lu", (u_long)timenow, + (u_long)boottime); + strcpy(buffer, header); + + for (; i < T_ANY+1; i++) { + if (typestats[i]) { + sprintf(buffer2, " %s=%lu", p_type(i), + typestats[i]); + if (strlen(buffer) + strlen(buffer2) > + sizeof(pvt->text) - 1) { + i--; + pvt->state--; /* we'll come back */ + break; + } + strcat(buffer, buffer2); + } + } + if (i >= T_ANY+1) + i = 0; + strcpy(pvt->text, buffer); + break; + } + case e_xstats: { + char buffer[1024]; + char buffer2[32], header[128]; + time_t timenow = time(NULL); + static int i = 0; + extern const char *statNames[nssLast]; + + sprintf(header, "XSTATS %lu %lu", + (u_long)timenow, (u_long)boottime); + strcpy(buffer, header); + for (; i < (int)nssLast; i++) { + sprintf(buffer2, " %s=%lu", + statNames[i]?statNames[i]:"?", + (u_long)globalStats[i]); + if (strlen(buffer) + strlen(buffer2) > + sizeof(pvt->text) - 1) { + i--; + pvt->state--; /* we'll be back */ + break; + } + strcat(buffer, buffer2); + } + if (i >= (int)nssLast) + i = 0; + strcpy(pvt->text, buffer); + break; + } case e_finito: return; } --- ns_stats.c-orig Wed Nov 8 01:33:09 2000 +++ ns_stats.c Fri Nov 17 02:31:12 2000 @@ -106,7 +106,7 @@ #include "named.h" -static u_long typestats[T_ANY+1]; +u_long typestats[T_ANY+1]; static void nameserStats(FILE *); void @@ -183,7 +183,7 @@ static int nameserInit; static FILE *nameserStatsFile; -static const char *statNames[nssLast] = { +const char *statNames[nssLast] = { "RR", /* sent us an answer */ "RNXD", /* sent us a negative response */ "RFwdR", /* sent us a response we had to fwd */