From owner-freebsd-bugs@FreeBSD.ORG Mon Jun 7 22:30:19 2004 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D12C516A4D0 for ; Mon, 7 Jun 2004 22:30:19 +0000 (GMT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id CAA5543D2F for ; Mon, 7 Jun 2004 22:30:19 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.11/8.12.11) with ESMTP id i57MUIFw016389 for ; Mon, 7 Jun 2004 22:30:18 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.11/8.12.11/Submit) id i57MUIxI016388; Mon, 7 Jun 2004 22:30:18 GMT (envelope-from gnats) Date: Mon, 7 Jun 2004 22:30:18 GMT Message-Id: <200406072230.i57MUIxI016388@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org From: Dan Nelson Subject: Re: misc/67687: read/write disk bandwidth monitoring? X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Dan Nelson List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 07 Jun 2004 22:30:20 -0000 The following reply was made to PR misc/67687; it has been noted by GNATS. From: Dan Nelson To: freebsd-gnats-submit@FreeBSD.org Cc: Subject: Re: misc/67687: read/write disk bandwidth monitoring? Date: Wed, 14 Apr 2004 14:27:30 -0500 --PEIAKu/WMn1b1Hv9 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In the last episode (Apr 14), Aditya said: > iostat can provide an aggregate number for transactions per second and Bytes > per transaction for a given device, but if it is a block device, is there a > counter accessible from iostat or elsewhere that I can see how much is read > transactions versus write transactions? > > > iostat -K -d -I 1 > ad0 ad2 da0 pass0 > KB/t xfrs MB KB/t xfrs MB KB/t xfrs MB KB/t xfrs MB > 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 > 7.50 8 0.06 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 > 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 > 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 0.00 0 0.00 > ^C > > tells me transactions per device, but not divided into reads versus writes... This is definitely possible, but iostat doesn't currently print it. I have patches that add a Solaris-style -x flag to iostat, which gives you output like: $ iostat -x 1 extended device statistics device r/s w/s kr/s kw/s wait actv svc_t %w %b da0 29.7 24.8 466.3 249.5 0 1 33.5 0 46 cd0 0.0 0.0 0.0 0.0 0 0 0.0 0 0 cd1 0.0 0.0 0.0 0.0 0 0 0.0 0 0 On -current, you can also use the "gstat" command (run it as root), which can give you read and write stats down to the partition level. -- Dan Nelson dnelson@allantgroup.com --PEIAKu/WMn1b1Hv9 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="iostat.diff" Index: iostat.c =================================================================== RCS file: /home/ncvs/src/usr.sbin/iostat/iostat.c,v retrieving revision 1.28 diff -u -r1.28 iostat.c --- iostat.c 15 Mar 2003 21:59:06 -0000 1.28 +++ iostat.c 17 Apr 2003 02:49:27 -0000 @@ -136,7 +136,7 @@ struct device_selection *dev_select; int maxshowdevs; volatile sig_atomic_t headercount; -int dflag = 0, Iflag = 0, Cflag = 0, Tflag = 0, oflag = 0, Kflag = 0; +int dflag = 0, Iflag = 0, Cflag = 0, Tflag = 0, oflag = 0, Kflag = 0, xflag = 0; /* local function declarations */ static void usage(void); @@ -156,7 +156,7 @@ * This isn't mentioned in the man page, or the usage statement, * but it is supported. */ - fprintf(stderr, "usage: iostat [-CdhIKoT?] [-c count] [-M core]" + fprintf(stderr, "usage: iostat [-CdhIKoTx?] [-c count] [-M core]" " [-n devs] [-N system]\n" "\t [-t type,if,pass] [-w wait] [drives]\n"); } @@ -184,7 +184,7 @@ matches = NULL; maxshowdevs = 3; - while ((c = getopt(argc, argv, "c:CdhIKM:n:N:ot:Tw:?")) != -1) { + while ((c = getopt(argc, argv, "c:CdhIKl:M:n:N:ot:Tw:x?")) != -1) { switch(c) { case 'c': cflag++; @@ -211,6 +211,7 @@ memf = optarg; break; case 'n': + case 'l': nflag++; maxshowdevs = atoi(optarg); if (maxshowdevs < 0) @@ -238,6 +239,9 @@ if (waittime < 1) errx(1, "wait time is < 1"); break; + case 'x': + xflag++; + break; default: usage(); exit(1); @@ -270,7 +274,7 @@ * Make sure Tflag and/or Cflag are set if dflag == 0. If dflag is * greater than 0, they may be 0 or non-zero. */ - if (dflag == 0) { + if (dflag == 0 && xflag == 0) { Cflag = 1; Tflag = 1; } @@ -547,16 +551,18 @@ last.cp_time[i] = tmp; } - if (Tflag > 0) + if (Tflag > 0 && !xflag) printf("%4.0Lf%5.0Lf", cur.tk_nin / etime, cur.tk_nout/etime); devstats(hflag, etime, havelast); - if (Cflag > 0) + if (Cflag > 0 && !xflag) cpustats(); - printf("\n"); + if (!xflag) + printf("\n"); + fflush(stdout); if (count >= 0 && --count <= 0) @@ -584,7 +590,9 @@ { register int i; int printed; - + + if (xflag) + return; if (Tflag > 0) (void)printf(" tty"); for (i = 0, printed=0;(i < num_devices) && (printed < maxshowdevs);i++){ @@ -639,11 +647,29 @@ devstats(int perf_select, long double etime, int havelast) { register int dn; - long double transfers_per_second; - long double kb_per_transfer, mb_per_second; + long double transfers_per_second,transfers_per_second_read,transfers_per_second_write; + long double kb_per_transfer, mb_per_second, mb_per_second_read, mb_per_second_write; u_int64_t total_bytes, total_transfers, total_blocks; + long double busy_pct; + u_int64_t queue_len; long double total_mb; long double blocks_per_second, ms_per_transaction; + int firstline = 1; + + if (xflag) { + printf (" extended device statistics "); + if (Tflag) + printf (" tty "); + if (Cflag) + printf (" cpu "); + printf ("\n"); + printf ("device r/s w/s kr/s kw/s wait actv svc_t %%w %%b "); + if (Tflag) + printf ("tin tout "); + if (Cflag) + printf ("us ni sy in id "); + printf ("\n"); + } for (dn = 0; dn < num_devices; dn++) { int di; @@ -661,9 +687,15 @@ DSM_TOTAL_BLOCKS, &total_blocks, DSM_KB_PER_TRANSFER, &kb_per_transfer, DSM_TRANSFERS_PER_SECOND, &transfers_per_second, + DSM_TRANSFERS_PER_SECOND_READ, &transfers_per_second_read, + DSM_TRANSFERS_PER_SECOND_WRITE, &transfers_per_second_write, DSM_MB_PER_SECOND, &mb_per_second, + DSM_MB_PER_SECOND_READ, &mb_per_second_read, + DSM_MB_PER_SECOND_WRITE, &mb_per_second_write, DSM_BLOCKS_PER_SECOND, &blocks_per_second, DSM_MS_PER_TRANSACTION, &ms_per_transaction, + DSM_BUSY_PCT, &busy_pct, + DSM_QUEUE_LENGTH, &queue_len, DSM_NONE) != 0) errx(1, "%s", devstat_errbuf); @@ -674,13 +706,34 @@ continue; } - if (Kflag) { + if (Kflag || xflag) { int block_size = cur.dinfo->devices[di].block_size; total_blocks = total_blocks * (block_size ? block_size : 512) / 1024; } - if (oflag > 0) { + if (xflag > 0) { + char *devname; + asprintf(&devname,"%s%d", + cur.dinfo->devices[di].device_name, + cur.dinfo->devices[di].unit_number); + printf ("%-8.8s %5.1Lf %5.1Lf %7.1Lf %7.1Lf %4qu %4qu %5.1Lf %3.0Lf %3.0Lf ", + devname, + transfers_per_second_read, transfers_per_second_write, + mb_per_second_read*1024, mb_per_second_write*1024, + (u_int64_t)0,queue_len,ms_per_transaction,(long double)0.0,busy_pct + ); + free(devname); + if (firstline) { + firstline = 0; + if (Tflag > 0) + printf("%4.0Lf%5.0Lf ", cur.tk_nin / etime, + cur.tk_nout/etime); + if (Cflag > 0) + cpustats(); + } + printf ("\n"); + } else if (oflag > 0) { int msdig = (ms_per_transaction < 100.0) ? 1 : 0; if (Iflag == 0) @@ -727,6 +780,7 @@ for (state = 0; state < CPUSTATES; ++state) printf(" %2.0f", rint(100. * cur.cp_time[state] / (time ? time : 1))); + printf(" "); } static int --PEIAKu/WMn1b1Hv9--