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