Author: mav
Date: Mon Sep 21 09:37:49 2015
New Revision: 288059
URL: https://svnweb.freebsd.org/changeset/base/288059

Log:
  Bunch of improvements to ctlstat.
  
  Add -p option to allow filtering by ports.
  Make -l and -p options work in all modes as filters.
  Improve output formatting to better fit columns.

Modified:
  head/usr.bin/ctlstat/ctlstat.8
  head/usr.bin/ctlstat/ctlstat.c

Modified: head/usr.bin/ctlstat/ctlstat.8
==============================================================================
--- head/usr.bin/ctlstat/ctlstat.8      Mon Sep 21 08:44:23 2015        
(r288058)
+++ head/usr.bin/ctlstat/ctlstat.8      Mon Sep 21 09:37:49 2015        
(r288059)
@@ -34,7 +34,7 @@
 .\" $Id: //depot/users/kenm/FreeBSD-test2/usr.bin/ctlstat/ctlstat.8#2 $
 .\" $FreeBSD$
 .\"
-.Dd May 22, 2015
+.Dd September 21, 2015
 .Dt CTLSTAT 8
 .Os
 .Sh NAME
@@ -50,6 +50,7 @@
 .Op Fl j
 .Op Fl l Ar lun
 .Op Fl n Ar numdevs
+.Op Fl p Ar port
 .Op Fl w Ar wait
 .Sh DESCRIPTION
 The
@@ -64,7 +65,7 @@ The options are as follows:
 .Bl -tag -width 10n
 .It Fl t
 Total mode.
-This displays separate columns with the total CTL read and write output,
+This displays separate columns with the total read and write output,
 and a combined total column that also includes non I/O operations.
 .It Fl c Ar count
 Display statistics this many times.
@@ -74,23 +75,20 @@ Disable CPU statistics display.
 Display DMA operation time (latency) instead of overall I/O time (latency).
 .It Fl D
 Text dump mode.
-Dump all available statistics every 30 seconds in a text format suitable
-for parsing.
+Dump statistics every 30 seconds in a text format suitable for parsing.
 No statistics are computed in this mode, only raw numbers are displayed.
 .It Fl h
 Suppress display of the header.
 .It Fl j
 JSON dump mode.
-Dump all available statistics every 30 seconds in JavaScript Object
-Notation (JSON) format.
+Dump statistics every 30 seconds in JavaScript Object Notation (JSON) format.
 No statistics are computed in this mode, only raw numbers are displayed.
 .It Fl l Ar lun
 Request statistics for the specified LUN.
-This option is incompatible with total
-.Fl ( t )
-mode.
 .It Fl n Ar numdevs
 Display statistics for this many devices.
+.It Fl p Ar port
+Request statistics for the specified port.
 .It Fl w Ar wait
 Wait this many seconds in between displays.
 If this option is not specified,

Modified: head/usr.bin/ctlstat/ctlstat.c
==============================================================================
--- head/usr.bin/ctlstat/ctlstat.c      Mon Sep 21 08:44:23 2015        
(r288058)
+++ head/usr.bin/ctlstat/ctlstat.c      Mon Sep 21 09:37:49 2015        
(r288059)
@@ -78,7 +78,7 @@ __FBSDID("$FreeBSD$");
  */
 #define        CTL_STAT_LUN_BITS       1024L
 
-static const char *ctlstat_opts = "Cc:Ddhjl:n:tw:";
+static const char *ctlstat_opts = "Cc:Ddhjl:n:p:tw:";
 static const char *ctlstat_usage = "Usage:  ctlstat [-CDdjht] [-l lunnum]"
                                   "[-c count] [-n numdevs] [-w wait]\n";
 
