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