misc/110419: rcp.rstatd reports bogus info
Bruce Becker
hostmaster at whois.gts.net
Sat Mar 17 03:30:03 UTC 2007
>Number: 110419
>Category: misc
>Synopsis: rcp.rstatd reports bogus info
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sat Mar 17 03:30:02 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator: Bruce Becker
>Release: 6.2
>Organization:
G.T.S.
>Environment:
FreeBSD server 6.2-STABLE FreeBSD 6.2-STABLE #3: Fri Feb 16 03:47:24 EST 2007 root at server:/usr/obj/usr/src/sys/SERVER i386
>Description:
packets/second value reported by rpc.rstatd to remote monitor hovers around
> 8000 or so with odd downward spikes approx every 90 seconds (it's not at
all related to actual interface traffic)
>How-To-Repeat:
view with SunOS/Solaris perfmeter or the sysutils/xsysstats port
>Fix:
Patch included
Patch attached with submission follows:
--- rstat_proc.c.orig Sun Jun 1 22:34:36 2003
+++ rstat_proc.c Sun Jan 29 02:17:10 2006
@@ -138,6 +138,7 @@
if (! stat_is_init)
stat_init();
sincelastreq = 0;
+ stats_all.s2.if_opackets = stats_all.s3.if_opackets;
return(&stats_all.s2);
}
@@ -147,6 +148,7 @@
if (! stat_is_init)
stat_init();
sincelastreq = 0;
+ stats_all.s1.if_opackets = stats_all.s3.if_opackets;
return(&stats_all.s1);
}
@@ -219,13 +221,13 @@
exit(1);
}
for(i = 0; i < RSTAT_CPUSTATES ; i++)
- stats_all.s1.cp_time[i] = bsd_cp_time[cp_time_xlat[i]];
+ stats_all.s3.cp_time[i] = bsd_cp_time[cp_time_xlat[i]];
(void)getloadavg(avrun, sizeof(avrun) / sizeof(avrun[0]));
- stats_all.s2.avenrun[0] = avrun[0] * FSCALE;
- stats_all.s2.avenrun[1] = avrun[1] * FSCALE;
- stats_all.s2.avenrun[2] = avrun[2] * FSCALE;
+ stats_all.s3.avenrun[0] = avrun[0] * FSCALE;
+ stats_all.s3.avenrun[1] = avrun[1] * FSCALE;
+ stats_all.s3.avenrun[2] = avrun[2] * FSCALE;
mib[0] = CTL_KERN;
mib[1] = KERN_BOOTTIME;
@@ -234,14 +236,13 @@
syslog(LOG_ERR, "sysctl(kern.boottime): %m");
exit(1);
}
-
- stats_all.s2.boottime.tv_sec = btm.tv_sec;
- stats_all.s2.boottime.tv_usec = btm.tv_usec;
+ stats_all.s3.boottime.tv_sec = btm.tv_sec;
+ stats_all.s3.boottime.tv_usec = btm.tv_usec;
#ifdef DEBUG
- fprintf(stderr, "%d %d %d %d\n", stats_all.s1.cp_time[0],
- stats_all.s1.cp_time[1], stats_all.s1.cp_time[2], stats_all.s1.cp_time[3]);
+ fprintf(stderr, "%d %d %d %d\n", stats_all.s3.cp_time[0],
+ stats_all.s3.cp_time[1], stats_all.s3.cp_time[2], stats_all.s3.cp_time[3]);
#endif
/* XXX - should use sysctl */
@@ -249,18 +250,18 @@
syslog(LOG_ERR, "rstat: can't read cnt from kmem");
exit(1);
}
- stats_all.s1.v_pgpgin = cnt.v_vnodepgsin;
- stats_all.s1.v_pgpgout = cnt.v_vnodepgsout;
- stats_all.s1.v_pswpin = cnt.v_swappgsin;
- stats_all.s1.v_pswpout = cnt.v_swappgsout;
- stats_all.s1.v_intr = cnt.v_intr;
+ stats_all.s3.v_pgpgin = cnt.v_vnodepgsin;
+ stats_all.s3.v_pgpgout = cnt.v_vnodepgsout;
+ stats_all.s3.v_pswpin = cnt.v_swappgsin;
+ stats_all.s3.v_pswpout = cnt.v_swappgsout;
+ stats_all.s3.v_intr = cnt.v_intr;
gettimeofday(&tm, (struct timezone *) 0);
- stats_all.s1.v_intr -= hz*(tm.tv_sec - btm.tv_sec) +
+ stats_all.s3.v_intr -= hz*(tm.tv_sec - btm.tv_sec) +
hz*(tm.tv_usec - btm.tv_usec)/1000000;
- stats_all.s2.v_swtch = cnt.v_swtch;
+ stats_all.s3.v_swtch = cnt.v_swtch;
/* update disk transfers */
- updatexfers(RSTAT_DK_NDRIVE, stats_all.s1.dk_xfer);
+ updatexfers(RSTAT_DK_NDRIVE, stats_all.s3.dk_xfer);
mib[0] = CTL_NET;
mib[1] = PF_LINK;
@@ -272,12 +273,11 @@
syslog(LOG_ERR, "sysctl(net.link.generic.system.ifcount): %m");
exit(1);
}
-
- stats_all.s1.if_ipackets = 0;
- stats_all.s1.if_opackets = 0;
- stats_all.s1.if_ierrors = 0;
- stats_all.s1.if_oerrors = 0;
- stats_all.s1.if_collisions = 0;
+ stats_all.s3.if_ipackets = 0;
+ stats_all.s3.if_opackets = 0;
+ stats_all.s3.if_ierrors = 0;
+ stats_all.s3.if_oerrors = 0;
+ stats_all.s3.if_collisions = 0;
for (i = 1; i <= ifcount; i++) {
len = sizeof ifmd;
mib[3] = IFMIB_IFDATA;
@@ -287,19 +287,19 @@
if (errno == ENOENT)
continue;
- syslog(LOG_ERR, "sysctl(net.link.ifdata.%d.general)"
- ": %m", i);
+ syslog(LOG_ERR, "sysctl(net.link.ifdata.%d.general): %m", i);
exit(1);
}
-
- stats_all.s1.if_ipackets += ifmd.ifmd_data.ifi_ipackets;
- stats_all.s1.if_opackets += ifmd.ifmd_data.ifi_opackets;
- stats_all.s1.if_ierrors += ifmd.ifmd_data.ifi_ierrors;
- stats_all.s1.if_oerrors += ifmd.ifmd_data.ifi_oerrors;
- stats_all.s1.if_collisions += ifmd.ifmd_data.ifi_collisions;
+ stats_all.s3.if_ipackets += ifmd.ifmd_data.ifi_ipackets;
+ stats_all.s3.if_opackets += ifmd.ifmd_data.ifi_opackets;
+ stats_all.s3.if_ierrors += ifmd.ifmd_data.ifi_ierrors;
+ stats_all.s3.if_oerrors += ifmd.ifmd_data.ifi_oerrors;
+ stats_all.s3.if_collisions += ifmd.ifmd_data.ifi_collisions;
}
- gettimeofday((struct timeval *)&stats_all.s3.curtime,
- (struct timezone *) 0);
+
+ gettimeofday(&tm, (struct timezone *) 0);
+ stats_all.s3.curtime.tv_sec = tm.tv_sec;
+ stats_all.s3.curtime.tv_usec = tm.tv_usec;
alarm(1);
}
@@ -307,12 +307,21 @@
setup()
{
char errbuf[_POSIX2_LINE_MAX];
-
int en;
+ static int is_kd_setup = 0;
- if ((kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf)) == NULL) {
- syslog(LOG_ERR, "rpc.rstatd, %s", errbuf);
- exit(1);
+ /* setup() is called after each dormant->active
+ * transition. Since we never close the kvm files
+ * (there's no reason), make sure we don't open them
+ * each time, as that can lead to exhaustion of all open
+ * files! */
+ if (!is_kd_setup) {
+ kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
+ if (kd == NULL) {
+ syslog(LOG_ERR, "%s", errbuf);
+ exit (1);
+ }
+ is_kd_setup = 1;
}
if ((en = kvm_nlist(kd, nl)) != 0) {
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list