1.\" 2.\" Copyright (c) 1998 Kenneth D. Merry. 3.\" All rights reserved. 4.\" 5.\" Redistribution and use in source and binary forms, with or without 6.\" modification, are permitted provided that the following conditions 7.\" are met: 8.\" 1. Redistributions of source code must retain the above copyright 9.\" notice, this list of conditions and the following disclaimer. 10.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" notice, this list of conditions and the following disclaimer in the 12.\" documentation and/or other materials provided with the distribution. 13.\" 3. The name of the author may not be used to endorse or promote products 14.\" derived from this software without specific prior written permission. 15.\" 16.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26.\" SUCH DAMAGE. 27.\" 28.\" $Id: devstat.3,v 1.3 1999/01/06 04:59:53 obrien Exp $ 29.\" 30.Dd May 21, 1998 31.Dt DEVSTAT 3 32.Os FreeBSD 3.0 33.Sh NAME 34.Nm devstat 35.Nd device statistics utility library 36.Sh SYNOPSIS 37.Fd #include <sys/dkstat.h> 38.Fd #include <devstat.h> 39.Ft int 40.Fn getnumdevs "void" 41.Ft long 42.Fn getgeneration "void" 43.Ft int 44.Fn getversion "void" 45.Ft int 46.Fn checkversion "void" 47.Ft int 48.Fn getdevs "struct statinfo *stats" 49.Ft int 50.Fo selectdevs 51.Fa "struct device_selection **dev_select" 52.Fa "int *num_selected" 53.Fa "int *num_selections" 54.Fa "long *select_generation" 55.Fa "long current_generation" 56.Fa "struct devstat *devices" 57.Fa "int numdevs" 58.Fa "struct devstat_match *matches" 59.Fa "int num_matches" 60.Fa "char **dev_selections" 61.Fa "int num_dev_selections" 62.Fa "devstat_select_mode select_mode" 63.Fa "int maxshowdevs" 64.Fa "int perf_select" 65.Fc 66.Ft int 67.Fo buildmatch 68.Fa "char *match_str" 69.Fa "struct devstat_match **matches" 70.Fa "int *num_matches" 71.Fc 72.Ft int 73.Fo compute_stats 74.Fa "struct devstat *current" 75.Fa "struct devstat *previous" 76.Fa "long double etime" 77.Fa "u_int64_t *total_bytes" 78.Fa "u_int64_t *total_transfers" 79.Fa "u_int64_t *total_blocks" 80.Fa "long double *kb_per_transfer" 81.Fa "long double *transfers_per_second" 82.Fa "long double *mb_per_second" 83.Fa "long double *blocks_per_second" 84.Fa "long double *ms_per_transaction" 85.Fc 86.Ft long double 87.Fo compute_etime 88.Fa "struct timeval cur_time" 89.Fa "struct timeval prev_time" 90.Fc 91.Sh DESCRIPTION 92The 93.Nm 94library is a library of helper functions for dealing with the kernel 95.Xr devstat 9 96interface, which is accessible to users via 97.Xr sysctl 3 . 98.Pp 99.Fn getnumdevs 100returns the number of devices registered with the 101.Nm devstat 102subsystem in the kernel. 103.Pp 104.Fn getgeneration 105returns the current generation of the 106.Nm devstat 107list of devices in the kernel. 108.Pp 109.Fn getversion 110returns the current kernel 111.Nm devstat 112version. 113.Pp 114.Fn checkversion 115checks the userland devstat version against the kernel devstat version. If 116the two are identical, it returns zero. Otherwise, it prints an 117appropriate error in 118.Va devstat_errbuf 119and returns -1. 120.Pp 121.Fn getdevs 122fetches the current list of devices and statistics into the supplied 123.Va statinfo 124structure. The 125.Va statinfo 126structure can be found in 127.Aq Pa devstat.h : 128.Bd -literal -offset indent 129struct statinfo { 130 long cp_time[CPUSTATES]; 131 long tk_nin; 132 long tk_nout; 133 struct devinfo *dinfo; 134 struct timeval busy_time; 135}; 136.Ed 137.Pp 138.Fn getdevs 139expects the 140.Va statinfo 141structure to be allocated, and it also expects the 142.Va dinfo 143subelement to be allocated ahead of time. The 144.Va dinfo 145subelement contains the following elements: 146.Bd -literal -offset indent 147struct devinfo { 148 struct devstat *devices; 149 u_int8_t *mem_ptr; 150 long generation; 151 int numdevs; 152}; 153.Ed 154.Pp 155The 156.Va kern.devstat.all 157.Nm sysctl 158variable contains an array of 159.Nm devstat 160structures, but at the head of the array is the current 161.Nm devstat 162generation. The reason the generation is at the head of the buffer is so 163that userland software accessing the devstat statistics information can 164atomically get both the statistics information and the corresponding 165generation number. If client software were forced to get the generation 166number via a separate 167.Nm sysctl 168variable (which is available for convenience), the list of devices could 169change between the time the client gets the generation and the time the 170client gets the device list. 171.Pp 172The 173.Va mem_ptr 174subelement of the 175.Va devinfo 176structure is a pointer to memory that is allocated, and resized if 177necessary, by 178.Fn getdevs . 179The devices subelement of the 180.Va devinfo 181structure is basically a pointer to the beginning of the array of devstat 182structures from the 183.Va kern.devstat.all 184.Nm sysctl 185variable. The generation subelement of the 186.Nm devinfo 187structure contains the generation number from the 188.Va kern.devstat.all 189.Nm sysctl 190variable. 191The 192.Va numdevs 193subelement of the 194.Va devinfo 195structure contains the current 196number of devices registered with the kernel 197.Nm devstat 198subsystem. 199.Pp 200.Fn selectdevs 201selects devices to display based upon a number of criteria: 202.Bl -tag -width flag 203.It specified devices 204Specified devices are the first selection priority. These are generally 205devices specified by name by the user. e.g. da0, da1, cd0. 206.It match patterns 207These are pattern matching expressions generated by 208.Fn buildmatch 209from user input. 210.It performance 211If performance mode is enabled, devices will be sorted based on the 212.Va bytes 213field in the 214.Va device_selection 215structure passed in to 216.Fn selectdevs . 217The 218.Va bytes 219value currently must be maintained by the user. In the future, 220this may be done for him in a 221.Nm 222library routine. 223If no devices have been selected by name or by pattern, the performance 224tracking code will select every device in the system, and sort them by 225performance. If devices have been selected by name or pattern, the 226performance tracking code will honor those selections and will only sort 227among the selected devices. 228.It order in the devstat list 229If the selection mode is set to DS_SELECT_ADD, and if there are still less 230than 231.Va maxshowdevs 232devices selected, 233.Fn selectdevs 234will automatically select up to 235.Va maxshowdevs 236devices. 237.El 238.Pp 239.Fn selectdevs 240performs selections in four different modes: 241.Bl -tag -width DS_SELECT_ADDONLY 242.It DS_SELECT_ADD 243In add mode, 244.Fn selectdevs 245will select any unselected devices specified by name or matching pattern. 246It will also select more devices, in devstat list order, until the number 247of selected devices is equal to 248.Va maxshowdevs 249or until all devices are 250selected. 251.It DS_SELECT_ONLY 252In only mode, 253.Fn selectdevs 254will clear all current selections, and will only select devices specified 255by name or by matching pattern. 256.It DS_SELECT_REMOVE 257In remove mode, 258.Fn selectdevs 259will remove devices specified by name or by matching pattern. It will not 260select any additional devices. 261.It DS_SELECT_ADDONLY 262In add only mode, 263.Fn selectdevs 264will select any unselected devices specified by name or matching pattern. 265In this respect it is identical to add mode. It will not, however, select 266any devices other than those specified. 267.El 268.Pp 269In all selection modes, 270.Fn selectdevs 271will not select any more than 272.Va maxshowdevs 273devices. One exception to 274this is when you are in 275.Dq top 276mode and no devices have been selected. In 277this case, 278.Fn selectdevs 279will select every device in the system. Client programs must pay attention 280to selection order when deciding whether to pay attention to a particular 281device. This may be the wrong behavior, and probably requires additional 282thought. 283.Pp 284.Fn selectdevs 285handles allocation and resizing of the 286.Va dev_select 287structure passed in 288by the client. 289.Fn selectdevs 290uses the 291.Va numdevs 292and 293.Va current_generation 294fields to track the 295current 296.Nm 297generation and number of devices. If 298.Va num_selections 299is not the same 300as 301.Va numdevs 302or if 303.Va select_generation 304is not the same as 305.Va current_generation , 306.Fn selectdevs 307will resize the selection list as necessary, and re-initialize the 308selection array. 309.Pp 310.Fn buildmatch 311takes a comma separated match string and compiles it into a 312\fBdevstat_match\fR structure that is understood by 313.Fn selectdevs . 314Match strings have the following format: 315.Pp 316.Bd -literal -offset indent 317device,type,if 318.Ed 319.Pp 320.Fn buildmatch 321takes care of allocating and reallocating the match list as necessary. 322Currently known match types include: 323.Pp 324.Bl -tag -width indent -compact 325.It device type: 326.Bl -tag -width 123456789 -compact 327.It da 328Direct Access devices 329.It sa 330Sequential Access devices 331.It printer 332Printers 333.It proc 334Processor devices 335.It worm 336Write Once Read Multiple devices 337.It cd 338CD devices 339.It scanner 340Scanner devices 341.It optical 342Optical Memory devices 343.It changer 344Medium Changer devices 345.It comm 346Communication devices 347.It array 348Storage Array devices 349.It enclosure 350Enclosure Services devices 351.It floppy 352Floppy devices 353.El 354.Pp 355.It interface: 356.Bl -tag -width 123456789 -compact 357.It IDE 358Integrated Drive Electronics devices 359.It SCSI 360Small Computer System Interface devices 361.It other 362Any other device interface 363.El 364.Pp 365.It passthrough: 366.Bl -tag -width 123456789 -compact 367.It pass 368Passthrough devices 369.El 370.El 371.Pp 372.Fn compute_stats 373provides an easy way to obtain various device statistics. Only two 374arguments are mandatory: 375.Va current 376and 377.Va etime . 378Every other argument is optional. For most applications, the user will 379want to supply both 380.Va current 381and 382.Va previous 383devstat structures so that statistics may be calculated over a given period 384of time. In some instances, for instance when calculating statistics since 385system boot, the user may pass in a NULL pointer for the 386.Va previous 387argument. In that case, 388.Fn compute_stats 389will use the total stats in the 390.Va current 391structure to calculate statistics over 392.Va etime . 393The various statistics that may be calculated by 394.Fn compute_stats 395should be mostly explained by the function declaration itself, but for 396completeness here is a list of variable names and the statistics that will 397be put in them: 398.Bl -tag -width transfers_per_second 399.It total_bytes 400This is the total number of bytes transferred on the given device, both 401reads and writes, between the acquisition of 402.Va previous 403and the acquisition of 404.Va current . 405If 406.Va previous 407is NULL, the result will be the total reads and writes given in 408.Va current . 409.It total_transfers 410This is the total number of transfers completed between the 411acquisition of 412.Va previous 413and the acquisition of 414.Va current . 415If 416.Va previous 417is NULL, the result will be the total number of transactions listed in 418.Va current . 419.It total_blocks 420This is basically 421.Va total_bytes 422divided by the device blocksize. If the device blocksize is listed as 423.Sq 0 , 424the device blocksize will default to 512 bytes. 425.It kb_per_transfer 426This is the average number of kilobytes per transfer during the measurement 427period. 428.It transfers_per_second 429This is the average number of transfers per second. 430.It mb_per_second 431This is average megabytes per second. 432.It blocks_per_second 433This is average blocks per second. If the device blocksize is 434.Sq 0 , 435a default blocksize of 512 bytes will be used instead. 436.It ms_per_transaction 437The average number of milliseconds per transaction. 438.El 439.Pp 440.Fn compute_etime 441provides an easy way to find the difference in seconds between two 442.Va timeval 443structures. This is most commonly used in conjunction with the time 444recorded by the 445.Fn getdevs 446function (in struct 447.Va statinfo ) 448each time it fetches the current 449.Nm 450list. 451.Sh RETURN VALUES 452.Fn getnumdevs , 453.Fn getgeneration , 454and 455.Fn getversion 456return the indicated \fBsysctl\fR variable, or -1 if there is an error 457fetching the variable. 458.Pp 459.Fn checkversion 460returns 0 if the kernel and userland 461.Nm devstat 462versions match. If they do not match, it returns -1. 463.Pp 464.Fn getdevs 465and 466.Fn selectdevs 467return -1 in case of an error, 0 if there is no error and 1 if the device 468list or selected devices have changed. A return value of 1 from 469.Fn getdevs 470is usually a hint to re-run 471.Fn selectdevs 472because the device list has changed. 473.Pp 474.Fn buildmatch 475returns -1 for error, and 0 if there is no error. 476.Pp 477.Fn compute_stats 478returns -1 for error, and 0 for success. 479.Pp 480.Fn compute_etime 481returns the computed elapsed time. 482.Pp 483If an error is returned from one of the 484.Nm 485library functions, the reason for the error is generally printed in 486the global string 487.Va devstat_errbuf 488which is 489.Dv DEVSTAT_ERRBUF_SIZE 490characters long. 491.Sh SEE ALSO 492.Xr systat 1 , 493.Xr iostat 8 , 494.Xr rpc.rstatd 8 , 495.Xr vmstat 8 , 496.Xr devstat 9 497.Sh HISTORY 498The 499.Nm 500statistics system first appeared in 501.Fx 3.0 . 502.Sh AUTHORS 503Kenneth Merry 504.Aq ken@FreeBSD.ORG 505.Sh BUGS 506There should probably be an interface to de-allocate memory allocated by 507.Fn getdevs , 508.Fn selectdevs , 509and 510.Fn buildmatch . 511.Pp 512.Fn selectdevs 513should probably not select more than 514.Va maxshowdevs 515devices in 516.Dq top 517mode when no devices have been selected previously. 518.Pp 519There should probably be functions to perform the statistics buffer 520swapping that goes on in most of the clients of this library. 521.Pp 522The 523.Va statinfo 524and 525.Va devinfo 526structures should probably be cleaned up and thought out a little more. 527