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