>> >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. > >nope. i know the current array size, and i know when i can't find an >open slot. there's no other accounting, and no desire to add any since >that kind of accounting is highly subject to off-by-one errors unless >one has tight module boundaries with functional interfaces to global >state, which is true in bind9 but NOT in bind8. fair enough. >> >> * 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? > >it's a side effect of how silly i think it is to change one's response to >a VERSION.BIND query. (and how silly i think it also is that non-BIND >implementations of DNS now universally answer VERSION.BIND queries.) anyone >who thinks they are buying any kind of security by changing this string needs >to look at nmap and similar utilities. and, such people need to see it in >their "ndc -t" output so they will be reminded, every single day, how silly >they are to think that obscurity improves security. i don't know for sure that nmap can tell me what version of bind i'm running (although i heard a rumor that you could :), but i see what you mean. still, i like to change it anyway...if only because i can. >> >> * 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. > >nice try. but the right thing to do is as a call into the stats module, >not to make private variables from the stats module into public variables >and then cement the structure of this data in an intermodule way. > >also, this change, even in that more correct form, would be too large to >put into 8.2.3 but i'll definitely be interested in it later. okay...try number two attached. it's a little larger, but i think it's much closer to the abstraction you're looking for (ie, calls into ns_stats.c and no private variables from ns_stats.c exposed to the outside world). -- |-----< "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 Tue Nov 28 14:14:34 2000 @@ -645,6 +645,9 @@ e_qrylog, e_priming, e_loading, + e_usage, + e_nstats, + e_xstats, e_finito }; @@ -702,6 +705,20 @@ case e_loading: sprintf(pvt->text, "server %s loading its configuration", loading ? "IS" : "IS NOT"); + break; + case e_usage: + if (ns_stats_usage(pvt->text, sizeof(pvt->text)) != 0) + pvt->state++; /* no data for this */ + /* FALLTHROUGH */ + else + break; + case e_nstats: + if (ns_stats_nstats(pvt->text, sizeof(pvt->text)) != 0) + pvt->state--; /* more data for this */ + break; + case e_xstats: + if (ns_stats_xstats(pvt->text, sizeof(pvt->text)) != 0) + pvt->state--; /* more data for this */ break; case e_finito: return; --- ns_stats.c-orig Wed Nov 8 01:33:09 2000 +++ ns_stats.c Tue Nov 28 14:39:48 2000 @@ -330,19 +330,13 @@ nameserStatsFile = NULL; } -void -ns_logstats(evContext ctx, void *uap, struct timespec due, - struct timespec inter) +int +ns_stats_usage(char *buffer, int buflen) { - char buffer[1024]; - char buffer2[32], header[128]; - time_t timenow = time(NULL); - int i; #ifdef HAVE_GETRUSAGE + char buffer2[128], header[128]; + time_t timenow = time(NULL); struct rusage usage, childu; -#endif /*HAVE_GETRUSAGE*/ - -#ifdef HAVE_GETRUSAGE # define tv_float(tv) ((tv).tv_sec + ((tv).tv_usec / 1000000.0)) getrusage(RUSAGE_SELF, &usage); @@ -354,42 +348,83 @@ * sprintf. * */ - sprintf(buffer, "CPU=%gu/%gs CHILDCPU=", tv_float(usage.ru_utime), + sprintf(buffer2, "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)); - ns_info(ns_log_statistics, "USAGE %lu %lu %s%s", (u_long)timenow, - (u_long)boottime, buffer, header); + sprintf(buffer, "USAGE %lu %lu %s%s", (u_long)timenow, + (u_long)boottime, buffer2, header); # undef tv_float + return 0; +#else /*HAVE_GETRUSAGE*/ + buffer[0] = buffer[buflen - 1] = 0; + return 1; #endif /*HAVE_GETRUSAGE*/ +} + +int +ns_stats_nstats(char *buffer, int buflen) +{ + char buffer2[128], header[128]; + time_t timenow = time(NULL); + static int i = 0; sprintf(header, "NSTATS %lu %lu", (u_long)timenow, (u_long)boottime); strcpy(buffer, header); - for (i = 0; i < T_ANY+1; i++) { + for (; i < T_ANY+1; i++) { if (typestats[i]) { sprintf(buffer2, " %s=%lu", p_type(i), typestats[i]); - if (strlen(buffer) + strlen(buffer2) > - sizeof(buffer) - 1) { - ns_info(ns_log_statistics, buffer); - strcpy(buffer, header); + if (strlen(buffer) + strlen(buffer2) > buflen) { + i--; + return 1; } strcat(buffer, buffer2); } } - ns_info(ns_log_statistics, buffer); + i = 0; + return 0; +} + +int +ns_stats_xstats(char *buffer, int buflen) +{ + char buffer2[32], header[128]; + time_t timenow = time(NULL); + static int i = 0; sprintf(header, "XSTATS %lu %lu", (u_long)timenow, (u_long)boottime); strcpy(buffer, header); - for (i = 0; i < (int)nssLast; i++) { + + for (; i < (int)nssLast; i++) { sprintf(buffer2, " %s=%lu", statNames[i]?statNames[i]:"?", (u_long)globalStats[i]); - if (strlen(buffer) + strlen(buffer2) > sizeof(buffer) - 1) { - ns_info(ns_log_statistics, buffer); - strcpy(buffer, header); + if (strlen(buffer) + strlen(buffer2) > buflen - 1) { + i--; + return 1; } strcat(buffer, buffer2); } + i = 0; + return 0; +} + +void +ns_logstats(evContext ctx, void *uap, struct timespec due, + struct timespec inter) +{ + char buffer[1024]; + int rc; + + if (ns_stats_usage(buffer, sizeof(buffer)) == 0) + ns_info(ns_log_statistics, buffer); + + while (ns_stats_nstats(buffer, sizeof(buffer)) != 0) + ns_info(ns_log_statistics, buffer); + ns_info(ns_log_statistics, buffer); + + while (ns_stats_xstats(buffer, sizeof(buffer)) != 0) + ns_info(ns_log_statistics, buffer); ns_info(ns_log_statistics, buffer); }