@@ -102,12 +102,16 @@ typedef enum {
 #define        CTLSTAT_FLAG_TOTALS             (1 << 3)
 #define        CTLSTAT_FLAG_DMA_TIME           (1 << 4)
 #define        CTLSTAT_FLAG_LUN_TIME_VALID     (1 << 5)
+#define        CTLSTAT_FLAG_LUN_MASK           (1 << 6)
+#define        CTLSTAT_FLAG_PORT_MASK          (1 << 7)
 #define        F_CPU(ctx) ((ctx)->flags & CTLSTAT_FLAG_CPU)
 #define        F_HDR(ctx) ((ctx)->flags & CTLSTAT_FLAG_HEADER)
 #define        F_FIRST(ctx) ((ctx)->flags & CTLSTAT_FLAG_FIRST_RUN)
 #define        F_TOTALS(ctx) ((ctx)->flags & CTLSTAT_FLAG_TOTALS)
 #define        F_DMA(ctx) ((ctx)->flags & CTLSTAT_FLAG_DMA_TIME)
 #define        F_LUNVAL(ctx) ((ctx)->flags & CTLSTAT_FLAG_LUN_TIME_VALID)
+#define        F_LUNMASK(ctx) ((ctx)->flags & CTLSTAT_FLAG_LUN_MASK)
+#define        F_PORTMASK(ctx) ((ctx)->flags & CTLSTAT_FLAG_PORT_MASK)
 
 struct ctlstat_context {
        ctlstat_mode_types mode;
@@ -120,6 +124,7 @@ struct ctlstat_context {
        uint64_t cur_total_jiffies, prev_total_jiffies;
        uint64_t cur_idle, prev_idle;
        bitstr_t bit_decl(lun_mask, CTL_STAT_LUN_BITS);
+       bitstr_t bit_decl(port_mask, CTL_MAX_PORTS);
        int num_luns;
        int numdevs;
        int header_interval;
@@ -133,7 +138,8 @@ static void usage(int error);
 static int getstats(int fd, int *num_luns, struct ctl_lun_io_stats 
**xlun_stats,
                    struct timespec *cur_time, int *lun_time_valid);
 static int getcpu(struct ctl_cpu_stats *cpu_stats);
-static void compute_stats(struct ctl_lun_io_stats *cur_stats,
+static void compute_stats(struct ctlstat_context *ctx,
+                         struct ctl_lun_io_stats *cur_stats,
                          struct ctl_lun_io_stats *prev_stats,
                          long double etime, long double *mbsec,
                          long double *kb_per_transfer,
@@ -234,7 +240,7 @@ getcpu(struct ctl_cpu_stats *cpu_stats)
 }
 
 static void
-compute_stats(struct ctl_lun_io_stats *cur_stats,
+compute_stats(struct ctlstat_context *ctx, struct ctl_lun_io_stats *cur_stats,
              struct ctl_lun_io_stats *prev_stats, long double etime,
              long double *mbsec, long double *kb_per_transfer,
              long double *transfers_per_second, long double *ms_per_transfer,
@@ -251,6 +257,9 @@ compute_stats(struct ctl_lun_io_stats *c
        bzero(&total_time_ts, sizeof(total_time_ts));
        bzero(&total_dma_ts, sizeof(total_dma_ts));
        for (port = 0; port < CTL_MAX_PORTS; port++) {
+               if (F_PORTMASK(ctx) &&
+                   bit_test(ctx->port_mask, port) == 0)
+                       continue;
                for (i = 0; i < CTL_STATS_NUM_TYPES; i++) {
                        total_bytes += cur_stats->ports[port].bytes[i];
                        total_operations +=
@@ -336,8 +345,13 @@ ctlstat_dump(struct ctlstat_context *ctx
        struct ctl_lun_io_stats *stats = ctx->cur_lun_stats;
 
        for (lun = 0; lun < ctx->num_luns;lun++) {
+               if (F_LUNMASK(ctx) && bit_test(ctx->lun_mask, lun) == 0)
+                       continue;
                printf("lun %d\n", lun);
                for (port = 0; port < CTL_MAX_PORTS; port++) {
+                       if (F_PORTMASK(ctx) &&
+                           bit_test(ctx->port_mask, port) == 0)
+                               continue;
                        printf(" port %d\n",
                            stats[lun].ports[port].targ_port);
                        for (iotype = 0; iotype < CTL_STATS_NUM_TYPES;
@@ -369,8 +383,13 @@ ctlstat_json(struct ctlstat_context *ctx
 
        printf("{\"luns\":[");
        for (lun = 0; lun < ctx->num_luns; lun++) {
+               if (F_LUNMASK(ctx) && bit_test(ctx->lun_mask, lun) == 0)
+                       continue;
                printf("{\"ports\":[");
                for (port = 0; port < CTL_MAX_PORTS;port++) {
+                       if (F_PORTMASK(ctx) &&
+                           bit_test(ctx->port_mask, port) == 0)
+                               continue;
                        printf("{\"num\":%d,\"io\":[",
                            stats[lun].ports[port].targ_port);
                        for (iotype = 0; iotype < CTL_STATS_NUM_TYPES;
@@ -441,17 +460,16 @@ ctlstat_standard(struct ctlstat_context 
 
                        hdr_devs = 0;
 
+                       if (F_CPU(ctx))
+                               fprintf(stdout, " CPU");
                        if (F_TOTALS(ctx)) {
-                               fprintf(stdout, "%s     System Read     %s"
-                                       "System Write     %sSystem Total%s\n",
-                                       (F_LUNVAL(ctx) != 0) ? "     " : "",
-                                       (F_LUNVAL(ctx) != 0) ? "     " : "",
-                                       (F_LUNVAL(ctx) != 0) ? "     " : "",
-                                       (F_CPU(ctx))   ? "    CPU" : "");
+                               fprintf(stdout, "%s     Read       %s"
+                                       "    Write       %s    Total\n",
+                                       (F_LUNVAL(ctx) != 0) ? "      " : "",
+                                       (F_LUNVAL(ctx) != 0) ? "      " : "",
+                                       (F_LUNVAL(ctx) != 0) ? "      " : "");
                                hdr_devs = 3;
                        } else {
-                               if (F_CPU(ctx))
-                                       fprintf(stdout, "  CPU  ");
                                for (i = 0; i < min(CTL_STAT_LUN_BITS,
                                     ctx->num_luns); i++) {
                                        int lun;
@@ -464,7 +482,8 @@ ctlstat_standard(struct ctlstat_context 
                                        lun = (int)ctx->cur_lun_stats[i
                                                ].lun_number;
 
-                                       if (bit_test(ctx->lun_mask, lun) == 0)
+                                       if (F_LUNMASK(ctx) &&
+                                           bit_test(ctx->lun_mask, lun) == 0)
                                                continue;
                                        fprintf(stdout, "%15.6s%d %s",
                                            "lun", lun,
@@ -473,17 +492,19 @@ ctlstat_standard(struct ctlstat_context 
                                }
                                fprintf(stdout, "\n");
                        }
+                       if (F_CPU(ctx))
+                               fprintf(stdout, "    ");
                        for (i = 0; i < hdr_devs; i++)
-                               fprintf(stdout, "%s  %sKB/t %s  MB/s ",
-                                       ((F_CPU(ctx) != 0) && (i == 0) &&
-                                       (F_TOTALS(ctx) == 0)) ?  "       " : "",
-                                       (F_LUNVAL(ctx) != 0) ? " ms  " : "",
+                               fprintf(stdout, "%s KB/t   %s MB/s",
+                                       (F_LUNVAL(ctx) != 0) ? "    ms" : "",
                                        (F_DMA(ctx) == 0) ? "tps" : "dps");
                        fprintf(stdout, "\n");
                        ctx->header_interval = 20;
                }
        }
 
+       if (F_CPU(ctx))
+               fprintf(stdout, "%3.0Lf%%", cpu_percentage);
        if (F_TOTALS(ctx) != 0) {
                long double mbsec[3];
                long double kb_per_transfer[3];
@@ -515,7 +536,13 @@ ctlstat_standard(struct ctlstat_context 
            &ctx->cur_lun_stats[i].ports[p].dma_time[j])
 
                for (i = 0; i < ctx->num_luns; i++) {
+                       if (F_LUNMASK(ctx) && bit_test(ctx->lun_mask,
+                           (int)ctx->cur_lun_stats[i].lun_number) == 0)
+                               continue;
                        for (port = 0; port < CTL_MAX_PORTS; port++) {
+                               if (F_PORTMASK(ctx) &&
+                                   bit_test(ctx->port_mask, port) == 0)
+                                       continue;
                                for (j = 0; j < CTL_STATS_NUM_TYPES; j++) {
                                        ADD_STATS_BYTES(2, port, i, j);
                                        ADD_STATS_OPERATIONS(2, port, i, j);
@@ -540,29 +567,24 @@ ctlstat_standard(struct ctlstat_context 
                }
 
                for (i = 0; i < 3; i++) {
-                       compute_stats(&ctx->cur_total_stats[i],
+                       compute_stats(ctx, &ctx->cur_total_stats[i],
                                F_FIRST(ctx) ? NULL : &ctx->prev_total_stats[i],
                                etime, &mbsec[i], &kb_per_transfer[i],
                                &transfers_per_sec[i],
                                &ms_per_transfer[i], &ms_per_dma[i],
                                &dmas_per_sec[i]);
                        if (F_DMA(ctx) != 0)
-                               fprintf(stdout, " %2.2Lf",
+                               fprintf(stdout, " %5.1Lf",
                                        ms_per_dma[i]);
                        else if (F_LUNVAL(ctx) != 0)
-                               fprintf(stdout, " %2.2Lf",
+                               fprintf(stdout, " %5.1Lf",
                                        ms_per_transfer[i]);
-                       fprintf(stdout, " %5.2Lf %3.0Lf %5.2Lf ",
+                       fprintf(stdout, " %4.0Lf %5.0Lf %4.0Lf",
                                kb_per_transfer[i],
                                (F_DMA(ctx) == 0) ? transfers_per_sec[i] :
                                dmas_per_sec[i], mbsec[i]);
                }
-               if (F_CPU(ctx))
-                       fprintf(stdout, " %5.1Lf%%", cpu_percentage);
        } else {
-               if (F_CPU(ctx))
-                       fprintf(stdout, "%5.1Lf%% ", cpu_percentage);
-
                for (i = 0; i < min(CTL_STAT_LUN_BITS, ctx->num_luns); i++) {
                        long double mbsec, kb_per_transfer;
                        long double transfers_per_sec;
@@ -570,21 +592,21 @@ ctlstat_standard(struct ctlstat_context 
                        long double ms_per_dma;
                        long double dmas_per_sec;
 
-                       if (bit_test(ctx->lun_mask,
+                       if (F_LUNMASK(ctx) && bit_test(ctx->lun_mask,
                            (int)ctx->cur_lun_stats[i].lun_number) == 0)
                                continue;
-                       compute_stats(&ctx->cur_lun_stats[i], F_FIRST(ctx) ?
-                               NULL : &ctx->prev_lun_stats[i], etime,
-                               &mbsec, &kb_per_transfer,
-                               &transfers_per_sec, &ms_per_transfer,
-                               &ms_per_dma, &dmas_per_sec);
+                       compute_stats(ctx, &ctx->cur_lun_stats[i],
+                           F_FIRST(ctx) ? NULL : &ctx->prev_lun_stats[i],
+                           etime, &mbsec, &kb_per_transfer,
+                           &transfers_per_sec, &ms_per_transfer,
+                           &ms_per_dma, &dmas_per_sec);
                        if (F_DMA(ctx))
-                               fprintf(stdout, " %2.2Lf",
+                               fprintf(stdout, " %5.1Lf",
                                        ms_per_dma);
                        else if (F_LUNVAL(ctx) != 0)
-                               fprintf(stdout, " %2.2Lf",
+                               fprintf(stdout, " %5.1Lf",
                                        ms_per_transfer);
-                       fprintf(stdout, " %5.2Lf %3.0Lf %5.2Lf ",
+                       fprintf(stdout, " %4.0Lf %5.0Lf %4.0Lf",
                                kb_per_transfer, (F_DMA(ctx) == 0) ?
                                transfers_per_sec : dmas_per_sec, mbsec);
                }
@@ -596,7 +618,6 @@ main(int argc, char **argv)
 {
        int c;
        int count, waittime;
-       int set_lun;
        int fd, retval;
        struct ctlstat_context ctx;
 
@@ -640,20 +661,30 @@ main(int argc, char **argv)
                        if (cur_lun > CTL_STAT_LUN_BITS)
                                errx(1, "Invalid LUN number %d", cur_lun);
 
-                       bit_ffs(ctx.lun_mask, CTL_STAT_LUN_BITS, &set_lun);
-                       if (set_lun == -1)
+                       if (!F_LUNMASK(&ctx))
                                ctx.numdevs = 1;
                        else
                                ctx.numdevs++;
                        bit_set(ctx.lun_mask, cur_lun);
+                       ctx.flags |= CTLSTAT_FLAG_LUN_MASK;
                        break;
                }
                case 'n':
                        ctx.numdevs = atoi(optarg);
                        break;
+               case 'p': {
+                       int cur_port;
+
+                       cur_port = atoi(optarg);
+                       if (cur_port > CTL_MAX_PORTS)
+                               errx(1, "Invalid LUN number %d", cur_port);
+
+                       bit_set(ctx.port_mask, cur_port);
+                       ctx.flags |= CTLSTAT_FLAG_PORT_MASK;
+                       break;
+               }
                case 't':
                        ctx.flags |= CTLSTAT_FLAG_TOTALS;
-                       ctx.numdevs = 3;
                        break;
                case 'w':
                        waittime = atoi(optarg);
@@ -666,13 +697,7 @@ main(int argc, char **argv)
                }
        }
 
-       bit_ffs(ctx.lun_mask, CTL_STAT_LUN_BITS, &set_lun);
-
-       if ((F_TOTALS(&ctx))
-        && (set_lun != -1)) {
-               errx(1, "Total Mode (-t) is incompatible with individual "
-                    "LUN mode (-l)");
-       } else if (set_lun == -1) {
+       if (!F_TOTALS(&ctx) && !F_LUNMASK(&ctx)) {
                /*
                 * Note that this just selects the first N LUNs to display,
                 * but at this point we have no knoweledge of which LUN
@@ -681,6 +706,7 @@ main(int argc, char **argv)
                 */
                bit_nset(ctx.lun_mask, 0, min(ctx.numdevs - 1,
                         CTL_STAT_LUN_BITS - 1));
+               ctx.flags |= CTLSTAT_FLAG_LUN_MASK;
        }
 
        if ((fd = open(CTL_DEFAULT_DEV, O_RDWR)) == -1)
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to