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