From owner-freebsd-bugs@FreeBSD.ORG Sat Oct 30 22:01:07 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 411AD16A4E2 for ; Sat, 30 Oct 2004 22:01:07 +0000 (GMT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0C37943D48 for ; Sat, 30 Oct 2004 22:01:07 +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 i9UM16mw094478 for ; Sat, 30 Oct 2004 22:01:06 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.11/8.12.11/Submit) id i9UM16ik094477; Sat, 30 Oct 2004 22:01:06 GMT (envelope-from gnats) Resent-Date: Sat, 30 Oct 2004 22:01:06 GMT Resent-Message-Id: <200410302201.i9UM16ik094477@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, "Peter Schuller" Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 84CC316A4CE for ; Sat, 30 Oct 2004 21:51:42 +0000 (GMT) Received: from mxfep02.bredband.com (mxfep02.bredband.com [195.54.107.73]) by mx1.FreeBSD.org (Postfix) with ESMTP id BCCC943D3F for ; Sat, 30 Oct 2004 21:51:36 +0000 (GMT) (envelope-from root@scode-whitestar.mine.nu) Received: from scode-whitestar.mine.nu ([83.226.138.136] [83.226.138.136]) by mxfep02.bredband.com with ESMTP <20041030215132.JWCM44.mxfep02.bredband.com@scode-whitestar.mine.nu>; Sat, 30 Oct 2004 23:51:32 +0200 Received: by scode-whitestar.mine.nu (Postfix, from userid 0) id 37E9717B872; Sat, 30 Oct 2004 23:56:34 +0200 (CEST) Message-Id: <20041030215634.37E9717B872@scode-whitestar.mine.nu> Date: Sat, 30 Oct 2004 23:56:34 +0200 (CEST) From: "Peter Schuller" To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 cc: peter.schuller@infidyne.com Subject: bin/73327: [PATCH] iostat - extended mode display X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 30 Oct 2004 22:01:07 -0000 >Number: 73327 >Category: bin >Synopsis: [PATCH] iostat - extended mode display >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Sat Oct 30 22:01:06 GMT 2004 >Closed-Date: >Last-Modified: >Originator: peter.schuller@infidyne.com >Release: FreeBSD 5.2.1-RELEASE-p9 i386 >Organization: >Environment: System: FreeBSD scode-whitestar.mine.nu 5.2.1-RELEASE-p9 FreeBSD 5.2.1-RELEASE-p9 #9: Sat Jul 3 17:14:56 CEST 2004 toor@scode-whitestar.mine.nu:/usr/obj/usr/src/sys/WHITESTAR i386 FreeBSD 5.2.1 >Description: FreeBSD's iostat lacks "extended" output (ala NetBSD's -x and the default on newer GNU systems). A one-device-per-line mode is very useful on systems with many devices. On such systems it is currently difficult to get an overall view of I/O activity using iostat.OB >How-To-Repeat: >Fix: The attached patches add a -x option to iostat and updates the manpage accordingly. In addition to showing devices on individual lines, extended mode also displayes read/write (in addition to total) statistics. The layout was also adjusted to accommodate larger values that are common on modern systems. --- patch-iostat.c begins here --- --- iostat_53.c Sat Oct 30 21:35:44 2004 +++ iostat.c Sat Oct 30 23:03:04 2004 @@ -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); @@ -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:CdhIKM:n:N:ot:Txw:?")) != -1) { switch(c) { case 'c': cflag++; @@ -232,6 +232,10 @@ case 'T': Tflag++; break; + case 'x': + xflag++; + dflag++; + break; case 'w': wflag++; waittime = atoi(optarg); @@ -279,18 +283,22 @@ * Figure out how many devices we should display. */ if (nflag == 0) { - if (oflag > 0) { - if ((dflag > 0) && (Cflag == 0) && (Tflag == 0)) - maxshowdevs = 5; - else if ((dflag > 0) && (Tflag > 0) && (Cflag == 0)) - maxshowdevs = 5; - else - maxshowdevs = 4; + if (xflag > 0) { + maxshowdevs = 20; /* Suitable for 25 line screens */ } else { - if ((dflag > 0) && (Cflag == 0)) - maxshowdevs = 4; - else - maxshowdevs = 3; + if (oflag > 0) { + if ((dflag > 0) && (Cflag == 0) && (Tflag == 0)) + maxshowdevs = 5; + else if ((dflag > 0) && (Tflag > 0) && (Cflag == 0)) + maxshowdevs = 5; + else + maxshowdevs = 4; + } else { + if ((dflag > 0) && (Cflag == 0)) + maxshowdevs = 4; + else + maxshowdevs = 3; + } } } @@ -441,7 +449,7 @@ } } - if (!--headercount) { + if (!--headercount || xflag > 0) { phdr(); headercount = 20; } @@ -587,20 +595,22 @@ if (Tflag > 0) (void)printf(" tty"); - for (i = 0, printed=0;(i < num_devices) && (printed < maxshowdevs);i++){ - int di; - if ((dev_select[i].selected != 0) - && (dev_select[i].selected <= maxshowdevs)) { - di = dev_select[i].position; - if (oflag > 0) - (void)printf("%12.6s%d ", - cur.dinfo->devices[di].device_name, - cur.dinfo->devices[di].unit_number); - else - printf("%15.6s%d ", - cur.dinfo->devices[di].device_name, - cur.dinfo->devices[di].unit_number); - printed++; + if (xflag == 0) { + for (i = 0, printed=0;(i < num_devices) && (printed < maxshowdevs);i++){ + int di; + if ((dev_select[i].selected != 0) + && (dev_select[i].selected <= maxshowdevs)) { + di = dev_select[i].position; + if (oflag > 0) + (void)printf("%12.6s%d ", + cur.dinfo->devices[di].device_name, + cur.dinfo->devices[di].unit_number); + else + printf("%15.6s%d ", + cur.dinfo->devices[di].device_name, + cur.dinfo->devices[di].unit_number); + printed++; + } } } if (Cflag > 0) @@ -611,21 +621,35 @@ if (Tflag > 0) (void)printf(" tin tout"); - for (i=0, printed = 0;(i < num_devices) && (printed < maxshowdevs);i++){ - if ((dev_select[i].selected != 0) - && (dev_select[i].selected <= maxshowdevs)) { - if (oflag > 0) { - if (Iflag == 0) - (void)printf(" sps tps msps "); - else - (void)printf(" blk xfr msps "); - } else { - if (Iflag == 0) - printf(" KB/t tps MB/s "); - else - printf(" KB/t xfrs MB "); + if (xflag > 0) { + if (oflag > 0) { + if (Iflag == 0) + printf(" dev sps r w tps msps"); + else + printf(" dev blk r w xfr msps"); + } else { + if (Iflag == 0) + printf(" dev KB/t tps MB/s MBr/s MRw/s"); + else + printf(" dev KB/t xfrs MB MBr MBw"); + } + } else { + for (i=0, printed = 0;(i < num_devices) && (printed < maxshowdevs);i++){ + if ((dev_select[i].selected != 0) + && (dev_select[i].selected <= maxshowdevs)) { + if (oflag > 0) { + if (Iflag == 0) + (void)printf(" sps tps msps "); + else + (void)printf(" blk xfr msps "); + } else { + if (Iflag == 0) + printf(" KB/t tps MB/s "); + else + printf(" KB/t xfrs MB "); + } + printed++; } - printed++; } } if (Cflag > 0) @@ -641,10 +665,16 @@ register int dn; long double transfers_per_second; long double kb_per_transfer, mb_per_second; + long double mb_per_second_read, mb_per_second_write; u_int64_t total_bytes, total_transfers, total_blocks; - long double total_mb; + u_int64_t total_bytes_read; + u_int64_t total_blocks_read; + u_int64_t total_bytes_write; + u_int64_t total_blocks_write; + long double total_mb, total_mb_read, total_mb_write; long double blocks_per_second, ms_per_transaction; - + long double blocks_per_second_read, blocks_per_second_write; + for (dn = 0; dn < num_devices; dn++) { int di; @@ -657,12 +687,20 @@ if (devstat_compute_statistics(&cur.dinfo->devices[di], havelast ? &last.dinfo->devices[di] : NULL, etime, DSM_TOTAL_BYTES, &total_bytes, + DSM_TOTAL_BYTES_READ, &total_bytes_read, + DSM_TOTAL_BYTES_WRITE, &total_bytes_write, DSM_TOTAL_TRANSFERS, &total_transfers, DSM_TOTAL_BLOCKS, &total_blocks, + DSM_TOTAL_BLOCKS_READ, &total_blocks_read, + DSM_TOTAL_BLOCKS_WRITE, &total_blocks_write, DSM_KB_PER_TRANSFER, &kb_per_transfer, DSM_TRANSFERS_PER_SECOND, &transfers_per_second, - DSM_MB_PER_SECOND, &mb_per_second, + 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_BLOCKS_PER_SECOND_READ, &blocks_per_second_read, + DSM_BLOCKS_PER_SECOND_WRITE, &blocks_per_second_write, DSM_MS_PER_TRANSACTION, &ms_per_transaction, DSM_NONE) != 0) errx(1, "%s", devstat_errbuf); @@ -684,31 +722,82 @@ int msdig = (ms_per_transaction < 100.0) ? 1 : 0; if (Iflag == 0) - printf("%4.0Lf%4.0Lf%5.*Lf ", - blocks_per_second, - transfers_per_second, - msdig, - ms_per_transaction); - else - printf("%4.1qu%4.1qu%5.*Lf ", - total_blocks, - total_transfers, - msdig, - ms_per_transaction); + if (xflag == 0) { + printf("%4.0Lf%4.0Lf%5.*Lf ", + blocks_per_second, + transfers_per_second, + msdig, + ms_per_transaction); + } else { + printf("%12.6s%d %8.0Lf%8.0Lf%8.0Lf%8.0Lf%8.*Lf\n", + dev_select[dn].device_name, + dev_select[dn].unit_number, + blocks_per_second, + blocks_per_second_read, + blocks_per_second_write, + transfers_per_second, + msdig, + ms_per_transaction); + } + else { + if (xflag == 0) { + printf("%4.1qu%4.1qu%5.*Lf ", + total_blocks, + total_transfers, + msdig, + ms_per_transaction); + } else { + printf("%12.6s%d %8.1qu%8.1qu%8.1qu%8.1qu%8.*Lf\n", + dev_select[dn].device_name, + dev_select[dn].unit_number, + total_blocks, + total_blocks_read, + total_blocks_write, + total_transfers, + msdig, + ms_per_transaction); + } + } } else { if (Iflag == 0) - printf(" %5.2Lf %3.0Lf %5.2Lf ", - kb_per_transfer, - transfers_per_second, - mb_per_second); + if (xflag == 0) { + printf(" %5.2Lf %3.0Lf %5.2Lf ", + kb_per_transfer, + transfers_per_second, + mb_per_second); + } else { + printf("%12.6s%d %8.2Lf %8.0Lf %8.2Lf %8.2Lf %8.2Lf\n", + dev_select[dn].device_name, + dev_select[dn].unit_number, + kb_per_transfer, + transfers_per_second, + mb_per_second, + mb_per_second_read, + mb_per_second_write); + } else { total_mb = total_bytes; total_mb /= 1024 * 1024; - - printf(" %5.2Lf %3.1qu %5.2Lf ", - kb_per_transfer, - total_transfers, - total_mb); + + if (xflag == 0) { + printf(" %5.2Lf %3.1qu %5.2Lf ", + kb_per_transfer, + total_transfers, + total_mb); + } else { + total_mb_read = total_bytes_read; + total_mb_read /= 1024 * 1024; + total_mb_write = total_bytes_write; + total_mb_write /= 1024 * 1024; + printf("%12.6s%d %8.2Lf %8.1qu %8.2Lf %8.2Lf %8.2Lf\n", + dev_select[dn].device_name, + dev_select[dn].unit_number, + kb_per_transfer, + total_transfers, + total_mb, + total_mb_read, + total_mb_write); + } } } } --- patch-iostat.c ends here --- --- patch-iostat.8 begins here --- --- iostat_53.8 Sat Oct 30 21:52:01 2004 +++ iostat.8 Sat Oct 30 23:07:07 2004 @@ -107,10 +107,16 @@ Display CPU statistics. This is on by default, unless .Fl d -is specified. +is specified. If +.Fl x +is specified, this option has no effect. .It Fl d -Display only device statistics. -If this flag is turned on, only device statistics will be displayed, unless +Display only device statistics. Default if +.Fl x +is specified. +If this flag is turned on, only device statistics will be displayed unless +.Fl x +is NOT specified and .Fl C or .Fl T @@ -231,7 +237,15 @@ Display TTY statistics. This is on by default, unless .Fl d +or +.Fl x is specified. +.It Fl x +Show extended statistics. Implies -d. By default up to 20 devices +are shown. In this mode each device is displayed on a line of its +own and the header is printed at each update. The layout is also +slightly adjusted to accommodate larger values. Individual read +and write statistics are printed in addition to the totals. .It Fl w Pause .Ar wait --- patch-iostat.8 ends here --- >Release-Note: >Audit-Trail: >Unformatted: