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
--h31gzZEtNLTqOjlF Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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 --h31gzZEtNLTqOjlF Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="devstat.stats.20010715" ==== //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) { --h31gzZEtNLTqOjlF-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010715204336.A60429>