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