Date: Sun, 15 Jul 2001 20:43:36 -0600 From: "Kenneth D. Merry" <ken@kdm.org> To: audit@FreeBSD.org Subject: new devstat statistics function Message-ID: <20010715204336.A60429@panzer.kdm.org>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Attached is a patch to add a new devstat(3) statistics calculation
function. The code was developed by Sergey Osokin <osa@freebsd.org.ru>
and myself.
It includes a patch to iostat(8) to change over to the new statistics
calculation function.
Anyway, comments would be appreciated.
This is likely a portion of the devstat changes that will be coming down
the pipe in the near term. Thomas Moestl <tmm@FreeBSD.org> has some
patches to allow devstat use on core files/kernels, and we're talking about
some more changes besides.
Ken
--
Kenneth Merry
ken@kdm.org
[-- Attachment #2 --]
==== //depot/FreeBSD-ken/src/lib/libdevstat/devstat.3#5 - /usr/home/ken/perforce/FreeBSD-ken/src/lib/libdevstat/devstat.3 ====
*** /tmp/tmp.1875.0 Sun Jul 15 20:36:42 2001
--- /usr/home/ken/perforce/FreeBSD-ken/src/lib/libdevstat/devstat.3 Sun Jul 15 20:33:42 2001
***************
*** 1,5 ****
.\"
! .\" Copyright (c) 1998, 1999 Kenneth D. Merry.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
--- 1,5 ----
.\"
! .\" Copyright (c) 1998, 1999, 2001 Kenneth D. Merry.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
***************
*** 27,33 ****
.\"
.\" $FreeBSD: src/lib/libdevstat/devstat.3,v 1.13 2001/07/10 13:41:33 ru Exp $
.\"
! .Dd May 21, 1998
.Dt DEVSTAT 3
.Os
.Sh NAME
--- 27,33 ----
.\"
.\" $FreeBSD: src/lib/libdevstat/devstat.3,v 1.13 2001/07/10 13:41:33 ru Exp $
.\"
! .Dd July 15, 2001
.Dt DEVSTAT 3
.Os
.Sh NAME
***************
*** 99,104 ****
--- 99,111 ----
.Fa "struct timeval cur_time"
.Fa "struct timeval prev_time"
.Fc
+ .Ft int
+ .Fo devstat_compute_statistics
+ .Fa "struct devstat *current"
+ .Fa "struct devstat *previous"
+ .Fa "long double *etime"
+ .Fa "..."
+ .Fc
.Sh DESCRIPTION
The
.Nm
***************
*** 466,471 ****
--- 473,728 ----
each time it fetches the current
.Nm
list.
+ .Pp
+ .Fn devstat_compute_statistics
+ is an updated version of
+ .Fn compute_stats
+ that provides more complete statistics calculation. There are four
+ arguments for which values \fBmust\fR be supplied:
+ .Va current ,
+ .Va previous ,
+ .Va etime ,
+ and the terminating argument for the varargs list,
+ .Va DSM_NONE .
+ For most applications, the user will want to supply valid devstat
+ structures for both
+ .Va current
+ and
+ .Va previous .
+ In some instances, for instance when calculating statistics since system
+ boot, the user may pass in a NULL pointer for the
+ .Va previous
+ argument. In that case,
+ .Fn devstat_compute_statistics
+ will use the total stats in the
+ .Va current
+ structure to calculate statistics over
+ .Va etime .
+ For each statistic to be calculated, the user should supply the proper
+ enumerated type (listed below), and a variable of the indicated type. All
+ statistics are either integer values, for which a u_int64_t is used, or
+ floating point, for which a long double is used.
+ The statistics that may be calculated are:
+ .Bl -tag -width DSM_TRANSFERS_PER_SECOND_OTHER
+ .It DSM_NONE
+ type: N/A
+ .Pp
+ This \fBmust\fR
+ be the last argument passed to
+ .Fn devstat_compute_statistics .
+ It is an argument list terminator.
+ .It DSM_TOTAL_BYTES
+ type: u_int64_t *
+ .Pp
+ The total number of bytes transferred between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ .It DSM_TOTAL_BYTES_READ
+ type: u_int64_t *
+ .Pp
+ The total number of bytes read between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ .It DSM_TOTAL_BYTES_WRITE
+ type: u_int64_t *
+ .Pp
+ The total number of bytes written between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ .It DSM_TOTAL_TRANSFERS
+ type: u_int64_t *
+ .Pp
+ The total number of transfers between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ .It DSM_TOTAL_TRANSFERS_READ
+ type: u_int64_t *
+ .Pp
+ The total number of reads between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ .It DSM_TOTAL_TRANSFERS_WRITE
+ type: u_int64_t *
+ .Pp
+ The total number of writes between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ .It DSM_TOTAL_TRANSFERS_OTHER
+ type: u_int64_t *
+ .Pp
+ The total number of transactions that are not reads or writes that occurred
+ between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ .It DSM_TOTAL_BLOCKS
+ type: u_int64_t *
+ .Pp
+ The total number of blocks transferred between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ This number is in terms of the blocksize reported by the device. If no
+ blocksize has been reported (i.e. the block size is 0), a default
+ blocksize of 512 bytes will be used in the calculation.
+ .It DSM_TOTAL_BLOCKS_READ
+ type: u_int64_t *
+ .Pp
+ The total number of blocks read between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ This number is in terms of the blocksize reported by the device. If no
+ blocksize has been reported (i.e. the block size is 0), a default
+ blocksize of 512 bytes will be used in the calculation.
+ .It DSM_TOTAL_BLOCKS_WRITE
+ type: u_int64_t *
+ .Pp
+ The total number of blocks written between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ This number is in terms of the blocksize reported by the device. If no
+ blocksize has been reported (i.e. the block size is 0), a default
+ blocksize of 512 bytes will be used in the calculation.
+ .It DSM_KB_PER_TRANSFER
+ type: long double *
+ .Pp
+ The average number of kilobytes per transfer between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ .It DSM_KB_PER_TRANSFER_READ
+ type: long double *
+ .Pp
+ The average number of kilobytes per read transaction between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ .It DSM_KB_PER_TRANSFER_WRITE
+ type: long double *
+ .Pp
+ The average number of kilobytes per write transaction between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ .It DSM_TRANSFERS_PER_SECOND
+ type: long double *
+ .Pp
+ The average number of transfers per second between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ .It DSM_TRANSFERS_PER_SECOND_READ
+ type: long double *
+ .Pp
+ The average number of reads per second between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ .It DSM_TRANSFERS_PER_SECOND_WRITE
+ type: long double *
+ .Pp
+ The average number of writes per second between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ .It DSM_TRANSFERS_PER_SECOND_OTHER
+ type: long double *
+ .Pp
+ The average number of non-read, non-write transactions per second between
+ the acquisition of
+ .Va previous
+ and
+ .Va current .
+ .It DSM_MB_PER_SECOND
+ type: long double *
+ .Pp
+ The average number of megabytes transferred per second between the
+ acquisition of
+ .Va previous
+ and
+ .Va current .
+ .It DSM_MB_PER_SECOND_READ
+ type: long double *
+ .Pp
+ The average number of megabytes read per second between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ .It DSM_MB_PER_SECOND_WRITE
+ type: long double *
+ .Pp
+ The average number of megabytes written per second between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ .It DSM_BLOCKS_PER_SECOND
+ type: long double *
+ .Pp
+ The average number of blocks transferred per second between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ This number is in terms of the blocksize reported by the device. If no
+ blocksize has been reported (i.e. the block size is 0), a default
+ blocksize of 512 bytes will be used in the calculation.
+ .It DSM_BLOCKS_PER_SECOND_READ
+ type: long double *
+ .Pp
+ The average number of blocks read per second between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ This number is in terms of the blocksize reported by the device. If no
+ blocksize has been reported (i.e. the block size is 0), a default
+ blocksize of 512 bytes will be used in the calculation.
+ .It DSM_BLOCKS_PER_SECOND_WRITE
+ type: long double *
+ .Pp
+ The average number of blocks written per second between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ This number is in terms of the blocksize reported by the device. If no
+ blocksize has been reported (i.e. the block size is 0), a default
+ blocksize of 512 bytes will be used in the calculation.
+ .It DSM_MS_PER_TRANSACTION
+ type: long double *
+ .Pp
+ The average rate of transaction completion between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ Note that this isn't a true reflection of the average number of
+ milliseconds per transaction, but rather is the average rate of transaction
+ completion. The number is derived by dividing the time elapsed by
+ the number of transactions completed.
+ .It DSM_MS_PER_TRANSACTION_READ
+ type: long double *
+ .Pp
+ The average rate of read completions between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ As above, this is not the true number of milliseconds per transaction, but
+ rather the average rate of read transaction completion.
+ .It DSM_MS_PER_TRANSACTION_WRITE
+ type: long double *
+ .Pp
+ The average rate of write transaction completion between the acquisition of
+ .Va previous
+ and
+ .Va current .
+ As above, this is not the true number of milliseconds per transaction, but
+ rather the average rate of write transaction completion.
+ .El
.Sh RETURN VALUES
.Fn getnumdevs ,
.Fn getgeneration ,
***************
*** 497,502 ****
--- 754,762 ----
.Pp
.Fn compute_etime
returns the computed elapsed time.
+ .Pp
+ .Fn devstat_compute_statistics
+ returns -1 for error, and 0 for success.
.Pp
If an error is returned from one of the
.Nm
==== //depot/FreeBSD-ken/src/lib/libdevstat/devstat.c#1 - /usr/home/ken/perforce/FreeBSD-ken/src/lib/libdevstat/devstat.c ====
*** /tmp/tmp.1875.1 Sun Jul 15 20:36:42 2001
--- /usr/home/ken/perforce/FreeBSD-ken/src/lib/libdevstat/devstat.c Mon May 28 15:33:57 2001
***************
*** 38,46 ****
--- 38,53 ----
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+ #include <stdarg.h>
#include "devstat.h"
+ typedef enum {
+ DEVSTAT_ARG_NOTYPE,
+ DEVSTAT_ARG_UINT64,
+ DEVSTAT_ARG_LD
+ } devstat_arg_type;
+
char devstat_errbuf[DEVSTAT_ERRBUF_SIZE];
/*
***************
*** 68,73 ****
--- 75,113 ----
{NULL, 0, 0}
};
+ struct devstat_args {
+ devstat_metric metric;
+ devstat_arg_type argtype;
+ } devstat_arg_list[] = {
+ { DSM_NONE, DEVSTAT_ARG_NOTYPE },
+ { DSM_TOTAL_BYTES, DEVSTAT_ARG_UINT64 },
+ { DSM_TOTAL_BYTES_READ, DEVSTAT_ARG_UINT64 },
+ { DSM_TOTAL_BYTES_WRITE, DEVSTAT_ARG_UINT64 },
+ { DSM_TOTAL_TRANSFERS, DEVSTAT_ARG_UINT64 },
+ { DSM_TOTAL_TRANSFERS_READ, DEVSTAT_ARG_UINT64 },
+ { DSM_TOTAL_TRANSFERS_WRITE, DEVSTAT_ARG_UINT64 },
+ { DSM_TOTAL_TRANSFERS_OTHER, DEVSTAT_ARG_UINT64 },
+ { DSM_TOTAL_BLOCKS, DEVSTAT_ARG_UINT64 },
+ { DSM_TOTAL_BLOCKS_READ, DEVSTAT_ARG_UINT64 },
+ { DSM_TOTAL_BLOCKS_WRITE, DEVSTAT_ARG_UINT64 },
+ { DSM_KB_PER_TRANSFER, DEVSTAT_ARG_LD },
+ { DSM_KB_PER_TRANSFER_READ, DEVSTAT_ARG_LD },
+ { DSM_KB_PER_TRANSFER_WRITE, DEVSTAT_ARG_LD },
+ { DSM_TRANSFERS_PER_SECOND, DEVSTAT_ARG_LD },
+ { DSM_TRANSFERS_PER_SECOND_READ, DEVSTAT_ARG_LD },
+ { DSM_TRANSFERS_PER_SECOND_WRITE, DEVSTAT_ARG_LD },
+ { DSM_TRANSFERS_PER_SECOND_OTHER, DEVSTAT_ARG_LD },
+ { DSM_MB_PER_SECOND, DEVSTAT_ARG_LD },
+ { DSM_MB_PER_SECOND_READ, DEVSTAT_ARG_LD },
+ { DSM_MB_PER_SECOND_WRITE, DEVSTAT_ARG_LD },
+ { DSM_BLOCKS_PER_SECOND, DEVSTAT_ARG_LD },
+ { DSM_BLOCKS_PER_SECOND_READ, DEVSTAT_ARG_LD },
+ { DSM_BLOCKS_PER_SECOND_WRITE, DEVSTAT_ARG_LD },
+ { DSM_MS_PER_TRANSACTION, DEVSTAT_ARG_LD },
+ { DSM_MS_PER_TRANSACTION_READ, DEVSTAT_ARG_LD },
+ { DSM_MS_PER_TRANSACTION_WRITE, DEVSTAT_ARG_LD }
+ };
+
/*
* Local function declarations.
*/
***************
*** 1125,1128 ****
--- 1165,1467 ----
etime /= 1000000;
return(etime);
+ }
+
+ int
+ devstat_compute_statistics(struct devstat *current, struct devstat *previous,
+ long double etime, ...)
+ {
+ char *func_name = "devstat_compute_statistics";
+ u_int64_t totalbytes, totalbytesread, totalbyteswrite;
+ u_int64_t totaltransfers, totaltransfersread, totaltransferswrite;
+ u_int64_t totaltransfersother, totalblocks, totalblocksread;
+ u_int64_t totalblockswrite;
+ va_list ap;
+ devstat_metric metric;
+ u_int64_t *destu64;
+ long double *destld;
+ int retval;
+
+ retval = 0;
+
+ /*
+ * current is the only mandatory field.
+ */
+ if (current == NULL) {
+ sprintf(devstat_errbuf, "%s: current stats structure was NULL",
+ func_name);
+ return(-1);
+ }
+
+ totalbytesread = current->bytes_read -
+ ((previous) ? previous->bytes_read : 0);
+ totalbyteswrite = current->bytes_written -
+ ((previous) ? previous->bytes_written : 0);
+
+ totalbytes = totalbytesread + totalbyteswrite;
+
+ totaltransfersread = current->num_reads -
+ ((previous) ? previous->num_reads : 0);
+
+ totaltransferswrite = current->num_writes -
+ ((previous) ? previous->num_writes : 0);
+
+ totaltransfersother = current->num_other -
+ ((previous) ? previous->num_other : 0);
+
+ totaltransfers = totaltransfersread + totaltransferswrite +
+ totaltransfersother;
+
+ totalblocks = totalbytes;
+ totalblocksread = totalbytesread;
+ totalblockswrite = totalbyteswrite;
+
+ if (current->block_size > 0) {
+ totalblocks /= current->block_size;
+ totalblocksread /= current->block_size;
+ totalblockswrite /= current->block_size;
+ } else {
+ totalblocks /= 512;
+ totalblocksread /= 512;
+ totalblockswrite /= 512;
+ }
+
+ va_start(ap, etime);
+
+ while ((metric = (devstat_metric)va_arg(ap, devstat_metric)) != 0) {
+
+ if (metric == DSM_NONE)
+ break;
+
+ if (metric >= DSM_MAX) {
+ sprintf(devstat_errbuf, "%s: metric %d is out of "
+ "range", func_name, metric);
+ retval = -1;
+ goto bailout;
+ }
+
+ switch (devstat_arg_list[metric].argtype) {
+ case DEVSTAT_ARG_UINT64:
+ destu64 = (u_int64_t *)va_arg(ap, u_int64_t *);
+ if (destu64 == NULL) {
+ sprintf(devstat_errbuf, "%s: argument type not"
+ " u_int64_t * or argument type missing",
+ func_name);
+ retval = -1;
+ goto bailout;
+ break; /* NOTREACHED */
+ }
+ break;
+ case DEVSTAT_ARG_LD:
+ destld = (long double *)va_arg(ap, long double *);
+ if (destld == NULL) {
+ sprintf(devstat_errbuf, "%s: argument type not"
+ " long double * or argument type "
+ "missing", func_name);
+ retval = -1;
+ goto bailout;
+ break; /* NOTREACHED */
+ }
+ break;
+ default:
+ sprintf(devstat_errbuf, "%s: unknown argument type %d",
+ func_name, devstat_arg_list[metric].argtype);
+ retval = -1;
+ goto bailout;
+ break; /* NOTREACHED */
+ }
+
+ switch (metric) {
+ case DSM_TOTAL_BYTES:
+ *destu64 = totalbytes;
+ break;
+ case DSM_TOTAL_BYTES_READ:
+ *destu64 = totalbytesread;
+ break;
+ case DSM_TOTAL_BYTES_WRITE:
+ *destu64 = totalbyteswrite;
+ break;
+ case DSM_TOTAL_TRANSFERS:
+ *destu64 = totaltransfers;
+ break;
+ case DSM_TOTAL_TRANSFERS_READ:
+ *destu64 = totaltransfersread;
+ break;
+ case DSM_TOTAL_TRANSFERS_WRITE:
+ *destu64 = totaltransferswrite;
+ break;
+ case DSM_TOTAL_TRANSFERS_OTHER:
+ *destu64 = totaltransfersother;
+ break;
+ case DSM_TOTAL_BLOCKS:
+ *destu64 = totalblocks;
+ break;
+ case DSM_TOTAL_BLOCKS_READ:
+ *destu64 = totalblocksread;
+ break;
+ case DSM_TOTAL_BLOCKS_WRITE:
+ *destu64 = totalblockswrite;
+ break;
+ case DSM_KB_PER_TRANSFER:
+ *destld = totalbytes;
+ *destld /= 1024;
+ if (totaltransfers > 0)
+ *destld /= totaltransfers;
+ else
+ *destld = 0.0;
+ break;
+ case DSM_KB_PER_TRANSFER_READ:
+ *destld = totalbytesread;
+ *destld /= 1024;
+ if (totaltransfersread > 0)
+ *destld /= totaltransfersread;
+ else
+ *destld = 0.0;
+ break;
+ case DSM_KB_PER_TRANSFER_WRITE:
+ *destld = totalbyteswrite;
+ *destld /= 1024;
+ if (totaltransferswrite > 0)
+ *destld /= totaltransferswrite;
+ else
+ *destld = 0.0;
+ break;
+ case DSM_TRANSFERS_PER_SECOND:
+ if (etime > 0.0) {
+ *destld = totaltransfers;
+ *destld /= etime;
+ } else
+ *destld = 0.0;
+ break;
+ case DSM_TRANSFERS_PER_SECOND_READ:
+ if (etime > 0.0) {
+ *destld = totaltransfersread;
+ *destld /= etime;
+ } else
+ *destld = 0.0;
+ break;
+ case DSM_TRANSFERS_PER_SECOND_WRITE:
+ if (etime > 0.0) {
+ *destld = totaltransferswrite;
+ *destld /= etime;
+ } else
+ *destld = 0.0;
+ break;
+ case DSM_TRANSFERS_PER_SECOND_OTHER:
+ if (etime > 0.0) {
+ *destld = totaltransfersother;
+ *destld /= etime;
+ } else
+ *destld = 0.0;
+ break;
+ case DSM_MB_PER_SECOND:
+ *destld = totalbytes;
+ *destld /= 1024 * 1024;
+ if (etime > 0.0)
+ *destld /= etime;
+ else
+ *destld = 0.0;
+ break;
+ case DSM_MB_PER_SECOND_READ:
+ *destld = totalbytesread;
+ *destld /= 1024 * 1024;
+ if (etime > 0.0)
+ *destld /= etime;
+ else
+ *destld = 0.0;
+ break;
+ case DSM_MB_PER_SECOND_WRITE:
+ *destld = totalbyteswrite;
+ *destld /= 1024 * 1024;
+ if (etime > 0.0)
+ *destld /= etime;
+ else
+ *destld = 0.0;
+ break;
+ case DSM_BLOCKS_PER_SECOND:
+ *destld = totalblocks;
+ if (etime > 0.0)
+ *destld /= etime;
+ else
+ *destld = 0.0;
+ break;
+ case DSM_BLOCKS_PER_SECOND_READ:
+ *destld = totalblocksread;
+ if (etime > 0.0)
+ *destld /= etime;
+ else
+ *destld = 0.0;
+ break;
+ case DSM_BLOCKS_PER_SECOND_WRITE:
+ *destld = totalblockswrite;
+ if (etime > 0.0)
+ *destld /= etime;
+ else
+ *destld = 0.0;
+ break;
+ /*
+ * This calculation is somewhat bogus. It simply divides
+ * the elapsed time by the total number of transactions
+ * completed. While that does give the caller a good
+ * picture of the average rate of transaction completion,
+ * it doesn't necessarily give the caller a good view of
+ * how long transactions took to complete on average.
+ * Those two numbers will be different for a device that
+ * can handle more than one transaction at a time. e.g.
+ * SCSI disks doing tagged queueing.
+ *
+ * The only way to accurately determine the real average
+ * time per transaction would be to compute and store the
+ * time on a per-transaction basis. That currently isn't
+ * done in the kernel, and would only be desireable if it
+ * could be implemented in a somewhat non-intrusive and high
+ * performance way.
+ */
+ case DSM_MS_PER_TRANSACTION:
+ if (totaltransfers > 0) {
+ *destld = etime;
+ *destld /= totaltransfers;
+ *destld *= 1000;
+ } else
+ *destld = 0.0;
+ break;
+ /*
+ * As above, these next two really only give the average
+ * rate of completion for read and write transactions, not
+ * the average time the transaction took to complete.
+ */
+ case DSM_MS_PER_TRANSACTION_READ:
+ if (totaltransfersread > 0) {
+ *destld = etime;
+ *destld /= totaltransfersread;
+ *destld *= 1000;
+ } else
+ *destld = 0.0;
+ break;
+ case DSM_MS_PER_TRANSACTION_WRITE:
+ if (totaltransferswrite > 0) {
+ *destld = etime;
+ *destld /= totaltransferswrite;
+ *destld *= 1000;
+ } else
+ *destld = 0.0;
+ break;
+ default:
+ /*
+ * This shouldn't happen, since we should have
+ * caught any out of range metrics at the top of
+ * the loop.
+ */
+ sprintf(devstat_errbuf, "%s: unknown metric %d",
+ func_name, metric);
+ retval = -1;
+ goto bailout;
+ break; /* NOTREACHED */
+ }
+ }
+
+ bailout:
+
+ va_end(ap);
+ return(retval);
}
==== //depot/FreeBSD-ken/src/lib/libdevstat/devstat.h#1 - /usr/home/ken/perforce/FreeBSD-ken/src/lib/libdevstat/devstat.h ====
*** /tmp/tmp.1875.2 Sun Jul 15 20:36:42 2001
--- /usr/home/ken/perforce/FreeBSD-ken/src/lib/libdevstat/devstat.h Mon May 28 15:31:45 2001
***************
*** 44,49 ****
--- 44,80 ----
DEVSTAT_MATCH_PASS = 0x04
} devstat_match_flags;
+ typedef enum {
+ DSM_NONE,
+ DSM_TOTAL_BYTES,
+ DSM_TOTAL_BYTES_READ,
+ DSM_TOTAL_BYTES_WRITE,
+ DSM_TOTAL_TRANSFERS,
+ DSM_TOTAL_TRANSFERS_READ,
+ DSM_TOTAL_TRANSFERS_WRITE,
+ DSM_TOTAL_TRANSFERS_OTHER,
+ DSM_TOTAL_BLOCKS,
+ DSM_TOTAL_BLOCKS_READ,
+ DSM_TOTAL_BLOCKS_WRITE,
+ DSM_KB_PER_TRANSFER,
+ DSM_KB_PER_TRANSFER_READ,
+ DSM_KB_PER_TRANSFER_WRITE,
+ DSM_TRANSFERS_PER_SECOND,
+ DSM_TRANSFERS_PER_SECOND_READ,
+ DSM_TRANSFERS_PER_SECOND_WRITE,
+ DSM_TRANSFERS_PER_SECOND_OTHER,
+ DSM_MB_PER_SECOND,
+ DSM_MB_PER_SECOND_READ,
+ DSM_MB_PER_SECOND_WRITE,
+ DSM_BLOCKS_PER_SECOND,
+ DSM_BLOCKS_PER_SECOND_READ,
+ DSM_BLOCKS_PER_SECOND_WRITE,
+ DSM_MS_PER_TRANSACTION,
+ DSM_MS_PER_TRANSACTION_READ,
+ DSM_MS_PER_TRANSACTION_WRITE,
+ DSM_MAX
+ } devstat_metric;
+
struct devstat_match {
devstat_match_flags match_fields;
devstat_type_flags device_type;
***************
*** 110,115 ****
--- 141,149 ----
long double *blocks_per_second,
long double *ms_per_transaction);
long double compute_etime(struct timeval cur_time, struct timeval prev_time);
+ int devstat_compute_statistics(struct devstat *current,
+ struct devstat *previous,
+ long double etime, ...);
__END_DECLS
#endif /* _DEVSTAT_H */
==== //depot/FreeBSD-ken/src/usr.sbin/iostat/iostat.c#4 - /usr/home/ken/perforce/FreeBSD-ken/src/usr.sbin/iostat/iostat.c ====
*** /tmp/tmp.1875.4 Sun Jul 15 20:36:42 2001
--- /usr/home/ken/perforce/FreeBSD-ken/src/usr.sbin/iostat/iostat.c Mon May 28 20:14:42 2001
***************
*** 608,619 ****
di = dev_select[dn].position;
! if (compute_stats(&cur.dinfo->devices[di],
! &last.dinfo->devices[di], busy_seconds,
! &total_bytes, &total_transfers,
! &total_blocks, &kb_per_transfer,
! &transfers_per_second, &mb_per_second,
! &blocks_per_second, &ms_per_transaction)!= 0)
errx(1, "%s", devstat_errbuf);
if (perf_select != 0) {
--- 608,624 ----
di = dev_select[dn].position;
! if (devstat_compute_statistics(&cur.dinfo->devices[di],
! &last.dinfo->devices[di], busy_seconds,
! DSM_TOTAL_BYTES, &total_bytes,
! DSM_TOTAL_TRANSFERS, &total_transfers,
! DSM_TOTAL_BLOCKS, &total_blocks,
! DSM_KB_PER_TRANSFER, &kb_per_transfer,
! DSM_TRANSFERS_PER_SECOND, &transfers_per_second,
! DSM_MB_PER_SECOND, &mb_per_second,
! DSM_BLOCKS_PER_SECOND, &blocks_per_second,
! DSM_MS_PER_TRANSACTION, &ms_per_transaction,
! DSM_NONE) != 0)
errx(1, "%s", devstat_errbuf);
if (perf_select != 0) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010715204336.A60429>
