2 .\" Copyright (c) 1998, 1999, 2001 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
35 .Nm devstat_getnumdevs ,
36 .Nm devstat_getgeneration ,
37 .Nm devstat_getversion ,
38 .Nm devstat_checkversion ,
40 .Nm devstat_selectdevs ,
41 .Nm devstat_buildmatch ,
42 .Nm devstat_compute_statistics ,
43 .Nm devstat_compute_etime
44 .Nd device statistics utility library
50 .Fn devstat_getnumdevs "kvm_t *kd"
52 .Fn devstat_getgeneration "kvm_t *kd"
54 .Fn devstat_getversion "kvm_t *kd"
56 .Fn devstat_checkversion "kvm_t *kd"
58 .Fn devstat_getdevs "kvm_t *kd" "struct statinfo *stats"
60 .Fo devstat_selectdevs
61 .Fa "struct device_selection **dev_select"
62 .Fa "int *num_selected"
63 .Fa "int *num_selections"
64 .Fa "long *select_generation"
65 .Fa "long current_generation"
66 .Fa "struct devstat *devices"
68 .Fa "struct devstat_match *matches"
70 .Fa "char **dev_selections"
71 .Fa "int num_dev_selections"
72 .Fa "devstat_select_mode select_mode"
77 .Fo devstat_buildmatch
79 .Fa "struct devstat_match **matches"
80 .Fa "int *num_matches"
83 .Fo devstat_compute_statistics
84 .Fa "struct devstat *current"
85 .Fa "struct devstat *previous"
86 .Fa "long double etime"
90 .Fo devstat_compute_etime
91 .Fa "struct bintime *cur_time"
92 .Fa "struct bintime *prev_time"
97 library is a library of helper functions for dealing with the kernel
99 interface, which is accessible to users via
103 All functions that take a
105 as first argument can be passed
107 instead of a kvm handle as this argument,
108 which causes the data to be read via
110 Otherwise, it is read via
112 using the supplied handle.
114 .Fn devstat_checkversion
116 should be called with each kvm handle that is going to be used (or with
120 is going to be used).
123 .Fn devstat_getnumdevs
125 returns the number of devices registered with the
127 subsystem in the kernel.
130 .Fn devstat_getgeneration
132 returns the current generation of the
134 list of devices in the kernel.
137 .Fn devstat_getversion
139 returns the current kernel
144 .Fn devstat_checkversion
148 version against the kernel
151 If the two are identical, it returns zero.
152 Otherwise, it prints an appropriate error in
159 fetches the current list of devices and statistics into the supplied
164 structure can be found in
166 .Bd -literal -offset indent
168 long cp_time[CPUSTATES];
171 struct devinfo *dinfo;
172 long double snap_time;
181 structure to be allocated, and it also expects the
183 subelement to be allocated and zeroed prior to the first invocation of
184 .Fn devstat_getdevs .
187 subelement is used to store state between calls, and should not be modified
188 after the first call to
189 .Fn devstat_getdevs .
192 subelement contains the following elements:
193 .Bd -literal -offset indent
195 struct devstat *devices;
205 variable contains an array of
207 structures, but at the head of the array is the current
210 The reason the generation is at the head of the buffer is so that userland
211 software accessing the
213 statistics information can atomically get
214 both the statistics information and the corresponding generation number.
215 If client software were forced to get the generation number via a separate
217 variable (which is available for convenience), the list of devices could
218 change between the time the client gets the generation and the time the
219 client gets the device list.
225 structure is a pointer to memory that is allocated, and resized if
227 .Fn devstat_getdevs .
228 The devices subelement of the
230 structure is basically a pointer to the beginning of the array of devstat
234 variable (or the corresponding values read via
236 The generation subelement of the
238 structure contains the corresponding generation number.
243 structure contains the current
244 number of devices registered with the kernel
249 .Fn devstat_selectdevs
251 selects devices to display based upon a number of criteria:
252 .Bl -tag -width indent
253 .It specified devices
254 Specified devices are the first selection priority.
255 These are generally devices specified by name by the user e.g.\&
256 .Li da0 , da1 , cd0 .
258 These are pattern matching expressions generated by
259 .Fn devstat_buildmatch
262 If performance mode is enabled, devices will be sorted based on the
266 structure passed in to
267 .Fn devstat_selectdevs .
270 value currently must be maintained by the user.
271 In the future, this may be done for him in a
274 If no devices have been selected by name or by pattern, the performance
275 tracking code will select every device in the system, and sort them by
277 If devices have been selected by name or pattern, the performance tracking
278 code will honor those selections and will only sort among the selected
280 .It order in the devstat list
281 If the selection mode is set to
283 and if there are still less
287 .Fn devstat_selectdevs
288 will automatically select up to
294 .Fn devstat_selectdevs
296 performs selections in four different modes:
297 .Bl -tag -width ".Dv DS_SELECT_ADDONLY"
302 .Fn devstat_selectdevs
303 will select any unselected devices specified by name or matching pattern.
304 It will also select more devices, in devstat list order, until the number
305 of selected devices is equal to
307 or until all devices are
309 .It Dv DS_SELECT_ONLY
313 .Fn devstat_selectdevs
314 will clear all current selections, and will only select devices specified
315 by name or by matching pattern.
316 .It Dv DS_SELECT_REMOVE
320 .Fn devstat_selectdevs
321 will remove devices specified by name or by matching pattern.
322 It will not select any additional devices.
323 .It Dv DS_SELECT_ADDONLY
327 .Fn devstat_selectdevs
328 will select any unselected devices specified by name or matching pattern.
329 In this respect it is identical to
332 It will not, however, select any devices other than those specified.
335 In all selection modes,
336 .Fn devstat_selectdevs
337 will not select any more than
340 One exception to this is when you are in
342 mode and no devices have been selected.
344 .Fn devstat_selectdevs
345 will select every device in the system.
346 Client programs must pay attention to selection order when deciding whether
347 to pay attention to a particular device.
348 This may be the wrong behavior, and probably requires additional thought.
351 .Fn devstat_selectdevs
353 handles allocation and resizing of the
358 .Fn devstat_selectdevs
363 .Fa current_generation
367 generation and number of devices.
374 .Fa select_generation
376 .Fa current_generation ,
377 .Fn devstat_selectdevs
378 will resize the selection list as necessary, and re-initialize the
382 .Fn devstat_buildmatch
384 takes a comma separated match string and compiles it into a
386 structure that is understood by
387 .Fn devstat_selectdevs .
388 Match strings have the following format:
390 .D1 Ar device , Ns Ar type , Ns Ar if
393 .Fn devstat_buildmatch
395 takes care of allocating and reallocating the match list as necessary.
396 Currently known match types include:
397 .Bl -tag -width indent
399 .Bl -tag -width ".Li enclosure" -compact
401 Direct Access devices
403 Sequential Access devices
409 Write Once Read Multiple devices
415 Optical Memory devices
417 Medium Changer devices
419 Communication devices
421 Storage Array devices
423 Enclosure Services devices
428 .Bl -tag -width ".Li enclosure" -compact
430 Integrated Drive Electronics devices
432 Small Computer System Interface devices
434 Any other device interface
437 .Bl -tag -width ".Li enclosure" -compact
444 .Fn devstat_compute_statistics
445 function provides complete statistics calculation.
446 There are four arguments for which values
452 and the terminating argument for the varargs list,
454 For most applications, the user will want to supply valid
460 In some instances, for instance when calculating statistics since system
461 boot, the user may pass in a
467 .Fn devstat_compute_statistics
468 will use the total stats in the
470 structure to calculate statistics over
472 For each statistics to be calculated, the user should supply the proper
473 enumerated type (listed below), and a variable of the indicated type.
474 All statistics are either integer values, for which a
477 or floating point, for which a
480 The statistics that may be calculated are:
481 .Bl -tag -width ".Dv DSM_TRANSFERS_PER_SECOND_OTHER"
487 be the last argument passed to
488 .Fn devstat_compute_statistics .
489 It is an argument list terminator.
490 .It Dv DSM_TOTAL_BYTES
494 The total number of bytes transferred between the acquisition of
498 .It Dv DSM_TOTAL_BYTES_READ
499 .It Dv DSM_TOTAL_BYTES_WRITE
500 .It Dv DSM_TOTAL_BYTES_FREE
504 The total number of bytes in transactions of the specified type
505 between the acquisition of
509 .It Dv DSM_TOTAL_TRANSFERS
513 The total number of transfers between the acquisition of
517 .It Dv DSM_TOTAL_TRANSFERS_OTHER
518 .It Dv DSM_TOTAL_TRANSFERS_READ
519 .It Dv DSM_TOTAL_TRANSFERS_WRITE
520 .It Dv DSM_TOTAL_TRANSFERS_FREE
524 The total number of transactions of the specified type between
529 .It Dv DSM_TOTAL_DURATION
533 The total duration of transactions, in seconds, between the acquisition of
537 .It Dv DSM_TOTAL_DURATION_OTHER
538 .It Dv DSM_TOTAL_DURATION_READ
539 .It Dv DSM_TOTAL_DURATION_WRITE
540 .It Dv DSM_TOTAL_DURATION_FREE
544 The total duration of transactions of the specified type between
549 .It Dv DSM_TOTAL_BUSY_TIME
553 Total time the device had one or more transactions outstanding
554 between the acquisition of
558 .It Dv DSM_TOTAL_BLOCKS
562 The total number of blocks transferred between the acquisition of
566 This number is in terms of the blocksize reported by the device.
567 If no blocksize has been reported (i.e., the block size is 0), a default
568 blocksize of 512 bytes will be used in the calculation.
569 .It Dv DSM_TOTAL_BLOCKS_READ
570 .It Dv DSM_TOTAL_BLOCKS_WRITE
571 .It Dv DSM_TOTAL_BLOCKS_FREE
575 The total number of blocks of the specified type between the acquisition of
579 This number is in terms of the blocksize reported by the device.
580 If no blocksize has been reported (i.e., the block size is 0), a default
581 blocksize of 512 bytes will be used in the calculation.
582 .It Dv DSM_KB_PER_TRANSFER
586 The average number of kilobytes per transfer between the acquisition of
590 .It Dv DSM_KB_PER_TRANSFER_READ
591 .It Dv DSM_KB_PER_TRANSFER_WRITE
592 .It Dv DSM_KB_PER_TRANSFER_FREE
596 The average number of kilobytes in the specified type transaction between
601 .It Dv DSM_TRANSFERS_PER_SECOND
605 The average number of transfers per second between the acquisition of
609 .It Dv DSM_TRANSFERS_PER_SECOND_OTHER
610 .It Dv DSM_TRANSFERS_PER_SECOND_READ
611 .It Dv DSM_TRANSFERS_PER_SECOND_WRITE
612 .It Dv DSM_TRANSFERS_PER_SECOND_FREE
616 The average number of transactions of the specified type per second
617 between the acquisition of
621 .It Dv DSM_MB_PER_SECOND
625 The average number of megabytes transferred per second between the
630 .It Dv DSM_MB_PER_SECOND_READ
631 .It Dv DSM_MB_PER_SECOND_WRITE
632 .It Dv DSM_MB_PER_SECOND_FREE
636 The average number of megabytes per second in the specified type of
637 transaction between the acquisition of
641 .It Dv DSM_BLOCKS_PER_SECOND
645 The average number of blocks transferred per second between the acquisition of
649 This number is in terms of the blocksize reported by the device.
650 If no blocksize has been reported (i.e., the block size is 0), a default
651 blocksize of 512 bytes will be used in the calculation.
652 .It Dv DSM_BLOCKS_PER_SECOND_READ
653 .It Dv DSM_BLOCKS_PER_SECOND_WRITE
654 .It Dv DSM_BLOCKS_PER_SECOND_FREE
658 The average number of blocks per second in the specified type of transaction
659 between the acquisition of
663 This number is in terms of the blocksize reported by the device.
664 If no blocksize has been reported (i.e., the block size is 0), a default
665 blocksize of 512 bytes will be used in the calculation.
666 .It Dv DSM_MS_PER_TRANSACTION
670 The average duration of transactions between the acquisition of
674 .It Dv DSM_MS_PER_TRANSACTION_OTHER
675 .It Dv DSM_MS_PER_TRANSACTION_READ
676 .It Dv DSM_MS_PER_TRANSACTION_WRITE
677 .It Dv DSM_MS_PER_TRANSACTION_FREE
681 The average duration of transactions of the specified type between the
690 The percentage of time the device had one or more transactions outstanding
691 between the acquisition of
695 .It Dv DSM_QUEUE_LENGTH
699 The number of not yet completed transactions at the time when
705 If you do not need a result from
706 .Fn devstat_compute_statistics ,
709 as first (type) parameter and
712 This can be useful in scenarios where the statistics to be calculated
713 are determined at run time.
717 .Fn devstat_compute_etime
719 provides an easy way to find the difference in seconds between two
722 This is most commonly used in conjunction with the time recorded by the
725 .Vt "struct statinfo" )
726 each time it fetches the current
731 .Fn devstat_getnumdevs ,
732 .Fn devstat_getgeneration ,
734 .Fn devstat_getversion
736 return the indicated sysctl variable, or \-1 if there is an error
737 fetching the variable.
740 .Fn devstat_checkversion
742 returns 0 if the kernel and userland
745 If they do not match, it returns \-1.
750 .Fn devstat_selectdevs
752 return \-1 in case of an error, 0 if there is no error, and 1 if the device
753 list or selected devices have changed.
754 A return value of 1 from
756 is usually a hint to re-run
757 .Fn devstat_selectdevs
758 because the device list has changed.
761 .Fn devstat_buildmatch
762 function returns \-1 for error, and 0 if there is no error.
765 .Fn devstat_compute_etime
767 returns the computed elapsed time.
770 .Fn devstat_compute_statistics
771 function returns \-1 for error, and 0 for success.
773 If an error is returned from one of the
775 library functions, the reason for the error is generally printed in
779 .Dv DEVSTAT_ERRBUF_SIZE
793 statistics system first appeared in
795 The new interface (the functions prefixed with
800 .An Kenneth Merry Aq Mt ken@FreeBSD.org
802 There should probably be an interface to de-allocate memory allocated by
803 .Fn devstat_getdevs ,
804 .Fn devstat_selectdevs ,
806 .Fn devstat_buildmatch .
809 .Fn devstat_selectdevs
811 should probably not select more than
815 mode when no devices have been selected previously.
817 There should probably be functions to perform the statistics buffer
818 swapping that goes on in most of the clients of this library.
824 structures should probably be cleaned up and thought out a little more.