2 .\" Copyright (c) 1998, 1999 Kenneth D. Merry.
3 .\" All rights reserved.
5 .\" Redistribution and use in source and binary forms, with or without
6 .\" modification, are permitted provided that the following conditions
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.
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
44 .Nd device statistics utility library
48 .Fd #include <sys/dkstat.h>
49 .Fd #include <devstat.h>
53 .Fn getgeneration "void"
57 .Fn checkversion "void"
59 .Fn getdevs "struct statinfo *stats"
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"
69 .Fa "struct devstat_match *matches"
71 .Fa "char **dev_selections"
72 .Fa "int num_dev_selections"
73 .Fa "devstat_select_mode select_mode"
80 .Fa "struct devstat_match **matches"
81 .Fa "int *num_matches"
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"
99 .Fa "struct timeval cur_time"
100 .Fa "struct timeval prev_time"
105 library is a library of helper functions for dealing with the kernel
107 interface, which is accessible to users via
111 returns the number of devices registered with the
113 subsystem in the kernel.
116 returns the current generation of the
118 list of devices in the kernel.
121 returns the current kernel
126 checks the userland devstat version against the kernel devstat version. If
127 the two are identical, it returns zero. Otherwise, it prints an
133 fetches the current list of devices and statistics into the supplied
137 structure can be found in
139 .Bd -literal -offset indent
141 long cp_time[CPUSTATES];
144 struct devinfo *dinfo;
145 struct timeval busy_time;
152 structure to be allocated, and it also expects the
154 subelement to be allocated and zeroed prior to the first invocation of
158 subelement is used to store state between calls, and should not be modified
159 after the first call to
163 subelement contains the following elements:
164 .Bd -literal -offset indent
166 struct devstat *devices;
176 variable contains an array of
178 structures, but at the head of the array is the current
180 generation. The reason the generation is at the head of the buffer is so
181 that userland software accessing the devstat statistics information can
182 atomically get both the statistics information and the corresponding
183 generation number. If client software were forced to get the generation
184 number via a separate
186 variable (which is available for convenience), the list of devices could
187 change between the time the client gets the generation and the time the
188 client gets the device list.
194 structure is a pointer to memory that is allocated, and resized if
197 The devices subelement of the
199 structure is basically a pointer to the beginning of the array of devstat
203 variable. The generation subelement of the
205 structure contains the generation number from the
213 structure contains the current
214 number of devices registered with the kernel
219 selects devices to display based upon a number of criteria:
221 .It specified devices
222 Specified devices are the first selection priority. These are generally
223 devices specified by name by the user. e.g. da0, da1, cd0.
225 These are pattern matching expressions generated by
229 If performance mode is enabled, devices will be sorted based on the
233 structure passed in to
237 value currently must be maintained by the user. In the future,
238 this may be done for him in a
241 If no devices have been selected by name or by pattern, the performance
242 tracking code will select every device in the system, and sort them by
243 performance. If devices have been selected by name or pattern, the
244 performance tracking code will honor those selections and will only sort
245 among the selected devices.
246 .It order in the devstat list
247 If the selection mode is set to DS_SELECT_ADD, and if there are still less
252 will automatically select up to
258 performs selections in four different modes:
259 .Bl -tag -width DS_SELECT_ADDONLY
263 will select any unselected devices specified by name or matching pattern.
264 It will also select more devices, in devstat list order, until the number
265 of selected devices is equal to
267 or until all devices are
272 will clear all current selections, and will only select devices specified
273 by name or by matching pattern.
277 will remove devices specified by name or by matching pattern. It will not
278 select any additional devices.
279 .It DS_SELECT_ADDONLY
282 will select any unselected devices specified by name or matching pattern.
283 In this respect it is identical to add mode. It will not, however, select
284 any devices other than those specified.
287 In all selection modes,
289 will not select any more than
291 devices. One exception to
292 this is when you are in
294 mode and no devices have been selected. In
297 will select every device in the system. Client programs must pay attention
298 to selection order when deciding whether to pay attention to a particular
299 device. This may be the wrong behavior, and probably requires additional
303 handles allocation and resizing of the
311 .Va current_generation
315 generation and number of devices. If
321 .Va select_generation
323 .Va current_generation ,
325 will resize the selection list as necessary, and re-initialize the
329 takes a comma separated match string and compiles it into a
330 \fBdevstat_match\fR structure that is understood by
332 Match strings have the following format:
334 .Bd -literal -offset indent
339 takes care of allocating and reallocating the match list as necessary.
340 Currently known match types include:
342 .Bl -tag -width indent -compact
344 .Bl -tag -width 9n -compact
346 Direct Access devices
348 Sequential Access devices
354 Write Once Read Multiple devices
360 Optical Memory devices
362 Medium Changer devices
364 Communication devices
366 Storage Array devices
368 Enclosure Services devices
374 .Bl -tag -width 9n -compact
376 Integrated Drive Electronics devices
378 Small Computer System Interface devices
380 Any other device interface
384 .Bl -tag -width 9n -compact
391 provides an easy way to obtain various device statistics. Only two
392 arguments are mandatory:
396 Every other argument is optional. For most applications, the user will
401 devstat structures so that statistics may be calculated over a given period
402 of time. In some instances, for instance when calculating statistics since
403 system boot, the user may pass in a NULL pointer for the
405 argument. In that case,
407 will use the total stats in the
409 structure to calculate statistics over
411 The various statistics that may be calculated by
413 should be mostly explained by the function declaration itself, but for
414 completeness here is a list of variable names and the statistics that will
416 .Bl -tag -width transfers_per_second
418 This is the total number of bytes transferred on the given device, both
419 reads and writes, between the acquisition of
421 and the acquisition of
425 is NULL, the result will be the total reads and writes given in
428 This is the total number of transfers completed between the
431 and the acquisition of
435 is NULL, the result will be the total number of transactions listed in
440 divided by the device blocksize. If the device blocksize is listed as
442 the device blocksize will default to 512 bytes.
444 This is the average number of kilobytes per transfer during the measurement
446 .It transfers_per_second
447 This is the average number of transfers per second.
449 This is average megabytes per second.
450 .It blocks_per_second
451 This is average blocks per second. If the device blocksize is
453 a default blocksize of 512 bytes will be used instead.
454 .It ms_per_transaction
455 The average number of milliseconds per transaction.
459 provides an easy way to find the difference in seconds between two
461 structures. This is most commonly used in conjunction with the time
466 each time it fetches the current
474 return the indicated \fBsysctl\fR variable, or -1 if there is an error
475 fetching the variable.
478 returns 0 if the kernel and userland
480 versions match. If they do not match, it returns -1.
485 return -1 in case of an error, 0 if there is no error and 1 if the device
486 list or selected devices have changed. A return value of 1 from
488 is usually a hint to re-run
490 because the device list has changed.
493 returns -1 for error, and 0 if there is no error.
496 returns -1 for error, and 0 for success.
499 returns the computed elapsed time.
501 If an error is returned from one of the
503 library functions, the reason for the error is generally printed in
507 .Dv DEVSTAT_ERRBUF_SIZE
518 statistics system first appeared in
521 .An Kenneth Merry Aq ken@FreeBSD.org
523 There should probably be an interface to de-allocate memory allocated by
530 should probably not select more than
534 mode when no devices have been selected previously.
536 There should probably be functions to perform the statistics buffer
537 swapping that goes on in most of the clients of this library.
543 structures should probably be cleaned up and thought out a little more.