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