Subject: Re: bin/32847
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org,>
From: Peter Postma <peter@pointless.nl>
List: netbsd-bugs
Date: 10/15/2006 15:50:02
The following reply was made to PR bin/32847; it has been noted by GNATS.

From: Peter Postma <peter@pointless.nl>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: bin/32847
Date: Sun, 15 Oct 2006 17:45:33 +0200

 --y0ulUmNC+osPPQO6
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 There seem to be at least two problems:
 - Some queueing disciplines (like cbq and hfsc) need the previous
   stats to calculate a "measure". That's why you see a 5 second delay
   and then nothing with count 1.
 - The check for count should be placed before the delay so that we can
   exit immediately and not after the delay.
 
 The attached patch should address both issues. For issue one, I've just
 left out the "measure" code when there's not enough information to show it,
 this means the bytes per second will only be shown if count > 1.
 
 -- 
 Peter Postma
 
 --y0ulUmNC+osPPQO6
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename="altqstat.diff"
 
 Index: altqstat.c
 ===================================================================
 RCS file: /cvsroot/src/usr.sbin/altq/altqstat/altqstat.c,v
 retrieving revision 1.6
 diff -u -r1.6 altqstat.c
 --- altqstat.c	12 Oct 2006 19:59:13 -0000	1.6
 +++ altqstat.c	15 Oct 2006 15:33:28 -0000
 @@ -105,6 +105,8 @@
  			break;
  		case 'c':
  			count = atoi(optarg);
 +			if (count < 1)
 +				errx(1, "Please supply a count value bigger than 0.");
  			break;
  		case 'e':
  			quip_echo = 1;
 Index: qdisc_blue.c
 ===================================================================
 RCS file: /cvsroot/src/usr.sbin/altq/altqstat/qdisc_blue.c,v
 retrieving revision 1.3
 diff -u -r1.3 qdisc_blue.c
 --- qdisc_blue.c	16 Aug 2001 07:48:10 -0000	1.3
 +++ qdisc_blue.c	15 Oct 2006 15:33:28 -0000
 @@ -61,8 +61,7 @@
  	last_time.tv_sec -= interval;
  	last_bytes = 0;
  
 -	while (count == 0 || cnt-- > 0) {
 -	
 +	for (;;) {
  		if (ioctl(fd, BLUE_GETSTATS, &blue_stats) < 0)
  			err(1, "ioctl BLUE_GETSTATS");
  
 @@ -86,6 +85,10 @@
  
  		last_bytes = blue_stats.xmit_bytes;
  		last_time = cur_time;
 +
 +		if (count != 0 && --cnt == 0)
 +			break;
 +
  		sleep(interval);
  	}
  }
 Index: qdisc_cbq.c
 ===================================================================
 RCS file: /cvsroot/src/usr.sbin/altq/altqstat/qdisc_cbq.c,v
 retrieving revision 1.6
 diff -u -r1.6 qdisc_cbq.c
 --- qdisc_cbq.c	12 Oct 2006 19:59:13 -0000	1.6
 +++ qdisc_cbq.c	15 Oct 2006 15:33:28 -0000
 @@ -67,7 +67,7 @@
  	struct timeval		cur_time, last_time;
  	int			i;
  	double			flow_bps, sec;
 -	int cnt = count;
 +	int			cnt = count;
  	sigset_t		omask;
  
  	strlcpy(get_stats.iface.cbq_ifacename, ifname,
 @@ -78,7 +78,7 @@
  	for (i = 0; i < NCLASSES; i++)
  	    clhandles[i] = NULL_CLASS_HANDLE;
  
 -	while (count == 0 || cnt-- > 0) {
 +	for (;;) {
  		get_stats.nclasses = NCLASSES;
  		get_stats.stats = new;
  		if (ioctl(fd, CBQ_GETSTATS, &get_stats) < 0)
 @@ -93,9 +93,8 @@
  
  			if (sp->handle != clhandles[i]) {
  				quip_chandle2name(ifname, sp->handle,
 -						  clnames[i], sizeof(clnames[0]));
 +				    clnames[i], sizeof(clnames[0]));
  				clhandles[i] = sp->handle;
 -				continue;
  			}
  
  			printf("Class %d on Interface %s: %s\n",
 @@ -109,10 +108,14 @@
  			printf(" offtime: %d [us] wrr_allot: %d bytes\n",
  			       sp->offtime, sp->wrr_allot);
  			printf("\tnsPerByte: %d", sp->ns_per_byte);
 -			printf("\t(%sbps),", rate2str(flow_bps));
 -			printf("\tMeasured: %s [bps]\n",
 -			       rate2str(calc_rate(sp->xmit_cnt.bytes,
 -						  lp->xmit_cnt.bytes, sec)));
 +			printf("\t(%sbps)", rate2str(flow_bps));
 +			if (lp->handle != NULL_CLASS_HANDLE) {
 +				printf(",\tMeasured: %s [bps]\n",
 +				       rate2str(calc_rate(sp->xmit_cnt.bytes,
 +						lp->xmit_cnt.bytes, sec)));
 +			} else {
 +				printf("\n");
 +			}
  			printf("\tpkts: %llu,\tbytes: %llu\n",
  			       (ull)sp->xmit_cnt.packets,
  			       (ull)sp->xmit_cnt.bytes);
 @@ -143,6 +146,9 @@
  
  		last_time = cur_time;
  
 +		if (count != 0 && --cnt == 0)
 +			break;
 +
  		/* wait for alarm signal */
  		if (sigprocmask(SIG_BLOCK, NULL, &omask) == 0)
  			sigsuspend(&omask);
 Index: qdisc_cdnr.c
 ===================================================================
 RCS file: /cvsroot/src/usr.sbin/altq/altqstat/qdisc_cdnr.c,v
 retrieving revision 1.4
 diff -u -r1.4 qdisc_cdnr.c
 --- qdisc_cdnr.c	12 Oct 2006 19:59:13 -0000	1.4
 +++ qdisc_cdnr.c	15 Oct 2006 15:33:29 -0000
 @@ -80,7 +80,7 @@
  	for (i = 0; i < NELEMENTS; i++)
  		stats1[i].tce_handle = stats2[i].tce_handle = CDNR_NULL_HANDLE;
  
 -	while (count == 0 || cnt-- > 0) {
 +	for (;;) {
  		get_stats.nskip = 0;
  		get_stats.nelements = NELEMENTS;
  		get_stats.tce_stats = new;
 @@ -106,8 +106,7 @@
  
  			if (sp->tce_handle != lp->tce_handle) {
  				quip_chandle2name(_ifname, sp->tce_handle,
 -						  cdnrnames[i], sizeof(cdnrnames[0]));
 -				continue;
 +				    cdnrnames[i], sizeof(cdnrnames[0]));
  			}
  
  			switch (sp->tce_type) {
 @@ -132,14 +131,18 @@
  			       element_names[sp->tce_type], cdnrnames[i],
  			       sp->tce_handle);
  			for (j = 0; j < nprofile; j++) {
 -				printf("  %s %10llu pkts %16llu bytes (%sbps)\n",
 -				       profile_names[j], 
 -				       (ull)sp->tce_cnts[j].packets,
 -				       (ull)sp->tce_cnts[j].bytes,
 -				       rate2str(
 -					       calc_rate(sp->tce_cnts[j].bytes,
 -							 lp->tce_cnts[j].bytes,
 -							 sec)));
 +				printf("  %s %10llu pkts %16llu bytes",
 +				    profile_names[j],
 +				    (ull)sp->tce_cnts[j].packets,
 +				    (ull)sp->tce_cnts[j].bytes);
 +				if (lp->tce_handle != CDNR_NULL_HANDLE) {
 +					printf(" (%sbps)\n",
 +					    rate2str(calc_rate(
 +					        sp->tce_cnts[j].bytes,
 +						lp->tce_cnts[j].bytes, sec)));
 +				} else {
 +					printf("\n");
 +				}
  			}
  		}
  		printf("\n");
 @@ -151,6 +154,9 @@
  
  		last_time = cur_time;
  
 +		if (count != 0 && --cnt == 0)
 +			break;
 +
  		/* wait for alarm signal */
  		if (sigprocmask(SIG_BLOCK, NULL, &omask) == 0)
  			sigsuspend(&omask);
 Index: qdisc_fifoq.c
 ===================================================================
 RCS file: /cvsroot/src/usr.sbin/altq/altqstat/qdisc_fifoq.c,v
 retrieving revision 1.4
 diff -u -r1.4 qdisc_fifoq.c
 --- qdisc_fifoq.c	12 Oct 2006 19:59:13 -0000	1.4
 +++ qdisc_fifoq.c	15 Oct 2006 15:33:29 -0000
 @@ -62,8 +62,7 @@
  	last_time.tv_sec -= interval;
  	last_bytes = 0;
  
 -	while (count == 0 || cnt-- > 0) {
 -	
 +	for (;;) {	
  		if (ioctl(fd, FIFOQ_GETSTATS, &get_stats) < 0)
  			err(1, "ioctl FIFOQ_GETSTATS");
  
 @@ -84,6 +83,9 @@
  		last_bytes = get_stats.xmit_cnt.bytes;
  		last_time = cur_time;
  
 +		if (count != 0 && --cnt == 0)
 +			break;
 +
  		/* wait for alarm signal */
  		if (sigprocmask(SIG_BLOCK, NULL, &omask) == 0)
  			sigsuspend(&omask);
 Index: qdisc_hfsc.c
 ===================================================================
 RCS file: /cvsroot/src/usr.sbin/altq/altqstat/qdisc_hfsc.c,v
 retrieving revision 1.5
 diff -u -r1.5 qdisc_hfsc.c
 --- qdisc_hfsc.c	12 Oct 2006 19:59:13 -0000	1.5
 +++ qdisc_hfsc.c	15 Oct 2006 15:33:29 -0000
 @@ -70,10 +70,12 @@
  	last = &stats2[0];
  
  	/* invalidate class ids */
 -	for (i=0; i<NCLASSES; i++)
 +	for (i = 0; i < NCLASSES; i++) {
  		last[i].class_id = 999999; /* XXX */
 +		last[i].class_handle = HFSC_NULLCLASS_HANDLE;
 +	}
  
 -	while (count == 0 || cnt-- > 0) {
 +	for (;;) {
  		get_stats.nskip = 0;
  		get_stats.nclasses = NCLASSES;
  		get_stats.stats = new;
 @@ -96,8 +98,7 @@
  
  			if (sp->class_id != lp->class_id) {
  				quip_chandle2name(ifname, sp->class_handle,
 -						  clnames[i], sizeof(clnames[0]));
 -				continue;
 +				    clnames[i], sizeof(clnames[0]));
  			}
  
  			printf("[%2d %s] handle:%#x [rt %s %ums %s][ls %s %ums %s]",
 @@ -112,12 +113,14 @@
  				       rate2str((double)sp->usc.m2));
  			else
  				 printf("\n");
 -			printf("  measured: %sbps [rt:%s ls:%s] qlen:%2d period:%u\n",
 -			       rate2str(calc_rate(sp->total, lp->total, sec)),
 -			       rate2str(calc_rate(sp->cumul, lp->cumul, sec)),
 -			       rate2str(calc_rate(sp->total - sp->cumul,
 -						  lp->total - lp->cumul, sec)),
 -			       sp->qlength, sp->period);
 +			if (lp->class_handle != HFSC_NULLCLASS_HANDLE) {
 +				printf("  measured: %sbps [rt:%s ls:%s] qlen:%2d period:%u\n",
 +				    rate2str(calc_rate(sp->total, lp->total, sec)),
 +				    rate2str(calc_rate(sp->cumul, lp->cumul, sec)),
 +				    rate2str(calc_rate(sp->total - sp->cumul,
 +					lp->total - lp->cumul, sec)),
 +				    sp->qlength, sp->period);
 +			}
  			printf("     packets:%llu (%llu bytes) drops:%llu (%llu bytes) \n",
  			       (ull)sp->xmit_cnt.packets,
  			       (ull)sp->xmit_cnt.bytes,
 @@ -155,6 +158,9 @@
  
  		last_time = cur_time;
  
 +		if (count != 0 && --cnt == 0)
 +			break;
 +
  		/* wait for alarm signal */
  		if (sigprocmask(SIG_BLOCK, NULL, &omask) == 0)
  			sigsuspend(&omask);
 Index: qdisc_jobs.c
 ===================================================================
 RCS file: /cvsroot/src/usr.sbin/altq/altqstat/qdisc_jobs.c,v
 retrieving revision 1.2
 diff -u -r1.2 qdisc_jobs.c
 --- qdisc_jobs.c	12 Oct 2006 19:59:13 -0000	1.2
 +++ qdisc_jobs.c	15 Oct 2006 15:33:29 -0000
 @@ -96,7 +96,7 @@
  	for (i=0; i<JOBS_MAXPRI; i++)
  		last[i].class_handle = JOBS_NULLCLASS_HANDLE;
  
 -	while (count == 0 || cnt-- > 0) {
 +	for (;;) {
  		get_stats.stats = new;
  		get_stats.maxpri = JOBS_MAXPRI;
  		if (ioctl(fd, JOBS_GETSTATS, &get_stats) < 0)
 @@ -169,6 +169,9 @@
  
  		last_time = cur_time;
  
 +		if (count != 0 && --cnt == 0)
 +			break;
 +
  		/* wait for alarm signal */
  		if (sigprocmask(SIG_BLOCK, NULL, &omask) == 0)
  			sigsuspend(&omask);
 Index: qdisc_priq.c
 ===================================================================
 RCS file: /cvsroot/src/usr.sbin/altq/altqstat/qdisc_priq.c,v
 retrieving revision 1.5
 diff -u -r1.5 qdisc_priq.c
 --- qdisc_priq.c	12 Oct 2006 19:59:13 -0000	1.5
 +++ qdisc_priq.c	15 Oct 2006 15:33:29 -0000
 @@ -68,7 +68,7 @@
  	for (i=0; i<PRIQ_MAXPRI; i++)
  		last[i].class_handle = PRIQ_NULLCLASS_HANDLE;
  
 -	while (count == 0 || cnt-- > 0) {
 +	for (;;) {
  		get_stats.stats = new;
  		get_stats.maxpri = PRIQ_MAXPRI;
  		if (ioctl(fd, PRIQ_GETSTATS, &get_stats) < 0)
 @@ -88,16 +88,17 @@
  
  			if (sp->class_handle != lp->class_handle) {
  				quip_chandle2name(ifname, sp->class_handle,
 -						  clnames[i], sizeof(clnames[0]));
 -				continue;
 +				    clnames[i], sizeof(clnames[0]));
  			}
  
  			printf("[%s] handle:%#x pri:%d\n",
  			       clnames[i], sp->class_handle, i);
 -			printf("  measured: %sbps qlen:%2d period:%u\n",
 -			       rate2str(calc_rate(sp->xmitcnt.bytes,
 -						  lp->xmitcnt.bytes, sec)),
 -			       sp->qlength, sp->period);
 +			if (lp->class_handle != PRIQ_NULLCLASS_HANDLE) {
 +				printf("  measured: %sbps qlen:%2d period:%u\n",
 +				    rate2str(calc_rate(sp->xmitcnt.bytes,
 +					lp->xmitcnt.bytes, sec)),
 +				    sp->qlength, sp->period);
 +			}
  			printf("     packets:%llu (%llu bytes) drops:%llu\n",
  			       (ull)sp->xmitcnt.packets,
  			       (ull)sp->xmitcnt.bytes,
 @@ -115,6 +116,9 @@
  
  		last_time = cur_time;
  
 +		if (count != 0 && --cnt == 0)
 +			break;
 +
  		/* wait for alarm signal */
  		if (sigprocmask(SIG_BLOCK, NULL, &omask) == 0)
  			sigsuspend(&omask);
 Index: qdisc_red.c
 ===================================================================
 RCS file: /cvsroot/src/usr.sbin/altq/altqstat/qdisc_red.c,v
 retrieving revision 1.4
 diff -u -r1.4 qdisc_red.c
 --- qdisc_red.c	12 Oct 2006 19:59:13 -0000	1.4
 +++ qdisc_red.c	15 Oct 2006 15:33:29 -0000
 @@ -64,8 +64,7 @@
  	last_time.tv_sec -= interval;
  	last_bytes = 0;
  
 -	while (count == 0 || cnt-- > 0) {
 -	
 +	for (;;) {	
  		if (ioctl(fd, RED_GETSTATS, &red_stats) < 0)
  			err(1, "ioctl RED_GETSTATS");
  
 @@ -100,6 +99,9 @@
  		last_bytes = red_stats.xmit_cnt.bytes;
  		last_time = cur_time;
  
 +		if (count != 0 && --cnt == 0)
 +			break;
 +
  		/* wait for alarm signal */
  		if (sigprocmask(SIG_BLOCK, NULL, &omask) == 0)
  			sigsuspend(&omask);
 Index: qdisc_rio.c
 ===================================================================
 RCS file: /cvsroot/src/usr.sbin/altq/altqstat/qdisc_rio.c,v
 retrieving revision 1.5
 diff -u -r1.5 qdisc_rio.c
 --- qdisc_rio.c	12 Oct 2006 19:59:13 -0000	1.5
 +++ qdisc_rio.c	15 Oct 2006 15:33:29 -0000
 @@ -66,8 +66,7 @@
  	gettimeofday(&last_time, NULL);
  	last_time.tv_sec -= interval;
  
 -	while (count == 0 || cnt-- > 0) {
 -	
 +	for (;;) {	
  		if (ioctl(fd, RIO_GETSTATS, &rio_stats) < 0)
  			err(1, "ioctl RIO_GETSTATS");
  
 @@ -130,6 +129,9 @@
  		last_bytes[2] = rio_stats.q_stats[2].xmit_cnt.bytes;
  		last_time = cur_time;
  
 +		if (count != 0 && --cnt == 0)
 +			break;
 +
  		/* wait for alarm signal */
  		if (sigprocmask(SIG_BLOCK, NULL, &omask) == 0)
  			sigsuspend(&omask);
 Index: qdisc_wfq.c
 ===================================================================
 RCS file: /cvsroot/src/usr.sbin/altq/altqstat/qdisc_wfq.c,v
 retrieving revision 1.4
 diff -u -r1.4 qdisc_wfq.c
 --- qdisc_wfq.c	12 Oct 2006 19:59:13 -0000	1.4
 +++ qdisc_wfq.c	15 Oct 2006 15:33:29 -0000
 @@ -97,8 +97,7 @@
  	gettimeofday(&last_time, NULL);
  	last_time.tv_sec -= interval;
  
 -	while (count == 0 || cnt-- > 0) {
 -
 +	for (;;) {
  		for (j = 0; j < ntop; j++)
  			top[j] = NULL;
  
 @@ -165,6 +164,9 @@
  
  		last_time = cur_time;
  
 +		if (count != 0 && --cnt == 0)
 +			break;
 +
  		/* wait for alarm signal */
  		if (sigprocmask(SIG_BLOCK, NULL, &omask) == 0)
  			sigsuspend(&omask);
 
 --y0ulUmNC+osPPQO6--