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.4 2005/01/08 19:19:26 joerg 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.Aq Pa 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.Pp 336.Bd -literal -offset indent 337device,type,if 338.Ed 339.Pp 340.Fn buildmatch 341takes care of allocating and reallocating the match list as necessary. 342Currently known match types include: 343.Pp 344.Bl -tag -width indent -compact 345.It device type: 346.Bl -tag -width 9n -compact 347.It da 348Direct Access devices 349.It sa 350Sequential Access devices 351.It printer 352Printers 353.It proc 354Processor devices 355.It worm 356Write Once Read Multiple devices 357.It cd 358CD devices 359.It scanner 360Scanner devices 361.It optical 362Optical Memory devices 363.It changer 364Medium Changer devices 365.It comm 366Communication devices 367.It array 368Storage Array devices 369.It enclosure 370Enclosure Services devices 371.It floppy 372Floppy devices 373.El 374.Pp 375.It interface: 376.Bl -tag -width 9n -compact 377.It IDE 378Integrated Drive Electronics devices 379.It SCSI 380Small Computer System Interface devices 381.It other 382Any other device interface 383.El 384.Pp 385.It passthrough: 386.Bl -tag -width 9n -compact 387.It pass 388Passthrough devices 389.El 390.El 391.Pp 392.Fn compute_stats 393provides an easy way to obtain various device statistics. 394Only two arguments are mandatory: 395.Va current 396and 397.Va etime . 398Every other argument is optional. 399For most applications, the user will want to supply both 400.Va current 401and 402.Va previous 403devstat structures so that statistics may be calculated over a given period 404of time. 405In some instances, for instance when calculating statistics since system boot, 406the user may pass in a NULL pointer for the 407.Va previous 408argument. 409In that case, 410.Fn compute_stats 411will use the total stats in the 412.Va current 413structure to calculate statistics over 414.Va etime . 415The various statistics that may be calculated by 416.Fn compute_stats 417should be mostly explained by the function declaration itself, but for 418completeness here is a list of variable names and the statistics that will 419be put in them: 420.Bl -tag -width transfers_per_second 421.It total_bytes 422This is the total number of bytes transferred on the given device, both 423reads and writes, between the acquisition of 424.Va previous 425and the acquisition of 426.Va current . 427If 428.Va previous 429is NULL, the result will be the total reads and writes given in 430.Va current . 431.It total_transfers 432This is the total number of transfers completed between the 433acquisition of 434.Va previous 435and the acquisition of 436.Va current . 437If 438.Va previous 439is NULL, the result will be the total number of transactions listed in 440.Va current . 441.It total_blocks 442This is basically 443.Va total_bytes 444divided by the device blocksize. 445If the device blocksize is listed as 446.Sq 0 , 447the device blocksize will default to 512 bytes. 448.It kb_per_transfer 449This is the average number of kilobytes per transfer during the measurement 450period. 451.It transfers_per_second 452This is the average number of transfers per second. 453.It mb_per_second 454This is average megabytes per second. 455.It blocks_per_second 456This is average blocks per second. 457If the device blocksize is 458.Sq 0 , 459a default blocksize of 512 bytes will be used instead. 460.It ms_per_transaction 461The average number of milliseconds per transaction. 462.El 463.Pp 464.Fn compute_etime 465provides an easy way to find the difference in seconds between two 466.Va timeval 467structures. 468This is most commonly used in conjunction with the time recorded by the 469.Fn getdevs 470function (in struct 471.Va statinfo ) 472each time it fetches the current 473.Nm 474list. 475.Sh RETURN VALUES 476.Fn getnumdevs , 477.Fn getgeneration , 478and 479.Fn getversion 480return the indicated \fBsysctl\fR variable, or -1 if there is an error 481fetching the variable. 482.Pp 483.Fn checkversion 484returns 0 if the kernel and userland 485.Nm 486versions match. 487If they do not match, it returns -1. 488.Pp 489.Fn getdevs 490and 491.Fn selectdevs 492return -1 in case of an error, 0 if there is no error and 1 if the device 493list or selected devices have changed. 494A return value of 1 from 495.Fn getdevs 496is usually a hint to re-run 497.Fn selectdevs 498because the device list has changed. 499.Pp 500.Fn buildmatch 501returns -1 for error, and 0 if there is no error. 502.Pp 503.Fn compute_stats 504returns -1 for error, and 0 for success. 505.Pp 506.Fn compute_etime 507returns the computed elapsed time. 508.Pp 509If an error is returned from one of the 510.Nm 511library functions, the reason for the error is generally printed in 512the global string 513.Va devstat_errbuf 514which is 515.Dv DEVSTAT_ERRBUF_SIZE 516characters long. 517.Sh SEE ALSO 518.Xr systat 1 , 519.Xr iostat 8 , 520.Xr rpc.rstatd 8 , 521.Xr vmstat 8 , 522.Xr devstat 9 523.Sh HISTORY 524The 525.Nm 526statistics system first appeared in 527.Fx 3.0 . 528.Sh AUTHORS 529.An Kenneth Merry Aq ken@FreeBSD.org 530.Sh BUGS 531There should probably be an interface to de-allocate memory allocated by 532.Fn getdevs , 533.Fn selectdevs , 534and 535.Fn buildmatch . 536.Pp 537.Fn selectdevs 538should probably not select more than 539.Va maxshowdevs 540devices in 541.Dq top 542mode when no devices have been selected previously. 543.Pp 544There should probably be functions to perform the statistics buffer 545swapping that goes on in most of the clients of this library. 546.Pp 547The 548.Va statinfo 549and 550.Va devinfo 551structures should probably be cleaned up and thought out a little more. 552